aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/Kconfig3
-rw-r--r--arch/alpha/Kconfig1
-rw-r--r--arch/alpha/include/asm/irqflags.h67
-rw-r--r--arch/alpha/include/asm/perf_event.h5
-rw-r--r--arch/alpha/include/asm/system.h28
-rw-r--r--arch/alpha/kernel/perf_event.c128
-rw-r--r--arch/alpha/kernel/signal.c2
-rw-r--r--arch/alpha/kernel/time.c30
-rw-r--r--arch/arm/Kconfig93
-rw-r--r--arch/arm/Kconfig.debug19
-rw-r--r--arch/arm/Makefile11
-rw-r--r--arch/arm/common/gic.c14
-rw-r--r--arch/arm/common/icst.c2
-rw-r--r--arch/arm/common/pl330.c7
-rw-r--r--arch/arm/common/sa1111.c2
-rw-r--r--arch/arm/common/scoop.c12
-rw-r--r--arch/arm/common/uengine.c18
-rw-r--r--arch/arm/configs/at91sam9g20ek_defconfig1
-rw-r--r--arch/arm/configs/kirkwood_defconfig1
-rw-r--r--arch/arm/configs/mx27_defconfig15
-rw-r--r--arch/arm/configs/mx31pdk_defconfig44
-rw-r--r--arch/arm/configs/mx3_defconfig2
-rw-r--r--arch/arm/configs/mx51_defconfig9
-rw-r--r--arch/arm/configs/realview-smp_defconfig15
-rw-r--r--arch/arm/configs/realview_defconfig15
-rw-r--r--arch/arm/configs/s5p64x0_defconfig (renamed from arch/arm/configs/s5p6440_defconfig)3
-rw-r--r--arch/arm/configs/u300_defconfig37
-rw-r--r--arch/arm/include/asm/assembler.h27
-rw-r--r--arch/arm/include/asm/cacheflush.h65
-rw-r--r--arch/arm/include/asm/cachetype.h8
-rw-r--r--arch/arm/include/asm/elf.h4
-rw-r--r--arch/arm/include/asm/ftrace.h20
-rw-r--r--arch/arm/include/asm/hardware/coresight.h34
-rw-r--r--arch/arm/include/asm/hardware/icst.h2
-rw-r--r--arch/arm/include/asm/hw_breakpoint.h133
-rw-r--r--arch/arm/include/asm/hw_irq.h2
-rw-r--r--arch/arm/include/asm/io.h1
-rw-r--r--arch/arm/include/asm/ioctls.h83
-rw-r--r--arch/arm/include/asm/irqflags.h145
-rw-r--r--arch/arm/include/asm/mach/arch.h9
-rw-r--r--arch/arm/include/asm/mmu_context.h29
-rw-r--r--arch/arm/include/asm/module.h31
-rw-r--r--arch/arm/include/asm/perf_event.h12
-rw-r--r--arch/arm/include/asm/pgtable.h26
-rw-r--r--arch/arm/include/asm/processor.h4
-rw-r--r--arch/arm/include/asm/ptrace.h2
-rw-r--r--arch/arm/include/asm/seccomp.h11
-rw-r--r--arch/arm/include/asm/smp_mpidr.h17
-rw-r--r--arch/arm/include/asm/smp_plat.h25
-rw-r--r--arch/arm/include/asm/system.h6
-rw-r--r--arch/arm/include/asm/thread_info.h2
-rw-r--r--arch/arm/include/asm/tlbflush.h36
-rw-r--r--arch/arm/kernel/Makefile1
-rw-r--r--arch/arm/kernel/armksyms.c2
-rw-r--r--arch/arm/kernel/asm-offsets.c2
-rw-r--r--arch/arm/kernel/debug.S35
-rw-r--r--arch/arm/kernel/entry-armv.S11
-rw-r--r--arch/arm/kernel/entry-common.S78
-rw-r--r--arch/arm/kernel/etm.c16
-rw-r--r--arch/arm/kernel/ftrace.c188
-rw-r--r--arch/arm/kernel/head-common.S305
-rw-r--r--arch/arm/kernel/head-nommu.S5
-rw-r--r--arch/arm/kernel/head.S323
-rw-r--r--arch/arm/kernel/hw_breakpoint.c849
-rw-r--r--arch/arm/kernel/irq.c10
-rw-r--r--arch/arm/kernel/kprobes-decode.c7
-rw-r--r--arch/arm/kernel/module.c68
-rw-r--r--arch/arm/kernel/perf_event.c212
-rw-r--r--arch/arm/kernel/process.c45
-rw-r--r--arch/arm/kernel/ptrace.c239
-rw-r--r--arch/arm/kernel/setup.c46
-rw-r--r--arch/arm/kernel/smp.c66
-rw-r--r--arch/arm/kernel/unwind.c2
-rw-r--r--arch/arm/kernel/vmlinux.lds.S39
-rw-r--r--arch/arm/mach-aaec2000/aaed2000.c2
-rw-r--r--arch/arm/mach-aaec2000/include/mach/debug-macro.S10
-rw-r--r--arch/arm/mach-aaec2000/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-at91/Kconfig21
-rw-r--r--arch/arm/mach-at91/Makefile4
-rw-r--r--arch/arm/mach-at91/board-1arm.c2
-rw-r--r--arch/arm/mach-at91/board-afeb-9260v1.c2
-rw-r--r--arch/arm/mach-at91/board-at572d940hf_ek.c4
-rw-r--r--arch/arm/mach-at91/board-cam60.c2
-rw-r--r--arch/arm/mach-at91/board-cap9adk.c2
-rw-r--r--arch/arm/mach-at91/board-carmeva.c2
-rw-r--r--arch/arm/mach-at91/board-cpu9krea.c2
-rw-r--r--arch/arm/mach-at91/board-cpuat91.c2
-rw-r--r--arch/arm/mach-at91/board-csb337.c2
-rw-r--r--arch/arm/mach-at91/board-csb637.c2
-rw-r--r--arch/arm/mach-at91/board-dk.c2
-rw-r--r--arch/arm/mach-at91/board-eb9200.c2
-rw-r--r--arch/arm/mach-at91/board-ecbat91.c2
-rw-r--r--arch/arm/mach-at91/board-eco920.c2
-rw-r--r--arch/arm/mach-at91/board-ek.c2
-rw-r--r--arch/arm/mach-at91/board-flexibity.c162
-rw-r--r--arch/arm/mach-at91/board-kafa.c2
-rw-r--r--arch/arm/mach-at91/board-kb9202.c2
-rw-r--r--arch/arm/mach-at91/board-neocore926.c2
-rw-r--r--arch/arm/mach-at91/board-picotux200.c2
-rw-r--r--arch/arm/mach-at91/board-qil-a9260.c2
-rw-r--r--arch/arm/mach-at91/board-sam9-l9260.c2
-rw-r--r--arch/arm/mach-at91/board-sam9260ek.c2
-rw-r--r--arch/arm/mach-at91/board-sam9261ek.c2
-rw-r--r--arch/arm/mach-at91/board-sam9263ek.c2
-rw-r--r--arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c329
-rw-r--r--arch/arm/mach-at91/board-sam9g20ek.c74
-rw-r--r--arch/arm/mach-at91/board-sam9m10g45ek.c6
-rw-r--r--arch/arm/mach-at91/board-sam9rlek.c2
-rw-r--r--arch/arm/mach-at91/board-snapper9260.c2
-rw-r--r--arch/arm/mach-at91/board-stamp9g20.c4
-rw-r--r--arch/arm/mach-at91/board-usb-a9260.c2
-rw-r--r--arch/arm/mach-at91/board-usb-a9263.c2
-rw-r--r--arch/arm/mach-at91/board-yl-9200.c2
-rw-r--r--arch/arm/mach-at91/include/mach/at91x40.h6
-rw-r--r--arch/arm/mach-at91/include/mach/debug-macro.S8
-rw-r--r--arch/arm/mach-at91/include/mach/system.h11
-rw-r--r--arch/arm/mach-bcmring/arch.c2
-rw-r--r--arch/arm/mach-bcmring/dma.c4
-rw-r--r--arch/arm/mach-bcmring/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-bcmring/irq.c6
-rw-r--r--arch/arm/mach-clps711x/autcpu12.c2
-rw-r--r--arch/arm/mach-clps711x/cdb89712.c2
-rw-r--r--arch/arm/mach-clps711x/ceiva.c2
-rw-r--r--arch/arm/mach-clps711x/clep7312.c2
-rw-r--r--arch/arm/mach-clps711x/edb7211-arch.c2
-rw-r--r--arch/arm/mach-clps711x/fortunet.c2
-rw-r--r--arch/arm/mach-clps711x/include/mach/debug-macro.S12
-rw-r--r--arch/arm/mach-clps711x/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-clps711x/p720t.c2
-rw-r--r--arch/arm/mach-cns3xxx/cns3420vb.c2
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/debug-macro.S10
-rw-r--r--arch/arm/mach-davinci/board-da830-evm.c2
-rw-r--r--arch/arm/mach-davinci/board-da850-evm.c2
-rw-r--r--arch/arm/mach-davinci/board-dm355-evm.c2
-rw-r--r--arch/arm/mach-davinci/board-dm355-leopard.c2
-rw-r--r--arch/arm/mach-davinci/board-dm365-evm.c2
-rw-r--r--arch/arm/mach-davinci/board-dm644x-evm.c2
-rw-r--r--arch/arm/mach-davinci/board-dm646x-evm.c4
-rw-r--r--arch/arm/mach-davinci/board-neuros-osd2.c2
-rw-r--r--arch/arm/mach-davinci/board-sffsdr.c2
-rw-r--r--arch/arm/mach-davinci/board-tnetv107x-evm.c2
-rw-r--r--arch/arm/mach-davinci/include/mach/debug-macro.S46
-rw-r--r--arch/arm/mach-dove/dove-db-setup.c2
-rw-r--r--arch/arm/mach-dove/include/mach/debug-macro.S11
-rw-r--r--arch/arm/mach-ebsa110/core.c2
-rw-r--r--arch/arm/mach-ebsa110/include/mach/debug-macro.S7
-rw-r--r--arch/arm/mach-ebsa110/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-ep93xx/adssphere.c2
-rw-r--r--arch/arm/mach-ep93xx/dma-m2p.c2
-rw-r--r--arch/arm/mach-ep93xx/edb93xx.c16
-rw-r--r--arch/arm/mach-ep93xx/gesbc9312.c2
-rw-r--r--arch/arm/mach-ep93xx/include/mach/debug-macro.S11
-rw-r--r--arch/arm/mach-ep93xx/micro9.c8
-rw-r--r--arch/arm/mach-ep93xx/simone.c2
-rw-r--r--arch/arm/mach-ep93xx/snappercl15.c2
-rw-r--r--arch/arm/mach-ep93xx/ts72xx.c2
-rw-r--r--arch/arm/mach-footbridge/cats-hw.c2
-rw-r--r--arch/arm/mach-footbridge/ebsa285.c2
-rw-r--r--arch/arm/mach-footbridge/include/mach/debug-macro.S22
-rw-r--r--arch/arm/mach-footbridge/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-footbridge/netwinder-hw.c2
-rw-r--r--arch/arm/mach-footbridge/personal.c2
-rw-r--r--arch/arm/mach-gemini/board-nas4220b.c2
-rw-r--r--arch/arm/mach-gemini/board-rut1xx.c2
-rw-r--r--arch/arm/mach-gemini/board-wbd111.c2
-rw-r--r--arch/arm/mach-gemini/board-wbd222.c2
-rw-r--r--arch/arm/mach-gemini/include/mach/debug-macro.S8
-rw-r--r--arch/arm/mach-h720x/h7201-eval.c2
-rw-r--r--arch/arm/mach-h720x/h7202-eval.c2
-rw-r--r--arch/arm/mach-h720x/include/mach/debug-macro.S10
-rw-r--r--arch/arm/mach-h720x/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-imx/Kconfig15
-rw-r--r--arch/arm/mach-imx/Makefile1
-rw-r--r--arch/arm/mach-imx/clock-imx1.c2
-rw-r--r--arch/arm/mach-imx/clock-imx21.c6
-rw-r--r--arch/arm/mach-imx/clock-imx27.c48
-rw-r--r--arch/arm/mach-imx/devices-imx1.h14
-rw-r--r--arch/arm/mach-imx/devices-imx21.h36
-rw-r--r--arch/arm/mach-imx/devices-imx27.h51
-rw-r--r--arch/arm/mach-imx/devices.c56
-rw-r--r--arch/arm/mach-imx/devices.h3
-rw-r--r--arch/arm/mach-imx/eukrea_mbimx27-baseboard.c8
-rw-r--r--arch/arm/mach-imx/mach-cpuimx27.c8
-rw-r--r--arch/arm/mach-imx/mach-imx27_visstrim_m10.c261
-rw-r--r--arch/arm/mach-imx/mach-imx27lite.c10
-rw-r--r--arch/arm/mach-imx/mach-mx1ads.c8
-rw-r--r--arch/arm/mach-imx/mach-mx21ads.c4
-rw-r--r--arch/arm/mach-imx/mach-mx27_3ds.c10
-rw-r--r--arch/arm/mach-imx/mach-mx27ads.c8
-rw-r--r--arch/arm/mach-imx/mach-mxt_td60.c15
-rw-r--r--arch/arm/mach-imx/mach-pca100.c17
-rw-r--r--arch/arm/mach-imx/mach-pcm038.c10
-rw-r--r--arch/arm/mach-imx/mach-scb9328.c4
-rw-r--r--arch/arm/mach-imx/pcm970-baseboard.c4
-rw-r--r--arch/arm/mach-integrator/include/mach/debug-macro.S10
-rw-r--r--arch/arm/mach-integrator/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-integrator/integrator_ap.c2
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c2
-rw-r--r--arch/arm/mach-iop13xx/include/mach/debug-macro.S16
-rw-r--r--arch/arm/mach-iop13xx/iq81340mc.c2
-rw-r--r--arch/arm/mach-iop13xx/iq81340sc.c2
-rw-r--r--arch/arm/mach-iop13xx/msi.c8
-rw-r--r--arch/arm/mach-iop32x/em7210.c2
-rw-r--r--arch/arm/mach-iop32x/glantank.c2
-rw-r--r--arch/arm/mach-iop32x/include/mach/debug-macro.S7
-rw-r--r--arch/arm/mach-iop32x/iq31244.c4
-rw-r--r--arch/arm/mach-iop32x/iq80321.c2
-rw-r--r--arch/arm/mach-iop32x/n2100.c2
-rw-r--r--arch/arm/mach-iop33x/include/mach/debug-macro.S12
-rw-r--r--arch/arm/mach-iop33x/iq80331.c2
-rw-r--r--arch/arm/mach-iop33x/iq80332.c2
-rw-r--r--arch/arm/mach-ixp2000/enp2611.c2
-rw-r--r--arch/arm/mach-ixp2000/include/mach/debug-macro.S14
-rw-r--r--arch/arm/mach-ixp2000/ixdp2400.c2
-rw-r--r--arch/arm/mach-ixp2000/ixdp2800.c2
-rw-r--r--arch/arm/mach-ixp2000/ixdp2x01.c6
-rw-r--r--arch/arm/mach-ixp23xx/espresso.c2
-rw-r--r--arch/arm/mach-ixp23xx/include/mach/debug-macro.S11
-rw-r--r--arch/arm/mach-ixp23xx/ixdp2351.c2
-rw-r--r--arch/arm/mach-ixp23xx/roadrunner.c2
-rw-r--r--arch/arm/mach-ixp4xx/avila-setup.c4
-rw-r--r--arch/arm/mach-ixp4xx/coyote-setup.c4
-rw-r--r--arch/arm/mach-ixp4xx/dsmg600-setup.c2
-rw-r--r--arch/arm/mach-ixp4xx/fsg-setup.c2
-rw-r--r--arch/arm/mach-ixp4xx/gateway7001-setup.c2
-rw-r--r--arch/arm/mach-ixp4xx/goramo_mlr.c2
-rw-r--r--arch/arm/mach-ixp4xx/gtwx5715-setup.c2
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/debug-macro.S16
-rw-r--r--arch/arm/mach-ixp4xx/ixdp425-setup.c8
-rw-r--r--arch/arm/mach-ixp4xx/nas100d-setup.c2
-rw-r--r--arch/arm/mach-ixp4xx/nslu2-setup.c2
-rw-r--r--arch/arm/mach-ixp4xx/vulcan-setup.c2
-rw-r--r--arch/arm/mach-ixp4xx/wg302v2-setup.c2
-rw-r--r--arch/arm/mach-kirkwood/Kconfig12
-rw-r--r--arch/arm/mach-kirkwood/Makefile12
-rw-r--r--arch/arm/mach-kirkwood/d2net_v2-setup.c229
-rw-r--r--arch/arm/mach-kirkwood/db88f6281-bp-setup.c2
-rw-r--r--arch/arm/mach-kirkwood/dockstar-setup.c110
-rw-r--r--arch/arm/mach-kirkwood/guruplug-setup.c2
-rw-r--r--arch/arm/mach-kirkwood/include/mach/debug-macro.S11
-rw-r--r--arch/arm/mach-kirkwood/include/mach/leds-netxbig.h55
-rw-r--r--arch/arm/mach-kirkwood/lacie_v2-common.c127
-rw-r--r--arch/arm/mach-kirkwood/lacie_v2-common.h18
-rw-r--r--arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c2
-rw-r--r--arch/arm/mach-kirkwood/netspace_v2-setup.c128
-rw-r--r--arch/arm/mach-kirkwood/netxbig_v2-setup.c273
-rw-r--r--arch/arm/mach-kirkwood/openrd-setup.c107
-rw-r--r--arch/arm/mach-kirkwood/rd88f6192-nas-setup.c2
-rw-r--r--arch/arm/mach-kirkwood/rd88f6281-setup.c2
-rw-r--r--arch/arm/mach-kirkwood/sheevaplug-setup.c4
-rw-r--r--arch/arm/mach-kirkwood/t5325-setup.c2
-rw-r--r--arch/arm/mach-kirkwood/ts219-setup.c2
-rw-r--r--arch/arm/mach-kirkwood/ts41x-setup.c2
-rw-r--r--arch/arm/mach-ks8695/board-acs5k.c2
-rw-r--r--arch/arm/mach-ks8695/board-dsm320.c2
-rw-r--r--arch/arm/mach-ks8695/board-micrel.c2
-rw-r--r--arch/arm/mach-ks8695/include/mach/debug-macro.S8
-rw-r--r--arch/arm/mach-l7200/include/mach/debug-macro.S38
-rw-r--r--arch/arm/mach-lh7a40x/arch-kev7a400.c2
-rw-r--r--arch/arm/mach-lh7a40x/arch-lpd7a40x.c4
-rw-r--r--arch/arm/mach-lh7a40x/include/mach/debug-macro.S10
-rw-r--r--arch/arm/mach-loki/include/mach/debug-macro.S11
-rw-r--r--arch/arm/mach-loki/lb88rc8480-setup.c2
-rw-r--r--arch/arm/mach-lpc32xx/include/mach/debug-macro.S8
-rw-r--r--arch/arm/mach-lpc32xx/phy3250.c9
-rw-r--r--arch/arm/mach-mmp/Kconfig7
-rw-r--r--arch/arm/mach-mmp/Makefile1
-rw-r--r--arch/arm/mach-mmp/aspenite.c94
-rw-r--r--arch/arm/mach-mmp/avengers_lite.c2
-rw-r--r--arch/arm/mach-mmp/common.c10
-rw-r--r--arch/arm/mach-mmp/flint.c6
-rw-r--r--arch/arm/mach-mmp/include/mach/cputype.h49
-rw-r--r--arch/arm/mach-mmp/include/mach/debug-macro.S11
-rw-r--r--arch/arm/mach-mmp/include/mach/irqs.h4
-rw-r--r--arch/arm/mach-mmp/include/mach/mfp-pxa168.h7
-rw-r--r--arch/arm/mach-mmp/include/mach/pxa168.h20
-rw-r--r--arch/arm/mach-mmp/include/mach/regs-apmu.h12
-rw-r--r--arch/arm/mach-mmp/include/mach/teton_bga.h27
-rw-r--r--arch/arm/mach-mmp/jasper.c7
-rw-r--r--arch/arm/mach-mmp/pxa168.c16
-rw-r--r--arch/arm/mach-mmp/tavorevb.c2
-rw-r--r--arch/arm/mach-mmp/teton_bga.c89
-rw-r--r--arch/arm/mach-mmp/ttc_dkb.c6
-rw-r--r--arch/arm/mach-msm/Kconfig55
-rw-r--r--arch/arm/mach-msm/Makefile21
-rw-r--r--arch/arm/mach-msm/board-halibut.c2
-rw-r--r--arch/arm/mach-msm/board-mahimahi.c2
-rw-r--r--arch/arm/mach-msm/board-msm7x27.c8
-rw-r--r--arch/arm/mach-msm/board-msm7x30.c28
-rw-r--r--arch/arm/mach-msm/board-msm8x60.c100
-rw-r--r--arch/arm/mach-msm/board-qsd8x50.c50
-rw-r--r--arch/arm/mach-msm/board-sapphire.c2
-rw-r--r--arch/arm/mach-msm/board-trout.c2
-rw-r--r--arch/arm/mach-msm/clock-dummy.c54
-rw-r--r--arch/arm/mach-msm/devices-msm7x30.c5
-rw-r--r--arch/arm/mach-msm/devices-msm8x60-iommu.c883
-rw-r--r--arch/arm/mach-msm/devices-qsd8x50.c5
-rw-r--r--arch/arm/mach-msm/gpio.c409
-rw-r--r--arch/arm/mach-msm/gpio_hw.h278
-rw-r--r--arch/arm/mach-msm/gpiomux-7x30.c38
-rw-r--r--arch/arm/mach-msm/gpiomux-8x50.c28
-rw-r--r--arch/arm/mach-msm/gpiomux-8x60.c19
-rw-r--r--arch/arm/mach-msm/gpiomux-v1.c33
-rw-r--r--arch/arm/mach-msm/gpiomux-v1.h67
-rw-r--r--arch/arm/mach-msm/gpiomux-v2.c25
-rw-r--r--arch/arm/mach-msm/gpiomux-v2.h61
-rw-r--r--arch/arm/mach-msm/gpiomux.c96
-rw-r--r--arch/arm/mach-msm/gpiomux.h114
-rw-r--r--arch/arm/mach-msm/include/mach/board.h2
-rw-r--r--arch/arm/mach-msm/include/mach/debug-macro.S22
-rw-r--r--arch/arm/mach-msm/include/mach/dma.h10
-rw-r--r--arch/arm/mach-msm/include/mach/entry-macro-qgic.S88
-rw-r--r--arch/arm/mach-msm/include/mach/entry-macro-vic.S37
-rw-r--r--arch/arm/mach-msm/include/mach/entry-macro.S43
-rw-r--r--arch/arm/mach-msm/include/mach/gpio.h123
-rw-r--r--arch/arm/mach-msm/include/mach/io.h1
-rw-r--r--arch/arm/mach-msm/include/mach/iommu.h103
-rw-r--r--arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h1871
-rw-r--r--arch/arm/mach-msm/include/mach/irqs-8x60.h253
-rw-r--r--arch/arm/mach-msm/include/mach/irqs.h2
-rw-r--r--arch/arm/mach-msm/include/mach/memory.h2
-rw-r--r--arch/arm/mach-msm/include/mach/msm_iomap-8x60.h101
-rw-r--r--arch/arm/mach-msm/include/mach/msm_iomap.h4
-rw-r--r--arch/arm/mach-msm/include/mach/smp.h39
-rw-r--r--arch/arm/mach-msm/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-msm/io.c15
-rw-r--r--arch/arm/mach-msm/iommu.c597
-rw-r--r--arch/arm/mach-msm/iommu_dev.c374
-rw-r--r--arch/arm/mach-msm/last_radio_log.c3
-rw-r--r--arch/arm/mach-msm/smd_debug.c1
-rw-r--r--arch/arm/mach-msm/timer.c23
-rw-r--r--arch/arm/mach-mv78xx0/buffalo-wxl-setup.c2
-rw-r--r--arch/arm/mach-mv78xx0/db78x00-bp-setup.c2
-rw-r--r--arch/arm/mach-mv78xx0/include/mach/debug-macro.S11
-rw-r--r--arch/arm/mach-mv78xx0/rd78x00-masa-setup.c2
-rw-r--r--arch/arm/mach-mx25/Kconfig6
-rw-r--r--arch/arm/mach-mx25/clock.c34
-rw-r--r--arch/arm/mach-mx25/devices-imx25.h61
-rw-r--r--arch/arm/mach-mx25/devices.c58
-rw-r--r--arch/arm/mach-mx25/devices.h3
-rw-r--r--arch/arm/mach-mx25/eukrea_mbimxsd-baseboard.c44
-rw-r--r--arch/arm/mach-mx25/mach-cpuimx25.c21
-rw-r--r--arch/arm/mach-mx25/mach-mx25_3ds.c7
-rw-r--r--arch/arm/mach-mx3/Kconfig11
-rw-r--r--arch/arm/mach-mx3/Makefile1
-rw-r--r--arch/arm/mach-mx3/clock-imx31.c10
-rw-r--r--arch/arm/mach-mx3/clock-imx35.c28
-rw-r--r--arch/arm/mach-mx3/cpu.c47
-rw-r--r--arch/arm/mach-mx3/devices-imx31.h49
-rw-r--r--arch/arm/mach-mx3/devices-imx35.h48
-rw-r--r--arch/arm/mach-mx3/devices.c63
-rw-r--r--arch/arm/mach-mx3/devices.h4
-rw-r--r--arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c59
-rw-r--r--arch/arm/mach-mx3/mach-armadillo5x0.c2
-rw-r--r--arch/arm/mach-mx3/mach-cpuimx35.c55
-rw-r--r--arch/arm/mach-mx3/mach-kzm_arm11_01.c2
-rw-r--r--arch/arm/mach-mx3/mach-mx31_3ds.c2
-rw-r--r--arch/arm/mach-mx3/mach-mx31ads.c11
-rw-r--r--arch/arm/mach-mx3/mach-mx31lilly.c2
-rw-r--r--arch/arm/mach-mx3/mach-mx31lite.c2
-rw-r--r--arch/arm/mach-mx3/mach-mx31moboard.c2
-rw-r--r--arch/arm/mach-mx3/mach-mx35_3ds.c53
-rw-r--r--arch/arm/mach-mx3/mach-pcm037.c2
-rw-r--r--arch/arm/mach-mx3/mach-pcm037_eet.c3
-rw-r--r--arch/arm/mach-mx3/mach-pcm043.c17
-rw-r--r--arch/arm/mach-mx3/mach-qong.c2
-rw-r--r--arch/arm/mach-mx3/mm.c18
-rw-r--r--arch/arm/mach-mx5/Kconfig42
-rw-r--r--arch/arm/mach-mx5/Makefile3
-rw-r--r--arch/arm/mach-mx5/board-cpuimx51.c25
-rw-r--r--arch/arm/mach-mx5/board-cpuimx51sd.c331
-rw-r--r--arch/arm/mach-mx5/board-mx51_3ds.c44
-rw-r--r--arch/arm/mach-mx5/board-mx51_babbage.c74
-rw-r--r--arch/arm/mach-mx5/board-mx51_efikamx.c119
-rw-r--r--arch/arm/mach-mx5/clock-mx51.c391
-rw-r--r--arch/arm/mach-mx5/cpu.c19
-rw-r--r--arch/arm/mach-mx5/devices-imx51.h42
-rw-r--r--arch/arm/mach-mx5/devices.c114
-rw-r--r--arch/arm/mach-mx5/devices.h6
-rw-r--r--arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c30
-rw-r--r--arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c166
-rw-r--r--arch/arm/mach-mxc91231/magx-zn5.c2
-rw-r--r--arch/arm/mach-netx/include/mach/debug-macro.S10
-rw-r--r--arch/arm/mach-netx/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-netx/nxdb500.c2
-rw-r--r--arch/arm/mach-netx/nxdkn.c2
-rw-r--r--arch/arm/mach-netx/nxeb500hmi.c2
-rw-r--r--arch/arm/mach-nomadik/board-nhk8815.c2
-rw-r--r--arch/arm/mach-nomadik/include/mach/debug-macro.S12
-rw-r--r--arch/arm/mach-ns9xxx/include/mach/debug-macro.S8
-rw-r--r--arch/arm/mach-nuc93x/mach-nuc932evb.c2
-rw-r--r--arch/arm/mach-omap1/Kconfig2
-rw-r--r--arch/arm/mach-omap1/board-ams-delta.c2
-rw-r--r--arch/arm/mach-omap1/board-fsample.c2
-rw-r--r--arch/arm/mach-omap1/board-generic.c2
-rw-r--r--arch/arm/mach-omap1/board-h2.c2
-rw-r--r--arch/arm/mach-omap1/board-h3.c2
-rw-r--r--arch/arm/mach-omap1/board-htcherald.c2
-rw-r--r--arch/arm/mach-omap1/board-innovator.c2
-rw-r--r--arch/arm/mach-omap1/board-nokia770.c2
-rw-r--r--arch/arm/mach-omap1/board-osk.c2
-rw-r--r--arch/arm/mach-omap1/board-palmte.c2
-rw-r--r--arch/arm/mach-omap1/board-palmtt.c2
-rw-r--r--arch/arm/mach-omap1/board-palmz71.c2
-rw-r--r--arch/arm/mach-omap1/board-perseus2.c2
-rw-r--r--arch/arm/mach-omap1/board-sx1.c2
-rw-r--r--arch/arm/mach-omap1/board-voiceblue.c2
-rw-r--r--arch/arm/mach-omap1/include/mach/debug-macro.S68
-rw-r--r--arch/arm/mach-omap1/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-omap2/board-2430sdp.c2
-rw-r--r--arch/arm/mach-omap2/board-3430sdp.c2
-rw-r--r--arch/arm/mach-omap2/board-3630sdp.c2
-rw-r--r--arch/arm/mach-omap2/board-4430sdp.c2
-rw-r--r--arch/arm/mach-omap2/board-am3517evm.c32
-rw-r--r--arch/arm/mach-omap2/board-apollon.c2
-rw-r--r--arch/arm/mach-omap2/board-cm-t35.c2
-rw-r--r--arch/arm/mach-omap2/board-devkit8000.c2
-rw-r--r--arch/arm/mach-omap2/board-generic.c2
-rw-r--r--arch/arm/mach-omap2/board-h4.c2
-rw-r--r--arch/arm/mach-omap2/board-igep0020.c2
-rw-r--r--arch/arm/mach-omap2/board-ldp.c2
-rw-r--r--arch/arm/mach-omap2/board-n8x0.c6
-rw-r--r--arch/arm/mach-omap2/board-omap3beagle.c2
-rw-r--r--arch/arm/mach-omap2/board-omap3evm.c2
-rw-r--r--arch/arm/mach-omap2/board-omap3pandora.c4
-rw-r--r--arch/arm/mach-omap2/board-omap3stalker.c2
-rw-r--r--arch/arm/mach-omap2/board-omap3touchbook.c2
-rw-r--r--arch/arm/mach-omap2/board-omap4panda.c2
-rw-r--r--arch/arm/mach-omap2/board-overo.c2
-rw-r--r--arch/arm/mach-omap2/board-rx51-peripherals.c2
-rw-r--r--arch/arm/mach-omap2/board-rx51.c2
-rw-r--r--arch/arm/mach-omap2/board-zoom-peripherals.c54
-rw-r--r--arch/arm/mach-omap2/board-zoom2.c2
-rw-r--r--arch/arm/mach-omap2/board-zoom3.c2
-rw-r--r--arch/arm/mach-omap2/clock2420_data.c2
-rw-r--r--arch/arm/mach-omap2/clock2430_data.c2
-rw-r--r--arch/arm/mach-omap2/clock3xxx_data.c2
-rw-r--r--arch/arm/mach-omap2/devices.c71
-rw-r--r--arch/arm/mach-omap2/hsmmc.h2
-rw-r--r--arch/arm/mach-omap2/include/mach/debug-macro.S127
-rw-r--r--arch/arm/mach-omap2/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-omap2/usb-musb.c4
-rw-r--r--arch/arm/mach-orion5x/d2net-setup.c4
-rw-r--r--arch/arm/mach-orion5x/db88f5281-setup.c2
-rw-r--r--arch/arm/mach-orion5x/dns323-setup.c2
-rw-r--r--arch/arm/mach-orion5x/edmini_v2-setup.c2
-rw-r--r--arch/arm/mach-orion5x/include/mach/debug-macro.S11
-rw-r--r--arch/arm/mach-orion5x/kurobox_pro-setup.c4
-rw-r--r--arch/arm/mach-orion5x/ls_hgl-setup.c2
-rw-r--r--arch/arm/mach-orion5x/lsmini-setup.c2
-rw-r--r--arch/arm/mach-orion5x/mss2-setup.c2
-rw-r--r--arch/arm/mach-orion5x/mv2120-setup.c2
-rw-r--r--arch/arm/mach-orion5x/net2big-setup.c2
-rw-r--r--arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c2
-rw-r--r--arch/arm/mach-orion5x/rd88f5181l-ge-setup.c2
-rw-r--r--arch/arm/mach-orion5x/rd88f5182-setup.c2
-rw-r--r--arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c2
-rw-r--r--arch/arm/mach-orion5x/terastation_pro2-setup.c2
-rw-r--r--arch/arm/mach-orion5x/ts209-setup.c2
-rw-r--r--arch/arm/mach-orion5x/ts409-setup.c2
-rw-r--r--arch/arm/mach-orion5x/ts78xx-setup.c2
-rw-r--r--arch/arm/mach-orion5x/wnr854t-setup.c2
-rw-r--r--arch/arm/mach-orion5x/wrt350n-v2-setup.c2
-rw-r--r--arch/arm/mach-pnx4008/core.c2
-rw-r--r--arch/arm/mach-pnx4008/include/mach/debug-macro.S10
-rw-r--r--arch/arm/mach-pnx4008/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-pxa/Kconfig27
-rw-r--r--arch/arm/mach-pxa/Makefile3
-rw-r--r--arch/arm/mach-pxa/balloon3.c107
-rw-r--r--arch/arm/mach-pxa/capc7117.c2
-rw-r--r--arch/arm/mach-pxa/cm-x2xx.c6
-rw-r--r--arch/arm/mach-pxa/cm-x300.c79
-rw-r--r--arch/arm/mach-pxa/colibri-pxa270.c4
-rw-r--r--arch/arm/mach-pxa/colibri-pxa300.c2
-rw-r--r--arch/arm/mach-pxa/colibri-pxa320.c2
-rw-r--r--arch/arm/mach-pxa/corgi.c6
-rw-r--r--arch/arm/mach-pxa/cpufreq-pxa3xx.c5
-rw-r--r--arch/arm/mach-pxa/csb726.c2
-rw-r--r--arch/arm/mach-pxa/devices.c30
-rw-r--r--arch/arm/mach-pxa/devices.h1
-rw-r--r--arch/arm/mach-pxa/em-x270.c6
-rw-r--r--arch/arm/mach-pxa/eseries.c19
-rw-r--r--arch/arm/mach-pxa/ezx.c22
-rw-r--r--arch/arm/mach-pxa/generic.c6
-rw-r--r--arch/arm/mach-pxa/generic.h2
-rw-r--r--arch/arm/mach-pxa/gumstix.c2
-rw-r--r--arch/arm/mach-pxa/h5000.c2
-rw-r--r--arch/arm/mach-pxa/himalaya.c2
-rw-r--r--arch/arm/mach-pxa/hx4700.c3
-rw-r--r--arch/arm/mach-pxa/icontrol.c2
-rw-r--r--arch/arm/mach-pxa/idp.c2
-rw-r--r--arch/arm/mach-pxa/include/mach/balloon3.h2
-rw-r--r--arch/arm/mach-pxa/include/mach/debug-macro.S10
-rw-r--r--arch/arm/mach-pxa/include/mach/eseries-irq.h1
-rw-r--r--arch/arm/mach-pxa/include/mach/hx4700.h1
-rw-r--r--arch/arm/mach-pxa/include/mach/irqs.h42
-rw-r--r--arch/arm/mach-pxa/include/mach/littleton.h2
-rw-r--r--arch/arm/mach-pxa/include/mach/lpd270.h1
-rw-r--r--arch/arm/mach-pxa/include/mach/lubbock.h3
-rw-r--r--arch/arm/mach-pxa/include/mach/magician.h2
-rw-r--r--arch/arm/mach-pxa/include/mach/mainstone.h2
-rw-r--r--arch/arm/mach-pxa/include/mach/mfp-pxa930.h7
-rw-r--r--arch/arm/mach-pxa/include/mach/pcm027.h2
-rw-r--r--arch/arm/mach-pxa/include/mach/poodle.h2
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa3xx-u2d.h35
-rw-r--r--arch/arm/mach-pxa/include/mach/tosa.h1
-rw-r--r--arch/arm/mach-pxa/include/mach/zeus.h2
-rw-r--r--arch/arm/mach-pxa/include/mach/zylonite.h2
-rw-r--r--arch/arm/mach-pxa/littleton.c5
-rw-r--r--arch/arm/mach-pxa/lpd270.c3
-rw-r--r--arch/arm/mach-pxa/lubbock.c5
-rw-r--r--arch/arm/mach-pxa/magician.c3
-rw-r--r--arch/arm/mach-pxa/mainstone.c5
-rw-r--r--arch/arm/mach-pxa/mioa701.c4
-rw-r--r--arch/arm/mach-pxa/mp900.c2
-rw-r--r--arch/arm/mach-pxa/palmld.c4
-rw-r--r--arch/arm/mach-pxa/palmt5.c4
-rw-r--r--arch/arm/mach-pxa/palmtc.c2
-rw-r--r--arch/arm/mach-pxa/palmte2.c2
-rw-r--r--arch/arm/mach-pxa/palmtreo.c6
-rw-r--r--arch/arm/mach-pxa/palmtx.c4
-rw-r--r--arch/arm/mach-pxa/palmz72.c4
-rw-r--r--arch/arm/mach-pxa/pcm027.c3
-rw-r--r--arch/arm/mach-pxa/poodle.c3
-rw-r--r--arch/arm/mach-pxa/pxa3xx-ulpi.c400
-rw-r--r--arch/arm/mach-pxa/pxa3xx.c19
-rw-r--r--arch/arm/mach-pxa/pxa930.c2
-rw-r--r--arch/arm/mach-pxa/raumfeld.c6
-rw-r--r--arch/arm/mach-pxa/saar.c2
-rw-r--r--arch/arm/mach-pxa/spitz.c6
-rw-r--r--arch/arm/mach-pxa/stargate2.c7
-rw-r--r--arch/arm/mach-pxa/tavorevb.c4
-rw-r--r--arch/arm/mach-pxa/tavorevb3.c135
-rw-r--r--arch/arm/mach-pxa/tosa.c3
-rw-r--r--arch/arm/mach-pxa/trizeps4.c4
-rw-r--r--arch/arm/mach-pxa/viper.c2
-rw-r--r--arch/arm/mach-pxa/vpac270.c2
-rw-r--r--arch/arm/mach-pxa/xcep.c2
-rw-r--r--arch/arm/mach-pxa/z2.c4
-rw-r--r--arch/arm/mach-pxa/zeus.c3
-rw-r--r--arch/arm/mach-pxa/zylonite.c5
-rw-r--r--arch/arm/mach-realview/core.c2
-rw-r--r--arch/arm/mach-realview/include/mach/debug-macro.S10
-rw-r--r--arch/arm/mach-realview/include/mach/smp.h10
-rw-r--r--arch/arm/mach-realview/realview_eb.c2
-rw-r--r--arch/arm/mach-realview/realview_pb1176.c2
-rw-r--r--arch/arm/mach-realview/realview_pb11mp.c2
-rw-r--r--arch/arm/mach-realview/realview_pba8.c2
-rw-r--r--arch/arm/mach-realview/realview_pbx.c2
-rw-r--r--arch/arm/mach-rpc/include/mach/debug-macro.S12
-rw-r--r--arch/arm/mach-rpc/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-rpc/riscpc.c2
-rw-r--r--arch/arm/mach-s3c2410/include/mach/debug-macro.S11
-rw-r--r--arch/arm/mach-s3c2410/mach-amlm5900.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-h1940.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-n30.c4
-rw-r--r--arch/arm/mach-s3c2410/mach-otom.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-qt2410.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-smdk2410.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-tct_hammer.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-vr1000.c2
-rw-r--r--arch/arm/mach-s3c2412/mach-jive.c2
-rw-r--r--arch/arm/mach-s3c2412/mach-smdk2413.c6
-rw-r--r--arch/arm/mach-s3c2412/mach-vstms.c2
-rw-r--r--arch/arm/mach-s3c2416/mach-smdk2416.c2
-rw-r--r--arch/arm/mach-s3c2440/mach-anubis.c2
-rw-r--r--arch/arm/mach-s3c2440/mach-at2440evb.c4
-rw-r--r--arch/arm/mach-s3c2440/mach-gta02.c2
-rw-r--r--arch/arm/mach-s3c2440/mach-mini2440.c2
-rw-r--r--arch/arm/mach-s3c2440/mach-nexcoder.c2
-rw-r--r--arch/arm/mach-s3c2440/mach-osiris.c2
-rw-r--r--arch/arm/mach-s3c2440/mach-rx1950.c2
-rw-r--r--arch/arm/mach-s3c2440/mach-rx3715.c2
-rw-r--r--arch/arm/mach-s3c2440/mach-smdk2440.c2
-rw-r--r--arch/arm/mach-s3c2443/mach-smdk2443.c2
-rw-r--r--arch/arm/mach-s3c24a0/include/mach/debug-macro.S11
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/debug-macro.S11
-rw-r--r--arch/arm/mach-s3c64xx/mach-anw6410.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-hmt.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-ncp.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-real6410.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-smartq.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-smartq5.c4
-rw-r--r--arch/arm/mach-s3c64xx/mach-smartq7.c4
-rw-r--r--arch/arm/mach-s3c64xx/mach-smdk6400.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-smdk6410.c2
-rw-r--r--arch/arm/mach-s5p6440/Kconfig33
-rw-r--r--arch/arm/mach-s5p6440/Makefile25
-rw-r--r--arch/arm/mach-s5p6440/clock.c846
-rw-r--r--arch/arm/mach-s5p6440/cpu.c116
-rw-r--r--arch/arm/mach-s5p6440/dev-audio.c127
-rw-r--r--arch/arm/mach-s5p6440/dev-spi.c176
-rw-r--r--arch/arm/mach-s5p6440/include/mach/debug-macro.S37
-rw-r--r--arch/arm/mach-s5p6440/include/mach/gpio.h80
-rw-r--r--arch/arm/mach-s5p6440/include/mach/io.h18
-rw-r--r--arch/arm/mach-s5p6440/include/mach/map.h86
-rw-r--r--arch/arm/mach-s5p6440/include/mach/regs-clock.h130
-rw-r--r--arch/arm/mach-s5p6440/include/mach/spi-clocks.h17
-rw-r--r--arch/arm/mach-s5p6440/include/mach/uncompress.h24
-rw-r--r--arch/arm/mach-s5p6440/init.c52
-rw-r--r--arch/arm/mach-s5p6442/cpu.c28
-rw-r--r--arch/arm/mach-s5p6442/include/mach/debug-macro.S11
-rw-r--r--arch/arm/mach-s5p6442/include/mach/map.h6
-rw-r--r--arch/arm/mach-s5p6442/mach-smdk6442.c2
-rw-r--r--arch/arm/mach-s5p64x0/Kconfig57
-rw-r--r--arch/arm/mach-s5p64x0/Makefile30
-rw-r--r--arch/arm/mach-s5p64x0/Makefile.boot (renamed from arch/arm/mach-s5p6440/Makefile.boot)0
-rw-r--r--arch/arm/mach-s5p64x0/clock-s5p6440.c626
-rw-r--r--arch/arm/mach-s5p64x0/clock-s5p6450.c655
-rw-r--r--arch/arm/mach-s5p64x0/clock.c253
-rw-r--r--arch/arm/mach-s5p64x0/cpu.c209
-rw-r--r--arch/arm/mach-s5p64x0/dev-audio.c164
-rw-r--r--arch/arm/mach-s5p64x0/dev-spi.c232
-rw-r--r--arch/arm/mach-s5p64x0/dma.c (renamed from arch/arm/mach-s5p6440/dma.c)86
-rw-r--r--arch/arm/mach-s5p64x0/gpio.c (renamed from arch/arm/mach-s5p6440/gpio.c)104
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/debug-macro.S33
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/dma.h (renamed from arch/arm/mach-s5p6440/include/mach/dma.h)0
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/entry-macro.S (renamed from arch/arm/mach-s5p6440/include/mach/entry-macro.S)8
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/gpio.h139
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/hardware.h (renamed from arch/arm/mach-s5p6440/include/mach/hardware.h)8
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/i2c.h17
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/io.h25
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/irqs.h (renamed from arch/arm/mach-s5p6440/include/mach/irqs.h)48
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/map.h83
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/memory.h (renamed from arch/arm/mach-s5p6440/include/mach/memory.h)12
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/pwm-clock.h (renamed from arch/arm/mach-s5p6440/include/mach/pwm-clock.h)10
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/regs-clock.h63
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/regs-gpio.h (renamed from arch/arm/mach-s5p6440/include/mach/regs-gpio.h)28
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/regs-irq.h (renamed from arch/arm/mach-s5p6440/include/mach/regs-irq.h)8
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h46
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/spi-clocks.h20
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/system.h (renamed from arch/arm/mach-s5p6440/include/mach/system.h)8
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/tick.h (renamed from arch/arm/mach-s5p6440/include/mach/tick.h)13
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/timex.h (renamed from arch/arm/mach-s5p6440/include/mach/timex.h)7
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/uncompress.h212
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/vmalloc.h (renamed from arch/arm/mach-s5p6440/include/mach/vmalloc.h)5
-rw-r--r--arch/arm/mach-s5p64x0/init.c73
-rw-r--r--arch/arm/mach-s5p64x0/mach-smdk6440.c (renamed from arch/arm/mach-s5p6440/mach-smdk6440.c)87
-rw-r--r--arch/arm/mach-s5p64x0/mach-smdk6450.c180
-rw-r--r--arch/arm/mach-s5p64x0/setup-i2c0.c (renamed from arch/arm/mach-s5p6440/setup-i2c0.c)24
-rw-r--r--arch/arm/mach-s5p64x0/setup-i2c1.c (renamed from arch/arm/mach-s5p6440/setup-i2c1.c)20
-rw-r--r--arch/arm/mach-s5pc100/cpu.c26
-rw-r--r--arch/arm/mach-s5pc100/include/mach/debug-macro.S11
-rw-r--r--arch/arm/mach-s5pc100/include/mach/map.h11
-rw-r--r--arch/arm/mach-s5pc100/mach-smdkc100.c2
-rw-r--r--arch/arm/mach-s5pv210/Kconfig9
-rw-r--r--arch/arm/mach-s5pv210/Makefile1
-rw-r--r--arch/arm/mach-s5pv210/clock.c5
-rw-r--r--arch/arm/mach-s5pv210/cpu.c23
-rw-r--r--arch/arm/mach-s5pv210/include/mach/debug-macro.S11
-rw-r--r--arch/arm/mach-s5pv210/include/mach/map.h11
-rw-r--r--arch/arm/mach-s5pv210/mach-aquila.c4
-rw-r--r--arch/arm/mach-s5pv210/mach-goni.c4
-rw-r--r--arch/arm/mach-s5pv210/mach-smdkc110.c2
-rw-r--r--arch/arm/mach-s5pv210/mach-smdkv210.c2
-rw-r--r--arch/arm/mach-s5pv310/cpu.c26
-rw-r--r--arch/arm/mach-s5pv310/include/mach/debug-macro.S11
-rw-r--r--arch/arm/mach-s5pv310/include/mach/irqs.h2
-rw-r--r--arch/arm/mach-s5pv310/include/mach/map.h7
-rw-r--r--arch/arm/mach-s5pv310/include/mach/smp.h9
-rw-r--r--arch/arm/mach-s5pv310/mach-smdkv310.c2
-rw-r--r--arch/arm/mach-s5pv310/mach-universal_c210.c2
-rw-r--r--arch/arm/mach-sa1100/Kconfig6
-rw-r--r--arch/arm/mach-sa1100/assabet.c2
-rw-r--r--arch/arm/mach-sa1100/badge4.c2
-rw-r--r--arch/arm/mach-sa1100/cerf.c2
-rw-r--r--arch/arm/mach-sa1100/collie.c2
-rw-r--r--arch/arm/mach-sa1100/cpu-sa1100.c2
-rw-r--r--arch/arm/mach-sa1100/h3100.c2
-rw-r--r--arch/arm/mach-sa1100/h3600.c2
-rw-r--r--arch/arm/mach-sa1100/hackkit.c2
-rw-r--r--arch/arm/mach-sa1100/include/mach/debug-macro.S36
-rw-r--r--arch/arm/mach-sa1100/jornada720.c2
-rw-r--r--arch/arm/mach-sa1100/lart.c2
-rw-r--r--arch/arm/mach-sa1100/pleb.c2
-rw-r--r--arch/arm/mach-sa1100/shannon.c2
-rw-r--r--arch/arm/mach-sa1100/simpad.c2
-rw-r--r--arch/arm/mach-shark/core.c2
-rw-r--r--arch/arm/mach-shark/include/mach/debug-macro.S7
-rw-r--r--arch/arm/mach-shark/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c2
-rw-r--r--arch/arm/mach-shmobile/board-g3evm.c2
-rw-r--r--arch/arm/mach-shmobile/board-g4evm.c2
-rw-r--r--arch/arm/mach-stmp378x/stmp378x_devb.c2
-rw-r--r--arch/arm/mach-stmp37xx/stmp37xx_devb.c2
-rw-r--r--arch/arm/mach-tcc8k/Kconfig11
-rw-r--r--arch/arm/mach-tcc8k/Makefile9
-rw-r--r--arch/arm/mach-tcc8k/Makefile.boot3
-rw-r--r--arch/arm/mach-tcc8k/board-tcc8000-sdk.c62
-rw-r--r--arch/arm/mach-tcc8k/clock.c567
-rw-r--r--arch/arm/mach-tcc8k/common.h15
-rw-r--r--arch/arm/mach-tcc8k/devices.c239
-rw-r--r--arch/arm/mach-tcc8k/io.c62
-rw-r--r--arch/arm/mach-tcc8k/irq.c111
-rw-r--r--arch/arm/mach-tcc8k/time.c149
-rw-r--r--arch/arm/mach-tegra/board-harmony.c2
-rw-r--r--arch/arm/mach-tegra/include/mach/debug-macro.S26
-rw-r--r--arch/arm/mach-tegra/include/mach/smp.h10
-rw-r--r--arch/arm/mach-u300/dummyspichip.c5
-rw-r--r--arch/arm/mach-u300/include/mach/debug-macro.S11
-rw-r--r--arch/arm/mach-u300/spi.c10
-rw-r--r--arch/arm/mach-u300/u300.c2
-rw-r--r--arch/arm/mach-ux500/Kconfig18
-rw-r--r--arch/arm/mach-ux500/Makefile8
-rw-r--r--arch/arm/mach-ux500/board-mop500-regulators.c101
-rw-r--r--arch/arm/mach-ux500/board-mop500-sdi.c91
-rw-r--r--arch/arm/mach-ux500/board-mop500.c173
-rw-r--r--arch/arm/mach-ux500/board-mop500.h12
-rw-r--r--arch/arm/mach-ux500/board-u5500.c2
-rw-r--r--arch/arm/mach-ux500/clock.c1
-rw-r--r--arch/arm/mach-ux500/cpu-db5500.c88
-rw-r--r--arch/arm/mach-ux500/cpu-db8500.c82
-rw-r--r--arch/arm/mach-ux500/devices-db8500.c114
-rw-r--r--arch/arm/mach-ux500/hotplug.c75
-rw-r--r--arch/arm/mach-ux500/include/mach/db5500-regs.h14
-rw-r--r--arch/arm/mach-ux500/include/mach/db8500-regs.h2
-rw-r--r--arch/arm/mach-ux500/include/mach/debug-macro.S8
-rw-r--r--arch/arm/mach-ux500/include/mach/devices.h8
-rw-r--r--arch/arm/mach-ux500/include/mach/hardware.h23
-rw-r--r--arch/arm/mach-ux500/include/mach/irqs-db5500.h1
-rw-r--r--arch/arm/mach-ux500/include/mach/irqs.h18
-rw-r--r--arch/arm/mach-ux500/include/mach/mbox.h88
-rw-r--r--arch/arm/mach-ux500/include/mach/prcmu-regs.h91
-rw-r--r--arch/arm/mach-ux500/include/mach/prcmu.h15
-rw-r--r--arch/arm/mach-ux500/include/mach/setup.h7
-rw-r--r--arch/arm/mach-ux500/include/mach/smp.h9
-rw-r--r--arch/arm/mach-ux500/mbox.c567
-rw-r--r--arch/arm/mach-ux500/modem_irq.c139
-rw-r--r--arch/arm/mach-ux500/pins-db5500.h620
-rw-r--r--arch/arm/mach-ux500/pins-db8500.h98
-rw-r--r--arch/arm/mach-ux500/platsmp.c2
-rw-r--r--arch/arm/mach-ux500/prcmu.c231
-rw-r--r--arch/arm/mach-ux500/ste-dma40-db5500.h135
-rw-r--r--arch/arm/mach-ux500/ste-dma40-db8500.h258
-rw-r--r--arch/arm/mach-versatile/include/mach/debug-macro.S12
-rw-r--r--arch/arm/mach-versatile/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-versatile/versatile_ab.c2
-rw-r--r--arch/arm/mach-versatile/versatile_pb.c2
-rw-r--r--arch/arm/mach-vexpress/ct-ca9x4.c6
-rw-r--r--arch/arm/mach-vexpress/include/mach/debug-macro.S10
-rw-r--r--arch/arm/mach-vexpress/include/mach/smp.h9
-rw-r--r--arch/arm/mach-vexpress/v2m.c2
-rw-r--r--arch/arm/mach-w90x900/mach-nuc910evb.c2
-rw-r--r--arch/arm/mach-w90x900/mach-nuc950evb.c2
-rw-r--r--arch/arm/mach-w90x900/mach-nuc960evb.c2
-rw-r--r--arch/arm/mm/cache-v6.S30
-rw-r--r--arch/arm/mm/cache-v7.S30
-rw-r--r--arch/arm/mm/copypage-v4mc.c2
-rw-r--r--arch/arm/mm/copypage-v6.c2
-rw-r--r--arch/arm/mm/copypage-xscale.c2
-rw-r--r--arch/arm/mm/dma-mapping.c6
-rw-r--r--arch/arm/mm/fault-armv.c8
-rw-r--r--arch/arm/mm/fault.c13
-rw-r--r--arch/arm/mm/flush.c69
-rw-r--r--arch/arm/mm/init.c41
-rw-r--r--arch/arm/mm/ioremap.c8
-rw-r--r--arch/arm/mm/mmap.c22
-rw-r--r--arch/arm/mm/mmu.c50
-rw-r--r--arch/arm/mm/proc-arm1020.S2
-rw-r--r--arch/arm/mm/proc-arm1020e.S2
-rw-r--r--arch/arm/mm/proc-arm1022.S2
-rw-r--r--arch/arm/mm/proc-arm1026.S2
-rw-r--r--arch/arm/mm/proc-arm6_7.S2
-rw-r--r--arch/arm/mm/proc-arm720.S2
-rw-r--r--arch/arm/mm/proc-arm740.S2
-rw-r--r--arch/arm/mm/proc-arm7tdmi.S2
-rw-r--r--arch/arm/mm/proc-arm920.S2
-rw-r--r--arch/arm/mm/proc-arm922.S2
-rw-r--r--arch/arm/mm/proc-arm925.S2
-rw-r--r--arch/arm/mm/proc-arm926.S2
-rw-r--r--arch/arm/mm/proc-arm940.S2
-rw-r--r--arch/arm/mm/proc-arm946.S2
-rw-r--r--arch/arm/mm/proc-arm9tdmi.S2
-rw-r--r--arch/arm/mm/proc-fa526.S2
-rw-r--r--arch/arm/mm/proc-feroceon.S2
-rw-r--r--arch/arm/mm/proc-mohawk.S2
-rw-r--r--arch/arm/mm/proc-sa110.S2
-rw-r--r--arch/arm/mm/proc-sa1100.S2
-rw-r--r--arch/arm/mm/proc-v6.S49
-rw-r--r--arch/arm/mm/proc-v7.S57
-rw-r--r--arch/arm/mm/proc-xsc3.S2
-rw-r--r--arch/arm/mm/proc-xscale.S2
-rw-r--r--arch/arm/mm/tlb-v7.S33
-rw-r--r--arch/arm/nwfpe/milieu.h4
-rw-r--r--arch/arm/nwfpe/softfloat-macros4
-rw-r--r--arch/arm/nwfpe/softfloat-specialize4
-rw-r--r--arch/arm/nwfpe/softfloat.c4
-rw-r--r--arch/arm/nwfpe/softfloat.h4
-rw-r--r--arch/arm/oprofile/Makefile4
-rw-r--r--arch/arm/oprofile/common.c308
-rw-r--r--arch/arm/plat-mxc/Kconfig16
-rw-r--r--arch/arm/plat-mxc/Makefile2
-rw-r--r--arch/arm/plat-mxc/audmux-v2.c9
-rw-r--r--arch/arm/plat-mxc/devices/Kconfig10
-rw-r--r--arch/arm/plat-mxc/devices/Makefile9
-rw-r--r--arch/arm/plat-mxc/devices/platform-esdhc.c71
-rw-r--r--arch/arm/plat-mxc/devices/platform-fec.c58
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-dma.c129
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-i2c.c85
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-ssi.c107
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-uart.c137
-rw-r--r--arch/arm/plat-mxc/devices/platform-mxc_nand.c85
-rw-r--r--arch/arm/plat-mxc/devices/platform-spi_imx.c89
-rw-r--r--arch/arm/plat-mxc/ehci.c4
-rw-r--r--arch/arm/plat-mxc/epit.c242
-rw-r--r--arch/arm/plat-mxc/gpio.c2
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx31ads.h33
-rw-r--r--arch/arm/plat-mxc/include/mach/common.h1
-rw-r--r--arch/arm/plat-mxc/include/mach/debug-macro.S8
-rw-r--r--arch/arm/plat-mxc/include/mach/devices-common.h112
-rw-r--r--arch/arm/plat-mxc/include/mach/esdhc.h16
-rw-r--r--arch/arm/plat-mxc/include/mach/eukrea-baseboards.h5
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx51.h120
-rw-r--r--arch/arm/plat-mxc/include/mach/iram.h41
-rw-r--r--arch/arm/plat-mxc/include/mach/mx21.h2
-rw-r--r--arch/arm/plat-mxc/include/mach/mx25.h17
-rw-r--r--arch/arm/plat-mxc/include/mach/mx27.h2
-rw-r--r--arch/arm/plat-mxc/include/mach/mx31.h11
-rw-r--r--arch/arm/plat-mxc/include/mach/mx35.h38
-rw-r--r--arch/arm/plat-mxc/include/mach/mx3x.h23
-rw-r--r--arch/arm/plat-mxc/include/mach/mx51.h657
-rw-r--r--arch/arm/plat-mxc/include/mach/system.h32
-rw-r--r--arch/arm/plat-mxc/include/mach/uncompress.h1
-rw-r--r--arch/arm/plat-mxc/iram_alloc.c73
-rw-r--r--arch/arm/plat-nomadik/gpio.c74
-rw-r--r--arch/arm/plat-nomadik/include/plat/gpio.h2
-rw-r--r--arch/arm/plat-nomadik/include/plat/pincfg.h36
-rw-r--r--arch/arm/plat-nomadik/include/plat/ske.h50
-rw-r--r--arch/arm/plat-omap/Kconfig2
-rw-r--r--arch/arm/plat-omap/fb.c6
-rw-r--r--arch/arm/plat-omap/include/plat/omap4-keypad.h14
-rw-r--r--arch/arm/plat-omap/include/plat/smp.h12
-rw-r--r--arch/arm/plat-omap/include/plat/usb.h21
-rw-r--r--arch/arm/plat-omap/iommu-debug.c2
-rw-r--r--arch/arm/plat-omap/iommu.c1
-rw-r--r--arch/arm/plat-omap/mcbsp.c2
-rw-r--r--arch/arm/plat-pxa/include/plat/pxa27x_keypad.h (renamed from arch/arm/mach-pxa/include/mach/pxa27x_keypad.h)10
-rw-r--r--arch/arm/plat-s5p/Kconfig9
-rw-r--r--arch/arm/plat-s5p/Makefile1
-rw-r--r--arch/arm/plat-s5p/clock.c19
-rw-r--r--arch/arm/plat-s5p/cpu.c34
-rw-r--r--arch/arm/plat-s5p/dev-onenand.c (renamed from arch/arm/mach-s5pv210/dev-onenand.c)28
-rw-r--r--arch/arm/plat-s5p/dev-uart.c58
-rw-r--r--arch/arm/plat-s5p/include/plat/pll.h7
-rw-r--r--arch/arm/plat-s5p/include/plat/s5p-clock.h8
-rw-r--r--arch/arm/plat-s5p/include/plat/s5p6440.h7
-rw-r--r--arch/arm/plat-s5p/include/plat/s5p6450.h36
-rw-r--r--arch/arm/plat-samsung/adc.c1
-rw-r--r--arch/arm/plat-samsung/clock.c27
-rw-r--r--arch/arm/plat-samsung/include/plat/adc.h2
-rw-r--r--arch/arm/plat-samsung/include/plat/cpu.h2
-rw-r--r--arch/arm/plat-samsung/include/plat/devs.h7
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h20
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c64xx-spi.h5
-rw-r--r--arch/arm/plat-spear/include/plat/debug-macro.S8
-rw-r--r--arch/arm/plat-stmp3xxx/include/mach/debug-macro.S11
-rw-r--r--arch/arm/plat-tcc/Kconfig20
-rw-r--r--arch/arm/plat-tcc/Makefile3
-rw-r--r--arch/arm/plat-tcc/clock.c179
-rw-r--r--arch/arm/plat-tcc/include/mach/clkdev.h7
-rw-r--r--arch/arm/plat-tcc/include/mach/clock.h48
-rw-r--r--arch/arm/plat-tcc/include/mach/debug-macro.S32
-rw-r--r--arch/arm/plat-tcc/include/mach/entry-macro.S68
-rw-r--r--arch/arm/plat-tcc/include/mach/hardware.h43
-rw-r--r--arch/arm/plat-tcc/include/mach/io.h23
-rw-r--r--arch/arm/plat-tcc/include/mach/irqs.h83
-rw-r--r--arch/arm/plat-tcc/include/mach/memory.h18
-rw-r--r--arch/arm/plat-tcc/include/mach/system.h31
-rw-r--r--arch/arm/plat-tcc/include/mach/tcc8k-regs.h807
-rw-r--r--arch/arm/plat-tcc/include/mach/timex.h5
-rw-r--r--arch/arm/plat-tcc/include/mach/uncompress.h34
-rw-r--r--arch/arm/plat-tcc/include/mach/vmalloc.h10
-rw-r--r--arch/arm/plat-tcc/system.c25
-rw-r--r--arch/avr32/Kconfig3
-rw-r--r--arch/avr32/boards/mimc200/fram.c1
-rw-r--r--arch/avr32/include/asm/ioctls.h86
-rw-r--r--arch/avr32/include/asm/irqflags.h29
-rw-r--r--arch/avr32/kernel/module.c3
-rw-r--r--arch/blackfin/Kconfig12
-rw-r--r--arch/blackfin/Makefile3
-rw-r--r--arch/blackfin/configs/BF527-AD7160-EVAL_defconfig105
-rw-r--r--arch/blackfin/configs/BF527-TLL6527M_defconfig180
-rw-r--r--arch/blackfin/include/asm/Kbuild1
-rw-r--r--arch/blackfin/include/asm/bfin5xx_spi.h96
-rw-r--r--arch/blackfin/include/asm/bfin_can.h9
-rw-r--r--arch/blackfin/include/asm/bfin_ppi.h51
-rw-r--r--arch/blackfin/include/asm/cachectl.h20
-rw-r--r--arch/blackfin/include/asm/cdef_LPBlackfin.h9
-rw-r--r--arch/blackfin/include/asm/ipipe.h8
-rw-r--r--arch/blackfin/include/asm/irqflags.h273
-rw-r--r--arch/blackfin/include/asm/mmu_context.h8
-rw-r--r--arch/blackfin/include/asm/ptrace.h3
-rw-r--r--arch/blackfin/include/asm/serial.h1
-rw-r--r--arch/blackfin/include/asm/system.h4
-rw-r--r--arch/blackfin/include/asm/unistd.h3
-rw-r--r--arch/blackfin/kernel/bfin_gpio.c287
-rw-r--r--arch/blackfin/kernel/cplb-mpu/cplbmgr.c8
-rw-r--r--arch/blackfin/kernel/ipipe.c38
-rw-r--r--arch/blackfin/kernel/kgdb_test.c1
-rw-r--r--arch/blackfin/kernel/process.c9
-rw-r--r--arch/blackfin/kernel/ptrace.c12
-rw-r--r--arch/blackfin/kernel/sys_bfin.c15
-rw-r--r--arch/blackfin/kernel/trace.c1
-rw-r--r--arch/blackfin/mach-bf518/boards/ezbrd.c21
-rw-r--r--arch/blackfin/mach-bf518/boards/tcm-bf518.c2
-rw-r--r--arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h82
-rw-r--r--arch/blackfin/mach-bf518/include/mach/defBF51x_base.h45
-rw-r--r--arch/blackfin/mach-bf518/include/mach/pll.h63
-rw-r--r--arch/blackfin/mach-bf527/boards/Kconfig10
-rw-r--r--arch/blackfin/mach-bf527/boards/Makefile2
-rw-r--r--arch/blackfin/mach-bf527/boards/ad7160eval.c870
-rw-r--r--arch/blackfin/mach-bf527/boards/cm_bf527.c12
-rw-r--r--arch/blackfin/mach-bf527/boards/ezbrd.c6
-rw-r--r--arch/blackfin/mach-bf527/boards/ezkit.c25
-rw-r--r--arch/blackfin/mach-bf527/boards/tll6527m.c986
-rw-r--r--arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h82
-rw-r--r--arch/blackfin/mach-bf527/include/mach/defBF52x_base.h45
-rw-r--r--arch/blackfin/mach-bf527/include/mach/pll.h63
-rw-r--r--arch/blackfin/mach-bf533/boards/H8606.c10
-rw-r--r--arch/blackfin/mach-bf533/boards/blackstamp.c5
-rw-r--r--arch/blackfin/mach-bf533/boards/cm_bf533.c10
-rw-r--r--arch/blackfin/mach-bf533/boards/ezkit.c12
-rw-r--r--arch/blackfin/mach-bf533/boards/ip0x.c3
-rw-r--r--arch/blackfin/mach-bf533/boards/stamp.c20
-rw-r--r--arch/blackfin/mach-bf533/include/mach/cdefBF532.h91
-rw-r--r--arch/blackfin/mach-bf533/include/mach/defBF532.h70
-rw-r--r--arch/blackfin/mach-bf533/include/mach/fio_flag.h55
-rw-r--r--arch/blackfin/mach-bf533/include/mach/pll.h57
-rw-r--r--arch/blackfin/mach-bf537/Kconfig4
-rw-r--r--arch/blackfin/mach-bf537/boards/cm_bf537e.c10
-rw-r--r--arch/blackfin/mach-bf537/boards/cm_bf537u.c10
-rw-r--r--arch/blackfin/mach-bf537/boards/pnav10.c12
-rw-r--r--arch/blackfin/mach-bf537/boards/stamp.c599
-rw-r--r--arch/blackfin/mach-bf537/boards/tcm_bf537.c10
-rw-r--r--arch/blackfin/mach-bf537/include/mach/cdefBF534.h44
-rw-r--r--arch/blackfin/mach-bf537/include/mach/defBF534.h44
-rw-r--r--arch/blackfin/mach-bf537/include/mach/pll.h57
-rw-r--r--arch/blackfin/mach-bf538/boards/ezkit.c4
-rw-r--r--arch/blackfin/mach-bf538/include/mach/cdefBF538.h50
-rw-r--r--arch/blackfin/mach-bf538/include/mach/defBF539.h73
-rw-r--r--arch/blackfin/mach-bf538/include/mach/pll.h63
-rw-r--r--arch/blackfin/mach-bf548/boards/cm_bf548.c47
-rw-r--r--arch/blackfin/mach-bf548/boards/ezkit.c31
-rw-r--r--arch/blackfin/mach-bf548/dma.c1
-rw-r--r--arch/blackfin/mach-bf548/include/mach/cdefBF54x_base.h58
-rw-r--r--arch/blackfin/mach-bf548/include/mach/defBF54x_base.h51
-rw-r--r--arch/blackfin/mach-bf548/include/mach/pll.h69
-rw-r--r--arch/blackfin/mach-bf561/boards/acvilon.c2
-rw-r--r--arch/blackfin/mach-bf561/boards/cm_bf561.c10
-rw-r--r--arch/blackfin/mach-bf561/boards/ezkit.c68
-rw-r--r--arch/blackfin/mach-bf561/coreb.c12
-rw-r--r--arch/blackfin/mach-bf561/include/mach/blackfin.h33
-rw-r--r--arch/blackfin/mach-bf561/include/mach/cdefBF561.h126
-rw-r--r--arch/blackfin/mach-bf561/include/mach/defBF561.h94
-rw-r--r--arch/blackfin/mach-bf561/include/mach/pll.h63
-rw-r--r--arch/blackfin/mach-bf561/ints-priority.c16
-rw-r--r--arch/blackfin/mach-bf561/smp.c24
-rw-r--r--arch/blackfin/mach-common/cpufreq.c4
-rw-r--r--arch/blackfin/mach-common/dpmc_modes.S50
-rw-r--r--arch/blackfin/mach-common/entry.S113
-rw-r--r--arch/blackfin/mach-common/interrupt.S17
-rw-r--r--arch/blackfin/mach-common/ints-priority.c35
-rw-r--r--arch/blackfin/mach-common/pm.c10
-rw-r--r--arch/blackfin/mm/init.c3
-rw-r--r--arch/cris/arch-v10/drivers/ds1302.c8
-rw-r--r--arch/cris/arch-v10/drivers/gpio.c1
-rw-r--r--arch/cris/arch-v10/drivers/i2c.c1
-rw-r--r--arch/cris/arch-v10/drivers/pcf8563.c7
-rw-r--r--arch/cris/arch-v10/drivers/sync_serial.c14
-rw-r--r--arch/cris/arch-v32/drivers/cryptocop.c7
-rw-r--r--arch/cris/arch-v32/drivers/i2c.c1
-rw-r--r--arch/cris/arch-v32/drivers/mach-a3/gpio.c12
-rw-r--r--arch/cris/arch-v32/drivers/mach-fs/gpio.c12
-rw-r--r--arch/cris/arch-v32/drivers/pcf8563.c7
-rw-r--r--arch/cris/arch-v32/drivers/sync_serial.c14
-rw-r--r--arch/cris/include/arch-v10/arch/irqflags.h45
-rw-r--r--arch/cris/include/arch-v10/arch/system.h16
-rw-r--r--arch/cris/include/arch-v32/arch/irqflags.h46
-rw-r--r--arch/cris/include/arch-v32/arch/system.h22
-rw-r--r--arch/cris/include/asm/ioctls.h84
-rw-r--r--arch/cris/include/asm/irqflags.h1
-rw-r--r--arch/cris/include/asm/system.h1
-rw-r--r--arch/cris/kernel/profile.c1
-rw-r--r--arch/frv/Kconfig1
-rw-r--r--arch/frv/include/asm/ioctls.h80
-rw-r--r--arch/frv/include/asm/irqflags.h158
-rw-r--r--arch/frv/include/asm/system.h136
-rw-r--r--arch/frv/lib/Makefile2
-rw-r--r--arch/frv/lib/perf_event.c19
-rw-r--r--arch/h8300/Kconfig.cpu8
-rw-r--r--arch/h8300/README1
-rw-r--r--arch/h8300/include/asm/ioctls.h81
-rw-r--r--arch/h8300/include/asm/irqflags.h43
-rw-r--r--arch/h8300/include/asm/system.h24
-rw-r--r--arch/h8300/kernel/module.c3
-rw-r--r--arch/ia64/Kconfig12
-rw-r--r--arch/ia64/hp/sim/simserial.c12
-rw-r--r--arch/ia64/include/asm/compat.h208
-rw-r--r--arch/ia64/include/asm/hardirq.h11
-rw-r--r--arch/ia64/include/asm/ioctls.h89
-rw-r--r--arch/ia64/include/asm/iommu_table.h6
-rw-r--r--arch/ia64/include/asm/irqflags.h94
-rw-r--r--arch/ia64/include/asm/system.h80
-rw-r--r--arch/ia64/kernel/Makefile1
-rw-r--r--arch/ia64/kernel/cyclone.c2
-rw-r--r--arch/ia64/kernel/iosapic.c60
-rw-r--r--arch/ia64/kernel/irq_ia64.c5
-rw-r--r--arch/ia64/kernel/mca.c38
-rw-r--r--arch/ia64/kernel/msi_ia64.c8
-rw-r--r--arch/ia64/kernel/palinfo.c2
-rw-r--r--arch/ia64/kernel/perfmon.c12
-rw-r--r--arch/ia64/kernel/salinfo.c4
-rw-r--r--arch/ia64/kernel/setup.c4
-rw-r--r--arch/ia64/kernel/stacktrace.c39
-rw-r--r--arch/ia64/kernel/unwind.c23
-rw-r--r--arch/ia64/kvm/lapic.h1
-rw-r--r--arch/ia64/sn/kernel/msi_sn.c4
-rw-r--r--arch/ia64/sn/kernel/sn2/sn_hwperf.c1
-rw-r--r--arch/ia64/xen/xen_pv_ops.c5
-rw-r--r--arch/m32r/Kconfig2
-rw-r--r--arch/m32r/include/asm/elf.h4
-rw-r--r--arch/m32r/include/asm/ioctls.h83
-rw-r--r--arch/m32r/include/asm/irqflags.h104
-rw-r--r--arch/m32r/include/asm/system.h66
-rw-r--r--arch/m32r/kernel/.gitignore1
-rw-r--r--arch/m32r/kernel/irq.c2
-rw-r--r--arch/m32r/kernel/signal.c4
-rw-r--r--arch/m32r/platforms/m32104ut/setup.c2
-rw-r--r--arch/m32r/platforms/m32700ut/setup.c8
-rw-r--r--arch/m32r/platforms/mappi/setup.c2
-rw-r--r--arch/m32r/platforms/mappi2/setup.c2
-rw-r--r--arch/m32r/platforms/mappi3/setup.c2
-rw-r--r--arch/m32r/platforms/oaks32r/setup.c2
-rw-r--r--arch/m32r/platforms/opsput/setup.c6
-rw-r--r--arch/m32r/platforms/usrv/setup.c4
-rw-r--r--arch/m68k/Kconfig4
-rw-r--r--arch/m68k/bvme6000/rtc.c1
-rw-r--r--arch/m68k/include/asm/amigahw.h1
-rw-r--r--arch/m68k/include/asm/atomic.h210
-rw-r--r--arch/m68k/include/asm/atomic_mm.h200
-rw-r--r--arch/m68k/include/asm/atomic_no.h155
-rw-r--r--arch/m68k/include/asm/cacheflush_no.h2
-rw-r--r--arch/m68k/include/asm/coldfire.h4
-rw-r--r--arch/m68k/include/asm/entry_mm.h3
-rw-r--r--arch/m68k/include/asm/entry_no.h2
-rw-r--r--arch/m68k/include/asm/gpio.h7
-rw-r--r--arch/m68k/include/asm/io_mm.h43
-rw-r--r--arch/m68k/include/asm/ioctls.h80
-rw-r--r--arch/m68k/include/asm/irqflags.h76
-rw-r--r--arch/m68k/include/asm/m548xgpt.h88
-rw-r--r--arch/m68k/include/asm/m548xsim.h55
-rw-r--r--arch/m68k/include/asm/machdep.h49
-rw-r--r--arch/m68k/include/asm/machdep_mm.h35
-rw-r--r--arch/m68k/include/asm/machdep_no.h26
-rw-r--r--arch/m68k/include/asm/mcfcache.h2
-rw-r--r--arch/m68k/include/asm/mcfsim.h2
-rw-r--r--arch/m68k/include/asm/mcfslt.h44
-rw-r--r--arch/m68k/include/asm/mcfuart.h9
-rw-r--r--arch/m68k/include/asm/page.h48
-rw-r--r--arch/m68k/include/asm/page_mm.h57
-rw-r--r--arch/m68k/include/asm/page_no.h51
-rw-r--r--arch/m68k/include/asm/string.h134
-rw-r--r--arch/m68k/include/asm/string_mm.h131
-rw-r--r--arch/m68k/include/asm/string_no.h126
-rw-r--r--arch/m68k/include/asm/system_mm.h27
-rw-r--r--arch/m68k/include/asm/system_no.h66
-rw-r--r--arch/m68k/include/asm/thread_info.h109
-rw-r--r--arch/m68k/include/asm/thread_info_mm.h71
-rw-r--r--arch/m68k/include/asm/thread_info_no.h102
-rw-r--r--arch/m68k/include/asm/traps.h275
-rw-r--r--arch/m68k/include/asm/traps_mm.h272
-rw-r--r--arch/m68k/include/asm/traps_no.h154
-rw-r--r--arch/m68k/kernel/asm-offsets.c12
-rw-r--r--arch/m68k/kernel/setup.c6
-rw-r--r--arch/m68k/kernel/sys_m68k.c3
-rw-r--r--arch/m68k/kernel/time.c2
-rw-r--r--arch/m68k/mac/macboing.c9
-rw-r--r--arch/m68k/mvme16x/rtc.c1
-rw-r--r--arch/m68k/q40/README2
-rw-r--r--arch/m68k/sun3/sun3ints.c2
-rw-r--r--arch/m68knommu/Kconfig11
-rw-r--r--arch/m68knommu/Makefile3
-rw-r--r--arch/m68knommu/kernel/.gitignore1
-rw-r--r--arch/m68knommu/kernel/asm-offsets.c13
-rw-r--r--arch/m68knommu/kernel/ptrace.c47
-rw-r--r--arch/m68knommu/kernel/setup.c3
-rw-r--r--arch/m68knommu/kernel/time.c16
-rw-r--r--arch/m68knommu/kernel/traps.c26
-rw-r--r--arch/m68knommu/platform/5206/Makefile4
-rw-r--r--arch/m68knommu/platform/5206e/Makefile4
-rw-r--r--arch/m68knommu/platform/520x/Makefile4
-rw-r--r--arch/m68knommu/platform/523x/Makefile4
-rw-r--r--arch/m68knommu/platform/5249/Makefile4
-rw-r--r--arch/m68knommu/platform/5272/Makefile4
-rw-r--r--arch/m68knommu/platform/5272/config.c16
-rw-r--r--arch/m68knommu/platform/5272/intc.c60
-rw-r--r--arch/m68knommu/platform/527x/Makefile4
-rw-r--r--arch/m68knommu/platform/528x/Makefile4
-rw-r--r--arch/m68knommu/platform/5307/Makefile4
-rw-r--r--arch/m68knommu/platform/532x/Makefile4
-rw-r--r--arch/m68knommu/platform/5407/Makefile4
-rw-r--r--arch/m68knommu/platform/548x/Makefile18
-rw-r--r--arch/m68knommu/platform/548x/config.c115
-rw-r--r--arch/m68knommu/platform/68328/entry.S36
-rw-r--r--arch/m68knommu/platform/68328/head-de2.S6
-rw-r--r--arch/m68knommu/platform/68328/head-ram.S27
-rw-r--r--arch/m68knommu/platform/68328/ints.c6
-rw-r--r--arch/m68knommu/platform/68360/entry.S13
-rw-r--r--arch/m68knommu/platform/68360/ints.c6
-rw-r--r--arch/m68knommu/platform/68VZ328/config.c5
-rw-r--r--arch/m68knommu/platform/coldfire/Makefile5
-rw-r--r--arch/m68knommu/platform/coldfire/entry.S8
-rw-r--r--arch/m68knommu/platform/coldfire/head.S1
-rw-r--r--arch/m68knommu/platform/coldfire/intc-2.c53
-rw-r--r--arch/m68knommu/platform/coldfire/intc-simr.c10
-rw-r--r--arch/m68knommu/platform/coldfire/intc.c8
-rw-r--r--arch/m68knommu/platform/coldfire/sltimers.c145
-rw-r--r--arch/microblaze/include/asm/irqflags.h193
-rw-r--r--arch/microblaze/include/asm/memblock.h3
-rw-r--r--arch/microblaze/kernel/prom.c5
-rw-r--r--arch/microblaze/mm/init.c30
-rw-r--r--arch/mips/Kbuild4
-rw-r--r--arch/mips/Kconfig44
-rw-r--r--arch/mips/alchemy/common/platform.c28
-rw-r--r--arch/mips/alchemy/common/power.c35
-rw-r--r--arch/mips/alchemy/common/prom.c5
-rw-r--r--arch/mips/alchemy/devboards/bcsr.c1
-rw-r--r--arch/mips/ar7/irq.c1
-rw-r--r--arch/mips/bcm63xx/irq.c1
-rw-r--r--arch/mips/boot/compressed/Makefile4
-rw-r--r--arch/mips/cavium-octeon/Kconfig4
-rw-r--r--arch/mips/cavium-octeon/cpu.c2
-rw-r--r--arch/mips/cavium-octeon/executive/Makefile2
-rw-r--r--arch/mips/cavium-octeon/serial.c1
-rw-r--r--arch/mips/dec/Platform2
-rw-r--r--arch/mips/dec/setup.c1
-rw-r--r--arch/mips/include/asm/atomic.h4
-rw-r--r--arch/mips/include/asm/cop2.h2
-rw-r--r--arch/mips/include/asm/fcntl.h1
-rw-r--r--arch/mips/include/asm/gic.h1
-rw-r--r--arch/mips/include/asm/irq.h5
-rw-r--r--arch/mips/include/asm/irqflags.h53
-rw-r--r--arch/mips/include/asm/mach-loongson/loongson.h1
-rw-r--r--arch/mips/include/asm/mach-tx49xx/kmalloc.h2
-rw-r--r--arch/mips/include/asm/mips-boards/maltaint.h3
-rw-r--r--arch/mips/include/asm/page.h14
-rw-r--r--arch/mips/include/asm/prom.h31
-rw-r--r--arch/mips/include/asm/siginfo.h1
-rw-r--r--arch/mips/include/asm/thread_info.h3
-rw-r--r--arch/mips/include/asm/unistd.h21
-rw-r--r--arch/mips/jazz/irq.c1
-rw-r--r--arch/mips/jz4740/Platform2
-rw-r--r--arch/mips/kernel/Makefile2
-rw-r--r--arch/mips/kernel/branch.c1
-rw-r--r--arch/mips/kernel/cevt-bcm1480.c1
-rw-r--r--arch/mips/kernel/cevt-ds1287.c1
-rw-r--r--arch/mips/kernel/cevt-gt641xx.c1
-rw-r--r--arch/mips/kernel/cevt-r4k.c1
-rw-r--r--arch/mips/kernel/cevt-sb1250.c1
-rw-r--r--arch/mips/kernel/cevt-smtc.c1
-rw-r--r--arch/mips/kernel/cevt-txx9.c1
-rw-r--r--arch/mips/kernel/i8253.c1
-rw-r--r--arch/mips/kernel/i8259.c1
-rw-r--r--arch/mips/kernel/irq-gic.c7
-rw-r--r--arch/mips/kernel/irq-rm7000.c1
-rw-r--r--arch/mips/kernel/irq-rm9000.c1
-rw-r--r--arch/mips/kernel/irq_cpu.c1
-rw-r--r--arch/mips/kernel/irq_txx9.c1
-rw-r--r--arch/mips/kernel/kgdb.c2
-rw-r--r--arch/mips/kernel/kspd.c2
-rw-r--r--arch/mips/kernel/linux32.c7
-rw-r--r--arch/mips/kernel/mips-mt-fpaff.c2
-rw-r--r--arch/mips/kernel/prom.c112
-rw-r--r--arch/mips/kernel/ptrace.c4
-rw-r--r--arch/mips/kernel/rtlx.c3
-rw-r--r--arch/mips/kernel/scall32-o32.S16
-rw-r--r--arch/mips/kernel/scall64-64.S14
-rw-r--r--arch/mips/kernel/scall64-n32.S17
-rw-r--r--arch/mips/kernel/scall64-o32.S20
-rw-r--r--arch/mips/kernel/setup.c2
-rw-r--r--arch/mips/kernel/signal.c45
-rw-r--r--arch/mips/kernel/signal_n32.c5
-rw-r--r--arch/mips/kernel/smtc.c4
-rw-r--r--arch/mips/kernel/traps.c2
-rw-r--r--arch/mips/kernel/unaligned.c2
-rw-r--r--arch/mips/kernel/vpe.c3
-rw-r--r--arch/mips/math-emu/cp1emu.c1
-rw-r--r--arch/mips/math-emu/dp_add.c1
-rw-r--r--arch/mips/math-emu/dp_cmp.c1
-rw-r--r--arch/mips/math-emu/dp_div.c1
-rw-r--r--arch/mips/math-emu/dp_fint.c1
-rw-r--r--arch/mips/math-emu/dp_flong.c1
-rw-r--r--arch/mips/math-emu/dp_frexp.c1
-rw-r--r--arch/mips/math-emu/dp_fsp.c1
-rw-r--r--arch/mips/math-emu/dp_logb.c1
-rw-r--r--arch/mips/math-emu/dp_modf.c1
-rw-r--r--arch/mips/math-emu/dp_mul.c1
-rw-r--r--arch/mips/math-emu/dp_scalb.c1
-rw-r--r--arch/mips/math-emu/dp_simple.c1
-rw-r--r--arch/mips/math-emu/dp_sqrt.c1
-rw-r--r--arch/mips/math-emu/dp_sub.c1
-rw-r--r--arch/mips/math-emu/dp_tint.c1
-rw-r--r--arch/mips/math-emu/dp_tlong.c1
-rw-r--r--arch/mips/math-emu/ieee754.c1
-rw-r--r--arch/mips/math-emu/ieee754.h1
-rw-r--r--arch/mips/math-emu/ieee754d.c1
-rw-r--r--arch/mips/math-emu/ieee754dp.c1
-rw-r--r--arch/mips/math-emu/ieee754dp.h1
-rw-r--r--arch/mips/math-emu/ieee754int.h1
-rw-r--r--arch/mips/math-emu/ieee754m.c1
-rw-r--r--arch/mips/math-emu/ieee754sp.c1
-rw-r--r--arch/mips/math-emu/ieee754sp.h1
-rw-r--r--arch/mips/math-emu/ieee754xcpt.c1
-rw-r--r--arch/mips/math-emu/sp_add.c1
-rw-r--r--arch/mips/math-emu/sp_cmp.c1
-rw-r--r--arch/mips/math-emu/sp_div.c1
-rw-r--r--arch/mips/math-emu/sp_fdp.c1
-rw-r--r--arch/mips/math-emu/sp_fint.c1
-rw-r--r--arch/mips/math-emu/sp_flong.c1
-rw-r--r--arch/mips/math-emu/sp_frexp.c1
-rw-r--r--arch/mips/math-emu/sp_logb.c1
-rw-r--r--arch/mips/math-emu/sp_modf.c1
-rw-r--r--arch/mips/math-emu/sp_mul.c1
-rw-r--r--arch/mips/math-emu/sp_scalb.c1
-rw-r--r--arch/mips/math-emu/sp_simple.c1
-rw-r--r--arch/mips/math-emu/sp_sqrt.c1
-rw-r--r--arch/mips/math-emu/sp_sub.c1
-rw-r--r--arch/mips/math-emu/sp_tint.c1
-rw-r--r--arch/mips/math-emu/sp_tlong.c1
-rw-r--r--arch/mips/mm/dma-default.c28
-rw-r--r--arch/mips/mm/sc-rm7k.c2
-rw-r--r--arch/mips/mti-malta/malta-int.c3
-rw-r--r--arch/mips/mti-malta/malta-platform.c1
-rw-r--r--arch/mips/pci/fixup-fuloong2e.c2
-rw-r--r--arch/mips/pci/ops-tx3927.c1
-rw-r--r--arch/mips/pci/ops-tx4927.c1
-rw-r--r--arch/mips/pci/pci-rc32434.c2
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c1
-rw-r--r--arch/mips/pnx8550/common/reset.c20
-rw-r--r--arch/mips/pnx8550/common/setup.c3
-rw-r--r--arch/mips/powertv/asic/irq_asic.c1
-rw-r--r--arch/mips/rb532/serial.c1
-rw-r--r--arch/mips/sibyte/common/sb_tbprof.c3
-rw-r--r--arch/mips/sni/a20r.c1
-rw-r--r--arch/mips/sni/pcimt.c1
-rw-r--r--arch/mips/sni/pcit.c1
-rw-r--r--arch/mips/sni/rm200.c1
-rw-r--r--arch/mips/sni/time.c1
-rw-r--r--arch/mips/txx9/generic/irq_tx4927.c1
-rw-r--r--arch/mips/txx9/generic/irq_tx4938.c1
-rw-r--r--arch/mips/txx9/generic/irq_tx4939.c1
-rw-r--r--arch/mips/txx9/generic/setup.c1
-rw-r--r--arch/mips/txx9/jmr3927/irq.c1
-rw-r--r--arch/mips/txx9/rbtx4927/irq.c1
-rw-r--r--arch/mips/txx9/rbtx4938/irq.c1
-rw-r--r--arch/mips/txx9/rbtx4939/irq.c1
-rw-r--r--arch/mips/vr41xx/common/irq.c1
-rw-r--r--arch/mips/vr41xx/common/siu.c1
-rw-r--r--arch/mn10300/include/asm/ioctls.h84
-rw-r--r--arch/mn10300/include/asm/irqflags.h123
-rw-r--r--arch/mn10300/include/asm/system.h109
-rw-r--r--arch/mn10300/kernel/entry.S1
-rw-r--r--arch/mn10300/kernel/module.c3
-rw-r--r--arch/mn10300/mm/cache.c20
-rw-r--r--arch/parisc/Kconfig1
-rw-r--r--arch/parisc/include/asm/irqflags.h46
-rw-r--r--arch/parisc/include/asm/perf_event.h3
-rw-r--r--arch/parisc/include/asm/system.h19
-rw-r--r--arch/parisc/kernel/module.c3
-rw-r--r--arch/parisc/kernel/perf.c4
-rw-r--r--arch/powerpc/Kconfig1
-rw-r--r--arch/powerpc/boot/addnote.c4
-rw-r--r--arch/powerpc/boot/dts/bluestone.dts254
-rw-r--r--arch/powerpc/boot/dts/mpc8308_p1m.dts332
-rw-r--r--arch/powerpc/boot/dts/mpc8536ds.dts52
-rw-r--r--arch/powerpc/boot/dts/p1022ds.dts11
-rw-r--r--arch/powerpc/boot/dts/p4080ds.dts11
-rw-r--r--arch/powerpc/configs/44x/bluestone_defconfig68
-rw-r--r--arch/powerpc/configs/e55xx_smp_defconfig84
-rw-r--r--arch/powerpc/configs/ppc44x_defconfig9
-rw-r--r--arch/powerpc/configs/ppc64e_defconfig4
-rw-r--r--arch/powerpc/include/asm/checksum.h10
-rw-r--r--arch/powerpc/include/asm/compat.h4
-rw-r--r--arch/powerpc/include/asm/cputable.h14
-rw-r--r--arch/powerpc/include/asm/dma-mapping.h14
-rw-r--r--arch/powerpc/include/asm/elf.h2
-rw-r--r--arch/powerpc/include/asm/exception-64s.h3
-rw-r--r--arch/powerpc/include/asm/fsl_85xx_cache_sram.h48
-rw-r--r--arch/powerpc/include/asm/hw_irq.h113
-rw-r--r--arch/powerpc/include/asm/hydra.h2
-rw-r--r--arch/powerpc/include/asm/irqflags.h2
-rw-r--r--arch/powerpc/include/asm/kexec.h1
-rw-r--r--arch/powerpc/include/asm/kvm.h1
-rw-r--r--arch/powerpc/include/asm/kvm_asm.h4
-rw-r--r--arch/powerpc/include/asm/kvm_book3s.h31
-rw-r--r--arch/powerpc/include/asm/kvm_fpu.h4
-rw-r--r--arch/powerpc/include/asm/kvm_host.h21
-rw-r--r--arch/powerpc/include/asm/kvm_para.h139
-rw-r--r--arch/powerpc/include/asm/kvm_ppc.h1
-rw-r--r--arch/powerpc/include/asm/lppaca.h29
-rw-r--r--arch/powerpc/include/asm/machdep.h3
-rw-r--r--arch/powerpc/include/asm/memblock.h7
-rw-r--r--arch/powerpc/include/asm/mmu-book3e.h15
-rw-r--r--arch/powerpc/include/asm/mmu.h12
-rw-r--r--arch/powerpc/include/asm/paca.h12
-rw-r--r--arch/powerpc/include/asm/page_64.h4
-rw-r--r--arch/powerpc/include/asm/ppc-pci.h4
-rw-r--r--arch/powerpc/include/asm/ppc_asm.h50
-rw-r--r--arch/powerpc/include/asm/processor.h4
-rw-r--r--arch/powerpc/include/asm/pte-common.h7
-rw-r--r--arch/powerpc/include/asm/rtas.h1
-rw-r--r--arch/powerpc/include/asm/systbl.h19
-rw-r--r--arch/powerpc/include/asm/system.h8
-rw-r--r--arch/powerpc/include/asm/time.h5
-rw-r--r--arch/powerpc/include/asm/unistd.h21
-rw-r--r--arch/powerpc/kernel/Makefile6
-rw-r--r--arch/powerpc/kernel/align.c4
-rw-r--r--arch/powerpc/kernel/asm-offsets.c37
-rw-r--r--arch/powerpc/kernel/cpu_setup_44x.S1
-rw-r--r--arch/powerpc/kernel/cpu_setup_fsl_booke.S15
-rw-r--r--arch/powerpc/kernel/cputable.c43
-rw-r--r--arch/powerpc/kernel/crash.c13
-rw-r--r--arch/powerpc/kernel/dma-iommu.c21
-rw-r--r--arch/powerpc/kernel/dma.c20
-rw-r--r--arch/powerpc/kernel/entry_64.S40
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S10
-rw-r--r--arch/powerpc/kernel/fpu.S10
-rw-r--r--arch/powerpc/kernel/head_40x.S6
-rw-r--r--arch/powerpc/kernel/head_64.S6
-rw-r--r--arch/powerpc/kernel/head_fsl_booke.S10
-rw-r--r--arch/powerpc/kernel/ibmebus.c11
-rw-r--r--arch/powerpc/kernel/irq.c10
-rw-r--r--arch/powerpc/kernel/kvm.c596
-rw-r--r--arch/powerpc/kernel/kvm_emul.S302
-rw-r--r--arch/powerpc/kernel/legacy_serial.c22
-rw-r--r--arch/powerpc/kernel/lparcfg.c15
-rw-r--r--arch/powerpc/kernel/machine_kexec.c24
-rw-r--r--arch/powerpc/kernel/machine_kexec_32.c4
-rw-r--r--arch/powerpc/kernel/module.c6
-rw-r--r--arch/powerpc/kernel/paca.c72
-rw-r--r--arch/powerpc/kernel/pci-common.c4
-rw-r--r--arch/powerpc/kernel/perf_callchain.c86
-rw-r--r--arch/powerpc/kernel/perf_event.c166
-rw-r--r--arch/powerpc/kernel/perf_event_fsl_emb.c148
-rw-r--r--arch/powerpc/kernel/ppc970-pmu.c2
-rw-r--r--arch/powerpc/kernel/process.c12
-rw-r--r--arch/powerpc/kernel/prom.c27
-rw-r--r--arch/powerpc/kernel/ptrace.c2
-rw-r--r--arch/powerpc/kernel/rtas.c6
-rw-r--r--arch/powerpc/kernel/rtas_flash.c3
-rw-r--r--arch/powerpc/kernel/rtasd.c1
-rw-r--r--arch/powerpc/kernel/setup_32.c4
-rw-r--r--arch/powerpc/kernel/setup_64.c2
-rw-r--r--arch/powerpc/kernel/smp.c14
-rw-r--r--arch/powerpc/kernel/time.c317
-rw-r--r--arch/powerpc/kernel/traps.c5
-rw-r--r--arch/powerpc/kernel/vdso.c6
-rw-r--r--arch/powerpc/kernel/vdso32/Makefile6
-rw-r--r--arch/powerpc/kernel/vdso64/Makefile6
-rw-r--r--arch/powerpc/kernel/vio.c10
-rw-r--r--arch/powerpc/kvm/44x.c10
-rw-r--r--arch/powerpc/kvm/44x_tlb.c9
-rw-r--r--arch/powerpc/kvm/Makefile2
-rw-r--r--arch/powerpc/kvm/book3s.c272
-rw-r--r--arch/powerpc/kvm/book3s_32_mmu.c111
-rw-r--r--arch/powerpc/kvm/book3s_32_mmu_host.c75
-rw-r--r--arch/powerpc/kvm/book3s_64_mmu.c42
-rw-r--r--arch/powerpc/kvm/book3s_64_mmu_host.c74
-rw-r--r--arch/powerpc/kvm/book3s_emulate.c73
-rw-r--r--arch/powerpc/kvm/book3s_mmu_hpte.c140
-rw-r--r--arch/powerpc/kvm/book3s_paired_singles.c55
-rw-r--r--arch/powerpc/kvm/book3s_rmhandlers.S32
-rw-r--r--arch/powerpc/kvm/booke.c108
-rw-r--r--arch/powerpc/kvm/booke.h10
-rw-r--r--arch/powerpc/kvm/booke_emulate.c14
-rw-r--r--arch/powerpc/kvm/booke_interrupts.S3
-rw-r--r--arch/powerpc/kvm/e500.c7
-rw-r--r--arch/powerpc/kvm/e500_tlb.c18
-rw-r--r--arch/powerpc/kvm/e500_tlb.h2
-rw-r--r--arch/powerpc/kvm/emulate.c40
-rw-r--r--arch/powerpc/kvm/fpu.S8
-rw-r--r--arch/powerpc/kvm/powerpc.c88
-rw-r--r--arch/powerpc/kvm/trace.h239
-rw-r--r--arch/powerpc/lib/Makefile7
-rw-r--r--arch/powerpc/lib/checksum_64.S482
-rw-r--r--arch/powerpc/lib/checksum_wrappers_64.c102
-rw-r--r--arch/powerpc/lib/copy_32.S2
-rw-r--r--arch/powerpc/lib/ldstfp.S36
-rw-r--r--arch/powerpc/lib/locks.c4
-rw-r--r--arch/powerpc/lib/sstep.c8
-rw-r--r--arch/powerpc/math-emu/Makefile2
-rw-r--r--arch/powerpc/mm/40x_mmu.c17
-rw-r--r--arch/powerpc/mm/44x_mmu.c14
-rw-r--r--arch/powerpc/mm/Makefile6
-rw-r--r--arch/powerpc/mm/fault.c6
-rw-r--r--arch/powerpc/mm/fsl_booke_mmu.c27
-rw-r--r--arch/powerpc/mm/hash_utils_64.c35
-rw-r--r--arch/powerpc/mm/init_32.c43
-rw-r--r--arch/powerpc/mm/init_64.c1
-rw-r--r--arch/powerpc/mm/mem.c94
-rw-r--r--arch/powerpc/mm/mmu_context_nohash.c6
-rw-r--r--arch/powerpc/mm/mmu_decl.h5
-rw-r--r--arch/powerpc/mm/numa.c17
-rw-r--r--arch/powerpc/mm/ppc_mmu_32.c18
-rw-r--r--arch/powerpc/mm/tlb_nohash.c72
-rw-r--r--arch/powerpc/mm/tlb_nohash_low.S2
-rw-r--r--arch/powerpc/oprofile/Makefile4
-rw-r--r--arch/powerpc/oprofile/backtrace.c2
-rw-r--r--arch/powerpc/oprofile/op_model_fsl_emb.c15
-rw-r--r--arch/powerpc/platforms/44x/Kconfig16
-rw-r--r--arch/powerpc/platforms/44x/ppc44x_simple.c1
-rw-r--r--arch/powerpc/platforms/512x/clock.c2
-rw-r--r--arch/powerpc/platforms/52xx/efika.c9
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_common.c8
-rw-r--r--arch/powerpc/platforms/83xx/Kconfig4
-rw-r--r--arch/powerpc/platforms/83xx/mpc830x_rdb.c3
-rw-r--r--arch/powerpc/platforms/85xx/Kconfig28
-rw-r--r--arch/powerpc/platforms/85xx/Makefile2
-rw-r--r--arch/powerpc/platforms/85xx/p1022_ds.c2
-rw-r--r--arch/powerpc/platforms/85xx/p3041_ds.c64
-rw-r--r--arch/powerpc/platforms/85xx/p5020_ds.c69
-rw-r--r--arch/powerpc/platforms/85xx/smp.c83
-rw-r--r--arch/powerpc/platforms/Kconfig10
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype8
-rw-r--r--arch/powerpc/platforms/cell/axon_msi.c6
-rw-r--r--arch/powerpc/platforms/cell/ras.c4
-rw-r--r--arch/powerpc/platforms/cell/spider-pic.c4
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c18
-rw-r--r--arch/powerpc/platforms/chrp/nvram.c4
-rw-r--r--arch/powerpc/platforms/embedded6xx/wii.c2
-rw-r--r--arch/powerpc/platforms/iseries/Makefile2
-rw-r--r--arch/powerpc/platforms/iseries/dt.c4
-rw-r--r--arch/powerpc/platforms/iseries/mf.c1
-rw-r--r--arch/powerpc/platforms/iseries/smp.c2
-rw-r--r--arch/powerpc/platforms/maple/setup.c1
-rw-r--r--arch/powerpc/platforms/powermac/pfunc_core.c9
-rw-r--r--arch/powerpc/platforms/pseries/Makefile13
-rw-r--r--arch/powerpc/platforms/pseries/dlpar.c7
-rw-r--r--arch/powerpc/platforms/pseries/dtl.c224
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c25
-rw-r--r--arch/powerpc/platforms/pseries/mobility.c362
-rw-r--r--arch/powerpc/platforms/pseries/pseries.h9
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c3
-rw-r--r--arch/powerpc/platforms/pseries/scanlog.c1
-rw-r--r--arch/powerpc/platforms/pseries/setup.c52
-rw-r--r--arch/powerpc/platforms/pseries/xics.c4
-rw-r--r--arch/powerpc/sysdev/Makefile5
-rw-r--r--arch/powerpc/sysdev/dart_iommu.c74
-rw-r--r--arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h101
-rw-r--r--arch/powerpc/sysdev/fsl_85xx_cache_sram.c159
-rw-r--r--arch/powerpc/sysdev/fsl_85xx_l2ctlr.c231
-rw-r--r--arch/powerpc/sysdev/fsl_msi.c13
-rw-r--r--arch/powerpc/sysdev/fsl_pci.c60
-rw-r--r--arch/powerpc/sysdev/fsl_pci.h1
-rw-r--r--arch/powerpc/sysdev/fsl_rio.c65
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c181
-rw-r--r--arch/powerpc/sysdev/mpc8xxx_gpio.c3
-rw-r--r--arch/powerpc/sysdev/mpic_pasemi_msi.c22
-rw-r--r--arch/powerpc/sysdev/mpic_u3msi.c18
-rw-r--r--arch/powerpc/sysdev/pmi.c2
-rw-r--r--arch/powerpc/xmon/Makefile4
-rw-r--r--arch/s390/Kconfig8
-rw-r--r--arch/s390/crypto/prng.c1
-rw-r--r--arch/s390/hypfs/hypfs_diag.c1
-rw-r--r--arch/s390/hypfs/hypfs_vm.c1
-rw-r--r--arch/s390/hypfs/inode.c1
-rw-r--r--arch/s390/include/asm/Kbuild1
-rw-r--r--arch/s390/include/asm/hardirq.h4
-rw-r--r--arch/s390/include/asm/ioctls.h88
-rw-r--r--arch/s390/include/asm/irqflags.h51
-rw-r--r--arch/s390/include/asm/kvm_virtio.h7
-rw-r--r--arch/s390/include/asm/perf_event.h3
-rw-r--r--arch/s390/include/asm/qdio.h13
-rw-r--r--arch/s390/include/asm/system.h3
-rw-r--r--arch/s390/include/asm/topology.h27
-rw-r--r--arch/s390/kernel/debug.c1
-rw-r--r--arch/s390/kernel/mem_detect.c4
-rw-r--r--arch/s390/kernel/module.c3
-rw-r--r--arch/s390/kernel/topology.c150
-rw-r--r--arch/s390/mm/init.c3
-rw-r--r--arch/s390/mm/maccess.c4
-rw-r--r--arch/score/include/asm/irqflags.h187
-rw-r--r--arch/sh/Kconfig20
-rw-r--r--arch/sh/boards/Kconfig18
-rw-r--r--arch/sh/boards/Makefile2
-rw-r--r--arch/sh/boards/board-sh2007.c133
-rw-r--r--arch/sh/boards/board-sh7757lcr.c374
-rw-r--r--arch/sh/boards/mach-ecovec24/setup.c6
-rw-r--r--arch/sh/boards/mach-landisk/gio.c1
-rw-r--r--arch/sh/boards/mach-sdk7786/Makefile5
-rw-r--r--arch/sh/boards/mach-sdk7786/gpio.c49
-rw-r--r--arch/sh/boards/mach-sdk7786/setup.c54
-rw-r--r--arch/sh/boards/mach-sdk7786/sram.c72
-rw-r--r--arch/sh/boards/mach-x3proto/Makefile2
-rw-r--r--arch/sh/boards/mach-x3proto/gpio.c135
-rw-r--r--arch/sh/boards/mach-x3proto/ilsel.c18
-rw-r--r--arch/sh/boards/mach-x3proto/setup.c132
-rw-r--r--arch/sh/boot/compressed/head_32.S4
-rw-r--r--arch/sh/cchips/hd6446x/Makefile2
-rw-r--r--arch/sh/configs/ap325rxa_defconfig1
-rw-r--r--arch/sh/configs/cayman_defconfig1
-rw-r--r--arch/sh/configs/dreamcast_defconfig1
-rw-r--r--arch/sh/configs/ecovec24-romimage_defconfig1
-rw-r--r--arch/sh/configs/edosk7760_defconfig1
-rw-r--r--arch/sh/configs/espt_defconfig1
-rw-r--r--arch/sh/configs/hp6xx_defconfig1
-rw-r--r--arch/sh/configs/kfr2r09-romimage_defconfig1
-rw-r--r--arch/sh/configs/kfr2r09_defconfig1
-rw-r--r--arch/sh/configs/landisk_defconfig1
-rw-r--r--arch/sh/configs/lboxre2_defconfig1
-rw-r--r--arch/sh/configs/magicpanelr2_defconfig1
-rw-r--r--arch/sh/configs/microdev_defconfig1
-rw-r--r--arch/sh/configs/migor_defconfig1
-rw-r--r--arch/sh/configs/polaris_defconfig1
-rw-r--r--arch/sh/configs/r7780mp_defconfig1
-rw-r--r--arch/sh/configs/r7785rp_defconfig1
-rw-r--r--arch/sh/configs/rts7751r2d1_defconfig1
-rw-r--r--arch/sh/configs/rts7751r2dplus_defconfig1
-rw-r--r--arch/sh/configs/sdk7780_defconfig1
-rw-r--r--arch/sh/configs/se7343_defconfig1
-rw-r--r--arch/sh/configs/se7712_defconfig1
-rw-r--r--arch/sh/configs/se7721_defconfig1
-rw-r--r--arch/sh/configs/se7722_defconfig1
-rw-r--r--arch/sh/configs/se7724_defconfig1
-rw-r--r--arch/sh/configs/se7750_defconfig1
-rw-r--r--arch/sh/configs/se7751_defconfig1
-rw-r--r--arch/sh/configs/se7780_defconfig1
-rw-r--r--arch/sh/configs/sh03_defconfig1
-rw-r--r--arch/sh/configs/sh2007_defconfig212
-rw-r--r--arch/sh/configs/sh7710voipgw_defconfig1
-rw-r--r--arch/sh/configs/sh7757lcr_defconfig85
-rw-r--r--arch/sh/configs/sh7763rdp_defconfig1
-rw-r--r--arch/sh/configs/sh7785lcr_defconfig1
-rw-r--r--arch/sh/configs/shx3_defconfig1
-rw-r--r--arch/sh/configs/snapgear_defconfig1
-rw-r--r--arch/sh/configs/systemh_defconfig1
-rw-r--r--arch/sh/configs/titan_defconfig1
-rw-r--r--arch/sh/configs/ul2_defconfig1
-rw-r--r--arch/sh/drivers/dma/dma-api.c4
-rw-r--r--arch/sh/drivers/pci/Makefile1
-rw-r--r--arch/sh/drivers/pci/fixups-sdk7786.c67
-rw-r--r--arch/sh/drivers/pci/ops-sh4.c11
-rw-r--r--arch/sh/drivers/pci/ops-sh7786.c69
-rw-r--r--arch/sh/drivers/pci/pci-sh7751.c2
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.c2
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.h6
-rw-r--r--arch/sh/drivers/pci/pci.c43
-rw-r--r--arch/sh/drivers/pci/pcie-sh7786.c251
-rw-r--r--arch/sh/drivers/pci/pcie-sh7786.h56
-rw-r--r--arch/sh/include/asm/Kbuild2
-rw-r--r--arch/sh/include/asm/elf.h27
-rw-r--r--arch/sh/include/asm/fixmap.h4
-rw-r--r--arch/sh/include/asm/gpio.h6
-rw-r--r--arch/sh/include/asm/irq.h2
-rw-r--r--arch/sh/include/asm/irqflags.h4
-rw-r--r--arch/sh/include/asm/kprobes.h1
-rw-r--r--arch/sh/include/asm/memblock.h2
-rw-r--r--arch/sh/include/asm/pci.h2
-rw-r--r--arch/sh/include/asm/perf_event.h7
-rw-r--r--arch/sh/include/asm/processor_32.h3
-rw-r--r--arch/sh/include/asm/processor_64.h3
-rw-r--r--arch/sh/include/asm/ptrace.h169
-rw-r--r--arch/sh/include/asm/ptrace_32.h83
-rw-r--r--arch/sh/include/asm/ptrace_64.h20
-rw-r--r--arch/sh/include/asm/sizes.h1
-rw-r--r--arch/sh/include/asm/sram.h38
-rw-r--r--arch/sh/include/asm/syscalls_32.h7
-rw-r--r--arch/sh/include/asm/system.h2
-rw-r--r--arch/sh/include/asm/system_32.h15
-rw-r--r--arch/sh/include/asm/tlbflush.h2
-rw-r--r--arch/sh/include/asm/unistd_32.h27
-rw-r--r--arch/sh/include/asm/unistd_64.h5
-rw-r--r--arch/sh/include/cpu-sh3/cpu/mmu_context.h1
-rw-r--r--arch/sh/include/cpu-sh4/cpu/freq.h4
-rw-r--r--arch/sh/include/cpu-sh4/cpu/sh7757.h301
-rw-r--r--arch/sh/include/cpu-sh4/cpu/shx3.h64
-rw-r--r--arch/sh/include/mach-common/mach/sh2007.h117
-rw-r--r--arch/sh/include/mach-sdk7786/mach/fpga.h26
-rw-r--r--arch/sh/include/mach-x3proto/mach/hardware.h12
-rw-r--r--arch/sh/include/mach-x3proto/mach/ilsel.h (renamed from arch/sh/include/asm/ilsel.h)0
-rw-r--r--arch/sh/kernel/Makefile8
-rw-r--r--arch/sh/kernel/clkdev.c4
-rw-r--r--arch/sh/kernel/cpu/sh4/probe.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/Makefile5
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7757.c199
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-shx3.c225
-rw-r--r--arch/sh/kernel/cpu/sh4a/intc-shx3.c34
-rw-r--r--arch/sh/kernel/cpu/sh4a/perf_event.c20
-rw-r--r--arch/sh/kernel/cpu/sh4a/pinmux-sh7757.c1582
-rw-r--r--arch/sh/kernel/cpu/sh4a/pinmux-shx3.c587
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7724.c66
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7757.c222
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7786.c126
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-shx3.c42
-rw-r--r--arch/sh/kernel/head_32.S2
-rw-r--r--arch/sh/kernel/io_trapped.c2
-rw-r--r--arch/sh/kernel/irq.c4
-rw-r--r--arch/sh/kernel/irq_32.c12
-rw-r--r--arch/sh/kernel/kdebugfs.c16
-rw-r--r--arch/sh/kernel/kprobes.c100
-rw-r--r--arch/sh/kernel/module.c2
-rw-r--r--arch/sh/kernel/perf_callchain.c50
-rw-r--r--arch/sh/kernel/perf_event.c159
-rw-r--r--arch/sh/kernel/ptrace.c33
-rw-r--r--arch/sh/kernel/ptrace_32.c27
-rw-r--r--arch/sh/kernel/ptrace_64.c88
-rw-r--r--arch/sh/kernel/reboot.c4
-rw-r--r--arch/sh/kernel/setup.c22
-rw-r--r--arch/sh/kernel/syscalls_32.S22
-rw-r--r--arch/sh/kernel/syscalls_64.S3
-rw-r--r--arch/sh/kernel/traps_32.c29
-rw-r--r--arch/sh/kernel/traps_64.c11
-rw-r--r--arch/sh/lib/Makefile2
-rw-r--r--arch/sh/math-emu/math.c3
-rw-r--r--arch/sh/mm/Kconfig4
-rw-r--r--arch/sh/mm/Makefile3
-rw-r--r--arch/sh/mm/asids-debugfs.c2
-rw-r--r--arch/sh/mm/cache-debugfs.c10
-rw-r--r--arch/sh/mm/consistent.c3
-rw-r--r--arch/sh/mm/init.c69
-rw-r--r--arch/sh/mm/nommu.c4
-rw-r--r--arch/sh/mm/pmb.c35
-rw-r--r--arch/sh/mm/sram.c34
-rw-r--r--arch/sh/mm/tlb-debugfs.c11
-rw-r--r--arch/sh/mm/tlbflush_32.c16
-rw-r--r--arch/sh/mm/tlbflush_64.c5
-rw-r--r--arch/sh/oprofile/Makefile4
-rw-r--r--arch/sh/oprofile/common.c115
-rw-r--r--arch/sh/oprofile/op_impl.h33
-rw-r--r--arch/sh/tools/mach-types2
-rw-r--r--arch/sparc/Kconfig4
-rw-r--r--arch/sparc/include/asm/Kbuild1
-rw-r--r--arch/sparc/include/asm/floppy_32.h3
-rw-r--r--arch/sparc/include/asm/irqflags_32.h35
-rw-r--r--arch/sparc/include/asm/irqflags_64.h29
-rw-r--r--arch/sparc/include/asm/jump_label.h32
-rw-r--r--arch/sparc/include/asm/memblock.h2
-rw-r--r--arch/sparc/include/asm/openprom.h16
-rw-r--r--arch/sparc/include/asm/oplib_32.h44
-rw-r--r--arch/sparc/include/asm/oplib_64.h39
-rw-r--r--arch/sparc/include/asm/perf_event.h4
-rw-r--r--arch/sparc/include/asm/prom.h5
-rw-r--r--arch/sparc/kernel/Makefile2
-rw-r--r--arch/sparc/kernel/apc.c1
-rw-r--r--arch/sparc/kernel/auxio_32.c4
-rw-r--r--arch/sparc/kernel/btext.c4
-rw-r--r--arch/sparc/kernel/devices.c23
-rw-r--r--arch/sparc/kernel/irq_32.c13
-rw-r--r--arch/sparc/kernel/jump_label.c47
-rw-r--r--arch/sparc/kernel/leon_kernel.c2
-rw-r--r--arch/sparc/kernel/mdesc.c1
-rw-r--r--arch/sparc/kernel/module.c6
-rw-r--r--arch/sparc/kernel/pci_msi.c8
-rw-r--r--arch/sparc/kernel/pcic.c4
-rw-r--r--arch/sparc/kernel/pcr.c8
-rw-r--r--arch/sparc/kernel/perf_event.c240
-rw-r--r--arch/sparc/kernel/prom.h6
-rw-r--r--arch/sparc/kernel/prom_common.c202
-rw-r--r--arch/sparc/kernel/setup_64.c2
-rw-r--r--arch/sparc/kernel/starfire.c2
-rw-r--r--arch/sparc/kernel/tadpole.c2
-rw-r--r--arch/sparc/mm/init_64.c48
-rw-r--r--arch/sparc/mm/srmmu.c8
-rw-r--r--arch/sparc/mm/sun4c.c2
-rw-r--r--arch/sparc/prom/init_32.c2
-rw-r--r--arch/sparc/prom/init_64.c4
-rw-r--r--arch/sparc/prom/memory.c3
-rw-r--r--arch/sparc/prom/misc_64.c6
-rw-r--r--arch/sparc/prom/p1275.c2
-rw-r--r--arch/sparc/prom/ranges.c6
-rw-r--r--arch/sparc/prom/tree_32.c58
-rw-r--r--arch/sparc/prom/tree_64.c62
-rw-r--r--arch/tile/include/asm/bitops.h1
-rw-r--r--arch/tile/include/asm/irqflags.h36
-rw-r--r--arch/tile/kernel/hardwall.c1
-rw-r--r--arch/tile/kernel/irq.c4
-rw-r--r--arch/um/drivers/harddog_kern.c14
-rw-r--r--arch/um/drivers/hostaudio_kern.c26
-rw-r--r--arch/um/drivers/mconsole_kern.c1
-rw-r--r--arch/um/drivers/mmapper_kern.c1
-rw-r--r--arch/um/drivers/net_kern.c17
-rw-r--r--arch/um/drivers/random.c1
-rw-r--r--arch/um/drivers/ubd_kern.c20
-rw-r--r--arch/um/kernel/exec.c2
-rw-r--r--arch/um/kernel/irq.c6
-rw-r--r--arch/x86/Kconfig145
-rw-r--r--arch/x86/Kconfig.debug14
-rw-r--r--arch/x86/Makefile8
-rw-r--r--arch/x86/boot/compressed/misc.c29
-rw-r--r--arch/x86/ia32/ia32_aout.c22
-rw-r--r--arch/x86/include/asm/alternative.h11
-rw-r--r--arch/x86/include/asm/amd_iommu.h6
-rw-r--r--arch/x86/include/asm/amd_iommu_proto.h2
-rw-r--r--arch/x86/include/asm/amd_iommu_types.h23
-rw-r--r--arch/x86/include/asm/amd_nb.h (renamed from arch/x86/include/asm/k8.h)21
-rw-r--r--arch/x86/include/asm/apb_timer.h1
-rw-r--r--arch/x86/include/asm/apic.h4
-rw-r--r--arch/x86/include/asm/apicdef.h1
-rw-r--r--arch/x86/include/asm/bitops.h2
-rw-r--r--arch/x86/include/asm/calgary.h4
-rw-r--r--arch/x86/include/asm/calling.h52
-rw-r--r--arch/x86/include/asm/cpu.h1
-rw-r--r--arch/x86/include/asm/cpufeature.h13
-rw-r--r--arch/x86/include/asm/dwarf2.h20
-rw-r--r--arch/x86/include/asm/e820.h20
-rw-r--r--arch/x86/include/asm/efi.h2
-rw-r--r--arch/x86/include/asm/entry_arch.h23
-rw-r--r--arch/x86/include/asm/fixmap.h15
-rw-r--r--arch/x86/include/asm/gart.h20
-rw-r--r--arch/x86/include/asm/hardirq.h2
-rw-r--r--arch/x86/include/asm/hpet.h10
-rw-r--r--arch/x86/include/asm/hw_irq.h19
-rw-r--r--arch/x86/include/asm/i387.h185
-rw-r--r--arch/x86/include/asm/i8259.h2
-rw-r--r--arch/x86/include/asm/io.h2
-rw-r--r--arch/x86/include/asm/io_apic.h6
-rw-r--r--arch/x86/include/asm/iommu_table.h100
-rw-r--r--arch/x86/include/asm/irq.h12
-rw-r--r--arch/x86/include/asm/irq_remapping.h35
-rw-r--r--arch/x86/include/asm/irq_vectors.h4
-rw-r--r--arch/x86/include/asm/irqflags.h32
-rw-r--r--arch/x86/include/asm/jump_label.h37
-rw-r--r--arch/x86/include/asm/kvm_emulate.h30
-rw-r--r--arch/x86/include/asm/kvm_host.h105
-rw-r--r--arch/x86/include/asm/kvm_para.h6
-rw-r--r--arch/x86/include/asm/memblock.h23
-rw-r--r--arch/x86/include/asm/module.h7
-rw-r--r--arch/x86/include/asm/mrst.h10
-rw-r--r--arch/x86/include/asm/msr-index.h1
-rw-r--r--arch/x86/include/asm/mwait.h15
-rw-r--r--arch/x86/include/asm/olpc_ofw.h4
-rw-r--r--arch/x86/include/asm/page_32_types.h4
-rw-r--r--arch/x86/include/asm/page_types.h2
-rw-r--r--arch/x86/include/asm/paravirt.h21
-rw-r--r--arch/x86/include/asm/paravirt_types.h1
-rw-r--r--arch/x86/include/asm/percpu.h14
-rw-r--r--arch/x86/include/asm/perf_event_p4.h52
-rw-r--r--arch/x86/include/asm/pgtable.h4
-rw-r--r--arch/x86/include/asm/pgtable_32.h2
-rw-r--r--arch/x86/include/asm/pgtable_64.h2
-rw-r--r--arch/x86/include/asm/processor.h29
-rw-r--r--arch/x86/include/asm/pvclock.h38
-rw-r--r--arch/x86/include/asm/segment.h32
-rw-r--r--arch/x86/include/asm/setup.h5
-rw-r--r--arch/x86/include/asm/swiotlb.h13
-rw-r--r--arch/x86/include/asm/tlbflush.h2
-rw-r--r--arch/x86/include/asm/trampoline.h3
-rw-r--r--arch/x86/include/asm/vmi.h269
-rw-r--r--arch/x86/include/asm/vmi_time.h98
-rw-r--r--arch/x86/kernel/Makefile10
-rw-r--r--arch/x86/kernel/acpi/cstate.c13
-rw-r--r--arch/x86/kernel/acpi/sleep.c16
-rw-r--r--arch/x86/kernel/alternative.c71
-rw-r--r--arch/x86/kernel/amd_iommu.c2
-rw-r--r--arch/x86/kernel/amd_iommu_init.c139
-rw-r--r--arch/x86/kernel/amd_nb.c (renamed from arch/x86/kernel/k8.c)56
-rw-r--r--arch/x86/kernel/apb_timer.c60
-rw-r--r--arch/x86/kernel/aperture_64.c31
-rw-r--r--arch/x86/kernel/apic/apic.c91
-rw-r--r--arch/x86/kernel/apic/io_apic.c877
-rw-r--r--arch/x86/kernel/apic/nmi.c2
-rw-r--r--arch/x86/kernel/apic/numaq_32.c3
-rw-r--r--arch/x86/kernel/apic/probe_64.c3
-rw-r--r--arch/x86/kernel/apm_32.c5
-rw-r--r--arch/x86/kernel/asm-offsets_32.c4
-rw-r--r--arch/x86/kernel/check.c16
-rw-r--r--arch/x86/kernel/cpu/amd.c77
-rw-r--r--arch/x86/kernel/cpu/common.c26
-rw-r--r--arch/x86/kernel/cpu/cpu.h2
-rw-r--r--arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c18
-rw-r--r--arch/x86/kernel/cpu/intel.c7
-rw-r--r--arch/x86/kernel/cpu/intel_cacheinfo.c14
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce-severity.c1
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.c1
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_amd.c36
-rw-r--r--arch/x86/kernel/cpu/mcheck/therm_throt.c5
-rw-r--r--arch/x86/kernel/cpu/mtrr/cleanup.c2
-rw-r--r--arch/x86/kernel/cpu/mtrr/generic.c128
-rw-r--r--arch/x86/kernel/cpu/perf_event.c280
-rw-r--r--arch/x86/kernel/cpu/perf_event_amd.c4
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel.c8
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_ds.c13
-rw-r--r--arch/x86/kernel/cpu/perf_event_p4.c298
-rw-r--r--arch/x86/kernel/cpu/perfctr-watchdog.c9
-rw-r--r--arch/x86/kernel/cpu/scattered.c6
-rw-r--r--arch/x86/kernel/crash_dump_64.c3
-rw-r--r--arch/x86/kernel/e820.c191
-rw-r--r--arch/x86/kernel/early-quirks.c2
-rw-r--r--arch/x86/kernel/early_printk.c13
-rw-r--r--arch/x86/kernel/early_printk_mrst.c319
-rw-r--r--arch/x86/kernel/efi.c5
-rw-r--r--arch/x86/kernel/entry_32.S310
-rw-r--r--arch/x86/kernel/entry_64.S134
-rw-r--r--arch/x86/kernel/ftrace.c63
-rw-r--r--arch/x86/kernel/head.c3
-rw-r--r--arch/x86/kernel/head32.c11
-rw-r--r--arch/x86/kernel/head64.c9
-rw-r--r--arch/x86/kernel/head_32.S55
-rw-r--r--arch/x86/kernel/hpet.c69
-rw-r--r--arch/x86/kernel/i387.c58
-rw-r--r--arch/x86/kernel/i8259.c63
-rw-r--r--arch/x86/kernel/irq.c32
-rw-r--r--arch/x86/kernel/irq_32.c12
-rw-r--r--arch/x86/kernel/irq_work.c30
-rw-r--r--arch/x86/kernel/irqinit.c23
-rw-r--r--arch/x86/kernel/jump_label.c50
-rw-r--r--arch/x86/kernel/kdebugfs.c1
-rw-r--r--arch/x86/kernel/kgdb.c11
-rw-r--r--arch/x86/kernel/kprobes.c14
-rw-r--r--arch/x86/kernel/kvmclock.c6
-rw-r--r--arch/x86/kernel/machine_kexec_64.c4
-rw-r--r--arch/x86/kernel/microcode_core.c3
-rw-r--r--arch/x86/kernel/microcode_intel.c2
-rw-r--r--arch/x86/kernel/module.c6
-rw-r--r--arch/x86/kernel/mpparse.c5
-rw-r--r--arch/x86/kernel/olpc-xo1.c140
-rw-r--r--arch/x86/kernel/olpc.c89
-rw-r--r--arch/x86/kernel/olpc_ofw.c6
-rw-r--r--arch/x86/kernel/paravirt.c1
-rw-r--r--arch/x86/kernel/pci-calgary_64.c18
-rw-r--r--arch/x86/kernel/pci-dma.c44
-rw-r--r--arch/x86/kernel/pci-gart_64.c33
-rw-r--r--arch/x86/kernel/pci-iommu_table.c89
-rw-r--r--arch/x86/kernel/pci-swiotlb.c44
-rw-r--r--arch/x86/kernel/pmtimer_64.c69
-rw-r--r--arch/x86/kernel/process_64.c2
-rw-r--r--arch/x86/kernel/pvclock.c3
-rw-r--r--arch/x86/kernel/quirks.c2
-rw-r--r--arch/x86/kernel/reboot.c12
-rw-r--r--arch/x86/kernel/setup.c233
-rw-r--r--arch/x86/kernel/setup_percpu.c8
-rw-r--r--arch/x86/kernel/sfi.c4
-rw-r--r--arch/x86/kernel/smpboot.c134
-rw-r--r--arch/x86/kernel/sys_i386_32.c4
-rw-r--r--arch/x86/kernel/tlb_uv.c12
-rw-r--r--arch/x86/kernel/trampoline.c26
-rw-r--r--arch/x86/kernel/traps.c36
-rw-r--r--arch/x86/kernel/tsc.c66
-rw-r--r--arch/x86/kernel/uv_irq.c55
-rw-r--r--arch/x86/kernel/visws_quirks.c140
-rw-r--r--arch/x86/kernel/vm86_32.c10
-rw-r--r--arch/x86/kernel/vmi_32.c893
-rw-r--r--arch/x86/kernel/vmiclock_32.c317
-rw-r--r--arch/x86/kernel/vmlinux.lds.S30
-rw-r--r--arch/x86/kvm/Kconfig7
-rw-r--r--arch/x86/kvm/emulate.c2262
-rw-r--r--arch/x86/kvm/i8254.c11
-rw-r--r--arch/x86/kvm/i8259.c25
-rw-r--r--arch/x86/kvm/irq.c9
-rw-r--r--arch/x86/kvm/irq.h2
-rw-r--r--arch/x86/kvm/kvm_cache_regs.h9
-rw-r--r--arch/x86/kvm/lapic.c18
-rw-r--r--arch/x86/kvm/mmu.c918
-rw-r--r--arch/x86/kvm/mmu.h9
-rw-r--r--arch/x86/kvm/mmu_audit.c299
-rw-r--r--arch/x86/kvm/mmutrace.h19
-rw-r--r--arch/x86/kvm/paging_tmpl.h202
-rw-r--r--arch/x86/kvm/svm.c298
-rw-r--r--arch/x86/kvm/timer.c2
-rw-r--r--arch/x86/kvm/vmx.c243
-rw-r--r--arch/x86/kvm/x86.c787
-rw-r--r--arch/x86/kvm/x86.h8
-rw-r--r--arch/x86/lguest/boot.c18
-rw-r--r--arch/x86/lib/memcpy_32.c199
-rw-r--r--arch/x86/lib/memcpy_64.S158
-rw-r--r--arch/x86/lib/memmove_64.c189
-rw-r--r--arch/x86/mm/Makefile2
-rw-r--r--arch/x86/mm/fault.c47
-rw-r--r--arch/x86/mm/init.c10
-rw-r--r--arch/x86/mm/init_32.c166
-rw-r--r--arch/x86/mm/init_64.c116
-rw-r--r--arch/x86/mm/ioremap.c5
-rw-r--r--arch/x86/mm/k8topology_64.c12
-rw-r--r--arch/x86/mm/kmemcheck/kmemcheck.c2
-rw-r--r--arch/x86/mm/kmemcheck/opcode.c2
-rw-r--r--arch/x86/mm/memblock.c348
-rw-r--r--arch/x86/mm/memtest.c7
-rw-r--r--arch/x86/mm/numa_32.c30
-rw-r--r--arch/x86/mm/numa_64.c86
-rw-r--r--arch/x86/mm/pgtable.c24
-rw-r--r--arch/x86/mm/srat_32.c3
-rw-r--r--arch/x86/mm/srat_64.c17
-rw-r--r--arch/x86/mm/tlb.c48
-rw-r--r--arch/x86/oprofile/backtrace.c70
-rw-r--r--arch/x86/oprofile/nmi_int.c10
-rw-r--r--arch/x86/oprofile/op_model_amd.c145
-rw-r--r--arch/x86/pci/olpc.c2
-rw-r--r--arch/x86/xen/debugfs.c1
-rw-r--r--arch/x86/xen/enlighten.c3
-rw-r--r--arch/x86/xen/mmu.c32
-rw-r--r--arch/x86/xen/pci-swiotlb-xen.c5
-rw-r--r--arch/x86/xen/setup.c3
-rw-r--r--arch/x86/xen/spinlock.c2
-rw-r--r--arch/x86/xen/time.c5
-rw-r--r--arch/xtensa/include/asm/irqflags.h58
-rw-r--r--arch/xtensa/include/asm/system.h33
-rw-r--r--arch/xtensa/include/asm/uaccess.h2
-rw-r--r--arch/xtensa/kernel/irq.c2
1899 files changed, 52868 insertions, 23696 deletions
diff --git a/arch/Kconfig b/arch/Kconfig
index fe48fc7a3eba..53d7f619a1b9 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -158,4 +158,7 @@ config HAVE_PERF_EVENTS_NMI
subsystem. Also has support for calculating CPU cycle events
to determine how many clock cycles in a given period.
+config HAVE_ARCH_JUMP_LABEL
+ bool
+
source "kernel/gcov/Kconfig"
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index b9647bb66d13..d04ccd73af45 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -9,6 +9,7 @@ config ALPHA
select HAVE_IDE
select HAVE_OPROFILE
select HAVE_SYSCALL_WRAPPERS
+ select HAVE_IRQ_WORK
select HAVE_PERF_EVENTS
select HAVE_DMA_ATTRS
help
diff --git a/arch/alpha/include/asm/irqflags.h b/arch/alpha/include/asm/irqflags.h
new file mode 100644
index 000000000000..299bbc7e9d71
--- /dev/null
+++ b/arch/alpha/include/asm/irqflags.h
@@ -0,0 +1,67 @@
+#ifndef __ALPHA_IRQFLAGS_H
+#define __ALPHA_IRQFLAGS_H
+
+#include <asm/system.h>
+
+#define IPL_MIN 0
+#define IPL_SW0 1
+#define IPL_SW1 2
+#define IPL_DEV0 3
+#define IPL_DEV1 4
+#define IPL_TIMER 5
+#define IPL_PERF 6
+#define IPL_POWERFAIL 6
+#define IPL_MCHECK 7
+#define IPL_MAX 7
+
+#ifdef CONFIG_ALPHA_BROKEN_IRQ_MASK
+#undef IPL_MIN
+#define IPL_MIN __min_ipl
+extern int __min_ipl;
+#endif
+
+#define getipl() (rdps() & 7)
+#define setipl(ipl) ((void) swpipl(ipl))
+
+static inline unsigned long arch_local_save_flags(void)
+{
+ return rdps();
+}
+
+static inline void arch_local_irq_disable(void)
+{
+ setipl(IPL_MAX);
+ barrier();
+}
+
+static inline unsigned long arch_local_irq_save(void)
+{
+ unsigned long flags = swpipl(IPL_MAX);
+ barrier();
+ return flags;
+}
+
+static inline void arch_local_irq_enable(void)
+{
+ barrier();
+ setipl(IPL_MIN);
+}
+
+static inline void arch_local_irq_restore(unsigned long flags)
+{
+ barrier();
+ setipl(flags);
+ barrier();
+}
+
+static inline bool arch_irqs_disabled_flags(unsigned long flags)
+{
+ return flags == IPL_MAX;
+}
+
+static inline bool arch_irqs_disabled(void)
+{
+ return arch_irqs_disabled_flags(getipl());
+}
+
+#endif /* __ALPHA_IRQFLAGS_H */
diff --git a/arch/alpha/include/asm/perf_event.h b/arch/alpha/include/asm/perf_event.h
index 4157cd3c44a9..fe792ca818f6 100644
--- a/arch/alpha/include/asm/perf_event.h
+++ b/arch/alpha/include/asm/perf_event.h
@@ -1,11 +1,6 @@
#ifndef __ASM_ALPHA_PERF_EVENT_H
#define __ASM_ALPHA_PERF_EVENT_H
-/* Alpha only supports software events through this interface. */
-extern void set_perf_event_pending(void);
-
-#define PERF_EVENT_INDEX_OFFSET 0
-
#ifdef CONFIG_PERF_EVENTS
extern void init_hw_perf_events(void);
#else
diff --git a/arch/alpha/include/asm/system.h b/arch/alpha/include/asm/system.h
index 5aa40cca4f23..9f78e6934637 100644
--- a/arch/alpha/include/asm/system.h
+++ b/arch/alpha/include/asm/system.h
@@ -259,34 +259,6 @@ __CALL_PAL_RW2(wrperfmon, unsigned long, unsigned long, unsigned long);
__CALL_PAL_W1(wrusp, unsigned long);
__CALL_PAL_W1(wrvptptr, unsigned long);
-#define IPL_MIN 0
-#define IPL_SW0 1
-#define IPL_SW1 2
-#define IPL_DEV0 3
-#define IPL_DEV1 4
-#define IPL_TIMER 5
-#define IPL_PERF 6
-#define IPL_POWERFAIL 6
-#define IPL_MCHECK 7
-#define IPL_MAX 7
-
-#ifdef CONFIG_ALPHA_BROKEN_IRQ_MASK
-#undef IPL_MIN
-#define IPL_MIN __min_ipl
-extern int __min_ipl;
-#endif
-
-#define getipl() (rdps() & 7)
-#define setipl(ipl) ((void) swpipl(ipl))
-
-#define local_irq_disable() do { setipl(IPL_MAX); barrier(); } while(0)
-#define local_irq_enable() do { barrier(); setipl(IPL_MIN); } while(0)
-#define local_save_flags(flags) ((flags) = rdps())
-#define local_irq_save(flags) do { (flags) = swpipl(IPL_MAX); barrier(); } while(0)
-#define local_irq_restore(flags) do { barrier(); setipl(flags); barrier(); } while(0)
-
-#define irqs_disabled() (getipl() == IPL_MAX)
-
/*
* TB routines..
*/
diff --git a/arch/alpha/kernel/perf_event.c b/arch/alpha/kernel/perf_event.c
index 85d8e4f58c83..1cc49683fb69 100644
--- a/arch/alpha/kernel/perf_event.c
+++ b/arch/alpha/kernel/perf_event.c
@@ -307,7 +307,7 @@ again:
new_raw_count) != prev_raw_count)
goto again;
- delta = (new_raw_count - (prev_raw_count & alpha_pmu->pmc_count_mask[idx])) + ovf;
+ delta = (new_raw_count - (prev_raw_count & alpha_pmu->pmc_count_mask[idx])) + ovf;
/* It is possible on very rare occasions that the PMC has overflowed
* but the interrupt is yet to come. Detect and fix this situation.
@@ -402,14 +402,13 @@ static void maybe_change_configuration(struct cpu_hw_events *cpuc)
struct hw_perf_event *hwc = &pe->hw;
int idx = hwc->idx;
- if (cpuc->current_idx[j] != PMC_NO_INDEX) {
- cpuc->idx_mask |= (1<<cpuc->current_idx[j]);
- continue;
+ if (cpuc->current_idx[j] == PMC_NO_INDEX) {
+ alpha_perf_event_set_period(pe, hwc, idx);
+ cpuc->current_idx[j] = idx;
}
- alpha_perf_event_set_period(pe, hwc, idx);
- cpuc->current_idx[j] = idx;
- cpuc->idx_mask |= (1<<cpuc->current_idx[j]);
+ if (!(hwc->state & PERF_HES_STOPPED))
+ cpuc->idx_mask |= (1<<cpuc->current_idx[j]);
}
cpuc->config = cpuc->event[0]->hw.config_base;
}
@@ -420,12 +419,13 @@ static void maybe_change_configuration(struct cpu_hw_events *cpuc)
* - this function is called from outside this module via the pmu struct
* returned from perf event initialisation.
*/
-static int alpha_pmu_enable(struct perf_event *event)
+static int alpha_pmu_add(struct perf_event *event, int flags)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ struct hw_perf_event *hwc = &event->hw;
int n0;
int ret;
- unsigned long flags;
+ unsigned long irq_flags;
/*
* The Sparc code has the IRQ disable first followed by the perf
@@ -435,8 +435,8 @@ static int alpha_pmu_enable(struct perf_event *event)
* nevertheless we disable the PMCs first to enable a potential
* final PMI to occur before we disable interrupts.
*/
- perf_disable();
- local_irq_save(flags);
+ perf_pmu_disable(event->pmu);
+ local_irq_save(irq_flags);
/* Default to error to be returned */
ret = -EAGAIN;
@@ -455,8 +455,12 @@ static int alpha_pmu_enable(struct perf_event *event)
}
}
- local_irq_restore(flags);
- perf_enable();
+ hwc->state = PERF_HES_UPTODATE;
+ if (!(flags & PERF_EF_START))
+ hwc->state |= PERF_HES_STOPPED;
+
+ local_irq_restore(irq_flags);
+ perf_pmu_enable(event->pmu);
return ret;
}
@@ -467,15 +471,15 @@ static int alpha_pmu_enable(struct perf_event *event)
* - this function is called from outside this module via the pmu struct
* returned from perf event initialisation.
*/
-static void alpha_pmu_disable(struct perf_event *event)
+static void alpha_pmu_del(struct perf_event *event, int flags)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
struct hw_perf_event *hwc = &event->hw;
- unsigned long flags;
+ unsigned long irq_flags;
int j;
- perf_disable();
- local_irq_save(flags);
+ perf_pmu_disable(event->pmu);
+ local_irq_save(irq_flags);
for (j = 0; j < cpuc->n_events; j++) {
if (event == cpuc->event[j]) {
@@ -501,8 +505,8 @@ static void alpha_pmu_disable(struct perf_event *event)
}
}
- local_irq_restore(flags);
- perf_enable();
+ local_irq_restore(irq_flags);
+ perf_pmu_enable(event->pmu);
}
@@ -514,13 +518,44 @@ static void alpha_pmu_read(struct perf_event *event)
}
-static void alpha_pmu_unthrottle(struct perf_event *event)
+static void alpha_pmu_stop(struct perf_event *event, int flags)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+ if (!(hwc->state & PERF_HES_STOPPED)) {
+ cpuc->idx_mask &= ~(1UL<<hwc->idx);
+ hwc->state |= PERF_HES_STOPPED;
+ }
+
+ if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
+ alpha_perf_event_update(event, hwc, hwc->idx, 0);
+ hwc->state |= PERF_HES_UPTODATE;
+ }
+
+ if (cpuc->enabled)
+ wrperfmon(PERFMON_CMD_DISABLE, (1UL<<hwc->idx));
+}
+
+
+static void alpha_pmu_start(struct perf_event *event, int flags)
{
struct hw_perf_event *hwc = &event->hw;
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
+ return;
+
+ if (flags & PERF_EF_RELOAD) {
+ WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
+ alpha_perf_event_set_period(event, hwc, hwc->idx);
+ }
+
+ hwc->state = 0;
+
cpuc->idx_mask |= 1UL<<hwc->idx;
- wrperfmon(PERFMON_CMD_ENABLE, (1UL<<hwc->idx));
+ if (cpuc->enabled)
+ wrperfmon(PERFMON_CMD_ENABLE, (1UL<<hwc->idx));
}
@@ -642,39 +677,36 @@ static int __hw_perf_event_init(struct perf_event *event)
return 0;
}
-static const struct pmu pmu = {
- .enable = alpha_pmu_enable,
- .disable = alpha_pmu_disable,
- .read = alpha_pmu_read,
- .unthrottle = alpha_pmu_unthrottle,
-};
-
-
/*
* Main entry point to initialise a HW performance event.
*/
-const struct pmu *hw_perf_event_init(struct perf_event *event)
+static int alpha_pmu_event_init(struct perf_event *event)
{
int err;
+ switch (event->attr.type) {
+ case PERF_TYPE_RAW:
+ case PERF_TYPE_HARDWARE:
+ case PERF_TYPE_HW_CACHE:
+ break;
+
+ default:
+ return -ENOENT;
+ }
+
if (!alpha_pmu)
- return ERR_PTR(-ENODEV);
+ return -ENODEV;
/* Do the real initialisation work. */
err = __hw_perf_event_init(event);
- if (err)
- return ERR_PTR(err);
-
- return &pmu;
+ return err;
}
-
-
/*
* Main entry point - enable HW performance counters.
*/
-void hw_perf_enable(void)
+static void alpha_pmu_enable(struct pmu *pmu)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
@@ -700,7 +732,7 @@ void hw_perf_enable(void)
* Main entry point - disable HW performance counters.
*/
-void hw_perf_disable(void)
+static void alpha_pmu_disable(struct pmu *pmu)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
@@ -713,6 +745,17 @@ void hw_perf_disable(void)
wrperfmon(PERFMON_CMD_DISABLE, cpuc->idx_mask);
}
+static struct pmu pmu = {
+ .pmu_enable = alpha_pmu_enable,
+ .pmu_disable = alpha_pmu_disable,
+ .event_init = alpha_pmu_event_init,
+ .add = alpha_pmu_add,
+ .del = alpha_pmu_del,
+ .start = alpha_pmu_start,
+ .stop = alpha_pmu_stop,
+ .read = alpha_pmu_read,
+};
+
/*
* Main entry point - don't know when this is called but it
@@ -766,7 +809,7 @@ static void alpha_perf_event_irq_handler(unsigned long la_ptr,
wrperfmon(PERFMON_CMD_DISABLE, cpuc->idx_mask);
/* la_ptr is the counter that overflowed. */
- if (unlikely(la_ptr >= perf_max_events)) {
+ if (unlikely(la_ptr >= alpha_pmu->num_pmcs)) {
/* This should never occur! */
irq_err_count++;
pr_warning("PMI: silly index %ld\n", la_ptr);
@@ -807,7 +850,7 @@ static void alpha_perf_event_irq_handler(unsigned long la_ptr,
/* Interrupts coming too quickly; "throttle" the
* counter, i.e., disable it for a little while.
*/
- cpuc->idx_mask &= ~(1UL<<idx);
+ alpha_pmu_stop(event, 0);
}
}
wrperfmon(PERFMON_CMD_ENABLE, cpuc->idx_mask);
@@ -837,6 +880,7 @@ void __init init_hw_perf_events(void)
/* And set up PMU specification */
alpha_pmu = &ev67_pmu;
- perf_max_events = alpha_pmu->num_pmcs;
+
+ perf_pmu_register(&pmu);
}
diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c
index d290845aef59..6f7feb5db271 100644
--- a/arch/alpha/kernel/signal.c
+++ b/arch/alpha/kernel/signal.c
@@ -48,7 +48,7 @@ SYSCALL_DEFINE2(osf_sigprocmask, int, how, unsigned long, newmask)
sigset_t mask;
unsigned long res;
- siginitset(&mask, newmask & ~_BLOCKABLE);
+ siginitset(&mask, newmask & _BLOCKABLE);
res = sigprocmask(how, &mask, &oldmask);
if (!res) {
force_successful_syscall_return();
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
index 396af1799ea4..0f1d8493cfca 100644
--- a/arch/alpha/kernel/time.c
+++ b/arch/alpha/kernel/time.c
@@ -41,7 +41,7 @@
#include <linux/init.h>
#include <linux/bcd.h>
#include <linux/profile.h>
-#include <linux/perf_event.h>
+#include <linux/irq_work.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -83,25 +83,25 @@ static struct {
unsigned long est_cycle_freq;
-#ifdef CONFIG_PERF_EVENTS
+#ifdef CONFIG_IRQ_WORK
-DEFINE_PER_CPU(u8, perf_event_pending);
+DEFINE_PER_CPU(u8, irq_work_pending);
-#define set_perf_event_pending_flag() __get_cpu_var(perf_event_pending) = 1
-#define test_perf_event_pending() __get_cpu_var(perf_event_pending)
-#define clear_perf_event_pending() __get_cpu_var(perf_event_pending) = 0
+#define set_irq_work_pending_flag() __get_cpu_var(irq_work_pending) = 1
+#define test_irq_work_pending() __get_cpu_var(irq_work_pending)
+#define clear_irq_work_pending() __get_cpu_var(irq_work_pending) = 0
-void set_perf_event_pending(void)
+void set_irq_work_pending(void)
{
- set_perf_event_pending_flag();
+ set_irq_work_pending_flag();
}
-#else /* CONFIG_PERF_EVENTS */
+#else /* CONFIG_IRQ_WORK */
-#define test_perf_event_pending() 0
-#define clear_perf_event_pending()
+#define test_irq_work_pending() 0
+#define clear_irq_work_pending()
-#endif /* CONFIG_PERF_EVENTS */
+#endif /* CONFIG_IRQ_WORK */
static inline __u32 rpcc(void)
@@ -191,9 +191,9 @@ irqreturn_t timer_interrupt(int irq, void *dev)
write_sequnlock(&xtime_lock);
- if (test_perf_event_pending()) {
- clear_perf_event_pending();
- perf_event_do_pending();
+ if (test_irq_work_pending()) {
+ clear_irq_work_pending();
+ irq_work_run();
}
#ifndef CONFIG_SMP
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 88c97bc7a6f5..b64e465ac49c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -19,13 +19,17 @@ config ARM
select HAVE_KPROBES if (!XIP_KERNEL)
select HAVE_KRETPROBES if (HAVE_KPROBES)
select HAVE_FUNCTION_TRACER if (!XIP_KERNEL)
+ select HAVE_FTRACE_MCOUNT_RECORD if (!XIP_KERNEL)
+ select HAVE_DYNAMIC_FTRACE if (!XIP_KERNEL)
select HAVE_GENERIC_DMA_COHERENT
select HAVE_KERNEL_GZIP
select HAVE_KERNEL_LZO
select HAVE_KERNEL_LZMA
+ select HAVE_IRQ_WORK
select HAVE_PERF_EVENTS
select PERF_USE_VMALLOC
select HAVE_REGS_AND_STACK_ACCESS_API
+ select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V7))
help
The ARM series is a line of low-power-consumption RISC chip designs
licensed by ARM Ltd and targeted at embedded applications and
@@ -145,6 +149,9 @@ config ARCH_HAS_CPUFREQ
and that the relevant menu configurations are displayed for
it.
+config ARCH_HAS_CPU_IDLE_WAIT
+ def_bool y
+
config GENERIC_HWEIGHT
bool
default y
@@ -510,6 +517,7 @@ config ARCH_MMP
select GENERIC_CLOCKEVENTS
select TICK_ONESHOT
select PLAT_PXA
+ select SPARSE_IRQ
help
Support for Marvell's PXA168/PXA910(MMP) and MMP2 processor line.
@@ -587,6 +595,7 @@ config ARCH_PXA
select GENERIC_CLOCKEVENTS
select TICK_ONESHOT
select PLAT_PXA
+ select SPARSE_IRQ
help
Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
@@ -678,8 +687,8 @@ config ARCH_S3C64XX
help
Samsung S3C64XX series based systems
-config ARCH_S5P6440
- bool "Samsung S5P6440"
+config ARCH_S5P64X0
+ bool "Samsung S5P6440 S5P6450"
select CPU_V6
select GENERIC_GPIO
select HAVE_CLK
@@ -688,7 +697,8 @@ config ARCH_S5P6440
select HAVE_S3C2410_I2C
select HAVE_S3C_RTC
help
- Samsung S5P6440 CPU based systems
+ Samsung S5P64X0 CPU based systems, such as the Samsung SMDK6440,
+ SMDK6450.
config ARCH_S5P6442
bool "Samsung S5P6442"
@@ -747,6 +757,15 @@ config ARCH_SHARK
Support for the StrongARM based Digital DNARD machine, also known
as "Shark" (<http://www.shark-linux.de/shark.html>).
+config ARCH_TCC_926
+ bool "Telechips TCC ARM926-based systems"
+ select CPU_ARM926T
+ select HAVE_CLK
+ select COMMON_CLKDEV
+ select GENERIC_CLOCKEVENTS
+ help
+ Support for Telechips TCC ARM926-based systems.
+
config ARCH_LH7A40X
bool "Sharp LH7A40X"
select CPU_ARM922T
@@ -915,6 +934,8 @@ source "arch/arm/plat-s5p/Kconfig"
source "arch/arm/plat-spear/Kconfig"
+source "arch/arm/plat-tcc/Kconfig"
+
if ARCH_S3C2410
source "arch/arm/mach-s3c2400/Kconfig"
source "arch/arm/mach-s3c2410/Kconfig"
@@ -928,7 +949,7 @@ if ARCH_S3C64XX
source "arch/arm/mach-s3c64xx/Kconfig"
endif
-source "arch/arm/mach-s5p6440/Kconfig"
+source "arch/arm/mach-s5p64x0/Kconfig"
source "arch/arm/mach-s5p6442/Kconfig"
@@ -1002,7 +1023,7 @@ endif
config ARM_ERRATA_411920
bool "ARM errata: Invalidation of the Instruction Cache operation can fail"
- depends on CPU_V6 && !SMP
+ depends on CPU_V6
help
Invalidation of the Instruction Cache operation can
fail. This erratum is present in 1136 (before r1p4), 1156 and 1176.
@@ -1101,6 +1122,20 @@ config ARM_ERRATA_720789
invalidated are not, resulting in an incoherency in the system page
tables. The workaround changes the TLB flushing routines to invalidate
entries regardless of the ASID.
+
+config ARM_ERRATA_743622
+ bool "ARM errata: Faulty hazard checking in the Store Buffer may lead to data corruption"
+ depends on CPU_V7
+ help
+ This option enables the workaround for the 743622 Cortex-A9
+ (r2p0..r2p2) erratum. Under very rare conditions, a faulty
+ optimisation in the Cortex-A9 Store Buffer may lead to data
+ corruption. This workaround sets a specific bit in the diagnostic
+ register of the Cortex-A9 which disables the Store Buffer
+ optimisation, preventing the defect from occurring. This has no
+ visible impact on the overall performance or power consumption of the
+ processor.
+
endmenu
source "arch/arm/common/Kconfig"
@@ -1167,13 +1202,13 @@ source "kernel/time/Kconfig"
config SMP
bool "Symmetric Multi-Processing (EXPERIMENTAL)"
- depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP ||\
- MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 ||\
- ARCH_S5PV310 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4)
+ depends on EXPERIMENTAL
depends on GENERIC_CLOCKEVENTS
+ depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \
+ MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 ||\
+ ARCH_S5PV310 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4
select USE_GENERIC_SMP_HELPERS
- select HAVE_ARM_SCU if ARCH_REALVIEW || ARCH_OMAP4 || ARCH_S5PV310 ||\
- ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4
+ select HAVE_ARM_SCU
help
This enables support for systems with more than one CPU. If you have
a system with only one CPU, like most personal computers, say N. If
@@ -1187,10 +1222,23 @@ config SMP
See also <file:Documentation/i386/IO-APIC.txt>,
<file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at
- <http://www.linuxdoc.org/docs.html#howto>.
+ <http://tldp.org/HOWTO/SMP-HOWTO.html>.
If you don't know what to do here, say N.
+config SMP_ON_UP
+ bool "Allow booting SMP kernel on uniprocessor systems (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
+ depends on SMP && !XIP && !THUMB2_KERNEL
+ default y
+ help
+ SMP kernels contain instructions which fail on non-SMP processors.
+ Enabling this option allows the kernel to modify itself to make
+ these instructions safe. Disabling it allows about 1K of space
+ savings.
+
+ If you don't know what to do here, say Y.
+
config HAVE_ARM_SCU
bool
depends on SMP
@@ -1241,12 +1289,9 @@ config HOTPLUG_CPU
config LOCAL_TIMERS
bool "Use local timer interrupts"
- depends on SMP && (REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || \
- REALVIEW_EB_A9MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \
- ARCH_S5PV310 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4)
+ depends on SMP
default y
- select HAVE_ARM_TWD if ARCH_REALVIEW || ARCH_OMAP4 || ARCH_S5PV310 || \
- ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS
+ select HAVE_ARM_TWD
help
Enable support for local timers on SMP platforms, rather then the
legacy IPI broadcast method. Local timers allows the system
@@ -1257,7 +1302,7 @@ source kernel/Kconfig.preempt
config HZ
int
- default 200 if ARCH_EBSA110 || ARCH_S3C2410 || ARCH_S5P6440 || \
+ default 200 if ARCH_EBSA110 || ARCH_S3C2410 || ARCH_S5P64X0 || \
ARCH_S5P6442 || ARCH_S5PV210 || ARCH_S5PV310
default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER
default AT91_TIMER_HZ if ARCH_AT91
@@ -1463,6 +1508,20 @@ config UACCESS_WITH_MEMCPY
However, if the CPU data cache is using a write-allocate mode,
this option is unlikely to provide any performance gain.
+config SECCOMP
+ bool
+ prompt "Enable seccomp to safely compute untrusted bytecode"
+ ---help---
+ This kernel feature is useful for number crunching applications
+ that may need to compute untrusted bytecode during their
+ execution. By using pipes or other transports made available to
+ the process as file descriptors supporting the read/write
+ syscalls, it's possible to isolate those applications in
+ their own address space using seccomp. Once seccomp is
+ enabled via prctl(PR_SET_SECCOMP), it cannot be disabled
+ and the task is only allowed to execute a few safe syscalls
+ defined by each seccomp mode.
+
config CC_STACKPROTECTOR
bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
help
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 91344af75f39..2fd0b99afc4b 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -2,6 +2,20 @@ menu "Kernel hacking"
source "lib/Kconfig.debug"
+config STRICT_DEVMEM
+ bool "Filter access to /dev/mem"
+ depends on MMU
+ ---help---
+ If this option is disabled, you allow userspace (root) access to all
+ of memory, including kernel and userspace memory. Accidental
+ access to this is obviously disastrous, but specific access can
+ be used by people debugging the kernel.
+
+ If this option is switched on, the /dev/mem file only allows
+ userspace access to memory mapped peripherals.
+
+ If in doubt, say Y.
+
# RMK wants arm kernels compiled with frame pointers or stack unwinding.
# If you know what you are doing and are willing to live without stack
# traces, you can get a slightly smaller kernel by setting this option to
@@ -27,6 +41,11 @@ config ARM_UNWIND
the performance is not affected. Currently, this feature
only works with EABI compilers. If unsure say Y.
+config OLD_MCOUNT
+ bool
+ depends on FUNCTION_TRACER && FRAME_POINTER
+ default y
+
config DEBUG_USER
bool "Verbose user fault messages"
help
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 59c1ce858fc8..b87aed028eef 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -173,7 +173,7 @@ machine-$(CONFIG_ARCH_RPC) := rpc
machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2416 s3c2440 s3c2443
machine-$(CONFIG_ARCH_S3C24A0) := s3c24a0
machine-$(CONFIG_ARCH_S3C64XX) := s3c64xx
-machine-$(CONFIG_ARCH_S5P6440) := s5p6440
+machine-$(CONFIG_ARCH_S5P64X0) := s5p64x0
machine-$(CONFIG_ARCH_S5P6442) := s5p6442
machine-$(CONFIG_ARCH_S5PC100) := s5pc100
machine-$(CONFIG_ARCH_S5PV210) := s5pv210
@@ -183,6 +183,7 @@ machine-$(CONFIG_ARCH_SHARK) := shark
machine-$(CONFIG_ARCH_SHMOBILE) := shmobile
machine-$(CONFIG_ARCH_STMP378X) := stmp378x
machine-$(CONFIG_ARCH_STMP37XX) := stmp37xx
+machine-$(CONFIG_ARCH_TCC8K) := tcc8k
machine-$(CONFIG_ARCH_TEGRA) := tegra
machine-$(CONFIG_ARCH_U300) := u300
machine-$(CONFIG_ARCH_U8500) := ux500
@@ -202,6 +203,7 @@ plat-$(CONFIG_ARCH_MXC) := mxc
plat-$(CONFIG_ARCH_OMAP) := omap
plat-$(CONFIG_ARCH_S3C64XX) := samsung
plat-$(CONFIG_ARCH_STMP3XXX) := stmp3xxx
+plat-$(CONFIG_ARCH_TCC_926) := tcc
plat-$(CONFIG_PLAT_IOP) := iop
plat-$(CONFIG_PLAT_NOMADIK) := nomadik
plat-$(CONFIG_PLAT_ORION) := orion
@@ -245,13 +247,14 @@ ifeq ($(FASTFPE),$(wildcard $(FASTFPE)))
FASTFPE_OBJ :=$(FASTFPE)/
endif
-# If we have a machine-specific directory, then include it in the build.
-core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
-core-y += $(machdirs) $(platdirs)
core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/
core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ)
core-$(CONFIG_VFP) += arch/arm/vfp/
+# If we have a machine-specific directory, then include it in the build.
+core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
+core-y += $(machdirs) $(platdirs)
+
drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
libs-y := arch/arm/lib/ $(libs-y)
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 7dfa9a85bc0c..ada6359160eb 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -67,25 +67,11 @@ static inline unsigned int gic_irq(unsigned int irq)
/*
* Routines to acknowledge, disable and enable interrupts
- *
- * Linux assumes that when we're done with an interrupt we need to
- * unmask it, in the same way we need to unmask an interrupt when
- * we first enable it.
- *
- * The GIC has a separate notion of "end of interrupt" to re-enable
- * an interrupt after handling, in order to support hardware
- * prioritisation.
- *
- * We can make the GIC behave in the way that Linux expects by making
- * our "acknowledge" routine disable the interrupt, then mark it as
- * complete.
*/
static void gic_ack_irq(unsigned int irq)
{
- u32 mask = 1 << (irq % 32);
spin_lock(&irq_controller_lock);
- writel(mask, gic_dist_base(irq) + GIC_DIST_ENABLE_CLEAR + (gic_irq(irq) / 32) * 4);
writel(gic_irq(irq), gic_cpu_base(irq) + GIC_CPU_EOI);
spin_unlock(&irq_controller_lock);
}
diff --git a/arch/arm/common/icst.c b/arch/arm/common/icst.c
index 9a7f09cff300..2dc6da70ae59 100644
--- a/arch/arm/common/icst.c
+++ b/arch/arm/common/icst.c
@@ -8,7 +8,7 @@
* published by the Free Software Foundation.
*
* Support functions for calculating clocks/divisors for the ICST307
- * clock generators. See http://www.icst.com/ for more information
+ * clock generators. See http://www.idt.com/ for more information
* on these devices.
*
* This is an almost identical implementation to the ICST525 clock generator.
diff --git a/arch/arm/common/pl330.c b/arch/arm/common/pl330.c
index 5ebbab6242a7..8f0f86db3602 100644
--- a/arch/arm/common/pl330.c
+++ b/arch/arm/common/pl330.c
@@ -146,8 +146,7 @@
#define DESIGNER 0x41
#define REVISION 0x0
#define INTEG_CFG 0x0
-#define PERIPH_ID_VAL ((PART << 0) | (DESIGNER << 12) \
- | (REVISION << 20) | (INTEG_CFG << 24))
+#define PERIPH_ID_VAL ((PART << 0) | (DESIGNER << 12))
#define PCELL_ID_VAL 0xb105f00d
@@ -1859,10 +1858,10 @@ int pl330_add(struct pl330_info *pi)
regs = pi->base;
/* Check if we can handle this DMAC */
- if (get_id(pi, PERIPH_ID) != PERIPH_ID_VAL
+ if ((get_id(pi, PERIPH_ID) & 0xfffff) != PERIPH_ID_VAL
|| get_id(pi, PCELL_ID) != PCELL_ID_VAL) {
dev_err(pi->dev, "PERIPH_ID 0x%x, PCELL_ID 0x%x !\n",
- readl(regs + PERIPH_ID), readl(regs + PCELL_ID));
+ get_id(pi, PERIPH_ID), get_id(pi, PCELL_ID));
return -EINVAL;
}
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index 517d50ddbeb3..c0258a8c103b 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -678,7 +678,7 @@ out:
* %-EBUSY physical address already marked in-use.
* %0 successful.
*/
-static int
+static int __devinit
__sa1111_probe(struct device *me, struct resource *mem, int irq)
{
struct sa1111 *sachip;
diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c
index 9012004321dd..c11af1e4bad3 100644
--- a/arch/arm/common/scoop.c
+++ b/arch/arm/common/scoop.c
@@ -44,12 +44,12 @@ void reset_scoop(struct device *dev)
{
struct scoop_dev *sdev = dev_get_drvdata(dev);
- iowrite16(0x0100, sdev->base + SCOOP_MCR); // 00
- iowrite16(0x0000, sdev->base + SCOOP_CDR); // 04
- iowrite16(0x0000, sdev->base + SCOOP_CCR); // 10
- iowrite16(0x0000, sdev->base + SCOOP_IMR); // 18
- iowrite16(0x00FF, sdev->base + SCOOP_IRM); // 14
- iowrite16(0x0000, sdev->base + SCOOP_ISR); // 1C
+ iowrite16(0x0100, sdev->base + SCOOP_MCR); /* 00 */
+ iowrite16(0x0000, sdev->base + SCOOP_CDR); /* 04 */
+ iowrite16(0x0000, sdev->base + SCOOP_CCR); /* 10 */
+ iowrite16(0x0000, sdev->base + SCOOP_IMR); /* 18 */
+ iowrite16(0x00FF, sdev->base + SCOOP_IRM); /* 14 */
+ iowrite16(0x0000, sdev->base + SCOOP_ISR); /* 1C */
iowrite16(0x0000, sdev->base + SCOOP_IRM);
}
diff --git a/arch/arm/common/uengine.c b/arch/arm/common/uengine.c
index b520e56216a9..bef408f3d76c 100644
--- a/arch/arm/common/uengine.c
+++ b/arch/arm/common/uengine.c
@@ -312,16 +312,16 @@ static void generate_ucode(u8 *ucode, u32 *gpr_a, u32 *gpr_b)
b1 = (gpr_a[i] >> 8) & 0xff;
b0 = gpr_a[i] & 0xff;
- // immed[@ai, (b1 << 8) | b0]
- // 11110000 0000VVVV VVVV11VV VVVVVV00 1IIIIIII
+ /* immed[@ai, (b1 << 8) | b0] */
+ /* 11110000 0000VVVV VVVV11VV VVVVVV00 1IIIIIII */
ucode[offset++] = 0xf0;
ucode[offset++] = (b1 >> 4);
ucode[offset++] = (b1 << 4) | 0x0c | (b0 >> 6);
ucode[offset++] = (b0 << 2);
ucode[offset++] = 0x80 | i;
- // immed_w1[@ai, (b3 << 8) | b2]
- // 11110100 0100VVVV VVVV11VV VVVVVV00 1IIIIIII
+ /* immed_w1[@ai, (b3 << 8) | b2] */
+ /* 11110100 0100VVVV VVVV11VV VVVVVV00 1IIIIIII */
ucode[offset++] = 0xf4;
ucode[offset++] = 0x40 | (b3 >> 4);
ucode[offset++] = (b3 << 4) | 0x0c | (b2 >> 6);
@@ -340,16 +340,16 @@ static void generate_ucode(u8 *ucode, u32 *gpr_a, u32 *gpr_b)
b1 = (gpr_b[i] >> 8) & 0xff;
b0 = gpr_b[i] & 0xff;
- // immed[@bi, (b1 << 8) | b0]
- // 11110000 0000VVVV VVVV001I IIIIII11 VVVVVVVV
+ /* immed[@bi, (b1 << 8) | b0] */
+ /* 11110000 0000VVVV VVVV001I IIIIII11 VVVVVVVV */
ucode[offset++] = 0xf0;
ucode[offset++] = (b1 >> 4);
ucode[offset++] = (b1 << 4) | 0x02 | (i >> 6);
ucode[offset++] = (i << 2) | 0x03;
ucode[offset++] = b0;
- // immed_w1[@bi, (b3 << 8) | b2]
- // 11110100 0100VVVV VVVV001I IIIIII11 VVVVVVVV
+ /* immed_w1[@bi, (b3 << 8) | b2] */
+ /* 11110100 0100VVVV VVVV001I IIIIII11 VVVVVVVV */
ucode[offset++] = 0xf4;
ucode[offset++] = 0x40 | (b3 >> 4);
ucode[offset++] = (b3 << 4) | 0x02 | (i >> 6);
@@ -357,7 +357,7 @@ static void generate_ucode(u8 *ucode, u32 *gpr_a, u32 *gpr_b)
ucode[offset++] = b2;
}
- // ctx_arb[kill]
+ /* ctx_arb[kill] */
ucode[offset++] = 0xe0;
ucode[offset++] = 0x00;
ucode[offset++] = 0x01;
diff --git a/arch/arm/configs/at91sam9g20ek_defconfig b/arch/arm/configs/at91sam9g20ek_defconfig
index f1bac70d6ce9..9e90e6d79297 100644
--- a/arch/arm/configs/at91sam9g20ek_defconfig
+++ b/arch/arm/configs/at91sam9g20ek_defconfig
@@ -13,6 +13,7 @@ CONFIG_MODULE_UNLOAD=y
CONFIG_ARCH_AT91=y
CONFIG_ARCH_AT91SAM9G20=y
CONFIG_MACH_AT91SAM9G20EK=y
+CONFIG_MACH_AT91SAM9G20EK_2MMC=y
CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
# CONFIG_ARM_THUMB is not set
CONFIG_AEABI=y
diff --git a/arch/arm/configs/kirkwood_defconfig b/arch/arm/configs/kirkwood_defconfig
index ccc9c9959b82..2f7042813765 100644
--- a/arch/arm/configs/kirkwood_defconfig
+++ b/arch/arm/configs/kirkwood_defconfig
@@ -15,6 +15,7 @@ CONFIG_MACH_MV88F6281GTW_GE=y
CONFIG_MACH_SHEEVAPLUG=y
CONFIG_MACH_ESATA_SHEEVAPLUG=y
CONFIG_MACH_GURUPLUG=y
+CONFIG_MACH_DOCKSTAR=y
CONFIG_MACH_TS219=y
CONFIG_MACH_TS41X=y
CONFIG_MACH_OPENRD_BASE=y
diff --git a/arch/arm/configs/mx27_defconfig b/arch/arm/configs/mx27_defconfig
index b2038b0e266f..813cfb366c18 100644
--- a/arch/arm/configs/mx27_defconfig
+++ b/arch/arm/configs/mx27_defconfig
@@ -21,8 +21,14 @@ CONFIG_ARCH_MX2=y
CONFIG_MACH_MX27=y
CONFIG_MACH_MX27ADS=y
CONFIG_MACH_PCM038=y
+CONFIG_MACH_CPUIMX27=y
+CONFIG_MACH_EUKREA_CPUIMX27_USESDHC2=y
+CONFIG_MACH_EUKREA_CPUIMX27_USEUART4=y
CONFIG_MACH_MX27_3DS=y
+CONFIG_MACH_IMX27_VISSTRIM_M10=y
CONFIG_MACH_IMX27LITE=y
+CONFIG_MACH_PCA100=y
+CONFIG_MACH_MXT_TD60=y
CONFIG_MXC_IRQ_PRIOR=y
CONFIG_MXC_PWM=y
CONFIG_NO_HZ=y
@@ -76,7 +82,9 @@ CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=m
# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=m
CONFIG_SERIAL_IMX=y
CONFIG_SERIAL_IMX_CONSOLE=y
# CONFIG_LEGACY_PTYS is not set
@@ -85,19 +93,20 @@ CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_IMX=y
CONFIG_SPI=y
-CONFIG_SPI_BITBANG=y
+CONFIG_SPI_IMX=y
CONFIG_W1=y
CONFIG_W1_MASTER_MXC=y
CONFIG_W1_SLAVE_THERM=y
# CONFIG_HWMON is not set
CONFIG_FB=y
CONFIG_FB_IMX=y
-# CONFIG_VGA_CONSOLE is not set
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FONTS=y
CONFIG_FONT_8x8=y
# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
+CONFIG_USB=m
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_ULPI=y
CONFIG_MMC=y
CONFIG_MMC_MXC=y
CONFIG_RTC_CLASS=y
diff --git a/arch/arm/configs/mx31pdk_defconfig b/arch/arm/configs/mx31pdk_defconfig
deleted file mode 100644
index 2d29329749e4..000000000000
--- a/arch/arm/configs/mx31pdk_defconfig
+++ /dev/null
@@ -1,44 +0,0 @@
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SWAP is not set
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-# CONFIG_COMPAT_BRK is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_MXC=y
-# CONFIG_MACH_MX31ADS is not set
-CONFIG_MACH_MX31_3DS=y
-CONFIG_AEABI=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_INET_LRO is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-# CONFIG_FIRMWARE_IN_KERNEL is not set
-# CONFIG_BLK_DEV is not set
-# CONFIG_MISC_DEVICES is not set
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-# CONFIG_DEVKMEM is not set
-CONFIG_SERIAL_IMX=y
-CONFIG_SERIAL_IMX_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_DNOTIFY is not set
-# CONFIG_ENABLE_WARN_DEPRECATED is not set
-# CONFIG_ENABLE_MUST_CHECK is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-# CONFIG_CRC32 is not set
diff --git a/arch/arm/configs/mx3_defconfig b/arch/arm/configs/mx3_defconfig
index 161f907b611f..f0c339fd5d21 100644
--- a/arch/arm/configs/mx3_defconfig
+++ b/arch/arm/configs/mx3_defconfig
@@ -24,6 +24,7 @@ CONFIG_MACH_PCM043=y
CONFIG_MACH_ARMADILLO5X0=y
CONFIG_MACH_MX35_3DS=y
CONFIG_MACH_KZM_ARM11_01=y
+CONFIG_MACH_EUKREA_CPUIMX35=y
CONFIG_MXC_IRQ_PRIOR=y
CONFIG_MXC_PWM=y
CONFIG_NO_HZ=y
@@ -108,7 +109,6 @@ CONFIG_MMC=y
CONFIG_MMC_MXC=y
CONFIG_DMADEVICES=y
# CONFIG_DNOTIFY is not set
-CONFIG_INOTIFY=y
CONFIG_TMPFS=y
CONFIG_JFFS2_FS=y
CONFIG_UBIFS_FS=y
diff --git a/arch/arm/configs/mx51_defconfig b/arch/arm/configs/mx51_defconfig
index a665ecbbe2bc..163cfee7644c 100644
--- a/arch/arm/configs/mx51_defconfig
+++ b/arch/arm/configs/mx51_defconfig
@@ -15,6 +15,8 @@ CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_ARCH_MXC=y
CONFIG_ARCH_MX5=y
CONFIG_MACH_MX51_BABBAGE=y
+CONFIG_MACH_MX51_3DS=y
+CONFIG_MACH_EUKREA_CPUIMX51=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_PREEMPT_VOLUNTARY=y
@@ -69,7 +71,6 @@ CONFIG_REALTEK_PHY=y
CONFIG_NATIONAL_PHY=y
CONFIG_STE10XP=y
CONFIG_LSI_ET1011C_PHY=y
-CONFIG_FIXED_PHY=y
CONFIG_MDIO_BITBANG=y
CONFIG_MDIO_GPIO=y
CONFIG_NET_ETHERNET=y
@@ -100,7 +101,6 @@ CONFIG_I2C_ALGOPCF=m
CONFIG_I2C_ALGOPCA=m
CONFIG_GPIO_SYSFS=y
# CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
# CONFIG_HID_SUPPORT is not set
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
@@ -117,13 +117,11 @@ CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
CONFIG_EXT3_FS=y
-CONFIG_EXT3_DEFAULTS_TO_ORDERED=y
CONFIG_EXT3_FS_POSIX_ACL=y
CONFIG_EXT3_FS_SECURITY=y
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
-CONFIG_INOTIFY=y
CONFIG_QUOTA=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
# CONFIG_PRINT_QUOTA_WARNING is not set
@@ -136,6 +134,7 @@ CONFIG_ZISOFS=y
CONFIG_UDF_FS=m
CONFIG_MSDOS_FS=m
CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
CONFIG_CONFIGFS_FS=m
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -151,7 +150,6 @@ CONFIG_NLS_UTF8=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_FS=y
CONFIG_DEBUG_KERNEL=y
-# CONFIG_DETECT_SOFTLOCKUP is not set
# CONFIG_SCHED_DEBUG is not set
# CONFIG_DEBUG_BUGVERBOSE is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
@@ -159,7 +157,6 @@ CONFIG_DEBUG_KERNEL=y
# CONFIG_ARM_UNWIND is not set
CONFIG_DEBUG_LL=y
CONFIG_EARLY_PRINTK=y
-CONFIG_KEYS=y
CONFIG_SECURITYFS=y
CONFIG_CRYPTO_DEFLATE=y
CONFIG_CRYPTO_LZO=y
diff --git a/arch/arm/configs/realview-smp_defconfig b/arch/arm/configs/realview-smp_defconfig
index 9312ef9f9bf4..5ca7a61f7c01 100644
--- a/arch/arm/configs/realview-smp_defconfig
+++ b/arch/arm/configs/realview-smp_defconfig
@@ -39,6 +39,7 @@ CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_ARM_INTEGRATOR=y
+CONFIG_ARM_CHARLCD=y
CONFIG_NETDEVICES=y
CONFIG_SMSC_PHY=y
CONFIG_NET_ETHERNET=y
@@ -52,10 +53,13 @@ CONFIG_SERIAL_AMBA_PL011=y
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
CONFIG_LEGACY_PTY_COUNT=16
# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_VERSATILE=y
+CONFIG_SPI=y
+CONFIG_GPIOLIB=y
# CONFIG_HWMON is not set
CONFIG_FB=y
CONFIG_FB_ARMCLCD=y
-# CONFIG_VGA_CONSOLE is not set
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
@@ -70,7 +74,13 @@ CONFIG_SND_ARMAACI=y
# CONFIG_USB_SUPPORT is not set
CONFIG_MMC=y
CONFIG_MMC_ARMMMCI=y
-CONFIG_INOTIFY=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_PL031=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
CONFIG_CRAMFS=y
@@ -80,6 +90,7 @@ CONFIG_ROOT_NFS=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
CONFIG_DEBUG_KERNEL=y
# CONFIG_SCHED_DEBUG is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
diff --git a/arch/arm/configs/realview_defconfig b/arch/arm/configs/realview_defconfig
index fb75192ee7e5..fcaa60328051 100644
--- a/arch/arm/configs/realview_defconfig
+++ b/arch/arm/configs/realview_defconfig
@@ -38,6 +38,7 @@ CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_ARM_INTEGRATOR=y
+CONFIG_ARM_CHARLCD=y
CONFIG_NETDEVICES=y
CONFIG_SMSC_PHY=y
CONFIG_NET_ETHERNET=y
@@ -51,10 +52,13 @@ CONFIG_SERIAL_AMBA_PL011=y
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
CONFIG_LEGACY_PTY_COUNT=16
# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_VERSATILE=y
+CONFIG_SPI=y
+CONFIG_GPIOLIB=y
# CONFIG_HWMON is not set
CONFIG_FB=y
CONFIG_FB_ARMCLCD=y
-# CONFIG_VGA_CONSOLE is not set
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
@@ -69,7 +73,13 @@ CONFIG_SND_ARMAACI=y
# CONFIG_USB_SUPPORT is not set
CONFIG_MMC=y
CONFIG_MMC_ARMMMCI=y
-CONFIG_INOTIFY=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_PL031=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
CONFIG_CRAMFS=y
@@ -79,6 +89,7 @@ CONFIG_ROOT_NFS=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
CONFIG_DEBUG_KERNEL=y
# CONFIG_SCHED_DEBUG is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
diff --git a/arch/arm/configs/s5p6440_defconfig b/arch/arm/configs/s5p64x0_defconfig
index 0b0266c6d326..2993ecd35145 100644
--- a/arch/arm/configs/s5p6440_defconfig
+++ b/arch/arm/configs/s5p64x0_defconfig
@@ -5,10 +5,11 @@ CONFIG_KALLSYMS_ALL=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_S5P6440=y
+CONFIG_ARCH_S5P64X0=y
CONFIG_S3C_BOOT_ERROR_RESET=y
CONFIG_S3C_LOWLEVEL_UART_PORT=1
CONFIG_MACH_SMDK6440=y
+CONFIG_MACH_SMDK6450=y
CONFIG_CPU_32v6K=y
CONFIG_AEABI=y
CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x20800000,8M console=ttySAC1,115200 init=/linuxrc"
diff --git a/arch/arm/configs/u300_defconfig b/arch/arm/configs/u300_defconfig
index 46e5e0747269..c1c252cdca60 100644
--- a/arch/arm/configs/u300_defconfig
+++ b/arch/arm/configs/u300_defconfig
@@ -28,26 +28,9 @@ CONFIG_CPU_IDLE=y
CONFIG_FPE_NWFPE=y
CONFIG_PM=y
# CONFIG_SUSPEND is not set
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-# CONFIG_WIRELESS is not set
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ECC_SMC=y
+# CONFIG_MISC_DEVICES is not set
# CONFIG_INPUT_MOUSEDEV is not set
CONFIG_INPUT_EVDEV=y
# CONFIG_KEYBOARD_ATKBD is not set
@@ -58,7 +41,6 @@ CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
CONFIG_LEGACY_PTY_COUNT=16
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
-CONFIG_POWER_SUPPLY=y
# CONFIG_HWMON is not set
CONFIG_WATCHDOG=y
CONFIG_REGULATOR=y
@@ -66,24 +48,10 @@ CONFIG_FB=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
# CONFIG_LCD_CLASS_DEVICE is not set
CONFIG_BACKLIGHT_CLASS_DEVICE=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_SOUND=y
-CONFIG_SND=y
-# CONFIG_SND_SUPPORT_OLD_API is not set
-# CONFIG_SND_VERBOSE_PROCFS is not set
-# CONFIG_SND_DRIVERS is not set
-# CONFIG_SND_ARM is not set
-# CONFIG_SND_SPI is not set
-CONFIG_SND_SOC=y
# CONFIG_HID_SUPPORT is not set
# CONFIG_USB_SUPPORT is not set
CONFIG_MMC=y
-CONFIG_MMC_DEBUG=y
CONFIG_MMC_ARMMMCI=y
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_BACKLIGHT=y
CONFIG_RTC_CLASS=y
# CONFIG_RTC_HCTOSYS is not set
CONFIG_RTC_DRV_COH901331=y
@@ -93,12 +61,11 @@ CONFIG_COH901318=y
CONFIG_FUSE_FS=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
-# CONFIG_NETWORK_FILESYSTEMS is not set
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_FS=y
CONFIG_DEBUG_KERNEL=y
-# CONFIG_DETECT_SOFTLOCKUP is not set
# CONFIG_SCHED_DEBUG is not set
CONFIG_TIMER_STATS=y
# CONFIG_DEBUG_PREEMPT is not set
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 6e8f05c8a1c8..062b58c029ab 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -154,16 +154,39 @@
.long 9999b,9001f; \
.popsection
+#ifdef CONFIG_SMP
+#define ALT_SMP(instr...) \
+9998: instr
+#define ALT_UP(instr...) \
+ .pushsection ".alt.smp.init", "a" ;\
+ .long 9998b ;\
+ instr ;\
+ .popsection
+#define ALT_UP_B(label) \
+ .equ up_b_offset, label - 9998b ;\
+ .pushsection ".alt.smp.init", "a" ;\
+ .long 9998b ;\
+ b . + up_b_offset ;\
+ .popsection
+#else
+#define ALT_SMP(instr...)
+#define ALT_UP(instr...) instr
+#define ALT_UP_B(label) b label
+#endif
+
/*
* SMP data memory barrier
*/
.macro smp_dmb
#ifdef CONFIG_SMP
#if __LINUX_ARM_ARCH__ >= 7
- dmb
+ ALT_SMP(dmb)
#elif __LINUX_ARM_ARCH__ == 6
- mcr p15, 0, r0, c7, c10, 5 @ dmb
+ ALT_SMP(mcr p15, 0, r0, c7, c10, 5) @ dmb
+#else
+#error Incompatible SMP platform
#endif
+ ALT_UP(nop)
#endif
.endm
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index 4656a24058d2..3acd8fa25e34 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -137,10 +137,10 @@
#endif
/*
- * This flag is used to indicate that the page pointed to by a pte
- * is dirty and requires cleaning before returning it to the user.
+ * This flag is used to indicate that the page pointed to by a pte is clean
+ * and does not require cleaning before returning it to the user.
*/
-#define PG_dcache_dirty PG_arch_1
+#define PG_dcache_clean PG_arch_1
/*
* MM Cache Management
@@ -156,6 +156,12 @@
* Please note that the implementation of these, and the required
* effects are cache-type (VIVT/VIPT/PIPT) specific.
*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ * Currently only needed for cache-v6.S and cache-v7.S, see
+ * __flush_icache_all for the generic implementation.
+ *
* flush_kern_all()
*
* Unconditionally clean and invalidate the entire cache.
@@ -206,6 +212,7 @@
*/
struct cpu_cache_fns {
+ void (*flush_icache_all)(void);
void (*flush_kern_all)(void);
void (*flush_user_all)(void);
void (*flush_user_range)(unsigned long, unsigned long, unsigned int);
@@ -227,6 +234,7 @@ struct cpu_cache_fns {
extern struct cpu_cache_fns cpu_cache;
+#define __cpuc_flush_icache_all cpu_cache.flush_icache_all
#define __cpuc_flush_kern_all cpu_cache.flush_kern_all
#define __cpuc_flush_user_all cpu_cache.flush_user_all
#define __cpuc_flush_user_range cpu_cache.flush_user_range
@@ -246,6 +254,7 @@ extern struct cpu_cache_fns cpu_cache;
#else
+#define __cpuc_flush_icache_all __glue(_CACHE,_flush_icache_all)
#define __cpuc_flush_kern_all __glue(_CACHE,_flush_kern_cache_all)
#define __cpuc_flush_user_all __glue(_CACHE,_flush_user_cache_all)
#define __cpuc_flush_user_range __glue(_CACHE,_flush_user_cache_range)
@@ -253,6 +262,7 @@ extern struct cpu_cache_fns cpu_cache;
#define __cpuc_coherent_user_range __glue(_CACHE,_coherent_user_range)
#define __cpuc_flush_dcache_area __glue(_CACHE,_flush_kern_dcache_area)
+extern void __cpuc_flush_icache_all(void);
extern void __cpuc_flush_kern_all(void);
extern void __cpuc_flush_user_all(void);
extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int);
@@ -291,6 +301,37 @@ extern void copy_to_user_page(struct vm_area_struct *, struct page *,
/*
* Convert calls to our calling convention.
*/
+
+/* Invalidate I-cache */
+#define __flush_icache_all_generic() \
+ asm("mcr p15, 0, %0, c7, c5, 0" \
+ : : "r" (0));
+
+/* Invalidate I-cache inner shareable */
+#define __flush_icache_all_v7_smp() \
+ asm("mcr p15, 0, %0, c7, c1, 0" \
+ : : "r" (0));
+
+/*
+ * Optimized __flush_icache_all for the common cases. Note that UP ARMv7
+ * will fall through to use __flush_icache_all_generic.
+ */
+#if (defined(CONFIG_CPU_V7) && defined(CONFIG_CPU_V6)) || \
+ defined(CONFIG_SMP_ON_UP)
+#define __flush_icache_preferred __cpuc_flush_icache_all
+#elif __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP)
+#define __flush_icache_preferred __flush_icache_all_v7_smp
+#elif __LINUX_ARM_ARCH__ == 6 && defined(CONFIG_ARM_ERRATA_411920)
+#define __flush_icache_preferred __cpuc_flush_icache_all
+#else
+#define __flush_icache_preferred __flush_icache_all_generic
+#endif
+
+static inline void __flush_icache_all(void)
+{
+ __flush_icache_preferred();
+}
+
#define flush_cache_all() __cpuc_flush_kern_all()
static inline void vivt_flush_cache_mm(struct mm_struct *mm)
@@ -366,21 +407,6 @@ extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr
#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
extern void flush_dcache_page(struct page *);
-static inline void __flush_icache_all(void)
-{
-#ifdef CONFIG_ARM_ERRATA_411920
- extern void v6_icache_inval_all(void);
- v6_icache_inval_all();
-#elif defined(CONFIG_SMP) && __LINUX_ARM_ARCH__ >= 7
- asm("mcr p15, 0, %0, c7, c1, 0 @ invalidate I-cache inner shareable\n"
- :
- : "r" (0));
-#else
- asm("mcr p15, 0, %0, c7, c5, 0 @ invalidate I-cache\n"
- :
- : "r" (0));
-#endif
-}
static inline void flush_kernel_vmap_range(void *addr, int size)
{
if ((cache_is_vivt() || cache_is_vipt_aliasing()))
@@ -405,9 +431,6 @@ static inline void flush_anon_page(struct vm_area_struct *vma,
#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
static inline void flush_kernel_dcache_page(struct page *page)
{
- /* highmem pages are always flushed upon kunmap already */
- if ((cache_is_vivt() || cache_is_vipt_aliasing()) && !PageHighMem(page))
- __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE);
}
#define flush_dcache_mmap_lock(mapping) \
diff --git a/arch/arm/include/asm/cachetype.h b/arch/arm/include/asm/cachetype.h
index d3a4c2cb9f2f..c023db09fcc1 100644
--- a/arch/arm/include/asm/cachetype.h
+++ b/arch/arm/include/asm/cachetype.h
@@ -6,6 +6,7 @@
#define CACHEID_VIPT_ALIASING (1 << 2)
#define CACHEID_VIPT (CACHEID_VIPT_ALIASING|CACHEID_VIPT_NONALIASING)
#define CACHEID_ASID_TAGGED (1 << 3)
+#define CACHEID_VIPT_I_ALIASING (1 << 4)
extern unsigned int cacheid;
@@ -14,15 +15,18 @@ extern unsigned int cacheid;
#define cache_is_vipt_nonaliasing() cacheid_is(CACHEID_VIPT_NONALIASING)
#define cache_is_vipt_aliasing() cacheid_is(CACHEID_VIPT_ALIASING)
#define icache_is_vivt_asid_tagged() cacheid_is(CACHEID_ASID_TAGGED)
+#define icache_is_vipt_aliasing() cacheid_is(CACHEID_VIPT_I_ALIASING)
/*
* __LINUX_ARM_ARCH__ is the minimum supported CPU architecture
* Mask out support which will never be present on newer CPUs.
* - v6+ is never VIVT
- * - v7+ VIPT never aliases
+ * - v7+ VIPT never aliases on D-side
*/
#if __LINUX_ARM_ARCH__ >= 7
-#define __CACHEID_ARCH_MIN (CACHEID_VIPT_NONALIASING | CACHEID_ASID_TAGGED)
+#define __CACHEID_ARCH_MIN (CACHEID_VIPT_NONALIASING |\
+ CACHEID_ASID_TAGGED |\
+ CACHEID_VIPT_I_ALIASING)
#elif __LINUX_ARM_ARCH__ >= 6
#define __CACHEID_ARCH_MIN (~CACHEID_VIVT)
#else
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index 5747a8baa413..8bb66bca2e3e 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -127,4 +127,8 @@ struct mm_struct;
extern unsigned long arch_randomize_brk(struct mm_struct *mm);
#define arch_randomize_brk arch_randomize_brk
+extern int vectors_user_mapping(void);
+#define arch_setup_additional_pages(bprm, uses_interp) vectors_user_mapping()
+#define ARCH_HAS_SETUP_ADDITIONAL_PAGES
+
#endif
diff --git a/arch/arm/include/asm/ftrace.h b/arch/arm/include/asm/ftrace.h
index 103f7ee97313..f89515adac60 100644
--- a/arch/arm/include/asm/ftrace.h
+++ b/arch/arm/include/asm/ftrace.h
@@ -2,12 +2,30 @@
#define _ASM_ARM_FTRACE
#ifdef CONFIG_FUNCTION_TRACER
-#define MCOUNT_ADDR ((long)(mcount))
+#define MCOUNT_ADDR ((unsigned long)(__gnu_mcount_nc))
#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */
#ifndef __ASSEMBLY__
extern void mcount(void);
extern void __gnu_mcount_nc(void);
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+struct dyn_arch_ftrace {
+#ifdef CONFIG_OLD_MCOUNT
+ bool old_mcount;
+#endif
+};
+
+static inline unsigned long ftrace_call_adjust(unsigned long addr)
+{
+ /* With Thumb-2, the recorded addresses have the lsb set */
+ return addr & ~1;
+}
+
+extern void ftrace_caller_old(void);
+extern void ftrace_call_old(void);
+#endif
+
#endif
#endif
diff --git a/arch/arm/include/asm/hardware/coresight.h b/arch/arm/include/asm/hardware/coresight.h
index 212e47828c79..7ecd793b8f5a 100644
--- a/arch/arm/include/asm/hardware/coresight.h
+++ b/arch/arm/include/asm/hardware/coresight.h
@@ -21,18 +21,6 @@
#define TRACER_RUNNING BIT(TRACER_RUNNING_BIT)
#define TRACER_CYCLE_ACC BIT(TRACER_CYCLE_ACC_BIT)
-struct tracectx {
- unsigned int etb_bufsz;
- void __iomem *etb_regs;
- void __iomem *etm_regs;
- unsigned long flags;
- int ncmppairs;
- int etm_portsz;
- struct device *dev;
- struct clk *emu_clk;
- struct mutex mutex;
-};
-
#define TRACER_TIMEOUT 10000
#define etm_writel(t, v, x) \
@@ -112,10 +100,10 @@ struct tracectx {
/* ETM status register, "ETM Architecture", 3.3.2 */
#define ETMR_STATUS (0x10)
-#define ETMST_OVERFLOW (1 << 0)
-#define ETMST_PROGBIT (1 << 1)
-#define ETMST_STARTSTOP (1 << 2)
-#define ETMST_TRIGGER (1 << 3)
+#define ETMST_OVERFLOW BIT(0)
+#define ETMST_PROGBIT BIT(1)
+#define ETMST_STARTSTOP BIT(2)
+#define ETMST_TRIGGER BIT(3)
#define etm_progbit(t) (etm_readl((t), ETMR_STATUS) & ETMST_PROGBIT)
#define etm_started(t) (etm_readl((t), ETMR_STATUS) & ETMST_STARTSTOP)
@@ -123,7 +111,7 @@ struct tracectx {
#define ETMR_TRACEENCTRL2 0x1c
#define ETMR_TRACEENCTRL 0x24
-#define ETMTE_INCLEXCL (1 << 24)
+#define ETMTE_INCLEXCL BIT(24)
#define ETMR_TRACEENEVT 0x20
#define ETMCTRL_OPTS (ETMCTRL_DO_CPRT | \
ETMCTRL_DATA_DO_ADDR | \
@@ -146,12 +134,12 @@ struct tracectx {
#define ETBR_CTRL 0x20
#define ETBR_FORMATTERCTRL 0x304
#define ETBFF_ENFTC 1
-#define ETBFF_ENFCONT (1 << 1)
-#define ETBFF_FONFLIN (1 << 4)
-#define ETBFF_MANUAL_FLUSH (1 << 6)
-#define ETBFF_TRIGIN (1 << 8)
-#define ETBFF_TRIGEVT (1 << 9)
-#define ETBFF_TRIGFL (1 << 10)
+#define ETBFF_ENFCONT BIT(1)
+#define ETBFF_FONFLIN BIT(4)
+#define ETBFF_MANUAL_FLUSH BIT(6)
+#define ETBFF_TRIGIN BIT(8)
+#define ETBFF_TRIGEVT BIT(9)
+#define ETBFF_TRIGFL BIT(10)
#define etb_writel(t, v, x) \
(__raw_writel((v), (t)->etb_regs + (x)))
diff --git a/arch/arm/include/asm/hardware/icst.h b/arch/arm/include/asm/hardware/icst.h
index 10382a3dcec9..794220b087d2 100644
--- a/arch/arm/include/asm/hardware/icst.h
+++ b/arch/arm/include/asm/hardware/icst.h
@@ -8,7 +8,7 @@
* published by the Free Software Foundation.
*
* Support functions for calculating clocks/divisors for the ICST
- * clock generators. See http://www.icst.com/ for more information
+ * clock generators. See http://www.idt.com/ for more information
* on these devices.
*/
#ifndef ASMARM_HARDWARE_ICST_H
diff --git a/arch/arm/include/asm/hw_breakpoint.h b/arch/arm/include/asm/hw_breakpoint.h
new file mode 100644
index 000000000000..4d8ae9d67abe
--- /dev/null
+++ b/arch/arm/include/asm/hw_breakpoint.h
@@ -0,0 +1,133 @@
+#ifndef _ARM_HW_BREAKPOINT_H
+#define _ARM_HW_BREAKPOINT_H
+
+#ifdef __KERNEL__
+
+struct task_struct;
+
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+
+struct arch_hw_breakpoint_ctrl {
+ u32 __reserved : 9,
+ mismatch : 1,
+ : 9,
+ len : 8,
+ type : 2,
+ privilege : 2,
+ enabled : 1;
+};
+
+struct arch_hw_breakpoint {
+ u32 address;
+ u32 trigger;
+ struct perf_event *suspended_wp;
+ struct arch_hw_breakpoint_ctrl ctrl;
+};
+
+static inline u32 encode_ctrl_reg(struct arch_hw_breakpoint_ctrl ctrl)
+{
+ return (ctrl.mismatch << 22) | (ctrl.len << 5) | (ctrl.type << 3) |
+ (ctrl.privilege << 1) | ctrl.enabled;
+}
+
+static inline void decode_ctrl_reg(u32 reg,
+ struct arch_hw_breakpoint_ctrl *ctrl)
+{
+ ctrl->enabled = reg & 0x1;
+ reg >>= 1;
+ ctrl->privilege = reg & 0x3;
+ reg >>= 2;
+ ctrl->type = reg & 0x3;
+ reg >>= 2;
+ ctrl->len = reg & 0xff;
+ reg >>= 17;
+ ctrl->mismatch = reg & 0x1;
+}
+
+/* Debug architecture numbers. */
+#define ARM_DEBUG_ARCH_RESERVED 0 /* In case of ptrace ABI updates. */
+#define ARM_DEBUG_ARCH_V6 1
+#define ARM_DEBUG_ARCH_V6_1 2
+#define ARM_DEBUG_ARCH_V7_ECP14 3
+#define ARM_DEBUG_ARCH_V7_MM 4
+
+/* Breakpoint */
+#define ARM_BREAKPOINT_EXECUTE 0
+
+/* Watchpoints */
+#define ARM_BREAKPOINT_LOAD 1
+#define ARM_BREAKPOINT_STORE 2
+
+/* Privilege Levels */
+#define ARM_BREAKPOINT_PRIV 1
+#define ARM_BREAKPOINT_USER 2
+
+/* Lengths */
+#define ARM_BREAKPOINT_LEN_1 0x1
+#define ARM_BREAKPOINT_LEN_2 0x3
+#define ARM_BREAKPOINT_LEN_4 0xf
+#define ARM_BREAKPOINT_LEN_8 0xff
+
+/* Limits */
+#define ARM_MAX_BRP 16
+#define ARM_MAX_WRP 16
+#define ARM_MAX_HBP_SLOTS (ARM_MAX_BRP + ARM_MAX_WRP)
+
+/* DSCR method of entry bits. */
+#define ARM_DSCR_MOE(x) ((x >> 2) & 0xf)
+#define ARM_ENTRY_BREAKPOINT 0x1
+#define ARM_ENTRY_ASYNC_WATCHPOINT 0x2
+#define ARM_ENTRY_SYNC_WATCHPOINT 0xa
+
+/* DSCR monitor/halting bits. */
+#define ARM_DSCR_HDBGEN (1 << 14)
+#define ARM_DSCR_MDBGEN (1 << 15)
+
+/* opcode2 numbers for the co-processor instructions. */
+#define ARM_OP2_BVR 4
+#define ARM_OP2_BCR 5
+#define ARM_OP2_WVR 6
+#define ARM_OP2_WCR 7
+
+/* Base register numbers for the debug registers. */
+#define ARM_BASE_BVR 64
+#define ARM_BASE_BCR 80
+#define ARM_BASE_WVR 96
+#define ARM_BASE_WCR 112
+
+/* Accessor macros for the debug registers. */
+#define ARM_DBG_READ(M, OP2, VAL) do {\
+ asm volatile("mrc p14, 0, %0, c0," #M ", " #OP2 : "=r" (VAL));\
+} while (0)
+
+#define ARM_DBG_WRITE(M, OP2, VAL) do {\
+ asm volatile("mcr p14, 0, %0, c0," #M ", " #OP2 : : "r" (VAL));\
+} while (0)
+
+struct notifier_block;
+struct perf_event;
+struct pmu;
+
+extern struct pmu perf_ops_bp;
+extern int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl,
+ int *gen_len, int *gen_type);
+extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
+extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
+extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
+ unsigned long val, void *data);
+
+extern u8 arch_get_debug_arch(void);
+extern u8 arch_get_max_wp_len(void);
+extern void clear_ptrace_hw_breakpoint(struct task_struct *tsk);
+
+int arch_install_hw_breakpoint(struct perf_event *bp);
+void arch_uninstall_hw_breakpoint(struct perf_event *bp);
+void hw_breakpoint_pmu_read(struct perf_event *bp);
+int hw_breakpoint_slots(int type);
+
+#else
+static inline void clear_ptrace_hw_breakpoint(struct task_struct *tsk) {}
+
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
+#endif /* __KERNEL__ */
+#endif /* _ARM_HW_BREAKPOINT_H */
diff --git a/arch/arm/include/asm/hw_irq.h b/arch/arm/include/asm/hw_irq.h
index 90831f6f5f5c..5586b7c8ef6f 100644
--- a/arch/arm/include/asm/hw_irq.h
+++ b/arch/arm/include/asm/hw_irq.h
@@ -24,4 +24,6 @@ void set_irq_flags(unsigned int irq, unsigned int flags);
#define IRQF_PROBE (1 << 1)
#define IRQF_NOAUTOEN (1 << 2)
+#define ARCH_IRQ_INIT_FLAGS (IRQ_NOREQUEST | IRQ_NOPROBE)
+
#endif
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 1261b1f928d9..815efa2d4e07 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -294,6 +294,7 @@ extern void pci_iounmap(struct pci_dev *dev, void __iomem *addr);
#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
extern int valid_phys_addr_range(unsigned long addr, size_t size);
extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size);
+extern int devmem_is_allowed(unsigned long pfn);
#endif
/*
diff --git a/arch/arm/include/asm/ioctls.h b/arch/arm/include/asm/ioctls.h
index 0b30894b5482..9c9629816128 100644
--- a/arch/arm/include/asm/ioctls.h
+++ b/arch/arm/include/asm/ioctls.h
@@ -1,89 +1,8 @@
#ifndef __ASM_ARM_IOCTLS_H
#define __ASM_ARM_IOCTLS_H
-#include <asm/ioctl.h>
-
-/* 0x54 is just a magic number to make these relatively unique ('T') */
-
-#define TCGETS 0x5401
-#define TCSETS 0x5402
-#define TCSETSW 0x5403
-#define TCSETSF 0x5404
-#define TCGETA 0x5405
-#define TCSETA 0x5406
-#define TCSETAW 0x5407
-#define TCSETAF 0x5408
-#define TCSBRK 0x5409
-#define TCXONC 0x540A
-#define TCFLSH 0x540B
-#define TIOCEXCL 0x540C
-#define TIOCNXCL 0x540D
-#define TIOCSCTTY 0x540E
-#define TIOCGPGRP 0x540F
-#define TIOCSPGRP 0x5410
-#define TIOCOUTQ 0x5411
-#define TIOCSTI 0x5412
-#define TIOCGWINSZ 0x5413
-#define TIOCSWINSZ 0x5414
-#define TIOCMGET 0x5415
-#define TIOCMBIS 0x5416
-#define TIOCMBIC 0x5417
-#define TIOCMSET 0x5418
-#define TIOCGSOFTCAR 0x5419
-#define TIOCSSOFTCAR 0x541A
-#define FIONREAD 0x541B
-#define TIOCINQ FIONREAD
-#define TIOCLINUX 0x541C
-#define TIOCCONS 0x541D
-#define TIOCGSERIAL 0x541E
-#define TIOCSSERIAL 0x541F
-#define TIOCPKT 0x5420
-#define FIONBIO 0x5421
-#define TIOCNOTTY 0x5422
-#define TIOCSETD 0x5423
-#define TIOCGETD 0x5424
-#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
-#define TIOCSBRK 0x5427 /* BSD compatibility */
-#define TIOCCBRK 0x5428 /* BSD compatibility */
-#define TIOCGSID 0x5429 /* Return the session ID of FD */
-#define TCGETS2 _IOR('T',0x2A, struct termios2)
-#define TCSETS2 _IOW('T',0x2B, struct termios2)
-#define TCSETSW2 _IOW('T',0x2C, struct termios2)
-#define TCSETSF2 _IOW('T',0x2D, struct termios2)
-#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
-#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
-#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */
-
-#define TIOCGRS485 0x542E
-#define TIOCSRS485 0x542F
-
-#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */
-#define FIOCLEX 0x5451
-#define FIOASYNC 0x5452
-#define TIOCSERCONFIG 0x5453
-#define TIOCSERGWILD 0x5454
-#define TIOCSERSWILD 0x5455
-#define TIOCGLCKTRMIOS 0x5456
-#define TIOCSLCKTRMIOS 0x5457
-#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
-#define TIOCSERGETLSR 0x5459 /* Get line status register */
-#define TIOCSERGETMULTI 0x545A /* Get multiport config */
-#define TIOCSERSETMULTI 0x545B /* Set multiport config */
-
-#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
-#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
#define FIOQSIZE 0x545E
-/* Used for packet mode */
-#define TIOCPKT_DATA 0
-#define TIOCPKT_FLUSHREAD 1
-#define TIOCPKT_FLUSHWRITE 2
-#define TIOCPKT_STOP 4
-#define TIOCPKT_START 8
-#define TIOCPKT_NOSTOP 16
-#define TIOCPKT_DOSTOP 32
-#define TIOCPKT_IOCTL 64
-
-#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
+#include <asm-generic/ioctls.h>
#endif
diff --git a/arch/arm/include/asm/irqflags.h b/arch/arm/include/asm/irqflags.h
index 6d09974e6646..1e6cca55c750 100644
--- a/arch/arm/include/asm/irqflags.h
+++ b/arch/arm/include/asm/irqflags.h
@@ -10,66 +10,85 @@
*/
#if __LINUX_ARM_ARCH__ >= 6
-#define raw_local_irq_save(x) \
- ({ \
- __asm__ __volatile__( \
- "mrs %0, cpsr @ local_irq_save\n" \
- "cpsid i" \
- : "=r" (x) : : "memory", "cc"); \
- })
+static inline unsigned long arch_local_irq_save(void)
+{
+ unsigned long flags;
+
+ asm volatile(
+ " mrs %0, cpsr @ arch_local_irq_save\n"
+ " cpsid i"
+ : "=r" (flags) : : "memory", "cc");
+ return flags;
+}
+
+static inline void arch_local_irq_enable(void)
+{
+ asm volatile(
+ " cpsie i @ arch_local_irq_enable"
+ :
+ :
+ : "memory", "cc");
+}
+
+static inline void arch_local_irq_disable(void)
+{
+ asm volatile(
+ " cpsid i @ arch_local_irq_disable"
+ :
+ :
+ : "memory", "cc");
+}
-#define raw_local_irq_enable() __asm__("cpsie i @ __sti" : : : "memory", "cc")
-#define raw_local_irq_disable() __asm__("cpsid i @ __cli" : : : "memory", "cc")
#define local_fiq_enable() __asm__("cpsie f @ __stf" : : : "memory", "cc")
#define local_fiq_disable() __asm__("cpsid f @ __clf" : : : "memory", "cc")
-
#else
/*
* Save the current interrupt enable state & disable IRQs
*/
-#define raw_local_irq_save(x) \
- ({ \
- unsigned long temp; \
- (void) (&temp == &x); \
- __asm__ __volatile__( \
- "mrs %0, cpsr @ local_irq_save\n" \
-" orr %1, %0, #128\n" \
-" msr cpsr_c, %1" \
- : "=r" (x), "=r" (temp) \
- : \
- : "memory", "cc"); \
- })
-
+static inline unsigned long arch_local_irq_save(void)
+{
+ unsigned long flags, temp;
+
+ asm volatile(
+ " mrs %0, cpsr @ arch_local_irq_save\n"
+ " orr %1, %0, #128\n"
+ " msr cpsr_c, %1"
+ : "=r" (flags), "=r" (temp)
+ :
+ : "memory", "cc");
+ return flags;
+}
+
/*
* Enable IRQs
*/
-#define raw_local_irq_enable() \
- ({ \
- unsigned long temp; \
- __asm__ __volatile__( \
- "mrs %0, cpsr @ local_irq_enable\n" \
-" bic %0, %0, #128\n" \
-" msr cpsr_c, %0" \
- : "=r" (temp) \
- : \
- : "memory", "cc"); \
- })
+static inline void arch_local_irq_enable(void)
+{
+ unsigned long temp;
+ asm volatile(
+ " mrs %0, cpsr @ arch_local_irq_enable\n"
+ " bic %0, %0, #128\n"
+ " msr cpsr_c, %0"
+ : "=r" (temp)
+ :
+ : "memory", "cc");
+}
/*
* Disable IRQs
*/
-#define raw_local_irq_disable() \
- ({ \
- unsigned long temp; \
- __asm__ __volatile__( \
- "mrs %0, cpsr @ local_irq_disable\n" \
-" orr %0, %0, #128\n" \
-" msr cpsr_c, %0" \
- : "=r" (temp) \
- : \
- : "memory", "cc"); \
- })
+static inline void arch_local_irq_disable(void)
+{
+ unsigned long temp;
+ asm volatile(
+ " mrs %0, cpsr @ arch_local_irq_disable\n"
+ " orr %0, %0, #128\n"
+ " msr cpsr_c, %0"
+ : "=r" (temp)
+ :
+ : "memory", "cc");
+}
/*
* Enable FIQs
@@ -106,27 +125,31 @@
/*
* Save the current interrupt enable state.
*/
-#define raw_local_save_flags(x) \
- ({ \
- __asm__ __volatile__( \
- "mrs %0, cpsr @ local_save_flags" \
- : "=r" (x) : : "memory", "cc"); \
- })
+static inline unsigned long arch_local_save_flags(void)
+{
+ unsigned long flags;
+ asm volatile(
+ " mrs %0, cpsr @ local_save_flags"
+ : "=r" (flags) : : "memory", "cc");
+ return flags;
+}
/*
* restore saved IRQ & FIQ state
*/
-#define raw_local_irq_restore(x) \
- __asm__ __volatile__( \
- "msr cpsr_c, %0 @ local_irq_restore\n" \
- : \
- : "r" (x) \
- : "memory", "cc")
+static inline void arch_local_irq_restore(unsigned long flags)
+{
+ asm volatile(
+ " msr cpsr_c, %0 @ local_irq_restore"
+ :
+ : "r" (flags)
+ : "memory", "cc");
+}
-#define raw_irqs_disabled_flags(flags) \
-({ \
- (int)((flags) & PSR_I_BIT); \
-})
+static inline int arch_irqs_disabled_flags(unsigned long flags)
+{
+ return flags & PSR_I_BIT;
+}
#endif
#endif
diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
index 8a0dd18ba642..d97a964207fa 100644
--- a/arch/arm/include/asm/mach/arch.h
+++ b/arch/arm/include/asm/mach/arch.h
@@ -16,18 +16,15 @@ struct sys_timer;
struct machine_desc {
/*
- * Note! The first four elements are used
+ * Note! The first two elements are used
* by assembler code in head.S, head-common.S
*/
unsigned int nr; /* architecture number */
- unsigned int nr_irqs; /* number of IRQs */
- unsigned int phys_io; /* start of physical io */
- unsigned int io_pg_offst; /* byte offset for io
- * page tabe entry */
-
const char *name; /* architecture name */
unsigned long boot_params; /* tagged list */
+ unsigned int nr_irqs; /* number of IRQs */
+
unsigned int video_start; /* start of video RAM */
unsigned int video_end; /* end of video RAM */
diff --git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h
index a0b3cac0547c..71605d9f8e42 100644
--- a/arch/arm/include/asm/mmu_context.h
+++ b/arch/arm/include/asm/mmu_context.h
@@ -18,7 +18,6 @@
#include <asm/cacheflush.h>
#include <asm/cachetype.h>
#include <asm/proc-fns.h>
-#include <asm-generic/mm_hooks.h>
void __check_kvm_seq(struct mm_struct *mm);
@@ -134,4 +133,32 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
#define deactivate_mm(tsk,mm) do { } while (0)
#define activate_mm(prev,next) switch_mm(prev, next, NULL)
+/*
+ * We are inserting a "fake" vma for the user-accessible vector page so
+ * gdb and friends can get to it through ptrace and /proc/<pid>/mem.
+ * But we also want to remove it before the generic code gets to see it
+ * during process exit or the unmapping of it would cause total havoc.
+ * (the macro is used as remove_vma() is static to mm/mmap.c)
+ */
+#define arch_exit_mmap(mm) \
+do { \
+ struct vm_area_struct *high_vma = find_vma(mm, 0xffff0000); \
+ if (high_vma) { \
+ BUG_ON(high_vma->vm_next); /* it should be last */ \
+ if (high_vma->vm_prev) \
+ high_vma->vm_prev->vm_next = NULL; \
+ else \
+ mm->mmap = NULL; \
+ rb_erase(&high_vma->vm_rb, &mm->mm_rb); \
+ mm->mmap_cache = NULL; \
+ mm->map_count--; \
+ remove_vma(high_vma); \
+ } \
+} while (0)
+
+static inline void arch_dup_mmap(struct mm_struct *oldmm,
+ struct mm_struct *mm)
+{
+}
+
#endif
diff --git a/arch/arm/include/asm/module.h b/arch/arm/include/asm/module.h
index e4dfa69abb68..cbb0bc295d2b 100644
--- a/arch/arm/include/asm/module.h
+++ b/arch/arm/include/asm/module.h
@@ -7,20 +7,27 @@
struct unwind_table;
-struct mod_arch_specific
-{
#ifdef CONFIG_ARM_UNWIND
- Elf_Shdr *unw_sec_init;
- Elf_Shdr *unw_sec_devinit;
- Elf_Shdr *unw_sec_core;
- Elf_Shdr *sec_init_text;
- Elf_Shdr *sec_devinit_text;
- Elf_Shdr *sec_core_text;
- struct unwind_table *unwind_init;
- struct unwind_table *unwind_devinit;
- struct unwind_table *unwind_core;
-#endif
+struct arm_unwind_mapping {
+ Elf_Shdr *unw_sec;
+ Elf_Shdr *sec_text;
+ struct unwind_table *unwind;
+};
+enum {
+ ARM_SEC_INIT,
+ ARM_SEC_DEVINIT,
+ ARM_SEC_CORE,
+ ARM_SEC_EXIT,
+ ARM_SEC_DEVEXIT,
+ ARM_SEC_MAX,
+};
+struct mod_arch_specific {
+ struct arm_unwind_mapping map[ARM_SEC_MAX];
};
+#else
+struct mod_arch_specific {
+};
+#endif
/*
* Include the ARM architecture version.
diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h
index b5799a3b7117..c4aa4e8c6af9 100644
--- a/arch/arm/include/asm/perf_event.h
+++ b/arch/arm/include/asm/perf_event.h
@@ -12,18 +12,6 @@
#ifndef __ARM_PERF_EVENT_H__
#define __ARM_PERF_EVENT_H__
-/*
- * NOP: on *most* (read: all supported) ARM platforms, the performance
- * counter interrupts are regular interrupts and not an NMI. This
- * means that when we receive the interrupt we can call
- * perf_event_do_pending() that handles all of the work with
- * interrupts disabled.
- */
-static inline void
-set_perf_event_pending(void)
-{
-}
-
/* ARM performance counters start from 1 (in the cp15 accesses) so use the
* same indexes here for consistency. */
#define PERF_EVENT_INDEX_OFFSET 1
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index e90b167ea848..a9672e8406a3 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -278,9 +278,24 @@ extern struct page *empty_zero_page;
#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
-#define set_pte_at(mm,addr,ptep,pteval) do { \
- set_pte_ext(ptep, pteval, (addr) >= TASK_SIZE ? 0 : PTE_EXT_NG); \
- } while (0)
+#if __LINUX_ARM_ARCH__ < 6
+static inline void __sync_icache_dcache(pte_t pteval)
+{
+}
+#else
+extern void __sync_icache_dcache(pte_t pteval);
+#endif
+
+static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pteval)
+{
+ if (addr >= TASK_SIZE)
+ set_pte_ext(ptep, pteval, 0);
+ else {
+ __sync_icache_dcache(pteval);
+ set_pte_ext(ptep, pteval, PTE_EXT_NG);
+ }
+}
/*
* The following only work if pte_present() is true.
@@ -290,8 +305,13 @@ extern struct page *empty_zero_page;
#define pte_write(pte) (pte_val(pte) & L_PTE_WRITE)
#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY)
#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG)
+#define pte_exec(pte) (pte_val(pte) & L_PTE_EXEC)
#define pte_special(pte) (0)
+#define pte_present_user(pte) \
+ ((pte_val(pte) & (L_PTE_PRESENT | L_PTE_USER)) == \
+ (L_PTE_PRESENT | L_PTE_USER))
+
#define PTE_BIT_FUNC(fn,op) \
static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h
index 7bed3daf83b8..67357baaeeeb 100644
--- a/arch/arm/include/asm/processor.h
+++ b/arch/arm/include/asm/processor.h
@@ -19,6 +19,7 @@
#ifdef __KERNEL__
+#include <asm/hw_breakpoint.h>
#include <asm/ptrace.h>
#include <asm/types.h>
@@ -41,6 +42,9 @@ struct debug_entry {
struct debug_info {
int nsaved;
struct debug_entry bp[2];
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+ struct perf_event *hbp[ARM_MAX_HBP_SLOTS];
+#endif
};
struct thread_struct {
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h
index 7ce15eb15f72..783d50f32618 100644
--- a/arch/arm/include/asm/ptrace.h
+++ b/arch/arm/include/asm/ptrace.h
@@ -29,6 +29,8 @@
#define PTRACE_SETCRUNCHREGS 26
#define PTRACE_GETVFPREGS 27
#define PTRACE_SETVFPREGS 28
+#define PTRACE_GETHBPREGS 29
+#define PTRACE_SETHBPREGS 30
/*
* PSR bits
diff --git a/arch/arm/include/asm/seccomp.h b/arch/arm/include/asm/seccomp.h
new file mode 100644
index 000000000000..52b156b341f5
--- /dev/null
+++ b/arch/arm/include/asm/seccomp.h
@@ -0,0 +1,11 @@
+#ifndef _ASM_ARM_SECCOMP_H
+#define _ASM_ARM_SECCOMP_H
+
+#include <linux/unistd.h>
+
+#define __NR_seccomp_read __NR_read
+#define __NR_seccomp_write __NR_write
+#define __NR_seccomp_exit __NR_exit
+#define __NR_seccomp_sigreturn __NR_rt_sigreturn
+
+#endif /* _ASM_ARM_SECCOMP_H */
diff --git a/arch/arm/include/asm/smp_mpidr.h b/arch/arm/include/asm/smp_mpidr.h
new file mode 100644
index 000000000000..6a9307d64900
--- /dev/null
+++ b/arch/arm/include/asm/smp_mpidr.h
@@ -0,0 +1,17 @@
+#ifndef ASMARM_SMP_MIDR_H
+#define ASMARM_SMP_MIDR_H
+
+#define hard_smp_processor_id() \
+ ({ \
+ unsigned int cpunum; \
+ __asm__("\n" \
+ "1: mrc p15, 0, %0, c0, c0, 5\n" \
+ " .pushsection \".alt.smp.init\", \"a\"\n"\
+ " .long 1b\n" \
+ " mov %0, #0\n" \
+ " .popsection" \
+ : "=r" (cpunum)); \
+ cpunum &= 0x0F; \
+ })
+
+#endif
diff --git a/arch/arm/include/asm/smp_plat.h b/arch/arm/include/asm/smp_plat.h
index e6215305544a..f24c1b9e211d 100644
--- a/arch/arm/include/asm/smp_plat.h
+++ b/arch/arm/include/asm/smp_plat.h
@@ -7,15 +7,40 @@
#include <asm/cputype.h>
+/*
+ * Return true if we are running on a SMP platform
+ */
+static inline bool is_smp(void)
+{
+#ifndef CONFIG_SMP
+ return false;
+#elif defined(CONFIG_SMP_ON_UP)
+ extern unsigned int smp_on_up;
+ return !!smp_on_up;
+#else
+ return true;
+#endif
+}
+
/* all SMP configurations have the extended CPUID registers */
static inline int tlb_ops_need_broadcast(void)
{
+ if (!is_smp())
+ return 0;
+
return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2;
}
+#if !defined(CONFIG_SMP) || __LINUX_ARM_ARCH__ >= 7
+#define cache_ops_need_broadcast() 0
+#else
static inline int cache_ops_need_broadcast(void)
{
+ if (!is_smp())
+ return 0;
+
return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 1;
}
+#endif
#endif
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 8ba1ccf82a02..1120f18a6b17 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -85,6 +85,10 @@ void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
struct pt_regs *),
int sig, int code, const char *name);
+void hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned int,
+ struct pt_regs *),
+ int sig, int code, const char *name);
+
#define xchg(ptr,x) \
((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
@@ -325,6 +329,8 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size
extern void disable_hlt(void);
extern void enable_hlt(void);
+void cpu_idle_wait(void);
+
#include <asm-generic/cmpxchg-local.h>
#if __LINUX_ARM_ARCH__ < 6
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index 763e29fa8530..7b5cc8dae06e 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -144,6 +144,7 @@ extern void vfp_flush_hwstate(struct thread_info *);
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */
#define TIF_FREEZE 19
#define TIF_RESTORE_SIGMASK 20
+#define TIF_SECCOMP 21
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
@@ -153,6 +154,7 @@ extern void vfp_flush_hwstate(struct thread_info *);
#define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT)
#define _TIF_FREEZE (1 << TIF_FREEZE)
#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
+#define _TIF_SECCOMP (1 << TIF_SECCOMP)
/*
* Change these and you break ASM code in entry-common.S
diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h
index 33b546ae72d4..ce7378ea15a2 100644
--- a/arch/arm/include/asm/tlbflush.h
+++ b/arch/arm/include/asm/tlbflush.h
@@ -70,6 +70,10 @@
#undef _TLB
#undef MULTI_TLB
+#ifdef CONFIG_SMP_ON_UP
+#define MULTI_TLB 1
+#endif
+
#define v3_tlb_flags (TLB_V3_FULL | TLB_V3_PAGE)
#ifdef CONFIG_CPU_TLB_V3
@@ -185,17 +189,23 @@
# define v6wbi_always_flags (-1UL)
#endif
-#ifdef CONFIG_SMP
-#define v7wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_V7_IS_BTB | \
+#define v7wbi_tlb_flags_smp (TLB_WB | TLB_DCLEAN | TLB_V7_IS_BTB | \
TLB_V7_UIS_FULL | TLB_V7_UIS_PAGE | TLB_V7_UIS_ASID)
-#else
-#define v7wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BTB | \
+#define v7wbi_tlb_flags_up (TLB_WB | TLB_DCLEAN | TLB_BTB | \
TLB_V6_U_FULL | TLB_V6_U_PAGE | TLB_V6_U_ASID)
-#endif
#ifdef CONFIG_CPU_TLB_V7
-# define v7wbi_possible_flags v7wbi_tlb_flags
-# define v7wbi_always_flags v7wbi_tlb_flags
+
+# ifdef CONFIG_SMP_ON_UP
+# define v7wbi_possible_flags (v7wbi_tlb_flags_smp | v7wbi_tlb_flags_up)
+# define v7wbi_always_flags (v7wbi_tlb_flags_smp & v7wbi_tlb_flags_up)
+# elif defined(CONFIG_SMP)
+# define v7wbi_possible_flags v7wbi_tlb_flags_smp
+# define v7wbi_always_flags v7wbi_tlb_flags_smp
+# else
+# define v7wbi_possible_flags v7wbi_tlb_flags_up
+# define v7wbi_always_flags v7wbi_tlb_flags_up
+# endif
# ifdef _TLB
# define MULTI_TLB 1
# else
@@ -560,12 +570,20 @@ extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
#endif
/*
- * if PG_dcache_dirty is set for the page, we need to ensure that any
+ * If PG_dcache_clean is not set for the page, we need to ensure that any
* cache entries for the kernels virtual memory range are written
- * back to the page.
+ * back to the page. On ARMv6 and later, the cache coherency is handled via
+ * the set_pte_at() function.
*/
+#if __LINUX_ARM_ARCH__ < 6
extern void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
pte_t *ptep);
+#else
+static inline void update_mmu_cache(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep)
+{
+}
+#endif
#endif
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 980b78e31328..5b9b268f4fbb 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_ARM_UNWIND) += unwind.o
obj-$(CONFIG_HAVE_TCM) += tcm.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
+obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o
AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 8214bfebfaca..e5e1e5387678 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -165,6 +165,8 @@ EXPORT_SYMBOL(_find_next_bit_be);
#endif
#ifdef CONFIG_FUNCTION_TRACER
+#ifdef CONFIG_OLD_MCOUNT
EXPORT_SYMBOL(mcount);
+#endif
EXPORT_SYMBOL(__gnu_mcount_nc);
#endif
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 85f2a019f77b..82da66172132 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -102,8 +102,6 @@ int main(void)
DEFINE(SIZEOF_MACHINE_DESC, sizeof(struct machine_desc));
DEFINE(MACHINFO_TYPE, offsetof(struct machine_desc, nr));
DEFINE(MACHINFO_NAME, offsetof(struct machine_desc, name));
- DEFINE(MACHINFO_PHYSIO, offsetof(struct machine_desc, phys_io));
- DEFINE(MACHINFO_PGOFFIO, offsetof(struct machine_desc, io_pg_offst));
BLANK();
DEFINE(PROC_INFO_SZ, sizeof(struct proc_info_list));
DEFINE(PROCINFO_INITFUNC, offsetof(struct proc_info_list, __cpu_flush));
diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S
index a38b4879441d..a0f07521ca8a 100644
--- a/arch/arm/kernel/debug.S
+++ b/arch/arm/kernel/debug.S
@@ -22,11 +22,11 @@
#if defined(CONFIG_DEBUG_ICEDCC)
@@ debug using ARM EmbeddedICE DCC channel
-#if defined(CONFIG_CPU_V6)
-
- .macro addruart, rx, tmp
+ .macro addruart, rp, rv
.endm
+#if defined(CONFIG_CPU_V6)
+
.macro senduart, rd, rx
mcr p14, 0, \rd, c0, c5, 0
.endm
@@ -51,9 +51,6 @@
#elif defined(CONFIG_CPU_V7)
- .macro addruart, rx, tmp
- .endm
-
.macro senduart, rd, rx
mcr p14, 0, \rd, c0, c5, 0
.endm
@@ -71,9 +68,6 @@ wait: mrc p14, 0, pc, c0, c1, 0
#elif defined(CONFIG_CPU_XSCALE)
- .macro addruart, rx, tmp
- .endm
-
.macro senduart, rd, rx
mcr p14, 0, \rd, c8, c0, 0
.endm
@@ -98,9 +92,6 @@ wait: mrc p14, 0, pc, c0, c1, 0
#else
- .macro addruart, rx, tmp
- .endm
-
.macro senduart, rd, rx
mcr p14, 0, \rd, c1, c0, 0
.endm
@@ -130,6 +121,22 @@ wait: mrc p14, 0, pc, c0, c1, 0
#include <mach/debug-macro.S>
#endif /* CONFIG_DEBUG_ICEDCC */
+#ifdef CONFIG_MMU
+ .macro addruart_current, rx, tmp1, tmp2
+ addruart \tmp1, \tmp2
+ mrc p15, 0, \rx, c1, c0
+ tst \rx, #1
+ moveq \rx, \tmp1
+ movne \rx, \tmp2
+ .endm
+
+#else /* !CONFIG_MMU */
+ .macro addruart_current, rx, tmp1, tmp2
+ addruart \rx, \tmp1
+ .endm
+
+#endif /* CONFIG_MMU */
+
/*
* Useful debugging routines
*/
@@ -164,7 +171,7 @@ ENDPROC(printhex2)
.ltorg
ENTRY(printascii)
- addruart r3, r1
+ addruart_current r3, r1, r2
b 2f
1: waituart r2, r3
senduart r1, r3
@@ -180,7 +187,7 @@ ENTRY(printascii)
ENDPROC(printascii)
ENTRY(printch)
- addruart r3, r1
+ addruart_current r3, r1, r2
mov r1, r0
mov r0, #0
b 1b
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index bb8e93a76407..c09e3573c5de 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -46,7 +46,8 @@
* this macro assumes that irqstat (r6) and base (r5) are
* preserved from get_irqnr_and_base above
*/
- test_for_ipi r0, r6, r5, lr
+ ALT_SMP(test_for_ipi r0, r6, r5, lr)
+ ALT_UP_B(9997f)
movne r0, sp
adrne lr, BSYM(1b)
bne do_IPI
@@ -57,6 +58,7 @@
adrne lr, BSYM(1b)
bne do_local_timer
#endif
+9997:
#endif
.endm
@@ -965,11 +967,8 @@ kuser_cmpxchg_fixup:
beq 1b
rsbs r0, r3, #0
/* beware -- each __kuser slot must be 8 instructions max */
-#ifdef CONFIG_SMP
- b __kuser_memory_barrier
-#else
- usr_ret lr
-#endif
+ ALT_SMP(b __kuser_memory_barrier)
+ ALT_UP(usr_ret lr)
#endif
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 7885722bdf4e..8bfa98757cd2 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -129,30 +129,58 @@ ENDPROC(ret_from_fork)
* clobber the ip register. This is OK because the ARM calling convention
* allows it to be clobbered in subroutines and doesn't use it to hold
* parameters.)
+ *
+ * When using dynamic ftrace, we patch out the mcount call by a "mov r0, r0"
+ * for the mcount case, and a "pop {lr}" for the __gnu_mcount_nc case (see
+ * arch/arm/kernel/ftrace.c).
*/
+
+#ifndef CONFIG_OLD_MCOUNT
+#if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 4))
+#error Ftrace requires CONFIG_FRAME_POINTER=y with GCC older than 4.4.0.
+#endif
+#endif
+
#ifdef CONFIG_DYNAMIC_FTRACE
-ENTRY(mcount)
+ENTRY(__gnu_mcount_nc)
+ mov ip, lr
+ ldmia sp!, {lr}
+ mov pc, ip
+ENDPROC(__gnu_mcount_nc)
+
+ENTRY(ftrace_caller)
stmdb sp!, {r0-r3, lr}
mov r0, lr
sub r0, r0, #MCOUNT_INSN_SIZE
+ ldr r1, [sp, #20]
- .globl mcount_call
-mcount_call:
+ .global ftrace_call
+ftrace_call:
bl ftrace_stub
- ldr lr, [fp, #-4] @ restore lr
- ldmia sp!, {r0-r3, pc}
+ ldmia sp!, {r0-r3, ip, lr}
+ mov pc, ip
+ENDPROC(ftrace_caller)
-ENTRY(ftrace_caller)
+#ifdef CONFIG_OLD_MCOUNT
+ENTRY(mcount)
+ stmdb sp!, {lr}
+ ldr lr, [fp, #-4]
+ ldmia sp!, {pc}
+ENDPROC(mcount)
+
+ENTRY(ftrace_caller_old)
stmdb sp!, {r0-r3, lr}
ldr r1, [fp, #-4]
mov r0, lr
sub r0, r0, #MCOUNT_INSN_SIZE
- .globl ftrace_call
-ftrace_call:
+ .globl ftrace_call_old
+ftrace_call_old:
bl ftrace_stub
ldr lr, [fp, #-4] @ restore lr
ldmia sp!, {r0-r3, pc}
+ENDPROC(ftrace_caller_old)
+#endif
#else
@@ -160,7 +188,7 @@ ENTRY(__gnu_mcount_nc)
stmdb sp!, {r0-r3, lr}
ldr r0, =ftrace_trace_function
ldr r2, [r0]
- adr r0, ftrace_stub
+ adr r0, .Lftrace_stub
cmp r0, r2
bne gnu_trace
ldmia sp!, {r0-r3, ip, lr}
@@ -170,11 +198,19 @@ gnu_trace:
ldr r1, [sp, #20] @ lr of instrumented routine
mov r0, lr
sub r0, r0, #MCOUNT_INSN_SIZE
- mov lr, pc
+ adr lr, BSYM(1f)
mov pc, r2
+1:
ldmia sp!, {r0-r3, ip, lr}
mov pc, ip
+ENDPROC(__gnu_mcount_nc)
+#ifdef CONFIG_OLD_MCOUNT
+/*
+ * This is under an ifdef in order to force link-time errors for people trying
+ * to build with !FRAME_POINTER with a GCC which doesn't use the new-style
+ * mcount.
+ */
ENTRY(mcount)
stmdb sp!, {r0-r3, lr}
ldr r0, =ftrace_trace_function
@@ -193,12 +229,15 @@ trace:
mov pc, r2
ldr lr, [fp, #-4] @ restore lr
ldmia sp!, {r0-r3, pc}
+ENDPROC(mcount)
+#endif
#endif /* CONFIG_DYNAMIC_FTRACE */
- .globl ftrace_stub
-ftrace_stub:
+ENTRY(ftrace_stub)
+.Lftrace_stub:
mov pc, lr
+ENDPROC(ftrace_stub)
#endif /* CONFIG_FUNCTION_TRACER */
@@ -295,7 +334,6 @@ ENTRY(vector_swi)
get_thread_info tsk
adr tbl, sys_call_table @ load syscall table pointer
- ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing
#if defined(CONFIG_OABI_COMPAT)
/*
@@ -312,8 +350,20 @@ ENTRY(vector_swi)
eor scno, scno, #__NR_SYSCALL_BASE @ check OS number
#endif
+ ldr r10, [tsk, #TI_FLAGS] @ check for syscall tracing
stmdb sp!, {r4, r5} @ push fifth and sixth args
- tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
+
+#ifdef CONFIG_SECCOMP
+ tst r10, #_TIF_SECCOMP
+ beq 1f
+ mov r0, scno
+ bl __secure_computing
+ add r0, sp, #S_R0 + S_OFF @ pointer to regs
+ ldmia r0, {r0 - r3} @ have to reload r0 - r3
+1:
+#endif
+
+ tst r10, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
bne __sys_trace
cmp scno, #NR_syscalls @ check upper syscall limit
diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index 33c7077174db..11db62806a1a 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -30,6 +30,21 @@
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Alexander Shishkin");
+/*
+ * ETM tracer state
+ */
+struct tracectx {
+ unsigned int etb_bufsz;
+ void __iomem *etb_regs;
+ void __iomem *etm_regs;
+ unsigned long flags;
+ int ncmppairs;
+ int etm_portsz;
+ struct device *dev;
+ struct clk *emu_clk;
+ struct mutex mutex;
+};
+
static struct tracectx tracer;
static inline bool trace_isrunning(struct tracectx *t)
@@ -314,6 +329,7 @@ static const struct file_operations etb_fops = {
.read = etb_read,
.open = etb_open,
.release = etb_release,
+ .llseek = no_llseek,
};
static struct miscdevice etb_miscdev = {
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
index 0298286ad4ad..971ac8c36ea7 100644
--- a/arch/arm/kernel/ftrace.c
+++ b/arch/arm/kernel/ftrace.c
@@ -2,102 +2,194 @@
* Dynamic function tracing support.
*
* Copyright (C) 2008 Abhishek Sagar <sagar.abhishek@gmail.com>
+ * Copyright (C) 2010 Rabin Vincent <rabin@rab.in>
*
* For licencing details, see COPYING.
*
* Defines low-level handling of mcount calls when the kernel
* is compiled with the -pg flag. When using dynamic ftrace, the
- * mcount call-sites get patched lazily with NOP till they are
- * enabled. All code mutation routines here take effect atomically.
+ * mcount call-sites get patched with NOP till they are enabled.
+ * All code mutation routines here are called under stop_machine().
*/
#include <linux/ftrace.h>
+#include <linux/uaccess.h>
#include <asm/cacheflush.h>
#include <asm/ftrace.h>
-#define PC_OFFSET 8
-#define BL_OPCODE 0xeb000000
-#define BL_OFFSET_MASK 0x00ffffff
+#ifdef CONFIG_THUMB2_KERNEL
+#define NOP 0xeb04f85d /* pop.w {lr} */
+#else
+#define NOP 0xe8bd4000 /* pop {lr} */
+#endif
-static unsigned long bl_insn;
-static const unsigned long NOP = 0xe1a00000; /* mov r0, r0 */
+#ifdef CONFIG_OLD_MCOUNT
+#define OLD_MCOUNT_ADDR ((unsigned long) mcount)
+#define OLD_FTRACE_ADDR ((unsigned long) ftrace_caller_old)
-unsigned char *ftrace_nop_replace(void)
+#define OLD_NOP 0xe1a00000 /* mov r0, r0 */
+
+static unsigned long ftrace_nop_replace(struct dyn_ftrace *rec)
{
- return (char *)&NOP;
+ return rec->arch.old_mcount ? OLD_NOP : NOP;
}
+static unsigned long adjust_address(struct dyn_ftrace *rec, unsigned long addr)
+{
+ if (!rec->arch.old_mcount)
+ return addr;
+
+ if (addr == MCOUNT_ADDR)
+ addr = OLD_MCOUNT_ADDR;
+ else if (addr == FTRACE_ADDR)
+ addr = OLD_FTRACE_ADDR;
+
+ return addr;
+}
+#else
+static unsigned long ftrace_nop_replace(struct dyn_ftrace *rec)
+{
+ return NOP;
+}
+
+static unsigned long adjust_address(struct dyn_ftrace *rec, unsigned long addr)
+{
+ return addr;
+}
+#endif
+
/* construct a branch (BL) instruction to addr */
-unsigned char *ftrace_call_replace(unsigned long pc, unsigned long addr)
+#ifdef CONFIG_THUMB2_KERNEL
+static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr)
{
+ unsigned long s, j1, j2, i1, i2, imm10, imm11;
+ unsigned long first, second;
long offset;
- offset = (long)addr - (long)(pc + PC_OFFSET);
+ offset = (long)addr - (long)(pc + 4);
+ if (offset < -16777216 || offset > 16777214) {
+ WARN_ON_ONCE(1);
+ return 0;
+ }
+
+ s = (offset >> 24) & 0x1;
+ i1 = (offset >> 23) & 0x1;
+ i2 = (offset >> 22) & 0x1;
+ imm10 = (offset >> 12) & 0x3ff;
+ imm11 = (offset >> 1) & 0x7ff;
+
+ j1 = (!i1) ^ s;
+ j2 = (!i2) ^ s;
+
+ first = 0xf000 | (s << 10) | imm10;
+ second = 0xd000 | (j1 << 13) | (j2 << 11) | imm11;
+
+ return (second << 16) | first;
+}
+#else
+static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr)
+{
+ long offset;
+
+ offset = (long)addr - (long)(pc + 8);
if (unlikely(offset < -33554432 || offset > 33554428)) {
/* Can't generate branches that far (from ARM ARM). Ftrace
* doesn't generate branches outside of kernel text.
*/
WARN_ON_ONCE(1);
- return NULL;
+ return 0;
}
- offset = (offset >> 2) & BL_OFFSET_MASK;
- bl_insn = BL_OPCODE | offset;
- return (unsigned char *)&bl_insn;
-}
-int ftrace_modify_code(unsigned long pc, unsigned char *old_code,
- unsigned char *new_code)
-{
- unsigned long err = 0, replaced = 0, old, new;
+ offset = (offset >> 2) & 0x00ffffff;
- old = *(unsigned long *)old_code;
- new = *(unsigned long *)new_code;
+ return 0xeb000000 | offset;
+}
+#endif
- __asm__ __volatile__ (
- "1: ldr %1, [%2] \n"
- " cmp %1, %4 \n"
- "2: streq %3, [%2] \n"
- " cmpne %1, %3 \n"
- " movne %0, #2 \n"
- "3:\n"
+static int ftrace_modify_code(unsigned long pc, unsigned long old,
+ unsigned long new)
+{
+ unsigned long replaced;
- ".pushsection .fixup, \"ax\"\n"
- "4: mov %0, #1 \n"
- " b 3b \n"
- ".popsection\n"
+ if (probe_kernel_read(&replaced, (void *)pc, MCOUNT_INSN_SIZE))
+ return -EFAULT;
- ".pushsection __ex_table, \"a\"\n"
- " .long 1b, 4b \n"
- " .long 2b, 4b \n"
- ".popsection\n"
+ if (replaced != old)
+ return -EINVAL;
- : "=r"(err), "=r"(replaced)
- : "r"(pc), "r"(new), "r"(old), "0"(err), "1"(replaced)
- : "memory");
+ if (probe_kernel_write((void *)pc, &new, MCOUNT_INSN_SIZE))
+ return -EPERM;
- if (!err && (replaced == old))
- flush_icache_range(pc, pc + MCOUNT_INSN_SIZE);
+ flush_icache_range(pc, pc + MCOUNT_INSN_SIZE);
- return err;
+ return 0;
}
int ftrace_update_ftrace_func(ftrace_func_t func)
{
- int ret;
unsigned long pc, old;
- unsigned char *new;
+ unsigned long new;
+ int ret;
pc = (unsigned long)&ftrace_call;
memcpy(&old, &ftrace_call, MCOUNT_INSN_SIZE);
new = ftrace_call_replace(pc, (unsigned long)func);
- ret = ftrace_modify_code(pc, (unsigned char *)&old, new);
+
+ ret = ftrace_modify_code(pc, old, new);
+
+#ifdef CONFIG_OLD_MCOUNT
+ if (!ret) {
+ pc = (unsigned long)&ftrace_call_old;
+ memcpy(&old, &ftrace_call_old, MCOUNT_INSN_SIZE);
+ new = ftrace_call_replace(pc, (unsigned long)func);
+
+ ret = ftrace_modify_code(pc, old, new);
+ }
+#endif
+
+ return ret;
+}
+
+int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
+{
+ unsigned long new, old;
+ unsigned long ip = rec->ip;
+
+ old = ftrace_nop_replace(rec);
+ new = ftrace_call_replace(ip, adjust_address(rec, addr));
+
+ return ftrace_modify_code(rec->ip, old, new);
+}
+
+int ftrace_make_nop(struct module *mod,
+ struct dyn_ftrace *rec, unsigned long addr)
+{
+ unsigned long ip = rec->ip;
+ unsigned long old;
+ unsigned long new;
+ int ret;
+
+ old = ftrace_call_replace(ip, adjust_address(rec, addr));
+ new = ftrace_nop_replace(rec);
+ ret = ftrace_modify_code(ip, old, new);
+
+#ifdef CONFIG_OLD_MCOUNT
+ if (ret == -EINVAL && addr == MCOUNT_ADDR) {
+ rec->arch.old_mcount = true;
+
+ old = ftrace_call_replace(ip, adjust_address(rec, addr));
+ new = ftrace_nop_replace(rec);
+ ret = ftrace_modify_code(ip, old, new);
+ }
+#endif
+
return ret;
}
-/* run from ftrace_init with irqs disabled */
int __init ftrace_dyn_arch_init(void *data)
{
- ftrace_mcount_set(data);
+ *(unsigned long *)data = 0;
+
return 0;
}
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
index b9505aa267c0..bbecaac1e013 100644
--- a/arch/arm/kernel/head-common.S
+++ b/arch/arm/kernel/head-common.S
@@ -15,55 +15,6 @@
#define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2)
#define ATAG_CORE_SIZE_EMPTY ((2*4) >> 2)
- .align 2
- .type __switch_data, %object
-__switch_data:
- .long __mmap_switched
- .long __data_loc @ r4
- .long _data @ r5
- .long __bss_start @ r6
- .long _end @ r7
- .long processor_id @ r4
- .long __machine_arch_type @ r5
- .long __atags_pointer @ r6
- .long cr_alignment @ r7
- .long init_thread_union + THREAD_START_SP @ sp
-
-/*
- * The following fragment of code is executed with the MMU on in MMU mode,
- * and uses absolute addresses; this is not position independent.
- *
- * r0 = cp#15 control register
- * r1 = machine ID
- * r2 = atags pointer
- * r9 = processor ID
- */
-__mmap_switched:
- adr r3, __switch_data + 4
-
- ldmia r3!, {r4, r5, r6, r7}
- cmp r4, r5 @ Copy data segment if needed
-1: cmpne r5, r6
- ldrne fp, [r4], #4
- strne fp, [r5], #4
- bne 1b
-
- mov fp, #0 @ Clear BSS (and zero fp)
-1: cmp r6, r7
- strcc fp, [r6],#4
- bcc 1b
-
- ARM( ldmia r3, {r4, r5, r6, r7, sp})
- THUMB( ldmia r3, {r4, r5, r6, r7} )
- THUMB( ldr sp, [r3, #16] )
- str r9, [r4] @ Save processor ID
- str r1, [r5] @ Save machine type
- str r2, [r6] @ Save atags pointer
- bic r4, r0, #CR_A @ Clear 'A' bit
- stmia r7, {r0, r4} @ Save control register values
- b start_kernel
-ENDPROC(__mmap_switched)
-
/*
* Exception handling. Something went wrong and we can't proceed. We
* ought to tell the user, but since we don't have any guarantee that
@@ -73,21 +24,7 @@ ENDPROC(__mmap_switched)
* and hope for the best (useful if bootloader fails to pass a proper
* machine ID for example).
*/
-__error_p:
-#ifdef CONFIG_DEBUG_LL
- adr r0, str_p1
- bl printascii
- mov r0, r9
- bl printhex8
- adr r0, str_p2
- bl printascii
- b __error
-str_p1: .asciz "\nError: unrecognized/unsupported processor variant (0x"
-str_p2: .asciz ").\n"
- .align
-#endif
-ENDPROC(__error_p)
-
+ __HEAD
__error_a:
#ifdef CONFIG_DEBUG_LL
mov r4, r1 @ preserve machine ID
@@ -97,7 +34,7 @@ __error_a:
bl printhex8
adr r0, str_a2
bl printascii
- adr r3, 4f
+ adr r3, __lookup_machine_type_data
ldmia r3, {r4, r5, r6} @ get machine desc list
sub r4, r3, r4 @ get offset between virt&phys
add r5, r5, r4 @ convert virt addresses to
@@ -125,78 +62,6 @@ str_a3: .asciz "\nPlease check your kernel config and/or bootloader.\n"
.align
#endif
-__error:
-#ifdef CONFIG_ARCH_RPC
-/*
- * Turn the screen red on a error - RiscPC only.
- */
- mov r0, #0x02000000
- mov r3, #0x11
- orr r3, r3, r3, lsl #8
- orr r3, r3, r3, lsl #16
- str r3, [r0], #4
- str r3, [r0], #4
- str r3, [r0], #4
- str r3, [r0], #4
-#endif
-1: mov r0, r0
- b 1b
-ENDPROC(__error)
-
-
-/*
- * Read processor ID register (CP#15, CR0), and look up in the linker-built
- * supported processor list. Note that we can't use the absolute addresses
- * for the __proc_info lists since we aren't running with the MMU on
- * (and therefore, we are not in the correct address space). We have to
- * calculate the offset.
- *
- * r9 = cpuid
- * Returns:
- * r3, r4, r6 corrupted
- * r5 = proc_info pointer in physical address space
- * r9 = cpuid (preserved)
- */
-__lookup_processor_type:
- adr r3, 3f
- ldmia r3, {r5 - r7}
- add r3, r3, #8
- sub r3, r3, r7 @ get offset between virt&phys
- add r5, r5, r3 @ convert virt addresses to
- add r6, r6, r3 @ physical address space
-1: ldmia r5, {r3, r4} @ value, mask
- and r4, r4, r9 @ mask wanted bits
- teq r3, r4
- beq 2f
- add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list)
- cmp r5, r6
- blo 1b
- mov r5, #0 @ unknown processor
-2: mov pc, lr
-ENDPROC(__lookup_processor_type)
-
-/*
- * This provides a C-API version of the above function.
- */
-ENTRY(lookup_processor_type)
- stmfd sp!, {r4 - r7, r9, lr}
- mov r9, r0
- bl __lookup_processor_type
- mov r0, r5
- ldmfd sp!, {r4 - r7, r9, pc}
-ENDPROC(lookup_processor_type)
-
-/*
- * Look in <asm/procinfo.h> and arch/arm/kernel/arch.[ch] for
- * more information about the __proc_info and __arch_info structures.
- */
- .align 2
-3: .long __proc_info_begin
- .long __proc_info_end
-4: .long .
- .long __arch_info_begin
- .long __arch_info_end
-
/*
* Lookup machine architecture in the linker-build list of architectures.
* Note that we can't use the absolute addresses for the __arch_info
@@ -209,7 +74,7 @@ ENDPROC(lookup_processor_type)
* r5 = mach_info pointer in physical address space
*/
__lookup_machine_type:
- adr r3, 4b
+ adr r3, __lookup_machine_type_data
ldmia r3, {r4, r5, r6}
sub r3, r3, r4 @ get offset between virt&phys
add r5, r5, r3 @ convert virt addresses to
@@ -225,15 +90,16 @@ __lookup_machine_type:
ENDPROC(__lookup_machine_type)
/*
- * This provides a C-API version of the above function.
+ * Look in arch/arm/kernel/arch.[ch] for information about the
+ * __arch_info structures.
*/
-ENTRY(lookup_machine_type)
- stmfd sp!, {r4 - r6, lr}
- mov r1, r0
- bl __lookup_machine_type
- mov r0, r5
- ldmfd sp!, {r4 - r6, pc}
-ENDPROC(lookup_machine_type)
+ .align 2
+ .type __lookup_machine_type_data, %object
+__lookup_machine_type_data:
+ .long .
+ .long __arch_info_begin
+ .long __arch_info_end
+ .size __lookup_machine_type_data, . - __lookup_machine_type_data
/* Determine validity of the r2 atags pointer. The heuristic requires
* that the pointer be aligned, in the first 16k of physical RAM and
@@ -265,3 +131,150 @@ __vet_atags:
1: mov r2, #0
mov pc, lr
ENDPROC(__vet_atags)
+
+/*
+ * The following fragment of code is executed with the MMU on in MMU mode,
+ * and uses absolute addresses; this is not position independent.
+ *
+ * r0 = cp#15 control register
+ * r1 = machine ID
+ * r2 = atags pointer
+ * r9 = processor ID
+ */
+ __INIT
+__mmap_switched:
+ adr r3, __mmap_switched_data
+
+ ldmia r3!, {r4, r5, r6, r7}
+ cmp r4, r5 @ Copy data segment if needed
+1: cmpne r5, r6
+ ldrne fp, [r4], #4
+ strne fp, [r5], #4
+ bne 1b
+
+ mov fp, #0 @ Clear BSS (and zero fp)
+1: cmp r6, r7
+ strcc fp, [r6],#4
+ bcc 1b
+
+ ARM( ldmia r3, {r4, r5, r6, r7, sp})
+ THUMB( ldmia r3, {r4, r5, r6, r7} )
+ THUMB( ldr sp, [r3, #16] )
+ str r9, [r4] @ Save processor ID
+ str r1, [r5] @ Save machine type
+ str r2, [r6] @ Save atags pointer
+ bic r4, r0, #CR_A @ Clear 'A' bit
+ stmia r7, {r0, r4} @ Save control register values
+ b start_kernel
+ENDPROC(__mmap_switched)
+
+ .align 2
+ .type __mmap_switched_data, %object
+__mmap_switched_data:
+ .long __data_loc @ r4
+ .long _sdata @ r5
+ .long __bss_start @ r6
+ .long _end @ r7
+ .long processor_id @ r4
+ .long __machine_arch_type @ r5
+ .long __atags_pointer @ r6
+ .long cr_alignment @ r7
+ .long init_thread_union + THREAD_START_SP @ sp
+ .size __mmap_switched_data, . - __mmap_switched_data
+
+/*
+ * This provides a C-API version of __lookup_machine_type
+ */
+ENTRY(lookup_machine_type)
+ stmfd sp!, {r4 - r6, lr}
+ mov r1, r0
+ bl __lookup_machine_type
+ mov r0, r5
+ ldmfd sp!, {r4 - r6, pc}
+ENDPROC(lookup_machine_type)
+
+/*
+ * This provides a C-API version of __lookup_processor_type
+ */
+ENTRY(lookup_processor_type)
+ stmfd sp!, {r4 - r6, r9, lr}
+ mov r9, r0
+ bl __lookup_processor_type
+ mov r0, r5
+ ldmfd sp!, {r4 - r6, r9, pc}
+ENDPROC(lookup_processor_type)
+
+/*
+ * Read processor ID register (CP#15, CR0), and look up in the linker-built
+ * supported processor list. Note that we can't use the absolute addresses
+ * for the __proc_info lists since we aren't running with the MMU on
+ * (and therefore, we are not in the correct address space). We have to
+ * calculate the offset.
+ *
+ * r9 = cpuid
+ * Returns:
+ * r3, r4, r6 corrupted
+ * r5 = proc_info pointer in physical address space
+ * r9 = cpuid (preserved)
+ */
+ __CPUINIT
+__lookup_processor_type:
+ adr r3, __lookup_processor_type_data
+ ldmia r3, {r4 - r6}
+ sub r3, r3, r4 @ get offset between virt&phys
+ add r5, r5, r3 @ convert virt addresses to
+ add r6, r6, r3 @ physical address space
+1: ldmia r5, {r3, r4} @ value, mask
+ and r4, r4, r9 @ mask wanted bits
+ teq r3, r4
+ beq 2f
+ add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list)
+ cmp r5, r6
+ blo 1b
+ mov r5, #0 @ unknown processor
+2: mov pc, lr
+ENDPROC(__lookup_processor_type)
+
+/*
+ * Look in <asm/procinfo.h> for information about the __proc_info structure.
+ */
+ .align 2
+ .type __lookup_processor_type_data, %object
+__lookup_processor_type_data:
+ .long .
+ .long __proc_info_begin
+ .long __proc_info_end
+ .size __lookup_processor_type_data, . - __lookup_processor_type_data
+
+__error_p:
+#ifdef CONFIG_DEBUG_LL
+ adr r0, str_p1
+ bl printascii
+ mov r0, r9
+ bl printhex8
+ adr r0, str_p2
+ bl printascii
+ b __error
+str_p1: .asciz "\nError: unrecognized/unsupported processor variant (0x"
+str_p2: .asciz ").\n"
+ .align
+#endif
+ENDPROC(__error_p)
+
+__error:
+#ifdef CONFIG_ARCH_RPC
+/*
+ * Turn the screen red on a error - RiscPC only.
+ */
+ mov r0, #0x02000000
+ mov r3, #0x11
+ orr r3, r3, r3, lsl #8
+ orr r3, r3, r3, lsl #16
+ str r3, [r0], #4
+ str r3, [r0], #4
+ str r3, [r0], #4
+ str r3, [r0], #4
+#endif
+1: mov r0, r0
+ b 1b
+ENDPROC(__error)
diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S
index 573b803dc6bf..814ce1a73270 100644
--- a/arch/arm/kernel/head-nommu.S
+++ b/arch/arm/kernel/head-nommu.S
@@ -48,8 +48,6 @@ ENTRY(stext)
movs r8, r5 @ invalid machine (r5=0)?
beq __error_a @ yes, error 'a'
- ldr r13, __switch_data @ address to jump to after
- @ the initialization is done
adr lr, BSYM(__after_proc_init) @ return (PIC) address
ARM( add pc, r10, #PROCINFO_INITFUNC )
THUMB( add r12, r10, #PROCINFO_INITFUNC )
@@ -87,8 +85,7 @@ __after_proc_init:
mcr p15, 0, r0, c1, c0, 0 @ write control reg
#endif /* CONFIG_CPU_CP15 */
- mov r3, r13
- mov pc, r3 @ clear the BSS and jump
+ b __mmap_switched @ clear the BSS and jump
@ to start_kernel
ENDPROC(__after_proc_init)
.ltorg
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index eb62bf947212..dd6b369ac69c 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -22,6 +22,10 @@
#include <asm/thread_info.h>
#include <asm/system.h>
+#ifdef CONFIG_DEBUG_LL
+#include <mach/debug-macro.S>
+#endif
+
#if (PHYS_OFFSET & 0x001fffff)
#error "PHYS_OFFSET must be at an even 2MiB boundary!"
#endif
@@ -86,6 +90,9 @@ ENTRY(stext)
movs r8, r5 @ invalid machine (r5=0)?
beq __error_a @ yes, error 'a'
bl __vet_atags
+#ifdef CONFIG_SMP_ON_UP
+ bl __fixup_smp
+#endif
bl __create_page_tables
/*
@@ -95,113 +102,15 @@ ENTRY(stext)
* above. On return, the CPU will be ready for the MMU to be
* turned on, and r0 will hold the CPU control register value.
*/
- ldr r13, __switch_data @ address to jump to after
+ ldr r13, =__mmap_switched @ address to jump to after
@ mmu has been enabled
- adr lr, BSYM(__enable_mmu) @ return (PIC) address
+ adr lr, BSYM(1f) @ return (PIC) address
ARM( add pc, r10, #PROCINFO_INITFUNC )
THUMB( add r12, r10, #PROCINFO_INITFUNC )
THUMB( mov pc, r12 )
+1: b __enable_mmu
ENDPROC(stext)
-
-#if defined(CONFIG_SMP)
-ENTRY(secondary_startup)
- /*
- * Common entry point for secondary CPUs.
- *
- * Ensure that we're in SVC mode, and IRQs are disabled. Lookup
- * the processor type - there is no need to check the machine type
- * as it has already been validated by the primary processor.
- */
- setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9
- mrc p15, 0, r9, c0, c0 @ get processor id
- bl __lookup_processor_type
- movs r10, r5 @ invalid processor?
- moveq r0, #'p' @ yes, error 'p'
- beq __error
-
- /*
- * Use the page tables supplied from __cpu_up.
- */
- adr r4, __secondary_data
- ldmia r4, {r5, r7, r12} @ address to jump to after
- sub r4, r4, r5 @ mmu has been enabled
- ldr r4, [r7, r4] @ get secondary_data.pgdir
- adr lr, BSYM(__enable_mmu) @ return address
- mov r13, r12 @ __secondary_switched address
- ARM( add pc, r10, #PROCINFO_INITFUNC ) @ initialise processor
- @ (return control reg)
- THUMB( add r12, r10, #PROCINFO_INITFUNC )
- THUMB( mov pc, r12 )
-ENDPROC(secondary_startup)
-
- /*
- * r6 = &secondary_data
- */
-ENTRY(__secondary_switched)
- ldr sp, [r7, #4] @ get secondary_data.stack
- mov fp, #0
- b secondary_start_kernel
-ENDPROC(__secondary_switched)
-
- .type __secondary_data, %object
-__secondary_data:
- .long .
- .long secondary_data
- .long __secondary_switched
-#endif /* defined(CONFIG_SMP) */
-
-
-
-/*
- * Setup common bits before finally enabling the MMU. Essentially
- * this is just loading the page table pointer and domain access
- * registers.
- */
-__enable_mmu:
-#ifdef CONFIG_ALIGNMENT_TRAP
- orr r0, r0, #CR_A
-#else
- bic r0, r0, #CR_A
-#endif
-#ifdef CONFIG_CPU_DCACHE_DISABLE
- bic r0, r0, #CR_C
-#endif
-#ifdef CONFIG_CPU_BPREDICT_DISABLE
- bic r0, r0, #CR_Z
-#endif
-#ifdef CONFIG_CPU_ICACHE_DISABLE
- bic r0, r0, #CR_I
-#endif
- mov r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
- domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
- domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
- domain_val(DOMAIN_IO, DOMAIN_CLIENT))
- mcr p15, 0, r5, c3, c0, 0 @ load domain access register
- mcr p15, 0, r4, c2, c0, 0 @ load page table pointer
- b __turn_mmu_on
-ENDPROC(__enable_mmu)
-
-/*
- * Enable the MMU. This completely changes the structure of the visible
- * memory space. You will not be able to trace execution through this.
- * If you have an enquiry about this, *please* check the linux-arm-kernel
- * mailing list archives BEFORE sending another post to the list.
- *
- * r0 = cp#15 control register
- * r13 = *virtual* address to jump to upon completion
- *
- * other registers depend on the function called upon completion
- */
- .align 5
-__turn_mmu_on:
- mov r0, r0
- mcr p15, 0, r0, c1, c0, 0 @ write control reg
- mrc p15, 0, r3, c0, c0, 0 @ read id reg
- mov r3, r3
- mov r3, r13
- mov pc, r3
-ENDPROC(__turn_mmu_on)
-
+ .ltorg
/*
* Setup the initial page tables. We only setup the barest
@@ -213,7 +122,7 @@ ENDPROC(__turn_mmu_on)
* r10 = procinfo
*
* Returns:
- * r0, r3, r6, r7 corrupted
+ * r0, r3, r5-r7 corrupted
* r4 = physical page table address
*/
__create_page_tables:
@@ -235,20 +144,30 @@ __create_page_tables:
ldr r7, [r10, #PROCINFO_MM_MMUFLAGS] @ mm_mmuflags
/*
- * Create identity mapping for first MB of kernel to
- * cater for the MMU enable. This identity mapping
- * will be removed by paging_init(). We use our current program
- * counter to determine corresponding section base address.
+ * Create identity mapping to cater for __enable_mmu.
+ * This identity mapping will be removed by paging_init().
*/
- mov r6, pc
- mov r6, r6, lsr #20 @ start of kernel section
- orr r3, r7, r6, lsl #20 @ flags + kernel base
- str r3, [r4, r6, lsl #2] @ identity mapping
+ adr r0, __enable_mmu_loc
+ ldmia r0, {r3, r5, r6}
+ sub r0, r0, r3 @ virt->phys offset
+ add r5, r5, r0 @ phys __enable_mmu
+ add r6, r6, r0 @ phys __enable_mmu_end
+ mov r5, r5, lsr #20
+ mov r6, r6, lsr #20
+
+1: orr r3, r7, r5, lsl #20 @ flags + kernel base
+ str r3, [r4, r5, lsl #2] @ identity mapping
+ teq r5, r6
+ addne r5, r5, #1 @ next section
+ bne 1b
/*
* Now setup the pagetables for our kernel direct
* mapped region.
*/
+ mov r3, pc
+ mov r3, r3, lsr #20
+ orr r3, r7, r3, lsl #20
add r0, r4, #(KERNEL_START & 0xff000000) >> 18
str r3, [r0, #(KERNEL_START & 0x00f00000) >> 18]!
ldr r6, =(KERNEL_END - 1)
@@ -289,24 +208,35 @@ __create_page_tables:
str r6, [r0]
#ifdef CONFIG_DEBUG_LL
- ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags
+#ifndef CONFIG_DEBUG_ICEDCC
/*
* Map in IO space for serial debugging.
* This allows debug messages to be output
* via a serial console before paging_init.
*/
- ldr r3, [r8, #MACHINFO_PGOFFIO]
+ addruart r7, r3
+
+ mov r3, r3, lsr #20
+ mov r3, r3, lsl #2
+
add r0, r4, r3
rsb r3, r3, #0x4000 @ PTRS_PER_PGD*sizeof(long)
cmp r3, #0x0800 @ limit to 512MB
movhi r3, #0x0800
add r6, r0, r3
- ldr r3, [r8, #MACHINFO_PHYSIO]
- orr r3, r3, r7
+ mov r3, r7, lsr #20
+ ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags
+ orr r3, r7, r3, lsl #20
1: str r3, [r0], #4
add r3, r3, #1 << 20
teq r0, r6
bne 1b
+
+#else /* CONFIG_DEBUG_ICEDCC */
+ /* we don't need any serial debugging mappings for ICEDCC */
+ ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags
+#endif /* !CONFIG_DEBUG_ICEDCC */
+
#if defined(CONFIG_ARCH_NETWINDER) || defined(CONFIG_ARCH_CATS)
/*
* If we're using the NetWinder or CATS, we also need to map
@@ -332,5 +262,168 @@ __create_page_tables:
mov pc, lr
ENDPROC(__create_page_tables)
.ltorg
+__enable_mmu_loc:
+ .long .
+ .long __enable_mmu
+ .long __enable_mmu_end
+
+#if defined(CONFIG_SMP)
+ __CPUINIT
+ENTRY(secondary_startup)
+ /*
+ * Common entry point for secondary CPUs.
+ *
+ * Ensure that we're in SVC mode, and IRQs are disabled. Lookup
+ * the processor type - there is no need to check the machine type
+ * as it has already been validated by the primary processor.
+ */
+ setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9
+ mrc p15, 0, r9, c0, c0 @ get processor id
+ bl __lookup_processor_type
+ movs r10, r5 @ invalid processor?
+ moveq r0, #'p' @ yes, error 'p'
+ beq __error_p
+
+ /*
+ * Use the page tables supplied from __cpu_up.
+ */
+ adr r4, __secondary_data
+ ldmia r4, {r5, r7, r12} @ address to jump to after
+ sub r4, r4, r5 @ mmu has been enabled
+ ldr r4, [r7, r4] @ get secondary_data.pgdir
+ adr lr, BSYM(__enable_mmu) @ return address
+ mov r13, r12 @ __secondary_switched address
+ ARM( add pc, r10, #PROCINFO_INITFUNC ) @ initialise processor
+ @ (return control reg)
+ THUMB( add r12, r10, #PROCINFO_INITFUNC )
+ THUMB( mov pc, r12 )
+ENDPROC(secondary_startup)
+
+ /*
+ * r6 = &secondary_data
+ */
+ENTRY(__secondary_switched)
+ ldr sp, [r7, #4] @ get secondary_data.stack
+ mov fp, #0
+ b secondary_start_kernel
+ENDPROC(__secondary_switched)
+
+ .type __secondary_data, %object
+__secondary_data:
+ .long .
+ .long secondary_data
+ .long __secondary_switched
+#endif /* defined(CONFIG_SMP) */
+
+
+
+/*
+ * Setup common bits before finally enabling the MMU. Essentially
+ * this is just loading the page table pointer and domain access
+ * registers.
+ *
+ * r0 = cp#15 control register
+ * r1 = machine ID
+ * r2 = atags pointer
+ * r4 = page table pointer
+ * r9 = processor ID
+ * r13 = *virtual* address to jump to upon completion
+ */
+__enable_mmu:
+#ifdef CONFIG_ALIGNMENT_TRAP
+ orr r0, r0, #CR_A
+#else
+ bic r0, r0, #CR_A
+#endif
+#ifdef CONFIG_CPU_DCACHE_DISABLE
+ bic r0, r0, #CR_C
+#endif
+#ifdef CONFIG_CPU_BPREDICT_DISABLE
+ bic r0, r0, #CR_Z
+#endif
+#ifdef CONFIG_CPU_ICACHE_DISABLE
+ bic r0, r0, #CR_I
+#endif
+ mov r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
+ domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
+ domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
+ domain_val(DOMAIN_IO, DOMAIN_CLIENT))
+ mcr p15, 0, r5, c3, c0, 0 @ load domain access register
+ mcr p15, 0, r4, c2, c0, 0 @ load page table pointer
+ b __turn_mmu_on
+ENDPROC(__enable_mmu)
+
+/*
+ * Enable the MMU. This completely changes the structure of the visible
+ * memory space. You will not be able to trace execution through this.
+ * If you have an enquiry about this, *please* check the linux-arm-kernel
+ * mailing list archives BEFORE sending another post to the list.
+ *
+ * r0 = cp#15 control register
+ * r1 = machine ID
+ * r2 = atags pointer
+ * r9 = processor ID
+ * r13 = *virtual* address to jump to upon completion
+ *
+ * other registers depend on the function called upon completion
+ */
+ .align 5
+__turn_mmu_on:
+ mov r0, r0
+ mcr p15, 0, r0, c1, c0, 0 @ write control reg
+ mrc p15, 0, r3, c0, c0, 0 @ read id reg
+ mov r3, r3
+ mov r3, r13
+ mov pc, r3
+__enable_mmu_end:
+ENDPROC(__turn_mmu_on)
+
+
+#ifdef CONFIG_SMP_ON_UP
+__fixup_smp:
+ mov r7, #0x00070000
+ orr r6, r7, #0xff000000 @ mask 0xff070000
+ orr r7, r7, #0x41000000 @ val 0x41070000
+ and r0, r9, r6
+ teq r0, r7 @ ARM CPU and ARMv6/v7?
+ bne __fixup_smp_on_up @ no, assume UP
+
+ orr r6, r6, #0x0000ff00
+ orr r6, r6, #0x000000f0 @ mask 0xff07fff0
+ orr r7, r7, #0x0000b000
+ orr r7, r7, #0x00000020 @ val 0x4107b020
+ and r0, r9, r6
+ teq r0, r7 @ ARM 11MPCore?
+ moveq pc, lr @ yes, assume SMP
+
+ mrc p15, 0, r0, c0, c0, 5 @ read MPIDR
+ tst r0, #1 << 31
+ movne pc, lr @ bit 31 => SMP
+
+__fixup_smp_on_up:
+ adr r0, 1f
+ ldmia r0, {r3, r6, r7}
+ sub r3, r0, r3
+ add r6, r6, r3
+ add r7, r7, r3
+2: cmp r6, r7
+ ldmia r6!, {r0, r4}
+ strlo r4, [r0, r3]
+ blo 2b
+ mov pc, lr
+ENDPROC(__fixup_smp)
+
+1: .word .
+ .word __smpalt_begin
+ .word __smpalt_end
+
+ .pushsection .data
+ .globl smp_on_up
+smp_on_up:
+ ALT_SMP(.long 1)
+ ALT_UP(.long 0)
+ .popsection
+
+#endif
#include "head-common.S"
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
new file mode 100644
index 000000000000..54593b0c241b
--- /dev/null
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -0,0 +1,849 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) 2009, 2010 ARM Limited
+ *
+ * Author: Will Deacon <will.deacon@arm.com>
+ */
+
+/*
+ * HW_breakpoint: a unified kernel/user-space hardware breakpoint facility,
+ * using the CPU's debug registers.
+ */
+#define pr_fmt(fmt) "hw-breakpoint: " fmt
+
+#include <linux/errno.h>
+#include <linux/perf_event.h>
+#include <linux/hw_breakpoint.h>
+#include <linux/smp.h>
+
+#include <asm/cacheflush.h>
+#include <asm/cputype.h>
+#include <asm/current.h>
+#include <asm/hw_breakpoint.h>
+#include <asm/kdebug.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+
+/* Breakpoint currently in use for each BRP. */
+static DEFINE_PER_CPU(struct perf_event *, bp_on_reg[ARM_MAX_BRP]);
+
+/* Watchpoint currently in use for each WRP. */
+static DEFINE_PER_CPU(struct perf_event *, wp_on_reg[ARM_MAX_WRP]);
+
+/* Number of BRP/WRP registers on this CPU. */
+static int core_num_brps;
+static int core_num_wrps;
+
+/* Debug architecture version. */
+static u8 debug_arch;
+
+/* Maximum supported watchpoint length. */
+static u8 max_watchpoint_len;
+
+/* Determine number of BRP registers available. */
+static int get_num_brps(void)
+{
+ u32 didr;
+ ARM_DBG_READ(c0, 0, didr);
+ return ((didr >> 24) & 0xf) + 1;
+}
+
+/* Determine number of WRP registers available. */
+static int get_num_wrps(void)
+{
+ /*
+ * FIXME: When a watchpoint fires, the only way to work out which
+ * watchpoint it was is by disassembling the faulting instruction
+ * and working out the address of the memory access.
+ *
+ * Furthermore, we can only do this if the watchpoint was precise
+ * since imprecise watchpoints prevent us from calculating register
+ * based addresses.
+ *
+ * For the time being, we only report 1 watchpoint register so we
+ * always know which watchpoint fired. In the future we can either
+ * add a disassembler and address generation emulator, or we can
+ * insert a check to see if the DFAR is set on watchpoint exception
+ * entry [the ARM ARM states that the DFAR is UNKNOWN, but
+ * experience shows that it is set on some implementations].
+ */
+
+#if 0
+ u32 didr, wrps;
+ ARM_DBG_READ(c0, 0, didr);
+ return ((didr >> 28) & 0xf) + 1;
+#endif
+
+ return 1;
+}
+
+int hw_breakpoint_slots(int type)
+{
+ /*
+ * We can be called early, so don't rely on
+ * our static variables being initialised.
+ */
+ switch (type) {
+ case TYPE_INST:
+ return get_num_brps();
+ case TYPE_DATA:
+ return get_num_wrps();
+ default:
+ pr_warning("unknown slot type: %d\n", type);
+ return 0;
+ }
+}
+
+/* Determine debug architecture. */
+static u8 get_debug_arch(void)
+{
+ u32 didr;
+
+ /* Do we implement the extended CPUID interface? */
+ if (((read_cpuid_id() >> 16) & 0xf) != 0xf) {
+ pr_warning("CPUID feature registers not supported. "
+ "Assuming v6 debug is present.\n");
+ return ARM_DEBUG_ARCH_V6;
+ }
+
+ ARM_DBG_READ(c0, 0, didr);
+ return (didr >> 16) & 0xf;
+}
+
+/* Does this core support mismatch breakpoints? */
+static int core_has_mismatch_bps(void)
+{
+ return debug_arch >= ARM_DEBUG_ARCH_V7_ECP14 && core_num_brps > 1;
+}
+
+u8 arch_get_debug_arch(void)
+{
+ return debug_arch;
+}
+
+#define READ_WB_REG_CASE(OP2, M, VAL) \
+ case ((OP2 << 4) + M): \
+ ARM_DBG_READ(c ## M, OP2, VAL); \
+ break
+
+#define WRITE_WB_REG_CASE(OP2, M, VAL) \
+ case ((OP2 << 4) + M): \
+ ARM_DBG_WRITE(c ## M, OP2, VAL);\
+ break
+
+#define GEN_READ_WB_REG_CASES(OP2, VAL) \
+ READ_WB_REG_CASE(OP2, 0, VAL); \
+ READ_WB_REG_CASE(OP2, 1, VAL); \
+ READ_WB_REG_CASE(OP2, 2, VAL); \
+ READ_WB_REG_CASE(OP2, 3, VAL); \
+ READ_WB_REG_CASE(OP2, 4, VAL); \
+ READ_WB_REG_CASE(OP2, 5, VAL); \
+ READ_WB_REG_CASE(OP2, 6, VAL); \
+ READ_WB_REG_CASE(OP2, 7, VAL); \
+ READ_WB_REG_CASE(OP2, 8, VAL); \
+ READ_WB_REG_CASE(OP2, 9, VAL); \
+ READ_WB_REG_CASE(OP2, 10, VAL); \
+ READ_WB_REG_CASE(OP2, 11, VAL); \
+ READ_WB_REG_CASE(OP2, 12, VAL); \
+ READ_WB_REG_CASE(OP2, 13, VAL); \
+ READ_WB_REG_CASE(OP2, 14, VAL); \
+ READ_WB_REG_CASE(OP2, 15, VAL)
+
+#define GEN_WRITE_WB_REG_CASES(OP2, VAL) \
+ WRITE_WB_REG_CASE(OP2, 0, VAL); \
+ WRITE_WB_REG_CASE(OP2, 1, VAL); \
+ WRITE_WB_REG_CASE(OP2, 2, VAL); \
+ WRITE_WB_REG_CASE(OP2, 3, VAL); \
+ WRITE_WB_REG_CASE(OP2, 4, VAL); \
+ WRITE_WB_REG_CASE(OP2, 5, VAL); \
+ WRITE_WB_REG_CASE(OP2, 6, VAL); \
+ WRITE_WB_REG_CASE(OP2, 7, VAL); \
+ WRITE_WB_REG_CASE(OP2, 8, VAL); \
+ WRITE_WB_REG_CASE(OP2, 9, VAL); \
+ WRITE_WB_REG_CASE(OP2, 10, VAL); \
+ WRITE_WB_REG_CASE(OP2, 11, VAL); \
+ WRITE_WB_REG_CASE(OP2, 12, VAL); \
+ WRITE_WB_REG_CASE(OP2, 13, VAL); \
+ WRITE_WB_REG_CASE(OP2, 14, VAL); \
+ WRITE_WB_REG_CASE(OP2, 15, VAL)
+
+static u32 read_wb_reg(int n)
+{
+ u32 val = 0;
+
+ switch (n) {
+ GEN_READ_WB_REG_CASES(ARM_OP2_BVR, val);
+ GEN_READ_WB_REG_CASES(ARM_OP2_BCR, val);
+ GEN_READ_WB_REG_CASES(ARM_OP2_WVR, val);
+ GEN_READ_WB_REG_CASES(ARM_OP2_WCR, val);
+ default:
+ pr_warning("attempt to read from unknown breakpoint "
+ "register %d\n", n);
+ }
+
+ return val;
+}
+
+static void write_wb_reg(int n, u32 val)
+{
+ switch (n) {
+ GEN_WRITE_WB_REG_CASES(ARM_OP2_BVR, val);
+ GEN_WRITE_WB_REG_CASES(ARM_OP2_BCR, val);
+ GEN_WRITE_WB_REG_CASES(ARM_OP2_WVR, val);
+ GEN_WRITE_WB_REG_CASES(ARM_OP2_WCR, val);
+ default:
+ pr_warning("attempt to write to unknown breakpoint "
+ "register %d\n", n);
+ }
+ isb();
+}
+
+/*
+ * In order to access the breakpoint/watchpoint control registers,
+ * we must be running in debug monitor mode. Unfortunately, we can
+ * be put into halting debug mode at any time by an external debugger
+ * but there is nothing we can do to prevent that.
+ */
+static int enable_monitor_mode(void)
+{
+ u32 dscr;
+ int ret = 0;
+
+ ARM_DBG_READ(c1, 0, dscr);
+
+ /* Ensure that halting mode is disabled. */
+ if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN, "halting debug mode enabled."
+ "Unable to access hardware resources.")) {
+ ret = -EPERM;
+ goto out;
+ }
+
+ /* Write to the corresponding DSCR. */
+ switch (debug_arch) {
+ case ARM_DEBUG_ARCH_V6:
+ case ARM_DEBUG_ARCH_V6_1:
+ ARM_DBG_WRITE(c1, 0, (dscr | ARM_DSCR_MDBGEN));
+ break;
+ case ARM_DEBUG_ARCH_V7_ECP14:
+ ARM_DBG_WRITE(c2, 2, (dscr | ARM_DSCR_MDBGEN));
+ break;
+ default:
+ ret = -ENODEV;
+ goto out;
+ }
+
+ /* Check that the write made it through. */
+ ARM_DBG_READ(c1, 0, dscr);
+ if (WARN_ONCE(!(dscr & ARM_DSCR_MDBGEN),
+ "failed to enable monitor mode.")) {
+ ret = -EPERM;
+ }
+
+out:
+ return ret;
+}
+
+/*
+ * Check if 8-bit byte-address select is available.
+ * This clobbers WRP 0.
+ */
+static u8 get_max_wp_len(void)
+{
+ u32 ctrl_reg;
+ struct arch_hw_breakpoint_ctrl ctrl;
+ u8 size = 4;
+
+ if (debug_arch < ARM_DEBUG_ARCH_V7_ECP14)
+ goto out;
+
+ if (enable_monitor_mode())
+ goto out;
+
+ memset(&ctrl, 0, sizeof(ctrl));
+ ctrl.len = ARM_BREAKPOINT_LEN_8;
+ ctrl_reg = encode_ctrl_reg(ctrl);
+
+ write_wb_reg(ARM_BASE_WVR, 0);
+ write_wb_reg(ARM_BASE_WCR, ctrl_reg);
+ if ((read_wb_reg(ARM_BASE_WCR) & ctrl_reg) == ctrl_reg)
+ size = 8;
+
+out:
+ return size;
+}
+
+u8 arch_get_max_wp_len(void)
+{
+ return max_watchpoint_len;
+}
+
+/*
+ * Handler for reactivating a suspended watchpoint when the single
+ * step `mismatch' breakpoint is triggered.
+ */
+static void wp_single_step_handler(struct perf_event *bp, int unused,
+ struct perf_sample_data *data,
+ struct pt_regs *regs)
+{
+ perf_event_enable(counter_arch_bp(bp)->suspended_wp);
+ unregister_hw_breakpoint(bp);
+}
+
+static int bp_is_single_step(struct perf_event *bp)
+{
+ return bp->overflow_handler == wp_single_step_handler;
+}
+
+/*
+ * Install a perf counter breakpoint.
+ */
+int arch_install_hw_breakpoint(struct perf_event *bp)
+{
+ struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+ struct perf_event **slot, **slots;
+ int i, max_slots, ctrl_base, val_base, ret = 0;
+
+ /* Ensure that we are in monitor mode and halting mode is disabled. */
+ ret = enable_monitor_mode();
+ if (ret)
+ goto out;
+
+ if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) {
+ /* Breakpoint */
+ ctrl_base = ARM_BASE_BCR;
+ val_base = ARM_BASE_BVR;
+ slots = __get_cpu_var(bp_on_reg);
+ max_slots = core_num_brps - 1;
+
+ if (bp_is_single_step(bp)) {
+ info->ctrl.mismatch = 1;
+ i = max_slots;
+ slots[i] = bp;
+ goto setup;
+ }
+ } else {
+ /* Watchpoint */
+ ctrl_base = ARM_BASE_WCR;
+ val_base = ARM_BASE_WVR;
+ slots = __get_cpu_var(wp_on_reg);
+ max_slots = core_num_wrps;
+ }
+
+ for (i = 0; i < max_slots; ++i) {
+ slot = &slots[i];
+
+ if (!*slot) {
+ *slot = bp;
+ break;
+ }
+ }
+
+ if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot")) {
+ ret = -EBUSY;
+ goto out;
+ }
+
+setup:
+ /* Setup the address register. */
+ write_wb_reg(val_base + i, info->address);
+
+ /* Setup the control register. */
+ write_wb_reg(ctrl_base + i, encode_ctrl_reg(info->ctrl) | 0x1);
+
+out:
+ return ret;
+}
+
+void arch_uninstall_hw_breakpoint(struct perf_event *bp)
+{
+ struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+ struct perf_event **slot, **slots;
+ int i, max_slots, base;
+
+ if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) {
+ /* Breakpoint */
+ base = ARM_BASE_BCR;
+ slots = __get_cpu_var(bp_on_reg);
+ max_slots = core_num_brps - 1;
+
+ if (bp_is_single_step(bp)) {
+ i = max_slots;
+ slots[i] = NULL;
+ goto reset;
+ }
+ } else {
+ /* Watchpoint */
+ base = ARM_BASE_WCR;
+ slots = __get_cpu_var(wp_on_reg);
+ max_slots = core_num_wrps;
+ }
+
+ /* Remove the breakpoint. */
+ for (i = 0; i < max_slots; ++i) {
+ slot = &slots[i];
+
+ if (*slot == bp) {
+ *slot = NULL;
+ break;
+ }
+ }
+
+ if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot"))
+ return;
+
+reset:
+ /* Reset the control register. */
+ write_wb_reg(base + i, 0);
+}
+
+static int get_hbp_len(u8 hbp_len)
+{
+ unsigned int len_in_bytes = 0;
+
+ switch (hbp_len) {
+ case ARM_BREAKPOINT_LEN_1:
+ len_in_bytes = 1;
+ break;
+ case ARM_BREAKPOINT_LEN_2:
+ len_in_bytes = 2;
+ break;
+ case ARM_BREAKPOINT_LEN_4:
+ len_in_bytes = 4;
+ break;
+ case ARM_BREAKPOINT_LEN_8:
+ len_in_bytes = 8;
+ break;
+ }
+
+ return len_in_bytes;
+}
+
+/*
+ * Check whether bp virtual address is in kernel space.
+ */
+int arch_check_bp_in_kernelspace(struct perf_event *bp)
+{
+ unsigned int len;
+ unsigned long va;
+ struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+
+ va = info->address;
+ len = get_hbp_len(info->ctrl.len);
+
+ return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
+}
+
+/*
+ * Extract generic type and length encodings from an arch_hw_breakpoint_ctrl.
+ * Hopefully this will disappear when ptrace can bypass the conversion
+ * to generic breakpoint descriptions.
+ */
+int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl,
+ int *gen_len, int *gen_type)
+{
+ /* Type */
+ switch (ctrl.type) {
+ case ARM_BREAKPOINT_EXECUTE:
+ *gen_type = HW_BREAKPOINT_X;
+ break;
+ case ARM_BREAKPOINT_LOAD:
+ *gen_type = HW_BREAKPOINT_R;
+ break;
+ case ARM_BREAKPOINT_STORE:
+ *gen_type = HW_BREAKPOINT_W;
+ break;
+ case ARM_BREAKPOINT_LOAD | ARM_BREAKPOINT_STORE:
+ *gen_type = HW_BREAKPOINT_RW;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Len */
+ switch (ctrl.len) {
+ case ARM_BREAKPOINT_LEN_1:
+ *gen_len = HW_BREAKPOINT_LEN_1;
+ break;
+ case ARM_BREAKPOINT_LEN_2:
+ *gen_len = HW_BREAKPOINT_LEN_2;
+ break;
+ case ARM_BREAKPOINT_LEN_4:
+ *gen_len = HW_BREAKPOINT_LEN_4;
+ break;
+ case ARM_BREAKPOINT_LEN_8:
+ *gen_len = HW_BREAKPOINT_LEN_8;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/*
+ * Construct an arch_hw_breakpoint from a perf_event.
+ */
+static int arch_build_bp_info(struct perf_event *bp)
+{
+ struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+
+ /* Type */
+ switch (bp->attr.bp_type) {
+ case HW_BREAKPOINT_X:
+ info->ctrl.type = ARM_BREAKPOINT_EXECUTE;
+ break;
+ case HW_BREAKPOINT_R:
+ info->ctrl.type = ARM_BREAKPOINT_LOAD;
+ break;
+ case HW_BREAKPOINT_W:
+ info->ctrl.type = ARM_BREAKPOINT_STORE;
+ break;
+ case HW_BREAKPOINT_RW:
+ info->ctrl.type = ARM_BREAKPOINT_LOAD | ARM_BREAKPOINT_STORE;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Len */
+ switch (bp->attr.bp_len) {
+ case HW_BREAKPOINT_LEN_1:
+ info->ctrl.len = ARM_BREAKPOINT_LEN_1;
+ break;
+ case HW_BREAKPOINT_LEN_2:
+ info->ctrl.len = ARM_BREAKPOINT_LEN_2;
+ break;
+ case HW_BREAKPOINT_LEN_4:
+ info->ctrl.len = ARM_BREAKPOINT_LEN_4;
+ break;
+ case HW_BREAKPOINT_LEN_8:
+ info->ctrl.len = ARM_BREAKPOINT_LEN_8;
+ if ((info->ctrl.type != ARM_BREAKPOINT_EXECUTE)
+ && max_watchpoint_len >= 8)
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Address */
+ info->address = bp->attr.bp_addr;
+
+ /* Privilege */
+ info->ctrl.privilege = ARM_BREAKPOINT_USER;
+ if (arch_check_bp_in_kernelspace(bp) && !bp_is_single_step(bp))
+ info->ctrl.privilege |= ARM_BREAKPOINT_PRIV;
+
+ /* Enabled? */
+ info->ctrl.enabled = !bp->attr.disabled;
+
+ /* Mismatch */
+ info->ctrl.mismatch = 0;
+
+ return 0;
+}
+
+/*
+ * Validate the arch-specific HW Breakpoint register settings.
+ */
+int arch_validate_hwbkpt_settings(struct perf_event *bp)
+{
+ struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+ int ret = 0;
+ u32 bytelen, max_len, offset, alignment_mask = 0x3;
+
+ /* Build the arch_hw_breakpoint. */
+ ret = arch_build_bp_info(bp);
+ if (ret)
+ goto out;
+
+ /* Check address alignment. */
+ if (info->ctrl.len == ARM_BREAKPOINT_LEN_8)
+ alignment_mask = 0x7;
+ if (info->address & alignment_mask) {
+ /*
+ * Try to fix the alignment. This may result in a length
+ * that is too large, so we must check for that.
+ */
+ bytelen = get_hbp_len(info->ctrl.len);
+ max_len = info->ctrl.type == ARM_BREAKPOINT_EXECUTE ? 4 :
+ max_watchpoint_len;
+
+ if (max_len >= 8)
+ offset = info->address & 0x7;
+ else
+ offset = info->address & 0x3;
+
+ if (bytelen > (1 << ((max_len - (offset + 1)) >> 1))) {
+ ret = -EFBIG;
+ goto out;
+ }
+
+ info->ctrl.len <<= offset;
+ info->address &= ~offset;
+
+ pr_debug("breakpoint alignment fixup: length = 0x%x, "
+ "address = 0x%x\n", info->ctrl.len, info->address);
+ }
+
+ /*
+ * Currently we rely on an overflow handler to take
+ * care of single-stepping the breakpoint when it fires.
+ * In the case of userspace breakpoints on a core with V7 debug,
+ * we can use the mismatch feature as a poor-man's hardware single-step.
+ */
+ if (WARN_ONCE(!bp->overflow_handler &&
+ (arch_check_bp_in_kernelspace(bp) || !core_has_mismatch_bps()),
+ "overflow handler required but none found")) {
+ ret = -EINVAL;
+ goto out;
+ }
+out:
+ return ret;
+}
+
+static void update_mismatch_flag(int idx, int flag)
+{
+ struct perf_event *bp = __get_cpu_var(bp_on_reg[idx]);
+ struct arch_hw_breakpoint *info;
+
+ if (bp == NULL)
+ return;
+
+ info = counter_arch_bp(bp);
+
+ /* Update the mismatch field to enter/exit `single-step' mode */
+ if (!bp->overflow_handler && info->ctrl.mismatch != flag) {
+ info->ctrl.mismatch = flag;
+ write_wb_reg(ARM_BASE_BCR + idx, encode_ctrl_reg(info->ctrl) | 0x1);
+ }
+}
+
+static void watchpoint_handler(unsigned long unknown, struct pt_regs *regs)
+{
+ int i;
+ struct perf_event *bp, **slots = __get_cpu_var(wp_on_reg);
+ struct arch_hw_breakpoint *info;
+ struct perf_event_attr attr;
+
+ /* Without a disassembler, we can only handle 1 watchpoint. */
+ BUG_ON(core_num_wrps > 1);
+
+ hw_breakpoint_init(&attr);
+ attr.bp_addr = regs->ARM_pc & ~0x3;
+ attr.bp_len = HW_BREAKPOINT_LEN_4;
+ attr.bp_type = HW_BREAKPOINT_X;
+
+ for (i = 0; i < core_num_wrps; ++i) {
+ rcu_read_lock();
+
+ if (slots[i] == NULL) {
+ rcu_read_unlock();
+ continue;
+ }
+
+ /*
+ * The DFAR is an unknown value. Since we only allow a
+ * single watchpoint, we can set the trigger to the lowest
+ * possible faulting address.
+ */
+ info = counter_arch_bp(slots[i]);
+ info->trigger = slots[i]->attr.bp_addr;
+ pr_debug("watchpoint fired: address = 0x%x\n", info->trigger);
+ perf_bp_event(slots[i], regs);
+
+ /*
+ * If no overflow handler is present, insert a temporary
+ * mismatch breakpoint so we can single-step over the
+ * watchpoint trigger.
+ */
+ if (!slots[i]->overflow_handler) {
+ bp = register_user_hw_breakpoint(&attr,
+ wp_single_step_handler,
+ current);
+ counter_arch_bp(bp)->suspended_wp = slots[i];
+ perf_event_disable(slots[i]);
+ }
+
+ rcu_read_unlock();
+ }
+}
+
+static void breakpoint_handler(unsigned long unknown, struct pt_regs *regs)
+{
+ int i;
+ int mismatch;
+ u32 ctrl_reg, val, addr;
+ struct perf_event *bp, **slots = __get_cpu_var(bp_on_reg);
+ struct arch_hw_breakpoint *info;
+ struct arch_hw_breakpoint_ctrl ctrl;
+
+ /* The exception entry code places the amended lr in the PC. */
+ addr = regs->ARM_pc;
+
+ for (i = 0; i < core_num_brps; ++i) {
+ rcu_read_lock();
+
+ bp = slots[i];
+
+ if (bp == NULL) {
+ rcu_read_unlock();
+ continue;
+ }
+
+ mismatch = 0;
+
+ /* Check if the breakpoint value matches. */
+ val = read_wb_reg(ARM_BASE_BVR + i);
+ if (val != (addr & ~0x3))
+ goto unlock;
+
+ /* Possible match, check the byte address select to confirm. */
+ ctrl_reg = read_wb_reg(ARM_BASE_BCR + i);
+ decode_ctrl_reg(ctrl_reg, &ctrl);
+ if ((1 << (addr & 0x3)) & ctrl.len) {
+ mismatch = 1;
+ info = counter_arch_bp(bp);
+ info->trigger = addr;
+ }
+
+unlock:
+ if ((mismatch && !info->ctrl.mismatch) || bp_is_single_step(bp)) {
+ pr_debug("breakpoint fired: address = 0x%x\n", addr);
+ perf_bp_event(bp, regs);
+ }
+
+ update_mismatch_flag(i, mismatch);
+ rcu_read_unlock();
+ }
+}
+
+/*
+ * Called from either the Data Abort Handler [watchpoint] or the
+ * Prefetch Abort Handler [breakpoint].
+ */
+static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr,
+ struct pt_regs *regs)
+{
+ int ret = 1; /* Unhandled fault. */
+ u32 dscr;
+
+ /* We only handle watchpoints and hardware breakpoints. */
+ ARM_DBG_READ(c1, 0, dscr);
+
+ /* Perform perf callbacks. */
+ switch (ARM_DSCR_MOE(dscr)) {
+ case ARM_ENTRY_BREAKPOINT:
+ breakpoint_handler(addr, regs);
+ break;
+ case ARM_ENTRY_ASYNC_WATCHPOINT:
+ WARN_ON("Asynchronous watchpoint exception taken. "
+ "Debugging results may be unreliable");
+ case ARM_ENTRY_SYNC_WATCHPOINT:
+ watchpoint_handler(addr, regs);
+ break;
+ default:
+ goto out;
+ }
+
+ ret = 0;
+out:
+ return ret;
+}
+
+/*
+ * One-time initialisation.
+ */
+static void __init reset_ctrl_regs(void *unused)
+{
+ int i;
+
+ if (enable_monitor_mode())
+ return;
+
+ for (i = 0; i < core_num_brps; ++i) {
+ write_wb_reg(ARM_BASE_BCR + i, 0UL);
+ write_wb_reg(ARM_BASE_BVR + i, 0UL);
+ }
+
+ for (i = 0; i < core_num_wrps; ++i) {
+ write_wb_reg(ARM_BASE_WCR + i, 0UL);
+ write_wb_reg(ARM_BASE_WVR + i, 0UL);
+ }
+}
+
+static int __init arch_hw_breakpoint_init(void)
+{
+ int ret = 0;
+ u32 dscr;
+
+ debug_arch = get_debug_arch();
+
+ if (debug_arch > ARM_DEBUG_ARCH_V7_ECP14) {
+ pr_info("debug architecture 0x%x unsupported.\n", debug_arch);
+ ret = -ENODEV;
+ goto out;
+ }
+
+ /* Determine how many BRPs/WRPs are available. */
+ core_num_brps = get_num_brps();
+ core_num_wrps = get_num_wrps();
+
+ pr_info("found %d breakpoint and %d watchpoint registers.\n",
+ core_num_brps, core_num_wrps);
+
+ if (core_has_mismatch_bps())
+ pr_info("1 breakpoint reserved for watchpoint single-step.\n");
+
+ ARM_DBG_READ(c1, 0, dscr);
+ if (dscr & ARM_DSCR_HDBGEN) {
+ pr_warning("halting debug mode enabled. Assuming maximum "
+ "watchpoint size of 4 bytes.");
+ } else {
+ /* Work out the maximum supported watchpoint length. */
+ max_watchpoint_len = get_max_wp_len();
+ pr_info("maximum watchpoint size is %u bytes.\n",
+ max_watchpoint_len);
+
+ /*
+ * Reset the breakpoint resources. We assume that a halting
+ * debugger will leave the world in a nice state for us.
+ */
+ smp_call_function(reset_ctrl_regs, NULL, 1);
+ reset_ctrl_regs(NULL);
+ }
+
+ /* Register debug fault handler. */
+ hook_fault_code(2, hw_breakpoint_pending, SIGTRAP, TRAP_HWBKPT,
+ "watchpoint debug exception");
+ hook_ifault_code(2, hw_breakpoint_pending, SIGTRAP, TRAP_HWBKPT,
+ "breakpoint debug exception");
+
+out:
+ return ret;
+}
+arch_initcall(arch_hw_breakpoint_init);
+
+void hw_breakpoint_pmu_read(struct perf_event *bp)
+{
+}
+
+/*
+ * Dummy function to register with die_notifier.
+ */
+int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
+ unsigned long val, void *data)
+{
+ return NOTIFY_DONE;
+}
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index c0d5c3b3a760..36ad3be4692a 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -154,14 +154,6 @@ void set_irq_flags(unsigned int irq, unsigned int iflags)
void __init init_IRQ(void)
{
- struct irq_desc *desc;
- int irq;
-
- for (irq = 0; irq < nr_irqs; irq++) {
- desc = irq_to_desc_alloc_node(irq, 0);
- desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE;
- }
-
init_arch_irq();
}
@@ -169,7 +161,7 @@ void __init init_IRQ(void)
int __init arch_probe_nr_irqs(void)
{
nr_irqs = arch_nr_irqs ? arch_nr_irqs : NR_IRQS;
- return 0;
+ return nr_irqs;
}
#endif
diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c
index 8bccbfa693ff..2c1f0050c9c4 100644
--- a/arch/arm/kernel/kprobes-decode.c
+++ b/arch/arm/kernel/kprobes-decode.c
@@ -1162,11 +1162,12 @@ space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
{
/*
* MSR : cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx
- * Undef : cccc 0011 0x00 xxxx xxxx xxxx xxxx xxxx
+ * Undef : cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx
* ALU op with S bit and Rd == 15 :
* cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx
*/
- if ((insn & 0x0f900000) == 0x03200000 || /* MSR & Undef */
+ if ((insn & 0x0fb00000) == 0x03200000 || /* MSR */
+ (insn & 0x0ff00000) == 0x03400000 || /* Undef */
(insn & 0x0e10f000) == 0x0210f000) /* ALU s-bit, R15 */
return INSN_REJECTED;
@@ -1177,7 +1178,7 @@ space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
* *S (bit 20) updates condition codes
* ADC/SBC/RSC reads the C flag
*/
- insn &= 0xfff00fff; /* Rn = r0, Rd = r0 */
+ insn &= 0xffff0fff; /* Rd = r0 */
asi->insn[0] = insn;
asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */
emulate_alu_imm_rwflags : emulate_alu_imm_rflags;
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index 6b4605893f1e..d9bd786ce23d 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -69,20 +69,31 @@ int module_frob_arch_sections(Elf_Ehdr *hdr,
{
#ifdef CONFIG_ARM_UNWIND
Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum;
+ struct arm_unwind_mapping *maps = mod->arch.map;
for (s = sechdrs; s < sechdrs_end; s++) {
- if (strcmp(".ARM.exidx.init.text", secstrings + s->sh_name) == 0)
- mod->arch.unw_sec_init = s;
- else if (strcmp(".ARM.exidx.devinit.text", secstrings + s->sh_name) == 0)
- mod->arch.unw_sec_devinit = s;
- else if (strcmp(".ARM.exidx", secstrings + s->sh_name) == 0)
- mod->arch.unw_sec_core = s;
- else if (strcmp(".init.text", secstrings + s->sh_name) == 0)
- mod->arch.sec_init_text = s;
- else if (strcmp(".devinit.text", secstrings + s->sh_name) == 0)
- mod->arch.sec_devinit_text = s;
- else if (strcmp(".text", secstrings + s->sh_name) == 0)
- mod->arch.sec_core_text = s;
+ char const *secname = secstrings + s->sh_name;
+
+ if (strcmp(".ARM.exidx.init.text", secname) == 0)
+ maps[ARM_SEC_INIT].unw_sec = s;
+ else if (strcmp(".ARM.exidx.devinit.text", secname) == 0)
+ maps[ARM_SEC_DEVINIT].unw_sec = s;
+ else if (strcmp(".ARM.exidx", secname) == 0)
+ maps[ARM_SEC_CORE].unw_sec = s;
+ else if (strcmp(".ARM.exidx.exit.text", secname) == 0)
+ maps[ARM_SEC_EXIT].unw_sec = s;
+ else if (strcmp(".ARM.exidx.devexit.text", secname) == 0)
+ maps[ARM_SEC_DEVEXIT].unw_sec = s;
+ else if (strcmp(".init.text", secname) == 0)
+ maps[ARM_SEC_INIT].sec_text = s;
+ else if (strcmp(".devinit.text", secname) == 0)
+ maps[ARM_SEC_DEVINIT].sec_text = s;
+ else if (strcmp(".text", secname) == 0)
+ maps[ARM_SEC_CORE].sec_text = s;
+ else if (strcmp(".exit.text", secname) == 0)
+ maps[ARM_SEC_EXIT].sec_text = s;
+ else if (strcmp(".devexit.text", secname) == 0)
+ maps[ARM_SEC_DEVEXIT].sec_text = s;
}
#endif
return 0;
@@ -292,31 +303,22 @@ apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
#ifdef CONFIG_ARM_UNWIND
static void register_unwind_tables(struct module *mod)
{
- if (mod->arch.unw_sec_init && mod->arch.sec_init_text)
- mod->arch.unwind_init =
- unwind_table_add(mod->arch.unw_sec_init->sh_addr,
- mod->arch.unw_sec_init->sh_size,
- mod->arch.sec_init_text->sh_addr,
- mod->arch.sec_init_text->sh_size);
- if (mod->arch.unw_sec_devinit && mod->arch.sec_devinit_text)
- mod->arch.unwind_devinit =
- unwind_table_add(mod->arch.unw_sec_devinit->sh_addr,
- mod->arch.unw_sec_devinit->sh_size,
- mod->arch.sec_devinit_text->sh_addr,
- mod->arch.sec_devinit_text->sh_size);
- if (mod->arch.unw_sec_core && mod->arch.sec_core_text)
- mod->arch.unwind_core =
- unwind_table_add(mod->arch.unw_sec_core->sh_addr,
- mod->arch.unw_sec_core->sh_size,
- mod->arch.sec_core_text->sh_addr,
- mod->arch.sec_core_text->sh_size);
+ int i;
+ for (i = 0; i < ARM_SEC_MAX; ++i) {
+ struct arm_unwind_mapping *map = &mod->arch.map[i];
+ if (map->unw_sec && map->sec_text)
+ map->unwind = unwind_table_add(map->unw_sec->sh_addr,
+ map->unw_sec->sh_size,
+ map->sec_text->sh_addr,
+ map->sec_text->sh_size);
+ }
}
static void unregister_unwind_tables(struct module *mod)
{
- unwind_table_del(mod->arch.unwind_init);
- unwind_table_del(mod->arch.unwind_devinit);
- unwind_table_del(mod->arch.unwind_core);
+ int i = ARM_SEC_MAX;
+ while (--i >= 0)
+ unwind_table_del(mod->arch.map[i].unwind);
}
#else
static inline void register_unwind_tables(struct module *mod) { }
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index ecbb0288e5dd..49643b1467e6 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -123,6 +123,12 @@ armpmu_get_max_events(void)
}
EXPORT_SYMBOL_GPL(armpmu_get_max_events);
+int perf_num_counters(void)
+{
+ return armpmu_get_max_events();
+}
+EXPORT_SYMBOL_GPL(perf_num_counters);
+
#define HW_OP_UNSUPPORTED 0xFFFF
#define C(_x) \
@@ -221,46 +227,56 @@ again:
}
static void
-armpmu_disable(struct perf_event *event)
+armpmu_read(struct perf_event *event)
{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
struct hw_perf_event *hwc = &event->hw;
- int idx = hwc->idx;
-
- WARN_ON(idx < 0);
-
- clear_bit(idx, cpuc->active_mask);
- armpmu->disable(hwc, idx);
-
- barrier();
- armpmu_event_update(event, hwc, idx);
- cpuc->events[idx] = NULL;
- clear_bit(idx, cpuc->used_mask);
+ /* Don't read disabled counters! */
+ if (hwc->idx < 0)
+ return;
- perf_event_update_userpage(event);
+ armpmu_event_update(event, hwc, hwc->idx);
}
static void
-armpmu_read(struct perf_event *event)
+armpmu_stop(struct perf_event *event, int flags)
{
struct hw_perf_event *hwc = &event->hw;
- /* Don't read disabled counters! */
- if (hwc->idx < 0)
+ if (!armpmu)
return;
- armpmu_event_update(event, hwc, hwc->idx);
+ /*
+ * ARM pmu always has to update the counter, so ignore
+ * PERF_EF_UPDATE, see comments in armpmu_start().
+ */
+ if (!(hwc->state & PERF_HES_STOPPED)) {
+ armpmu->disable(hwc, hwc->idx);
+ barrier(); /* why? */
+ armpmu_event_update(event, hwc, hwc->idx);
+ hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
+ }
}
static void
-armpmu_unthrottle(struct perf_event *event)
+armpmu_start(struct perf_event *event, int flags)
{
struct hw_perf_event *hwc = &event->hw;
+ if (!armpmu)
+ return;
+
+ /*
+ * ARM pmu always has to reprogram the period, so ignore
+ * PERF_EF_RELOAD, see the comment below.
+ */
+ if (flags & PERF_EF_RELOAD)
+ WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
+
+ hwc->state = 0;
/*
* Set the period again. Some counters can't be stopped, so when we
- * were throttled we simply disabled the IRQ source and the counter
+ * were stopped we simply disabled the IRQ source and the counter
* may have been left counting. If we don't do this step then we may
* get an interrupt too soon or *way* too late if the overflow has
* happened since disabling.
@@ -269,14 +285,33 @@ armpmu_unthrottle(struct perf_event *event)
armpmu->enable(hwc, hwc->idx);
}
+static void
+armpmu_del(struct perf_event *event, int flags)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ struct hw_perf_event *hwc = &event->hw;
+ int idx = hwc->idx;
+
+ WARN_ON(idx < 0);
+
+ clear_bit(idx, cpuc->active_mask);
+ armpmu_stop(event, PERF_EF_UPDATE);
+ cpuc->events[idx] = NULL;
+ clear_bit(idx, cpuc->used_mask);
+
+ perf_event_update_userpage(event);
+}
+
static int
-armpmu_enable(struct perf_event *event)
+armpmu_add(struct perf_event *event, int flags)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
struct hw_perf_event *hwc = &event->hw;
int idx;
int err = 0;
+ perf_pmu_disable(event->pmu);
+
/* If we don't have a space for the counter then finish early. */
idx = armpmu->get_event_idx(cpuc, hwc);
if (idx < 0) {
@@ -293,25 +328,19 @@ armpmu_enable(struct perf_event *event)
cpuc->events[idx] = event;
set_bit(idx, cpuc->active_mask);
- /* Set the period for the event. */
- armpmu_event_set_period(event, hwc, idx);
-
- /* Enable the event. */
- armpmu->enable(hwc, idx);
+ hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
+ if (flags & PERF_EF_START)
+ armpmu_start(event, PERF_EF_RELOAD);
/* Propagate our changes to the userspace mapping. */
perf_event_update_userpage(event);
out:
+ perf_pmu_enable(event->pmu);
return err;
}
-static struct pmu pmu = {
- .enable = armpmu_enable,
- .disable = armpmu_disable,
- .unthrottle = armpmu_unthrottle,
- .read = armpmu_read,
-};
+static struct pmu pmu;
static int
validate_event(struct cpu_hw_events *cpuc,
@@ -491,20 +520,29 @@ __hw_perf_event_init(struct perf_event *event)
return err;
}
-const struct pmu *
-hw_perf_event_init(struct perf_event *event)
+static int armpmu_event_init(struct perf_event *event)
{
int err = 0;
+ switch (event->attr.type) {
+ case PERF_TYPE_RAW:
+ case PERF_TYPE_HARDWARE:
+ case PERF_TYPE_HW_CACHE:
+ break;
+
+ default:
+ return -ENOENT;
+ }
+
if (!armpmu)
- return ERR_PTR(-ENODEV);
+ return -ENODEV;
event->destroy = hw_perf_event_destroy;
if (!atomic_inc_not_zero(&active_events)) {
- if (atomic_read(&active_events) > perf_max_events) {
+ if (atomic_read(&active_events) > armpmu->num_events) {
atomic_dec(&active_events);
- return ERR_PTR(-ENOSPC);
+ return -ENOSPC;
}
mutex_lock(&pmu_reserve_mutex);
@@ -518,17 +556,16 @@ hw_perf_event_init(struct perf_event *event)
}
if (err)
- return ERR_PTR(err);
+ return err;
err = __hw_perf_event_init(event);
if (err)
hw_perf_event_destroy(event);
- return err ? ERR_PTR(err) : &pmu;
+ return err;
}
-void
-hw_perf_enable(void)
+static void armpmu_enable(struct pmu *pmu)
{
/* Enable all of the perf events on hardware. */
int idx;
@@ -549,13 +586,23 @@ hw_perf_enable(void)
armpmu->start();
}
-void
-hw_perf_disable(void)
+static void armpmu_disable(struct pmu *pmu)
{
if (armpmu)
armpmu->stop();
}
+static struct pmu pmu = {
+ .pmu_enable = armpmu_enable,
+ .pmu_disable = armpmu_disable,
+ .event_init = armpmu_event_init,
+ .add = armpmu_add,
+ .del = armpmu_del,
+ .start = armpmu_start,
+ .stop = armpmu_stop,
+ .read = armpmu_read,
+};
+
/*
* ARMv6 Performance counter handling code.
*
@@ -1045,7 +1092,7 @@ armv6pmu_handle_irq(int irq_num,
* platforms that can have the PMU interrupts raised as an NMI, this
* will not work.
*/
- perf_event_do_pending();
+ irq_work_run();
return IRQ_HANDLED;
}
@@ -2021,7 +2068,7 @@ static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)
* platforms that can have the PMU interrupts raised as an NMI, this
* will not work.
*/
- perf_event_do_pending();
+ irq_work_run();
return IRQ_HANDLED;
}
@@ -2389,7 +2436,7 @@ xscale1pmu_handle_irq(int irq_num, void *dev)
armpmu->disable(hwc, idx);
}
- perf_event_do_pending();
+ irq_work_run();
/*
* Re-enable the PMU.
@@ -2716,7 +2763,7 @@ xscale2pmu_handle_irq(int irq_num, void *dev)
armpmu->disable(hwc, idx);
}
- perf_event_do_pending();
+ irq_work_run();
/*
* Re-enable the PMU.
@@ -2933,14 +2980,12 @@ init_hw_perf_events(void)
armpmu = &armv6pmu;
memcpy(armpmu_perf_cache_map, armv6_perf_cache_map,
sizeof(armv6_perf_cache_map));
- perf_max_events = armv6pmu.num_events;
break;
case 0xB020: /* ARM11mpcore */
armpmu = &armv6mpcore_pmu;
memcpy(armpmu_perf_cache_map,
armv6mpcore_perf_cache_map,
sizeof(armv6mpcore_perf_cache_map));
- perf_max_events = armv6mpcore_pmu.num_events;
break;
case 0xC080: /* Cortex-A8 */
armv7pmu.id = ARM_PERF_PMU_ID_CA8;
@@ -2952,7 +2997,6 @@ init_hw_perf_events(void)
/* Reset PMNC and read the nb of CNTx counters
supported */
armv7pmu.num_events = armv7_reset_read_pmnc();
- perf_max_events = armv7pmu.num_events;
break;
case 0xC090: /* Cortex-A9 */
armv7pmu.id = ARM_PERF_PMU_ID_CA9;
@@ -2964,7 +3008,6 @@ init_hw_perf_events(void)
/* Reset PMNC and read the nb of CNTx counters
supported */
armv7pmu.num_events = armv7_reset_read_pmnc();
- perf_max_events = armv7pmu.num_events;
break;
}
/* Intel CPUs [xscale]. */
@@ -2975,13 +3018,11 @@ init_hw_perf_events(void)
armpmu = &xscale1pmu;
memcpy(armpmu_perf_cache_map, xscale_perf_cache_map,
sizeof(xscale_perf_cache_map));
- perf_max_events = xscale1pmu.num_events;
break;
case 2:
armpmu = &xscale2pmu;
memcpy(armpmu_perf_cache_map, xscale_perf_cache_map,
sizeof(xscale_perf_cache_map));
- perf_max_events = xscale2pmu.num_events;
break;
}
}
@@ -2991,9 +3032,10 @@ init_hw_perf_events(void)
arm_pmu_names[armpmu->id], armpmu->num_events);
} else {
pr_info("no hardware support available\n");
- perf_max_events = -1;
}
+ perf_pmu_register(&pmu);
+
return 0;
}
arch_initcall(init_hw_perf_events);
@@ -3001,13 +3043,6 @@ arch_initcall(init_hw_perf_events);
/*
* Callchain handling code.
*/
-static inline void
-callchain_store(struct perf_callchain_entry *entry,
- u64 ip)
-{
- if (entry->nr < PERF_MAX_STACK_DEPTH)
- entry->ip[entry->nr++] = ip;
-}
/*
* The registers we're interested in are at the end of the variable
@@ -3039,7 +3074,7 @@ user_backtrace(struct frame_tail *tail,
if (__copy_from_user_inatomic(&buftail, tail, sizeof(buftail)))
return NULL;
- callchain_store(entry, buftail.lr);
+ perf_callchain_store(entry, buftail.lr);
/*
* Frame pointers should strictly progress back up the stack
@@ -3051,16 +3086,11 @@ user_backtrace(struct frame_tail *tail,
return buftail.fp - 1;
}
-static void
-perf_callchain_user(struct pt_regs *regs,
- struct perf_callchain_entry *entry)
+void
+perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
{
struct frame_tail *tail;
- callchain_store(entry, PERF_CONTEXT_USER);
-
- if (!user_mode(regs))
- regs = task_pt_regs(current);
tail = (struct frame_tail *)regs->ARM_fp - 1;
@@ -3078,56 +3108,18 @@ callchain_trace(struct stackframe *fr,
void *data)
{
struct perf_callchain_entry *entry = data;
- callchain_store(entry, fr->pc);
+ perf_callchain_store(entry, fr->pc);
return 0;
}
-static void
-perf_callchain_kernel(struct pt_regs *regs,
- struct perf_callchain_entry *entry)
+void
+perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs)
{
struct stackframe fr;
- callchain_store(entry, PERF_CONTEXT_KERNEL);
fr.fp = regs->ARM_fp;
fr.sp = regs->ARM_sp;
fr.lr = regs->ARM_lr;
fr.pc = regs->ARM_pc;
walk_stackframe(&fr, callchain_trace, entry);
}
-
-static void
-perf_do_callchain(struct pt_regs *regs,
- struct perf_callchain_entry *entry)
-{
- int is_user;
-
- if (!regs)
- return;
-
- is_user = user_mode(regs);
-
- if (!current || !current->pid)
- return;
-
- if (is_user && current->state != TASK_RUNNING)
- return;
-
- if (!is_user)
- perf_callchain_kernel(regs, entry);
-
- if (current->mm)
- perf_callchain_user(regs, entry);
-}
-
-static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_irq_entry);
-
-struct perf_callchain_entry *
-perf_callchain(struct pt_regs *regs)
-{
- struct perf_callchain_entry *entry = &__get_cpu_var(pmc_irq_entry);
-
- entry->nr = 0;
- perf_do_callchain(regs, entry);
- return entry;
-}
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 401e38be1f78..e76fcaadce03 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -29,6 +29,7 @@
#include <linux/utsname.h>
#include <linux/uaccess.h>
#include <linux/random.h>
+#include <linux/hw_breakpoint.h>
#include <asm/cacheflush.h>
#include <asm/leds.h>
@@ -135,6 +136,25 @@ EXPORT_SYMBOL(pm_power_off);
void (*arm_pm_restart)(char str, const char *cmd) = arm_machine_restart;
EXPORT_SYMBOL_GPL(arm_pm_restart);
+static void do_nothing(void *unused)
+{
+}
+
+/*
+ * cpu_idle_wait - Used to ensure that all the CPUs discard old value of
+ * pm_idle and update to new pm_idle value. Required while changing pm_idle
+ * handler on SMP systems.
+ *
+ * Caller must have changed pm_idle to the new value before the call. Old
+ * pm_idle value will not be used by any CPU after the return of this function.
+ */
+void cpu_idle_wait(void)
+{
+ smp_mb();
+ /* kick all the CPUs so that they exit out of pm_idle */
+ smp_call_function(do_nothing, NULL, 1);
+}
+EXPORT_SYMBOL_GPL(cpu_idle_wait);
/*
* This is our default idle handler. We need to disable
@@ -317,6 +337,8 @@ void flush_thread(void)
struct thread_info *thread = current_thread_info();
struct task_struct *tsk = current;
+ flush_ptrace_hw_breakpoint(tsk);
+
memset(thread->used_cp, 0, sizeof(thread->used_cp));
memset(&tsk->thread.debug, 0, sizeof(struct debug_info));
memset(&thread->fpstate, 0, sizeof(union fp_state));
@@ -345,6 +367,8 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start,
thread->cpu_context.sp = (unsigned long)childregs;
thread->cpu_context.pc = (unsigned long)ret_from_fork;
+ clear_ptrace_hw_breakpoint(p);
+
if (clone_flags & CLONE_SETTLS)
thread->tp_value = regs->ARM_r3;
@@ -458,3 +482,24 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
unsigned long range_end = mm->brk + 0x02000000;
return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
}
+
+/*
+ * The vectors page is always readable from user space for the
+ * atomic helpers and the signal restart code. Let's declare a mapping
+ * for it so it is visible through ptrace and /proc/<pid>/mem.
+ */
+
+int vectors_user_mapping(void)
+{
+ struct mm_struct *mm = current->mm;
+ return install_special_mapping(mm, 0xffff0000, PAGE_SIZE,
+ VM_READ | VM_EXEC |
+ VM_MAYREAD | VM_MAYEXEC |
+ VM_ALWAYSDUMP | VM_RESERVED,
+ NULL);
+}
+
+const char *arch_vma_name(struct vm_area_struct *vma)
+{
+ return (vma->vm_start == 0xffff0000) ? "[vectors]" : NULL;
+}
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index f99d489822d5..e0cb6370ed14 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -19,6 +19,8 @@
#include <linux/init.h>
#include <linux/signal.h>
#include <linux/uaccess.h>
+#include <linux/perf_event.h>
+#include <linux/hw_breakpoint.h>
#include <asm/pgtable.h>
#include <asm/system.h>
@@ -847,6 +849,232 @@ static int ptrace_setvfpregs(struct task_struct *tsk, void __user *data)
}
#endif
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+/*
+ * Convert a virtual register number into an index for a thread_info
+ * breakpoint array. Breakpoints are identified using positive numbers
+ * whilst watchpoints are negative. The registers are laid out as pairs
+ * of (address, control), each pair mapping to a unique hw_breakpoint struct.
+ * Register 0 is reserved for describing resource information.
+ */
+static int ptrace_hbp_num_to_idx(long num)
+{
+ if (num < 0)
+ num = (ARM_MAX_BRP << 1) - num;
+ return (num - 1) >> 1;
+}
+
+/*
+ * Returns the virtual register number for the address of the
+ * breakpoint at index idx.
+ */
+static long ptrace_hbp_idx_to_num(int idx)
+{
+ long mid = ARM_MAX_BRP << 1;
+ long num = (idx << 1) + 1;
+ return num > mid ? mid - num : num;
+}
+
+/*
+ * Handle hitting a HW-breakpoint.
+ */
+static void ptrace_hbptriggered(struct perf_event *bp, int unused,
+ struct perf_sample_data *data,
+ struct pt_regs *regs)
+{
+ struct arch_hw_breakpoint *bkpt = counter_arch_bp(bp);
+ long num;
+ int i;
+ siginfo_t info;
+
+ for (i = 0; i < ARM_MAX_HBP_SLOTS; ++i)
+ if (current->thread.debug.hbp[i] == bp)
+ break;
+
+ num = (i == ARM_MAX_HBP_SLOTS) ? 0 : ptrace_hbp_idx_to_num(i);
+
+ info.si_signo = SIGTRAP;
+ info.si_errno = (int)num;
+ info.si_code = TRAP_HWBKPT;
+ info.si_addr = (void __user *)(bkpt->trigger);
+
+ force_sig_info(SIGTRAP, &info, current);
+}
+
+/*
+ * Set ptrace breakpoint pointers to zero for this task.
+ * This is required in order to prevent child processes from unregistering
+ * breakpoints held by their parent.
+ */
+void clear_ptrace_hw_breakpoint(struct task_struct *tsk)
+{
+ memset(tsk->thread.debug.hbp, 0, sizeof(tsk->thread.debug.hbp));
+}
+
+/*
+ * Unregister breakpoints from this task and reset the pointers in
+ * the thread_struct.
+ */
+void flush_ptrace_hw_breakpoint(struct task_struct *tsk)
+{
+ int i;
+ struct thread_struct *t = &tsk->thread;
+
+ for (i = 0; i < ARM_MAX_HBP_SLOTS; i++) {
+ if (t->debug.hbp[i]) {
+ unregister_hw_breakpoint(t->debug.hbp[i]);
+ t->debug.hbp[i] = NULL;
+ }
+ }
+}
+
+static u32 ptrace_get_hbp_resource_info(void)
+{
+ u8 num_brps, num_wrps, debug_arch, wp_len;
+ u32 reg = 0;
+
+ num_brps = hw_breakpoint_slots(TYPE_INST);
+ num_wrps = hw_breakpoint_slots(TYPE_DATA);
+ debug_arch = arch_get_debug_arch();
+ wp_len = arch_get_max_wp_len();
+
+ reg |= debug_arch;
+ reg <<= 8;
+ reg |= wp_len;
+ reg <<= 8;
+ reg |= num_wrps;
+ reg <<= 8;
+ reg |= num_brps;
+
+ return reg;
+}
+
+static struct perf_event *ptrace_hbp_create(struct task_struct *tsk, int type)
+{
+ struct perf_event_attr attr;
+
+ ptrace_breakpoint_init(&attr);
+
+ /* Initialise fields to sane defaults. */
+ attr.bp_addr = 0;
+ attr.bp_len = HW_BREAKPOINT_LEN_4;
+ attr.bp_type = type;
+ attr.disabled = 1;
+
+ return register_user_hw_breakpoint(&attr, ptrace_hbptriggered, tsk);
+}
+
+static int ptrace_gethbpregs(struct task_struct *tsk, long num,
+ unsigned long __user *data)
+{
+ u32 reg;
+ int idx, ret = 0;
+ struct perf_event *bp;
+ struct arch_hw_breakpoint_ctrl arch_ctrl;
+
+ if (num == 0) {
+ reg = ptrace_get_hbp_resource_info();
+ } else {
+ idx = ptrace_hbp_num_to_idx(num);
+ if (idx < 0 || idx >= ARM_MAX_HBP_SLOTS) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ bp = tsk->thread.debug.hbp[idx];
+ if (!bp) {
+ reg = 0;
+ goto put;
+ }
+
+ arch_ctrl = counter_arch_bp(bp)->ctrl;
+
+ /*
+ * Fix up the len because we may have adjusted it
+ * to compensate for an unaligned address.
+ */
+ while (!(arch_ctrl.len & 0x1))
+ arch_ctrl.len >>= 1;
+
+ if (idx & 0x1)
+ reg = encode_ctrl_reg(arch_ctrl);
+ else
+ reg = bp->attr.bp_addr;
+ }
+
+put:
+ if (put_user(reg, data))
+ ret = -EFAULT;
+
+out:
+ return ret;
+}
+
+static int ptrace_sethbpregs(struct task_struct *tsk, long num,
+ unsigned long __user *data)
+{
+ int idx, gen_len, gen_type, implied_type, ret = 0;
+ u32 user_val;
+ struct perf_event *bp;
+ struct arch_hw_breakpoint_ctrl ctrl;
+ struct perf_event_attr attr;
+
+ if (num == 0)
+ goto out;
+ else if (num < 0)
+ implied_type = HW_BREAKPOINT_RW;
+ else
+ implied_type = HW_BREAKPOINT_X;
+
+ idx = ptrace_hbp_num_to_idx(num);
+ if (idx < 0 || idx >= ARM_MAX_HBP_SLOTS) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (get_user(user_val, data)) {
+ ret = -EFAULT;
+ goto out;
+ }
+
+ bp = tsk->thread.debug.hbp[idx];
+ if (!bp) {
+ bp = ptrace_hbp_create(tsk, implied_type);
+ if (IS_ERR(bp)) {
+ ret = PTR_ERR(bp);
+ goto out;
+ }
+ tsk->thread.debug.hbp[idx] = bp;
+ }
+
+ attr = bp->attr;
+
+ if (num & 0x1) {
+ /* Address */
+ attr.bp_addr = user_val;
+ } else {
+ /* Control */
+ decode_ctrl_reg(user_val, &ctrl);
+ ret = arch_bp_generic_fields(ctrl, &gen_len, &gen_type);
+ if (ret)
+ goto out;
+
+ if ((gen_type & implied_type) != gen_type) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ attr.bp_len = gen_len;
+ attr.bp_type = gen_type;
+ attr.disabled = !ctrl.enabled;
+ }
+
+ ret = modify_user_hw_breakpoint(bp, &attr);
+out:
+ return ret;
+}
+#endif
+
long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
int ret;
@@ -916,6 +1144,17 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
#endif
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+ case PTRACE_GETHBPREGS:
+ ret = ptrace_gethbpregs(child, addr,
+ (unsigned long __user *)data);
+ break;
+ case PTRACE_SETHBPREGS:
+ ret = ptrace_sethbpregs(child, addr,
+ (unsigned long __user *)data);
+ break;
+#endif
+
default:
ret = ptrace_request(child, request, addr, data);
break;
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index d5231ae7355a..336f14e0e5c2 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -36,6 +36,7 @@
#include <asm/procinfo.h>
#include <asm/sections.h>
#include <asm/setup.h>
+#include <asm/smp_plat.h>
#include <asm/mach-types.h>
#include <asm/cacheflush.h>
#include <asm/cachetype.h>
@@ -238,6 +239,35 @@ int cpu_architecture(void)
return cpu_arch;
}
+static int cpu_has_aliasing_icache(unsigned int arch)
+{
+ int aliasing_icache;
+ unsigned int id_reg, num_sets, line_size;
+
+ /* arch specifies the register format */
+ switch (arch) {
+ case CPU_ARCH_ARMv7:
+ asm("mcr p15, 2, %0, c0, c0, 0 @ set CSSELR"
+ : /* No output operands */
+ : "r" (1));
+ isb();
+ asm("mrc p15, 1, %0, c0, c0, 0 @ read CCSIDR"
+ : "=r" (id_reg));
+ line_size = 4 << ((id_reg & 0x7) + 2);
+ num_sets = ((id_reg >> 13) & 0x7fff) + 1;
+ aliasing_icache = (line_size * num_sets) > PAGE_SIZE;
+ break;
+ case CPU_ARCH_ARMv6:
+ aliasing_icache = read_cpuid_cachetype() & (1 << 11);
+ break;
+ default:
+ /* I-cache aliases will be handled by D-cache aliasing code */
+ aliasing_icache = 0;
+ }
+
+ return aliasing_icache;
+}
+
static void __init cacheid_init(void)
{
unsigned int cachetype = read_cpuid_cachetype();
@@ -249,10 +279,15 @@ static void __init cacheid_init(void)
cacheid = CACHEID_VIPT_NONALIASING;
if ((cachetype & (3 << 14)) == 1 << 14)
cacheid |= CACHEID_ASID_TAGGED;
- } else if (cachetype & (1 << 23))
+ else if (cpu_has_aliasing_icache(CPU_ARCH_ARMv7))
+ cacheid |= CACHEID_VIPT_I_ALIASING;
+ } else if (cachetype & (1 << 23)) {
cacheid = CACHEID_VIPT_ALIASING;
- else
+ } else {
cacheid = CACHEID_VIPT_NONALIASING;
+ if (cpu_has_aliasing_icache(CPU_ARCH_ARMv6))
+ cacheid |= CACHEID_VIPT_I_ALIASING;
+ }
} else {
cacheid = CACHEID_VIVT;
}
@@ -263,7 +298,7 @@ static void __init cacheid_init(void)
cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown",
cache_is_vivt() ? "VIVT" :
icache_is_vivt_asid_tagged() ? "VIVT ASID tagged" :
- cache_is_vipt_aliasing() ? "VIPT aliasing" :
+ icache_is_vipt_aliasing() ? "VIPT aliasing" :
cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown");
}
@@ -490,7 +525,7 @@ request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc)
kernel_code.start = virt_to_phys(_text);
kernel_code.end = virt_to_phys(_etext - 1);
- kernel_data.start = virt_to_phys(_data);
+ kernel_data.start = virt_to_phys(_sdata);
kernel_data.end = virt_to_phys(_end - 1);
for (i = 0; i < mi->nr_banks; i++) {
@@ -825,7 +860,8 @@ void __init setup_arch(char **cmdline_p)
request_standard_resources(&meminfo, mdesc);
#ifdef CONFIG_SMP
- smp_init_cpus();
+ if (is_smp())
+ smp_init_cpus();
#endif
reserve_crashkernel();
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 40dc74f2b27f..8c1959590252 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -33,6 +33,7 @@
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
#include <asm/processor.h>
+#include <asm/sections.h>
#include <asm/tlbflush.h>
#include <asm/ptrace.h>
#include <asm/localtimer.h>
@@ -67,12 +68,47 @@ enum ipi_msg_type {
IPI_CPU_STOP,
};
+static inline void identity_mapping_add(pgd_t *pgd, unsigned long start,
+ unsigned long end)
+{
+ unsigned long addr, prot;
+ pmd_t *pmd;
+
+ prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE;
+ if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
+ prot |= PMD_BIT4;
+
+ for (addr = start & PGDIR_MASK; addr < end;) {
+ pmd = pmd_offset(pgd + pgd_index(addr), addr);
+ pmd[0] = __pmd(addr | prot);
+ addr += SECTION_SIZE;
+ pmd[1] = __pmd(addr | prot);
+ addr += SECTION_SIZE;
+ flush_pmd_entry(pmd);
+ outer_clean_range(__pa(pmd), __pa(pmd + 1));
+ }
+}
+
+static inline void identity_mapping_del(pgd_t *pgd, unsigned long start,
+ unsigned long end)
+{
+ unsigned long addr;
+ pmd_t *pmd;
+
+ for (addr = start & PGDIR_MASK; addr < end; addr += PGDIR_SIZE) {
+ pmd = pmd_offset(pgd + pgd_index(addr), addr);
+ pmd[0] = __pmd(0);
+ pmd[1] = __pmd(0);
+ clean_pmd_entry(pmd);
+ outer_clean_range(__pa(pmd), __pa(pmd + 1));
+ }
+}
+
int __cpuinit __cpu_up(unsigned int cpu)
{
struct cpuinfo_arm *ci = &per_cpu(cpu_data, cpu);
struct task_struct *idle = ci->idle;
pgd_t *pgd;
- pmd_t *pmd;
int ret;
/*
@@ -101,11 +137,16 @@ int __cpuinit __cpu_up(unsigned int cpu)
* a 1:1 mapping for the physical address of the kernel.
*/
pgd = pgd_alloc(&init_mm);
- pmd = pmd_offset(pgd + pgd_index(PHYS_OFFSET), PHYS_OFFSET);
- *pmd = __pmd((PHYS_OFFSET & PGDIR_MASK) |
- PMD_TYPE_SECT | PMD_SECT_AP_WRITE);
- flush_pmd_entry(pmd);
- outer_clean_range(__pa(pmd), __pa(pmd + 1));
+ if (!pgd)
+ return -ENOMEM;
+
+ if (PHYS_OFFSET != PAGE_OFFSET) {
+#ifndef CONFIG_HOTPLUG_CPU
+ identity_mapping_add(pgd, __pa(__init_begin), __pa(__init_end));
+#endif
+ identity_mapping_add(pgd, __pa(_stext), __pa(_etext));
+ identity_mapping_add(pgd, __pa(_sdata), __pa(_edata));
+ }
/*
* We need to tell the secondary core where to find
@@ -143,8 +184,14 @@ int __cpuinit __cpu_up(unsigned int cpu)
secondary_data.stack = NULL;
secondary_data.pgdir = 0;
- *pmd = __pmd(0);
- clean_pmd_entry(pmd);
+ if (PHYS_OFFSET != PAGE_OFFSET) {
+#ifndef CONFIG_HOTPLUG_CPU
+ identity_mapping_del(pgd, __pa(__init_begin), __pa(__init_end));
+#endif
+ identity_mapping_del(pgd, __pa(_stext), __pa(_etext));
+ identity_mapping_del(pgd, __pa(_sdata), __pa(_edata));
+ }
+
pgd_free(&init_mm, pgd);
if (ret) {
@@ -567,7 +614,8 @@ void smp_send_stop(void)
{
cpumask_t mask = cpu_online_map;
cpu_clear(smp_processor_id(), mask);
- send_ipi_message(&mask, IPI_CPU_STOP);
+ if (!cpus_empty(mask))
+ send_ipi_message(&mask, IPI_CPU_STOP);
}
/*
diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
index dd81a918c106..2a161765f6d5 100644
--- a/arch/arm/kernel/unwind.c
+++ b/arch/arm/kernel/unwind.c
@@ -146,6 +146,8 @@ static struct unwind_idx *unwind_find_idx(unsigned long addr)
addr < table->end_addr) {
idx = search_index(addr, table->start,
table->stop - 1);
+ /* Move-to-front to exploit common traces */
+ list_move(&table->list, &unwind_tables);
break;
}
}
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index b16c07914b55..1953e3d21abf 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -8,6 +8,19 @@
#include <asm/memory.h>
#include <asm/page.h>
+#define PROC_INFO \
+ VMLINUX_SYMBOL(__proc_info_begin) = .; \
+ *(.proc.info.init) \
+ VMLINUX_SYMBOL(__proc_info_end) = .;
+
+#ifdef CONFIG_HOTPLUG_CPU
+#define ARM_CPU_DISCARD(x)
+#define ARM_CPU_KEEP(x) x
+#else
+#define ARM_CPU_DISCARD(x) x
+#define ARM_CPU_KEEP(x)
+#endif
+
OUTPUT_ARCH(arm)
ENTRY(stext)
@@ -31,15 +44,18 @@ SECTIONS
HEAD_TEXT
INIT_TEXT
_einittext = .;
- __proc_info_begin = .;
- *(.proc.info.init)
- __proc_info_end = .;
+ ARM_CPU_DISCARD(PROC_INFO)
__arch_info_begin = .;
*(.arch.info.init)
__arch_info_end = .;
__tagtable_begin = .;
*(.taglist.init)
__tagtable_end = .;
+#ifdef CONFIG_SMP_ON_UP
+ __smpalt_begin = .;
+ *(.alt.smp.init)
+ __smpalt_end = .;
+#endif
INIT_SETUP(16)
@@ -68,10 +84,8 @@ SECTIONS
/DISCARD/ : {
*(.ARM.exidx.exit.text)
*(.ARM.extab.exit.text)
-#ifndef CONFIG_HOTPLUG_CPU
- *(.ARM.exidx.cpuexit.text)
- *(.ARM.extab.cpuexit.text)
-#endif
+ ARM_CPU_DISCARD(*(.ARM.exidx.cpuexit.text))
+ ARM_CPU_DISCARD(*(.ARM.extab.cpuexit.text))
#ifndef CONFIG_HOTPLUG
*(.ARM.exidx.devexit.text)
*(.ARM.extab.devexit.text)
@@ -100,12 +114,11 @@ SECTIONS
*(.glue_7)
*(.glue_7t)
*(.got) /* Global offset table */
+ ARM_CPU_KEEP(PROC_INFO)
}
RO_DATA(PAGE_SIZE)
- _etext = .; /* End of text and rodata section */
-
#ifdef CONFIG_ARM_UNWIND
/*
* Stack unwinding tables
@@ -123,6 +136,8 @@ SECTIONS
}
#endif
+ _etext = .; /* End of text and rodata section */
+
#ifdef CONFIG_XIP_KERNEL
__data_loc = ALIGN(4); /* location in binary */
. = PAGE_OFFSET + TEXT_OFFSET;
@@ -237,6 +252,12 @@ SECTIONS
/* Default discards */
DISCARDS
+
+#ifndef CONFIG_SMP_ON_UP
+ /DISCARD/ : {
+ *(.alt.smp.init)
+ }
+#endif
}
/*
diff --git a/arch/arm/mach-aaec2000/aaed2000.c b/arch/arm/mach-aaec2000/aaed2000.c
index 81a3ecc0d104..0eb3e3e5b2d1 100644
--- a/arch/arm/mach-aaec2000/aaed2000.c
+++ b/arch/arm/mach-aaec2000/aaed2000.c
@@ -95,8 +95,6 @@ static void __init aaed2000_map_io(void)
MACHINE_START(AAED2000, "Agilent AAED-2000 Development Platform")
/* Maintainer: Nicolas Bellido Y Ortega */
- .phys_io = PIO_BASE,
- .io_pg_offst = ((VIO_BASE) >> 18) & 0xfffc,
.map_io = aaed2000_map_io,
.init_irq = aaed2000_init_irq,
.timer = &aaec2000_timer,
diff --git a/arch/arm/mach-aaec2000/include/mach/debug-macro.S b/arch/arm/mach-aaec2000/include/mach/debug-macro.S
index a9cac368bfe6..bc7ad5561c4c 100644
--- a/arch/arm/mach-aaec2000/include/mach/debug-macro.S
+++ b/arch/arm/mach-aaec2000/include/mach/debug-macro.S
@@ -10,12 +10,10 @@
*/
#include "hardware.h"
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- moveq \rx, #0x80000000 @ physical
- movne \rx, #io_p2v(0x80000000) @ virtual
- orr \rx, \rx, #0x00000800
+ .macro addruart, rp, rv
+ mov \rp, 0x00000800
+ orr \rv, \rp, #io_p2v(0x80000000) @ virtual
+ orr \rp, \rp, #0x80000000 @ physical
.endm
.macro senduart,rd,rx
diff --git a/arch/arm/mach-aaec2000/include/mach/vmalloc.h b/arch/arm/mach-aaec2000/include/mach/vmalloc.h
index 551f68f666bf..cff4e0a996ce 100644
--- a/arch/arm/mach-aaec2000/include/mach/vmalloc.h
+++ b/arch/arm/mach-aaec2000/include/mach/vmalloc.h
@@ -11,6 +11,6 @@
#ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H
-#define VMALLOC_END (PAGE_OFFSET + 0x10000000)
+#define VMALLOC_END 0xd0000000
#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 939bccd70569..abed4d15a7fd 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -33,6 +33,7 @@ config ARCH_AT91SAM9260
select HAVE_AT91_USART3
select HAVE_AT91_USART4
select HAVE_AT91_USART5
+ select HAVE_NET_MACB
config ARCH_AT91SAM9261
bool "AT91SAM9261"
@@ -51,6 +52,7 @@ config ARCH_AT91SAM9263
select CPU_ARM926T
select GENERIC_CLOCKEVENTS
select HAVE_FB_ATMEL
+ select HAVE_NET_MACB
config ARCH_AT91SAM9RL
bool "AT91SAM9RL"
@@ -66,6 +68,7 @@ config ARCH_AT91SAM9G20
select HAVE_AT91_USART3
select HAVE_AT91_USART4
select HAVE_AT91_USART5
+ select HAVE_NET_MACB
config ARCH_AT91SAM9G45
bool "AT91SAM9G45"
@@ -73,6 +76,7 @@ config ARCH_AT91SAM9G45
select GENERIC_CLOCKEVENTS
select HAVE_AT91_USART3
select HAVE_FB_ATMEL
+ select HAVE_NET_MACB
config ARCH_AT91CAP9
bool "AT91CAP9"
@@ -105,7 +109,7 @@ config MACH_ONEARM
bool "Ajeco 1ARM Single Board Computer"
help
Select this if you are using Ajeco's 1ARM Single Board Computer.
- <http://www.ajeco.fi/products.htm>
+ <http://www.ajeco.fi/>
config ARCH_AT91RM9200DK
bool "Atmel AT91RM9200-DK Development board"
@@ -137,7 +141,7 @@ config MACH_CARMEVA
bool "Conitec ARM&EVA"
help
Select this if you are using Conitec's AT91RM9200-MCU-Module.
- <http://www.conitec.net/english/linuxboard.htm>
+ <http://www.conitec.net/english/linuxboard.php>
config MACH_ATEB9200
bool "Embest ATEB9200"
@@ -149,7 +153,7 @@ config MACH_KB9200
bool "KwikByte KB920x"
help
Select this if you are using KwikByte's KB920x board.
- <http://kwikbyte.com/KB9202_description_new.htm>
+ <http://www.kwikbyte.com/KB9202.html>
config MACH_PICOTUX2XX
bool "picotux 200"
@@ -248,6 +252,12 @@ config MACH_CPU9260
Select this if you are using a Eukrea Electromatique's
CPU9260 Board <http://www.eukrea.com/>
+config MACH_FLEXIBITY
+ bool "Flexibity Connect board"
+ help
+ Select this if you are using Flexibity Connect board
+ <http://www.flexibity.com>
+
endif
# ----------------------------------------------------------
@@ -338,6 +348,7 @@ config MACH_AT91SAM9G20EK
that embeds only one SD/MMC slot.
config MACH_AT91SAM9G20EK_2MMC
+ depends on MACH_AT91SAM9G20EK
bool "Atmel AT91SAM9G20-EK Evaluation Kit with 2 SD/MMC Slots"
select HAVE_NAND_ATMEL_BUSWIDTH_16
help
@@ -383,8 +394,8 @@ if ARCH_AT91SAM9G45
comment "AT91SAM9G45 Board Type"
-config MACH_AT91SAM9G45EKES
- bool "Atmel AT91SAM9G45-EKES Evaluation Kit"
+config MACH_AT91SAM9M10G45EK
+ bool "Atmel AT91SAM9M10G45-EK Evaluation Kits"
select HAVE_NAND_ATMEL_BUSWIDTH_16
help
Select this if you are using Atmel's AT91SAM9G45-EKES Evaluation Kit.
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index ca2ac003f41f..412b3a471a4b 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_MACH_USB_A9260) += board-usb-a9260.o
obj-$(CONFIG_MACH_QIL_A9260) += board-qil-a9260.o
obj-$(CONFIG_MACH_AFEB9260) += board-afeb-9260v1.o
obj-$(CONFIG_MACH_CPU9260) += board-cpu9krea.o
+obj-$(CONFIG_MACH_FLEXIBITY) += board-flexibity.o
# AT91SAM9261 board-specific support
obj-$(CONFIG_MACH_AT91SAM9261EK) += board-sam9261ek.o
@@ -61,7 +62,6 @@ obj-$(CONFIG_MACH_AT91SAM9RLEK) += board-sam9rlek.o
# AT91SAM9G20 board-specific support
obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o
-obj-$(CONFIG_MACH_AT91SAM9G20EK_2MMC) += board-sam9g20ek-2slot-mmc.o
obj-$(CONFIG_MACH_CPU9G20) += board-cpu9krea.o
obj-$(CONFIG_MACH_STAMP9G20) += board-stamp9g20.o
obj-$(CONFIG_MACH_PORTUXG20) += board-stamp9g20.o
@@ -70,7 +70,7 @@ obj-$(CONFIG_MACH_PORTUXG20) += board-stamp9g20.o
obj-$(CONFIG_MACH_SNAPPER_9260) += board-snapper9260.o
# AT91SAM9G45 board-specific support
-obj-$(CONFIG_MACH_AT91SAM9G45EKES) += board-sam9m10g45ek.o
+obj-$(CONFIG_MACH_AT91SAM9M10G45EK) += board-sam9m10g45ek.o
# AT91CAP9 board-specific support
obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o
diff --git a/arch/arm/mach-at91/board-1arm.c b/arch/arm/mach-at91/board-1arm.c
index 9b27d167bff0..46bdc82d3fbf 100644
--- a/arch/arm/mach-at91/board-1arm.c
+++ b/arch/arm/mach-at91/board-1arm.c
@@ -92,8 +92,6 @@ static void __init onearm_board_init(void)
MACHINE_START(ONEARM, "Ajeco 1ARM single board computer")
/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91rm9200_timer,
.map_io = onearm_map_io,
diff --git a/arch/arm/mach-at91/board-afeb-9260v1.c b/arch/arm/mach-at91/board-afeb-9260v1.c
index 50667bed7cc9..cba7f7771fee 100644
--- a/arch/arm/mach-at91/board-afeb-9260v1.c
+++ b/arch/arm/mach-at91/board-afeb-9260v1.c
@@ -218,8 +218,6 @@ static void __init afeb9260_board_init(void)
MACHINE_START(AFEB9260, "Custom afeb9260 board")
/* Maintainer: Sergey Lapin <slapin@ossfans.org> */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91sam926x_timer,
.map_io = afeb9260_map_io,
diff --git a/arch/arm/mach-at91/board-at572d940hf_ek.c b/arch/arm/mach-at91/board-at572d940hf_ek.c
index 5daff277f53e..3929f1c9e4e5 100644
--- a/arch/arm/mach-at91/board-at572d940hf_ek.c
+++ b/arch/arm/mach-at91/board-at572d940hf_ek.c
@@ -216,7 +216,7 @@ static struct atmel_nand_data __initdata eb_nand_data = {
/* .rdy_pin = AT91_PIN_PC16, */
.enable_pin = AT91_PIN_PA15,
.partition_info = nand_partitions,
-#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
+#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
.bus_width_16 = 1,
#else
.bus_width_16 = 0,
@@ -318,8 +318,6 @@ static void __init eb_board_init(void)
MACHINE_START(AT572D940HFEB, "Atmel AT91D940HF-EB")
/* Maintainer: Atmel <costa.antonior@gmail.com> */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91sam926x_timer,
.map_io = eb_map_io,
diff --git a/arch/arm/mach-at91/board-cam60.c b/arch/arm/mach-at91/board-cam60.c
index 44eb9f764938..b54e3e6fceb6 100644
--- a/arch/arm/mach-at91/board-cam60.c
+++ b/arch/arm/mach-at91/board-cam60.c
@@ -198,8 +198,6 @@ static void __init cam60_board_init(void)
MACHINE_START(CAM60, "KwikByte CAM60")
/* Maintainer: KwikByte */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91sam926x_timer,
.map_io = cam60_map_io,
diff --git a/arch/arm/mach-at91/board-cap9adk.c b/arch/arm/mach-at91/board-cap9adk.c
index d6940870e403..e7274440ead9 100644
--- a/arch/arm/mach-at91/board-cap9adk.c
+++ b/arch/arm/mach-at91/board-cap9adk.c
@@ -399,8 +399,6 @@ static void __init cap9adk_board_init(void)
MACHINE_START(AT91CAP9ADK, "Atmel AT91CAP9A-DK")
/* Maintainer: Stelian Pop <stelian.pop@leadtechdesign.com> */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91sam926x_timer,
.map_io = cap9adk_map_io,
diff --git a/arch/arm/mach-at91/board-carmeva.c b/arch/arm/mach-at91/board-carmeva.c
index db1f9544d2e0..2e74a19874d1 100644
--- a/arch/arm/mach-at91/board-carmeva.c
+++ b/arch/arm/mach-at91/board-carmeva.c
@@ -162,8 +162,6 @@ static void __init carmeva_board_init(void)
MACHINE_START(CARMEVA, "Carmeva")
/* Maintainer: Conitec Datasystems */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91rm9200_timer,
.map_io = carmeva_map_io,
diff --git a/arch/arm/mach-at91/board-cpu9krea.c b/arch/arm/mach-at91/board-cpu9krea.c
index 4bc2e9f6ebb5..3838594578f3 100644
--- a/arch/arm/mach-at91/board-cpu9krea.c
+++ b/arch/arm/mach-at91/board-cpu9krea.c
@@ -375,8 +375,6 @@ MACHINE_START(CPUAT9260, "Eukrea CPU9260")
MACHINE_START(CPUAT9G20, "Eukrea CPU9G20")
#endif
/* Maintainer: Eric Benard - EUKREA Electromatique */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91sam926x_timer,
.map_io = cpu9krea_map_io,
diff --git a/arch/arm/mach-at91/board-cpuat91.c b/arch/arm/mach-at91/board-cpuat91.c
index a28d99656190..2f4dd8cdd484 100644
--- a/arch/arm/mach-at91/board-cpuat91.c
+++ b/arch/arm/mach-at91/board-cpuat91.c
@@ -175,8 +175,6 @@ static void __init cpuat91_board_init(void)
MACHINE_START(CPUAT91, "Eukrea")
/* Maintainer: Eric Benard - EUKREA Electromatique */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91rm9200_timer,
.map_io = cpuat91_map_io,
diff --git a/arch/arm/mach-at91/board-csb337.c b/arch/arm/mach-at91/board-csb337.c
index fea2529ebcf9..464839dc39bd 100644
--- a/arch/arm/mach-at91/board-csb337.c
+++ b/arch/arm/mach-at91/board-csb337.c
@@ -257,8 +257,6 @@ static void __init csb337_board_init(void)
MACHINE_START(CSB337, "Cogent CSB337")
/* Maintainer: Bill Gatliff */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91rm9200_timer,
.map_io = csb337_map_io,
diff --git a/arch/arm/mach-at91/board-csb637.c b/arch/arm/mach-at91/board-csb637.c
index cfa3f04b2205..431688c61412 100644
--- a/arch/arm/mach-at91/board-csb637.c
+++ b/arch/arm/mach-at91/board-csb637.c
@@ -138,8 +138,6 @@ static void __init csb637_board_init(void)
MACHINE_START(CSB637, "Cogent CSB637")
/* Maintainer: Bill Gatliff */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91rm9200_timer,
.map_io = csb637_map_io,
diff --git a/arch/arm/mach-at91/board-dk.c b/arch/arm/mach-at91/board-dk.c
index 0fd0f5bc77ea..e14f0e165680 100644
--- a/arch/arm/mach-at91/board-dk.c
+++ b/arch/arm/mach-at91/board-dk.c
@@ -225,8 +225,6 @@ static void __init dk_board_init(void)
MACHINE_START(AT91RM9200DK, "Atmel AT91RM9200-DK")
/* Maintainer: SAN People/Atmel */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91rm9200_timer,
.map_io = dk_map_io,
diff --git a/arch/arm/mach-at91/board-eb9200.c b/arch/arm/mach-at91/board-eb9200.c
index 528656761ff7..6cf6566ae346 100644
--- a/arch/arm/mach-at91/board-eb9200.c
+++ b/arch/arm/mach-at91/board-eb9200.c
@@ -120,8 +120,6 @@ static void __init eb9200_board_init(void)
}
MACHINE_START(ATEB9200, "Embest ATEB9200")
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91rm9200_timer,
.map_io = eb9200_map_io,
diff --git a/arch/arm/mach-at91/board-ecbat91.c b/arch/arm/mach-at91/board-ecbat91.c
index 1d69908617f0..7b58c948a957 100644
--- a/arch/arm/mach-at91/board-ecbat91.c
+++ b/arch/arm/mach-at91/board-ecbat91.c
@@ -168,8 +168,6 @@ static void __init ecb_at91board_init(void)
MACHINE_START(ECBAT91, "emQbit's ECB_AT91")
/* Maintainer: emQbit.com */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91rm9200_timer,
.map_io = ecb_at91map_io,
diff --git a/arch/arm/mach-at91/board-eco920.c b/arch/arm/mach-at91/board-eco920.c
index 295a96609e71..a158a0ce458f 100644
--- a/arch/arm/mach-at91/board-eco920.c
+++ b/arch/arm/mach-at91/board-eco920.c
@@ -148,8 +148,6 @@ static void __init eco920_board_init(void)
MACHINE_START(ECO920, "eco920")
/* Maintainer: Sascha Hauer */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91rm9200_timer,
.map_io = eco920_map_io,
diff --git a/arch/arm/mach-at91/board-ek.c b/arch/arm/mach-at91/board-ek.c
index 4cdfaac8e590..56e92c4bbc2a 100644
--- a/arch/arm/mach-at91/board-ek.c
+++ b/arch/arm/mach-at91/board-ek.c
@@ -191,8 +191,6 @@ static void __init ek_board_init(void)
MACHINE_START(AT91RM9200EK, "Atmel AT91RM9200-EK")
/* Maintainer: SAN People/Atmel */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91rm9200_timer,
.map_io = ek_map_io,
diff --git a/arch/arm/mach-at91/board-flexibity.c b/arch/arm/mach-at91/board-flexibity.c
new file mode 100644
index 000000000000..c8a62dc8fa65
--- /dev/null
+++ b/arch/arm/mach-at91/board-flexibity.c
@@ -0,0 +1,162 @@
+/*
+ * linux/arch/arm/mach-at91/board-flexibity.c
+ *
+ * Copyright (C) 2010 Flexibity
+ * Copyright (C) 2005 SAN People
+ * Copyright (C) 2006 Atmel
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/board.h>
+
+#include "generic.h"
+
+static void __init flexibity_map_io(void)
+{
+ /* Initialize processor: 18.432 MHz crystal */
+ at91sam9260_initialize(18432000);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init flexibity_init_irq(void)
+{
+ at91sam9260_init_interrupts(NULL);
+}
+
+/* USB Host port */
+static struct at91_usbh_data __initdata flexibity_usbh_data = {
+ .ports = 2,
+};
+
+/* USB Device port */
+static struct at91_udc_data __initdata flexibity_udc_data = {
+ .vbus_pin = AT91_PIN_PC5,
+ .pullup_pin = 0, /* pull-up driven by UDC */
+};
+
+/* SPI devices */
+static struct spi_board_info flexibity_spi_devices[] = {
+ { /* DataFlash chip */
+ .modalias = "mtd_dataflash",
+ .chip_select = 1,
+ .max_speed_hz = 15 * 1000 * 1000,
+ .bus_num = 0,
+ },
+};
+
+/* MCI (SD/MMC) */
+static struct at91_mmc_data __initdata flexibity_mmc_data = {
+ .slot_b = 0,
+ .wire4 = 1,
+ .det_pin = AT91_PIN_PC9,
+ .wp_pin = AT91_PIN_PC4,
+};
+
+/* LEDs */
+static struct gpio_led flexibity_leds[] = {
+ {
+ .name = "usb1:green",
+ .gpio = AT91_PIN_PA12,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "usb1:red",
+ .gpio = AT91_PIN_PA13,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "usb2:green",
+ .gpio = AT91_PIN_PB26,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "usb2:red",
+ .gpio = AT91_PIN_PB27,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "usb3:green",
+ .gpio = AT91_PIN_PC8,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "usb3:red",
+ .gpio = AT91_PIN_PC6,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "usb4:green",
+ .gpio = AT91_PIN_PB4,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "usb4:red",
+ .gpio = AT91_PIN_PB5,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ }
+};
+
+static void __init flexibity_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* USB Host */
+ at91_add_device_usbh(&flexibity_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&flexibity_udc_data);
+ /* SPI */
+ at91_add_device_spi(flexibity_spi_devices,
+ ARRAY_SIZE(flexibity_spi_devices));
+ /* MMC */
+ at91_add_device_mmc(0, &flexibity_mmc_data);
+ /* LEDs */
+ at91_gpio_leds(flexibity_leds, ARRAY_SIZE(flexibity_leds));
+}
+
+MACHINE_START(FLEXIBITY, "Flexibity Connect")
+ /* Maintainer: Maxim Osipov */
+ .boot_params = AT91_SDRAM_BASE + 0x100,
+ .timer = &at91sam926x_timer,
+ .map_io = flexibity_map_io,
+ .init_irq = flexibity_init_irq,
+ .init_machine = flexibity_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-kafa.c b/arch/arm/mach-at91/board-kafa.c
index a87956c0a74f..c0ce79d431a0 100644
--- a/arch/arm/mach-at91/board-kafa.c
+++ b/arch/arm/mach-at91/board-kafa.c
@@ -99,8 +99,6 @@ static void __init kafa_board_init(void)
MACHINE_START(KAFA, "Sperry-Sun KAFA")
/* Maintainer: Sergei Sharonov */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91rm9200_timer,
.map_io = kafa_map_io,
diff --git a/arch/arm/mach-at91/board-kb9202.c b/arch/arm/mach-at91/board-kb9202.c
index fe9b9913fa3c..a13d2063faff 100644
--- a/arch/arm/mach-at91/board-kb9202.c
+++ b/arch/arm/mach-at91/board-kb9202.c
@@ -136,8 +136,6 @@ static void __init kb9202_board_init(void)
MACHINE_START(KB9200, "KB920x")
/* Maintainer: KwikByte, Inc. */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91rm9200_timer,
.map_io = kb9202_map_io,
diff --git a/arch/arm/mach-at91/board-neocore926.c b/arch/arm/mach-at91/board-neocore926.c
index 7c1e382330fb..fe5f1d47e6e2 100644
--- a/arch/arm/mach-at91/board-neocore926.c
+++ b/arch/arm/mach-at91/board-neocore926.c
@@ -387,8 +387,6 @@ static void __init neocore926_board_init(void)
MACHINE_START(NEOCORE926, "ADENEO NEOCORE 926")
/* Maintainer: ADENEO */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91sam926x_timer,
.map_io = neocore926_map_io,
diff --git a/arch/arm/mach-at91/board-picotux200.c b/arch/arm/mach-at91/board-picotux200.c
index 859727e7ea30..9d833bbc592d 100644
--- a/arch/arm/mach-at91/board-picotux200.c
+++ b/arch/arm/mach-at91/board-picotux200.c
@@ -156,8 +156,6 @@ static void __init picotux200_board_init(void)
MACHINE_START(PICOTUX2XX, "picotux 200")
/* Maintainer: Kleinhenz Elektronik GmbH */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91rm9200_timer,
.map_io = picotux200_map_io,
diff --git a/arch/arm/mach-at91/board-qil-a9260.c b/arch/arm/mach-at91/board-qil-a9260.c
index 664938e8f661..69d15a875b66 100644
--- a/arch/arm/mach-at91/board-qil-a9260.c
+++ b/arch/arm/mach-at91/board-qil-a9260.c
@@ -268,8 +268,6 @@ static void __init ek_board_init(void)
MACHINE_START(QIL_A9260, "CALAO QIL_A9260")
/* Maintainer: calao-systems */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91sam926x_timer,
.map_io = ek_map_io,
diff --git a/arch/arm/mach-at91/board-sam9-l9260.c b/arch/arm/mach-at91/board-sam9-l9260.c
index b48346977534..25a26beaa728 100644
--- a/arch/arm/mach-at91/board-sam9-l9260.c
+++ b/arch/arm/mach-at91/board-sam9-l9260.c
@@ -212,8 +212,6 @@ static void __init ek_board_init(void)
MACHINE_START(SAM9_L9260, "Olimex SAM9-L9260")
/* Maintainer: Olimex */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91sam926x_timer,
.map_io = ek_map_io,
diff --git a/arch/arm/mach-at91/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c
index ba9d501b5c50..de1816e0e1d9 100644
--- a/arch/arm/mach-at91/board-sam9260ek.c
+++ b/arch/arm/mach-at91/board-sam9260ek.c
@@ -356,8 +356,6 @@ static void __init ek_board_init(void)
MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK")
/* Maintainer: Atmel */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91sam926x_timer,
.map_io = ek_map_io,
diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c
index 65eb0943194f..14acc901e24c 100644
--- a/arch/arm/mach-at91/board-sam9261ek.c
+++ b/arch/arm/mach-at91/board-sam9261ek.c
@@ -623,8 +623,6 @@ MACHINE_START(AT91SAM9261EK, "Atmel AT91SAM9261-EK")
MACHINE_START(AT91SAM9G10EK, "Atmel AT91SAM9G10-EK")
#endif
/* Maintainer: Atmel */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91sam926x_timer,
.map_io = ek_map_io,
diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c
index 2d867fb0630f..bfe490df58be 100644
--- a/arch/arm/mach-at91/board-sam9263ek.c
+++ b/arch/arm/mach-at91/board-sam9263ek.c
@@ -454,8 +454,6 @@ static void __init ek_board_init(void)
MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK")
/* Maintainer: Atmel */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91sam926x_timer,
.map_io = ek_map_io,
diff --git a/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c b/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c
deleted file mode 100644
index c49f5c003ee1..000000000000
--- a/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * Copyright (C) 2005 SAN People
- * Copyright (C) 2008 Atmel
- * Copyright (C) 2009 Rob Emanuele
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/at73c213.h>
-#include <linux/clk.h>
-#include <linux/regulator/machine.h>
-#include <linux/regulator/fixed.h>
-#include <linux/regulator/consumer.h>
-
-#include <mach/hardware.h>
-#include <asm/setup.h>
-#include <asm/mach-types.h>
-#include <asm/irq.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/board.h>
-#include <mach/gpio.h>
-#include <mach/at91sam9_smc.h>
-
-#include "sam9_smc.h"
-#include "generic.h"
-
-
-static void __init ek_map_io(void)
-{
- /* Initialize processor: 18.432 MHz crystal */
- at91sam9260_initialize(18432000);
-
- /* DGBU on ttyS0. (Rx & Tx only) */
- at91_register_uart(0, 0, 0);
-
- /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
- at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
- | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
- | ATMEL_UART_RI);
-
- /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */
- at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS);
-
- /* set serial console to ttyS0 (ie, DBGU) */
- at91_set_serial_console(0);
-}
-
-static void __init ek_init_irq(void)
-{
- at91sam9260_init_interrupts(NULL);
-}
-
-
-/*
- * USB Host port
- */
-static struct at91_usbh_data __initdata ek_usbh_data = {
- .ports = 2,
-};
-
-/*
- * USB Device port
- */
-static struct at91_udc_data __initdata ek_udc_data = {
- .vbus_pin = AT91_PIN_PC5,
- .pullup_pin = 0, /* pull-up driven by UDC */
-};
-
-
-/*
- * SPI devices.
- */
-static struct spi_board_info ek_spi_devices[] = {
-#if !(defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_AT91))
- { /* DataFlash chip */
- .modalias = "mtd_dataflash",
- .chip_select = 1,
- .max_speed_hz = 15 * 1000 * 1000,
- .bus_num = 0,
- },
-#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
- { /* DataFlash card */
- .modalias = "mtd_dataflash",
- .chip_select = 0,
- .max_speed_hz = 15 * 1000 * 1000,
- .bus_num = 0,
- },
-#endif
-#endif
-};
-
-
-/*
- * MACB Ethernet device
- */
-static struct at91_eth_data __initdata ek_macb_data = {
- .phy_irq_pin = AT91_PIN_PB0,
- .is_rmii = 1,
-};
-
-
-/*
- * NAND flash
- */
-static struct mtd_partition __initdata ek_nand_partition[] = {
- {
- .name = "Bootstrap",
- .offset = 0,
- .size = 4 * SZ_1M,
- },
- {
- .name = "Partition 1",
- .offset = MTDPART_OFS_NXTBLK,
- .size = 60 * SZ_1M,
- },
- {
- .name = "Partition 2",
- .offset = MTDPART_OFS_NXTBLK,
- .size = MTDPART_SIZ_FULL,
- },
-};
-
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
- *num_partitions = ARRAY_SIZE(ek_nand_partition);
- return ek_nand_partition;
-}
-
-/* det_pin is not connected */
-static struct atmel_nand_data __initdata ek_nand_data = {
- .ale = 21,
- .cle = 22,
- .rdy_pin = AT91_PIN_PC13,
- .enable_pin = AT91_PIN_PC14,
- .partition_info = nand_partitions,
-#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
- .bus_width_16 = 1,
-#else
- .bus_width_16 = 0,
-#endif
-};
-
-static struct sam9_smc_config __initdata ek_nand_smc_config = {
- .ncs_read_setup = 0,
- .nrd_setup = 2,
- .ncs_write_setup = 0,
- .nwe_setup = 2,
-
- .ncs_read_pulse = 4,
- .nrd_pulse = 4,
- .ncs_write_pulse = 4,
- .nwe_pulse = 4,
-
- .read_cycle = 7,
- .write_cycle = 7,
-
- .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE,
- .tdf_cycles = 3,
-};
-
-static void __init ek_add_device_nand(void)
-{
- /* setup bus-width (8 or 16) */
- if (ek_nand_data.bus_width_16)
- ek_nand_smc_config.mode |= AT91_SMC_DBW_16;
- else
- ek_nand_smc_config.mode |= AT91_SMC_DBW_8;
-
- /* configure chip-select 3 (NAND) */
- sam9_smc_configure(3, &ek_nand_smc_config);
-
- at91_add_device_nand(&ek_nand_data);
-}
-
-
-/*
- * MCI (SD/MMC)
- * wp_pin is not connected
- */
-#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
-static struct mci_platform_data __initdata ek_mmc_data = {
- .slot[0] = {
- .bus_width = 4,
- .detect_pin = AT91_PIN_PC2,
- .wp_pin = -ENODEV,
- },
- .slot[1] = {
- .bus_width = 4,
- .detect_pin = AT91_PIN_PC9,
- .wp_pin = -ENODEV,
- },
-
-};
-#else
-static struct at91_mmc_data __initdata ek_mmc_data = {
- .slot_b = 1, /* Only one slot so use slot B */
- .wire4 = 1,
- .det_pin = AT91_PIN_PC9,
-};
-#endif
-
-/*
- * LEDs
- */
-static struct gpio_led ek_leds[] = {
- { /* "bottom" led, green, userled1 to be defined */
- .name = "ds5",
- .gpio = AT91_PIN_PB8,
- .active_low = 1,
- .default_trigger = "none",
- },
- { /* "power" led, yellow */
- .name = "ds1",
- .gpio = AT91_PIN_PB9,
- .default_trigger = "heartbeat",
- }
-};
-
-#if defined(CONFIG_REGULATOR_FIXED_VOLTAGE) || defined(CONFIG_REGULATOR_FIXED_VOLTAGE_MODULE)
-static struct regulator_consumer_supply ek_audio_consumer_supplies[] = {
- REGULATOR_SUPPLY("AVDD", "0-001b"),
- REGULATOR_SUPPLY("HPVDD", "0-001b"),
- REGULATOR_SUPPLY("DBVDD", "0-001b"),
- REGULATOR_SUPPLY("DCVDD", "0-001b"),
-};
-
-static struct regulator_init_data ek_avdd_reg_init_data = {
- .constraints = {
- .name = "3V3",
- .valid_ops_mask = REGULATOR_CHANGE_STATUS,
- },
- .consumer_supplies = ek_audio_consumer_supplies,
- .num_consumer_supplies = ARRAY_SIZE(ek_audio_consumer_supplies),
-};
-
-static struct fixed_voltage_config ek_vdd_pdata = {
- .supply_name = "board-3V3",
- .microvolts = 3300000,
- .gpio = -EINVAL,
- .enabled_at_boot = 0,
- .init_data = &ek_avdd_reg_init_data,
-};
-static struct platform_device ek_voltage_regulator = {
- .name = "reg-fixed-voltage",
- .id = -1,
- .num_resources = 0,
- .dev = {
- .platform_data = &ek_vdd_pdata,
- },
-};
-static void __init ek_add_regulators(void)
-{
- platform_device_register(&ek_voltage_regulator);
-}
-#else
-static void __init ek_add_regulators(void) {}
-#endif
-
-static struct i2c_board_info __initdata ek_i2c_devices[] = {
- {
- I2C_BOARD_INFO("24c512", 0x50),
- },
-};
-
-
-static void __init ek_board_init(void)
-{
- /* Serial */
- at91_add_device_serial();
- /* USB Host */
- at91_add_device_usbh(&ek_usbh_data);
- /* USB Device */
- at91_add_device_udc(&ek_udc_data);
- /* SPI */
- at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
- /* NAND */
- ek_add_device_nand();
- /* Ethernet */
- at91_add_device_eth(&ek_macb_data);
- /* Regulators */
- ek_add_regulators();
- /* MMC */
-#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
- at91_add_device_mci(0, &ek_mmc_data);
-#else
- at91_add_device_mmc(0, &ek_mmc_data);
-#endif
- /* I2C */
- at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices));
- /* LEDs */
- at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
- /* PCK0 provides MCLK to the WM8731 */
- at91_set_B_periph(AT91_PIN_PC1, 0);
- /* SSC (for WM8731) */
- at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX);
-}
-
-MACHINE_START(AT91SAM9G20EK_2MMC, "Atmel AT91SAM9G20-EK 2 MMC Slot Mod")
- /* Maintainer: Rob Emanuele */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
- .boot_params = AT91_SDRAM_BASE + 0x100,
- .timer = &at91sam926x_timer,
- .map_io = ek_map_io,
- .init_irq = ek_init_irq,
- .init_machine = ek_board_init,
-MACHINE_END
diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c
index 6ea9808b8868..ca8198b3c168 100644
--- a/arch/arm/mach-at91/board-sam9g20ek.c
+++ b/arch/arm/mach-at91/board-sam9g20ek.c
@@ -47,6 +47,18 @@
#include "sam9_smc.h"
#include "generic.h"
+/*
+ * board revision encoding
+ * bit 0:
+ * 0 => 1 sd/mmc slot
+ * 1 => 2 sd/mmc slots connectors (board from revision C)
+ */
+#define HAVE_2MMC (1 << 0)
+static int inline ek_have_2mmc(void)
+{
+ return machine_is_at91sam9g20ek_2mmc() || (system_rev & HAVE_2MMC);
+}
+
static void __init ek_map_io(void)
{
@@ -94,7 +106,7 @@ static struct at91_udc_data __initdata ek_udc_data = {
* SPI devices.
*/
static struct spi_board_info ek_spi_devices[] = {
-#if !defined(CONFIG_MMC_AT91)
+#if !(defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_AT91))
{ /* DataFlash chip */
.modalias = "mtd_dataflash",
.chip_select = 1,
@@ -121,6 +133,13 @@ static struct at91_eth_data __initdata ek_macb_data = {
.is_rmii = 1,
};
+static void __init ek_add_device_macb(void)
+{
+ if (ek_have_2mmc())
+ ek_macb_data.phy_irq_pin = AT91_PIN_PB0;
+
+ at91_add_device_eth(&ek_macb_data);
+}
/*
* NAND flash
@@ -198,13 +217,36 @@ static void __init ek_add_device_nand(void)
/*
* MCI (SD/MMC)
- * det_pin, wp_pin and vcc_pin are not connected
+ * wp_pin and vcc_pin are not connected
*/
+#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
+static struct mci_platform_data __initdata ek_mmc_data = {
+ .slot[1] = {
+ .bus_width = 4,
+ .detect_pin = AT91_PIN_PC9,
+ },
+
+};
+#else
static struct at91_mmc_data __initdata ek_mmc_data = {
- .slot_b = 1,
+ .slot_b = 1, /* Only one slot so use slot B */
.wire4 = 1,
+ .det_pin = AT91_PIN_PC9,
};
+#endif
+static void __init ek_add_device_mmc(void)
+{
+#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
+ if (ek_have_2mmc()) {
+ ek_mmc_data.slot[0].bus_width = 4;
+ ek_mmc_data.slot[0].detect_pin = AT91_PIN_PC2;
+ }
+ at91_add_device_mci(0, &ek_mmc_data);
+#else
+ at91_add_device_mmc(0, &ek_mmc_data);
+#endif
+}
/*
* LEDs
@@ -223,6 +265,15 @@ static struct gpio_led ek_leds[] = {
}
};
+static void __init ek_add_device_gpio_leds(void)
+{
+ if (ek_have_2mmc()) {
+ ek_leds[0].gpio = AT91_PIN_PB8;
+ ek_leds[1].gpio = AT91_PIN_PB9;
+ }
+
+ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+}
/*
* GPIO Buttons
@@ -336,15 +387,15 @@ static void __init ek_board_init(void)
/* NAND */
ek_add_device_nand();
/* Ethernet */
- at91_add_device_eth(&ek_macb_data);
+ ek_add_device_macb();
/* Regulators */
ek_add_regulators();
/* MMC */
- at91_add_device_mmc(0, &ek_mmc_data);
+ ek_add_device_mmc();
/* I2C */
at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices));
/* LEDs */
- at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+ ek_add_device_gpio_leds();
/* Push Buttons */
ek_add_device_buttons();
/* PCK0 provides MCLK to the WM8731 */
@@ -355,8 +406,15 @@ static void __init ek_board_init(void)
MACHINE_START(AT91SAM9G20EK, "Atmel AT91SAM9G20-EK")
/* Maintainer: Atmel */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
+ .boot_params = AT91_SDRAM_BASE + 0x100,
+ .timer = &at91sam926x_timer,
+ .map_io = ek_map_io,
+ .init_irq = ek_init_irq,
+ .init_machine = ek_board_init,
+MACHINE_END
+
+MACHINE_START(AT91SAM9G20EK_2MMC, "Atmel AT91SAM9G20-EK 2 MMC Slot Mod")
+ /* Maintainer: Atmel */
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91sam926x_timer,
.map_io = ek_map_io,
diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c
index ee800595594d..7913984f6de9 100644
--- a/arch/arm/mach-at91/board-sam9m10g45ek.c
+++ b/arch/arm/mach-at91/board-sam9m10g45ek.c
@@ -135,7 +135,7 @@ static struct atmel_nand_data __initdata ek_nand_data = {
.rdy_pin = AT91_PIN_PC8,
.enable_pin = AT91_PIN_PC14,
.partition_info = nand_partitions,
-#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
+#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
.bus_width_16 = 1,
#else
.bus_width_16 = 0,
@@ -399,10 +399,8 @@ static void __init ek_board_init(void)
at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led));
}
-MACHINE_START(AT91SAM9G45EKES, "Atmel AT91SAM9G45-EKES")
+MACHINE_START(AT91SAM9M10G45EK, "Atmel AT91SAM9M10G45-EK")
/* Maintainer: Atmel */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91sam926x_timer,
.map_io = ek_map_io,
diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c
index 7ac20f3a2067..3bf3408e94c1 100644
--- a/arch/arm/mach-at91/board-sam9rlek.c
+++ b/arch/arm/mach-at91/board-sam9rlek.c
@@ -329,8 +329,6 @@ static void __init ek_board_init(void)
MACHINE_START(AT91SAM9RLEK, "Atmel AT91SAM9RL-EK")
/* Maintainer: Atmel */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91sam926x_timer,
.map_io = ek_map_io,
diff --git a/arch/arm/mach-at91/board-snapper9260.c b/arch/arm/mach-at91/board-snapper9260.c
index 2c08ae4ad3a1..0a99b3cedd7a 100644
--- a/arch/arm/mach-at91/board-snapper9260.c
+++ b/arch/arm/mach-at91/board-snapper9260.c
@@ -177,8 +177,6 @@ static void __init snapper9260_board_init(void)
}
MACHINE_START(SNAPPER_9260, "Bluewater Systems Snapper 9260/9G20 module")
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91sam926x_timer,
.map_io = snapper9260_map_io,
diff --git a/arch/arm/mach-at91/board-stamp9g20.c b/arch/arm/mach-at91/board-stamp9g20.c
index 87958274290f..5206eef4a67e 100644
--- a/arch/arm/mach-at91/board-stamp9g20.c
+++ b/arch/arm/mach-at91/board-stamp9g20.c
@@ -294,8 +294,6 @@ static void __init stamp9g20_board_init(void)
MACHINE_START(PORTUXG20, "taskit PortuxG20")
/* Maintainer: taskit GmbH */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91sam926x_timer,
.map_io = portuxg20_map_io,
@@ -305,8 +303,6 @@ MACHINE_END
MACHINE_START(STAMP9G20, "taskit Stamp9G20")
/* Maintainer: taskit GmbH */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91sam926x_timer,
.map_io = stamp9g20_map_io,
diff --git a/arch/arm/mach-at91/board-usb-a9260.c b/arch/arm/mach-at91/board-usb-a9260.c
index 905d6ef76807..07784baeae84 100644
--- a/arch/arm/mach-at91/board-usb-a9260.c
+++ b/arch/arm/mach-at91/board-usb-a9260.c
@@ -228,8 +228,6 @@ static void __init ek_board_init(void)
MACHINE_START(USB_A9260, "CALAO USB_A9260")
/* Maintainer: calao-systems */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91sam926x_timer,
.map_io = ek_map_io,
diff --git a/arch/arm/mach-at91/board-usb-a9263.c b/arch/arm/mach-at91/board-usb-a9263.c
index b6a3480383e5..b614508931fd 100644
--- a/arch/arm/mach-at91/board-usb-a9263.c
+++ b/arch/arm/mach-at91/board-usb-a9263.c
@@ -244,8 +244,6 @@ static void __init ek_board_init(void)
MACHINE_START(USB_A9263, "CALAO USB_A9263")
/* Maintainer: calao-systems */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91sam926x_timer,
.map_io = ek_map_io,
diff --git a/arch/arm/mach-at91/board-yl-9200.c b/arch/arm/mach-at91/board-yl-9200.c
index e22bf051f835..89df00a9d2f7 100644
--- a/arch/arm/mach-at91/board-yl-9200.c
+++ b/arch/arm/mach-at91/board-yl-9200.c
@@ -594,8 +594,6 @@ static void __init yl9200_board_init(void)
MACHINE_START(YL9200, "uCdragon YL-9200")
/* Maintainer: S.Birtles */
- .phys_io = AT91_BASE_SYS,
- .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91rm9200_timer,
.map_io = yl9200_map_io,
diff --git a/arch/arm/mach-at91/include/mach/at91x40.h b/arch/arm/mach-at91/include/mach/at91x40.h
index d34cdb8abdca..063ac44a0204 100644
--- a/arch/arm/mach-at91/include/mach/at91x40.h
+++ b/arch/arm/mach-at91/include/mach/at91x40.h
@@ -52,4 +52,10 @@
#define AT91_DBGU_CIDR (AT91_SF + 0) /* CIDR in PS segment */
#define AT91_DBGU_EXID (AT91_SF + 4) /* EXID in PS segment */
+/*
+ * Support defines for the simple Power Controller module.
+ */
+#define AT91_PS_CR (AT91_PS + 0) /* PS Control register */
+#define AT91_PS_CR_CPU (1 << 0) /* CPU clock disable bit */
+
#endif /* AT91X40_H */
diff --git a/arch/arm/mach-at91/include/mach/debug-macro.S b/arch/arm/mach-at91/include/mach/debug-macro.S
index 9e750a1c1b5a..0f959faf74a9 100644
--- a/arch/arm/mach-at91/include/mach/debug-macro.S
+++ b/arch/arm/mach-at91/include/mach/debug-macro.S
@@ -14,11 +14,9 @@
#include <mach/hardware.h>
#include <mach/at91_dbgu.h>
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- ldreq \rx, =(AT91_BASE_SYS + AT91_DBGU) @ System peripherals (phys address)
- ldrne \rx, =(AT91_VA_BASE_SYS + AT91_DBGU) @ System peripherals (virt address)
+ .macro addruart, rp, rv
+ ldr \rp, =(AT91_BASE_SYS + AT91_DBGU) @ System peripherals (phys address)
+ ldr \rv, =(AT91_VA_BASE_SYS + AT91_DBGU) @ System peripherals (virt address)
.endm
.macro senduart,rd,rx
diff --git a/arch/arm/mach-at91/include/mach/system.h b/arch/arm/mach-at91/include/mach/system.h
index c80e090b3670..36af14bc13bb 100644
--- a/arch/arm/mach-at91/include/mach/system.h
+++ b/arch/arm/mach-at91/include/mach/system.h
@@ -28,17 +28,20 @@
static inline void arch_idle(void)
{
-#ifndef CONFIG_DEBUG_KERNEL
/*
* Disable the processor clock. The processor will be automatically
* re-enabled by an interrupt or by a reset.
*/
- at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
+#ifdef AT91_PS
+ at91_sys_write(AT91_PS_CR, AT91_PS_CR_CPU);
#else
+ at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
+#endif
+#ifndef CONFIG_CPU_ARM920T
/*
* Set the processor (CP15) into 'Wait for Interrupt' mode.
- * Unlike disabling the processor clock via the PMC (above)
- * this allows the processor to be woken via JTAG.
+ * Post-RM9200 processors need this in conjunction with the above
+ * to save power when idle.
*/
cpu_do_idle();
#endif
diff --git a/arch/arm/mach-bcmring/arch.c b/arch/arm/mach-bcmring/arch.c
index 2f139196d63d..73eb066d2329 100644
--- a/arch/arm/mach-bcmring/arch.c
+++ b/arch/arm/mach-bcmring/arch.c
@@ -167,8 +167,6 @@ static void __init bcmring_fixup(struct machine_desc *desc,
MACHINE_START(BCMRING, "BCMRING")
/* Maintainer: Broadcom Corporation */
- .phys_io = MM_IO_START,
- .io_pg_offst = (MM_IO_BASE >> 18) & 0xfffc,
.fixup = bcmring_fixup,
.map_io = bcmring_map_io,
.init_irq = bcmring_init_irq,
diff --git a/arch/arm/mach-bcmring/dma.c b/arch/arm/mach-bcmring/dma.c
index 29c0a911df26..77eb35c89cd0 100644
--- a/arch/arm/mach-bcmring/dma.c
+++ b/arch/arm/mach-bcmring/dma.c
@@ -691,7 +691,7 @@ int dma_init(void)
memset(&gDMA, 0, sizeof(gDMA));
- init_MUTEX_LOCKED(&gDMA.lock);
+ sema_init(&gDMA.lock, 0);
init_waitqueue_head(&gDMA.freeChannelQ);
/* Initialize the Hardware */
@@ -1574,7 +1574,7 @@ int dma_init_mem_map(DMA_MemMap_t *memMap)
{
memset(memMap, 0, sizeof(*memMap));
- init_MUTEX(&memMap->lock);
+ sema_init(&memMap->lock, 1);
return 0;
}
diff --git a/arch/arm/mach-bcmring/include/mach/vmalloc.h b/arch/arm/mach-bcmring/include/mach/vmalloc.h
index 35e2ead8395c..3db3a09fd398 100644
--- a/arch/arm/mach-bcmring/include/mach/vmalloc.h
+++ b/arch/arm/mach-bcmring/include/mach/vmalloc.h
@@ -22,4 +22,4 @@
* 0xe0000000 to 0xefffffff. This gives us 256 MB of vm space and handles
* larger physical memory designs better.
*/
-#define VMALLOC_END (PAGE_OFFSET + 0x30000000)
+#define VMALLOC_END 0xf0000000
diff --git a/arch/arm/mach-bcmring/irq.c b/arch/arm/mach-bcmring/irq.c
index dc1c4939b0ce..e3152631eb37 100644
--- a/arch/arm/mach-bcmring/irq.c
+++ b/arch/arm/mach-bcmring/irq.c
@@ -67,21 +67,21 @@ static void bcmring_unmask_irq2(unsigned int irq)
}
static struct irq_chip bcmring_irq0_chip = {
- .typename = "ARM-INTC0",
+ .name = "ARM-INTC0",
.ack = bcmring_mask_irq0,
.mask = bcmring_mask_irq0, /* mask a specific interrupt, blocking its delivery. */
.unmask = bcmring_unmask_irq0, /* unmaks an interrupt */
};
static struct irq_chip bcmring_irq1_chip = {
- .typename = "ARM-INTC1",
+ .name = "ARM-INTC1",
.ack = bcmring_mask_irq1,
.mask = bcmring_mask_irq1,
.unmask = bcmring_unmask_irq1,
};
static struct irq_chip bcmring_irq2_chip = {
- .typename = "ARM-SINTC",
+ .name = "ARM-SINTC",
.ack = bcmring_mask_irq2,
.mask = bcmring_mask_irq2,
.unmask = bcmring_unmask_irq2,
diff --git a/arch/arm/mach-clps711x/autcpu12.c b/arch/arm/mach-clps711x/autcpu12.c
index 5f18eccdc725..4a74b2c959bd 100644
--- a/arch/arm/mach-clps711x/autcpu12.c
+++ b/arch/arm/mach-clps711x/autcpu12.c
@@ -64,8 +64,6 @@ void __init autcpu12_map_io(void)
MACHINE_START(AUTCPU12, "autronix autcpu12")
/* Maintainer: Thomas Gleixner */
- .phys_io = 0x80000000,
- .io_pg_offst = ((0xff000000) >> 18) & 0xfffc,
.boot_params = 0xc0020000,
.map_io = autcpu12_map_io,
.init_irq = clps711x_init_irq,
diff --git a/arch/arm/mach-clps711x/cdb89712.c b/arch/arm/mach-clps711x/cdb89712.c
index 71a80b5b8ad6..5a1689d48793 100644
--- a/arch/arm/mach-clps711x/cdb89712.c
+++ b/arch/arm/mach-clps711x/cdb89712.c
@@ -55,8 +55,6 @@ static void __init cdb89712_map_io(void)
MACHINE_START(CDB89712, "Cirrus-CDB89712")
/* Maintainer: Ray Lehtiniemi */
- .phys_io = 0x80000000,
- .io_pg_offst = ((0xff000000) >> 18) & 0xfffc,
.boot_params = 0xc0000100,
.map_io = cdb89712_map_io,
.init_irq = clps711x_init_irq,
diff --git a/arch/arm/mach-clps711x/ceiva.c b/arch/arm/mach-clps711x/ceiva.c
index 8ada20184978..16481cf3e931 100644
--- a/arch/arm/mach-clps711x/ceiva.c
+++ b/arch/arm/mach-clps711x/ceiva.c
@@ -56,8 +56,6 @@ static void __init ceiva_map_io(void)
MACHINE_START(CEIVA, "CEIVA/Polaroid Photo MAX Digital Picture Frame")
/* Maintainer: Rob Scott */
- .phys_io = 0x80000000,
- .io_pg_offst = ((0xff000000) >> 18) & 0xfffc,
.boot_params = 0xc0000100,
.map_io = ceiva_map_io,
.init_irq = clps711x_init_irq,
diff --git a/arch/arm/mach-clps711x/clep7312.c b/arch/arm/mach-clps711x/clep7312.c
index 3c3bf45039ff..67b5abb4a60a 100644
--- a/arch/arm/mach-clps711x/clep7312.c
+++ b/arch/arm/mach-clps711x/clep7312.c
@@ -37,8 +37,6 @@ fixup_clep7312(struct machine_desc *desc, struct tag *tags,
MACHINE_START(CLEP7212, "Cirrus Logic 7212/7312")
/* Maintainer: Nobody */
- .phys_io = 0x80000000,
- .io_pg_offst = ((0xff000000) >> 18) & 0xfffc,
.boot_params = 0xc0000100,
.fixup = fixup_clep7312,
.map_io = clps711x_map_io,
diff --git a/arch/arm/mach-clps711x/edb7211-arch.c b/arch/arm/mach-clps711x/edb7211-arch.c
index 4a7a2322979a..98ca5b2e940d 100644
--- a/arch/arm/mach-clps711x/edb7211-arch.c
+++ b/arch/arm/mach-clps711x/edb7211-arch.c
@@ -57,8 +57,6 @@ fixup_edb7211(struct machine_desc *desc, struct tag *tags,
MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)")
/* Maintainer: Jon McClintock */
- .phys_io = 0x80000000,
- .io_pg_offst = ((0xff000000) >> 18) & 0xfffc,
.boot_params = 0xc0020100, /* 0xc0000000 - 0xc001ffff can be video RAM */
.fixup = fixup_edb7211,
.map_io = edb7211_map_io,
diff --git a/arch/arm/mach-clps711x/fortunet.c b/arch/arm/mach-clps711x/fortunet.c
index a696099aa4f8..b1cb479e71e9 100644
--- a/arch/arm/mach-clps711x/fortunet.c
+++ b/arch/arm/mach-clps711x/fortunet.c
@@ -75,8 +75,6 @@ fortunet_fixup(struct machine_desc *desc, struct tag *tags,
MACHINE_START(FORTUNET, "ARM-FortuNet")
/* Maintainer: FortuNet Inc. */
- .phys_io = 0x80000000,
- .io_pg_offst = ((0xf0000000) >> 18) & 0xfffc,
.boot_params = 0x00000000,
.fixup = fortunet_fixup,
.map_io = clps711x_map_io,
diff --git a/arch/arm/mach-clps711x/include/mach/debug-macro.S b/arch/arm/mach-clps711x/include/mach/debug-macro.S
index 072cc6b61ba3..507c6873b7ee 100644
--- a/arch/arm/mach-clps711x/include/mach/debug-macro.S
+++ b/arch/arm/mach-clps711x/include/mach/debug-macro.S
@@ -14,16 +14,14 @@
#include <mach/hardware.h>
#include <asm/hardware/clps7111.h>
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- moveq \rx, #CLPS7111_PHYS_BASE
- movne \rx, #CLPS7111_VIRT_BASE
+ .macro addruart, rp, rv
#ifndef CONFIG_DEBUG_CLPS711X_UART2
- add \rx, \rx, #0x0000 @ UART1
+ mov \rp, #0x0000 @ UART1
#else
- add \rx, \rx, #0x1000 @ UART2
+ mov \rp, #0x1000 @ UART2
#endif
+ orr \rv, \rp, #CLPS7111_VIRT_BASE
+ orr \rp, \rp, #CLPS7111_PHYS_BASE
.endm
.macro senduart,rd,rx
diff --git a/arch/arm/mach-clps711x/include/mach/vmalloc.h b/arch/arm/mach-clps711x/include/mach/vmalloc.h
index ea6cc7beff28..30b3a287ed88 100644
--- a/arch/arm/mach-clps711x/include/mach/vmalloc.h
+++ b/arch/arm/mach-clps711x/include/mach/vmalloc.h
@@ -17,4 +17,4 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#define VMALLOC_END (PAGE_OFFSET + 0x10000000)
+#define VMALLOC_END 0xd0000000
diff --git a/arch/arm/mach-clps711x/p720t.c b/arch/arm/mach-clps711x/p720t.c
index 0d94a30fd6fc..cefbce0480b9 100644
--- a/arch/arm/mach-clps711x/p720t.c
+++ b/arch/arm/mach-clps711x/p720t.c
@@ -89,8 +89,6 @@ static void __init p720t_map_io(void)
MACHINE_START(P720T, "ARM-Prospector720T")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
- .phys_io = 0x80000000,
- .io_pg_offst = ((0xff000000) >> 18) & 0xfffc,
.boot_params = 0xc0000100,
.fixup = fixup_p720t,
.map_io = p720t_map_io,
diff --git a/arch/arm/mach-cns3xxx/cns3420vb.c b/arch/arm/mach-cns3xxx/cns3420vb.c
index 9df8391fd78a..90fe9ab8591d 100644
--- a/arch/arm/mach-cns3xxx/cns3420vb.c
+++ b/arch/arm/mach-cns3xxx/cns3420vb.c
@@ -142,8 +142,6 @@ static void __init cns3420_map_io(void)
}
MACHINE_START(CNS3420VB, "Cavium Networks CNS3420 Validation Board")
- .phys_io = CNS3XXX_UART0_BASE,
- .io_pg_offst = (CNS3XXX_UART0_BASE_VIRT >> 18) & 0xfffc,
.boot_params = 0x00000100,
.map_io = cns3420_map_io,
.init_irq = cns3xxx_init_irq,
diff --git a/arch/arm/mach-cns3xxx/include/mach/debug-macro.S b/arch/arm/mach-cns3xxx/include/mach/debug-macro.S
index d16ce7eb00e9..56d828634db5 100644
--- a/arch/arm/mach-cns3xxx/include/mach/debug-macro.S
+++ b/arch/arm/mach-cns3xxx/include/mach/debug-macro.S
@@ -10,12 +10,10 @@
* published by the Free Software Foundation.
*/
- .macro addruart,rx
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- moveq \rx, #0x10000000
- movne \rx, #0xf0000000 @ virtual base
- orr \rx, \rx, #0x00009000
+ .macro addruart,rp,rv
+ mov \rp, #0x00009000
+ orr \rv, \rp, #0xf0000000 @ virtual base
+ orr \rp, \rp, #0x10000000
.endm
#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c
index c3994f341e49..7f3cdbfc0fbb 100644
--- a/arch/arm/mach-davinci/board-da830-evm.c
+++ b/arch/arm/mach-davinci/board-da830-evm.c
@@ -597,8 +597,6 @@ static void __init da830_evm_map_io(void)
}
MACHINE_START(DAVINCI_DA830_EVM, "DaVinci DA830/OMAP-L137 EVM")
- .phys_io = IO_PHYS,
- .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
.boot_params = (DA8XX_DDR_BASE + 0x100),
.map_io = da830_evm_map_io,
.init_irq = cp_intc_init,
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index fdc2cc500fc6..b26f5cbfce3e 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -817,8 +817,6 @@ static void __init da850_evm_map_io(void)
}
MACHINE_START(DAVINCI_DA850_EVM, "DaVinci DA850/OMAP-L138 EVM")
- .phys_io = IO_PHYS,
- .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
.boot_params = (DA8XX_DDR_BASE + 0x100),
.map_io = da850_evm_map_io,
.init_irq = cp_intc_init,
diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c
index a3191015efee..6e7cad13352c 100644
--- a/arch/arm/mach-davinci/board-dm355-evm.c
+++ b/arch/arm/mach-davinci/board-dm355-evm.c
@@ -351,8 +351,6 @@ static __init void dm355_evm_init(void)
}
MACHINE_START(DAVINCI_DM355_EVM, "DaVinci DM355 EVM")
- .phys_io = IO_PHYS,
- .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
.boot_params = (0x80000100),
.map_io = dm355_evm_map_io,
.init_irq = davinci_irq_init,
diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c
index f1d8132cf0c3..543f9911b281 100644
--- a/arch/arm/mach-davinci/board-dm355-leopard.c
+++ b/arch/arm/mach-davinci/board-dm355-leopard.c
@@ -270,8 +270,6 @@ static __init void dm355_leopard_init(void)
}
MACHINE_START(DM355_LEOPARD, "DaVinci DM355 leopard")
- .phys_io = IO_PHYS,
- .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
.boot_params = (0x80000100),
.map_io = dm355_leopard_map_io,
.init_irq = davinci_irq_init,
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
index 84acef1d0b3d..944a0cbaf5cb 100644
--- a/arch/arm/mach-davinci/board-dm365-evm.c
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -613,8 +613,6 @@ static __init void dm365_evm_init(void)
}
MACHINE_START(DAVINCI_DM365_EVM, "DaVinci DM365 EVM")
- .phys_io = IO_PHYS,
- .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
.boot_params = (0x80000100),
.map_io = dm365_evm_map_io,
.init_irq = davinci_irq_init,
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c
index 34c8b418cd72..d59fba15ba8d 100644
--- a/arch/arm/mach-davinci/board-dm644x-evm.c
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -706,8 +706,6 @@ static __init void davinci_evm_init(void)
MACHINE_START(DAVINCI_EVM, "DaVinci DM644x EVM")
/* Maintainer: MontaVista Software <source@mvista.com> */
- .phys_io = IO_PHYS,
- .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
.boot_params = (DAVINCI_DDR_BASE + 0x100),
.map_io = davinci_evm_map_io,
.init_irq = davinci_irq_init,
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c
index 4502f346b2b0..6890488fb92b 100644
--- a/arch/arm/mach-davinci/board-dm646x-evm.c
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -786,8 +786,6 @@ void __init dm646x_board_setup_refclk(struct clk *clk)
}
MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM")
- .phys_io = IO_PHYS,
- .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
.boot_params = (0x80000100),
.map_io = davinci_map_io,
.init_irq = davinci_irq_init,
@@ -796,8 +794,6 @@ MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM")
MACHINE_END
MACHINE_START(DAVINCI_DM6467TEVM, "DaVinci DM6467T EVM")
- .phys_io = IO_PHYS,
- .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
.boot_params = (0x80000100),
.map_io = davinci_map_io,
.init_irq = davinci_irq_init,
diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c
index 4c30e929bbf9..a4def889275c 100644
--- a/arch/arm/mach-davinci/board-neuros-osd2.c
+++ b/arch/arm/mach-davinci/board-neuros-osd2.c
@@ -275,8 +275,6 @@ static __init void davinci_ntosd2_init(void)
MACHINE_START(NEUROS_OSD2, "Neuros OSD2")
/* Maintainer: Neuros Technologies <neuros@groups.google.com> */
- .phys_io = IO_PHYS,
- .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
.boot_params = (DAVINCI_DDR_BASE + 0x100),
.map_io = davinci_ntosd2_map_io,
.init_irq = davinci_irq_init,
diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c
index 23e664a1a802..9bdf8aafcc84 100644
--- a/arch/arm/mach-davinci/board-sffsdr.c
+++ b/arch/arm/mach-davinci/board-sffsdr.c
@@ -154,8 +154,6 @@ static __init void davinci_sffsdr_init(void)
MACHINE_START(SFFSDR, "Lyrtech SFFSDR")
/* Maintainer: Hugo Villeneuve hugo.villeneuve@lyrtech.com */
- .phys_io = IO_PHYS,
- .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
.boot_params = (DAVINCI_DDR_BASE + 0x100),
.map_io = davinci_sffsdr_map_io,
.init_irq = davinci_irq_init,
diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c
index fe2a9d9c8bb7..b4de35b78904 100644
--- a/arch/arm/mach-davinci/board-tnetv107x-evm.c
+++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c
@@ -164,8 +164,6 @@ console_initcall(tnetv107x_evm_console_init);
#endif
MACHINE_START(TNETV107X, "TNETV107X EVM")
- .phys_io = TNETV107X_IO_BASE,
- .io_pg_offst = (TNETV107X_IO_VIRT >> 18) & 0xfffc,
.boot_params = (TNETV107X_DDR_BASE + 0x100),
.map_io = tnetv107x_init,
.init_irq = cp_intc_init,
diff --git a/arch/arm/mach-davinci/include/mach/debug-macro.S b/arch/arm/mach-davinci/include/mach/debug-macro.S
index f761dfdb8689..9f1befc5ac38 100644
--- a/arch/arm/mach-davinci/include/mach/debug-macro.S
+++ b/arch/arm/mach-davinci/include/mach/debug-macro.S
@@ -29,35 +29,39 @@ davinci_uart_phys: .word 0
davinci_uart_virt: .word 0
.popsection
- .macro addruart, rx, tmp
+ .macro addruart, rp, rv
/* Use davinci_uart_phys/virt if already configured */
-10: mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- ldreq \rx, =__virt_to_phys(davinci_uart_phys)
- ldrne \rx, =davinci_uart_virt
- ldr \rx, [\rx]
- cmp \rx, #0 @ is port configured?
+10: mrc p15, 0, \rp, c1, c0
+ tst \rp, #1 @ MMU enabled?
+ ldreq \rp, =__virt_to_phys(davinci_uart_phys)
+ ldrne \rp, =davinci_uart_phys
+ add \rv, \rp, #4 @ davinci_uart_virt
+ ldr \rp, [\rp, #0]
+ ldr \rv, [\rv, #0]
+ cmp \rp, #0 @ is port configured?
+ cmpne \rv, #0
bne 99f @ already configured
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
+ /* Check the debug UART address set in uncompress.h */
+ mrc p15, 0, \rp, c1, c0
+ tst \rp, #1 @ MMU enabled?
/* Copy uart phys address from decompressor uart info */
- ldreq \tmp, =__virt_to_phys(davinci_uart_phys)
- ldrne \tmp, =davinci_uart_phys
- ldreq \rx, =DAVINCI_UART_INFO
- ldrne \rx, =__phys_to_virt(DAVINCI_UART_INFO)
- ldr \rx, [\rx, #0]
- str \rx, [\tmp]
+ ldreq \rv, =__virt_to_phys(davinci_uart_phys)
+ ldrne \rv, =davinci_uart_phys
+ ldreq \rp, =DAVINCI_UART_INFO
+ ldrne \rp, =__phys_to_virt(DAVINCI_UART_INFO)
+ ldr \rp, [\rp, #0]
+ str \rp, [\rv]
/* Copy uart virt address from decompressor uart info */
- ldreq \tmp, =__virt_to_phys(davinci_uart_virt)
- ldrne \tmp, =davinci_uart_virt
- ldreq \rx, =DAVINCI_UART_INFO
- ldrne \rx, =__phys_to_virt(DAVINCI_UART_INFO)
- ldr \rx, [\rx, #4]
- str \rx, [\tmp]
+ ldreq \rv, =__virt_to_phys(davinci_uart_virt)
+ ldrne \rv, =davinci_uart_virt
+ ldreq \rp, =DAVINCI_UART_INFO
+ ldrne \rp, =__phys_to_virt(DAVINCI_UART_INFO)
+ ldr \rp, [\rp, #4]
+ str \rp, [\rv]
b 10b
99:
diff --git a/arch/arm/mach-dove/dove-db-setup.c b/arch/arm/mach-dove/dove-db-setup.c
index bef70460fbc6..95925aa76dd9 100644
--- a/arch/arm/mach-dove/dove-db-setup.c
+++ b/arch/arm/mach-dove/dove-db-setup.c
@@ -94,8 +94,6 @@ static void __init dove_db_init(void)
}
MACHINE_START(DOVE_DB, "Marvell DB-MV88AP510-BP Development Board")
- .phys_io = DOVE_SB_REGS_PHYS_BASE,
- .io_pg_offst = ((DOVE_SB_REGS_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.init_machine = dove_db_init,
.map_io = dove_map_io,
diff --git a/arch/arm/mach-dove/include/mach/debug-macro.S b/arch/arm/mach-dove/include/mach/debug-macro.S
index 1521d13f1d14..da8bf2bad3b1 100644
--- a/arch/arm/mach-dove/include/mach/debug-macro.S
+++ b/arch/arm/mach-dove/include/mach/debug-macro.S
@@ -8,12 +8,11 @@
#include <mach/bridge-regs.h>
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- ldreq \rx, =DOVE_SB_REGS_PHYS_BASE
- ldrne \rx, =DOVE_SB_REGS_VIRT_BASE
- orr \rx, \rx, #0x00012000
+ .macro addruart, rp, rv
+ ldr \rp, =DOVE_SB_REGS_PHYS_BASE
+ ldr \rv, =DOVE_SB_REGS_VIRT_BASE
+ orr \rp, \rp, #0x00012000
+ orr \rv, \rv, #0x00012000
.endm
#define UART_SHIFT 2
diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c
index c7bc7fbb11a6..5df4099fc14f 100644
--- a/arch/arm/mach-ebsa110/core.c
+++ b/arch/arm/mach-ebsa110/core.c
@@ -280,8 +280,6 @@ arch_initcall(ebsa110_init);
MACHINE_START(EBSA110, "EBSA110")
/* Maintainer: Russell King */
- .phys_io = 0xe0000000,
- .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc,
.boot_params = 0x00000400,
.reserve_lp0 = 1,
.reserve_lp2 = 1,
diff --git a/arch/arm/mach-ebsa110/include/mach/debug-macro.S b/arch/arm/mach-ebsa110/include/mach/debug-macro.S
index ebbd89f0e6c0..7ef5690fd08c 100644
--- a/arch/arm/mach-ebsa110/include/mach/debug-macro.S
+++ b/arch/arm/mach-ebsa110/include/mach/debug-macro.S
@@ -11,9 +11,10 @@
*
**/
- .macro addruart, rx, tmp
- mov \rx, #0xf0000000
- orr \rx, \rx, #0x00000be0
+ .macro addruart, rp, rv
+ mov \rp, #0xf0000000
+ orr \rp, \rp, #0x00000be0
+ mov \rp, \rv
.endm
#define UART_SHIFT 2
diff --git a/arch/arm/mach-ebsa110/include/mach/vmalloc.h b/arch/arm/mach-ebsa110/include/mach/vmalloc.h
index 9b44c19e95ec..60bde56fba4c 100644
--- a/arch/arm/mach-ebsa110/include/mach/vmalloc.h
+++ b/arch/arm/mach-ebsa110/include/mach/vmalloc.h
@@ -7,4 +7,4 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-#define VMALLOC_END (PAGE_OFFSET + 0x1f000000)
+#define VMALLOC_END 0xdf000000
diff --git a/arch/arm/mach-ep93xx/adssphere.c b/arch/arm/mach-ep93xx/adssphere.c
index f744f676783f..61b98ce4b673 100644
--- a/arch/arm/mach-ep93xx/adssphere.c
+++ b/arch/arm/mach-ep93xx/adssphere.c
@@ -33,8 +33,6 @@ static void __init adssphere_init_machine(void)
MACHINE_START(ADSSPHERE, "ADS Sphere board")
/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
- .phys_io = EP93XX_APB_PHYS_BASE,
- .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
diff --git a/arch/arm/mach-ep93xx/dma-m2p.c b/arch/arm/mach-ep93xx/dma-m2p.c
index 8904ca4e2e24..a696d354b1f8 100644
--- a/arch/arm/mach-ep93xx/dma-m2p.c
+++ b/arch/arm/mach-ep93xx/dma-m2p.c
@@ -276,7 +276,7 @@ static void channel_disable(struct m2p_channel *ch)
v &= ~(M2P_CONTROL_STALL_IRQ_EN | M2P_CONTROL_NFB_IRQ_EN);
m2p_set_control(ch, v);
- while (m2p_channel_state(ch) == STATE_ON)
+ while (m2p_channel_state(ch) >= STATE_ON)
cpu_relax();
m2p_set_control(ch, 0x0);
diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c
index c2ce9034ba87..4b0431652131 100644
--- a/arch/arm/mach-ep93xx/edb93xx.c
+++ b/arch/arm/mach-ep93xx/edb93xx.c
@@ -124,8 +124,6 @@ static void __init edb93xx_init_machine(void)
#ifdef CONFIG_MACH_EDB9301
MACHINE_START(EDB9301, "Cirrus Logic EDB9301 Evaluation Board")
/* Maintainer: H Hartley Sweeten <hsweeten@visionengravers.com> */
- .phys_io = EP93XX_APB_PHYS_BASE,
- .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
@@ -137,8 +135,6 @@ MACHINE_END
#ifdef CONFIG_MACH_EDB9302
MACHINE_START(EDB9302, "Cirrus Logic EDB9302 Evaluation Board")
/* Maintainer: George Kashperko <george@chas.com.ua> */
- .phys_io = EP93XX_APB_PHYS_BASE,
- .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
@@ -150,8 +146,6 @@ MACHINE_END
#ifdef CONFIG_MACH_EDB9302A
MACHINE_START(EDB9302A, "Cirrus Logic EDB9302A Evaluation Board")
/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
- .phys_io = EP93XX_APB_PHYS_BASE,
- .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = EP93XX_SDCE0_PHYS_BASE + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
@@ -163,8 +157,6 @@ MACHINE_END
#ifdef CONFIG_MACH_EDB9307
MACHINE_START(EDB9307, "Cirrus Logic EDB9307 Evaluation Board")
/* Maintainer: Herbert Valerio Riedel <hvr@gnu.org> */
- .phys_io = EP93XX_APB_PHYS_BASE,
- .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
@@ -176,8 +168,6 @@ MACHINE_END
#ifdef CONFIG_MACH_EDB9307A
MACHINE_START(EDB9307A, "Cirrus Logic EDB9307A Evaluation Board")
/* Maintainer: H Hartley Sweeten <hsweeten@visionengravers.com> */
- .phys_io = EP93XX_APB_PHYS_BASE,
- .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = EP93XX_SDCE0_PHYS_BASE + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
@@ -189,8 +179,6 @@ MACHINE_END
#ifdef CONFIG_MACH_EDB9312
MACHINE_START(EDB9312, "Cirrus Logic EDB9312 Evaluation Board")
/* Maintainer: Toufeeq Hussain <toufeeq_hussain@infosys.com> */
- .phys_io = EP93XX_APB_PHYS_BASE,
- .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
@@ -202,8 +190,6 @@ MACHINE_END
#ifdef CONFIG_MACH_EDB9315
MACHINE_START(EDB9315, "Cirrus Logic EDB9315 Evaluation Board")
/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
- .phys_io = EP93XX_APB_PHYS_BASE,
- .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
@@ -215,8 +201,6 @@ MACHINE_END
#ifdef CONFIG_MACH_EDB9315A
MACHINE_START(EDB9315A, "Cirrus Logic EDB9315A Evaluation Board")
/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
- .phys_io = EP93XX_APB_PHYS_BASE,
- .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = EP93XX_SDCE0_PHYS_BASE + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
diff --git a/arch/arm/mach-ep93xx/gesbc9312.c b/arch/arm/mach-ep93xx/gesbc9312.c
index d97168c0ba33..9bd3152bff9a 100644
--- a/arch/arm/mach-ep93xx/gesbc9312.c
+++ b/arch/arm/mach-ep93xx/gesbc9312.c
@@ -33,8 +33,6 @@ static void __init gesbc9312_init_machine(void)
MACHINE_START(GESBC9312, "Glomation GESBC-9312-sx")
/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
- .phys_io = EP93XX_APB_PHYS_BASE,
- .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
diff --git a/arch/arm/mach-ep93xx/include/mach/debug-macro.S b/arch/arm/mach-ep93xx/include/mach/debug-macro.S
index 5cd22444e223..b25bc9076367 100644
--- a/arch/arm/mach-ep93xx/include/mach/debug-macro.S
+++ b/arch/arm/mach-ep93xx/include/mach/debug-macro.S
@@ -11,12 +11,11 @@
*/
#include <mach/ep93xx-regs.h>
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- ldreq \rx, =EP93XX_APB_PHYS_BASE @ Physical base
- ldrne \rx, =EP93XX_APB_VIRT_BASE @ virtual base
- orr \rx, \rx, #0x000c0000
+ .macro addruart, rp, rv
+ ldr \rp, =EP93XX_APB_PHYS_BASE @ Physical base
+ ldr \rv, =EP93XX_APB_VIRT_BASE @ virtual base
+ orr \rp, \rp, #0x000c0000
+ orr \rv, \rv, #0x000c0000
.endm
#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-ep93xx/micro9.c b/arch/arm/mach-ep93xx/micro9.c
index 2ba776320a82..7adea6258efe 100644
--- a/arch/arm/mach-ep93xx/micro9.c
+++ b/arch/arm/mach-ep93xx/micro9.c
@@ -77,8 +77,6 @@ static void __init micro9_init_machine(void)
#ifdef CONFIG_MACH_MICRO9H
MACHINE_START(MICRO9, "Contec Micro9-High")
/* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */
- .phys_io = EP93XX_APB_PHYS_BASE,
- .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
@@ -90,8 +88,6 @@ MACHINE_END
#ifdef CONFIG_MACH_MICRO9M
MACHINE_START(MICRO9M, "Contec Micro9-Mid")
/* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */
- .phys_io = EP93XX_APB_PHYS_BASE,
- .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = EP93XX_SDCE3_PHYS_BASE_ASYNC + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
@@ -103,8 +99,6 @@ MACHINE_END
#ifdef CONFIG_MACH_MICRO9L
MACHINE_START(MICRO9L, "Contec Micro9-Lite")
/* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */
- .phys_io = EP93XX_APB_PHYS_BASE,
- .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
@@ -116,8 +110,6 @@ MACHINE_END
#ifdef CONFIG_MACH_MICRO9S
MACHINE_START(MICRO9S, "Contec Micro9-Slim")
/* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */
- .phys_io = EP93XX_APB_PHYS_BASE,
- .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = EP93XX_SDCE3_PHYS_BASE_ASYNC + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
diff --git a/arch/arm/mach-ep93xx/simone.c b/arch/arm/mach-ep93xx/simone.c
index 5dded5884133..f22ce8db7947 100644
--- a/arch/arm/mach-ep93xx/simone.c
+++ b/arch/arm/mach-ep93xx/simone.c
@@ -65,8 +65,6 @@ static void __init simone_init_machine(void)
MACHINE_START(SIM_ONE, "Simplemachines Sim.One Board")
/* Maintainer: Ryan Mallon <ryan@bluewatersys.com> */
- .phys_io = EP93XX_APB_PHYS_BASE,
- .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = EP93XX_SDCE0_PHYS_BASE + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
diff --git a/arch/arm/mach-ep93xx/snappercl15.c b/arch/arm/mach-ep93xx/snappercl15.c
index a12c89301297..ac601fe2b448 100644
--- a/arch/arm/mach-ep93xx/snappercl15.c
+++ b/arch/arm/mach-ep93xx/snappercl15.c
@@ -163,8 +163,6 @@ static void __init snappercl15_init_machine(void)
MACHINE_START(SNAPPER_CL15, "Bluewater Systems Snapper CL15")
/* Maintainer: Ryan Mallon <ryan@bluewatersys.com> */
- .phys_io = EP93XX_APB_PHYS_BASE,
- .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = EP93XX_SDCE0_PHYS_BASE + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c
index 93aeab8af705..c2d2cf40ead9 100644
--- a/arch/arm/mach-ep93xx/ts72xx.c
+++ b/arch/arm/mach-ep93xx/ts72xx.c
@@ -257,8 +257,6 @@ static void __init ts72xx_init_machine(void)
MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC")
/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
- .phys_io = EP93XX_APB_PHYS_BASE,
- .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
.map_io = ts72xx_map_io,
.init_irq = ep93xx_init_irq,
diff --git a/arch/arm/mach-footbridge/cats-hw.c b/arch/arm/mach-footbridge/cats-hw.c
index 1b996b26d2e0..5b1a8db779be 100644
--- a/arch/arm/mach-footbridge/cats-hw.c
+++ b/arch/arm/mach-footbridge/cats-hw.c
@@ -86,8 +86,6 @@ fixup_cats(struct machine_desc *desc, struct tag *tags,
MACHINE_START(CATS, "Chalice-CATS")
/* Maintainer: Philip Blundell */
- .phys_io = DC21285_ARMCSR_BASE,
- .io_pg_offst = ((0xfe000000) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.soft_reboot = 1,
.fixup = fixup_cats,
diff --git a/arch/arm/mach-footbridge/ebsa285.c b/arch/arm/mach-footbridge/ebsa285.c
index 30040fd588cc..2ef69ff44ba8 100644
--- a/arch/arm/mach-footbridge/ebsa285.c
+++ b/arch/arm/mach-footbridge/ebsa285.c
@@ -15,8 +15,6 @@
MACHINE_START(EBSA285, "EBSA285")
/* Maintainer: Russell King */
- .phys_io = DC21285_ARMCSR_BASE,
- .io_pg_offst = ((0xfe000000) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.video_start = 0x000a0000,
.video_end = 0x000bffff,
diff --git a/arch/arm/mach-footbridge/include/mach/debug-macro.S b/arch/arm/mach-footbridge/include/mach/debug-macro.S
index 60dda1318f22..3c9e0c40c679 100644
--- a/arch/arm/mach-footbridge/include/mach/debug-macro.S
+++ b/arch/arm/mach-footbridge/include/mach/debug-macro.S
@@ -15,12 +15,10 @@
#ifndef CONFIG_DEBUG_DC21285_PORT
/* For NetWinder debugging */
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- moveq \rx, #0x7c000000 @ physical
- movne \rx, #0xff000000 @ virtual
- orr \rx, \rx, #0x000003f8
+ .macro addruart, rp, rv
+ mov \rp, #0x000003f8
+ orr \rv, \rp, #0x7c000000 @ physical
+ orr \rp, \rp, #0xff000000 @ virtual
.endm
#define UART_SHIFT 0
@@ -32,14 +30,14 @@
.equ dc21285_high, ARMCSR_BASE & 0xff000000
.equ dc21285_low, ARMCSR_BASE & 0x00ffffff
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- moveq \rx, #0x42000000
- movne \rx, #dc21285_high
+ .macro addruart, rp, rv
.if dc21285_low
- orrne \rx, \rx, #dc21285_low
+ mov \rp, #dc21285_low
+ .else
+ mov \rp, #0
.endif
+ orr \rv, \rp, #0x42000000
+ orr \rp, \rp, #dc21285_high
.endm
.macro senduart,rd,rx
diff --git a/arch/arm/mach-footbridge/include/mach/vmalloc.h b/arch/arm/mach-footbridge/include/mach/vmalloc.h
index d0958d860a3c..0ffbb7c85e59 100644
--- a/arch/arm/mach-footbridge/include/mach/vmalloc.h
+++ b/arch/arm/mach-footbridge/include/mach/vmalloc.h
@@ -7,4 +7,4 @@
*/
-#define VMALLOC_END (PAGE_OFFSET + 0x30000000)
+#define VMALLOC_END 0xf0000000
diff --git a/arch/arm/mach-footbridge/netwinder-hw.c b/arch/arm/mach-footbridge/netwinder-hw.c
index ac7ffa6fc413..06e514f372d0 100644
--- a/arch/arm/mach-footbridge/netwinder-hw.c
+++ b/arch/arm/mach-footbridge/netwinder-hw.c
@@ -648,8 +648,6 @@ fixup_netwinder(struct machine_desc *desc, struct tag *tags,
MACHINE_START(NETWINDER, "Rebel-NetWinder")
/* Maintainer: Russell King/Rebel.com */
- .phys_io = DC21285_ARMCSR_BASE,
- .io_pg_offst = ((0xfe000000) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.video_start = 0x000a0000,
.video_end = 0x000bffff,
diff --git a/arch/arm/mach-footbridge/personal.c b/arch/arm/mach-footbridge/personal.c
index e2c9f0690b16..3285e91ca8c1 100644
--- a/arch/arm/mach-footbridge/personal.c
+++ b/arch/arm/mach-footbridge/personal.c
@@ -15,8 +15,6 @@
MACHINE_START(PERSONAL_SERVER, "Compaq-PersonalServer")
/* Maintainer: Jamey Hicks / George France */
- .phys_io = DC21285_ARMCSR_BASE,
- .io_pg_offst = ((0xfe000000) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.map_io = footbridge_map_io,
.init_irq = footbridge_init_irq,
diff --git a/arch/arm/mach-gemini/board-nas4220b.c b/arch/arm/mach-gemini/board-nas4220b.c
index 01f1d6daab44..2ba096de0034 100644
--- a/arch/arm/mach-gemini/board-nas4220b.c
+++ b/arch/arm/mach-gemini/board-nas4220b.c
@@ -101,8 +101,6 @@ static void __init ib4220b_init(void)
}
MACHINE_START(NAS4220B, "Raidsonic NAS IB-4220-B")
- .phys_io = 0x7fffc000,
- .io_pg_offst = ((0xffffc000) >> 18) & 0xfffc,
.boot_params = 0x100,
.map_io = gemini_map_io,
.init_irq = gemini_init_irq,
diff --git a/arch/arm/mach-gemini/board-rut1xx.c b/arch/arm/mach-gemini/board-rut1xx.c
index e0de968e32a6..a9a0d8b01942 100644
--- a/arch/arm/mach-gemini/board-rut1xx.c
+++ b/arch/arm/mach-gemini/board-rut1xx.c
@@ -85,8 +85,6 @@ static void __init rut1xx_init(void)
}
MACHINE_START(RUT100, "Teltonika RUT100")
- .phys_io = 0x7fffc000,
- .io_pg_offst = ((0xffffc000) >> 18) & 0xfffc,
.boot_params = 0x100,
.map_io = gemini_map_io,
.init_irq = gemini_init_irq,
diff --git a/arch/arm/mach-gemini/board-wbd111.c b/arch/arm/mach-gemini/board-wbd111.c
index 36538c15b3c4..8b88d50d4337 100644
--- a/arch/arm/mach-gemini/board-wbd111.c
+++ b/arch/arm/mach-gemini/board-wbd111.c
@@ -133,8 +133,6 @@ static void __init wbd111_init(void)
}
MACHINE_START(WBD111, "Wiliboard WBD-111")
- .phys_io = 0x7fffc000,
- .io_pg_offst = ((0xffffc000) >> 18) & 0xfffc,
.boot_params = 0x100,
.map_io = gemini_map_io,
.init_irq = gemini_init_irq,
diff --git a/arch/arm/mach-gemini/board-wbd222.c b/arch/arm/mach-gemini/board-wbd222.c
index ece8b4c65110..1eebcecd1c33 100644
--- a/arch/arm/mach-gemini/board-wbd222.c
+++ b/arch/arm/mach-gemini/board-wbd222.c
@@ -133,8 +133,6 @@ static void __init wbd222_init(void)
}
MACHINE_START(WBD222, "Wiliboard WBD-222")
- .phys_io = 0x7fffc000,
- .io_pg_offst = ((0xffffc000) >> 18) & 0xfffc,
.boot_params = 0x100,
.map_io = gemini_map_io,
.init_irq = gemini_init_irq,
diff --git a/arch/arm/mach-gemini/include/mach/debug-macro.S b/arch/arm/mach-gemini/include/mach/debug-macro.S
index ad477047069d..f40e006d296e 100644
--- a/arch/arm/mach-gemini/include/mach/debug-macro.S
+++ b/arch/arm/mach-gemini/include/mach/debug-macro.S
@@ -11,11 +11,9 @@
*/
#include <mach/hardware.h>
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- ldreq \rx, =GEMINI_UART_BASE @ physical
- ldrne \rx, =IO_ADDRESS(GEMINI_UART_BASE) @ virtual
+ .macro addruart, rp, rv
+ ldr \rp, =GEMINI_UART_BASE @ physical
+ ldr \rv, =IO_ADDRESS(GEMINI_UART_BASE) @ virtual
.endm
#define UART_SHIFT 2
diff --git a/arch/arm/mach-h720x/h7201-eval.c b/arch/arm/mach-h720x/h7201-eval.c
index 78be457dc324..79f0b896e446 100644
--- a/arch/arm/mach-h720x/h7201-eval.c
+++ b/arch/arm/mach-h720x/h7201-eval.c
@@ -30,8 +30,6 @@
MACHINE_START(H7201, "Hynix GMS30C7201")
/* Maintainer: Robert Schwebel, Pengutronix */
- .phys_io = 0x80000000,
- .io_pg_offst = ((0xf0000000) >> 18) & 0xfffc,
.boot_params = 0xc0001000,
.map_io = h720x_map_io,
.init_irq = h720x_init_irq,
diff --git a/arch/arm/mach-h720x/h7202-eval.c b/arch/arm/mach-h720x/h7202-eval.c
index 8c0ba99d683f..cc28b1efe047 100644
--- a/arch/arm/mach-h720x/h7202-eval.c
+++ b/arch/arm/mach-h720x/h7202-eval.c
@@ -72,8 +72,6 @@ static void __init init_eval_h7202(void)
MACHINE_START(H7202, "Hynix HMS30C7202")
/* Maintainer: Robert Schwebel, Pengutronix */
- .phys_io = 0x80000000,
- .io_pg_offst = ((0xf0000000) >> 18) & 0xfffc,
.boot_params = 0x40000100,
.map_io = h720x_map_io,
.init_irq = h7202_init_irq,
diff --git a/arch/arm/mach-h720x/include/mach/debug-macro.S b/arch/arm/mach-h720x/include/mach/debug-macro.S
index 27cafd12f033..c2093e835720 100644
--- a/arch/arm/mach-h720x/include/mach/debug-macro.S
+++ b/arch/arm/mach-h720x/include/mach/debug-macro.S
@@ -16,12 +16,10 @@
.equ io_virt, IO_VIRT
.equ io_phys, IO_PHYS
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- moveq \rx, #io_phys @ physical base address
- movne \rx, #io_virt @ virtual address
- add \rx, \rx, #0x00020000 @ UART1
+ .macro addruart, rp, rv
+ mov \rp, #0x00020000 @ UART1
+ add \rv, \rp, #io_virt @ virtual address
+ add \rp, \rp, #io_phys @ physical base address
.endm
.macro senduart,rd,rx
diff --git a/arch/arm/mach-h720x/include/mach/vmalloc.h b/arch/arm/mach-h720x/include/mach/vmalloc.h
index ff1460d6841b..a45915b88756 100644
--- a/arch/arm/mach-h720x/include/mach/vmalloc.h
+++ b/arch/arm/mach-h720x/include/mach/vmalloc.h
@@ -5,6 +5,6 @@
#ifndef __ARCH_ARM_VMALLOC_H
#define __ARCH_ARM_VMALLOC_H
-#define VMALLOC_END (PAGE_OFFSET + 0x10000000)
+#define VMALLOC_END 0xd0000000
#endif
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index c5c0369bb481..197f9e241cff 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -122,6 +122,7 @@ config MACH_CPUIMX27
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_MXC_NAND
+ select MXC_ULPI if USB_ULPI
help
Include support for Eukrea CPUIMX27 platform. This includes
specific configurations for the module and its peripherals.
@@ -146,8 +147,8 @@ choice
default MACH_EUKREA_MBIMX27_BASEBOARD
config MACH_EUKREA_MBIMX27_BASEBOARD
- prompt "Eukrea MBIMX27 development board"
- bool
+ bool "Eukrea MBIMX27 development board"
+ select IMX_HAVE_PLATFORM_IMX_SSI
select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_SPI_IMX
help
@@ -163,6 +164,15 @@ config MACH_MX27_3DS
Include support for MX27PDK platform. This includes specific
configurations for the board and its peripherals.
+config MACH_IMX27_VISSTRIM_M10
+ bool "Vista Silicon i.MX27 Visstrim_m10"
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ help
+ Include support for Visstrim_m10 platform and its different variants.
+ This includes specific configurations for the board and its
+ peripherals.
+
config MACH_IMX27LITE
bool "LogicPD MX27 LITEKIT platform"
select IMX_HAVE_PLATFORM_IMX_UART
@@ -173,6 +183,7 @@ config MACH_IMX27LITE
config MACH_PCA100
bool "Phytec phyCARD-s (pca100)"
select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_SSI
select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_MXC_NAND
select IMX_HAVE_PLATFORM_SPI_IMX
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 46a9fdfbbd15..5582692bb176 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_MACH_PCM038) += mach-pcm038.o
obj-$(CONFIG_MACH_PCM970_BASEBOARD) += pcm970-baseboard.o
obj-$(CONFIG_MACH_MX27_3DS) += mach-mx27_3ds.o
obj-$(CONFIG_MACH_IMX27LITE) += mach-imx27lite.o
+obj-$(CONFIG_MACH_IMX27_VISSTRIM_M10) += mach-imx27_visstrim_m10.o
obj-$(CONFIG_MACH_CPUIMX27) += mach-cpuimx27.o
obj-$(CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD) += eukrea_mbimx27-baseboard.o
obj-$(CONFIG_MACH_PCA100) += mach-pca100.o
diff --git a/arch/arm/mach-imx/clock-imx1.c b/arch/arm/mach-imx/clock-imx1.c
index c05096c38301..daca30b2d5b1 100644
--- a/arch/arm/mach-imx/clock-imx1.c
+++ b/arch/arm/mach-imx/clock-imx1.c
@@ -592,7 +592,7 @@ static struct clk_lookup lookups[] __initdata = {
_REGISTER_CLOCK("imx-uart.1", NULL, uart_clk)
_REGISTER_CLOCK("imx-uart.2", NULL, uart_clk)
_REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
- _REGISTER_CLOCK("spi_imx.0", NULL, spi_clk)
+ _REGISTER_CLOCK("imx1-cspi.0", NULL, spi_clk)
_REGISTER_CLOCK("imx-mmc.0", NULL, sdhc_clk)
_REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
_REGISTER_CLOCK(NULL, "mshc", mshc_clk)
diff --git a/arch/arm/mach-imx/clock-imx21.c b/arch/arm/mach-imx/clock-imx21.c
index bb419ef4d133..cf15ea516a72 100644
--- a/arch/arm/mach-imx/clock-imx21.c
+++ b/arch/arm/mach-imx/clock-imx21.c
@@ -1172,9 +1172,9 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK(NULL, "pwm", pwm_clk[0])
_REGISTER_CLOCK(NULL, "sdhc1", sdhc_clk[0])
_REGISTER_CLOCK(NULL, "sdhc2", sdhc_clk[1])
- _REGISTER_CLOCK(NULL, "cspi1", cspi_clk[0])
- _REGISTER_CLOCK(NULL, "cspi2", cspi_clk[1])
- _REGISTER_CLOCK(NULL, "cspi3", cspi_clk[2])
+ _REGISTER_CLOCK("imx21-cspi.0", NULL, cspi_clk[0])
+ _REGISTER_CLOCK("imx21-cspi.1", NULL, cspi_clk[1])
+ _REGISTER_CLOCK("imx21-cspi.2", NULL, cspi_clk[2])
_REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk[0])
_REGISTER_CLOCK(NULL, "csi", csi_clk[0])
_REGISTER_CLOCK("imx21-hcd.0", NULL, usb_clk[0])
diff --git a/arch/arm/mach-imx/clock-imx27.c b/arch/arm/mach-imx/clock-imx27.c
index 5a1aa15c8a16..98a25bada783 100644
--- a/arch/arm/mach-imx/clock-imx27.c
+++ b/arch/arm/mach-imx/clock-imx27.c
@@ -594,27 +594,27 @@ DEFINE_CLOCK(uart2_clk1, 0, PCCR1, 30, NULL, NULL, &ipg_clk);
DEFINE_CLOCK(uart1_clk1, 0, PCCR1, 31, NULL, NULL, &ipg_clk);
/* Clocks we cannot directly gate, but drivers need their rates */
-DEFINE_CLOCK(cspi1_clk, 0, 0, 0, NULL, &cspi1_clk1, &per2_clk);
-DEFINE_CLOCK(cspi2_clk, 1, 0, 0, NULL, &cspi2_clk1, &per2_clk);
-DEFINE_CLOCK(cspi3_clk, 2, 0, 0, NULL, &cspi13_clk1, &per2_clk);
-DEFINE_CLOCK(sdhc1_clk, 0, 0, 0, NULL, &sdhc1_clk1, &per2_clk);
-DEFINE_CLOCK(sdhc2_clk, 1, 0, 0, NULL, &sdhc2_clk1, &per2_clk);
-DEFINE_CLOCK(sdhc3_clk, 2, 0, 0, NULL, &sdhc3_clk1, &per2_clk);
-DEFINE_CLOCK(pwm_clk, 0, 0, 0, NULL, &pwm_clk1, &per1_clk);
-DEFINE_CLOCK(gpt1_clk, 0, 0, 0, NULL, &gpt1_clk1, &per1_clk);
-DEFINE_CLOCK(gpt2_clk, 1, 0, 0, NULL, &gpt2_clk1, &per1_clk);
-DEFINE_CLOCK(gpt3_clk, 2, 0, 0, NULL, &gpt3_clk1, &per1_clk);
-DEFINE_CLOCK(gpt4_clk, 3, 0, 0, NULL, &gpt4_clk1, &per1_clk);
-DEFINE_CLOCK(gpt5_clk, 4, 0, 0, NULL, &gpt5_clk1, &per1_clk);
-DEFINE_CLOCK(gpt6_clk, 5, 0, 0, NULL, &gpt6_clk1, &per1_clk);
-DEFINE_CLOCK(uart1_clk, 0, 0, 0, NULL, &uart1_clk1, &per1_clk);
-DEFINE_CLOCK(uart2_clk, 1, 0, 0, NULL, &uart2_clk1, &per1_clk);
-DEFINE_CLOCK(uart3_clk, 2, 0, 0, NULL, &uart3_clk1, &per1_clk);
-DEFINE_CLOCK(uart4_clk, 3, 0, 0, NULL, &uart4_clk1, &per1_clk);
-DEFINE_CLOCK(uart5_clk, 4, 0, 0, NULL, &uart5_clk1, &per1_clk);
-DEFINE_CLOCK(uart6_clk, 5, 0, 0, NULL, &uart6_clk1, &per1_clk);
-DEFINE_CLOCK1(lcdc_clk, 0, 0, 0, parent, &lcdc_clk1, &per3_clk);
-DEFINE_CLOCK1(csi_clk, 0, 0, 0, parent, &csi_clk1, &per4_clk);
+DEFINE_CLOCK(cspi1_clk, 0, NULL, 0, NULL, &cspi1_clk1, &per2_clk);
+DEFINE_CLOCK(cspi2_clk, 1, NULL, 0, NULL, &cspi2_clk1, &per2_clk);
+DEFINE_CLOCK(cspi3_clk, 2, NULL, 0, NULL, &cspi13_clk1, &per2_clk);
+DEFINE_CLOCK(sdhc1_clk, 0, NULL, 0, NULL, &sdhc1_clk1, &per2_clk);
+DEFINE_CLOCK(sdhc2_clk, 1, NULL, 0, NULL, &sdhc2_clk1, &per2_clk);
+DEFINE_CLOCK(sdhc3_clk, 2, NULL, 0, NULL, &sdhc3_clk1, &per2_clk);
+DEFINE_CLOCK(pwm_clk, 0, NULL, 0, NULL, &pwm_clk1, &per1_clk);
+DEFINE_CLOCK(gpt1_clk, 0, NULL, 0, NULL, &gpt1_clk1, &per1_clk);
+DEFINE_CLOCK(gpt2_clk, 1, NULL, 0, NULL, &gpt2_clk1, &per1_clk);
+DEFINE_CLOCK(gpt3_clk, 2, NULL, 0, NULL, &gpt3_clk1, &per1_clk);
+DEFINE_CLOCK(gpt4_clk, 3, NULL, 0, NULL, &gpt4_clk1, &per1_clk);
+DEFINE_CLOCK(gpt5_clk, 4, NULL, 0, NULL, &gpt5_clk1, &per1_clk);
+DEFINE_CLOCK(gpt6_clk, 5, NULL, 0, NULL, &gpt6_clk1, &per1_clk);
+DEFINE_CLOCK(uart1_clk, 0, NULL, 0, NULL, &uart1_clk1, &per1_clk);
+DEFINE_CLOCK(uart2_clk, 1, NULL, 0, NULL, &uart2_clk1, &per1_clk);
+DEFINE_CLOCK(uart3_clk, 2, NULL, 0, NULL, &uart3_clk1, &per1_clk);
+DEFINE_CLOCK(uart4_clk, 3, NULL, 0, NULL, &uart4_clk1, &per1_clk);
+DEFINE_CLOCK(uart5_clk, 4, NULL, 0, NULL, &uart5_clk1, &per1_clk);
+DEFINE_CLOCK(uart6_clk, 5, NULL, 0, NULL, &uart6_clk1, &per1_clk);
+DEFINE_CLOCK1(lcdc_clk, 0, NULL, 0, parent, &lcdc_clk1, &per3_clk);
+DEFINE_CLOCK1(csi_clk, 0, NULL, 0, parent, &csi_clk1, &per4_clk);
#define _REGISTER_CLOCK(d, n, c) \
{ \
@@ -640,9 +640,9 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk)
_REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk)
_REGISTER_CLOCK("mxc-mmc.2", NULL, sdhc3_clk)
- _REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk)
- _REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk)
- _REGISTER_CLOCK("spi_imx.2", NULL, cspi3_clk)
+ _REGISTER_CLOCK("imx27-cspi.0", NULL, cspi1_clk)
+ _REGISTER_CLOCK("imx27-cspi.1", NULL, cspi2_clk)
+ _REGISTER_CLOCK("imx27-cspi.2", NULL, cspi3_clk)
_REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
_REGISTER_CLOCK("mx2-camera.0", NULL, csi_clk)
_REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk)
diff --git a/arch/arm/mach-imx/devices-imx1.h b/arch/arm/mach-imx/devices-imx1.h
index a8d94f078196..81979486218e 100644
--- a/arch/arm/mach-imx/devices-imx1.h
+++ b/arch/arm/mach-imx/devices-imx1.h
@@ -9,10 +9,12 @@
#include <mach/mx1.h>
#include <mach/devices-common.h>
-#define imx1_add_i2c_imx(pdata) \
- imx_add_imx_i2c(0, MX1_I2C_BASE_ADDR, SZ_4K, MX1_INT_I2C, pdata)
+extern const struct imx_imx_i2c_data imx1_imx_i2c_data __initconst;
+#define imx1_add_imx_i2c(pdata) \
+ imx_add_imx_i2c(&imx1_imx_i2c_data, pdata)
-#define imx1_add_imx_uart0(pdata) \
- imx_add_imx_uart_3irq(0, MX1_UART1_BASE_ADDR, 0xd0, MX1_INT_UART1RX, MX1_INT_UART1TX, MX1_INT_UART1RTS, pdata)
-#define imx1_add_imx_uart1(pdata) \
- imx_add_imx_uart_3irq(0, MX1_UART2_BASE_ADDR, 0xd0, MX1_INT_UART2RX, MX1_INT_UART2TX, MX1_INT_UART2RTS, pdata)
+extern const struct imx_imx_uart_3irq_data imx1_imx_uart_data[] __initconst;
+#define imx1_add_imx_uart(id, pdata) \
+ imx_add_imx_uart_3irq(&imx1_imx_uart_data[id], pdata)
+#define imx1_add_imx_uart0(pdata) imx1_add_imx_uart(0, pdata)
+#define imx1_add_imx_uart1(pdata) imx1_add_imx_uart(1, pdata)
diff --git a/arch/arm/mach-imx/devices-imx21.h b/arch/arm/mach-imx/devices-imx21.h
index 42788e99d127..d189039749b0 100644
--- a/arch/arm/mach-imx/devices-imx21.h
+++ b/arch/arm/mach-imx/devices-imx21.h
@@ -9,22 +9,28 @@
#include <mach/mx21.h>
#include <mach/devices-common.h>
-#define imx21_add_i2c_imx(pdata) \
- imx_add_imx_i2c(0, MX2x_I2C_BASE_ADDR, SZ_4K, MX2x_INT_I2C, pdata)
+extern const struct imx_imx_i2c_data imx21_imx_i2c_data __initconst;
+#define imx21_add_imx_i2c(pdata) \
+ imx_add_imx_i2c(&imx21_imx_i2c_data, pdata)
-#define imx21_add_imx_uart0(pdata) \
- imx_add_imx_uart_1irq(0, MX21_UART1_BASE_ADDR, SZ_4K, MX21_INT_UART1, pdata)
-#define imx21_add_imx_uart1(pdata) \
- imx_add_imx_uart_1irq(1, MX21_UART2_BASE_ADDR, SZ_4K, MX21_INT_UART2, pdata)
-#define imx21_add_imx_uart2(pdata) \
- imx_add_imx_uart_1irq(2, MX21_UART3_BASE_ADDR, SZ_4K, MX21_INT_UART3, pdata)
-#define imx21_add_imx_uart3(pdata) \
- imx_add_imx_uart_1irq(3, MX21_UART4_BASE_ADDR, SZ_4K, MX21_INT_UART4, pdata)
+extern const struct imx_imx_ssi_data imx21_imx_ssi_data[] __initconst;
+#define imx21_add_imx_ssi(id, pdata) \
+ imx_add_imx_ssi(&imx21_imx_ssi_data[id], pdata)
+extern const struct imx_imx_uart_1irq_data imx21_imx_uart_data[] __initconst;
+#define imx21_add_imx_uart(id, pdata) \
+ imx_add_imx_uart_1irq(&imx21_imx_uart_data[id], pdata)
+#define imx21_add_imx_uart0(pdata) imx21_add_imx_uart(0, pdata)
+#define imx21_add_imx_uart1(pdata) imx21_add_imx_uart(1, pdata)
+#define imx21_add_imx_uart2(pdata) imx21_add_imx_uart(2, pdata)
+#define imx21_add_imx_uart3(pdata) imx21_add_imx_uart(3, pdata)
+
+extern const struct imx_mxc_nand_data imx21_mxc_nand_data __initconst;
#define imx21_add_mxc_nand(pdata) \
- imx_add_mxc_nand_v1(MX21_NFC_BASE_ADDR, MX21_INT_NANDFC, pdata)
+ imx_add_mxc_nand(&imx21_mxc_nand_data, pdata)
-#define imx21_add_spi_imx0(pdata) \
- imx_add_spi_imx(0, MX21_CSPI1_BASE_ADDR, SZ_4K, MX21_INT_CSPI1, pdata)
-#define imx21_add_spi_imx1(pdata) \
- imx_add_spi_imx(1, MX21_CSPI2_BASE_ADDR, SZ_4K, MX21_INT_CSPI2, pdata)
+extern const struct imx_spi_imx_data imx21_cspi_data[] __initconst;
+#define imx21_add_cspi(id, pdata) \
+ imx_add_spi_imx(&imx21_cspi_data[id], pdata)
+#define imx21_add_spi_imx0(pdata) imx21_add_cspi(0, pdata)
+#define imx21_add_spi_imx1(pdata) imx21_add_cspi(1, pdata)
diff --git a/arch/arm/mach-imx/devices-imx27.h b/arch/arm/mach-imx/devices-imx27.h
index 65e7bb7ec2e8..7011690364f2 100644
--- a/arch/arm/mach-imx/devices-imx27.h
+++ b/arch/arm/mach-imx/devices-imx27.h
@@ -9,30 +9,35 @@
#include <mach/mx27.h>
#include <mach/devices-common.h>
-#define imx27_add_i2c_imx0(pdata) \
- imx_add_imx_i2c(0, MX27_I2C1_BASE_ADDR, SZ_4K, MX27_INT_I2C1, pdata)
-#define imx27_add_i2c_imx1(pdata) \
- imx_add_imx_i2c(1, MX27_I2C2_BASE_ADDR, SZ_4K, MX27_INT_I2C2, pdata)
+extern const struct imx_fec_data imx27_fec_data __initconst;
+#define imx27_add_fec(pdata) \
+ imx_add_fec(&imx27_fec_data, pdata)
-#define imx27_add_imx_uart0(pdata) \
- imx_add_imx_uart_1irq(0, MX27_UART1_BASE_ADDR, SZ_4K, MX27_INT_UART1, pdata)
-#define imx27_add_imx_uart1(pdata) \
- imx_add_imx_uart_1irq(1, MX27_UART2_BASE_ADDR, SZ_4K, MX27_INT_UART2, pdata)
-#define imx27_add_imx_uart2(pdata) \
- imx_add_imx_uart_1irq(2, MX27_UART3_BASE_ADDR, SZ_4K, MX27_INT_UART3, pdata)
-#define imx27_add_imx_uart3(pdata) \
- imx_add_imx_uart_1irq(3, MX27_UART4_BASE_ADDR, SZ_4K, MX27_INT_UART4, pdata)
-#define imx27_add_imx_uart4(pdata) \
- imx_add_imx_uart_1irq(4, MX27_UART5_BASE_ADDR, SZ_4K, MX27_INT_UART5, pdata)
-#define imx27_add_imx_uart5(pdata) \
- imx_add_imx_uart_1irq(5, MX27_UART6_BASE_ADDR, SZ_4K, MX27_INT_UART6, pdata)
+extern const struct imx_imx_i2c_data imx27_imx_i2c_data[] __initconst;
+#define imx27_add_imx_i2c(id, pdata) \
+ imx_add_imx_i2c(&imx27_imx_i2c_data[id], pdata)
+extern const struct imx_imx_ssi_data imx27_imx_ssi_data[] __initconst;
+#define imx27_add_imx_ssi(id, pdata) \
+ imx_add_imx_ssi(&imx27_imx_ssi_data[id], pdata)
+
+extern const struct imx_imx_uart_1irq_data imx27_imx_uart_data[] __initconst;
+#define imx27_add_imx_uart(id, pdata) \
+ imx_add_imx_uart_1irq(&imx27_imx_uart_data[id], pdata)
+#define imx27_add_imx_uart0(pdata) imx27_add_imx_uart(0, pdata)
+#define imx27_add_imx_uart1(pdata) imx27_add_imx_uart(1, pdata)
+#define imx27_add_imx_uart2(pdata) imx27_add_imx_uart(2, pdata)
+#define imx27_add_imx_uart3(pdata) imx27_add_imx_uart(3, pdata)
+#define imx27_add_imx_uart4(pdata) imx27_add_imx_uart(4, pdata)
+#define imx27_add_imx_uart5(pdata) imx27_add_imx_uart(5, pdata)
+
+extern const struct imx_mxc_nand_data imx27_mxc_nand_data __initconst;
#define imx27_add_mxc_nand(pdata) \
- imx_add_mxc_nand_v1(MX27_NFC_BASE_ADDR, MX27_INT_NANDFC, pdata)
+ imx_add_mxc_nand(&imx27_mxc_nand_data, pdata)
-#define imx27_add_spi_imx0(pdata) \
- imx_add_spi_imx(0, MX27_CSPI1_BASE_ADDR, SZ_4K, MX27_INT_CSPI1, pdata)
-#define imx27_add_spi_imx1(pdata) \
- imx_add_spi_imx(1, MX27_CSPI2_BASE_ADDR, SZ_4K, MX27_INT_CSPI2, pdata)
-#define imx27_add_spi_imx2(pdata) \
- imx_add_spi_imx(2, MX27_CSPI3_BASE_ADDR, SZ_4K, MX27_INT_CSPI3, pdata)
+extern const struct imx_spi_imx_data imx27_cspi_data[] __initconst;
+#define imx27_add_cspi(id, pdata) \
+ imx_add_spi_imx(&imx27_cspi_data[id], pdata)
+#define imx27_add_spi_imx0(pdata) imx27_add_cspi(0, pdata)
+#define imx27_add_spi_imx1(pdata) imx27_add_cspi(1, pdata)
+#define imx27_add_spi_imx2(pdata) imx27_add_cspi(2, pdata)
diff --git a/arch/arm/mach-imx/devices.c b/arch/arm/mach-imx/devices.c
index 9c271a752b84..fba5047de8b1 100644
--- a/arch/arm/mach-imx/devices.c
+++ b/arch/arm/mach-imx/devices.c
@@ -314,27 +314,6 @@ struct platform_device mxc_fb_device = {
},
};
-#ifdef CONFIG_MACH_MX27
-static struct resource mxc_fec_resources[] = {
- {
- .start = MX27_FEC_BASE_ADDR,
- .end = MX27_FEC_BASE_ADDR + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX27_INT_FEC,
- .end = MX27_INT_FEC,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_fec_device = {
- .name = "fec",
- .id = 0,
- .num_resources = ARRAY_SIZE(mxc_fec_resources),
- .resource = mxc_fec_resources,
-};
-#endif
-
static struct resource mxc_pwm_resources[] = {
{
.start = MX2x_PWM_BASE_ADDR,
@@ -480,41 +459,6 @@ struct platform_device mxc_usbh2 = {
};
#endif
-#define DEFINE_IMX_SSI_DMARES(_name, ssin, suffix) \
- { \
- .name = _name, \
- .start = MX2x_DMA_REQ_SSI ## ssin ## _ ## suffix, \
- .end = MX2x_DMA_REQ_SSI ## ssin ## _ ## suffix, \
- .flags = IORESOURCE_DMA, \
- }
-
-#define DEFINE_IMX_SSI_DEVICE(n, ssin, baseaddr, irq) \
- static struct resource imx_ssi_resources ## n[] = { \
- { \
- .start = MX2x_SSI ## ssin ## _BASE_ADDR, \
- .end = MX2x_SSI ## ssin ## _BASE_ADDR + 0x6f, \
- .flags = IORESOURCE_MEM, \
- }, { \
- .start = MX2x_INT_SSI1, \
- .end = MX2x_INT_SSI1, \
- .flags = IORESOURCE_IRQ, \
- }, \
- DEFINE_IMX_SSI_DMARES("tx0", ssin, TX0), \
- DEFINE_IMX_SSI_DMARES("rx0", ssin, RX0), \
- DEFINE_IMX_SSI_DMARES("tx1", ssin, TX1), \
- DEFINE_IMX_SSI_DMARES("rx1", ssin, RX1), \
- }; \
- \
- struct platform_device imx_ssi_device ## n = { \
- .name = "imx-ssi", \
- .id = n, \
- .num_resources = ARRAY_SIZE(imx_ssi_resources ## n), \
- .resource = imx_ssi_resources ## n, \
- }
-
-DEFINE_IMX_SSI_DEVICE(0, 1, MX2x_SSI1_BASE_ADDR, MX2x_INT_SSI1);
-DEFINE_IMX_SSI_DEVICE(1, 2, MX2x_SSI1_BASE_ADDR, MX2x_INT_SSI1);
-
/* GPIO port description */
#define DEFINE_MXC_GPIO_PORT_IRQ(SOC, n, _irq) \
{ \
diff --git a/arch/arm/mach-imx/devices.h b/arch/arm/mach-imx/devices.h
index efd4527506a5..807f02a031c9 100644
--- a/arch/arm/mach-imx/devices.h
+++ b/arch/arm/mach-imx/devices.h
@@ -16,7 +16,6 @@ extern struct platform_device mxc_gpt5;
extern struct platform_device mxc_wdt;
extern struct platform_device mxc_w1_master_device;
extern struct platform_device mxc_fb_device;
-extern struct platform_device mxc_fec_device;
extern struct platform_device mxc_pwm_device;
extern struct platform_device mxc_sdhc_device0;
extern struct platform_device mxc_sdhc_device1;
@@ -26,7 +25,5 @@ extern struct platform_device mxc_otg_host;
extern struct platform_device mxc_usbh1;
extern struct platform_device mxc_usbh2;
extern struct platform_device mx21_usbhc_device;
-extern struct platform_device imx_ssi_device0;
-extern struct platform_device imx_ssi_device1;
extern struct platform_device imx_kpp_device;
#endif
diff --git a/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c b/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c
index 4edc5f439201..026263c665ca 100644
--- a/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c
+++ b/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c
@@ -36,13 +36,12 @@
#include <mach/hardware.h>
#include <mach/mmc.h>
#include <mach/spi.h>
-#include <mach/ssi.h>
#include <mach/audmux.h>
#include "devices-imx27.h"
#include "devices.h"
-static int eukrea_mbimx27_pins[] = {
+static const int eukrea_mbimx27_pins[] __initconst = {
/* UART2 */
PE3_PF_UART2_CTS,
PE4_PF_UART2_RTS,
@@ -311,7 +310,8 @@ static struct imxmmc_platform_data sdhc_pdata = {
.dat3_card_detect = 1,
};
-struct imx_ssi_platform_data eukrea_mbimx27_ssi_pdata = {
+static const
+struct imx_ssi_platform_data eukrea_mbimx27_ssi_pdata __initconst = {
.flags = IMX_SSI_DMA | IMX_SSI_USE_I2S_SLAVE,
};
@@ -357,7 +357,7 @@ void __init eukrea_mbimx27_baseboard_init(void)
i2c_register_board_info(0, eukrea_mbimx27_i2c_devices,
ARRAY_SIZE(eukrea_mbimx27_i2c_devices));
- mxc_register_device(&imx_ssi_device0, &eukrea_mbimx27_ssi_pdata);
+ imx27_add_imx_ssi(0, &eukrea_mbimx27_ssi_pdata);
#if defined(CONFIG_TOUCHSCREEN_ADS7846) \
|| defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
diff --git a/arch/arm/mach-imx/mach-cpuimx27.c b/arch/arm/mach-imx/mach-cpuimx27.c
index 339150ab0ea5..745ee60fb068 100644
--- a/arch/arm/mach-imx/mach-cpuimx27.c
+++ b/arch/arm/mach-imx/mach-cpuimx27.c
@@ -46,7 +46,7 @@
#include "devices-imx27.h"
#include "devices.h"
-static int eukrea_cpuimx27_pins[] = {
+static const int eukrea_cpuimx27_pins[] __initconst = {
/* UART1 */
PE12_PF_UART1_TXD,
PE13_PF_UART1_RXD,
@@ -157,7 +157,6 @@ cpuimx27_nand_board_info __initconst = {
static struct platform_device *platform_devices[] __initdata = {
&eukrea_cpuimx27_nor_mtd_device,
- &mxc_fec_device,
&mxc_wdt,
&mxc_w1_master_device,
};
@@ -259,8 +258,9 @@ static void __init eukrea_cpuimx27_init(void)
i2c_register_board_info(0, eukrea_cpuimx27_i2c_devices,
ARRAY_SIZE(eukrea_cpuimx27_i2c_devices));
- imx27_add_i2c_imx1(&cpuimx27_i2c1_data);
+ imx27_add_imx_i2c(0, &cpuimx27_i2c1_data);
+ imx27_add_fec(NULL);
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
#if defined(CONFIG_MACH_EUKREA_CPUIMX27_USESDHC2)
@@ -307,8 +307,6 @@ static struct sys_timer eukrea_cpuimx27_timer = {
};
MACHINE_START(CPUIMX27, "EUKREA CPUIMX27")
- .phys_io = MX27_AIPI_BASE_ADDR,
- .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
.boot_params = MX27_PHYS_OFFSET + 0x100,
.map_io = mx27_map_io,
.init_irq = mx27_init_irq,
diff --git a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
new file mode 100644
index 000000000000..59716fab586d
--- /dev/null
+++ b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
@@ -0,0 +1,261 @@
+/*
+ * mach-imx27_visstrim_m10.c
+ *
+ * Copyright 2010 Javier Martin <javier.martin@vista-silicon.com>
+ *
+ * Based on mach-pcm038.c, mach-pca100.c, mach-mx27ads.c and others.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pca953x.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <mach/common.h>
+#include <mach/mmc.h>
+#include <mach/iomux.h>
+#include <mach/mxc_ehci.h>
+
+#include "devices-imx27.h"
+#include "devices.h"
+
+#define OTG_PHY_CS_GPIO (GPIO_PORTF + 17)
+#define SDHC1_IRQ IRQ_GPIOB(25)
+
+static const int visstrim_m10_pins[] __initconst = {
+ /* UART1 (console) */
+ PE12_PF_UART1_TXD,
+ PE13_PF_UART1_RXD,
+ PE14_PF_UART1_CTS,
+ PE15_PF_UART1_RTS,
+ /* FEC */
+ PD0_AIN_FEC_TXD0,
+ PD1_AIN_FEC_TXD1,
+ PD2_AIN_FEC_TXD2,
+ PD3_AIN_FEC_TXD3,
+ PD4_AOUT_FEC_RX_ER,
+ PD5_AOUT_FEC_RXD1,
+ PD6_AOUT_FEC_RXD2,
+ PD7_AOUT_FEC_RXD3,
+ PD8_AF_FEC_MDIO,
+ PD9_AIN_FEC_MDC,
+ PD10_AOUT_FEC_CRS,
+ PD11_AOUT_FEC_TX_CLK,
+ PD12_AOUT_FEC_RXD0,
+ PD13_AOUT_FEC_RX_DV,
+ PD14_AOUT_FEC_RX_CLK,
+ PD15_AOUT_FEC_COL,
+ PD16_AIN_FEC_TX_ER,
+ PF23_AIN_FEC_TX_EN,
+ /* SDHC1 */
+ PE18_PF_SD1_D0,
+ PE19_PF_SD1_D1,
+ PE20_PF_SD1_D2,
+ PE21_PF_SD1_D3,
+ PE22_PF_SD1_CMD,
+ PE23_PF_SD1_CLK,
+ /* Both I2Cs */
+ PD17_PF_I2C_DATA,
+ PD18_PF_I2C_CLK,
+ PC5_PF_I2C2_SDA,
+ PC6_PF_I2C2_SCL,
+ /* USB OTG */
+ OTG_PHY_CS_GPIO | GPIO_GPIO | GPIO_OUT,
+ PC9_PF_USBOTG_DATA0,
+ PC11_PF_USBOTG_DATA1,
+ PC10_PF_USBOTG_DATA2,
+ PC13_PF_USBOTG_DATA3,
+ PC12_PF_USBOTG_DATA4,
+ PC7_PF_USBOTG_DATA5,
+ PC8_PF_USBOTG_DATA6,
+ PE25_PF_USBOTG_DATA7,
+ PE24_PF_USBOTG_CLK,
+ PE2_PF_USBOTG_DIR,
+ PE0_PF_USBOTG_NXT,
+ PE1_PF_USBOTG_STP,
+ PB23_PF_USB_PWR,
+ PB24_PF_USB_OC,
+};
+
+/* GPIOs used as events for applications */
+static struct gpio_keys_button visstrim_gpio_keys[] = {
+ {
+ .type = EV_KEY,
+ .code = KEY_RESTART,
+ .gpio = (GPIO_PORTC + 15),
+ .desc = "Default config",
+ .active_low = 0,
+ .wakeup = 1,
+ },
+ {
+ .type = EV_KEY,
+ .code = KEY_RECORD,
+ .gpio = (GPIO_PORTF + 14),
+ .desc = "Record",
+ .active_low = 0,
+ .wakeup = 1,
+ },
+ {
+ .type = EV_KEY,
+ .code = KEY_STOP,
+ .gpio = (GPIO_PORTF + 13),
+ .desc = "Stop",
+ .active_low = 0,
+ .wakeup = 1,
+ }
+};
+
+static struct gpio_keys_platform_data visstrim_gpio_keys_platform_data = {
+ .buttons = visstrim_gpio_keys,
+ .nbuttons = ARRAY_SIZE(visstrim_gpio_keys),
+};
+
+static struct platform_device visstrim_gpio_keys_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &visstrim_gpio_keys_platform_data,
+ },
+};
+
+/* Visstrim_SM10 has a microSD slot connected to sdhc1 */
+static int visstrim_m10_sdhc1_init(struct device *dev,
+ irq_handler_t detect_irq, void *data)
+{
+ int ret;
+
+ ret = request_irq(SDHC1_IRQ, detect_irq, IRQF_TRIGGER_FALLING,
+ "mmc-detect", data);
+ return ret;
+}
+
+static void visstrim_m10_sdhc1_exit(struct device *dev, void *data)
+{
+ free_irq(SDHC1_IRQ, data);
+}
+
+static struct imxmmc_platform_data visstrim_m10_sdhc_pdata = {
+ .init = visstrim_m10_sdhc1_init,
+ .exit = visstrim_m10_sdhc1_exit,
+};
+
+/* Visstrim_SM10 NOR flash */
+static struct physmap_flash_data visstrim_m10_flash_data = {
+ .width = 2,
+};
+
+static struct resource visstrim_m10_flash_resource = {
+ .start = 0xc0000000,
+ .end = 0xc0000000 + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device visstrim_m10_nor_mtd_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &visstrim_m10_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &visstrim_m10_flash_resource,
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+ &visstrim_gpio_keys_device,
+ &visstrim_m10_nor_mtd_device,
+};
+
+/* Visstrim_M10 uses UART0 as console */
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+/* I2C */
+static const struct imxi2c_platform_data visstrim_m10_i2c_data __initconst = {
+ .bitrate = 100000,
+};
+
+static struct pca953x_platform_data visstrim_m10_pca9555_pdata = {
+ .gpio_base = 240, /* After MX27 internal GPIOs */
+ .invert = 0,
+};
+
+static struct i2c_board_info visstrim_m10_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("pca9555", 0x20),
+ .platform_data = &visstrim_m10_pca9555_pdata,
+ },
+};
+
+/* USB OTG */
+static int otg_phy_init(struct platform_device *pdev)
+{
+ gpio_set_value(OTG_PHY_CS_GPIO, 0);
+ return 0;
+}
+
+static struct mxc_usbh_platform_data visstrim_m10_usbotg_pdata = {
+ .init = otg_phy_init,
+ .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+ .flags = MXC_EHCI_POWER_PINS_ENABLED,
+};
+
+static void __init visstrim_m10_board_init(void)
+{
+ int ret;
+
+ ret = mxc_gpio_setup_multiple_pins(visstrim_m10_pins,
+ ARRAY_SIZE(visstrim_m10_pins), "VISSTRIM_M10");
+ if (ret)
+ pr_err("Failed to setup pins (%d)\n", ret);
+
+ imx27_add_imx_uart0(&uart_pdata);
+
+ i2c_register_board_info(0, visstrim_m10_i2c_devices,
+ ARRAY_SIZE(visstrim_m10_i2c_devices));
+ imx27_add_imx_i2c(0, &visstrim_m10_i2c_data);
+ imx27_add_imx_i2c(1, &visstrim_m10_i2c_data);
+ mxc_register_device(&mxc_sdhc_device0, &visstrim_m10_sdhc_pdata);
+ mxc_register_device(&mxc_otg_host, &visstrim_m10_usbotg_pdata);
+ imx27_add_fec(NULL);
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+}
+
+static void __init visstrim_m10_timer_init(void)
+{
+ mx27_clocks_init((unsigned long)25000000);
+}
+
+static struct sys_timer visstrim_m10_timer = {
+ .init = visstrim_m10_timer_init,
+};
+
+MACHINE_START(IMX27_VISSTRIM_M10, "Vista Silicon Visstrim_M10")
+ .boot_params = MX27_PHYS_OFFSET + 0x100,
+ .map_io = mx27_map_io,
+ .init_irq = mx27_init_irq,
+ .init_machine = visstrim_m10_board_init,
+ .timer = &visstrim_m10_timer,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-imx27lite.c b/arch/arm/mach-imx/mach-imx27lite.c
index 22a2b5d91213..bbdbc75127d3 100644
--- a/arch/arm/mach-imx/mach-imx27lite.c
+++ b/arch/arm/mach-imx/mach-imx27lite.c
@@ -27,7 +27,7 @@
#include "devices-imx27.h"
#include "devices.h"
-static unsigned int mx27lite_pins[] = {
+static const int mx27lite_pins[] __initconst = {
/* UART1 */
PE12_PF_UART1_TXD,
PE13_PF_UART1_RXD,
@@ -58,16 +58,12 @@ static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
-static struct platform_device *platform_devices[] __initdata = {
- &mxc_fec_device,
-};
-
static void __init mx27lite_init(void)
{
mxc_gpio_setup_multiple_pins(mx27lite_pins, ARRAY_SIZE(mx27lite_pins),
"imx27lite");
imx27_add_imx_uart0(&uart_pdata);
- platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+ imx27_add_fec(NULL);
}
static void __init mx27lite_timer_init(void)
@@ -80,8 +76,6 @@ static struct sys_timer mx27lite_timer = {
};
MACHINE_START(IMX27LITE, "LogicPD i.MX27LITE")
- .phys_io = MX27_AIPI_BASE_ADDR,
- .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
.boot_params = MX27_PHYS_OFFSET + 0x100,
.map_io = mx27_map_io,
.init_irq = mx27_init_irq,
diff --git a/arch/arm/mach-imx/mach-mx1ads.c b/arch/arm/mach-imx/mach-mx1ads.c
index 77a760cfadc0..6187ce9ba7d5 100644
--- a/arch/arm/mach-imx/mach-mx1ads.c
+++ b/arch/arm/mach-imx/mach-mx1ads.c
@@ -32,7 +32,7 @@
#include "devices-imx1.h"
#include "devices.h"
-static int mx1ads_pins[] = {
+static const int mx1ads_pins[] __initconst = {
/* UART1 */
PC9_PF_UART1_CTS,
PC10_PF_UART1_RTS,
@@ -131,7 +131,7 @@ static void __init mx1ads_init(void)
i2c_register_board_info(0, mx1ads_i2c_devices,
ARRAY_SIZE(mx1ads_i2c_devices));
- imx1_add_i2c_imx(&mx1ads_i2c_data);
+ imx1_add_imx_i2c(&mx1ads_i2c_data);
}
static void __init mx1ads_timer_init(void)
@@ -145,8 +145,6 @@ struct sys_timer mx1ads_timer = {
MACHINE_START(MX1ADS, "Freescale MX1ADS")
/* Maintainer: Sascha Hauer, Pengutronix */
- .phys_io = MX1_IO_BASE_ADDR,
- .io_pg_offst = (MX1_IO_BASE_ADDR_VIRT >> 18) & 0xfffc,
.boot_params = MX1_PHYS_OFFSET + 0x100,
.map_io = mx1_map_io,
.init_irq = mx1_init_irq,
@@ -155,8 +153,6 @@ MACHINE_START(MX1ADS, "Freescale MX1ADS")
MACHINE_END
MACHINE_START(MXLADS, "Freescale MXLADS")
- .phys_io = MX1_IO_BASE_ADDR,
- .io_pg_offst = (MX1_IO_BASE_ADDR_VIRT >> 18) & 0xfffc,
.boot_params = MX1_PHYS_OFFSET + 0x100,
.map_io = mx1_map_io,
.init_irq = mx1_init_irq,
diff --git a/arch/arm/mach-imx/mach-mx21ads.c b/arch/arm/mach-imx/mach-mx21ads.c
index 96d7f8189f32..e1282e9f50ff 100644
--- a/arch/arm/mach-imx/mach-mx21ads.c
+++ b/arch/arm/mach-imx/mach-mx21ads.c
@@ -67,7 +67,7 @@
#define MX21ADS_IO_LED4_ON 0x4000
#define MX21ADS_IO_LED3_ON 0x8000
-static unsigned int mx21ads_pins[] = {
+static const int mx21ads_pins[] __initconst = {
/* CS8900A */
(GPIO_PORTE | GPIO_GPIO | GPIO_IN | 11),
@@ -314,8 +314,6 @@ static struct sys_timer mx21ads_timer = {
MACHINE_START(MX21ADS, "Freescale i.MX21ADS")
/* maintainer: Freescale Semiconductor, Inc. */
- .phys_io = MX21_AIPI_BASE_ADDR,
- .io_pg_offst = ((MX21_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
.boot_params = MX21_PHYS_OFFSET + 0x100,
.map_io = mx21ads_map_io,
.init_irq = mx21_init_irq,
diff --git a/arch/arm/mach-imx/mach-mx27_3ds.c b/arch/arm/mach-imx/mach-mx27_3ds.c
index e66ffaa1c26c..b8bbd31aa850 100644
--- a/arch/arm/mach-imx/mach-mx27_3ds.c
+++ b/arch/arm/mach-imx/mach-mx27_3ds.c
@@ -33,7 +33,7 @@
#include "devices-imx27.h"
#include "devices.h"
-static unsigned int mx27pdk_pins[] = {
+static const int mx27pdk_pins[] __initconst = {
/* UART1 */
PE12_PF_UART1_TXD,
PE13_PF_UART1_RXD,
@@ -64,10 +64,6 @@ static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
-static struct platform_device *platform_devices[] __initdata = {
- &mxc_fec_device,
-};
-
/*
* Matrix keyboard
*/
@@ -94,7 +90,7 @@ static void __init mx27pdk_init(void)
mxc_gpio_setup_multiple_pins(mx27pdk_pins, ARRAY_SIZE(mx27pdk_pins),
"mx27pdk");
imx27_add_imx_uart0(&uart_pdata);
- platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+ imx27_add_fec(NULL);
mxc_register_device(&imx_kpp_device, &mx27_3ds_keymap_data);
}
@@ -109,8 +105,6 @@ static struct sys_timer mx27pdk_timer = {
MACHINE_START(MX27_3DS, "Freescale MX27PDK")
/* maintainer: Freescale Semiconductor, Inc. */
- .phys_io = MX27_AIPI_BASE_ADDR,
- .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
.boot_params = MX27_PHYS_OFFSET + 0x100,
.map_io = mx27_map_io,
.init_irq = mx27_init_irq,
diff --git a/arch/arm/mach-imx/mach-mx27ads.c b/arch/arm/mach-imx/mach-mx27ads.c
index 9c77da98a10e..a1e4bc573afc 100644
--- a/arch/arm/mach-imx/mach-mx27ads.c
+++ b/arch/arm/mach-imx/mach-mx27ads.c
@@ -66,7 +66,7 @@
/* to determine the correct external crystal reference */
#define CKIH_27MHZ_BIT_SET (1 << 3)
-static unsigned int mx27ads_pins[] = {
+static const int mx27ads_pins[] __initconst = {
/* UART0 */
PE12_PF_UART1_TXD,
PE13_PF_UART1_RXD,
@@ -284,7 +284,6 @@ static struct imxmmc_platform_data sdhc2_pdata = {
static struct platform_device *platform_devices[] __initdata = {
&mx27ads_nor_mtd_device,
- &mxc_fec_device,
&mxc_w1_master_device,
};
@@ -308,11 +307,12 @@ static void __init mx27ads_board_init(void)
/* only the i2c master 1 is used on this CPU card */
i2c_register_board_info(1, mx27ads_i2c_devices,
ARRAY_SIZE(mx27ads_i2c_devices));
- imx27_add_i2c_imx1(&mx27ads_i2c1_data);
+ imx27_add_imx_i2c(1, &mx27ads_i2c1_data);
mxc_register_device(&mxc_fb_device, &mx27ads_fb_data);
mxc_register_device(&mxc_sdhc_device0, &sdhc1_pdata);
mxc_register_device(&mxc_sdhc_device1, &sdhc2_pdata);
+ imx27_add_fec(NULL);
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
}
@@ -347,8 +347,6 @@ static void __init mx27ads_map_io(void)
MACHINE_START(MX27ADS, "Freescale i.MX27ADS")
/* maintainer: Freescale Semiconductor, Inc. */
- .phys_io = MX27_AIPI_BASE_ADDR,
- .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
.boot_params = MX27_PHYS_OFFSET + 0x100,
.map_io = mx27ads_map_io,
.init_irq = mx27_init_irq,
diff --git a/arch/arm/mach-imx/mach-mxt_td60.c b/arch/arm/mach-imx/mach-mxt_td60.c
index a3a1e452d4c5..38d3a4ae17c7 100644
--- a/arch/arm/mach-imx/mach-mxt_td60.c
+++ b/arch/arm/mach-imx/mach-mxt_td60.c
@@ -37,7 +37,7 @@
#include "devices-imx27.h"
#include "devices.h"
-static unsigned int mxt_td60_pins[] __initdata = {
+static const int mxt_td60_pins[] __initconst = {
/* UART0 */
PE12_PF_UART1_TXD,
PE13_PF_UART1_RXD,
@@ -231,10 +231,6 @@ static struct imxmmc_platform_data sdhc1_pdata = {
.exit = mxt_td60_sdhc1_exit,
};
-static struct platform_device *platform_devices[] __initdata = {
- &mxc_fec_device,
-};
-
static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
@@ -255,12 +251,11 @@ static void __init mxt_td60_board_init(void)
i2c_register_board_info(1, mxt_td60_i2c2_devices,
ARRAY_SIZE(mxt_td60_i2c2_devices));
- imx27_add_i2c_imx0(&mxt_td60_i2c0_data);
- imx27_add_i2c_imx1(&mxt_td60_i2c1_data);
+ imx27_add_imx_i2c(0, &mxt_td60_i2c0_data);
+ imx27_add_imx_i2c(1, &mxt_td60_i2c1_data);
mxc_register_device(&mxc_fb_device, &mxt_td60_fb_data);
mxc_register_device(&mxc_sdhc_device0, &sdhc1_pdata);
-
- platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+ imx27_add_fec(NULL);
}
static void __init mxt_td60_timer_init(void)
@@ -274,8 +269,6 @@ static struct sys_timer mxt_td60_timer = {
MACHINE_START(MXT_TD60, "Maxtrack i-MXT TD60")
/* maintainer: Maxtrack Industrial */
- .phys_io = MX27_AIPI_BASE_ADDR,
- .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
.boot_params = MX27_PHYS_OFFSET + 0x100,
.map_io = mx27_map_io,
.init_irq = mx27_init_irq,
diff --git a/arch/arm/mach-imx/mach-pca100.c b/arch/arm/mach-imx/mach-pca100.c
index 23c9e1f37b9c..8c720d44602a 100644
--- a/arch/arm/mach-imx/mach-pca100.c
+++ b/arch/arm/mach-imx/mach-pca100.c
@@ -38,7 +38,6 @@
#include <mach/iomux-mx27.h>
#include <asm/mach/time.h>
#include <mach/audmux.h>
-#include <mach/ssi.h>
#include <mach/mxc_nand.h>
#include <mach/irqs.h>
#include <mach/mmc.h>
@@ -55,7 +54,7 @@
#define SPI1_SS1 (GPIO_PORTD + 27)
#define SD2_CD (GPIO_PORTC + 29)
-static int pca100_pins[] = {
+static const int pca100_pins[] __initconst = {
/* UART1 */
PE12_PF_UART1_TXD,
PE13_PF_UART1_RXD,
@@ -174,7 +173,6 @@ pca100_nand_board_info __initconst = {
static struct platform_device *platform_devices[] __initdata = {
&mxc_w1_master_device,
- &mxc_fec_device,
&mxc_wdt,
};
@@ -193,11 +191,9 @@ static struct i2c_board_info pca100_i2c_devices[] = {
I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
.platform_data = &board_eeprom,
}, {
- I2C_BOARD_INFO("rtc-pcf8563", 0x51),
- .type = "pcf8563"
+ I2C_BOARD_INFO("pcf8563", 0x51),
}, {
I2C_BOARD_INFO("lm75", 0x4a),
- .type = "lm75"
}
};
@@ -252,7 +248,7 @@ static void pca100_ac97_cold_reset(struct snd_ac97 *ac97)
msleep(2);
}
-static struct imx_ssi_platform_data pca100_ssi_pdata = {
+static const struct imx_ssi_platform_data pca100_ssi_pdata __initconst = {
.ac97_reset = pca100_ac97_cold_reset,
.ac97_warm_reset = pca100_ac97_warm_reset,
.flags = IMX_SSI_USE_AC97,
@@ -389,7 +385,7 @@ static void __init pca100_init(void)
if (ret)
printk(KERN_ERR "pca100: Failed to setup pins (%d)\n", ret);
- mxc_register_device(&imx_ssi_device0, &pca100_ssi_pdata);
+ imx27_add_imx_ssi(0, &pca100_ssi_pdata);
imx27_add_imx_uart0(&uart_pdata);
@@ -401,7 +397,7 @@ static void __init pca100_init(void)
i2c_register_board_info(1, pca100_i2c_devices,
ARRAY_SIZE(pca100_i2c_devices));
- imx27_add_i2c_imx1(&pca100_i2c1_data);
+ imx27_add_imx_i2c(1, &pca100_i2c1_data);
#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_IN);
@@ -436,6 +432,7 @@ static void __init pca100_init(void)
mxc_register_device(&mxc_fb_device, &pca100_fb_data);
+ imx27_add_fec(NULL);
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
}
@@ -449,8 +446,6 @@ static struct sys_timer pca100_timer = {
};
MACHINE_START(PCA100, "phyCARD-i.MX27")
- .phys_io = MX27_AIPI_BASE_ADDR,
- .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
.boot_params = MX27_PHYS_OFFSET + 0x100,
.map_io = mx27_map_io,
.init_irq = mx27_init_irq,
diff --git a/arch/arm/mach-imx/mach-pcm038.c b/arch/arm/mach-imx/mach-pcm038.c
index 9212e8f37001..49a97ce07426 100644
--- a/arch/arm/mach-imx/mach-pcm038.c
+++ b/arch/arm/mach-imx/mach-pcm038.c
@@ -43,7 +43,7 @@
#include "devices-imx27.h"
#include "devices.h"
-static int pcm038_pins[] = {
+static const int pcm038_pins[] __initconst = {
/* UART1 */
PE12_PF_UART1_TXD,
PE13_PF_UART1_RXD,
@@ -173,7 +173,6 @@ pcm038_nand_board_info __initconst = {
static struct platform_device *platform_devices[] __initdata = {
&pcm038_nor_mtd_device,
&mxc_w1_master_device,
- &mxc_fec_device,
&pcm038_sram_mtd_device,
&mxc_wdt,
};
@@ -257,7 +256,7 @@ static struct regulator_init_data cam_data = {
.consumer_supplies = cam_consumers,
};
-struct mc13783_regulator_init_data pcm038_regulators[] = {
+static struct mc13783_regulator_init_data pcm038_regulators[] = {
{
.id = MC13783_REGU_VCAM,
.init_data = &cam_data,
@@ -309,7 +308,7 @@ static void __init pcm038_init(void)
i2c_register_board_info(1, pcm038_i2c_devices,
ARRAY_SIZE(pcm038_i2c_devices));
- imx27_add_i2c_imx1(&pcm038_i2c1_data);
+ imx27_add_imx_i2c(1, &pcm038_i2c1_data);
/* PE18 for user-LED D40 */
mxc_gpio_mode(GPIO_PORTE | 18 | GPIO_GPIO | GPIO_OUT);
@@ -325,6 +324,7 @@ static void __init pcm038_init(void)
mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+ imx27_add_fec(NULL);
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
#ifdef CONFIG_MACH_PCM970_BASEBOARD
@@ -342,8 +342,6 @@ static struct sys_timer pcm038_timer = {
};
MACHINE_START(PCM038, "phyCORE-i.MX27")
- .phys_io = MX27_AIPI_BASE_ADDR,
- .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
.boot_params = MX27_PHYS_OFFSET + 0x100,
.map_io = mx27_map_io,
.init_irq = mx27_init_irq,
diff --git a/arch/arm/mach-imx/mach-scb9328.c b/arch/arm/mach-imx/mach-scb9328.c
index 88bf0d1e26e6..1fbdd3faa7ab 100644
--- a/arch/arm/mach-imx/mach-scb9328.c
+++ b/arch/arm/mach-imx/mach-scb9328.c
@@ -95,7 +95,7 @@ static struct platform_device dm9000x_device = {
}
};
-static int mxc_uart1_pins[] = {
+static const int mxc_uart1_pins[] = {
PC9_PF_UART1_CTS,
PC10_PF_UART1_RTS,
PC11_PF_UART1_TXD,
@@ -147,8 +147,6 @@ static struct sys_timer scb9328_timer = {
MACHINE_START(SCB9328, "Synertronixx scb9328")
/* Sascha Hauer */
- .phys_io = 0x00200000,
- .io_pg_offst = ((0xe0200000) >> 18) & 0xfffc,
.boot_params = 0x08000100,
.map_io = mx1_map_io,
.init_irq = mx1_init_irq,
diff --git a/arch/arm/mach-imx/pcm970-baseboard.c b/arch/arm/mach-imx/pcm970-baseboard.c
index f490a406d57e..9110d9cca7a2 100644
--- a/arch/arm/mach-imx/pcm970-baseboard.c
+++ b/arch/arm/mach-imx/pcm970-baseboard.c
@@ -31,7 +31,7 @@
#include "devices.h"
-static int pcm970_pins[] = {
+static const int pcm970_pins[] __initconst = {
/* SDHC */
PB4_PF_SD2_D0,
PB5_PF_SD2_D1,
@@ -200,7 +200,7 @@ static struct resource pcm970_sja1000_resources[] = {
},
};
-struct sja1000_platform_data pcm970_sja1000_platform_data = {
+static struct sja1000_platform_data pcm970_sja1000_platform_data = {
.osc_freq = 16000000,
.ocr = OCR_TX1_PULLDOWN | OCR_TX0_PUSHPULL,
.cdr = CDR_CBP,
diff --git a/arch/arm/mach-integrator/include/mach/debug-macro.S b/arch/arm/mach-integrator/include/mach/debug-macro.S
index 87a6888ae011..a1f598fd3a56 100644
--- a/arch/arm/mach-integrator/include/mach/debug-macro.S
+++ b/arch/arm/mach-integrator/include/mach/debug-macro.S
@@ -11,12 +11,10 @@
*
*/
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- moveq \rx, #0x16000000 @ physical base address
- movne \rx, #0xf0000000 @ virtual base
- addne \rx, \rx, #0x16000000 >> 4
+ .macro addruart, rp, rv
+ mov \rp, #0x16000000 @ physical base address
+ mov \rv, #0xf0000000 @ virtual base
+ add \rv, \rv, #0x16000000 >> 4
.endm
#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-integrator/include/mach/vmalloc.h b/arch/arm/mach-integrator/include/mach/vmalloc.h
index e87ab0b37bdd..e056e7cf5645 100644
--- a/arch/arm/mach-integrator/include/mach/vmalloc.h
+++ b/arch/arm/mach-integrator/include/mach/vmalloc.h
@@ -17,4 +17,4 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#define VMALLOC_END (PAGE_OFFSET + 0x10000000)
+#define VMALLOC_END 0xd0000000
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 6ab5a03ab9d8..548208f11179 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -500,8 +500,6 @@ static struct sys_timer ap_timer = {
MACHINE_START(INTEGRATOR, "ARM-Integrator")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
- .phys_io = 0x16000000,
- .io_pg_offst = ((0xf1600000) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.map_io = ap_map_io,
.reserve = integrator_reserve,
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 05db40e3c4f7..6258c90d020c 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -599,8 +599,6 @@ static struct sys_timer cp_timer = {
MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
- .phys_io = 0x16000000,
- .io_pg_offst = ((0xf1600000) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.map_io = intcp_map_io,
.reserve = integrator_reserve,
diff --git a/arch/arm/mach-iop13xx/include/mach/debug-macro.S b/arch/arm/mach-iop13xx/include/mach/debug-macro.S
index c9d6ba46963d..e664466d51bf 100644
--- a/arch/arm/mach-iop13xx/include/mach/debug-macro.S
+++ b/arch/arm/mach-iop13xx/include/mach/debug-macro.S
@@ -11,15 +11,13 @@
* published by the Free Software Foundation.
*/
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ mmu enabled?
- moveq \rx, #0xff000000 @ physical
- orreq \rx, \rx, #0x00d80000
- movne \rx, #0xfe000000 @ virtual
- orrne \rx, \rx, #0x00e80000
- orr \rx, \rx, #0x00002300
- orr \rx, \rx, #0x00000040
+ .macro addruart, rp, rv
+ mov \rp, #0x00002300
+ orr \rp, \rp, #0x00000040
+ orr \rv, \rp, #0xfe000000 @ virtual
+ orr \rv, \rv, #0x00e80000
+ orr \rp, \rp, #0xff000000 @ physical
+ orr \rp, \rp, #0x00d80000
.endm
#define UART_SHIFT 2
diff --git a/arch/arm/mach-iop13xx/iq81340mc.c b/arch/arm/mach-iop13xx/iq81340mc.c
index f91f3154577d..9b5a63f5d07d 100644
--- a/arch/arm/mach-iop13xx/iq81340mc.c
+++ b/arch/arm/mach-iop13xx/iq81340mc.c
@@ -91,8 +91,6 @@ static struct sys_timer iq81340mc_timer = {
MACHINE_START(IQ81340MC, "Intel IQ81340MC")
/* Maintainer: Dan Williams <dan.j.williams@intel.com> */
- .phys_io = IOP13XX_PMMR_PHYS_MEM_BASE,
- .io_pg_offst = (IOP13XX_PMMR_VIRT_MEM_BASE >> 18) & 0xfffc,
.boot_params = 0x00000100,
.map_io = iop13xx_map_io,
.init_irq = iop13xx_init_irq,
diff --git a/arch/arm/mach-iop13xx/iq81340sc.c b/arch/arm/mach-iop13xx/iq81340sc.c
index ddb7a3435de9..df3492a9c280 100644
--- a/arch/arm/mach-iop13xx/iq81340sc.c
+++ b/arch/arm/mach-iop13xx/iq81340sc.c
@@ -93,8 +93,6 @@ static struct sys_timer iq81340sc_timer = {
MACHINE_START(IQ81340SC, "Intel IQ81340SC")
/* Maintainer: Dan Williams <dan.j.williams@intel.com> */
- .phys_io = IOP13XX_PMMR_PHYS_MEM_BASE,
- .io_pg_offst = (IOP13XX_PMMR_VIRT_MEM_BASE >> 18) & 0xfffc,
.boot_params = 0x00000100,
.map_io = iop13xx_map_io,
.init_irq = iop13xx_init_irq,
diff --git a/arch/arm/mach-iop13xx/msi.c b/arch/arm/mach-iop13xx/msi.c
index f34b0ed80630..7149fcc16c8a 100644
--- a/arch/arm/mach-iop13xx/msi.c
+++ b/arch/arm/mach-iop13xx/msi.c
@@ -164,10 +164,10 @@ static void iop13xx_msi_nop(unsigned int irq)
static struct irq_chip iop13xx_msi_chip = {
.name = "PCI-MSI",
.ack = iop13xx_msi_nop,
- .enable = unmask_msi_irq,
- .disable = mask_msi_irq,
- .mask = mask_msi_irq,
- .unmask = unmask_msi_irq,
+ .irq_enable = unmask_msi_irq,
+ .irq_disable = mask_msi_irq,
+ .irq_mask = mask_msi_irq,
+ .irq_unmask = unmask_msi_irq,
};
int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
diff --git a/arch/arm/mach-iop32x/em7210.c b/arch/arm/mach-iop32x/em7210.c
index 2bef9b6e1cc9..779f924af302 100644
--- a/arch/arm/mach-iop32x/em7210.c
+++ b/arch/arm/mach-iop32x/em7210.c
@@ -203,8 +203,6 @@ static void __init em7210_init_machine(void)
}
MACHINE_START(EM7210, "Lanner EM7210")
- .phys_io = IQ31244_UART,
- .io_pg_offst = ((IQ31244_UART) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = em7210_map_io,
.init_irq = iop32x_init_irq,
diff --git a/arch/arm/mach-iop32x/glantank.c b/arch/arm/mach-iop32x/glantank.c
index 10384fc37cb2..c6b6f9c5650d 100644
--- a/arch/arm/mach-iop32x/glantank.c
+++ b/arch/arm/mach-iop32x/glantank.c
@@ -207,8 +207,6 @@ static void __init glantank_init_machine(void)
MACHINE_START(GLANTANK, "GLAN Tank")
/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
- .phys_io = GLANTANK_UART,
- .io_pg_offst = ((GLANTANK_UART) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = glantank_map_io,
.init_irq = iop32x_init_irq,
diff --git a/arch/arm/mach-iop32x/include/mach/debug-macro.S b/arch/arm/mach-iop32x/include/mach/debug-macro.S
index 736afe1edd1f..ff9e76c09f35 100644
--- a/arch/arm/mach-iop32x/include/mach/debug-macro.S
+++ b/arch/arm/mach-iop32x/include/mach/debug-macro.S
@@ -11,9 +11,10 @@
* published by the Free Software Foundation.
*/
- .macro addruart, rx, tmp
- mov \rx, #0xfe000000 @ physical as well as virtual
- orr \rx, \rx, #0x00800000 @ location of the UART
+ .macro addruart, rp, rv
+ mov \rp, #0xfe000000 @ physical as well as virtual
+ orr \rp, \rp, #0x00800000 @ location of the UART
+ mov \rv, \rp
.endm
#define UART_SHIFT 0
diff --git a/arch/arm/mach-iop32x/iq31244.c b/arch/arm/mach-iop32x/iq31244.c
index d6ac85ff109d..fde962c057f0 100644
--- a/arch/arm/mach-iop32x/iq31244.c
+++ b/arch/arm/mach-iop32x/iq31244.c
@@ -313,8 +313,6 @@ __setup("force_ep80219", force_ep80219_setup);
MACHINE_START(IQ31244, "Intel IQ31244")
/* Maintainer: Intel Corp. */
- .phys_io = IQ31244_UART,
- .io_pg_offst = ((IQ31244_UART) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = iq31244_map_io,
.init_irq = iop32x_init_irq,
@@ -329,8 +327,6 @@ MACHINE_END
*/
MACHINE_START(EP80219, "Intel EP80219")
/* Maintainer: Intel Corp. */
- .phys_io = IQ31244_UART,
- .io_pg_offst = ((IQ31244_UART) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = iq31244_map_io,
.init_irq = iop32x_init_irq,
diff --git a/arch/arm/mach-iop32x/iq80321.c b/arch/arm/mach-iop32x/iq80321.c
index c6a0e4ee9d91..3a95950e8737 100644
--- a/arch/arm/mach-iop32x/iq80321.c
+++ b/arch/arm/mach-iop32x/iq80321.c
@@ -186,8 +186,6 @@ static void __init iq80321_init_machine(void)
MACHINE_START(IQ80321, "Intel IQ80321")
/* Maintainer: Intel Corp. */
- .phys_io = IQ80321_UART,
- .io_pg_offst = ((IQ80321_UART) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = iq80321_map_io,
.init_irq = iop32x_init_irq,
diff --git a/arch/arm/mach-iop32x/n2100.c b/arch/arm/mach-iop32x/n2100.c
index f108a31afc2b..626aa375915d 100644
--- a/arch/arm/mach-iop32x/n2100.c
+++ b/arch/arm/mach-iop32x/n2100.c
@@ -327,8 +327,6 @@ static void __init n2100_init_machine(void)
MACHINE_START(N2100, "Thecus N2100")
/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
- .phys_io = N2100_UART,
- .io_pg_offst = ((N2100_UART) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = n2100_map_io,
.init_irq = iop32x_init_irq,
diff --git a/arch/arm/mach-iop33x/include/mach/debug-macro.S b/arch/arm/mach-iop33x/include/mach/debug-macro.S
index addb2da78422..40c500dd1fac 100644
--- a/arch/arm/mach-iop33x/include/mach/debug-macro.S
+++ b/arch/arm/mach-iop33x/include/mach/debug-macro.S
@@ -11,13 +11,11 @@
* published by the Free Software Foundation.
*/
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ mmu enabled?
- moveq \rx, #0xff000000 @ physical
- movne \rx, #0xfe000000 @ virtual
- orr \rx, \rx, #0x00ff0000
- orr \rx, \rx, #0x0000f700
+ .macro addruart, rp, rv
+ mov \rp, #0x00ff0000
+ orr \rp, \rp, #0x0000f700
+ orr \rv, #0xfe000000 @ virtual
+ orr \rp, #0xff000000 @ physical
.endm
#define UART_SHIFT 2
diff --git a/arch/arm/mach-iop33x/iq80331.c b/arch/arm/mach-iop33x/iq80331.c
index c6ff5523b380..c565f8d1e3a4 100644
--- a/arch/arm/mach-iop33x/iq80331.c
+++ b/arch/arm/mach-iop33x/iq80331.c
@@ -141,8 +141,6 @@ static void __init iq80331_init_machine(void)
MACHINE_START(IQ80331, "Intel IQ80331")
/* Maintainer: Intel Corp. */
- .phys_io = 0xfefff000,
- .io_pg_offst = ((0xfffff000) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.map_io = iop3xx_map_io,
.init_irq = iop33x_init_irq,
diff --git a/arch/arm/mach-iop33x/iq80332.c b/arch/arm/mach-iop33x/iq80332.c
index fbf551409394..36a9efb254c2 100644
--- a/arch/arm/mach-iop33x/iq80332.c
+++ b/arch/arm/mach-iop33x/iq80332.c
@@ -141,8 +141,6 @@ static void __init iq80332_init_machine(void)
MACHINE_START(IQ80332, "Intel IQ80332")
/* Maintainer: Intel Corp. */
- .phys_io = 0xfefff000,
- .io_pg_offst = ((0xfffff000) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.map_io = iop3xx_map_io,
.init_irq = iop33x_init_irq,
diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c
index 1a557e0d055b..88663ab1d2ad 100644
--- a/arch/arm/mach-ixp2000/enp2611.c
+++ b/arch/arm/mach-ixp2000/enp2611.c
@@ -253,8 +253,6 @@ static void __init enp2611_init_machine(void)
MACHINE_START(ENP2611, "Radisys ENP-2611 PCI network processor board")
/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
- .phys_io = IXP2000_UART_PHYS_BASE,
- .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.map_io = enp2611_map_io,
.init_irq = ixp2000_init_irq,
diff --git a/arch/arm/mach-ixp2000/include/mach/debug-macro.S b/arch/arm/mach-ixp2000/include/mach/debug-macro.S
index 6a827681680f..0ef533b20972 100644
--- a/arch/arm/mach-ixp2000/include/mach/debug-macro.S
+++ b/arch/arm/mach-ixp2000/include/mach/debug-macro.S
@@ -11,16 +11,14 @@
*
*/
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- moveq \rx, #0xc0000000 @ Physical base
- movne \rx, #0xfe000000 @ virtual base
- orrne \rx, \rx, #0x00f00000
- orr \rx, \rx, #0x00030000
+ .macro addruart, rp, rv
+ mov \rp, #0x00030000
#ifdef __ARMEB__
- orr \rx, \rx, #0x00000003
+ orr \rp, \rp, #0x00000003
#endif
+ orr \rv, \rp, #0xfe000000 @ virtual base
+ orr \rv, \rv, #0x00f00000
+ orr \rp, \rp, #0xc0000000 @ Physical base
.endm
#define UART_SHIFT 2
diff --git a/arch/arm/mach-ixp2000/ixdp2400.c b/arch/arm/mach-ixp2000/ixdp2400.c
index 55e5c69352ad..dfffc1e817fa 100644
--- a/arch/arm/mach-ixp2000/ixdp2400.c
+++ b/arch/arm/mach-ixp2000/ixdp2400.c
@@ -170,8 +170,6 @@ void __init ixdp2400_init_irq(void)
MACHINE_START(IXDP2400, "Intel IXDP2400 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
- .phys_io = IXP2000_UART_PHYS_BASE,
- .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.map_io = ixdp2x00_map_io,
.init_irq = ixdp2400_init_irq,
diff --git a/arch/arm/mach-ixp2000/ixdp2800.c b/arch/arm/mach-ixp2000/ixdp2800.c
index 237b61a85e9a..cd4c9bcff2b5 100644
--- a/arch/arm/mach-ixp2000/ixdp2800.c
+++ b/arch/arm/mach-ixp2000/ixdp2800.c
@@ -285,8 +285,6 @@ void __init ixdp2800_init_irq(void)
MACHINE_START(IXDP2800, "Intel IXDP2800 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
- .phys_io = IXP2000_UART_PHYS_BASE,
- .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.map_io = ixdp2x00_map_io,
.init_irq = ixdp2800_init_irq,
diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c
index 0369ec4242a6..6c121bdbe311 100644
--- a/arch/arm/mach-ixp2000/ixdp2x01.c
+++ b/arch/arm/mach-ixp2000/ixdp2x01.c
@@ -416,8 +416,6 @@ static void __init ixdp2x01_init_machine(void)
#ifdef CONFIG_ARCH_IXDP2401
MACHINE_START(IXDP2401, "Intel IXDP2401 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
- .phys_io = IXP2000_UART_PHYS_BASE,
- .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.map_io = ixdp2x01_map_io,
.init_irq = ixdp2x01_init_irq,
@@ -429,8 +427,6 @@ MACHINE_END
#ifdef CONFIG_ARCH_IXDP2801
MACHINE_START(IXDP2801, "Intel IXDP2801 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
- .phys_io = IXP2000_UART_PHYS_BASE,
- .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.map_io = ixdp2x01_map_io,
.init_irq = ixdp2x01_init_irq,
@@ -444,8 +440,6 @@ MACHINE_END
*/
MACHINE_START(IXDP28X5, "Intel IXDP2805/2855 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
- .phys_io = IXP2000_UART_PHYS_BASE,
- .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.map_io = ixdp2x01_map_io,
.init_irq = ixdp2x01_init_irq,
diff --git a/arch/arm/mach-ixp23xx/espresso.c b/arch/arm/mach-ixp23xx/espresso.c
index 1c06bfc5a7ef..e25e5fe183ba 100644
--- a/arch/arm/mach-ixp23xx/espresso.c
+++ b/arch/arm/mach-ixp23xx/espresso.c
@@ -85,8 +85,6 @@ static void __init espresso_init(void)
MACHINE_START(ESPRESSO, "IP Fabrics Double Espresso")
/* Maintainer: Lennert Buytenhek */
- .phys_io = IXP23XX_PERIPHERAL_PHYS,
- .io_pg_offst = ((IXP23XX_PERIPHERAL_VIRT >> 18)) & 0xfffc,
.map_io = ixp23xx_map_io,
.init_irq = ixp23xx_init_irq,
.timer = &ixp23xx_timer,
diff --git a/arch/arm/mach-ixp23xx/include/mach/debug-macro.S b/arch/arm/mach-ixp23xx/include/mach/debug-macro.S
index a82e375465e2..f7c6eef7fa22 100644
--- a/arch/arm/mach-ixp23xx/include/mach/debug-macro.S
+++ b/arch/arm/mach-ixp23xx/include/mach/debug-macro.S
@@ -12,13 +12,12 @@
*/
#include <mach/ixp23xx.h>
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ mmu enabled?
- ldreq \rx, =IXP23XX_PERIPHERAL_PHYS @ physical
- ldrne \rx, =IXP23XX_PERIPHERAL_VIRT @ virtual
+ .macro addruart, rp, rv
+ ldr \rp, =IXP23XX_PERIPHERAL_PHYS @ physical
+ ldr \rv, =IXP23XX_PERIPHERAL_VIRT @ virtual
#ifdef __ARMEB__
- orr \rx, \rx, #0x00000003
+ orr \rp, \rp, #0x00000003
+ orr \rv, \rv, #0x00000003
#endif
.endm
diff --git a/arch/arm/mach-ixp23xx/ixdp2351.c b/arch/arm/mach-ixp23xx/ixdp2351.c
index f1b124a709ab..664e39c2a903 100644
--- a/arch/arm/mach-ixp23xx/ixdp2351.c
+++ b/arch/arm/mach-ixp23xx/ixdp2351.c
@@ -328,8 +328,6 @@ static void __init ixdp2351_init(void)
MACHINE_START(IXDP2351, "Intel IXDP2351 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
- .phys_io = IXP23XX_PERIPHERAL_PHYS,
- .io_pg_offst = ((IXP23XX_PERIPHERAL_VIRT >> 18)) & 0xfffc,
.map_io = ixdp2351_map_io,
.init_irq = ixdp2351_init_irq,
.timer = &ixp23xx_timer,
diff --git a/arch/arm/mach-ixp23xx/roadrunner.c b/arch/arm/mach-ixp23xx/roadrunner.c
index 6d38d769761c..76c61ba73218 100644
--- a/arch/arm/mach-ixp23xx/roadrunner.c
+++ b/arch/arm/mach-ixp23xx/roadrunner.c
@@ -171,8 +171,6 @@ static void __init roadrunner_init(void)
MACHINE_START(ROADRUNNER, "ADI Engineering RoadRunner Development Platform")
/* Maintainer: Deepak Saxena */
- .phys_io = IXP23XX_PERIPHERAL_PHYS,
- .io_pg_offst = ((IXP23XX_PERIPHERAL_VIRT >> 18)) & 0xfffc,
.map_io = ixp23xx_map_io,
.init_irq = ixp23xx_init_irq,
.timer = &ixp23xx_timer,
diff --git a/arch/arm/mach-ixp4xx/avila-setup.c b/arch/arm/mach-ixp4xx/avila-setup.c
index d8bc86d76f1d..73745ff102d5 100644
--- a/arch/arm/mach-ixp4xx/avila-setup.c
+++ b/arch/arm/mach-ixp4xx/avila-setup.c
@@ -164,8 +164,6 @@ static void __init avila_init(void)
MACHINE_START(AVILA, "Gateworks Avila Network Platform")
/* Maintainer: Deepak Saxena <dsaxena@plexity.net> */
- .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
- .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
.timer = &ixp4xx_timer,
@@ -181,8 +179,6 @@ MACHINE_END
#ifdef CONFIG_MACH_LOFT
MACHINE_START(LOFT, "Giant Shoulder Inc Loft board")
/* Maintainer: Tom Billman <kernel@giantshoulderinc.com> */
- .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
- .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
.timer = &ixp4xx_timer,
diff --git a/arch/arm/mach-ixp4xx/coyote-setup.c b/arch/arm/mach-ixp4xx/coyote-setup.c
index 31a47f6a8939..355e3de38733 100644
--- a/arch/arm/mach-ixp4xx/coyote-setup.c
+++ b/arch/arm/mach-ixp4xx/coyote-setup.c
@@ -109,8 +109,6 @@ static void __init coyote_init(void)
#ifdef CONFIG_ARCH_ADI_COYOTE
MACHINE_START(ADI_COYOTE, "ADI Engineering Coyote")
/* Maintainer: MontaVista Software, Inc. */
- .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
- .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
.timer = &ixp4xx_timer,
@@ -126,8 +124,6 @@ MACHINE_END
#ifdef CONFIG_MACH_IXDPG425
MACHINE_START(IXDPG425, "Intel IXDPG425")
/* Maintainer: MontaVista Software, Inc. */
- .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
- .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
.timer = &ixp4xx_timer,
diff --git a/arch/arm/mach-ixp4xx/dsmg600-setup.c b/arch/arm/mach-ixp4xx/dsmg600-setup.c
index 7c1fa54a6145..d398229cfaa5 100644
--- a/arch/arm/mach-ixp4xx/dsmg600-setup.c
+++ b/arch/arm/mach-ixp4xx/dsmg600-setup.c
@@ -279,8 +279,6 @@ static void __init dsmg600_init(void)
MACHINE_START(DSMG600, "D-Link DSM-G600 RevA")
/* Maintainer: www.nslu2-linux.org */
- .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
- .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
diff --git a/arch/arm/mach-ixp4xx/fsg-setup.c b/arch/arm/mach-ixp4xx/fsg-setup.c
index e7f4befba422..727ee39ce11c 100644
--- a/arch/arm/mach-ixp4xx/fsg-setup.c
+++ b/arch/arm/mach-ixp4xx/fsg-setup.c
@@ -270,8 +270,6 @@ static void __init fsg_init(void)
MACHINE_START(FSG, "Freecom FSG-3")
/* Maintainer: www.nslu2-linux.org */
- .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
- .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
.timer = &ixp4xx_timer,
diff --git a/arch/arm/mach-ixp4xx/gateway7001-setup.c b/arch/arm/mach-ixp4xx/gateway7001-setup.c
index 2583b2a13174..9dc0b4eaa65a 100644
--- a/arch/arm/mach-ixp4xx/gateway7001-setup.c
+++ b/arch/arm/mach-ixp4xx/gateway7001-setup.c
@@ -96,8 +96,6 @@ static void __init gateway7001_init(void)
#ifdef CONFIG_MACH_GATEWAY7001
MACHINE_START(GATEWAY7001, "Gateway 7001 AP")
/* Maintainer: Imre Kaloz <kaloz@openwrt.org> */
- .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
- .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
.timer = &ixp4xx_timer,
diff --git a/arch/arm/mach-ixp4xx/goramo_mlr.c b/arch/arm/mach-ixp4xx/goramo_mlr.c
index 1c28048209c1..d0e4861ac03d 100644
--- a/arch/arm/mach-ixp4xx/goramo_mlr.c
+++ b/arch/arm/mach-ixp4xx/goramo_mlr.c
@@ -496,8 +496,6 @@ subsys_initcall(gmlr_pci_init);
MACHINE_START(GORAMO_MLR, "MultiLink")
/* Maintainer: Krzysztof Halasa */
- .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
- .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
.timer = &ixp4xx_timer,
diff --git a/arch/arm/mach-ixp4xx/gtwx5715-setup.c b/arch/arm/mach-ixp4xx/gtwx5715-setup.c
index c67586b79400..77abead36227 100644
--- a/arch/arm/mach-ixp4xx/gtwx5715-setup.c
+++ b/arch/arm/mach-ixp4xx/gtwx5715-setup.c
@@ -164,8 +164,6 @@ static void __init gtwx5715_init(void)
MACHINE_START(GTWX5715, "Gemtek GTWX5715 (Linksys WRV54G)")
/* Maintainer: George Joseph */
- .phys_io = IXP4XX_UART2_BASE_PHYS,
- .io_pg_offst = ((IXP4XX_UART2_BASE_VIRT) >> 18) & 0xfffc,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
.timer = &ixp4xx_timer,
diff --git a/arch/arm/mach-ixp4xx/include/mach/debug-macro.S b/arch/arm/mach-ixp4xx/include/mach/debug-macro.S
index 3fc66d6d00a0..b974a49c0aff 100644
--- a/arch/arm/mach-ixp4xx/include/mach/debug-macro.S
+++ b/arch/arm/mach-ixp4xx/include/mach/debug-macro.S
@@ -10,16 +10,16 @@
* published by the Free Software Foundation.
*/
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- moveq \rx, #0xc8000000
- movne \rx, #0xff000000
- orrne \rx, \rx, #0x00b00000
+ .macro addruart, rp, rv
#ifdef __ARMEB__
- add \rx,\rx,#3 @ Uart regs are at off set of 3 if
- @ byte writes used - Big Endian.
+ mov \rp, #3 @ Uart regs are at off set of 3 if
+ @ byte writes used - Big Endian.
+#else
+ mov \rp, #0
#endif
+ orr \rv, \rp, #0xff000000 @ virtual
+ orr \rv, \rv, #0x00b00000
+ orr \rp, \rp, #0xc8000000 @ physical
.endm
#define UART_SHIFT 2
diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c
index ea9ee4ed0a3e..140783386785 100644
--- a/arch/arm/mach-ixp4xx/ixdp425-setup.c
+++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c
@@ -257,8 +257,6 @@ static void __init ixdp425_init(void)
#ifdef CONFIG_ARCH_IXDP425
MACHINE_START(IXDP425, "Intel IXDP425 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
- .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
- .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
.timer = &ixp4xx_timer,
@@ -270,8 +268,6 @@ MACHINE_END
#ifdef CONFIG_MACH_IXDP465
MACHINE_START(IXDP465, "Intel IXDP465 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
- .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
- .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
.timer = &ixp4xx_timer,
@@ -283,8 +279,6 @@ MACHINE_END
#ifdef CONFIG_ARCH_PRPMC1100
MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
- .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
- .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
.timer = &ixp4xx_timer,
@@ -296,8 +290,6 @@ MACHINE_END
#ifdef CONFIG_MACH_KIXRP435
MACHINE_START(KIXRP435, "Intel KIXRP435 Reference Platform")
/* Maintainer: MontaVista Software, Inc. */
- .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
- .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
.timer = &ixp4xx_timer,
diff --git a/arch/arm/mach-ixp4xx/nas100d-setup.c b/arch/arm/mach-ixp4xx/nas100d-setup.c
index e3ee880aa1e6..f18fee748878 100644
--- a/arch/arm/mach-ixp4xx/nas100d-setup.c
+++ b/arch/arm/mach-ixp4xx/nas100d-setup.c
@@ -314,8 +314,6 @@ static void __init nas100d_init(void)
MACHINE_START(NAS100D, "Iomega NAS 100d")
/* Maintainer: www.nslu2-linux.org */
- .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
- .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
diff --git a/arch/arm/mach-ixp4xx/nslu2-setup.c b/arch/arm/mach-ixp4xx/nslu2-setup.c
index c14e0034be4b..f79b62eb7614 100644
--- a/arch/arm/mach-ixp4xx/nslu2-setup.c
+++ b/arch/arm/mach-ixp4xx/nslu2-setup.c
@@ -300,8 +300,6 @@ static void __init nslu2_init(void)
MACHINE_START(NSLU2, "Linksys NSLU2")
/* Maintainer: www.nslu2-linux.org */
- .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
- .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
diff --git a/arch/arm/mach-ixp4xx/vulcan-setup.c b/arch/arm/mach-ixp4xx/vulcan-setup.c
index 465cc5cce687..4e72cfdd3c46 100644
--- a/arch/arm/mach-ixp4xx/vulcan-setup.c
+++ b/arch/arm/mach-ixp4xx/vulcan-setup.c
@@ -236,8 +236,6 @@ static void __init vulcan_init(void)
MACHINE_START(ARCOM_VULCAN, "Arcom/Eurotech Vulcan")
/* Maintainer: Marc Zyngier <maz@misterjones.org> */
- .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
- .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
.timer = &ixp4xx_timer,
diff --git a/arch/arm/mach-ixp4xx/wg302v2-setup.c b/arch/arm/mach-ixp4xx/wg302v2-setup.c
index 4dd74863daa9..5d148c7bc4fb 100644
--- a/arch/arm/mach-ixp4xx/wg302v2-setup.c
+++ b/arch/arm/mach-ixp4xx/wg302v2-setup.c
@@ -97,8 +97,6 @@ static void __init wg302v2_init(void)
#ifdef CONFIG_MACH_WG302V2
MACHINE_START(WG302V2, "Netgear WG302 v2 / WAG302 v2")
/* Maintainer: Imre Kaloz <kaloz@openwrt.org> */
- .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
- .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
.timer = &ixp4xx_timer,
diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig
index cc25501b57fa..34106335c728 100644
--- a/arch/arm/mach-kirkwood/Kconfig
+++ b/arch/arm/mach-kirkwood/Kconfig
@@ -58,6 +58,12 @@ config MACH_TS41X
QNAP TS-410, TS-410U, TS-419P and TS-419U Turbo NAS
devices.
+config MACH_DOCKSTAR
+ bool "Seagate FreeAgent DockStar"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Seagate FreeAgent DockStar.
+
config MACH_OPENRD
bool
@@ -100,6 +106,12 @@ config MACH_NETSPACE_MAX_V2
Say 'Y' here if you want your kernel to support the
LaCie Network Space Max v2 NAS.
+config MACH_D2NET_V2
+ bool "LaCie d2 Network v2 NAS Board"
+ help
+ Say 'Y' here if you want your kernel to support the
+ LaCie d2 Network v2 NAS.
+
config MACH_NET2BIG_V2
bool "LaCie 2Big Network v2 NAS Board"
help
diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile
index 295d7baa6ae1..5dcaa81a2ec3 100644
--- a/arch/arm/mach-kirkwood/Makefile
+++ b/arch/arm/mach-kirkwood/Makefile
@@ -7,14 +7,16 @@ obj-$(CONFIG_MACH_MV88F6281GTW_GE) += mv88f6281gtw_ge-setup.o
obj-$(CONFIG_MACH_SHEEVAPLUG) += sheevaplug-setup.o
obj-$(CONFIG_MACH_ESATA_SHEEVAPLUG) += sheevaplug-setup.o
obj-$(CONFIG_MACH_GURUPLUG) += guruplug-setup.o
+obj-$(CONFIG_MACH_DOCKSTAR) += dockstar-setup.o
obj-$(CONFIG_MACH_TS219) += ts219-setup.o tsx1x-common.o
obj-$(CONFIG_MACH_TS41X) += ts41x-setup.o tsx1x-common.o
obj-$(CONFIG_MACH_OPENRD) += openrd-setup.o
-obj-$(CONFIG_MACH_NETSPACE_V2) += netspace_v2-setup.o
-obj-$(CONFIG_MACH_INETSPACE_V2) += netspace_v2-setup.o
-obj-$(CONFIG_MACH_NETSPACE_MAX_V2) += netspace_v2-setup.o
-obj-$(CONFIG_MACH_NET2BIG_V2) += netxbig_v2-setup.o
-obj-$(CONFIG_MACH_NET5BIG_V2) += netxbig_v2-setup.o
+obj-$(CONFIG_MACH_NETSPACE_V2) += netspace_v2-setup.o lacie_v2-common.o
+obj-$(CONFIG_MACH_INETSPACE_V2) += netspace_v2-setup.o lacie_v2-common.o
+obj-$(CONFIG_MACH_NETSPACE_MAX_V2) += netspace_v2-setup.o lacie_v2-common.o
+obj-$(CONFIG_MACH_D2NET_V2) += d2net_v2-setup.o lacie_v2-common.o
+obj-$(CONFIG_MACH_NET2BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o
+obj-$(CONFIG_MACH_NET5BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o
obj-$(CONFIG_MACH_T5325) += t5325-setup.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
diff --git a/arch/arm/mach-kirkwood/d2net_v2-setup.c b/arch/arm/mach-kirkwood/d2net_v2-setup.c
new file mode 100644
index 000000000000..4aa86e4a152c
--- /dev/null
+++ b/arch/arm/mach-kirkwood/d2net_v2-setup.c
@@ -0,0 +1,229 @@
+/*
+ * arch/arm/mach-kirkwood/d2net_v2-setup.c
+ *
+ * LaCie d2 Network Space v2 Board Setup
+ *
+ * Copyright (C) 2010 Simon Guinot <sguinot@lacie.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/leds.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/kirkwood.h>
+#include <mach/leds-ns2.h>
+#include "common.h"
+#include "mpp.h"
+#include "lacie_v2-common.h"
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data d2net_v2_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+
+static struct mv_sata_platform_data d2net_v2_sata_data = {
+ .n_ports = 2,
+};
+
+/*****************************************************************************
+ * GPIO keys
+ ****************************************************************************/
+
+#define D2NET_V2_GPIO_PUSH_BUTTON 34
+#define D2NET_V2_GPIO_POWER_SWITCH_ON 13
+#define D2NET_V2_GPIO_POWER_SWITCH_OFF 15
+
+#define D2NET_V2_SWITCH_POWER_ON 0x1
+#define D2NET_V2_SWITCH_POWER_OFF 0x2
+
+static struct gpio_keys_button d2net_v2_buttons[] = {
+ [0] = {
+ .type = EV_SW,
+ .code = D2NET_V2_SWITCH_POWER_ON,
+ .gpio = D2NET_V2_GPIO_POWER_SWITCH_ON,
+ .desc = "Back power switch (on|auto)",
+ .active_low = 0,
+ },
+ [1] = {
+ .type = EV_SW,
+ .code = D2NET_V2_SWITCH_POWER_OFF,
+ .gpio = D2NET_V2_GPIO_POWER_SWITCH_OFF,
+ .desc = "Back power switch (auto|off)",
+ .active_low = 0,
+ },
+ [2] = {
+ .code = KEY_POWER,
+ .gpio = D2NET_V2_GPIO_PUSH_BUTTON,
+ .desc = "Front Push Button",
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data d2net_v2_button_data = {
+ .buttons = d2net_v2_buttons,
+ .nbuttons = ARRAY_SIZE(d2net_v2_buttons),
+};
+
+static struct platform_device d2net_v2_gpio_buttons = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &d2net_v2_button_data,
+ },
+};
+
+/*****************************************************************************
+ * GPIO LEDs
+ ****************************************************************************/
+
+#define D2NET_V2_GPIO_RED_LED 12
+
+static struct gpio_led d2net_v2_gpio_led_pins[] = {
+ {
+ .name = "d2net_v2:red:fail",
+ .gpio = D2NET_V2_GPIO_RED_LED,
+ },
+};
+
+static struct gpio_led_platform_data d2net_v2_gpio_leds_data = {
+ .num_leds = ARRAY_SIZE(d2net_v2_gpio_led_pins),
+ .leds = d2net_v2_gpio_led_pins,
+};
+
+static struct platform_device d2net_v2_gpio_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &d2net_v2_gpio_leds_data,
+ },
+};
+
+/*****************************************************************************
+ * Dual-GPIO CPLD LEDs
+ ****************************************************************************/
+
+#define D2NET_V2_GPIO_BLUE_LED_SLOW 29
+#define D2NET_V2_GPIO_BLUE_LED_CMD 30
+
+static struct ns2_led d2net_v2_led_pins[] = {
+ {
+ .name = "d2net_v2:blue:sata",
+ .cmd = D2NET_V2_GPIO_BLUE_LED_CMD,
+ .slow = D2NET_V2_GPIO_BLUE_LED_SLOW,
+ },
+};
+
+static struct ns2_led_platform_data d2net_v2_leds_data = {
+ .num_leds = ARRAY_SIZE(d2net_v2_led_pins),
+ .leds = d2net_v2_led_pins,
+};
+
+static struct platform_device d2net_v2_leds = {
+ .name = "leds-ns2",
+ .id = -1,
+ .dev = {
+ .platform_data = &d2net_v2_leds_data,
+ },
+};
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+
+static unsigned int d2net_v2_mpp_config[] __initdata = {
+ MPP0_SPI_SCn,
+ MPP1_SPI_MOSI,
+ MPP2_SPI_SCK,
+ MPP3_SPI_MISO,
+ MPP6_SYSRST_OUTn,
+ MPP7_GPO, /* Request power-off */
+ MPP8_TW0_SDA,
+ MPP9_TW0_SCK,
+ MPP10_UART0_TXD,
+ MPP11_UART0_RXD,
+ MPP12_GPO, /* Red led */
+ MPP13_GPIO, /* Rear power switch (on|auto) */
+ MPP14_GPIO, /* USB fuse */
+ MPP15_GPIO, /* Rear power switch (auto|off) */
+ MPP16_GPIO, /* SATA 0 power */
+ MPP21_SATA0_ACTn,
+ MPP24_GPIO, /* USB mode select */
+ MPP26_GPIO, /* USB device vbus */
+ MPP28_GPIO, /* USB enable host vbus */
+ MPP29_GPIO, /* Blue led (slow register) */
+ MPP30_GPIO, /* Blue led (command register) */
+ MPP34_GPIO, /* Power button (1 = Released, 0 = Pushed) */
+ MPP35_GPIO, /* Inhibit power-off */
+ 0
+};
+
+#define D2NET_V2_GPIO_POWER_OFF 7
+
+static void d2net_v2_power_off(void)
+{
+ gpio_set_value(D2NET_V2_GPIO_POWER_OFF, 1);
+}
+
+static void __init d2net_v2_init(void)
+{
+ /*
+ * Basic setup. Needs to be called early.
+ */
+ kirkwood_init();
+ kirkwood_mpp_conf(d2net_v2_mpp_config);
+
+ lacie_v2_hdd_power_init(1);
+
+ kirkwood_ehci_init();
+ kirkwood_ge00_init(&d2net_v2_ge00_data);
+ kirkwood_sata_init(&d2net_v2_sata_data);
+ kirkwood_uart0_init();
+ lacie_v2_register_flash();
+ lacie_v2_register_i2c_devices();
+
+ platform_device_register(&d2net_v2_leds);
+ platform_device_register(&d2net_v2_gpio_leds);
+ platform_device_register(&d2net_v2_gpio_buttons);
+
+ if (gpio_request(D2NET_V2_GPIO_POWER_OFF, "power-off") == 0 &&
+ gpio_direction_output(D2NET_V2_GPIO_POWER_OFF, 0) == 0)
+ pm_power_off = d2net_v2_power_off;
+ else
+ pr_err("d2net_v2: failed to configure power-off GPIO\n");
+}
+
+MACHINE_START(D2NET_V2, "LaCie d2 Network v2")
+ .boot_params = 0x00000100,
+ .init_machine = d2net_v2_init,
+ .map_io = kirkwood_map_io,
+ .init_irq = kirkwood_init_irq,
+ .timer = &lacie_v2_timer,
+MACHINE_END
diff --git a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
index 16f6691e7c68..9ea71182d31a 100644
--- a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
+++ b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
@@ -97,8 +97,6 @@ subsys_initcall(db88f6281_pci_init);
MACHINE_START(DB88F6281_BP, "Marvell DB-88F6281-BP Development Board")
/* Maintainer: Saeed Bishara <saeed@marvell.com> */
- .phys_io = KIRKWOOD_REGS_PHYS_BASE,
- .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.init_machine = db88f6281_init,
.map_io = kirkwood_map_io,
diff --git a/arch/arm/mach-kirkwood/dockstar-setup.c b/arch/arm/mach-kirkwood/dockstar-setup.c
new file mode 100644
index 000000000000..433ea368c060
--- /dev/null
+++ b/arch/arm/mach-kirkwood/dockstar-setup.c
@@ -0,0 +1,110 @@
+/*
+ * arch/arm/mach-kirkwood/dockstar-setup.c
+ *
+ * Seagate FreeAgent DockStar Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/kirkwood.h>
+#include <plat/mvsdio.h>
+#include "common.h"
+#include "mpp.h"
+
+static struct mtd_partition dockstar_nand_parts[] = {
+ {
+ .name = "u-boot",
+ .offset = 0,
+ .size = SZ_1M
+ }, {
+ .name = "uImage",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = SZ_4M
+ }, {
+ .name = "root",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL
+ },
+};
+
+static struct mv643xx_eth_platform_data dockstar_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(0),
+};
+
+static struct gpio_led dockstar_led_pins[] = {
+ {
+ .name = "dockstar:green:health",
+ .default_trigger = "default-on",
+ .gpio = 46,
+ .active_low = 1,
+ },
+ {
+ .name = "dockstar:orange:misc",
+ .default_trigger = "none",
+ .gpio = 47,
+ .active_low = 1,
+ },
+};
+
+static struct gpio_led_platform_data dockstar_led_data = {
+ .leds = dockstar_led_pins,
+ .num_leds = ARRAY_SIZE(dockstar_led_pins),
+};
+
+static struct platform_device dockstar_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &dockstar_led_data,
+ }
+};
+
+static unsigned int dockstar_mpp_config[] __initdata = {
+ MPP29_GPIO, /* USB Power Enable */
+ MPP46_GPIO, /* LED green */
+ MPP47_GPIO, /* LED orange */
+ 0
+};
+
+static void __init dockstar_init(void)
+{
+ /*
+ * Basic setup. Needs to be called early.
+ */
+ kirkwood_init();
+
+ /* setup gpio pin select */
+ kirkwood_mpp_conf(dockstar_mpp_config);
+
+ kirkwood_uart0_init();
+ kirkwood_nand_init(ARRAY_AND_SIZE(dockstar_nand_parts), 25);
+
+ if (gpio_request(29, "USB Power Enable") != 0 ||
+ gpio_direction_output(29, 1) != 0)
+ printk(KERN_ERR "can't set up GPIO 29 (USB Power Enable)\n");
+ kirkwood_ehci_init();
+
+ kirkwood_ge00_init(&dockstar_ge00_data);
+
+ platform_device_register(&dockstar_leds);
+}
+
+MACHINE_START(DOCKSTAR, "Seagate FreeAgent DockStar")
+ .boot_params = 0x00000100,
+ .init_machine = dockstar_init,
+ .map_io = kirkwood_map_io,
+ .init_irq = kirkwood_init_irq,
+ .timer = &kirkwood_timer,
+MACHINE_END
diff --git a/arch/arm/mach-kirkwood/guruplug-setup.c b/arch/arm/mach-kirkwood/guruplug-setup.c
index 54d07c89d4ff..8f47dc0a2fef 100644
--- a/arch/arm/mach-kirkwood/guruplug-setup.c
+++ b/arch/arm/mach-kirkwood/guruplug-setup.c
@@ -121,8 +121,6 @@ static void __init guruplug_init(void)
MACHINE_START(GURUPLUG, "Marvell GuruPlug Reference Board")
/* Maintainer: Siddarth Gore <gores@marvell.com> */
- .phys_io = KIRKWOOD_REGS_PHYS_BASE,
- .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.init_machine = guruplug_init,
.map_io = kirkwood_map_io,
diff --git a/arch/arm/mach-kirkwood/include/mach/debug-macro.S b/arch/arm/mach-kirkwood/include/mach/debug-macro.S
index d0606774dea7..db06ae437d08 100644
--- a/arch/arm/mach-kirkwood/include/mach/debug-macro.S
+++ b/arch/arm/mach-kirkwood/include/mach/debug-macro.S
@@ -8,12 +8,11 @@
#include <mach/bridge-regs.h>
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- ldreq \rx, =KIRKWOOD_REGS_PHYS_BASE
- ldrne \rx, =KIRKWOOD_REGS_VIRT_BASE
- orr \rx, \rx, #0x00012000
+ .macro addruart, rp, rv
+ ldr \rp, =KIRKWOOD_REGS_PHYS_BASE
+ ldr \rv, =KIRKWOOD_REGS_VIRT_BASE
+ orr \rp, \rp, #0x00012000
+ orr \rv, \rv, #0x00012000
.endm
#define UART_SHIFT 2
diff --git a/arch/arm/mach-kirkwood/include/mach/leds-netxbig.h b/arch/arm/mach-kirkwood/include/mach/leds-netxbig.h
new file mode 100644
index 000000000000..24b536ebdf13
--- /dev/null
+++ b/arch/arm/mach-kirkwood/include/mach/leds-netxbig.h
@@ -0,0 +1,55 @@
+/*
+ * arch/arm/mach-kirkwood/include/mach/leds-netxbig.h
+ *
+ * Platform data structure for netxbig LED driver
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_LEDS_NETXBIG_H
+#define __MACH_LEDS_NETXBIG_H
+
+struct netxbig_gpio_ext {
+ unsigned *addr;
+ int num_addr;
+ unsigned *data;
+ int num_data;
+ unsigned enable;
+};
+
+enum netxbig_led_mode {
+ NETXBIG_LED_OFF,
+ NETXBIG_LED_ON,
+ NETXBIG_LED_SATA,
+ NETXBIG_LED_TIMER1,
+ NETXBIG_LED_TIMER2,
+ NETXBIG_LED_MODE_NUM,
+};
+
+#define NETXBIG_LED_INVALID_MODE NETXBIG_LED_MODE_NUM
+
+struct netxbig_led_timer {
+ unsigned long delay_on;
+ unsigned long delay_off;
+ enum netxbig_led_mode mode;
+};
+
+struct netxbig_led {
+ const char *name;
+ const char *default_trigger;
+ int mode_addr;
+ int *mode_val;
+ int bright_addr;
+};
+
+struct netxbig_led_platform_data {
+ struct netxbig_gpio_ext *gpio_ext;
+ struct netxbig_led_timer *timer;
+ int num_timer;
+ struct netxbig_led *leds;
+ int num_leds;
+};
+
+#endif /* __MACH_LEDS_NETXBIG_H */
diff --git a/arch/arm/mach-kirkwood/lacie_v2-common.c b/arch/arm/mach-kirkwood/lacie_v2-common.c
new file mode 100644
index 000000000000..d3ea1b6c8a02
--- /dev/null
+++ b/arch/arm/mach-kirkwood/lacie_v2-common.c
@@ -0,0 +1,127 @@
+/*
+ * arch/arm/mach-kirkwood/lacie_v2-common.c
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mtd/physmap.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/gpio.h>
+#include <asm/mach/time.h>
+#include <mach/kirkwood.h>
+#include <mach/irqs.h>
+#include <plat/time.h>
+#include "common.h"
+
+/*****************************************************************************
+ * 512KB SPI Flash on Boot Device (MACRONIX MX25L4005)
+ ****************************************************************************/
+
+static struct mtd_partition lacie_v2_flash_parts[] = {
+ {
+ .name = "u-boot",
+ .size = MTDPART_SIZ_FULL,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+};
+
+static const struct flash_platform_data lacie_v2_flash = {
+ .type = "mx25l4005a",
+ .name = "spi_flash",
+ .parts = lacie_v2_flash_parts,
+ .nr_parts = ARRAY_SIZE(lacie_v2_flash_parts),
+};
+
+static struct spi_board_info __initdata lacie_v2_spi_slave_info[] = {
+ {
+ .modalias = "m25p80",
+ .platform_data = &lacie_v2_flash,
+ .irq = -1,
+ .max_speed_hz = 20000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ },
+};
+
+void __init lacie_v2_register_flash(void)
+{
+ spi_register_board_info(lacie_v2_spi_slave_info,
+ ARRAY_SIZE(lacie_v2_spi_slave_info));
+ kirkwood_spi_init();
+}
+
+/*****************************************************************************
+ * I2C devices
+ ****************************************************************************/
+
+static struct at24_platform_data at24c04 = {
+ .byte_len = SZ_4K / 8,
+ .page_size = 16,
+};
+
+/*
+ * i2c addr | chip | description
+ * 0x50 | HT24LC04 | eeprom (512B)
+ */
+
+static struct i2c_board_info __initdata lacie_v2_i2c_info[] = {
+ {
+ I2C_BOARD_INFO("24c04", 0x50),
+ .platform_data = &at24c04,
+ }
+};
+
+void __init lacie_v2_register_i2c_devices(void)
+{
+ kirkwood_i2c_init();
+ i2c_register_board_info(0, lacie_v2_i2c_info,
+ ARRAY_SIZE(lacie_v2_i2c_info));
+}
+
+/*****************************************************************************
+ * Hard Disk power
+ ****************************************************************************/
+
+static int __initdata lacie_v2_gpio_hdd_power[] = { 16, 17, 41, 42, 43 };
+
+void __init lacie_v2_hdd_power_init(int hdd_num)
+{
+ int i;
+ int err;
+
+ /* Power up all hard disks. */
+ for (i = 0; i < hdd_num; i++) {
+ err = gpio_request(lacie_v2_gpio_hdd_power[i], NULL);
+ if (err == 0) {
+ err = gpio_direction_output(
+ lacie_v2_gpio_hdd_power[i], 1);
+ /* Free the HDD power GPIOs. This allow user-space to
+ * configure them via the gpiolib sysfs interface. */
+ gpio_free(lacie_v2_gpio_hdd_power[i]);
+ }
+ if (err)
+ pr_err("Failed to power up HDD%d\n", i + 1);
+ }
+}
+
+/*****************************************************************************
+ * Timer
+ ****************************************************************************/
+
+static void lacie_v2_timer_init(void)
+{
+ kirkwood_tclk = 166666667;
+ orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk);
+}
+
+struct sys_timer lacie_v2_timer = {
+ .init = lacie_v2_timer_init,
+};
diff --git a/arch/arm/mach-kirkwood/lacie_v2-common.h b/arch/arm/mach-kirkwood/lacie_v2-common.h
new file mode 100644
index 000000000000..af521315b87b
--- /dev/null
+++ b/arch/arm/mach-kirkwood/lacie_v2-common.h
@@ -0,0 +1,18 @@
+/*
+ * arch/arm/mach-kirkwood/lacie_v2-common.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ARCH_KIRKWOOD_LACIE_V2_COMMON_H
+#define __ARCH_KIRKWOOD_LACIE_V2_COMMON_H
+
+void lacie_v2_register_flash(void);
+void lacie_v2_register_i2c_devices(void);
+void lacie_v2_hdd_power_init(int hdd_num);
+
+extern struct sys_timer lacie_v2_timer;
+
+#endif
diff --git a/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
index c6b92b42eb4e..1e5266f57e2a 100644
--- a/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
+++ b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
@@ -163,8 +163,6 @@ subsys_initcall(mv88f6281gtw_ge_pci_init);
MACHINE_START(MV88F6281GTW_GE, "Marvell 88F6281 GTW GE Board")
/* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
- .phys_io = KIRKWOOD_REGS_PHYS_BASE,
- .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.init_machine = mv88f6281gtw_ge_init,
.map_io = kirkwood_map_io,
diff --git a/arch/arm/mach-kirkwood/netspace_v2-setup.c b/arch/arm/mach-kirkwood/netspace_v2-setup.c
index d26bf324738b..5e286441b8f4 100644
--- a/arch/arm/mach-kirkwood/netspace_v2-setup.c
+++ b/arch/arm/mach-kirkwood/netspace_v2-setup.c
@@ -24,56 +24,19 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
-#include <linux/spi/flash.h>
-#include <linux/spi/spi.h>
#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
-#include <linux/i2c.h>
-#include <linux/i2c/at24.h>
#include <linux/input.h>
#include <linux/gpio.h>
#include <linux/gpio_keys.h>
#include <linux/leds.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
#include <mach/kirkwood.h>
#include <mach/leds-ns2.h>
-#include <plat/time.h>
#include "common.h"
#include "mpp.h"
-
-/*****************************************************************************
- * 512KB SPI Flash on Boot Device (MACRONIX MX25L4005)
- ****************************************************************************/
-
-static struct mtd_partition netspace_v2_flash_parts[] = {
- {
- .name = "u-boot",
- .size = MTDPART_SIZ_FULL,
- .offset = 0,
- .mask_flags = MTD_WRITEABLE, /* force read-only */
- },
-};
-
-static const struct flash_platform_data netspace_v2_flash = {
- .type = "mx25l4005a",
- .name = "spi_flash",
- .parts = netspace_v2_flash_parts,
- .nr_parts = ARRAY_SIZE(netspace_v2_flash_parts),
-};
-
-static struct spi_board_info __initdata netspace_v2_spi_slave_info[] = {
- {
- .modalias = "m25p80",
- .platform_data = &netspace_v2_flash,
- .irq = -1,
- .max_speed_hz = 20000000,
- .bus_num = 0,
- .chip_select = 0,
- },
-};
+#include "lacie_v2-common.h"
/*****************************************************************************
* Ethernet
@@ -84,27 +47,6 @@ static struct mv643xx_eth_platform_data netspace_v2_ge00_data = {
};
/*****************************************************************************
- * I2C devices
- ****************************************************************************/
-
-static struct at24_platform_data at24c04 = {
- .byte_len = SZ_4K / 8,
- .page_size = 16,
-};
-
-/*
- * i2c addr | chip | description
- * 0x50 | HT24LC04 | eeprom (512B)
- */
-
-static struct i2c_board_info __initdata netspace_v2_i2c_info[] = {
- {
- I2C_BOARD_INFO("24c04", 0x50),
- .platform_data = &at24c04,
- }
-};
-
-/*****************************************************************************
* SATA
****************************************************************************/
@@ -112,35 +54,6 @@ static struct mv_sata_platform_data netspace_v2_sata_data = {
.n_ports = 2,
};
-#define NETSPACE_V2_GPIO_SATA0_POWER 16
-#define NETSPACE_V2_GPIO_SATA1_POWER 17
-
-static void __init netspace_v2_sata_power_init(void)
-{
- int err;
-
- err = gpio_request(NETSPACE_V2_GPIO_SATA0_POWER, "SATA0 power");
- if (err == 0) {
- err = gpio_direction_output(NETSPACE_V2_GPIO_SATA0_POWER, 1);
- if (err)
- gpio_free(NETSPACE_V2_GPIO_SATA0_POWER);
- }
- if (err)
- pr_err("netspace_v2: failed to setup SATA0 power\n");
-
- if (machine_is_netspace_max_v2()) {
- err = gpio_request(NETSPACE_V2_GPIO_SATA1_POWER, "SATA1 power");
- if (err == 0) {
- err = gpio_direction_output(
- NETSPACE_V2_GPIO_SATA1_POWER, 1);
- if (err)
- gpio_free(NETSPACE_V2_GPIO_SATA1_POWER);
- }
- if (err)
- pr_err("netspace_v2: failed to setup SATA1 power\n");
- }
-}
-
/*****************************************************************************
* GPIO keys
****************************************************************************/
@@ -224,20 +137,6 @@ static struct platform_device netspace_v2_leds = {
};
/*****************************************************************************
- * Timer
- ****************************************************************************/
-
-static void netspace_v2_timer_init(void)
-{
- kirkwood_tclk = 166666667;
- orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk);
-}
-
-struct sys_timer netspace_v2_timer = {
- .init = netspace_v2_timer_init,
-};
-
-/*****************************************************************************
* General Setup
****************************************************************************/
@@ -291,18 +190,17 @@ static void __init netspace_v2_init(void)
kirkwood_init();
kirkwood_mpp_conf(netspace_v2_mpp_config);
- netspace_v2_sata_power_init();
+ if (machine_is_netspace_max_v2())
+ lacie_v2_hdd_power_init(2);
+ else
+ lacie_v2_hdd_power_init(1);
kirkwood_ehci_init();
kirkwood_ge00_init(&netspace_v2_ge00_data);
kirkwood_sata_init(&netspace_v2_sata_data);
kirkwood_uart0_init();
- spi_register_board_info(netspace_v2_spi_slave_info,
- ARRAY_SIZE(netspace_v2_spi_slave_info));
- kirkwood_spi_init();
- kirkwood_i2c_init();
- i2c_register_board_info(0, netspace_v2_i2c_info,
- ARRAY_SIZE(netspace_v2_i2c_info));
+ lacie_v2_register_flash();
+ lacie_v2_register_i2c_devices();
platform_device_register(&netspace_v2_leds);
platform_device_register(&netspace_v2_gpio_leds);
@@ -317,36 +215,30 @@ static void __init netspace_v2_init(void)
#ifdef CONFIG_MACH_NETSPACE_V2
MACHINE_START(NETSPACE_V2, "LaCie Network Space v2")
- .phys_io = KIRKWOOD_REGS_PHYS_BASE,
- .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.init_machine = netspace_v2_init,
.map_io = kirkwood_map_io,
.init_irq = kirkwood_init_irq,
- .timer = &netspace_v2_timer,
+ .timer = &lacie_v2_timer,
MACHINE_END
#endif
#ifdef CONFIG_MACH_INETSPACE_V2
MACHINE_START(INETSPACE_V2, "LaCie Internet Space v2")
- .phys_io = KIRKWOOD_REGS_PHYS_BASE,
- .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.init_machine = netspace_v2_init,
.map_io = kirkwood_map_io,
.init_irq = kirkwood_init_irq,
- .timer = &netspace_v2_timer,
+ .timer = &lacie_v2_timer,
MACHINE_END
#endif
#ifdef CONFIG_MACH_NETSPACE_MAX_V2
MACHINE_START(NETSPACE_MAX_V2, "LaCie Network Space Max v2")
- .phys_io = KIRKWOOD_REGS_PHYS_BASE,
- .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.init_machine = netspace_v2_init,
.map_io = kirkwood_map_io,
.init_irq = kirkwood_init_irq,
- .timer = &netspace_v2_timer,
+ .timer = &lacie_v2_timer,
MACHINE_END
#endif
diff --git a/arch/arm/mach-kirkwood/netxbig_v2-setup.c b/arch/arm/mach-kirkwood/netxbig_v2-setup.c
index 2bd14c5079de..a1b45d501aef 100644
--- a/arch/arm/mach-kirkwood/netxbig_v2-setup.c
+++ b/arch/arm/mach-kirkwood/netxbig_v2-setup.c
@@ -23,55 +23,19 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
-#include <linux/spi/flash.h>
-#include <linux/spi/spi.h>
#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
-#include <linux/i2c.h>
-#include <linux/i2c/at24.h>
#include <linux/input.h>
#include <linux/gpio.h>
#include <linux/gpio_keys.h>
#include <linux/leds.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
#include <mach/kirkwood.h>
-#include <plat/time.h>
+#include <mach/leds-netxbig.h>
#include "common.h"
#include "mpp.h"
-
-/*****************************************************************************
- * 512KB SPI Flash on Boot Device (MACRONIX MX25L4005)
- ****************************************************************************/
-
-static struct mtd_partition netxbig_v2_flash_parts[] = {
- {
- .name = "u-boot",
- .size = MTDPART_SIZ_FULL,
- .offset = 0,
- .mask_flags = MTD_WRITEABLE, /* force read-only */
- },
-};
-
-static const struct flash_platform_data netxbig_v2_flash = {
- .type = "mx25l4005a",
- .name = "spi_flash",
- .parts = netxbig_v2_flash_parts,
- .nr_parts = ARRAY_SIZE(netxbig_v2_flash_parts),
-};
-
-static struct spi_board_info __initdata netxbig_v2_spi_slave_info[] = {
- {
- .modalias = "m25p80",
- .platform_data = &netxbig_v2_flash,
- .irq = -1,
- .max_speed_hz = 20000000,
- .bus_num = 0,
- .chip_select = 0,
- },
-};
+#include "lacie_v2-common.h"
/*****************************************************************************
* Ethernet
@@ -86,27 +50,6 @@ static struct mv643xx_eth_platform_data netxbig_v2_ge01_data = {
};
/*****************************************************************************
- * I2C devices
- ****************************************************************************/
-
-static struct at24_platform_data at24c04 = {
- .byte_len = SZ_4K / 8,
- .page_size = 16,
-};
-
-/*
- * i2c addr | chip | description
- * 0x50 | HT24LC04 | eeprom (512B)
- */
-
-static struct i2c_board_info __initdata netxbig_v2_i2c_info[] = {
- {
- I2C_BOARD_INFO("24c04", 0x50),
- .platform_data = &at24c04,
- }
-};
-
-/*****************************************************************************
* SATA
****************************************************************************/
@@ -114,34 +57,6 @@ static struct mv_sata_platform_data netxbig_v2_sata_data = {
.n_ports = 2,
};
-static int __initdata netxbig_v2_gpio_hdd_power[] = { 16, 17, 41, 42, 43 };
-
-static void __init netxbig_v2_sata_power_init(void)
-{
- int i;
- int err;
- int hdd_nb;
-
- if (machine_is_net2big_v2())
- hdd_nb = 2;
- else
- hdd_nb = 5;
-
- /* Power up all hard disks. */
- for (i = 0; i < hdd_nb; i++) {
- err = gpio_request(netxbig_v2_gpio_hdd_power[i], NULL);
- if (err == 0) {
- err = gpio_direction_output(
- netxbig_v2_gpio_hdd_power[i], 1);
- /* Free the HDD power GPIOs. This allow user-space to
- * configure them via the gpiolib sysfs interface. */
- gpio_free(netxbig_v2_gpio_hdd_power[i]);
- }
- if (err)
- pr_err("netxbig_v2: failed to power up HDD%d\n", i + 1);
- }
-}
-
/*****************************************************************************
* GPIO keys
****************************************************************************/
@@ -190,7 +105,7 @@ static struct platform_device netxbig_v2_gpio_buttons = {
};
/*****************************************************************************
- * GPIO LEDs
+ * GPIO extension LEDs
****************************************************************************/
/*
@@ -200,19 +115,32 @@ static struct platform_device netxbig_v2_gpio_buttons = {
* - address register : bit [0-2] -> GPIO [47-49]
* - data register : bit [0-2] -> GPIO [44-46]
* - enable register : GPIO 29
- *
+ */
+
+static int netxbig_v2_gpio_ext_addr[] = { 47, 48, 49 };
+static int netxbig_v2_gpio_ext_data[] = { 44, 45, 46 };
+
+static struct netxbig_gpio_ext netxbig_v2_gpio_ext = {
+ .addr = netxbig_v2_gpio_ext_addr,
+ .num_addr = ARRAY_SIZE(netxbig_v2_gpio_ext_addr),
+ .data = netxbig_v2_gpio_ext_data,
+ .num_data = ARRAY_SIZE(netxbig_v2_gpio_ext_data),
+ .enable = 29,
+};
+
+/*
* Address register selection:
*
* addr | register
* ----------------------------
* 0 | front LED
* 1 | front LED brightness
- * 2 | HDD LED brightness
- * 3 | HDD1 LED
- * 4 | HDD2 LED
- * 5 | HDD3 LED
- * 6 | HDD4 LED
- * 7 | HDD5 LED
+ * 2 | SATA LED brightness
+ * 3 | SATA0 LED
+ * 4 | SATA1 LED
+ * 5 | SATA2 LED
+ * 6 | SATA3 LED
+ * 7 | SATA4 LED
*
* Data register configuration:
*
@@ -233,30 +161,107 @@ static struct platform_device netxbig_v2_gpio_buttons = {
* 6 | blink blue on=1 sec and red on=1 sec
* 7 | blink blue on=0.5 sec and blue off=2.5 sec
*
- * data | HDD LED mode
+ * data | SATA LED mode
* -------------------------------------------------
- * 0 | fix blue on
+ * 0 | fix off
* 1 | SATA activity blink
* 2 | fix red on
* 3 | blink blue on=1 sec and blue off=1 sec
* 4 | blink red on=1 sec and red off=1 sec
* 5 | blink blue on=2.5 sec and red on=0.5 sec
* 6 | blink blue on=1 sec and red on=1 sec
- * 7 | blink blue on=0.5 sec and blue off=2.5 sec
+ * 7 | fix blue on
*/
-/*****************************************************************************
- * Timer
- ****************************************************************************/
+static int netxbig_v2_red_mled[NETXBIG_LED_MODE_NUM] = {
+ [NETXBIG_LED_OFF] = 0,
+ [NETXBIG_LED_ON] = 2,
+ [NETXBIG_LED_SATA] = NETXBIG_LED_INVALID_MODE,
+ [NETXBIG_LED_TIMER1] = 4,
+ [NETXBIG_LED_TIMER2] = NETXBIG_LED_INVALID_MODE,
+};
-static void netxbig_v2_timer_init(void)
-{
- kirkwood_tclk = 166666667;
- orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk);
-}
+static int netxbig_v2_blue_pwr_mled[NETXBIG_LED_MODE_NUM] = {
+ [NETXBIG_LED_OFF] = 0,
+ [NETXBIG_LED_ON] = 1,
+ [NETXBIG_LED_SATA] = NETXBIG_LED_INVALID_MODE,
+ [NETXBIG_LED_TIMER1] = 3,
+ [NETXBIG_LED_TIMER2] = 7,
+};
+
+static int netxbig_v2_blue_sata_mled[NETXBIG_LED_MODE_NUM] = {
+ [NETXBIG_LED_OFF] = 0,
+ [NETXBIG_LED_ON] = 7,
+ [NETXBIG_LED_SATA] = 1,
+ [NETXBIG_LED_TIMER1] = 3,
+ [NETXBIG_LED_TIMER2] = NETXBIG_LED_INVALID_MODE,
+};
+
+static struct netxbig_led_timer netxbig_v2_led_timer[] = {
+ [0] = {
+ .delay_on = 500,
+ .delay_off = 500,
+ .mode = NETXBIG_LED_TIMER1,
+ },
+ [1] = {
+ .delay_on = 500,
+ .delay_off = 1000,
+ .mode = NETXBIG_LED_TIMER2,
+ },
+};
+
+#define NETXBIG_LED(_name, maddr, mval, baddr) \
+ { .name = _name, \
+ .mode_addr = maddr, \
+ .mode_val = mval, \
+ .bright_addr = baddr }
+
+static struct netxbig_led net2big_v2_leds_ctrl[] = {
+ NETXBIG_LED("net2big-v2:blue:power", 0, netxbig_v2_blue_pwr_mled, 1),
+ NETXBIG_LED("net2big-v2:red:power", 0, netxbig_v2_red_mled, 1),
+ NETXBIG_LED("net2big-v2:blue:sata0", 3, netxbig_v2_blue_sata_mled, 2),
+ NETXBIG_LED("net2big-v2:red:sata0", 3, netxbig_v2_red_mled, 2),
+ NETXBIG_LED("net2big-v2:blue:sata1", 4, netxbig_v2_blue_sata_mled, 2),
+ NETXBIG_LED("net2big-v2:red:sata1", 4, netxbig_v2_red_mled, 2),
+};
+
+static struct netxbig_led_platform_data net2big_v2_leds_data = {
+ .gpio_ext = &netxbig_v2_gpio_ext,
+ .timer = netxbig_v2_led_timer,
+ .num_timer = ARRAY_SIZE(netxbig_v2_led_timer),
+ .leds = net2big_v2_leds_ctrl,
+ .num_leds = ARRAY_SIZE(net2big_v2_leds_ctrl),
+};
+
+static struct netxbig_led net5big_v2_leds_ctrl[] = {
+ NETXBIG_LED("net5big-v2:blue:power", 0, netxbig_v2_blue_pwr_mled, 1),
+ NETXBIG_LED("net5big-v2:red:power", 0, netxbig_v2_red_mled, 1),
+ NETXBIG_LED("net5big-v2:blue:sata0", 3, netxbig_v2_blue_sata_mled, 2),
+ NETXBIG_LED("net5big-v2:red:sata0", 3, netxbig_v2_red_mled, 2),
+ NETXBIG_LED("net5big-v2:blue:sata1", 4, netxbig_v2_blue_sata_mled, 2),
+ NETXBIG_LED("net5big-v2:red:sata1", 4, netxbig_v2_red_mled, 2),
+ NETXBIG_LED("net5big-v2:blue:sata2", 5, netxbig_v2_blue_sata_mled, 2),
+ NETXBIG_LED("net5big-v2:red:sata2", 5, netxbig_v2_red_mled, 2),
+ NETXBIG_LED("net5big-v2:blue:sata3", 6, netxbig_v2_blue_sata_mled, 2),
+ NETXBIG_LED("net5big-v2:red:sata3", 6, netxbig_v2_red_mled, 2),
+ NETXBIG_LED("net5big-v2:blue:sata4", 7, netxbig_v2_blue_sata_mled, 2),
+ NETXBIG_LED("net5big-v2:red:sata5", 7, netxbig_v2_red_mled, 2),
+};
-struct sys_timer netxbig_v2_timer = {
- .init = netxbig_v2_timer_init,
+static struct netxbig_led_platform_data net5big_v2_leds_data = {
+ .gpio_ext = &netxbig_v2_gpio_ext,
+ .timer = netxbig_v2_led_timer,
+ .num_timer = ARRAY_SIZE(netxbig_v2_led_timer),
+ .leds = net5big_v2_leds_ctrl,
+ .num_leds = ARRAY_SIZE(net5big_v2_leds_ctrl),
+};
+
+static struct platform_device netxbig_v2_leds = {
+ .name = "leds-netxbig",
+ .id = -1,
+ .dev = {
+ .platform_data = &net2big_v2_leds_data,
+ },
};
/*****************************************************************************
@@ -284,18 +289,18 @@ static unsigned int net2big_v2_mpp_config[] __initdata = {
MPP24_GPIO, /* USB mode select */
MPP26_GPIO, /* USB device vbus */
MPP28_GPIO, /* USB enable host vbus */
- MPP29_GPIO, /* CPLD extension ALE */
+ MPP29_GPIO, /* GPIO extension ALE */
MPP34_GPIO, /* Rear Push button */
MPP35_GPIO, /* Inhibit switch power-off */
MPP36_GPIO, /* SATA HDD1 presence */
MPP37_GPIO, /* SATA HDD2 presence */
MPP40_GPIO, /* eSATA presence */
- MPP44_GPIO, /* CPLD extension (data 0) */
- MPP45_GPIO, /* CPLD extension (data 1) */
- MPP46_GPIO, /* CPLD extension (data 2) */
- MPP47_GPIO, /* CPLD extension (addr 0) */
- MPP48_GPIO, /* CPLD extension (addr 1) */
- MPP49_GPIO, /* CPLD extension (addr 2) */
+ MPP44_GPIO, /* GPIO extension (data 0) */
+ MPP45_GPIO, /* GPIO extension (data 1) */
+ MPP46_GPIO, /* GPIO extension (data 2) */
+ MPP47_GPIO, /* GPIO extension (addr 0) */
+ MPP48_GPIO, /* GPIO extension (addr 1) */
+ MPP49_GPIO, /* GPIO extension (addr 2) */
0
};
@@ -324,7 +329,7 @@ static unsigned int net5big_v2_mpp_config[] __initdata = {
MPP26_GE1_RXD2,
MPP27_GE1_RXD3,
MPP28_GPIO, /* USB enable host vbus */
- MPP29_GPIO, /* CPLD extension ALE */
+ MPP29_GPIO, /* GPIO extension ALE */
MPP30_GE1_RXCTL,
MPP31_GE1_RXCLK,
MPP32_GE1_TCLKOUT,
@@ -339,12 +344,12 @@ static unsigned int net5big_v2_mpp_config[] __initdata = {
MPP41_GPIO, /* SATA HDD3 power */
MPP42_GPIO, /* SATA HDD4 power */
MPP43_GPIO, /* SATA HDD5 power */
- MPP44_GPIO, /* CPLD extension (data 0) */
- MPP45_GPIO, /* CPLD extension (data 1) */
- MPP46_GPIO, /* CPLD extension (data 2) */
- MPP47_GPIO, /* CPLD extension (addr 0) */
- MPP48_GPIO, /* CPLD extension (addr 1) */
- MPP49_GPIO, /* CPLD extension (addr 2) */
+ MPP44_GPIO, /* GPIO extension (data 0) */
+ MPP45_GPIO, /* GPIO extension (data 1) */
+ MPP46_GPIO, /* GPIO extension (data 2) */
+ MPP47_GPIO, /* GPIO extension (addr 0) */
+ MPP48_GPIO, /* GPIO extension (addr 1) */
+ MPP49_GPIO, /* GPIO extension (addr 2) */
0
};
@@ -366,7 +371,10 @@ static void __init netxbig_v2_init(void)
else
kirkwood_mpp_conf(net5big_v2_mpp_config);
- netxbig_v2_sata_power_init();
+ if (machine_is_net2big_v2())
+ lacie_v2_hdd_power_init(2);
+ else
+ lacie_v2_hdd_power_init(5);
kirkwood_ehci_init();
kirkwood_ge00_init(&netxbig_v2_ge00_data);
@@ -374,13 +382,12 @@ static void __init netxbig_v2_init(void)
kirkwood_ge01_init(&netxbig_v2_ge01_data);
kirkwood_sata_init(&netxbig_v2_sata_data);
kirkwood_uart0_init();
- spi_register_board_info(netxbig_v2_spi_slave_info,
- ARRAY_SIZE(netxbig_v2_spi_slave_info));
- kirkwood_spi_init();
- kirkwood_i2c_init();
- i2c_register_board_info(0, netxbig_v2_i2c_info,
- ARRAY_SIZE(netxbig_v2_i2c_info));
+ lacie_v2_register_flash();
+ lacie_v2_register_i2c_devices();
+ if (machine_is_net5big_v2())
+ netxbig_v2_leds.dev.platform_data = &net5big_v2_leds_data;
+ platform_device_register(&netxbig_v2_leds);
platform_device_register(&netxbig_v2_gpio_buttons);
if (gpio_request(NETXBIG_V2_GPIO_POWER_OFF, "power-off") == 0 &&
@@ -392,24 +399,20 @@ static void __init netxbig_v2_init(void)
#ifdef CONFIG_MACH_NET2BIG_V2
MACHINE_START(NET2BIG_V2, "LaCie 2Big Network v2")
- .phys_io = KIRKWOOD_REGS_PHYS_BASE,
- .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.init_machine = netxbig_v2_init,
.map_io = kirkwood_map_io,
.init_irq = kirkwood_init_irq,
- .timer = &netxbig_v2_timer,
+ .timer = &lacie_v2_timer,
MACHINE_END
#endif
#ifdef CONFIG_MACH_NET5BIG_V2
MACHINE_START(NET5BIG_V2, "LaCie 5Big Network v2")
- .phys_io = KIRKWOOD_REGS_PHYS_BASE,
- .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.init_machine = netxbig_v2_init,
.map_io = kirkwood_map_io,
.init_irq = kirkwood_init_irq,
- .timer = &netxbig_v2_timer,
+ .timer = &lacie_v2_timer,
MACHINE_END
#endif
diff --git a/arch/arm/mach-kirkwood/openrd-setup.c b/arch/arm/mach-kirkwood/openrd-setup.c
index fd06be618815..c9d77fad10ab 100644
--- a/arch/arm/mach-kirkwood/openrd-setup.c
+++ b/arch/arm/mach-kirkwood/openrd-setup.c
@@ -16,6 +16,7 @@
#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
#include <linux/i2c.h>
+#include <linux/gpio.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/kirkwood.h>
@@ -57,7 +58,22 @@ static struct mvsdio_platform_data openrd_mvsdio_data = {
};
static unsigned int openrd_mpp_config[] __initdata = {
+ MPP12_SD_CLK,
+ MPP13_SD_CMD,
+ MPP14_SD_D0,
+ MPP15_SD_D1,
+ MPP16_SD_D2,
+ MPP17_SD_D3,
+ MPP28_GPIO,
MPP29_GPIO,
+ MPP34_GPIO,
+ 0
+};
+
+/* Configure MPP for UART1 */
+static unsigned int openrd_uart1_mpp_config[] __initdata = {
+ MPP13_UART1_TXD,
+ MPP14_UART1_RXD,
0
};
@@ -67,6 +83,68 @@ static struct i2c_board_info i2c_board_info[] __initdata = {
},
};
+static int __initdata uart1;
+
+static int __init sd_uart_selection(char *str)
+{
+ uart1 = -EINVAL;
+
+ /* Default is SD. Change if required, for UART */
+ if (!str)
+ return 0;
+
+ if (!strncmp(str, "232", 3)) {
+ uart1 = 232;
+ } else if (!strncmp(str, "485", 3)) {
+ /* OpenRD-Base doesn't have RS485. Treat is as an
+ * unknown argument & just have default setting -
+ * which is SD */
+ if (machine_is_openrd_base()) {
+ uart1 = -ENODEV;
+ return 1;
+ }
+
+ uart1 = 485;
+ }
+ return 1;
+}
+/* Parse boot_command_line string kw_openrd_init_uart1=232/485 */
+__setup("kw_openrd_init_uart1=", sd_uart_selection);
+
+static int __init uart1_mpp_config(void)
+{
+ kirkwood_mpp_conf(openrd_uart1_mpp_config);
+
+ if (gpio_request(34, "SD_UART1_SEL")) {
+ printk(KERN_ERR "GPIO request failed for SD/UART1 selection"
+ ", gpio: 34\n");
+ return -EIO;
+ }
+
+ if (gpio_request(28, "RS232_RS485_SEL")) {
+ printk(KERN_ERR "GPIO request failed for RS232/RS485 selection"
+ ", gpio# 28\n");
+ gpio_free(34);
+ return -EIO;
+ }
+
+ /* Select UART1
+ * Pin # 34: 0 => UART1, 1 => SD */
+ gpio_direction_output(34, 0);
+
+ /* Select RS232 OR RS485
+ * Pin # 28: 0 => RS232, 1 => RS485 */
+ if (uart1 == 232)
+ gpio_direction_output(28, 0);
+ else
+ gpio_direction_output(28, 1);
+
+ gpio_free(34);
+ gpio_free(28);
+
+ return 0;
+}
+
static void __init openrd_init(void)
{
/*
@@ -90,7 +168,6 @@ static void __init openrd_init(void)
kirkwood_ge01_init(&openrd_ge01_data);
kirkwood_sata_init(&openrd_sata_data);
- kirkwood_sdio_init(&openrd_mvsdio_data);
kirkwood_i2c_init();
@@ -99,6 +176,28 @@ static void __init openrd_init(void)
ARRAY_SIZE(i2c_board_info));
kirkwood_audio_init();
}
+
+ if (uart1 <= 0) {
+ if (uart1 < 0)
+ printk(KERN_ERR "Invalid kernel parameter to select "
+ "UART1. Defaulting to SD. ERROR CODE: %d\n",
+ uart1);
+
+ /* Select SD
+ * Pin # 34: 0 => UART1, 1 => SD */
+ if (gpio_request(34, "SD_UART1_SEL")) {
+ printk(KERN_ERR "GPIO request failed for SD/UART1 "
+ "selection, gpio: 34\n");
+ } else {
+
+ gpio_direction_output(34, 1);
+ gpio_free(34);
+ kirkwood_sdio_init(&openrd_mvsdio_data);
+ }
+ } else {
+ if (!uart1_mpp_config())
+ kirkwood_uart1_init();
+ }
}
static int __init openrd_pci_init(void)
@@ -115,8 +214,6 @@ subsys_initcall(openrd_pci_init);
#ifdef CONFIG_MACH_OPENRD_BASE
MACHINE_START(OPENRD_BASE, "Marvell OpenRD Base Board")
/* Maintainer: Dhaval Vasa <dhaval.vasa@einfochips.com> */
- .phys_io = KIRKWOOD_REGS_PHYS_BASE,
- .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.init_machine = openrd_init,
.map_io = kirkwood_map_io,
@@ -128,8 +225,6 @@ MACHINE_END
#ifdef CONFIG_MACH_OPENRD_CLIENT
MACHINE_START(OPENRD_CLIENT, "Marvell OpenRD Client Board")
/* Maintainer: Dhaval Vasa <dhaval.vasa@einfochips.com> */
- .phys_io = KIRKWOOD_REGS_PHYS_BASE,
- .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.init_machine = openrd_init,
.map_io = kirkwood_map_io,
@@ -141,8 +236,6 @@ MACHINE_END
#ifdef CONFIG_MACH_OPENRD_ULTIMATE
MACHINE_START(OPENRD_ULTIMATE, "Marvell OpenRD Ultimate Board")
/* Maintainer: Dhaval Vasa <dhaval.vasa@einfochips.com> */
- .phys_io = KIRKWOOD_REGS_PHYS_BASE,
- .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.init_machine = openrd_init,
.map_io = kirkwood_map_io,
diff --git a/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
index c34718c2cfe5..0049614cd324 100644
--- a/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
+++ b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
@@ -79,8 +79,6 @@ subsys_initcall(rd88f6192_pci_init);
MACHINE_START(RD88F6192_NAS, "Marvell RD-88F6192-NAS Development Board")
/* Maintainer: Saeed Bishara <saeed@marvell.com> */
- .phys_io = KIRKWOOD_REGS_PHYS_BASE,
- .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.init_machine = rd88f6192_init,
.map_io = kirkwood_map_io,
diff --git a/arch/arm/mach-kirkwood/rd88f6281-setup.c b/arch/arm/mach-kirkwood/rd88f6281-setup.c
index 3d1477135e12..0998a08cf42d 100644
--- a/arch/arm/mach-kirkwood/rd88f6281-setup.c
+++ b/arch/arm/mach-kirkwood/rd88f6281-setup.c
@@ -115,8 +115,6 @@ subsys_initcall(rd88f6281_pci_init);
MACHINE_START(RD88F6281, "Marvell RD-88F6281 Reference Board")
/* Maintainer: Saeed Bishara <saeed@marvell.com> */
- .phys_io = KIRKWOOD_REGS_PHYS_BASE,
- .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.init_machine = rd88f6281_init,
.map_io = kirkwood_map_io,
diff --git a/arch/arm/mach-kirkwood/sheevaplug-setup.c b/arch/arm/mach-kirkwood/sheevaplug-setup.c
index a00879d34d54..d2eec35dfe0f 100644
--- a/arch/arm/mach-kirkwood/sheevaplug-setup.c
+++ b/arch/arm/mach-kirkwood/sheevaplug-setup.c
@@ -131,8 +131,6 @@ static void __init sheevaplug_init(void)
#ifdef CONFIG_MACH_SHEEVAPLUG
MACHINE_START(SHEEVAPLUG, "Marvell SheevaPlug Reference Board")
/* Maintainer: shadi Ammouri <shadi@marvell.com> */
- .phys_io = KIRKWOOD_REGS_PHYS_BASE,
- .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.init_machine = sheevaplug_init,
.map_io = kirkwood_map_io,
@@ -143,8 +141,6 @@ MACHINE_END
#ifdef CONFIG_MACH_ESATA_SHEEVAPLUG
MACHINE_START(ESATA_SHEEVAPLUG, "Marvell eSATA SheevaPlug Reference Board")
- .phys_io = KIRKWOOD_REGS_PHYS_BASE,
- .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.init_machine = sheevaplug_init,
.map_io = kirkwood_map_io,
diff --git a/arch/arm/mach-kirkwood/t5325-setup.c b/arch/arm/mach-kirkwood/t5325-setup.c
index d01bf89cedbe..ce50e61aac9f 100644
--- a/arch/arm/mach-kirkwood/t5325-setup.c
+++ b/arch/arm/mach-kirkwood/t5325-setup.c
@@ -184,8 +184,6 @@ subsys_initcall(hp_t5325_pci_init);
MACHINE_START(T5325, "HP t5325 Thin Client")
/* Maintainer: Martin Michlmayr <tbm@cyrius.com> */
- .phys_io = KIRKWOOD_REGS_PHYS_BASE,
- .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.init_machine = hp_t5325_init,
.map_io = kirkwood_map_io,
diff --git a/arch/arm/mach-kirkwood/ts219-setup.c b/arch/arm/mach-kirkwood/ts219-setup.c
index a5bd7fde04a9..6710bd7773b8 100644
--- a/arch/arm/mach-kirkwood/ts219-setup.c
+++ b/arch/arm/mach-kirkwood/ts219-setup.c
@@ -120,8 +120,6 @@ subsys_initcall(ts219_pci_init);
MACHINE_START(TS219, "QNAP TS-119/TS-219")
/* Maintainer: Martin Michlmayr <tbm@cyrius.com> */
- .phys_io = KIRKWOOD_REGS_PHYS_BASE,
- .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.init_machine = qnap_ts219_init,
.map_io = kirkwood_map_io,
diff --git a/arch/arm/mach-kirkwood/ts41x-setup.c b/arch/arm/mach-kirkwood/ts41x-setup.c
index 2e14afef07a2..8be09a0ce4ac 100644
--- a/arch/arm/mach-kirkwood/ts41x-setup.c
+++ b/arch/arm/mach-kirkwood/ts41x-setup.c
@@ -149,8 +149,6 @@ subsys_initcall(ts41x_pci_init);
MACHINE_START(TS41X, "QNAP TS-41x")
/* Maintainer: Martin Michlmayr <tbm@cyrius.com> */
- .phys_io = KIRKWOOD_REGS_PHYS_BASE,
- .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.init_machine = qnap_ts41x_init,
.map_io = kirkwood_map_io,
diff --git a/arch/arm/mach-ks8695/board-acs5k.c b/arch/arm/mach-ks8695/board-acs5k.c
index 9e3e5a640ad2..3ca4f8e6f54f 100644
--- a/arch/arm/mach-ks8695/board-acs5k.c
+++ b/arch/arm/mach-ks8695/board-acs5k.c
@@ -223,8 +223,6 @@ static void __init acs5k_init(void)
MACHINE_START(ACS5K, "Brivo Systems LLC ACS-5000 Master board")
/* Maintainer: Simtec Electronics. */
- .phys_io = KS8695_IO_PA,
- .io_pg_offst = (KS8695_IO_VA >> 18) & 0xfffc,
.boot_params = KS8695_SDRAM_PA + 0x100,
.map_io = ks8695_map_io,
.init_irq = ks8695_init_irq,
diff --git a/arch/arm/mach-ks8695/board-dsm320.c b/arch/arm/mach-ks8695/board-dsm320.c
index 521ff0789f39..ada92b6bed24 100644
--- a/arch/arm/mach-ks8695/board-dsm320.c
+++ b/arch/arm/mach-ks8695/board-dsm320.c
@@ -121,8 +121,6 @@ static void __init dsm320_init(void)
MACHINE_START(DSM320, "D-Link DSM-320 Wireless Media Player")
/* Maintainer: Simtec Electronics. */
- .phys_io = KS8695_IO_PA,
- .io_pg_offst = (KS8695_IO_VA >> 18) & 0xfffc,
.boot_params = KS8695_SDRAM_PA + 0x100,
.map_io = ks8695_map_io,
.init_irq = ks8695_init_irq,
diff --git a/arch/arm/mach-ks8695/board-micrel.c b/arch/arm/mach-ks8695/board-micrel.c
index 8ceaf5ac6e2c..c7ad09bd6ea2 100644
--- a/arch/arm/mach-ks8695/board-micrel.c
+++ b/arch/arm/mach-ks8695/board-micrel.c
@@ -53,8 +53,6 @@ static void __init micrel_init(void)
MACHINE_START(KS8695, "KS8695 Centaur Development Board")
/* Maintainer: Micrel Semiconductor Inc. */
- .phys_io = KS8695_IO_PA,
- .io_pg_offst = (KS8695_IO_VA >> 18) & 0xfffc,
.boot_params = KS8695_SDRAM_PA + 0x100,
.map_io = ks8695_map_io,
.init_irq = ks8695_init_irq,
diff --git a/arch/arm/mach-ks8695/include/mach/debug-macro.S b/arch/arm/mach-ks8695/include/mach/debug-macro.S
index cf2095da2372..bf516adf1925 100644
--- a/arch/arm/mach-ks8695/include/mach/debug-macro.S
+++ b/arch/arm/mach-ks8695/include/mach/debug-macro.S
@@ -14,11 +14,9 @@
#include <mach/hardware.h>
#include <mach/regs-uart.h>
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- ldreq \rx, =KS8695_UART_PA @ physical base address
- ldrne \rx, =KS8695_UART_VA @ virtual base address
+ .macro addruart, rp, rv
+ ldr \rp, =KS8695_UART_PA @ physical base address
+ ldr \rv, =KS8695_UART_VA @ virtual base address
.endm
.macro senduart, rd, rx
diff --git a/arch/arm/mach-l7200/include/mach/debug-macro.S b/arch/arm/mach-l7200/include/mach/debug-macro.S
new file mode 100644
index 000000000000..b0a2db77d392
--- /dev/null
+++ b/arch/arm/mach-l7200/include/mach/debug-macro.S
@@ -0,0 +1,38 @@
+/* arch/arm/mach-l7200/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+ .equ io_virt, IO_BASE
+ .equ io_phys, IO_START
+
+ .macro addruart, rp, rv
+ mov \rp, #0x00044000 @ UART1
+@ mov \rp, #0x00045000 @ UART2
+ add \rv, \rp, #io_virt @ virtual address
+ add \rp, \rp, #io_phys @ physical base address
+ .endm
+
+ .macro senduart,rd,rx
+ str \rd, [\rx, #0x0] @ UARTDR
+ .endm
+
+ .macro waituart,rd,rx
+1001: ldr \rd, [\rx, #0x18] @ UARTFLG
+ tst \rd, #1 << 5 @ UARTFLGUTXFF - 1 when full
+ bne 1001b
+ .endm
+
+ .macro busyuart,rd,rx
+1001: ldr \rd, [\rx, #0x18] @ UARTFLG
+ tst \rd, #1 << 3 @ UARTFLGUBUSY - 1 when busy
+ bne 1001b
+ .endm
diff --git a/arch/arm/mach-lh7a40x/arch-kev7a400.c b/arch/arm/mach-lh7a40x/arch-kev7a400.c
index 3d7bd50b9095..9088c16662e8 100644
--- a/arch/arm/mach-lh7a40x/arch-kev7a400.c
+++ b/arch/arm/mach-lh7a40x/arch-kev7a400.c
@@ -111,8 +111,6 @@ void __init lh7a40x_init_board_irq (void)
MACHINE_START (KEV7A400, "Sharp KEV7a400")
/* Maintainer: Marc Singer */
- .phys_io = 0x80000000,
- .io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc,
.boot_params = 0xc0000100,
.map_io = kev7a400_map_io,
.init_irq = lh7a400_init_irq,
diff --git a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
index cb15e5d32120..7315a569aea1 100644
--- a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
+++ b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
@@ -398,8 +398,6 @@ lpd7a40x_map_io(void)
MACHINE_START (LPD7A400, "Logic Product Development LPD7A400-10")
/* Maintainer: Marc Singer */
- .phys_io = 0x80000000,
- .io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc,
.boot_params = 0xc0000100,
.map_io = lpd7a40x_map_io,
.init_irq = lh7a400_init_irq,
@@ -413,8 +411,6 @@ MACHINE_END
MACHINE_START (LPD7A404, "Logic Product Development LPD7A404-10")
/* Maintainer: Marc Singer */
- .phys_io = 0x80000000,
- .io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc,
.boot_params = 0xc0000100,
.map_io = lpd7a40x_map_io,
.init_irq = lh7a404_init_irq,
diff --git a/arch/arm/mach-lh7a40x/include/mach/debug-macro.S b/arch/arm/mach-lh7a40x/include/mach/debug-macro.S
index c0dcbbba22ba..cff33625276f 100644
--- a/arch/arm/mach-lh7a40x/include/mach/debug-macro.S
+++ b/arch/arm/mach-lh7a40x/include/mach/debug-macro.S
@@ -14,12 +14,10 @@
@ It is not known if this will be appropriate for every 40x
@ board.
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- mov \rx, #0x00000700 @ offset from base
- orreq \rx, \rx, #0x80000000 @ physical base
- orrne \rx, \rx, #0xf8000000 @ virtual base
+ .macro addruart, rp, rv
+ mov \rp, #0x00000700 @ offset from base
+ orr \rv, \rp, #0xf8000000 @ virtual base
+ orr \rp, \rp, #0x80000000 @ physical base
.endm
.macro senduart,rd,rx
diff --git a/arch/arm/mach-loki/include/mach/debug-macro.S b/arch/arm/mach-loki/include/mach/debug-macro.S
index 3136c913a92c..cc90d99ac76c 100644
--- a/arch/arm/mach-loki/include/mach/debug-macro.S
+++ b/arch/arm/mach-loki/include/mach/debug-macro.S
@@ -8,12 +8,11 @@
#include <mach/loki.h>
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- ldreq \rx, =LOKI_REGS_PHYS_BASE
- ldrne \rx, =LOKI_REGS_VIRT_BASE
- orr \rx, \rx, #0x00012000
+ .macro addruart, rp, rv
+ ldr \rp, =LOKI_REGS_PHYS_BASE
+ ldr \rv, =LOKI_REGS_VIRT_BASE
+ orr \rp, \rp, #0x00012000
+ orr \rv, \rv, #0x00012000
.endm
#define UART_SHIFT 2
diff --git a/arch/arm/mach-loki/lb88rc8480-setup.c b/arch/arm/mach-loki/lb88rc8480-setup.c
index 85f9c1296aa0..a1e75e7fc500 100644
--- a/arch/arm/mach-loki/lb88rc8480-setup.c
+++ b/arch/arm/mach-loki/lb88rc8480-setup.c
@@ -90,8 +90,6 @@ static void __init lb88rc8480_init(void)
MACHINE_START(LB88RC8480, "Marvell LB88RC8480 Development Board")
/* Maintainer: Ke Wei <kewei@marvell.com> */
- .phys_io = LOKI_REGS_PHYS_BASE,
- .io_pg_offst = ((LOKI_REGS_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.init_machine = lb88rc8480_init,
.map_io = loki_map_io,
diff --git a/arch/arm/mach-lpc32xx/include/mach/debug-macro.S b/arch/arm/mach-lpc32xx/include/mach/debug-macro.S
index 621744d6b152..629e744aeb9e 100644
--- a/arch/arm/mach-lpc32xx/include/mach/debug-macro.S
+++ b/arch/arm/mach-lpc32xx/include/mach/debug-macro.S
@@ -20,11 +20,9 @@
* Debug output is hardcoded to standard UART 5
*/
- .macro addruart,rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- ldreq \rx, =0x40090000
- ldrne \rx, =0xF4090000
+ .macro addruart, rp, rv
+ ldreq \rp, =0x40090000
+ ldrne \rv, =0xF4090000
.endm
#define UART_SHIFT 2
diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c
index bc9a42da2145..7993b096778e 100644
--- a/arch/arm/mach-lpc32xx/phy3250.c
+++ b/arch/arm/mach-lpc32xx/phy3250.c
@@ -172,18 +172,12 @@ static void phy3250_spi_cs_set(u32 control)
}
static struct pl022_config_chip spi0_chip_info = {
- .lbm = LOOPBACK_DISABLED,
.com_mode = INTERRUPT_TRANSFER,
.iface = SSP_INTERFACE_MOTOROLA_SPI,
.hierarchy = SSP_MASTER,
.slave_tx_disable = 0,
- .endian_tx = SSP_TX_LSB,
- .endian_rx = SSP_RX_LSB,
- .data_size = SSP_DATA_BITS_8,
.rx_lev_trig = SSP_RX_4_OR_MORE_ELEM,
.tx_lev_trig = SSP_TX_4_OR_MORE_EMPTY_LOC,
- .clk_phase = SSP_CLK_FIRST_EDGE,
- .clk_pol = SSP_CLK_POL_IDLE_LOW,
.ctrl_len = SSP_BITS_8,
.wait_state = SSP_MWIRE_WAIT_ZERO,
.duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX,
@@ -239,6 +233,7 @@ static int __init phy3250_spi_board_register(void)
.max_speed_hz = 5000000,
.bus_num = 0,
.chip_select = 0,
+ .mode = SPI_MODE_0,
.platform_data = &eeprom,
.controller_data = &spi0_chip_info,
},
@@ -387,8 +382,6 @@ arch_initcall(lpc32xx_display_uid);
MACHINE_START(PHY3250, "Phytec 3250 board with the LPC3250 Microcontroller")
/* Maintainer: Kevin Wells, NXP Semiconductors */
- .phys_io = LPC32XX_UART5_BASE,
- .io_pg_offst = ((IO_ADDRESS(LPC32XX_UART5_BASE))>>18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = lpc32xx_map_io,
.init_irq = lpc32xx_init_irq,
diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig
index 6ab843eaa35b..0711d3b620ad 100644
--- a/arch/arm/mach-mmp/Kconfig
+++ b/arch/arm/mach-mmp/Kconfig
@@ -57,6 +57,13 @@ config MACH_MARVELL_JASPER
PXA910-based development board. Since MMP2 is compatible to
ARMv6 architecture.
+config MACH_TETON_BGA
+ bool "Marvell's PXA168 Teton BGA Development Board"
+ select CPU_PXA168
+ help
+ Say 'Y' here if you want to support the Marvell PXA168-based
+ Teton BGA Development Board.
+
endmenu
config CPU_PXA168
diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile
index 8b66d06739c4..751cdbf733c8 100644
--- a/arch/arm/mach-mmp/Makefile
+++ b/arch/arm/mach-mmp/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_MACH_TAVOREVB) += tavorevb.o
obj-$(CONFIG_MACH_TTC_DKB) += ttc_dkb.o
obj-$(CONFIG_MACH_FLINT) += flint.o
obj-$(CONFIG_MACH_MARVELL_JASPER) += jasper.o
+obj-$(CONFIG_MACH_TETON_BGA) += teton_bga.o
diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c
index 0629394a5fb9..06b5fa853c93 100644
--- a/arch/arm/mach-mmp/aspenite.c
+++ b/arch/arm/mach-mmp/aspenite.c
@@ -16,6 +16,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand.h>
+#include <linux/interrupt.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -23,6 +24,9 @@
#include <mach/mfp-pxa168.h>
#include <mach/pxa168.h>
#include <mach/gpio.h>
+#include <video/pxa168fb.h>
+#include <linux/input.h>
+#include <plat/pxa27x_keypad.h>
#include "common.h"
@@ -66,6 +70,43 @@ static unsigned long common_pin_config[] __initdata = {
GPIO115_I2S_BCLK,
GPIO116_I2S_RXD,
GPIO117_I2S_TXD,
+
+ /* LCD */
+ GPIO56_LCD_FCLK_RD,
+ GPIO57_LCD_LCLK_A0,
+ GPIO58_LCD_PCLK_WR,
+ GPIO59_LCD_DENA_BIAS,
+ GPIO60_LCD_DD0,
+ GPIO61_LCD_DD1,
+ GPIO62_LCD_DD2,
+ GPIO63_LCD_DD3,
+ GPIO64_LCD_DD4,
+ GPIO65_LCD_DD5,
+ GPIO66_LCD_DD6,
+ GPIO67_LCD_DD7,
+ GPIO68_LCD_DD8,
+ GPIO69_LCD_DD9,
+ GPIO70_LCD_DD10,
+ GPIO71_LCD_DD11,
+ GPIO72_LCD_DD12,
+ GPIO73_LCD_DD13,
+ GPIO74_LCD_DD14,
+ GPIO75_LCD_DD15,
+ GPIO76_LCD_DD16,
+ GPIO77_LCD_DD17,
+ GPIO78_LCD_DD18,
+ GPIO79_LCD_DD19,
+ GPIO80_LCD_DD20,
+ GPIO81_LCD_DD21,
+ GPIO82_LCD_DD22,
+ GPIO83_LCD_DD23,
+
+ /* Keypad */
+ GPIO109_KP_MKIN1,
+ GPIO110_KP_MKIN0,
+ GPIO111_KP_MKOUT7,
+ GPIO112_KP_MKOUT6,
+ GPIO121_KP_MKIN4,
};
static struct smc91x_platdata smc91x_info = {
@@ -134,6 +175,51 @@ static struct i2c_board_info aspenite_i2c_info[] __initdata = {
{ I2C_BOARD_INFO("wm8753", 0x1b), },
};
+static struct fb_videomode video_modes[] = {
+ [0] = {
+ .pixclock = 30120,
+ .refresh = 60,
+ .xres = 800,
+ .yres = 480,
+ .hsync_len = 1,
+ .left_margin = 215,
+ .right_margin = 40,
+ .vsync_len = 1,
+ .upper_margin = 34,
+ .lower_margin = 10,
+ .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
+ },
+};
+
+struct pxa168fb_mach_info aspenite_lcd_info = {
+ .id = "Graphic Frame",
+ .modes = video_modes,
+ .num_modes = ARRAY_SIZE(video_modes),
+ .pix_fmt = PIX_FMT_RGB565,
+ .io_pin_allocation_mode = PIN_MODE_DUMB_24,
+ .dumb_mode = DUMB_MODE_RGB888,
+ .active = 1,
+ .panel_rbswap = 0,
+ .invert_pixclock = 0,
+};
+
+static unsigned int aspenite_matrix_key_map[] = {
+ KEY(0, 6, KEY_UP), /* SW 4 */
+ KEY(0, 7, KEY_DOWN), /* SW 5 */
+ KEY(1, 6, KEY_LEFT), /* SW 6 */
+ KEY(1, 7, KEY_RIGHT), /* SW 7 */
+ KEY(4, 6, KEY_ENTER), /* SW 8 */
+ KEY(4, 7, KEY_ESC), /* SW 9 */
+};
+
+static struct pxa27x_keypad_platform_data aspenite_keypad_info __initdata = {
+ .matrix_key_rows = 5,
+ .matrix_key_cols = 8,
+ .matrix_key_map = aspenite_matrix_key_map,
+ .matrix_key_map_size = ARRAY_SIZE(aspenite_matrix_key_map),
+ .debounce_interval = 30,
+};
+
static void __init common_init(void)
{
mfp_config(ARRAY_AND_SIZE(common_pin_config));
@@ -143,24 +229,24 @@ static void __init common_init(void)
pxa168_add_twsi(1, NULL, ARRAY_AND_SIZE(aspenite_i2c_info));
pxa168_add_ssp(1);
pxa168_add_nand(&aspenite_nand_info);
+ pxa168_add_fb(&aspenite_lcd_info);
+ pxa168_add_keypad(&aspenite_keypad_info);
/* off-chip devices */
platform_device_register(&smc91x_device);
}
MACHINE_START(ASPENITE, "PXA168-based Aspenite Development Platform")
- .phys_io = APB_PHYS_BASE,
- .io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc,
.map_io = mmp_map_io,
+ .nr_irqs = IRQ_BOARD_START,
.init_irq = pxa168_init_irq,
.timer = &pxa168_timer,
.init_machine = common_init,
MACHINE_END
MACHINE_START(ZYLONITE2, "PXA168-based Zylonite2 Development Platform")
- .phys_io = APB_PHYS_BASE,
- .io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc,
.map_io = mmp_map_io,
+ .nr_irqs = IRQ_BOARD_START,
.init_irq = pxa168_init_irq,
.timer = &pxa168_timer,
.init_machine = common_init,
diff --git a/arch/arm/mach-mmp/avengers_lite.c b/arch/arm/mach-mmp/avengers_lite.c
index 69bcba11f53f..39f0878d64a0 100644
--- a/arch/arm/mach-mmp/avengers_lite.c
+++ b/arch/arm/mach-mmp/avengers_lite.c
@@ -41,8 +41,6 @@ static void __init avengers_lite_init(void)
}
MACHINE_START(AVENGERS_LITE, "PXA168 Avengers lite Development Platform")
- .phys_io = APB_PHYS_BASE,
- .io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc,
.map_io = mmp_map_io,
.init_irq = pxa168_init_irq,
.timer = &pxa168_timer,
diff --git a/arch/arm/mach-mmp/common.c b/arch/arm/mach-mmp/common.c
index 3b29fa7e9b08..0ec0ca80bb3e 100644
--- a/arch/arm/mach-mmp/common.c
+++ b/arch/arm/mach-mmp/common.c
@@ -10,13 +10,20 @@
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/module.h>
#include <asm/page.h>
#include <asm/mach/map.h>
#include <mach/addr-map.h>
+#include <mach/cputype.h>
#include "common.h"
+#define MMP_CHIPID (AXI_VIRT_BASE + 0x82c00)
+
+unsigned int mmp_chip_id;
+EXPORT_SYMBOL(mmp_chip_id);
+
static struct map_desc standard_io_desc[] __initdata = {
{
.pfn = __phys_to_pfn(APB_PHYS_BASE),
@@ -34,4 +41,7 @@ static struct map_desc standard_io_desc[] __initdata = {
void __init mmp_map_io(void)
{
iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
+
+ /* this is early, initialize mmp_chip_id here */
+ mmp_chip_id = __raw_readl(MMP_CHIPID);
}
diff --git a/arch/arm/mach-mmp/flint.c b/arch/arm/mach-mmp/flint.c
index e4312d238eae..bdeb6db4d49a 100644
--- a/arch/arm/mach-mmp/flint.c
+++ b/arch/arm/mach-mmp/flint.c
@@ -16,6 +16,7 @@
#include <linux/smc91x.h>
#include <linux/io.h>
#include <linux/gpio.h>
+#include <linux/interrupt.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -25,6 +26,8 @@
#include "common.h"
+#define FLINT_NR_IRQS (IRQ_BOARD_START + 48)
+
static unsigned long flint_pin_config[] __initdata = {
/* UART1 */
GPIO45_UART1_RXD,
@@ -113,9 +116,8 @@ static void __init flint_init(void)
}
MACHINE_START(FLINT, "Flint Development Platform")
- .phys_io = APB_PHYS_BASE,
- .io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc,
.map_io = mmp_map_io,
+ .nr_irqs = FLINT_NR_IRQS,
.init_irq = mmp2_init_irq,
.timer = &mmp2_timer,
.init_machine = flint_init,
diff --git a/arch/arm/mach-mmp/include/mach/cputype.h b/arch/arm/mach-mmp/include/mach/cputype.h
index 83b18721d933..f43a68b213f1 100644
--- a/arch/arm/mach-mmp/include/mach/cputype.h
+++ b/arch/arm/mach-mmp/include/mach/cputype.h
@@ -4,36 +4,51 @@
#include <asm/cputype.h>
/*
- * CPU Stepping OLD_ID CPU_ID CHIP_ID
+ * CPU Stepping CPU_ID CHIP_ID
*
- * PXA168 A0 0x41159263 0x56158400 0x00A0A333
- * PXA910 Y0 0x41159262 0x56158000 0x00F0C910
- * MMP2 Z0 0x560f5811
+ * PXA168 S0 0x56158400 0x0000C910
+ * PXA168 A0 0x56158400 0x00A0A168
+ * PXA910 Y1 0x56158400 0x00F2C920
+ * PXA910 A0 0x56158400 0x00F2C910
+ * PXA910 A1 0x56158400 0x00A0C910
+ * PXA920 Y0 0x56158400 0x00F2C920
+ * PXA920 A0 0x56158400 0x00A0C920
+ * PXA920 A1 0x56158400 0x00A1C920
+ * MMP2 Z0 0x560f5811 0x00F00410
+ * MMP2 Z1 0x560f5811 0x00E00410
+ * MMP2 A0 0x560f5811 0x00A0A610
*/
+extern unsigned int mmp_chip_id;
+
#ifdef CONFIG_CPU_PXA168
-# define __cpu_is_pxa168(id) \
- ({ unsigned int _id = ((id) >> 8) & 0xff; _id == 0x84; })
+static inline int cpu_is_pxa168(void)
+{
+ return (((read_cpuid_id() >> 8) & 0xff) == 0x84) &&
+ ((mmp_chip_id & 0xfff) == 0x168);
+}
#else
-# define __cpu_is_pxa168(id) (0)
+#define cpu_is_pxa168() (0)
#endif
+/* cpu_is_pxa910() is shared on both pxa910 and pxa920 */
#ifdef CONFIG_CPU_PXA910
-# define __cpu_is_pxa910(id) \
- ({ unsigned int _id = ((id) >> 8) & 0xff; _id == 0x80; })
+static inline int cpu_is_pxa910(void)
+{
+ return (((read_cpuid_id() >> 8) & 0xff) == 0x84) &&
+ (((mmp_chip_id & 0xfff) == 0x910) ||
+ ((mmp_chip_id & 0xfff) == 0x920));
+}
#else
-# define __cpu_is_pxa910(id) (0)
+#define cpu_is_pxa910() (0)
#endif
#ifdef CONFIG_CPU_MMP2
-# define __cpu_is_mmp2(id) \
- ({ unsigned int _id = ((id) >> 8) & 0xff; _id == 0x58; })
+static inline int cpu_is_mmp2(void)
+{
+ return (((cpu_readid_id() >> 8) & 0xff) == 0x58);
#else
-# define __cpu_is_mmp2(id) (0)
+#define cpu_is_mmp2() (0)
#endif
-#define cpu_is_pxa168() ({ __cpu_is_pxa168(read_cpuid_id()); })
-#define cpu_is_pxa910() ({ __cpu_is_pxa910(read_cpuid_id()); })
-#define cpu_is_mmp2() ({ __cpu_is_mmp2(read_cpuid_id()); })
-
#endif /* __ASM_MACH_CPUTYPE_H */
diff --git a/arch/arm/mach-mmp/include/mach/debug-macro.S b/arch/arm/mach-mmp/include/mach/debug-macro.S
index 76deff238e1c..7e2ebd3efc7c 100644
--- a/arch/arm/mach-mmp/include/mach/debug-macro.S
+++ b/arch/arm/mach-mmp/include/mach/debug-macro.S
@@ -11,12 +11,11 @@
#include <mach/addr-map.h>
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- ldreq \rx, =APB_PHYS_BASE @ physical
- ldrne \rx, =APB_VIRT_BASE @ virtual
- orr \rx, \rx, #0x00017000
+ .macro addruart, rp, rv
+ ldr \rp, =APB_PHYS_BASE @ physical
+ ldr \rv, =APB_VIRT_BASE @ virtual
+ orr \rp, \rp, #0x00017000
+ orr \rv, \rv, #0x00017000
.endm
#define UART_SHIFT 2
diff --git a/arch/arm/mach-mmp/include/mach/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h
index b379cdec4d38..a09d328e2ddd 100644
--- a/arch/arm/mach-mmp/include/mach/irqs.h
+++ b/arch/arm/mach-mmp/include/mach/irqs.h
@@ -222,10 +222,8 @@
#define IRQ_GPIO_NUM 192
#define IRQ_GPIO(x) (IRQ_GPIO_START + (x))
-/* Board IRQ - 64 by default, increase if not enough */
#define IRQ_BOARD_START (IRQ_GPIO_START + IRQ_GPIO_NUM)
-#define IRQ_BOARD_END (IRQ_BOARD_START + 64)
-#define NR_IRQS (IRQ_BOARD_END)
+#define NR_IRQS (IRQ_BOARD_START)
#endif /* __ASM_MACH_IRQS_H */
diff --git a/arch/arm/mach-mmp/include/mach/mfp-pxa168.h b/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
index ded43c455ec3..4621067c7720 100644
--- a/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
+++ b/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
@@ -289,4 +289,11 @@
#define GPIO86_PWM1_OUT MFP_CFG(GPIO86, AF2)
#define GPIO86_PWM2_OUT MFP_CFG(GPIO86, AF3)
+/* Keypad */
+#define GPIO109_KP_MKIN1 MFP_CFG(GPIO109, AF7)
+#define GPIO110_KP_MKIN0 MFP_CFG(GPIO110, AF7)
+#define GPIO111_KP_MKOUT7 MFP_CFG(GPIO111, AF7)
+#define GPIO112_KP_MKOUT6 MFP_CFG(GPIO112, AF7)
+#define GPIO121_KP_MKIN4 MFP_CFG(GPIO121, AF7)
+
#endif /* __ASM_MACH_MFP_PXA168_H */
diff --git a/arch/arm/mach-mmp/include/mach/pxa168.h b/arch/arm/mach-mmp/include/mach/pxa168.h
index 27e1bc758623..1801e4206232 100644
--- a/arch/arm/mach-mmp/include/mach/pxa168.h
+++ b/arch/arm/mach-mmp/include/mach/pxa168.h
@@ -5,11 +5,15 @@ struct sys_timer;
extern struct sys_timer pxa168_timer;
extern void __init pxa168_init_irq(void);
+extern void pxa168_clear_keypad_wakeup(void);
#include <linux/i2c.h>
#include <mach/devices.h>
#include <plat/i2c.h>
#include <plat/pxa3xx_nand.h>
+#include <video/pxa168fb.h>
+#include <plat/pxa27x_keypad.h>
+#include <mach/cputype.h>
extern struct pxa_device_desc pxa168_device_uart1;
extern struct pxa_device_desc pxa168_device_uart2;
@@ -25,6 +29,8 @@ extern struct pxa_device_desc pxa168_device_ssp3;
extern struct pxa_device_desc pxa168_device_ssp4;
extern struct pxa_device_desc pxa168_device_ssp5;
extern struct pxa_device_desc pxa168_device_nand;
+extern struct pxa_device_desc pxa168_device_fb;
+extern struct pxa_device_desc pxa168_device_keypad;
static inline int pxa168_add_uart(int id)
{
@@ -97,4 +103,18 @@ static inline int pxa168_add_nand(struct pxa3xx_nand_platform_data *info)
{
return pxa_register_device(&pxa168_device_nand, info, sizeof(*info));
}
+
+static inline int pxa168_add_fb(struct pxa168fb_mach_info *mi)
+{
+ return pxa_register_device(&pxa168_device_fb, mi, sizeof(*mi));
+}
+
+static inline int pxa168_add_keypad(struct pxa27x_keypad_platform_data *data)
+{
+ if (cpu_is_pxa168())
+ data->clear_wakeup_event = pxa168_clear_keypad_wakeup;
+
+ return pxa_register_device(&pxa168_device_keypad, data, sizeof(*data));
+}
+
#endif /* __ASM_MACH_PXA168_H */
diff --git a/arch/arm/mach-mmp/include/mach/regs-apmu.h b/arch/arm/mach-mmp/include/mach/regs-apmu.h
index 919030514120..ac4702357a6e 100644
--- a/arch/arm/mach-mmp/include/mach/regs-apmu.h
+++ b/arch/arm/mach-mmp/include/mach/regs-apmu.h
@@ -33,4 +33,16 @@
#define APMU_FNRST_DIS (1 << 1)
#define APMU_AXIRST_DIS (1 << 0)
+/* Wake Clear Register */
+#define APMU_WAKE_CLR APMU_REG(0x07c)
+
+#define APMU_PXA168_KP_WAKE_CLR (1 << 7)
+#define APMU_PXA168_CFI_WAKE_CLR (1 << 6)
+#define APMU_PXA168_XD_WAKE_CLR (1 << 5)
+#define APMU_PXA168_MSP_WAKE_CLR (1 << 4)
+#define APMU_PXA168_SD4_WAKE_CLR (1 << 3)
+#define APMU_PXA168_SD3_WAKE_CLR (1 << 2)
+#define APMU_PXA168_SD2_WAKE_CLR (1 << 1)
+#define APMU_PXA168_SD1_WAKE_CLR (1 << 0)
+
#endif /* __ASM_MACH_REGS_APMU_H */
diff --git a/arch/arm/mach-mmp/include/mach/teton_bga.h b/arch/arm/mach-mmp/include/mach/teton_bga.h
new file mode 100644
index 000000000000..61a539b2cc98
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/teton_bga.h
@@ -0,0 +1,27 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/teton_bga.h
+ *
+ * Support for the Marvell PXA168 Teton BGA Development Platform.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+#ifndef __ASM_MACH_TETON_BGA_H
+#define __ASM_MACH_TETON_BGA_H
+
+/* GPIOs */
+#define MMC_PWENA_GPIO 27
+#define USBHPENB_GPIO 55
+#define RTC_INT_GPIO 78
+#define LCD_VBLK_EN_GPIO 79
+#define LCD_DVDD_EN_GPIO 80
+#define RST_WIFI_GPIO 81
+#define CF_PWEN_GPIO 82
+#define USB_OC_GPIO 83
+#define PWM_GPIO 84
+#define USBHPENA_GPIO 85
+#define TS_INT_GPIO 86
+#define CIR_GPIO 108
+
+#endif /* __ASM_MACH_TETON_BGA_H */
diff --git a/arch/arm/mach-mmp/jasper.c b/arch/arm/mach-mmp/jasper.c
index 80c3e7ab1e17..2a684fa50773 100644
--- a/arch/arm/mach-mmp/jasper.c
+++ b/arch/arm/mach-mmp/jasper.c
@@ -18,16 +18,18 @@
#include <linux/regulator/machine.h>
#include <linux/regulator/max8649.h>
#include <linux/mfd/max8925.h>
+#include <linux/interrupt.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/addr-map.h>
#include <mach/mfp-mmp2.h>
#include <mach/mmp2.h>
-#include <mach/irqs.h>
#include "common.h"
+#define JASPER_NR_IRQS (IRQ_BOARD_START + 48)
+
static unsigned long jasper_pin_config[] __initdata = {
/* UART1 */
GPIO29_UART1_RXD,
@@ -134,9 +136,8 @@ static void __init jasper_init(void)
}
MACHINE_START(MARVELL_JASPER, "Jasper Development Platform")
- .phys_io = APB_PHYS_BASE,
- .io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc,
.map_io = mmp_map_io,
+ .nr_irqs = JASPER_NR_IRQS,
.init_irq = mmp2_init_irq,
.timer = &mmp2_timer,
.init_machine = jasper_init,
diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c
index 652ae660634c..72b4e7631583 100644
--- a/arch/arm/mach-mmp/pxa168.c
+++ b/arch/arm/mach-mmp/pxa168.c
@@ -77,8 +77,10 @@ static APBC_CLK(ssp2, PXA168_SSP2, 4, 0);
static APBC_CLK(ssp3, PXA168_SSP3, 4, 0);
static APBC_CLK(ssp4, PXA168_SSP4, 4, 0);
static APBC_CLK(ssp5, PXA168_SSP5, 4, 0);
+static APBC_CLK(keypad, PXA168_KPC, 0, 32000);
static APMU_CLK(nand, NAND, 0x01db, 208000000);
+static APMU_CLK(lcd, LCD, 0x7f, 312000000);
/* device and clock bindings */
static struct clk_lookup pxa168_clkregs[] = {
@@ -96,6 +98,8 @@ static struct clk_lookup pxa168_clkregs[] = {
INIT_CLKREG(&clk_ssp4, "pxa168-ssp.3", NULL),
INIT_CLKREG(&clk_ssp5, "pxa168-ssp.4", NULL),
INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
+ INIT_CLKREG(&clk_lcd, "pxa168-fb", NULL),
+ INIT_CLKREG(&clk_keypad, "pxa27x-keypad", NULL),
};
static int __init pxa168_init(void)
@@ -132,6 +136,16 @@ struct sys_timer pxa168_timer = {
.init = pxa168_timer_init,
};
+void pxa168_clear_keypad_wakeup(void)
+{
+ uint32_t val;
+ uint32_t mask = APMU_PXA168_KP_WAKE_CLR;
+
+ /* wake event clear is needed in order to clear keypad interrupt */
+ val = __raw_readl(APMU_WAKE_CLR);
+ __raw_writel(val | mask, APMU_WAKE_CLR);
+}
+
/* on-chip devices */
PXA168_DEVICE(uart1, "pxa2xx-uart", 0, UART1, 0xd4017000, 0x30, 21, 22);
PXA168_DEVICE(uart2, "pxa2xx-uart", 1, UART2, 0xd4018000, 0x30, 23, 24);
@@ -147,3 +161,5 @@ PXA168_DEVICE(ssp2, "pxa168-ssp", 1, SSP2, 0xd401c000, 0x40, 54, 55);
PXA168_DEVICE(ssp3, "pxa168-ssp", 2, SSP3, 0xd401f000, 0x40, 56, 57);
PXA168_DEVICE(ssp4, "pxa168-ssp", 3, SSP4, 0xd4020000, 0x40, 58, 59);
PXA168_DEVICE(ssp5, "pxa168-ssp", 4, SSP5, 0xd4021000, 0x40, 60, 61);
+PXA168_DEVICE(fb, "pxa168-fb", -1, LCD, 0xd420b000, 0x1c8);
+PXA168_DEVICE(keypad, "pxa27x-keypad", -1, KEYPAD, 0xd4012000, 0x4c);
diff --git a/arch/arm/mach-mmp/tavorevb.c b/arch/arm/mach-mmp/tavorevb.c
index e81db7428215..c296b75c4453 100644
--- a/arch/arm/mach-mmp/tavorevb.c
+++ b/arch/arm/mach-mmp/tavorevb.c
@@ -99,8 +99,6 @@ static void __init tavorevb_init(void)
}
MACHINE_START(TAVOREVB, "PXA910 Evaluation Board (aka TavorEVB)")
- .phys_io = APB_PHYS_BASE,
- .io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc,
.map_io = mmp_map_io,
.init_irq = pxa910_init_irq,
.timer = &pxa910_timer,
diff --git a/arch/arm/mach-mmp/teton_bga.c b/arch/arm/mach-mmp/teton_bga.c
new file mode 100644
index 000000000000..bbe4727b96cc
--- /dev/null
+++ b/arch/arm/mach-mmp/teton_bga.c
@@ -0,0 +1,89 @@
+/*
+ * linux/arch/arm/mach-mmp/teton_bga.c
+ *
+ * Support for the Marvell PXA168 Teton BGA Development Platform.
+ *
+ * Author: Mark F. Brown <mark.brown314@gmail.com>
+ *
+ * This code is based on aspenite.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <plat/pxa27x_keypad.h>
+#include <linux/i2c.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/addr-map.h>
+#include <mach/mfp-pxa168.h>
+#include <mach/pxa168.h>
+#include <mach/teton_bga.h>
+
+#include "common.h"
+
+static unsigned long teton_bga_pin_config[] __initdata = {
+ /* UART1 */
+ GPIO107_UART1_TXD,
+ GPIO108_UART1_RXD,
+
+ /* Keypad */
+ GPIO109_KP_MKIN1,
+ GPIO110_KP_MKIN0,
+ GPIO111_KP_MKOUT7,
+ GPIO112_KP_MKOUT6,
+
+ /* I2C Bus */
+ GPIO105_CI2C_SDA,
+ GPIO106_CI2C_SCL,
+
+ /* RTC */
+ GPIO78_GPIO,
+};
+
+static unsigned int teton_bga_matrix_key_map[] = {
+ KEY(0, 6, KEY_ESC),
+ KEY(0, 7, KEY_ENTER),
+ KEY(1, 6, KEY_LEFT),
+ KEY(1, 7, KEY_RIGHT),
+};
+
+static struct pxa27x_keypad_platform_data teton_bga_keypad_info __initdata = {
+ .matrix_key_rows = 2,
+ .matrix_key_cols = 8,
+ .matrix_key_map = teton_bga_matrix_key_map,
+ .matrix_key_map_size = ARRAY_SIZE(teton_bga_matrix_key_map),
+ .debounce_interval = 30,
+};
+
+static struct i2c_board_info teton_bga_i2c_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("ds1337", 0x68),
+ .irq = gpio_to_irq(RTC_INT_GPIO)
+ },
+};
+
+static void __init teton_bga_init(void)
+{
+ mfp_config(ARRAY_AND_SIZE(teton_bga_pin_config));
+
+ /* on-chip devices */
+ pxa168_add_uart(1);
+ pxa168_add_keypad(&teton_bga_keypad_info);
+ pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(teton_bga_i2c_info));
+}
+
+MACHINE_START(TETON_BGA, "PXA168-based Teton BGA Development Platform")
+ .map_io = mmp_map_io,
+ .nr_irqs = IRQ_BOARD_START,
+ .init_irq = pxa168_init_irq,
+ .timer = &pxa168_timer,
+ .init_machine = teton_bga_init,
+MACHINE_END
diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c
index ee65e05f0cf1..e411039ea59e 100644
--- a/arch/arm/mach-mmp/ttc_dkb.c
+++ b/arch/arm/mach-mmp/ttc_dkb.c
@@ -14,6 +14,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/onenand.h>
+#include <linux/interrupt.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -24,6 +25,8 @@
#include "common.h"
+#define TTCDKB_NR_IRQS (IRQ_BOARD_START + 24)
+
static unsigned long ttc_dkb_pin_config[] __initdata = {
/* UART2 */
GPIO47_UART2_RXD,
@@ -122,9 +125,8 @@ static void __init ttc_dkb_init(void)
}
MACHINE_START(TTC_DKB, "PXA910-based TTC_DKB Development Platform")
- .phys_io = APB_PHYS_BASE,
- .io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc,
.map_io = mmp_map_io,
+ .nr_irqs = TTCDKB_NR_IRQS,
.init_irq = pxa910_init_irq,
.timer = &pxa910_timer,
.init_machine = ttc_dkb_init,
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 47264a76eeb3..3115a29dec4e 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -10,6 +10,8 @@ config ARCH_MSM7X00A
select MSM_SMD
select MSM_SMD_PKG3
select CPU_V6
+ select MSM_PROC_COMM
+ select HAS_MSM_DEBUG_UART_PHYS
config ARCH_MSM7X30
bool "MSM7x30"
@@ -18,6 +20,9 @@ config ARCH_MSM7X30
select MSM_VIC
select CPU_V7
select MSM_REMOTE_SPINLOCK_DEKKERS
+ select MSM_GPIOMUX
+ select MSM_PROC_COMM
+ select HAS_MSM_DEBUG_UART_PHYS
config ARCH_QSD8X50
bool "QSD8X50"
@@ -26,6 +31,19 @@ config ARCH_QSD8X50
select MSM_VIC
select CPU_V7
select MSM_REMOTE_SPINLOCK_LDREX
+ select MSM_GPIOMUX
+ select MSM_PROC_COMM
+ select HAS_MSM_DEBUG_UART_PHYS
+
+config ARCH_MSM8X60
+ bool "MSM8X60"
+ select ARM_GIC
+ select CPU_V7
+ select MSM_V2_TLMM
+ select MSM_GPIOMUX
+ select MACH_MSM8X60_SURF if (!MACH_MSM8X60_RUMI3 && !MACH_MSM8X60_SIM \
+ && !MACH_MSM8X60_FFA)
+
endchoice
config MSM_SOC_REV_A
@@ -36,6 +54,9 @@ config ARCH_MSM_ARM11
config ARCH_MSM_SCORPION
bool
+config HAS_MSM_DEBUG_UART_PHYS
+ bool
+
config MSM_VIC
bool
@@ -74,6 +95,30 @@ config MACH_QSD8X50A_ST1_5
help
Support for the Qualcomm ST1.5.
+config MACH_MSM8X60_RUMI3
+ depends on ARCH_MSM8X60
+ bool "MSM8x60 RUMI3"
+ help
+ Support for the Qualcomm MSM8x60 RUMI3 emulator.
+
+config MACH_MSM8X60_SURF
+ depends on ARCH_MSM8X60
+ bool "MSM8x60 SURF"
+ help
+ Support for the Qualcomm MSM8x60 SURF eval board.
+
+config MACH_MSM8X60_SIM
+ depends on ARCH_MSM8X60
+ bool "MSM8x60 Simulator"
+ help
+ Support for the Qualcomm MSM8x60 simulator.
+
+config MACH_MSM8X60_FFA
+ depends on ARCH_MSM8X60
+ bool "MSM8x60 FFA"
+ help
+ Support for the Qualcomm MSM8x60 FFA eval board.
+
endmenu
config MSM_DEBUG_UART
@@ -82,6 +127,7 @@ config MSM_DEBUG_UART
default 2 if MSM_DEBUG_UART2
default 3 if MSM_DEBUG_UART3
+if HAS_MSM_DEBUG_UART_PHYS
choice
prompt "Debug UART"
@@ -99,11 +145,20 @@ choice
config MSM_DEBUG_UART3
bool "UART3"
endchoice
+endif
config MSM_SMD_PKG3
bool
+config MSM_PROC_COMM
+ bool
+
config MSM_SMD
bool
+config MSM_GPIOMUX
+ bool
+
+config MSM_V2_TLMM
+ bool
endif
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 704610648a25..b5a7b07a44f5 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -1,16 +1,20 @@
-obj-y += proc_comm.o
-obj-y += io.o idle.o timer.o dma.o
-obj-y += vreg.o
+obj-y += io.o idle.o timer.o
+ifndef CONFIG_ARCH_MSM8X60
obj-y += acpuclock-arm11.o
-obj-y += clock.o clock-pcom.o
-obj-y += gpio.o
+obj-y += dma.o
+endif
ifdef CONFIG_MSM_VIC
obj-y += irq-vic.o
else
+ifndef CONFIG_ARCH_MSM8X60
obj-y += irq.o
endif
+endif
+obj-$(CONFIG_ARCH_MSM8X60) += clock-dummy.o iommu.o iommu_dev.o devices-msm8x60-iommu.o
+obj-$(CONFIG_MSM_PROC_COMM) += proc_comm.o clock-pcom.o vreg.o
+obj-$(CONFIG_MSM_PROC_COMM) += clock.o
obj-$(CONFIG_ARCH_QSD8X50) += sirc.o
obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o
obj-$(CONFIG_MSM_SMD) += last_radio_log.o
@@ -19,4 +23,11 @@ obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o d
obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o
obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o
obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o
+obj-$(CONFIG_ARCH_MSM8X60) += board-msm8x60.o
+obj-$(CONFIG_ARCH_MSM7X30) += gpiomux-7x30.o gpiomux-v1.o gpiomux.o
+obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o gpiomux-v1.o gpiomux.o
+obj-$(CONFIG_ARCH_MSM8X60) += gpiomux-8x60.o gpiomux-v2.o gpiomux.o
+ifndef CONFIG_MSM_V2_TLMM
+obj-y += gpio.o
+endif
diff --git a/arch/arm/mach-msm/board-halibut.c b/arch/arm/mach-msm/board-halibut.c
index 7bd72e8f127e..59edecbe126c 100644
--- a/arch/arm/mach-msm/board-halibut.c
+++ b/arch/arm/mach-msm/board-halibut.c
@@ -95,8 +95,6 @@ static void __init halibut_map_io(void)
MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)")
#ifdef CONFIG_MSM_DEBUG_UART
- .phys_io = MSM_DEBUG_UART_PHYS,
- .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
#endif
.boot_params = 0x10000100,
.fixup = halibut_fixup,
diff --git a/arch/arm/mach-msm/board-mahimahi.c b/arch/arm/mach-msm/board-mahimahi.c
index bcbefdfe7b5e..ef3ebf2f763b 100644
--- a/arch/arm/mach-msm/board-mahimahi.c
+++ b/arch/arm/mach-msm/board-mahimahi.c
@@ -75,8 +75,6 @@ extern struct sys_timer msm_timer;
MACHINE_START(MAHIMAHI, "mahimahi")
#ifdef CONFIG_MSM_DEBUG_UART
- .phys_io = MSM_DEBUG_UART_PHYS,
- .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
#endif
.boot_params = 0x20000100,
.fixup = mahimahi_fixup,
diff --git a/arch/arm/mach-msm/board-msm7x27.c b/arch/arm/mach-msm/board-msm7x27.c
index db9381b85bf0..e7a76eff57d9 100644
--- a/arch/arm/mach-msm/board-msm7x27.c
+++ b/arch/arm/mach-msm/board-msm7x27.c
@@ -131,8 +131,6 @@ static void __init msm7x2x_map_io(void)
MACHINE_START(MSM7X27_SURF, "QCT MSM7x27 SURF")
#ifdef CONFIG_MSM_DEBUG_UART
- .phys_io = MSM_DEBUG_UART_PHYS,
- .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
#endif
.boot_params = PHYS_OFFSET + 0x100,
.map_io = msm7x2x_map_io,
@@ -143,8 +141,6 @@ MACHINE_END
MACHINE_START(MSM7X27_FFA, "QCT MSM7x27 FFA")
#ifdef CONFIG_MSM_DEBUG_UART
- .phys_io = MSM_DEBUG_UART_PHYS,
- .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
#endif
.boot_params = PHYS_OFFSET + 0x100,
.map_io = msm7x2x_map_io,
@@ -155,8 +151,6 @@ MACHINE_END
MACHINE_START(MSM7X25_SURF, "QCT MSM7x25 SURF")
#ifdef CONFIG_MSM_DEBUG_UART
- .phys_io = MSM_DEBUG_UART_PHYS,
- .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
#endif
.boot_params = PHYS_OFFSET + 0x100,
.map_io = msm7x2x_map_io,
@@ -167,8 +161,6 @@ MACHINE_END
MACHINE_START(MSM7X25_FFA, "QCT MSM7x25 FFA")
#ifdef CONFIG_MSM_DEBUG_UART
- .phys_io = MSM_DEBUG_UART_PHYS,
- .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
#endif
.boot_params = PHYS_OFFSET + 0x100,
.map_io = msm7x2x_map_io,
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
index e32981928c77..05241df3f9b6 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -39,27 +39,11 @@
extern struct sys_timer msm_timer;
-#ifdef CONFIG_SERIAL_MSM_CONSOLE
-static struct msm_gpio uart2_config_data[] = {
- { GPIO_CFG(49, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_RFR"},
- { GPIO_CFG(50, 2, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_CTS"},
- { GPIO_CFG(51, 2, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_Rx"},
- { GPIO_CFG(52, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_Tx"},
-};
-
-static void msm7x30_init_uart2(void)
-{
- msm_gpios_request_enable(uart2_config_data,
- ARRAY_SIZE(uart2_config_data));
-
-}
-#endif
-
static struct platform_device *devices[] __initdata = {
#if defined(CONFIG_SERIAL_MSM) || defined(CONFIG_MSM_SERIAL_DEBUGGER)
&msm_device_uart2,
#endif
-
+ &msm_device_smd,
};
static void __init msm7x30_init_irq(void)
@@ -70,10 +54,6 @@ static void __init msm7x30_init_irq(void)
static void __init msm7x30_init(void)
{
platform_add_devices(devices, ARRAY_SIZE(devices));
-#ifdef CONFIG_SERIAL_MSM_CONSOLE
- msm7x30_init_uart2();
-#endif
-
}
static void __init msm7x30_map_io(void)
@@ -84,8 +64,6 @@ static void __init msm7x30_map_io(void)
MACHINE_START(MSM7X30_SURF, "QCT MSM7X30 SURF")
#ifdef CONFIG_MSM_DEBUG_UART
- .phys_io = MSM_DEBUG_UART_PHYS,
- .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
#endif
.boot_params = PHYS_OFFSET + 0x100,
.map_io = msm7x30_map_io,
@@ -96,8 +74,6 @@ MACHINE_END
MACHINE_START(MSM7X30_FFA, "QCT MSM7X30 FFA")
#ifdef CONFIG_MSM_DEBUG_UART
- .phys_io = MSM_DEBUG_UART_PHYS,
- .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
#endif
.boot_params = PHYS_OFFSET + 0x100,
.map_io = msm7x30_map_io,
@@ -108,8 +84,6 @@ MACHINE_END
MACHINE_START(MSM7X30_FLUID, "QCT MSM7X30 FLUID")
#ifdef CONFIG_MSM_DEBUG_UART
- .phys_io = MSM_DEBUG_UART_PHYS,
- .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
#endif
.boot_params = PHYS_OFFSET + 0x100,
.map_io = msm7x30_map_io,
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
new file mode 100644
index 000000000000..7486a681cc71
--- /dev/null
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -0,0 +1,100 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/hardware/gic.h>
+
+#include <mach/board.h>
+#include <mach/msm_iomap.h>
+
+void __iomem *gic_cpu_base_addr;
+
+unsigned long clk_get_max_axi_khz(void)
+{
+ return 0;
+}
+
+static void __init msm8x60_map_io(void)
+{
+ msm_map_msm8x60_io();
+}
+
+static void __init msm8x60_init_irq(void)
+{
+ unsigned int i;
+
+ gic_dist_init(0, MSM_QGIC_DIST_BASE, GIC_PPI_START);
+ gic_cpu_base_addr = (void *)MSM_QGIC_CPU_BASE;
+ gic_cpu_init(0, MSM_QGIC_CPU_BASE);
+
+ /* Edge trigger PPIs except AVS_SVICINT and AVS_SVICINTSWDONE */
+ writel(0xFFFFD7FF, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4);
+
+ /* RUMI does not adhere to GIC spec by enabling STIs by default.
+ * Enable/clear is supposed to be RO for STIs, but is RW on RUMI.
+ */
+ if (!machine_is_msm8x60_sim())
+ writel(0x0000FFFF, MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET);
+
+ /* FIXME: Not installing AVS_SVICINT and AVS_SVICINTSWDONE yet
+ * as they are configured as level, which does not play nice with
+ * handle_percpu_irq.
+ */
+ for (i = GIC_PPI_START; i < GIC_SPI_START; i++) {
+ if (i != AVS_SVICINT && i != AVS_SVICINTSWDONE)
+ set_irq_handler(i, handle_percpu_irq);
+ }
+}
+
+static void __init msm8x60_init(void)
+{
+}
+
+MACHINE_START(MSM8X60_RUMI3, "QCT MSM8X60 RUMI3")
+ .map_io = msm8x60_map_io,
+ .init_irq = msm8x60_init_irq,
+ .init_machine = msm8x60_init,
+ .timer = &msm_timer,
+MACHINE_END
+
+MACHINE_START(MSM8X60_SURF, "QCT MSM8X60 SURF")
+ .map_io = msm8x60_map_io,
+ .init_irq = msm8x60_init_irq,
+ .init_machine = msm8x60_init,
+ .timer = &msm_timer,
+MACHINE_END
+
+MACHINE_START(MSM8X60_SIM, "QCT MSM8X60 SIMULATOR")
+ .map_io = msm8x60_map_io,
+ .init_irq = msm8x60_init_irq,
+ .init_machine = msm8x60_init,
+ .timer = &msm_timer,
+MACHINE_END
+
+MACHINE_START(MSM8X60_FFA, "QCT MSM8X60 FFA")
+ .map_io = msm8x60_map_io,
+ .init_irq = msm8x60_init_irq,
+ .init_machine = msm8x60_init,
+ .timer = &msm_timer,
+MACHINE_END
diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c
index e3cc80792d6c..ed2af4ad97ed 100644
--- a/arch/arm/mach-msm/board-qsd8x50.c
+++ b/arch/arm/mach-msm/board-qsd8x50.c
@@ -35,20 +35,49 @@
extern struct sys_timer msm_timer;
-static struct msm_gpio uart3_config_data[] = {
- { GPIO_CFG(86, 1, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_Rx"},
- { GPIO_CFG(87, 1, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_Tx"},
+static const resource_size_t qsd8x50_surf_smc91x_base __initdata = 0x70000300;
+static const unsigned qsd8x50_surf_smc91x_gpio __initdata = 156;
+
+/* Leave smc91x resources empty here, as we'll fill them in
+ * at run-time: they vary from board to board, and the true
+ * configuration won't be known until boot.
+ */
+static struct resource smc91x_resources[] __initdata = {
+ [0] = {
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .flags = IORESOURCE_IRQ,
+ },
};
-static struct platform_device *devices[] __initdata = {
- &msm_device_uart3,
+static struct platform_device smc91x_device __initdata = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
};
-static void msm8x50_init_uart3(void)
+static int __init msm_init_smc91x(void)
{
- msm_gpios_request_enable(uart3_config_data,
- ARRAY_SIZE(uart3_config_data));
+ if (machine_is_qsd8x50_surf()) {
+ smc91x_resources[0].start = qsd8x50_surf_smc91x_base;
+ smc91x_resources[0].end = qsd8x50_surf_smc91x_base + 0xff;
+ smc91x_resources[1].start =
+ gpio_to_irq(qsd8x50_surf_smc91x_gpio);
+ smc91x_resources[1].end =
+ gpio_to_irq(qsd8x50_surf_smc91x_gpio);
+ platform_device_register(&smc91x_device);
+ }
+
+ return 0;
}
+module_init(msm_init_smc91x);
+
+static struct platform_device *devices[] __initdata = {
+ &msm_device_uart3,
+ &msm_device_smd,
+};
static void __init qsd8x50_map_io(void)
{
@@ -64,14 +93,11 @@ static void __init qsd8x50_init_irq(void)
static void __init qsd8x50_init(void)
{
- msm8x50_init_uart3();
platform_add_devices(devices, ARRAY_SIZE(devices));
}
MACHINE_START(QSD8X50_SURF, "QCT QSD8X50 SURF")
#ifdef CONFIG_MSM_DEBUG_UART
- .phys_io = MSM_DEBUG_UART_PHYS,
- .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
#endif
.boot_params = PHYS_OFFSET + 0x100,
.map_io = qsd8x50_map_io,
@@ -82,8 +108,6 @@ MACHINE_END
MACHINE_START(QSD8X50A_ST1_5, "QCT QSD8X50A ST1.5")
#ifdef CONFIG_MSM_DEBUG_UART
- .phys_io = MSM_DEBUG_UART_PHYS,
- .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
#endif
.boot_params = PHYS_OFFSET + 0x100,
.map_io = qsd8x50_map_io,
diff --git a/arch/arm/mach-msm/board-sapphire.c b/arch/arm/mach-msm/board-sapphire.c
index 2bc1b9d5623e..8919ffb17196 100644
--- a/arch/arm/mach-msm/board-sapphire.c
+++ b/arch/arm/mach-msm/board-sapphire.c
@@ -106,8 +106,6 @@ static void __init sapphire_map_io(void)
MACHINE_START(SAPPHIRE, "sapphire")
/* Maintainer: Brian Swetland <swetland@google.com> */
#ifdef CONFIG_MSM_DEBUG_UART
- .phys_io = MSM_DEBUG_UART_PHYS,
- .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
#endif
.boot_params = PHYS_OFFSET + 0x100,
.fixup = sapphire_fixup,
diff --git a/arch/arm/mach-msm/board-trout.c b/arch/arm/mach-msm/board-trout.c
index 469e0be3499d..73f146066542 100644
--- a/arch/arm/mach-msm/board-trout.c
+++ b/arch/arm/mach-msm/board-trout.c
@@ -93,8 +93,6 @@ static void __init trout_map_io(void)
MACHINE_START(TROUT, "HTC Dream")
#ifdef CONFIG_MSM_DEBUG_UART
- .phys_io = MSM_DEBUG_UART_PHYS,
- .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
#endif
.boot_params = 0x10000100,
.fixup = trout_fixup,
diff --git a/arch/arm/mach-msm/clock-dummy.c b/arch/arm/mach-msm/clock-dummy.c
new file mode 100644
index 000000000000..1250d22082ee
--- /dev/null
+++ b/arch/arm/mach-msm/clock-dummy.c
@@ -0,0 +1,54 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/module.h>
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+ return ERR_PTR(-ENOENT);
+}
+EXPORT_SYMBOL(clk_get);
+
+int clk_enable(struct clk *clk)
+{
+ return -ENOENT;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ return 0;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ return -ENOENT;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+void clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_put);
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c
index b449e8ad2904..7fcf2e3b7698 100644
--- a/arch/arm/mach-msm/devices-msm7x30.c
+++ b/arch/arm/mach-msm/devices-msm7x30.c
@@ -51,6 +51,11 @@ struct platform_device msm_device_uart2 = {
.resource = resources_uart2,
};
+struct platform_device msm_device_smd = {
+ .name = "msm_smd",
+ .id = -1,
+};
+
struct clk msm_clocks_7x30[] = {
CLK_PCOM("adm_clk", ADM_CLK, NULL, 0),
CLK_PCOM("adsp_clk", ADSP_CLK, NULL, 0),
diff --git a/arch/arm/mach-msm/devices-msm8x60-iommu.c b/arch/arm/mach-msm/devices-msm8x60-iommu.c
new file mode 100644
index 000000000000..89b9d4437e92
--- /dev/null
+++ b/arch/arm/mach-msm/devices-msm8x60-iommu.c
@@ -0,0 +1,883 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/bootmem.h>
+
+#include <mach/msm_iomap-8x60.h>
+#include <mach/irqs-8x60.h>
+#include <mach/iommu.h>
+
+static struct resource msm_iommu_jpegd_resources[] = {
+ {
+ .start = MSM_IOMMU_JPEGD_PHYS,
+ .end = MSM_IOMMU_JPEGD_PHYS + MSM_IOMMU_JPEGD_SIZE - 1,
+ .name = "physbase",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "nonsecure_irq",
+ .start = SMMU_JPEGD_CB_SC_NON_SECURE_IRQ,
+ .end = SMMU_JPEGD_CB_SC_NON_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "secure_irq",
+ .start = SMMU_JPEGD_CB_SC_SECURE_IRQ,
+ .end = SMMU_JPEGD_CB_SC_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource msm_iommu_vpe_resources[] = {
+ {
+ .start = MSM_IOMMU_VPE_PHYS,
+ .end = MSM_IOMMU_VPE_PHYS + MSM_IOMMU_VPE_SIZE - 1,
+ .name = "physbase",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "nonsecure_irq",
+ .start = SMMU_VPE_CB_SC_NON_SECURE_IRQ,
+ .end = SMMU_VPE_CB_SC_NON_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "secure_irq",
+ .start = SMMU_VPE_CB_SC_SECURE_IRQ,
+ .end = SMMU_VPE_CB_SC_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource msm_iommu_mdp0_resources[] = {
+ {
+ .start = MSM_IOMMU_MDP0_PHYS,
+ .end = MSM_IOMMU_MDP0_PHYS + MSM_IOMMU_MDP0_SIZE - 1,
+ .name = "physbase",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "nonsecure_irq",
+ .start = SMMU_MDP0_CB_SC_NON_SECURE_IRQ,
+ .end = SMMU_MDP0_CB_SC_NON_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "secure_irq",
+ .start = SMMU_MDP0_CB_SC_SECURE_IRQ,
+ .end = SMMU_MDP0_CB_SC_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource msm_iommu_mdp1_resources[] = {
+ {
+ .start = MSM_IOMMU_MDP1_PHYS,
+ .end = MSM_IOMMU_MDP1_PHYS + MSM_IOMMU_MDP1_SIZE - 1,
+ .name = "physbase",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "nonsecure_irq",
+ .start = SMMU_MDP1_CB_SC_NON_SECURE_IRQ,
+ .end = SMMU_MDP1_CB_SC_NON_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "secure_irq",
+ .start = SMMU_MDP1_CB_SC_SECURE_IRQ,
+ .end = SMMU_MDP1_CB_SC_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource msm_iommu_rot_resources[] = {
+ {
+ .start = MSM_IOMMU_ROT_PHYS,
+ .end = MSM_IOMMU_ROT_PHYS + MSM_IOMMU_ROT_SIZE - 1,
+ .name = "physbase",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "nonsecure_irq",
+ .start = SMMU_ROT_CB_SC_NON_SECURE_IRQ,
+ .end = SMMU_ROT_CB_SC_NON_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "secure_irq",
+ .start = SMMU_ROT_CB_SC_SECURE_IRQ,
+ .end = SMMU_ROT_CB_SC_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource msm_iommu_ijpeg_resources[] = {
+ {
+ .start = MSM_IOMMU_IJPEG_PHYS,
+ .end = MSM_IOMMU_IJPEG_PHYS + MSM_IOMMU_IJPEG_SIZE - 1,
+ .name = "physbase",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "nonsecure_irq",
+ .start = SMMU_IJPEG_CB_SC_NON_SECURE_IRQ,
+ .end = SMMU_IJPEG_CB_SC_NON_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "secure_irq",
+ .start = SMMU_IJPEG_CB_SC_SECURE_IRQ,
+ .end = SMMU_IJPEG_CB_SC_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource msm_iommu_vfe_resources[] = {
+ {
+ .start = MSM_IOMMU_VFE_PHYS,
+ .end = MSM_IOMMU_VFE_PHYS + MSM_IOMMU_VFE_SIZE - 1,
+ .name = "physbase",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "nonsecure_irq",
+ .start = SMMU_VFE_CB_SC_NON_SECURE_IRQ,
+ .end = SMMU_VFE_CB_SC_NON_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "secure_irq",
+ .start = SMMU_VFE_CB_SC_SECURE_IRQ,
+ .end = SMMU_VFE_CB_SC_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource msm_iommu_vcodec_a_resources[] = {
+ {
+ .start = MSM_IOMMU_VCODEC_A_PHYS,
+ .end = MSM_IOMMU_VCODEC_A_PHYS + MSM_IOMMU_VCODEC_A_SIZE - 1,
+ .name = "physbase",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "nonsecure_irq",
+ .start = SMMU_VCODEC_A_CB_SC_NON_SECURE_IRQ,
+ .end = SMMU_VCODEC_A_CB_SC_NON_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "secure_irq",
+ .start = SMMU_VCODEC_A_CB_SC_SECURE_IRQ,
+ .end = SMMU_VCODEC_A_CB_SC_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource msm_iommu_vcodec_b_resources[] = {
+ {
+ .start = MSM_IOMMU_VCODEC_B_PHYS,
+ .end = MSM_IOMMU_VCODEC_B_PHYS + MSM_IOMMU_VCODEC_B_SIZE - 1,
+ .name = "physbase",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "nonsecure_irq",
+ .start = SMMU_VCODEC_B_CB_SC_NON_SECURE_IRQ,
+ .end = SMMU_VCODEC_B_CB_SC_NON_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "secure_irq",
+ .start = SMMU_VCODEC_B_CB_SC_SECURE_IRQ,
+ .end = SMMU_VCODEC_B_CB_SC_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource msm_iommu_gfx3d_resources[] = {
+ {
+ .start = MSM_IOMMU_GFX3D_PHYS,
+ .end = MSM_IOMMU_GFX3D_PHYS + MSM_IOMMU_GFX3D_SIZE - 1,
+ .name = "physbase",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "nonsecure_irq",
+ .start = SMMU_GFX3D_CB_SC_NON_SECURE_IRQ,
+ .end = SMMU_GFX3D_CB_SC_NON_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "secure_irq",
+ .start = SMMU_GFX3D_CB_SC_SECURE_IRQ,
+ .end = SMMU_GFX3D_CB_SC_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource msm_iommu_gfx2d0_resources[] = {
+ {
+ .start = MSM_IOMMU_GFX2D0_PHYS,
+ .end = MSM_IOMMU_GFX2D0_PHYS + MSM_IOMMU_GFX2D0_SIZE - 1,
+ .name = "physbase",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "nonsecure_irq",
+ .start = SMMU_GFX2D0_CB_SC_NON_SECURE_IRQ,
+ .end = SMMU_GFX2D0_CB_SC_NON_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "secure_irq",
+ .start = SMMU_GFX2D0_CB_SC_SECURE_IRQ,
+ .end = SMMU_GFX2D0_CB_SC_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device msm_root_iommu_dev = {
+ .name = "msm_iommu",
+ .id = -1,
+};
+
+static struct msm_iommu_dev jpegd_smmu = {
+ .name = "jpegd",
+ .clk_rate = -1
+};
+
+static struct msm_iommu_dev vpe_smmu = {
+ .name = "vpe"
+};
+
+static struct msm_iommu_dev mdp0_smmu = {
+ .name = "mdp0"
+};
+
+static struct msm_iommu_dev mdp1_smmu = {
+ .name = "mdp1"
+};
+
+static struct msm_iommu_dev rot_smmu = {
+ .name = "rot"
+};
+
+static struct msm_iommu_dev ijpeg_smmu = {
+ .name = "ijpeg"
+};
+
+static struct msm_iommu_dev vfe_smmu = {
+ .name = "vfe",
+ .clk_rate = -1
+};
+
+static struct msm_iommu_dev vcodec_a_smmu = {
+ .name = "vcodec_a"
+};
+
+static struct msm_iommu_dev vcodec_b_smmu = {
+ .name = "vcodec_b"
+};
+
+static struct msm_iommu_dev gfx3d_smmu = {
+ .name = "gfx3d",
+ .clk_rate = 27000000
+};
+
+static struct msm_iommu_dev gfx2d0_smmu = {
+ .name = "gfx2d0",
+ .clk_rate = 27000000
+};
+
+static struct platform_device msm_device_smmu_jpegd = {
+ .name = "msm_iommu",
+ .id = 0,
+ .dev = {
+ .parent = &msm_root_iommu_dev.dev,
+ },
+ .num_resources = ARRAY_SIZE(msm_iommu_jpegd_resources),
+ .resource = msm_iommu_jpegd_resources,
+};
+
+static struct platform_device msm_device_smmu_vpe = {
+ .name = "msm_iommu",
+ .id = 1,
+ .dev = {
+ .parent = &msm_root_iommu_dev.dev,
+ },
+ .num_resources = ARRAY_SIZE(msm_iommu_vpe_resources),
+ .resource = msm_iommu_vpe_resources,
+};
+
+static struct platform_device msm_device_smmu_mdp0 = {
+ .name = "msm_iommu",
+ .id = 2,
+ .dev = {
+ .parent = &msm_root_iommu_dev.dev,
+ },
+ .num_resources = ARRAY_SIZE(msm_iommu_mdp0_resources),
+ .resource = msm_iommu_mdp0_resources,
+};
+
+static struct platform_device msm_device_smmu_mdp1 = {
+ .name = "msm_iommu",
+ .id = 3,
+ .dev = {
+ .parent = &msm_root_iommu_dev.dev,
+ },
+ .num_resources = ARRAY_SIZE(msm_iommu_mdp1_resources),
+ .resource = msm_iommu_mdp1_resources,
+};
+
+static struct platform_device msm_device_smmu_rot = {
+ .name = "msm_iommu",
+ .id = 4,
+ .dev = {
+ .parent = &msm_root_iommu_dev.dev,
+ },
+ .num_resources = ARRAY_SIZE(msm_iommu_rot_resources),
+ .resource = msm_iommu_rot_resources,
+};
+
+static struct platform_device msm_device_smmu_ijpeg = {
+ .name = "msm_iommu",
+ .id = 5,
+ .dev = {
+ .parent = &msm_root_iommu_dev.dev,
+ },
+ .num_resources = ARRAY_SIZE(msm_iommu_ijpeg_resources),
+ .resource = msm_iommu_ijpeg_resources,
+};
+
+static struct platform_device msm_device_smmu_vfe = {
+ .name = "msm_iommu",
+ .id = 6,
+ .dev = {
+ .parent = &msm_root_iommu_dev.dev,
+ },
+ .num_resources = ARRAY_SIZE(msm_iommu_vfe_resources),
+ .resource = msm_iommu_vfe_resources,
+};
+
+static struct platform_device msm_device_smmu_vcodec_a = {
+ .name = "msm_iommu",
+ .id = 7,
+ .dev = {
+ .parent = &msm_root_iommu_dev.dev,
+ },
+ .num_resources = ARRAY_SIZE(msm_iommu_vcodec_a_resources),
+ .resource = msm_iommu_vcodec_a_resources,
+};
+
+static struct platform_device msm_device_smmu_vcodec_b = {
+ .name = "msm_iommu",
+ .id = 8,
+ .dev = {
+ .parent = &msm_root_iommu_dev.dev,
+ },
+ .num_resources = ARRAY_SIZE(msm_iommu_vcodec_b_resources),
+ .resource = msm_iommu_vcodec_b_resources,
+};
+
+static struct platform_device msm_device_smmu_gfx3d = {
+ .name = "msm_iommu",
+ .id = 9,
+ .dev = {
+ .parent = &msm_root_iommu_dev.dev,
+ },
+ .num_resources = ARRAY_SIZE(msm_iommu_gfx3d_resources),
+ .resource = msm_iommu_gfx3d_resources,
+};
+
+static struct platform_device msm_device_smmu_gfx2d0 = {
+ .name = "msm_iommu",
+ .id = 10,
+ .dev = {
+ .parent = &msm_root_iommu_dev.dev,
+ },
+ .num_resources = ARRAY_SIZE(msm_iommu_gfx2d0_resources),
+ .resource = msm_iommu_gfx2d0_resources,
+};
+
+static struct msm_iommu_ctx_dev jpegd_src_ctx = {
+ .name = "jpegd_src",
+ .num = 0,
+ .mids = {0, -1}
+};
+
+static struct msm_iommu_ctx_dev jpegd_dst_ctx = {
+ .name = "jpegd_dst",
+ .num = 1,
+ .mids = {1, -1}
+};
+
+static struct msm_iommu_ctx_dev vpe_src_ctx = {
+ .name = "vpe_src",
+ .num = 0,
+ .mids = {0, -1}
+};
+
+static struct msm_iommu_ctx_dev vpe_dst_ctx = {
+ .name = "vpe_dst",
+ .num = 1,
+ .mids = {1, -1}
+};
+
+static struct msm_iommu_ctx_dev mdp_vg1_ctx = {
+ .name = "mdp_vg1",
+ .num = 0,
+ .mids = {0, 2, -1}
+};
+
+static struct msm_iommu_ctx_dev mdp_rgb1_ctx = {
+ .name = "mdp_rgb1",
+ .num = 1,
+ .mids = {1, 3, 4, 5, 6, 7, 8, 9, 10, -1}
+};
+
+static struct msm_iommu_ctx_dev mdp_vg2_ctx = {
+ .name = "mdp_vg2",
+ .num = 0,
+ .mids = {0, 2, -1}
+};
+
+static struct msm_iommu_ctx_dev mdp_rgb2_ctx = {
+ .name = "mdp_rgb2",
+ .num = 1,
+ .mids = {1, 3, 4, 5, 6, 7, 8, 9, 10, -1}
+};
+
+static struct msm_iommu_ctx_dev rot_src_ctx = {
+ .name = "rot_src",
+ .num = 0,
+ .mids = {0, -1}
+};
+
+static struct msm_iommu_ctx_dev rot_dst_ctx = {
+ .name = "rot_dst",
+ .num = 1,
+ .mids = {1, -1}
+};
+
+static struct msm_iommu_ctx_dev ijpeg_src_ctx = {
+ .name = "ijpeg_src",
+ .num = 0,
+ .mids = {0, -1}
+};
+
+static struct msm_iommu_ctx_dev ijpeg_dst_ctx = {
+ .name = "ijpeg_dst",
+ .num = 1,
+ .mids = {1, -1}
+};
+
+static struct msm_iommu_ctx_dev vfe_imgwr_ctx = {
+ .name = "vfe_imgwr",
+ .num = 0,
+ .mids = {2, 3, 4, 5, 6, 7, 8, -1}
+};
+
+static struct msm_iommu_ctx_dev vfe_misc_ctx = {
+ .name = "vfe_misc",
+ .num = 1,
+ .mids = {0, 1, 9, -1}
+};
+
+static struct msm_iommu_ctx_dev vcodec_a_stream_ctx = {
+ .name = "vcodec_a_stream",
+ .num = 0,
+ .mids = {2, 5, -1}
+};
+
+static struct msm_iommu_ctx_dev vcodec_a_mm1_ctx = {
+ .name = "vcodec_a_mm1",
+ .num = 1,
+ .mids = {0, 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1}
+};
+
+static struct msm_iommu_ctx_dev vcodec_b_mm2_ctx = {
+ .name = "vcodec_b_mm2",
+ .num = 0,
+ .mids = {0, 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1}
+};
+
+static struct msm_iommu_ctx_dev gfx3d_rbpa_ctx = {
+ .name = "gfx3d_rbpa",
+ .num = 0,
+ .mids = {-1}
+};
+
+static struct msm_iommu_ctx_dev gfx3d_cpvgttc_ctx = {
+ .name = "gfx3d_cpvgttc",
+ .num = 1,
+ .mids = {0, 1, 2, 3, 4, 5, 6, 7, -1}
+};
+
+static struct msm_iommu_ctx_dev gfx3d_smmu_ctx = {
+ .name = "gfx3d_smmu",
+ .num = 2,
+ .mids = {8, 9, 10, 11, 12, -1}
+};
+
+static struct msm_iommu_ctx_dev gfx2d0_pixv1_ctx = {
+ .name = "gfx2d0_pixv1_smmu",
+ .num = 0,
+ .mids = {0, 3, 4, -1}
+};
+
+static struct msm_iommu_ctx_dev gfx2d0_texv3_ctx = {
+ .name = "gfx2d0_texv3_smmu",
+ .num = 1,
+ .mids = {1, 6, 7, -1}
+};
+
+static struct platform_device msm_device_jpegd_src_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 0,
+ .dev = {
+ .parent = &msm_device_smmu_jpegd.dev,
+ },
+};
+
+static struct platform_device msm_device_jpegd_dst_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 1,
+ .dev = {
+ .parent = &msm_device_smmu_jpegd.dev,
+ },
+};
+
+static struct platform_device msm_device_vpe_src_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 2,
+ .dev = {
+ .parent = &msm_device_smmu_vpe.dev,
+ },
+};
+
+static struct platform_device msm_device_vpe_dst_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 3,
+ .dev = {
+ .parent = &msm_device_smmu_vpe.dev,
+ },
+};
+
+static struct platform_device msm_device_mdp_vg1_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 4,
+ .dev = {
+ .parent = &msm_device_smmu_mdp0.dev,
+ },
+};
+
+static struct platform_device msm_device_mdp_rgb1_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 5,
+ .dev = {
+ .parent = &msm_device_smmu_mdp0.dev,
+ },
+};
+
+static struct platform_device msm_device_mdp_vg2_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 6,
+ .dev = {
+ .parent = &msm_device_smmu_mdp1.dev,
+ },
+};
+
+static struct platform_device msm_device_mdp_rgb2_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 7,
+ .dev = {
+ .parent = &msm_device_smmu_mdp1.dev,
+ },
+};
+
+static struct platform_device msm_device_rot_src_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 8,
+ .dev = {
+ .parent = &msm_device_smmu_rot.dev,
+ },
+};
+
+static struct platform_device msm_device_rot_dst_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 9,
+ .dev = {
+ .parent = &msm_device_smmu_rot.dev,
+ },
+};
+
+static struct platform_device msm_device_ijpeg_src_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 10,
+ .dev = {
+ .parent = &msm_device_smmu_ijpeg.dev,
+ },
+};
+
+static struct platform_device msm_device_ijpeg_dst_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 11,
+ .dev = {
+ .parent = &msm_device_smmu_ijpeg.dev,
+ },
+};
+
+static struct platform_device msm_device_vfe_imgwr_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 12,
+ .dev = {
+ .parent = &msm_device_smmu_vfe.dev,
+ },
+};
+
+static struct platform_device msm_device_vfe_misc_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 13,
+ .dev = {
+ .parent = &msm_device_smmu_vfe.dev,
+ },
+};
+
+static struct platform_device msm_device_vcodec_a_stream_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 14,
+ .dev = {
+ .parent = &msm_device_smmu_vcodec_a.dev,
+ },
+};
+
+static struct platform_device msm_device_vcodec_a_mm1_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 15,
+ .dev = {
+ .parent = &msm_device_smmu_vcodec_a.dev,
+ },
+};
+
+static struct platform_device msm_device_vcodec_b_mm2_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 16,
+ .dev = {
+ .parent = &msm_device_smmu_vcodec_b.dev,
+ },
+};
+
+static struct platform_device msm_device_gfx3d_rbpa_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 17,
+ .dev = {
+ .parent = &msm_device_smmu_gfx3d.dev,
+ },
+};
+
+static struct platform_device msm_device_gfx3d_cpvgttc_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 18,
+ .dev = {
+ .parent = &msm_device_smmu_gfx3d.dev,
+ },
+};
+
+static struct platform_device msm_device_gfx3d_smmu_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 19,
+ .dev = {
+ .parent = &msm_device_smmu_gfx3d.dev,
+ },
+};
+
+static struct platform_device msm_device_gfx2d0_pixv1_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 20,
+ .dev = {
+ .parent = &msm_device_smmu_gfx2d0.dev,
+ },
+};
+
+static struct platform_device msm_device_gfx2d0_texv3_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 21,
+ .dev = {
+ .parent = &msm_device_smmu_gfx2d0.dev,
+ },
+};
+
+static struct platform_device *msm_iommu_devs[] = {
+ &msm_device_smmu_jpegd,
+ &msm_device_smmu_vpe,
+ &msm_device_smmu_mdp0,
+ &msm_device_smmu_mdp1,
+ &msm_device_smmu_rot,
+ &msm_device_smmu_ijpeg,
+ &msm_device_smmu_vfe,
+ &msm_device_smmu_vcodec_a,
+ &msm_device_smmu_vcodec_b,
+ &msm_device_smmu_gfx3d,
+ &msm_device_smmu_gfx2d0,
+};
+
+static struct msm_iommu_dev *msm_iommu_data[] = {
+ &jpegd_smmu,
+ &vpe_smmu,
+ &mdp0_smmu,
+ &mdp1_smmu,
+ &rot_smmu,
+ &ijpeg_smmu,
+ &vfe_smmu,
+ &vcodec_a_smmu,
+ &vcodec_b_smmu,
+ &gfx3d_smmu,
+ &gfx2d0_smmu,
+};
+
+static struct platform_device *msm_iommu_ctx_devs[] = {
+ &msm_device_jpegd_src_ctx,
+ &msm_device_jpegd_dst_ctx,
+ &msm_device_vpe_src_ctx,
+ &msm_device_vpe_dst_ctx,
+ &msm_device_mdp_vg1_ctx,
+ &msm_device_mdp_rgb1_ctx,
+ &msm_device_mdp_vg2_ctx,
+ &msm_device_mdp_rgb2_ctx,
+ &msm_device_rot_src_ctx,
+ &msm_device_rot_dst_ctx,
+ &msm_device_ijpeg_src_ctx,
+ &msm_device_ijpeg_dst_ctx,
+ &msm_device_vfe_imgwr_ctx,
+ &msm_device_vfe_misc_ctx,
+ &msm_device_vcodec_a_stream_ctx,
+ &msm_device_vcodec_a_mm1_ctx,
+ &msm_device_vcodec_b_mm2_ctx,
+ &msm_device_gfx3d_rbpa_ctx,
+ &msm_device_gfx3d_cpvgttc_ctx,
+ &msm_device_gfx3d_smmu_ctx,
+ &msm_device_gfx2d0_pixv1_ctx,
+ &msm_device_gfx2d0_texv3_ctx,
+};
+
+static struct msm_iommu_ctx_dev *msm_iommu_ctx_data[] = {
+ &jpegd_src_ctx,
+ &jpegd_dst_ctx,
+ &vpe_src_ctx,
+ &vpe_dst_ctx,
+ &mdp_vg1_ctx,
+ &mdp_rgb1_ctx,
+ &mdp_vg2_ctx,
+ &mdp_rgb2_ctx,
+ &rot_src_ctx,
+ &rot_dst_ctx,
+ &ijpeg_src_ctx,
+ &ijpeg_dst_ctx,
+ &vfe_imgwr_ctx,
+ &vfe_misc_ctx,
+ &vcodec_a_stream_ctx,
+ &vcodec_a_mm1_ctx,
+ &vcodec_b_mm2_ctx,
+ &gfx3d_rbpa_ctx,
+ &gfx3d_cpvgttc_ctx,
+ &gfx3d_smmu_ctx,
+ &gfx2d0_pixv1_ctx,
+ &gfx2d0_texv3_ctx,
+};
+
+static int msm8x60_iommu_init(void)
+{
+ int ret, i;
+
+ ret = platform_device_register(&msm_root_iommu_dev);
+ if (ret != 0) {
+ pr_err("Failed to register root IOMMU device!\n");
+ goto failure;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(msm_iommu_devs); i++) {
+ ret = platform_device_add_data(msm_iommu_devs[i],
+ msm_iommu_data[i],
+ sizeof(struct msm_iommu_dev));
+ if (ret != 0) {
+ pr_err("platform_device_add_data failed, "
+ "i = %d\n", i);
+ goto failure_unwind;
+ }
+
+ ret = platform_device_register(msm_iommu_devs[i]);
+
+ if (ret != 0) {
+ pr_err("platform_device_register smmu failed, "
+ "i = %d\n", i);
+ goto failure_unwind;
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(msm_iommu_ctx_devs); i++) {
+ ret = platform_device_add_data(msm_iommu_ctx_devs[i],
+ msm_iommu_ctx_data[i],
+ sizeof(*msm_iommu_ctx_devs[i]));
+ if (ret != 0) {
+ pr_err("platform_device_add_data smmu failed, "
+ "i = %d\n", i);
+ goto failure_unwind2;
+ }
+
+ ret = platform_device_register(msm_iommu_ctx_devs[i]);
+ if (ret != 0) {
+ pr_err("platform_device_register ctx failed, "
+ "i = %d\n", i);
+ goto failure_unwind2;
+ }
+ }
+ return 0;
+
+failure_unwind2:
+ while (--i >= 0)
+ platform_device_unregister(msm_iommu_ctx_devs[i]);
+failure_unwind:
+ while (--i >= 0)
+ platform_device_unregister(msm_iommu_devs[i]);
+
+ platform_device_unregister(&msm_root_iommu_dev);
+failure:
+ return ret;
+}
+
+static void msm8x60_iommu_exit(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(msm_iommu_ctx_devs); i++)
+ platform_device_unregister(msm_iommu_ctx_devs[i]);
+
+ for (i = 0; i < ARRAY_SIZE(msm_iommu_devs); ++i)
+ platform_device_unregister(msm_iommu_devs[i]);
+
+ platform_device_unregister(&msm_root_iommu_dev);
+}
+
+subsys_initcall(msm8x60_iommu_init);
+module_exit(msm8x60_iommu_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>");
diff --git a/arch/arm/mach-msm/devices-qsd8x50.c b/arch/arm/mach-msm/devices-qsd8x50.c
index 4d4a50785e34..6fe67c5d1ae0 100644
--- a/arch/arm/mach-msm/devices-qsd8x50.c
+++ b/arch/arm/mach-msm/devices-qsd8x50.c
@@ -48,6 +48,11 @@ struct platform_device msm_device_uart3 = {
.resource = resources_uart3,
};
+struct platform_device msm_device_smd = {
+ .name = "msm_smd",
+ .id = -1,
+};
+
struct clk msm_clocks_8x50[] = {
CLK_PCOM("adm_clk", ADM_CLK, NULL, 0),
CLK_PCOM("ebi1_clk", EBI1_CLK, NULL, CLK_MIN),
diff --git a/arch/arm/mach-msm/gpio.c b/arch/arm/mach-msm/gpio.c
index bc32c845c7b0..33051b509e88 100644
--- a/arch/arm/mach-msm/gpio.c
+++ b/arch/arm/mach-msm/gpio.c
@@ -1,7 +1,7 @@
/* linux/arch/arm/mach-msm/gpio.c
*
* Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -14,72 +14,363 @@
*
*/
+#include <linux/bitops.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
#include <linux/module.h>
-#include <mach/gpio.h>
-#include "proc_comm.h"
-
-int gpio_tlmm_config(unsigned config, unsigned disable)
-{
- return msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &config, &disable);
-}
-EXPORT_SYMBOL(gpio_tlmm_config);
-
-int msm_gpios_enable(const struct msm_gpio *table, int size)
-{
- int rc;
- int i;
- const struct msm_gpio *g;
- for (i = 0; i < size; i++) {
- g = table + i;
- rc = gpio_tlmm_config(g->gpio_cfg, GPIO_ENABLE);
- if (rc) {
- pr_err("gpio_tlmm_config(0x%08x, GPIO_ENABLE)"
- " <%s> failed: %d\n",
- g->gpio_cfg, g->label ?: "?", rc);
- pr_err("pin %d func %d dir %d pull %d drvstr %d\n",
- GPIO_PIN(g->gpio_cfg), GPIO_FUNC(g->gpio_cfg),
- GPIO_DIR(g->gpio_cfg), GPIO_PULL(g->gpio_cfg),
- GPIO_DRVSTR(g->gpio_cfg));
- goto err;
- }
+#include "gpio_hw.h"
+#include "gpiomux.h"
+
+#define FIRST_GPIO_IRQ MSM_GPIO_TO_INT(0)
+
+#define MSM_GPIO_BANK(bank, first, last) \
+ { \
+ .regs = { \
+ .out = MSM_GPIO_OUT_##bank, \
+ .in = MSM_GPIO_IN_##bank, \
+ .int_status = MSM_GPIO_INT_STATUS_##bank, \
+ .int_clear = MSM_GPIO_INT_CLEAR_##bank, \
+ .int_en = MSM_GPIO_INT_EN_##bank, \
+ .int_edge = MSM_GPIO_INT_EDGE_##bank, \
+ .int_pos = MSM_GPIO_INT_POS_##bank, \
+ .oe = MSM_GPIO_OE_##bank, \
+ }, \
+ .chip = { \
+ .base = (first), \
+ .ngpio = (last) - (first) + 1, \
+ .get = msm_gpio_get, \
+ .set = msm_gpio_set, \
+ .direction_input = msm_gpio_direction_input, \
+ .direction_output = msm_gpio_direction_output, \
+ .to_irq = msm_gpio_to_irq, \
+ .request = msm_gpio_request, \
+ .free = msm_gpio_free, \
+ } \
}
+
+#define MSM_GPIO_BROKEN_INT_CLEAR 1
+
+struct msm_gpio_regs {
+ void __iomem *out;
+ void __iomem *in;
+ void __iomem *int_status;
+ void __iomem *int_clear;
+ void __iomem *int_en;
+ void __iomem *int_edge;
+ void __iomem *int_pos;
+ void __iomem *oe;
+};
+
+struct msm_gpio_chip {
+ spinlock_t lock;
+ struct gpio_chip chip;
+ struct msm_gpio_regs regs;
+#if MSM_GPIO_BROKEN_INT_CLEAR
+ unsigned int_status_copy;
+#endif
+ unsigned int both_edge_detect;
+ unsigned int int_enable[2]; /* 0: awake, 1: sleep */
+};
+
+static int msm_gpio_write(struct msm_gpio_chip *msm_chip,
+ unsigned offset, unsigned on)
+{
+ unsigned mask = BIT(offset);
+ unsigned val;
+
+ val = readl(msm_chip->regs.out);
+ if (on)
+ writel(val | mask, msm_chip->regs.out);
+ else
+ writel(val & ~mask, msm_chip->regs.out);
return 0;
-err:
- msm_gpios_disable(table, i);
- return rc;
-}
-EXPORT_SYMBOL(msm_gpios_enable);
-
-void msm_gpios_disable(const struct msm_gpio *table, int size)
-{
- int rc;
- int i;
- const struct msm_gpio *g;
- for (i = size-1; i >= 0; i--) {
- g = table + i;
- rc = gpio_tlmm_config(g->gpio_cfg, GPIO_DISABLE);
- if (rc) {
- pr_err("gpio_tlmm_config(0x%08x, GPIO_DISABLE)"
- " <%s> failed: %d\n",
- g->gpio_cfg, g->label ?: "?", rc);
- pr_err("pin %d func %d dir %d pull %d drvstr %d\n",
- GPIO_PIN(g->gpio_cfg), GPIO_FUNC(g->gpio_cfg),
- GPIO_DIR(g->gpio_cfg), GPIO_PULL(g->gpio_cfg),
- GPIO_DRVSTR(g->gpio_cfg));
- }
+}
+
+static void msm_gpio_update_both_edge_detect(struct msm_gpio_chip *msm_chip)
+{
+ int loop_limit = 100;
+ unsigned pol, val, val2, intstat;
+ do {
+ val = readl(msm_chip->regs.in);
+ pol = readl(msm_chip->regs.int_pos);
+ pol = (pol & ~msm_chip->both_edge_detect) |
+ (~val & msm_chip->both_edge_detect);
+ writel(pol, msm_chip->regs.int_pos);
+ intstat = readl(msm_chip->regs.int_status);
+ val2 = readl(msm_chip->regs.in);
+ if (((val ^ val2) & msm_chip->both_edge_detect & ~intstat) == 0)
+ return;
+ } while (loop_limit-- > 0);
+ printk(KERN_ERR "msm_gpio_update_both_edge_detect, "
+ "failed to reach stable state %x != %x\n", val, val2);
+}
+
+static int msm_gpio_clear_detect_status(struct msm_gpio_chip *msm_chip,
+ unsigned offset)
+{
+ unsigned bit = BIT(offset);
+
+#if MSM_GPIO_BROKEN_INT_CLEAR
+ /* Save interrupts that already triggered before we loose them. */
+ /* Any interrupt that triggers between the read of int_status */
+ /* and the write to int_clear will still be lost though. */
+ msm_chip->int_status_copy |= readl(msm_chip->regs.int_status);
+ msm_chip->int_status_copy &= ~bit;
+#endif
+ writel(bit, msm_chip->regs.int_clear);
+ msm_gpio_update_both_edge_detect(msm_chip);
+ return 0;
+}
+
+static int msm_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct msm_gpio_chip *msm_chip;
+ unsigned long irq_flags;
+
+ msm_chip = container_of(chip, struct msm_gpio_chip, chip);
+ spin_lock_irqsave(&msm_chip->lock, irq_flags);
+ writel(readl(msm_chip->regs.oe) & ~BIT(offset), msm_chip->regs.oe);
+ spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+ return 0;
+}
+
+static int
+msm_gpio_direction_output(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct msm_gpio_chip *msm_chip;
+ unsigned long irq_flags;
+
+ msm_chip = container_of(chip, struct msm_gpio_chip, chip);
+ spin_lock_irqsave(&msm_chip->lock, irq_flags);
+ msm_gpio_write(msm_chip, offset, value);
+ writel(readl(msm_chip->regs.oe) | BIT(offset), msm_chip->regs.oe);
+ spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+ return 0;
+}
+
+static int msm_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct msm_gpio_chip *msm_chip;
+
+ msm_chip = container_of(chip, struct msm_gpio_chip, chip);
+ return (readl(msm_chip->regs.in) & (1U << offset)) ? 1 : 0;
+}
+
+static void msm_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct msm_gpio_chip *msm_chip;
+ unsigned long irq_flags;
+
+ msm_chip = container_of(chip, struct msm_gpio_chip, chip);
+ spin_lock_irqsave(&msm_chip->lock, irq_flags);
+ msm_gpio_write(msm_chip, offset, value);
+ spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+}
+
+static int msm_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ return MSM_GPIO_TO_INT(chip->base + offset);
+}
+
+#ifdef CONFIG_MSM_GPIOMUX
+static int msm_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+ return msm_gpiomux_get(chip->base + offset);
+}
+
+static void msm_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+ msm_gpiomux_put(chip->base + offset);
+}
+#else
+#define msm_gpio_request NULL
+#define msm_gpio_free NULL
+#endif
+
+struct msm_gpio_chip msm_gpio_chips[] = {
+#if defined(CONFIG_ARCH_MSM7X00A)
+ MSM_GPIO_BANK(0, 0, 15),
+ MSM_GPIO_BANK(1, 16, 42),
+ MSM_GPIO_BANK(2, 43, 67),
+ MSM_GPIO_BANK(3, 68, 94),
+ MSM_GPIO_BANK(4, 95, 106),
+ MSM_GPIO_BANK(5, 107, 121),
+#elif defined(CONFIG_ARCH_MSM7X25) || defined(CONFIG_ARCH_MSM7X27)
+ MSM_GPIO_BANK(0, 0, 15),
+ MSM_GPIO_BANK(1, 16, 42),
+ MSM_GPIO_BANK(2, 43, 67),
+ MSM_GPIO_BANK(3, 68, 94),
+ MSM_GPIO_BANK(4, 95, 106),
+ MSM_GPIO_BANK(5, 107, 132),
+#elif defined(CONFIG_ARCH_MSM7X30)
+ MSM_GPIO_BANK(0, 0, 15),
+ MSM_GPIO_BANK(1, 16, 43),
+ MSM_GPIO_BANK(2, 44, 67),
+ MSM_GPIO_BANK(3, 68, 94),
+ MSM_GPIO_BANK(4, 95, 106),
+ MSM_GPIO_BANK(5, 107, 133),
+ MSM_GPIO_BANK(6, 134, 150),
+ MSM_GPIO_BANK(7, 151, 181),
+#elif defined(CONFIG_ARCH_QSD8X50)
+ MSM_GPIO_BANK(0, 0, 15),
+ MSM_GPIO_BANK(1, 16, 42),
+ MSM_GPIO_BANK(2, 43, 67),
+ MSM_GPIO_BANK(3, 68, 94),
+ MSM_GPIO_BANK(4, 95, 103),
+ MSM_GPIO_BANK(5, 104, 121),
+ MSM_GPIO_BANK(6, 122, 152),
+ MSM_GPIO_BANK(7, 153, 164),
+#endif
+};
+
+static void msm_gpio_irq_ack(unsigned int irq)
+{
+ unsigned long irq_flags;
+ struct msm_gpio_chip *msm_chip = get_irq_chip_data(irq);
+ spin_lock_irqsave(&msm_chip->lock, irq_flags);
+ msm_gpio_clear_detect_status(msm_chip,
+ irq - gpio_to_irq(msm_chip->chip.base));
+ spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+}
+
+static void msm_gpio_irq_mask(unsigned int irq)
+{
+ unsigned long irq_flags;
+ struct msm_gpio_chip *msm_chip = get_irq_chip_data(irq);
+ unsigned offset = irq - gpio_to_irq(msm_chip->chip.base);
+
+ spin_lock_irqsave(&msm_chip->lock, irq_flags);
+ /* level triggered interrupts are also latched */
+ if (!(readl(msm_chip->regs.int_edge) & BIT(offset)))
+ msm_gpio_clear_detect_status(msm_chip, offset);
+ msm_chip->int_enable[0] &= ~BIT(offset);
+ writel(msm_chip->int_enable[0], msm_chip->regs.int_en);
+ spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+}
+
+static void msm_gpio_irq_unmask(unsigned int irq)
+{
+ unsigned long irq_flags;
+ struct msm_gpio_chip *msm_chip = get_irq_chip_data(irq);
+ unsigned offset = irq - gpio_to_irq(msm_chip->chip.base);
+
+ spin_lock_irqsave(&msm_chip->lock, irq_flags);
+ /* level triggered interrupts are also latched */
+ if (!(readl(msm_chip->regs.int_edge) & BIT(offset)))
+ msm_gpio_clear_detect_status(msm_chip, offset);
+ msm_chip->int_enable[0] |= BIT(offset);
+ writel(msm_chip->int_enable[0], msm_chip->regs.int_en);
+ spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+}
+
+static int msm_gpio_irq_set_wake(unsigned int irq, unsigned int on)
+{
+ unsigned long irq_flags;
+ struct msm_gpio_chip *msm_chip = get_irq_chip_data(irq);
+ unsigned offset = irq - gpio_to_irq(msm_chip->chip.base);
+
+ spin_lock_irqsave(&msm_chip->lock, irq_flags);
+
+ if (on)
+ msm_chip->int_enable[1] |= BIT(offset);
+ else
+ msm_chip->int_enable[1] &= ~BIT(offset);
+
+ spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+ return 0;
+}
+
+static int msm_gpio_irq_set_type(unsigned int irq, unsigned int flow_type)
+{
+ unsigned long irq_flags;
+ struct msm_gpio_chip *msm_chip = get_irq_chip_data(irq);
+ unsigned offset = irq - gpio_to_irq(msm_chip->chip.base);
+ unsigned val, mask = BIT(offset);
+
+ spin_lock_irqsave(&msm_chip->lock, irq_flags);
+ val = readl(msm_chip->regs.int_edge);
+ if (flow_type & IRQ_TYPE_EDGE_BOTH) {
+ writel(val | mask, msm_chip->regs.int_edge);
+ irq_desc[irq].handle_irq = handle_edge_irq;
+ } else {
+ writel(val & ~mask, msm_chip->regs.int_edge);
+ irq_desc[irq].handle_irq = handle_level_irq;
+ }
+ if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) {
+ msm_chip->both_edge_detect |= mask;
+ msm_gpio_update_both_edge_detect(msm_chip);
+ } else {
+ msm_chip->both_edge_detect &= ~mask;
+ val = readl(msm_chip->regs.int_pos);
+ if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_HIGH))
+ writel(val | mask, msm_chip->regs.int_pos);
+ else
+ writel(val & ~mask, msm_chip->regs.int_pos);
}
+ spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+ return 0;
}
-EXPORT_SYMBOL(msm_gpios_disable);
-int msm_gpios_request_enable(const struct msm_gpio *table, int size)
+static void msm_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
{
- int rc = msm_gpios_enable(table, size);
- return rc;
+ int i, j, mask;
+ unsigned val;
+
+ for (i = 0; i < ARRAY_SIZE(msm_gpio_chips); i++) {
+ struct msm_gpio_chip *msm_chip = &msm_gpio_chips[i];
+ val = readl(msm_chip->regs.int_status);
+ val &= msm_chip->int_enable[0];
+ while (val) {
+ mask = val & -val;
+ j = fls(mask) - 1;
+ /* printk("%s %08x %08x bit %d gpio %d irq %d\n",
+ __func__, v, m, j, msm_chip->chip.start + j,
+ FIRST_GPIO_IRQ + msm_chip->chip.start + j); */
+ val &= ~mask;
+ generic_handle_irq(FIRST_GPIO_IRQ +
+ msm_chip->chip.base + j);
+ }
+ }
+ desc->chip->ack(irq);
}
-EXPORT_SYMBOL(msm_gpios_request_enable);
-void msm_gpios_disable_free(const struct msm_gpio *table, int size)
+static struct irq_chip msm_gpio_irq_chip = {
+ .name = "msmgpio",
+ .ack = msm_gpio_irq_ack,
+ .mask = msm_gpio_irq_mask,
+ .unmask = msm_gpio_irq_unmask,
+ .set_wake = msm_gpio_irq_set_wake,
+ .set_type = msm_gpio_irq_set_type,
+};
+
+static int __init msm_init_gpio(void)
{
- msm_gpios_disable(table, size);
+ int i, j = 0;
+
+ for (i = FIRST_GPIO_IRQ; i < FIRST_GPIO_IRQ + NR_GPIO_IRQS; i++) {
+ if (i - FIRST_GPIO_IRQ >=
+ msm_gpio_chips[j].chip.base +
+ msm_gpio_chips[j].chip.ngpio)
+ j++;
+ set_irq_chip_data(i, &msm_gpio_chips[j]);
+ set_irq_chip(i, &msm_gpio_irq_chip);
+ set_irq_handler(i, handle_edge_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(msm_gpio_chips); i++) {
+ spin_lock_init(&msm_gpio_chips[i].lock);
+ writel(0, msm_gpio_chips[i].regs.int_en);
+ gpiochip_add(&msm_gpio_chips[i].chip);
+ }
+
+ set_irq_chained_handler(INT_GPIO_GROUP1, msm_gpio_irq_handler);
+ set_irq_chained_handler(INT_GPIO_GROUP2, msm_gpio_irq_handler);
+ set_irq_wake(INT_GPIO_GROUP1, 1);
+ set_irq_wake(INT_GPIO_GROUP2, 2);
+ return 0;
}
-EXPORT_SYMBOL(msm_gpios_disable_free);
+
+postcore_initcall(msm_init_gpio);
diff --git a/arch/arm/mach-msm/gpio_hw.h b/arch/arm/mach-msm/gpio_hw.h
new file mode 100644
index 000000000000..6b5066038baa
--- /dev/null
+++ b/arch/arm/mach-msm/gpio_hw.h
@@ -0,0 +1,278 @@
+/* arch/arm/mach-msm/gpio_hw.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ARCH_ARM_MACH_MSM_GPIO_HW_H
+#define __ARCH_ARM_MACH_MSM_GPIO_HW_H
+
+#include <mach/msm_iomap.h>
+
+/* see 80-VA736-2 Rev C pp 695-751
+**
+** These are actually the *shadow* gpio registers, since the
+** real ones (which allow full access) are only available to the
+** ARM9 side of the world.
+**
+** Since the _BASE need to be page-aligned when we're mapping them
+** to virtual addresses, adjust for the additional offset in these
+** macros.
+*/
+
+#if defined(CONFIG_ARCH_MSM7X30)
+#define MSM_GPIO1_REG(off) (MSM_GPIO1_BASE + (off))
+#define MSM_GPIO2_REG(off) (MSM_GPIO2_BASE + 0x400 + (off))
+#else
+#define MSM_GPIO1_REG(off) (MSM_GPIO1_BASE + 0x800 + (off))
+#define MSM_GPIO2_REG(off) (MSM_GPIO2_BASE + 0xC00 + (off))
+#endif
+
+#if defined(CONFIG_ARCH_MSM7X00A) || defined(CONFIG_ARCH_MSM7X25) ||\
+ defined(CONFIG_ARCH_MSM7X27)
+
+/* output value */
+#define MSM_GPIO_OUT_0 MSM_GPIO1_REG(0x00) /* gpio 15-0 */
+#define MSM_GPIO_OUT_1 MSM_GPIO2_REG(0x00) /* gpio 42-16 */
+#define MSM_GPIO_OUT_2 MSM_GPIO1_REG(0x04) /* gpio 67-43 */
+#define MSM_GPIO_OUT_3 MSM_GPIO1_REG(0x08) /* gpio 94-68 */
+#define MSM_GPIO_OUT_4 MSM_GPIO1_REG(0x0C) /* gpio 106-95 */
+#define MSM_GPIO_OUT_5 MSM_GPIO1_REG(0x50) /* gpio 107-121 */
+
+/* same pin map as above, output enable */
+#define MSM_GPIO_OE_0 MSM_GPIO1_REG(0x10)
+#define MSM_GPIO_OE_1 MSM_GPIO2_REG(0x08)
+#define MSM_GPIO_OE_2 MSM_GPIO1_REG(0x14)
+#define MSM_GPIO_OE_3 MSM_GPIO1_REG(0x18)
+#define MSM_GPIO_OE_4 MSM_GPIO1_REG(0x1C)
+#define MSM_GPIO_OE_5 MSM_GPIO1_REG(0x54)
+
+/* same pin map as above, input read */
+#define MSM_GPIO_IN_0 MSM_GPIO1_REG(0x34)
+#define MSM_GPIO_IN_1 MSM_GPIO2_REG(0x20)
+#define MSM_GPIO_IN_2 MSM_GPIO1_REG(0x38)
+#define MSM_GPIO_IN_3 MSM_GPIO1_REG(0x3C)
+#define MSM_GPIO_IN_4 MSM_GPIO1_REG(0x40)
+#define MSM_GPIO_IN_5 MSM_GPIO1_REG(0x44)
+
+/* same pin map as above, 1=edge 0=level interrup */
+#define MSM_GPIO_INT_EDGE_0 MSM_GPIO1_REG(0x60)
+#define MSM_GPIO_INT_EDGE_1 MSM_GPIO2_REG(0x50)
+#define MSM_GPIO_INT_EDGE_2 MSM_GPIO1_REG(0x64)
+#define MSM_GPIO_INT_EDGE_3 MSM_GPIO1_REG(0x68)
+#define MSM_GPIO_INT_EDGE_4 MSM_GPIO1_REG(0x6C)
+#define MSM_GPIO_INT_EDGE_5 MSM_GPIO1_REG(0xC0)
+
+/* same pin map as above, 1=positive 0=negative */
+#define MSM_GPIO_INT_POS_0 MSM_GPIO1_REG(0x70)
+#define MSM_GPIO_INT_POS_1 MSM_GPIO2_REG(0x58)
+#define MSM_GPIO_INT_POS_2 MSM_GPIO1_REG(0x74)
+#define MSM_GPIO_INT_POS_3 MSM_GPIO1_REG(0x78)
+#define MSM_GPIO_INT_POS_4 MSM_GPIO1_REG(0x7C)
+#define MSM_GPIO_INT_POS_5 MSM_GPIO1_REG(0xBC)
+
+/* same pin map as above, interrupt enable */
+#define MSM_GPIO_INT_EN_0 MSM_GPIO1_REG(0x80)
+#define MSM_GPIO_INT_EN_1 MSM_GPIO2_REG(0x60)
+#define MSM_GPIO_INT_EN_2 MSM_GPIO1_REG(0x84)
+#define MSM_GPIO_INT_EN_3 MSM_GPIO1_REG(0x88)
+#define MSM_GPIO_INT_EN_4 MSM_GPIO1_REG(0x8C)
+#define MSM_GPIO_INT_EN_5 MSM_GPIO1_REG(0xB8)
+
+/* same pin map as above, write 1 to clear interrupt */
+#define MSM_GPIO_INT_CLEAR_0 MSM_GPIO1_REG(0x90)
+#define MSM_GPIO_INT_CLEAR_1 MSM_GPIO2_REG(0x68)
+#define MSM_GPIO_INT_CLEAR_2 MSM_GPIO1_REG(0x94)
+#define MSM_GPIO_INT_CLEAR_3 MSM_GPIO1_REG(0x98)
+#define MSM_GPIO_INT_CLEAR_4 MSM_GPIO1_REG(0x9C)
+#define MSM_GPIO_INT_CLEAR_5 MSM_GPIO1_REG(0xB4)
+
+/* same pin map as above, 1=interrupt pending */
+#define MSM_GPIO_INT_STATUS_0 MSM_GPIO1_REG(0xA0)
+#define MSM_GPIO_INT_STATUS_1 MSM_GPIO2_REG(0x70)
+#define MSM_GPIO_INT_STATUS_2 MSM_GPIO1_REG(0xA4)
+#define MSM_GPIO_INT_STATUS_3 MSM_GPIO1_REG(0xA8)
+#define MSM_GPIO_INT_STATUS_4 MSM_GPIO1_REG(0xAC)
+#define MSM_GPIO_INT_STATUS_5 MSM_GPIO1_REG(0xB0)
+
+#endif
+
+#if defined(CONFIG_ARCH_QSD8X50)
+/* output value */
+#define MSM_GPIO_OUT_0 MSM_GPIO1_REG(0x00) /* gpio 15-0 */
+#define MSM_GPIO_OUT_1 MSM_GPIO2_REG(0x00) /* gpio 42-16 */
+#define MSM_GPIO_OUT_2 MSM_GPIO1_REG(0x04) /* gpio 67-43 */
+#define MSM_GPIO_OUT_3 MSM_GPIO1_REG(0x08) /* gpio 94-68 */
+#define MSM_GPIO_OUT_4 MSM_GPIO1_REG(0x0C) /* gpio 103-95 */
+#define MSM_GPIO_OUT_5 MSM_GPIO1_REG(0x10) /* gpio 121-104 */
+#define MSM_GPIO_OUT_6 MSM_GPIO1_REG(0x14) /* gpio 152-122 */
+#define MSM_GPIO_OUT_7 MSM_GPIO1_REG(0x18) /* gpio 164-153 */
+
+/* same pin map as above, output enable */
+#define MSM_GPIO_OE_0 MSM_GPIO1_REG(0x20)
+#define MSM_GPIO_OE_1 MSM_GPIO2_REG(0x08)
+#define MSM_GPIO_OE_2 MSM_GPIO1_REG(0x24)
+#define MSM_GPIO_OE_3 MSM_GPIO1_REG(0x28)
+#define MSM_GPIO_OE_4 MSM_GPIO1_REG(0x2C)
+#define MSM_GPIO_OE_5 MSM_GPIO1_REG(0x30)
+#define MSM_GPIO_OE_6 MSM_GPIO1_REG(0x34)
+#define MSM_GPIO_OE_7 MSM_GPIO1_REG(0x38)
+
+/* same pin map as above, input read */
+#define MSM_GPIO_IN_0 MSM_GPIO1_REG(0x50)
+#define MSM_GPIO_IN_1 MSM_GPIO2_REG(0x20)
+#define MSM_GPIO_IN_2 MSM_GPIO1_REG(0x54)
+#define MSM_GPIO_IN_3 MSM_GPIO1_REG(0x58)
+#define MSM_GPIO_IN_4 MSM_GPIO1_REG(0x5C)
+#define MSM_GPIO_IN_5 MSM_GPIO1_REG(0x60)
+#define MSM_GPIO_IN_6 MSM_GPIO1_REG(0x64)
+#define MSM_GPIO_IN_7 MSM_GPIO1_REG(0x68)
+
+/* same pin map as above, 1=edge 0=level interrup */
+#define MSM_GPIO_INT_EDGE_0 MSM_GPIO1_REG(0x70)
+#define MSM_GPIO_INT_EDGE_1 MSM_GPIO2_REG(0x50)
+#define MSM_GPIO_INT_EDGE_2 MSM_GPIO1_REG(0x74)
+#define MSM_GPIO_INT_EDGE_3 MSM_GPIO1_REG(0x78)
+#define MSM_GPIO_INT_EDGE_4 MSM_GPIO1_REG(0x7C)
+#define MSM_GPIO_INT_EDGE_5 MSM_GPIO1_REG(0x80)
+#define MSM_GPIO_INT_EDGE_6 MSM_GPIO1_REG(0x84)
+#define MSM_GPIO_INT_EDGE_7 MSM_GPIO1_REG(0x88)
+
+/* same pin map as above, 1=positive 0=negative */
+#define MSM_GPIO_INT_POS_0 MSM_GPIO1_REG(0x90)
+#define MSM_GPIO_INT_POS_1 MSM_GPIO2_REG(0x58)
+#define MSM_GPIO_INT_POS_2 MSM_GPIO1_REG(0x94)
+#define MSM_GPIO_INT_POS_3 MSM_GPIO1_REG(0x98)
+#define MSM_GPIO_INT_POS_4 MSM_GPIO1_REG(0x9C)
+#define MSM_GPIO_INT_POS_5 MSM_GPIO1_REG(0xA0)
+#define MSM_GPIO_INT_POS_6 MSM_GPIO1_REG(0xA4)
+#define MSM_GPIO_INT_POS_7 MSM_GPIO1_REG(0xA8)
+
+/* same pin map as above, interrupt enable */
+#define MSM_GPIO_INT_EN_0 MSM_GPIO1_REG(0xB0)
+#define MSM_GPIO_INT_EN_1 MSM_GPIO2_REG(0x60)
+#define MSM_GPIO_INT_EN_2 MSM_GPIO1_REG(0xB4)
+#define MSM_GPIO_INT_EN_3 MSM_GPIO1_REG(0xB8)
+#define MSM_GPIO_INT_EN_4 MSM_GPIO1_REG(0xBC)
+#define MSM_GPIO_INT_EN_5 MSM_GPIO1_REG(0xC0)
+#define MSM_GPIO_INT_EN_6 MSM_GPIO1_REG(0xC4)
+#define MSM_GPIO_INT_EN_7 MSM_GPIO1_REG(0xC8)
+
+/* same pin map as above, write 1 to clear interrupt */
+#define MSM_GPIO_INT_CLEAR_0 MSM_GPIO1_REG(0xD0)
+#define MSM_GPIO_INT_CLEAR_1 MSM_GPIO2_REG(0x68)
+#define MSM_GPIO_INT_CLEAR_2 MSM_GPIO1_REG(0xD4)
+#define MSM_GPIO_INT_CLEAR_3 MSM_GPIO1_REG(0xD8)
+#define MSM_GPIO_INT_CLEAR_4 MSM_GPIO1_REG(0xDC)
+#define MSM_GPIO_INT_CLEAR_5 MSM_GPIO1_REG(0xE0)
+#define MSM_GPIO_INT_CLEAR_6 MSM_GPIO1_REG(0xE4)
+#define MSM_GPIO_INT_CLEAR_7 MSM_GPIO1_REG(0xE8)
+
+/* same pin map as above, 1=interrupt pending */
+#define MSM_GPIO_INT_STATUS_0 MSM_GPIO1_REG(0xF0)
+#define MSM_GPIO_INT_STATUS_1 MSM_GPIO2_REG(0x70)
+#define MSM_GPIO_INT_STATUS_2 MSM_GPIO1_REG(0xF4)
+#define MSM_GPIO_INT_STATUS_3 MSM_GPIO1_REG(0xF8)
+#define MSM_GPIO_INT_STATUS_4 MSM_GPIO1_REG(0xFC)
+#define MSM_GPIO_INT_STATUS_5 MSM_GPIO1_REG(0x100)
+#define MSM_GPIO_INT_STATUS_6 MSM_GPIO1_REG(0x104)
+#define MSM_GPIO_INT_STATUS_7 MSM_GPIO1_REG(0x108)
+
+#endif
+
+#if defined(CONFIG_ARCH_MSM7X30)
+
+/* output value */
+#define MSM_GPIO_OUT_0 MSM_GPIO1_REG(0x00) /* gpio 15-0 */
+#define MSM_GPIO_OUT_1 MSM_GPIO2_REG(0x00) /* gpio 43-16 */
+#define MSM_GPIO_OUT_2 MSM_GPIO1_REG(0x04) /* gpio 67-44 */
+#define MSM_GPIO_OUT_3 MSM_GPIO1_REG(0x08) /* gpio 94-68 */
+#define MSM_GPIO_OUT_4 MSM_GPIO1_REG(0x0C) /* gpio 106-95 */
+#define MSM_GPIO_OUT_5 MSM_GPIO1_REG(0x50) /* gpio 133-107 */
+#define MSM_GPIO_OUT_6 MSM_GPIO1_REG(0xC4) /* gpio 150-134 */
+#define MSM_GPIO_OUT_7 MSM_GPIO1_REG(0x214) /* gpio 181-151 */
+
+/* same pin map as above, output enable */
+#define MSM_GPIO_OE_0 MSM_GPIO1_REG(0x10)
+#define MSM_GPIO_OE_1 MSM_GPIO2_REG(0x08)
+#define MSM_GPIO_OE_2 MSM_GPIO1_REG(0x14)
+#define MSM_GPIO_OE_3 MSM_GPIO1_REG(0x18)
+#define MSM_GPIO_OE_4 MSM_GPIO1_REG(0x1C)
+#define MSM_GPIO_OE_5 MSM_GPIO1_REG(0x54)
+#define MSM_GPIO_OE_6 MSM_GPIO1_REG(0xC8)
+#define MSM_GPIO_OE_7 MSM_GPIO1_REG(0x218)
+
+/* same pin map as above, input read */
+#define MSM_GPIO_IN_0 MSM_GPIO1_REG(0x34)
+#define MSM_GPIO_IN_1 MSM_GPIO2_REG(0x20)
+#define MSM_GPIO_IN_2 MSM_GPIO1_REG(0x38)
+#define MSM_GPIO_IN_3 MSM_GPIO1_REG(0x3C)
+#define MSM_GPIO_IN_4 MSM_GPIO1_REG(0x40)
+#define MSM_GPIO_IN_5 MSM_GPIO1_REG(0x44)
+#define MSM_GPIO_IN_6 MSM_GPIO1_REG(0xCC)
+#define MSM_GPIO_IN_7 MSM_GPIO1_REG(0x21C)
+
+/* same pin map as above, 1=edge 0=level interrup */
+#define MSM_GPIO_INT_EDGE_0 MSM_GPIO1_REG(0x60)
+#define MSM_GPIO_INT_EDGE_1 MSM_GPIO2_REG(0x50)
+#define MSM_GPIO_INT_EDGE_2 MSM_GPIO1_REG(0x64)
+#define MSM_GPIO_INT_EDGE_3 MSM_GPIO1_REG(0x68)
+#define MSM_GPIO_INT_EDGE_4 MSM_GPIO1_REG(0x6C)
+#define MSM_GPIO_INT_EDGE_5 MSM_GPIO1_REG(0xC0)
+#define MSM_GPIO_INT_EDGE_6 MSM_GPIO1_REG(0xD0)
+#define MSM_GPIO_INT_EDGE_7 MSM_GPIO1_REG(0x240)
+
+/* same pin map as above, 1=positive 0=negative */
+#define MSM_GPIO_INT_POS_0 MSM_GPIO1_REG(0x70)
+#define MSM_GPIO_INT_POS_1 MSM_GPIO2_REG(0x58)
+#define MSM_GPIO_INT_POS_2 MSM_GPIO1_REG(0x74)
+#define MSM_GPIO_INT_POS_3 MSM_GPIO1_REG(0x78)
+#define MSM_GPIO_INT_POS_4 MSM_GPIO1_REG(0x7C)
+#define MSM_GPIO_INT_POS_5 MSM_GPIO1_REG(0xBC)
+#define MSM_GPIO_INT_POS_6 MSM_GPIO1_REG(0xD4)
+#define MSM_GPIO_INT_POS_7 MSM_GPIO1_REG(0x228)
+
+/* same pin map as above, interrupt enable */
+#define MSM_GPIO_INT_EN_0 MSM_GPIO1_REG(0x80)
+#define MSM_GPIO_INT_EN_1 MSM_GPIO2_REG(0x60)
+#define MSM_GPIO_INT_EN_2 MSM_GPIO1_REG(0x84)
+#define MSM_GPIO_INT_EN_3 MSM_GPIO1_REG(0x88)
+#define MSM_GPIO_INT_EN_4 MSM_GPIO1_REG(0x8C)
+#define MSM_GPIO_INT_EN_5 MSM_GPIO1_REG(0xB8)
+#define MSM_GPIO_INT_EN_6 MSM_GPIO1_REG(0xD8)
+#define MSM_GPIO_INT_EN_7 MSM_GPIO1_REG(0x22C)
+
+/* same pin map as above, write 1 to clear interrupt */
+#define MSM_GPIO_INT_CLEAR_0 MSM_GPIO1_REG(0x90)
+#define MSM_GPIO_INT_CLEAR_1 MSM_GPIO2_REG(0x68)
+#define MSM_GPIO_INT_CLEAR_2 MSM_GPIO1_REG(0x94)
+#define MSM_GPIO_INT_CLEAR_3 MSM_GPIO1_REG(0x98)
+#define MSM_GPIO_INT_CLEAR_4 MSM_GPIO1_REG(0x9C)
+#define MSM_GPIO_INT_CLEAR_5 MSM_GPIO1_REG(0xB4)
+#define MSM_GPIO_INT_CLEAR_6 MSM_GPIO1_REG(0xDC)
+#define MSM_GPIO_INT_CLEAR_7 MSM_GPIO1_REG(0x230)
+
+/* same pin map as above, 1=interrupt pending */
+#define MSM_GPIO_INT_STATUS_0 MSM_GPIO1_REG(0xA0)
+#define MSM_GPIO_INT_STATUS_1 MSM_GPIO2_REG(0x70)
+#define MSM_GPIO_INT_STATUS_2 MSM_GPIO1_REG(0xA4)
+#define MSM_GPIO_INT_STATUS_3 MSM_GPIO1_REG(0xA8)
+#define MSM_GPIO_INT_STATUS_4 MSM_GPIO1_REG(0xAC)
+#define MSM_GPIO_INT_STATUS_5 MSM_GPIO1_REG(0xB0)
+#define MSM_GPIO_INT_STATUS_6 MSM_GPIO1_REG(0xE0)
+#define MSM_GPIO_INT_STATUS_7 MSM_GPIO1_REG(0x234)
+
+#endif
+
+#endif
diff --git a/arch/arm/mach-msm/gpiomux-7x30.c b/arch/arm/mach-msm/gpiomux-7x30.c
new file mode 100644
index 000000000000..6ce41c5241a5
--- /dev/null
+++ b/arch/arm/mach-msm/gpiomux-7x30.c
@@ -0,0 +1,38 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#include "gpiomux.h"
+
+struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = {
+#ifdef CONFIG_SERIAL_MSM_CONSOLE
+ [49] = { /* UART2 RFR */
+ .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
+ GPIOMUX_FUNC_2 | GPIOMUX_VALID,
+ },
+ [50] = { /* UART2 CTS */
+ .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
+ GPIOMUX_FUNC_2 | GPIOMUX_VALID,
+ },
+ [51] = { /* UART2 RX */
+ .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
+ GPIOMUX_FUNC_2 | GPIOMUX_VALID,
+ },
+ [52] = { /* UART2 TX */
+ .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
+ GPIOMUX_FUNC_2 | GPIOMUX_VALID,
+ },
+#endif
+};
diff --git a/arch/arm/mach-msm/gpiomux-8x50.c b/arch/arm/mach-msm/gpiomux-8x50.c
new file mode 100644
index 000000000000..4406e0f4ae95
--- /dev/null
+++ b/arch/arm/mach-msm/gpiomux-8x50.c
@@ -0,0 +1,28 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#include "gpiomux.h"
+
+struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = {
+ [86] = { /* UART3 RX */
+ .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
+ GPIOMUX_FUNC_1 | GPIOMUX_VALID,
+ },
+ [87] = { /* UART3 TX */
+ .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
+ GPIOMUX_FUNC_1 | GPIOMUX_VALID,
+ },
+};
diff --git a/arch/arm/mach-msm/gpiomux-8x60.c b/arch/arm/mach-msm/gpiomux-8x60.c
new file mode 100644
index 000000000000..7b380b31bd0e
--- /dev/null
+++ b/arch/arm/mach-msm/gpiomux-8x60.c
@@ -0,0 +1,19 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#include "gpiomux.h"
+
+struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = {};
diff --git a/arch/arm/mach-msm/gpiomux-v1.c b/arch/arm/mach-msm/gpiomux-v1.c
new file mode 100644
index 000000000000..27de2abd7144
--- /dev/null
+++ b/arch/arm/mach-msm/gpiomux-v1.c
@@ -0,0 +1,33 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#include <linux/kernel.h>
+#include "gpiomux.h"
+#include "proc_comm.h"
+
+void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val)
+{
+ unsigned tlmm_config = (val & ~GPIOMUX_CTL_MASK) |
+ ((gpio & 0x3ff) << 4);
+ unsigned tlmm_disable = 0;
+ int rc;
+
+ rc = msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX,
+ &tlmm_config, &tlmm_disable);
+ if (rc)
+ pr_err("%s: unexpected proc_comm failure %d: %08x %08x\n",
+ __func__, rc, tlmm_config, tlmm_disable);
+}
diff --git a/arch/arm/mach-msm/gpiomux-v1.h b/arch/arm/mach-msm/gpiomux-v1.h
new file mode 100644
index 000000000000..71d86feba450
--- /dev/null
+++ b/arch/arm/mach-msm/gpiomux-v1.h
@@ -0,0 +1,67 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#ifndef __ARCH_ARM_MACH_MSM_GPIOMUX_V1_H
+#define __ARCH_ARM_MACH_MSM_GPIOMUX_V1_H
+
+#if defined(CONFIG_ARCH_MSM7X30)
+#define GPIOMUX_NGPIOS 182
+#elif defined(CONFIG_ARCH_QSD8X50)
+#define GPIOMUX_NGPIOS 165
+#else
+#define GPIOMUX_NGPIOS 133
+#endif
+
+typedef u32 gpiomux_config_t;
+
+enum {
+ GPIOMUX_DRV_2MA = 0UL << 17,
+ GPIOMUX_DRV_4MA = 1UL << 17,
+ GPIOMUX_DRV_6MA = 2UL << 17,
+ GPIOMUX_DRV_8MA = 3UL << 17,
+ GPIOMUX_DRV_10MA = 4UL << 17,
+ GPIOMUX_DRV_12MA = 5UL << 17,
+ GPIOMUX_DRV_14MA = 6UL << 17,
+ GPIOMUX_DRV_16MA = 7UL << 17,
+};
+
+enum {
+ GPIOMUX_FUNC_GPIO = 0UL,
+ GPIOMUX_FUNC_1 = 1UL,
+ GPIOMUX_FUNC_2 = 2UL,
+ GPIOMUX_FUNC_3 = 3UL,
+ GPIOMUX_FUNC_4 = 4UL,
+ GPIOMUX_FUNC_5 = 5UL,
+ GPIOMUX_FUNC_6 = 6UL,
+ GPIOMUX_FUNC_7 = 7UL,
+ GPIOMUX_FUNC_8 = 8UL,
+ GPIOMUX_FUNC_9 = 9UL,
+ GPIOMUX_FUNC_A = 10UL,
+ GPIOMUX_FUNC_B = 11UL,
+ GPIOMUX_FUNC_C = 12UL,
+ GPIOMUX_FUNC_D = 13UL,
+ GPIOMUX_FUNC_E = 14UL,
+ GPIOMUX_FUNC_F = 15UL,
+};
+
+enum {
+ GPIOMUX_PULL_NONE = 0UL << 15,
+ GPIOMUX_PULL_DOWN = 1UL << 15,
+ GPIOMUX_PULL_KEEPER = 2UL << 15,
+ GPIOMUX_PULL_UP = 3UL << 15,
+};
+
+#endif
diff --git a/arch/arm/mach-msm/gpiomux-v2.c b/arch/arm/mach-msm/gpiomux-v2.c
new file mode 100644
index 000000000000..273396d2b127
--- /dev/null
+++ b/arch/arm/mach-msm/gpiomux-v2.c
@@ -0,0 +1,25 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#include <linux/io.h>
+#include <mach/msm_iomap.h>
+#include "gpiomux.h"
+
+void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val)
+{
+ writel(val & ~GPIOMUX_CTL_MASK,
+ MSM_TLMM_BASE + 0x1000 + (0x10 * gpio));
+}
diff --git a/arch/arm/mach-msm/gpiomux-v2.h b/arch/arm/mach-msm/gpiomux-v2.h
new file mode 100644
index 000000000000..3bf10e7f0381
--- /dev/null
+++ b/arch/arm/mach-msm/gpiomux-v2.h
@@ -0,0 +1,61 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#ifndef __ARCH_ARM_MACH_MSM_GPIOMUX_V2_H
+#define __ARCH_ARM_MACH_MSM_GPIOMUX_V2_H
+
+#define GPIOMUX_NGPIOS 173
+
+typedef u16 gpiomux_config_t;
+
+enum {
+ GPIOMUX_DRV_2MA = 0UL << 6,
+ GPIOMUX_DRV_4MA = 1UL << 6,
+ GPIOMUX_DRV_6MA = 2UL << 6,
+ GPIOMUX_DRV_8MA = 3UL << 6,
+ GPIOMUX_DRV_10MA = 4UL << 6,
+ GPIOMUX_DRV_12MA = 5UL << 6,
+ GPIOMUX_DRV_14MA = 6UL << 6,
+ GPIOMUX_DRV_16MA = 7UL << 6,
+};
+
+enum {
+ GPIOMUX_FUNC_GPIO = 0UL << 2,
+ GPIOMUX_FUNC_1 = 1UL << 2,
+ GPIOMUX_FUNC_2 = 2UL << 2,
+ GPIOMUX_FUNC_3 = 3UL << 2,
+ GPIOMUX_FUNC_4 = 4UL << 2,
+ GPIOMUX_FUNC_5 = 5UL << 2,
+ GPIOMUX_FUNC_6 = 6UL << 2,
+ GPIOMUX_FUNC_7 = 7UL << 2,
+ GPIOMUX_FUNC_8 = 8UL << 2,
+ GPIOMUX_FUNC_9 = 9UL << 2,
+ GPIOMUX_FUNC_A = 10UL << 2,
+ GPIOMUX_FUNC_B = 11UL << 2,
+ GPIOMUX_FUNC_C = 12UL << 2,
+ GPIOMUX_FUNC_D = 13UL << 2,
+ GPIOMUX_FUNC_E = 14UL << 2,
+ GPIOMUX_FUNC_F = 15UL << 2,
+};
+
+enum {
+ GPIOMUX_PULL_NONE = 0UL,
+ GPIOMUX_PULL_DOWN = 1UL,
+ GPIOMUX_PULL_KEEPER = 2UL,
+ GPIOMUX_PULL_UP = 3UL,
+};
+
+#endif
diff --git a/arch/arm/mach-msm/gpiomux.c b/arch/arm/mach-msm/gpiomux.c
new file mode 100644
index 000000000000..53af21abd155
--- /dev/null
+++ b/arch/arm/mach-msm/gpiomux.c
@@ -0,0 +1,96 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include "gpiomux.h"
+
+static DEFINE_SPINLOCK(gpiomux_lock);
+
+int msm_gpiomux_write(unsigned gpio,
+ gpiomux_config_t active,
+ gpiomux_config_t suspended)
+{
+ struct msm_gpiomux_config *cfg = msm_gpiomux_configs + gpio;
+ unsigned long irq_flags;
+ gpiomux_config_t setting;
+
+ if (gpio >= GPIOMUX_NGPIOS)
+ return -EINVAL;
+
+ spin_lock_irqsave(&gpiomux_lock, irq_flags);
+
+ if (active & GPIOMUX_VALID)
+ cfg->active = active;
+
+ if (suspended & GPIOMUX_VALID)
+ cfg->suspended = suspended;
+
+ setting = cfg->ref ? active : suspended;
+ if (setting & GPIOMUX_VALID)
+ __msm_gpiomux_write(gpio, setting);
+
+ spin_unlock_irqrestore(&gpiomux_lock, irq_flags);
+ return 0;
+}
+EXPORT_SYMBOL(msm_gpiomux_write);
+
+int msm_gpiomux_get(unsigned gpio)
+{
+ struct msm_gpiomux_config *cfg = msm_gpiomux_configs + gpio;
+ unsigned long irq_flags;
+
+ if (gpio >= GPIOMUX_NGPIOS)
+ return -EINVAL;
+
+ spin_lock_irqsave(&gpiomux_lock, irq_flags);
+ if (cfg->ref++ == 0 && cfg->active & GPIOMUX_VALID)
+ __msm_gpiomux_write(gpio, cfg->active);
+ spin_unlock_irqrestore(&gpiomux_lock, irq_flags);
+ return 0;
+}
+EXPORT_SYMBOL(msm_gpiomux_get);
+
+int msm_gpiomux_put(unsigned gpio)
+{
+ struct msm_gpiomux_config *cfg = msm_gpiomux_configs + gpio;
+ unsigned long irq_flags;
+
+ if (gpio >= GPIOMUX_NGPIOS)
+ return -EINVAL;
+
+ spin_lock_irqsave(&gpiomux_lock, irq_flags);
+ BUG_ON(cfg->ref == 0);
+ if (--cfg->ref == 0 && cfg->suspended & GPIOMUX_VALID)
+ __msm_gpiomux_write(gpio, cfg->suspended);
+ spin_unlock_irqrestore(&gpiomux_lock, irq_flags);
+ return 0;
+}
+EXPORT_SYMBOL(msm_gpiomux_put);
+
+static int __init gpiomux_init(void)
+{
+ unsigned n;
+
+ for (n = 0; n < GPIOMUX_NGPIOS; ++n) {
+ msm_gpiomux_configs[n].ref = 0;
+ if (!(msm_gpiomux_configs[n].suspended & GPIOMUX_VALID))
+ continue;
+ __msm_gpiomux_write(n, msm_gpiomux_configs[n].suspended);
+ }
+ return 0;
+}
+postcore_initcall(gpiomux_init);
diff --git a/arch/arm/mach-msm/gpiomux.h b/arch/arm/mach-msm/gpiomux.h
new file mode 100644
index 000000000000..b178d9cb742f
--- /dev/null
+++ b/arch/arm/mach-msm/gpiomux.h
@@ -0,0 +1,114 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#ifndef __ARCH_ARM_MACH_MSM_GPIOMUX_H
+#define __ARCH_ARM_MACH_MSM_GPIOMUX_H
+
+#include <linux/bitops.h>
+#include <linux/errno.h>
+
+#if defined(CONFIG_MSM_V2_TLMM)
+#include "gpiomux-v2.h"
+#else
+#include "gpiomux-v1.h"
+#endif
+
+/**
+ * struct msm_gpiomux_config: gpiomux settings for one gpio line.
+ *
+ * A complete gpiomux config is the bitwise-or of a drive-strength,
+ * function, and pull. For functions other than GPIO, the OE
+ * is hard-wired according to the function. For GPIO mode,
+ * OE is controlled by gpiolib.
+ *
+ * Available settings differ by target; see the gpiomux header
+ * specific to your target arch for available configurations.
+ *
+ * @active: The configuration to be installed when the line is
+ * active, or its reference count is > 0.
+ * @suspended: The configuration to be installed when the line
+ * is suspended, or its reference count is 0.
+ * @ref: The reference count of the line. For internal use of
+ * the gpiomux framework only.
+ */
+struct msm_gpiomux_config {
+ gpiomux_config_t active;
+ gpiomux_config_t suspended;
+ unsigned ref;
+};
+
+/**
+ * @GPIOMUX_VALID: If set, the config field contains 'good data'.
+ * The absence of this bit will prevent the gpiomux
+ * system from applying the configuration under all
+ * circumstances.
+ */
+enum {
+ GPIOMUX_VALID = BIT(sizeof(gpiomux_config_t) * BITS_PER_BYTE - 1),
+ GPIOMUX_CTL_MASK = GPIOMUX_VALID,
+};
+
+#ifdef CONFIG_MSM_GPIOMUX
+
+/* Each architecture must provide its own instance of this table.
+ * To avoid having gpiomux manage any given gpio, one or both of
+ * the entries can avoid setting GPIOMUX_VALID - the absence
+ * of that flag will prevent the configuration from being applied
+ * during state transitions.
+ */
+extern struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS];
+
+/* Increment a gpio's reference count, possibly activating the line. */
+int __must_check msm_gpiomux_get(unsigned gpio);
+
+/* Decrement a gpio's reference count, possibly suspending the line. */
+int msm_gpiomux_put(unsigned gpio);
+
+/* Install a new configuration to the gpio line. To avoid overwriting
+ * a configuration, leave the VALID bit out.
+ */
+int msm_gpiomux_write(unsigned gpio,
+ gpiomux_config_t active,
+ gpiomux_config_t suspended);
+
+/* Architecture-internal function for use by the framework only.
+ * This function can assume the following:
+ * - the gpio value has passed a bounds-check
+ * - the gpiomux spinlock has been obtained
+ *
+ * This function is not for public consumption. External users
+ * should use msm_gpiomux_write.
+ */
+void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val);
+#else
+static inline int __must_check msm_gpiomux_get(unsigned gpio)
+{
+ return -ENOSYS;
+}
+
+static inline int msm_gpiomux_put(unsigned gpio)
+{
+ return -ENOSYS;
+}
+
+static inline int msm_gpiomux_write(unsigned gpio,
+ gpiomux_config_t active,
+ gpiomux_config_t suspended)
+{
+ return -ENOSYS;
+}
+#endif
+#endif
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index 5a79bcf50413..6abf4a6eadc1 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -33,6 +33,8 @@ struct msm_acpu_clock_platform_data
struct clk;
+extern struct sys_timer msm_timer;
+
/* common init routines for use by arch/arm/mach-msm/board-*.c */
void __init msm_add_devices(void);
diff --git a/arch/arm/mach-msm/include/mach/debug-macro.S b/arch/arm/mach-msm/include/mach/debug-macro.S
index 528750f307e9..fbd5d90dcc8c 100644
--- a/arch/arm/mach-msm/include/mach/debug-macro.S
+++ b/arch/arm/mach-msm/include/mach/debug-macro.S
@@ -19,13 +19,10 @@
#include <mach/hardware.h>
#include <mach/msm_iomap.h>
-#ifdef CONFIG_MSM_DEBUG_UART
- .macro addruart, rx, tmp
- @ see if the MMU is enabled and select appropriate base address
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1
- ldreq \rx, =MSM_DEBUG_UART_PHYS
- ldrne \rx, =MSM_DEBUG_UART_BASE
+#ifdef CONFIG_HAS_MSM_DEBUG_UART_PHYS
+ .macro addruart, rp, rv
+ ldr \rp, =MSM_DEBUG_UART_PHYS
+ ldr \rv, =MSM_DEBUG_UART_BASE
.endm
.macro senduart,rd,rx
@@ -39,16 +36,7 @@
tst \rd, #0x04
beq 1001b
.endm
-#else
- .macro addruart, rx, tmp
- .endm
-
- .macro senduart,rd,rx
- .endm
-
- .macro waituart,rd,rx
- .endm
-#endif
.macro busyuart,rd,rx
.endm
+#endif
diff --git a/arch/arm/mach-msm/include/mach/dma.h b/arch/arm/mach-msm/include/mach/dma.h
index 00f9bbfadbe6..05583f569524 100644
--- a/arch/arm/mach-msm/include/mach/dma.h
+++ b/arch/arm/mach-msm/include/mach/dma.h
@@ -32,10 +32,18 @@ struct msm_dmov_cmd {
void *data;
};
+#ifndef CONFIG_ARCH_MSM8X60
void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd);
void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful);
int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr);
-
+#else
+static inline
+void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd) { }
+static inline
+void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful) { }
+static inline
+int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr) { return -EIO; }
+#endif
#define DMOV_SD0(off, ch) (MSM_DMOV_BASE + 0x0000 + (off) + ((ch) << 2))
diff --git a/arch/arm/mach-msm/include/mach/entry-macro-qgic.S b/arch/arm/mach-msm/include/mach/entry-macro-qgic.S
new file mode 100644
index 000000000000..4dc99aa65d07
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/entry-macro-qgic.S
@@ -0,0 +1,88 @@
+/*
+ * Low-level IRQ helper macros
+ *
+ * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <mach/hardware.h>
+#include <asm/hardware/gic.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =gic_cpu_base_addr
+ ldr \base, [\base]
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ /*
+ * The interrupt numbering scheme is defined in the
+ * interrupt controller spec. To wit:
+ *
+ * Migrated the code from ARM MP port to be more consistant
+ * with interrupt processing , the following still holds true
+ * however, all interrupts are treated the same regardless of
+ * if they are local IPI or PPI
+ *
+ * Interrupts 0-15 are IPI
+ * 16-31 are PPI
+ * (16-18 are the timers)
+ * 32-1020 are global
+ * 1021-1022 are reserved
+ * 1023 is "spurious" (no interrupt)
+ *
+ * A simple read from the controller will tell us the number of the
+ * highest priority enabled interrupt. We then just need to check
+ * whether it is in the valid range for an IRQ (0-1020 inclusive).
+ *
+ * Base ARM code assumes that the local (private) peripheral interrupts
+ * are not valid, we treat them differently, in that the privates are
+ * handled like normal shared interrupts with the exception that only
+ * one processor can register the interrupt and the handler must be
+ * the same for all processors.
+ */
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+ ldr \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 =srcCPU,
+ 9-0 =int # */
+
+ bic \irqnr, \irqstat, #0x1c00 @mask src
+ cmp \irqnr, #15
+ ldr \tmp, =1021
+ cmpcc \irqnr, \irqnr
+ cmpne \irqnr, \tmp
+ cmpcs \irqnr, \irqnr
+
+ .endm
+
+ /* We assume that irqstat (the raw value of the IRQ acknowledge
+ * register) is preserved from the macro above.
+ * If there is an IPI, we immediately signal end of interrupt on the
+ * controller, since this requires the original irqstat value which
+ * we won't easily be able to recreate later.
+ */
+ .macro test_for_ipi, irqnr, irqstat, base, tmp
+ bic \irqnr, \irqstat, #0x1c00
+ cmp \irqnr, #16
+ strcc \irqstat, [\base, #GIC_CPU_EOI]
+ cmpcs \irqnr, \irqnr
+ .endm
+
+ /* As above, this assumes that irqstat and base are preserved.. */
+
+ .macro test_for_ltirq, irqnr, irqstat, base, tmp
+ bic \irqnr, \irqstat, #0x1c00
+ mov \tmp, #0
+ cmp \irqnr, #16
+ moveq \tmp, #1
+ streq \irqstat, [\base, #GIC_CPU_EOI]
+ cmp \tmp, #0
+ .endm
diff --git a/arch/arm/mach-msm/include/mach/entry-macro-vic.S b/arch/arm/mach-msm/include/mach/entry-macro-vic.S
new file mode 100644
index 000000000000..70563ed11b36
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/entry-macro-vic.S
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <mach/msm_iomap.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ @ enable imprecise aborts
+ cpsie a
+ mov \base, #MSM_VIC_BASE
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ @ 0xD0 has irq# or old irq# if the irq has been handled
+ @ 0xD4 has irq# or -1 if none pending *but* if you just
+ @ read 0xD4 you never get the first irq for some reason
+ ldr \irqnr, [\base, #0xD0]
+ ldr \irqnr, [\base, #0xD4]
+ cmp \irqnr, #0xffffffff
+ .endm
diff --git a/arch/arm/mach-msm/include/mach/entry-macro.S b/arch/arm/mach-msm/include/mach/entry-macro.S
index d2259486bcb1..b16f082eeb6f 100644
--- a/arch/arm/mach-msm/include/mach/entry-macro.S
+++ b/arch/arm/mach-msm/include/mach/entry-macro.S
@@ -1,38 +1,23 @@
-/* arch/arm/mach-msm7200/include/mach/entry-macro.S
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
*
- * Copyright (C) 2007 Google, Inc.
- * Author: Brian Swetland <swetland@google.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
*/
-#include <mach/msm_iomap.h>
-
- .macro disable_fiq
- .endm
-
- .macro get_irqnr_preamble, base, tmp
- @ enable imprecise aborts
- cpsie a
- mov \base, #MSM_VIC_BASE
- .endm
-
- .macro arch_ret_to_user, tmp1, tmp2
- .endm
-
- .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
- @ 0xD0 has irq# or old irq# if the irq has been handled
- @ 0xD4 has irq# or -1 if none pending *but* if you just
- @ read 0xD4 you never get the first irq for some reason
- ldr \irqnr, [\base, #0xD0]
- ldr \irqnr, [\base, #0xD4]
- cmp \irqnr, #0xffffffff
- .endm
+#if defined(CONFIG_ARM_GIC)
+#include <mach/entry-macro-qgic.S>
+#else
+#include <mach/entry-macro-vic.S>
+#endif
diff --git a/arch/arm/mach-msm/include/mach/gpio.h b/arch/arm/mach-msm/include/mach/gpio.h
index 83e47c0d5c2e..36ad50d3bfaa 100644
--- a/arch/arm/mach-msm/include/mach/gpio.h
+++ b/arch/arm/mach-msm/include/mach/gpio.h
@@ -23,127 +23,4 @@
#define gpio_cansleep __gpio_cansleep
#define gpio_to_irq __gpio_to_irq
-/**
- * struct msm_gpio - GPIO pin description
- * @gpio_cfg - configuration bitmap, as per gpio_tlmm_config()
- * @label - textual label
- *
- * Usually, GPIO's are operated by sets.
- * This struct accumulate all GPIO information in single source
- * and facilitete group operations provided by msm_gpios_xxx()
- */
-struct msm_gpio {
- u32 gpio_cfg;
- const char *label;
-};
-
-/**
- * msm_gpios_request_enable() - request and enable set of GPIOs
- *
- * Request and configure set of GPIO's
- * In case of error, all operations rolled back.
- * Return error code.
- *
- * @table: GPIO table
- * @size: number of entries in @table
- */
-int msm_gpios_request_enable(const struct msm_gpio *table, int size);
-
-/**
- * msm_gpios_disable_free() - disable and free set of GPIOs
- *
- * @table: GPIO table
- * @size: number of entries in @table
- */
-void msm_gpios_disable_free(const struct msm_gpio *table, int size);
-
-/**
- * msm_gpios_request() - request set of GPIOs
- * In case of error, all operations rolled back.
- * Return error code.
- *
- * @table: GPIO table
- * @size: number of entries in @table
- */
-int msm_gpios_request(const struct msm_gpio *table, int size);
-
-/**
- * msm_gpios_free() - free set of GPIOs
- *
- * @table: GPIO table
- * @size: number of entries in @table
- */
-void msm_gpios_free(const struct msm_gpio *table, int size);
-
-/**
- * msm_gpios_enable() - enable set of GPIOs
- * In case of error, all operations rolled back.
- * Return error code.
- *
- * @table: GPIO table
- * @size: number of entries in @table
- */
-int msm_gpios_enable(const struct msm_gpio *table, int size);
-
-/**
- * msm_gpios_disable() - disable set of GPIOs
- *
- * @table: GPIO table
- * @size: number of entries in @table
- */
-void msm_gpios_disable(const struct msm_gpio *table, int size);
-
-/* GPIO TLMM (Top Level Multiplexing) Definitions */
-
-/* GPIO TLMM: Function -- GPIO specific */
-
-/* GPIO TLMM: Direction */
-enum {
- GPIO_INPUT,
- GPIO_OUTPUT,
-};
-
-/* GPIO TLMM: Pullup/Pulldown */
-enum {
- GPIO_NO_PULL,
- GPIO_PULL_DOWN,
- GPIO_KEEPER,
- GPIO_PULL_UP,
-};
-
-/* GPIO TLMM: Drive Strength */
-enum {
- GPIO_2MA,
- GPIO_4MA,
- GPIO_6MA,
- GPIO_8MA,
- GPIO_10MA,
- GPIO_12MA,
- GPIO_14MA,
- GPIO_16MA,
-};
-
-enum {
- GPIO_ENABLE,
- GPIO_DISABLE,
-};
-
-#define GPIO_CFG(gpio, func, dir, pull, drvstr) \
- ((((gpio) & 0x3FF) << 4) | \
- ((func) & 0xf) | \
- (((dir) & 0x1) << 14) | \
- (((pull) & 0x3) << 15) | \
- (((drvstr) & 0xF) << 17))
-
-/**
- * extract GPIO pin from bit-field used for gpio_tlmm_config
- */
-#define GPIO_PIN(gpio_cfg) (((gpio_cfg) >> 4) & 0x3ff)
-#define GPIO_FUNC(gpio_cfg) (((gpio_cfg) >> 0) & 0xf)
-#define GPIO_DIR(gpio_cfg) (((gpio_cfg) >> 14) & 0x1)
-#define GPIO_PULL(gpio_cfg) (((gpio_cfg) >> 15) & 0x3)
-#define GPIO_DRVSTR(gpio_cfg) (((gpio_cfg) >> 17) & 0xf)
-
-int gpio_tlmm_config(unsigned config, unsigned disable);
-
#endif /* __ASM_ARCH_MSM_GPIO_H */
diff --git a/arch/arm/mach-msm/include/mach/io.h b/arch/arm/mach-msm/include/mach/io.h
index c35b29f9ac0f..7386e732baad 100644
--- a/arch/arm/mach-msm/include/mach/io.h
+++ b/arch/arm/mach-msm/include/mach/io.h
@@ -28,6 +28,7 @@ void __iomem *__msm_ioremap(unsigned long phys_addr, size_t size, unsigned int m
void msm_map_qsd8x50_io(void);
void msm_map_msm7x30_io(void);
+void msm_map_msm8x60_io(void);
extern unsigned int msm_shared_ram_phys;
diff --git a/arch/arm/mach-msm/include/mach/iommu.h b/arch/arm/mach-msm/include/mach/iommu.h
new file mode 100644
index 000000000000..218ef5732a24
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/iommu.h
@@ -0,0 +1,103 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef MSM_IOMMU_H
+#define MSM_IOMMU_H
+
+#include <linux/interrupt.h>
+
+/* Maximum number of Machine IDs that we are allowing to be mapped to the same
+ * context bank. The number of MIDs mapped to the same CB does not affect
+ * performance, but there is a practical limit on how many distinct MIDs may
+ * be present. These mappings are typically determined at design time and are
+ * not expected to change at run time.
+ */
+#define MAX_NUM_MIDS 16
+
+/**
+ * struct msm_iommu_dev - a single IOMMU hardware instance
+ * name Human-readable name given to this IOMMU HW instance
+ * clk_rate Rate to set for this IOMMU's clock, if applicable to this
+ * particular IOMMU. 0 means don't set a rate.
+ * -1 means it is an AXI clock with no valid rate
+ *
+ */
+struct msm_iommu_dev {
+ const char *name;
+ int clk_rate;
+};
+
+/**
+ * struct msm_iommu_ctx_dev - an IOMMU context bank instance
+ * name Human-readable name given to this context bank
+ * num Index of this context bank within the hardware
+ * mids List of Machine IDs that are to be mapped into this context
+ * bank, terminated by -1. The MID is a set of signals on the
+ * AXI bus that identifies the function associated with a specific
+ * memory request. (See ARM spec).
+ */
+struct msm_iommu_ctx_dev {
+ const char *name;
+ int num;
+ int mids[MAX_NUM_MIDS];
+};
+
+
+/**
+ * struct msm_iommu_drvdata - A single IOMMU hardware instance
+ * @base: IOMMU config port base address (VA)
+ * @irq: Interrupt number
+ *
+ * A msm_iommu_drvdata holds the global driver data about a single piece
+ * of an IOMMU hardware instance.
+ */
+struct msm_iommu_drvdata {
+ void __iomem *base;
+ int irq;
+};
+
+/**
+ * struct msm_iommu_ctx_drvdata - an IOMMU context bank instance
+ * @num: Hardware context number of this context
+ * @pdev: Platform device associated wit this HW instance
+ * @attached_elm: List element for domains to track which devices are
+ * attached to them
+ *
+ * A msm_iommu_ctx_drvdata holds the driver data for a single context bank
+ * within each IOMMU hardware instance
+ */
+struct msm_iommu_ctx_drvdata {
+ int num;
+ struct platform_device *pdev;
+ struct list_head attached_elm;
+};
+
+/*
+ * Look up an IOMMU context device by its context name. NULL if none found.
+ * Useful for testing and drivers that do not yet fully have IOMMU stuff in
+ * their platform devices.
+ */
+struct device *msm_iommu_get_ctx(const char *ctx_name);
+
+/*
+ * Interrupt handler for the IOMMU context fault interrupt. Hooking the
+ * interrupt is not supported in the API yet, but this will print an error
+ * message and dump useful IOMMU registers.
+ */
+irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id);
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h b/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h
new file mode 100644
index 000000000000..f9386d3a2f77
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h
@@ -0,0 +1,1871 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef __ARCH_ARM_MACH_MSM_IOMMU_HW_8XXX_H
+#define __ARCH_ARM_MACH_MSM_IOMMU_HW_8XXX_H
+
+#define CTX_SHIFT 12
+
+#define GET_GLOBAL_REG(reg, base) (readl((base) + (reg)))
+#define GET_CTX_REG(reg, base, ctx) \
+ (readl((base) + (reg) + ((ctx) << CTX_SHIFT)))
+
+#define SET_GLOBAL_REG(reg, base, val) writel((val), ((base) + (reg)))
+
+#define SET_CTX_REG(reg, base, ctx, val) \
+ writel((val), ((base) + (reg) + ((ctx) << CTX_SHIFT)))
+
+/* Wrappers for numbered registers */
+#define SET_GLOBAL_REG_N(b, n, r, v) SET_GLOBAL_REG(b, ((r) + (n << 2)), (v))
+#define GET_GLOBAL_REG_N(b, n, r) GET_GLOBAL_REG(b, ((r) + (n << 2)))
+
+/* Field wrappers */
+#define GET_GLOBAL_FIELD(b, r, F) GET_FIELD(((b) + (r)), F##_MASK, F##_SHIFT)
+#define GET_CONTEXT_FIELD(b, c, r, F) \
+ GET_FIELD(((b) + (r) + ((c) << CTX_SHIFT)), F##_MASK, F##_SHIFT)
+
+#define SET_GLOBAL_FIELD(b, r, F, v) \
+ SET_FIELD(((b) + (r)), F##_MASK, F##_SHIFT, (v))
+#define SET_CONTEXT_FIELD(b, c, r, F, v) \
+ SET_FIELD(((b) + (r) + ((c) << CTX_SHIFT)), F##_MASK, F##_SHIFT, (v))
+
+#define GET_FIELD(addr, mask, shift) ((readl(addr) >> (shift)) & (mask))
+
+#define SET_FIELD(addr, mask, shift, v) \
+do { \
+ int t = readl(addr); \
+ writel((t & ~((mask) << (shift))) + (((v) & (mask)) << (shift)), addr);\
+} while (0)
+
+
+#define NUM_FL_PTE 4096
+#define NUM_SL_PTE 256
+
+/* First-level page table bits */
+#define FL_BASE_MASK 0xFFFFFC00
+#define FL_TYPE_TABLE (1 << 0)
+#define FL_TYPE_SECT (2 << 0)
+#define FL_SUPERSECTION (1 << 18)
+#define FL_AP_WRITE (1 << 10)
+#define FL_AP_READ (1 << 11)
+#define FL_SHARED (1 << 16)
+#define FL_OFFSET(va) (((va) & 0xFFF00000) >> 20)
+
+/* Second-level page table bits */
+#define SL_BASE_MASK_LARGE 0xFFFF0000
+#define SL_BASE_MASK_SMALL 0xFFFFF000
+#define SL_TYPE_LARGE (1 << 0)
+#define SL_TYPE_SMALL (2 << 0)
+#define SL_AP0 (1 << 4)
+#define SL_AP1 (2 << 4)
+#define SL_SHARED (1 << 10)
+#define SL_OFFSET(va) (((va) & 0xFF000) >> 12)
+
+/* Global register setters / getters */
+#define SET_M2VCBR_N(b, N, v) SET_GLOBAL_REG_N(M2VCBR_N, N, (b), (v))
+#define SET_CBACR_N(b, N, v) SET_GLOBAL_REG_N(CBACR_N, N, (b), (v))
+#define SET_TLBRSW(b, v) SET_GLOBAL_REG(TLBRSW, (b), (v))
+#define SET_TLBTR0(b, v) SET_GLOBAL_REG(TLBTR0, (b), (v))
+#define SET_TLBTR1(b, v) SET_GLOBAL_REG(TLBTR1, (b), (v))
+#define SET_TLBTR2(b, v) SET_GLOBAL_REG(TLBTR2, (b), (v))
+#define SET_TESTBUSCR(b, v) SET_GLOBAL_REG(TESTBUSCR, (b), (v))
+#define SET_GLOBAL_TLBIALL(b, v) SET_GLOBAL_REG(GLOBAL_TLBIALL, (b), (v))
+#define SET_TLBIVMID(b, v) SET_GLOBAL_REG(TLBIVMID, (b), (v))
+#define SET_CR(b, v) SET_GLOBAL_REG(CR, (b), (v))
+#define SET_EAR(b, v) SET_GLOBAL_REG(EAR, (b), (v))
+#define SET_ESR(b, v) SET_GLOBAL_REG(ESR, (b), (v))
+#define SET_ESRRESTORE(b, v) SET_GLOBAL_REG(ESRRESTORE, (b), (v))
+#define SET_ESYNR0(b, v) SET_GLOBAL_REG(ESYNR0, (b), (v))
+#define SET_ESYNR1(b, v) SET_GLOBAL_REG(ESYNR1, (b), (v))
+#define SET_RPU_ACR(b, v) SET_GLOBAL_REG(RPU_ACR, (b), (v))
+
+#define GET_M2VCBR_N(b, N) GET_GLOBAL_REG_N(M2VCBR_N, N, (b))
+#define GET_CBACR_N(b, N) GET_GLOBAL_REG_N(CBACR_N, N, (b))
+#define GET_TLBTR0(b) GET_GLOBAL_REG(TLBTR0, (b))
+#define GET_TLBTR1(b) GET_GLOBAL_REG(TLBTR1, (b))
+#define GET_TLBTR2(b) GET_GLOBAL_REG(TLBTR2, (b))
+#define GET_TESTBUSCR(b) GET_GLOBAL_REG(TESTBUSCR, (b))
+#define GET_GLOBAL_TLBIALL(b) GET_GLOBAL_REG(GLOBAL_TLBIALL, (b))
+#define GET_TLBIVMID(b) GET_GLOBAL_REG(TLBIVMID, (b))
+#define GET_CR(b) GET_GLOBAL_REG(CR, (b))
+#define GET_EAR(b) GET_GLOBAL_REG(EAR, (b))
+#define GET_ESR(b) GET_GLOBAL_REG(ESR, (b))
+#define GET_ESRRESTORE(b) GET_GLOBAL_REG(ESRRESTORE, (b))
+#define GET_ESYNR0(b) GET_GLOBAL_REG(ESYNR0, (b))
+#define GET_ESYNR1(b) GET_GLOBAL_REG(ESYNR1, (b))
+#define GET_REV(b) GET_GLOBAL_REG(REV, (b))
+#define GET_IDR(b) GET_GLOBAL_REG(IDR, (b))
+#define GET_RPU_ACR(b) GET_GLOBAL_REG(RPU_ACR, (b))
+
+
+/* Context register setters/getters */
+#define SET_SCTLR(b, c, v) SET_CTX_REG(SCTLR, (b), (c), (v))
+#define SET_ACTLR(b, c, v) SET_CTX_REG(ACTLR, (b), (c), (v))
+#define SET_CONTEXTIDR(b, c, v) SET_CTX_REG(CONTEXTIDR, (b), (c), (v))
+#define SET_TTBR0(b, c, v) SET_CTX_REG(TTBR0, (b), (c), (v))
+#define SET_TTBR1(b, c, v) SET_CTX_REG(TTBR1, (b), (c), (v))
+#define SET_TTBCR(b, c, v) SET_CTX_REG(TTBCR, (b), (c), (v))
+#define SET_PAR(b, c, v) SET_CTX_REG(PAR, (b), (c), (v))
+#define SET_FSR(b, c, v) SET_CTX_REG(FSR, (b), (c), (v))
+#define SET_FSRRESTORE(b, c, v) SET_CTX_REG(FSRRESTORE, (b), (c), (v))
+#define SET_FAR(b, c, v) SET_CTX_REG(FAR, (b), (c), (v))
+#define SET_FSYNR0(b, c, v) SET_CTX_REG(FSYNR0, (b), (c), (v))
+#define SET_FSYNR1(b, c, v) SET_CTX_REG(FSYNR1, (b), (c), (v))
+#define SET_PRRR(b, c, v) SET_CTX_REG(PRRR, (b), (c), (v))
+#define SET_NMRR(b, c, v) SET_CTX_REG(NMRR, (b), (c), (v))
+#define SET_TLBLKCR(b, c, v) SET_CTX_REG(TLBLCKR, (b), (c), (v))
+#define SET_V2PSR(b, c, v) SET_CTX_REG(V2PSR, (b), (c), (v))
+#define SET_TLBFLPTER(b, c, v) SET_CTX_REG(TLBFLPTER, (b), (c), (v))
+#define SET_TLBSLPTER(b, c, v) SET_CTX_REG(TLBSLPTER, (b), (c), (v))
+#define SET_BFBCR(b, c, v) SET_CTX_REG(BFBCR, (b), (c), (v))
+#define SET_CTX_TLBIALL(b, c, v) SET_CTX_REG(CTX_TLBIALL, (b), (c), (v))
+#define SET_TLBIASID(b, c, v) SET_CTX_REG(TLBIASID, (b), (c), (v))
+#define SET_TLBIVA(b, c, v) SET_CTX_REG(TLBIVA, (b), (c), (v))
+#define SET_TLBIVAA(b, c, v) SET_CTX_REG(TLBIVAA, (b), (c), (v))
+#define SET_V2PPR(b, c, v) SET_CTX_REG(V2PPR, (b), (c), (v))
+#define SET_V2PPW(b, c, v) SET_CTX_REG(V2PPW, (b), (c), (v))
+#define SET_V2PUR(b, c, v) SET_CTX_REG(V2PUR, (b), (c), (v))
+#define SET_V2PUW(b, c, v) SET_CTX_REG(V2PUW, (b), (c), (v))
+#define SET_RESUME(b, c, v) SET_CTX_REG(RESUME, (b), (c), (v))
+
+#define GET_SCTLR(b, c) GET_CTX_REG(SCTLR, (b), (c))
+#define GET_ACTLR(b, c) GET_CTX_REG(ACTLR, (b), (c))
+#define GET_CONTEXTIDR(b, c) GET_CTX_REG(CONTEXTIDR, (b), (c))
+#define GET_TTBR0(b, c) GET_CTX_REG(TTBR0, (b), (c))
+#define GET_TTBR1(b, c) GET_CTX_REG(TTBR1, (b), (c))
+#define GET_TTBCR(b, c) GET_CTX_REG(TTBCR, (b), (c))
+#define GET_PAR(b, c) GET_CTX_REG(PAR, (b), (c))
+#define GET_FSR(b, c) GET_CTX_REG(FSR, (b), (c))
+#define GET_FSRRESTORE(b, c) GET_CTX_REG(FSRRESTORE, (b), (c))
+#define GET_FAR(b, c) GET_CTX_REG(FAR, (b), (c))
+#define GET_FSYNR0(b, c) GET_CTX_REG(FSYNR0, (b), (c))
+#define GET_FSYNR1(b, c) GET_CTX_REG(FSYNR1, (b), (c))
+#define GET_PRRR(b, c) GET_CTX_REG(PRRR, (b), (c))
+#define GET_NMRR(b, c) GET_CTX_REG(NMRR, (b), (c))
+#define GET_TLBLCKR(b, c) GET_CTX_REG(TLBLCKR, (b), (c))
+#define GET_V2PSR(b, c) GET_CTX_REG(V2PSR, (b), (c))
+#define GET_TLBFLPTER(b, c) GET_CTX_REG(TLBFLPTER, (b), (c))
+#define GET_TLBSLPTER(b, c) GET_CTX_REG(TLBSLPTER, (b), (c))
+#define GET_BFBCR(b, c) GET_CTX_REG(BFBCR, (b), (c))
+#define GET_CTX_TLBIALL(b, c) GET_CTX_REG(CTX_TLBIALL, (b), (c))
+#define GET_TLBIASID(b, c) GET_CTX_REG(TLBIASID, (b), (c))
+#define GET_TLBIVA(b, c) GET_CTX_REG(TLBIVA, (b), (c))
+#define GET_TLBIVAA(b, c) GET_CTX_REG(TLBIVAA, (b), (c))
+#define GET_V2PPR(b, c) GET_CTX_REG(V2PPR, (b), (c))
+#define GET_V2PPW(b, c) GET_CTX_REG(V2PPW, (b), (c))
+#define GET_V2PUR(b, c) GET_CTX_REG(V2PUR, (b), (c))
+#define GET_V2PUW(b, c) GET_CTX_REG(V2PUW, (b), (c))
+#define GET_RESUME(b, c) GET_CTX_REG(RESUME, (b), (c))
+
+
+/* Global field setters / getters */
+/* Global Field Setters: */
+/* CBACR_N */
+#define SET_RWVMID(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWVMID, v)
+#define SET_RWE(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWE, v)
+#define SET_RWGE(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWGE, v)
+#define SET_CBVMID(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), CBVMID, v)
+#define SET_IRPTNDX(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), IRPTNDX, v)
+
+
+/* M2VCBR_N */
+#define SET_VMID(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), VMID, v)
+#define SET_CBNDX(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), CBNDX, v)
+#define SET_BYPASSD(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BYPASSD, v)
+#define SET_BPRCOSH(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCOSH, v)
+#define SET_BPRCISH(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCISH, v)
+#define SET_BPRCNSH(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCNSH, v)
+#define SET_BPSHCFG(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPSHCFG, v)
+#define SET_NSCFG(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), NSCFG, v)
+#define SET_BPMTCFG(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPMTCFG, v)
+#define SET_BPMEMTYPE(b, n, v) \
+ SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPMEMTYPE, v)
+
+
+/* CR */
+#define SET_RPUE(b, v) SET_GLOBAL_FIELD(b, CR, RPUE, v)
+#define SET_RPUERE(b, v) SET_GLOBAL_FIELD(b, CR, RPUERE, v)
+#define SET_RPUEIE(b, v) SET_GLOBAL_FIELD(b, CR, RPUEIE, v)
+#define SET_DCDEE(b, v) SET_GLOBAL_FIELD(b, CR, DCDEE, v)
+#define SET_CLIENTPD(b, v) SET_GLOBAL_FIELD(b, CR, CLIENTPD, v)
+#define SET_STALLD(b, v) SET_GLOBAL_FIELD(b, CR, STALLD, v)
+#define SET_TLBLKCRWE(b, v) SET_GLOBAL_FIELD(b, CR, TLBLKCRWE, v)
+#define SET_CR_TLBIALLCFG(b, v) SET_GLOBAL_FIELD(b, CR, CR_TLBIALLCFG, v)
+#define SET_TLBIVMIDCFG(b, v) SET_GLOBAL_FIELD(b, CR, TLBIVMIDCFG, v)
+#define SET_CR_HUME(b, v) SET_GLOBAL_FIELD(b, CR, CR_HUME, v)
+
+
+/* ESR */
+#define SET_CFG(b, v) SET_GLOBAL_FIELD(b, ESR, CFG, v)
+#define SET_BYPASS(b, v) SET_GLOBAL_FIELD(b, ESR, BYPASS, v)
+#define SET_ESR_MULTI(b, v) SET_GLOBAL_FIELD(b, ESR, ESR_MULTI, v)
+
+
+/* ESYNR0 */
+#define SET_ESYNR0_AMID(b, v) SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_AMID, v)
+#define SET_ESYNR0_APID(b, v) SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_APID, v)
+#define SET_ESYNR0_ABID(b, v) SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_ABID, v)
+#define SET_ESYNR0_AVMID(b, v) SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_AVMID, v)
+#define SET_ESYNR0_ATID(b, v) SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_ATID, v)
+
+
+/* ESYNR1 */
+#define SET_ESYNR1_AMEMTYPE(b, v) \
+ SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AMEMTYPE, v)
+#define SET_ESYNR1_ASHARED(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ASHARED, v)
+#define SET_ESYNR1_AINNERSHARED(b, v) \
+ SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AINNERSHARED, v)
+#define SET_ESYNR1_APRIV(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_APRIV, v)
+#define SET_ESYNR1_APROTNS(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_APROTNS, v)
+#define SET_ESYNR1_AINST(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AINST, v)
+#define SET_ESYNR1_AWRITE(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AWRITE, v)
+#define SET_ESYNR1_ABURST(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ABURST, v)
+#define SET_ESYNR1_ALEN(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ALEN, v)
+#define SET_ESYNR1_ASIZE(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ASIZE, v)
+#define SET_ESYNR1_ALOCK(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ALOCK, v)
+#define SET_ESYNR1_AOOO(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AOOO, v)
+#define SET_ESYNR1_AFULL(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AFULL, v)
+#define SET_ESYNR1_AC(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AC, v)
+#define SET_ESYNR1_DCD(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_DCD, v)
+
+
+/* TESTBUSCR */
+#define SET_TBE(b, v) SET_GLOBAL_FIELD(b, TESTBUSCR, TBE, v)
+#define SET_SPDMBE(b, v) SET_GLOBAL_FIELD(b, TESTBUSCR, SPDMBE, v)
+#define SET_WGSEL(b, v) SET_GLOBAL_FIELD(b, TESTBUSCR, WGSEL, v)
+#define SET_TBLSEL(b, v) SET_GLOBAL_FIELD(b, TESTBUSCR, TBLSEL, v)
+#define SET_TBHSEL(b, v) SET_GLOBAL_FIELD(b, TESTBUSCR, TBHSEL, v)
+#define SET_SPDM0SEL(b, v) SET_GLOBAL_FIELD(b, TESTBUSCR, SPDM0SEL, v)
+#define SET_SPDM1SEL(b, v) SET_GLOBAL_FIELD(b, TESTBUSCR, SPDM1SEL, v)
+#define SET_SPDM2SEL(b, v) SET_GLOBAL_FIELD(b, TESTBUSCR, SPDM2SEL, v)
+#define SET_SPDM3SEL(b, v) SET_GLOBAL_FIELD(b, TESTBUSCR, SPDM3SEL, v)
+
+
+/* TLBIVMID */
+#define SET_TLBIVMID_VMID(b, v) SET_GLOBAL_FIELD(b, TLBIVMID, TLBIVMID_VMID, v)
+
+
+/* TLBRSW */
+#define SET_TLBRSW_INDEX(b, v) SET_GLOBAL_FIELD(b, TLBRSW, TLBRSW_INDEX, v)
+#define SET_TLBBFBS(b, v) SET_GLOBAL_FIELD(b, TLBRSW, TLBBFBS, v)
+
+
+/* TLBTR0 */
+#define SET_PR(b, v) SET_GLOBAL_FIELD(b, TLBTR0, PR, v)
+#define SET_PW(b, v) SET_GLOBAL_FIELD(b, TLBTR0, PW, v)
+#define SET_UR(b, v) SET_GLOBAL_FIELD(b, TLBTR0, UR, v)
+#define SET_UW(b, v) SET_GLOBAL_FIELD(b, TLBTR0, UW, v)
+#define SET_XN(b, v) SET_GLOBAL_FIELD(b, TLBTR0, XN, v)
+#define SET_NSDESC(b, v) SET_GLOBAL_FIELD(b, TLBTR0, NSDESC, v)
+#define SET_ISH(b, v) SET_GLOBAL_FIELD(b, TLBTR0, ISH, v)
+#define SET_SH(b, v) SET_GLOBAL_FIELD(b, TLBTR0, SH, v)
+#define SET_MT(b, v) SET_GLOBAL_FIELD(b, TLBTR0, MT, v)
+#define SET_DPSIZR(b, v) SET_GLOBAL_FIELD(b, TLBTR0, DPSIZR, v)
+#define SET_DPSIZC(b, v) SET_GLOBAL_FIELD(b, TLBTR0, DPSIZC, v)
+
+
+/* TLBTR1 */
+#define SET_TLBTR1_VMID(b, v) SET_GLOBAL_FIELD(b, TLBTR1, TLBTR1_VMID, v)
+#define SET_TLBTR1_PA(b, v) SET_GLOBAL_FIELD(b, TLBTR1, TLBTR1_PA, v)
+
+
+/* TLBTR2 */
+#define SET_TLBTR2_ASID(b, v) SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_ASID, v)
+#define SET_TLBTR2_V(b, v) SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_V, v)
+#define SET_TLBTR2_NSTID(b, v) SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_NSTID, v)
+#define SET_TLBTR2_NV(b, v) SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_NV, v)
+#define SET_TLBTR2_VA(b, v) SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_VA, v)
+
+
+/* Global Field Getters */
+/* CBACR_N */
+#define GET_RWVMID(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWVMID)
+#define GET_RWE(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWE)
+#define GET_RWGE(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWGE)
+#define GET_CBVMID(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), CBVMID)
+#define GET_IRPTNDX(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), IRPTNDX)
+
+
+/* M2VCBR_N */
+#define GET_VMID(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), VMID)
+#define GET_CBNDX(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), CBNDX)
+#define GET_BYPASSD(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BYPASSD)
+#define GET_BPRCOSH(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCOSH)
+#define GET_BPRCISH(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCISH)
+#define GET_BPRCNSH(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCNSH)
+#define GET_BPSHCFG(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPSHCFG)
+#define GET_NSCFG(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), NSCFG)
+#define GET_BPMTCFG(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPMTCFG)
+#define GET_BPMEMTYPE(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPMEMTYPE)
+
+
+/* CR */
+#define GET_RPUE(b) GET_GLOBAL_FIELD(b, CR, RPUE)
+#define GET_RPUERE(b) GET_GLOBAL_FIELD(b, CR, RPUERE)
+#define GET_RPUEIE(b) GET_GLOBAL_FIELD(b, CR, RPUEIE)
+#define GET_DCDEE(b) GET_GLOBAL_FIELD(b, CR, DCDEE)
+#define GET_CLIENTPD(b) GET_GLOBAL_FIELD(b, CR, CLIENTPD)
+#define GET_STALLD(b) GET_GLOBAL_FIELD(b, CR, STALLD)
+#define GET_TLBLKCRWE(b) GET_GLOBAL_FIELD(b, CR, TLBLKCRWE)
+#define GET_CR_TLBIALLCFG(b) GET_GLOBAL_FIELD(b, CR, CR_TLBIALLCFG)
+#define GET_TLBIVMIDCFG(b) GET_GLOBAL_FIELD(b, CR, TLBIVMIDCFG)
+#define GET_CR_HUME(b) GET_GLOBAL_FIELD(b, CR, CR_HUME)
+
+
+/* ESR */
+#define GET_CFG(b) GET_GLOBAL_FIELD(b, ESR, CFG)
+#define GET_BYPASS(b) GET_GLOBAL_FIELD(b, ESR, BYPASS)
+#define GET_ESR_MULTI(b) GET_GLOBAL_FIELD(b, ESR, ESR_MULTI)
+
+
+/* ESYNR0 */
+#define GET_ESYNR0_AMID(b) GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_AMID)
+#define GET_ESYNR0_APID(b) GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_APID)
+#define GET_ESYNR0_ABID(b) GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_ABID)
+#define GET_ESYNR0_AVMID(b) GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_AVMID)
+#define GET_ESYNR0_ATID(b) GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_ATID)
+
+
+/* ESYNR1 */
+#define GET_ESYNR1_AMEMTYPE(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AMEMTYPE)
+#define GET_ESYNR1_ASHARED(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ASHARED)
+#define GET_ESYNR1_AINNERSHARED(b) \
+ GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AINNERSHARED)
+#define GET_ESYNR1_APRIV(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_APRIV)
+#define GET_ESYNR1_APROTNS(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_APROTNS)
+#define GET_ESYNR1_AINST(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AINST)
+#define GET_ESYNR1_AWRITE(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AWRITE)
+#define GET_ESYNR1_ABURST(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ABURST)
+#define GET_ESYNR1_ALEN(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ALEN)
+#define GET_ESYNR1_ASIZE(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ASIZE)
+#define GET_ESYNR1_ALOCK(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ALOCK)
+#define GET_ESYNR1_AOOO(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AOOO)
+#define GET_ESYNR1_AFULL(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AFULL)
+#define GET_ESYNR1_AC(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AC)
+#define GET_ESYNR1_DCD(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_DCD)
+
+
+/* IDR */
+#define GET_NM2VCBMT(b) GET_GLOBAL_FIELD(b, IDR, NM2VCBMT)
+#define GET_HTW(b) GET_GLOBAL_FIELD(b, IDR, HTW)
+#define GET_HUM(b) GET_GLOBAL_FIELD(b, IDR, HUM)
+#define GET_TLBSIZE(b) GET_GLOBAL_FIELD(b, IDR, TLBSIZE)
+#define GET_NCB(b) GET_GLOBAL_FIELD(b, IDR, NCB)
+#define GET_NIRPT(b) GET_GLOBAL_FIELD(b, IDR, NIRPT)
+
+
+/* REV */
+#define GET_MAJOR(b) GET_GLOBAL_FIELD(b, REV, MAJOR)
+#define GET_MINOR(b) GET_GLOBAL_FIELD(b, REV, MINOR)
+
+
+/* TESTBUSCR */
+#define GET_TBE(b) GET_GLOBAL_FIELD(b, TESTBUSCR, TBE)
+#define GET_SPDMBE(b) GET_GLOBAL_FIELD(b, TESTBUSCR, SPDMBE)
+#define GET_WGSEL(b) GET_GLOBAL_FIELD(b, TESTBUSCR, WGSEL)
+#define GET_TBLSEL(b) GET_GLOBAL_FIELD(b, TESTBUSCR, TBLSEL)
+#define GET_TBHSEL(b) GET_GLOBAL_FIELD(b, TESTBUSCR, TBHSEL)
+#define GET_SPDM0SEL(b) GET_GLOBAL_FIELD(b, TESTBUSCR, SPDM0SEL)
+#define GET_SPDM1SEL(b) GET_GLOBAL_FIELD(b, TESTBUSCR, SPDM1SEL)
+#define GET_SPDM2SEL(b) GET_GLOBAL_FIELD(b, TESTBUSCR, SPDM2SEL)
+#define GET_SPDM3SEL(b) GET_GLOBAL_FIELD(b, TESTBUSCR, SPDM3SEL)
+
+
+/* TLBIVMID */
+#define GET_TLBIVMID_VMID(b) GET_GLOBAL_FIELD(b, TLBIVMID, TLBIVMID_VMID)
+
+
+/* TLBTR0 */
+#define GET_PR(b) GET_GLOBAL_FIELD(b, TLBTR0, PR)
+#define GET_PW(b) GET_GLOBAL_FIELD(b, TLBTR0, PW)
+#define GET_UR(b) GET_GLOBAL_FIELD(b, TLBTR0, UR)
+#define GET_UW(b) GET_GLOBAL_FIELD(b, TLBTR0, UW)
+#define GET_XN(b) GET_GLOBAL_FIELD(b, TLBTR0, XN)
+#define GET_NSDESC(b) GET_GLOBAL_FIELD(b, TLBTR0, NSDESC)
+#define GET_ISH(b) GET_GLOBAL_FIELD(b, TLBTR0, ISH)
+#define GET_SH(b) GET_GLOBAL_FIELD(b, TLBTR0, SH)
+#define GET_MT(b) GET_GLOBAL_FIELD(b, TLBTR0, MT)
+#define GET_DPSIZR(b) GET_GLOBAL_FIELD(b, TLBTR0, DPSIZR)
+#define GET_DPSIZC(b) GET_GLOBAL_FIELD(b, TLBTR0, DPSIZC)
+
+
+/* TLBTR1 */
+#define GET_TLBTR1_VMID(b) GET_GLOBAL_FIELD(b, TLBTR1, TLBTR1_VMID)
+#define GET_TLBTR1_PA(b) GET_GLOBAL_FIELD(b, TLBTR1, TLBTR1_PA)
+
+
+/* TLBTR2 */
+#define GET_TLBTR2_ASID(b) GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_ASID)
+#define GET_TLBTR2_V(b) GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_V)
+#define GET_TLBTR2_NSTID(b) GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_NSTID)
+#define GET_TLBTR2_NV(b) GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_NV)
+#define GET_TLBTR2_VA(b) GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_VA)
+
+
+/* Context Register setters / getters */
+/* Context Register setters */
+/* ACTLR */
+#define SET_CFERE(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, CFERE, v)
+#define SET_CFEIE(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, CFEIE, v)
+#define SET_PTSHCFG(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, PTSHCFG, v)
+#define SET_RCOSH(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, RCOSH, v)
+#define SET_RCISH(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, RCISH, v)
+#define SET_RCNSH(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, RCNSH, v)
+#define SET_PRIVCFG(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, PRIVCFG, v)
+#define SET_DNA(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, DNA, v)
+#define SET_DNLV2PA(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, DNLV2PA, v)
+#define SET_TLBMCFG(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, TLBMCFG, v)
+#define SET_CFCFG(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, CFCFG, v)
+#define SET_TIPCF(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, TIPCF, v)
+#define SET_V2PCFG(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, V2PCFG, v)
+#define SET_HUME(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, HUME, v)
+#define SET_PTMTCFG(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, PTMTCFG, v)
+#define SET_PTMEMTYPE(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, PTMEMTYPE, v)
+
+
+/* BFBCR */
+#define SET_BFBDFE(b, c, v) SET_CONTEXT_FIELD(b, c, BFBCR, BFBDFE, v)
+#define SET_BFBSFE(b, c, v) SET_CONTEXT_FIELD(b, c, BFBCR, BFBSFE, v)
+#define SET_SFVS(b, c, v) SET_CONTEXT_FIELD(b, c, BFBCR, SFVS, v)
+#define SET_FLVIC(b, c, v) SET_CONTEXT_FIELD(b, c, BFBCR, FLVIC, v)
+#define SET_SLVIC(b, c, v) SET_CONTEXT_FIELD(b, c, BFBCR, SLVIC, v)
+
+
+/* CONTEXTIDR */
+#define SET_CONTEXTIDR_ASID(b, c, v) \
+ SET_CONTEXT_FIELD(b, c, CONTEXTIDR, CONTEXTIDR_ASID, v)
+#define SET_CONTEXTIDR_PROCID(b, c, v) \
+ SET_CONTEXT_FIELD(b, c, CONTEXTIDR, PROCID, v)
+
+
+/* FSR */
+#define SET_TF(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, TF, v)
+#define SET_AFF(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, AFF, v)
+#define SET_APF(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, APF, v)
+#define SET_TLBMF(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, TLBMF, v)
+#define SET_HTWDEEF(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, HTWDEEF, v)
+#define SET_HTWSEEF(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, HTWSEEF, v)
+#define SET_MHF(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, MHF, v)
+#define SET_SL(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, SL, v)
+#define SET_SS(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, SS, v)
+#define SET_MULTI(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, MULTI, v)
+
+
+/* FSYNR0 */
+#define SET_AMID(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR0, AMID, v)
+#define SET_APID(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR0, APID, v)
+#define SET_ABID(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR0, ABID, v)
+#define SET_ATID(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR0, ATID, v)
+
+
+/* FSYNR1 */
+#define SET_AMEMTYPE(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, AMEMTYPE, v)
+#define SET_ASHARED(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, ASHARED, v)
+#define SET_AINNERSHARED(b, c, v) \
+ SET_CONTEXT_FIELD(b, c, FSYNR1, AINNERSHARED, v)
+#define SET_APRIV(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, APRIV, v)
+#define SET_APROTNS(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, APROTNS, v)
+#define SET_AINST(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, AINST, v)
+#define SET_AWRITE(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, AWRITE, v)
+#define SET_ABURST(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, ABURST, v)
+#define SET_ALEN(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, ALEN, v)
+#define SET_FSYNR1_ASIZE(b, c, v) \
+ SET_CONTEXT_FIELD(b, c, FSYNR1, FSYNR1_ASIZE, v)
+#define SET_ALOCK(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, ALOCK, v)
+#define SET_AFULL(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, AFULL, v)
+
+
+/* NMRR */
+#define SET_ICPC0(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, ICPC0, v)
+#define SET_ICPC1(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, ICPC1, v)
+#define SET_ICPC2(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, ICPC2, v)
+#define SET_ICPC3(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, ICPC3, v)
+#define SET_ICPC4(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, ICPC4, v)
+#define SET_ICPC5(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, ICPC5, v)
+#define SET_ICPC6(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, ICPC6, v)
+#define SET_ICPC7(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, ICPC7, v)
+#define SET_OCPC0(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, OCPC0, v)
+#define SET_OCPC1(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, OCPC1, v)
+#define SET_OCPC2(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, OCPC2, v)
+#define SET_OCPC3(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, OCPC3, v)
+#define SET_OCPC4(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, OCPC4, v)
+#define SET_OCPC5(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, OCPC5, v)
+#define SET_OCPC6(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, OCPC6, v)
+#define SET_OCPC7(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, OCPC7, v)
+
+
+/* PAR */
+#define SET_FAULT(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, FAULT, v)
+
+#define SET_FAULT_TF(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, FAULT_TF, v)
+#define SET_FAULT_AFF(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, FAULT_AFF, v)
+#define SET_FAULT_APF(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, FAULT_APF, v)
+#define SET_FAULT_TLBMF(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, FAULT_TLBMF, v)
+#define SET_FAULT_HTWDEEF(b, c, v) \
+ SET_CONTEXT_FIELD(b, c, PAR, FAULT_HTWDEEF, v)
+#define SET_FAULT_HTWSEEF(b, c, v) \
+ SET_CONTEXT_FIELD(b, c, PAR, FAULT_HTWSEEF, v)
+#define SET_FAULT_MHF(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, FAULT_MHF, v)
+#define SET_FAULT_SL(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, FAULT_SL, v)
+#define SET_FAULT_SS(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, FAULT_SS, v)
+
+#define SET_NOFAULT_SS(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_SS, v)
+#define SET_NOFAULT_MT(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_MT, v)
+#define SET_NOFAULT_SH(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_SH, v)
+#define SET_NOFAULT_NS(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_NS, v)
+#define SET_NOFAULT_NOS(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_NOS, v)
+#define SET_NPFAULT_PA(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, NPFAULT_PA, v)
+
+
+/* PRRR */
+#define SET_MTC0(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, MTC0, v)
+#define SET_MTC1(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, MTC1, v)
+#define SET_MTC2(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, MTC2, v)
+#define SET_MTC3(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, MTC3, v)
+#define SET_MTC4(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, MTC4, v)
+#define SET_MTC5(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, MTC5, v)
+#define SET_MTC6(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, MTC6, v)
+#define SET_MTC7(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, MTC7, v)
+#define SET_SHDSH0(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, SHDSH0, v)
+#define SET_SHDSH1(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, SHDSH1, v)
+#define SET_SHNMSH0(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, SHNMSH0, v)
+#define SET_SHNMSH1(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, SHNMSH1, v)
+#define SET_NOS0(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, NOS0, v)
+#define SET_NOS1(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, NOS1, v)
+#define SET_NOS2(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, NOS2, v)
+#define SET_NOS3(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, NOS3, v)
+#define SET_NOS4(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, NOS4, v)
+#define SET_NOS5(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, NOS5, v)
+#define SET_NOS6(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, NOS6, v)
+#define SET_NOS7(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, NOS7, v)
+
+
+/* RESUME */
+#define SET_TNR(b, c, v) SET_CONTEXT_FIELD(b, c, RESUME, TNR, v)
+
+
+/* SCTLR */
+#define SET_M(b, c, v) SET_CONTEXT_FIELD(b, c, SCTLR, M, v)
+#define SET_TRE(b, c, v) SET_CONTEXT_FIELD(b, c, SCTLR, TRE, v)
+#define SET_AFE(b, c, v) SET_CONTEXT_FIELD(b, c, SCTLR, AFE, v)
+#define SET_HAF(b, c, v) SET_CONTEXT_FIELD(b, c, SCTLR, HAF, v)
+#define SET_BE(b, c, v) SET_CONTEXT_FIELD(b, c, SCTLR, BE, v)
+#define SET_AFFD(b, c, v) SET_CONTEXT_FIELD(b, c, SCTLR, AFFD, v)
+
+
+/* TLBLKCR */
+#define SET_LKE(b, c, v) SET_CONTEXT_FIELD(b, c, TLBLKCR, LKE, v)
+#define SET_TLBLKCR_TLBIALLCFG(b, c, v) \
+ SET_CONTEXT_FIELD(b, c, TLBLKCR, TLBLCKR_TLBIALLCFG, v)
+#define SET_TLBIASIDCFG(b, c, v) \
+ SET_CONTEXT_FIELD(b, c, TLBLKCR, TLBIASIDCFG, v)
+#define SET_TLBIVAACFG(b, c, v) SET_CONTEXT_FIELD(b, c, TLBLKCR, TLBIVAACFG, v)
+#define SET_FLOOR(b, c, v) SET_CONTEXT_FIELD(b, c, TLBLKCR, FLOOR, v)
+#define SET_VICTIM(b, c, v) SET_CONTEXT_FIELD(b, c, TLBLKCR, VICTIM, v)
+
+
+/* TTBCR */
+#define SET_N(b, c, v) SET_CONTEXT_FIELD(b, c, TTBCR, N, v)
+#define SET_PD0(b, c, v) SET_CONTEXT_FIELD(b, c, TTBCR, PD0, v)
+#define SET_PD1(b, c, v) SET_CONTEXT_FIELD(b, c, TTBCR, PD1, v)
+
+
+/* TTBR0 */
+#define SET_TTBR0_IRGNH(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_IRGNH, v)
+#define SET_TTBR0_SH(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_SH, v)
+#define SET_TTBR0_ORGN(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_ORGN, v)
+#define SET_TTBR0_NOS(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_NOS, v)
+#define SET_TTBR0_IRGNL(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_IRGNL, v)
+#define SET_TTBR0_PA(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_PA, v)
+
+
+/* TTBR1 */
+#define SET_TTBR1_IRGNH(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_IRGNH, v)
+#define SET_TTBR1_SH(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_SH, v)
+#define SET_TTBR1_ORGN(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_ORGN, v)
+#define SET_TTBR1_NOS(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_NOS, v)
+#define SET_TTBR1_IRGNL(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_IRGNL, v)
+#define SET_TTBR1_PA(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_PA, v)
+
+
+/* V2PSR */
+#define SET_HIT(b, c, v) SET_CONTEXT_FIELD(b, c, V2PSR, HIT, v)
+#define SET_INDEX(b, c, v) SET_CONTEXT_FIELD(b, c, V2PSR, INDEX, v)
+
+
+/* V2Pxx UW UR PW PR */
+#define SET_V2PUW_INDEX(b, c, v) SET_CONTEXT_FIELD(b, c, V2PUW, V2Pxx_INDEX, v)
+#define SET_V2PUW_VA(b, c, v) SET_CONTEXT_FIELD(b, c, V2PUW, V2Pxx_VA, v)
+
+#define SET_V2PUR_INDEX(b, c, v) SET_CONTEXT_FIELD(b, c, V2PUR, V2Pxx_INDEX, v)
+#define SET_V2PUR_VA(b, c, v) SET_CONTEXT_FIELD(b, c, V2PUR, V2Pxx_VA, v)
+
+#define SET_V2PPW_INDEX(b, c, v) SET_CONTEXT_FIELD(b, c, V2PPW, V2Pxx_INDEX, v)
+#define SET_V2PPW_VA(b, c, v) SET_CONTEXT_FIELD(b, c, V2PPW, V2Pxx_VA, v)
+
+#define SET_V2PPR_INDEX(b, c, v) SET_CONTEXT_FIELD(b, c, V2PPR, V2Pxx_INDEX, v)
+#define SET_V2PPR_VA(b, c, v) SET_CONTEXT_FIELD(b, c, V2PPR, V2Pxx_VA, v)
+
+
+/* Context Register getters */
+/* ACTLR */
+#define GET_CFERE(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, CFERE)
+#define GET_CFEIE(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, CFEIE)
+#define GET_PTSHCFG(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, PTSHCFG)
+#define GET_RCOSH(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, RCOSH)
+#define GET_RCISH(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, RCISH)
+#define GET_RCNSH(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, RCNSH)
+#define GET_PRIVCFG(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, PRIVCFG)
+#define GET_DNA(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, DNA)
+#define GET_DNLV2PA(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, DNLV2PA)
+#define GET_TLBMCFG(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, TLBMCFG)
+#define GET_CFCFG(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, CFCFG)
+#define GET_TIPCF(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, TIPCF)
+#define GET_V2PCFG(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, V2PCFG)
+#define GET_HUME(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, HUME)
+#define GET_PTMTCFG(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, PTMTCFG)
+#define GET_PTMEMTYPE(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, PTMEMTYPE)
+
+/* BFBCR */
+#define GET_BFBDFE(b, c) GET_CONTEXT_FIELD(b, c, BFBCR, BFBDFE)
+#define GET_BFBSFE(b, c) GET_CONTEXT_FIELD(b, c, BFBCR, BFBSFE)
+#define GET_SFVS(b, c) GET_CONTEXT_FIELD(b, c, BFBCR, SFVS)
+#define GET_FLVIC(b, c) GET_CONTEXT_FIELD(b, c, BFBCR, FLVIC)
+#define GET_SLVIC(b, c) GET_CONTEXT_FIELD(b, c, BFBCR, SLVIC)
+
+
+/* CONTEXTIDR */
+#define GET_CONTEXTIDR_ASID(b, c) \
+ GET_CONTEXT_FIELD(b, c, CONTEXTIDR, CONTEXTIDR_ASID)
+#define GET_CONTEXTIDR_PROCID(b, c) GET_CONTEXT_FIELD(b, c, CONTEXTIDR, PROCID)
+
+
+/* FSR */
+#define GET_TF(b, c) GET_CONTEXT_FIELD(b, c, FSR, TF)
+#define GET_AFF(b, c) GET_CONTEXT_FIELD(b, c, FSR, AFF)
+#define GET_APF(b, c) GET_CONTEXT_FIELD(b, c, FSR, APF)
+#define GET_TLBMF(b, c) GET_CONTEXT_FIELD(b, c, FSR, TLBMF)
+#define GET_HTWDEEF(b, c) GET_CONTEXT_FIELD(b, c, FSR, HTWDEEF)
+#define GET_HTWSEEF(b, c) GET_CONTEXT_FIELD(b, c, FSR, HTWSEEF)
+#define GET_MHF(b, c) GET_CONTEXT_FIELD(b, c, FSR, MHF)
+#define GET_SL(b, c) GET_CONTEXT_FIELD(b, c, FSR, SL)
+#define GET_SS(b, c) GET_CONTEXT_FIELD(b, c, FSR, SS)
+#define GET_MULTI(b, c) GET_CONTEXT_FIELD(b, c, FSR, MULTI)
+
+
+/* FSYNR0 */
+#define GET_AMID(b, c) GET_CONTEXT_FIELD(b, c, FSYNR0, AMID)
+#define GET_APID(b, c) GET_CONTEXT_FIELD(b, c, FSYNR0, APID)
+#define GET_ABID(b, c) GET_CONTEXT_FIELD(b, c, FSYNR0, ABID)
+#define GET_ATID(b, c) GET_CONTEXT_FIELD(b, c, FSYNR0, ATID)
+
+
+/* FSYNR1 */
+#define GET_AMEMTYPE(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, AMEMTYPE)
+#define GET_ASHARED(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, ASHARED)
+#define GET_AINNERSHARED(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, AINNERSHARED)
+#define GET_APRIV(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, APRIV)
+#define GET_APROTNS(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, APROTNS)
+#define GET_AINST(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, AINST)
+#define GET_AWRITE(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, AWRITE)
+#define GET_ABURST(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, ABURST)
+#define GET_ALEN(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, ALEN)
+#define GET_FSYNR1_ASIZE(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, FSYNR1_ASIZE)
+#define GET_ALOCK(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, ALOCK)
+#define GET_AFULL(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, AFULL)
+
+
+/* NMRR */
+#define GET_ICPC0(b, c) GET_CONTEXT_FIELD(b, c, NMRR, ICPC0)
+#define GET_ICPC1(b, c) GET_CONTEXT_FIELD(b, c, NMRR, ICPC1)
+#define GET_ICPC2(b, c) GET_CONTEXT_FIELD(b, c, NMRR, ICPC2)
+#define GET_ICPC3(b, c) GET_CONTEXT_FIELD(b, c, NMRR, ICPC3)
+#define GET_ICPC4(b, c) GET_CONTEXT_FIELD(b, c, NMRR, ICPC4)
+#define GET_ICPC5(b, c) GET_CONTEXT_FIELD(b, c, NMRR, ICPC5)
+#define GET_ICPC6(b, c) GET_CONTEXT_FIELD(b, c, NMRR, ICPC6)
+#define GET_ICPC7(b, c) GET_CONTEXT_FIELD(b, c, NMRR, ICPC7)
+#define GET_OCPC0(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC0)
+#define GET_OCPC1(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC1)
+#define GET_OCPC2(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC2)
+#define GET_OCPC3(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC3)
+#define GET_OCPC4(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC4)
+#define GET_OCPC5(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC5)
+#define GET_OCPC6(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC6)
+#define GET_OCPC7(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC7)
+
+
+/* PAR */
+#define GET_FAULT(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT)
+
+#define GET_FAULT_TF(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_TF)
+#define GET_FAULT_AFF(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_AFF)
+#define GET_FAULT_APF(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_APF)
+#define GET_FAULT_TLBMF(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_TLBMF)
+#define GET_FAULT_HTWDEEF(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_HTWDEEF)
+#define GET_FAULT_HTWSEEF(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_HTWSEEF)
+#define GET_FAULT_MHF(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_MHF)
+#define GET_FAULT_SL(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_SL)
+#define GET_FAULT_SS(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_SS)
+
+#define GET_NOFAULT_SS(b, c) GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_SS)
+#define GET_NOFAULT_MT(b, c) GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_MT)
+#define GET_NOFAULT_SH(b, c) GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_SH)
+#define GET_NOFAULT_NS(b, c) GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_NS)
+#define GET_NOFAULT_NOS(b, c) GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_NOS)
+#define GET_NPFAULT_PA(b, c) GET_CONTEXT_FIELD(b, c, PAR, PAR_NPFAULT_PA)
+
+
+/* PRRR */
+#define GET_MTC0(b, c) GET_CONTEXT_FIELD(b, c, PRRR, MTC0)
+#define GET_MTC1(b, c) GET_CONTEXT_FIELD(b, c, PRRR, MTC1)
+#define GET_MTC2(b, c) GET_CONTEXT_FIELD(b, c, PRRR, MTC2)
+#define GET_MTC3(b, c) GET_CONTEXT_FIELD(b, c, PRRR, MTC3)
+#define GET_MTC4(b, c) GET_CONTEXT_FIELD(b, c, PRRR, MTC4)
+#define GET_MTC5(b, c) GET_CONTEXT_FIELD(b, c, PRRR, MTC5)
+#define GET_MTC6(b, c) GET_CONTEXT_FIELD(b, c, PRRR, MTC6)
+#define GET_MTC7(b, c) GET_CONTEXT_FIELD(b, c, PRRR, MTC7)
+#define GET_SHDSH0(b, c) GET_CONTEXT_FIELD(b, c, PRRR, SHDSH0)
+#define GET_SHDSH1(b, c) GET_CONTEXT_FIELD(b, c, PRRR, SHDSH1)
+#define GET_SHNMSH0(b, c) GET_CONTEXT_FIELD(b, c, PRRR, SHNMSH0)
+#define GET_SHNMSH1(b, c) GET_CONTEXT_FIELD(b, c, PRRR, SHNMSH1)
+#define GET_NOS0(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS0)
+#define GET_NOS1(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS1)
+#define GET_NOS2(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS2)
+#define GET_NOS3(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS3)
+#define GET_NOS4(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS4)
+#define GET_NOS5(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS5)
+#define GET_NOS6(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS6)
+#define GET_NOS7(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS7)
+
+
+/* RESUME */
+#define GET_TNR(b, c) GET_CONTEXT_FIELD(b, c, RESUME, TNR)
+
+
+/* SCTLR */
+#define GET_M(b, c) GET_CONTEXT_FIELD(b, c, SCTLR, M)
+#define GET_TRE(b, c) GET_CONTEXT_FIELD(b, c, SCTLR, TRE)
+#define GET_AFE(b, c) GET_CONTEXT_FIELD(b, c, SCTLR, AFE)
+#define GET_HAF(b, c) GET_CONTEXT_FIELD(b, c, SCTLR, HAF)
+#define GET_BE(b, c) GET_CONTEXT_FIELD(b, c, SCTLR, BE)
+#define GET_AFFD(b, c) GET_CONTEXT_FIELD(b, c, SCTLR, AFFD)
+
+
+/* TLBLKCR */
+#define GET_LKE(b, c) GET_CONTEXT_FIELD(b, c, TLBLKCR, LKE)
+#define GET_TLBLCKR_TLBIALLCFG(b, c) \
+ GET_CONTEXT_FIELD(b, c, TLBLKCR, TLBLCKR_TLBIALLCFG)
+#define GET_TLBIASIDCFG(b, c) GET_CONTEXT_FIELD(b, c, TLBLKCR, TLBIASIDCFG)
+#define GET_TLBIVAACFG(b, c) GET_CONTEXT_FIELD(b, c, TLBLKCR, TLBIVAACFG)
+#define GET_FLOOR(b, c) GET_CONTEXT_FIELD(b, c, TLBLKCR, FLOOR)
+#define GET_VICTIM(b, c) GET_CONTEXT_FIELD(b, c, TLBLKCR, VICTIM)
+
+
+/* TTBCR */
+#define GET_N(b, c) GET_CONTEXT_FIELD(b, c, TTBCR, N)
+#define GET_PD0(b, c) GET_CONTEXT_FIELD(b, c, TTBCR, PD0)
+#define GET_PD1(b, c) GET_CONTEXT_FIELD(b, c, TTBCR, PD1)
+
+
+/* TTBR0 */
+#define GET_TTBR0_IRGNH(b, c) GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_IRGNH)
+#define GET_TTBR0_SH(b, c) GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_SH)
+#define GET_TTBR0_ORGN(b, c) GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_ORGN)
+#define GET_TTBR0_NOS(b, c) GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_NOS)
+#define GET_TTBR0_IRGNL(b, c) GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_IRGNL)
+#define GET_TTBR0_PA(b, c) GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_PA)
+
+
+/* TTBR1 */
+#define GET_TTBR1_IRGNH(b, c) GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_IRGNH)
+#define GET_TTBR1_SH(b, c) GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_SH)
+#define GET_TTBR1_ORGN(b, c) GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_ORGN)
+#define GET_TTBR1_NOS(b, c) GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_NOS)
+#define GET_TTBR1_IRGNL(b, c) GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_IRGNL)
+#define GET_TTBR1_PA(b, c) GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_PA)
+
+
+/* V2PSR */
+#define GET_HIT(b, c) GET_CONTEXT_FIELD(b, c, V2PSR, HIT)
+#define GET_INDEX(b, c) GET_CONTEXT_FIELD(b, c, V2PSR, INDEX)
+
+
+/* V2Pxx UW UR PW PR */
+#define GET_V2PUW_INDEX(b, c) GET_CONTEXT_FIELD(b, c, V2PUW, V2Pxx_INDEX)
+#define GET_V2PUW_VA(b, c) GET_CONTEXT_FIELD(b, c, V2PUW, V2Pxx_VA)
+
+#define GET_V2PUR_INDEX(b, c) GET_CONTEXT_FIELD(b, c, V2PUR, V2Pxx_INDEX)
+#define GET_V2PUR_VA(b, c) GET_CONTEXT_FIELD(b, c, V2PUR, V2Pxx_VA)
+
+#define GET_V2PPW_INDEX(b, c) GET_CONTEXT_FIELD(b, c, V2PPW, V2Pxx_INDEX)
+#define GET_V2PPW_VA(b, c) GET_CONTEXT_FIELD(b, c, V2PPW, V2Pxx_VA)
+
+#define GET_V2PPR_INDEX(b, c) GET_CONTEXT_FIELD(b, c, V2PPR, V2Pxx_INDEX)
+#define GET_V2PPR_VA(b, c) GET_CONTEXT_FIELD(b, c, V2PPR, V2Pxx_VA)
+
+
+/* Global Registers */
+#define M2VCBR_N (0xFF000)
+#define CBACR_N (0xFF800)
+#define TLBRSW (0xFFE00)
+#define TLBTR0 (0xFFE80)
+#define TLBTR1 (0xFFE84)
+#define TLBTR2 (0xFFE88)
+#define TESTBUSCR (0xFFE8C)
+#define GLOBAL_TLBIALL (0xFFF00)
+#define TLBIVMID (0xFFF04)
+#define CR (0xFFF80)
+#define EAR (0xFFF84)
+#define ESR (0xFFF88)
+#define ESRRESTORE (0xFFF8C)
+#define ESYNR0 (0xFFF90)
+#define ESYNR1 (0xFFF94)
+#define REV (0xFFFF4)
+#define IDR (0xFFFF8)
+#define RPU_ACR (0xFFFFC)
+
+
+/* Context Bank Registers */
+#define SCTLR (0x000)
+#define ACTLR (0x004)
+#define CONTEXTIDR (0x008)
+#define TTBR0 (0x010)
+#define TTBR1 (0x014)
+#define TTBCR (0x018)
+#define PAR (0x01C)
+#define FSR (0x020)
+#define FSRRESTORE (0x024)
+#define FAR (0x028)
+#define FSYNR0 (0x02C)
+#define FSYNR1 (0x030)
+#define PRRR (0x034)
+#define NMRR (0x038)
+#define TLBLCKR (0x03C)
+#define V2PSR (0x040)
+#define TLBFLPTER (0x044)
+#define TLBSLPTER (0x048)
+#define BFBCR (0x04C)
+#define CTX_TLBIALL (0x800)
+#define TLBIASID (0x804)
+#define TLBIVA (0x808)
+#define TLBIVAA (0x80C)
+#define V2PPR (0x810)
+#define V2PPW (0x814)
+#define V2PUR (0x818)
+#define V2PUW (0x81C)
+#define RESUME (0x820)
+
+
+/* Global Register Fields */
+/* CBACRn */
+#define RWVMID (RWVMID_MASK << RWVMID_SHIFT)
+#define RWE (RWE_MASK << RWE_SHIFT)
+#define RWGE (RWGE_MASK << RWGE_SHIFT)
+#define CBVMID (CBVMID_MASK << CBVMID_SHIFT)
+#define IRPTNDX (IRPTNDX_MASK << IRPTNDX_SHIFT)
+
+
+/* CR */
+#define RPUE (RPUE_MASK << RPUE_SHIFT)
+#define RPUERE (RPUERE_MASK << RPUERE_SHIFT)
+#define RPUEIE (RPUEIE_MASK << RPUEIE_SHIFT)
+#define DCDEE (DCDEE_MASK << DCDEE_SHIFT)
+#define CLIENTPD (CLIENTPD_MASK << CLIENTPD_SHIFT)
+#define STALLD (STALLD_MASK << STALLD_SHIFT)
+#define TLBLKCRWE (TLBLKCRWE_MASK << TLBLKCRWE_SHIFT)
+#define CR_TLBIALLCFG (CR_TLBIALLCFG_MASK << CR_TLBIALLCFG_SHIFT)
+#define TLBIVMIDCFG (TLBIVMIDCFG_MASK << TLBIVMIDCFG_SHIFT)
+#define CR_HUME (CR_HUME_MASK << CR_HUME_SHIFT)
+
+
+/* ESR */
+#define CFG (CFG_MASK << CFG_SHIFT)
+#define BYPASS (BYPASS_MASK << BYPASS_SHIFT)
+#define ESR_MULTI (ESR_MULTI_MASK << ESR_MULTI_SHIFT)
+
+
+/* ESYNR0 */
+#define ESYNR0_AMID (ESYNR0_AMID_MASK << ESYNR0_AMID_SHIFT)
+#define ESYNR0_APID (ESYNR0_APID_MASK << ESYNR0_APID_SHIFT)
+#define ESYNR0_ABID (ESYNR0_ABID_MASK << ESYNR0_ABID_SHIFT)
+#define ESYNR0_AVMID (ESYNR0_AVMID_MASK << ESYNR0_AVMID_SHIFT)
+#define ESYNR0_ATID (ESYNR0_ATID_MASK << ESYNR0_ATID_SHIFT)
+
+
+/* ESYNR1 */
+#define ESYNR1_AMEMTYPE (ESYNR1_AMEMTYPE_MASK << ESYNR1_AMEMTYPE_SHIFT)
+#define ESYNR1_ASHARED (ESYNR1_ASHARED_MASK << ESYNR1_ASHARED_SHIFT)
+#define ESYNR1_AINNERSHARED (ESYNR1_AINNERSHARED_MASK<< \
+ ESYNR1_AINNERSHARED_SHIFT)
+#define ESYNR1_APRIV (ESYNR1_APRIV_MASK << ESYNR1_APRIV_SHIFT)
+#define ESYNR1_APROTNS (ESYNR1_APROTNS_MASK << ESYNR1_APROTNS_SHIFT)
+#define ESYNR1_AINST (ESYNR1_AINST_MASK << ESYNR1_AINST_SHIFT)
+#define ESYNR1_AWRITE (ESYNR1_AWRITE_MASK << ESYNR1_AWRITE_SHIFT)
+#define ESYNR1_ABURST (ESYNR1_ABURST_MASK << ESYNR1_ABURST_SHIFT)
+#define ESYNR1_ALEN (ESYNR1_ALEN_MASK << ESYNR1_ALEN_SHIFT)
+#define ESYNR1_ASIZE (ESYNR1_ASIZE_MASK << ESYNR1_ASIZE_SHIFT)
+#define ESYNR1_ALOCK (ESYNR1_ALOCK_MASK << ESYNR1_ALOCK_SHIFT)
+#define ESYNR1_AOOO (ESYNR1_AOOO_MASK << ESYNR1_AOOO_SHIFT)
+#define ESYNR1_AFULL (ESYNR1_AFULL_MASK << ESYNR1_AFULL_SHIFT)
+#define ESYNR1_AC (ESYNR1_AC_MASK << ESYNR1_AC_SHIFT)
+#define ESYNR1_DCD (ESYNR1_DCD_MASK << ESYNR1_DCD_SHIFT)
+
+
+/* IDR */
+#define NM2VCBMT (NM2VCBMT_MASK << NM2VCBMT_SHIFT)
+#define HTW (HTW_MASK << HTW_SHIFT)
+#define HUM (HUM_MASK << HUM_SHIFT)
+#define TLBSIZE (TLBSIZE_MASK << TLBSIZE_SHIFT)
+#define NCB (NCB_MASK << NCB_SHIFT)
+#define NIRPT (NIRPT_MASK << NIRPT_SHIFT)
+
+
+/* M2VCBRn */
+#define VMID (VMID_MASK << VMID_SHIFT)
+#define CBNDX (CBNDX_MASK << CBNDX_SHIFT)
+#define BYPASSD (BYPASSD_MASK << BYPASSD_SHIFT)
+#define BPRCOSH (BPRCOSH_MASK << BPRCOSH_SHIFT)
+#define BPRCISH (BPRCISH_MASK << BPRCISH_SHIFT)
+#define BPRCNSH (BPRCNSH_MASK << BPRCNSH_SHIFT)
+#define BPSHCFG (BPSHCFG_MASK << BPSHCFG_SHIFT)
+#define NSCFG (NSCFG_MASK << NSCFG_SHIFT)
+#define BPMTCFG (BPMTCFG_MASK << BPMTCFG_SHIFT)
+#define BPMEMTYPE (BPMEMTYPE_MASK << BPMEMTYPE_SHIFT)
+
+
+/* REV */
+#define IDR_MINOR (MINOR_MASK << MINOR_SHIFT)
+#define IDR_MAJOR (MAJOR_MASK << MAJOR_SHIFT)
+
+
+/* TESTBUSCR */
+#define TBE (TBE_MASK << TBE_SHIFT)
+#define SPDMBE (SPDMBE_MASK << SPDMBE_SHIFT)
+#define WGSEL (WGSEL_MASK << WGSEL_SHIFT)
+#define TBLSEL (TBLSEL_MASK << TBLSEL_SHIFT)
+#define TBHSEL (TBHSEL_MASK << TBHSEL_SHIFT)
+#define SPDM0SEL (SPDM0SEL_MASK << SPDM0SEL_SHIFT)
+#define SPDM1SEL (SPDM1SEL_MASK << SPDM1SEL_SHIFT)
+#define SPDM2SEL (SPDM2SEL_MASK << SPDM2SEL_SHIFT)
+#define SPDM3SEL (SPDM3SEL_MASK << SPDM3SEL_SHIFT)
+
+
+/* TLBIVMID */
+#define TLBIVMID_VMID (TLBIVMID_VMID_MASK << TLBIVMID_VMID_SHIFT)
+
+
+/* TLBRSW */
+#define TLBRSW_INDEX (TLBRSW_INDEX_MASK << TLBRSW_INDEX_SHIFT)
+#define TLBBFBS (TLBBFBS_MASK << TLBBFBS_SHIFT)
+
+
+/* TLBTR0 */
+#define PR (PR_MASK << PR_SHIFT)
+#define PW (PW_MASK << PW_SHIFT)
+#define UR (UR_MASK << UR_SHIFT)
+#define UW (UW_MASK << UW_SHIFT)
+#define XN (XN_MASK << XN_SHIFT)
+#define NSDESC (NSDESC_MASK << NSDESC_SHIFT)
+#define ISH (ISH_MASK << ISH_SHIFT)
+#define SH (SH_MASK << SH_SHIFT)
+#define MT (MT_MASK << MT_SHIFT)
+#define DPSIZR (DPSIZR_MASK << DPSIZR_SHIFT)
+#define DPSIZC (DPSIZC_MASK << DPSIZC_SHIFT)
+
+
+/* TLBTR1 */
+#define TLBTR1_VMID (TLBTR1_VMID_MASK << TLBTR1_VMID_SHIFT)
+#define TLBTR1_PA (TLBTR1_PA_MASK << TLBTR1_PA_SHIFT)
+
+
+/* TLBTR2 */
+#define TLBTR2_ASID (TLBTR2_ASID_MASK << TLBTR2_ASID_SHIFT)
+#define TLBTR2_V (TLBTR2_V_MASK << TLBTR2_V_SHIFT)
+#define TLBTR2_NSTID (TLBTR2_NSTID_MASK << TLBTR2_NSTID_SHIFT)
+#define TLBTR2_NV (TLBTR2_NV_MASK << TLBTR2_NV_SHIFT)
+#define TLBTR2_VA (TLBTR2_VA_MASK << TLBTR2_VA_SHIFT)
+
+
+/* Context Register Fields */
+/* ACTLR */
+#define CFERE (CFERE_MASK << CFERE_SHIFT)
+#define CFEIE (CFEIE_MASK << CFEIE_SHIFT)
+#define PTSHCFG (PTSHCFG_MASK << PTSHCFG_SHIFT)
+#define RCOSH (RCOSH_MASK << RCOSH_SHIFT)
+#define RCISH (RCISH_MASK << RCISH_SHIFT)
+#define RCNSH (RCNSH_MASK << RCNSH_SHIFT)
+#define PRIVCFG (PRIVCFG_MASK << PRIVCFG_SHIFT)
+#define DNA (DNA_MASK << DNA_SHIFT)
+#define DNLV2PA (DNLV2PA_MASK << DNLV2PA_SHIFT)
+#define TLBMCFG (TLBMCFG_MASK << TLBMCFG_SHIFT)
+#define CFCFG (CFCFG_MASK << CFCFG_SHIFT)
+#define TIPCF (TIPCF_MASK << TIPCF_SHIFT)
+#define V2PCFG (V2PCFG_MASK << V2PCFG_SHIFT)
+#define HUME (HUME_MASK << HUME_SHIFT)
+#define PTMTCFG (PTMTCFG_MASK << PTMTCFG_SHIFT)
+#define PTMEMTYPE (PTMEMTYPE_MASK << PTMEMTYPE_SHIFT)
+
+
+/* BFBCR */
+#define BFBDFE (BFBDFE_MASK << BFBDFE_SHIFT)
+#define BFBSFE (BFBSFE_MASK << BFBSFE_SHIFT)
+#define SFVS (SFVS_MASK << SFVS_SHIFT)
+#define FLVIC (FLVIC_MASK << FLVIC_SHIFT)
+#define SLVIC (SLVIC_MASK << SLVIC_SHIFT)
+
+
+/* CONTEXTIDR */
+#define CONTEXTIDR_ASID (CONTEXTIDR_ASID_MASK << CONTEXTIDR_ASID_SHIFT)
+#define PROCID (PROCID_MASK << PROCID_SHIFT)
+
+
+/* FSR */
+#define TF (TF_MASK << TF_SHIFT)
+#define AFF (AFF_MASK << AFF_SHIFT)
+#define APF (APF_MASK << APF_SHIFT)
+#define TLBMF (TLBMF_MASK << TLBMF_SHIFT)
+#define HTWDEEF (HTWDEEF_MASK << HTWDEEF_SHIFT)
+#define HTWSEEF (HTWSEEF_MASK << HTWSEEF_SHIFT)
+#define MHF (MHF_MASK << MHF_SHIFT)
+#define SL (SL_MASK << SL_SHIFT)
+#define SS (SS_MASK << SS_SHIFT)
+#define MULTI (MULTI_MASK << MULTI_SHIFT)
+
+
+/* FSYNR0 */
+#define AMID (AMID_MASK << AMID_SHIFT)
+#define APID (APID_MASK << APID_SHIFT)
+#define ABID (ABID_MASK << ABID_SHIFT)
+#define ATID (ATID_MASK << ATID_SHIFT)
+
+
+/* FSYNR1 */
+#define AMEMTYPE (AMEMTYPE_MASK << AMEMTYPE_SHIFT)
+#define ASHARED (ASHARED_MASK << ASHARED_SHIFT)
+#define AINNERSHARED (AINNERSHARED_MASK << AINNERSHARED_SHIFT)
+#define APRIV (APRIV_MASK << APRIV_SHIFT)
+#define APROTNS (APROTNS_MASK << APROTNS_SHIFT)
+#define AINST (AINST_MASK << AINST_SHIFT)
+#define AWRITE (AWRITE_MASK << AWRITE_SHIFT)
+#define ABURST (ABURST_MASK << ABURST_SHIFT)
+#define ALEN (ALEN_MASK << ALEN_SHIFT)
+#define FSYNR1_ASIZE (FSYNR1_ASIZE_MASK << FSYNR1_ASIZE_SHIFT)
+#define ALOCK (ALOCK_MASK << ALOCK_SHIFT)
+#define AFULL (AFULL_MASK << AFULL_SHIFT)
+
+
+/* NMRR */
+#define ICPC0 (ICPC0_MASK << ICPC0_SHIFT)
+#define ICPC1 (ICPC1_MASK << ICPC1_SHIFT)
+#define ICPC2 (ICPC2_MASK << ICPC2_SHIFT)
+#define ICPC3 (ICPC3_MASK << ICPC3_SHIFT)
+#define ICPC4 (ICPC4_MASK << ICPC4_SHIFT)
+#define ICPC5 (ICPC5_MASK << ICPC5_SHIFT)
+#define ICPC6 (ICPC6_MASK << ICPC6_SHIFT)
+#define ICPC7 (ICPC7_MASK << ICPC7_SHIFT)
+#define OCPC0 (OCPC0_MASK << OCPC0_SHIFT)
+#define OCPC1 (OCPC1_MASK << OCPC1_SHIFT)
+#define OCPC2 (OCPC2_MASK << OCPC2_SHIFT)
+#define OCPC3 (OCPC3_MASK << OCPC3_SHIFT)
+#define OCPC4 (OCPC4_MASK << OCPC4_SHIFT)
+#define OCPC5 (OCPC5_MASK << OCPC5_SHIFT)
+#define OCPC6 (OCPC6_MASK << OCPC6_SHIFT)
+#define OCPC7 (OCPC7_MASK << OCPC7_SHIFT)
+
+
+/* PAR */
+#define FAULT (FAULT_MASK << FAULT_SHIFT)
+/* If a fault is present, these are the
+same as the fault fields in the FAR */
+#define FAULT_TF (FAULT_TF_MASK << FAULT_TF_SHIFT)
+#define FAULT_AFF (FAULT_AFF_MASK << FAULT_AFF_SHIFT)
+#define FAULT_APF (FAULT_APF_MASK << FAULT_APF_SHIFT)
+#define FAULT_TLBMF (FAULT_TLBMF_MASK << FAULT_TLBMF_SHIFT)
+#define FAULT_HTWDEEF (FAULT_HTWDEEF_MASK << FAULT_HTWDEEF_SHIFT)
+#define FAULT_HTWSEEF (FAULT_HTWSEEF_MASK << FAULT_HTWSEEF_SHIFT)
+#define FAULT_MHF (FAULT_MHF_MASK << FAULT_MHF_SHIFT)
+#define FAULT_SL (FAULT_SL_MASK << FAULT_SL_SHIFT)
+#define FAULT_SS (FAULT_SS_MASK << FAULT_SS_SHIFT)
+
+/* If NO fault is present, the following fields are in effect */
+/* (FAULT remains as before) */
+#define PAR_NOFAULT_SS (PAR_NOFAULT_SS_MASK << PAR_NOFAULT_SS_SHIFT)
+#define PAR_NOFAULT_MT (PAR_NOFAULT_MT_MASK << PAR_NOFAULT_MT_SHIFT)
+#define PAR_NOFAULT_SH (PAR_NOFAULT_SH_MASK << PAR_NOFAULT_SH_SHIFT)
+#define PAR_NOFAULT_NS (PAR_NOFAULT_NS_MASK << PAR_NOFAULT_NS_SHIFT)
+#define PAR_NOFAULT_NOS (PAR_NOFAULT_NOS_MASK << PAR_NOFAULT_NOS_SHIFT)
+#define PAR_NPFAULT_PA (PAR_NPFAULT_PA_MASK << PAR_NPFAULT_PA_SHIFT)
+
+
+/* PRRR */
+#define MTC0 (MTC0_MASK << MTC0_SHIFT)
+#define MTC1 (MTC1_MASK << MTC1_SHIFT)
+#define MTC2 (MTC2_MASK << MTC2_SHIFT)
+#define MTC3 (MTC3_MASK << MTC3_SHIFT)
+#define MTC4 (MTC4_MASK << MTC4_SHIFT)
+#define MTC5 (MTC5_MASK << MTC5_SHIFT)
+#define MTC6 (MTC6_MASK << MTC6_SHIFT)
+#define MTC7 (MTC7_MASK << MTC7_SHIFT)
+#define SHDSH0 (SHDSH0_MASK << SHDSH0_SHIFT)
+#define SHDSH1 (SHDSH1_MASK << SHDSH1_SHIFT)
+#define SHNMSH0 (SHNMSH0_MASK << SHNMSH0_SHIFT)
+#define SHNMSH1 (SHNMSH1_MASK << SHNMSH1_SHIFT)
+#define NOS0 (NOS0_MASK << NOS0_SHIFT)
+#define NOS1 (NOS1_MASK << NOS1_SHIFT)
+#define NOS2 (NOS2_MASK << NOS2_SHIFT)
+#define NOS3 (NOS3_MASK << NOS3_SHIFT)
+#define NOS4 (NOS4_MASK << NOS4_SHIFT)
+#define NOS5 (NOS5_MASK << NOS5_SHIFT)
+#define NOS6 (NOS6_MASK << NOS6_SHIFT)
+#define NOS7 (NOS7_MASK << NOS7_SHIFT)
+
+
+/* RESUME */
+#define TNR (TNR_MASK << TNR_SHIFT)
+
+
+/* SCTLR */
+#define M (M_MASK << M_SHIFT)
+#define TRE (TRE_MASK << TRE_SHIFT)
+#define AFE (AFE_MASK << AFE_SHIFT)
+#define HAF (HAF_MASK << HAF_SHIFT)
+#define BE (BE_MASK << BE_SHIFT)
+#define AFFD (AFFD_MASK << AFFD_SHIFT)
+
+
+/* TLBIASID */
+#define TLBIASID_ASID (TLBIASID_ASID_MASK << TLBIASID_ASID_SHIFT)
+
+
+/* TLBIVA */
+#define TLBIVA_ASID (TLBIVA_ASID_MASK << TLBIVA_ASID_SHIFT)
+#define TLBIVA_VA (TLBIVA_VA_MASK << TLBIVA_VA_SHIFT)
+
+
+/* TLBIVAA */
+#define TLBIVAA_VA (TLBIVAA_VA_MASK << TLBIVAA_VA_SHIFT)
+
+
+/* TLBLCKR */
+#define LKE (LKE_MASK << LKE_SHIFT)
+#define TLBLCKR_TLBIALLCFG (TLBLCKR_TLBIALLCFG_MASK<<TLBLCKR_TLBIALLCFG_SHIFT)
+#define TLBIASIDCFG (TLBIASIDCFG_MASK << TLBIASIDCFG_SHIFT)
+#define TLBIVAACFG (TLBIVAACFG_MASK << TLBIVAACFG_SHIFT)
+#define FLOOR (FLOOR_MASK << FLOOR_SHIFT)
+#define VICTIM (VICTIM_MASK << VICTIM_SHIFT)
+
+
+/* TTBCR */
+#define N (N_MASK << N_SHIFT)
+#define PD0 (PD0_MASK << PD0_SHIFT)
+#define PD1 (PD1_MASK << PD1_SHIFT)
+
+
+/* TTBR0 */
+#define TTBR0_IRGNH (TTBR0_IRGNH_MASK << TTBR0_IRGNH_SHIFT)
+#define TTBR0_SH (TTBR0_SH_MASK << TTBR0_SH_SHIFT)
+#define TTBR0_ORGN (TTBR0_ORGN_MASK << TTBR0_ORGN_SHIFT)
+#define TTBR0_NOS (TTBR0_NOS_MASK << TTBR0_NOS_SHIFT)
+#define TTBR0_IRGNL (TTBR0_IRGNL_MASK << TTBR0_IRGNL_SHIFT)
+#define TTBR0_PA (TTBR0_PA_MASK << TTBR0_PA_SHIFT)
+
+
+/* TTBR1 */
+#define TTBR1_IRGNH (TTBR1_IRGNH_MASK << TTBR1_IRGNH_SHIFT)
+#define TTBR1_SH (TTBR1_SH_MASK << TTBR1_SH_SHIFT)
+#define TTBR1_ORGN (TTBR1_ORGN_MASK << TTBR1_ORGN_SHIFT)
+#define TTBR1_NOS (TTBR1_NOS_MASK << TTBR1_NOS_SHIFT)
+#define TTBR1_IRGNL (TTBR1_IRGNL_MASK << TTBR1_IRGNL_SHIFT)
+#define TTBR1_PA (TTBR1_PA_MASK << TTBR1_PA_SHIFT)
+
+
+/* V2PSR */
+#define HIT (HIT_MASK << HIT_SHIFT)
+#define INDEX (INDEX_MASK << INDEX_SHIFT)
+
+
+/* V2Pxx */
+#define V2Pxx_INDEX (V2Pxx_INDEX_MASK << V2Pxx_INDEX_SHIFT)
+#define V2Pxx_VA (V2Pxx_VA_MASK << V2Pxx_VA_SHIFT)
+
+
+/* Global Register Masks */
+/* CBACRn */
+#define RWVMID_MASK 0x1F
+#define RWE_MASK 0x01
+#define RWGE_MASK 0x01
+#define CBVMID_MASK 0x1F
+#define IRPTNDX_MASK 0xFF
+
+
+/* CR */
+#define RPUE_MASK 0x01
+#define RPUERE_MASK 0x01
+#define RPUEIE_MASK 0x01
+#define DCDEE_MASK 0x01
+#define CLIENTPD_MASK 0x01
+#define STALLD_MASK 0x01
+#define TLBLKCRWE_MASK 0x01
+#define CR_TLBIALLCFG_MASK 0x01
+#define TLBIVMIDCFG_MASK 0x01
+#define CR_HUME_MASK 0x01
+
+
+/* ESR */
+#define CFG_MASK 0x01
+#define BYPASS_MASK 0x01
+#define ESR_MULTI_MASK 0x01
+
+
+/* ESYNR0 */
+#define ESYNR0_AMID_MASK 0xFF
+#define ESYNR0_APID_MASK 0x1F
+#define ESYNR0_ABID_MASK 0x07
+#define ESYNR0_AVMID_MASK 0x1F
+#define ESYNR0_ATID_MASK 0xFF
+
+
+/* ESYNR1 */
+#define ESYNR1_AMEMTYPE_MASK 0x07
+#define ESYNR1_ASHARED_MASK 0x01
+#define ESYNR1_AINNERSHARED_MASK 0x01
+#define ESYNR1_APRIV_MASK 0x01
+#define ESYNR1_APROTNS_MASK 0x01
+#define ESYNR1_AINST_MASK 0x01
+#define ESYNR1_AWRITE_MASK 0x01
+#define ESYNR1_ABURST_MASK 0x01
+#define ESYNR1_ALEN_MASK 0x0F
+#define ESYNR1_ASIZE_MASK 0x01
+#define ESYNR1_ALOCK_MASK 0x03
+#define ESYNR1_AOOO_MASK 0x01
+#define ESYNR1_AFULL_MASK 0x01
+#define ESYNR1_AC_MASK 0x01
+#define ESYNR1_DCD_MASK 0x01
+
+
+/* IDR */
+#define NM2VCBMT_MASK 0x1FF
+#define HTW_MASK 0x01
+#define HUM_MASK 0x01
+#define TLBSIZE_MASK 0x0F
+#define NCB_MASK 0xFF
+#define NIRPT_MASK 0xFF
+
+
+/* M2VCBRn */
+#define VMID_MASK 0x1F
+#define CBNDX_MASK 0xFF
+#define BYPASSD_MASK 0x01
+#define BPRCOSH_MASK 0x01
+#define BPRCISH_MASK 0x01
+#define BPRCNSH_MASK 0x01
+#define BPSHCFG_MASK 0x03
+#define NSCFG_MASK 0x03
+#define BPMTCFG_MASK 0x01
+#define BPMEMTYPE_MASK 0x07
+
+
+/* REV */
+#define MINOR_MASK 0x0F
+#define MAJOR_MASK 0x0F
+
+
+/* TESTBUSCR */
+#define TBE_MASK 0x01
+#define SPDMBE_MASK 0x01
+#define WGSEL_MASK 0x03
+#define TBLSEL_MASK 0x03
+#define TBHSEL_MASK 0x03
+#define SPDM0SEL_MASK 0x0F
+#define SPDM1SEL_MASK 0x0F
+#define SPDM2SEL_MASK 0x0F
+#define SPDM3SEL_MASK 0x0F
+
+
+/* TLBIMID */
+#define TLBIVMID_VMID_MASK 0x1F
+
+
+/* TLBRSW */
+#define TLBRSW_INDEX_MASK 0xFF
+#define TLBBFBS_MASK 0x03
+
+
+/* TLBTR0 */
+#define PR_MASK 0x01
+#define PW_MASK 0x01
+#define UR_MASK 0x01
+#define UW_MASK 0x01
+#define XN_MASK 0x01
+#define NSDESC_MASK 0x01
+#define ISH_MASK 0x01
+#define SH_MASK 0x01
+#define MT_MASK 0x07
+#define DPSIZR_MASK 0x07
+#define DPSIZC_MASK 0x07
+
+
+/* TLBTR1 */
+#define TLBTR1_VMID_MASK 0x1F
+#define TLBTR1_PA_MASK 0x000FFFFF
+
+
+/* TLBTR2 */
+#define TLBTR2_ASID_MASK 0xFF
+#define TLBTR2_V_MASK 0x01
+#define TLBTR2_NSTID_MASK 0x01
+#define TLBTR2_NV_MASK 0x01
+#define TLBTR2_VA_MASK 0x000FFFFF
+
+
+/* Global Register Shifts */
+/* CBACRn */
+#define RWVMID_SHIFT 0
+#define RWE_SHIFT 8
+#define RWGE_SHIFT 9
+#define CBVMID_SHIFT 16
+#define IRPTNDX_SHIFT 24
+
+
+/* CR */
+#define RPUE_SHIFT 0
+#define RPUERE_SHIFT 1
+#define RPUEIE_SHIFT 2
+#define DCDEE_SHIFT 3
+#define CLIENTPD_SHIFT 4
+#define STALLD_SHIFT 5
+#define TLBLKCRWE_SHIFT 6
+#define CR_TLBIALLCFG_SHIFT 7
+#define TLBIVMIDCFG_SHIFT 8
+#define CR_HUME_SHIFT 9
+
+
+/* ESR */
+#define CFG_SHIFT 0
+#define BYPASS_SHIFT 1
+#define ESR_MULTI_SHIFT 31
+
+
+/* ESYNR0 */
+#define ESYNR0_AMID_SHIFT 0
+#define ESYNR0_APID_SHIFT 8
+#define ESYNR0_ABID_SHIFT 13
+#define ESYNR0_AVMID_SHIFT 16
+#define ESYNR0_ATID_SHIFT 24
+
+
+/* ESYNR1 */
+#define ESYNR1_AMEMTYPE_SHIFT 0
+#define ESYNR1_ASHARED_SHIFT 3
+#define ESYNR1_AINNERSHARED_SHIFT 4
+#define ESYNR1_APRIV_SHIFT 5
+#define ESYNR1_APROTNS_SHIFT 6
+#define ESYNR1_AINST_SHIFT 7
+#define ESYNR1_AWRITE_SHIFT 8
+#define ESYNR1_ABURST_SHIFT 10
+#define ESYNR1_ALEN_SHIFT 12
+#define ESYNR1_ASIZE_SHIFT 16
+#define ESYNR1_ALOCK_SHIFT 20
+#define ESYNR1_AOOO_SHIFT 22
+#define ESYNR1_AFULL_SHIFT 24
+#define ESYNR1_AC_SHIFT 30
+#define ESYNR1_DCD_SHIFT 31
+
+
+/* IDR */
+#define NM2VCBMT_SHIFT 0
+#define HTW_SHIFT 9
+#define HUM_SHIFT 10
+#define TLBSIZE_SHIFT 12
+#define NCB_SHIFT 16
+#define NIRPT_SHIFT 24
+
+
+/* M2VCBRn */
+#define VMID_SHIFT 0
+#define CBNDX_SHIFT 8
+#define BYPASSD_SHIFT 16
+#define BPRCOSH_SHIFT 17
+#define BPRCISH_SHIFT 18
+#define BPRCNSH_SHIFT 19
+#define BPSHCFG_SHIFT 20
+#define NSCFG_SHIFT 22
+#define BPMTCFG_SHIFT 24
+#define BPMEMTYPE_SHIFT 25
+
+
+/* REV */
+#define MINOR_SHIFT 0
+#define MAJOR_SHIFT 4
+
+
+/* TESTBUSCR */
+#define TBE_SHIFT 0
+#define SPDMBE_SHIFT 1
+#define WGSEL_SHIFT 8
+#define TBLSEL_SHIFT 12
+#define TBHSEL_SHIFT 14
+#define SPDM0SEL_SHIFT 16
+#define SPDM1SEL_SHIFT 20
+#define SPDM2SEL_SHIFT 24
+#define SPDM3SEL_SHIFT 28
+
+
+/* TLBIMID */
+#define TLBIVMID_VMID_SHIFT 0
+
+
+/* TLBRSW */
+#define TLBRSW_INDEX_SHIFT 0
+#define TLBBFBS_SHIFT 8
+
+
+/* TLBTR0 */
+#define PR_SHIFT 0
+#define PW_SHIFT 1
+#define UR_SHIFT 2
+#define UW_SHIFT 3
+#define XN_SHIFT 4
+#define NSDESC_SHIFT 6
+#define ISH_SHIFT 7
+#define SH_SHIFT 8
+#define MT_SHIFT 9
+#define DPSIZR_SHIFT 16
+#define DPSIZC_SHIFT 20
+
+
+/* TLBTR1 */
+#define TLBTR1_VMID_SHIFT 0
+#define TLBTR1_PA_SHIFT 12
+
+
+/* TLBTR2 */
+#define TLBTR2_ASID_SHIFT 0
+#define TLBTR2_V_SHIFT 8
+#define TLBTR2_NSTID_SHIFT 9
+#define TLBTR2_NV_SHIFT 10
+#define TLBTR2_VA_SHIFT 12
+
+
+/* Context Register Masks */
+/* ACTLR */
+#define CFERE_MASK 0x01
+#define CFEIE_MASK 0x01
+#define PTSHCFG_MASK 0x03
+#define RCOSH_MASK 0x01
+#define RCISH_MASK 0x01
+#define RCNSH_MASK 0x01
+#define PRIVCFG_MASK 0x03
+#define DNA_MASK 0x01
+#define DNLV2PA_MASK 0x01
+#define TLBMCFG_MASK 0x03
+#define CFCFG_MASK 0x01
+#define TIPCF_MASK 0x01
+#define V2PCFG_MASK 0x03
+#define HUME_MASK 0x01
+#define PTMTCFG_MASK 0x01
+#define PTMEMTYPE_MASK 0x07
+
+
+/* BFBCR */
+#define BFBDFE_MASK 0x01
+#define BFBSFE_MASK 0x01
+#define SFVS_MASK 0x01
+#define FLVIC_MASK 0x0F
+#define SLVIC_MASK 0x0F
+
+
+/* CONTEXTIDR */
+#define CONTEXTIDR_ASID_MASK 0xFF
+#define PROCID_MASK 0x00FFFFFF
+
+
+/* FSR */
+#define TF_MASK 0x01
+#define AFF_MASK 0x01
+#define APF_MASK 0x01
+#define TLBMF_MASK 0x01
+#define HTWDEEF_MASK 0x01
+#define HTWSEEF_MASK 0x01
+#define MHF_MASK 0x01
+#define SL_MASK 0x01
+#define SS_MASK 0x01
+#define MULTI_MASK 0x01
+
+
+/* FSYNR0 */
+#define AMID_MASK 0xFF
+#define APID_MASK 0x1F
+#define ABID_MASK 0x07
+#define ATID_MASK 0xFF
+
+
+/* FSYNR1 */
+#define AMEMTYPE_MASK 0x07
+#define ASHARED_MASK 0x01
+#define AINNERSHARED_MASK 0x01
+#define APRIV_MASK 0x01
+#define APROTNS_MASK 0x01
+#define AINST_MASK 0x01
+#define AWRITE_MASK 0x01
+#define ABURST_MASK 0x01
+#define ALEN_MASK 0x0F
+#define FSYNR1_ASIZE_MASK 0x07
+#define ALOCK_MASK 0x03
+#define AFULL_MASK 0x01
+
+
+/* NMRR */
+#define ICPC0_MASK 0x03
+#define ICPC1_MASK 0x03
+#define ICPC2_MASK 0x03
+#define ICPC3_MASK 0x03
+#define ICPC4_MASK 0x03
+#define ICPC5_MASK 0x03
+#define ICPC6_MASK 0x03
+#define ICPC7_MASK 0x03
+#define OCPC0_MASK 0x03
+#define OCPC1_MASK 0x03
+#define OCPC2_MASK 0x03
+#define OCPC3_MASK 0x03
+#define OCPC4_MASK 0x03
+#define OCPC5_MASK 0x03
+#define OCPC6_MASK 0x03
+#define OCPC7_MASK 0x03
+
+
+/* PAR */
+#define FAULT_MASK 0x01
+/* If a fault is present, these are the
+same as the fault fields in the FAR */
+#define FAULT_TF_MASK 0x01
+#define FAULT_AFF_MASK 0x01
+#define FAULT_APF_MASK 0x01
+#define FAULT_TLBMF_MASK 0x01
+#define FAULT_HTWDEEF_MASK 0x01
+#define FAULT_HTWSEEF_MASK 0x01
+#define FAULT_MHF_MASK 0x01
+#define FAULT_SL_MASK 0x01
+#define FAULT_SS_MASK 0x01
+
+/* If NO fault is present, the following
+ * fields are in effect
+ * (FAULT remains as before) */
+#define PAR_NOFAULT_SS_MASK 0x01
+#define PAR_NOFAULT_MT_MASK 0x07
+#define PAR_NOFAULT_SH_MASK 0x01
+#define PAR_NOFAULT_NS_MASK 0x01
+#define PAR_NOFAULT_NOS_MASK 0x01
+#define PAR_NPFAULT_PA_MASK 0x000FFFFF
+
+
+/* PRRR */
+#define MTC0_MASK 0x03
+#define MTC1_MASK 0x03
+#define MTC2_MASK 0x03
+#define MTC3_MASK 0x03
+#define MTC4_MASK 0x03
+#define MTC5_MASK 0x03
+#define MTC6_MASK 0x03
+#define MTC7_MASK 0x03
+#define SHDSH0_MASK 0x01
+#define SHDSH1_MASK 0x01
+#define SHNMSH0_MASK 0x01
+#define SHNMSH1_MASK 0x01
+#define NOS0_MASK 0x01
+#define NOS1_MASK 0x01
+#define NOS2_MASK 0x01
+#define NOS3_MASK 0x01
+#define NOS4_MASK 0x01
+#define NOS5_MASK 0x01
+#define NOS6_MASK 0x01
+#define NOS7_MASK 0x01
+
+
+/* RESUME */
+#define TNR_MASK 0x01
+
+
+/* SCTLR */
+#define M_MASK 0x01
+#define TRE_MASK 0x01
+#define AFE_MASK 0x01
+#define HAF_MASK 0x01
+#define BE_MASK 0x01
+#define AFFD_MASK 0x01
+
+
+/* TLBIASID */
+#define TLBIASID_ASID_MASK 0xFF
+
+
+/* TLBIVA */
+#define TLBIVA_ASID_MASK 0xFF
+#define TLBIVA_VA_MASK 0x000FFFFF
+
+
+/* TLBIVAA */
+#define TLBIVAA_VA_MASK 0x000FFFFF
+
+
+/* TLBLCKR */
+#define LKE_MASK 0x01
+#define TLBLCKR_TLBIALLCFG_MASK 0x01
+#define TLBIASIDCFG_MASK 0x01
+#define TLBIVAACFG_MASK 0x01
+#define FLOOR_MASK 0xFF
+#define VICTIM_MASK 0xFF
+
+
+/* TTBCR */
+#define N_MASK 0x07
+#define PD0_MASK 0x01
+#define PD1_MASK 0x01
+
+
+/* TTBR0 */
+#define TTBR0_IRGNH_MASK 0x01
+#define TTBR0_SH_MASK 0x01
+#define TTBR0_ORGN_MASK 0x03
+#define TTBR0_NOS_MASK 0x01
+#define TTBR0_IRGNL_MASK 0x01
+#define TTBR0_PA_MASK 0x0003FFFF
+
+
+/* TTBR1 */
+#define TTBR1_IRGNH_MASK 0x01
+#define TTBR1_SH_MASK 0x01
+#define TTBR1_ORGN_MASK 0x03
+#define TTBR1_NOS_MASK 0x01
+#define TTBR1_IRGNL_MASK 0x01
+#define TTBR1_PA_MASK 0x0003FFFF
+
+
+/* V2PSR */
+#define HIT_MASK 0x01
+#define INDEX_MASK 0xFF
+
+
+/* V2Pxx */
+#define V2Pxx_INDEX_MASK 0xFF
+#define V2Pxx_VA_MASK 0x000FFFFF
+
+
+/* Context Register Shifts */
+/* ACTLR */
+#define CFERE_SHIFT 0
+#define CFEIE_SHIFT 1
+#define PTSHCFG_SHIFT 2
+#define RCOSH_SHIFT 4
+#define RCISH_SHIFT 5
+#define RCNSH_SHIFT 6
+#define PRIVCFG_SHIFT 8
+#define DNA_SHIFT 10
+#define DNLV2PA_SHIFT 11
+#define TLBMCFG_SHIFT 12
+#define CFCFG_SHIFT 14
+#define TIPCF_SHIFT 15
+#define V2PCFG_SHIFT 16
+#define HUME_SHIFT 18
+#define PTMTCFG_SHIFT 20
+#define PTMEMTYPE_SHIFT 21
+
+
+/* BFBCR */
+#define BFBDFE_SHIFT 0
+#define BFBSFE_SHIFT 1
+#define SFVS_SHIFT 2
+#define FLVIC_SHIFT 4
+#define SLVIC_SHIFT 8
+
+
+/* CONTEXTIDR */
+#define CONTEXTIDR_ASID_SHIFT 0
+#define PROCID_SHIFT 8
+
+
+/* FSR */
+#define TF_SHIFT 1
+#define AFF_SHIFT 2
+#define APF_SHIFT 3
+#define TLBMF_SHIFT 4
+#define HTWDEEF_SHIFT 5
+#define HTWSEEF_SHIFT 6
+#define MHF_SHIFT 7
+#define SL_SHIFT 16
+#define SS_SHIFT 30
+#define MULTI_SHIFT 31
+
+
+/* FSYNR0 */
+#define AMID_SHIFT 0
+#define APID_SHIFT 8
+#define ABID_SHIFT 13
+#define ATID_SHIFT 24
+
+
+/* FSYNR1 */
+#define AMEMTYPE_SHIFT 0
+#define ASHARED_SHIFT 3
+#define AINNERSHARED_SHIFT 4
+#define APRIV_SHIFT 5
+#define APROTNS_SHIFT 6
+#define AINST_SHIFT 7
+#define AWRITE_SHIFT 8
+#define ABURST_SHIFT 10
+#define ALEN_SHIFT 12
+#define FSYNR1_ASIZE_SHIFT 16
+#define ALOCK_SHIFT 20
+#define AFULL_SHIFT 24
+
+
+/* NMRR */
+#define ICPC0_SHIFT 0
+#define ICPC1_SHIFT 2
+#define ICPC2_SHIFT 4
+#define ICPC3_SHIFT 6
+#define ICPC4_SHIFT 8
+#define ICPC5_SHIFT 10
+#define ICPC6_SHIFT 12
+#define ICPC7_SHIFT 14
+#define OCPC0_SHIFT 16
+#define OCPC1_SHIFT 18
+#define OCPC2_SHIFT 20
+#define OCPC3_SHIFT 22
+#define OCPC4_SHIFT 24
+#define OCPC5_SHIFT 26
+#define OCPC6_SHIFT 28
+#define OCPC7_SHIFT 30
+
+
+/* PAR */
+#define FAULT_SHIFT 0
+/* If a fault is present, these are the
+same as the fault fields in the FAR */
+#define FAULT_TF_SHIFT 1
+#define FAULT_AFF_SHIFT 2
+#define FAULT_APF_SHIFT 3
+#define FAULT_TLBMF_SHIFT 4
+#define FAULT_HTWDEEF_SHIFT 5
+#define FAULT_HTWSEEF_SHIFT 6
+#define FAULT_MHF_SHIFT 7
+#define FAULT_SL_SHIFT 16
+#define FAULT_SS_SHIFT 30
+
+/* If NO fault is present, the following
+ * fields are in effect
+ * (FAULT remains as before) */
+#define PAR_NOFAULT_SS_SHIFT 1
+#define PAR_NOFAULT_MT_SHIFT 4
+#define PAR_NOFAULT_SH_SHIFT 7
+#define PAR_NOFAULT_NS_SHIFT 9
+#define PAR_NOFAULT_NOS_SHIFT 10
+#define PAR_NPFAULT_PA_SHIFT 12
+
+
+/* PRRR */
+#define MTC0_SHIFT 0
+#define MTC1_SHIFT 2
+#define MTC2_SHIFT 4
+#define MTC3_SHIFT 6
+#define MTC4_SHIFT 8
+#define MTC5_SHIFT 10
+#define MTC6_SHIFT 12
+#define MTC7_SHIFT 14
+#define SHDSH0_SHIFT 16
+#define SHDSH1_SHIFT 17
+#define SHNMSH0_SHIFT 18
+#define SHNMSH1_SHIFT 19
+#define NOS0_SHIFT 24
+#define NOS1_SHIFT 25
+#define NOS2_SHIFT 26
+#define NOS3_SHIFT 27
+#define NOS4_SHIFT 28
+#define NOS5_SHIFT 29
+#define NOS6_SHIFT 30
+#define NOS7_SHIFT 31
+
+
+/* RESUME */
+#define TNR_SHIFT 0
+
+
+/* SCTLR */
+#define M_SHIFT 0
+#define TRE_SHIFT 1
+#define AFE_SHIFT 2
+#define HAF_SHIFT 3
+#define BE_SHIFT 4
+#define AFFD_SHIFT 5
+
+
+/* TLBIASID */
+#define TLBIASID_ASID_SHIFT 0
+
+
+/* TLBIVA */
+#define TLBIVA_ASID_SHIFT 0
+#define TLBIVA_VA_SHIFT 12
+
+
+/* TLBIVAA */
+#define TLBIVAA_VA_SHIFT 12
+
+
+/* TLBLCKR */
+#define LKE_SHIFT 0
+#define TLBLCKR_TLBIALLCFG_SHIFT 1
+#define TLBIASIDCFG_SHIFT 2
+#define TLBIVAACFG_SHIFT 3
+#define FLOOR_SHIFT 8
+#define VICTIM_SHIFT 8
+
+
+/* TTBCR */
+#define N_SHIFT 3
+#define PD0_SHIFT 4
+#define PD1_SHIFT 5
+
+
+/* TTBR0 */
+#define TTBR0_IRGNH_SHIFT 0
+#define TTBR0_SH_SHIFT 1
+#define TTBR0_ORGN_SHIFT 3
+#define TTBR0_NOS_SHIFT 5
+#define TTBR0_IRGNL_SHIFT 6
+#define TTBR0_PA_SHIFT 14
+
+
+/* TTBR1 */
+#define TTBR1_IRGNH_SHIFT 0
+#define TTBR1_SH_SHIFT 1
+#define TTBR1_ORGN_SHIFT 3
+#define TTBR1_NOS_SHIFT 5
+#define TTBR1_IRGNL_SHIFT 6
+#define TTBR1_PA_SHIFT 14
+
+
+/* V2PSR */
+#define HIT_SHIFT 0
+#define INDEX_SHIFT 8
+
+
+/* V2Pxx */
+#define V2Pxx_INDEX_SHIFT 0
+#define V2Pxx_VA_SHIFT 12
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/irqs-8x60.h b/arch/arm/mach-msm/include/mach/irqs-8x60.h
new file mode 100644
index 000000000000..36074cfc9ad2
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/irqs-8x60.h
@@ -0,0 +1,253 @@
+/* Copyright (c) 2010 Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_IRQS_8X60_H
+#define __ASM_ARCH_MSM_IRQS_8X60_H
+
+/* MSM ACPU Interrupt Numbers */
+
+/* 0-15: STI/SGI (software triggered/generated interrupts)
+ * 16-31: PPI (private peripheral interrupts)
+ * 32+: SPI (shared peripheral interrupts)
+ */
+
+#define GIC_PPI_START 16
+#define GIC_SPI_START 32
+
+#define INT_DEBUG_TIMER_EXP (GIC_PPI_START + 0)
+#define INT_GP_TIMER_EXP (GIC_PPI_START + 1)
+#define INT_GP_TIMER2_EXP (GIC_PPI_START + 2)
+#define WDT0_ACCSCSSNBARK_INT (GIC_PPI_START + 3)
+#define WDT1_ACCSCSSNBARK_INT (GIC_PPI_START + 4)
+#define AVS_SVICINT (GIC_PPI_START + 5)
+#define AVS_SVICINTSWDONE (GIC_PPI_START + 6)
+#define CPU_DBGCPUXCOMMRXFULL (GIC_PPI_START + 7)
+#define CPU_DBGCPUXCOMMTXEMPTY (GIC_PPI_START + 8)
+#define CPU_SICCPUXPERFMONIRPTREQ (GIC_PPI_START + 9)
+#define SC_AVSCPUXDOWN (GIC_PPI_START + 10)
+#define SC_AVSCPUXUP (GIC_PPI_START + 11)
+#define SC_SICCPUXACGIRPTREQ (GIC_PPI_START + 12)
+/* PPI 13 to 15 are unused */
+
+
+#define SC_SICMPUIRPTREQ (GIC_SPI_START + 0)
+#define SC_SICL2IRPTREQ (GIC_SPI_START + 1)
+#define SC_SICL2ACGIRPTREQ (GIC_SPI_START + 2)
+#define NC (GIC_SPI_START + 3)
+#define TLMM_SCSS_DIR_CONN_IRQ_0 (GIC_SPI_START + 4)
+#define TLMM_SCSS_DIR_CONN_IRQ_1 (GIC_SPI_START + 5)
+#define TLMM_SCSS_DIR_CONN_IRQ_2 (GIC_SPI_START + 6)
+#define TLMM_SCSS_DIR_CONN_IRQ_3 (GIC_SPI_START + 7)
+#define TLMM_SCSS_DIR_CONN_IRQ_4 (GIC_SPI_START + 8)
+#define TLMM_SCSS_DIR_CONN_IRQ_5 (GIC_SPI_START + 9)
+#define TLMM_SCSS_DIR_CONN_IRQ_6 (GIC_SPI_START + 10)
+#define TLMM_SCSS_DIR_CONN_IRQ_7 (GIC_SPI_START + 11)
+#define TLMM_SCSS_DIR_CONN_IRQ_8 (GIC_SPI_START + 12)
+#define TLMM_SCSS_DIR_CONN_IRQ_9 (GIC_SPI_START + 13)
+#define PM8058_SEC_IRQ_N (GIC_SPI_START + 14)
+#define PM8901_SEC_IRQ_N (GIC_SPI_START + 15)
+#define TLMM_SCSS_SUMMARY_IRQ (GIC_SPI_START + 16)
+#define SPDM_RT_1_IRQ (GIC_SPI_START + 17)
+#define SPDM_DIAG_IRQ (GIC_SPI_START + 18)
+#define RPM_SCSS_CPU0_GP_HIGH_IRQ (GIC_SPI_START + 19)
+#define RPM_SCSS_CPU0_GP_MEDIUM_IRQ (GIC_SPI_START + 20)
+#define RPM_SCSS_CPU0_GP_LOW_IRQ (GIC_SPI_START + 21)
+#define RPM_SCSS_CPU0_WAKE_UP_IRQ (GIC_SPI_START + 22)
+#define RPM_SCSS_CPU1_GP_HIGH_IRQ (GIC_SPI_START + 23)
+#define RPM_SCSS_CPU1_GP_MEDIUM_IRQ (GIC_SPI_START + 24)
+#define RPM_SCSS_CPU1_GP_LOW_IRQ (GIC_SPI_START + 25)
+#define RPM_SCSS_CPU1_WAKE_UP_IRQ (GIC_SPI_START + 26)
+#define SSBI2_2_SC_CPU0_SECURE_INT (GIC_SPI_START + 27)
+#define SSBI2_2_SC_CPU0_NON_SECURE_INT (GIC_SPI_START + 28)
+#define SSBI2_1_SC_CPU0_SECURE_INT (GIC_SPI_START + 29)
+#define SSBI2_1_SC_CPU0_NON_SECURE_INT (GIC_SPI_START + 30)
+#define MSMC_SC_SEC_CE_IRQ (GIC_SPI_START + 31)
+#define MSMC_SC_PRI_CE_IRQ (GIC_SPI_START + 32)
+#define MARM_FIQ (GIC_SPI_START + 33)
+#define MARM_IRQ (GIC_SPI_START + 34)
+#define MARM_L2CC_IRQ (GIC_SPI_START + 35)
+#define MARM_WDOG_EXPIRED (GIC_SPI_START + 36)
+#define MARM_SCSS_GP_IRQ_0 (GIC_SPI_START + 37)
+#define MARM_SCSS_GP_IRQ_1 (GIC_SPI_START + 38)
+#define MARM_SCSS_GP_IRQ_2 (GIC_SPI_START + 39)
+#define MARM_SCSS_GP_IRQ_3 (GIC_SPI_START + 40)
+#define MARM_SCSS_GP_IRQ_4 (GIC_SPI_START + 41)
+#define MARM_SCSS_GP_IRQ_5 (GIC_SPI_START + 42)
+#define MARM_SCSS_GP_IRQ_6 (GIC_SPI_START + 43)
+#define MARM_SCSS_GP_IRQ_7 (GIC_SPI_START + 44)
+#define MARM_SCSS_GP_IRQ_8 (GIC_SPI_START + 45)
+#define MARM_SCSS_GP_IRQ_9 (GIC_SPI_START + 46)
+#define VPE_IRQ (GIC_SPI_START + 47)
+#define VFE_IRQ (GIC_SPI_START + 48)
+#define VCODEC_IRQ (GIC_SPI_START + 49)
+#define TV_ENC_IRQ (GIC_SPI_START + 50)
+#define SMMU_VPE_CB_SC_SECURE_IRQ (GIC_SPI_START + 51)
+#define SMMU_VPE_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 52)
+#define SMMU_VFE_CB_SC_SECURE_IRQ (GIC_SPI_START + 53)
+#define SMMU_VFE_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 54)
+#define SMMU_VCODEC_B_CB_SC_SECURE_IRQ (GIC_SPI_START + 55)
+#define SMMU_VCODEC_B_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 56)
+#define SMMU_VCODEC_A_CB_SC_SECURE_IRQ (GIC_SPI_START + 57)
+#define SMMU_VCODEC_A_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 58)
+#define SMMU_ROT_CB_SC_SECURE_IRQ (GIC_SPI_START + 59)
+#define SMMU_ROT_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 60)
+#define SMMU_MDP1_CB_SC_SECURE_IRQ (GIC_SPI_START + 61)
+#define SMMU_MDP1_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 62)
+#define SMMU_MDP0_CB_SC_SECURE_IRQ (GIC_SPI_START + 63)
+#define SMMU_MDP0_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 64)
+#define SMMU_JPEGD_CB_SC_SECURE_IRQ (GIC_SPI_START + 65)
+#define SMMU_JPEGD_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 66)
+#define SMMU_IJPEG_CB_SC_SECURE_IRQ (GIC_SPI_START + 67)
+#define SMMU_IJPEG_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 68)
+#define SMMU_GFX3D_CB_SC_SECURE_IRQ (GIC_SPI_START + 69)
+#define SMMU_GFX3D_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 70)
+#define SMMU_GFX2D0_CB_SC_SECURE_IRQ (GIC_SPI_START + 71)
+#define SMMU_GFX2D0_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 72)
+#define ROT_IRQ (GIC_SPI_START + 73)
+#define MMSS_FABRIC_IRQ (GIC_SPI_START + 74)
+#define MDP_IRQ (GIC_SPI_START + 75)
+#define JPEGD_IRQ (GIC_SPI_START + 76)
+#define JPEG_IRQ (GIC_SPI_START + 77)
+#define MMSS_IMEM_IRQ (GIC_SPI_START + 78)
+#define HDMI_IRQ (GIC_SPI_START + 79)
+#define GFX3D_IRQ (GIC_SPI_START + 80)
+#define GFX2D0_IRQ (GIC_SPI_START + 81)
+#define DSI_IRQ (GIC_SPI_START + 82)
+#define CSI_1_IRQ (GIC_SPI_START + 83)
+#define CSI_0_IRQ (GIC_SPI_START + 84)
+#define LPASS_SCSS_AUDIO_IF_OUT0_IRQ (GIC_SPI_START + 85)
+#define LPASS_SCSS_MIDI_IRQ (GIC_SPI_START + 86)
+#define LPASS_Q6SS_WDOG_EXPIRED (GIC_SPI_START + 87)
+#define LPASS_SCSS_GP_LOW_IRQ (GIC_SPI_START + 88)
+#define LPASS_SCSS_GP_MEDIUM_IRQ (GIC_SPI_START + 89)
+#define LPASS_SCSS_GP_HIGH_IRQ (GIC_SPI_START + 90)
+#define TOP_IMEM_IRQ (GIC_SPI_START + 91)
+#define FABRIC_SYS_IRQ (GIC_SPI_START + 92)
+#define FABRIC_APPS_IRQ (GIC_SPI_START + 93)
+#define USB1_HS_BAM_IRQ (GIC_SPI_START + 94)
+#define SDC4_BAM_IRQ (GIC_SPI_START + 95)
+#define SDC3_BAM_IRQ (GIC_SPI_START + 96)
+#define SDC2_BAM_IRQ (GIC_SPI_START + 97)
+#define SDC1_BAM_IRQ (GIC_SPI_START + 98)
+#define FABRIC_SPS_IRQ (GIC_SPI_START + 99)
+#define USB1_HS_IRQ (GIC_SPI_START + 100)
+#define SDC4_IRQ_0 (GIC_SPI_START + 101)
+#define SDC3_IRQ_0 (GIC_SPI_START + 102)
+#define SDC2_IRQ_0 (GIC_SPI_START + 103)
+#define SDC1_IRQ_0 (GIC_SPI_START + 104)
+#define SPS_BAM_DMA_IRQ (GIC_SPI_START + 105)
+#define SPS_SEC_VIOL_IRQ (GIC_SPI_START + 106)
+#define SPS_MTI_0 (GIC_SPI_START + 107)
+#define SPS_MTI_1 (GIC_SPI_START + 108)
+#define SPS_MTI_2 (GIC_SPI_START + 109)
+#define SPS_MTI_3 (GIC_SPI_START + 110)
+#define SPS_MTI_4 (GIC_SPI_START + 111)
+#define SPS_MTI_5 (GIC_SPI_START + 112)
+#define SPS_MTI_6 (GIC_SPI_START + 113)
+#define SPS_MTI_7 (GIC_SPI_START + 114)
+#define SPS_MTI_8 (GIC_SPI_START + 115)
+#define SPS_MTI_9 (GIC_SPI_START + 116)
+#define SPS_MTI_10 (GIC_SPI_START + 117)
+#define SPS_MTI_11 (GIC_SPI_START + 118)
+#define SPS_MTI_12 (GIC_SPI_START + 119)
+#define SPS_MTI_13 (GIC_SPI_START + 120)
+#define SPS_MTI_14 (GIC_SPI_START + 121)
+#define SPS_MTI_15 (GIC_SPI_START + 122)
+#define SPS_MTI_16 (GIC_SPI_START + 123)
+#define SPS_MTI_17 (GIC_SPI_START + 124)
+#define SPS_MTI_18 (GIC_SPI_START + 125)
+#define SPS_MTI_19 (GIC_SPI_START + 126)
+#define SPS_MTI_20 (GIC_SPI_START + 127)
+#define SPS_MTI_21 (GIC_SPI_START + 128)
+#define SPS_MTI_22 (GIC_SPI_START + 129)
+#define SPS_MTI_23 (GIC_SPI_START + 130)
+#define SPS_MTI_24 (GIC_SPI_START + 131)
+#define SPS_MTI_25 (GIC_SPI_START + 132)
+#define SPS_MTI_26 (GIC_SPI_START + 133)
+#define SPS_MTI_27 (GIC_SPI_START + 134)
+#define SPS_MTI_28 (GIC_SPI_START + 135)
+#define SPS_MTI_29 (GIC_SPI_START + 136)
+#define SPS_MTI_30 (GIC_SPI_START + 137)
+#define SPS_MTI_31 (GIC_SPI_START + 138)
+#define UXMC_EBI2_WR_ER_DONE_IRQ (GIC_SPI_START + 139)
+#define UXMC_EBI2_OP_DONE_IRQ (GIC_SPI_START + 140)
+#define USB2_IRQ (GIC_SPI_START + 141)
+#define USB1_IRQ (GIC_SPI_START + 142)
+#define TSSC_SSBI_IRQ (GIC_SPI_START + 143)
+#define TSSC_SAMPLE_IRQ (GIC_SPI_START + 144)
+#define TSSC_PENUP_IRQ (GIC_SPI_START + 145)
+#define INT_UART1DM_IRQ (GIC_SPI_START + 146)
+#define GSBI1_QUP_IRQ (GIC_SPI_START + 147)
+#define INT_UART2DM_IRQ (GIC_SPI_START + 148)
+#define GSBI2_QUP_IRQ (GIC_SPI_START + 149)
+#define INT_UART3DM_IRQ (GIC_SPI_START + 150)
+#define GSBI3_QUP_IRQ (GIC_SPI_START + 151)
+#define INT_UART4DM_IRQ (GIC_SPI_START + 152)
+#define GSBI4_QUP_IRQ (GIC_SPI_START + 153)
+#define INT_UART5DM_IRQ (GIC_SPI_START + 154)
+#define GSBI5_QUP_IRQ (GIC_SPI_START + 155)
+#define INT_UART6DM_IRQ (GIC_SPI_START + 156)
+#define GSBI6_QUP_IRQ (GIC_SPI_START + 157)
+#define INT_UART7DM_IRQ (GIC_SPI_START + 158)
+#define GSBI7_QUP_IRQ (GIC_SPI_START + 159)
+#define INT_UART8DM_IRQ (GIC_SPI_START + 160)
+#define GSBI8_QUP_IRQ (GIC_SPI_START + 161)
+#define TSIF_TSPP_IRQ (GIC_SPI_START + 162)
+#define TSIF_BAM_IRQ (GIC_SPI_START + 163)
+#define TSIF2_IRQ (GIC_SPI_START + 164)
+#define TSIF1_IRQ (GIC_SPI_START + 165)
+#define INT_ADM1_MASTER (GIC_SPI_START + 166)
+#define INT_ADM1_AARM (GIC_SPI_START + 167)
+#define INT_ADM1_SD2 (GIC_SPI_START + 168)
+#define INT_ADM1_SD3 (GIC_SPI_START + 169)
+#define INT_ADM0_MASTER (GIC_SPI_START + 170)
+#define INT_ADM0_AARM (GIC_SPI_START + 171)
+#define INT_ADM0_SD2 (GIC_SPI_START + 172)
+#define INT_ADM0_SD3 (GIC_SPI_START + 173)
+#define CC_SCSS_WDT1CPU1BITEEXPIRED (GIC_SPI_START + 174)
+#define CC_SCSS_WDT1CPU0BITEEXPIRED (GIC_SPI_START + 175)
+#define CC_SCSS_WDT0CPU1BITEEXPIRED (GIC_SPI_START + 176)
+#define CC_SCSS_WDT0CPU0BITEEXPIRED (GIC_SPI_START + 177)
+#define TSENS_UPPER_LOWER_INT (GIC_SPI_START + 178)
+#define SSBI2_2_SC_CPU1_SECURE_INT (GIC_SPI_START + 179)
+#define SSBI2_2_SC_CPU1_NON_SECURE_INT (GIC_SPI_START + 180)
+#define SSBI2_1_SC_CPU1_SECURE_INT (GIC_SPI_START + 181)
+#define SSBI2_1_SC_CPU1_NON_SECURE_INT (GIC_SPI_START + 182)
+#define XPU_SUMMARY_IRQ (GIC_SPI_START + 183)
+#define BUS_EXCEPTION_SUMMARY_IRQ (GIC_SPI_START + 184)
+#define HSDDRX_SMICH0_IRQ (GIC_SPI_START + 185)
+#define HSDDRX_EBI1_IRQ (GIC_SPI_START + 186)
+#define SDC5_BAM_IRQ (GIC_SPI_START + 187)
+#define SDC5_IRQ_0 (GIC_SPI_START + 188)
+#define INT_UART9DM_IRQ (GIC_SPI_START + 189)
+#define GSBI9_QUP_IRQ (GIC_SPI_START + 190)
+#define INT_UART10DM_IRQ (GIC_SPI_START + 191)
+#define GSBI10_QUP_IRQ (GIC_SPI_START + 192)
+#define INT_UART11DM_IRQ (GIC_SPI_START + 193)
+#define GSBI11_QUP_IRQ (GIC_SPI_START + 194)
+#define INT_UART12DM_IRQ (GIC_SPI_START + 195)
+#define GSBI12_QUP_IRQ (GIC_SPI_START + 196)
+/*SPI 197 to 216 arent used in 8x60*/
+#define SMPSS_SPARE_1 (GIC_SPI_START + 217)
+#define SMPSS_SPARE_2 (GIC_SPI_START + 218)
+#define SMPSS_SPARE_3 (GIC_SPI_START + 219)
+#define SMPSS_SPARE_4 (GIC_SPI_START + 220)
+#define SMPSS_SPARE_5 (GIC_SPI_START + 221)
+#define SMPSS_SPARE_6 (GIC_SPI_START + 222)
+#define SMPSS_SPARE_7 (GIC_SPI_START + 223)
+
+#define NR_GPIO_IRQS 173
+#define NR_MSM_IRQS 256
+#define NR_BOARD_IRQS 0
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/irqs.h b/arch/arm/mach-msm/include/mach/irqs.h
index 164d355c96ea..8679a4564744 100644
--- a/arch/arm/mach-msm/include/mach/irqs.h
+++ b/arch/arm/mach-msm/include/mach/irqs.h
@@ -24,6 +24,8 @@
#elif defined(CONFIG_ARCH_QSD8X50)
#include "irqs-8x50.h"
#include "sirc.h"
+#elif defined(CONFIG_ARCH_MSM8X60)
+#include "irqs-8x60.h"
#elif defined(CONFIG_ARCH_MSM_ARM11)
#include "irqs-7x00.h"
#else
diff --git a/arch/arm/mach-msm/include/mach/memory.h b/arch/arm/mach-msm/include/mach/memory.h
index 50c7847e6002..070e17d237f1 100644
--- a/arch/arm/mach-msm/include/mach/memory.h
+++ b/arch/arm/mach-msm/include/mach/memory.h
@@ -23,6 +23,8 @@
#define PHYS_OFFSET UL(0x20000000)
#elif defined(CONFIG_ARCH_MSM7X30)
#define PHYS_OFFSET UL(0x00200000)
+#elif defined(CONFIG_ARCH_MSM8X60)
+#define PHYS_OFFSET UL(0x40200000)
#else
#define PHYS_OFFSET UL(0x10000000)
#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
new file mode 100644
index 000000000000..45bab50e3ee6
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ *
+ * The MSM peripherals are spread all over across 768MB of physical
+ * space, which makes just having a simple IO_ADDRESS macro to slide
+ * them into the right virtual location rough. Instead, we will
+ * provide a master phys->virt mapping for peripherals here.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_IOMAP_8X60_H
+#define __ASM_ARCH_MSM_IOMAP_8X60_H
+
+/* Physical base address and size of peripherals.
+ * Ordered by the virtual base addresses they will be mapped at.
+ *
+ * MSM_VIC_BASE must be an value that can be loaded via a "mov"
+ * instruction, otherwise entry-macro.S will not compile.
+ *
+ * If you add or remove entries here, you'll want to edit the
+ * msm_io_desc array in arch/arm/mach-msm/io.c to reflect your
+ * changes.
+ *
+ */
+
+#define MSM_QGIC_DIST_BASE IOMEM(0xF0000000)
+#define MSM_QGIC_DIST_PHYS 0x02080000
+#define MSM_QGIC_DIST_SIZE SZ_4K
+
+#define MSM_QGIC_CPU_BASE IOMEM(0xF0001000)
+#define MSM_QGIC_CPU_PHYS 0x02081000
+#define MSM_QGIC_CPU_SIZE SZ_4K
+
+#define MSM_ACC_BASE IOMEM(0xF0002000)
+#define MSM_ACC_PHYS 0x02001000
+#define MSM_ACC_SIZE SZ_4K
+
+#define MSM_GCC_BASE IOMEM(0xF0003000)
+#define MSM_GCC_PHYS 0x02082000
+#define MSM_GCC_SIZE SZ_4K
+
+#define MSM_TLMM_BASE IOMEM(0xF0004000)
+#define MSM_TLMM_PHYS 0x00800000
+#define MSM_TLMM_SIZE SZ_16K
+
+#define MSM_SHARED_RAM_BASE IOMEM(0xF0100000)
+#define MSM_SHARED_RAM_SIZE SZ_1M
+
+#define MSM_TMR_BASE IOMEM(0xF0200000)
+#define MSM_TMR_PHYS 0x02000000
+#define MSM_TMR_SIZE (SZ_1M)
+
+#define MSM_GPT_BASE (MSM_TMR_BASE + 0x4)
+#define MSM_DGT_BASE (MSM_TMR_BASE + 0x24)
+
+#define MSM_IOMMU_JPEGD_PHYS 0x07300000
+#define MSM_IOMMU_JPEGD_SIZE SZ_1M
+
+#define MSM_IOMMU_VPE_PHYS 0x07400000
+#define MSM_IOMMU_VPE_SIZE SZ_1M
+
+#define MSM_IOMMU_MDP0_PHYS 0x07500000
+#define MSM_IOMMU_MDP0_SIZE SZ_1M
+
+#define MSM_IOMMU_MDP1_PHYS 0x07600000
+#define MSM_IOMMU_MDP1_SIZE SZ_1M
+
+#define MSM_IOMMU_ROT_PHYS 0x07700000
+#define MSM_IOMMU_ROT_SIZE SZ_1M
+
+#define MSM_IOMMU_IJPEG_PHYS 0x07800000
+#define MSM_IOMMU_IJPEG_SIZE SZ_1M
+
+#define MSM_IOMMU_VFE_PHYS 0x07900000
+#define MSM_IOMMU_VFE_SIZE SZ_1M
+
+#define MSM_IOMMU_VCODEC_A_PHYS 0x07A00000
+#define MSM_IOMMU_VCODEC_A_SIZE SZ_1M
+
+#define MSM_IOMMU_VCODEC_B_PHYS 0x07B00000
+#define MSM_IOMMU_VCODEC_B_SIZE SZ_1M
+
+#define MSM_IOMMU_GFX3D_PHYS 0x07C00000
+#define MSM_IOMMU_GFX3D_SIZE SZ_1M
+
+#define MSM_IOMMU_GFX2D0_PHYS 0x07D00000
+#define MSM_IOMMU_GFX2D0_SIZE SZ_1M
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h
index e6b1821cc4ea..8e24dd812139 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap.h
@@ -47,8 +47,12 @@
#include "msm_iomap-7x30.h"
#elif defined(CONFIG_ARCH_QSD8X50)
#include "msm_iomap-8x50.h"
+#elif defined(CONFIG_ARCH_MSM8X60)
+#include "msm_iomap-8x60.h"
#else
#include "msm_iomap-7x00.h"
#endif
+
+
#endif
diff --git a/arch/arm/mach-msm/include/mach/smp.h b/arch/arm/mach-msm/include/mach/smp.h
new file mode 100644
index 000000000000..3ff7bf5e679e
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/smp.h
@@ -0,0 +1,39 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Code Aurora nor
+ * the names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_SMP_H
+#define __ASM_ARCH_MSM_SMP_H
+
+#include <asm/hardware/gic.h>
+
+static inline void smp_cross_call(const struct cpumask *mask)
+{
+ gic_raise_softirq(mask, 1);
+}
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/vmalloc.h b/arch/arm/mach-msm/include/mach/vmalloc.h
index 05f81fd8623c..31a32ad062dc 100644
--- a/arch/arm/mach-msm/include/mach/vmalloc.h
+++ b/arch/arm/mach-msm/include/mach/vmalloc.h
@@ -16,7 +16,7 @@
#ifndef __ASM_ARCH_MSM_VMALLOC_H
#define __ASM_ARCH_MSM_VMALLOC_H
-#define VMALLOC_END (PAGE_OFFSET + 0x10000000)
+#define VMALLOC_END 0xd0000000
#endif
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index 1c05060b5f3b..d36b61074146 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -100,6 +100,21 @@ void __init msm_map_qsd8x50_io(void)
}
#endif /* CONFIG_ARCH_QSD8X50 */
+#ifdef CONFIG_ARCH_MSM8X60
+static struct map_desc msm8x60_io_desc[] __initdata = {
+ MSM_DEVICE(QGIC_DIST),
+ MSM_DEVICE(QGIC_CPU),
+ MSM_DEVICE(TMR),
+ MSM_DEVICE(ACC),
+ MSM_DEVICE(GCC),
+};
+
+void __init msm_map_msm8x60_io(void)
+{
+ iotable_init(msm8x60_io_desc, ARRAY_SIZE(msm8x60_io_desc));
+}
+#endif /* CONFIG_ARCH_MSM8X60 */
+
#ifdef CONFIG_ARCH_MSM7X30
static struct map_desc msm7x30_io_desc[] __initdata = {
MSM_DEVICE(VIC),
diff --git a/arch/arm/mach-msm/iommu.c b/arch/arm/mach-msm/iommu.c
new file mode 100644
index 000000000000..f71747db3bee
--- /dev/null
+++ b/arch/arm/mach-msm/iommu.c
@@ -0,0 +1,597 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/iommu.h>
+
+#include <asm/cacheflush.h>
+#include <asm/sizes.h>
+
+#include <mach/iommu_hw-8xxx.h>
+#include <mach/iommu.h>
+
+DEFINE_SPINLOCK(msm_iommu_lock);
+
+struct msm_priv {
+ unsigned long *pgtable;
+ struct list_head list_attached;
+};
+
+static void __flush_iotlb(struct iommu_domain *domain)
+{
+ struct msm_priv *priv = domain->priv;
+ struct msm_iommu_drvdata *iommu_drvdata;
+ struct msm_iommu_ctx_drvdata *ctx_drvdata;
+
+#ifndef CONFIG_IOMMU_PGTABLES_L2
+ unsigned long *fl_table = priv->pgtable;
+ int i;
+
+ dmac_flush_range(fl_table, fl_table + SZ_16K);
+
+ for (i = 0; i < NUM_FL_PTE; i++)
+ if ((fl_table[i] & 0x03) == FL_TYPE_TABLE) {
+ void *sl_table = __va(fl_table[i] & FL_BASE_MASK);
+ dmac_flush_range(sl_table, sl_table + SZ_4K);
+ }
+#endif
+
+ list_for_each_entry(ctx_drvdata, &priv->list_attached, attached_elm) {
+ if (!ctx_drvdata->pdev || !ctx_drvdata->pdev->dev.parent)
+ BUG();
+
+ iommu_drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent);
+ SET_CTX_TLBIALL(iommu_drvdata->base, ctx_drvdata->num, 0);
+ }
+}
+
+static void __reset_context(void __iomem *base, int ctx)
+{
+ SET_BPRCOSH(base, ctx, 0);
+ SET_BPRCISH(base, ctx, 0);
+ SET_BPRCNSH(base, ctx, 0);
+ SET_BPSHCFG(base, ctx, 0);
+ SET_BPMTCFG(base, ctx, 0);
+ SET_ACTLR(base, ctx, 0);
+ SET_SCTLR(base, ctx, 0);
+ SET_FSRRESTORE(base, ctx, 0);
+ SET_TTBR0(base, ctx, 0);
+ SET_TTBR1(base, ctx, 0);
+ SET_TTBCR(base, ctx, 0);
+ SET_BFBCR(base, ctx, 0);
+ SET_PAR(base, ctx, 0);
+ SET_FAR(base, ctx, 0);
+ SET_CTX_TLBIALL(base, ctx, 0);
+ SET_TLBFLPTER(base, ctx, 0);
+ SET_TLBSLPTER(base, ctx, 0);
+ SET_TLBLKCR(base, ctx, 0);
+ SET_PRRR(base, ctx, 0);
+ SET_NMRR(base, ctx, 0);
+ SET_CONTEXTIDR(base, ctx, 0);
+}
+
+static void __program_context(void __iomem *base, int ctx, phys_addr_t pgtable)
+{
+ __reset_context(base, ctx);
+
+ /* Set up HTW mode */
+ /* TLB miss configuration: perform HTW on miss */
+ SET_TLBMCFG(base, ctx, 0x3);
+
+ /* V2P configuration: HTW for access */
+ SET_V2PCFG(base, ctx, 0x3);
+
+ SET_TTBCR(base, ctx, 0);
+ SET_TTBR0_PA(base, ctx, (pgtable >> 14));
+
+ /* Invalidate the TLB for this context */
+ SET_CTX_TLBIALL(base, ctx, 0);
+
+ /* Set interrupt number to "secure" interrupt */
+ SET_IRPTNDX(base, ctx, 0);
+
+ /* Enable context fault interrupt */
+ SET_CFEIE(base, ctx, 1);
+
+ /* Stall access on a context fault and let the handler deal with it */
+ SET_CFCFG(base, ctx, 1);
+
+ /* Redirect all cacheable requests to L2 slave port. */
+ SET_RCISH(base, ctx, 1);
+ SET_RCOSH(base, ctx, 1);
+ SET_RCNSH(base, ctx, 1);
+
+ /* Turn on TEX Remap */
+ SET_TRE(base, ctx, 1);
+
+ /* Do not configure PRRR / NMRR on the IOMMU for now. We will assume
+ * TEX class 0 for everything until attributes are properly worked out
+ */
+ SET_PRRR(base, ctx, 0);
+ SET_NMRR(base, ctx, 0);
+
+ /* Turn on BFB prefetch */
+ SET_BFBDFE(base, ctx, 1);
+
+#ifdef CONFIG_IOMMU_PGTABLES_L2
+ /* Configure page tables as inner-cacheable and shareable to reduce
+ * the TLB miss penalty.
+ */
+ SET_TTBR0_SH(base, ctx, 1);
+ SET_TTBR1_SH(base, ctx, 1);
+
+ SET_TTBR0_NOS(base, ctx, 1);
+ SET_TTBR1_NOS(base, ctx, 1);
+
+ SET_TTBR0_IRGNH(base, ctx, 0); /* WB, WA */
+ SET_TTBR0_IRGNL(base, ctx, 1);
+
+ SET_TTBR1_IRGNH(base, ctx, 0); /* WB, WA */
+ SET_TTBR1_IRGNL(base, ctx, 1);
+
+ SET_TTBR0_ORGN(base, ctx, 1); /* WB, WA */
+ SET_TTBR1_ORGN(base, ctx, 1); /* WB, WA */
+#endif
+
+ /* Enable the MMU */
+ SET_M(base, ctx, 1);
+}
+
+static int msm_iommu_domain_init(struct iommu_domain *domain)
+{
+ struct msm_priv *priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+
+ if (!priv)
+ goto fail_nomem;
+
+ INIT_LIST_HEAD(&priv->list_attached);
+ priv->pgtable = (unsigned long *)__get_free_pages(GFP_KERNEL,
+ get_order(SZ_16K));
+
+ if (!priv->pgtable)
+ goto fail_nomem;
+
+ memset(priv->pgtable, 0, SZ_16K);
+ domain->priv = priv;
+ return 0;
+
+fail_nomem:
+ kfree(priv);
+ return -ENOMEM;
+}
+
+static void msm_iommu_domain_destroy(struct iommu_domain *domain)
+{
+ struct msm_priv *priv;
+ unsigned long flags;
+ unsigned long *fl_table;
+ int i;
+
+ spin_lock_irqsave(&msm_iommu_lock, flags);
+ priv = domain->priv;
+ domain->priv = NULL;
+
+ if (priv) {
+ fl_table = priv->pgtable;
+
+ for (i = 0; i < NUM_FL_PTE; i++)
+ if ((fl_table[i] & 0x03) == FL_TYPE_TABLE)
+ free_page((unsigned long) __va(((fl_table[i]) &
+ FL_BASE_MASK)));
+
+ free_pages((unsigned long)priv->pgtable, get_order(SZ_16K));
+ priv->pgtable = NULL;
+ }
+
+ kfree(priv);
+ spin_unlock_irqrestore(&msm_iommu_lock, flags);
+}
+
+static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
+{
+ struct msm_priv *priv;
+ struct msm_iommu_ctx_dev *ctx_dev;
+ struct msm_iommu_drvdata *iommu_drvdata;
+ struct msm_iommu_ctx_drvdata *ctx_drvdata;
+ struct msm_iommu_ctx_drvdata *tmp_drvdata;
+ int ret = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&msm_iommu_lock, flags);
+
+ priv = domain->priv;
+
+ if (!priv || !dev) {
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ iommu_drvdata = dev_get_drvdata(dev->parent);
+ ctx_drvdata = dev_get_drvdata(dev);
+ ctx_dev = dev->platform_data;
+
+ if (!iommu_drvdata || !ctx_drvdata || !ctx_dev) {
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ list_for_each_entry(tmp_drvdata, &priv->list_attached, attached_elm)
+ if (tmp_drvdata == ctx_drvdata) {
+ ret = -EBUSY;
+ goto fail;
+ }
+
+ __program_context(iommu_drvdata->base, ctx_dev->num,
+ __pa(priv->pgtable));
+
+ list_add(&(ctx_drvdata->attached_elm), &priv->list_attached);
+ __flush_iotlb(domain);
+
+fail:
+ spin_unlock_irqrestore(&msm_iommu_lock, flags);
+ return ret;
+}
+
+static void msm_iommu_detach_dev(struct iommu_domain *domain,
+ struct device *dev)
+{
+ struct msm_priv *priv;
+ struct msm_iommu_ctx_dev *ctx_dev;
+ struct msm_iommu_drvdata *iommu_drvdata;
+ struct msm_iommu_ctx_drvdata *ctx_drvdata;
+ unsigned long flags;
+
+ spin_lock_irqsave(&msm_iommu_lock, flags);
+ priv = domain->priv;
+
+ if (!priv || !dev)
+ goto fail;
+
+ iommu_drvdata = dev_get_drvdata(dev->parent);
+ ctx_drvdata = dev_get_drvdata(dev);
+ ctx_dev = dev->platform_data;
+
+ if (!iommu_drvdata || !ctx_drvdata || !ctx_dev)
+ goto fail;
+
+ __flush_iotlb(domain);
+ __reset_context(iommu_drvdata->base, ctx_dev->num);
+ list_del_init(&ctx_drvdata->attached_elm);
+
+fail:
+ spin_unlock_irqrestore(&msm_iommu_lock, flags);
+}
+
+static int msm_iommu_map(struct iommu_domain *domain, unsigned long va,
+ phys_addr_t pa, int order, int prot)
+{
+ struct msm_priv *priv;
+ unsigned long flags;
+ unsigned long *fl_table;
+ unsigned long *fl_pte;
+ unsigned long fl_offset;
+ unsigned long *sl_table;
+ unsigned long *sl_pte;
+ unsigned long sl_offset;
+ size_t len = 0x1000UL << order;
+ int ret = 0;
+
+ spin_lock_irqsave(&msm_iommu_lock, flags);
+ priv = domain->priv;
+
+ if (!priv) {
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ fl_table = priv->pgtable;
+
+ if (len != SZ_16M && len != SZ_1M &&
+ len != SZ_64K && len != SZ_4K) {
+ pr_debug("Bad size: %d\n", len);
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ if (!fl_table) {
+ pr_debug("Null page table\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ fl_offset = FL_OFFSET(va); /* Upper 12 bits */
+ fl_pte = fl_table + fl_offset; /* int pointers, 4 bytes */
+
+ if (len == SZ_16M) {
+ int i = 0;
+ for (i = 0; i < 16; i++)
+ *(fl_pte+i) = (pa & 0xFF000000) | FL_SUPERSECTION |
+ FL_AP_READ | FL_AP_WRITE | FL_TYPE_SECT |
+ FL_SHARED;
+ }
+
+ if (len == SZ_1M)
+ *fl_pte = (pa & 0xFFF00000) | FL_AP_READ | FL_AP_WRITE |
+ FL_TYPE_SECT | FL_SHARED;
+
+ /* Need a 2nd level table */
+ if ((len == SZ_4K || len == SZ_64K) && (*fl_pte) == 0) {
+ unsigned long *sl;
+ sl = (unsigned long *) __get_free_pages(GFP_KERNEL,
+ get_order(SZ_4K));
+
+ if (!sl) {
+ pr_debug("Could not allocate second level table\n");
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ memset(sl, 0, SZ_4K);
+ *fl_pte = ((((int)__pa(sl)) & FL_BASE_MASK) | FL_TYPE_TABLE);
+ }
+
+ sl_table = (unsigned long *) __va(((*fl_pte) & FL_BASE_MASK));
+ sl_offset = SL_OFFSET(va);
+ sl_pte = sl_table + sl_offset;
+
+
+ if (len == SZ_4K)
+ *sl_pte = (pa & SL_BASE_MASK_SMALL) | SL_AP0 | SL_AP1 |
+ SL_SHARED | SL_TYPE_SMALL;
+
+ if (len == SZ_64K) {
+ int i;
+
+ for (i = 0; i < 16; i++)
+ *(sl_pte+i) = (pa & SL_BASE_MASK_LARGE) | SL_AP0 |
+ SL_AP1 | SL_SHARED | SL_TYPE_LARGE;
+ }
+
+ __flush_iotlb(domain);
+fail:
+ spin_unlock_irqrestore(&msm_iommu_lock, flags);
+ return ret;
+}
+
+static int msm_iommu_unmap(struct iommu_domain *domain, unsigned long va,
+ int order)
+{
+ struct msm_priv *priv;
+ unsigned long flags;
+ unsigned long *fl_table;
+ unsigned long *fl_pte;
+ unsigned long fl_offset;
+ unsigned long *sl_table;
+ unsigned long *sl_pte;
+ unsigned long sl_offset;
+ size_t len = 0x1000UL << order;
+ int i, ret = 0;
+
+ spin_lock_irqsave(&msm_iommu_lock, flags);
+
+ priv = domain->priv;
+
+ if (!priv) {
+ ret = -ENODEV;
+ goto fail;
+ }
+
+ fl_table = priv->pgtable;
+
+ if (len != SZ_16M && len != SZ_1M &&
+ len != SZ_64K && len != SZ_4K) {
+ pr_debug("Bad length: %d\n", len);
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ if (!fl_table) {
+ pr_debug("Null page table\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ fl_offset = FL_OFFSET(va); /* Upper 12 bits */
+ fl_pte = fl_table + fl_offset; /* int pointers, 4 bytes */
+
+ if (*fl_pte == 0) {
+ pr_debug("First level PTE is 0\n");
+ ret = -ENODEV;
+ goto fail;
+ }
+
+ /* Unmap supersection */
+ if (len == SZ_16M)
+ for (i = 0; i < 16; i++)
+ *(fl_pte+i) = 0;
+
+ if (len == SZ_1M)
+ *fl_pte = 0;
+
+ sl_table = (unsigned long *) __va(((*fl_pte) & FL_BASE_MASK));
+ sl_offset = SL_OFFSET(va);
+ sl_pte = sl_table + sl_offset;
+
+ if (len == SZ_64K) {
+ for (i = 0; i < 16; i++)
+ *(sl_pte+i) = 0;
+ }
+
+ if (len == SZ_4K)
+ *sl_pte = 0;
+
+ if (len == SZ_4K || len == SZ_64K) {
+ int used = 0;
+
+ for (i = 0; i < NUM_SL_PTE; i++)
+ if (sl_table[i])
+ used = 1;
+ if (!used) {
+ free_page((unsigned long)sl_table);
+ *fl_pte = 0;
+ }
+ }
+
+ __flush_iotlb(domain);
+fail:
+ spin_unlock_irqrestore(&msm_iommu_lock, flags);
+ return ret;
+}
+
+static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain,
+ unsigned long va)
+{
+ struct msm_priv *priv;
+ struct msm_iommu_drvdata *iommu_drvdata;
+ struct msm_iommu_ctx_drvdata *ctx_drvdata;
+ unsigned int par;
+ unsigned long flags;
+ void __iomem *base;
+ phys_addr_t ret = 0;
+ int ctx;
+
+ spin_lock_irqsave(&msm_iommu_lock, flags);
+
+ priv = domain->priv;
+ if (list_empty(&priv->list_attached))
+ goto fail;
+
+ ctx_drvdata = list_entry(priv->list_attached.next,
+ struct msm_iommu_ctx_drvdata, attached_elm);
+ iommu_drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent);
+
+ base = iommu_drvdata->base;
+ ctx = ctx_drvdata->num;
+
+ /* Invalidate context TLB */
+ SET_CTX_TLBIALL(base, ctx, 0);
+ SET_V2PPR_VA(base, ctx, va >> V2Pxx_VA_SHIFT);
+
+ if (GET_FAULT(base, ctx))
+ goto fail;
+
+ par = GET_PAR(base, ctx);
+
+ /* We are dealing with a supersection */
+ if (GET_NOFAULT_SS(base, ctx))
+ ret = (par & 0xFF000000) | (va & 0x00FFFFFF);
+ else /* Upper 20 bits from PAR, lower 12 from VA */
+ ret = (par & 0xFFFFF000) | (va & 0x00000FFF);
+
+fail:
+ spin_unlock_irqrestore(&msm_iommu_lock, flags);
+ return ret;
+}
+
+static int msm_iommu_domain_has_cap(struct iommu_domain *domain,
+ unsigned long cap)
+{
+ return 0;
+}
+
+static void print_ctx_regs(void __iomem *base, int ctx)
+{
+ unsigned int fsr = GET_FSR(base, ctx);
+ pr_err("FAR = %08x PAR = %08x\n",
+ GET_FAR(base, ctx), GET_PAR(base, ctx));
+ pr_err("FSR = %08x [%s%s%s%s%s%s%s%s%s%s]\n", fsr,
+ (fsr & 0x02) ? "TF " : "",
+ (fsr & 0x04) ? "AFF " : "",
+ (fsr & 0x08) ? "APF " : "",
+ (fsr & 0x10) ? "TLBMF " : "",
+ (fsr & 0x20) ? "HTWDEEF " : "",
+ (fsr & 0x40) ? "HTWSEEF " : "",
+ (fsr & 0x80) ? "MHF " : "",
+ (fsr & 0x10000) ? "SL " : "",
+ (fsr & 0x40000000) ? "SS " : "",
+ (fsr & 0x80000000) ? "MULTI " : "");
+
+ pr_err("FSYNR0 = %08x FSYNR1 = %08x\n",
+ GET_FSYNR0(base, ctx), GET_FSYNR1(base, ctx));
+ pr_err("TTBR0 = %08x TTBR1 = %08x\n",
+ GET_TTBR0(base, ctx), GET_TTBR1(base, ctx));
+ pr_err("SCTLR = %08x ACTLR = %08x\n",
+ GET_SCTLR(base, ctx), GET_ACTLR(base, ctx));
+ pr_err("PRRR = %08x NMRR = %08x\n",
+ GET_PRRR(base, ctx), GET_NMRR(base, ctx));
+}
+
+irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id)
+{
+ struct msm_iommu_drvdata *drvdata = dev_id;
+ void __iomem *base;
+ unsigned int fsr = 0;
+ int ncb = 0, i = 0;
+
+ spin_lock(&msm_iommu_lock);
+
+ if (!drvdata) {
+ pr_err("Invalid device ID in context interrupt handler\n");
+ goto fail;
+ }
+
+ base = drvdata->base;
+
+ pr_err("===== WOAH! =====\n");
+ pr_err("Unexpected IOMMU page fault!\n");
+ pr_err("base = %08x\n", (unsigned int) base);
+
+ ncb = GET_NCB(base)+1;
+ for (i = 0; i < ncb; i++) {
+ fsr = GET_FSR(base, i);
+ if (fsr) {
+ pr_err("Fault occurred in context %d.\n", i);
+ pr_err("Interesting registers:\n");
+ print_ctx_regs(base, i);
+ SET_FSR(base, i, 0x4000000F);
+ }
+ }
+fail:
+ spin_unlock(&msm_iommu_lock);
+ return 0;
+}
+
+static struct iommu_ops msm_iommu_ops = {
+ .domain_init = msm_iommu_domain_init,
+ .domain_destroy = msm_iommu_domain_destroy,
+ .attach_dev = msm_iommu_attach_dev,
+ .detach_dev = msm_iommu_detach_dev,
+ .map = msm_iommu_map,
+ .unmap = msm_iommu_unmap,
+ .iova_to_phys = msm_iommu_iova_to_phys,
+ .domain_has_cap = msm_iommu_domain_has_cap
+};
+
+static int msm_iommu_init(void)
+{
+ register_iommu(&msm_iommu_ops);
+ return 0;
+}
+
+subsys_initcall(msm_iommu_init);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>");
diff --git a/arch/arm/mach-msm/iommu_dev.c b/arch/arm/mach-msm/iommu_dev.c
new file mode 100644
index 000000000000..c33ae786c41f
--- /dev/null
+++ b/arch/arm/mach-msm/iommu_dev.c
@@ -0,0 +1,374 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/iommu.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+
+#include <mach/iommu_hw-8xxx.h>
+#include <mach/iommu.h>
+
+struct iommu_ctx_iter_data {
+ /* input */
+ const char *name;
+
+ /* output */
+ struct device *dev;
+};
+
+static struct platform_device *msm_iommu_root_dev;
+
+static int each_iommu_ctx(struct device *dev, void *data)
+{
+ struct iommu_ctx_iter_data *res = data;
+ struct msm_iommu_ctx_dev *c = dev->platform_data;
+
+ if (!res || !c || !c->name || !res->name)
+ return -EINVAL;
+
+ if (!strcmp(res->name, c->name)) {
+ res->dev = dev;
+ return 1;
+ }
+ return 0;
+}
+
+static int each_iommu(struct device *dev, void *data)
+{
+ return device_for_each_child(dev, data, each_iommu_ctx);
+}
+
+struct device *msm_iommu_get_ctx(const char *ctx_name)
+{
+ struct iommu_ctx_iter_data r;
+ int found;
+
+ if (!msm_iommu_root_dev) {
+ pr_err("No root IOMMU device.\n");
+ goto fail;
+ }
+
+ r.name = ctx_name;
+ found = device_for_each_child(&msm_iommu_root_dev->dev, &r, each_iommu);
+
+ if (!found) {
+ pr_err("Could not find context <%s>\n", ctx_name);
+ goto fail;
+ }
+
+ return r.dev;
+fail:
+ return NULL;
+}
+EXPORT_SYMBOL(msm_iommu_get_ctx);
+
+static void msm_iommu_reset(void __iomem *base)
+{
+ int ctx, ncb;
+
+ SET_RPUE(base, 0);
+ SET_RPUEIE(base, 0);
+ SET_ESRRESTORE(base, 0);
+ SET_TBE(base, 0);
+ SET_CR(base, 0);
+ SET_SPDMBE(base, 0);
+ SET_TESTBUSCR(base, 0);
+ SET_TLBRSW(base, 0);
+ SET_GLOBAL_TLBIALL(base, 0);
+ SET_RPU_ACR(base, 0);
+ SET_TLBLKCRWE(base, 1);
+ ncb = GET_NCB(base)+1;
+
+ for (ctx = 0; ctx < ncb; ctx++) {
+ SET_BPRCOSH(base, ctx, 0);
+ SET_BPRCISH(base, ctx, 0);
+ SET_BPRCNSH(base, ctx, 0);
+ SET_BPSHCFG(base, ctx, 0);
+ SET_BPMTCFG(base, ctx, 0);
+ SET_ACTLR(base, ctx, 0);
+ SET_SCTLR(base, ctx, 0);
+ SET_FSRRESTORE(base, ctx, 0);
+ SET_TTBR0(base, ctx, 0);
+ SET_TTBR1(base, ctx, 0);
+ SET_TTBCR(base, ctx, 0);
+ SET_BFBCR(base, ctx, 0);
+ SET_PAR(base, ctx, 0);
+ SET_FAR(base, ctx, 0);
+ SET_CTX_TLBIALL(base, ctx, 0);
+ SET_TLBFLPTER(base, ctx, 0);
+ SET_TLBSLPTER(base, ctx, 0);
+ SET_TLBLKCR(base, ctx, 0);
+ SET_PRRR(base, ctx, 0);
+ SET_NMRR(base, ctx, 0);
+ SET_CONTEXTIDR(base, ctx, 0);
+ }
+}
+
+static int msm_iommu_probe(struct platform_device *pdev)
+{
+ struct resource *r;
+ struct clk *iommu_clk;
+ struct msm_iommu_drvdata *drvdata;
+ struct msm_iommu_dev *iommu_dev = pdev->dev.platform_data;
+ void __iomem *regs_base;
+ resource_size_t len;
+ int ret = 0, ncb, nm2v, irq;
+
+ if (pdev->id != -1) {
+ drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
+
+ if (!drvdata) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ if (!iommu_dev) {
+ ret = -ENODEV;
+ goto fail;
+ }
+
+ if (iommu_dev->clk_rate != 0) {
+ iommu_clk = clk_get(&pdev->dev, "iommu_clk");
+
+ if (IS_ERR(iommu_clk)) {
+ ret = -ENODEV;
+ goto fail;
+ }
+
+ if (iommu_dev->clk_rate > 0) {
+ ret = clk_set_rate(iommu_clk,
+ iommu_dev->clk_rate);
+ if (ret) {
+ clk_put(iommu_clk);
+ goto fail;
+ }
+ }
+
+ ret = clk_enable(iommu_clk);
+ if (ret) {
+ clk_put(iommu_clk);
+ goto fail;
+ }
+ clk_put(iommu_clk);
+ }
+
+ r = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "physbase");
+ if (!r) {
+ ret = -ENODEV;
+ goto fail;
+ }
+
+ len = r->end - r->start + 1;
+
+ r = request_mem_region(r->start, len, r->name);
+ if (!r) {
+ pr_err("Could not request memory region: "
+ "start=%p, len=%d\n", (void *) r->start, len);
+ ret = -EBUSY;
+ goto fail;
+ }
+
+ regs_base = ioremap(r->start, len);
+
+ if (!regs_base) {
+ pr_err("Could not ioremap: start=%p, len=%d\n",
+ (void *) r->start, len);
+ ret = -EBUSY;
+ goto fail;
+ }
+
+ irq = platform_get_irq_byname(pdev, "secure_irq");
+ if (irq < 0) {
+ ret = -ENODEV;
+ goto fail;
+ }
+
+ mb();
+
+ if (GET_IDR(regs_base) == 0) {
+ pr_err("Invalid IDR value detected\n");
+ ret = -ENODEV;
+ goto fail;
+ }
+
+ ret = request_irq(irq, msm_iommu_fault_handler, 0,
+ "msm_iommu_secure_irpt_handler", drvdata);
+ if (ret) {
+ pr_err("Request IRQ %d failed with ret=%d\n", irq, ret);
+ goto fail;
+ }
+
+ msm_iommu_reset(regs_base);
+ drvdata->base = regs_base;
+ drvdata->irq = irq;
+
+ nm2v = GET_NM2VCBMT((unsigned long) regs_base);
+ ncb = GET_NCB((unsigned long) regs_base);
+
+ pr_info("device %s mapped at %p, irq %d with %d ctx banks\n",
+ iommu_dev->name, regs_base, irq, ncb+1);
+
+ platform_set_drvdata(pdev, drvdata);
+ } else
+ msm_iommu_root_dev = pdev;
+
+ return 0;
+
+fail:
+ kfree(drvdata);
+ return ret;
+}
+
+static int msm_iommu_remove(struct platform_device *pdev)
+{
+ struct msm_iommu_drvdata *drv = NULL;
+
+ drv = platform_get_drvdata(pdev);
+ if (drv) {
+ memset(drv, 0, sizeof(struct msm_iommu_drvdata));
+ kfree(drv);
+ platform_set_drvdata(pdev, NULL);
+ }
+ return 0;
+}
+
+static int msm_iommu_ctx_probe(struct platform_device *pdev)
+{
+ struct msm_iommu_ctx_dev *c = pdev->dev.platform_data;
+ struct msm_iommu_drvdata *drvdata;
+ struct msm_iommu_ctx_drvdata *ctx_drvdata = NULL;
+ int i, ret = 0;
+ if (!c || !pdev->dev.parent) {
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ drvdata = dev_get_drvdata(pdev->dev.parent);
+
+ if (!drvdata) {
+ ret = -ENODEV;
+ goto fail;
+ }
+
+ ctx_drvdata = kzalloc(sizeof(*ctx_drvdata), GFP_KERNEL);
+ if (!ctx_drvdata) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+ ctx_drvdata->num = c->num;
+ ctx_drvdata->pdev = pdev;
+
+ INIT_LIST_HEAD(&ctx_drvdata->attached_elm);
+ platform_set_drvdata(pdev, ctx_drvdata);
+
+ /* Program the M2V tables for this context */
+ for (i = 0; i < MAX_NUM_MIDS; i++) {
+ int mid = c->mids[i];
+ if (mid == -1)
+ break;
+
+ SET_M2VCBR_N(drvdata->base, mid, 0);
+ SET_CBACR_N(drvdata->base, c->num, 0);
+
+ /* Set VMID = MID */
+ SET_VMID(drvdata->base, mid, mid);
+
+ /* Set the context number for that MID to this context */
+ SET_CBNDX(drvdata->base, mid, c->num);
+
+ /* Set MID associated with this context bank */
+ SET_CBVMID(drvdata->base, c->num, mid);
+
+ /* Set security bit override to be Non-secure */
+ SET_NSCFG(drvdata->base, mid, 3);
+ }
+
+ pr_info("context device %s with bank index %d\n", c->name, c->num);
+
+ return 0;
+fail:
+ kfree(ctx_drvdata);
+ return ret;
+}
+
+static int msm_iommu_ctx_remove(struct platform_device *pdev)
+{
+ struct msm_iommu_ctx_drvdata *drv = NULL;
+ drv = platform_get_drvdata(pdev);
+ if (drv) {
+ memset(drv, 0, sizeof(struct msm_iommu_ctx_drvdata));
+ kfree(drv);
+ platform_set_drvdata(pdev, NULL);
+ }
+ return 0;
+}
+
+static struct platform_driver msm_iommu_driver = {
+ .driver = {
+ .name = "msm_iommu",
+ },
+ .probe = msm_iommu_probe,
+ .remove = msm_iommu_remove,
+};
+
+static struct platform_driver msm_iommu_ctx_driver = {
+ .driver = {
+ .name = "msm_iommu_ctx",
+ },
+ .probe = msm_iommu_ctx_probe,
+ .remove = msm_iommu_ctx_remove,
+};
+
+static int msm_iommu_driver_init(void)
+{
+ int ret;
+ ret = platform_driver_register(&msm_iommu_driver);
+ if (ret != 0) {
+ pr_err("Failed to register IOMMU driver\n");
+ goto error;
+ }
+
+ ret = platform_driver_register(&msm_iommu_ctx_driver);
+ if (ret != 0) {
+ pr_err("Failed to register IOMMU context driver\n");
+ goto error;
+ }
+
+error:
+ return ret;
+}
+
+static void msm_iommu_driver_exit(void)
+{
+ platform_driver_unregister(&msm_iommu_ctx_driver);
+ platform_driver_unregister(&msm_iommu_driver);
+}
+
+subsys_initcall(msm_iommu_driver_init);
+module_exit(msm_iommu_driver_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>");
diff --git a/arch/arm/mach-msm/last_radio_log.c b/arch/arm/mach-msm/last_radio_log.c
index b64ba5a98686..1e243f46a969 100644
--- a/arch/arm/mach-msm/last_radio_log.c
+++ b/arch/arm/mach-msm/last_radio_log.c
@@ -48,7 +48,8 @@ static ssize_t last_radio_log_read(struct file *file, char __user *buf,
}
static struct file_operations last_radio_log_fops = {
- .read = last_radio_log_read
+ .read = last_radio_log_read,
+ .llseek = default_llseek,
};
void msm_init_last_radio_log(struct module *owner)
diff --git a/arch/arm/mach-msm/smd_debug.c b/arch/arm/mach-msm/smd_debug.c
index 3b2dd717b788..f91c3b7bc655 100644
--- a/arch/arm/mach-msm/smd_debug.c
+++ b/arch/arm/mach-msm/smd_debug.c
@@ -212,6 +212,7 @@ static int debug_open(struct inode *inode, struct file *file)
static const struct file_operations debug_ops = {
.read = debug_read,
.open = debug_open,
+ .llseek = default_llseek,
};
static void debug_create(const char *name, mode_t mode,
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index dec5ca622d7d..7689848ec680 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -28,7 +28,6 @@
#ifndef MSM_DGT_BASE
#define MSM_DGT_BASE (MSM_GPT_BASE + 0x10)
#endif
-#define MSM_DGT_SHIFT (5)
#define TIMER_MATCH_VAL 0x0000
#define TIMER_COUNT_VAL 0x0004
@@ -36,12 +35,28 @@
#define TIMER_ENABLE_CLR_ON_MATCH_EN 2
#define TIMER_ENABLE_EN 1
#define TIMER_CLEAR 0x000C
-
+#define DGT_CLK_CTL 0x0034
+enum {
+ DGT_CLK_CTL_DIV_1 = 0,
+ DGT_CLK_CTL_DIV_2 = 1,
+ DGT_CLK_CTL_DIV_3 = 2,
+ DGT_CLK_CTL_DIV_4 = 3,
+};
#define CSR_PROTECTION 0x0020
#define CSR_PROTECTION_EN 1
#define GPT_HZ 32768
+
+#if defined(CONFIG_ARCH_QSD8X50)
+#define DGT_HZ (19200000 / 4) /* 19.2 MHz / 4 by default */
+#define MSM_DGT_SHIFT (0)
+#elif defined(CONFIG_ARCH_MSM7X30) || defined(CONFIG_ARCH_MSM8X60)
+#define DGT_HZ (24576000 / 4) /* 24.576 MHz (LPXO) / 4 by default */
+#define MSM_DGT_SHIFT (0)
+#else
#define DGT_HZ 19200000 /* 19.2 MHz or 600 KHz after shift */
+#define MSM_DGT_SHIFT (5)
+#endif
struct msm_clock {
struct clock_event_device clockevent;
@@ -170,6 +185,10 @@ static void __init msm_timer_init(void)
int i;
int res;
+#ifdef CONFIG_ARCH_MSM8X60
+ writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL);
+#endif
+
for (i = 0; i < ARRAY_SIZE(msm_clocks); i++) {
struct msm_clock *clock = &msm_clocks[i];
struct clock_event_device *ce = &clock->clockevent;
diff --git a/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c b/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c
index 61e5e583603b..29e390e89ff4 100644
--- a/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c
+++ b/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c
@@ -145,8 +145,6 @@ subsys_initcall(wxl_pci_init);
MACHINE_START(TERASTATION_WXL, "Buffalo Nas WXL")
/* Maintainer: Sebastien Requiem <sebastien@requiem.fr> */
- .phys_io = MV78XX0_REGS_PHYS_BASE,
- .io_pg_offst = ((MV78XX0_REGS_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.init_machine = wxl_init,
.map_io = mv78xx0_map_io,
diff --git a/arch/arm/mach-mv78xx0/db78x00-bp-setup.c b/arch/arm/mach-mv78xx0/db78x00-bp-setup.c
index efdabe04c69e..207c95e403b9 100644
--- a/arch/arm/mach-mv78xx0/db78x00-bp-setup.c
+++ b/arch/arm/mach-mv78xx0/db78x00-bp-setup.c
@@ -93,8 +93,6 @@ subsys_initcall(db78x00_pci_init);
MACHINE_START(DB78X00_BP, "Marvell DB-78x00-BP Development Board")
/* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
- .phys_io = MV78XX0_REGS_PHYS_BASE,
- .io_pg_offst = ((MV78XX0_REGS_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.init_machine = db78x00_init,
.map_io = mv78xx0_map_io,
diff --git a/arch/arm/mach-mv78xx0/include/mach/debug-macro.S b/arch/arm/mach-mv78xx0/include/mach/debug-macro.S
index cd81689c4621..04891428e48b 100644
--- a/arch/arm/mach-mv78xx0/include/mach/debug-macro.S
+++ b/arch/arm/mach-mv78xx0/include/mach/debug-macro.S
@@ -8,12 +8,11 @@
#include <mach/mv78xx0.h>
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- ldreq \rx, =MV78XX0_REGS_PHYS_BASE
- ldrne \rx, =MV78XX0_REGS_VIRT_BASE
- orr \rx, \rx, #0x00012000
+ .macro addruart, rp, rv
+ ldr \rp, =MV78XX0_REGS_PHYS_BASE
+ ldr \rv, =MV78XX0_REGS_VIRT_BASE
+ orr \rp, \rp, #0x00012000
+ orr \rv, \rv, #0x00012000
.endm
#define UART_SHIFT 2
diff --git a/arch/arm/mach-mv78xx0/rd78x00-masa-setup.c b/arch/arm/mach-mv78xx0/rd78x00-masa-setup.c
index e136b7a03355..3511ad4d973b 100644
--- a/arch/arm/mach-mv78xx0/rd78x00-masa-setup.c
+++ b/arch/arm/mach-mv78xx0/rd78x00-masa-setup.c
@@ -78,8 +78,6 @@ subsys_initcall(rd78x00_pci_init);
MACHINE_START(RD78X00_MASA, "Marvell RD-78x00-MASA Development Board")
/* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
- .phys_io = MV78XX0_REGS_PHYS_BASE,
- .io_pg_offst = ((MV78XX0_REGS_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.init_machine = rd78x00_masa_init,
.map_io = mv78xx0_map_io,
diff --git a/arch/arm/mach-mx25/Kconfig b/arch/arm/mach-mx25/Kconfig
index c71a7bc19284..aa57e35ce3cd 100644
--- a/arch/arm/mach-mx25/Kconfig
+++ b/arch/arm/mach-mx25/Kconfig
@@ -12,6 +12,8 @@ config MACH_EUKREA_CPUIMX25
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_FLEXCAN
+ select IMX_HAVE_PLATFORM_ESDHC
select MXC_ULPI if USB_ULPI
choice
@@ -20,8 +22,8 @@ choice
default MACH_EUKREA_MBIMXSD25_BASEBOARD
config MACH_EUKREA_MBIMXSD25_BASEBOARD
- prompt "Eukrea MBIMXSD development board"
- bool
+ bool "Eukrea MBIMXSD development board"
+ select IMX_HAVE_PLATFORM_IMX_SSI
help
This adds board specific devices that can be found on Eukrea's
MBIMXSD evaluation board.
diff --git a/arch/arm/mach-mx25/clock.c b/arch/arm/mach-mx25/clock.c
index 40c7cc41cee3..9e4a5578c2fb 100644
--- a/arch/arm/mach-mx25/clock.c
+++ b/arch/arm/mach-mx25/clock.c
@@ -72,7 +72,7 @@ unsigned long get_rate_arm(struct clk *clk)
unsigned long rate = get_rate_mpll();
if (cctl & (1 << 14))
- rate = (rate * 3) >> 1;
+ rate = (rate * 3) >> 2;
return rate / ((cctl >> 30) + 1);
}
@@ -99,7 +99,7 @@ static unsigned long get_rate_per(int per)
if (readl(CRM_BASE + 0x64) & (1 << per))
fref = get_rate_upll();
else
- fref = get_rate_ipg(NULL);
+ fref = get_rate_ahb(NULL);
return fref / (val + 1);
}
@@ -139,6 +139,16 @@ static unsigned long get_rate_lcdc(struct clk *clk)
return get_rate_per(7);
}
+static unsigned long get_rate_esdhc1(struct clk *clk)
+{
+ return get_rate_per(3);
+}
+
+static unsigned long get_rate_esdhc2(struct clk *clk)
+{
+ return get_rate_per(4);
+}
+
static unsigned long get_rate_csi(struct clk *clk)
{
return get_rate_per(0);
@@ -213,6 +223,12 @@ DEFINE_CLOCK(ssi2_per_clk, 0, CCM_CGCR0, 14, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(cspi1_clk, 0, CCM_CGCR1, 5, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(cspi2_clk, 0, CCM_CGCR1, 6, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(cspi3_clk, 0, CCM_CGCR1, 7, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(esdhc1_ahb_clk, 0, CCM_CGCR0, 21, get_rate_esdhc1, NULL, NULL);
+DEFINE_CLOCK(esdhc1_per_clk, 0, CCM_CGCR0, 3, get_rate_esdhc1, NULL,
+ &esdhc1_ahb_clk);
+DEFINE_CLOCK(esdhc2_ahb_clk, 0, CCM_CGCR0, 22, get_rate_esdhc2, NULL, NULL);
+DEFINE_CLOCK(esdhc2_per_clk, 0, CCM_CGCR0, 4, get_rate_esdhc2, NULL,
+ &esdhc2_ahb_clk);
DEFINE_CLOCK(fec_ahb_clk, 0, CCM_CGCR0, 23, NULL, NULL, NULL);
DEFINE_CLOCK(lcdc_ahb_clk, 0, CCM_CGCR0, 24, NULL, NULL, NULL);
DEFINE_CLOCK(lcdc_per_clk, 0, CCM_CGCR0, 7, NULL, NULL, &lcdc_ahb_clk);
@@ -238,10 +254,14 @@ DEFINE_CLOCK(lcdc_clk, 0, CCM_CGCR1, 29, get_rate_lcdc, NULL, &lcdc_per_clk);
DEFINE_CLOCK(wdt_clk, 0, CCM_CGCR2, 19, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(ssi1_clk, 0, CCM_CGCR2, 11, get_rate_ssi1, NULL, &ssi1_per_clk);
DEFINE_CLOCK(ssi2_clk, 1, CCM_CGCR2, 12, get_rate_ssi2, NULL, &ssi2_per_clk);
+DEFINE_CLOCK(esdhc1_clk, 0, CCM_CGCR1, 13, get_rate_esdhc1, NULL,
+ &esdhc1_per_clk);
+DEFINE_CLOCK(esdhc2_clk, 1, CCM_CGCR1, 14, get_rate_esdhc2, NULL,
+ &esdhc2_per_clk);
DEFINE_CLOCK(audmux_clk, 0, CCM_CGCR1, 0, NULL, NULL, NULL);
DEFINE_CLOCK(csi_clk, 0, CCM_CGCR1, 4, get_rate_csi, NULL, &csi_per_clk);
DEFINE_CLOCK(can1_clk, 0, CCM_CGCR1, 2, get_rate_ipg, NULL, NULL);
-DEFINE_CLOCK(can2_clk, 0, CCM_CGCR1, 3, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(can2_clk, 1, CCM_CGCR1, 3, get_rate_ipg, NULL, NULL);
#define _REGISTER_CLOCK(d, n, c) \
{ \
@@ -261,9 +281,9 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk)
_REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk)
_REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
- _REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk)
- _REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk)
- _REGISTER_CLOCK("spi_imx.2", NULL, cspi3_clk)
+ _REGISTER_CLOCK("imx25-cspi.0", NULL, cspi1_clk)
+ _REGISTER_CLOCK("imx25-cspi.1", NULL, cspi2_clk)
+ _REGISTER_CLOCK("imx25-cspi.2", NULL, cspi3_clk)
_REGISTER_CLOCK("mxc_pwm.0", NULL, pwm1_clk)
_REGISTER_CLOCK("mxc_pwm.1", NULL, pwm2_clk)
_REGISTER_CLOCK("mxc_pwm.2", NULL, pwm3_clk)
@@ -279,6 +299,8 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("imx-wdt.0", NULL, wdt_clk)
_REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
_REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
+ _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk)
+ _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk)
_REGISTER_CLOCK("mx2-camera.0", NULL, csi_clk)
_REGISTER_CLOCK(NULL, "audmux", audmux_clk)
_REGISTER_CLOCK("flexcan.0", NULL, can1_clk)
diff --git a/arch/arm/mach-mx25/devices-imx25.h b/arch/arm/mach-mx25/devices-imx25.h
index d86a7c3ca8b0..93afa10b13cf 100644
--- a/arch/arm/mach-mx25/devices-imx25.h
+++ b/arch/arm/mach-mx25/devices-imx25.h
@@ -9,35 +9,46 @@
#include <mach/mx25.h>
#include <mach/devices-common.h>
+extern const struct imx_fec_data imx25_fec_data __initconst;
+#define imx25_add_fec(pdata) \
+ imx_add_fec(&imx25_fec_data, pdata)
+
#define imx25_add_flexcan0(pdata) \
imx_add_flexcan(0, MX25_CAN1_BASE_ADDR, SZ_16K, MX25_INT_CAN1, pdata)
#define imx25_add_flexcan1(pdata) \
imx_add_flexcan(1, MX25_CAN2_BASE_ADDR, SZ_16K, MX25_INT_CAN2, pdata)
-#define imx25_add_imx_i2c0(pdata) \
- imx_add_imx_i2c(0, MX25_I2C1_BASE_ADDR, SZ_16K, MX25_INT_I2C1, pdata)
-#define imx25_add_imx_i2c1(pdata) \
- imx_add_imx_i2c(1, MX25_I2C2_BASE_ADDR, SZ_16K, MX25_INT_I2C2, pdata)
-#define imx25_add_imx_i2c2(pdata) \
- imx_add_imx_i2c(2, MX25_I2C3_BASE_ADDR, SZ_16K, MX25_INT_I2C3, pdata)
-
-#define imx25_add_imx_uart0(pdata) \
- imx_add_imx_uart_1irq(0, MX25_UART1_BASE_ADDR, SZ_16K, MX25_INT_UART1, pdata)
-#define imx25_add_imx_uart1(pdata) \
- imx_add_imx_uart_1irq(1, MX25_UART2_BASE_ADDR, SZ_16K, MX25_INT_UART2, pdata)
-#define imx25_add_imx_uart2(pdata) \
- imx_add_imx_uart_1irq(2, MX25_UART3_BASE_ADDR, SZ_16K, MX25_INT_UART3, pdata)
-#define imx25_add_imx_uart3(pdata) \
- imx_add_imx_uart_1irq(3, MX25_UART4_BASE_ADDR, SZ_16K, MX25_INT_UART4, pdata)
-#define imx25_add_imx_uart4(pdata) \
- imx_add_imx_uart_1irq(4, MX25_UART5_BASE_ADDR, SZ_16K, MX25_INT_UART5, pdata)
+extern const struct imx_imx_i2c_data imx25_imx_i2c_data[] __initconst;
+#define imx25_add_imx_i2c(id, pdata) \
+ imx_add_imx_i2c(&imx25_imx_i2c_data[id], pdata)
+#define imx25_add_imx_i2c0(pdata) imx25_add_imx_i2c(0, pdata)
+#define imx25_add_imx_i2c1(pdata) imx25_add_imx_i2c(1, pdata)
+#define imx25_add_imx_i2c2(pdata) imx25_add_imx_i2c(2, pdata)
+
+extern const struct imx_imx_ssi_data imx25_imx_ssi_data[] __initconst;
+#define imx25_add_imx_ssi(id, pdata) \
+ imx_add_imx_ssi(&imx25_imx_ssi_data[id], pdata)
+
+extern const struct imx_imx_uart_1irq_data imx25_imx_uart_data[] __initconst;
+#define imx25_add_imx_uart(id, pdata) \
+ imx_add_imx_uart_1irq(&imx25_imx_uart_data[id], pdata)
+#define imx25_add_imx_uart0(pdata) imx25_add_imx_uart(0, pdata)
+#define imx25_add_imx_uart1(pdata) imx25_add_imx_uart(1, pdata)
+#define imx25_add_imx_uart2(pdata) imx25_add_imx_uart(2, pdata)
+#define imx25_add_imx_uart3(pdata) imx25_add_imx_uart(3, pdata)
+#define imx25_add_imx_uart4(pdata) imx25_add_imx_uart(4, pdata)
+extern const struct imx_mxc_nand_data imx25_mxc_nand_data __initconst;
#define imx25_add_mxc_nand(pdata) \
- imx_add_mxc_nand_v21(MX25_NFC_BASE_ADDR, MX25_INT_NANDFC, pdata)
-
-#define imx25_add_spi_imx0(pdata) \
- imx_add_spi_imx(0, MX25_CSPI1_BASE_ADDR, SZ_16K, MX25_INT_CSPI1, pdata)
-#define imx25_add_spi_imx1(pdata) \
- imx_add_spi_imx(1, MX25_CSPI2_BASE_ADDR, SZ_16K, MX25_INT_CSPI2, pdata)
-#define imx25_add_spi_imx2(pdata) \
- imx_add_spi_imx(2, MX25_CSPI3_BASE_ADDR, SZ_16K, MX25_INT_CSPI3, pdata)
+ imx_add_mxc_nand(&imx25_mxc_nand_data, pdata)
+
+extern const struct imx_spi_imx_data imx25_spi_imx_data[] __initconst;
+#define imx25_add_spi_imx(id, pdata) \
+ imx_add_spi_imx(&imx25_spi_imx_data[id], pdata)
+#define imx25_add_spi_imx0(pdata) imx25_add_spi_imx(0, pdata)
+#define imx25_add_spi_imx1(pdata) imx25_add_spi_imx(1, pdata)
+#define imx25_add_spi_imx2(pdata) imx25_add_spi_imx(2, pdata)
+
+extern const struct imx_esdhc_imx_data imx25_esdhc_data[] __initconst;
+#define imx25_add_esdhc(id, pdata) \
+ imx_add_esdhc(&imx25_esdhc_data[id], pdata)
diff --git a/arch/arm/mach-mx25/devices.c b/arch/arm/mach-mx25/devices.c
index 3468eb15b236..1d0eb3e85941 100644
--- a/arch/arm/mach-mx25/devices.c
+++ b/arch/arm/mach-mx25/devices.c
@@ -208,26 +208,6 @@ int __init imx25_register_gpios(void)
return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports));
}
-static struct resource mx25_fec_resources[] = {
- {
- .start = MX25_FEC_BASE_ADDR,
- .end = MX25_FEC_BASE_ADDR + 0xfff,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = MX25_INT_FEC,
- .end = MX25_INT_FEC,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mx25_fec_device = {
- .name = "fec",
- .id = 0,
- .num_resources = ARRAY_SIZE(mx25_fec_resources),
- .resource = mx25_fec_resources,
-};
-
static struct resource mx25_rtc_resources[] = {
{
.start = MX25_DRYICE_BASE_ADDR,
@@ -305,44 +285,6 @@ struct platform_device mx25_kpp_device = {
.resource = mx25_kpp_resources,
};
-static struct resource imx_ssi_resources0[] = {
- {
- .start = MX25_SSI1_BASE_ADDR,
- .end = MX25_SSI1_BASE_ADDR + 0x3fff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX25_INT_SSI1,
- .end = MX25_INT_SSI1,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct resource imx_ssi_resources1[] = {
- {
- .start = MX25_SSI2_BASE_ADDR,
- .end = MX25_SSI2_BASE_ADDR + 0x3fff,
- .flags = IORESOURCE_MEM
- }, {
- .start = MX25_INT_SSI2,
- .end = MX25_INT_SSI2,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device imx_ssi_device0 = {
- .name = "imx-ssi",
- .id = 0,
- .num_resources = ARRAY_SIZE(imx_ssi_resources0),
- .resource = imx_ssi_resources0,
-};
-
-struct platform_device imx_ssi_device1 = {
- .name = "imx-ssi",
- .id = 1,
- .num_resources = ARRAY_SIZE(imx_ssi_resources1),
- .resource = imx_ssi_resources1,
-};
-
static struct resource mx25_csi_resources[] = {
{
.start = MX25_CSI_BASE_ADDR,
diff --git a/arch/arm/mach-mx25/devices.h b/arch/arm/mach-mx25/devices.h
index 4aceb68e35a7..7b70a43c3a4b 100644
--- a/arch/arm/mach-mx25/devices.h
+++ b/arch/arm/mach-mx25/devices.h
@@ -6,11 +6,8 @@ extern struct platform_device mxc_pwm_device1;
extern struct platform_device mxc_pwm_device2;
extern struct platform_device mxc_pwm_device3;
extern struct platform_device mxc_keypad_device;
-extern struct platform_device mx25_fec_device;
extern struct platform_device mx25_rtc_device;
extern struct platform_device mx25_fb_device;
extern struct platform_device mxc_wdt;
extern struct platform_device mx25_kpp_device;
-extern struct platform_device imx_ssi_device0;
-extern struct platform_device imx_ssi_device1;
extern struct platform_device mx25_csi_device;
diff --git a/arch/arm/mach-mx25/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-mx25/eukrea_mbimxsd-baseboard.c
index 4aaadc753d3e..e765ac5d9a08 100644
--- a/arch/arm/mach-mx25/eukrea_mbimxsd-baseboard.c
+++ b/arch/arm/mach-mx25/eukrea_mbimxsd-baseboard.c
@@ -34,7 +34,6 @@
#include <mach/mx25.h>
#include <mach/imx-uart.h>
#include <mach/imxfb.h>
-#include <mach/ssi.h>
#include <mach/audmux.h>
#include "devices-imx25.h"
@@ -90,6 +89,9 @@ static struct pad_desc eukrea_mbimxsd_pads[] = {
MX25_PAD_KPP_COL2__AUD5_TXC,
MX25_PAD_KPP_COL1__AUD5_RXD,
MX25_PAD_KPP_COL0__AUD5_TXD,
+ /* CAN */
+ MX25_PAD_GPIO_D__CAN2_RX,
+ MX25_PAD_GPIO_C__CAN2_TX,
};
#define GPIO_LED1 83
@@ -114,6 +116,38 @@ static struct imx_fb_videomode eukrea_mximxsd_modes[] = {
},
.bpp = 16,
.pcr = 0xCAD08B80,
+ }, {
+ .mode = {
+ .name = "DVI-VGA",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 32000,
+ .hsync_len = 7,
+ .left_margin = 100,
+ .right_margin = 100,
+ .vsync_len = 7,
+ .upper_margin = 7,
+ .lower_margin = 100,
+ },
+ .pcr = 0xFA208B80,
+ .bpp = 16,
+ }, {
+ .mode = {
+ .name = "DVI-SVGA",
+ .refresh = 60,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 25000,
+ .hsync_len = 7,
+ .left_margin = 75,
+ .right_margin = 75,
+ .vsync_len = 7,
+ .upper_margin = 7,
+ .lower_margin = 75,
+ },
+ .pcr = 0xFA208B80,
+ .bpp = 16,
},
};
@@ -205,7 +239,8 @@ static struct i2c_board_info eukrea_mbimxsd_i2c_devices[] = {
},
};
-struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata = {
+static const
+struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata __initconst = {
.flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE,
};
@@ -239,7 +274,10 @@ void __init eukrea_mbimxsd25_baseboard_init(void)
imx25_add_imx_uart1(&uart_pdata);
mxc_register_device(&mx25_fb_device, &eukrea_mximxsd_fb_pdata);
- mxc_register_device(&imx_ssi_device0, &eukrea_mbimxsd_ssi_pdata);
+ imx25_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);
+
+ imx25_add_flexcan1(NULL);
+ imx25_add_esdhc(0, NULL);
gpio_request(GPIO_LED1, "LED1");
gpio_direction_output(GPIO_LED1, 1);
diff --git a/arch/arm/mach-mx25/mach-cpuimx25.c b/arch/arm/mach-mx25/mach-cpuimx25.c
index e064bb3d6919..f6f9ad60c25e 100644
--- a/arch/arm/mach-mx25/mach-cpuimx25.c
+++ b/arch/arm/mach-mx25/mach-cpuimx25.c
@@ -23,7 +23,6 @@
#include <linux/clk.h>
#include <linux/irq.h>
#include <linux/gpio.h>
-#include <linux/fec.h>
#include <linux/platform_device.h>
#include <linux/usb/otg.h>
#include <linux/usb/ulpi.h>
@@ -41,7 +40,6 @@
#include <mach/mxc_nand.h>
#include <mach/imxfb.h>
#include <mach/mxc_ehci.h>
-#include <mach/ulpi.h>
#include <mach/iomux-mx25.h>
#include "devices-imx25.h"
@@ -67,7 +65,7 @@ static struct pad_desc eukrea_cpuimx25_pads[] = {
MX25_PAD_I2C1_DAT__I2C1_DAT,
};
-static struct fec_platform_data mx25_fec_pdata = {
+static const struct fec_platform_data mx25_fec_pdata __initconst = {
.phy = PHY_INTERFACE_MODE_RMII,
};
@@ -129,24 +127,19 @@ static void __init eukrea_cpuimx25_init(void)
imx25_add_imx_uart0(&uart_pdata);
imx25_add_mxc_nand(&eukrea_cpuimx25_nand_board_info);
mxc_register_device(&mx25_rtc_device, NULL);
- mxc_register_device(&mx25_fec_device, &mx25_fec_pdata);
+ imx25_add_fec(&mx25_fec_pdata);
i2c_register_board_info(0, eukrea_cpuimx25_i2c_devices,
ARRAY_SIZE(eukrea_cpuimx25_i2c_devices));
imx25_add_imx_i2c0(&eukrea_cpuimx25_i2c0_data);
-#if defined(CONFIG_USB_ULPI)
- if (otg_mode_host) {
- otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
- ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
-
+ if (otg_mode_host)
mxc_register_device(&mxc_otg, &otg_pdata);
- }
- mxc_register_device(&mxc_usbh2, &usbh2_pdata);
-#endif
- if (!otg_mode_host)
+ else
mxc_register_device(&otg_udc_device, &otg_device_pdata);
+ mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+
#ifdef CONFIG_MACH_EUKREA_MBIMXSD25_BASEBOARD
eukrea_mbimxsd25_baseboard_init();
#endif
@@ -163,8 +156,6 @@ static struct sys_timer eukrea_cpuimx25_timer = {
MACHINE_START(EUKREA_CPUIMX25, "Eukrea CPUIMX25")
/* Maintainer: Eukrea Electromatique */
- .phys_io = MX25_AIPS1_BASE_ADDR,
- .io_pg_offst = ((MX25_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
.boot_params = MX25_PHYS_OFFSET + 0x100,
.map_io = mx25_map_io,
.init_irq = mx25_init_irq,
diff --git a/arch/arm/mach-mx25/mach-mx25_3ds.c b/arch/arm/mach-mx25/mach-mx25_3ds.c
index 62bc21f11a71..80805107a73e 100644
--- a/arch/arm/mach-mx25/mach-mx25_3ds.c
+++ b/arch/arm/mach-mx25/mach-mx25_3ds.c
@@ -28,7 +28,6 @@
#include <linux/clk.h>
#include <linux/irq.h>
#include <linux/gpio.h>
-#include <linux/fec.h>
#include <linux/platform_device.h>
#include <linux/input/matrix_keypad.h>
@@ -99,7 +98,7 @@ static struct pad_desc mx25pdk_pads[] = {
MX25_PAD_KPP_COL3__KPP_COL3,
};
-static struct fec_platform_data mx25_fec_pdata = {
+static const struct fec_platform_data mx25_fec_pdata __initconst = {
.phy = PHY_INTERFACE_MODE_RMII,
};
@@ -192,7 +191,7 @@ static void __init mx25pdk_init(void)
mxc_register_device(&mxc_wdt, NULL);
mx25pdk_fec_reset();
- mxc_register_device(&mx25_fec_device, &mx25_fec_pdata);
+ imx25_add_fec(&mx25_fec_pdata);
mxc_register_device(&mx25_kpp_device, &mx25pdk_keymap_data);
}
@@ -207,8 +206,6 @@ static struct sys_timer mx25pdk_timer = {
MACHINE_START(MX25_3DS, "Freescale MX25PDK (3DS)")
/* Maintainer: Freescale Semiconductor, Inc. */
- .phys_io = MX25_AIPS1_BASE_ADDR,
- .io_pg_offst = ((MX25_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
.boot_params = MX25_PHYS_OFFSET + 0x100,
.map_io = mx25_map_io,
.init_irq = mx25_init_irq,
diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig
index 85beece802aa..096fd33f8ab9 100644
--- a/arch/arm/mach-mx3/Kconfig
+++ b/arch/arm/mach-mx3/Kconfig
@@ -9,6 +9,7 @@ config ARCH_MX35
bool
select ARCH_MXC_IOMUX_V3
select ARCH_MXC_AUDMUX_V2
+ select HAVE_EPIT
comment "MX3 platforms:"
@@ -16,6 +17,7 @@ config MACH_MX31ADS
bool "Support MX31ADS platforms"
select ARCH_MX31
select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_SSI
select IMX_HAVE_PLATFORM_IMX_UART
default y
help
@@ -117,9 +119,11 @@ config MACH_PCM043
bool "Support Phytec pcm043 (i.MX35) platforms"
select ARCH_MX35
select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_SSI
select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_MXC_NAND
select IMX_HAVE_PLATFORM_FLEXCAN
+ select IMX_HAVE_PLATFORM_ESDHC
select MXC_ULPI if USB_ULPI
help
Include support for Phytec pcm043 platform. This includes
@@ -140,6 +144,7 @@ config MACH_MX35_3DS
bool "Support MX35PDK platform"
select ARCH_MX35
select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_NAND
default n
help
Include support for MX35PDK platform. This includes specific
@@ -159,6 +164,8 @@ config MACH_EUKREA_CPUIMX35
select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_FLEXCAN
+ select IMX_HAVE_PLATFORM_ESDHC
select MXC_ULPI if USB_ULPI
help
Include support for Eukrea CPUIMX35 platform. This includes
@@ -170,8 +177,8 @@ choice
default MACH_EUKREA_MBIMXSD35_BASEBOARD
config MACH_EUKREA_MBIMXSD35_BASEBOARD
- prompt "Eukrea MBIMXSD development board"
- bool
+ bool "Eukrea MBIMXSD development board"
+ select IMX_HAVE_PLATFORM_IMX_SSI
help
This adds board specific devices that can be found on Eukrea's
MBIMXSD evaluation board.
diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile
index 2bd7beceb991..8a182d0a3fcf 100644
--- a/arch/arm/mach-mx3/Makefile
+++ b/arch/arm/mach-mx3/Makefile
@@ -7,7 +7,6 @@
obj-y := mm.o devices.o cpu.o
CFLAGS_mm.o = -DIMX_NEEDS_DEPRECATED_SYMBOLS
CFLAGS_devices.o = -DIMX_NEEDS_DEPRECATED_SYMBOLS
-CFLAGS_cpu.o = -DIMX_NEEDS_DEPRECATED_SYMBOLS
obj-$(CONFIG_ARCH_MX31) += clock-imx31.o iomux-imx31.o
obj-$(CONFIG_ARCH_MX35) += clock-imx35.o
obj-$(CONFIG_MACH_MX31ADS) += mach-mx31ads.o
diff --git a/arch/arm/mach-mx3/clock-imx31.c b/arch/arm/mach-mx3/clock-imx31.c
index 9a9eb6de6127..109e98f323e0 100644
--- a/arch/arm/mach-mx3/clock-imx31.c
+++ b/arch/arm/mach-mx3/clock-imx31.c
@@ -477,7 +477,7 @@ DEFINE_CLOCK(epit1_clk, 0, MXC_CCM_CGR0, 6, NULL, NULL, &perclk_clk);
DEFINE_CLOCK(epit2_clk, 1, MXC_CCM_CGR0, 8, NULL, NULL, &perclk_clk);
DEFINE_CLOCK(iim_clk, 0, MXC_CCM_CGR0, 10, NULL, NULL, &ipg_clk);
DEFINE_CLOCK(ata_clk, 0, MXC_CCM_CGR0, 12, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(sdma_clk1, 0, MXC_CCM_CGR0, 14, NULL, &sdma_clk1, &ahb_clk);
+DEFINE_CLOCK(sdma_clk1, 0, MXC_CCM_CGR0, 14, NULL, NULL, &ahb_clk);
DEFINE_CLOCK(cspi3_clk, 2, MXC_CCM_CGR0, 16, NULL, NULL, &ipg_clk);
DEFINE_CLOCK(rng_clk, 0, MXC_CCM_CGR0, 18, NULL, NULL, &ipg_clk);
DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CGR0, 20, NULL, NULL, &perclk_clk);
@@ -525,9 +525,9 @@ DEFINE_CLOCK(ipg_clk, 0, NULL, 0, ipg_get_rate, NULL, &ahb_clk);
static struct clk_lookup lookups[] = {
_REGISTER_CLOCK(NULL, "emi", emi_clk)
- _REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk)
- _REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk)
- _REGISTER_CLOCK("spi_imx.2", NULL, cspi3_clk)
+ _REGISTER_CLOCK("imx31-cspi.0", NULL, cspi1_clk)
+ _REGISTER_CLOCK("imx31-cspi.1", NULL, cspi2_clk)
+ _REGISTER_CLOCK("imx31-cspi.2", NULL, cspi3_clk)
_REGISTER_CLOCK(NULL, "gpt", gpt_clk)
_REGISTER_CLOCK(NULL, "pwm", pwm_clk)
_REGISTER_CLOCK("imx-wdt.0", NULL, wdog_clk)
@@ -564,7 +564,7 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK(NULL, "ata", ata_clk)
_REGISTER_CLOCK(NULL, "rtic", rtic_clk)
_REGISTER_CLOCK(NULL, "rng", rng_clk)
- _REGISTER_CLOCK(NULL, "sdma_ahb", sdma_clk1)
+ _REGISTER_CLOCK("imx-sdma", NULL, sdma_clk1)
_REGISTER_CLOCK(NULL, "sdma_ipg", sdma_clk2)
_REGISTER_CLOCK(NULL, "mstick", mstick1_clk)
_REGISTER_CLOCK(NULL, "mstick", mstick2_clk)
diff --git a/arch/arm/mach-mx3/clock-imx35.c b/arch/arm/mach-mx3/clock-imx35.c
index 7a62e744a8b0..61e4a318980a 100644
--- a/arch/arm/mach-mx3/clock-imx35.c
+++ b/arch/arm/mach-mx3/clock-imx35.c
@@ -364,8 +364,8 @@ DEFINE_CLOCK(cspi2_clk, 1, CCM_CGR0, 12, get_rate_ipg, NULL);
DEFINE_CLOCK(ect_clk, 0, CCM_CGR0, 14, get_rate_ipg, NULL);
DEFINE_CLOCK(edio_clk, 0, CCM_CGR0, 16, NULL, NULL);
DEFINE_CLOCK(emi_clk, 0, CCM_CGR0, 18, get_rate_ipg, NULL);
-DEFINE_CLOCK(epit1_clk, 0, CCM_CGR0, 20, get_rate_ipg_per, NULL);
-DEFINE_CLOCK(epit2_clk, 1, CCM_CGR0, 22, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(epit1_clk, 0, CCM_CGR0, 20, get_rate_ipg, NULL);
+DEFINE_CLOCK(epit2_clk, 1, CCM_CGR0, 22, get_rate_ipg, NULL);
DEFINE_CLOCK(esai_clk, 0, CCM_CGR0, 24, NULL, NULL);
DEFINE_CLOCK(esdhc1_clk, 0, CCM_CGR0, 26, get_rate_sdhc, NULL);
DEFINE_CLOCK(esdhc2_clk, 1, CCM_CGR0, 28, get_rate_sdhc, NULL);
@@ -451,17 +451,17 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK(NULL, "ata", ata_clk)
_REGISTER_CLOCK("flexcan.0", NULL, can1_clk)
_REGISTER_CLOCK("flexcan.1", NULL, can2_clk)
- _REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk)
- _REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk)
+ _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi1_clk)
+ _REGISTER_CLOCK("imx35-cspi.1", NULL, cspi2_clk)
_REGISTER_CLOCK(NULL, "ect", ect_clk)
_REGISTER_CLOCK(NULL, "edio", edio_clk)
_REGISTER_CLOCK(NULL, "emi", emi_clk)
- _REGISTER_CLOCK(NULL, "epit", epit1_clk)
- _REGISTER_CLOCK(NULL, "epit", epit2_clk)
+ _REGISTER_CLOCK("imx-epit.0", NULL, epit1_clk)
+ _REGISTER_CLOCK("imx-epit.1", NULL, epit2_clk)
_REGISTER_CLOCK(NULL, "esai", esai_clk)
- _REGISTER_CLOCK(NULL, "sdhc", esdhc1_clk)
- _REGISTER_CLOCK(NULL, "sdhc", esdhc2_clk)
- _REGISTER_CLOCK(NULL, "sdhc", esdhc3_clk)
+ _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk)
+ _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk)
+ _REGISTER_CLOCK("sdhci-esdhc-imx.2", NULL, esdhc3_clk)
_REGISTER_CLOCK("fec.0", NULL, fec_clk)
_REGISTER_CLOCK(NULL, "gpio", gpio1_clk)
_REGISTER_CLOCK(NULL, "gpio", gpio2_clk)
@@ -482,7 +482,7 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK(NULL, "rtc", rtc_clk)
_REGISTER_CLOCK(NULL, "rtic", rtic_clk)
_REGISTER_CLOCK(NULL, "scc", scc_clk)
- _REGISTER_CLOCK(NULL, "sdma", sdma_clk)
+ _REGISTER_CLOCK("imx-sdma", NULL, sdma_clk)
_REGISTER_CLOCK(NULL, "spba", spba_clk)
_REGISTER_CLOCK(NULL, "spdif", spdif_clk)
_REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
@@ -535,8 +535,16 @@ int __init mx35_clocks_init()
__raw_writel(cgr2, CCM_BASE + CCM_CGR2);
__raw_writel(cgr3, CCM_BASE + CCM_CGR3);
+ clk_enable(&iim_clk);
+ mx35_read_cpu_rev();
+
+#ifdef CONFIG_MXC_USE_EPIT
+ epit_timer_init(&epit1_clk,
+ MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1);
+#else
mxc_timer_init(&gpt_clk,
MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT);
+#endif
return 0;
}
diff --git a/arch/arm/mach-mx3/cpu.c b/arch/arm/mach-mx3/cpu.c
index 861afe0fe3ad..d00a75457812 100644
--- a/arch/arm/mach-mx3/cpu.c
+++ b/arch/arm/mach-mx3/cpu.c
@@ -25,15 +25,15 @@ struct mx3_cpu_type {
};
static struct mx3_cpu_type mx31_cpu_type[] __initdata = {
- { .srev = 0x00, .name = "i.MX31(L)", .v = "1.0", .rev = CHIP_REV_1_0 },
- { .srev = 0x10, .name = "i.MX31", .v = "1.1", .rev = CHIP_REV_1_1 },
- { .srev = 0x11, .name = "i.MX31L", .v = "1.1", .rev = CHIP_REV_1_1 },
- { .srev = 0x12, .name = "i.MX31", .v = "1.15", .rev = CHIP_REV_1_1 },
- { .srev = 0x13, .name = "i.MX31L", .v = "1.15", .rev = CHIP_REV_1_1 },
- { .srev = 0x14, .name = "i.MX31", .v = "1.2", .rev = CHIP_REV_1_2 },
- { .srev = 0x15, .name = "i.MX31L", .v = "1.2", .rev = CHIP_REV_1_2 },
- { .srev = 0x28, .name = "i.MX31", .v = "2.0", .rev = CHIP_REV_2_0 },
- { .srev = 0x29, .name = "i.MX31L", .v = "2.0", .rev = CHIP_REV_2_0 },
+ { .srev = 0x00, .name = "i.MX31(L)", .v = "1.0", .rev = MX3x_CHIP_REV_1_0 },
+ { .srev = 0x10, .name = "i.MX31", .v = "1.1", .rev = MX3x_CHIP_REV_1_1 },
+ { .srev = 0x11, .name = "i.MX31L", .v = "1.1", .rev = MX3x_CHIP_REV_1_1 },
+ { .srev = 0x12, .name = "i.MX31", .v = "1.15", .rev = MX3x_CHIP_REV_1_1 },
+ { .srev = 0x13, .name = "i.MX31L", .v = "1.15", .rev = MX3x_CHIP_REV_1_1 },
+ { .srev = 0x14, .name = "i.MX31", .v = "1.2", .rev = MX3x_CHIP_REV_1_2 },
+ { .srev = 0x15, .name = "i.MX31L", .v = "1.2", .rev = MX3x_CHIP_REV_1_2 },
+ { .srev = 0x28, .name = "i.MX31", .v = "2.0", .rev = MX3x_CHIP_REV_2_0 },
+ { .srev = 0x29, .name = "i.MX31L", .v = "2.0", .rev = MX3x_CHIP_REV_2_0 },
};
void __init mx31_read_cpu_rev(void)
@@ -41,7 +41,7 @@ void __init mx31_read_cpu_rev(void)
u32 i, srev;
/* read SREV register from IIM module */
- srev = __raw_readl(IO_ADDRESS(IIM_BASE_ADDR + MXC_IIMSREV));
+ srev = __raw_readl(MX31_IO_ADDRESS(MX31_IIM_BASE_ADDR + MXC_IIMSREV));
for (i = 0; i < ARRAY_SIZE(mx31_cpu_type); i++)
if (srev == mx31_cpu_type[i].srev) {
@@ -55,3 +55,30 @@ void __init mx31_read_cpu_rev(void)
printk(KERN_WARNING "Unknown CPU identifier. srev = %02x\n", srev);
}
+
+unsigned int mx35_cpu_rev;
+EXPORT_SYMBOL(mx35_cpu_rev);
+
+void __init mx35_read_cpu_rev(void)
+{
+ u32 rev;
+ char *srev = "unknown";
+
+ rev = __raw_readl(MX35_IO_ADDRESS(MX35_IIM_BASE_ADDR + MXC_IIMSREV));
+ switch (rev) {
+ case 0x00:
+ mx35_cpu_rev = MX3x_CHIP_REV_1_0;
+ srev = "1.0";
+ break;
+ case 0x10:
+ mx35_cpu_rev = MX3x_CHIP_REV_2_0;
+ srev = "2.0";
+ break;
+ case 0x11:
+ mx35_cpu_rev = MX3x_CHIP_REV_2_1;
+ srev = "2.1";
+ break;
+ }
+
+ printk(KERN_INFO "CPU identified as i.MX35, silicon rev %s\n", srev);
+}
diff --git a/arch/arm/mach-mx3/devices-imx31.h b/arch/arm/mach-mx3/devices-imx31.h
index 3b1a44a20585..de9598590eba 100644
--- a/arch/arm/mach-mx3/devices-imx31.h
+++ b/arch/arm/mach-mx3/devices-imx31.h
@@ -9,30 +9,33 @@
#include <mach/mx31.h>
#include <mach/devices-common.h>
-#define imx31_add_imx_i2c0(pdata) \
- imx_add_imx_i2c(0, MX31_I2C1_BASE_ADDR, SZ_4K, MX31_INT_I2C1, pdata)
-#define imx31_add_imx_i2c1(pdata) \
- imx_add_imx_i2c(1, MX31_I2C2_BASE_ADDR, SZ_4K, MX31_INT_I2C2, pdata)
-#define imx31_add_imx_i2c2(pdata) \
- imx_add_imx_i2c(2, MX31_I2C3_BASE_ADDR, SZ_4K, MX31_INT_I2C3, pdata)
+extern const struct imx_imx_i2c_data imx31_imx_i2c_data[] __initconst;
+#define imx31_add_imx_i2c(id, pdata) \
+ imx_add_imx_i2c(&imx31_imx_i2c_data[id], pdata)
+#define imx31_add_imx_i2c0(pdata) imx31_add_imx_i2c(0, pdata)
+#define imx31_add_imx_i2c1(pdata) imx31_add_imx_i2c(1, pdata)
+#define imx31_add_imx_i2c2(pdata) imx31_add_imx_i2c(2, pdata)
-#define imx31_add_imx_uart0(pdata) \
- imx_add_imx_uart_1irq(0, MX31_UART1_BASE_ADDR, SZ_16K, MX31_INT_UART1, pdata)
-#define imx31_add_imx_uart1(pdata) \
- imx_add_imx_uart_1irq(1, MX31_UART2_BASE_ADDR, SZ_16K, MX31_INT_UART2, pdata)
-#define imx31_add_imx_uart2(pdata) \
- imx_add_imx_uart_1irq(2, MX31_UART3_BASE_ADDR, SZ_16K, MX31_INT_UART3, pdata)
-#define imx31_add_imx_uart3(pdata) \
- imx_add_imx_uart_1irq(3, MX31_UART4_BASE_ADDR, SZ_16K, MX31_INT_UART4, pdata)
-#define imx31_add_imx_uart4(pdata) \
- imx_add_imx_uart_1irq(4, MX31_UART5_BASE_ADDR, SZ_16K, MX31_INT_UART5, pdata)
+extern const struct imx_imx_ssi_data imx31_imx_ssi_data[] __initconst;
+#define imx31_add_imx_ssi(id, pdata) \
+ imx_add_imx_ssi(&imx31_imx_ssi_data[id], pdata)
+extern const struct imx_imx_uart_1irq_data imx31_imx_uart_data[] __initconst;
+#define imx31_add_imx_uart(id, pdata) \
+ imx_add_imx_uart_1irq(&imx31_imx_uart_data[id], pdata)
+#define imx31_add_imx_uart0(pdata) imx31_add_imx_uart(0, pdata)
+#define imx31_add_imx_uart1(pdata) imx31_add_imx_uart(1, pdata)
+#define imx31_add_imx_uart2(pdata) imx31_add_imx_uart(2, pdata)
+#define imx31_add_imx_uart3(pdata) imx31_add_imx_uart(3, pdata)
+#define imx31_add_imx_uart4(pdata) imx31_add_imx_uart(4, pdata)
+
+extern const struct imx_mxc_nand_data imx31_mxc_nand_data __initconst;
#define imx31_add_mxc_nand(pdata) \
- imx_add_mxc_nand_v1(MX31_NFC_BASE_ADDR, MX31_INT_NANDFC, pdata)
+ imx_add_mxc_nand(&imx31_mxc_nand_data, pdata)
-#define imx31_add_spi_imx0(pdata) \
- imx_add_spi_imx(0, MX31_CSPI1_BASE_ADDR, SZ_4K, MX31_INT_CSPI1, pdata)
-#define imx31_add_spi_imx1(pdata) \
- imx_add_spi_imx(1, MX31_CSPI2_BASE_ADDR, SZ_4K, MX31_INT_CSPI2, pdata)
-#define imx31_add_spi_imx2(pdata) \
- imx_add_spi_imx(2, MX31_CSPI3_BASE_ADDR, SZ_4K, MX31_INT_CSPI3, pdata)
+extern const struct imx_spi_imx_data imx31_cspi_data[] __initconst;
+#define imx31_add_cspi(id, pdata) \
+ imx_add_spi_imx(&imx31_cspi_data[id], pdata)
+#define imx31_add_spi_imx0(pdata) imx31_add_cspi(0, pdata)
+#define imx31_add_spi_imx1(pdata) imx31_add_cspi(1, pdata)
+#define imx31_add_spi_imx2(pdata) imx31_add_cspi(2, pdata)
diff --git a/arch/arm/mach-mx3/devices-imx35.h b/arch/arm/mach-mx3/devices-imx35.h
index f6a431a4c3d2..5eb917b638d0 100644
--- a/arch/arm/mach-mx3/devices-imx35.h
+++ b/arch/arm/mach-mx3/devices-imx35.h
@@ -9,29 +9,43 @@
#include <mach/mx35.h>
#include <mach/devices-common.h>
+extern const struct imx_fec_data imx35_fec_data __initconst;
+#define imx35_add_fec(pdata) \
+ imx_add_fec(&imx35_fec_data, pdata)
+
#define imx35_add_flexcan0(pdata) \
imx_add_flexcan(0, MX35_CAN1_BASE_ADDR, SZ_16K, MX35_INT_CAN1, pdata)
#define imx35_add_flexcan1(pdata) \
imx_add_flexcan(1, MX35_CAN2_BASE_ADDR, SZ_16K, MX35_INT_CAN2, pdata)
-#define imx35_add_imx_i2c0(pdata) \
- imx_add_imx_i2c(0, MX35_I2C1_BASE_ADDR, SZ_4K, MX35_INT_I2C1, pdata)
-#define imx35_add_imx_i2c1(pdata) \
- imx_add_imx_i2c(1, MX35_I2C2_BASE_ADDR, SZ_4K, MX35_INT_I2C2, pdata)
-#define imx35_add_imx_i2c2(pdata) \
- imx_add_imx_i2c(2, MX35_I2C3_BASE_ADDR, SZ_4K, MX35_INT_I2C3, pdata)
+extern const struct imx_imx_i2c_data imx35_imx_i2c_data[] __initconst;
+#define imx35_add_imx_i2c(id, pdata) \
+ imx_add_imx_i2c(&imx35_imx_i2c_data[id], pdata)
+#define imx35_add_imx_i2c0(pdata) imx35_add_imx_i2c(0, pdata)
+#define imx35_add_imx_i2c1(pdata) imx35_add_imx_i2c(1, pdata)
+#define imx35_add_imx_i2c2(pdata) imx35_add_imx_i2c(2, pdata)
+
+extern const struct imx_imx_ssi_data imx35_imx_ssi_data[] __initconst;
+#define imx35_add_imx_ssi(id, pdata) \
+ imx_add_imx_ssi(&imx35_imx_ssi_data[id], pdata)
-#define imx35_add_imx_uart0(pdata) \
- imx_add_imx_uart_1irq(0, MX35_UART1_BASE_ADDR, SZ_16K, MX35_INT_UART1, pdata)
-#define imx35_add_imx_uart1(pdata) \
- imx_add_imx_uart_1irq(1, MX35_UART2_BASE_ADDR, SZ_16K, MX35_INT_UART2, pdata)
-#define imx35_add_imx_uart2(pdata) \
- imx_add_imx_uart_1irq(2, MX35_UART3_BASE_ADDR, SZ_16K, MX35_INT_UART3, pdata)
+extern const struct imx_imx_uart_1irq_data imx35_imx_uart_data[] __initconst;
+#define imx35_add_imx_uart(id, pdata) \
+ imx_add_imx_uart_1irq(&imx35_imx_uart_data[id], pdata)
+#define imx35_add_imx_uart0(pdata) imx35_add_imx_uart(0, pdata)
+#define imx35_add_imx_uart1(pdata) imx35_add_imx_uart(1, pdata)
+#define imx35_add_imx_uart2(pdata) imx35_add_imx_uart(2, pdata)
+extern const struct imx_mxc_nand_data imx35_mxc_nand_data __initconst;
#define imx35_add_mxc_nand(pdata) \
- imx_add_mxc_nand_v21(MX35_NFC_BASE_ADDR, MX35_INT_NANDFC, pdata)
+ imx_add_mxc_nand(&imx35_mxc_nand_data, pdata)
+
+extern const struct imx_spi_imx_data imx35_cspi_data[] __initconst;
+#define imx35_add_cspi(id, pdata) \
+ imx_add_spi_imx(&imx35_cspi_data[id], pdata)
+#define imx35_add_spi_imx0(pdata) imx35_add_cspi(0, pdata)
+#define imx35_add_spi_imx1(pdata) imx35_add_cspi(1, pdata)
-#define imx35_add_spi_imx0(pdata) \
- imx_add_spi_imx(0, MX35_CSPI1_BASE_ADDR, SZ_4K, MX35_INT_CSPI1, pdata)
-#define imx35_add_spi_imx1(pdata) \
- imx_add_spi_imx(1, MX35_CSPI2_BASE_ADDR, SZ_4K, MX35_INT_CSPI2, pdata)
+extern const struct imx_esdhc_imx_data imx35_esdhc_data[] __initconst;
+#define imx35_add_esdhc(id, pdata) \
+ imx_add_esdhc(&imx35_esdhc_data[id], pdata)
diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c
index a4fd1a26fc91..f4dff11aaee7 100644
--- a/arch/arm/mach-mx3/devices.c
+++ b/arch/arm/mach-mx3/devices.c
@@ -281,65 +281,6 @@ struct platform_device mxc_usbh2 = {
.num_resources = ARRAY_SIZE(mxc_usbh2_resources),
};
-#if defined(CONFIG_ARCH_MX35)
-static struct resource mxc_fec_resources[] = {
- {
- .start = MXC_FEC_BASE_ADDR,
- .end = MXC_FEC_BASE_ADDR + 0xfff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_FEC,
- .end = MXC_INT_FEC,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_fec_device = {
- .name = "fec",
- .id = 0,
- .num_resources = ARRAY_SIZE(mxc_fec_resources),
- .resource = mxc_fec_resources,
-};
-#endif
-
-static struct resource imx_ssi_resources0[] = {
- {
- .start = SSI1_BASE_ADDR,
- .end = SSI1_BASE_ADDR + 0xfff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX31_INT_SSI1,
- .end = MX31_INT_SSI1,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct resource imx_ssi_resources1[] = {
- {
- .start = SSI2_BASE_ADDR,
- .end = SSI2_BASE_ADDR + 0xfff,
- .flags = IORESOURCE_MEM
- }, {
- .start = MX31_INT_SSI2,
- .end = MX31_INT_SSI2,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device imx_ssi_device0 = {
- .name = "imx-ssi",
- .id = 0,
- .num_resources = ARRAY_SIZE(imx_ssi_resources0),
- .resource = imx_ssi_resources0,
-};
-
-struct platform_device imx_ssi_device1 = {
- .name = "imx-ssi",
- .id = 1,
- .num_resources = ARRAY_SIZE(imx_ssi_resources1),
- .resource = imx_ssi_resources1,
-};
-
static struct resource imx_wdt_resources[] = {
{
.flags = IORESOURCE_MEM,
@@ -410,10 +351,6 @@ static int __init mx3_devices_init(void)
mxc_usbh1_resources[0].end = MX35_OTG_BASE_ADDR + 0x5ff;
mxc_usbh1_resources[1].start = MXC_INT_USBHS;
mxc_usbh1_resources[1].end = MXC_INT_USBHS;
- imx_ssi_resources0[1].start = MX35_INT_SSI1;
- imx_ssi_resources0[1].end = MX35_INT_SSI1;
- imx_ssi_resources1[1].start = MX35_INT_SSI2;
- imx_ssi_resources1[1].end = MX35_INT_SSI2;
imx_wdt_resources[0].start = MX35_WDOG_BASE_ADDR;
imx_wdt_resources[0].end = MX35_WDOG_BASE_ADDR + 0x3fff;
}
diff --git a/arch/arm/mach-mx3/devices.h b/arch/arm/mach-mx3/devices.h
index e5535234839f..585f814473d5 100644
--- a/arch/arm/mach-mx3/devices.h
+++ b/arch/arm/mach-mx3/devices.h
@@ -2,7 +2,6 @@ extern struct platform_device mxc_w1_master_device;
extern struct platform_device mx3_ipu;
extern struct platform_device mx3_fb;
extern struct platform_device mx3_camera;
-extern struct platform_device mxc_fec_device;
extern struct platform_device mxcsdhc_device0;
extern struct platform_device mxcsdhc_device1;
extern struct platform_device mxc_otg_udc_device;
@@ -10,9 +9,6 @@ extern struct platform_device mxc_otg_host;
extern struct platform_device mxc_usbh1;
extern struct platform_device mxc_usbh2;
extern struct platform_device mxc_rnga_device;
-extern struct platform_device imx_ssi_device0;
-extern struct platform_device imx_ssi_device1;
-extern struct platform_device imx_ssi_device1;
extern struct platform_device imx_wdt_device0;
extern struct platform_device imx_rtc_device0;
extern struct platform_device imx_kpp_device;
diff --git a/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c
index f8f15e3ac7a0..1abc10d52922 100644
--- a/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c
+++ b/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c
@@ -43,14 +43,13 @@
#include <mach/ipu.h>
#include <mach/mx3fb.h>
#include <mach/audmux.h>
-#include <mach/ssi.h>
#include "devices-imx35.h"
#include "devices.h"
static const struct fb_videomode fb_modedb[] = {
{
- .name = "CMO_QVGA",
+ .name = "CMO-QVGA",
.refresh = 60,
.xres = 320,
.yres = 240,
@@ -65,6 +64,40 @@ static const struct fb_videomode fb_modedb[] = {
.vmode = FB_VMODE_NONINTERLACED,
.flag = 0,
},
+ {
+ .name = "DVI-VGA",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 32000,
+ .left_margin = 100,
+ .right_margin = 100,
+ .upper_margin = 7,
+ .lower_margin = 100,
+ .hsync_len = 7,
+ .vsync_len = 7,
+ .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT |
+ FB_SYNC_OE_ACT_HIGH | FB_SYNC_CLK_INVERT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ },
+ {
+ .name = "DVI-SVGA",
+ .refresh = 60,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 25000,
+ .left_margin = 75,
+ .right_margin = 75,
+ .upper_margin = 7,
+ .lower_margin = 75,
+ .hsync_len = 7,
+ .vsync_len = 7,
+ .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT |
+ FB_SYNC_OE_ACT_HIGH | FB_SYNC_CLK_INVERT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ },
};
static struct ipu_platform_data mx3_ipu_data = {
@@ -73,7 +106,7 @@ static struct ipu_platform_data mx3_ipu_data = {
static struct mx3fb_platform_data mx3fb_pdata = {
.dma_dev = &mx3_ipu.dev,
- .name = "CMO_QVGA",
+ .name = "CMO-QVGA",
.mode = fb_modedb,
.num_modes = ARRAY_SIZE(fb_modedb),
};
@@ -120,6 +153,16 @@ static struct pad_desc eukrea_mbimxsd_pads[] = {
MX35_PAD_STXD4__AUDMUX_AUD4_TXD,
MX35_PAD_SRXD4__AUDMUX_AUD4_RXD,
MX35_PAD_SCK4__AUDMUX_AUD4_TXC,
+ /* CAN2 */
+ MX35_PAD_TX5_RX0__CAN2_TXCAN,
+ MX35_PAD_TX4_RX1__CAN2_RXCAN,
+ /* SDCARD */
+ MX35_PAD_SD1_CMD__ESDHC1_CMD,
+ MX35_PAD_SD1_CLK__ESDHC1_CLK,
+ MX35_PAD_SD1_DATA0__ESDHC1_DAT0,
+ MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
+ MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
+ MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
};
#define GPIO_LED1 (2 * 32 + 29)
@@ -206,7 +249,8 @@ static struct i2c_board_info eukrea_mbimxsd_i2c_devices[] = {
},
};
-struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata = {
+static const
+struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata __initconst = {
.flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE,
};
@@ -242,7 +286,10 @@ void __init eukrea_mbimxsd35_baseboard_init(void)
mxc_register_device(&mx3_ipu, &mx3_ipu_data);
mxc_register_device(&mx3_fb, &mx3fb_pdata);
- mxc_register_device(&imx_ssi_device0, &eukrea_mbimxsd_ssi_pdata);
+ imx35_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);
+
+ imx35_add_flexcan1(NULL);
+ imx35_add_esdhc(0, NULL);
gpio_request(GPIO_LED1, "LED1");
gpio_direction_output(GPIO_LED1, 1);
@@ -254,7 +301,7 @@ void __init eukrea_mbimxsd35_baseboard_init(void)
gpio_request(GPIO_LCDPWR, "LCDPWR");
gpio_direction_output(GPIO_LCDPWR, 1);
- gpio_free(GPIO_SWITCH1);
+ gpio_free(GPIO_LCDPWR);
i2c_register_board_info(0, eukrea_mbimxsd_i2c_devices,
ARRAY_SIZE(eukrea_mbimxsd_i2c_devices));
diff --git a/arch/arm/mach-mx3/mach-armadillo5x0.c b/arch/arm/mach-mx3/mach-armadillo5x0.c
index 68879c996a55..aaa30fe18f85 100644
--- a/arch/arm/mach-mx3/mach-armadillo5x0.c
+++ b/arch/arm/mach-mx3/mach-armadillo5x0.c
@@ -571,8 +571,6 @@ static struct sys_timer armadillo5x0_timer = {
MACHINE_START(ARMADILLO5X0, "Armadillo-500")
/* Maintainer: Alberto Panizzo */
- .phys_io = MX31_AIPS1_BASE_ADDR,
- .io_pg_offst = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
.boot_params = MX3x_PHYS_OFFSET + 0x100,
.map_io = mx31_map_io,
.init_irq = mx31_init_irq,
diff --git a/arch/arm/mach-mx3/mach-cpuimx35.c b/arch/arm/mach-mx3/mach-cpuimx35.c
index 2a4f8b781ba4..9fde873f5889 100644
--- a/arch/arm/mach-mx3/mach-cpuimx35.c
+++ b/arch/arm/mach-mx3/mach-cpuimx35.c
@@ -31,6 +31,7 @@
#include <linux/usb/otg.h>
#include <linux/usb/ulpi.h>
#include <linux/fsl_devices.h>
+#include <linux/i2c-gpio.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -43,7 +44,6 @@
#include <mach/iomux-mx35.h>
#include <mach/mxc_nand.h>
#include <mach/mxc_ehci.h>
-#include <mach/ulpi.h>
#include "devices-imx35.h"
#include "devices.h"
@@ -53,39 +53,16 @@ static const struct imxuart_platform_data uart_pdata __initconst = {
};
static const struct imxi2c_platform_data
-eukrea_cpuimx35_i2c0_data __initconst = {
- .bitrate = 50000,
+ eukrea_cpuimx35_i2c0_data __initconst = {
+ .bitrate = 100000,
};
-#define TSC2007_IRQGPIO (2 * 32 + 2)
-static int ts_get_pendown_state(void)
-{
- int val = 0;
- gpio_free(TSC2007_IRQGPIO);
- gpio_request(TSC2007_IRQGPIO, NULL);
- gpio_direction_input(TSC2007_IRQGPIO);
-
- val = gpio_get_value(TSC2007_IRQGPIO);
-
- gpio_free(TSC2007_IRQGPIO);
- gpio_request(TSC2007_IRQGPIO, NULL);
-
- return val ? 0 : 1;
-}
-
-static int ts_init(void)
-{
- gpio_request(TSC2007_IRQGPIO, NULL);
- return 0;
-}
-
static struct tsc2007_platform_data tsc2007_info = {
.model = 2007,
.x_plate_ohms = 180,
- .get_pendown_state = ts_get_pendown_state,
- .init_platform_hw = ts_init,
};
+#define TSC2007_IRQGPIO (2 * 32 + 2)
static struct i2c_board_info eukrea_cpuimx35_i2c_devices[] = {
{
I2C_BOARD_INFO("pcf8563", 0x51),
@@ -98,7 +75,6 @@ static struct i2c_board_info eukrea_cpuimx35_i2c_devices[] = {
};
static struct platform_device *devices[] __initdata = {
- &mxc_fec_device,
&imx_wdt_device0,
};
@@ -135,18 +111,18 @@ static struct pad_desc eukrea_cpuimx35_pads[] = {
};
static const struct mxc_nand_platform_data
-eukrea_cpuimx35_nand_board_info __initconst = {
+ eukrea_cpuimx35_nand_board_info __initconst = {
.width = 1,
.hw_ecc = 1,
.flash_bbt = 1,
};
-static struct mxc_usbh_platform_data otg_pdata = {
+static struct mxc_usbh_platform_data __maybe_unused otg_pdata = {
.portsc = MXC_EHCI_MODE_UTMI,
.flags = MXC_EHCI_INTERFACE_DIFF_UNI,
};
-static struct mxc_usbh_platform_data usbh1_pdata = {
+static struct mxc_usbh_platform_data __maybe_unused usbh1_pdata = {
.portsc = MXC_EHCI_MODE_SERIAL,
.flags = MXC_EHCI_INTERFACE_SINGLE_UNI | MXC_EHCI_INTERNAL_PHY |
MXC_EHCI_IPPUE_DOWN,
@@ -155,6 +131,7 @@ static struct mxc_usbh_platform_data usbh1_pdata = {
static struct fsl_usb2_platform_data otg_device_pdata = {
.operating_mode = FSL_USB2_DR_DEVICE,
.phy_mode = FSL_USB2_PHY_UTMI,
+ .workaround = FLS_USB2_WORKAROUND_ENGCM09152,
};
static int otg_mode_host;
@@ -180,6 +157,7 @@ static void __init mxc_board_init(void)
mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx35_pads,
ARRAY_SIZE(eukrea_cpuimx35_pads));
+ imx35_add_fec(NULL);
platform_add_devices(devices, ARRAY_SIZE(devices));
imx35_add_imx_uart0(&uart_pdata);
@@ -189,18 +167,13 @@ static void __init mxc_board_init(void)
ARRAY_SIZE(eukrea_cpuimx35_i2c_devices));
imx35_add_imx_i2c0(&eukrea_cpuimx35_i2c0_data);
-#if defined(CONFIG_USB_ULPI)
- if (otg_mode_host) {
- otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
- ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
-
+ if (otg_mode_host)
mxc_register_device(&mxc_otg_host, &otg_pdata);
- }
- mxc_register_device(&mxc_usbh1, &usbh1_pdata);
-#endif
- if (!otg_mode_host)
+ else
mxc_register_device(&mxc_otg_udc_device, &otg_device_pdata);
+ mxc_register_device(&mxc_usbh1, &usbh1_pdata);
+
#ifdef CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD
eukrea_mbimxsd35_baseboard_init();
#endif
@@ -217,8 +190,6 @@ struct sys_timer eukrea_cpuimx35_timer = {
MACHINE_START(EUKREA_CPUIMX35, "Eukrea CPUIMX35")
/* Maintainer: Eukrea Electromatique */
- .phys_io = MX35_AIPS1_BASE_ADDR,
- .io_pg_offst = ((MX35_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
.boot_params = MX3x_PHYS_OFFSET + 0x100,
.map_io = mx35_map_io,
.init_irq = mx35_init_irq,
diff --git a/arch/arm/mach-mx3/mach-kzm_arm11_01.c b/arch/arm/mach-mx3/mach-kzm_arm11_01.c
index 5b23e416d6c7..042cd5655e17 100644
--- a/arch/arm/mach-mx3/mach-kzm_arm11_01.c
+++ b/arch/arm/mach-mx3/mach-kzm_arm11_01.c
@@ -274,8 +274,6 @@ static struct sys_timer kzm_timer = {
* initialize __mach_desc_KZM_ARM11_01 data structure.
*/
MACHINE_START(KZM_ARM11_01, "Kyoto Microcomputer Co., Ltd. KZM-ARM11-01")
- .phys_io = MX31_AIPS1_BASE_ADDR,
- .io_pg_offst = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
.boot_params = MX3x_PHYS_OFFSET + 0x100,
.map_io = kzm_map_io,
.init_irq = mx31_init_irq,
diff --git a/arch/arm/mach-mx3/mach-mx31_3ds.c b/arch/arm/mach-mx3/mach-mx31_3ds.c
index 6fe69e124d30..5c1d0e86c91e 100644
--- a/arch/arm/mach-mx3/mach-mx31_3ds.c
+++ b/arch/arm/mach-mx3/mach-mx31_3ds.c
@@ -301,8 +301,6 @@ static struct sys_timer mx31_3ds_timer = {
*/
MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)")
/* Maintainer: Freescale Semiconductor, Inc. */
- .phys_io = MX31_AIPS1_BASE_ADDR,
- .io_pg_offst = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
.boot_params = MX3x_PHYS_OFFSET + 0x100,
.map_io = mx31_3ds_map_io,
.init_irq = mx31_init_irq,
diff --git a/arch/arm/mach-mx3/mach-mx31ads.c b/arch/arm/mach-mx3/mach-mx31ads.c
index 94b3e7c42404..b993b9bf6179 100644
--- a/arch/arm/mach-mx3/mach-mx31ads.c
+++ b/arch/arm/mach-mx3/mach-mx31ads.c
@@ -22,13 +22,13 @@
#include <linux/i2c.h>
#include <linux/irq.h>
-#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
#include <asm/memory.h>
#include <asm/mach/map.h>
#include <mach/common.h>
+#include <mach/board-mx31ads.h>
#include <mach/iomux-mx3.h>
#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
@@ -40,10 +40,6 @@
#include "devices-imx31.h"
#include "devices.h"
-/* Base address of PBC controller */
-#define PBC_BASE_ADDRESS MX31_CS4_BASE_ADDR_VIRT
-/* Offsets for the PBC Controller register */
-
/* PBC Board interrupt status register */
#define PBC_INTSTATUS 0x000016
@@ -67,7 +63,6 @@
#define PBC_INTMASK_CLEAR_REG (PBC_INTMASK_CLEAR + PBC_BASE_ADDRESS)
#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_4)
-#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START)
#define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_EXP_IO_BASE)
#define EXPIO_INT_XUART_INTA (MXC_EXP_IO_BASE + 10)
@@ -517,7 +512,7 @@ static unsigned int ssi_pins[] = {
static void mxc_init_audio(void)
{
- mxc_register_device(&imx_ssi_device0, NULL);
+ imx31_add_imx_ssi(0, NULL);
mxc_iomux_setup_multiple_pins(ssi_pins, ARRAY_SIZE(ssi_pins), "ssi");
}
@@ -574,8 +569,6 @@ static struct sys_timer mx31ads_timer = {
*/
MACHINE_START(MX31ADS, "Freescale MX31ADS")
/* Maintainer: Freescale Semiconductor, Inc. */
- .phys_io = MX31_AIPS1_BASE_ADDR,
- .io_pg_offst = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
.boot_params = MX3x_PHYS_OFFSET + 0x100,
.map_io = mx31ads_map_io,
.init_irq = mx31ads_init_irq,
diff --git a/arch/arm/mach-mx3/mach-mx31lilly.c b/arch/arm/mach-mx3/mach-mx31lilly.c
index 7c37daabb757..42f47faa6fd6 100644
--- a/arch/arm/mach-mx3/mach-mx31lilly.c
+++ b/arch/arm/mach-mx3/mach-mx31lilly.c
@@ -348,8 +348,6 @@ static struct sys_timer mx31lilly_timer = {
};
MACHINE_START(LILLY1131, "INCO startec LILLY-1131")
- .phys_io = MX31_AIPS1_BASE_ADDR,
- .io_pg_offst = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
.boot_params = MX3x_PHYS_OFFSET + 0x100,
.map_io = mx31_map_io,
.init_irq = mx31_init_irq,
diff --git a/arch/arm/mach-mx3/mach-mx31lite.c b/arch/arm/mach-mx3/mach-mx31lite.c
index f66a9576d8c2..b93895814cdf 100644
--- a/arch/arm/mach-mx3/mach-mx31lite.c
+++ b/arch/arm/mach-mx3/mach-mx31lite.c
@@ -282,8 +282,6 @@ struct sys_timer mx31lite_timer = {
MACHINE_START(MX31LITE, "LogicPD i.MX31 SOM")
/* Maintainer: Freescale Semiconductor, Inc. */
- .phys_io = MX31_AIPS1_BASE_ADDR,
- .io_pg_offst = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
.boot_params = MX3x_PHYS_OFFSET + 0x100,
.map_io = mx31lite_map_io,
.init_irq = mx31_init_irq,
diff --git a/arch/arm/mach-mx3/mach-mx31moboard.c b/arch/arm/mach-mx3/mach-mx31moboard.c
index 7a075e8bf2d4..eb5f426df224 100644
--- a/arch/arm/mach-mx3/mach-mx31moboard.c
+++ b/arch/arm/mach-mx3/mach-mx31moboard.c
@@ -560,8 +560,6 @@ struct sys_timer mx31moboard_timer = {
MACHINE_START(MX31MOBOARD, "EPFL Mobots mx31moboard")
/* Maintainer: Valentin Longchamp, EPFL Mobots group */
- .phys_io = MX31_AIPS1_BASE_ADDR,
- .io_pg_offst = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
.boot_params = MX3x_PHYS_OFFSET + 0x100,
.map_io = mx31_map_io,
.init_irq = mx31_init_irq,
diff --git a/arch/arm/mach-mx3/mach-mx35_3ds.c b/arch/arm/mach-mx3/mach-mx35_3ds.c
index 1c30d7212f17..05f628d90725 100644
--- a/arch/arm/mach-mx3/mach-mx35_3ds.c
+++ b/arch/arm/mach-mx3/mach-mx35_3ds.c
@@ -1,5 +1,6 @@
/*
* Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009 Marc Kleine-Budde, Pengutronix
*
* Author: Fabio Estevam <fabio.estevam@freescale.com>
*
@@ -27,6 +28,8 @@
#include <linux/gpio.h>
#include <linux/fsl_devices.h>
+#include <linux/mtd/physmap.h>
+
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
@@ -35,6 +38,7 @@
#include <mach/hardware.h>
#include <mach/common.h>
#include <mach/iomux-mx35.h>
+#include <mach/mxc_ehci.h>
#include "devices-imx35.h"
#include "devices.h"
@@ -43,8 +47,34 @@ static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
+static struct physmap_flash_data mx35pdk_flash_data = {
+ .width = 2,
+};
+
+static struct resource mx35pdk_flash_resource = {
+ .start = MX35_CS0_BASE_ADDR,
+ .end = MX35_CS0_BASE_ADDR + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device mx35pdk_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &mx35pdk_flash_data,
+ },
+ .resource = &mx35pdk_flash_resource,
+ .num_resources = 1,
+};
+
+static const struct mxc_nand_platform_data mx35pdk_nand_board_info __initconst = {
+ .width = 1,
+ .hw_ecc = 1,
+ .flash_bbt = 1,
+};
+
static struct platform_device *devices[] __initdata = {
- &mxc_fec_device,
+ &mx35pdk_flash,
};
static struct pad_desc mx35pdk_pads[] = {
@@ -75,14 +105,24 @@ static struct pad_desc mx35pdk_pads[] = {
/* USBOTG */
MX35_PAD_USBOTG_PWR__USB_TOP_USBOTG_PWR,
MX35_PAD_USBOTG_OC__USB_TOP_USBOTG_OC,
+ /* USBH1 */
+ MX35_PAD_I2C2_CLK__USB_TOP_USBH2_PWR,
+ MX35_PAD_I2C2_DAT__USB_TOP_USBH2_OC,
};
/* OTG config */
-static struct fsl_usb2_platform_data usb_pdata = {
+static struct fsl_usb2_platform_data usb_otg_pdata = {
.operating_mode = FSL_USB2_DR_DEVICE,
.phy_mode = FSL_USB2_PHY_UTMI_WIDE,
};
+/* USB HOST config */
+static struct mxc_usbh_platform_data usb_host_pdata = {
+ .portsc = MXC_EHCI_MODE_SERIAL,
+ .flags = MXC_EHCI_INTERFACE_SINGLE_UNI |
+ MXC_EHCI_INTERNAL_PHY,
+};
+
/*
* Board specific initialization.
*/
@@ -90,11 +130,16 @@ static void __init mxc_board_init(void)
{
mxc_iomux_v3_setup_multiple_pads(mx35pdk_pads, ARRAY_SIZE(mx35pdk_pads));
+ imx35_add_fec(NULL);
platform_add_devices(devices, ARRAY_SIZE(devices));
imx35_add_imx_uart0(&uart_pdata);
- mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
+ mxc_register_device(&mxc_otg_udc_device, &usb_otg_pdata);
+
+ mxc_register_device(&mxc_usbh1, &usb_host_pdata);
+
+ imx35_add_mxc_nand(&mx35pdk_nand_board_info);
}
static void __init mx35pdk_timer_init(void)
@@ -108,8 +153,6 @@ struct sys_timer mx35pdk_timer = {
MACHINE_START(MX35_3DS, "Freescale MX35PDK")
/* Maintainer: Freescale Semiconductor, Inc */
- .phys_io = MX35_AIPS1_BASE_ADDR,
- .io_pg_offst = ((MX35_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
.boot_params = MX3x_PHYS_OFFSET + 0x100,
.map_io = mx35_map_io,
.init_irq = mx35_init_irq,
diff --git a/arch/arm/mach-mx3/mach-pcm037.c b/arch/arm/mach-mx3/mach-pcm037.c
index 214de11b20b9..86e86c1300d5 100644
--- a/arch/arm/mach-mx3/mach-pcm037.c
+++ b/arch/arm/mach-mx3/mach-pcm037.c
@@ -680,8 +680,6 @@ struct sys_timer pcm037_timer = {
MACHINE_START(PCM037, "Phytec Phycore pcm037")
/* Maintainer: Pengutronix */
- .phys_io = MX31_AIPS1_BASE_ADDR,
- .io_pg_offst = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
.boot_params = MX3x_PHYS_OFFSET + 0x100,
.map_io = mx31_map_io,
.init_irq = mx31_init_irq,
diff --git a/arch/arm/mach-mx3/mach-pcm037_eet.c b/arch/arm/mach-mx3/mach-pcm037_eet.c
index c8b98218efee..99e0894e07db 100644
--- a/arch/arm/mach-mx3/mach-pcm037_eet.c
+++ b/arch/arm/mach-mx3/mach-pcm037_eet.c
@@ -19,6 +19,7 @@
#include "pcm037.h"
#include "devices.h"
+#include "devices-imx31.h"
static unsigned int pcm037_eet_pins[] = {
/* Reserve and hardwire GPIO 57 high - S6E63D6 chipselect */
@@ -181,7 +182,7 @@ static int eet_init_devices(void)
/* SPI */
spi_register_board_info(pcm037_spi_dev, ARRAY_SIZE(pcm037_spi_dev));
#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
- imx35_add_spi_imx0(&pcm037_spi1_pdata);
+ imx31_add_spi_imx0(&pcm037_spi1_pdata);
#endif
platform_device_register(&pcm037_gpio_keys_device);
diff --git a/arch/arm/mach-mx3/mach-pcm043.c b/arch/arm/mach-mx3/mach-pcm043.c
index 28886f0e62f9..4e1de87995d4 100644
--- a/arch/arm/mach-mx3/mach-pcm043.c
+++ b/arch/arm/mach-mx3/mach-pcm043.c
@@ -42,7 +42,6 @@
#include <mach/mxc_ehci.h>
#include <mach/ulpi.h>
#include <mach/audmux.h>
-#include <mach/ssi.h>
#include "devices-imx35.h"
#include "devices.h"
@@ -141,7 +140,6 @@ static struct i2c_board_info pcm043_i2c_devices[] = {
static struct platform_device *devices[] __initdata = {
&pcm043_flash,
- &mxc_fec_device,
&imx_wdt_device0,
};
@@ -217,6 +215,13 @@ static struct pad_desc pcm043_pads[] = {
/* CAN2 */
MX35_PAD_TX5_RX0__CAN2_TXCAN,
MX35_PAD_TX4_RX1__CAN2_RXCAN,
+ /* esdhc */
+ MX35_PAD_SD1_CMD__ESDHC1_CMD,
+ MX35_PAD_SD1_CLK__ESDHC1_CLK,
+ MX35_PAD_SD1_DATA0__ESDHC1_DAT0,
+ MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
+ MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
+ MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
};
#define AC97_GPIO_TXFS (1 * 32 + 31)
@@ -293,7 +298,7 @@ err1:
mdelay(1);
}
-static struct imx_ssi_platform_data pcm043_ssi_pdata = {
+static const struct imx_ssi_platform_data pcm043_ssi_pdata __initconst = {
.ac97_reset = pcm043_ac97_cold_reset,
.ac97_warm_reset = pcm043_ac97_warm_reset,
.flags = IMX_SSI_USE_AC97,
@@ -357,11 +362,12 @@ static void __init mxc_board_init(void)
MXC_AUDMUX_V2_PTCR_TCLKDIR, /* clock is output */
MXC_AUDMUX_V2_PDCR_RXDSEL(3));
+ imx35_add_fec(NULL);
platform_add_devices(devices, ARRAY_SIZE(devices));
imx35_add_imx_uart0(&uart_pdata);
imx35_add_mxc_nand(&pcm037_nand_board_info);
- mxc_register_device(&imx_ssi_device0, &pcm043_ssi_pdata);
+ imx35_add_imx_ssi(0, &pcm043_ssi_pdata);
imx35_add_imx_uart1(&uart_pdata);
@@ -389,6 +395,7 @@ static void __init mxc_board_init(void)
mxc_register_device(&mxc_otg_udc_device, &otg_device_pdata);
imx35_add_flexcan1(NULL);
+ imx35_add_esdhc(0, NULL);
}
static void __init pcm043_timer_init(void)
@@ -402,8 +409,6 @@ struct sys_timer pcm043_timer = {
MACHINE_START(PCM043, "Phytec Phycore pcm043")
/* Maintainer: Pengutronix */
- .phys_io = MX35_AIPS1_BASE_ADDR,
- .io_pg_offst = ((MX35_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
.boot_params = MX3x_PHYS_OFFSET + 0x100,
.map_io = mx35_map_io,
.init_irq = mx35_init_irq,
diff --git a/arch/arm/mach-mx3/mach-qong.c b/arch/arm/mach-mx3/mach-qong.c
index c8c380eef74c..fd1050c40964 100644
--- a/arch/arm/mach-mx3/mach-qong.c
+++ b/arch/arm/mach-mx3/mach-qong.c
@@ -270,8 +270,6 @@ static struct sys_timer qong_timer = {
MACHINE_START(QONG, "Dave/DENX QongEVB-LITE")
/* Maintainer: DENX Software Engineering GmbH */
- .phys_io = MX31_AIPS1_BASE_ADDR,
- .io_pg_offst = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
.boot_params = MX3x_PHYS_OFFSET + 0x100,
.map_io = mx31_map_io,
.init_irq = mx31_init_irq,
diff --git a/arch/arm/mach-mx3/mm.c b/arch/arm/mach-mx3/mm.c
index 20e48c0195c4..b4ffc531a82c 100644
--- a/arch/arm/mach-mx3/mm.c
+++ b/arch/arm/mach-mx3/mm.c
@@ -110,6 +110,24 @@ void __init mx35_init_irq(void)
static int mxc_init_l2x0(void)
{
void __iomem *l2x0_base;
+ void __iomem *clkctl_base;
+/*
+ * First of all, we must repair broken chip settings. There are some
+ * i.MX35 CPUs in the wild, comming with bogus L2 cache settings. These
+ * misconfigured CPUs will run amok immediately when the L2 cache gets enabled.
+ * Workaraound is to setup the correct register setting prior enabling the
+ * L2 cache. This should not hurt already working CPUs, as they are using the
+ * same value
+ */
+#define L2_MEM_VAL 0x10
+
+ clkctl_base = ioremap(MX35_CLKCTL_BASE_ADDR, 4096);
+ if (clkctl_base != NULL) {
+ writel(0x00000515, clkctl_base + L2_MEM_VAL);
+ iounmap(clkctl_base);
+ } else {
+ pr_err("L2 cache: Cannot fix timing. Trying to continue without\n");
+ }
l2x0_base = ioremap(L2CC_BASE_ADDR, 4096);
if (IS_ERR(l2x0_base)) {
diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig
index 0848db5dd364..a2df9ac37996 100644
--- a/arch/arm/mach-mx5/Kconfig
+++ b/arch/arm/mach-mx5/Kconfig
@@ -5,11 +5,14 @@ config ARCH_MX51
default y
select MXC_TZIC
select ARCH_MXC_IOMUX_V3
+ select ARCH_MXC_AUDMUX_V2
comment "MX5 platforms:"
config MACH_MX51_BABBAGE
bool "Support MX51 BABBAGE platforms"
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
help
Include support for MX51 Babbage platform, also known as MX51EVK in
u-boot. This includes specific configurations for the board and its
@@ -17,6 +20,8 @@ config MACH_MX51_BABBAGE
config MACH_MX51_3DS
bool "Support MX51PDK (3DS)"
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_SPI_IMX
select MXC_DEBUG_BOARD
help
Include support for MX51PDK (3DS) platform. This includes specific
@@ -24,6 +29,10 @@ config MACH_MX51_3DS
config MACH_EUKREA_CPUIMX51
bool "Support Eukrea CPUIMX51 module"
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_SPI_IMX
help
Include support for Eukrea CPUIMX51 platform. This includes
specific configurations for the module and its peripherals.
@@ -36,10 +45,43 @@ choice
config MACH_EUKREA_MBIMX51_BASEBOARD
prompt "Eukrea MBIMX51 development board"
bool
+ select IMX_HAVE_PLATFORM_ESDHC
help
This adds board specific devices that can be found on Eukrea's
MBIMX51 evaluation board.
endchoice
+config MACH_EUKREA_CPUIMX51SD
+ bool "Support Eukrea CPUIMX51SD module"
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ help
+ Include support for Eukrea CPUIMX51SD platform. This includes
+ specific configurations for the module and its peripherals.
+
+choice
+ prompt "Baseboard"
+ depends on MACH_EUKREA_CPUIMX51SD
+ default MACH_EUKREA_MBIMXSD51_BASEBOARD
+
+config MACH_EUKREA_MBIMXSD51_BASEBOARD
+ prompt "Eukrea MBIMXSD development board"
+ bool
+ select IMX_HAVE_PLATFORM_ESDHC
+ help
+ This adds board specific devices that can be found on Eukrea's
+ MBIMXSD evaluation board.
+
+endchoice
+
+config MACH_MX51_EFIKAMX
+ bool "Support MX51 Genesi Efika MX nettop"
+ select IMX_HAVE_PLATFORM_IMX_UART
+ help
+ Include support for Genesi Efika MX nettop. This includes specific
+ configurations for the board and its peripherals.
+
endif
diff --git a/arch/arm/mach-mx5/Makefile b/arch/arm/mach-mx5/Makefile
index 86c66e7f52f3..1769c161a60d 100644
--- a/arch/arm/mach-mx5/Makefile
+++ b/arch/arm/mach-mx5/Makefile
@@ -9,3 +9,6 @@ obj-$(CONFIG_MACH_MX51_BABBAGE) += board-mx51_babbage.o
obj-$(CONFIG_MACH_MX51_3DS) += board-mx51_3ds.o
obj-$(CONFIG_MACH_EUKREA_CPUIMX51) += board-cpuimx51.o
obj-$(CONFIG_MACH_EUKREA_MBIMX51_BASEBOARD) += eukrea_mbimx51-baseboard.o
+obj-$(CONFIG_MACH_EUKREA_CPUIMX51SD) += board-cpuimx51sd.o
+obj-$(CONFIG_MACH_EUKREA_MBIMXSD51_BASEBOARD) += eukrea_mbimxsd-baseboard.o
+obj-$(CONFIG_MACH_MX51_EFIKAMX) += board-mx51_efikamx.o
diff --git a/arch/arm/mach-mx5/board-cpuimx51.c b/arch/arm/mach-mx5/board-cpuimx51.c
index 623607a20f57..6a9792fd0a76 100644
--- a/arch/arm/mach-mx5/board-cpuimx51.c
+++ b/arch/arm/mach-mx5/board-cpuimx51.c
@@ -28,9 +28,7 @@
#include <mach/eukrea-baseboards.h>
#include <mach/common.h>
#include <mach/hardware.h>
-#include <mach/imx-uart.h>
#include <mach/iomux-mx51.h>
-#include <mach/i2c.h>
#include <mach/mxc_ehci.h>
#include <asm/irq.h>
@@ -39,6 +37,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
+#include "devices-imx51.h"
#include "devices.h"
#define CPUIMX51_USBH1_STP (0*32 + 27)
@@ -109,7 +108,6 @@ static struct platform_device serial_device = {
#endif
static struct platform_device *devices[] __initdata = {
- &mxc_fec_device,
#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
&serial_device,
#endif
@@ -148,11 +146,19 @@ static struct pad_desc eukrea_cpuimx51_pads[] = {
MX51_PAD_USBH1_STP__USBH1_STP,
};
-static struct imxuart_platform_data uart_pdata = {
+static const struct mxc_nand_platform_data
+ eukrea_cpuimx51_nand_board_info __initconst = {
+ .width = 1,
+ .hw_ecc = 1,
+ .flash_bbt = 1,
+};
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
-static struct imxi2c_platform_data eukrea_cpuimx51_i2c_data = {
+static const
+struct imxi2c_platform_data eukrea_cpuimx51_i2c_data __initconst = {
.bitrate = 100000,
};
@@ -239,7 +245,9 @@ static void __init eukrea_cpuimx51_init(void)
mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx51_pads,
ARRAY_SIZE(eukrea_cpuimx51_pads));
- mxc_register_device(&mxc_uart_device0, &uart_pdata);
+ imx51_add_imx_uart(0, &uart_pdata);
+ imx51_add_mxc_nand(&eukrea_cpuimx51_nand_board_info);
+
gpio_request(CPUIMX51_QUARTA_GPIO, "quarta_irq");
gpio_direction_input(CPUIMX51_QUARTA_GPIO);
gpio_free(CPUIMX51_QUARTA_GPIO);
@@ -253,9 +261,10 @@ static void __init eukrea_cpuimx51_init(void)
gpio_direction_input(CPUIMX51_QUARTD_GPIO);
gpio_free(CPUIMX51_QUARTD_GPIO);
+ imx51_add_fec(NULL);
platform_add_devices(devices, ARRAY_SIZE(devices));
- mxc_register_device(&mxc_i2c_device1, &eukrea_cpuimx51_i2c_data);
+ imx51_add_imx_i2c(1, &eukrea_cpuimx51_i2c_data);
i2c_register_board_info(1, eukrea_cpuimx51_i2c_devices,
ARRAY_SIZE(eukrea_cpuimx51_i2c_devices));
@@ -283,8 +292,6 @@ static struct sys_timer mxc_timer = {
MACHINE_START(EUKREA_CPUIMX51, "Eukrea CPUIMX51 Module")
/* Maintainer: Eric Bénard <eric@eukrea.com> */
- .phys_io = MX51_AIPS1_BASE_ADDR,
- .io_pg_offst = ((MX51_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x100,
.map_io = mx51_map_io,
.init_irq = mx51_init_irq,
diff --git a/arch/arm/mach-mx5/board-cpuimx51sd.c b/arch/arm/mach-mx5/board-cpuimx51sd.c
new file mode 100644
index 000000000000..4b3a6119c5fb
--- /dev/null
+++ b/arch/arm/mach-mx5/board-cpuimx51sd.c
@@ -0,0 +1,331 @@
+/*
+ *
+ * Copyright (C) 2010 Eric Bénard <eric@eukrea.com>
+ *
+ * based on board-mx51_babbage.c which is
+ * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/i2c/tsc2007.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/fsl_devices.h>
+#include <linux/i2c-gpio.h>
+#include <linux/spi/spi.h>
+#include <linux/can/platform/mcp251x.h>
+
+#include <mach/eukrea-baseboards.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux-mx51.h>
+#include <mach/mxc_ehci.h>
+
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "devices-imx51.h"
+#include "devices.h"
+
+#define USBH1_RST (1*32 + 28)
+#define ETH_RST (1*32 + 31)
+#define TSC2007_IRQGPIO (2*32 + 12)
+#define CAN_IRQGPIO (0*32 + 1)
+#define CAN_RST (3*32 + 15)
+#define CAN_NCS (3*32 + 24)
+#define CAN_RXOBF (0*32 + 4)
+#define CAN_RX1BF (0*32 + 6)
+#define CAN_TXORTS (0*32 + 7)
+#define CAN_TX1RTS (0*32 + 8)
+#define CAN_TX2RTS (0*32 + 9)
+#define I2C_SCL (3*32 + 16)
+#define I2C_SDA (3*32 + 17)
+
+/* USB_CTRL_1 */
+#define MX51_USB_CTRL_1_OFFSET 0x10
+#define MX51_USB_CTRL_UH1_EXT_CLK_EN (1 << 25)
+
+#define MX51_USB_PLLDIV_12_MHZ 0x00
+#define MX51_USB_PLL_DIV_19_2_MHZ 0x01
+#define MX51_USB_PLL_DIV_24_MHZ 0x02
+
+#define CPUIMX51SD_GPIO_3_12 IOMUX_PAD(0x57C, 0x194, 3, 0x0, 0, \
+ MX51_PAD_CTRL_1 | PAD_CTL_PUS_22K_UP)
+
+static struct pad_desc eukrea_cpuimx51sd_pads[] = {
+ /* UART1 */
+ MX51_PAD_UART1_RXD__UART1_RXD,
+ MX51_PAD_UART1_TXD__UART1_TXD,
+ MX51_PAD_UART1_RTS__UART1_RTS,
+ MX51_PAD_UART1_CTS__UART1_CTS,
+
+ /* USB HOST1 */
+ MX51_PAD_USBH1_CLK__USBH1_CLK,
+ MX51_PAD_USBH1_DIR__USBH1_DIR,
+ MX51_PAD_USBH1_NXT__USBH1_NXT,
+ MX51_PAD_USBH1_DATA0__USBH1_DATA0,
+ MX51_PAD_USBH1_DATA1__USBH1_DATA1,
+ MX51_PAD_USBH1_DATA2__USBH1_DATA2,
+ MX51_PAD_USBH1_DATA3__USBH1_DATA3,
+ MX51_PAD_USBH1_DATA4__USBH1_DATA4,
+ MX51_PAD_USBH1_DATA5__USBH1_DATA5,
+ MX51_PAD_USBH1_DATA6__USBH1_DATA6,
+ MX51_PAD_USBH1_DATA7__USBH1_DATA7,
+ MX51_PAD_USBH1_STP__USBH1_STP,
+ MX51_PAD_EIM_CS3__GPIO_2_28, /* PHY nRESET */
+
+ /* FEC */
+ MX51_PAD_EIM_DTACK__GPIO_2_31, /* PHY nRESET */
+
+ /* HSI2C */
+ MX51_PAD_I2C1_CLK__GPIO_4_16,
+ MX51_PAD_I2C1_DAT__GPIO_4_17,
+
+ /* CAN */
+ MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI,
+ MX51_PAD_CSPI1_MISO__ECSPI1_MISO,
+ MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK,
+ MX51_PAD_CSPI1_SS0__GPIO_4_24, /* nCS */
+ MX51_PAD_CSI2_PIXCLK__GPIO_4_15, /* nReset */
+ MX51_PAD_GPIO_1_1__GPIO_1_1, /* IRQ */
+ MX51_PAD_GPIO_1_4__GPIO_1_4, /* Control signals */
+ MX51_PAD_GPIO_1_6__GPIO_1_6,
+ MX51_PAD_GPIO_1_7__GPIO_1_7,
+ MX51_PAD_GPIO_1_8__GPIO_1_8,
+ MX51_PAD_GPIO_1_9__GPIO_1_9,
+
+ /* Touchscreen */
+ CPUIMX51SD_GPIO_3_12, /* IRQ */
+};
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static int ts_get_pendown_state(void)
+{
+ return gpio_get_value(TSC2007_IRQGPIO) ? 0 : 1;
+}
+
+static struct tsc2007_platform_data tsc2007_info = {
+ .model = 2007,
+ .x_plate_ohms = 180,
+ .get_pendown_state = ts_get_pendown_state,
+};
+
+static struct i2c_board_info eukrea_cpuimx51sd_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("pcf8563", 0x51),
+ }, {
+ I2C_BOARD_INFO("tsc2007", 0x49),
+ .type = "tsc2007",
+ .platform_data = &tsc2007_info,
+ .irq = gpio_to_irq(TSC2007_IRQGPIO),
+ },
+};
+
+static const struct mxc_nand_platform_data
+ eukrea_cpuimx51sd_nand_board_info __initconst = {
+ .width = 1,
+ .hw_ecc = 1,
+ .flash_bbt = 1,
+};
+
+/* This function is board specific as the bit mask for the plldiv will also
+be different for other Freescale SoCs, thus a common bitmask is not
+possible and cannot get place in /plat-mxc/ehci.c.*/
+static int initialize_otg_port(struct platform_device *pdev)
+{
+ u32 v;
+ void __iomem *usb_base;
+ void __iomem *usbother_base;
+
+ usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
+ usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
+
+ /* Set the PHY clock to 19.2MHz */
+ v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC2_OFFSET);
+ v &= ~MX5_USB_UTMI_PHYCTRL1_PLLDIV_MASK;
+ v |= MX51_USB_PLL_DIV_19_2_MHZ;
+ __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC2_OFFSET);
+ iounmap(usb_base);
+ return 0;
+}
+
+static int initialize_usbh1_port(struct platform_device *pdev)
+{
+ u32 v;
+ void __iomem *usb_base;
+ void __iomem *usbother_base;
+
+ usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
+ usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
+
+ /* The clock for the USBH1 ULPI port will come from the PHY. */
+ v = __raw_readl(usbother_base + MX51_USB_CTRL_1_OFFSET);
+ __raw_writel(v | MX51_USB_CTRL_UH1_EXT_CLK_EN,
+ usbother_base + MX51_USB_CTRL_1_OFFSET);
+ iounmap(usb_base);
+ return 0;
+}
+
+static struct mxc_usbh_platform_data dr_utmi_config = {
+ .init = initialize_otg_port,
+ .portsc = MXC_EHCI_UTMI_16BIT,
+ .flags = MXC_EHCI_INTERNAL_PHY,
+};
+
+static struct fsl_usb2_platform_data usb_pdata = {
+ .operating_mode = FSL_USB2_DR_DEVICE,
+ .phy_mode = FSL_USB2_PHY_UTMI_WIDE,
+};
+
+static struct mxc_usbh_platform_data usbh1_config = {
+ .init = initialize_usbh1_port,
+ .portsc = MXC_EHCI_MODE_ULPI,
+ .flags = (MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_ITC_NO_THRESHOLD),
+};
+
+static int otg_mode_host;
+
+static int __init eukrea_cpuimx51sd_otg_mode(char *options)
+{
+ if (!strcmp(options, "host"))
+ otg_mode_host = 1;
+ else if (!strcmp(options, "device"))
+ otg_mode_host = 0;
+ else
+ pr_info("otg_mode neither \"host\" nor \"device\". "
+ "Defaulting to device\n");
+ return 0;
+}
+__setup("otg_mode=", eukrea_cpuimx51sd_otg_mode);
+
+static struct i2c_gpio_platform_data pdata = {
+ .sda_pin = I2C_SDA,
+ .sda_is_open_drain = 0,
+ .scl_pin = I2C_SCL,
+ .scl_is_open_drain = 0,
+ .udelay = 2,
+};
+
+static struct platform_device hsi2c_gpio_device = {
+ .name = "i2c-gpio",
+ .id = 0,
+ .dev.platform_data = &pdata,
+};
+
+static struct mcp251x_platform_data mcp251x_info = {
+ .oscillator_frequency = 24E6,
+};
+
+static struct spi_board_info cpuimx51sd_spi_device[] = {
+ {
+ .modalias = "mcp2515",
+ .max_speed_hz = 6500000,
+ .bus_num = 0,
+ .mode = SPI_MODE_0,
+ .chip_select = 0,
+ .platform_data = &mcp251x_info,
+ .irq = gpio_to_irq(0 * 32 + 1)
+ },
+};
+
+static int cpuimx51sd_spi1_cs[] = {
+ CAN_NCS,
+};
+
+static const struct spi_imx_master cpuimx51sd_ecspi1_pdata __initconst = {
+ .chipselect = cpuimx51sd_spi1_cs,
+ .num_chipselect = ARRAY_SIZE(cpuimx51sd_spi1_cs),
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+ &hsi2c_gpio_device,
+};
+
+static void __init eukrea_cpuimx51sd_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx51sd_pads,
+ ARRAY_SIZE(eukrea_cpuimx51sd_pads));
+
+ imx51_add_imx_uart(0, &uart_pdata);
+ imx51_add_mxc_nand(&eukrea_cpuimx51sd_nand_board_info);
+
+ gpio_request(ETH_RST, "eth_rst");
+ gpio_set_value(ETH_RST, 1);
+ imx51_add_fec(NULL);
+
+ gpio_request(CAN_IRQGPIO, "can_irq");
+ gpio_direction_input(CAN_IRQGPIO);
+ gpio_free(CAN_IRQGPIO);
+ gpio_request(CAN_NCS, "can_ncs");
+ gpio_direction_output(CAN_NCS, 1);
+ gpio_free(CAN_NCS);
+ gpio_request(CAN_RST, "can_rst");
+ gpio_direction_output(CAN_RST, 0);
+ msleep(20);
+ gpio_set_value(CAN_RST, 1);
+ imx51_add_ecspi(0, &cpuimx51sd_ecspi1_pdata);
+ spi_register_board_info(cpuimx51sd_spi_device,
+ ARRAY_SIZE(cpuimx51sd_spi_device));
+
+ gpio_request(TSC2007_IRQGPIO, "tsc2007_irq");
+ gpio_direction_input(TSC2007_IRQGPIO);
+ gpio_free(TSC2007_IRQGPIO);
+
+ i2c_register_board_info(0, eukrea_cpuimx51sd_i2c_devices,
+ ARRAY_SIZE(eukrea_cpuimx51sd_i2c_devices));
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+
+ if (otg_mode_host)
+ mxc_register_device(&mxc_usbdr_host_device, &dr_utmi_config);
+ else {
+ initialize_otg_port(NULL);
+ mxc_register_device(&mxc_usbdr_udc_device, &usb_pdata);
+ }
+
+ gpio_request(USBH1_RST, "usb_rst");
+ gpio_direction_output(USBH1_RST, 0);
+ msleep(20);
+ gpio_set_value(USBH1_RST, 1);
+ mxc_register_device(&mxc_usbh1_device, &usbh1_config);
+
+#ifdef CONFIG_MACH_EUKREA_MBIMXSD51_BASEBOARD
+ eukrea_mbimxsd51_baseboard_init();
+#endif
+}
+
+static void __init eukrea_cpuimx51sd_timer_init(void)
+{
+ mx51_clocks_init(32768, 24000000, 22579200, 0);
+}
+
+static struct sys_timer mxc_timer = {
+ .init = eukrea_cpuimx51sd_timer_init,
+};
+
+MACHINE_START(EUKREA_CPUIMX51SD, "Eukrea CPUIMX51SD")
+ /* Maintainer: Eric Bénard <eric@eukrea.com> */
+ .boot_params = PHYS_OFFSET + 0x100,
+ .map_io = mx51_map_io,
+ .init_irq = mx51_init_irq,
+ .init_machine = eukrea_cpuimx51sd_init,
+ .timer = &mxc_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx5/board-mx51_3ds.c b/arch/arm/mach-mx5/board-mx51_3ds.c
index f95c2fd94667..79ce8dcf3cda 100644
--- a/arch/arm/mach-mx5/board-mx51_3ds.c
+++ b/arch/arm/mach-mx5/board-mx51_3ds.c
@@ -13,6 +13,7 @@
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/input/matrix_keypad.h>
+#include <linux/spi/spi.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -21,12 +22,13 @@
#include <mach/hardware.h>
#include <mach/common.h>
#include <mach/iomux-mx51.h>
-#include <mach/imx-uart.h>
#include <mach/3ds_debugboard.h>
+#include "devices-imx51.h"
#include "devices.h"
#define EXPIO_PARENT_INT (MXC_INTERNAL_IRQS + GPIO_PORTA + 6)
+#define MX51_3DS_ECSPI2_CS (GPIO_PORTC + 28)
static struct pad_desc mx51_3ds_pads[] = {
/* UART1 */
@@ -61,19 +63,25 @@ static struct pad_desc mx51_3ds_pads[] = {
MX51_PAD_KEY_COL3__KEY_COL3,
MX51_PAD_KEY_COL4__KEY_COL4,
MX51_PAD_KEY_COL5__KEY_COL5,
+
+ /* eCSPI2 */
+ MX51_PAD_NANDF_RB2__ECSPI2_SCLK,
+ MX51_PAD_NANDF_RB3__ECSPI2_MISO,
+ MX51_PAD_NANDF_D15__ECSPI2_MOSI,
+ MX51_PAD_NANDF_D12__GPIO_3_28,
};
/* Serial ports */
#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
-static struct imxuart_platform_data uart_pdata = {
+static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
static inline void mxc_init_imx_uart(void)
{
- mxc_register_device(&mxc_uart_device0, &uart_pdata);
- mxc_register_device(&mxc_uart_device1, &uart_pdata);
- mxc_register_device(&mxc_uart_device2, &uart_pdata);
+ imx51_add_imx_uart(0, &uart_pdata);
+ imx51_add_imx_uart(1, &uart_pdata);
+ imx51_add_imx_uart(2, &uart_pdata);
}
#else /* !SERIAL_IMX */
static inline void mxc_init_imx_uart(void)
@@ -127,6 +135,26 @@ static inline void mxc_init_keypad(void)
}
#endif
+static int mx51_3ds_spi2_cs[] = {
+ MXC_SPI_CS(0),
+ MX51_3DS_ECSPI2_CS,
+};
+
+static const struct spi_imx_master mx51_3ds_ecspi2_pdata __initconst = {
+ .chipselect = mx51_3ds_spi2_cs,
+ .num_chipselect = ARRAY_SIZE(mx51_3ds_spi2_cs),
+};
+
+static struct spi_board_info mx51_3ds_spi_nor_device[] = {
+ {
+ .modalias = "m25p80",
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 1,
+ .mode = SPI_MODE_0,
+ .platform_data = NULL,},
+};
+
/*
* Board specific initialization.
*/
@@ -136,6 +164,10 @@ static void __init mxc_board_init(void)
ARRAY_SIZE(mx51_3ds_pads));
mxc_init_imx_uart();
+ imx51_add_ecspi(1, &mx51_3ds_ecspi2_pdata);
+ spi_register_board_info(mx51_3ds_spi_nor_device,
+ ARRAY_SIZE(mx51_3ds_spi_nor_device));
+
if (mxc_expio_init(MX51_CS5_BASE_ADDR, EXPIO_PARENT_INT))
printk(KERN_WARNING "Init of the debugboard failed, all "
"devices on the board are unusable.\n");
@@ -154,8 +186,6 @@ static struct sys_timer mxc_timer = {
MACHINE_START(MX51_3DS, "Freescale MX51 3-Stack Board")
/* Maintainer: Freescale Semiconductor, Inc. */
- .phys_io = MX51_AIPS1_BASE_ADDR,
- .io_pg_offst = ((MX51_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x100,
.map_io = mx51_map_io,
.init_irq = mx51_init_irq,
diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c
index 6e384d92e625..0821fe9b3b27 100644
--- a/arch/arm/mach-mx5/board-mx51_babbage.c
+++ b/arch/arm/mach-mx5/board-mx51_babbage.c
@@ -17,12 +17,11 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/fsl_devices.h>
+#include <linux/fec.h>
#include <mach/common.h>
#include <mach/hardware.h>
-#include <mach/imx-uart.h>
#include <mach/iomux-mx51.h>
-#include <mach/i2c.h>
#include <mach/mxc_ehci.h>
#include <asm/irq.h>
@@ -31,11 +30,13 @@
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
+#include "devices-imx51.h"
#include "devices.h"
#define BABBAGE_USB_HUB_RESET (0*32 + 7) /* GPIO_1_7 */
#define BABBAGE_USBH1_STP (0*32 + 27) /* GPIO_1_27 */
-#define BABBAGE_PHY_RESET (1*32 +5) /* GPIO_2_5 */
+#define BABBAGE_PHY_RESET (1*32 + 5) /* GPIO_2_5 */
+#define BABBAGE_FEC_PHY_RESET (1*32 + 14) /* GPIO_2_14 */
/* USB_CTRL_1 */
#define MX51_USB_CTRL_1_OFFSET 0x10
@@ -45,10 +46,6 @@
#define MX51_USB_PLL_DIV_19_2_MHZ 0x01
#define MX51_USB_PLL_DIV_24_MHZ 0x02
-static struct platform_device *devices[] __initdata = {
- &mxc_fec_device,
-};
-
static struct pad_desc mx51babbage_pads[] = {
/* UART1 */
MX51_PAD_UART1_RXD__UART1_RXD,
@@ -93,19 +90,41 @@ static struct pad_desc mx51babbage_pads[] = {
/* USB HUB reset line*/
MX51_PAD_GPIO_1_7__GPIO_1_7,
+
+ /* FEC */
+ MX51_PAD_EIM_EB2__FEC_MDIO,
+ MX51_PAD_EIM_EB3__FEC_RDAT1,
+ MX51_PAD_EIM_CS2__FEC_RDAT2,
+ MX51_PAD_EIM_CS3__FEC_RDAT3,
+ MX51_PAD_EIM_CS4__FEC_RX_ER,
+ MX51_PAD_EIM_CS5__FEC_CRS,
+ MX51_PAD_NANDF_RB2__FEC_COL,
+ MX51_PAD_NANDF_RB3__FEC_RXCLK,
+ MX51_PAD_NANDF_RB6__FEC_RDAT0,
+ MX51_PAD_NANDF_RB7__FEC_TDAT0,
+ MX51_PAD_NANDF_CS2__FEC_TX_ER,
+ MX51_PAD_NANDF_CS3__FEC_MDC,
+ MX51_PAD_NANDF_CS4__FEC_TDAT1,
+ MX51_PAD_NANDF_CS5__FEC_TDAT2,
+ MX51_PAD_NANDF_CS6__FEC_TDAT3,
+ MX51_PAD_NANDF_CS7__FEC_TX_EN,
+ MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK,
+
+ /* FEC PHY reset line */
+ MX51_PAD_EIM_A20__GPIO_2_14,
};
/* Serial ports */
#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
-static struct imxuart_platform_data uart_pdata = {
+static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
static inline void mxc_init_imx_uart(void)
{
- mxc_register_device(&mxc_uart_device0, &uart_pdata);
- mxc_register_device(&mxc_uart_device1, &uart_pdata);
- mxc_register_device(&mxc_uart_device2, &uart_pdata);
+ imx51_add_imx_uart(0, &uart_pdata);
+ imx51_add_imx_uart(1, &uart_pdata);
+ imx51_add_imx_uart(2, &uart_pdata);
}
#else /* !SERIAL_IMX */
static inline void mxc_init_imx_uart(void)
@@ -113,7 +132,7 @@ static inline void mxc_init_imx_uart(void)
}
#endif /* SERIAL_IMX */
-static struct imxi2c_platform_data babbage_i2c_data = {
+static const struct imxi2c_platform_data babbage_i2c_data __initconst = {
.bitrate = 100000,
};
@@ -171,6 +190,22 @@ static inline void babbage_usbhub_reset(void)
gpio_set_value(BABBAGE_USB_HUB_RESET, 1);
}
+static inline void babbage_fec_reset(void)
+{
+ int ret;
+
+ /* reset FEC PHY */
+ ret = gpio_request(BABBAGE_FEC_PHY_RESET, "fec-phy-reset");
+ if (ret) {
+ printk(KERN_ERR"failed to get GPIO_FEC_PHY_RESET: %d\n", ret);
+ return;
+ }
+ gpio_direction_output(BABBAGE_FEC_PHY_RESET, 0);
+ gpio_set_value(BABBAGE_FEC_PHY_RESET, 0);
+ msleep(1);
+ gpio_set_value(BABBAGE_FEC_PHY_RESET, 1);
+}
+
/* This function is board specific as the bit mask for the plldiv will also
be different for other Freescale SoCs, thus a common bitmask is not
possible and cannot get place in /plat-mxc/ehci.c.*/
@@ -178,7 +213,7 @@ static int initialize_otg_port(struct platform_device *pdev)
{
u32 v;
void __iomem *usb_base;
- u32 usbother_base;
+ void __iomem *usbother_base;
usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
@@ -196,7 +231,7 @@ static int initialize_usbh1_port(struct platform_device *pdev)
{
u32 v;
void __iomem *usb_base;
- u32 usbother_base;
+ void __iomem *usbother_base;
usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
@@ -250,10 +285,11 @@ static void __init mxc_board_init(void)
mxc_iomux_v3_setup_multiple_pads(mx51babbage_pads,
ARRAY_SIZE(mx51babbage_pads));
mxc_init_imx_uart();
- platform_add_devices(devices, ARRAY_SIZE(devices));
+ babbage_fec_reset();
+ imx51_add_fec(NULL);
- mxc_register_device(&mxc_i2c_device0, &babbage_i2c_data);
- mxc_register_device(&mxc_i2c_device1, &babbage_i2c_data);
+ imx51_add_imx_i2c(0, &babbage_i2c_data);
+ imx51_add_imx_i2c(1, &babbage_i2c_data);
mxc_register_device(&mxc_hsi2c_device, &babbage_hsi2c_data);
if (otg_mode_host)
@@ -281,9 +317,7 @@ static struct sys_timer mxc_timer = {
MACHINE_START(MX51_BABBAGE, "Freescale MX51 Babbage Board")
/* Maintainer: Amit Kucheria <amit.kucheria@canonical.com> */
- .phys_io = MX51_AIPS1_BASE_ADDR,
- .io_pg_offst = ((MX51_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
- .boot_params = PHYS_OFFSET + 0x100,
+ .boot_params = MX51_PHYS_OFFSET + 0x100,
.map_io = mx51_map_io,
.init_irq = mx51_init_irq,
.init_machine = mxc_board_init,
diff --git a/arch/arm/mach-mx5/board-mx51_efikamx.c b/arch/arm/mach-mx5/board-mx51_efikamx.c
new file mode 100644
index 000000000000..6e623bda3ee7
--- /dev/null
+++ b/arch/arm/mach-mx5/board-mx51_efikamx.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2010 Linaro Limited
+ *
+ * based on code from the following
+ * Copyright 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2009-2010 Pegatron Corporation. All Rights Reserved.
+ * Copyright 2009-2010 Genesi USA, Inc. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/fsl_devices.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux-mx51.h>
+#include <mach/i2c.h>
+#include <mach/mxc_ehci.h>
+
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "devices-imx51.h"
+#include "devices.h"
+
+#define MX51_USB_PLL_DIV_24_MHZ 0x01
+
+static struct pad_desc mx51efikamx_pads[] = {
+ /* UART1 */
+ MX51_PAD_UART1_RXD__UART1_RXD,
+ MX51_PAD_UART1_TXD__UART1_TXD,
+ MX51_PAD_UART1_RTS__UART1_RTS,
+ MX51_PAD_UART1_CTS__UART1_CTS,
+};
+
+/* Serial ports */
+#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
+static const struct imxuart_platform_data uart_pdata = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static inline void mxc_init_imx_uart(void)
+{
+ imx51_add_imx_uart(0, &uart_pdata);
+ imx51_add_imx_uart(1, &uart_pdata);
+ imx51_add_imx_uart(2, &uart_pdata);
+}
+#else /* !SERIAL_IMX */
+static inline void mxc_init_imx_uart(void)
+{
+}
+#endif /* SERIAL_IMX */
+
+/* This function is board specific as the bit mask for the plldiv will also
+ * be different for other Freescale SoCs, thus a common bitmask is not
+ * possible and cannot get place in /plat-mxc/ehci.c.
+ */
+static int initialize_otg_port(struct platform_device *pdev)
+{
+ u32 v;
+ void __iomem *usb_base;
+ void __iomem *usbother_base;
+ usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
+ usbother_base = (void __iomem *)(usb_base + MX5_USBOTHER_REGS_OFFSET);
+
+ /* Set the PHY clock to 19.2MHz */
+ v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC2_OFFSET);
+ v &= ~MX5_USB_UTMI_PHYCTRL1_PLLDIV_MASK;
+ v |= MX51_USB_PLL_DIV_24_MHZ;
+ __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC2_OFFSET);
+ iounmap(usb_base);
+ return 0;
+}
+
+static struct mxc_usbh_platform_data dr_utmi_config = {
+ .init = initialize_otg_port,
+ .portsc = MXC_EHCI_UTMI_16BIT,
+ .flags = MXC_EHCI_INTERNAL_PHY,
+};
+
+static void __init mxc_board_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx51efikamx_pads,
+ ARRAY_SIZE(mx51efikamx_pads));
+ mxc_register_device(&mxc_usbdr_host_device, &dr_utmi_config);
+ mxc_init_imx_uart();
+}
+
+static void __init mx51_efikamx_timer_init(void)
+{
+ mx51_clocks_init(32768, 24000000, 22579200, 24576000);
+}
+
+static struct sys_timer mxc_timer = {
+ .init = mx51_efikamx_timer_init,
+};
+
+MACHINE_START(MX51_EFIKAMX, "Genesi EfikaMX nettop")
+ /* Maintainer: Amit Kucheria <amit.kucheria@linaro.org> */
+ .boot_params = MX51_PHYS_OFFSET + 0x100,
+ .map_io = mx51_map_io,
+ .init_irq = mx51_init_irq,
+ .init_machine = mxc_board_init,
+ .timer = &mxc_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51.c
index 57c10a9926cc..f2aae92cf0e2 100644
--- a/arch/arm/mach-mx5/clock-mx51.c
+++ b/arch/arm/mach-mx5/clock-mx51.c
@@ -41,34 +41,66 @@ static struct clk usboh3_clk;
#define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */
-static int _clk_ccgr_enable(struct clk *clk)
+/* calculate best pre and post dividers to get the required divider */
+static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post,
+ u32 max_pre, u32 max_post)
{
- u32 reg;
+ if (div >= max_pre * max_post) {
+ *pre = max_pre;
+ *post = max_post;
+ } else if (div >= max_pre) {
+ u32 min_pre, temp_pre, old_err, err;
+ min_pre = DIV_ROUND_UP(div, max_post);
+ old_err = max_pre;
+ for (temp_pre = max_pre; temp_pre >= min_pre; temp_pre--) {
+ err = div % temp_pre;
+ if (err == 0) {
+ *pre = temp_pre;
+ break;
+ }
+ err = temp_pre - err;
+ if (err < old_err) {
+ old_err = err;
+ *pre = temp_pre;
+ }
+ }
+ *post = DIV_ROUND_UP(div, *pre);
+ } else {
+ *pre = div;
+ *post = 1;
+ }
+}
+
+static void _clk_ccgr_setclk(struct clk *clk, unsigned mode)
+{
+ u32 reg = __raw_readl(clk->enable_reg);
+
+ reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
+ reg |= mode << clk->enable_shift;
- reg = __raw_readl(clk->enable_reg);
- reg |= MXC_CCM_CCGRx_MOD_ON << clk->enable_shift;
__raw_writel(reg, clk->enable_reg);
+}
+static int _clk_ccgr_enable(struct clk *clk)
+{
+ _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_ON);
return 0;
}
static void _clk_ccgr_disable(struct clk *clk)
{
- u32 reg;
- reg = __raw_readl(clk->enable_reg);
- reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
- __raw_writel(reg, clk->enable_reg);
+ _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_OFF);
+}
+static int _clk_ccgr_enable_inrun(struct clk *clk)
+{
+ _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_IDLE);
+ return 0;
}
static void _clk_ccgr_disable_inwait(struct clk *clk)
{
- u32 reg;
-
- reg = __raw_readl(clk->enable_reg);
- reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
- reg |= MXC_CCM_CCGRx_MOD_IDLE << clk->enable_shift;
- __raw_writel(reg, clk->enable_reg);
+ _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_IDLE);
}
/*
@@ -542,60 +574,60 @@ static int _clk_ipg_per_set_parent(struct clk *clk, struct clk *parent)
return 0;
}
-static unsigned long clk_uart_get_rate(struct clk *clk)
-{
- u32 reg, prediv, podf;
- unsigned long parent_rate;
+#define clk_nfc_set_parent NULL
- parent_rate = clk_get_rate(clk->parent);
-
- reg = __raw_readl(MXC_CCM_CSCDR1);
- prediv = ((reg & MXC_CCM_CSCDR1_UART_CLK_PRED_MASK) >>
- MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET) + 1;
- podf = ((reg & MXC_CCM_CSCDR1_UART_CLK_PODF_MASK) >>
- MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET) + 1;
+static unsigned long clk_nfc_get_rate(struct clk *clk)
+{
+ unsigned long rate;
+ u32 reg, div;
- return parent_rate / (prediv * podf);
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_NFC_PODF_MASK) >>
+ MXC_CCM_CBCDR_NFC_PODF_OFFSET) + 1;
+ rate = clk_get_rate(clk->parent) / div;
+ WARN_ON(rate == 0);
+ return rate;
}
-static int _clk_uart_set_parent(struct clk *clk, struct clk *parent)
+static unsigned long clk_nfc_round_rate(struct clk *clk,
+ unsigned long rate)
{
- u32 reg, mux;
+ u32 div;
+ unsigned long parent_rate = clk_get_rate(clk->parent);
- mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
- &lp_apm_clk);
- reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_UART_CLK_SEL_MASK;
- reg |= mux << MXC_CCM_CSCMR1_UART_CLK_SEL_OFFSET;
- __raw_writel(reg, MXC_CCM_CSCMR1);
+ if (!rate)
+ return -EINVAL;
- return 0;
-}
+ div = parent_rate / rate;
-static unsigned long clk_usboh3_get_rate(struct clk *clk)
-{
- u32 reg, prediv, podf;
- unsigned long parent_rate;
+ if (parent_rate % rate)
+ div++;
- parent_rate = clk_get_rate(clk->parent);
+ if (div > 8)
+ return -EINVAL;
- reg = __raw_readl(MXC_CCM_CSCDR1);
- prediv = ((reg & MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK) >>
- MXC_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET) + 1;
- podf = ((reg & MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK) >>
- MXC_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET) + 1;
+ return parent_rate / div;
- return parent_rate / (prediv * podf);
}
-static int _clk_usboh3_set_parent(struct clk *clk, struct clk *parent)
+static int clk_nfc_set_rate(struct clk *clk, unsigned long rate)
{
- u32 reg, mux;
+ u32 reg, div;
+
+ div = clk_get_rate(clk->parent) / rate;
+ if (div == 0)
+ div++;
+ if (((clk_get_rate(clk->parent) / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_NFC_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCDR_NFC_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCDR);
- mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
- &lp_apm_clk);
- reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_USBOH3_CLK_SEL_MASK;
- reg |= mux << MXC_CCM_CSCMR1_USBOH3_CLK_SEL_OFFSET;
- __raw_writel(reg, MXC_CCM_CSCMR1);
+ while (__raw_readl(MXC_CCM_CDHIPR) &
+ MXC_CCM_CDHIPR_NFC_IPG_INT_MEM_PODF_BUSY){
+ }
return 0;
}
@@ -620,6 +652,17 @@ static unsigned long get_ckih2_reference_clock_rate(struct clk *clk)
return ckih2_reference;
}
+static unsigned long clk_emi_slow_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_EMI_PODF_MASK) >>
+ MXC_CCM_CBCDR_EMI_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
/* External high frequency clock */
static struct clk ckih_clk = {
.get_rate = get_high_reference_clock_rate,
@@ -715,18 +758,6 @@ static struct clk ipg_perclk = {
.set_parent = _clk_ipg_per_set_parent,
};
-static struct clk uart_root_clk = {
- .parent = &pll2_sw_clk,
- .get_rate = clk_uart_get_rate,
- .set_parent = _clk_uart_set_parent,
-};
-
-static struct clk usboh3_clk = {
- .parent = &pll2_sw_clk,
- .get_rate = clk_usboh3_get_rate,
- .set_parent = _clk_usboh3_set_parent,
-};
-
static struct clk ahb_max_clk = {
.parent = &ahb_clk,
.enable_reg = MXC_CCM_CCGR0,
@@ -762,45 +793,183 @@ static struct clk kpp_clk = {
.id = 0,
};
-#define DEFINE_CLOCK(name, i, er, es, gr, sr, p, s) \
+static struct clk emi_slow_clk = {
+ .parent = &pll2_sw_clk,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
+ .enable = _clk_ccgr_enable,
+ .disable = _clk_ccgr_disable_inwait,
+ .get_rate = clk_emi_slow_get_rate,
+};
+
+#define DEFINE_CLOCK_CCGR(name, i, er, es, pfx, p, s) \
static struct clk name = { \
.id = i, \
.enable_reg = er, \
.enable_shift = es, \
- .get_rate = gr, \
- .set_rate = sr, \
+ .get_rate = pfx##_get_rate, \
+ .set_rate = pfx##_set_rate, \
+ .round_rate = pfx##_round_rate, \
+ .set_parent = pfx##_set_parent, \
.enable = _clk_ccgr_enable, \
.disable = _clk_ccgr_disable, \
.parent = p, \
.secondary = s, \
}
-/* DEFINE_CLOCK(name, id, enable_reg, enable_shift,
- get_rate, set_rate, parent, secondary); */
+#define DEFINE_CLOCK_MAX(name, i, er, es, pfx, p, s) \
+ static struct clk name = { \
+ .id = i, \
+ .enable_reg = er, \
+ .enable_shift = es, \
+ .get_rate = pfx##_get_rate, \
+ .set_rate = pfx##_set_rate, \
+ .set_parent = pfx##_set_parent, \
+ .enable = _clk_max_enable, \
+ .disable = _clk_max_disable, \
+ .parent = p, \
+ .secondary = s, \
+ }
+
+#define CLK_GET_RATE(name, nr, bitsname) \
+static unsigned long clk_##name##_get_rate(struct clk *clk) \
+{ \
+ u32 reg, pred, podf; \
+ \
+ reg = __raw_readl(MXC_CCM_CSCDR##nr); \
+ pred = (reg & MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK) \
+ >> MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET; \
+ podf = (reg & MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK) \
+ >> MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET; \
+ \
+ return DIV_ROUND_CLOSEST(clk_get_rate(clk->parent), \
+ (pred + 1) * (podf + 1)); \
+}
+
+#define CLK_SET_PARENT(name, nr, bitsname) \
+static int clk_##name##_set_parent(struct clk *clk, struct clk *parent) \
+{ \
+ u32 reg, mux; \
+ \
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, \
+ &pll3_sw_clk, &lp_apm_clk); \
+ reg = __raw_readl(MXC_CCM_CSCMR##nr) & \
+ ~MXC_CCM_CSCMR##nr##_##bitsname##_CLK_SEL_MASK; \
+ reg |= mux << MXC_CCM_CSCMR##nr##_##bitsname##_CLK_SEL_OFFSET; \
+ __raw_writel(reg, MXC_CCM_CSCMR##nr); \
+ \
+ return 0; \
+}
+
+#define CLK_SET_RATE(name, nr, bitsname) \
+static int clk_##name##_set_rate(struct clk *clk, unsigned long rate) \
+{ \
+ u32 reg, div, parent_rate; \
+ u32 pre = 0, post = 0; \
+ \
+ parent_rate = clk_get_rate(clk->parent); \
+ div = parent_rate / rate; \
+ \
+ if ((parent_rate / div) != rate) \
+ return -EINVAL; \
+ \
+ __calc_pre_post_dividers(div, &pre, &post, \
+ (MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK >> \
+ MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET) + 1, \
+ (MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK >> \
+ MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET) + 1);\
+ \
+ /* Set sdhc1 clock divider */ \
+ reg = __raw_readl(MXC_CCM_CSCDR##nr) & \
+ ~(MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK \
+ | MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK); \
+ reg |= (post - 1) << \
+ MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET; \
+ reg |= (pre - 1) << \
+ MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET; \
+ __raw_writel(reg, MXC_CCM_CSCDR##nr); \
+ \
+ return 0; \
+}
+
+/* UART */
+CLK_GET_RATE(uart, 1, UART)
+CLK_SET_PARENT(uart, 1, UART)
+
+static struct clk uart_root_clk = {
+ .parent = &pll2_sw_clk,
+ .get_rate = clk_uart_get_rate,
+ .set_parent = clk_uart_set_parent,
+};
+
+/* USBOH3 */
+CLK_GET_RATE(usboh3, 1, USBOH3)
+CLK_SET_PARENT(usboh3, 1, USBOH3)
+
+static struct clk usboh3_clk = {
+ .parent = &pll2_sw_clk,
+ .get_rate = clk_usboh3_get_rate,
+ .set_parent = clk_usboh3_set_parent,
+};
+
+/* eCSPI */
+CLK_GET_RATE(ecspi, 2, CSPI)
+CLK_SET_PARENT(ecspi, 1, CSPI)
+
+static struct clk ecspi_main_clk = {
+ .parent = &pll3_sw_clk,
+ .get_rate = clk_ecspi_get_rate,
+ .set_parent = clk_ecspi_set_parent,
+};
+
+/* eSDHC */
+CLK_GET_RATE(esdhc1, 1, ESDHC1_MSHC1)
+CLK_SET_PARENT(esdhc1, 1, ESDHC1_MSHC1)
+CLK_SET_RATE(esdhc1, 1, ESDHC1_MSHC1)
+
+CLK_GET_RATE(esdhc2, 1, ESDHC2_MSHC2)
+CLK_SET_PARENT(esdhc2, 1, ESDHC2_MSHC2)
+CLK_SET_RATE(esdhc2, 1, ESDHC2_MSHC2)
+
+#define DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, e, d, p, s) \
+ static struct clk name = { \
+ .id = i, \
+ .enable_reg = er, \
+ .enable_shift = es, \
+ .get_rate = gr, \
+ .set_rate = sr, \
+ .enable = e, \
+ .disable = d, \
+ .parent = p, \
+ .secondary = s, \
+ }
+
+#define DEFINE_CLOCK(name, i, er, es, gr, sr, p, s) \
+ DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, _clk_ccgr_enable, _clk_ccgr_disable, p, s)
/* Shared peripheral bus arbiter */
DEFINE_CLOCK(spba_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG0_OFFSET,
NULL, NULL, &ipg_clk, NULL);
/* UART */
-DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG4_OFFSET,
- NULL, NULL, &uart_root_clk, NULL);
-DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG6_OFFSET,
- NULL, NULL, &uart_root_clk, NULL);
-DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG8_OFFSET,
- NULL, NULL, &uart_root_clk, NULL);
DEFINE_CLOCK(uart1_ipg_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG3_OFFSET,
NULL, NULL, &ipg_clk, &aips_tz1_clk);
DEFINE_CLOCK(uart2_ipg_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG5_OFFSET,
NULL, NULL, &ipg_clk, &aips_tz1_clk);
DEFINE_CLOCK(uart3_ipg_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG7_OFFSET,
NULL, NULL, &ipg_clk, &spba_clk);
+DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG4_OFFSET,
+ NULL, NULL, &uart_root_clk, &uart1_ipg_clk);
+DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG6_OFFSET,
+ NULL, NULL, &uart_root_clk, &uart2_ipg_clk);
+DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG8_OFFSET,
+ NULL, NULL, &uart_root_clk, &uart3_ipg_clk);
/* GPT */
-DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET,
- NULL, NULL, &ipg_clk, NULL);
DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET,
NULL, NULL, &ipg_clk, NULL);
+DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET,
+ NULL, NULL, &ipg_clk, &gpt_ipg_clk);
/* I2C */
DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG9_OFFSET,
@@ -814,6 +983,52 @@ DEFINE_CLOCK(hsi2c_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG11_OFFSET,
DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET,
NULL, NULL, &ipg_clk, NULL);
+/* NFC */
+DEFINE_CLOCK_CCGR(nfc_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG10_OFFSET,
+ clk_nfc, &emi_slow_clk, NULL);
+
+/* SSI */
+DEFINE_CLOCK(ssi1_ipg_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG8_OFFSET,
+ NULL, NULL, &ipg_clk, NULL);
+DEFINE_CLOCK(ssi1_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG9_OFFSET,
+ NULL, NULL, &pll3_sw_clk, &ssi1_ipg_clk);
+DEFINE_CLOCK(ssi2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG10_OFFSET,
+ NULL, NULL, &ipg_clk, NULL);
+DEFINE_CLOCK(ssi2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG11_OFFSET,
+ NULL, NULL, &pll3_sw_clk, &ssi2_ipg_clk);
+
+/* eCSPI */
+DEFINE_CLOCK_FULL(ecspi1_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG9_OFFSET,
+ NULL, NULL, _clk_ccgr_enable_inrun, _clk_ccgr_disable,
+ &ipg_clk, &spba_clk);
+DEFINE_CLOCK(ecspi1_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG10_OFFSET,
+ NULL, NULL, &ecspi_main_clk, &ecspi1_ipg_clk);
+DEFINE_CLOCK_FULL(ecspi2_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG11_OFFSET,
+ NULL, NULL, _clk_ccgr_enable_inrun, _clk_ccgr_disable,
+ &ipg_clk, &aips_tz2_clk);
+DEFINE_CLOCK(ecspi2_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG12_OFFSET,
+ NULL, NULL, &ecspi_main_clk, &ecspi2_ipg_clk);
+
+/* CSPI */
+DEFINE_CLOCK(cspi_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG9_OFFSET,
+ NULL, NULL, &ipg_clk, &aips_tz2_clk);
+DEFINE_CLOCK(cspi_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG13_OFFSET,
+ NULL, NULL, &ipg_clk, &cspi_ipg_clk);
+
+/* SDMA */
+DEFINE_CLOCK(sdma_clk, 1, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG15_OFFSET,
+ NULL, NULL, &ahb_clk, NULL);
+
+/* eSDHC */
+DEFINE_CLOCK_FULL(esdhc1_ipg_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG0_OFFSET,
+ NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
+DEFINE_CLOCK_MAX(esdhc1_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG1_OFFSET,
+ clk_esdhc1, &pll2_sw_clk, &esdhc1_ipg_clk);
+DEFINE_CLOCK_FULL(esdhc2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG2_OFFSET,
+ NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
+DEFINE_CLOCK_MAX(esdhc2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG3_OFFSET,
+ clk_esdhc2, &pll2_sw_clk, &esdhc2_ipg_clk);
+
#define _REGISTER_CLOCK(d, n, c) \
{ \
.dev_id = d, \
@@ -837,6 +1052,18 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("fsl-usb2-udc", "usb", usboh3_clk)
_REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", ahb_clk)
_REGISTER_CLOCK("imx-keypad.0", NULL, kpp_clk)
+ _REGISTER_CLOCK("mxc_nand", NULL, nfc_clk)
+ _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
+ _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
+ _REGISTER_CLOCK("imx-sdma", NULL, sdma_clk)
+ _REGISTER_CLOCK(NULL, "ckih", ckih_clk)
+ _REGISTER_CLOCK(NULL, "ckih2", ckih2_clk)
+ _REGISTER_CLOCK(NULL, "gpt_32k", gpt_32k_clk)
+ _REGISTER_CLOCK("imx51-ecspi.0", NULL, ecspi1_clk)
+ _REGISTER_CLOCK("imx51-ecspi.1", NULL, ecspi2_clk)
+ _REGISTER_CLOCK("imx51-cspi.0", NULL, cspi_clk)
+ _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk)
+ _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk)
};
static void clk_tree_init(void)
@@ -880,6 +1107,14 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
/* set the usboh3_clk parent to pll2_sw_clk */
clk_set_parent(&usboh3_clk, &pll2_sw_clk);
+ /* Set SDHC parents to be PLL2 */
+ clk_set_parent(&esdhc1_clk, &pll2_sw_clk);
+ clk_set_parent(&esdhc2_clk, &pll2_sw_clk);
+
+ /* set SDHC root clock as 166.25MHZ*/
+ clk_set_rate(&esdhc1_clk, 166250000);
+ clk_set_rate(&esdhc2_clk, 166250000);
+
/* System timer */
mxc_timer_init(&gpt_clk, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR),
MX51_MXC_INT_GPT);
diff --git a/arch/arm/mach-mx5/cpu.c b/arch/arm/mach-mx5/cpu.c
index 2d37785e3857..eaacb6e9b5d0 100644
--- a/arch/arm/mach-mx5/cpu.c
+++ b/arch/arm/mach-mx5/cpu.c
@@ -70,6 +70,25 @@ int mx51_revision(void)
}
EXPORT_SYMBOL(mx51_revision);
+#ifdef CONFIG_NEON
+
+/*
+ * All versions of the silicon before Rev. 3 have broken NEON implementations.
+ * Dependent on link order - so the assumption is that vfp_init is called
+ * before us.
+ */
+static int __init mx51_neon_fixup(void)
+{
+ if (mx51_revision() < MX51_CHIP_REV_3_0 && (elf_hwcap & HWCAP_NEON)) {
+ elf_hwcap &= ~HWCAP_NEON;
+ pr_info("Turning off NEON support, detected broken NEON implementation\n");
+ }
+ return 0;
+}
+
+late_initcall(mx51_neon_fixup);
+#endif
+
static int __init post_cpu_init(void)
{
unsigned int reg;
diff --git a/arch/arm/mach-mx5/devices-imx51.h b/arch/arm/mach-mx5/devices-imx51.h
new file mode 100644
index 000000000000..5cc910e60538
--- /dev/null
+++ b/arch/arm/mach-mx5/devices-imx51.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/mx51.h>
+#include <mach/devices-common.h>
+
+extern const struct imx_fec_data imx51_fec_data __initconst;
+#define imx51_add_fec(pdata) \
+ imx_add_fec(&imx51_fec_data, pdata)
+
+extern const struct imx_imx_i2c_data imx51_imx_i2c_data[] __initconst;
+#define imx51_add_imx_i2c(id, pdata) \
+ imx_add_imx_i2c(&imx51_imx_i2c_data[id], pdata)
+
+extern const struct imx_imx_ssi_data imx51_imx_ssi_data[] __initconst;
+#define imx51_add_imx_ssi(id, pdata) \
+ imx_add_imx_ssi(&imx51_imx_ssi_data[id], pdata)
+
+extern const struct imx_imx_uart_1irq_data imx51_imx_uart_data[] __initconst;
+#define imx51_add_imx_uart(id, pdata) \
+ imx_add_imx_uart_1irq(&imx51_imx_uart_data[id], pdata)
+
+extern const struct imx_mxc_nand_data imx51_mxc_nand_data __initconst;
+#define imx51_add_mxc_nand(pdata) \
+ imx_add_mxc_nand(&imx51_mxc_nand_data, pdata)
+
+extern const struct imx_spi_imx_data imx51_cspi_data __initconst;
+#define imx51_add_cspi(pdata) \
+ imx_add_spi_imx(&imx51_cspi_data, pdata)
+
+extern const struct imx_spi_imx_data imx51_ecspi_data[] __initconst;
+#define imx51_add_ecspi(id, pdata) \
+ imx_add_spi_imx(&imx51_ecspi_data[id], pdata)
+
+extern const struct imx_esdhc_imx_data imx51_esdhc_data[] __initconst;
+#define imx51_add_esdhc(id, pdata) \
+ imx_add_esdhc(&imx51_esdhc_data[id], pdata)
diff --git a/arch/arm/mach-mx5/devices.c b/arch/arm/mach-mx5/devices.c
index 1920ff4963b2..4c7be87a7c9d 100644
--- a/arch/arm/mach-mx5/devices.c
+++ b/arch/arm/mach-mx5/devices.c
@@ -17,120 +17,6 @@
#include <mach/imx-uart.h>
#include <mach/irqs.h>
-static struct resource uart0[] = {
- {
- .start = MX51_UART1_BASE_ADDR,
- .end = MX51_UART1_BASE_ADDR + 0xfff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX51_MXC_INT_UART1,
- .end = MX51_MXC_INT_UART1,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_uart_device0 = {
- .name = "imx-uart",
- .id = 0,
- .resource = uart0,
- .num_resources = ARRAY_SIZE(uart0),
-};
-
-static struct resource uart1[] = {
- {
- .start = MX51_UART2_BASE_ADDR,
- .end = MX51_UART2_BASE_ADDR + 0xfff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX51_MXC_INT_UART2,
- .end = MX51_MXC_INT_UART2,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_uart_device1 = {
- .name = "imx-uart",
- .id = 1,
- .resource = uart1,
- .num_resources = ARRAY_SIZE(uart1),
-};
-
-static struct resource uart2[] = {
- {
- .start = MX51_UART3_BASE_ADDR,
- .end = MX51_UART3_BASE_ADDR + 0xfff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX51_MXC_INT_UART3,
- .end = MX51_MXC_INT_UART3,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_uart_device2 = {
- .name = "imx-uart",
- .id = 2,
- .resource = uart2,
- .num_resources = ARRAY_SIZE(uart2),
-};
-
-static struct resource mxc_fec_resources[] = {
- {
- .start = MX51_MXC_FEC_BASE_ADDR,
- .end = MX51_MXC_FEC_BASE_ADDR + 0xfff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX51_MXC_INT_FEC,
- .end = MX51_MXC_INT_FEC,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_fec_device = {
- .name = "fec",
- .id = 0,
- .num_resources = ARRAY_SIZE(mxc_fec_resources),
- .resource = mxc_fec_resources,
-};
-
-static struct resource mxc_i2c0_resources[] = {
- {
- .start = MX51_I2C1_BASE_ADDR,
- .end = MX51_I2C1_BASE_ADDR + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX51_MXC_INT_I2C1,
- .end = MX51_MXC_INT_I2C1,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_i2c_device0 = {
- .name = "imx-i2c",
- .id = 0,
- .num_resources = ARRAY_SIZE(mxc_i2c0_resources),
- .resource = mxc_i2c0_resources,
-};
-
-static struct resource mxc_i2c1_resources[] = {
- {
- .start = MX51_I2C2_BASE_ADDR,
- .end = MX51_I2C2_BASE_ADDR + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX51_MXC_INT_I2C2,
- .end = MX51_MXC_INT_I2C2,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_i2c_device1 = {
- .name = "imx-i2c",
- .id = 1,
- .num_resources = ARRAY_SIZE(mxc_i2c1_resources),
- .resource = mxc_i2c1_resources,
-};
-
static struct resource mxc_hsi2c_resources[] = {
{
.start = MX51_HSI2C_DMA_BASE_ADDR,
diff --git a/arch/arm/mach-mx5/devices.h b/arch/arm/mach-mx5/devices.h
index e509cfaad1d4..af1d07c0bbc1 100644
--- a/arch/arm/mach-mx5/devices.h
+++ b/arch/arm/mach-mx5/devices.h
@@ -1,12 +1,6 @@
-extern struct platform_device mxc_uart_device0;
-extern struct platform_device mxc_uart_device1;
-extern struct platform_device mxc_uart_device2;
-extern struct platform_device mxc_fec_device;
extern struct platform_device mxc_usbdr_host_device;
extern struct platform_device mxc_usbh1_device;
extern struct platform_device mxc_usbdr_udc_device;
extern struct platform_device mxc_wdt;
-extern struct platform_device mxc_i2c_device0;
-extern struct platform_device mxc_i2c_device1;
extern struct platform_device mxc_hsi2c_device;
extern struct platform_device mxc_keypad_device;
diff --git a/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c b/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c
index ffa93d1d6ef8..a2e6e8c39d25 100644
--- a/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c
+++ b/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c
@@ -30,6 +30,7 @@
#include <asm/mach/arch.h>
+#include "devices-imx51.h"
#include "devices.h"
#define MBIMX51_TSC2007_GPIO (2*32 + 30)
@@ -112,9 +113,25 @@ static struct pad_desc mbimx51_pads[] = {
MX51_PAD_KEY_COL1__KEY_COL1,
MX51_PAD_KEY_COL2__KEY_COL2,
MX51_PAD_KEY_COL3__KEY_COL3,
+
+ /* SD 1 */
+ MX51_PAD_SD1_CMD__SD1_CMD,
+ MX51_PAD_SD1_CLK__SD1_CLK,
+ MX51_PAD_SD1_DATA0__SD1_DATA0,
+ MX51_PAD_SD1_DATA1__SD1_DATA1,
+ MX51_PAD_SD1_DATA2__SD1_DATA2,
+ MX51_PAD_SD1_DATA3__SD1_DATA3,
+
+ /* SD 2 */
+ MX51_PAD_SD2_CMD__SD2_CMD,
+ MX51_PAD_SD2_CLK__SD2_CLK,
+ MX51_PAD_SD2_DATA0__SD2_DATA0,
+ MX51_PAD_SD2_DATA1__SD2_DATA1,
+ MX51_PAD_SD2_DATA2__SD2_DATA2,
+ MX51_PAD_SD2_DATA3__SD2_DATA3,
};
-static struct imxuart_platform_data uart_pdata = {
+static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
@@ -158,9 +175,11 @@ struct tsc2007_platform_data tsc2007_data = {
static struct i2c_board_info mbimx51_i2c_devices[] = {
{
- I2C_BOARD_INFO("tsc2007", 0x48),
+ I2C_BOARD_INFO("tsc2007", 0x49),
.irq = MBIMX51_TSC2007_IRQ,
.platform_data = &tsc2007_data,
+ }, {
+ I2C_BOARD_INFO("tlv320aic23", 0x1a),
},
};
@@ -172,8 +191,8 @@ void __init eukrea_mbimx51_baseboard_init(void)
mxc_iomux_v3_setup_multiple_pads(mbimx51_pads,
ARRAY_SIZE(mbimx51_pads));
- mxc_register_device(&mxc_uart_device1, NULL);
- mxc_register_device(&mxc_uart_device2, &uart_pdata);
+ imx51_add_imx_uart(1, NULL);
+ imx51_add_imx_uart(2, &uart_pdata);
gpio_request(MBIMX51_LED0, "LED0");
gpio_direction_output(MBIMX51_LED0, 1);
@@ -197,4 +216,7 @@ void __init eukrea_mbimx51_baseboard_init(void)
set_irq_type(MBIMX51_TSC2007_IRQ, IRQF_TRIGGER_FALLING);
i2c_register_board_info(1, mbimx51_i2c_devices,
ARRAY_SIZE(mbimx51_i2c_devices));
+
+ imx51_add_esdhc(0, NULL);
+ imx51_add_esdhc(1, NULL);
}
diff --git a/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c
new file mode 100644
index 000000000000..2b48f5190830
--- /dev/null
+++ b/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2010 Eric Benard - eric@eukrea.com
+ *
+ * Based on pcm970-baseboard.c which is :
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx51.h>
+#include <mach/audmux.h>
+
+#include "devices-imx51.h"
+#include "devices.h"
+
+#define MBIMXSD_GPIO_3_31 IOMUX_PAD(0x554, 0x16C, 3, 0x0, 0, \
+ MX51_PAD_CTRL_1 | PAD_CTL_PUS_22K_UP)
+
+static struct pad_desc eukrea_mbimxsd_pads[] = {
+ /* LED */
+ MX51_PAD_NANDF_D10__GPIO_3_30,
+ /* SWITCH */
+ MBIMXSD_GPIO_3_31,
+ /* UART2 */
+ MX51_PAD_UART2_RXD__UART2_RXD,
+ MX51_PAD_UART2_TXD__UART2_TXD,
+ /* UART 3 */
+ MX51_PAD_UART3_RXD__UART3_RXD,
+ MX51_PAD_UART3_TXD__UART3_TXD,
+ MX51_PAD_KEY_COL4__UART3_RTS,
+ MX51_PAD_KEY_COL5__UART3_CTS,
+ /* SD */
+ MX51_PAD_SD1_CMD__SD1_CMD,
+ MX51_PAD_SD1_CLK__SD1_CLK,
+ MX51_PAD_SD1_DATA0__SD1_DATA0,
+ MX51_PAD_SD1_DATA1__SD1_DATA1,
+ MX51_PAD_SD1_DATA2__SD1_DATA2,
+ MX51_PAD_SD1_DATA3__SD1_DATA3,
+};
+
+#define GPIO_LED1 (2 * 32 + 30)
+#define GPIO_SWITCH1 (2 * 32 + 31)
+
+static struct gpio_led eukrea_mbimxsd_leds[] = {
+ {
+ .name = "led1",
+ .default_trigger = "heartbeat",
+ .active_low = 1,
+ .gpio = GPIO_LED1,
+ },
+};
+
+static struct gpio_led_platform_data eukrea_mbimxsd_led_info = {
+ .leds = eukrea_mbimxsd_leds,
+ .num_leds = ARRAY_SIZE(eukrea_mbimxsd_leds),
+};
+
+static struct platform_device eukrea_mbimxsd_leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &eukrea_mbimxsd_led_info,
+ },
+};
+
+static struct gpio_keys_button eukrea_mbimxsd_gpio_buttons[] = {
+ {
+ .gpio = GPIO_SWITCH1,
+ .code = BTN_0,
+ .desc = "BP1",
+ .active_low = 1,
+ .wakeup = 1,
+ },
+};
+
+static struct gpio_keys_platform_data eukrea_mbimxsd_button_data = {
+ .buttons = eukrea_mbimxsd_gpio_buttons,
+ .nbuttons = ARRAY_SIZE(eukrea_mbimxsd_gpio_buttons),
+};
+
+static struct platform_device eukrea_mbimxsd_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &eukrea_mbimxsd_button_data,
+ }
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+ &eukrea_mbimxsd_leds_gpio,
+ &eukrea_mbimxsd_button_device,
+};
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct i2c_board_info eukrea_mbimxsd_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("tlv320aic23", 0x1a),
+ },
+};
+
+/*
+ * system init for baseboard usage. Will be called by cpuimx51sd init.
+ *
+ * Add platform devices present on this baseboard and init
+ * them from CPU side as far as required to use them later on
+ */
+void __init eukrea_mbimxsd51_baseboard_init(void)
+{
+ if (mxc_iomux_v3_setup_multiple_pads(eukrea_mbimxsd_pads,
+ ARRAY_SIZE(eukrea_mbimxsd_pads)))
+ printk(KERN_ERR "error setting mbimxsd pads !\n");
+
+ imx51_add_imx_uart(1, NULL);
+ imx51_add_imx_uart(2, &uart_pdata);
+
+ imx51_add_esdhc(0, NULL);
+
+ gpio_request(GPIO_LED1, "LED1");
+ gpio_direction_output(GPIO_LED1, 1);
+ gpio_free(GPIO_LED1);
+
+ gpio_request(GPIO_SWITCH1, "SWITCH1");
+ gpio_direction_input(GPIO_SWITCH1);
+ gpio_free(GPIO_SWITCH1);
+
+ i2c_register_board_info(0, eukrea_mbimxsd_i2c_devices,
+ ARRAY_SIZE(eukrea_mbimxsd_i2c_devices));
+
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+}
diff --git a/arch/arm/mach-mxc91231/magx-zn5.c b/arch/arm/mach-mxc91231/magx-zn5.c
index 69816ba82930..395d83be8c98 100644
--- a/arch/arm/mach-mxc91231/magx-zn5.c
+++ b/arch/arm/mach-mxc91231/magx-zn5.c
@@ -53,8 +53,6 @@ struct sys_timer zn5_timer = {
};
MACHINE_START(MAGX_ZN5, "Motorola Zn5")
- .phys_io = MXC91231_AIPS1_BASE_ADDR,
- .io_pg_offst = ((MXC91231_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
.boot_params = MXC91231_PHYS_OFFSET + 0x100,
.map_io = mxc91231_map_io,
.init_irq = mxc91231_init_irq,
diff --git a/arch/arm/mach-netx/include/mach/debug-macro.S b/arch/arm/mach-netx/include/mach/debug-macro.S
index e96339e71d88..56a915228180 100644
--- a/arch/arm/mach-netx/include/mach/debug-macro.S
+++ b/arch/arm/mach-netx/include/mach/debug-macro.S
@@ -13,12 +13,10 @@
#include "hardware.h"
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- moveq \rx, #0x00100000 @ physical
- movne \rx, #io_p2v(0x00100000) @ virtual
- orr \rx, \rx, #0x00000a00
+ .macro addruart, rp, rv
+ mov \rp, #0x00000a00
+ orr \rv, \rp, #io_p2v(0x00100000) @ virtual
+ orr \rp, \rp, #0x00100000 @ physical
.endm
.macro senduart,rd,rx
diff --git a/arch/arm/mach-netx/include/mach/vmalloc.h b/arch/arm/mach-netx/include/mach/vmalloc.h
index 25d5cc676e0f..7cca3574308f 100644
--- a/arch/arm/mach-netx/include/mach/vmalloc.h
+++ b/arch/arm/mach-netx/include/mach/vmalloc.h
@@ -16,4 +16,4 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#define VMALLOC_END (PAGE_OFFSET + 0x10000000)
+#define VMALLOC_END 0xd0000000
diff --git a/arch/arm/mach-netx/nxdb500.c b/arch/arm/mach-netx/nxdb500.c
index c9b174bc8ccf..ca8b203a3c99 100644
--- a/arch/arm/mach-netx/nxdb500.c
+++ b/arch/arm/mach-netx/nxdb500.c
@@ -200,8 +200,6 @@ static void __init nxdb500_init(void)
}
MACHINE_START(NXDB500, "Hilscher nxdb500")
- .phys_io = 0x00100000,
- .io_pg_offst = (io_p2v(0x00100000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = netx_map_io,
.init_irq = netx_init_irq,
diff --git a/arch/arm/mach-netx/nxdkn.c b/arch/arm/mach-netx/nxdkn.c
index 15b54c62d60f..d775cbe07278 100644
--- a/arch/arm/mach-netx/nxdkn.c
+++ b/arch/arm/mach-netx/nxdkn.c
@@ -93,8 +93,6 @@ static void __init nxdkn_init(void)
}
MACHINE_START(NXDKN, "Hilscher nxdkn")
- .phys_io = 0x00100000,
- .io_pg_offst = (io_p2v(0x00100000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = netx_map_io,
.init_irq = netx_init_irq,
diff --git a/arch/arm/mach-netx/nxeb500hmi.c b/arch/arm/mach-netx/nxeb500hmi.c
index 1061c01ff679..de369cd1dcbe 100644
--- a/arch/arm/mach-netx/nxeb500hmi.c
+++ b/arch/arm/mach-netx/nxeb500hmi.c
@@ -177,8 +177,6 @@ static void __init nxeb500hmi_init(void)
}
MACHINE_START(NXEB500HMI, "Hilscher nxeb500hmi")
- .phys_io = 0x00100000,
- .io_pg_offst = (io_p2v(0x00100000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = netx_map_io,
.init_irq = netx_init_irq,
diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c
index 841d459ad59d..139930350d93 100644
--- a/arch/arm/mach-nomadik/board-nhk8815.c
+++ b/arch/arm/mach-nomadik/board-nhk8815.c
@@ -276,8 +276,6 @@ static void __init nhk8815_platform_init(void)
MACHINE_START(NOMADIK, "NHK8815")
/* Maintainer: ST MicroElectronics */
- .phys_io = NOMADIK_UART0_BASE,
- .io_pg_offst = (IO_ADDRESS(NOMADIK_UART0_BASE) >> 18) & 0xfffc,
.boot_params = 0x100,
.map_io = cpu8815_map_io,
.init_irq = cpu8815_init_irq,
diff --git a/arch/arm/mach-nomadik/include/mach/debug-macro.S b/arch/arm/mach-nomadik/include/mach/debug-macro.S
index 4f92acfba954..e7151b4b8889 100644
--- a/arch/arm/mach-nomadik/include/mach/debug-macro.S
+++ b/arch/arm/mach-nomadik/include/mach/debug-macro.S
@@ -10,13 +10,11 @@
*
*/
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- moveq \rx, #0x10000000 @ physical base address
- movne \rx, #0xf0000000 @ virtual base
- add \rx, \rx, #0x00100000
- add \rx, \rx, #0x000fb000
+ .macro addruart, rp, rv
+ mov \rp, #0x00100000
+ add \rp, \rp, #0x000fb000
+ add \rv, \rp, #0xf0000000 @ virtual base
+ add \rp, \rp, #0x10000000 @ physical base address
.endm
#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-ns9xxx/include/mach/debug-macro.S b/arch/arm/mach-ns9xxx/include/mach/debug-macro.S
index 5c934bdb7158..5a2acbdc3d67 100644
--- a/arch/arm/mach-ns9xxx/include/mach/debug-macro.S
+++ b/arch/arm/mach-ns9xxx/include/mach/debug-macro.S
@@ -12,11 +12,9 @@
#include <mach/regs-board-a9m9750dev.h>
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1
- ldreq \rx, =NS9XXX_CSxSTAT_PHYS(0)
- ldrne \rx, =io_p2v(NS9XXX_CSxSTAT_PHYS(0))
+ .macro addruart, rp, rv
+ ldr \rp, =NS9XXX_CSxSTAT_PHYS(0)
+ ldr \rv, =io_p2v(NS9XXX_CSxSTAT_PHYS(0))
.endm
#define UART_SHIFT 2
diff --git a/arch/arm/mach-nuc93x/mach-nuc932evb.c b/arch/arm/mach-nuc93x/mach-nuc932evb.c
index 9f79266f08e2..d70257042480 100644
--- a/arch/arm/mach-nuc93x/mach-nuc932evb.c
+++ b/arch/arm/mach-nuc93x/mach-nuc932evb.c
@@ -35,8 +35,6 @@ static void __init nuc932evb_init(void)
MACHINE_START(NUC932EVB, "NUC932EVB")
/* Maintainer: Wan ZongShun */
- .phys_io = NUC93X_PA_UART,
- .io_pg_offst = (((u32)NUC93X_VA_UART) >> 18) & 0xfffc,
.boot_params = 0,
.map_io = nuc932evb_map_io,
.init_irq = nuc93x_init_irq,
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
index 3b02d3b944af..5f6496375404 100644
--- a/arch/arm/mach-omap1/Kconfig
+++ b/arch/arm/mach-omap1/Kconfig
@@ -128,7 +128,7 @@ config MACH_OMAP_PALMTT
help
Support for the Palm Tungsten|T PDA. To boot the kernel, you'll
need a PalmOS compatible bootloader (Garux); check out
- http://www.hackndev.com/palm/tt/ for more information.
+ http://garux.sourceforge.net/ for more information.
Say Y here if you have this PDA model, say N otherwise.
config MACH_SX1
diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
index 41992ab71961..73c86392fcd3 100644
--- a/arch/arm/mach-omap1/board-ams-delta.c
+++ b/arch/arm/mach-omap1/board-ams-delta.c
@@ -297,8 +297,6 @@ static void __init ams_delta_map_io(void)
MACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)")
/* Maintainer: Jonathan McDowell <noodles@earth.li> */
- .phys_io = 0xfff00000,
- .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = ams_delta_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c
index 180ce79e5eac..149fdd32e127 100644
--- a/arch/arm/mach-omap1/board-fsample.c
+++ b/arch/arm/mach-omap1/board-fsample.c
@@ -386,8 +386,6 @@ static void __init omap_fsample_map_io(void)
MACHINE_START(OMAP_FSAMPLE, "OMAP730 F-Sample")
/* Maintainer: Brian Swetland <swetland@google.com> */
- .phys_io = 0xfff00000,
- .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = omap_fsample_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c
index 93b9ab8fc3be..23f4ab9e2651 100644
--- a/arch/arm/mach-omap1/board-generic.c
+++ b/arch/arm/mach-omap1/board-generic.c
@@ -94,8 +94,6 @@ static void __init omap_generic_map_io(void)
MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710")
/* Maintainer: Tony Lindgren <tony@atomide.com> */
- .phys_io = 0xfff00000,
- .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = omap_generic_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index d2cda58bcc48..197adb49dc5a 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -458,8 +458,6 @@ static void __init h2_map_io(void)
MACHINE_START(OMAP_H2, "TI-H2")
/* Maintainer: Imre Deak <imre.deak@nokia.com> */
- .phys_io = 0xfff00000,
- .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = h2_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index c2ef4ff846c7..9126e3e37b4a 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -446,8 +446,6 @@ static void __init h3_map_io(void)
MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board")
/* Maintainer: Texas Instruments, Inc. */
- .phys_io = 0xfff00000,
- .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = h3_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap1/board-htcherald.c b/arch/arm/mach-omap1/board-htcherald.c
index 311899ff5ffc..86afb2952225 100644
--- a/arch/arm/mach-omap1/board-htcherald.c
+++ b/arch/arm/mach-omap1/board-htcherald.c
@@ -300,8 +300,6 @@ static void __init htcherald_init_irq(void)
MACHINE_START(HERALD, "HTC Herald")
/* Maintainer: Cory Maccarrone <darkstar6262@gmail.com> */
/* Maintainer: wing-linux.sourceforge.net */
- .phys_io = 0xfff00000,
- .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = htcherald_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index 3daf87ad2576..dc2b86fd66c1 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -459,8 +459,6 @@ static void __init innovator_map_io(void)
MACHINE_START(OMAP_INNOVATOR, "TI-Innovator")
/* Maintainer: MontaVista Software, Inc. */
- .phys_io = 0xfff00000,
- .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = innovator_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
index 51a4539aecf5..aa8375b2a0a3 100644
--- a/arch/arm/mach-omap1/board-nokia770.c
+++ b/arch/arm/mach-omap1/board-nokia770.c
@@ -262,8 +262,6 @@ static void __init omap_nokia770_map_io(void)
}
MACHINE_START(NOKIA770, "Nokia 770")
- .phys_io = 0xfff00000,
- .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = omap_nokia770_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index 679740cc1e90..e9dd79149a8e 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -580,8 +580,6 @@ static void __init osk_map_io(void)
MACHINE_START(OMAP_OSK, "TI-OSK")
/* Maintainer: Dirk Behme <dirk.behme@de.bosch.com> */
- .phys_io = 0xfff00000,
- .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = osk_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
index 782bb257a85d..f32738b1eb6b 100644
--- a/arch/arm/mach-omap1/board-palmte.c
+++ b/arch/arm/mach-omap1/board-palmte.c
@@ -285,8 +285,6 @@ static void __init omap_palmte_map_io(void)
}
MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E")
- .phys_io = 0xfff00000,
- .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = omap_palmte_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap1/board-palmtt.c b/arch/arm/mach-omap1/board-palmtt.c
index 0b35ef54a64f..ed1400a67f75 100644
--- a/arch/arm/mach-omap1/board-palmtt.c
+++ b/arch/arm/mach-omap1/board-palmtt.c
@@ -317,8 +317,6 @@ static void __init omap_palmtt_map_io(void)
}
MACHINE_START(OMAP_PALMTT, "OMAP1510 based Palm Tungsten|T")
- .phys_io = 0xfff00000,
- .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = omap_palmtt_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c
index 66362903b6e2..d7a245cef9a4 100644
--- a/arch/arm/mach-omap1/board-palmz71.c
+++ b/arch/arm/mach-omap1/board-palmz71.c
@@ -338,8 +338,6 @@ omap_palmz71_map_io(void)
}
MACHINE_START(OMAP_PALMZ71, "OMAP310 based Palm Zire71")
- .phys_io = 0xfff00000,
- .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = omap_palmz71_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
index 34ab354758b0..a8d16a255c18 100644
--- a/arch/arm/mach-omap1/board-perseus2.c
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -347,8 +347,6 @@ static void __init omap_perseus2_map_io(void)
MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")
/* Maintainer: Kevin Hilman <kjh@hilman.org> */
- .phys_io = 0xfff00000,
- .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = omap_perseus2_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c
index 2eb148b8de93..d25f59e5a773 100644
--- a/arch/arm/mach-omap1/board-sx1.c
+++ b/arch/arm/mach-omap1/board-sx1.c
@@ -419,8 +419,6 @@ static void __init omap_sx1_map_io(void)
}
MACHINE_START(SX1, "OMAP310 based Siemens SX1")
- .phys_io = 0xfff00000,
- .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = omap_sx1_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index 6b3cf14bc757..f5992c239bcd 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -283,8 +283,6 @@ EXPORT_SYMBOL(voiceblue_wdt_ping);
MACHINE_START(VOICEBLUE, "VoiceBlue OMAP5910")
/* Maintainer: Ladislav Michl <michl@2n.cz> */
- .phys_io = 0xfff00000,
- .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = voiceblue_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap1/include/mach/debug-macro.S b/arch/arm/mach-omap1/include/mach/debug-macro.S
index 671408eb4ab4..6a0fa0462365 100644
--- a/arch/arm/mach-omap1/include/mach/debug-macro.S
+++ b/arch/arm/mach-omap1/include/mach/debug-macro.S
@@ -28,56 +28,58 @@ omap_uart_virt: .word 0x0
* the desired UART phys and virt addresses temporarily into
* the omap_uart_phys and omap_uart_virt above.
*/
- .macro addruart, rx, tmp
+ .macro addruart, rp, rv
/* Use omap_uart_phys/virt if already configured */
-9: mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- ldreq \rx, =__virt_to_phys(omap_uart_phys) @ physical base address
- ldrne \rx, =omap_uart_virt @ virtual base
- ldr \rx, [\rx, #0]
- cmp \rx, #0 @ is port configured?
+9: mrc p15, 0, \rp, c1, c0
+ tst \rp, #1 @ MMU enabled?
+ ldreq \rp, =__virt_to_phys(omap_uart_phys) @ MMU not enabled
+ ldrne \rp, =omap_uart_phys @ MMU enabled
+ add \rv, \rp, #4 @ omap_uart_virt
+ ldr \rp, [\rp, #0]
+ ldr \rv, [\rv, #0]
+ cmp \rp, #0 @ is port configured?
+ cmpne \rv, #0
bne 99f @ already configured
/* Check the debug UART configuration set in uncompress.h */
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- ldreq \rx, =OMAP_UART_INFO
- ldrne \rx, =__phys_to_virt(OMAP_UART_INFO)
- ldr \rx, [\rx, #0]
+ mrc p15, 0, \rp, c1, c0
+ tst \rp, #1 @ MMU enabled?
+ ldreq \rp, =OMAP_UART_INFO @ MMU not enabled
+ ldrne \rp, =__phys_to_virt(OMAP_UART_INFO) @ MMU enabled
+ ldr \rp, [\rp, #0]
/* Select the UART to use based on the UART1 scratchpad value */
-10: cmp \rx, #0 @ no port configured?
+10: cmp \rp, #0 @ no port configured?
beq 11f @ if none, try to use UART1
- cmp \rx, #OMAP1UART1
+ cmp \rp, #OMAP1UART1
beq 11f @ configure OMAP1UART1
- cmp \rx, #OMAP1UART2
+ cmp \rp, #OMAP1UART2
beq 12f @ configure OMAP1UART2
- cmp \rx, #OMAP1UART3
+ cmp \rp, #OMAP1UART3
beq 13f @ configure OMAP2UART3
/* Configure the UART offset from the phys/virt base */
-11: mov \rx, #0x00fb0000 @ OMAP1UART1
+11: mov \rp, #0x00fb0000 @ OMAP1UART1
b 98f
-12: mov \rx, #0x00fb0000 @ OMAP1UART1
- orr \rx, \rx, #0x00000800 @ OMAP1UART2
+12: mov \rp, #0x00fb0000 @ OMAP1UART1
+ orr \rp, \rp, #0x00000800 @ OMAP1UART2
b 98f
-13: mov \rx, #0x00fb0000 @ OMAP1UART1
- orr \rx, \rx, #0x00000800 @ OMAP1UART2
- orr \rx, \rx, #0x00009000 @ OMAP1UART3
+13: mov \rp, #0x00fb0000 @ OMAP1UART1
+ orr \rp, \rp, #0x00000800 @ OMAP1UART2
+ orr \rp, \rp, #0x00009000 @ OMAP1UART3
/* Store both phys and virt address for the uart */
-98: add \rx, \rx, #0xff000000 @ phys base
- mrc p15, 0, \tmp, c1, c0
- tst \tmp, #1 @ MMU enabled?
- ldreq \tmp, =__virt_to_phys(omap_uart_phys)
- ldrne \tmp, =omap_uart_phys
- str \rx, [\tmp, #0]
- sub \rx, \rx, #0xff000000 @ phys base
- add \rx, \rx, #0xfe000000 @ virt base
- ldreq \tmp, =__virt_to_phys(omap_uart_virt)
- ldrne \tmp, =omap_uart_virt
- str \rx, [\tmp, #0]
+98: add \rp, \rp, #0xff000000 @ phys base
+ mrc p15, 0, \rv, c1, c0
+ tst \rv, #1 @ MMU enabled?
+ ldreq \rv, =__virt_to_phys(omap_uart_phys) @ MMU not enabled
+ ldrne \rv, =omap_uart_phys @ MMU enabled
+ str \rp, [\rv, #0]
+ sub \rp, \rp, #0xff000000 @ phys base
+ add \rp, \rp, #0xfe000000 @ virt base
+ add \rv, \rv, #4 @ omap_uart_lsr
+ str \rp, [\rv, #0]
b 9b
99:
.endm
diff --git a/arch/arm/mach-omap1/include/mach/vmalloc.h b/arch/arm/mach-omap1/include/mach/vmalloc.h
index 1b2af14df151..b001f67d695b 100644
--- a/arch/arm/mach-omap1/include/mach/vmalloc.h
+++ b/arch/arm/mach-omap1/include/mach/vmalloc.h
@@ -17,4 +17,4 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#define VMALLOC_END (PAGE_OFFSET + 0x18000000)
+#define VMALLOC_END 0xd8000000
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index 8538e4131d27..b857ce484510 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -253,8 +253,6 @@ static void __init omap_2430sdp_map_io(void)
MACHINE_START(OMAP_2430SDP, "OMAP2430 sdp2430 board")
/* Maintainer: Syed Khasim - Texas Instruments Inc */
- .phys_io = 0x48000000,
- .io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = omap_2430sdp_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index 67b95b5f1a2f..a5b095cf2adc 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -817,8 +817,6 @@ static void __init omap_3430sdp_init(void)
MACHINE_START(OMAP_3430SDP, "OMAP3430 3430SDP board")
/* Maintainer: Syed Khasim - Texas Instruments Inc */
- .phys_io = 0x48000000,
- .io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = omap3_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c
index b359c3f7bb39..fd27ac0860b0 100644
--- a/arch/arm/mach-omap2/board-3630sdp.c
+++ b/arch/arm/mach-omap2/board-3630sdp.c
@@ -217,8 +217,6 @@ static void __init omap_sdp_init(void)
}
MACHINE_START(OMAP_3630SDP, "OMAP 3630SDP board")
- .phys_io = 0x48000000,
- .io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = omap3_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 9447644774c2..0b6a65f3a10a 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -458,8 +458,6 @@ static void __init omap_4430sdp_map_io(void)
MACHINE_START(OMAP_4430SDP, "OMAP4430 4430SDP board")
/* Maintainer: Santosh Shilimkar - Texas Instruments Inc */
- .phys_io = 0x48000000,
- .io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = omap_4430sdp_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
index 4d0f58592864..d547036aff3f 100644
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -375,6 +375,31 @@ static void __init am3517_evm_init_irq(void)
omap_gpio_init();
}
+static struct omap_musb_board_data musb_board_data = {
+ .interface_type = MUSB_INTERFACE_ULPI,
+ .mode = MUSB_OTG,
+ .power = 500,
+};
+
+static __init void am3517_evm_musb_init(void)
+{
+ u32 devconf2;
+
+ /*
+ * Set up USB clock/mode in the DEVCONF2 register.
+ */
+ devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
+
+ /* USB2.0 PHY reference clock is 13 MHz */
+ devconf2 &= ~(CONF2_REFFREQ | CONF2_OTGMODE | CONF2_PHY_GPIOMODE);
+ devconf2 |= CONF2_REFFREQ_13MHZ | CONF2_SESENDEN | CONF2_VBDTCTEN
+ | CONF2_DATPOL;
+
+ omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
+
+ usb_musb_init(&musb_board_data);
+}
+
static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
.port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
#if defined(CONFIG_PANEL_SHARP_LQ043T1DG01) || \
@@ -393,6 +418,8 @@ static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
#ifdef CONFIG_OMAP_MUX
static struct omap_board_mux board_mux[] __initdata = {
+ /* USB OTG DRVVBUS offset = 0x212 */
+ OMAP3_MUX(SAD2D_MCAD23, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
#else
@@ -459,11 +486,12 @@ static void __init am3517_evm_init(void)
ARRAY_SIZE(am3517evm_i2c1_boardinfo));
/*Ethernet*/
am3517_evm_ethernet_init(&am3517_evm_emac_pdata);
+
+ /* MUSB */
+ am3517_evm_musb_init();
}
MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM")
- .phys_io = 0x48000000,
- .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = omap3_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index c6421a72514a..68f07f5f441a 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -356,8 +356,6 @@ static void __init omap_apollon_map_io(void)
MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon")
/* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
- .phys_io = 0x48000000,
- .io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = omap_apollon_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index e10bc109415c..934d9380c372 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -809,8 +809,6 @@ static void __init cm_t35_init(void)
}
MACHINE_START(CM_T35, "Compulab CM-T35")
- .phys_io = 0x48000000,
- .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = omap3_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index a07086d6a0b2..2205c20a4cdb 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -800,8 +800,6 @@ static void __init devkit8000_init(void)
}
MACHINE_START(DEVKIT8000, "OMAP3 Devkit8000")
- .phys_io = 0x48000000,
- .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = omap3_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 3482b99e8c86..69064b1c6a75 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -54,8 +54,6 @@ static void __init omap_generic_map_io(void)
MACHINE_START(OMAP_GENERIC, "Generic OMAP24xx")
/* Maintainer: Paul Mundt <paul.mundt@nokia.com> */
- .phys_io = 0x48000000,
- .io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = omap_generic_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index e09bd686389f..cc39fc866524 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -376,8 +376,6 @@ static void __init omap_h4_map_io(void)
MACHINE_START(OMAP_H4, "OMAP2420 H4 board")
/* Maintainer: Paul Mundt <paul.mundt@nokia.com> */
- .phys_io = 0x48000000,
- .io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = omap_h4_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index 175f04339761..b62a68ba069b 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -533,8 +533,6 @@ static void __init igep2_init(void)
}
MACHINE_START(IGEP0020, "IGEP v2 board")
- .phys_io = 0x48000000,
- .io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = omap3_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index 00d9b13b01c5..f28fd77bceb3 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -442,8 +442,6 @@ static void __init omap_ldp_init(void)
}
MACHINE_START(OMAP_LDP, "OMAP LDP board")
- .phys_io = 0x48000000,
- .io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = omap3_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index a3e2b49aa39f..3f7966873507 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -674,8 +674,6 @@ static void __init n8x0_init_machine(void)
}
MACHINE_START(NOKIA_N800, "Nokia N800")
- .phys_io = 0x48000000,
- .io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = n8x0_map_io,
.reserve = omap_reserve,
@@ -685,8 +683,6 @@ MACHINE_START(NOKIA_N800, "Nokia N800")
MACHINE_END
MACHINE_START(NOKIA_N810, "Nokia N810")
- .phys_io = 0x48000000,
- .io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = n8x0_map_io,
.reserve = omap_reserve,
@@ -696,8 +692,6 @@ MACHINE_START(NOKIA_N810, "Nokia N810")
MACHINE_END
MACHINE_START(NOKIA_N810_WIMAX, "Nokia N810 WiMAX")
- .phys_io = 0x48000000,
- .io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = n8x0_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 87969c7df652..9d9f5b881ee8 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -487,8 +487,6 @@ static void __init omap3_beagle_init(void)
MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board")
/* Maintainer: Syed Mohammed Khasim - http://beagleboard.org */
- .phys_io = 0x48000000,
- .io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = omap3_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index f76d9c0a47a1..8936e4fba334 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -714,8 +714,6 @@ static void __init omap3_evm_init(void)
MACHINE_START(OMAP3EVM, "OMAP3 EVM")
/* Maintainer: Syed Mohammed Khasim - Texas Instruments */
- .phys_io = 0x48000000,
- .io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = omap3_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index dd3af2be13be..41d6f549070c 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -25,7 +25,7 @@
#include <linux/spi/ads7846.h>
#include <linux/regulator/machine.h>
#include <linux/i2c/twl.h>
-#include <linux/spi/wl12xx.h>
+#include <linux/wl12xx.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand.h>
#include <linux/leds.h>
@@ -717,8 +717,6 @@ static void __init omap3pandora_init(void)
}
MACHINE_START(OMAP3_PANDORA, "Pandora Handheld Console")
- .phys_io = 0x48000000,
- .io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = omap3_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index bcd01d278c65..bc5ac83bd4cf 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -654,8 +654,6 @@ static void __init omap3_stalker_init(void)
MACHINE_START(SBC3530, "OMAP3 STALKER")
/* Maintainer: Jason Lam -lzg@ema-tech.com */
- .phys_io = 0x48000000,
- .io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = omap3_map_io,
.init_irq = omap3_stalker_init_irq,
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index 663c62d271e8..0e99ce584dbf 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -538,8 +538,6 @@ static void __init omap3_touchbook_init(void)
MACHINE_START(TOUCHBOOK, "OMAP3 touchbook Board")
/* Maintainer: Gregoire Gentil - http://www.alwaysinnovating.com */
- .phys_io = 0x48000000,
- .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = omap3_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index c03d1d56db56..db69bcadf4c7 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -294,8 +294,6 @@ static void __init omap4_panda_map_io(void)
MACHINE_START(OMAP4_PANDA, "OMAP4 Panda board")
/* Maintainer: David Anders - Texas Instruments Inc */
- .phys_io = 0x48000000,
- .io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = omap4_panda_map_io,
.init_irq = omap4_panda_init_irq,
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 4c4843618350..5e528ca015a1 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -501,8 +501,6 @@ static void __init overo_init(void)
}
MACHINE_START(OVERO, "Gumstix Overo")
- .phys_io = 0x48000000,
- .io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = omap3_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index 9a5eb87425fc..ce28a851dcd3 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -14,7 +14,7 @@
#include <linux/input.h>
#include <linux/input/matrix_keypad.h>
#include <linux/spi/spi.h>
-#include <linux/spi/wl12xx.h>
+#include <linux/wl12xx.h>
#include <linux/i2c.h>
#include <linux/i2c/twl.h>
#include <linux/clk.h>
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index a58e8cb1a7fc..36f2cf4efd57 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -150,8 +150,6 @@ static void __init rx51_map_io(void)
MACHINE_START(NOKIA_RX51, "Nokia RX-51 board")
/* Maintainer: Lauri Leukkunen <lauri.leukkunen@nokia.com> */
- .phys_io = 0x48000000,
- .io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = rx51_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
index 6b3984964cc5..189a6d1600b2 100644
--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -16,6 +16,8 @@
#include <linux/gpio.h>
#include <linux/i2c/twl.h>
#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/wl12xx.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -27,6 +29,9 @@
#include "mux.h"
#include "hsmmc.h"
+#define OMAP_ZOOM_WLAN_PMENA_GPIO (101)
+#define OMAP_ZOOM_WLAN_IRQ_GPIO (162)
+
/* Zoom2 has Qwerty keyboard*/
static int board_keymap[] = {
KEY(0, 0, KEY_E),
@@ -106,6 +111,11 @@ static struct regulator_consumer_supply zoom_vmmc2_supply = {
.supply = "vmmc",
};
+static struct regulator_consumer_supply zoom_vmmc3_supply = {
+ .supply = "vmmc",
+ .dev_name = "mmci-omap-hs.2",
+};
+
/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */
static struct regulator_init_data zoom_vmmc1 = {
.constraints = {
@@ -151,6 +161,38 @@ static struct regulator_init_data zoom_vsim = {
.consumer_supplies = &zoom_vsim_supply,
};
+static struct regulator_init_data zoom_vmmc3 = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &zoom_vmmc3_supply,
+};
+
+static struct fixed_voltage_config zoom_vwlan = {
+ .supply_name = "vwl1271",
+ .microvolts = 1800000, /* 1.8V */
+ .gpio = OMAP_ZOOM_WLAN_PMENA_GPIO,
+ .startup_delay = 70000, /* 70msec */
+ .enable_high = 1,
+ .enabled_at_boot = 0,
+ .init_data = &zoom_vmmc3,
+};
+
+static struct platform_device omap_vwlan_device = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &zoom_vwlan,
+ },
+};
+
+struct wl12xx_platform_data omap_zoom_wlan_data __initdata = {
+ .irq = OMAP_GPIO_IRQ(OMAP_ZOOM_WLAN_IRQ_GPIO),
+ /* ZOOM ref clock is 26 MHz */
+ .board_ref_clock = 1,
+};
+
static struct omap2_hsmmc_info mmc[] __initdata = {
{
.name = "external",
@@ -168,6 +210,14 @@ static struct omap2_hsmmc_info mmc[] __initdata = {
.nonremovable = true,
.power_saving = true,
},
+ {
+ .name = "wl1271",
+ .mmc = 3,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_wp = -EINVAL,
+ .gpio_cd = -EINVAL,
+ .nonremovable = true,
+ },
{} /* Terminator */
};
@@ -279,7 +329,11 @@ static void enable_board_wakeup_source(void)
void __init zoom_peripherals_init(void)
{
+ if (wl12xx_set_platform_data(&omap_zoom_wlan_data))
+ pr_err("error setting wl12xx data\n");
+
omap_i2c_init();
+ platform_device_register(&omap_vwlan_device);
usb_musb_init(&musb_board_data);
enable_board_wakeup_source();
}
diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-omap2/board-zoom2.c
index 3ad9ecf7f5e2..24bbd0def64f 100644
--- a/arch/arm/mach-omap2/board-zoom2.c
+++ b/arch/arm/mach-omap2/board-zoom2.c
@@ -141,8 +141,6 @@ static void __init omap_zoom2_init(void)
}
MACHINE_START(OMAP_ZOOM2, "OMAP Zoom2 board")
- .phys_io = ZOOM_UART_BASE,
- .io_pg_offst = (ZOOM_UART_VIRT >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = omap3_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap2/board-zoom3.c b/arch/arm/mach-omap2/board-zoom3.c
index 6ca0b8341615..b2bb3ff971ac 100644
--- a/arch/arm/mach-omap2/board-zoom3.c
+++ b/arch/arm/mach-omap2/board-zoom3.c
@@ -123,8 +123,6 @@ static void __init omap_zoom_init(void)
}
MACHINE_START(OMAP_ZOOM3, "OMAP Zoom3 board")
- .phys_io = ZOOM_UART_BASE,
- .io_pg_offst = (ZOOM_UART_VIRT >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = omap3_map_io,
.reserve = omap_reserve,
diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
index 37d65d62ed8f..5f2066a6ba74 100644
--- a/arch/arm/mach-omap2/clock2420_data.c
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -1838,7 +1838,7 @@ static struct omap_clk omap2420_clks[] = {
CLK(NULL, "des_ick", &des_ick, CK_242X),
CLK("omap-sham", "ick", &sha_ick, CK_242X),
CLK("omap_rng", "ick", &rng_ick, CK_242X),
- CLK(NULL, "aes_ick", &aes_ick, CK_242X),
+ CLK("omap-aes", "ick", &aes_ick, CK_242X),
CLK(NULL, "pka_ick", &pka_ick, CK_242X),
CLK(NULL, "usb_fck", &usb_fck, CK_242X),
CLK("musb_hdrc", "fck", &osc_ck, CK_242X),
diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c
index b33118fb6a87..701a1716019e 100644
--- a/arch/arm/mach-omap2/clock2430_data.c
+++ b/arch/arm/mach-omap2/clock2430_data.c
@@ -1926,7 +1926,7 @@ static struct omap_clk omap2430_clks[] = {
CLK(NULL, "des_ick", &des_ick, CK_243X),
CLK("omap-sham", "ick", &sha_ick, CK_243X),
CLK("omap_rng", "ick", &rng_ick, CK_243X),
- CLK(NULL, "aes_ick", &aes_ick, CK_243X),
+ CLK("omap-aes", "ick", &aes_ick, CK_243X),
CLK(NULL, "pka_ick", &pka_ick, CK_243X),
CLK(NULL, "usb_fck", &usb_fck, CK_243X),
CLK("musb_hdrc", "ick", &usbhs_ick, CK_243X),
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
index dfdce2d82779..c73906d17458 100644
--- a/arch/arm/mach-omap2/clock3xxx_data.c
+++ b/arch/arm/mach-omap2/clock3xxx_data.c
@@ -3288,7 +3288,7 @@ static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "usbtll_ick", &usbtll_ick, CK_3430ES2 | CK_AM35XX),
CLK("mmci-omap-hs.2", "ick", &mmchs3_ick, CK_3430ES2 | CK_AM35XX),
CLK(NULL, "icr_ick", &icr_ick, CK_343X),
- CLK(NULL, "aes2_ick", &aes2_ick, CK_343X),
+ CLK("omap-aes", "ick", &aes2_ick, CK_343X),
CLK("omap-sham", "ick", &sha12_ick, CK_343X),
CLK(NULL, "des2_ick", &des2_ick, CK_343X),
CLK("mmci-omap-hs.1", "ick", &mmchs2_ick, CK_3XXX),
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 2dbb265bedd4..b27e7cbb3f29 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -498,6 +498,76 @@ static void omap_init_sham(void)
static inline void omap_init_sham(void) { }
#endif
+#if defined(CONFIG_CRYPTO_DEV_OMAP_AES) || defined(CONFIG_CRYPTO_DEV_OMAP_AES_MODULE)
+
+#ifdef CONFIG_ARCH_OMAP24XX
+static struct resource omap2_aes_resources[] = {
+ {
+ .start = OMAP24XX_SEC_AES_BASE,
+ .end = OMAP24XX_SEC_AES_BASE + 0x4C,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP24XX_DMA_AES_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = OMAP24XX_DMA_AES_RX,
+ .flags = IORESOURCE_DMA,
+ }
+};
+static int omap2_aes_resources_sz = ARRAY_SIZE(omap2_aes_resources);
+#else
+#define omap2_aes_resources NULL
+#define omap2_aes_resources_sz 0
+#endif
+
+#ifdef CONFIG_ARCH_OMAP34XX
+static struct resource omap3_aes_resources[] = {
+ {
+ .start = OMAP34XX_SEC_AES_BASE,
+ .end = OMAP34XX_SEC_AES_BASE + 0x4C,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP34XX_DMA_AES2_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = OMAP34XX_DMA_AES2_RX,
+ .flags = IORESOURCE_DMA,
+ }
+};
+static int omap3_aes_resources_sz = ARRAY_SIZE(omap3_aes_resources);
+#else
+#define omap3_aes_resources NULL
+#define omap3_aes_resources_sz 0
+#endif
+
+static struct platform_device aes_device = {
+ .name = "omap-aes",
+ .id = -1,
+};
+
+static void omap_init_aes(void)
+{
+ if (cpu_is_omap24xx()) {
+ aes_device.resource = omap2_aes_resources;
+ aes_device.num_resources = omap2_aes_resources_sz;
+ } else if (cpu_is_omap34xx()) {
+ aes_device.resource = omap3_aes_resources;
+ aes_device.num_resources = omap3_aes_resources_sz;
+ } else {
+ pr_err("%s: platform not supported\n", __func__);
+ return;
+ }
+ platform_device_register(&aes_device);
+}
+
+#else
+static inline void omap_init_aes(void) { }
+#endif
+
/*-------------------------------------------------------------------------*/
#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
@@ -854,6 +924,7 @@ static int __init omap2_init_devices(void)
omap_hdq_init();
omap_init_sti();
omap_init_sham();
+ omap_init_aes();
omap_init_vout();
return 0;
diff --git a/arch/arm/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h
index 1fe6f0187177..0f8a2e6ee284 100644
--- a/arch/arm/mach-omap2/hsmmc.h
+++ b/arch/arm/mach-omap2/hsmmc.h
@@ -23,7 +23,7 @@ struct omap2_hsmmc_info {
char *name; /* or NULL for default */
struct device *dev; /* returned: pointer to mmc adapter */
int ocr_mask; /* temporary HACK */
- /* Remux (pad configuation) when powering on/off */
+ /* Remux (pad configuration) when powering on/off */
void (*remux)(struct device *dev, int slot, int power_on);
/* init some special card */
void (*init_card)(struct mmc_card *card);
diff --git a/arch/arm/mach-omap2/include/mach/debug-macro.S b/arch/arm/mach-omap2/include/mach/debug-macro.S
index 09331bbbda52..6a4d4136002e 100644
--- a/arch/arm/mach-omap2/include/mach/debug-macro.S
+++ b/arch/arm/mach-omap2/include/mach/debug-macro.S
@@ -31,95 +31,94 @@ omap_uart_lsr: .word 0
* the desired UART phys and virt addresses temporarily into
* the omap_uart_phys and omap_uart_virt above.
*/
- .macro addruart, rx, tmp
+ .macro addruart, rp, rv
/* Use omap_uart_phys/virt if already configured */
-10: mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- ldreq \rx, =__virt_to_phys(omap_uart_phys) @ physical base address
- ldrne \rx, =omap_uart_virt @ virtual base address
- ldr \rx, [\rx, #0]
- cmp \rx, #0 @ is port configured?
+10: mrc p15, 0, \rp, c1, c0
+ tst \rp, #1 @ MMU enabled?
+ ldreq \rp, =__virt_to_phys(omap_uart_phys) @ MMU not enabled
+ ldrne \rp, =omap_uart_phys @ MMU enabled
+ add \rv, \rp, #4 @ omap_uart_virt
+ ldr \rp, [\rp, #0]
+ ldr \rv, [\rv, #0]
+ cmp \rp, #0 @ is port configured?
+ cmpne \rv, #0
bne 99f @ already configured
/* Check the debug UART configuration set in uncompress.h */
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- ldreq \rx, =OMAP_UART_INFO
- ldrne \rx, =__phys_to_virt(OMAP_UART_INFO)
- ldr \rx, [\rx, #0]
+ mrc p15, 0, \rp, c1, c0
+ tst \rp, #1 @ MMU enabled?
+ ldreq \rp, =OMAP_UART_INFO @ MMU not enabled
+ ldrne \rp, =__phys_to_virt(OMAP_UART_INFO) @ MMU enabled
+ ldr \rp, [\rp, #0]
/* Select the UART to use based on the UART1 scratchpad value */
- cmp \rx, #0 @ no port configured?
+ cmp \rp, #0 @ no port configured?
beq 21f @ if none, try to use UART1
- cmp \rx, #OMAP2UART1 @ OMAP2/3/4UART1
+ cmp \rp, #OMAP2UART1 @ OMAP2/3/4UART1
beq 21f @ configure OMAP2/3/4UART1
- cmp \rx, #OMAP2UART2 @ OMAP2/3/4UART2
+ cmp \rp, #OMAP2UART2 @ OMAP2/3/4UART2
beq 22f @ configure OMAP2/3/4UART2
- cmp \rx, #OMAP2UART3 @ only on 24xx
+ cmp \rp, #OMAP2UART3 @ only on 24xx
beq 23f @ configure OMAP2UART3
- cmp \rx, #OMAP3UART3 @ only on 34xx
+ cmp \rp, #OMAP3UART3 @ only on 34xx
beq 33f @ configure OMAP3UART3
- cmp \rx, #OMAP4UART3 @ only on 44xx
+ cmp \rp, #OMAP4UART3 @ only on 44xx
beq 43f @ configure OMAP4UART3
- cmp \rx, #OMAP3UART4 @ only on 36xx
+ cmp \rp, #OMAP3UART4 @ only on 36xx
beq 34f @ configure OMAP3UART4
- cmp \rx, #OMAP4UART4 @ only on 44xx
+ cmp \rp, #OMAP4UART4 @ only on 44xx
beq 44f @ configure OMAP4UART4
- cmp \rx, #ZOOM_UART @ only on zoom2/3
+ cmp \rp, #ZOOM_UART @ only on zoom2/3
beq 95f @ configure ZOOM_UART
/* Configure the UART offset from the phys/virt base */
-21: mov \rx, #UART_OFFSET(OMAP2_UART1_BASE) @ omap2/3/4
+21: mov \rp, #UART_OFFSET(OMAP2_UART1_BASE) @ omap2/3/4
b 98f
-22: mov \rx, #UART_OFFSET(OMAP2_UART2_BASE) @ omap2/3/4
+22: mov \rp, #UART_OFFSET(OMAP2_UART2_BASE) @ omap2/3/4
b 98f
-23: mov \rx, #UART_OFFSET(OMAP2_UART3_BASE)
+23: mov \rp, #UART_OFFSET(OMAP2_UART3_BASE)
b 98f
-33: mov \rx, #UART_OFFSET(OMAP3_UART1_BASE)
- add \rx, \rx, #0x00fb0000
- add \rx, \rx, #0x00006000 @ OMAP3_UART3_BASE
+33: mov \rp, #UART_OFFSET(OMAP3_UART1_BASE)
+ add \rp, \rp, #0x00fb0000
+ add \rp, \rp, #0x00006000 @ OMAP3_UART3_BASE
b 98f
-34: mov \rx, #UART_OFFSET(OMAP3_UART1_BASE)
- add \rx, \rx, #0x00fb0000
- add \rx, \rx, #0x00028000 @ OMAP3_UART4_BASE
+34: mov \rp, #UART_OFFSET(OMAP3_UART1_BASE)
+ add \rp, \rp, #0x00fb0000
+ add \rp, \rp, #0x00028000 @ OMAP3_UART4_BASE
b 98f
-43: mov \rx, #UART_OFFSET(OMAP4_UART3_BASE)
+43: mov \rp, #UART_OFFSET(OMAP4_UART3_BASE)
b 98f
-44: mov \rx, #UART_OFFSET(OMAP4_UART4_BASE)
+44: mov \rp, #UART_OFFSET(OMAP4_UART4_BASE)
b 98f
-95: ldr \rx, =ZOOM_UART_BASE
- mrc p15, 0, \tmp, c1, c0
- tst \tmp, #1 @ MMU enabled?
- ldreq \tmp, =__virt_to_phys(omap_uart_phys)
- ldrne \tmp, =omap_uart_phys
- str \rx, [\tmp, #0]
- ldr \rx, =ZOOM_UART_VIRT
- ldreq \tmp, =__virt_to_phys(omap_uart_virt)
- ldrne \tmp, =omap_uart_virt
- str \rx, [\tmp, #0]
- mov \rx, #(UART_LSR << ZOOM_PORT_SHIFT)
- ldreq \tmp, =__virt_to_phys(omap_uart_lsr)
- ldrne \tmp, =omap_uart_lsr
- str \rx, [\tmp, #0]
+95: ldr \rp, =ZOOM_UART_BASE
+ mrc p15, 0, \rv, c1, c0
+ tst \rv, #1 @ MMU enabled?
+ ldreq \rv, =__virt_to_phys(omap_uart_phys) @ MMU not enabled
+ ldrne \rv, =omap_uart_phys @ MMU enabled
+ str \rp, [\rv, #0]
+ ldr \rp, =ZOOM_UART_VIRT
+ add \rv, \rv, #4 @ omap_uart_virt
+ str \rp, [\rv, #0]
+ mov \rp, #(UART_LSR << ZOOM_PORT_SHIFT)
+ add \rv, \rv, #4 @ omap_uart_lsr
+ str \rp, [\rv, #0]
b 10b
/* Store both phys and virt address for the uart */
-98: add \rx, \rx, #0x48000000 @ phys base
- mrc p15, 0, \tmp, c1, c0
- tst \tmp, #1 @ MMU enabled?
- ldreq \tmp, =__virt_to_phys(omap_uart_phys)
- ldrne \tmp, =omap_uart_phys
- str \rx, [\tmp, #0]
- sub \rx, \rx, #0x48000000 @ phys base
- add \rx, \rx, #0xfa000000 @ virt base
- ldreq \tmp, =__virt_to_phys(omap_uart_virt)
- ldrne \tmp, =omap_uart_virt
- str \rx, [\tmp, #0]
- mov \rx, #(UART_LSR << OMAP_PORT_SHIFT)
- ldreq \tmp, =__virt_to_phys(omap_uart_lsr)
- ldrne \tmp, =omap_uart_lsr
- str \rx, [\tmp, #0]
+98: add \rp, \rp, #0x48000000 @ phys base
+ mrc p15, 0, \rv, c1, c0
+ tst \rv, #1 @ MMU enabled?
+ ldreq \rv, =__virt_to_phys(omap_uart_phys) @ MMU not enabled
+ ldrne \rv, =omap_uart_phys @ MMU enabled
+ str \rp, [\rv, #0]
+ sub \rp, \rp, #0x48000000 @ phys base
+ add \rp, \rp, #0xfa000000 @ virt base
+ add \rv, \rv, #4 @ omap_uart_virt
+ str \rp, [\rv, #0]
+ mov \rp, #(UART_LSR << OMAP_PORT_SHIFT)
+ add \rv, \rv, #4 @ omap_uart_lsr
+ str \rp, [\rv, #0]
b 10b
99:
@@ -131,9 +130,9 @@ omap_uart_lsr: .word 0
.macro busyuart,rd,rx
1001: mrc p15, 0, \rd, c1, c0
- tst \rd, #1 @ MMU enabled?
- ldreq \rd, =__virt_to_phys(omap_uart_lsr)
- ldrne \rd, =omap_uart_lsr
+ tst \rd, #1 @ MMU enabled?
+ ldreq \rd, =__virt_to_phys(omap_uart_lsr) @ MMU not enabled
+ ldrne \rd, =omap_uart_lsr @ MMU enabled
ldr \rd, [\rd, #0]
ldrb \rd, [\rx, \rd]
and \rd, \rd, #(UART_LSR_TEMT | UART_LSR_THRE)
diff --git a/arch/arm/mach-omap2/include/mach/vmalloc.h b/arch/arm/mach-omap2/include/mach/vmalloc.h
index 9ce9b6e8ad23..4da31e997efe 100644
--- a/arch/arm/mach-omap2/include/mach/vmalloc.h
+++ b/arch/arm/mach-omap2/include/mach/vmalloc.h
@@ -17,4 +17,4 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#define VMALLOC_END (PAGE_OFFSET + 0x38000000)
+#define VMALLOC_END 0xf8000000
diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c
index 33a5cde1c227..72605584bfff 100644
--- a/arch/arm/mach-omap2/usb-musb.c
+++ b/arch/arm/mach-omap2/usb-musb.c
@@ -28,6 +28,7 @@
#include <mach/hardware.h>
#include <mach/irqs.h>
+#include <mach/am35xx.h>
#include <plat/usb.h>
#ifdef CONFIG_USB_MUSB_SOC
@@ -89,6 +90,9 @@ void __init usb_musb_init(struct omap_musb_board_data *board_data)
{
if (cpu_is_omap243x()) {
musb_resources[0].start = OMAP243X_HS_BASE;
+ } else if (cpu_is_omap3517() || cpu_is_omap3505()) {
+ musb_resources[0].start = AM35XX_IPSS_USBOTGSS_BASE;
+ musb_resources[1].start = INT_35XX_USBOTG_IRQ;
} else if (cpu_is_omap34xx()) {
musb_resources[0].start = OMAP34XX_HSUSB_OTG_BASE;
} else if (cpu_is_omap44xx()) {
diff --git a/arch/arm/mach-orion5x/d2net-setup.c b/arch/arm/mach-orion5x/d2net-setup.c
index 7130904ad999..b1c451f5ee27 100644
--- a/arch/arm/mach-orion5x/d2net-setup.c
+++ b/arch/arm/mach-orion5x/d2net-setup.c
@@ -336,8 +336,6 @@ static void __init d2net_init(void)
#ifdef CONFIG_MACH_D2NET
MACHINE_START(D2NET, "LaCie d2 Network")
- .phys_io = ORION5X_REGS_PHYS_BASE,
- .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.init_machine = d2net_init,
.map_io = orion5x_map_io,
@@ -349,8 +347,6 @@ MACHINE_END
#ifdef CONFIG_MACH_BIGDISK
MACHINE_START(BIGDISK, "LaCie Big Disk Network")
- .phys_io = ORION5X_REGS_PHYS_BASE,
- .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.init_machine = d2net_init,
.map_io = orion5x_map_io,
diff --git a/arch/arm/mach-orion5x/db88f5281-setup.c b/arch/arm/mach-orion5x/db88f5281-setup.c
index d318bea2af91..df1083f5b6eb 100644
--- a/arch/arm/mach-orion5x/db88f5281-setup.c
+++ b/arch/arm/mach-orion5x/db88f5281-setup.c
@@ -358,8 +358,6 @@ static void __init db88f5281_init(void)
MACHINE_START(DB88F5281, "Marvell Orion-2 Development Board")
/* Maintainer: Tzachi Perelstein <tzachi@marvell.com> */
- .phys_io = ORION5X_REGS_PHYS_BASE,
- .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.init_machine = db88f5281_init,
.map_io = orion5x_map_io,
diff --git a/arch/arm/mach-orion5x/dns323-setup.c b/arch/arm/mach-orion5x/dns323-setup.c
index a47100d46a4e..3a7bc0e36982 100644
--- a/arch/arm/mach-orion5x/dns323-setup.c
+++ b/arch/arm/mach-orion5x/dns323-setup.c
@@ -730,8 +730,6 @@ static void __init dns323_init(void)
/* Warning: D-Link uses a wrong mach-type (=526) in their bootloader */
MACHINE_START(DNS323, "D-Link DNS-323")
/* Maintainer: Herbert Valerio Riedel <hvr@gnu.org> */
- .phys_io = ORION5X_REGS_PHYS_BASE,
- .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.init_machine = dns323_init,
.map_io = orion5x_map_io,
diff --git a/arch/arm/mach-orion5x/edmini_v2-setup.c b/arch/arm/mach-orion5x/edmini_v2-setup.c
index b24ee0c2cd61..ba98459f44b0 100644
--- a/arch/arm/mach-orion5x/edmini_v2-setup.c
+++ b/arch/arm/mach-orion5x/edmini_v2-setup.c
@@ -251,8 +251,6 @@ static void __init edmini_v2_init(void)
/* Warning: LaCie use a wrong mach-type (0x20e=526) in their bootloader. */
MACHINE_START(EDMINI_V2, "LaCie Ethernet Disk mini V2")
/* Maintainer: Christopher Moore <moore@free.fr> */
- .phys_io = ORION5X_REGS_PHYS_BASE,
- .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.init_machine = edmini_v2_init,
.map_io = orion5x_map_io,
diff --git a/arch/arm/mach-orion5x/include/mach/debug-macro.S b/arch/arm/mach-orion5x/include/mach/debug-macro.S
index 91e0e39bb23f..5e3bf5b68aec 100644
--- a/arch/arm/mach-orion5x/include/mach/debug-macro.S
+++ b/arch/arm/mach-orion5x/include/mach/debug-macro.S
@@ -10,12 +10,11 @@
#include <mach/orion5x.h>
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- ldreq \rx, =ORION5X_REGS_PHYS_BASE
- ldrne \rx, =ORION5X_REGS_VIRT_BASE
- orr \rx, \rx, #0x00012000
+ .macro addruart, rp, rv
+ ldr \rp, =ORION5X_REGS_PHYS_BASE
+ ldr \rv, =ORION5X_REGS_VIRT_BASE
+ orr \rp, \rp, #0x00012000
+ orr \rv, \rv, #0x00012000
.endm
#define UART_SHIFT 2
diff --git a/arch/arm/mach-orion5x/kurobox_pro-setup.c b/arch/arm/mach-orion5x/kurobox_pro-setup.c
index dfbb68df7b09..4be9aa08de69 100644
--- a/arch/arm/mach-orion5x/kurobox_pro-setup.c
+++ b/arch/arm/mach-orion5x/kurobox_pro-setup.c
@@ -379,8 +379,6 @@ static void __init kurobox_pro_init(void)
#ifdef CONFIG_MACH_KUROBOX_PRO
MACHINE_START(KUROBOX_PRO, "Buffalo/Revogear Kurobox Pro")
/* Maintainer: Ronen Shitrit <rshitrit@marvell.com> */
- .phys_io = ORION5X_REGS_PHYS_BASE,
- .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.init_machine = kurobox_pro_init,
.map_io = orion5x_map_io,
@@ -393,8 +391,6 @@ MACHINE_END
#ifdef CONFIG_MACH_LINKSTATION_PRO
MACHINE_START(LINKSTATION_PRO, "Buffalo Linkstation Pro/Live")
/* Maintainer: Byron Bradley <byron.bbradley@gmail.com> */
- .phys_io = ORION5X_REGS_PHYS_BASE,
- .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.init_machine = kurobox_pro_init,
.map_io = orion5x_map_io,
diff --git a/arch/arm/mach-orion5x/ls_hgl-setup.c b/arch/arm/mach-orion5x/ls_hgl-setup.c
index 8e569be6e2c7..437364b7168e 100644
--- a/arch/arm/mach-orion5x/ls_hgl-setup.c
+++ b/arch/arm/mach-orion5x/ls_hgl-setup.c
@@ -265,8 +265,6 @@ static void __init ls_hgl_init(void)
MACHINE_START(LINKSTATION_LS_HGL, "Buffalo Linkstation LS-HGL")
/* Maintainer: Zhu Qingsen <zhuqs@cn.fujistu.com> */
- .phys_io = ORION5X_REGS_PHYS_BASE,
- .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.init_machine = ls_hgl_init,
.map_io = orion5x_map_io,
diff --git a/arch/arm/mach-orion5x/lsmini-setup.c b/arch/arm/mach-orion5x/lsmini-setup.c
index c704f056de1e..ab9b0cf0a90b 100644
--- a/arch/arm/mach-orion5x/lsmini-setup.c
+++ b/arch/arm/mach-orion5x/lsmini-setup.c
@@ -267,8 +267,6 @@ static void __init lsmini_init(void)
#ifdef CONFIG_MACH_LINKSTATION_MINI
MACHINE_START(LINKSTATION_MINI, "Buffalo Linkstation Mini")
/* Maintainer: Alexey Kopytko <alexey@kopytko.ru> */
- .phys_io = ORION5X_REGS_PHYS_BASE,
- .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.init_machine = lsmini_init,
.map_io = orion5x_map_io,
diff --git a/arch/arm/mach-orion5x/mss2-setup.c b/arch/arm/mach-orion5x/mss2-setup.c
index 61c086b66723..2f0e16cd7e81 100644
--- a/arch/arm/mach-orion5x/mss2-setup.c
+++ b/arch/arm/mach-orion5x/mss2-setup.c
@@ -261,8 +261,6 @@ static void __init mss2_init(void)
MACHINE_START(MSS2, "Maxtor Shared Storage II")
/* Maintainer: Sylver Bruneau <sylver.bruneau@googlemail.com> */
- .phys_io = ORION5X_REGS_PHYS_BASE,
- .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.init_machine = mss2_init,
.map_io = orion5x_map_io,
diff --git a/arch/arm/mach-orion5x/mv2120-setup.c b/arch/arm/mach-orion5x/mv2120-setup.c
index 97c9ccb2ac60..b3d90f25de9f 100644
--- a/arch/arm/mach-orion5x/mv2120-setup.c
+++ b/arch/arm/mach-orion5x/mv2120-setup.c
@@ -229,8 +229,6 @@ static void __init mv2120_init(void)
/* Warning: HP uses a wrong mach-type (=526) in their bootloader */
MACHINE_START(MV2120, "HP Media Vault mv2120")
/* Maintainer: Martin Michlmayr <tbm@cyrius.com> */
- .phys_io = ORION5X_REGS_PHYS_BASE,
- .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.init_machine = mv2120_init,
.map_io = orion5x_map_io,
diff --git a/arch/arm/mach-orion5x/net2big-setup.c b/arch/arm/mach-orion5x/net2big-setup.c
index 7bd6283476f9..d6665b31665f 100644
--- a/arch/arm/mach-orion5x/net2big-setup.c
+++ b/arch/arm/mach-orion5x/net2big-setup.c
@@ -419,8 +419,6 @@ static void __init net2big_init(void)
/* Warning: LaCie use a wrong mach-type (0x20e=526) in their bootloader. */
MACHINE_START(NET2BIG, "LaCie 2Big Network")
- .phys_io = ORION5X_REGS_PHYS_BASE,
- .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.init_machine = net2big_init,
.map_io = orion5x_map_io,
diff --git a/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
index 9c1ca41730ba..f4c26fd731f4 100644
--- a/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
+++ b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
@@ -169,8 +169,6 @@ subsys_initcall(rd88f5181l_fxo_pci_init);
MACHINE_START(RD88F5181L_FXO, "Marvell Orion-VoIP FXO Reference Design")
/* Maintainer: Nicolas Pitre <nico@marvell.com> */
- .phys_io = ORION5X_REGS_PHYS_BASE,
- .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.init_machine = rd88f5181l_fxo_init,
.map_io = orion5x_map_io,
diff --git a/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
index ee1399ff0ced..b5942909bab0 100644
--- a/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
+++ b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
@@ -181,8 +181,6 @@ subsys_initcall(rd88f5181l_ge_pci_init);
MACHINE_START(RD88F5181L_GE, "Marvell Orion-VoIP GE Reference Design")
/* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
- .phys_io = ORION5X_REGS_PHYS_BASE,
- .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.init_machine = rd88f5181l_ge_init,
.map_io = orion5x_map_io,
diff --git a/arch/arm/mach-orion5x/rd88f5182-setup.c b/arch/arm/mach-orion5x/rd88f5182-setup.c
index a04f9e4b633a..165ed87029b2 100644
--- a/arch/arm/mach-orion5x/rd88f5182-setup.c
+++ b/arch/arm/mach-orion5x/rd88f5182-setup.c
@@ -305,8 +305,6 @@ static void __init rd88f5182_init(void)
MACHINE_START(RD88F5182, "Marvell Orion-NAS Reference Design")
/* Maintainer: Ronen Shitrit <rshitrit@marvell.com> */
- .phys_io = ORION5X_REGS_PHYS_BASE,
- .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.init_machine = rd88f5182_init,
.map_io = orion5x_map_io,
diff --git a/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
index 7737cf9a8f50..02ff45f3e2e3 100644
--- a/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
+++ b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
@@ -123,8 +123,6 @@ subsys_initcall(rd88f6183ap_ge_pci_init);
MACHINE_START(RD88F6183AP_GE, "Marvell Orion-1-90 AP GE Reference Design")
/* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
- .phys_io = ORION5X_REGS_PHYS_BASE,
- .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.init_machine = rd88f6183ap_ge_init,
.map_io = orion5x_map_io,
diff --git a/arch/arm/mach-orion5x/terastation_pro2-setup.c b/arch/arm/mach-orion5x/terastation_pro2-setup.c
index 0b101d7d41c2..4403fae5ab0e 100644
--- a/arch/arm/mach-orion5x/terastation_pro2-setup.c
+++ b/arch/arm/mach-orion5x/terastation_pro2-setup.c
@@ -358,8 +358,6 @@ static void __init tsp2_init(void)
MACHINE_START(TERASTATION_PRO2, "Buffalo Terastation Pro II/Live")
/* Maintainer: Sylver Bruneau <sylver.bruneau@googlemail.com> */
- .phys_io = ORION5X_REGS_PHYS_BASE,
- .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.init_machine = tsp2_init,
.map_io = orion5x_map_io,
diff --git a/arch/arm/mach-orion5x/ts209-setup.c b/arch/arm/mach-orion5x/ts209-setup.c
index 9d6890514199..1e196129d763 100644
--- a/arch/arm/mach-orion5x/ts209-setup.c
+++ b/arch/arm/mach-orion5x/ts209-setup.c
@@ -322,8 +322,6 @@ static void __init qnap_ts209_init(void)
MACHINE_START(TS209, "QNAP TS-109/TS-209")
/* Maintainer: Byron Bradley <byron.bbradley@gmail.com> */
- .phys_io = ORION5X_REGS_PHYS_BASE,
- .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.init_machine = qnap_ts209_init,
.map_io = orion5x_map_io,
diff --git a/arch/arm/mach-orion5x/ts409-setup.c b/arch/arm/mach-orion5x/ts409-setup.c
index d85588ac7ef8..428af2046e36 100644
--- a/arch/arm/mach-orion5x/ts409-setup.c
+++ b/arch/arm/mach-orion5x/ts409-setup.c
@@ -311,8 +311,6 @@ static void __init qnap_ts409_init(void)
MACHINE_START(TS409, "QNAP TS-409")
/* Maintainer: Sylver Bruneau <sylver.bruneau@gmail.com> */
- .phys_io = ORION5X_REGS_PHYS_BASE,
- .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.init_machine = qnap_ts409_init,
.map_io = orion5x_map_io,
diff --git a/arch/arm/mach-orion5x/ts78xx-setup.c b/arch/arm/mach-orion5x/ts78xx-setup.c
index 696b1a97f9e2..16f1bd5324be 100644
--- a/arch/arm/mach-orion5x/ts78xx-setup.c
+++ b/arch/arm/mach-orion5x/ts78xx-setup.c
@@ -550,8 +550,6 @@ static void __init ts78xx_init(void)
MACHINE_START(TS78XX, "Technologic Systems TS-78xx SBC")
/* Maintainer: Alexander Clouter <alex@digriz.org.uk> */
- .phys_io = ORION5X_REGS_PHYS_BASE,
- .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.init_machine = ts78xx_init,
.map_io = ts78xx_map_io,
diff --git a/arch/arm/mach-orion5x/wnr854t-setup.c b/arch/arm/mach-orion5x/wnr854t-setup.c
index 69208217b220..7994d6ec08a8 100644
--- a/arch/arm/mach-orion5x/wnr854t-setup.c
+++ b/arch/arm/mach-orion5x/wnr854t-setup.c
@@ -172,8 +172,6 @@ subsys_initcall(wnr854t_pci_init);
MACHINE_START(WNR854T, "Netgear WNR854T")
/* Maintainer: Imre Kaloz <kaloz@openwrt.org> */
- .phys_io = ORION5X_REGS_PHYS_BASE,
- .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.init_machine = wnr854t_init,
.map_io = orion5x_map_io,
diff --git a/arch/arm/mach-orion5x/wrt350n-v2-setup.c b/arch/arm/mach-orion5x/wrt350n-v2-setup.c
index f9f222ebb7ed..a5989b7eb53e 100644
--- a/arch/arm/mach-orion5x/wrt350n-v2-setup.c
+++ b/arch/arm/mach-orion5x/wrt350n-v2-setup.c
@@ -260,8 +260,6 @@ subsys_initcall(wrt350n_v2_pci_init);
MACHINE_START(WRT350N_V2, "Linksys WRT350N v2")
/* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
- .phys_io = ORION5X_REGS_PHYS_BASE,
- .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.init_machine = wrt350n_v2_init,
.map_io = orion5x_map_io,
diff --git a/arch/arm/mach-pnx4008/core.c b/arch/arm/mach-pnx4008/core.c
index 45734bb880a8..63399755f199 100644
--- a/arch/arm/mach-pnx4008/core.c
+++ b/arch/arm/mach-pnx4008/core.c
@@ -264,8 +264,6 @@ extern struct sys_timer pnx4008_timer;
MACHINE_START(PNX4008, "Philips PNX4008")
/* Maintainer: MontaVista Software Inc. */
- .phys_io = 0x40090000,
- .io_pg_offst = (0xf4090000 >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = pnx4008_map_io,
.init_irq = pnx4008_init_irq,
diff --git a/arch/arm/mach-pnx4008/include/mach/debug-macro.S b/arch/arm/mach-pnx4008/include/mach/debug-macro.S
index 6ca8bd30bf46..931afebaf064 100644
--- a/arch/arm/mach-pnx4008/include/mach/debug-macro.S
+++ b/arch/arm/mach-pnx4008/include/mach/debug-macro.S
@@ -11,12 +11,10 @@
*
*/
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- mov \rx, #0x00090000
- addeq \rx, \rx, #0x40000000
- addne \rx, \rx, #0xf4000000
+ .macro addruart, rp, rv
+ mov \rp, #0x00090000
+ add \rv, \rp, #0xf4000000 @ virtual
+ add \rp, \rp, #0x40000000 @ physical
.endm
#define UART_SHIFT 2
diff --git a/arch/arm/mach-pnx4008/include/mach/vmalloc.h b/arch/arm/mach-pnx4008/include/mach/vmalloc.h
index 2ad398378aed..31b65ee07b0b 100644
--- a/arch/arm/mach-pnx4008/include/mach/vmalloc.h
+++ b/arch/arm/mach-pnx4008/include/mach/vmalloc.h
@@ -17,4 +17,4 @@
* The vmalloc() routines leaves a hole of 4kB between each vmalloced
* area for the same reason. ;)
*/
-#define VMALLOC_END (PAGE_OFFSET + 0x10000000)
+#define VMALLOC_END 0xd0000000
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 7aefb9074852..dd235ecc9d6c 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -8,19 +8,16 @@ config ARCH_LUBBOCK
bool "Intel DBPXA250 Development Platform (aka Lubbock)"
select PXA25x
select SA1111
- select PXA_HAVE_BOARD_IRQS
config MACH_MAINSTONE
bool "Intel HCDDBBVA0 Development Platform (aka Mainstone)"
select PXA27x
select HAVE_PWM
- select PXA_HAVE_BOARD_IRQS
config MACH_ZYLONITE
bool
select PXA3xx
select HAVE_PWM
- select PXA_HAVE_BOARD_IRQS
config MACH_ZYLONITE300
bool "PXA3xx Development Platform (aka Zylonite) PXA300/310"
@@ -44,6 +41,10 @@ config MACH_TAVOREVB
select PXA3xx
select CPU_PXA930
+config MACH_TAVOREVB3
+ bool "PXA95x Development Platform (aka TavorEVB III)"
+ select CPU_PXA950
+
config MACH_SAAR
bool "PXA930 Handheld Platform (aka SAAR)"
select PXA3xx
@@ -61,7 +62,6 @@ config ARCH_VIPER
select ISA
select I2C_GPIO
select HAVE_PWM
- select PXA_HAVE_BOARD_IRQS
select PXA_HAVE_ISA_IRQS
select ARCOM_PCMCIA
@@ -69,7 +69,6 @@ config MACH_ARCOM_ZEUS
bool "Arcom/Eurotech ZEUS SBC"
select PXA27x
select ISA
- select PXA_HAVE_BOARD_IRQS
select PXA_HAVE_ISA_IRQS
select ARCOM_PCMCIA
@@ -77,7 +76,6 @@ config MACH_BALLOON3
bool "Balloon 3 board"
select PXA27x
select IWMMXT
- select PXA_HAVE_BOARD_IRQS
config MACH_CSB726
bool "Enable Cogent CSB726 System On a Module"
@@ -140,13 +138,11 @@ config MACH_INTELMOTE2
bool "Intel Mote 2 Platform"
select PXA27x
select IWMMXT
- select PXA_HAVE_BOARD_IRQS
config MACH_STARGATE2
bool "Intel Stargate 2 Platform"
select PXA27x
select IWMMXT
- select PXA_HAVE_BOARD_IRQS
config MACH_XCEP
bool "Iskratel Electronics XCEP"
@@ -206,13 +202,11 @@ config MACH_LOGICPD_PXA270
bool "LogicPD PXA270 Card Engine Development Platform"
select PXA27x
select HAVE_PWM
- select PXA_HAVE_BOARD_IRQS
config MACH_PCM027
bool "Phytec phyCORE-PXA270 CPU module (PCM-027)"
select PXA27x
select IWMMXT
- select PXA_HAVE_BOARD_IRQS
config MACH_PCM990_BASEBOARD
bool "PHYTEC PCM-990 development board"
@@ -247,7 +241,6 @@ config MACH_COLIBRI_PXA270_INCOME
depends on MACH_COLIBRI
select PXA27x
select HAVE_PWM
- select PXA_HAVE_BOARD_IRQS
config MACH_COLIBRI300
bool "Toradex Colibri PXA300/310"
@@ -274,7 +267,6 @@ config MACH_H4700
select PXA27x
select IWMMXT
select HAVE_PWM
- select PXA_HAVE_BOARD_IRQS
config MACH_H5000
bool "HP iPAQ h5000"
@@ -289,7 +281,6 @@ config MACH_MAGICIAN
select PXA27x
select IWMMXT
select HAVE_PWM
- select PXA_HAVE_BOARD_IRQS
config MACH_MIOA701
bool "Mitac Mio A701 Support"
@@ -307,7 +298,6 @@ config PXA_EZX
select PXA27x
select IWMMXT
select HAVE_PWM
- select PXA_HAVE_BOARD_IRQS
config MACH_EZX_A780
bool "Motorola EZX A780"
@@ -478,7 +468,6 @@ config MACH_POODLE
depends on PXA_SHARPSL
select PXA25x
select SHARP_LOCOMO
- select PXA_HAVE_BOARD_IRQS
config MACH_CORGI
bool "Enable Sharp SL-C700 (Corgi) Support"
@@ -523,7 +512,6 @@ config MACH_TOSA
bool "Enable Sharp SL-6000x (Tosa) Support"
depends on PXA_SHARPSL
select PXA25x
- select PXA_HAVE_BOARD_IRQS
config TOSA_BT
tristate "Control the state of built-in bluetooth chip on Sharp SL-6000"
@@ -552,7 +540,6 @@ config MACH_ICONTROL
config ARCH_PXA_ESERIES
bool "PXA based Toshiba e-series PDAs"
select PXA25x
- select PXA_HAVE_BOARD_IRQS
config MACH_E330
bool "Toshiba e330"
@@ -606,7 +593,6 @@ config MACH_ZIPIT2
bool "Zipit Z2 Handheld"
select PXA27x
select HAVE_PWM
- select PXA_HAVE_BOARD_IRQS
endmenu
@@ -643,6 +629,7 @@ config CPU_PXA300
config CPU_PXA310
bool
select CPU_PXA300
+ select PXA310_ULPI if USB_ULPI
help
PXA310 (codename Monahans-LV)
@@ -692,10 +679,10 @@ config SHARPSL_PM_MAX1111
select HWMON
select SENSORS_MAX1111
-config PXA_HAVE_BOARD_IRQS
+config PXA_HAVE_ISA_IRQS
bool
-config PXA_HAVE_ISA_IRQS
+config PXA310_ULPI
bool
endif
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index 85c7fb324dbb..e2f89c2c6f49 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -18,7 +18,7 @@ endif
# SoC-specific code
obj-$(CONFIG_PXA25x) += mfp-pxa2xx.o pxa2xx.o pxa25x.o
obj-$(CONFIG_PXA27x) += mfp-pxa2xx.o pxa2xx.o pxa27x.o
-obj-$(CONFIG_PXA3xx) += mfp-pxa3xx.o pxa3xx.o smemc.o
+obj-$(CONFIG_PXA3xx) += mfp-pxa3xx.o pxa3xx.o smemc.o pxa3xx-ulpi.o
obj-$(CONFIG_CPU_PXA300) += pxa300.o
obj-$(CONFIG_CPU_PXA320) += pxa320.o
obj-$(CONFIG_CPU_PXA930) += pxa930.o
@@ -32,6 +32,7 @@ obj-$(CONFIG_MACH_ZYLONITE300) += zylonite.o zylonite_pxa300.o
obj-$(CONFIG_MACH_ZYLONITE320) += zylonite.o zylonite_pxa320.o
obj-$(CONFIG_MACH_LITTLETON) += littleton.o
obj-$(CONFIG_MACH_TAVOREVB) += tavorevb.o
+obj-$(CONFIG_MACH_TAVOREVB3) += tavorevb3.o
obj-$(CONFIG_MACH_SAAR) += saar.o
# 3rd Party Dev Platforms
diff --git a/arch/arm/mach-pxa/balloon3.c b/arch/arm/mach-pxa/balloon3.c
index 9041340fee1d..21e188901935 100644
--- a/arch/arm/mach-pxa/balloon3.c
+++ b/arch/arm/mach-pxa/balloon3.c
@@ -68,42 +68,6 @@ static unsigned long balloon3_pin_config[] __initdata = {
/* Reset, configured as GPIO wakeup source */
GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH,
-
- /* LEDs */
- GPIO9_GPIO, /* NAND activity LED */
- GPIO10_GPIO, /* Heartbeat LED */
-
- /* AC97 */
- GPIO28_AC97_BITCLK,
- GPIO29_AC97_SDATA_IN_0,
- GPIO30_AC97_SDATA_OUT,
- GPIO31_AC97_SYNC,
- GPIO113_AC97_nRESET,
- GPIO95_GPIO,
-
- /* MMC */
- GPIO32_MMC_CLK,
- GPIO92_MMC_DAT_0,
- GPIO109_MMC_DAT_1,
- GPIO110_MMC_DAT_2,
- GPIO111_MMC_DAT_3,
- GPIO112_MMC_CMD,
-
- /* USB Host */
- GPIO88_USBH1_PWR,
- GPIO89_USBH1_PEN,
-
- /* PC Card */
- GPIO48_nPOE,
- GPIO49_nPWE,
- GPIO50_nPIOR,
- GPIO51_nPIOW,
- GPIO85_nPCE_1,
- GPIO54_nPCE_2,
- GPIO79_PSKTSEL,
- GPIO55_nPREG,
- GPIO56_nPWAIT,
- GPIO57_nIOIS16,
};
/******************************************************************************
@@ -132,6 +96,34 @@ int __init parse_balloon3_features(char *arg)
early_param("balloon3_features", parse_balloon3_features);
/******************************************************************************
+ * Compact Flash slot
+ ******************************************************************************/
+#if defined(CONFIG_PCMCIA_PXA2XX) || defined(CONFIG_PCMCIA_PXA2XX_MODULE)
+static unsigned long balloon3_cf_pin_config[] __initdata = {
+ GPIO48_nPOE,
+ GPIO49_nPWE,
+ GPIO50_nPIOR,
+ GPIO51_nPIOW,
+ GPIO85_nPCE_1,
+ GPIO54_nPCE_2,
+ GPIO79_PSKTSEL,
+ GPIO55_nPREG,
+ GPIO56_nPWAIT,
+ GPIO57_nIOIS16,
+};
+
+static void __init balloon3_cf_init(void)
+{
+ if (!balloon3_has(BALLOON3_FEATURE_CF))
+ return;
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_cf_pin_config));
+}
+#else
+static inline void balloon3_cf_init(void) {}
+#endif
+
+/******************************************************************************
* NOR Flash
******************************************************************************/
#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
@@ -179,6 +171,15 @@ static inline void balloon3_nor_init(void) {}
******************************************************************************/
#if defined(CONFIG_TOUCHSCREEN_UCB1400) || \
defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE)
+static unsigned long balloon3_ac97_pin_config[] __initdata = {
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+ GPIO113_AC97_nRESET,
+ GPIO95_GPIO,
+};
+
static struct ucb1400_pdata vpac270_ucb1400_pdata = {
.irq = IRQ_GPIO(BALLOON3_GPIO_CODEC_IRQ),
};
@@ -197,6 +198,7 @@ static void __init balloon3_ts_init(void)
if (!balloon3_has(BALLOON3_FEATURE_AUDIO))
return;
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_ac97_pin_config));
pxa_set_ac97_info(NULL);
platform_device_register(&balloon3_ucb1400_device);
}
@@ -208,6 +210,11 @@ static inline void balloon3_ts_init(void) {}
* Framebuffer
******************************************************************************/
#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static unsigned long balloon3_lcd_pin_config[] __initdata = {
+ GPIOxx_LCD_TFT_16BPP,
+ GPIO99_GPIO,
+};
+
static struct pxafb_mode_info balloon3_lcd_modes[] = {
{
.pixclock = 38000,
@@ -242,6 +249,8 @@ static void __init balloon3_lcd_init(void)
if (!balloon3_has(BALLOON3_FEATURE_TOPPOLY))
return;
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_lcd_pin_config));
+
ret = gpio_request(BALLOON3_GPIO_RUN_BACKLIGHT, "BKL-ON");
if (ret) {
pr_err("Requesting BKL-ON GPIO failed!\n");
@@ -271,6 +280,15 @@ static inline void balloon3_lcd_init(void) {}
* SD/MMC card controller
******************************************************************************/
#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
+static unsigned long balloon3_mmc_pin_config[] __initdata = {
+ GPIO32_MMC_CLK,
+ GPIO92_MMC_DAT_0,
+ GPIO109_MMC_DAT_1,
+ GPIO110_MMC_DAT_2,
+ GPIO111_MMC_DAT_3,
+ GPIO112_MMC_CMD,
+};
+
static struct pxamci_platform_data balloon3_mci_platform_data = {
.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
.gpio_card_detect = -1,
@@ -281,6 +299,7 @@ static struct pxamci_platform_data balloon3_mci_platform_data = {
static void __init balloon3_mmc_init(void)
{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_mmc_pin_config));
pxa_set_mci_info(&balloon3_mci_platform_data);
}
#else
@@ -339,6 +358,11 @@ static inline void balloon3_irda_init(void) {}
* USB Host
******************************************************************************/
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static unsigned long balloon3_uhc_pin_config[] __initdata = {
+ GPIO88_USBH1_PWR,
+ GPIO89_USBH1_PEN,
+};
+
static struct pxaohci_platform_data balloon3_ohci_info = {
.port_mode = PMM_PERPORT_MODE,
.flags = ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW,
@@ -348,6 +372,7 @@ static void __init balloon3_uhc_init(void)
{
if (!balloon3_has(BALLOON3_FEATURE_OHCI))
return;
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_uhc_pin_config));
pxa_set_ohci_info(&balloon3_ohci_info);
}
#else
@@ -358,6 +383,11 @@ static inline void balloon3_uhc_init(void) {}
* LEDs
******************************************************************************/
#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+static unsigned long balloon3_led_pin_config[] __initdata = {
+ GPIO9_GPIO, /* NAND activity LED */
+ GPIO10_GPIO, /* Heartbeat LED */
+};
+
struct gpio_led balloon3_gpio_leds[] = {
{
.name = "balloon3:green:idle",
@@ -436,6 +466,7 @@ static struct platform_device balloon3_pcf_leds = {
static void __init balloon3_leds_init(void)
{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_led_pin_config));
platform_device_register(&balloon3_leds);
platform_device_register(&balloon3_pcf_leds);
}
@@ -757,6 +788,7 @@ static void __init balloon3_init(void)
balloon3_ts_init();
balloon3_udc_init();
balloon3_uhc_init();
+ balloon3_cf_init();
}
static struct map_desc balloon3_io_desc[] __initdata = {
@@ -776,9 +808,8 @@ static void __init balloon3_map_io(void)
MACHINE_START(BALLOON3, "Balloon3")
/* Maintainer: Nick Bane. */
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = balloon3_map_io,
+ .nr_irqs = BALLOON3_NR_IRQS,
.init_irq = balloon3_init_irq,
.timer = &pxa_timer,
.init_machine = balloon3_init,
diff --git a/arch/arm/mach-pxa/capc7117.c b/arch/arm/mach-pxa/capc7117.c
index aae544631a8b..4bd7a3cda48c 100644
--- a/arch/arm/mach-pxa/capc7117.c
+++ b/arch/arm/mach-pxa/capc7117.c
@@ -148,9 +148,7 @@ static void __init capc7117_init(void)
MACHINE_START(CAPC7117,
"Embedian CAPC-7117 evaluation kit based on the MXM-8x10 CoM")
- .phys_io = 0x40000000,
.boot_params = 0xa0000100,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = pxa_map_io,
.init_irq = pxa3xx_init_irq,
.timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/cm-x2xx.c b/arch/arm/mach-pxa/cm-x2xx.c
index bff6e78f033d..ac5598ce9724 100644
--- a/arch/arm/mach-pxa/cm-x2xx.c
+++ b/arch/arm/mach-pxa/cm-x2xx.c
@@ -33,6 +33,9 @@
extern void cmx255_init(void);
extern void cmx270_init(void);
+/* reserve IRQs for IT8152 */
+#define CMX2XX_NR_IRQS (IRQ_BOARD_START + 40)
+
/* virtual addresses for statically mapped regions */
#define CMX2XX_VIRT_BASE (0xe8000000)
#define CMX2XX_IT8152_VIRT (CMX2XX_VIRT_BASE)
@@ -511,9 +514,8 @@ static void __init cmx2xx_map_io(void)
MACHINE_START(ARMCORE, "Compulab CM-X2XX")
.boot_params = 0xa0000100,
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = cmx2xx_map_io,
+ .nr_irqs = CMX2XX_NR_IRQS,
.init_irq = cmx2xx_init_irq,
.timer = &pxa_timer,
.init_machine = cmx2xx_init,
diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c
index c70e6c2f4e7c..922b1075b9de 100644
--- a/arch/arm/mach-pxa/cm-x300.c
+++ b/arch/arm/mach-pxa/cm-x300.c
@@ -19,6 +19,7 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
+#include <linux/clk.h>
#include <linux/gpio.h>
#include <linux/dm9000.h>
@@ -50,6 +51,7 @@
#include <plat/i2c.h>
#include <plat/pxa3xx_nand.h>
#include <mach/audio.h>
+#include <mach/pxa3xx-u2d.h>
#include <asm/mach/map.h>
@@ -68,6 +70,8 @@
#define GPIO97_RTC_RD (97)
#define GPIO98_RTC_IO (98)
+#define GPIO_ULPI_PHY_RST (127)
+
static mfp_cfg_t cm_x3xx_mfp_cfg[] __initdata = {
/* LCD */
GPIO54_LCD_LDD_0,
@@ -472,6 +476,78 @@ static void __init cm_x300_init_mmc(void)
static inline void cm_x300_init_mmc(void) {}
#endif
+#if defined(CONFIG_PXA310_ULPI)
+static struct clk *pout_clk;
+
+static int cm_x300_ulpi_phy_reset(void)
+{
+ int err;
+
+ /* reset the PHY */
+ err = gpio_request(GPIO_ULPI_PHY_RST, "ulpi reset");
+ if (err) {
+ pr_err("%s: failed to request ULPI reset GPIO: %d\n",
+ __func__, err);
+ return err;
+ }
+
+ gpio_direction_output(GPIO_ULPI_PHY_RST, 0);
+ msleep(10);
+ gpio_set_value(GPIO_ULPI_PHY_RST, 1);
+ msleep(10);
+
+ gpio_free(GPIO_ULPI_PHY_RST);
+
+ return 0;
+}
+
+static inline int cm_x300_u2d_init(struct device *dev)
+{
+ int err = 0;
+
+ if (cpu_is_pxa310()) {
+ /* CLK_POUT is connected to the ULPI PHY */
+ pout_clk = clk_get(NULL, "CLK_POUT");
+ if (IS_ERR(pout_clk)) {
+ err = PTR_ERR(pout_clk);
+ pr_err("%s: failed to get CLK_POUT: %d\n",
+ __func__, err);
+ return err;
+ }
+ clk_enable(pout_clk);
+
+ err = cm_x300_ulpi_phy_reset();
+ if (err) {
+ clk_disable(pout_clk);
+ clk_put(pout_clk);
+ }
+ }
+
+ return err;
+}
+
+static void cm_x300_u2d_exit(struct device *dev)
+{
+ if (cpu_is_pxa310()) {
+ clk_disable(pout_clk);
+ clk_put(pout_clk);
+ }
+}
+
+static struct pxa3xx_u2d_platform_data cm_x300_u2d_platform_data = {
+ .ulpi_mode = ULPI_SER_6PIN,
+ .init = cm_x300_u2d_init,
+ .exit = cm_x300_u2d_exit,
+};
+
+static void cm_x300_init_u2d(void)
+{
+ pxa3xx_set_u2d_info(&cm_x300_u2d_platform_data);
+}
+#else
+static inline void cm_x300_init_u2d(void) {}
+#endif
+
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
static int cm_x300_ohci_init(struct device *dev)
{
@@ -754,6 +830,7 @@ static void __init cm_x300_init(void)
cm_x300_init_da9030();
cm_x300_init_dm9000();
cm_x300_init_lcd();
+ cm_x300_init_u2d();
cm_x300_init_ohci();
cm_x300_init_mmc();
cm_x300_init_nand();
@@ -779,9 +856,7 @@ static void __init cm_x300_fixup(struct machine_desc *mdesc, struct tag *tags,
}
MACHINE_START(CM_X300, "CM-X300 module")
- .phys_io = 0x40000000,
.boot_params = 0xa0000100,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = pxa_map_io,
.init_irq = pxa3xx_init_irq,
.timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/colibri-pxa270.c b/arch/arm/mach-pxa/colibri-pxa270.c
index 98673ac6efd0..bc045100ec15 100644
--- a/arch/arm/mach-pxa/colibri-pxa270.c
+++ b/arch/arm/mach-pxa/colibri-pxa270.c
@@ -207,8 +207,6 @@ static void __init colibri_pxa270_income_init(void)
}
MACHINE_START(COLIBRI, "Toradex Colibri PXA270")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = COLIBRI_SDRAM_BASE + 0x100,
.init_machine = colibri_pxa270_init,
.map_io = pxa_map_io,
@@ -217,8 +215,6 @@ MACHINE_START(COLIBRI, "Toradex Colibri PXA270")
MACHINE_END
MACHINE_START(INCOME, "Income s.r.o. SH-Dmaster PXA270 SBC")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.init_machine = colibri_pxa270_income_init,
.map_io = pxa_map_io,
diff --git a/arch/arm/mach-pxa/colibri-pxa300.c b/arch/arm/mach-pxa/colibri-pxa300.c
index 40b6ac2de876..a70b256591e6 100644
--- a/arch/arm/mach-pxa/colibri-pxa300.c
+++ b/arch/arm/mach-pxa/colibri-pxa300.c
@@ -186,8 +186,6 @@ void __init colibri_pxa300_init(void)
}
MACHINE_START(COLIBRI300, "Toradex Colibri PXA300")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = COLIBRI_SDRAM_BASE + 0x100,
.init_machine = colibri_pxa300_init,
.map_io = pxa_map_io,
diff --git a/arch/arm/mach-pxa/colibri-pxa320.c b/arch/arm/mach-pxa/colibri-pxa320.c
index 99e850d84710..ca5f29e2e9cd 100644
--- a/arch/arm/mach-pxa/colibri-pxa320.c
+++ b/arch/arm/mach-pxa/colibri-pxa320.c
@@ -255,8 +255,6 @@ void __init colibri_pxa320_init(void)
}
MACHINE_START(COLIBRI320, "Toradex Colibri PXA320")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = COLIBRI_SDRAM_BASE + 0x100,
.init_machine = colibri_pxa320_init,
.map_io = pxa_map_io,
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 3fb0fc099080..821229acabe6 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -720,8 +720,6 @@ static void __init fixup_corgi(struct machine_desc *desc,
#ifdef CONFIG_MACH_CORGI
MACHINE_START(CORGI, "SHARP Corgi")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = fixup_corgi,
.map_io = pxa_map_io,
.init_irq = pxa25x_init_irq,
@@ -732,8 +730,6 @@ MACHINE_END
#ifdef CONFIG_MACH_SHEPHERD
MACHINE_START(SHEPHERD, "SHARP Shepherd")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = fixup_corgi,
.map_io = pxa_map_io,
.init_irq = pxa25x_init_irq,
@@ -744,8 +740,6 @@ MACHINE_END
#ifdef CONFIG_MACH_HUSKY
MACHINE_START(HUSKY, "SHARP Husky")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = fixup_corgi,
.map_io = pxa_map_io,
.init_irq = pxa25x_init_irq,
diff --git a/arch/arm/mach-pxa/cpufreq-pxa3xx.c b/arch/arm/mach-pxa/cpufreq-pxa3xx.c
index 0a0d0fe99220..88fbec05ec50 100644
--- a/arch/arm/mach-pxa/cpufreq-pxa3xx.c
+++ b/arch/arm/mach-pxa/cpufreq-pxa3xx.c
@@ -159,7 +159,7 @@ static int pxa3xx_cpufreq_verify(struct cpufreq_policy *policy)
static unsigned int pxa3xx_cpufreq_get(unsigned int cpu)
{
- return get_clk_frequency_khz(0);
+ return pxa3xx_get_clk_frequency_khz(0);
}
static int pxa3xx_cpufreq_set(struct cpufreq_policy *policy,
@@ -212,7 +212,8 @@ static int pxa3xx_cpufreq_init(struct cpufreq_policy *policy)
policy->cpuinfo.min_freq = 104000;
policy->cpuinfo.max_freq = (cpu_is_pxa320()) ? 806000 : 624000;
policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */
- policy->cur = policy->min = policy->max = get_clk_frequency_khz(0);
+ policy->max = pxa3xx_get_clk_frequency_khz(0);
+ policy->cur = policy->min = policy->max;
if (cpu_is_pxa300() || cpu_is_pxa310())
ret = setup_freqs_table(policy, ARRAY_AND_SIZE(pxa300_freqs));
diff --git a/arch/arm/mach-pxa/csb726.c b/arch/arm/mach-pxa/csb726.c
index 91fd4fea6a54..57cacaff194d 100644
--- a/arch/arm/mach-pxa/csb726.c
+++ b/arch/arm/mach-pxa/csb726.c
@@ -272,9 +272,7 @@ static void __init csb726_init(void)
}
MACHINE_START(CSB726, "Cogent CSB726")
- .phys_io = 0x40000000,
.boot_params = 0xa0000100,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = pxa_map_io,
.init_irq = pxa27x_init_irq,
.init_machine = csb726_init,
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
index 65447dc736c2..08b410343870 100644
--- a/arch/arm/mach-pxa/devices.c
+++ b/arch/arm/mach-pxa/devices.c
@@ -6,11 +6,12 @@
#include <asm/pmu.h>
#include <mach/udc.h>
+#include <mach/pxa3xx-u2d.h>
#include <mach/pxafb.h>
#include <mach/mmc.h>
#include <mach/irda.h>
#include <mach/ohci.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
#include <mach/pxa2xx_spi.h>
#include <mach/camera.h>
#include <mach/audio.h>
@@ -134,6 +135,33 @@ struct platform_device pxa27x_device_udc = {
}
};
+#ifdef CONFIG_PXA3xx
+static struct resource pxa3xx_u2d_resources[] = {
+ [0] = {
+ .start = 0x54100000,
+ .end = 0x54100fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_USB2,
+ .end = IRQ_USB2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device pxa3xx_device_u2d = {
+ .name = "pxa3xx-u2d",
+ .id = -1,
+ .resource = pxa3xx_u2d_resources,
+ .num_resources = ARRAY_SIZE(pxa3xx_u2d_resources),
+};
+
+void __init pxa3xx_set_u2d_info(struct pxa3xx_u2d_platform_data *info)
+{
+ pxa_register_device(&pxa3xx_device_u2d, info);
+}
+#endif /* CONFIG_PXA3xx */
+
static struct resource pxafb_resources[] = {
[0] = {
.start = 0x44000000,
diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h
index 50353ea49ba4..715e8bd02e24 100644
--- a/arch/arm/mach-pxa/devices.h
+++ b/arch/arm/mach-pxa/devices.h
@@ -4,6 +4,7 @@ extern struct platform_device pxa3xx_device_mci2;
extern struct platform_device pxa3xx_device_mci3;
extern struct platform_device pxa25x_device_udc;
extern struct platform_device pxa27x_device_udc;
+extern struct platform_device pxa3xx_device_u2d;
extern struct platform_device pxa_device_fb;
extern struct platform_device pxa_device_ffuart;
extern struct platform_device pxa_device_btuart;
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c
index 0517c17978f3..ab48bb81b570 100644
--- a/arch/arm/mach-pxa/em-x270.c
+++ b/arch/arm/mach-pxa/em-x270.c
@@ -43,7 +43,7 @@
#include <mach/pxafb.h>
#include <mach/ohci.h>
#include <mach/mmc.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
#include <plat/i2c.h>
#include <mach/camera.h>
#include <mach/pxa2xx_spi.h>
@@ -1301,8 +1301,6 @@ static void __init em_x270_init(void)
MACHINE_START(EM_X270, "Compulab EM-X270")
.boot_params = 0xa0000100,
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = pxa_map_io,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
@@ -1311,8 +1309,6 @@ MACHINE_END
MACHINE_START(EXEDA, "Compulab eXeda")
.boot_params = 0xa0000100,
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = pxa_map_io,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c
index 349212a1cbd3..b25690ccadc4 100644
--- a/arch/arm/mach-pxa/eseries.c
+++ b/arch/arm/mach-pxa/eseries.c
@@ -29,6 +29,7 @@
#include <mach/pxa25x.h>
#include <mach/eseries-gpio.h>
+#include <mach/eseries-irq.h>
#include <mach/audio.h>
#include <mach/pxafb.h>
#include <mach/udc.h>
@@ -179,10 +180,9 @@ static void __init e330_init(void)
MACHINE_START(E330, "Toshiba e330")
/* Maintainer: Ian Molton (spyro@f2s.com) */
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .nr_irqs = ESERIES_NR_IRQS,
.init_irq = pxa25x_init_irq,
.fixup = eseries_fixup,
.init_machine = e330_init,
@@ -229,10 +229,9 @@ static void __init e350_init(void)
MACHINE_START(E350, "Toshiba e350")
/* Maintainer: Ian Molton (spyro@f2s.com) */
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .nr_irqs = ESERIES_NR_IRQS,
.init_irq = pxa25x_init_irq,
.fixup = eseries_fixup,
.init_machine = e350_init,
@@ -352,10 +351,9 @@ static void __init e400_init(void)
MACHINE_START(E400, "Toshiba e400")
/* Maintainer: Ian Molton (spyro@f2s.com) */
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .nr_irqs = ESERIES_NR_IRQS,
.init_irq = pxa25x_init_irq,
.fixup = eseries_fixup,
.init_machine = e400_init,
@@ -541,10 +539,9 @@ static void __init e740_init(void)
MACHINE_START(E740, "Toshiba e740")
/* Maintainer: Ian Molton (spyro@f2s.com) */
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .nr_irqs = ESERIES_NR_IRQS,
.init_irq = pxa25x_init_irq,
.fixup = eseries_fixup,
.init_machine = e740_init,
@@ -733,10 +730,9 @@ static void __init e750_init(void)
MACHINE_START(E750, "Toshiba e750")
/* Maintainer: Ian Molton (spyro@f2s.com) */
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .nr_irqs = ESERIES_NR_IRQS,
.init_irq = pxa25x_init_irq,
.fixup = eseries_fixup,
.init_machine = e750_init,
@@ -929,10 +925,9 @@ static void __init e800_init(void)
MACHINE_START(E800, "Toshiba e800")
/* Maintainer: Ian Molton (spyro@f2s.com) */
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .nr_irqs = ESERIES_NR_IRQS,
.init_irq = pxa25x_init_irq,
.fixup = eseries_fixup,
.init_machine = e800_init,
diff --git a/arch/arm/mach-pxa/ezx.c b/arch/arm/mach-pxa/ezx.c
index 626c82b13970..80a9352d43f3 100644
--- a/arch/arm/mach-pxa/ezx.c
+++ b/arch/arm/mach-pxa/ezx.c
@@ -32,12 +32,14 @@
#include <mach/ohci.h>
#include <plat/i2c.h>
#include <mach/hardware.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
#include <mach/camera.h>
#include "devices.h"
#include "generic.h"
+#define EZX_NR_IRQS (IRQ_BOARD_START + 24)
+
#define GPIO12_A780_FLIP_LID 12
#define GPIO15_A1200_FLIP_LID 15
#define GPIO15_A910_FLIP_LID 15
@@ -796,10 +798,9 @@ static void __init a780_init(void)
}
MACHINE_START(EZX_A780, "Motorola EZX A780")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .nr_irqs = EZX_NR_IRQS,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = a780_init,
@@ -862,10 +863,9 @@ static void __init e680_init(void)
}
MACHINE_START(EZX_E680, "Motorola EZX E680")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .nr_irqs = EZX_NR_IRQS,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = e680_init,
@@ -928,10 +928,9 @@ static void __init a1200_init(void)
}
MACHINE_START(EZX_A1200, "Motorola EZX A1200")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .nr_irqs = EZX_NR_IRQS,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = a1200_init,
@@ -1120,10 +1119,9 @@ static void __init a910_init(void)
}
MACHINE_START(EZX_A910, "Motorola EZX A910")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .nr_irqs = EZX_NR_IRQS,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = a910_init,
@@ -1186,10 +1184,9 @@ static void __init e6_init(void)
}
MACHINE_START(EZX_E6, "Motorola EZX E6")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .nr_irqs = EZX_NR_IRQS,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = e6_init,
@@ -1226,10 +1223,9 @@ static void __init e2_init(void)
}
MACHINE_START(EZX_E2, "Motorola EZX E2")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .nr_irqs = EZX_NR_IRQS,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = e2_init,
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index baabb3ce088e..6451e9c3a93f 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -66,8 +66,7 @@ unsigned int get_clk_frequency_khz(int info)
return pxa25x_get_clk_frequency_khz(info);
else if (cpu_is_pxa27x())
return pxa27x_get_clk_frequency_khz(info);
- else
- return pxa3xx_get_clk_frequency_khz(info);
+ return 0;
}
EXPORT_SYMBOL(get_clk_frequency_khz);
@@ -80,8 +79,7 @@ unsigned int get_memclk_frequency_10khz(void)
return pxa25x_get_memclk_frequency_10khz();
else if (cpu_is_pxa27x())
return pxa27x_get_memclk_frequency_10khz();
- else
- return pxa3xx_get_memclk_frequency_10khz();
+ return 0;
}
EXPORT_SYMBOL(get_memclk_frequency_10khz);
diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h
index c6305c5b8a72..4b1ad2769ed7 100644
--- a/arch/arm/mach-pxa/generic.h
+++ b/arch/arm/mach-pxa/generic.h
@@ -54,11 +54,9 @@ static inline void pxa2xx_clear_reset_status(unsigned int mask) {}
#ifdef CONFIG_PXA3xx
extern unsigned pxa3xx_get_clk_frequency_khz(int);
-extern unsigned pxa3xx_get_memclk_frequency_10khz(void);
extern void pxa3xx_clear_reset_status(unsigned int);
#else
#define pxa3xx_get_clk_frequency_khz(x) (0)
-#define pxa3xx_get_memclk_frequency_10khz() (0)
static inline void pxa3xx_clear_reset_status(unsigned int mask) {}
#endif
diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c
index 96c345129135..1e2a9a13aec1 100644
--- a/arch/arm/mach-pxa/gumstix.c
+++ b/arch/arm/mach-pxa/gumstix.c
@@ -224,9 +224,7 @@ static void __init gumstix_init(void)
}
MACHINE_START(GUMSTIX, "Gumstix")
- .phys_io = 0x40000000,
.boot_params = 0xa0000100, /* match u-boot bi_boot_params */
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = pxa_map_io,
.init_irq = pxa25x_init_irq,
.timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/h5000.c b/arch/arm/mach-pxa/h5000.c
index c1cab0871c99..7057a1f46db4 100644
--- a/arch/arm/mach-pxa/h5000.c
+++ b/arch/arm/mach-pxa/h5000.c
@@ -201,8 +201,6 @@ static void __init h5000_init(void)
}
MACHINE_START(H5400, "HP iPAQ H5000")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
.init_irq = pxa25x_init_irq,
diff --git a/arch/arm/mach-pxa/himalaya.c b/arch/arm/mach-pxa/himalaya.c
index f9a2e4b0f090..01b7f07ebad2 100644
--- a/arch/arm/mach-pxa/himalaya.c
+++ b/arch/arm/mach-pxa/himalaya.c
@@ -159,8 +159,6 @@ static void __init himalaya_init(void)
MACHINE_START(HIMALAYA, "HTC Himalaya")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
.init_irq = pxa25x_init_irq,
diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c
index 848c861dd23f..76d93a25bab6 100644
--- a/arch/arm/mach-pxa/hx4700.c
+++ b/arch/arm/mach-pxa/hx4700.c
@@ -870,10 +870,9 @@ static void __init hx4700_init(void)
}
MACHINE_START(H4700, "HP iPAQ HX4700")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .nr_irqs = HX4700_NR_IRQS,
.init_irq = pxa27x_init_irq,
.init_machine = hx4700_init,
.timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/icontrol.c b/arch/arm/mach-pxa/icontrol.c
index 5ccb0ceff6c4..d51ee3d25e70 100644
--- a/arch/arm/mach-pxa/icontrol.c
+++ b/arch/arm/mach-pxa/icontrol.c
@@ -191,9 +191,7 @@ static void __init icontrol_init(void)
}
MACHINE_START(ICONTROL, "iControl/SafeTcam boards using Embedian MXM-8x10 CoM")
- .phys_io = 0x40000000,
.boot_params = 0xa0000100,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = pxa_map_io,
.init_irq = pxa3xx_init_irq,
.timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
index bc78c4dc0c66..e773dceeabc6 100644
--- a/arch/arm/mach-pxa/idp.c
+++ b/arch/arm/mach-pxa/idp.c
@@ -194,8 +194,6 @@ static void __init idp_map_io(void)
MACHINE_START(PXA_IDP, "Vibren PXA255 IDP")
/* Maintainer: Vibren Technologies */
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = idp_map_io,
.init_irq = pxa25x_init_irq,
.timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/include/mach/balloon3.h b/arch/arm/mach-pxa/include/mach/balloon3.h
index eec92e6fd7cf..561562b4360b 100644
--- a/arch/arm/mach-pxa/include/mach/balloon3.h
+++ b/arch/arm/mach-pxa/include/mach/balloon3.h
@@ -174,6 +174,8 @@ enum balloon3_features {
#define BALLOON3_CODEC_IRQ IRQ_GPIO(BALLOON3_GPIO_CODEC_IRQ)
#define BALLOON3_S0_CD_IRQ IRQ_GPIO(BALLOON3_GPIO_S0_CD)
+#define BALLOON3_NR_IRQS (IRQ_BOARD_START + 4)
+
extern int balloon3_has(enum balloon3_features feature);
#endif
diff --git a/arch/arm/mach-pxa/include/mach/debug-macro.S b/arch/arm/mach-pxa/include/mach/debug-macro.S
index 01cf81393fe2..7d5c75125d65 100644
--- a/arch/arm/mach-pxa/include/mach/debug-macro.S
+++ b/arch/arm/mach-pxa/include/mach/debug-macro.S
@@ -13,12 +13,10 @@
#include "hardware.h"
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- moveq \rx, #0x40000000 @ physical
- movne \rx, #io_p2v(0x40000000) @ virtual
- orr \rx, \rx, #0x00100000
+ .macro addruart, rp, rv
+ mov \rp, #0x00100000
+ orr \rv, \rp, #io_p2v(0x40000000) @ virtual
+ orr \rp, \rp, #0x40000000 @ physical
.endm
#define UART_SHIFT 2
diff --git a/arch/arm/mach-pxa/include/mach/eseries-irq.h b/arch/arm/mach-pxa/include/mach/eseries-irq.h
index f2a93d5e31d3..de292b269c63 100644
--- a/arch/arm/mach-pxa/include/mach/eseries-irq.h
+++ b/arch/arm/mach-pxa/include/mach/eseries-irq.h
@@ -25,3 +25,4 @@
#define TMIO_SD_IRQ IRQ_TMIO(1)
#define TMIO_USB_IRQ IRQ_TMIO(2)
+#define ESERIES_NR_IRQS (IRQ_BOARD_START + 16)
diff --git a/arch/arm/mach-pxa/include/mach/hx4700.h b/arch/arm/mach-pxa/include/mach/hx4700.h
index 9eaeed1f87f1..37408449ec25 100644
--- a/arch/arm/mach-pxa/include/mach/hx4700.h
+++ b/arch/arm/mach-pxa/include/mach/hx4700.h
@@ -17,6 +17,7 @@
#define HX4700_ASIC3_GPIO_BASE NR_BUILTIN_GPIO
#define HX4700_EGPIO_BASE (HX4700_ASIC3_GPIO_BASE + ASIC3_NUM_GPIOS)
+#define HX4700_NR_IRQS (IRQ_BOARD_START + 70)
/*
* PXA GPIOs
diff --git a/arch/arm/mach-pxa/include/mach/irqs.h b/arch/arm/mach-pxa/include/mach/irqs.h
index ffc8314520f2..d372caa75dc7 100644
--- a/arch/arm/mach-pxa/include/mach/irqs.h
+++ b/arch/arm/mach-pxa/include/mach/irqs.h
@@ -117,48 +117,12 @@
/*
* The following interrupts are for board specific purposes. Since
* the kernel can only run on one machine at a time, we can re-use
- * these. There will be 16 IRQs by default. If it is not enough,
- * IRQ_BOARD_END is allowed be customized for each board, but keep
- * the numbers within sensible limits and in descending order, so
- * when multiple config options are selected, the maximum will be
- * used.
+ * these.
+ * By default, no board IRQ is reserved. It should be finished in
+ * custom board since sparse IRQ is already enabled.
*/
#define IRQ_BOARD_START (PXA_GPIO_IRQ_BASE + PXA_GPIO_IRQ_NUM)
-#if defined(CONFIG_MACH_H4700)
-#define IRQ_BOARD_END (IRQ_BOARD_START + 70)
-#elif defined(CONFIG_MACH_ZYLONITE)
-#define IRQ_BOARD_END (IRQ_BOARD_START + 32)
-#elif defined(CONFIG_PXA_EZX)
-#define IRQ_BOARD_END (IRQ_BOARD_START + 23)
-#else
-#define IRQ_BOARD_END (IRQ_BOARD_START + 16)
-#endif
-
-/*
- * Figure out the MAX IRQ number.
- *
- * If we have an SA1111, the max IRQ is S1_BVD1_STSCHG+1.
- * If we have an LoCoMo, the max IRQ is IRQ_LOCOMO_SPI_TEND+1
- * Otherwise, we have the standard IRQs only.
- */
-#ifdef CONFIG_SA1111
-#define NR_IRQS (IRQ_BOARD_END + 55)
-#elif defined(CONFIG_PXA_HAVE_BOARD_IRQS)
-#define NR_IRQS (IRQ_BOARD_END)
-#else
#define NR_IRQS (IRQ_BOARD_START)
-#endif
-
-/* add IT8152 IRQs beyond BOARD_END */
-#ifdef CONFIG_PCI_HOST_ITE8152
-#define IT8152_LAST_IRQ (IRQ_BOARD_END + 40)
-
-#if NR_IRQS < (IT8152_LAST_IRQ+1)
-#undef NR_IRQS
-#define NR_IRQS (IT8152_LAST_IRQ+1)
-#endif
-
-#endif /* CONFIG_PCI_HOST_ITE8152 */
#endif /* __ASM_MACH_IRQS_H */
diff --git a/arch/arm/mach-pxa/include/mach/littleton.h b/arch/arm/mach-pxa/include/mach/littleton.h
index 6c9b21c51322..2a5726c15e0e 100644
--- a/arch/arm/mach-pxa/include/mach/littleton.h
+++ b/arch/arm/mach-pxa/include/mach/littleton.h
@@ -10,4 +10,6 @@
#define EXT0_GPIO_BASE (NR_BUILTIN_GPIO)
#define EXT0_GPIO(x) (EXT0_GPIO_BASE + (x))
+#define LITTLETON_NR_IRQS (IRQ_BOARD_START + 8)
+
#endif /* __ASM_ARCH_LITTLETON_H */
diff --git a/arch/arm/mach-pxa/include/mach/lpd270.h b/arch/arm/mach-pxa/include/mach/lpd270.h
index 0e6440c81683..cd070092b6eb 100644
--- a/arch/arm/mach-pxa/include/mach/lpd270.h
+++ b/arch/arm/mach-pxa/include/mach/lpd270.h
@@ -38,5 +38,6 @@
#define LPD270_USBC_IRQ LPD270_IRQ(2)
#define LPD270_ETHERNET_IRQ LPD270_IRQ(3)
#define LPD270_AC97_IRQ LPD270_IRQ(4)
+#define LPD270_NR_IRQS (IRQ_BOARD_START + 5)
#endif
diff --git a/arch/arm/mach-pxa/include/mach/lubbock.h b/arch/arm/mach-pxa/include/mach/lubbock.h
index a0d4247f08fc..2a086e8373eb 100644
--- a/arch/arm/mach-pxa/include/mach/lubbock.h
+++ b/arch/arm/mach-pxa/include/mach/lubbock.h
@@ -45,6 +45,9 @@
#define LUBBOCK_USB_DISC_IRQ LUBBOCK_IRQ(6) /* usb disconnect */
#define LUBBOCK_LAST_IRQ LUBBOCK_IRQ(6)
+#define LUBBOCK_SA1111_IRQ_BASE (IRQ_BOARD_START + 16)
+#define LUBBOCK_NR_IRQS (IRQ_BOARD_START + 16 + 55)
+
#ifndef __ASSEMBLY__
extern void lubbock_set_misc_wr(unsigned int mask, unsigned int set);
#endif
diff --git a/arch/arm/mach-pxa/include/mach/magician.h b/arch/arm/mach-pxa/include/mach/magician.h
index 20ef37d4a9a7..0a2efcf7947c 100644
--- a/arch/arm/mach-pxa/include/mach/magician.h
+++ b/arch/arm/mach-pxa/include/mach/magician.h
@@ -71,6 +71,8 @@
#define IRQ_MAGICIAN_BT (IRQ_BOARD_START + 2)
#define IRQ_MAGICIAN_VBUS (IRQ_BOARD_START + 3)
+#define MAGICIAN_NR_IRQS (IRQ_BOARD_START + 8)
+
/*
* CPLD EGPIOs
*/
diff --git a/arch/arm/mach-pxa/include/mach/mainstone.h b/arch/arm/mach-pxa/include/mach/mainstone.h
index 86e623abd64d..4c2d11cd824d 100644
--- a/arch/arm/mach-pxa/include/mach/mainstone.h
+++ b/arch/arm/mach-pxa/include/mach/mainstone.h
@@ -134,4 +134,6 @@
#define MAINSTONE_S1_STSCHG_IRQ MAINSTONE_IRQ(14)
#define MAINSTONE_S1_IRQ MAINSTONE_IRQ(15)
+#define MAINSTONE_NR_IRQS (IRQ_BOARD_START + 16)
+
#endif
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa930.h b/arch/arm/mach-pxa/include/mach/mfp-pxa930.h
index 0d119d3b9221..04f7c97044f3 100644
--- a/arch/arm/mach-pxa/include/mach/mfp-pxa930.h
+++ b/arch/arm/mach-pxa/include/mach/mfp-pxa930.h
@@ -69,6 +69,7 @@
#define nBE0_GPIO_60 MFP_CFG(nBE0, AF0)
#define nBE1_GPIO_61 MFP_CFG(nBE1, AF0)
#define RDY_GPIO_62 MFP_CFG(RDY, AF0)
+#define PMIC_INT_GPIO83 MFP_CFG_LPM(PMIC_INT, AF0, PULL_HIGH)
/* Chip Select */
#define DF_nCS0_nCS2 MFP_CFG_LPM(DF_nCS0, AF3, PULL_HIGH)
@@ -92,6 +93,9 @@
#define GPIO63_CI2C_SCL MFP_CFG_LPM(GPIO63, AF4, PULL_HIGH)
#define GPIO64_CI2C_SDA MFP_CFG_LPM(GPIO64, AF4, PULL_HIGH)
+#define GPIO73_CI2C_SCL MFP_CFG_LPM(GPIO73, AF1, PULL_HIGH)
+#define GPIO74_CI2C_SDA MFP_CFG_LPM(GPIO74, AF1, PULL_HIGH)
+
#define GPIO77_CI2C_SCL MFP_CFG_LPM(GPIO77, AF2, PULL_HIGH)
#define GPIO78_CI2C_SDA MFP_CFG_LPM(GPIO78, AF2, PULL_HIGH)
@@ -345,6 +349,9 @@
#define GPIO69_UART1_CTS MFP_CFG(GPIO69, AF2)
#define GPIO70_UART1_RTS MFP_CFG(GPIO70, AF2)
+#define GPIO53_UART1_TXD MFP_CFG(GPIO53, AF2)
+#define GPIO54_UART1_RXD MFP_CFG(GPIO54, AF2)
+
/* UART2 - BTUART */
#define GPIO91_UART2_RXD MFP_CFG(GPIO91, AF1)
#define GPIO92_UART2_TXD MFP_CFG(GPIO92, AF1)
diff --git a/arch/arm/mach-pxa/include/mach/pcm027.h b/arch/arm/mach-pxa/include/mach/pcm027.h
index 04083263167e..4bac588478a8 100644
--- a/arch/arm/mach-pxa/include/mach/pcm027.h
+++ b/arch/arm/mach-pxa/include/mach/pcm027.h
@@ -30,6 +30,8 @@
#define PCM027_MMCDET_IRQ PCM027_IRQ(2)
#define PCM027_PM_5V_IRQ PCM027_IRQ(3)
+#define PCM027_NR_IRQS (IRQ_BOARD_START + 32)
+
/* I2C RTC */
#define PCM027_RTC_IRQ_GPIO 0
#define PCM027_RTC_IRQ IRQ_GPIO(PCM027_RTC_IRQ_GPIO)
diff --git a/arch/arm/mach-pxa/include/mach/poodle.h b/arch/arm/mach-pxa/include/mach/poodle.h
index 0b3e6d051c64..83d1cfd00fc9 100644
--- a/arch/arm/mach-pxa/include/mach/poodle.h
+++ b/arch/arm/mach-pxa/include/mach/poodle.h
@@ -85,6 +85,8 @@
#define POODLE_LOCOMO_GPIO_232VCC_ON LOCOMO_GPIO(12)
#define POODLE_LOCOMO_GPIO_JK_B LOCOMO_GPIO(13)
+#define POODLE_NR_IRQS (IRQ_BOARD_START + 4) /* 4 for LoCoMo */
+
extern struct platform_device poodle_locomo_device;
#endif /* __ASM_ARCH_POODLE_H */
diff --git a/arch/arm/mach-pxa/include/mach/pxa3xx-u2d.h b/arch/arm/mach-pxa/include/mach/pxa3xx-u2d.h
new file mode 100644
index 000000000000..9d82cb65ea56
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxa3xx-u2d.h
@@ -0,0 +1,35 @@
+/*
+ * PXA3xx U2D header
+ *
+ * Copyright (C) 2010 CompuLab Ltd.
+ *
+ * Igor Grinberg <grinberg@compulab.co.il>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __PXA310_U2D__
+#define __PXA310_U2D__
+
+#include <linux/usb/ulpi.h>
+
+struct pxa3xx_u2d_platform_data {
+
+#define ULPI_SER_6PIN (1 << 0)
+#define ULPI_SER_3PIN (1 << 1)
+ unsigned int ulpi_mode;
+
+ int (*init)(struct device *);
+ void (*exit)(struct device *);
+};
+
+
+/* Start PXA3xx U2D host */
+int pxa3xx_u2d_start_hc(struct usb_bus *host);
+/* Stop PXA3xx U2D host */
+void pxa3xx_u2d_stop_hc(struct usb_bus *host);
+
+extern void pxa3xx_set_u2d_info(struct pxa3xx_u2d_platform_data *info);
+
+#endif /* __PXA310_U2D__ */
diff --git a/arch/arm/mach-pxa/include/mach/tosa.h b/arch/arm/mach-pxa/include/mach/tosa.h
index 1bbd1f2e4beb..1272c4b56ceb 100644
--- a/arch/arm/mach-pxa/include/mach/tosa.h
+++ b/arch/arm/mach-pxa/include/mach/tosa.h
@@ -20,6 +20,7 @@
/* Jacket Scoop */
#define TOSA_SCOOP_PHYS (PXA_CS5_PHYS + 0x00800000)
+#define TOSA_NR_IRQS (IRQ_BOARD_START + TC6393XB_NR_IRQS)
/*
* SCOOP2 internal GPIOs
*/
diff --git a/arch/arm/mach-pxa/include/mach/zeus.h b/arch/arm/mach-pxa/include/mach/zeus.h
index 6e119976003e..faa408ab7ad7 100644
--- a/arch/arm/mach-pxa/include/mach/zeus.h
+++ b/arch/arm/mach-pxa/include/mach/zeus.h
@@ -15,6 +15,8 @@
#ifndef _MACH_ZEUS_H
#define _MACH_ZEUS_H
+#define ZEUS_NR_IRQS (IRQ_BOARD_START + 48)
+
/* Physical addresses */
#define ZEUS_FLASH_PHYS PXA_CS0_PHYS
#define ZEUS_ETH0_PHYS PXA_CS1_PHYS
diff --git a/arch/arm/mach-pxa/include/mach/zylonite.h b/arch/arm/mach-pxa/include/mach/zylonite.h
index 9edf645368d6..ea24998b923c 100644
--- a/arch/arm/mach-pxa/include/mach/zylonite.h
+++ b/arch/arm/mach-pxa/include/mach/zylonite.h
@@ -5,6 +5,8 @@
#define EXT_GPIO(x) (128 + (x))
+#define ZYLONITE_NR_IRQS (IRQ_BOARD_START + 32)
+
/* the following variables are processor specific and initialized
* by the corresponding zylonite_pxa3xx_init()
*/
diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c
index 9b9046185b00..41aa89e35772 100644
--- a/arch/arm/mach-pxa/littleton.c
+++ b/arch/arm/mach-pxa/littleton.c
@@ -43,7 +43,7 @@
#include <mach/pxafb.h>
#include <mach/mmc.h>
#include <mach/pxa2xx_spi.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
#include <mach/littleton.h>
#include <plat/i2c.h>
#include <plat/pxa3xx_nand.h>
@@ -437,10 +437,9 @@ static void __init littleton_init(void)
}
MACHINE_START(LITTLETON, "Marvell Form Factor Development Platform (aka Littleton)")
- .phys_io = 0x40000000,
.boot_params = 0xa0000100,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = pxa_map_io,
+ .nr_irqs = LITTLETON_NR_IRQS,
.init_irq = pxa3xx_init_irq,
.timer = &pxa_timer,
.init_machine = littleton_init,
diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c
index d279507fc748..623af0232a54 100644
--- a/arch/arm/mach-pxa/lpd270.c
+++ b/arch/arm/mach-pxa/lpd270.c
@@ -505,10 +505,9 @@ static void __init lpd270_map_io(void)
MACHINE_START(LOGICPD_PXA270, "LogicPD PXA270 Card Engine")
/* Maintainer: Peter Barada */
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = lpd270_map_io,
+ .nr_irqs = LPD270_NR_IRQS,
.init_irq = lpd270_init_irq,
.timer = &pxa_timer,
.init_machine = lpd270_init,
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 330c3282856e..1499493cd070 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -229,7 +229,7 @@ static struct resource sa1111_resources[] = {
};
static struct sa1111_platform_data sa1111_info = {
- .irq_base = IRQ_BOARD_END,
+ .irq_base = LUBBOCK_SA1111_IRQ_BASE,
};
static struct platform_device sa1111_device = {
@@ -557,9 +557,8 @@ static void __init lubbock_map_io(void)
MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform (aka Lubbock)")
/* Maintainer: MontaVista Software Inc. */
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = lubbock_map_io,
+ .nr_irqs = LUBBOCK_NR_IRQS,
.init_irq = lubbock_init_irq,
.timer = &pxa_timer,
.init_machine = lubbock_init,
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index e81dd0c8e40d..90663760307a 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -764,10 +764,9 @@ static void __init magician_init(void)
MACHINE_START(MAGICIAN, "HTC Magician")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .nr_irqs = MAGICIAN_NR_IRQS,
.init_irq = pxa27x_init_irq,
.init_machine = magician_init,
.timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index 5543c64da9ef..a980a5c93e49 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -50,7 +50,7 @@
#include <mach/mmc.h>
#include <mach/irda.h>
#include <mach/ohci.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
#include "generic.h"
#include "devices.h"
@@ -624,10 +624,9 @@ static void __init mainstone_map_io(void)
MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)")
/* Maintainer: MontaVista Software Inc. */
- .phys_io = 0x40000000,
.boot_params = 0xa0000100, /* BLOB boot parameter setting */
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = mainstone_map_io,
+ .nr_irqs = MAINSTONE_NR_IRQS,
.init_irq = mainstone_init_irq,
.timer = &pxa_timer,
.init_machine = mainstone_init,
diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c
index dc66942ef9ab..0c31fabfc7fd 100644
--- a/arch/arm/mach-pxa/mioa701.c
+++ b/arch/arm/mach-pxa/mioa701.c
@@ -45,7 +45,7 @@
#include <mach/pxa27x.h>
#include <mach/regs-rtc.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
#include <mach/pxafb.h>
#include <mach/mmc.h>
#include <mach/udc.h>
@@ -819,8 +819,6 @@ static void mioa701_machine_exit(void)
}
MACHINE_START(MIOA701, "MIO A701")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = &pxa_map_io,
.init_irq = &pxa27x_init_irq,
diff --git a/arch/arm/mach-pxa/mp900.c b/arch/arm/mach-pxa/mp900.c
index 6d4503927a76..116167aaba68 100644
--- a/arch/arm/mach-pxa/mp900.c
+++ b/arch/arm/mach-pxa/mp900.c
@@ -92,9 +92,7 @@ static void __init mp900c_init(void)
/* Maintainer - Michael Petchkovsky <mkpetch@internode.on.net> */
MACHINE_START(NEC_MP900, "MobilePro900/C")
- .phys_io = 0x40000000,
.boot_params = 0xa0220100,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.timer = &pxa_timer,
.map_io = pxa_map_io,
.init_irq = pxa25x_init_irq,
diff --git a/arch/arm/mach-pxa/palmld.c b/arch/arm/mach-pxa/palmld.c
index 91038eeafe44..ce092c521e6d 100644
--- a/arch/arm/mach-pxa/palmld.c
+++ b/arch/arm/mach-pxa/palmld.c
@@ -39,7 +39,7 @@
#include <mach/mmc.h>
#include <mach/pxafb.h>
#include <mach/irda.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
#include <mach/palmasoc.h>
#include <mach/palm27x.h>
@@ -343,8 +343,6 @@ static void __init palmld_init(void)
}
MACHINE_START(PALMLD, "Palm LifeDrive")
- .phys_io = PALMLD_PHYS_IO_START,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = palmld_map_io,
.init_irq = pxa27x_init_irq,
diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c
index 1c281995f658..862da812cd10 100644
--- a/arch/arm/mach-pxa/palmt5.c
+++ b/arch/arm/mach-pxa/palmt5.c
@@ -39,7 +39,7 @@
#include <mach/mmc.h>
#include <mach/pxafb.h>
#include <mach/irda.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
#include <mach/udc.h>
#include <mach/palmasoc.h>
#include <mach/palm27x.h>
@@ -202,8 +202,6 @@ static void __init palmt5_init(void)
}
MACHINE_START(PALMT5, "Palm Tungsten|T5")
- .phys_io = PALMT5_PHYS_IO_START,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
.reserve = palmt5_reserve,
diff --git a/arch/arm/mach-pxa/palmtc.c b/arch/arm/mach-pxa/palmtc.c
index ce1104d1bc17..2131d5860919 100644
--- a/arch/arm/mach-pxa/palmtc.c
+++ b/arch/arm/mach-pxa/palmtc.c
@@ -412,9 +412,7 @@ static void __init palmtc_init(void)
};
MACHINE_START(PALMTC, "Palm Tungsten|C")
- .phys_io = 0x40000000,
.boot_params = 0xa0000100,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = pxa_map_io,
.init_irq = pxa25x_init_irq,
.timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/palmte2.c b/arch/arm/mach-pxa/palmte2.c
index 93c11a0438d5..a9dae7bc35d9 100644
--- a/arch/arm/mach-pxa/palmte2.c
+++ b/arch/arm/mach-pxa/palmte2.c
@@ -373,8 +373,6 @@ static void __init palmte2_init(void)
}
MACHINE_START(PALMTE2, "Palm Tungsten|E2")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
.init_irq = pxa25x_init_irq,
diff --git a/arch/arm/mach-pxa/palmtreo.c b/arch/arm/mach-pxa/palmtreo.c
index 52defd5e42e5..00e2d7ba84ed 100644
--- a/arch/arm/mach-pxa/palmtreo.c
+++ b/arch/arm/mach-pxa/palmtreo.c
@@ -39,7 +39,7 @@
#include <mach/mmc.h>
#include <mach/pxafb.h>
#include <mach/irda.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
#include <mach/udc.h>
#include <mach/ohci.h>
#include <mach/pxa2xx-regs.h>
@@ -441,8 +441,6 @@ static void __init centro_init(void)
}
MACHINE_START(TREO680, "Palm Treo 680")
- .phys_io = TREO_PHYS_IO_START,
- .io_pg_offst = io_p2v(0x40000000),
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
.reserve = treo_reserve,
@@ -452,8 +450,6 @@ MACHINE_START(TREO680, "Palm Treo 680")
MACHINE_END
MACHINE_START(CENTRO, "Palm Centro 685")
- .phys_io = TREO_PHYS_IO_START,
- .io_pg_offst = io_p2v(0x40000000),
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
.reserve = treo_reserve,
diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c
index 144dc2b6911f..d2060a1d1d68 100644
--- a/arch/arm/mach-pxa/palmtx.c
+++ b/arch/arm/mach-pxa/palmtx.c
@@ -43,7 +43,7 @@
#include <mach/mmc.h>
#include <mach/pxafb.h>
#include <mach/irda.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
#include <mach/udc.h>
#include <mach/palmasoc.h>
#include <mach/palm27x.h>
@@ -363,8 +363,6 @@ static void __init palmtx_init(void)
}
MACHINE_START(PALMTX, "Palm T|X")
- .phys_io = PALMTX_PHYS_IO_START,
- .io_pg_offst = io_p2v(0x40000000),
.boot_params = 0xa0000100,
.map_io = palmtx_map_io,
.init_irq = pxa27x_init_irq,
diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c
index 87e4b1044e0b..af6203fbca9c 100644
--- a/arch/arm/mach-pxa/palmz72.c
+++ b/arch/arm/mach-pxa/palmz72.c
@@ -41,7 +41,7 @@
#include <mach/mmc.h>
#include <mach/pxafb.h>
#include <mach/irda.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
#include <mach/udc.h>
#include <mach/palmasoc.h>
#include <mach/palm27x.h>
@@ -279,8 +279,6 @@ static void __init palmz72_init(void)
}
MACHINE_START(PALMZ72, "Palm Zire72")
- .phys_io = 0x40000000,
- .io_pg_offst = io_p2v(0x40000000),
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
.init_irq = pxa27x_init_irq,
diff --git a/arch/arm/mach-pxa/pcm027.c b/arch/arm/mach-pxa/pcm027.c
index 2190af066470..c77e8f30a439 100644
--- a/arch/arm/mach-pxa/pcm027.c
+++ b/arch/arm/mach-pxa/pcm027.c
@@ -259,9 +259,8 @@ static void __init pcm027_map_io(void)
MACHINE_START(PCM027, "Phytec Messtechnik GmbH phyCORE-PXA270")
/* Maintainer: Pengutronix */
.boot_params = 0xa0000100,
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = pcm027_map_io,
+ .nr_irqs = PCM027_NR_IRQS,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = pcm027_init,
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 55e8fcde0141..93a191c889df 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -465,10 +465,9 @@ static void __init fixup_poodle(struct machine_desc *desc,
}
MACHINE_START(POODLE, "SHARP Poodle")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = fixup_poodle,
.map_io = pxa_map_io,
+ .nr_irqs = POODLE_NR_IRQS, /* 4 for LoCoMo */
.init_irq = pxa25x_init_irq,
.timer = &pxa_timer,
.init_machine = poodle_init,
diff --git a/arch/arm/mach-pxa/pxa3xx-ulpi.c b/arch/arm/mach-pxa/pxa3xx-ulpi.c
new file mode 100644
index 000000000000..ce7168b233e2
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa3xx-ulpi.c
@@ -0,0 +1,400 @@
+/*
+ * linux/arch/arm/mach-pxa/pxa3xx-ulpi.c
+ *
+ * code specific to pxa3xx aka Monahans
+ *
+ * Copyright (C) 2010 CompuLab Ltd.
+ *
+ * 2010-13-07: Igor Grinberg <grinberg@compulab.co.il>
+ * initial version: pxa310 USB Host mode support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/usb.h>
+#include <linux/usb/otg.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-u2d.h>
+#include <mach/pxa3xx-u2d.h>
+
+struct pxa3xx_u2d_ulpi {
+ struct clk *clk;
+ void __iomem *mmio_base;
+
+ struct otg_transceiver *otg;
+ unsigned int ulpi_mode;
+};
+
+static struct pxa3xx_u2d_ulpi *u2d;
+
+static inline u32 u2d_readl(u32 reg)
+{
+ return __raw_readl(u2d->mmio_base + reg);
+}
+
+static inline void u2d_writel(u32 reg, u32 val)
+{
+ __raw_writel(val, u2d->mmio_base + reg);
+}
+
+#if defined(CONFIG_PXA310_ULPI)
+enum u2d_ulpi_phy_mode {
+ SYNCH = 0,
+ CARKIT = (1 << 0),
+ SER_3PIN = (1 << 1),
+ SER_6PIN = (1 << 2),
+ LOWPOWER = (1 << 3),
+};
+
+static inline enum u2d_ulpi_phy_mode pxa310_ulpi_get_phymode(void)
+{
+ return (u2d_readl(U2DOTGUSR) >> 28) & 0xF;
+}
+
+static int pxa310_ulpi_poll(void)
+{
+ int timeout = 50000;
+
+ while (timeout--) {
+ if (!(u2d_readl(U2DOTGUCR) & U2DOTGUCR_RUN))
+ return 0;
+
+ cpu_relax();
+ }
+
+ pr_warning("%s: ULPI access timed out!\n", __func__);
+
+ return -ETIMEDOUT;
+}
+
+static int pxa310_ulpi_read(struct otg_transceiver *otg, u32 reg)
+{
+ int err;
+
+ if (pxa310_ulpi_get_phymode() != SYNCH) {
+ pr_warning("%s: PHY is not in SYNCH mode!\n", __func__);
+ return -EBUSY;
+ }
+
+ u2d_writel(U2DOTGUCR, U2DOTGUCR_RUN | U2DOTGUCR_RNW | (reg << 16));
+ msleep(5);
+
+ err = pxa310_ulpi_poll();
+ if (err)
+ return err;
+
+ return u2d_readl(U2DOTGUCR) & U2DOTGUCR_RDATA;
+}
+
+static int pxa310_ulpi_write(struct otg_transceiver *otg, u32 val, u32 reg)
+{
+ if (pxa310_ulpi_get_phymode() != SYNCH) {
+ pr_warning("%s: PHY is not in SYNCH mode!\n", __func__);
+ return -EBUSY;
+ }
+
+ u2d_writel(U2DOTGUCR, U2DOTGUCR_RUN | (reg << 16) | (val << 8));
+ msleep(5);
+
+ return pxa310_ulpi_poll();
+}
+
+struct otg_io_access_ops pxa310_ulpi_access_ops = {
+ .read = pxa310_ulpi_read,
+ .write = pxa310_ulpi_write,
+};
+
+static void pxa310_otg_transceiver_rtsm(void)
+{
+ u32 u2dotgcr;
+
+ /* put PHY to sync mode */
+ u2dotgcr = u2d_readl(U2DOTGCR);
+ u2dotgcr |= U2DOTGCR_RTSM | U2DOTGCR_UTMID;
+ u2d_writel(U2DOTGCR, u2dotgcr);
+ msleep(10);
+
+ /* setup OTG sync mode */
+ u2dotgcr = u2d_readl(U2DOTGCR);
+ u2dotgcr |= U2DOTGCR_ULAF;
+ u2dotgcr &= ~(U2DOTGCR_SMAF | U2DOTGCR_CKAF);
+ u2d_writel(U2DOTGCR, u2dotgcr);
+}
+
+static int pxa310_start_otg_host_transcvr(struct usb_bus *host)
+{
+ int err;
+
+ pxa310_otg_transceiver_rtsm();
+
+ err = otg_init(u2d->otg);
+ if (err) {
+ pr_err("OTG transceiver init failed");
+ return err;
+ }
+
+ err = otg_set_vbus(u2d->otg, 1);
+ if (err) {
+ pr_err("OTG transceiver VBUS set failed");
+ return err;
+ }
+
+ err = otg_set_host(u2d->otg, host);
+ if (err)
+ pr_err("OTG transceiver Host mode set failed");
+
+ return err;
+}
+
+static int pxa310_start_otg_hc(struct usb_bus *host)
+{
+ u32 u2dotgcr;
+ int err;
+
+ /* disable USB device controller */
+ u2d_writel(U2DCR, u2d_readl(U2DCR) & ~U2DCR_UDE);
+ u2d_writel(U2DOTGCR, u2d_readl(U2DOTGCR) | U2DOTGCR_UTMID);
+ u2d_writel(U2DOTGICR, u2d_readl(U2DOTGICR) & ~0x37F7F);
+
+ err = pxa310_start_otg_host_transcvr(host);
+ if (err)
+ return err;
+
+ /* set xceiver mode */
+ if (u2d->ulpi_mode & ULPI_IC_6PIN_SERIAL)
+ u2d_writel(U2DP3CR, u2d_readl(U2DP3CR) & ~U2DP3CR_P2SS);
+ else if (u2d->ulpi_mode & ULPI_IC_3PIN_SERIAL)
+ u2d_writel(U2DP3CR, u2d_readl(U2DP3CR) | U2DP3CR_P2SS);
+
+ /* start OTG host controller */
+ u2dotgcr = u2d_readl(U2DOTGCR) | U2DOTGCR_SMAF;
+ u2d_writel(U2DOTGCR, u2dotgcr & ~(U2DOTGCR_ULAF | U2DOTGCR_CKAF));
+
+ return 0;
+}
+
+static void pxa310_stop_otg_hc(void)
+{
+ pxa310_otg_transceiver_rtsm();
+
+ otg_set_host(u2d->otg, NULL);
+ otg_set_vbus(u2d->otg, 0);
+ otg_shutdown(u2d->otg);
+}
+
+static void pxa310_u2d_setup_otg_hc(void)
+{
+ u32 u2dotgcr;
+
+ u2dotgcr = u2d_readl(U2DOTGCR);
+ u2dotgcr |= U2DOTGCR_ULAF | U2DOTGCR_UTMID;
+ u2dotgcr &= ~(U2DOTGCR_SMAF | U2DOTGCR_CKAF);
+ u2d_writel(U2DOTGCR, u2dotgcr);
+ msleep(5);
+ u2d_writel(U2DOTGCR, u2dotgcr | U2DOTGCR_ULE);
+ msleep(5);
+ u2d_writel(U2DOTGICR, u2d_readl(U2DOTGICR) & ~0x37F7F);
+}
+
+static int pxa310_otg_init(struct pxa3xx_u2d_platform_data *pdata)
+{
+ unsigned int ulpi_mode = ULPI_OTG_DRVVBUS;
+
+ if (pdata) {
+ if (pdata->ulpi_mode & ULPI_SER_6PIN)
+ ulpi_mode |= ULPI_IC_6PIN_SERIAL;
+ else if (pdata->ulpi_mode & ULPI_SER_3PIN)
+ ulpi_mode |= ULPI_IC_3PIN_SERIAL;
+ }
+
+ u2d->ulpi_mode = ulpi_mode;
+
+ u2d->otg = otg_ulpi_create(&pxa310_ulpi_access_ops, ulpi_mode);
+ if (!u2d->otg)
+ return -ENOMEM;
+
+ u2d->otg->io_priv = u2d->mmio_base;
+
+ return 0;
+}
+
+static void pxa310_otg_exit(void)
+{
+ kfree(u2d->otg);
+}
+#else
+static inline void pxa310_u2d_setup_otg_hc(void) {}
+static inline int pxa310_start_otg_hc(struct usb_bus *host)
+{
+ return 0;
+}
+static inline void pxa310_stop_otg_hc(void) {}
+static inline int pxa310_otg_init(struct pxa3xx_u2d_platform_data *pdata)
+{
+ return 0;
+}
+static inline void pxa310_otg_exit(void) {}
+#endif /* CONFIG_PXA310_ULPI */
+
+int pxa3xx_u2d_start_hc(struct usb_bus *host)
+{
+ int err = 0;
+
+ /* In case the PXA3xx ULPI isn't used, do nothing. */
+ if (!u2d)
+ return 0;
+
+ clk_enable(u2d->clk);
+
+ if (cpu_is_pxa310()) {
+ pxa310_u2d_setup_otg_hc();
+ err = pxa310_start_otg_hc(host);
+ }
+
+ return err;
+}
+
+void pxa3xx_u2d_stop_hc(struct usb_bus *host)
+{
+ /* In case the PXA3xx ULPI isn't used, do nothing. */
+ if (!u2d)
+ return;
+
+ if (cpu_is_pxa310())
+ pxa310_stop_otg_hc();
+
+ clk_disable(u2d->clk);
+}
+
+static int pxa3xx_u2d_probe(struct platform_device *pdev)
+{
+ struct pxa3xx_u2d_platform_data *pdata = pdev->dev.platform_data;
+ struct resource *r;
+ int err;
+
+ u2d = kzalloc(sizeof(struct pxa3xx_u2d_ulpi), GFP_KERNEL);
+ if (!u2d) {
+ dev_err(&pdev->dev, "failed to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ u2d->clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(u2d->clk)) {
+ dev_err(&pdev->dev, "failed to get u2d clock\n");
+ err = PTR_ERR(u2d->clk);
+ goto err_free_mem;
+ }
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r) {
+ dev_err(&pdev->dev, "no IO memory resource defined\n");
+ err = -ENODEV;
+ goto err_put_clk;
+ }
+
+ r = request_mem_region(r->start, resource_size(r), pdev->name);
+ if (!r) {
+ dev_err(&pdev->dev, "failed to request memory resource\n");
+ err = -EBUSY;
+ goto err_put_clk;
+ }
+
+ u2d->mmio_base = ioremap(r->start, resource_size(r));
+ if (!u2d->mmio_base) {
+ dev_err(&pdev->dev, "ioremap() failed\n");
+ err = -ENODEV;
+ goto err_free_res;
+ }
+
+ if (pdata->init) {
+ err = pdata->init(&pdev->dev);
+ if (err)
+ goto err_free_io;
+ }
+
+ /* Only PXA310 U2D has OTG functionality */
+ if (cpu_is_pxa310()) {
+ err = pxa310_otg_init(pdata);
+ if (err)
+ goto err_free_plat;
+ }
+
+ platform_set_drvdata(pdev, &u2d);
+
+ return 0;
+
+err_free_plat:
+ if (pdata->exit)
+ pdata->exit(&pdev->dev);
+err_free_io:
+ iounmap(u2d->mmio_base);
+err_free_res:
+ release_mem_region(r->start, resource_size(r));
+err_put_clk:
+ clk_put(u2d->clk);
+err_free_mem:
+ kfree(u2d);
+ return err;
+}
+
+static int pxa3xx_u2d_remove(struct platform_device *pdev)
+{
+ struct pxa3xx_u2d_platform_data *pdata = pdev->dev.platform_data;
+ struct resource *r;
+
+ if (cpu_is_pxa310()) {
+ pxa310_stop_otg_hc();
+ pxa310_otg_exit();
+ }
+
+ if (pdata->exit)
+ pdata->exit(&pdev->dev);
+
+ platform_set_drvdata(pdev, NULL);
+ iounmap(u2d->mmio_base);
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(r->start, resource_size(r));
+
+ clk_put(u2d->clk);
+
+ kfree(u2d);
+
+ return 0;
+}
+
+static struct platform_driver pxa3xx_u2d_ulpi_driver = {
+ .driver = {
+ .name = "pxa3xx-u2d",
+ .owner = THIS_MODULE,
+ },
+ .probe = pxa3xx_u2d_probe,
+ .remove = pxa3xx_u2d_remove,
+};
+
+static int pxa3xx_u2d_ulpi_init(void)
+{
+ return platform_driver_register(&pxa3xx_u2d_ulpi_driver);
+}
+module_init(pxa3xx_u2d_ulpi_init);
+
+static void __exit pxa3xx_u2d_ulpi_exit(void)
+{
+ platform_driver_unregister(&pxa3xx_u2d_ulpi_driver);
+}
+module_exit(pxa3xx_u2d_ulpi_exit);
+
+MODULE_DESCRIPTION("PXA3xx U2D ULPI driver");
+MODULE_AUTHOR("Igor Grinberg");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index fa0014847c71..c85c3a7abd31 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -98,23 +98,6 @@ unsigned int pxa3xx_get_clk_frequency_khz(int info)
return CLK / 1000;
}
-/*
- * Return the current static memory controller clock frequency
- * in units of 10kHz
- */
-unsigned int pxa3xx_get_memclk_frequency_10khz(void)
-{
- unsigned long acsr;
- unsigned int smcfs, clk = 0;
-
- acsr = ACSR;
-
- smcfs = (acsr >> 23) & 0x7;
- clk = (acsr & ACCR_D0CS) ? RO_CLK : smcfs_mult[smcfs] * BASE_CLK;
-
- return (clk / 10000);
-}
-
void pxa3xx_clear_reset_status(unsigned int mask)
{
/* RESET_STATUS_* has a 1:1 mapping with ARSR */
@@ -265,7 +248,7 @@ static struct clk_lookup pxa3xx_clkregs[] = {
INIT_CLKREG(&clk_pxa3xx_i2c, "pxa2xx-i2c.0", NULL),
INIT_CLKREG(&clk_pxa3xx_udc, "pxa27x-udc", NULL),
INIT_CLKREG(&clk_pxa3xx_usbh, "pxa27x-ohci", NULL),
- INIT_CLKREG(&clk_pxa3xx_u2d, NULL, "U2DCLK"),
+ INIT_CLKREG(&clk_pxa3xx_u2d, "pxa3xx-u2d", NULL),
INIT_CLKREG(&clk_pxa3xx_keypad, "pxa27x-keypad", NULL),
INIT_CLKREG(&clk_pxa3xx_ssp1, "pxa27x-ssp.0", NULL),
INIT_CLKREG(&clk_pxa3xx_ssp2, "pxa27x-ssp.1", NULL),
diff --git a/arch/arm/mach-pxa/pxa930.c b/arch/arm/mach-pxa/pxa930.c
index 064292008288..7d29dd3af79d 100644
--- a/arch/arm/mach-pxa/pxa930.c
+++ b/arch/arm/mach-pxa/pxa930.c
@@ -192,7 +192,7 @@ static struct mfp_addr_map pxa935_mfp_addr_map[] __initdata = {
static int __init pxa930_init(void)
{
- if (cpu_is_pxa930() || cpu_is_pxa935()) {
+ if (cpu_is_pxa930() || cpu_is_pxa935() || cpu_is_pxa950()) {
mfp_init_base(io_p2v(MFPR_BASE));
mfp_init_addr(pxa930_mfp_addr_map);
}
diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c
index 67e04f4e07c1..4121d03ea2c3 100644
--- a/arch/arm/mach-pxa/raumfeld.c
+++ b/arch/arm/mach-pxa/raumfeld.c
@@ -1083,8 +1083,6 @@ static void __init raumfeld_speaker_init(void)
#ifdef CONFIG_MACH_RAUMFELD_RC
MACHINE_START(RAUMFELD_RC, "Raumfeld Controller")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = RAUMFELD_SDRAM_BASE + 0x100,
.init_machine = raumfeld_controller_init,
.map_io = pxa_map_io,
@@ -1095,8 +1093,6 @@ MACHINE_END
#ifdef CONFIG_MACH_RAUMFELD_CONNECTOR
MACHINE_START(RAUMFELD_CONNECTOR, "Raumfeld Connector")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = RAUMFELD_SDRAM_BASE + 0x100,
.init_machine = raumfeld_connector_init,
.map_io = pxa_map_io,
@@ -1107,8 +1103,6 @@ MACHINE_END
#ifdef CONFIG_MACH_RAUMFELD_SPEAKER
MACHINE_START(RAUMFELD_SPEAKER, "Raumfeld Speaker")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = RAUMFELD_SDRAM_BASE + 0x100,
.init_machine = raumfeld_speaker_init,
.map_io = pxa_map_io,
diff --git a/arch/arm/mach-pxa/saar.c b/arch/arm/mach-pxa/saar.c
index 115b6f234bdd..4b521e045d75 100644
--- a/arch/arm/mach-pxa/saar.c
+++ b/arch/arm/mach-pxa/saar.c
@@ -596,9 +596,7 @@ static void __init saar_init(void)
MACHINE_START(SAAR, "PXA930 Handheld Platform (aka SAAR)")
/* Maintainer: Eric Miao <eric.miao@marvell.com> */
- .phys_io = 0x40000000,
.boot_params = 0xa0000100,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = pxa_map_io,
.init_irq = pxa3xx_init_irq,
.timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 1cd99cb87bb1..f736119f1ebf 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -979,8 +979,6 @@ static void __init spitz_fixup(struct machine_desc *desc,
#ifdef CONFIG_MACH_SPITZ
MACHINE_START(SPITZ, "SHARP Spitz")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = spitz_fixup,
.map_io = pxa_map_io,
.init_irq = pxa27x_init_irq,
@@ -991,8 +989,6 @@ MACHINE_END
#ifdef CONFIG_MACH_BORZOI
MACHINE_START(BORZOI, "SHARP Borzoi")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = spitz_fixup,
.map_io = pxa_map_io,
.init_irq = pxa27x_init_irq,
@@ -1003,8 +999,6 @@ MACHINE_END
#ifdef CONFIG_MACH_AKITA
MACHINE_START(AKITA, "SHARP Akita")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = spitz_fixup,
.map_io = pxa_map_io,
.init_irq = pxa27x_init_irq,
diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c
index a654d1e6b38a..738adc1773fd 100644
--- a/arch/arm/mach-pxa/stargate2.c
+++ b/arch/arm/mach-pxa/stargate2.c
@@ -56,6 +56,8 @@
#include "devices.h"
#include "generic.h"
+#define STARGATE_NR_IRQS (IRQ_BOARD_START + 8)
+
/* Bluetooth */
#define SG2_BT_RESET 81
@@ -996,8 +998,6 @@ static void __init stargate2_init(void)
#ifdef CONFIG_MACH_INTELMOTE2
MACHINE_START(INTELMOTE2, "IMOTE 2")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = pxa_map_io,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
@@ -1008,9 +1008,8 @@ MACHINE_END
#ifdef CONFIG_MACH_STARGATE2
MACHINE_START(STARGATE2, "Stargate 2")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = pxa_map_io,
+ .nr_irqs = STARGATE_NR_IRQS,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = stargate2_init,
diff --git a/arch/arm/mach-pxa/tavorevb.c b/arch/arm/mach-pxa/tavorevb.c
index f02dcb5b4e97..2ea7545273ad 100644
--- a/arch/arm/mach-pxa/tavorevb.c
+++ b/arch/arm/mach-pxa/tavorevb.c
@@ -25,7 +25,7 @@
#include <mach/pxa930.h>
#include <mach/pxafb.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
#include "devices.h"
#include "generic.h"
@@ -489,9 +489,7 @@ static void __init tavorevb_init(void)
MACHINE_START(TAVOREVB, "PXA930 Evaluation Board (aka TavorEVB)")
/* Maintainer: Eric Miao <eric.miao@marvell.com> */
- .phys_io = 0x40000000,
.boot_params = 0xa0000100,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = pxa_map_io,
.init_irq = pxa3xx_init_irq,
.timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/tavorevb3.c b/arch/arm/mach-pxa/tavorevb3.c
new file mode 100644
index 000000000000..dc3011697bbf
--- /dev/null
+++ b/arch/arm/mach-pxa/tavorevb3.c
@@ -0,0 +1,135 @@
+/*
+ * linux/arch/arm/mach-pxa/tavorevb3.c
+ *
+ * Support for the Marvell EVB3 Development Platform.
+ *
+ * Copyright: (C) Copyright 2008-2010 Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/mfd/88pm860x.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/pxa930.h>
+
+#include <plat/i2c.h>
+
+#include "devices.h"
+#include "generic.h"
+
+#define TAVOREVB3_NR_IRQS (IRQ_BOARD_START + 24)
+
+static mfp_cfg_t evb3_mfp_cfg[] __initdata = {
+ /* UART */
+ GPIO53_UART1_TXD,
+ GPIO54_UART1_RXD,
+
+ /* PMIC */
+ PMIC_INT_GPIO83,
+};
+
+#if defined(CONFIG_I2C_PXA) || defined(CONFIG_I2C_PXA_MODULE)
+static struct pm860x_touch_pdata evb3_touch = {
+ .gpadc_prebias = 1,
+ .slot_cycle = 1,
+ .tsi_prebias = 6,
+ .pen_prebias = 16,
+ .pen_prechg = 2,
+ .res_x = 300,
+};
+
+static struct pm860x_backlight_pdata evb3_backlight[] = {
+ {
+ .id = PM8606_ID_BACKLIGHT,
+ .iset = PM8606_WLED_CURRENT(24),
+ .flags = PM8606_BACKLIGHT1,
+ },
+ {},
+};
+
+static struct pm860x_led_pdata evb3_led[] = {
+ {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED1_RED,
+ }, {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED1_GREEN,
+ }, {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED1_BLUE,
+ }, {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED2_RED,
+ }, {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED2_GREEN,
+ }, {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED2_BLUE,
+ },
+};
+
+static struct pm860x_platform_data evb3_pm8607_info = {
+ .touch = &evb3_touch,
+ .backlight = &evb3_backlight[0],
+ .led = &evb3_led[0],
+ .companion_addr = 0x10,
+ .irq_mode = 0,
+ .irq_base = IRQ_BOARD_START,
+
+ .i2c_port = GI2C_PORT,
+};
+
+static struct i2c_board_info evb3_i2c_info[] = {
+ {
+ .type = "88PM860x",
+ .addr = 0x34,
+ .platform_data = &evb3_pm8607_info,
+ .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO83)),
+ },
+};
+
+static void __init evb3_init_i2c(void)
+{
+ pxa_set_i2c_info(NULL);
+ i2c_register_board_info(0, ARRAY_AND_SIZE(evb3_i2c_info));
+}
+#else
+static inline void evb3_init_i2c(void) {}
+#endif
+
+static void __init evb3_init(void)
+{
+ /* initialize MFP configurations */
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(evb3_mfp_cfg));
+
+ pxa_set_ffuart_info(NULL);
+
+ evb3_init_i2c();
+}
+
+MACHINE_START(TAVOREVB3, "PXA950 Evaluation Board (aka TavorEVB3)")
+ .boot_params = 0xa0000100,
+ .map_io = pxa_map_io,
+ .nr_irqs = TAVOREVB3_NR_IRQS,
+ .init_irq = pxa3xx_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = evb3_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index 83cc3a18c2e9..0ee1df49606d 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -952,10 +952,9 @@ static void __init fixup_tosa(struct machine_desc *desc,
}
MACHINE_START(TOSA, "SHARP Tosa")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = fixup_tosa,
.map_io = pxa_map_io,
+ .nr_irqs = TOSA_NR_IRQS,
.init_irq = pxa25x_init_irq,
.init_machine = tosa_init,
.timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c
index 0acff172ef22..565d062f51d5 100644
--- a/arch/arm/mach-pxa/trizeps4.c
+++ b/arch/arm/mach-pxa/trizeps4.c
@@ -555,8 +555,6 @@ static void __init trizeps4_map_io(void)
MACHINE_START(TRIZEPS4, "Keith und Koep Trizeps IV module")
/* MAINTAINER("Jürgen Schindele") */
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = TRIZEPS4_SDRAM_BASE + 0x100,
.init_machine = trizeps4_init,
.map_io = trizeps4_map_io,
@@ -566,8 +564,6 @@ MACHINE_END
MACHINE_START(TRIZEPS4WL, "Keith und Koep Trizeps IV-WL module")
/* MAINTAINER("Jürgen Schindele") */
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = TRIZEPS4_SDRAM_BASE + 0x100,
.init_machine = trizeps4_init,
.map_io = trizeps4_map_io,
diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c
index e90114a7e246..438fc9a5ed59 100644
--- a/arch/arm/mach-pxa/viper.c
+++ b/arch/arm/mach-pxa/viper.c
@@ -992,8 +992,6 @@ static void __init viper_map_io(void)
MACHINE_START(VIPER, "Arcom/Eurotech VIPER SBC")
/* Maintainer: Marc Zyngier <maz@misterjones.org> */
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = viper_map_io,
.init_irq = viper_init_irq,
diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c
index 37d6173bbb66..f45ac0961778 100644
--- a/arch/arm/mach-pxa/vpac270.c
+++ b/arch/arm/mach-pxa/vpac270.c
@@ -718,8 +718,6 @@ static void __init vpac270_init(void)
}
MACHINE_START(VPAC270, "Voipac PXA270")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
.init_irq = pxa27x_init_irq,
diff --git a/arch/arm/mach-pxa/xcep.c b/arch/arm/mach-pxa/xcep.c
index d3b4e3f2e033..3260ce73d327 100644
--- a/arch/arm/mach-pxa/xcep.c
+++ b/arch/arm/mach-pxa/xcep.c
@@ -181,8 +181,6 @@ static void __init xcep_init(void)
}
MACHINE_START(XCEP, "Iskratel XCEP")
- .phys_io = 0x40000000,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.init_machine = xcep_init,
.map_io = pxa_map_io,
diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c
index f0d02288b4ca..fefde9848d82 100644
--- a/arch/arm/mach-pxa/z2.c
+++ b/arch/arm/mach-pxa/z2.c
@@ -37,7 +37,7 @@
#include <mach/z2.h>
#include <mach/pxafb.h>
#include <mach/mmc.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
#include <mach/pxa2xx_spi.h>
#include <plat/i2c.h>
@@ -703,9 +703,7 @@ static void __init z2_init(void)
}
MACHINE_START(ZIPIT2, "Zipit Z2")
- .phys_io = 0x40000000,
.boot_params = 0xa0000100,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = pxa_map_io,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c
index 03b9cb910e08..dea46a2d089b 100644
--- a/arch/arm/mach-pxa/zeus.c
+++ b/arch/arm/mach-pxa/zeus.c
@@ -900,10 +900,9 @@ static void __init zeus_map_io(void)
MACHINE_START(ARCOM_ZEUS, "Arcom/Eurotech ZEUS")
/* Maintainer: Marc Zyngier <maz@misterjones.org> */
- .phys_io = 0x40000000,
- .io_pg_offst = ((io_p2v(0x40000000) >> 18) & 0xfffc),
.boot_params = 0xa0000100,
.map_io = zeus_map_io,
+ .nr_irqs = ZEUS_NR_IRQS,
.init_irq = zeus_init_irq,
.timer = &pxa_timer,
.init_machine = zeus_init,
diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c
index c479cbecf784..f25fb6245bd7 100644
--- a/arch/arm/mach-pxa/zylonite.c
+++ b/arch/arm/mach-pxa/zylonite.c
@@ -30,7 +30,7 @@
#include <mach/zylonite.h>
#include <mach/mmc.h>
#include <mach/ohci.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
#include <plat/pxa3xx_nand.h>
#include "devices.h"
@@ -411,10 +411,9 @@ static void __init zylonite_init(void)
}
MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)")
- .phys_io = 0x40000000,
.boot_params = 0xa0000100,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = pxa_map_io,
+ .nr_irqs = ZYLONITE_NR_IRQS,
.init_irq = pxa3xx_init_irq,
.timer = &pxa_timer,
.init_machine = zylonite_init,
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index 2fa38df28414..07c08151dfe6 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -259,6 +259,7 @@ struct mmci_platform_data realview_mmc0_plat_data = {
.status = realview_mmc_status,
.gpio_wp = 17,
.gpio_cd = 16,
+ .cd_invert = true,
};
struct mmci_platform_data realview_mmc1_plat_data = {
@@ -266,6 +267,7 @@ struct mmci_platform_data realview_mmc1_plat_data = {
.status = realview_mmc_status,
.gpio_wp = 19,
.gpio_cd = 18,
+ .cd_invert = true,
};
/*
diff --git a/arch/arm/mach-realview/include/mach/debug-macro.S b/arch/arm/mach-realview/include/mach/debug-macro.S
index 86622289b74e..90b687cbe04e 100644
--- a/arch/arm/mach-realview/include/mach/debug-macro.S
+++ b/arch/arm/mach-realview/include/mach/debug-macro.S
@@ -33,12 +33,10 @@
#error "Unknown RealView platform"
#endif
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- moveq \rx, #0x10000000
- movne \rx, #0xfb000000 @ virtual base
- orr \rx, \rx, #DEBUG_LL_UART_OFFSET
+ .macro addruart, rp, rv
+ mov \rp, #DEBUG_LL_UART_OFFSET
+ orr \rv, \rp, #0xfb000000 @ virtual base
+ orr \rp, \rp, #0x10000000 @ physical base
.endm
#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-realview/include/mach/smp.h b/arch/arm/mach-realview/include/mach/smp.h
index dd53892d44a7..d3cd265cb058 100644
--- a/arch/arm/mach-realview/include/mach/smp.h
+++ b/arch/arm/mach-realview/include/mach/smp.h
@@ -1,16 +1,8 @@
#ifndef ASMARM_ARCH_SMP_H
#define ASMARM_ARCH_SMP_H
-
#include <asm/hardware/gic.h>
-
-#define hard_smp_processor_id() \
- ({ \
- unsigned int cpunum; \
- __asm__("mrc p15, 0, %0, c0, c0, 5" \
- : "=r" (cpunum)); \
- cpunum &= 0x0F; \
- })
+#include <asm/smp_mpidr.h>
/*
* We use IRQ1 as the IPI
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index 991c1f8390e2..f2697106f809 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -486,8 +486,6 @@ static void __init realview_eb_init(void)
MACHINE_START(REALVIEW_EB, "ARM-RealView EB")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
- .phys_io = REALVIEW_EB_UART0_BASE & SECTION_MASK,
- .io_pg_offst = (IO_ADDRESS(REALVIEW_EB_UART0_BASE) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x00000100,
.fixup = realview_fixup,
.map_io = realview_eb_map_io,
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c
index d2be12eb829e..a4125619d71b 100644
--- a/arch/arm/mach-realview/realview_pb1176.c
+++ b/arch/arm/mach-realview/realview_pb1176.c
@@ -378,8 +378,6 @@ static void __init realview_pb1176_init(void)
MACHINE_START(REALVIEW_PB1176, "ARM-RealView PB1176")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
- .phys_io = REALVIEW_PB1176_UART0_BASE & SECTION_MASK,
- .io_pg_offst = (IO_ADDRESS(REALVIEW_PB1176_UART0_BASE) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x00000100,
.fixup = realview_pb1176_fixup,
.map_io = realview_pb1176_map_io,
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c
index d591bc00b86e..117b95b2ca15 100644
--- a/arch/arm/mach-realview/realview_pb11mp.c
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -381,8 +381,6 @@ static void __init realview_pb11mp_init(void)
MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
- .phys_io = REALVIEW_PB11MP_UART0_BASE & SECTION_MASK,
- .io_pg_offst = (IO_ADDRESS(REALVIEW_PB11MP_UART0_BASE) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x00000100,
.fixup = realview_fixup,
.map_io = realview_pb11mp_map_io,
diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c
index 6c37621217bc..929b8dc12e81 100644
--- a/arch/arm/mach-realview/realview_pba8.c
+++ b/arch/arm/mach-realview/realview_pba8.c
@@ -331,8 +331,6 @@ static void __init realview_pba8_init(void)
MACHINE_START(REALVIEW_PBA8, "ARM-RealView PB-A8")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
- .phys_io = REALVIEW_PBA8_UART0_BASE & SECTION_MASK,
- .io_pg_offst = (IO_ADDRESS(REALVIEW_PBA8_UART0_BASE) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x00000100,
.fixup = realview_fixup,
.map_io = realview_pba8_map_io,
diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c
index 9428eff0b116..b9f9e20031a7 100644
--- a/arch/arm/mach-realview/realview_pbx.c
+++ b/arch/arm/mach-realview/realview_pbx.c
@@ -417,8 +417,6 @@ static void __init realview_pbx_init(void)
MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
- .phys_io = REALVIEW_PBX_UART0_BASE & SECTION_MASK,
- .io_pg_offst = (IO_ADDRESS(REALVIEW_PBX_UART0_BASE) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x00000100,
.fixup = realview_pbx_fixup,
.map_io = realview_pbx_map_io,
diff --git a/arch/arm/mach-rpc/include/mach/debug-macro.S b/arch/arm/mach-rpc/include/mach/debug-macro.S
index 6fc8d66395dc..85effffdc2b2 100644
--- a/arch/arm/mach-rpc/include/mach/debug-macro.S
+++ b/arch/arm/mach-rpc/include/mach/debug-macro.S
@@ -11,13 +11,11 @@
*
*/
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- moveq \rx, #0x03000000
- movne \rx, #0xe0000000
- orr \rx, \rx, #0x00010000
- orr \rx, \rx, #0x00000fe0
+ .macro addruart, rp, rv
+ mov \rp, #0x00010000
+ orr \rp, \rp, #0x00000fe0
+ orr \rv, \rp, #0xe0000000 @ virtual
+ orr \rp, \rp, #0x03000000 @ physical
.endm
#define UART_SHIFT 2
diff --git a/arch/arm/mach-rpc/include/mach/vmalloc.h b/arch/arm/mach-rpc/include/mach/vmalloc.h
index 9a96fd69e705..3bcd86fadb81 100644
--- a/arch/arm/mach-rpc/include/mach/vmalloc.h
+++ b/arch/arm/mach-rpc/include/mach/vmalloc.h
@@ -7,4 +7,4 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-#define VMALLOC_END (PAGE_OFFSET + 0x1c000000)
+#define VMALLOC_END 0xdc000000
diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c
index c7fc01e9d1f6..580b3c73d2c7 100644
--- a/arch/arm/mach-rpc/riscpc.c
+++ b/arch/arm/mach-rpc/riscpc.c
@@ -218,8 +218,6 @@ extern struct sys_timer ioc_timer;
MACHINE_START(RISCPC, "Acorn-RiscPC")
/* Maintainer: Russell King */
- .phys_io = 0x03000000,
- .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.reserve_lp0 = 1,
.reserve_lp1 = 1,
diff --git a/arch/arm/mach-s3c2410/include/mach/debug-macro.S b/arch/arm/mach-s3c2410/include/mach/debug-macro.S
index 0eef78b4a6ed..5882deaa56be 100644
--- a/arch/arm/mach-s3c2410/include/mach/debug-macro.S
+++ b/arch/arm/mach-s3c2410/include/mach/debug-macro.S
@@ -19,13 +19,12 @@
#define S3C2410_UART1_OFF (0x4000)
#define SHIFT_2440TXF (14-9)
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1
- ldreq \rx, = S3C24XX_PA_UART
- ldrne \rx, = S3C24XX_VA_UART
+ .macro addruart, rp, rv
+ ldr \rp, = S3C24XX_PA_UART
+ ldr \rv, = S3C24XX_VA_UART
#if CONFIG_DEBUG_S3C_UART != 0
- add \rx, \rx, #(S3C2410_UART1_OFF * CONFIG_DEBUG_S3C_UART)
+ add \rp, \rp, #(S3C2410_UART1_OFF * CONFIG_DEBUG_S3C_UART)
+ add \rv, \rv, #(S3C2410_UART1_OFF * CONFIG_DEBUG_S3C_UART)
#endif
.endm
diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c
index 34fc05a4244b..44440cbd7620 100644
--- a/arch/arm/mach-s3c2410/mach-amlm5900.c
+++ b/arch/arm/mach-s3c2410/mach-amlm5900.c
@@ -241,8 +241,6 @@ static void __init amlm5900_init(void)
}
MACHINE_START(AML_M5900, "AML_M5900")
- .phys_io = S3C2410_PA_UART,
- .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = amlm5900_map_io,
.init_irq = s3c24xx_init_irq,
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index c1f90f6fab42..2970ea9f7c2b 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -664,8 +664,6 @@ static void __init bast_init(void)
MACHINE_START(BAST, "Simtec-BAST")
/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
- .phys_io = S3C2410_PA_UART,
- .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = bast_map_io,
.init_irq = s3c24xx_init_irq,
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index 3ba3bab139d0..98c5c9e81ee9 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -350,8 +350,6 @@ static void __init h1940_init(void)
MACHINE_START(H1940, "IPAQ-H1940")
/* Maintainer: Ben Dooks <ben-linux@fluff.org> */
- .phys_io = S3C2410_PA_UART,
- .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = h1940_map_io,
.reserve = h1940_reserve,
diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c
index 41f299d983eb..271b9aa6d40a 100644
--- a/arch/arm/mach-s3c2410/mach-n30.c
+++ b/arch/arm/mach-s3c2410/mach-n30.c
@@ -605,8 +605,6 @@ MACHINE_START(N30, "Acer-N30")
/* Maintainer: Christer Weinigel <christer@weinigel.se>,
Ben Dooks <ben-linux@fluff.org>
*/
- .phys_io = S3C2410_PA_UART,
- .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.timer = &s3c24xx_timer,
.init_machine = n30_init,
@@ -617,8 +615,6 @@ MACHINE_END
MACHINE_START(N35, "Acer-N35")
/* Maintainer: Christer Weinigel <christer@weinigel.se>
*/
- .phys_io = S3C2410_PA_UART,
- .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.timer = &s3c24xx_timer,
.init_machine = n30_init,
diff --git a/arch/arm/mach-s3c2410/mach-otom.c b/arch/arm/mach-s3c2410/mach-otom.c
index d8c7f2efc1a7..0aa16cd5acbc 100644
--- a/arch/arm/mach-s3c2410/mach-otom.c
+++ b/arch/arm/mach-s3c2410/mach-otom.c
@@ -116,8 +116,6 @@ static void __init otom11_init(void)
MACHINE_START(OTOM, "Nex Vision - Otom 1.1")
/* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */
- .phys_io = S3C2410_PA_UART,
- .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = otom11_map_io,
.init_machine = otom11_init,
diff --git a/arch/arm/mach-s3c2410/mach-qt2410.c b/arch/arm/mach-s3c2410/mach-qt2410.c
index d0e87b6e2e0f..e8f49feef28c 100644
--- a/arch/arm/mach-s3c2410/mach-qt2410.c
+++ b/arch/arm/mach-s3c2410/mach-qt2410.c
@@ -362,8 +362,6 @@ static void __init qt2410_machine_init(void)
}
MACHINE_START(QT2410, "QT2410")
- .phys_io = S3C2410_PA_UART,
- .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = qt2410_map_io,
.init_irq = s3c24xx_init_irq,
diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c
index 452223042201..e17f03387aba 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2410.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2410.c
@@ -111,8 +111,6 @@ static void __init smdk2410_init(void)
MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch
* to SMDK2410 */
/* Maintainer: Jonas Dietsche */
- .phys_io = S3C2410_PA_UART,
- .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = smdk2410_map_io,
.init_irq = s3c24xx_init_irq,
diff --git a/arch/arm/mach-s3c2410/mach-tct_hammer.c b/arch/arm/mach-s3c2410/mach-tct_hammer.c
index 929164a8e9b1..a15d0621c22f 100644
--- a/arch/arm/mach-s3c2410/mach-tct_hammer.c
+++ b/arch/arm/mach-s3c2410/mach-tct_hammer.c
@@ -152,8 +152,6 @@ static void __init tct_hammer_init(void)
}
MACHINE_START(TCT_HAMMER, "TCT_HAMMER")
- .phys_io = S3C2410_PA_UART,
- .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = tct_hammer_map_io,
.init_irq = s3c24xx_init_irq,
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index d540d79dd264..6ccce5a761b4 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -400,8 +400,6 @@ static void __init vr1000_init(void)
MACHINE_START(VR1000, "Thorcom-VR1000")
/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
- .phys_io = S3C2410_PA_UART,
- .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = vr1000_map_io,
.init_machine = vr1000_init,
diff --git a/arch/arm/mach-s3c2412/mach-jive.c b/arch/arm/mach-s3c2412/mach-jive.c
index 478f4b4606c2..923e01bdf017 100644
--- a/arch/arm/mach-s3c2412/mach-jive.c
+++ b/arch/arm/mach-s3c2412/mach-jive.c
@@ -675,8 +675,6 @@ static void __init jive_machine_init(void)
MACHINE_START(JIVE, "JIVE")
/* Maintainer: Ben Dooks <ben-linux@fluff.org> */
- .phys_io = S3C2410_PA_UART,
- .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.init_irq = s3c24xx_init_irq,
diff --git a/arch/arm/mach-s3c2412/mach-smdk2413.c b/arch/arm/mach-s3c2412/mach-smdk2413.c
index 054c9f92232a..8e5758bdd666 100644
--- a/arch/arm/mach-s3c2412/mach-smdk2413.c
+++ b/arch/arm/mach-s3c2412/mach-smdk2413.c
@@ -150,8 +150,6 @@ static void __init smdk2413_machine_init(void)
MACHINE_START(S3C2413, "S3C2413")
/* Maintainer: Ben Dooks <ben-linux@fluff.org> */
- .phys_io = S3C2410_PA_UART,
- .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.fixup = smdk2413_fixup,
@@ -163,8 +161,6 @@ MACHINE_END
MACHINE_START(SMDK2412, "SMDK2412")
/* Maintainer: Ben Dooks <ben-linux@fluff.org> */
- .phys_io = S3C2410_PA_UART,
- .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.fixup = smdk2413_fixup,
@@ -176,8 +172,6 @@ MACHINE_END
MACHINE_START(SMDK2413, "SMDK2413")
/* Maintainer: Ben Dooks <ben-linux@fluff.org> */
- .phys_io = S3C2410_PA_UART,
- .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.fixup = smdk2413_fixup,
diff --git a/arch/arm/mach-s3c2412/mach-vstms.c b/arch/arm/mach-s3c2412/mach-vstms.c
index f291ac25d312..83544ebe20ac 100644
--- a/arch/arm/mach-s3c2412/mach-vstms.c
+++ b/arch/arm/mach-s3c2412/mach-vstms.c
@@ -156,8 +156,6 @@ static void __init vstms_init(void)
}
MACHINE_START(VSTMS, "VSTMS")
- .phys_io = S3C2410_PA_UART,
- .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.fixup = vstms_fixup,
diff --git a/arch/arm/mach-s3c2416/mach-smdk2416.c b/arch/arm/mach-s3c2416/mach-smdk2416.c
index 5fc3f67ef265..7fc366476d7e 100644
--- a/arch/arm/mach-s3c2416/mach-smdk2416.c
+++ b/arch/arm/mach-s3c2416/mach-smdk2416.c
@@ -195,8 +195,6 @@ static void __init smdk2416_machine_init(void)
MACHINE_START(SMDK2416, "SMDK2416")
/* Maintainer: Yauhen Kharuzhy <jekhor@gmail.com> */
- .phys_io = S3C2410_PA_UART,
- .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.init_irq = s3c24xx_init_irq,
diff --git a/arch/arm/mach-s3c2440/mach-anubis.c b/arch/arm/mach-s3c2440/mach-anubis.c
index b73f78a9da5c..d7086788b1ff 100644
--- a/arch/arm/mach-s3c2440/mach-anubis.c
+++ b/arch/arm/mach-s3c2440/mach-anubis.c
@@ -498,8 +498,6 @@ static void __init anubis_init(void)
MACHINE_START(ANUBIS, "Simtec-Anubis")
/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
- .phys_io = S3C2410_PA_UART,
- .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = anubis_map_io,
.init_machine = anubis_init,
diff --git a/arch/arm/mach-s3c2440/mach-at2440evb.c b/arch/arm/mach-s3c2440/mach-at2440evb.c
index 84725791e6bf..6c98b789b8c6 100644
--- a/arch/arm/mach-s3c2440/mach-at2440evb.c
+++ b/arch/arm/mach-s3c2440/mach-at2440evb.c
@@ -5,7 +5,7 @@
* and modifications by SBZ <sbz@spgui.org> and
* Weibing <http://weibing.blogbus.com>
*
- * For product information, visit http://www.arm9e.com/
+ * For product information, visit http://www.arm.com/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -233,8 +233,6 @@ static void __init at2440evb_init(void)
MACHINE_START(AT2440EVB, "AT2440EVB")
- .phys_io = S3C2410_PA_UART,
- .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = at2440evb_map_io,
.init_machine = at2440evb_init,
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
index deaabe86741d..9f2c14ec7181 100644
--- a/arch/arm/mach-s3c2440/mach-gta02.c
+++ b/arch/arm/mach-s3c2440/mach-gta02.c
@@ -572,8 +572,6 @@ static void __init gta02_machine_init(void)
MACHINE_START(NEO1973_GTA02, "GTA02")
/* Maintainer: Nelson Castillo <arhuaco@freaks-unidos.net> */
- .phys_io = S3C2410_PA_UART,
- .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = gta02_map_io,
.init_irq = s3c24xx_init_irq,
diff --git a/arch/arm/mach-s3c2440/mach-mini2440.c b/arch/arm/mach-s3c2440/mach-mini2440.c
index a76bcda210ad..f62bb4c793bd 100644
--- a/arch/arm/mach-s3c2440/mach-mini2440.c
+++ b/arch/arm/mach-s3c2440/mach-mini2440.c
@@ -691,8 +691,6 @@ static void __init mini2440_init(void)
MACHINE_START(MINI2440, "MINI2440")
/* Maintainer: Michel Pollet <buserror@gmail.com> */
- .phys_io = S3C2410_PA_UART,
- .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = mini2440_map_io,
.init_machine = mini2440_init,
diff --git a/arch/arm/mach-s3c2440/mach-nexcoder.c b/arch/arm/mach-s3c2440/mach-nexcoder.c
index 3ff62de45fde..37dd306fb7dc 100644
--- a/arch/arm/mach-s3c2440/mach-nexcoder.c
+++ b/arch/arm/mach-s3c2440/mach-nexcoder.c
@@ -151,8 +151,6 @@ static void __init nexcoder_init(void)
MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440")
/* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */
- .phys_io = S3C2410_PA_UART,
- .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = nexcoder_map_io,
.init_machine = nexcoder_init,
diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c
index 319458da71a0..14dc67897757 100644
--- a/arch/arm/mach-s3c2440/mach-osiris.c
+++ b/arch/arm/mach-s3c2440/mach-osiris.c
@@ -455,8 +455,6 @@ static void __init osiris_init(void)
MACHINE_START(OSIRIS, "Simtec-OSIRIS")
/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
- .phys_io = S3C2410_PA_UART,
- .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = osiris_map_io,
.init_irq = s3c24xx_init_irq,
diff --git a/arch/arm/mach-s3c2440/mach-rx1950.c b/arch/arm/mach-s3c2440/mach-rx1950.c
index 142d1f921176..32019bd9db3b 100644
--- a/arch/arm/mach-s3c2440/mach-rx1950.c
+++ b/arch/arm/mach-s3c2440/mach-rx1950.c
@@ -580,8 +580,6 @@ static void __init rx1950_reserve(void)
MACHINE_START(RX1950, "HP iPAQ RX1950")
/* Maintainers: Vasily Khoruzhick */
- .phys_io = S3C2410_PA_UART,
- .io_pg_offst = (((u32) S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = rx1950_map_io,
.reserve = rx1950_reserve,
diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c
index 6bb44f75a9ce..1472b1a5b2fb 100644
--- a/arch/arm/mach-s3c2440/mach-rx3715.c
+++ b/arch/arm/mach-s3c2440/mach-rx3715.c
@@ -218,8 +218,6 @@ static void __init rx3715_init_machine(void)
MACHINE_START(RX3715, "IPAQ-RX3715")
/* Maintainer: Ben Dooks <ben-linux@fluff.org> */
- .phys_io = S3C2410_PA_UART,
- .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = rx3715_map_io,
.reserve = rx3715_reserve,
diff --git a/arch/arm/mach-s3c2440/mach-smdk2440.c b/arch/arm/mach-s3c2440/mach-smdk2440.c
index df83276d85ae..eedfe0f11643 100644
--- a/arch/arm/mach-s3c2440/mach-smdk2440.c
+++ b/arch/arm/mach-s3c2440/mach-smdk2440.c
@@ -175,8 +175,6 @@ static void __init smdk2440_machine_init(void)
MACHINE_START(S3C2440, "SMDK2440")
/* Maintainer: Ben Dooks <ben-linux@fluff.org> */
- .phys_io = S3C2410_PA_UART,
- .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.init_irq = s3c24xx_init_irq,
diff --git a/arch/arm/mach-s3c2443/mach-smdk2443.c b/arch/arm/mach-s3c2443/mach-smdk2443.c
index 4c863d3a52f4..4337f0a9960d 100644
--- a/arch/arm/mach-s3c2443/mach-smdk2443.c
+++ b/arch/arm/mach-s3c2443/mach-smdk2443.c
@@ -132,8 +132,6 @@ static void __init smdk2443_machine_init(void)
MACHINE_START(SMDK2443, "SMDK2443")
/* Maintainer: Ben Dooks <ben-linux@fluff.org> */
- .phys_io = S3C2410_PA_UART,
- .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.init_irq = s3c24xx_init_irq,
diff --git a/arch/arm/mach-s3c24a0/include/mach/debug-macro.S b/arch/arm/mach-s3c24a0/include/mach/debug-macro.S
index 239476b81f3b..0c5a73805560 100644
--- a/arch/arm/mach-s3c24a0/include/mach/debug-macro.S
+++ b/arch/arm/mach-s3c24a0/include/mach/debug-macro.S
@@ -10,13 +10,12 @@
#include <mach/map.h>
#include <plat/regs-serial.h>
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1
- ldreq \rx, = S3C24XX_PA_UART
- ldrne \rx, = S3C24XX_VA_UART
+ .macro addruart, rp, rv
+ ldr \rp, = S3C24XX_PA_UART
+ ldr \rv, = S3C24XX_VA_UART
#if CONFIG_DEBUG_S3C_UART != 0
- add \rx, \rx, #(S3C2410_UART1_OFF * CONFIG_DEBUG_S3C_UART)
+ add \rp, \rp, #(S3C2410_UART1_OFF * CONFIG_DEBUG_S3C_UART)
+ add \rv, \rv, #(S3C2410_UART1_OFF * CONFIG_DEBUG_S3C_UART)
#endif
.endm
diff --git a/arch/arm/mach-s3c64xx/include/mach/debug-macro.S b/arch/arm/mach-s3c64xx/include/mach/debug-macro.S
index f9ab5d26052a..a29e70550c70 100644
--- a/arch/arm/mach-s3c64xx/include/mach/debug-macro.S
+++ b/arch/arm/mach-s3c64xx/include/mach/debug-macro.S
@@ -21,13 +21,12 @@
* aligned and add in the offset when we load the value here.
*/
- .macro addruart, rx, rtmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1
- ldreq \rx, = S3C_PA_UART
- ldrne \rx, = (S3C_VA_UART + S3C_PA_UART & 0xfffff)
+ .macro addruart, rp, rv
+ ldr \rp, = S3C_PA_UART
+ ldr \rv, = (S3C_VA_UART + S3C_PA_UART & 0xfffff)
#if CONFIG_DEBUG_S3C_UART != 0
- add \rx, \rx, #(0x400 * CONFIG_DEBUG_S3C_UART)
+ add \rp, \rp, #(0x400 * CONFIG_DEBUG_S3C_UART)
+ add \rv, \rv, #(0x400 * CONFIG_DEBUG_S3C_UART)
#endif
.endm
diff --git a/arch/arm/mach-s3c64xx/mach-anw6410.c b/arch/arm/mach-s3c64xx/mach-anw6410.c
index 742dc87bd9c1..a53cf149476e 100644
--- a/arch/arm/mach-s3c64xx/mach-anw6410.c
+++ b/arch/arm/mach-s3c64xx/mach-anw6410.c
@@ -233,8 +233,6 @@ static void __init anw6410_machine_init(void)
MACHINE_START(ANW6410, "A&W6410")
/* Maintainer: Kwangwoo Lee <kwangwoo.lee@gmail.com> */
- .phys_io = S3C_PA_UART & 0xfff00000,
- .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C64XX_PA_SDRAM + 0x100,
.init_irq = s3c6410_init_irq,
diff --git a/arch/arm/mach-s3c64xx/mach-hmt.c b/arch/arm/mach-s3c64xx/mach-hmt.c
index fba90229f0df..b2639582caca 100644
--- a/arch/arm/mach-s3c64xx/mach-hmt.c
+++ b/arch/arm/mach-s3c64xx/mach-hmt.c
@@ -265,8 +265,6 @@ static void __init hmt_machine_init(void)
MACHINE_START(HMT, "Airgoo-HMT")
/* Maintainer: Peter Korsgaard <jacmet@sunsite.dk> */
- .phys_io = S3C_PA_UART & 0xfff00000,
- .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C64XX_PA_SDRAM + 0x100,
.init_irq = s3c6410_init_irq,
.map_io = hmt_map_io,
diff --git a/arch/arm/mach-s3c64xx/mach-ncp.c b/arch/arm/mach-s3c64xx/mach-ncp.c
index bf65747ea68e..c4986498cd12 100644
--- a/arch/arm/mach-s3c64xx/mach-ncp.c
+++ b/arch/arm/mach-s3c64xx/mach-ncp.c
@@ -97,8 +97,6 @@ static void __init ncp_machine_init(void)
MACHINE_START(NCP, "NCP")
/* Maintainer: Samsung Electronics */
- .phys_io = S3C_PA_UART & 0xfff00000,
- .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C64XX_PA_SDRAM + 0x100,
.init_irq = s3c6410_init_irq,
.map_io = ncp_map_io,
diff --git a/arch/arm/mach-s3c64xx/mach-real6410.c b/arch/arm/mach-s3c64xx/mach-real6410.c
index e130379ba0e8..4b4475da8ec6 100644
--- a/arch/arm/mach-s3c64xx/mach-real6410.c
+++ b/arch/arm/mach-s3c64xx/mach-real6410.c
@@ -141,8 +141,6 @@ static void __init real6410_machine_init(void)
MACHINE_START(REAL6410, "REAL6410")
/* Maintainer: Darius Augulis <augulis.darius@gmail.com> */
- .phys_io = S3C_PA_UART & 0xfff00000,
- .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C64XX_PA_SDRAM + 0x100,
.init_irq = s3c6410_init_irq,
diff --git a/arch/arm/mach-s3c64xx/mach-smartq.c b/arch/arm/mach-s3c64xx/mach-smartq.c
index 3a9639bc3d9b..cb1ebeb08763 100644
--- a/arch/arm/mach-s3c64xx/mach-smartq.c
+++ b/arch/arm/mach-s3c64xx/mach-smartq.c
@@ -136,7 +136,7 @@ static struct platform_device smartq_usb_otg_vbus_dev = {
.dev.platform_data = &smartq_usb_otg_vbus_pdata,
};
-static int __init smartq_bl_init(struct device *dev)
+static int smartq_bl_init(struct device *dev)
{
s3c_gpio_cfgpin(S3C64XX_GPF(15), S3C_GPIO_SFN(2));
diff --git a/arch/arm/mach-s3c64xx/mach-smartq5.c b/arch/arm/mach-s3c64xx/mach-smartq5.c
index a4d59b076e3d..3a3e5acde523 100644
--- a/arch/arm/mach-s3c64xx/mach-smartq5.c
+++ b/arch/arm/mach-s3c64xx/mach-smartq5.c
@@ -32,7 +32,7 @@
#include "mach-smartq.h"
-static struct gpio_led smartq5_leds[] __initdata = {
+static struct gpio_led smartq5_leds[] = {
{
.name = "smartq5:green",
.active_low = 1,
@@ -146,8 +146,6 @@ static void __init smartq5_machine_init(void)
MACHINE_START(SMARTQ5, "SmartQ 5")
/* Maintainer: Maurus Cuelenaere <mcuelenaere AT gmail DOT com> */
- .phys_io = S3C_PA_UART & 0xfff00000,
- .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C64XX_PA_SDRAM + 0x100,
.init_irq = s3c6410_init_irq,
.map_io = smartq_map_io,
diff --git a/arch/arm/mach-s3c64xx/mach-smartq7.c b/arch/arm/mach-s3c64xx/mach-smartq7.c
index e50a7d781732..e65375877d53 100644
--- a/arch/arm/mach-s3c64xx/mach-smartq7.c
+++ b/arch/arm/mach-s3c64xx/mach-smartq7.c
@@ -32,7 +32,7 @@
#include "mach-smartq.h"
-static struct gpio_led smartq7_leds[] __initdata = {
+static struct gpio_led smartq7_leds[] = {
{
.name = "smartq7:red",
.active_low = 1,
@@ -162,8 +162,6 @@ static void __init smartq7_machine_init(void)
MACHINE_START(SMARTQ7, "SmartQ 7")
/* Maintainer: Maurus Cuelenaere <mcuelenaere AT gmail DOT com> */
- .phys_io = S3C_PA_UART & 0xfff00000,
- .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C64XX_PA_SDRAM + 0x100,
.init_irq = s3c6410_init_irq,
.map_io = smartq_map_io,
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6400.c b/arch/arm/mach-s3c64xx/mach-smdk6400.c
index 59916676d8d2..3cca642f1e6d 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6400.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6400.c
@@ -85,8 +85,6 @@ static void __init smdk6400_machine_init(void)
MACHINE_START(SMDK6400, "SMDK6400")
/* Maintainer: Ben Dooks <ben-linux@fluff.org> */
- .phys_io = S3C_PA_UART & 0xfff00000,
- .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C64XX_PA_SDRAM + 0x100,
.init_irq = s3c6400_init_irq,
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
index d498219fff1b..ec8865c03a19 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -704,8 +704,6 @@ static void __init smdk6410_machine_init(void)
MACHINE_START(SMDK6410, "SMDK6410")
/* Maintainer: Ben Dooks <ben-linux@fluff.org> */
- .phys_io = S3C_PA_UART & 0xfff00000,
- .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C64XX_PA_SDRAM + 0x100,
.init_irq = s3c6410_init_irq,
diff --git a/arch/arm/mach-s5p6440/Kconfig b/arch/arm/mach-s5p6440/Kconfig
deleted file mode 100644
index 6a4af7f57584..000000000000
--- a/arch/arm/mach-s5p6440/Kconfig
+++ /dev/null
@@ -1,33 +0,0 @@
-# arch/arm/mach-s5p6440/Kconfig
-#
-# Copyright (c) 2009 Samsung Electronics Co., Ltd.
-# http://www.samsung.com/
-#
-# Licensed under GPLv2
-
-if ARCH_S5P6440
-
-config CPU_S5P6440
- bool
- select S3C_PL330_DMA
- help
- Enable S5P6440 CPU support
-
-config S5P6440_SETUP_I2C1
- bool
- help
- Common setup code for i2c bus 1.
-
-config MACH_SMDK6440
- bool "SMDK6440"
- select CPU_S5P6440
- select S3C_DEV_I2C1
- select S3C_DEV_RTC
- select S3C_DEV_WDT
- select SAMSUNG_DEV_ADC
- select SAMSUNG_DEV_TS
- select S5P6440_SETUP_I2C1
- help
- Machine support for the Samsung SMDK6440
-
-endif
diff --git a/arch/arm/mach-s5p6440/Makefile b/arch/arm/mach-s5p6440/Makefile
deleted file mode 100644
index c3fe4d3662a9..000000000000
--- a/arch/arm/mach-s5p6440/Makefile
+++ /dev/null
@@ -1,25 +0,0 @@
-# arch/arm/mach-s5p6440/Makefile
-#
-# Copyright (c) 2009 Samsung Electronics Co., Ltd.
-# http://www.samsung.com/
-#
-# Licensed under GPLv2
-
-obj-y :=
-obj-m :=
-obj-n :=
-obj- :=
-
-# Core support for S5P6440 system
-
-obj-$(CONFIG_CPU_S5P6440) += cpu.o init.o clock.o gpio.o dma.o
-obj-$(CONFIG_CPU_S5P6440) += setup-i2c0.o
-
-# machine support
-
-obj-$(CONFIG_MACH_SMDK6440) += mach-smdk6440.o
-
-# device support
-obj-y += dev-audio.o
-obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o
-obj-$(CONFIG_S5P6440_SETUP_I2C1) += setup-i2c1.o
diff --git a/arch/arm/mach-s5p6440/clock.c b/arch/arm/mach-s5p6440/clock.c
deleted file mode 100644
index ca6e48dce777..000000000000
--- a/arch/arm/mach-s5p6440/clock.c
+++ /dev/null
@@ -1,846 +0,0 @@
-/* linux/arch/arm/mach-s5p6440/clock.c
- *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * S5P6440 - Clock support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/sysdev.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <mach/map.h>
-
-#include <plat/cpu-freq.h>
-#include <mach/regs-clock.h>
-#include <plat/clock.h>
-#include <plat/cpu.h>
-#include <plat/clock-clksrc.h>
-#include <plat/s5p-clock.h>
-#include <plat/pll.h>
-#include <plat/s5p6440.h>
-
-/* APLL Mux output clock */
-static struct clksrc_clk clk_mout_apll = {
- .clk = {
- .name = "mout_apll",
- .id = -1,
- },
- .sources = &clk_src_apll,
- .reg_src = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 },
-};
-
-static int s5p6440_epll_enable(struct clk *clk, int enable)
-{
- unsigned int ctrlbit = clk->ctrlbit;
- unsigned int epll_con = __raw_readl(S5P_EPLL_CON) & ~ctrlbit;
-
- if (enable)
- __raw_writel(epll_con | ctrlbit, S5P_EPLL_CON);
- else
- __raw_writel(epll_con, S5P_EPLL_CON);
-
- return 0;
-}
-
-static unsigned long s5p6440_epll_get_rate(struct clk *clk)
-{
- return clk->rate;
-}
-
-static u32 epll_div[][5] = {
- { 36000000, 0, 48, 1, 4 },
- { 48000000, 0, 32, 1, 3 },
- { 60000000, 0, 40, 1, 3 },
- { 72000000, 0, 48, 1, 3 },
- { 84000000, 0, 28, 1, 2 },
- { 96000000, 0, 32, 1, 2 },
- { 32768000, 45264, 43, 1, 4 },
- { 45158000, 6903, 30, 1, 3 },
- { 49152000, 50332, 32, 1, 3 },
- { 67738000, 10398, 45, 1, 3 },
- { 73728000, 9961, 49, 1, 3 }
-};
-
-static int s5p6440_epll_set_rate(struct clk *clk, unsigned long rate)
-{
- unsigned int epll_con, epll_con_k;
- unsigned int i;
-
- if (clk->rate == rate) /* Return if nothing changed */
- return 0;
-
- epll_con = __raw_readl(S5P_EPLL_CON);
- epll_con_k = __raw_readl(S5P_EPLL_CON_K);
-
- epll_con_k &= ~(PLL90XX_KDIV_MASK);
- epll_con &= ~(PLL90XX_MDIV_MASK | PLL90XX_PDIV_MASK | PLL90XX_SDIV_MASK);
-
- for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
- if (epll_div[i][0] == rate) {
- epll_con_k |= (epll_div[i][1] << PLL90XX_KDIV_SHIFT);
- epll_con |= (epll_div[i][2] << PLL90XX_MDIV_SHIFT) |
- (epll_div[i][3] << PLL90XX_PDIV_SHIFT) |
- (epll_div[i][4] << PLL90XX_SDIV_SHIFT);
- break;
- }
- }
-
- if (i == ARRAY_SIZE(epll_div)) {
- printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__);
- return -EINVAL;
- }
-
- __raw_writel(epll_con, S5P_EPLL_CON);
- __raw_writel(epll_con_k, S5P_EPLL_CON_K);
-
- clk->rate = rate;
-
- return 0;
-}
-
-static struct clk_ops s5p6440_epll_ops = {
- .get_rate = s5p6440_epll_get_rate,
- .set_rate = s5p6440_epll_set_rate,
-};
-
-static struct clksrc_clk clk_mout_epll = {
- .clk = {
- .name = "mout_epll",
- .id = -1,
- },
- .sources = &clk_src_epll,
- .reg_src = { .reg = S5P_CLK_SRC0, .shift = 2, .size = 1 },
-};
-
-static struct clksrc_clk clk_mout_mpll = {
- .clk = {
- .name = "mout_mpll",
- .id = -1,
- },
- .sources = &clk_src_mpll,
- .reg_src = { .reg = S5P_CLK_SRC0, .shift = 1, .size = 1 },
-};
-
-enum perf_level {
- L0 = 532*1000,
- L1 = 266*1000,
- L2 = 133*1000,
-};
-
-static const u32 clock_table[][3] = {
- /*{ARM_CLK, DIVarm, DIVhclk}*/
- {L0 * 1000, (0 << ARM_DIV_RATIO_SHIFT), (3 << S5P_CLKDIV0_HCLK_SHIFT)},
- {L1 * 1000, (1 << ARM_DIV_RATIO_SHIFT), (1 << S5P_CLKDIV0_HCLK_SHIFT)},
- {L2 * 1000, (3 << ARM_DIV_RATIO_SHIFT), (0 << S5P_CLKDIV0_HCLK_SHIFT)},
-};
-
-static unsigned long s5p6440_armclk_get_rate(struct clk *clk)
-{
- unsigned long rate = clk_get_rate(clk->parent);
- u32 clkdiv;
-
- /* divisor mask starts at bit0, so no need to shift */
- clkdiv = __raw_readl(ARM_CLK_DIV) & ARM_DIV_MASK;
-
- return rate / (clkdiv + 1);
-}
-
-static unsigned long s5p6440_armclk_round_rate(struct clk *clk,
- unsigned long rate)
-{
- u32 iter;
-
- for (iter = 1 ; iter < ARRAY_SIZE(clock_table) ; iter++) {
- if (rate > clock_table[iter][0])
- return clock_table[iter-1][0];
- }
-
- return clock_table[ARRAY_SIZE(clock_table) - 1][0];
-}
-
-static int s5p6440_armclk_set_rate(struct clk *clk, unsigned long rate)
-{
- u32 round_tmp;
- u32 iter;
- u32 clk_div0_tmp;
- u32 cur_rate = clk->ops->get_rate(clk);
- unsigned long flags;
-
- round_tmp = clk->ops->round_rate(clk, rate);
- if (round_tmp == cur_rate)
- return 0;
-
-
- for (iter = 0 ; iter < ARRAY_SIZE(clock_table) ; iter++) {
- if (round_tmp == clock_table[iter][0])
- break;
- }
-
- if (iter >= ARRAY_SIZE(clock_table))
- iter = ARRAY_SIZE(clock_table) - 1;
-
- local_irq_save(flags);
- if (cur_rate > round_tmp) {
- /* Frequency Down */
- clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & ~(ARM_DIV_MASK);
- clk_div0_tmp |= clock_table[iter][1];
- __raw_writel(clk_div0_tmp, ARM_CLK_DIV);
-
- clk_div0_tmp = __raw_readl(ARM_CLK_DIV) &
- ~(S5P_CLKDIV0_HCLK_MASK);
- clk_div0_tmp |= clock_table[iter][2];
- __raw_writel(clk_div0_tmp, ARM_CLK_DIV);
-
-
- } else {
- /* Frequency Up */
- clk_div0_tmp = __raw_readl(ARM_CLK_DIV) &
- ~(S5P_CLKDIV0_HCLK_MASK);
- clk_div0_tmp |= clock_table[iter][2];
- __raw_writel(clk_div0_tmp, ARM_CLK_DIV);
-
- clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & ~(ARM_DIV_MASK);
- clk_div0_tmp |= clock_table[iter][1];
- __raw_writel(clk_div0_tmp, ARM_CLK_DIV);
- }
- local_irq_restore(flags);
-
- clk->rate = clock_table[iter][0];
-
- return 0;
-}
-
-static struct clk_ops s5p6440_clkarm_ops = {
- .get_rate = s5p6440_armclk_get_rate,
- .set_rate = s5p6440_armclk_set_rate,
- .round_rate = s5p6440_armclk_round_rate,
-};
-
-static struct clksrc_clk clk_armclk = {
- .clk = {
- .name = "armclk",
- .id = 1,
- .parent = &clk_mout_apll.clk,
- .ops = &s5p6440_clkarm_ops,
- },
- .reg_div = { .reg = S5P_CLK_DIV0, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk clk_dout_mpll = {
- .clk = {
- .name = "dout_mpll",
- .id = -1,
- .parent = &clk_mout_mpll.clk,
- },
- .reg_div = { .reg = S5P_CLK_DIV0, .shift = 4, .size = 1 },
-};
-
-static struct clksrc_clk clk_hclk = {
- .clk = {
- .name = "clk_hclk",
- .id = -1,
- .parent = &clk_armclk.clk,
- },
- .reg_div = { .reg = S5P_CLK_DIV0, .shift = 8, .size = 4 },
-};
-
-static struct clksrc_clk clk_pclk = {
- .clk = {
- .name = "clk_pclk",
- .id = -1,
- .parent = &clk_hclk.clk,
- },
- .reg_div = { .reg = S5P_CLK_DIV0, .shift = 12, .size = 4 },
-};
-
-static struct clk *clkset_hclklow_list[] = {
- &clk_mout_apll.clk,
- &clk_mout_mpll.clk,
-};
-
-static struct clksrc_sources clkset_hclklow = {
- .sources = clkset_hclklow_list,
- .nr_sources = ARRAY_SIZE(clkset_hclklow_list),
-};
-
-static struct clksrc_clk clk_hclk_low = {
- .clk = {
- .name = "hclk_low",
- .id = -1,
- },
- .sources = &clkset_hclklow,
- .reg_src = { .reg = S5P_SYS_OTHERS, .shift = 6, .size = 1 },
- .reg_div = { .reg = S5P_CLK_DIV3, .shift = 8, .size = 4 },
-};
-
-static struct clksrc_clk clk_pclk_low = {
- .clk = {
- .name = "pclk_low",
- .id = -1,
- .parent = &clk_hclk_low.clk,
- },
- .reg_div = { .reg = S5P_CLK_DIV3, .shift = 12, .size = 4 },
-};
-
-int s5p6440_clk48m_ctrl(struct clk *clk, int enable)
-{
- unsigned long flags;
- u32 val;
-
- /* can't rely on clock lock, this register has other usages */
- local_irq_save(flags);
-
- val = __raw_readl(S5P_OTHERS);
- if (enable)
- val |= S5P_OTHERS_USB_SIG_MASK;
- else
- val &= ~S5P_OTHERS_USB_SIG_MASK;
-
- __raw_writel(val, S5P_OTHERS);
-
- local_irq_restore(flags);
-
- return 0;
-}
-
-static int s5p6440_pclk_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(S5P_CLK_GATE_PCLK, clk, enable);
-}
-
-static int s5p6440_hclk0_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(S5P_CLK_GATE_HCLK0, clk, enable);
-}
-
-static int s5p6440_hclk1_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(S5P_CLK_GATE_HCLK1, clk, enable);
-}
-
-static int s5p6440_sclk_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(S5P_CLK_GATE_SCLK0, clk, enable);
-}
-
-static int s5p6440_sclk1_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(S5P_CLK_GATE_SCLK1, clk, enable);
-}
-
-static int s5p6440_mem_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(S5P_CLK_GATE_MEM0, clk, enable);
-}
-
-/*
- * The following clocks will be disabled during clock initialization. It is
- * recommended to keep the following clocks disabled until the driver requests
- * for enabling the clock.
- */
-static struct clk init_clocks_disable[] = {
- {
- .name = "nand",
- .id = -1,
- .parent = &clk_hclk.clk,
- .enable = s5p6440_mem_ctrl,
- .ctrlbit = S5P_CLKCON_MEM0_HCLK_NFCON,
- }, {
- .name = "adc",
- .id = -1,
- .parent = &clk_pclk_low.clk,
- .enable = s5p6440_pclk_ctrl,
- .ctrlbit = S5P_CLKCON_PCLK_TSADC,
- }, {
- .name = "i2c",
- .id = -1,
- .parent = &clk_pclk_low.clk,
- .enable = s5p6440_pclk_ctrl,
- .ctrlbit = S5P_CLKCON_PCLK_IIC0,
- }, {
- .name = "i2s_v40",
- .id = 0,
- .parent = &clk_pclk_low.clk,
- .enable = s5p6440_pclk_ctrl,
- .ctrlbit = S5P_CLKCON_PCLK_IIS2,
- }, {
- .name = "spi",
- .id = 0,
- .parent = &clk_pclk_low.clk,
- .enable = s5p6440_pclk_ctrl,
- .ctrlbit = S5P_CLKCON_PCLK_SPI0,
- }, {
- .name = "spi",
- .id = 1,
- .parent = &clk_pclk_low.clk,
- .enable = s5p6440_pclk_ctrl,
- .ctrlbit = S5P_CLKCON_PCLK_SPI1,
- }, {
- .name = "sclk_spi_48",
- .id = 0,
- .parent = &clk_48m,
- .enable = s5p6440_sclk_ctrl,
- .ctrlbit = S5P_CLKCON_SCLK0_SPI0_48,
- }, {
- .name = "sclk_spi_48",
- .id = 1,
- .parent = &clk_48m,
- .enable = s5p6440_sclk_ctrl,
- .ctrlbit = S5P_CLKCON_SCLK0_SPI1_48,
- }, {
- .name = "mmc_48m",
- .id = 0,
- .parent = &clk_48m,
- .enable = s5p6440_sclk_ctrl,
- .ctrlbit = S5P_CLKCON_SCLK0_MMC0_48,
- }, {
- .name = "mmc_48m",
- .id = 1,
- .parent = &clk_48m,
- .enable = s5p6440_sclk_ctrl,
- .ctrlbit = S5P_CLKCON_SCLK0_MMC1_48,
- }, {
- .name = "mmc_48m",
- .id = 2,
- .parent = &clk_48m,
- .enable = s5p6440_sclk_ctrl,
- .ctrlbit = S5P_CLKCON_SCLK0_MMC2_48,
- }, {
- .name = "otg",
- .id = -1,
- .parent = &clk_hclk_low.clk,
- .enable = s5p6440_hclk0_ctrl,
- .ctrlbit = S5P_CLKCON_HCLK0_USB
- }, {
- .name = "post",
- .id = -1,
- .parent = &clk_hclk_low.clk,
- .enable = s5p6440_hclk0_ctrl,
- .ctrlbit = S5P_CLKCON_HCLK0_POST0
- }, {
- .name = "lcd",
- .id = -1,
- .parent = &clk_hclk_low.clk,
- .enable = s5p6440_hclk1_ctrl,
- .ctrlbit = S5P_CLKCON_HCLK1_DISPCON,
- }, {
- .name = "hsmmc",
- .id = 0,
- .parent = &clk_hclk_low.clk,
- .enable = s5p6440_hclk0_ctrl,
- .ctrlbit = S5P_CLKCON_HCLK0_HSMMC0,
- }, {
- .name = "hsmmc",
- .id = 1,
- .parent = &clk_hclk_low.clk,
- .enable = s5p6440_hclk0_ctrl,
- .ctrlbit = S5P_CLKCON_HCLK0_HSMMC1,
- }, {
- .name = "hsmmc",
- .id = 2,
- .parent = &clk_hclk_low.clk,
- .enable = s5p6440_hclk0_ctrl,
- .ctrlbit = S5P_CLKCON_HCLK0_HSMMC2,
- }, {
- .name = "rtc",
- .id = -1,
- .parent = &clk_pclk_low.clk,
- .enable = s5p6440_pclk_ctrl,
- .ctrlbit = S5P_CLKCON_PCLK_RTC,
- }, {
- .name = "watchdog",
- .id = -1,
- .parent = &clk_pclk_low.clk,
- .enable = s5p6440_pclk_ctrl,
- .ctrlbit = S5P_CLKCON_PCLK_WDT,
- }, {
- .name = "timers",
- .id = -1,
- .parent = &clk_pclk_low.clk,
- .enable = s5p6440_pclk_ctrl,
- .ctrlbit = S5P_CLKCON_PCLK_PWM,
- }, {
- .name = "hclk_fimgvg",
- .id = -1,
- .parent = &clk_hclk.clk,
- .enable = s5p6440_hclk1_ctrl,
- .ctrlbit = (1 << 2),
- }, {
- .name = "tsi",
- .id = -1,
- .parent = &clk_hclk_low.clk,
- .enable = s5p6440_hclk1_ctrl,
- .ctrlbit = (1 << 0),
- }, {
- .name = "pclk_fimgvg",
- .id = -1,
- .parent = &clk_pclk.clk,
- .enable = s5p6440_pclk_ctrl,
- .ctrlbit = (1 << 31),
- }, {
- .name = "dmc0",
- .id = -1,
- .parent = &clk_pclk.clk,
- .enable = s5p6440_pclk_ctrl,
- .ctrlbit = (1 << 30),
- }, {
- .name = "etm",
- .id = -1,
- .parent = &clk_pclk.clk,
- .enable = s5p6440_pclk_ctrl,
- .ctrlbit = (1 << 29),
- }, {
- .name = "dsim",
- .id = -1,
- .parent = &clk_pclk_low.clk,
- .enable = s5p6440_pclk_ctrl,
- .ctrlbit = (1 << 28),
- }, {
- .name = "gps",
- .id = -1,
- .parent = &clk_pclk_low.clk,
- .enable = s5p6440_pclk_ctrl,
- .ctrlbit = (1 << 25),
- }, {
- .name = "pcm",
- .id = -1,
- .parent = &clk_pclk_low.clk,
- .enable = s5p6440_pclk_ctrl,
- .ctrlbit = (1 << 8),
- }, {
- .name = "irom",
- .id = -1,
- .parent = &clk_hclk.clk,
- .enable = s5p6440_hclk0_ctrl,
- .ctrlbit = (1 << 25),
- }, {
- .name = "dma",
- .id = -1,
- .parent = &clk_hclk_low.clk,
- .enable = s5p6440_hclk0_ctrl,
- .ctrlbit = (1 << 12),
- }, {
- .name = "2d",
- .id = -1,
- .parent = &clk_hclk.clk,
- .enable = s5p6440_hclk0_ctrl,
- .ctrlbit = (1 << 8),
- },
-};
-
-/*
- * The following clocks will be enabled during clock initialization.
- */
-static struct clk init_clocks[] = {
- {
- .name = "gpio",
- .id = -1,
- .parent = &clk_pclk_low.clk,
- .enable = s5p6440_pclk_ctrl,
- .ctrlbit = S5P_CLKCON_PCLK_GPIO,
- }, {
- .name = "uart",
- .id = 0,
- .parent = &clk_pclk_low.clk,
- .enable = s5p6440_pclk_ctrl,
- .ctrlbit = S5P_CLKCON_PCLK_UART0,
- }, {
- .name = "uart",
- .id = 1,
- .parent = &clk_pclk_low.clk,
- .enable = s5p6440_pclk_ctrl,
- .ctrlbit = S5P_CLKCON_PCLK_UART1,
- }, {
- .name = "uart",
- .id = 2,
- .parent = &clk_pclk_low.clk,
- .enable = s5p6440_pclk_ctrl,
- .ctrlbit = S5P_CLKCON_PCLK_UART2,
- }, {
- .name = "uart",
- .id = 3,
- .parent = &clk_pclk_low.clk,
- .enable = s5p6440_pclk_ctrl,
- .ctrlbit = S5P_CLKCON_PCLK_UART3,
- }, {
- .name = "mem",
- .id = -1,
- .parent = &clk_hclk.clk,
- .enable = s5p6440_hclk0_ctrl,
- .ctrlbit = (1 << 21),
- }, {
- .name = "intc",
- .id = -1,
- .parent = &clk_hclk.clk,
- .enable = s5p6440_hclk0_ctrl,
- .ctrlbit = (1 << 1),
- },
-};
-
-static struct clk clk_iis_cd_v40 = {
- .name = "iis_cdclk_v40",
- .id = -1,
-};
-
-static struct clk clk_pcm_cd = {
- .name = "pcm_cdclk",
- .id = -1,
-};
-
-static struct clk *clkset_group1_list[] = {
- &clk_mout_epll.clk,
- &clk_dout_mpll.clk,
- &clk_fin_epll,
-};
-
-static struct clksrc_sources clkset_group1 = {
- .sources = clkset_group1_list,
- .nr_sources = ARRAY_SIZE(clkset_group1_list),
-};
-
-static struct clk *clkset_uart_list[] = {
- &clk_mout_epll.clk,
- &clk_dout_mpll.clk,
-};
-
-static struct clksrc_sources clkset_uart = {
- .sources = clkset_uart_list,
- .nr_sources = ARRAY_SIZE(clkset_uart_list),
-};
-
-static struct clk *clkset_audio_list[] = {
- &clk_mout_epll.clk,
- &clk_dout_mpll.clk,
- &clk_fin_epll,
- &clk_iis_cd_v40,
- &clk_pcm_cd,
-};
-
-static struct clksrc_sources clkset_audio = {
- .sources = clkset_audio_list,
- .nr_sources = ARRAY_SIZE(clkset_audio_list),
-};
-
-static struct clksrc_clk clksrcs[] = {
- {
- .clk = {
- .name = "mmc_bus",
- .id = 0,
- .ctrlbit = S5P_CLKCON_SCLK0_MMC0,
- .enable = s5p6440_sclk_ctrl,
- },
- .sources = &clkset_group1,
- .reg_src = { .reg = S5P_CLK_SRC0, .shift = 18, .size = 2 },
- .reg_div = { .reg = S5P_CLK_DIV1, .shift = 0, .size = 4 },
- }, {
- .clk = {
- .name = "mmc_bus",
- .id = 1,
- .ctrlbit = S5P_CLKCON_SCLK0_MMC1,
- .enable = s5p6440_sclk_ctrl,
- },
- .sources = &clkset_group1,
- .reg_src = { .reg = S5P_CLK_SRC0, .shift = 20, .size = 2 },
- .reg_div = { .reg = S5P_CLK_DIV1, .shift = 4, .size = 4 },
- }, {
- .clk = {
- .name = "mmc_bus",
- .id = 2,
- .ctrlbit = S5P_CLKCON_SCLK0_MMC2,
- .enable = s5p6440_sclk_ctrl,
- },
- .sources = &clkset_group1,
- .reg_src = { .reg = S5P_CLK_SRC0, .shift = 22, .size = 2 },
- .reg_div = { .reg = S5P_CLK_DIV1, .shift = 8, .size = 4 },
- }, {
- .clk = {
- .name = "uclk1",
- .id = -1,
- .ctrlbit = S5P_CLKCON_SCLK0_UART,
- .enable = s5p6440_sclk_ctrl,
- },
- .sources = &clkset_uart,
- .reg_src = { .reg = S5P_CLK_SRC0, .shift = 13, .size = 1 },
- .reg_div = { .reg = S5P_CLK_DIV2, .shift = 16, .size = 4 },
- }, {
- .clk = {
- .name = "spi_epll",
- .id = 0,
- .ctrlbit = S5P_CLKCON_SCLK0_SPI0,
- .enable = s5p6440_sclk_ctrl,
- },
- .sources = &clkset_group1,
- .reg_src = { .reg = S5P_CLK_SRC0, .shift = 14, .size = 2 },
- .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
- }, {
- .clk = {
- .name = "spi_epll",
- .id = 1,
- .ctrlbit = S5P_CLKCON_SCLK0_SPI1,
- .enable = s5p6440_sclk_ctrl,
- },
- .sources = &clkset_group1,
- .reg_src = { .reg = S5P_CLK_SRC0, .shift = 16, .size = 2 },
- .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_post",
- .id = -1,
- .ctrlbit = (1 << 10),
- .enable = s5p6440_sclk_ctrl,
- },
- .sources = &clkset_group1,
- .reg_src = { .reg = S5P_CLK_SRC0, .shift = 26, .size = 2 },
- .reg_div = { .reg = S5P_CLK_DIV1, .shift = 12, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_dispcon",
- .id = -1,
- .ctrlbit = (1 << 1),
- .enable = s5p6440_sclk1_ctrl,
- },
- .sources = &clkset_group1,
- .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 2 },
- .reg_div = { .reg = S5P_CLK_DIV3, .shift = 0, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_fimgvg",
- .id = -1,
- .ctrlbit = (1 << 2),
- .enable = s5p6440_sclk1_ctrl,
- },
- .sources = &clkset_group1,
- .reg_src = { .reg = S5P_CLK_SRC1, .shift = 8, .size = 2 },
- .reg_div = { .reg = S5P_CLK_DIV3, .shift = 4, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_audio2",
- .id = -1,
- .ctrlbit = (1 << 11),
- .enable = s5p6440_sclk_ctrl,
- },
- .sources = &clkset_audio,
- .reg_src = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 3 },
- .reg_div = { .reg = S5P_CLK_DIV2, .shift = 24, .size = 4 },
- },
-};
-
-/* Clock initialisation code */
-static struct clksrc_clk *sysclks[] = {
- &clk_mout_apll,
- &clk_mout_epll,
- &clk_mout_mpll,
- &clk_dout_mpll,
- &clk_armclk,
- &clk_hclk,
- &clk_pclk,
- &clk_hclk_low,
- &clk_pclk_low,
-};
-
-void __init_or_cpufreq s5p6440_setup_clocks(void)
-{
- struct clk *xtal_clk;
- unsigned long xtal;
- unsigned long fclk;
- unsigned long hclk;
- unsigned long hclk_low;
- unsigned long pclk;
- unsigned long pclk_low;
- unsigned long epll;
- unsigned long apll;
- unsigned long mpll;
- unsigned int ptr;
-
- /* Set S5P6440 functions for clk_fout_epll */
- clk_fout_epll.enable = s5p6440_epll_enable;
- clk_fout_epll.ops = &s5p6440_epll_ops;
-
- clk_48m.enable = s5p6440_clk48m_ctrl;
-
- xtal_clk = clk_get(NULL, "ext_xtal");
- BUG_ON(IS_ERR(xtal_clk));
-
- xtal = clk_get_rate(xtal_clk);
- clk_put(xtal_clk);
-
- epll = s5p_get_pll90xx(xtal, __raw_readl(S5P_EPLL_CON),
- __raw_readl(S5P_EPLL_CON_K));
- mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502);
- apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4502);
-
- clk_fout_mpll.rate = mpll;
- clk_fout_epll.rate = epll;
- clk_fout_apll.rate = apll;
-
- printk(KERN_INFO "S5P6440: PLL settings, A=%ld.%ldMHz, M=%ld.%ldMHz," \
- " E=%ld.%ldMHz\n",
- print_mhz(apll), print_mhz(mpll), print_mhz(epll));
-
- fclk = clk_get_rate(&clk_armclk.clk);
- hclk = clk_get_rate(&clk_hclk.clk);
- pclk = clk_get_rate(&clk_pclk.clk);
- hclk_low = clk_get_rate(&clk_hclk_low.clk);
- pclk_low = clk_get_rate(&clk_pclk_low.clk);
-
- printk(KERN_INFO "S5P6440: HCLK=%ld.%ldMHz, HCLK_LOW=%ld.%ldMHz," \
- " PCLK=%ld.%ldMHz, PCLK_LOW=%ld.%ldMHz\n",
- print_mhz(hclk), print_mhz(hclk_low),
- print_mhz(pclk), print_mhz(pclk_low));
-
- clk_f.rate = fclk;
- clk_h.rate = hclk;
- clk_p.rate = pclk;
-
- for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
- s3c_set_clksrc(&clksrcs[ptr], true);
-}
-
-static struct clk *clks[] __initdata = {
- &clk_ext,
- &clk_iis_cd_v40,
- &clk_pcm_cd,
-};
-
-void __init s5p6440_register_clocks(void)
-{
- struct clk *clkp;
- int ret;
- int ptr;
-
- ret = s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
- if (ret > 0)
- printk(KERN_ERR "Failed to register %u clocks\n", ret);
-
- for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
- s3c_register_clksrc(sysclks[ptr], 1);
-
- s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
- s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
-
- clkp = init_clocks_disable;
- for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
-
- ret = s3c24xx_register_clock(clkp);
- if (ret < 0) {
- printk(KERN_ERR "Failed to register clock %s (%d)\n",
- clkp->name, ret);
- }
- (clkp->enable)(clkp, 0);
- }
-
- s3c_pwmclk_init();
-}
diff --git a/arch/arm/mach-s5p6440/cpu.c b/arch/arm/mach-s5p6440/cpu.c
deleted file mode 100644
index 526f33adb31d..000000000000
--- a/arch/arm/mach-s5p6440/cpu.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/* linux/arch/arm/mach-s5p6440/cpu.c
- *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/sysdev.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <asm/proc-fns.h>
-
-#include <mach/hardware.h>
-#include <mach/map.h>
-#include <asm/irq.h>
-
-#include <plat/regs-serial.h>
-#include <mach/regs-clock.h>
-
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/clock.h>
-#include <plat/s5p6440.h>
-#include <plat/adc-core.h>
-
-static void s5p6440_idle(void)
-{
- unsigned long val;
-
- if (!need_resched()) {
- val = __raw_readl(S5P_PWR_CFG);
- val &= ~(0x3<<5);
- val |= (0x1<<5);
- __raw_writel(val, S5P_PWR_CFG);
-
- cpu_do_idle();
- }
- local_irq_enable();
-}
-
-/* s5p6440_map_io
- *
- * register the standard cpu IO areas
-*/
-
-void __init s5p6440_map_io(void)
-{
- /* initialize any device information early */
- s3c_adc_setname("s3c64xx-adc");
-}
-
-void __init s5p6440_init_clocks(int xtal)
-{
- printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
-
- s3c24xx_register_baseclocks(xtal);
- s5p_register_clocks(xtal);
- s5p6440_register_clocks();
- s5p6440_setup_clocks();
-}
-
-void __init s5p6440_init_irq(void)
-{
- /* S5P6440 supports only 2 VIC */
- u32 vic[2];
-
- /*
- * VIC0 is missing IRQ_VIC0[3, 4, 8, 10, (12-22)]
- * VIC1 is missing IRQ VIC1[1, 3, 4, 10, 11, 12, 14, 15, 22]
- */
- vic[0] = 0xff800ae7;
- vic[1] = 0xffbf23e5;
-
- s5p_init_irq(vic, ARRAY_SIZE(vic));
-}
-
-struct sysdev_class s5p6440_sysclass = {
- .name = "s5p6440-core",
-};
-
-static struct sys_device s5p6440_sysdev = {
- .cls = &s5p6440_sysclass,
-};
-
-static int __init s5p6440_core_init(void)
-{
- return sysdev_class_register(&s5p6440_sysclass);
-}
-
-core_initcall(s5p6440_core_init);
-
-int __init s5p6440_init(void)
-{
- printk(KERN_INFO "S5P6440: Initializing architecture\n");
-
- /* set idle function */
- pm_idle = s5p6440_idle;
-
- return sysdev_register(&s5p6440_sysdev);
-}
diff --git a/arch/arm/mach-s5p6440/dev-audio.c b/arch/arm/mach-s5p6440/dev-audio.c
deleted file mode 100644
index 3ca0d2b8275d..000000000000
--- a/arch/arm/mach-s5p6440/dev-audio.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/* linux/arch/arm/mach-s5p6440/dev-audio.c
- *
- * Copyright (c) 2010 Samsung Electronics Co. Ltd
- * Jaswinder Singh <jassi.brar@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/gpio.h>
-
-#include <plat/gpio-cfg.h>
-#include <plat/audio.h>
-
-#include <mach/map.h>
-#include <mach/dma.h>
-#include <mach/irqs.h>
-
-static int s5p6440_cfg_i2s(struct platform_device *pdev)
-{
- /* configure GPIO for i2s port */
- switch (pdev->id) {
- case -1:
- s3c_gpio_cfgpin(S5P6440_GPR(4), S3C_GPIO_SFN(5));
- s3c_gpio_cfgpin(S5P6440_GPR(5), S3C_GPIO_SFN(5));
- s3c_gpio_cfgpin(S5P6440_GPR(6), S3C_GPIO_SFN(5));
- s3c_gpio_cfgpin(S5P6440_GPR(7), S3C_GPIO_SFN(5));
- s3c_gpio_cfgpin(S5P6440_GPR(8), S3C_GPIO_SFN(5));
- s3c_gpio_cfgpin(S5P6440_GPR(13), S3C_GPIO_SFN(5));
- s3c_gpio_cfgpin(S5P6440_GPR(14), S3C_GPIO_SFN(5));
- break;
-
- default:
- printk(KERN_ERR "Invalid Device %d\n", pdev->id);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static struct s3c_audio_pdata s3c_i2s_pdata = {
- .cfg_gpio = s5p6440_cfg_i2s,
-};
-
-static struct resource s5p6440_iis0_resource[] = {
- [0] = {
- .start = S5P6440_PA_I2S,
- .end = S5P6440_PA_I2S + 0x100 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = DMACH_I2S0_TX,
- .end = DMACH_I2S0_TX,
- .flags = IORESOURCE_DMA,
- },
- [2] = {
- .start = DMACH_I2S0_RX,
- .end = DMACH_I2S0_RX,
- .flags = IORESOURCE_DMA,
- },
-};
-
-struct platform_device s5p6440_device_iis = {
- .name = "s3c64xx-iis-v4",
- .id = -1,
- .num_resources = ARRAY_SIZE(s5p6440_iis0_resource),
- .resource = s5p6440_iis0_resource,
- .dev = {
- .platform_data = &s3c_i2s_pdata,
- },
-};
-
-/* PCM Controller platform_devices */
-
-static int s5p6440_pcm_cfg_gpio(struct platform_device *pdev)
-{
- switch (pdev->id) {
- case 0:
- s3c_gpio_cfgpin(S5P6440_GPR(7), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5P6440_GPR(13), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5P6440_GPR(14), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5P6440_GPR(8), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5P6440_GPR(6), S3C_GPIO_SFN(2));
- break;
-
- default:
- printk(KERN_DEBUG "Invalid PCM Controller number!");
- return -EINVAL;
- }
-
- return 0;
-}
-
-static struct s3c_audio_pdata s3c_pcm_pdata = {
- .cfg_gpio = s5p6440_pcm_cfg_gpio,
-};
-
-static struct resource s5p6440_pcm0_resource[] = {
- [0] = {
- .start = S5P6440_PA_PCM,
- .end = S5P6440_PA_PCM + 0x100 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = DMACH_PCM0_TX,
- .end = DMACH_PCM0_TX,
- .flags = IORESOURCE_DMA,
- },
- [2] = {
- .start = DMACH_PCM0_RX,
- .end = DMACH_PCM0_RX,
- .flags = IORESOURCE_DMA,
- },
-};
-
-struct platform_device s5p6440_device_pcm = {
- .name = "samsung-pcm",
- .id = 0,
- .num_resources = ARRAY_SIZE(s5p6440_pcm0_resource),
- .resource = s5p6440_pcm0_resource,
- .dev = {
- .platform_data = &s3c_pcm_pdata,
- },
-};
diff --git a/arch/arm/mach-s5p6440/dev-spi.c b/arch/arm/mach-s5p6440/dev-spi.c
deleted file mode 100644
index 510af44d180c..000000000000
--- a/arch/arm/mach-s5p6440/dev-spi.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/* linux/arch/arm/mach-s5p6440/dev-spi.c
- *
- * Copyright (C) 2010 Samsung Electronics Co. Ltd.
- * Jaswinder Singh <jassi.brar@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/gpio.h>
-
-#include <mach/dma.h>
-#include <mach/map.h>
-#include <mach/irqs.h>
-#include <mach/spi-clocks.h>
-
-#include <plat/s3c64xx-spi.h>
-#include <plat/gpio-cfg.h>
-
-static char *spi_src_clks[] = {
- [S5P6440_SPI_SRCCLK_PCLK] = "pclk",
- [S5P6440_SPI_SRCCLK_SCLK] = "spi_epll",
-};
-
-/* SPI Controller platform_devices */
-
-/* Since we emulate multi-cs capability, we do not touch the CS.
- * The emulated CS is toggled by board specific mechanism, as it can
- * be either some immediate GPIO or some signal out of some other
- * chip in between ... or some yet another way.
- * We simply do not assume anything about CS.
- */
-static int s5p6440_spi_cfg_gpio(struct platform_device *pdev)
-{
- switch (pdev->id) {
- case 0:
- s3c_gpio_cfgpin(S5P6440_GPC(0), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5P6440_GPC(1), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5P6440_GPC(2), S3C_GPIO_SFN(2));
- s3c_gpio_setpull(S5P6440_GPC(0), S3C_GPIO_PULL_UP);
- s3c_gpio_setpull(S5P6440_GPC(1), S3C_GPIO_PULL_UP);
- s3c_gpio_setpull(S5P6440_GPC(2), S3C_GPIO_PULL_UP);
- break;
-
- case 1:
- s3c_gpio_cfgpin(S5P6440_GPC(4), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5P6440_GPC(5), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5P6440_GPC(6), S3C_GPIO_SFN(2));
- s3c_gpio_setpull(S5P6440_GPC(4), S3C_GPIO_PULL_UP);
- s3c_gpio_setpull(S5P6440_GPC(5), S3C_GPIO_PULL_UP);
- s3c_gpio_setpull(S5P6440_GPC(6), S3C_GPIO_PULL_UP);
- break;
-
- default:
- dev_err(&pdev->dev, "Invalid SPI Controller number!");
- return -EINVAL;
- }
-
- return 0;
-}
-
-static struct resource s5p6440_spi0_resource[] = {
- [0] = {
- .start = S5P6440_PA_SPI0,
- .end = S5P6440_PA_SPI0 + 0x100 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = DMACH_SPI0_TX,
- .end = DMACH_SPI0_TX,
- .flags = IORESOURCE_DMA,
- },
- [2] = {
- .start = DMACH_SPI0_RX,
- .end = DMACH_SPI0_RX,
- .flags = IORESOURCE_DMA,
- },
- [3] = {
- .start = IRQ_SPI0,
- .end = IRQ_SPI0,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct s3c64xx_spi_info s5p6440_spi0_pdata = {
- .cfg_gpio = s5p6440_spi_cfg_gpio,
- .fifo_lvl_mask = 0x1ff,
- .rx_lvl_offset = 15,
-};
-
-static u64 spi_dmamask = DMA_BIT_MASK(32);
-
-struct platform_device s5p6440_device_spi0 = {
- .name = "s3c64xx-spi",
- .id = 0,
- .num_resources = ARRAY_SIZE(s5p6440_spi0_resource),
- .resource = s5p6440_spi0_resource,
- .dev = {
- .dma_mask = &spi_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- .platform_data = &s5p6440_spi0_pdata,
- },
-};
-
-static struct resource s5p6440_spi1_resource[] = {
- [0] = {
- .start = S5P6440_PA_SPI1,
- .end = S5P6440_PA_SPI1 + 0x100 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = DMACH_SPI1_TX,
- .end = DMACH_SPI1_TX,
- .flags = IORESOURCE_DMA,
- },
- [2] = {
- .start = DMACH_SPI1_RX,
- .end = DMACH_SPI1_RX,
- .flags = IORESOURCE_DMA,
- },
- [3] = {
- .start = IRQ_SPI1,
- .end = IRQ_SPI1,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct s3c64xx_spi_info s5p6440_spi1_pdata = {
- .cfg_gpio = s5p6440_spi_cfg_gpio,
- .fifo_lvl_mask = 0x7f,
- .rx_lvl_offset = 15,
-};
-
-struct platform_device s5p6440_device_spi1 = {
- .name = "s3c64xx-spi",
- .id = 1,
- .num_resources = ARRAY_SIZE(s5p6440_spi1_resource),
- .resource = s5p6440_spi1_resource,
- .dev = {
- .dma_mask = &spi_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- .platform_data = &s5p6440_spi1_pdata,
- },
-};
-
-void __init s5p6440_spi_set_info(int cntrlr, int src_clk_nr, int num_cs)
-{
- struct s3c64xx_spi_info *pd;
-
- /* Reject invalid configuration */
- if (!num_cs || src_clk_nr < 0
- || src_clk_nr > S5P6440_SPI_SRCCLK_SCLK) {
- printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__);
- return;
- }
-
- switch (cntrlr) {
- case 0:
- pd = &s5p6440_spi0_pdata;
- break;
- case 1:
- pd = &s5p6440_spi1_pdata;
- break;
- default:
- printk(KERN_ERR "%s: Invalid SPI controller(%d)\n",
- __func__, cntrlr);
- return;
- }
-
- pd->num_cs = num_cs;
- pd->src_clk_nr = src_clk_nr;
- pd->src_clk_name = spi_src_clks[src_clk_nr];
-}
diff --git a/arch/arm/mach-s5p6440/include/mach/debug-macro.S b/arch/arm/mach-s5p6440/include/mach/debug-macro.S
deleted file mode 100644
index 1347d7f99079..000000000000
--- a/arch/arm/mach-s5p6440/include/mach/debug-macro.S
+++ /dev/null
@@ -1,37 +0,0 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/debug-macro.S
- *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-/* pull in the relevant register and map files. */
-
-#include <mach/map.h>
-#include <plat/regs-serial.h>
-
- /* note, for the boot process to work we have to keep the UART
- * virtual address aligned to an 1MiB boundary for the L1
- * mapping the head code makes. We keep the UART virtual address
- * aligned and add in the offset when we load the value here.
- */
-
- .macro addruart, rx, rtmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1
- ldreq \rx, = S3C_PA_UART
- ldrne \rx, = S3C_VA_UART
-#if CONFIG_DEBUG_S3C_UART != 0
- add \rx, \rx, #(0x400 * CONFIG_DEBUG_S3C_UART)
-#endif
- .endm
-
-/* include the reset of the code which will do the work, we're only
- * compiling for a single cpu processor type so the default of s3c2440
- * will be fine with us.
- */
-
-#include <plat/debug-macro.S>
diff --git a/arch/arm/mach-s5p6440/include/mach/gpio.h b/arch/arm/mach-s5p6440/include/mach/gpio.h
deleted file mode 100644
index 21783834f2a2..000000000000
--- a/arch/arm/mach-s5p6440/include/mach/gpio.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/gpio.h
- *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * S5P6440 - GPIO lib support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_GPIO_H
-#define __ASM_ARCH_GPIO_H __FILE__
-
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep __gpio_cansleep
-#define gpio_to_irq __gpio_to_irq
-
-/* GPIO bank sizes */
-#define S5P6440_GPIO_A_NR (6)
-#define S5P6440_GPIO_B_NR (7)
-#define S5P6440_GPIO_C_NR (8)
-#define S5P6440_GPIO_F_NR (2)
-#define S5P6440_GPIO_G_NR (7)
-#define S5P6440_GPIO_H_NR (10)
-#define S5P6440_GPIO_I_NR (16)
-#define S5P6440_GPIO_J_NR (12)
-#define S5P6440_GPIO_N_NR (16)
-#define S5P6440_GPIO_P_NR (8)
-#define S5P6440_GPIO_R_NR (15)
-
-/* GPIO bank numbers */
-
-/* CONFIG_S3C_GPIO_SPACE allows the user to select extra
- * space for debugging purposes so that any accidental
- * change from one gpio bank to another can be caught.
-*/
-#define S5P6440_GPIO_NEXT(__gpio) \
- ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
-
-enum s5p_gpio_number {
- S5P6440_GPIO_A_START = 0,
- S5P6440_GPIO_B_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_A),
- S5P6440_GPIO_C_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_B),
- S5P6440_GPIO_F_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_C),
- S5P6440_GPIO_G_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_F),
- S5P6440_GPIO_H_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_G),
- S5P6440_GPIO_I_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_H),
- S5P6440_GPIO_J_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_I),
- S5P6440_GPIO_N_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_J),
- S5P6440_GPIO_P_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_N),
- S5P6440_GPIO_R_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_P),
-};
-
-/* S5P6440 GPIO number definitions. */
-#define S5P6440_GPA(_nr) (S5P6440_GPIO_A_START + (_nr))
-#define S5P6440_GPB(_nr) (S5P6440_GPIO_B_START + (_nr))
-#define S5P6440_GPC(_nr) (S5P6440_GPIO_C_START + (_nr))
-#define S5P6440_GPF(_nr) (S5P6440_GPIO_F_START + (_nr))
-#define S5P6440_GPG(_nr) (S5P6440_GPIO_G_START + (_nr))
-#define S5P6440_GPH(_nr) (S5P6440_GPIO_H_START + (_nr))
-#define S5P6440_GPI(_nr) (S5P6440_GPIO_I_START + (_nr))
-#define S5P6440_GPJ(_nr) (S5P6440_GPIO_J_START + (_nr))
-#define S5P6440_GPN(_nr) (S5P6440_GPIO_N_START + (_nr))
-#define S5P6440_GPP(_nr) (S5P6440_GPIO_P_START + (_nr))
-#define S5P6440_GPR(_nr) (S5P6440_GPIO_R_START + (_nr))
-
-/* the end of the S5P6440 specific gpios */
-#define S5P6440_GPIO_END (S5P6440_GPR(S5P6440_GPIO_R_NR) + 1)
-#define S3C_GPIO_END S5P6440_GPIO_END
-
-/* define the number of gpios we need to the one after the GPR() range */
-#define ARCH_NR_GPIOS (S5P6440_GPR(S5P6440_GPIO_R_NR) + \
- CONFIG_SAMSUNG_GPIO_EXTRA + 1)
-
-#include <asm-generic/gpio.h>
-
-#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-s5p6440/include/mach/io.h b/arch/arm/mach-s5p6440/include/mach/io.h
deleted file mode 100644
index fa2d69cb1ad7..000000000000
--- a/arch/arm/mach-s5p6440/include/mach/io.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* arch/arm/mach-s5p6440/include/mach/io.h
- *
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben-linux@fluff.org>
- *
- * Default IO routines for S3C64XX based
- */
-
-#ifndef __ASM_ARM_ARCH_IO_H
-#define __ASM_ARM_ARCH_IO_H
-
-/* No current ISA/PCI bus support. */
-#define __io(a) __typesafe_io(a)
-#define __mem_pci(a) (a)
-
-#define IO_SPACE_LIMIT (0xFFFFFFFF)
-
-#endif
diff --git a/arch/arm/mach-s5p6440/include/mach/map.h b/arch/arm/mach-s5p6440/include/mach/map.h
deleted file mode 100644
index 6cc5cbc88ffb..000000000000
--- a/arch/arm/mach-s5p6440/include/mach/map.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/map.h
- *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * S5P6440 - Memory map definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_MAP_H
-#define __ASM_ARCH_MAP_H __FILE__
-
-#include <plat/map-base.h>
-#include <plat/map-s5p.h>
-
-#define S5P6440_PA_CHIPID (0xE0000000)
-#define S5P_PA_CHIPID S5P6440_PA_CHIPID
-
-#define S5P6440_PA_SYSCON (0xE0100000)
-#define S5P6440_PA_CLK (S5P6440_PA_SYSCON + 0x0)
-#define S5P_PA_SYSCON S5P6440_PA_SYSCON
-
-#define S5P6440_PA_GPIO (0xE0308000)
-#define S5P_PA_GPIO S5P6440_PA_GPIO
-
-#define S5P6440_PA_VIC0 (0xE4000000)
-#define S5P_PA_VIC0 S5P6440_PA_VIC0
-
-#define S5P6440_PA_PDMA 0xE9000000
-
-#define S5P6440_PA_VIC1 (0xE4100000)
-#define S5P_PA_VIC1 S5P6440_PA_VIC1
-
-#define S5P6440_PA_TIMER (0xEA000000)
-#define S5P_PA_TIMER S5P6440_PA_TIMER
-
-#define S5P6440_PA_RTC (0xEA100000)
-
-#define S5P6440_PA_WDT (0xEA200000)
-#define S5P_PA_WDT S5P6440_PA_WDT
-
-#define S5P6440_PA_UART (0xEC000000)
-
-#define S5P_PA_UART0 (S5P6440_PA_UART + 0x0)
-#define S5P_PA_UART1 (S5P6440_PA_UART + 0x400)
-#define S5P_PA_UART2 (S5P6440_PA_UART + 0x800)
-#define S5P_PA_UART3 (S5P6440_PA_UART + 0xC00)
-
-#define S5P_SZ_UART SZ_256
-
-#define S5P6440_PA_IIC0 (0xEC104000)
-#define S5P6440_PA_IIC1 (0xEC20F000)
-
-#define S5P6440_PA_SPI0 0xEC400000
-#define S5P6440_PA_SPI1 0xEC500000
-
-#define S5P6440_PA_HSOTG (0xED100000)
-
-#define S5P6440_PA_HSMMC0 (0xED800000)
-#define S5P6440_PA_HSMMC1 (0xED900000)
-#define S5P6440_PA_HSMMC2 (0xEDA00000)
-
-#define S5P6440_PA_SDRAM (0x20000000)
-#define S5P_PA_SDRAM S5P6440_PA_SDRAM
-
-/* I2S */
-#define S5P6440_PA_I2S 0xF2000000
-
-/* PCM */
-#define S5P6440_PA_PCM 0xF2100000
-
-#define S5P6440_PA_ADC (0xF3000000)
-
-/* compatibiltiy defines. */
-#define S3C_PA_UART S5P6440_PA_UART
-#define S3C_PA_IIC S5P6440_PA_IIC0
-#define S3C_PA_RTC S5P6440_PA_RTC
-#define S3C_PA_IIC1 S5P6440_PA_IIC1
-#define S3C_PA_WDT S5P6440_PA_WDT
-
-#define SAMSUNG_PA_ADC S5P6440_PA_ADC
-
-#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s5p6440/include/mach/regs-clock.h b/arch/arm/mach-s5p6440/include/mach/regs-clock.h
deleted file mode 100644
index c783ecc9f193..000000000000
--- a/arch/arm/mach-s5p6440/include/mach/regs-clock.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/regs-clock.h
- *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * S5P6440 - Clock register definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_REGS_CLOCK_H
-#define __ASM_ARCH_REGS_CLOCK_H __FILE__
-
-#include <mach/map.h>
-
-#define S5P_CLKREG(x) (S3C_VA_SYS + (x))
-
-#define S5P_APLL_LOCK S5P_CLKREG(0x00)
-#define S5P_MPLL_LOCK S5P_CLKREG(0x04)
-#define S5P_EPLL_LOCK S5P_CLKREG(0x08)
-#define S5P_APLL_CON S5P_CLKREG(0x0C)
-#define S5P_MPLL_CON S5P_CLKREG(0x10)
-#define S5P_EPLL_CON S5P_CLKREG(0x14)
-#define S5P_EPLL_CON_K S5P_CLKREG(0x18)
-#define S5P_CLK_SRC0 S5P_CLKREG(0x1C)
-#define S5P_CLK_DIV0 S5P_CLKREG(0x20)
-#define S5P_CLK_DIV1 S5P_CLKREG(0x24)
-#define S5P_CLK_DIV2 S5P_CLKREG(0x28)
-#define S5P_CLK_OUT S5P_CLKREG(0x2C)
-#define S5P_CLK_GATE_HCLK0 S5P_CLKREG(0x30)
-#define S5P_CLK_GATE_PCLK S5P_CLKREG(0x34)
-#define S5P_CLK_GATE_SCLK0 S5P_CLKREG(0x38)
-#define S5P_CLK_GATE_MEM0 S5P_CLKREG(0x3C)
-#define S5P_CLK_DIV3 S5P_CLKREG(0x40)
-#define S5P_CLK_GATE_HCLK1 S5P_CLKREG(0x44)
-#define S5P_CLK_GATE_SCLK1 S5P_CLKREG(0x48)
-#define S5P_AHB_CON0 S5P_CLKREG(0x100)
-#define S5P_CLK_SRC1 S5P_CLKREG(0x10C)
-#define S5P_SWRESET S5P_CLKREG(0x114)
-#define S5P_SYS_ID S5P_CLKREG(0x118)
-#define S5P_SYS_OTHERS S5P_CLKREG(0x11C)
-#define S5P_MEM_CFG_STAT S5P_CLKREG(0x12C)
-#define S5P_PWR_CFG S5P_CLKREG(0x804)
-#define S5P_EINT_WAKEUP_MASK S5P_CLKREG(0x808)
-#define S5P_NORMAL_CFG S5P_CLKREG(0x810)
-#define S5P_STOP_CFG S5P_CLKREG(0x814)
-#define S5P_SLEEP_CFG S5P_CLKREG(0x818)
-#define S5P_OSC_FREQ S5P_CLKREG(0x820)
-#define S5P_OSC_STABLE S5P_CLKREG(0x824)
-#define S5P_PWR_STABLE S5P_CLKREG(0x828)
-#define S5P_MTC_STABLE S5P_CLKREG(0x830)
-#define S5P_OTHERS S5P_CLKREG(0x900)
-#define S5P_RST_STAT S5P_CLKREG(0x904)
-#define S5P_WAKEUP_STAT S5P_CLKREG(0x908)
-#define S5P_SLPEN S5P_CLKREG(0x930)
-#define S5P_INFORM0 S5P_CLKREG(0xA00)
-#define S5P_INFORM1 S5P_CLKREG(0xA04)
-#define S5P_INFORM2 S5P_CLKREG(0xA08)
-#define S5P_INFORM3 S5P_CLKREG(0xA0C)
-
-/* CLKDIV0 */
-#define S5P_CLKDIV0_PCLK_MASK (0xf << 12)
-#define S5P_CLKDIV0_PCLK_SHIFT (12)
-#define S5P_CLKDIV0_HCLK_MASK (0xf << 8)
-#define S5P_CLKDIV0_HCLK_SHIFT (8)
-#define S5P_CLKDIV0_MPLL_MASK (0x1 << 4)
-#define S5P_CLKDIV0_ARM_MASK (0xf << 0)
-#define S5P_CLKDIV0_ARM_SHIFT (0)
-
-/* CLKDIV3 */
-#define S5P_CLKDIV3_PCLK_LOW_MASK (0xf << 12)
-#define S5P_CLKDIV3_PCLK_LOW_SHIFT (12)
-#define S5P_CLKDIV3_HCLK_LOW_MASK (0xf << 8)
-#define S5P_CLKDIV3_HCLK_LOW_SHIFT (8)
-
-/* HCLK0 GATE Registers */
-#define S5P_CLKCON_HCLK0_USB (1<<20)
-#define S5P_CLKCON_HCLK0_HSMMC2 (1<<19)
-#define S5P_CLKCON_HCLK0_HSMMC1 (1<<18)
-#define S5P_CLKCON_HCLK0_HSMMC0 (1<<17)
-#define S5P_CLKCON_HCLK0_POST0 (1<<5)
-
-/* HCLK1 GATE Registers */
-#define S5P_CLKCON_HCLK1_DISPCON (1<<1)
-
-/* PCLK GATE Registers */
-#define S5P_CLKCON_PCLK_IIS2 (1<<26)
-#define S5P_CLKCON_PCLK_SPI1 (1<<22)
-#define S5P_CLKCON_PCLK_SPI0 (1<<21)
-#define S5P_CLKCON_PCLK_GPIO (1<<18)
-#define S5P_CLKCON_PCLK_IIC0 (1<<17)
-#define S5P_CLKCON_PCLK_TSADC (1<<12)
-#define S5P_CLKCON_PCLK_PWM (1<<7)
-#define S5P_CLKCON_PCLK_RTC (1<<6)
-#define S5P_CLKCON_PCLK_WDT (1<<5)
-#define S5P_CLKCON_PCLK_UART3 (1<<4)
-#define S5P_CLKCON_PCLK_UART2 (1<<3)
-#define S5P_CLKCON_PCLK_UART1 (1<<2)
-#define S5P_CLKCON_PCLK_UART0 (1<<1)
-
-/* SCLK0 GATE Registers */
-#define S5P_CLKCON_SCLK0_MMC2_48 (1<<29)
-#define S5P_CLKCON_SCLK0_MMC1_48 (1<<28)
-#define S5P_CLKCON_SCLK0_MMC0_48 (1<<27)
-#define S5P_CLKCON_SCLK0_MMC2 (1<<26)
-#define S5P_CLKCON_SCLK0_MMC1 (1<<25)
-#define S5P_CLKCON_SCLK0_MMC0 (1<<24)
-#define S5P_CLKCON_SCLK0_SPI1_48 (1<<23)
-#define S5P_CLKCON_SCLK0_SPI0_48 (1<<22)
-#define S5P_CLKCON_SCLK0_SPI1 (1<<21)
-#define S5P_CLKCON_SCLK0_SPI0 (1<<20)
-#define S5P_CLKCON_SCLK0_UART (1<<5)
-
-/* SCLK1 GATE Registers */
-
-/* MEM0 GATE Registers */
-#define S5P_CLKCON_MEM0_HCLK_NFCON (1<<2)
-
-/*OTHERS Resgister */
-#define S5P_OTHERS_USB_SIG_MASK (1<<16)
-#define S5P_OTHERS_HCLK_LOW_SEL_MPLL (1<<6)
-
-/* Compatibility defines */
-#define ARM_CLK_DIV S5P_CLK_DIV0
-#define ARM_DIV_RATIO_SHIFT 0
-#define ARM_DIV_MASK (0xf << ARM_DIV_RATIO_SHIFT)
-
-#endif /* __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-s5p6440/include/mach/spi-clocks.h b/arch/arm/mach-s5p6440/include/mach/spi-clocks.h
deleted file mode 100644
index 5fbca50d1cfb..000000000000
--- a/arch/arm/mach-s5p6440/include/mach/spi-clocks.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/spi-clocks.h
- *
- * Copyright (C) 2010 Samsung Electronics Co. Ltd.
- * Jaswinder Singh <jassi.brar@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __S5P6440_PLAT_SPI_CLKS_H
-#define __S5P6440_PLAT_SPI_CLKS_H __FILE__
-
-#define S5P6440_SPI_SRCCLK_PCLK 0
-#define S5P6440_SPI_SRCCLK_SCLK 1
-
-#endif /* __S5P6440_PLAT_SPI_CLKS_H */
diff --git a/arch/arm/mach-s5p6440/include/mach/uncompress.h b/arch/arm/mach-s5p6440/include/mach/uncompress.h
deleted file mode 100644
index 7c1f600d65c0..000000000000
--- a/arch/arm/mach-s5p6440/include/mach/uncompress.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/uncompress.h
- *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * S5P6440 - uncompress code
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_UNCOMPRESS_H
-#define __ASM_ARCH_UNCOMPRESS_H
-
-#include <mach/map.h>
-#include <plat/uncompress.h>
-
-static void arch_detect_cpu(void)
-{
- /* we do not need to do any cpu detection here at the moment. */
-}
-
-#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-s5p6440/init.c b/arch/arm/mach-s5p6440/init.c
deleted file mode 100644
index a1f3727e4021..000000000000
--- a/arch/arm/mach-s5p6440/init.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/* linux/arch/arm/mach-s5p6440/init.c
- *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * S5P6440 - Init support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/s5p6440.h>
-#include <plat/regs-serial.h>
-
-static struct s3c24xx_uart_clksrc s5p6440_serial_clocks[] = {
- [0] = {
- .name = "pclk_low",
- .divisor = 1,
- .min_baud = 0,
- .max_baud = 0,
- },
- [1] = {
- .name = "uclk1",
- .divisor = 1,
- .min_baud = 0,
- .max_baud = 0,
- },
-};
-
-/* uart registration process */
-void __init s5p6440_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
-{
- struct s3c2410_uartcfg *tcfg = cfg;
- u32 ucnt;
-
- for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
- if (!tcfg->clocks) {
- tcfg->clocks = s5p6440_serial_clocks;
- tcfg->clocks_size = ARRAY_SIZE(s5p6440_serial_clocks);
- }
- }
-
- s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
-}
diff --git a/arch/arm/mach-s5p6442/cpu.c b/arch/arm/mach-s5p6442/cpu.c
index a48fb553fd01..842af86bda6d 100644
--- a/arch/arm/mach-s5p6442/cpu.c
+++ b/arch/arm/mach-s5p6442/cpu.c
@@ -1,7 +1,7 @@
/* linux/arch/arm/mach-s5p6442/cpu.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
+ * http://www.samsung.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -19,6 +19,7 @@
#include <linux/sysdev.h>
#include <linux/serial_core.h>
#include <linux/platform_device.h>
+#include <linux/sched.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -47,10 +48,30 @@ static struct map_desc s5p6442_iodesc[] __initdata = {
.length = SZ_16K,
.type = MT_DEVICE,
}, {
+ .virtual = (unsigned long)S5P_VA_GPIO,
+ .pfn = __phys_to_pfn(S5P6442_PA_GPIO),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC0,
+ .pfn = __phys_to_pfn(S5P6442_PA_VIC0),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC1,
+ .pfn = __phys_to_pfn(S5P6442_PA_VIC1),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
.virtual = (unsigned long)VA_VIC2,
.pfn = __phys_to_pfn(S5P6442_PA_VIC2),
.length = SZ_16K,
.type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_UART,
+ .pfn = __phys_to_pfn(S3C_PA_UART),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
}
};
@@ -62,10 +83,11 @@ static void s5p6442_idle(void)
local_irq_enable();
}
-/* s5p6442_map_io
+/*
+ * s5p6442_map_io
*
* register the standard cpu IO areas
-*/
+ */
void __init s5p6442_map_io(void)
{
diff --git a/arch/arm/mach-s5p6442/include/mach/debug-macro.S b/arch/arm/mach-s5p6442/include/mach/debug-macro.S
index bb6536147ffb..e2213205d780 100644
--- a/arch/arm/mach-s5p6442/include/mach/debug-macro.S
+++ b/arch/arm/mach-s5p6442/include/mach/debug-macro.S
@@ -15,13 +15,12 @@
#include <mach/map.h>
#include <plat/regs-serial.h>
- .macro addruart, rx, rtmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1
- ldreq \rx, = S3C_PA_UART
- ldrne \rx, = S3C_VA_UART
+ .macro addruart, rp, rv
+ ldr \rp, = S3C_PA_UART
+ ldr \rv, = S3C_VA_UART
#if CONFIG_DEBUG_S3C_UART != 0
- add \rx, \rx, #(0x400 * CONFIG_DEBUG_S3C_UART)
+ add \rp, \rp, #(0x400 * CONFIG_DEBUG_S3C_UART)
+ add \rv, \rv, #(0x400 * CONFIG_DEBUG_S3C_UART)
#endif
.endm
diff --git a/arch/arm/mach-s5p6442/include/mach/map.h b/arch/arm/mach-s5p6442/include/mach/map.h
index 281d256faafb..31fb2e68d527 100644
--- a/arch/arm/mach-s5p6442/include/mach/map.h
+++ b/arch/arm/mach-s5p6442/include/mach/map.h
@@ -23,16 +23,10 @@
#define S5P_PA_SYSCON S5P6442_PA_SYSCON
#define S5P6442_PA_GPIO (0xE0200000)
-#define S5P_PA_GPIO S5P6442_PA_GPIO
#define S5P6442_PA_VIC0 (0xE4000000)
-#define S5P_PA_VIC0 S5P6442_PA_VIC0
-
#define S5P6442_PA_VIC1 (0xE4100000)
-#define S5P_PA_VIC1 S5P6442_PA_VIC1
-
#define S5P6442_PA_VIC2 (0xE4200000)
-#define S5P_PA_VIC2 S5P6442_PA_VIC2
#define S5P6442_PA_MDMA 0xE8000000
#define S5P6442_PA_PDMA 0xE9000000
diff --git a/arch/arm/mach-s5p6442/mach-smdk6442.c b/arch/arm/mach-s5p6442/mach-smdk6442.c
index 8d8d04272f85..819fd80d00af 100644
--- a/arch/arm/mach-s5p6442/mach-smdk6442.c
+++ b/arch/arm/mach-s5p6442/mach-smdk6442.c
@@ -83,8 +83,6 @@ static void __init smdk6442_machine_init(void)
MACHINE_START(SMDK6442, "SMDK6442")
/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
- .phys_io = S3C_PA_UART & 0xfff00000,
- .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
.boot_params = S5P_PA_SDRAM + 0x100,
.init_irq = s5p6442_init_irq,
.map_io = smdk6442_map_io,
diff --git a/arch/arm/mach-s5p64x0/Kconfig b/arch/arm/mach-s5p64x0/Kconfig
new file mode 100644
index 000000000000..fbcae9352022
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/Kconfig
@@ -0,0 +1,57 @@
+# arch/arm/mach-s5p64x0/Kconfig
+#
+# Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+# http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+if ARCH_S5P64X0
+
+config CPU_S5P6440
+ bool
+ select PLAT_S5P
+ select S3C_PL330_DMA
+ help
+ Enable S5P6440 CPU support
+
+config CPU_S5P6450
+ bool
+ select PLAT_S5P
+ select S3C_PL330_DMA
+ help
+ Enable S5P6450 CPU support
+
+config S5P64X0_SETUP_I2C1
+ bool
+ help
+ Common setup code for i2c bus 1.
+
+# machine support
+
+config MACH_SMDK6440
+ bool "SMDK6440"
+ select CPU_S5P6440
+ select S3C_DEV_I2C1
+ select S3C_DEV_RTC
+ select S3C_DEV_WDT
+ select S3C64XX_DEV_SPI
+ select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_TS
+ select S5P64X0_SETUP_I2C1
+ help
+ Machine support for the Samsung SMDK6440
+
+config MACH_SMDK6450
+ bool "SMDK6450"
+ select CPU_S5P6450
+ select S3C_DEV_I2C1
+ select S3C_DEV_RTC
+ select S3C_DEV_WDT
+ select S3C64XX_DEV_SPI
+ select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_TS
+ select S5P64X0_SETUP_I2C1
+ help
+ Machine support for the Samsung SMDK6450
+
+endif
diff --git a/arch/arm/mach-s5p64x0/Makefile b/arch/arm/mach-s5p64x0/Makefile
new file mode 100644
index 000000000000..2655829e6bf8
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/Makefile
@@ -0,0 +1,30 @@
+# arch/arm/mach-s5p64x0/Makefile
+#
+# Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+# http://www.samsung.com
+#
+# Licensed under GPLv2
+
+obj-y :=
+obj-m :=
+obj-n :=
+obj- :=
+
+# Core support for S5P64X0 system
+
+obj-$(CONFIG_ARCH_S5P64X0) += cpu.o init.o clock.o dma.o
+obj-$(CONFIG_ARCH_S5P64X0) += setup-i2c0.o
+obj-$(CONFIG_CPU_S5P6440) += clock-s5p6440.o gpio.o
+obj-$(CONFIG_CPU_S5P6450) += clock-s5p6450.o
+
+# machine support
+
+obj-$(CONFIG_MACH_SMDK6440) += mach-smdk6440.o
+obj-$(CONFIG_MACH_SMDK6450) += mach-smdk6450.o
+
+# device support
+
+obj-y += dev-audio.o
+obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o
+
+obj-$(CONFIG_S5P64X0_SETUP_I2C1) += setup-i2c1.o
diff --git a/arch/arm/mach-s5p6440/Makefile.boot b/arch/arm/mach-s5p64x0/Makefile.boot
index ff90aa13bd67..ff90aa13bd67 100644
--- a/arch/arm/mach-s5p6440/Makefile.boot
+++ b/arch/arm/mach-s5p64x0/Makefile.boot
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c
new file mode 100644
index 000000000000..f93dcd8b4d6a
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c
@@ -0,0 +1,626 @@
+/* linux/arch/arm/mach-s5p64x0/clock-s5p6440.c
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P6440 - Clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/s5p64x0-clock.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/s5p-clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/s5p6440.h>
+
+static u32 epll_div[][5] = {
+ { 36000000, 0, 48, 1, 4 },
+ { 48000000, 0, 32, 1, 3 },
+ { 60000000, 0, 40, 1, 3 },
+ { 72000000, 0, 48, 1, 3 },
+ { 84000000, 0, 28, 1, 2 },
+ { 96000000, 0, 32, 1, 2 },
+ { 32768000, 45264, 43, 1, 4 },
+ { 45158000, 6903, 30, 1, 3 },
+ { 49152000, 50332, 32, 1, 3 },
+ { 67738000, 10398, 45, 1, 3 },
+ { 73728000, 9961, 49, 1, 3 }
+};
+
+static int s5p6440_epll_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int epll_con, epll_con_k;
+ unsigned int i;
+
+ if (clk->rate == rate) /* Return if nothing changed */
+ return 0;
+
+ epll_con = __raw_readl(S5P64X0_EPLL_CON);
+ epll_con_k = __raw_readl(S5P64X0_EPLL_CON_K);
+
+ epll_con_k &= ~(PLL90XX_KDIV_MASK);
+ epll_con &= ~(PLL90XX_MDIV_MASK | PLL90XX_PDIV_MASK | PLL90XX_SDIV_MASK);
+
+ for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
+ if (epll_div[i][0] == rate) {
+ epll_con_k |= (epll_div[i][1] << PLL90XX_KDIV_SHIFT);
+ epll_con |= (epll_div[i][2] << PLL90XX_MDIV_SHIFT) |
+ (epll_div[i][3] << PLL90XX_PDIV_SHIFT) |
+ (epll_div[i][4] << PLL90XX_SDIV_SHIFT);
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(epll_div)) {
+ printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__);
+ return -EINVAL;
+ }
+
+ __raw_writel(epll_con, S5P64X0_EPLL_CON);
+ __raw_writel(epll_con_k, S5P64X0_EPLL_CON_K);
+
+ clk->rate = rate;
+
+ return 0;
+}
+
+static struct clk_ops s5p6440_epll_ops = {
+ .get_rate = s5p64x0_epll_get_rate,
+ .set_rate = s5p6440_epll_set_rate,
+};
+
+static struct clksrc_clk clk_hclk = {
+ .clk = {
+ .name = "clk_hclk",
+ .id = -1,
+ .parent = &clk_armclk.clk,
+ },
+ .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 8, .size = 4 },
+};
+
+static struct clksrc_clk clk_pclk = {
+ .clk = {
+ .name = "clk_pclk",
+ .id = -1,
+ .parent = &clk_hclk.clk,
+ },
+ .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 12, .size = 4 },
+};
+static struct clksrc_clk clk_hclk_low = {
+ .clk = {
+ .name = "clk_hclk_low",
+ .id = -1,
+ },
+ .sources = &clkset_hclk_low,
+ .reg_src = { .reg = S5P64X0_SYS_OTHERS, .shift = 6, .size = 1 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 8, .size = 4 },
+};
+
+static struct clksrc_clk clk_pclk_low = {
+ .clk = {
+ .name = "clk_pclk_low",
+ .id = -1,
+ .parent = &clk_hclk_low.clk,
+ },
+ .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 12, .size = 4 },
+};
+
+/*
+ * The following clocks will be disabled during clock initialization. It is
+ * recommended to keep the following clocks disabled until the driver requests
+ * for enabling the clock.
+ */
+static struct clk init_clocks_disable[] = {
+ {
+ .name = "nand",
+ .id = -1,
+ .parent = &clk_hclk.clk,
+ .enable = s5p64x0_mem_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "post",
+ .id = -1,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 5)
+ }, {
+ .name = "2d",
+ .id = -1,
+ .parent = &clk_hclk.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 8),
+ }, {
+ .name = "hsmmc",
+ .id = 0,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 17),
+ }, {
+ .name = "hsmmc",
+ .id = 1,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 18),
+ }, {
+ .name = "hsmmc",
+ .id = 2,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 19),
+ }, {
+ .name = "otg",
+ .id = -1,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 20)
+ }, {
+ .name = "irom",
+ .id = -1,
+ .parent = &clk_hclk.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 25),
+ }, {
+ .name = "lcd",
+ .id = -1,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk1_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "hclk_fimgvg",
+ .id = -1,
+ .parent = &clk_hclk.clk,
+ .enable = s5p64x0_hclk1_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "tsi",
+ .id = -1,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk1_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "watchdog",
+ .id = -1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 5),
+ }, {
+ .name = "rtc",
+ .id = -1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 6),
+ }, {
+ .name = "timers",
+ .id = -1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = "pcm",
+ .id = -1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 8),
+ }, {
+ .name = "adc",
+ .id = -1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 12),
+ }, {
+ .name = "i2c",
+ .id = -1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 17),
+ }, {
+ .name = "spi",
+ .id = 0,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 21),
+ }, {
+ .name = "spi",
+ .id = 1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 22),
+ }, {
+ .name = "gps",
+ .id = -1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 25),
+ }, {
+ .name = "i2s_v40",
+ .id = 0,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 26),
+ }, {
+ .name = "dsim",
+ .id = -1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 28),
+ }, {
+ .name = "etm",
+ .id = -1,
+ .parent = &clk_pclk.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 29),
+ }, {
+ .name = "dmc0",
+ .id = -1,
+ .parent = &clk_pclk.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 30),
+ }, {
+ .name = "pclk_fimgvg",
+ .id = -1,
+ .parent = &clk_pclk.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 31),
+ }, {
+ .name = "sclk_spi_48",
+ .id = 0,
+ .parent = &clk_48m,
+ .enable = s5p64x0_sclk_ctrl,
+ .ctrlbit = (1 << 22),
+ }, {
+ .name = "sclk_spi_48",
+ .id = 1,
+ .parent = &clk_48m,
+ .enable = s5p64x0_sclk_ctrl,
+ .ctrlbit = (1 << 23),
+ }, {
+ .name = "mmc_48m",
+ .id = 0,
+ .parent = &clk_48m,
+ .enable = s5p64x0_sclk_ctrl,
+ .ctrlbit = (1 << 27),
+ }, {
+ .name = "mmc_48m",
+ .id = 1,
+ .parent = &clk_48m,
+ .enable = s5p64x0_sclk_ctrl,
+ .ctrlbit = (1 << 28),
+ }, {
+ .name = "mmc_48m",
+ .id = 2,
+ .parent = &clk_48m,
+ .enable = s5p64x0_sclk_ctrl,
+ .ctrlbit = (1 << 29),
+ },
+};
+
+/*
+ * The following clocks will be enabled during clock initialization.
+ */
+static struct clk init_clocks[] = {
+ {
+ .name = "intc",
+ .id = -1,
+ .parent = &clk_hclk.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "mem",
+ .id = -1,
+ .parent = &clk_hclk.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 21),
+ }, {
+ .name = "dma",
+ .id = -1,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 12),
+ }, {
+ .name = "uart",
+ .id = 0,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "uart",
+ .id = 1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "uart",
+ .id = 2,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "uart",
+ .id = 3,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "gpio",
+ .id = -1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 18),
+ },
+};
+
+static struct clk clk_iis_cd_v40 = {
+ .name = "iis_cdclk_v40",
+ .id = -1,
+};
+
+static struct clk clk_pcm_cd = {
+ .name = "pcm_cdclk",
+ .id = -1,
+};
+
+static struct clk *clkset_group1_list[] = {
+ &clk_mout_epll.clk,
+ &clk_dout_mpll.clk,
+ &clk_fin_epll,
+};
+
+static struct clksrc_sources clkset_group1 = {
+ .sources = clkset_group1_list,
+ .nr_sources = ARRAY_SIZE(clkset_group1_list),
+};
+
+static struct clk *clkset_uart_list[] = {
+ &clk_mout_epll.clk,
+ &clk_dout_mpll.clk,
+};
+
+static struct clksrc_sources clkset_uart = {
+ .sources = clkset_uart_list,
+ .nr_sources = ARRAY_SIZE(clkset_uart_list),
+};
+
+static struct clk *clkset_audio_list[] = {
+ &clk_mout_epll.clk,
+ &clk_dout_mpll.clk,
+ &clk_fin_epll,
+ &clk_iis_cd_v40,
+ &clk_pcm_cd,
+};
+
+static struct clksrc_sources clkset_audio = {
+ .sources = clkset_audio_list,
+ .nr_sources = ARRAY_SIZE(clkset_audio_list),
+};
+
+static struct clksrc_clk clksrcs[] = {
+ {
+ .clk = {
+ .name = "mmc_bus",
+ .id = 0,
+ .ctrlbit = (1 << 24),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group1,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 18, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "mmc_bus",
+ .id = 1,
+ .ctrlbit = (1 << 25),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group1,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 20, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 4, .size = 4 },
+ }, {
+ .clk = {
+ .name = "mmc_bus",
+ .id = 2,
+ .ctrlbit = (1 << 26),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group1,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 22, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 },
+ }, {
+ .clk = {
+ .name = "uclk1",
+ .id = -1,
+ .ctrlbit = (1 << 5),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_uart,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_spi",
+ .id = 0,
+ .ctrlbit = (1 << 20),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group1,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_spi",
+ .id = 1,
+ .ctrlbit = (1 << 21),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group1,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_post",
+ .id = -1,
+ .ctrlbit = (1 << 10),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group1,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 26, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 12, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_dispcon",
+ .id = -1,
+ .ctrlbit = (1 << 1),
+ .enable = s5p64x0_sclk1_ctrl,
+ },
+ .sources = &clkset_group1,
+ .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 4, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimgvg",
+ .id = -1,
+ .ctrlbit = (1 << 2),
+ .enable = s5p64x0_sclk1_ctrl,
+ },
+ .sources = &clkset_group1,
+ .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 8, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 4, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_audio2",
+ .id = -1,
+ .ctrlbit = (1 << 11),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_audio,
+ .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 0, .size = 3 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 24, .size = 4 },
+ },
+};
+
+/* Clock initialization code */
+static struct clksrc_clk *sysclks[] = {
+ &clk_mout_apll,
+ &clk_mout_epll,
+ &clk_mout_mpll,
+ &clk_dout_mpll,
+ &clk_armclk,
+ &clk_hclk,
+ &clk_pclk,
+ &clk_hclk_low,
+ &clk_pclk_low,
+};
+
+void __init_or_cpufreq s5p6440_setup_clocks(void)
+{
+ struct clk *xtal_clk;
+
+ unsigned long xtal;
+ unsigned long fclk;
+ unsigned long hclk;
+ unsigned long hclk_low;
+ unsigned long pclk;
+ unsigned long pclk_low;
+
+ unsigned long apll;
+ unsigned long mpll;
+ unsigned long epll;
+ unsigned int ptr;
+
+ /* Set S5P6440 functions for clk_fout_epll */
+
+ clk_fout_epll.enable = s5p64x0_epll_enable;
+ clk_fout_epll.ops = &s5p6440_epll_ops;
+
+ clk_48m.enable = s5p64x0_clk48m_ctrl;
+
+ xtal_clk = clk_get(NULL, "ext_xtal");
+ BUG_ON(IS_ERR(xtal_clk));
+
+ xtal = clk_get_rate(xtal_clk);
+ clk_put(xtal_clk);
+
+ apll = s5p_get_pll45xx(xtal, __raw_readl(S5P64X0_APLL_CON), pll_4502);
+ mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P64X0_MPLL_CON), pll_4502);
+ epll = s5p_get_pll90xx(xtal, __raw_readl(S5P64X0_EPLL_CON),
+ __raw_readl(S5P64X0_EPLL_CON_K));
+
+ clk_fout_apll.rate = apll;
+ clk_fout_mpll.rate = mpll;
+ clk_fout_epll.rate = epll;
+
+ printk(KERN_INFO "S5P6440: PLL settings, A=%ld.%ldMHz, M=%ld.%ldMHz," \
+ " E=%ld.%ldMHz\n",
+ print_mhz(apll), print_mhz(mpll), print_mhz(epll));
+
+ fclk = clk_get_rate(&clk_armclk.clk);
+ hclk = clk_get_rate(&clk_hclk.clk);
+ pclk = clk_get_rate(&clk_pclk.clk);
+ hclk_low = clk_get_rate(&clk_hclk_low.clk);
+ pclk_low = clk_get_rate(&clk_pclk_low.clk);
+
+ printk(KERN_INFO "S5P6440: HCLK=%ld.%ldMHz, HCLK_LOW=%ld.%ldMHz," \
+ " PCLK=%ld.%ldMHz, PCLK_LOW=%ld.%ldMHz\n",
+ print_mhz(hclk), print_mhz(hclk_low),
+ print_mhz(pclk), print_mhz(pclk_low));
+
+ clk_f.rate = fclk;
+ clk_h.rate = hclk;
+ clk_p.rate = pclk;
+
+ for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+ s3c_set_clksrc(&clksrcs[ptr], true);
+}
+
+static struct clk *clks[] __initdata = {
+ &clk_ext,
+ &clk_iis_cd_v40,
+ &clk_pcm_cd,
+};
+
+void __init s5p6440_register_clocks(void)
+{
+ struct clk *clkp;
+ int ret;
+ int ptr;
+
+ s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
+
+ for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
+ s3c_register_clksrc(sysclks[ptr], 1);
+
+ s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
+ s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
+
+ clkp = init_clocks_disable;
+ for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
+
+ ret = s3c24xx_register_clock(clkp);
+ if (ret < 0) {
+ printk(KERN_ERR "Failed to register clock %s (%d)\n",
+ clkp->name, ret);
+ }
+ (clkp->enable)(clkp, 0);
+ }
+
+ s3c_pwmclk_init();
+}
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c
new file mode 100644
index 000000000000..f9afb05b217c
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c
@@ -0,0 +1,655 @@
+/* linux/arch/arm/mach-s5p64x0/clock-s5p6450.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P6450 - Clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/s5p64x0-clock.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/s5p-clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/s5p6450.h>
+
+static struct clksrc_clk clk_mout_dpll = {
+ .clk = {
+ .name = "mout_dpll",
+ .id = -1,
+ },
+ .sources = &clk_src_dpll,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 5, .size = 1 },
+};
+
+static u32 epll_div[][5] = {
+ { 133000000, 27307, 55, 2, 2 },
+ { 100000000, 43691, 41, 2, 2 },
+ { 480000000, 0, 80, 2, 0 },
+};
+
+static int s5p6450_epll_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int epll_con, epll_con_k;
+ unsigned int i;
+
+ if (clk->rate == rate) /* Return if nothing changed */
+ return 0;
+
+ epll_con = __raw_readl(S5P64X0_EPLL_CON);
+ epll_con_k = __raw_readl(S5P64X0_EPLL_CON_K);
+
+ epll_con_k &= ~(PLL90XX_KDIV_MASK);
+ epll_con &= ~(PLL90XX_MDIV_MASK | PLL90XX_PDIV_MASK | PLL90XX_SDIV_MASK);
+
+ for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
+ if (epll_div[i][0] == rate) {
+ epll_con_k |= (epll_div[i][1] << PLL90XX_KDIV_SHIFT);
+ epll_con |= (epll_div[i][2] << PLL90XX_MDIV_SHIFT) |
+ (epll_div[i][3] << PLL90XX_PDIV_SHIFT) |
+ (epll_div[i][4] << PLL90XX_SDIV_SHIFT);
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(epll_div)) {
+ printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__);
+ return -EINVAL;
+ }
+
+ __raw_writel(epll_con, S5P64X0_EPLL_CON);
+ __raw_writel(epll_con_k, S5P64X0_EPLL_CON_K);
+
+ clk->rate = rate;
+
+ return 0;
+}
+
+static struct clk_ops s5p6450_epll_ops = {
+ .get_rate = s5p64x0_epll_get_rate,
+ .set_rate = s5p6450_epll_set_rate,
+};
+
+static struct clksrc_clk clk_dout_epll = {
+ .clk = {
+ .name = "dout_epll",
+ .id = -1,
+ .parent = &clk_mout_epll.clk,
+ },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 24, .size = 4 },
+};
+
+static struct clksrc_clk clk_mout_hclk_sel = {
+ .clk = {
+ .name = "mout_hclk_sel",
+ .id = -1,
+ },
+ .sources = &clkset_hclk_low,
+ .reg_src = { .reg = S5P64X0_OTHERS, .shift = 15, .size = 1 },
+};
+
+static struct clk *clkset_hclk_list[] = {
+ &clk_mout_hclk_sel.clk,
+ &clk_armclk.clk,
+};
+
+static struct clksrc_sources clkset_hclk = {
+ .sources = clkset_hclk_list,
+ .nr_sources = ARRAY_SIZE(clkset_hclk_list),
+};
+
+static struct clksrc_clk clk_hclk = {
+ .clk = {
+ .name = "clk_hclk",
+ .id = -1,
+ },
+ .sources = &clkset_hclk,
+ .reg_src = { .reg = S5P64X0_OTHERS, .shift = 14, .size = 1 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 8, .size = 4 },
+};
+
+static struct clksrc_clk clk_pclk = {
+ .clk = {
+ .name = "clk_pclk",
+ .id = -1,
+ .parent = &clk_hclk.clk,
+ },
+ .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 12, .size = 4 },
+};
+static struct clksrc_clk clk_dout_pwm_ratio0 = {
+ .clk = {
+ .name = "clk_dout_pwm_ratio0",
+ .id = -1,
+ .parent = &clk_mout_hclk_sel.clk,
+ },
+ .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk clk_pclk_to_wdt_pwm = {
+ .clk = {
+ .name = "clk_pclk_to_wdt_pwm",
+ .id = -1,
+ .parent = &clk_dout_pwm_ratio0.clk,
+ },
+ .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 20, .size = 4 },
+};
+
+static struct clksrc_clk clk_hclk_low = {
+ .clk = {
+ .name = "clk_hclk_low",
+ .id = -1,
+ },
+ .sources = &clkset_hclk_low,
+ .reg_src = { .reg = S5P64X0_OTHERS, .shift = 6, .size = 1 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 8, .size = 4 },
+};
+
+static struct clksrc_clk clk_pclk_low = {
+ .clk = {
+ .name = "clk_pclk_low",
+ .id = -1,
+ .parent = &clk_hclk_low.clk,
+ },
+ .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 12, .size = 4 },
+};
+
+/*
+ * The following clocks will be disabled during clock initialization. It is
+ * recommended to keep the following clocks disabled until the driver requests
+ * for enabling the clock.
+ */
+static struct clk init_clocks_disable[] = {
+ {
+ .name = "usbhost",
+ .id = -1,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "hsmmc",
+ .id = 0,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 17),
+ }, {
+ .name = "hsmmc",
+ .id = 1,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 18),
+ }, {
+ .name = "hsmmc",
+ .id = 2,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 19),
+ }, {
+ .name = "usbotg",
+ .id = -1,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 20),
+ }, {
+ .name = "lcd",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s5p64x0_hclk1_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "watchdog",
+ .id = -1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 5),
+ }, {
+ .name = "adc",
+ .id = -1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 12),
+ }, {
+ .name = "i2c",
+ .id = 0,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 17),
+ }, {
+ .name = "spi",
+ .id = 0,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 21),
+ }, {
+ .name = "spi",
+ .id = 1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 22),
+ }, {
+ .name = "iis",
+ .id = -1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 26),
+ }, {
+ .name = "i2c",
+ .id = 1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 27),
+ }, {
+ .name = "dmc0",
+ .id = -1,
+ .parent = &clk_pclk.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 30),
+ }
+};
+
+/*
+ * The following clocks will be enabled during clock initialization.
+ */
+static struct clk init_clocks[] = {
+ {
+ .name = "intc",
+ .id = -1,
+ .parent = &clk_hclk.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "mem",
+ .id = -1,
+ .parent = &clk_hclk.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 21),
+ }, {
+ .name = "dma",
+ .id = -1,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 12),
+ }, {
+ .name = "uart",
+ .id = 0,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "uart",
+ .id = 1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "uart",
+ .id = 2,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "uart",
+ .id = 3,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "timers",
+ .id = -1,
+ .parent = &clk_pclk_to_wdt_pwm.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = "gpio",
+ .id = -1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 18),
+ },
+};
+
+static struct clk *clkset_uart_list[] = {
+ &clk_dout_epll.clk,
+ &clk_dout_mpll.clk,
+};
+
+static struct clksrc_sources clkset_uart = {
+ .sources = clkset_uart_list,
+ .nr_sources = ARRAY_SIZE(clkset_uart_list),
+};
+
+static struct clk *clkset_mali_list[] = {
+ &clk_mout_epll.clk,
+ &clk_mout_apll.clk,
+ &clk_mout_mpll.clk,
+};
+
+static struct clksrc_sources clkset_mali = {
+ .sources = clkset_mali_list,
+ .nr_sources = ARRAY_SIZE(clkset_mali_list),
+};
+
+static struct clk *clkset_group2_list[] = {
+ &clk_dout_epll.clk,
+ &clk_dout_mpll.clk,
+ &clk_ext_xtal_mux,
+};
+
+static struct clksrc_sources clkset_group2 = {
+ .sources = clkset_group2_list,
+ .nr_sources = ARRAY_SIZE(clkset_group2_list),
+};
+
+static struct clk *clkset_dispcon_list[] = {
+ &clk_dout_epll.clk,
+ &clk_dout_mpll.clk,
+ &clk_ext_xtal_mux,
+ &clk_mout_dpll.clk,
+};
+
+static struct clksrc_sources clkset_dispcon = {
+ .sources = clkset_dispcon_list,
+ .nr_sources = ARRAY_SIZE(clkset_dispcon_list),
+};
+
+static struct clk *clkset_hsmmc44_list[] = {
+ &clk_dout_epll.clk,
+ &clk_dout_mpll.clk,
+ &clk_ext_xtal_mux,
+ &s5p_clk_27m,
+ &clk_48m,
+};
+
+static struct clksrc_sources clkset_hsmmc44 = {
+ .sources = clkset_hsmmc44_list,
+ .nr_sources = ARRAY_SIZE(clkset_hsmmc44_list),
+};
+
+static struct clk *clkset_sclk_audio0_list[] = {
+ [0] = &clk_dout_epll.clk,
+ [1] = &clk_dout_mpll.clk,
+ [2] = &clk_ext_xtal_mux,
+ [3] = NULL,
+ [4] = NULL,
+};
+
+static struct clksrc_sources clkset_sclk_audio0 = {
+ .sources = clkset_sclk_audio0_list,
+ .nr_sources = ARRAY_SIZE(clkset_sclk_audio0_list),
+};
+
+static struct clksrc_clk clk_sclk_audio0 = {
+ .clk = {
+ .name = "audio-bus",
+ .id = -1,
+ .enable = s5p64x0_sclk_ctrl,
+ .ctrlbit = (1 << 8),
+ .parent = &clk_dout_epll.clk,
+ },
+ .sources = &clkset_sclk_audio0,
+ .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 10, .size = 3 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 8, .size = 4 },
+};
+
+static struct clksrc_clk clksrcs[] = {
+ {
+ .clk = {
+ .name = "sclk_mmc",
+ .id = 0,
+ .ctrlbit = (1 << 24),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 18, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .id = 1,
+ .ctrlbit = (1 << 25),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 20, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 4, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .id = 2,
+ .ctrlbit = (1 << 26),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 22, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 },
+ }, {
+ .clk = {
+ .name = "uclk1",
+ .id = -1,
+ .ctrlbit = (1 << 5),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_uart,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_spi",
+ .id = 0,
+ .ctrlbit = (1 << 20),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_spi",
+ .id = 1,
+ .ctrlbit = (1 << 21),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimc",
+ .id = -1,
+ .ctrlbit = (1 << 10),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 26, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 12, .size = 4 },
+ }, {
+ .clk = {
+ .name = "aclk_mali",
+ .id = -1,
+ .ctrlbit = (1 << 2),
+ .enable = s5p64x0_sclk1_ctrl,
+ },
+ .sources = &clkset_mali,
+ .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 8, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 4, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_2d",
+ .id = -1,
+ .ctrlbit = (1 << 12),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_mali,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 30, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 20, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_usi",
+ .id = -1,
+ .ctrlbit = (1 << 7),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 10, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 16, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_camif",
+ .id = -1,
+ .ctrlbit = (1 << 6),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 28, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 20, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_dispcon",
+ .id = -1,
+ .ctrlbit = (1 << 1),
+ .enable = s5p64x0_sclk1_ctrl,
+ },
+ .sources = &clkset_dispcon,
+ .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 4, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_hsmmc44",
+ .id = -1,
+ .ctrlbit = (1 << 30),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_hsmmc44,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 6, .size = 3 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 28, .size = 4 },
+ },
+};
+
+/* Clock initialization code */
+static struct clksrc_clk *sysclks[] = {
+ &clk_mout_apll,
+ &clk_mout_epll,
+ &clk_dout_epll,
+ &clk_mout_mpll,
+ &clk_dout_mpll,
+ &clk_armclk,
+ &clk_mout_hclk_sel,
+ &clk_dout_pwm_ratio0,
+ &clk_pclk_to_wdt_pwm,
+ &clk_hclk,
+ &clk_pclk,
+ &clk_hclk_low,
+ &clk_pclk_low,
+ &clk_sclk_audio0,
+};
+
+void __init_or_cpufreq s5p6450_setup_clocks(void)
+{
+ struct clk *xtal_clk;
+
+ unsigned long xtal;
+ unsigned long fclk;
+ unsigned long hclk;
+ unsigned long hclk_low;
+ unsigned long pclk;
+ unsigned long pclk_low;
+
+ unsigned long apll;
+ unsigned long mpll;
+ unsigned long epll;
+ unsigned long dpll;
+ unsigned int ptr;
+
+ /* Set S5P6450 functions for clk_fout_epll */
+
+ clk_fout_epll.enable = s5p64x0_epll_enable;
+ clk_fout_epll.ops = &s5p6450_epll_ops;
+
+ clk_48m.enable = s5p64x0_clk48m_ctrl;
+
+ xtal_clk = clk_get(NULL, "ext_xtal");
+ BUG_ON(IS_ERR(xtal_clk));
+
+ xtal = clk_get_rate(xtal_clk);
+ clk_put(xtal_clk);
+
+ apll = s5p_get_pll45xx(xtal, __raw_readl(S5P64X0_APLL_CON), pll_4502);
+ mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P64X0_MPLL_CON), pll_4502);
+ epll = s5p_get_pll90xx(xtal, __raw_readl(S5P64X0_EPLL_CON),
+ __raw_readl(S5P64X0_EPLL_CON_K));
+ dpll = s5p_get_pll46xx(xtal, __raw_readl(S5P6450_DPLL_CON),
+ __raw_readl(S5P6450_DPLL_CON_K), pll_4650c);
+
+ clk_fout_apll.rate = apll;
+ clk_fout_mpll.rate = mpll;
+ clk_fout_epll.rate = epll;
+ clk_fout_dpll.rate = dpll;
+
+ printk(KERN_INFO "S5P6450: PLL settings, A=%ld.%ldMHz, M=%ld.%ldMHz," \
+ " E=%ld.%ldMHz, D=%ld.%ldMHz\n",
+ print_mhz(apll), print_mhz(mpll), print_mhz(epll),
+ print_mhz(dpll));
+
+ fclk = clk_get_rate(&clk_armclk.clk);
+ hclk = clk_get_rate(&clk_hclk.clk);
+ pclk = clk_get_rate(&clk_pclk.clk);
+ hclk_low = clk_get_rate(&clk_hclk_low.clk);
+ pclk_low = clk_get_rate(&clk_pclk_low.clk);
+
+ printk(KERN_INFO "S5P6450: HCLK=%ld.%ldMHz, HCLK_LOW=%ld.%ldMHz," \
+ " PCLK=%ld.%ldMHz, PCLK_LOW=%ld.%ldMHz\n",
+ print_mhz(hclk), print_mhz(hclk_low),
+ print_mhz(pclk), print_mhz(pclk_low));
+
+ clk_f.rate = fclk;
+ clk_h.rate = hclk;
+ clk_p.rate = pclk;
+
+ for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+ s3c_set_clksrc(&clksrcs[ptr], true);
+}
+
+void __init s5p6450_register_clocks(void)
+{
+ struct clk *clkp;
+ int ret;
+ int ptr;
+
+ for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
+ s3c_register_clksrc(sysclks[ptr], 1);
+
+ s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
+ s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
+
+ clkp = init_clocks_disable;
+ for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
+
+ ret = s3c24xx_register_clock(clkp);
+ if (ret < 0) {
+ printk(KERN_ERR "Failed to register clock %s (%d)\n",
+ clkp->name, ret);
+ }
+ (clkp->enable)(clkp, 0);
+ }
+
+ s3c_pwmclk_init();
+}
diff --git a/arch/arm/mach-s5p64x0/clock.c b/arch/arm/mach-s5p64x0/clock.c
new file mode 100644
index 000000000000..523ba8039ac2
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/clock.c
@@ -0,0 +1,253 @@
+/* linux/arch/arm/mach-s5p64x0/clock.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P64X0 - Clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/s5p-clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/s5p6440.h>
+#include <plat/s5p6450.h>
+
+struct clksrc_clk clk_mout_apll = {
+ .clk = {
+ .name = "mout_apll",
+ .id = -1,
+ },
+ .sources = &clk_src_apll,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 0, .size = 1 },
+};
+
+struct clksrc_clk clk_mout_mpll = {
+ .clk = {
+ .name = "mout_mpll",
+ .id = -1,
+ },
+ .sources = &clk_src_mpll,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 1, .size = 1 },
+};
+
+struct clksrc_clk clk_mout_epll = {
+ .clk = {
+ .name = "mout_epll",
+ .id = -1,
+ },
+ .sources = &clk_src_epll,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 2, .size = 1 },
+};
+
+enum perf_level {
+ L0 = 532*1000,
+ L1 = 266*1000,
+ L2 = 133*1000,
+};
+
+static const u32 clock_table[][3] = {
+ /*{ARM_CLK, DIVarm, DIVhclk}*/
+ {L0 * 1000, (0 << ARM_DIV_RATIO_SHIFT), (3 << S5P64X0_CLKDIV0_HCLK_SHIFT)},
+ {L1 * 1000, (1 << ARM_DIV_RATIO_SHIFT), (1 << S5P64X0_CLKDIV0_HCLK_SHIFT)},
+ {L2 * 1000, (3 << ARM_DIV_RATIO_SHIFT), (0 << S5P64X0_CLKDIV0_HCLK_SHIFT)},
+};
+
+int s5p64x0_epll_enable(struct clk *clk, int enable)
+{
+ unsigned int ctrlbit = clk->ctrlbit;
+ unsigned int epll_con = __raw_readl(S5P64X0_EPLL_CON) & ~ctrlbit;
+
+ if (enable)
+ __raw_writel(epll_con | ctrlbit, S5P64X0_EPLL_CON);
+ else
+ __raw_writel(epll_con, S5P64X0_EPLL_CON);
+
+ return 0;
+}
+
+unsigned long s5p64x0_epll_get_rate(struct clk *clk)
+{
+ return clk->rate;
+}
+
+unsigned long s5p64x0_armclk_get_rate(struct clk *clk)
+{
+ unsigned long rate = clk_get_rate(clk->parent);
+ u32 clkdiv;
+
+ /* divisor mask starts at bit0, so no need to shift */
+ clkdiv = __raw_readl(ARM_CLK_DIV) & ARM_DIV_MASK;
+
+ return rate / (clkdiv + 1);
+}
+
+unsigned long s5p64x0_armclk_round_rate(struct clk *clk, unsigned long rate)
+{
+ u32 iter;
+
+ for (iter = 1 ; iter < ARRAY_SIZE(clock_table) ; iter++) {
+ if (rate > clock_table[iter][0])
+ return clock_table[iter-1][0];
+ }
+
+ return clock_table[ARRAY_SIZE(clock_table) - 1][0];
+}
+
+int s5p64x0_armclk_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 round_tmp;
+ u32 iter;
+ u32 clk_div0_tmp;
+ u32 cur_rate = clk->ops->get_rate(clk);
+ unsigned long flags;
+
+ round_tmp = clk->ops->round_rate(clk, rate);
+ if (round_tmp == cur_rate)
+ return 0;
+
+
+ for (iter = 0 ; iter < ARRAY_SIZE(clock_table) ; iter++) {
+ if (round_tmp == clock_table[iter][0])
+ break;
+ }
+
+ if (iter >= ARRAY_SIZE(clock_table))
+ iter = ARRAY_SIZE(clock_table) - 1;
+
+ local_irq_save(flags);
+ if (cur_rate > round_tmp) {
+ /* Frequency Down */
+ clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & ~(ARM_DIV_MASK);
+ clk_div0_tmp |= clock_table[iter][1];
+ __raw_writel(clk_div0_tmp, ARM_CLK_DIV);
+
+ clk_div0_tmp = __raw_readl(ARM_CLK_DIV) &
+ ~(S5P64X0_CLKDIV0_HCLK_MASK);
+ clk_div0_tmp |= clock_table[iter][2];
+ __raw_writel(clk_div0_tmp, ARM_CLK_DIV);
+
+
+ } else {
+ /* Frequency Up */
+ clk_div0_tmp = __raw_readl(ARM_CLK_DIV) &
+ ~(S5P64X0_CLKDIV0_HCLK_MASK);
+ clk_div0_tmp |= clock_table[iter][2];
+ __raw_writel(clk_div0_tmp, ARM_CLK_DIV);
+
+ clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & ~(ARM_DIV_MASK);
+ clk_div0_tmp |= clock_table[iter][1];
+ __raw_writel(clk_div0_tmp, ARM_CLK_DIV);
+ }
+ local_irq_restore(flags);
+
+ clk->rate = clock_table[iter][0];
+
+ return 0;
+}
+
+struct clk_ops s5p64x0_clkarm_ops = {
+ .get_rate = s5p64x0_armclk_get_rate,
+ .set_rate = s5p64x0_armclk_set_rate,
+ .round_rate = s5p64x0_armclk_round_rate,
+};
+
+struct clksrc_clk clk_armclk = {
+ .clk = {
+ .name = "armclk",
+ .id = 1,
+ .parent = &clk_mout_apll.clk,
+ .ops = &s5p64x0_clkarm_ops,
+ },
+ .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 0, .size = 4 },
+};
+
+struct clksrc_clk clk_dout_mpll = {
+ .clk = {
+ .name = "dout_mpll",
+ .id = -1,
+ .parent = &clk_mout_mpll.clk,
+ },
+ .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 4, .size = 1 },
+};
+
+struct clk *clkset_hclk_low_list[] = {
+ &clk_mout_apll.clk,
+ &clk_mout_mpll.clk,
+};
+
+struct clksrc_sources clkset_hclk_low = {
+ .sources = clkset_hclk_low_list,
+ .nr_sources = ARRAY_SIZE(clkset_hclk_low_list),
+};
+
+int s5p64x0_pclk_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P64X0_CLK_GATE_PCLK, clk, enable);
+}
+
+int s5p64x0_hclk0_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P64X0_CLK_GATE_HCLK0, clk, enable);
+}
+
+int s5p64x0_hclk1_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P64X0_CLK_GATE_HCLK1, clk, enable);
+}
+
+int s5p64x0_sclk_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P64X0_CLK_GATE_SCLK0, clk, enable);
+}
+
+int s5p64x0_sclk1_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P64X0_CLK_GATE_SCLK1, clk, enable);
+}
+
+int s5p64x0_mem_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P64X0_CLK_GATE_MEM0, clk, enable);
+}
+
+int s5p64x0_clk48m_ctrl(struct clk *clk, int enable)
+{
+ unsigned long flags;
+ u32 val;
+
+ /* can't rely on clock lock, this register has other usages */
+ local_irq_save(flags);
+
+ val = __raw_readl(S5P64X0_OTHERS);
+ if (enable)
+ val |= S5P64X0_OTHERS_USB_SIG_MASK;
+ else
+ val &= ~S5P64X0_OTHERS_USB_SIG_MASK;
+
+ __raw_writel(val, S5P64X0_OTHERS);
+
+ local_irq_restore(flags);
+
+ return 0;
+}
diff --git a/arch/arm/mach-s5p64x0/cpu.c b/arch/arm/mach-s5p64x0/cpu.c
new file mode 100644
index 000000000000..b8d02eb4cf30
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/cpu.c
@@ -0,0 +1,209 @@
+/* linux/arch/arm/mach-s5p64x0/cpu.c
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/proc-fns.h>
+#include <asm/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+
+#include <plat/regs-serial.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+#include <plat/s5p6440.h>
+#include <plat/s5p6450.h>
+#include <plat/adc-core.h>
+
+/* Initial IO mappings */
+
+static struct map_desc s5p64x0_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S5P_VA_GPIO,
+ .pfn = __phys_to_pfn(S5P64X0_PA_GPIO),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC0,
+ .pfn = __phys_to_pfn(S5P64X0_PA_VIC0),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC1,
+ .pfn = __phys_to_pfn(S5P64X0_PA_VIC1),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ },
+};
+
+static struct map_desc s5p6440_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S3C_VA_UART,
+ .pfn = __phys_to_pfn(S5P6440_PA_UART(0)),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+};
+
+static struct map_desc s5p6450_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S3C_VA_UART,
+ .pfn = __phys_to_pfn(S5P6450_PA_UART(0)),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_UART + SZ_512K,
+ .pfn = __phys_to_pfn(S5P6450_PA_UART(5)),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+};
+
+static void s5p64x0_idle(void)
+{
+ unsigned long val;
+
+ if (!need_resched()) {
+ val = __raw_readl(S5P64X0_PWR_CFG);
+ val &= ~(0x3 << 5);
+ val |= (0x1 << 5);
+ __raw_writel(val, S5P64X0_PWR_CFG);
+
+ cpu_do_idle();
+ }
+ local_irq_enable();
+}
+
+/*
+ * s5p64x0_map_io
+ *
+ * register the standard CPU IO areas
+ */
+
+void __init s5p6440_map_io(void)
+{
+ /* initialize any device information early */
+ s3c_adc_setname("s3c64xx-adc");
+
+ iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc));
+ iotable_init(s5p6440_iodesc, ARRAY_SIZE(s5p6440_iodesc));
+}
+
+void __init s5p6450_map_io(void)
+{
+ /* initialize any device information early */
+ s3c_adc_setname("s3c64xx-adc");
+
+ iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc));
+ iotable_init(s5p6450_iodesc, ARRAY_SIZE(s5p6440_iodesc));
+}
+
+/*
+ * s5p64x0_init_clocks
+ *
+ * register and setup the CPU clocks
+ */
+
+void __init s5p6440_init_clocks(int xtal)
+{
+ printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
+
+ s3c24xx_register_baseclocks(xtal);
+ s5p_register_clocks(xtal);
+ s5p6440_register_clocks();
+ s5p6440_setup_clocks();
+}
+
+void __init s5p6450_init_clocks(int xtal)
+{
+ printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
+
+ s3c24xx_register_baseclocks(xtal);
+ s5p_register_clocks(xtal);
+ s5p6450_register_clocks();
+ s5p6450_setup_clocks();
+}
+
+/*
+ * s5p64x0_init_irq
+ *
+ * register the CPU interrupts
+ */
+
+void __init s5p6440_init_irq(void)
+{
+ /* S5P6440 supports 2 VIC */
+ u32 vic[2];
+
+ /*
+ * VIC0 is missing IRQ_VIC0[3, 4, 8, 10, (12-22)]
+ * VIC1 is missing IRQ VIC1[1, 3, 4, 10, 11, 12, 14, 15, 22]
+ */
+ vic[0] = 0xff800ae7;
+ vic[1] = 0xffbf23e5;
+
+ s5p_init_irq(vic, ARRAY_SIZE(vic));
+}
+
+void __init s5p6450_init_irq(void)
+{
+ /* S5P6450 supports only 2 VIC */
+ u32 vic[2];
+
+ /*
+ * VIC0 is missing IRQ_VIC0[(13-15), (21-22)]
+ * VIC1 is missing IRQ VIC1[12, 14, 23]
+ */
+ vic[0] = 0xff9f1fff;
+ vic[1] = 0xff7fafff;
+
+ s5p_init_irq(vic, ARRAY_SIZE(vic));
+}
+
+struct sysdev_class s5p64x0_sysclass = {
+ .name = "s5p64x0-core",
+};
+
+static struct sys_device s5p64x0_sysdev = {
+ .cls = &s5p64x0_sysclass,
+};
+
+static int __init s5p64x0_core_init(void)
+{
+ return sysdev_class_register(&s5p64x0_sysclass);
+}
+core_initcall(s5p64x0_core_init);
+
+int __init s5p64x0_init(void)
+{
+ printk(KERN_INFO "S5P64X0(S5P6440/S5P6450): Initializing architecture\n");
+
+ /* set idle function */
+ pm_idle = s5p64x0_idle;
+
+ return sysdev_register(&s5p64x0_sysdev);
+}
diff --git a/arch/arm/mach-s5p64x0/dev-audio.c b/arch/arm/mach-s5p64x0/dev-audio.c
new file mode 100644
index 000000000000..fa097bd68ca4
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/dev-audio.c
@@ -0,0 +1,164 @@
+/* linux/arch/arm/mach-s5p64x0/dev-audio.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co. Ltd
+ * Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/audio.h>
+
+#include <mach/map.h>
+#include <mach/dma.h>
+#include <mach/irqs.h>
+
+static int s5p6440_cfg_i2s(struct platform_device *pdev)
+{
+ /* configure GPIO for i2s port */
+ switch (pdev->id) {
+ case -1:
+ s3c_gpio_cfgpin(S5P6440_GPR(4), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin(S5P6440_GPR(5), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin(S5P6440_GPR(6), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin(S5P6440_GPR(7), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin(S5P6440_GPR(8), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin(S5P6440_GPR(13), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin(S5P6440_GPR(14), S3C_GPIO_SFN(5));
+ break;
+
+ default:
+ printk(KERN_ERR "Invalid Device %d\n", pdev->id);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int s5p6450_cfg_i2s(struct platform_device *pdev)
+{
+ /* configure GPIO for i2s port */
+ switch (pdev->id) {
+ case -1:
+ s3c_gpio_cfgpin(S5P6450_GPB(4), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin(S5P6450_GPR(4), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin(S5P6450_GPR(5), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin(S5P6450_GPR(6), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin(S5P6450_GPR(7), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin(S5P6450_GPR(8), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin(S5P6450_GPR(13), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin(S5P6450_GPR(14), S3C_GPIO_SFN(5));
+ break;
+
+ default:
+ printk(KERN_ERR "Invalid Device %d\n", pdev->id);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct s3c_audio_pdata s5p6440_i2s_pdata = {
+ .cfg_gpio = s5p6440_cfg_i2s,
+};
+
+static struct s3c_audio_pdata s5p6450_i2s_pdata = {
+ .cfg_gpio = s5p6450_cfg_i2s,
+};
+
+static struct resource s5p64x0_iis0_resource[] = {
+ [0] = {
+ .start = S5P64X0_PA_I2S,
+ .end = S5P64X0_PA_I2S + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_I2S0_TX,
+ .end = DMACH_I2S0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_I2S0_RX,
+ .end = DMACH_I2S0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device s5p6440_device_iis = {
+ .name = "s3c64xx-iis-v4",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5p64x0_iis0_resource),
+ .resource = s5p64x0_iis0_resource,
+ .dev = {
+ .platform_data = &s5p6440_i2s_pdata,
+ },
+};
+
+struct platform_device s5p6450_device_iis0 = {
+ .name = "s3c64xx-iis-v4",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5p64x0_iis0_resource),
+ .resource = s5p64x0_iis0_resource,
+ .dev = {
+ .platform_data = &s5p6450_i2s_pdata,
+ },
+};
+
+/* PCM Controller platform_devices */
+
+static int s5p6440_pcm_cfg_gpio(struct platform_device *pdev)
+{
+ switch (pdev->id) {
+ case 0:
+ s3c_gpio_cfgpin(S5P6440_GPR(7), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(S5P6440_GPR(13), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(S5P6440_GPR(14), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(S5P6440_GPR(8), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(S5P6440_GPR(6), S3C_GPIO_SFN(2));
+ break;
+
+ default:
+ printk(KERN_DEBUG "Invalid PCM Controller number!");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct s3c_audio_pdata s5p6440_pcm_pdata = {
+ .cfg_gpio = s5p6440_pcm_cfg_gpio,
+};
+
+static struct resource s5p6440_pcm0_resource[] = {
+ [0] = {
+ .start = S5P64X0_PA_PCM,
+ .end = S5P64X0_PA_PCM + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_PCM0_TX,
+ .end = DMACH_PCM0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_PCM0_RX,
+ .end = DMACH_PCM0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device s5p6440_device_pcm = {
+ .name = "samsung-pcm",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5p6440_pcm0_resource),
+ .resource = s5p6440_pcm0_resource,
+ .dev = {
+ .platform_data = &s5p6440_pcm_pdata,
+ },
+};
diff --git a/arch/arm/mach-s5p64x0/dev-spi.c b/arch/arm/mach-s5p64x0/dev-spi.c
new file mode 100644
index 000000000000..5b69ec4c8af3
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/dev-spi.c
@@ -0,0 +1,232 @@
+/* linux/arch/arm/mach-s5p64x0/dev-spi.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Copyright (C) 2010 Samsung Electronics Co. Ltd.
+ * Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
+
+#include <mach/dma.h>
+#include <mach/map.h>
+#include <mach/irqs.h>
+#include <mach/regs-clock.h>
+#include <mach/spi-clocks.h>
+
+#include <plat/s3c64xx-spi.h>
+#include <plat/gpio-cfg.h>
+
+static char *s5p64x0_spi_src_clks[] = {
+ [S5P64X0_SPI_SRCCLK_PCLK] = "pclk",
+ [S5P64X0_SPI_SRCCLK_SCLK] = "sclk_spi",
+};
+
+/* SPI Controller platform_devices */
+
+/* Since we emulate multi-cs capability, we do not touch the CS.
+ * The emulated CS is toggled by board specific mechanism, as it can
+ * be either some immediate GPIO or some signal out of some other
+ * chip in between ... or some yet another way.
+ * We simply do not assume anything about CS.
+ */
+static int s5p6440_spi_cfg_gpio(struct platform_device *pdev)
+{
+ switch (pdev->id) {
+ case 0:
+ s3c_gpio_cfgpin(S5P6440_GPC(0), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(S5P6440_GPC(1), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(S5P6440_GPC(2), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(S5P6440_GPC(0), S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(S5P6440_GPC(1), S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(S5P6440_GPC(2), S3C_GPIO_PULL_UP);
+ break;
+
+ case 1:
+ s3c_gpio_cfgpin(S5P6440_GPC(4), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(S5P6440_GPC(5), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(S5P6440_GPC(6), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(S5P6440_GPC(4), S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(S5P6440_GPC(5), S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(S5P6440_GPC(6), S3C_GPIO_PULL_UP);
+ break;
+
+ default:
+ dev_err(&pdev->dev, "Invalid SPI Controller number!");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int s5p6450_spi_cfg_gpio(struct platform_device *pdev)
+{
+ switch (pdev->id) {
+ case 0:
+ s3c_gpio_cfgpin(S5P6450_GPC(0), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(S5P6450_GPC(1), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(S5P6450_GPC(2), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(S5P6450_GPC(0), S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(S5P6450_GPC(1), S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(S5P6450_GPC(2), S3C_GPIO_PULL_UP);
+ break;
+
+ case 1:
+ s3c_gpio_cfgpin(S5P6450_GPC(4), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(S5P6450_GPC(5), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(S5P6450_GPC(6), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(S5P6450_GPC(4), S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(S5P6450_GPC(5), S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(S5P6450_GPC(6), S3C_GPIO_PULL_UP);
+ break;
+
+ default:
+ dev_err(&pdev->dev, "Invalid SPI Controller number!");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct resource s5p64x0_spi0_resource[] = {
+ [0] = {
+ .start = S5P64X0_PA_SPI0,
+ .end = S5P64X0_PA_SPI0 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_SPI0_TX,
+ .end = DMACH_SPI0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_SPI0_RX,
+ .end = DMACH_SPI0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = IRQ_SPI0,
+ .end = IRQ_SPI0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct s3c64xx_spi_info s5p6440_spi0_pdata = {
+ .cfg_gpio = s5p6440_spi_cfg_gpio,
+ .fifo_lvl_mask = 0x1ff,
+ .rx_lvl_offset = 15,
+};
+
+static struct s3c64xx_spi_info s5p6450_spi0_pdata = {
+ .cfg_gpio = s5p6450_spi_cfg_gpio,
+ .fifo_lvl_mask = 0x1ff,
+ .rx_lvl_offset = 15,
+};
+
+static u64 spi_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s5p64x0_device_spi0 = {
+ .name = "s3c64xx-spi",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5p64x0_spi0_resource),
+ .resource = s5p64x0_spi0_resource,
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct resource s5p64x0_spi1_resource[] = {
+ [0] = {
+ .start = S5P64X0_PA_SPI1,
+ .end = S5P64X0_PA_SPI1 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_SPI1_TX,
+ .end = DMACH_SPI1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_SPI1_RX,
+ .end = DMACH_SPI1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = IRQ_SPI1,
+ .end = IRQ_SPI1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct s3c64xx_spi_info s5p6440_spi1_pdata = {
+ .cfg_gpio = s5p6440_spi_cfg_gpio,
+ .fifo_lvl_mask = 0x7f,
+ .rx_lvl_offset = 15,
+};
+
+static struct s3c64xx_spi_info s5p6450_spi1_pdata = {
+ .cfg_gpio = s5p6450_spi_cfg_gpio,
+ .fifo_lvl_mask = 0x7f,
+ .rx_lvl_offset = 15,
+};
+
+struct platform_device s5p64x0_device_spi1 = {
+ .name = "s3c64xx-spi",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s5p64x0_spi1_resource),
+ .resource = s5p64x0_spi1_resource,
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init s5p64x0_spi_set_info(int cntrlr, int src_clk_nr, int num_cs)
+{
+ unsigned int id;
+ struct s3c64xx_spi_info *pd;
+
+ id = __raw_readl(S5P64X0_SYS_ID) & 0xFF000;
+
+ /* Reject invalid configuration */
+ if (!num_cs || src_clk_nr < 0
+ || src_clk_nr > S5P64X0_SPI_SRCCLK_SCLK) {
+ printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__);
+ return;
+ }
+
+ switch (cntrlr) {
+ case 0:
+ if (id == 0x50000)
+ pd = &s5p6450_spi0_pdata;
+ else
+ pd = &s5p6440_spi0_pdata;
+
+ s5p64x0_device_spi0.dev.platform_data = pd;
+ break;
+ case 1:
+ if (id == 0x50000)
+ pd = &s5p6450_spi1_pdata;
+ else
+ pd = &s5p6440_spi1_pdata;
+
+ s5p64x0_device_spi1.dev.platform_data = pd;
+ break;
+ default:
+ printk(KERN_ERR "%s: Invalid SPI controller(%d)\n",
+ __func__, cntrlr);
+ return;
+ }
+
+ pd->num_cs = num_cs;
+ pd->src_clk_nr = src_clk_nr;
+ pd->src_clk_name = s5p64x0_spi_src_clks[src_clk_nr];
+}
diff --git a/arch/arm/mach-s5p6440/dma.c b/arch/arm/mach-s5p64x0/dma.c
index 07606ad57519..29a8c2410049 100644
--- a/arch/arm/mach-s5p6440/dma.c
+++ b/arch/arm/mach-s5p64x0/dma.c
@@ -1,4 +1,8 @@
-/*
+/* linux/arch/arm/mach-s5p64x0/dma.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
* Copyright (C) 2010 Samsung Electronics Co. Ltd.
* Jaswinder Singh <jassi.brar@samsung.com>
*
@@ -15,26 +19,25 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
+*/
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
-#include <plat/devs.h>
-#include <plat/irqs.h>
-
#include <mach/map.h>
#include <mach/irqs.h>
+#include <mach/regs-clock.h>
+#include <plat/devs.h>
#include <plat/s3c-pl330-pdata.h>
static u64 dma_dmamask = DMA_BIT_MASK(32);
-static struct resource s5p6440_pdma_resource[] = {
+static struct resource s5p64x0_pdma_resource[] = {
[0] = {
- .start = S5P6440_PA_PDMA,
- .end = S5P6440_PA_PDMA + SZ_4K,
- .flags = IORESOURCE_MEM,
+ .start = S5P64X0_PA_PDMA,
+ .end = S5P64X0_PA_PDMA + SZ_4K,
+ .flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_DMA0,
@@ -80,26 +83,67 @@ static struct s3c_pl330_platdata s5p6440_pdma_pdata = {
},
};
-static struct platform_device s5p6440_device_pdma = {
+static struct s3c_pl330_platdata s5p6450_pdma_pdata = {
+ .peri = {
+ [0] = DMACH_UART0_RX,
+ [1] = DMACH_UART0_TX,
+ [2] = DMACH_UART1_RX,
+ [3] = DMACH_UART1_TX,
+ [4] = DMACH_UART2_RX,
+ [5] = DMACH_UART2_TX,
+ [6] = DMACH_UART3_RX,
+ [7] = DMACH_UART3_TX,
+ [8] = DMACH_UART4_RX,
+ [9] = DMACH_UART4_TX,
+ [10] = DMACH_PCM0_TX,
+ [11] = DMACH_PCM0_RX,
+ [12] = DMACH_I2S0_TX,
+ [13] = DMACH_I2S0_RX,
+ [14] = DMACH_SPI0_TX,
+ [15] = DMACH_SPI0_RX,
+ [16] = DMACH_PCM1_TX,
+ [17] = DMACH_PCM1_RX,
+ [18] = DMACH_PCM2_TX,
+ [19] = DMACH_PCM2_RX,
+ [20] = DMACH_SPI1_TX,
+ [21] = DMACH_SPI1_RX,
+ [22] = DMACH_USI_TX,
+ [23] = DMACH_USI_RX,
+ [24] = DMACH_MAX,
+ [25] = DMACH_I2S1_TX,
+ [26] = DMACH_I2S1_RX,
+ [27] = DMACH_I2S2_TX,
+ [28] = DMACH_I2S2_RX,
+ [29] = DMACH_PWM,
+ [30] = DMACH_UART5_RX,
+ [31] = DMACH_UART5_TX,
+ },
+};
+
+static struct platform_device s5p64x0_device_pdma = {
.name = "s3c-pl330",
- .id = 1,
- .num_resources = ARRAY_SIZE(s5p6440_pdma_resource),
- .resource = s5p6440_pdma_resource,
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5p64x0_pdma_resource),
+ .resource = s5p64x0_pdma_resource,
.dev = {
.dma_mask = &dma_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
- .platform_data = &s5p6440_pdma_pdata,
},
};
-static struct platform_device *s5p6440_dmacs[] __initdata = {
- &s5p6440_device_pdma,
-};
-
-static int __init s5p6440_dma_init(void)
+static int __init s5p64x0_dma_init(void)
{
- platform_add_devices(s5p6440_dmacs, ARRAY_SIZE(s5p6440_dmacs));
+ unsigned int id;
+
+ id = __raw_readl(S5P64X0_SYS_ID) & 0xFF000;
+
+ if (id == 0x50000)
+ s5p64x0_device_pdma.dev.platform_data = &s5p6450_pdma_pdata;
+ else
+ s5p64x0_device_pdma.dev.platform_data = &s5p6440_pdma_pdata;
+
+ platform_device_register(&s5p64x0_device_pdma);
return 0;
}
-arch_initcall(s5p6440_dma_init);
+arch_initcall(s5p64x0_dma_init);
diff --git a/arch/arm/mach-s5p6440/gpio.c b/arch/arm/mach-s5p64x0/gpio.c
index 8bf6e0ce51c9..39159dd5a29a 100644
--- a/arch/arm/mach-s5p6440/gpio.c
+++ b/arch/arm/mach-s5p64x0/gpio.c
@@ -1,14 +1,14 @@
-/* arch/arm/mach-s5p6440/gpio.c
+/* linux/arch/arm/mach-s5p64x0/gpio.c
*
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
*
- * S5P6440 - GPIOlib support
+ * S5P64X0 - GPIOlib support
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
- */
+*/
#include <linux/kernel.h>
#include <linux/irq.h>
@@ -22,26 +22,29 @@
#include <plat/gpio-cfg.h>
#include <plat/gpio-cfg-helpers.h>
-/* GPIO bank summary:
-*
-* Bank GPIOs Style SlpCon ExtInt Group
-* A 6 4Bit Yes 1
-* B 7 4Bit Yes 1
-* C 8 4Bit Yes 2
-* F 2 2Bit Yes 4 [1]
-* G 7 4Bit Yes 5
-* H 10 4Bit[2] Yes 6
-* I 16 2Bit Yes None
-* J 12 2Bit Yes None
-* N 16 2Bit No IRQ_EINT
-* P 8 2Bit Yes 8
-* R 15 4Bit[2] Yes 8
-*
-* [1] BANKF pins 14,15 do not form part of the external interrupt sources
-* [2] BANK has two control registers, GPxCON0 and GPxCON1
-*/
+/* To be implemented S5P6450 GPIO */
+
+/*
+ * S5P6440 GPIO bank summary:
+ *
+ * Bank GPIOs Style SlpCon ExtInt Group
+ * A 6 4Bit Yes 1
+ * B 7 4Bit Yes 1
+ * C 8 4Bit Yes 2
+ * F 2 2Bit Yes 4 [1]
+ * G 7 4Bit Yes 5
+ * H 10 4Bit[2] Yes 6
+ * I 16 2Bit Yes None
+ * J 12 2Bit Yes None
+ * N 16 2Bit No IRQ_EINT
+ * P 8 2Bit Yes 8
+ * R 15 4Bit[2] Yes 8
+ *
+ * [1] BANKF pins 14,15 do not form part of the external interrupt sources
+ * [2] BANK has two control registers, GPxCON0 and GPxCON1
+ */
-static int s5p6440_gpiolib_rbank_4bit2_input(struct gpio_chip *chip,
+static int s5p64x0_gpiolib_rbank_4bit2_input(struct gpio_chip *chip,
unsigned int offset)
{
struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
@@ -77,7 +80,7 @@ static int s5p6440_gpiolib_rbank_4bit2_input(struct gpio_chip *chip,
return 0;
}
-static int s5p6440_gpiolib_rbank_4bit2_output(struct gpio_chip *chip,
+static int s5p64x0_gpiolib_rbank_4bit2_output(struct gpio_chip *chip,
unsigned int offset, int value)
{
struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
@@ -124,12 +127,11 @@ static int s5p6440_gpiolib_rbank_4bit2_output(struct gpio_chip *chip,
return 0;
}
-int s5p6440_gpio_setcfg_4bit_rbank(struct s3c_gpio_chip *chip,
+int s5p64x0_gpio_setcfg_4bit_rbank(struct s3c_gpio_chip *chip,
unsigned int off, unsigned int cfg)
{
void __iomem *reg = chip->base;
unsigned int shift;
- unsigned long flags;
u32 con;
switch (off) {
@@ -155,26 +157,22 @@ int s5p6440_gpio_setcfg_4bit_rbank(struct s3c_gpio_chip *chip,
cfg <<= shift;
}
- s3c_gpio_lock(chip, flags);
-
con = __raw_readl(reg);
con &= ~(0xf << shift);
con |= cfg;
__raw_writel(con, reg);
- s3c_gpio_unlock(chip, flags);
-
return 0;
}
-static struct s3c_gpio_cfg s5p6440_gpio_cfgs[] = {
+static struct s3c_gpio_cfg s5p64x0_gpio_cfgs[] = {
{
.cfg_eint = 0,
}, {
.cfg_eint = 7,
}, {
.cfg_eint = 3,
- .set_config = s5p6440_gpio_setcfg_4bit_rbank,
+ .set_config = s5p64x0_gpio_setcfg_4bit_rbank,
}, {
.cfg_eint = 0,
.set_config = s3c_gpio_setcfg_s3c24xx,
@@ -193,7 +191,7 @@ static struct s3c_gpio_cfg s5p6440_gpio_cfgs[] = {
static struct s3c_gpio_chip s5p6440_gpio_4bit[] = {
{
.base = S5P6440_GPA_BASE,
- .config = &s5p6440_gpio_cfgs[1],
+ .config = &s5p64x0_gpio_cfgs[1],
.chip = {
.base = S5P6440_GPA(0),
.ngpio = S5P6440_GPIO_A_NR,
@@ -201,7 +199,7 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit[] = {
},
}, {
.base = S5P6440_GPB_BASE,
- .config = &s5p6440_gpio_cfgs[1],
+ .config = &s5p64x0_gpio_cfgs[1],
.chip = {
.base = S5P6440_GPB(0),
.ngpio = S5P6440_GPIO_B_NR,
@@ -209,7 +207,7 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit[] = {
},
}, {
.base = S5P6440_GPC_BASE,
- .config = &s5p6440_gpio_cfgs[1],
+ .config = &s5p64x0_gpio_cfgs[1],
.chip = {
.base = S5P6440_GPC(0),
.ngpio = S5P6440_GPIO_C_NR,
@@ -217,7 +215,7 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit[] = {
},
}, {
.base = S5P6440_GPG_BASE,
- .config = &s5p6440_gpio_cfgs[1],
+ .config = &s5p64x0_gpio_cfgs[1],
.chip = {
.base = S5P6440_GPG(0),
.ngpio = S5P6440_GPIO_G_NR,
@@ -229,7 +227,7 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit[] = {
static struct s3c_gpio_chip s5p6440_gpio_4bit2[] = {
{
.base = S5P6440_GPH_BASE + 0x4,
- .config = &s5p6440_gpio_cfgs[1],
+ .config = &s5p64x0_gpio_cfgs[1],
.chip = {
.base = S5P6440_GPH(0),
.ngpio = S5P6440_GPIO_H_NR,
@@ -238,10 +236,10 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit2[] = {
},
};
-static struct s3c_gpio_chip gpio_rbank_4bit2[] = {
+static struct s3c_gpio_chip s5p6440_gpio_rbank_4bit2[] = {
{
.base = S5P6440_GPR_BASE + 0x4,
- .config = &s5p6440_gpio_cfgs[2],
+ .config = &s5p64x0_gpio_cfgs[2],
.chip = {
.base = S5P6440_GPR(0),
.ngpio = S5P6440_GPIO_R_NR,
@@ -253,7 +251,7 @@ static struct s3c_gpio_chip gpio_rbank_4bit2[] = {
static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
{
.base = S5P6440_GPF_BASE,
- .config = &s5p6440_gpio_cfgs[5],
+ .config = &s5p64x0_gpio_cfgs[5],
.chip = {
.base = S5P6440_GPF(0),
.ngpio = S5P6440_GPIO_F_NR,
@@ -261,7 +259,7 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
},
}, {
.base = S5P6440_GPI_BASE,
- .config = &s5p6440_gpio_cfgs[3],
+ .config = &s5p64x0_gpio_cfgs[3],
.chip = {
.base = S5P6440_GPI(0),
.ngpio = S5P6440_GPIO_I_NR,
@@ -269,7 +267,7 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
},
}, {
.base = S5P6440_GPJ_BASE,
- .config = &s5p6440_gpio_cfgs[3],
+ .config = &s5p64x0_gpio_cfgs[3],
.chip = {
.base = S5P6440_GPJ(0),
.ngpio = S5P6440_GPIO_J_NR,
@@ -277,7 +275,7 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
},
}, {
.base = S5P6440_GPN_BASE,
- .config = &s5p6440_gpio_cfgs[4],
+ .config = &s5p64x0_gpio_cfgs[4],
.chip = {
.base = S5P6440_GPN(0),
.ngpio = S5P6440_GPIO_N_NR,
@@ -285,7 +283,7 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
},
}, {
.base = S5P6440_GPP_BASE,
- .config = &s5p6440_gpio_cfgs[5],
+ .config = &s5p64x0_gpio_cfgs[5],
.chip = {
.base = S5P6440_GPP(0),
.ngpio = S5P6440_GPIO_P_NR,
@@ -294,7 +292,7 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
},
};
-void __init s5p6440_gpiolib_set_cfg(struct s3c_gpio_cfg *chipcfg, int nr_chips)
+void __init s5p64x0_gpiolib_set_cfg(struct s3c_gpio_cfg *chipcfg, int nr_chips)
{
for (; nr_chips > 0; nr_chips--, chipcfg++) {
if (!chipcfg->set_config)
@@ -308,13 +306,13 @@ void __init s5p6440_gpiolib_set_cfg(struct s3c_gpio_cfg *chipcfg, int nr_chips)
}
}
-static void __init s5p6440_gpio_add_rbank_4bit2(struct s3c_gpio_chip *chip,
+static void __init s5p64x0_gpio_add_rbank_4bit2(struct s3c_gpio_chip *chip,
int nr_chips)
{
for (; nr_chips > 0; nr_chips--, chip++) {
- chip->chip.direction_input = s5p6440_gpiolib_rbank_4bit2_input;
+ chip->chip.direction_input = s5p64x0_gpiolib_rbank_4bit2_input;
chip->chip.direction_output =
- s5p6440_gpiolib_rbank_4bit2_output;
+ s5p64x0_gpiolib_rbank_4bit2_output;
s3c_gpiolib_add(chip);
}
}
@@ -324,8 +322,8 @@ static int __init s5p6440_gpiolib_init(void)
struct s3c_gpio_chip *chips = s5p6440_gpio_2bit;
int nr_chips = ARRAY_SIZE(s5p6440_gpio_2bit);
- s5p6440_gpiolib_set_cfg(s5p6440_gpio_cfgs,
- ARRAY_SIZE(s5p6440_gpio_cfgs));
+ s5p64x0_gpiolib_set_cfg(s5p64x0_gpio_cfgs,
+ ARRAY_SIZE(s5p64x0_gpio_cfgs));
for (; nr_chips > 0; nr_chips--, chips++)
s3c_gpiolib_add(chips);
@@ -336,8 +334,8 @@ static int __init s5p6440_gpiolib_init(void)
samsung_gpiolib_add_4bit2_chips(s5p6440_gpio_4bit2,
ARRAY_SIZE(s5p6440_gpio_4bit2));
- s5p6440_gpio_add_rbank_4bit2(gpio_rbank_4bit2,
- ARRAY_SIZE(gpio_rbank_4bit2));
+ s5p64x0_gpio_add_rbank_4bit2(s5p6440_gpio_rbank_4bit2,
+ ARRAY_SIZE(s5p6440_gpio_rbank_4bit2));
return 0;
}
diff --git a/arch/arm/mach-s5p64x0/include/mach/debug-macro.S b/arch/arm/mach-s5p64x0/include/mach/debug-macro.S
new file mode 100644
index 000000000000..79b04e6a6f8e
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/debug-macro.S
@@ -0,0 +1,33 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/debug-macro.S
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* pull in the relevant register and map files. */
+
+#include <plat/map-base.h>
+#include <plat/map-s5p.h>
+
+#include <plat/regs-serial.h>
+
+ .macro addruart, rp, rv
+ mov \rp, #0xE0000000
+ orr \rp, \rp, #0x00100000
+ ldr \rp, [\rp, #0x118 ]
+ and \rp, \rp, #0xff000
+ teq \rp, #0x50000 @@ S5P6450
+ ldreq \rp, =0xEC800000
+ movne \rp, #0xEC000000 @@ S5P6440
+ ldrne \rv, = S3C_VA_UART
+#if CONFIG_DEBUG_S3C_UART != 0
+ add \rp, \rp, #(0x400 * CONFIG_DEBUG_S3C_UART)
+ add \rv, \rv, #(0x400 * CONFIG_DEBUG_S3C_UART)
+#endif
+ .endm
+
+#include <plat/debug-macro.S>
diff --git a/arch/arm/mach-s5p6440/include/mach/dma.h b/arch/arm/mach-s5p64x0/include/mach/dma.h
index 81209eb1409b..81209eb1409b 100644
--- a/arch/arm/mach-s5p6440/include/mach/dma.h
+++ b/arch/arm/mach-s5p64x0/include/mach/dma.h
diff --git a/arch/arm/mach-s5p6440/include/mach/entry-macro.S b/arch/arm/mach-s5p64x0/include/mach/entry-macro.S
index e65f1b967262..10b62b4f8211 100644
--- a/arch/arm/mach-s5p6440/include/mach/entry-macro.S
+++ b/arch/arm/mach-s5p64x0/include/mach/entry-macro.S
@@ -1,9 +1,9 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/entry-macro.S
+/* linux/arch/arm/mach-s5p64x0/include/mach/entry-macro.S
*
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
*
- * Low-level IRQ helper macros for the Samsung S5P6440
+ * Low-level IRQ helper macros for the Samsung S5P64X0
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/arch/arm/mach-s5p64x0/include/mach/gpio.h b/arch/arm/mach-s5p64x0/include/mach/gpio.h
new file mode 100644
index 000000000000..5486c8f01f1d
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/gpio.h
@@ -0,0 +1,139 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/gpio.h
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P64X0 - GPIO lib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H __FILE__
+
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+#define gpio_to_irq __gpio_to_irq
+
+/* GPIO bank sizes */
+
+#define S5P6440_GPIO_A_NR (6)
+#define S5P6440_GPIO_B_NR (7)
+#define S5P6440_GPIO_C_NR (8)
+#define S5P6440_GPIO_F_NR (2)
+#define S5P6440_GPIO_G_NR (7)
+#define S5P6440_GPIO_H_NR (10)
+#define S5P6440_GPIO_I_NR (16)
+#define S5P6440_GPIO_J_NR (12)
+#define S5P6440_GPIO_N_NR (16)
+#define S5P6440_GPIO_P_NR (8)
+#define S5P6440_GPIO_R_NR (15)
+
+#define S5P6450_GPIO_A_NR (6)
+#define S5P6450_GPIO_B_NR (7)
+#define S5P6450_GPIO_C_NR (8)
+#define S5P6450_GPIO_D_NR (8)
+#define S5P6450_GPIO_F_NR (2)
+#define S5P6450_GPIO_G_NR (14)
+#define S5P6450_GPIO_H_NR (10)
+#define S5P6450_GPIO_I_NR (16)
+#define S5P6450_GPIO_J_NR (12)
+#define S5P6450_GPIO_K_NR (5)
+#define S5P6450_GPIO_N_NR (16)
+#define S5P6450_GPIO_P_NR (11)
+#define S5P6450_GPIO_Q_NR (14)
+#define S5P6450_GPIO_R_NR (15)
+#define S5P6450_GPIO_S_NR (8)
+
+/* GPIO bank numbers */
+
+/* CONFIG_S3C_GPIO_SPACE allows the user to select extra
+ * space for debugging purposes so that any accidental
+ * change from one gpio bank to another can be caught.
+*/
+
+#define S5P64X0_GPIO_NEXT(__gpio) \
+ ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
+
+enum s5p6440_gpio_number {
+ S5P6440_GPIO_A_START = 0,
+ S5P6440_GPIO_B_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_A),
+ S5P6440_GPIO_C_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_B),
+ S5P6440_GPIO_F_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_C),
+ S5P6440_GPIO_G_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_F),
+ S5P6440_GPIO_H_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_G),
+ S5P6440_GPIO_I_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_H),
+ S5P6440_GPIO_J_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_I),
+ S5P6440_GPIO_N_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_J),
+ S5P6440_GPIO_P_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_N),
+ S5P6440_GPIO_R_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_P),
+};
+
+enum s5p6450_gpio_number {
+ S5P6450_GPIO_A_START = 0,
+ S5P6450_GPIO_B_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_A),
+ S5P6450_GPIO_C_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_B),
+ S5P6450_GPIO_D_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_C),
+ S5P6450_GPIO_F_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_D),
+ S5P6450_GPIO_G_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_F),
+ S5P6450_GPIO_H_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_G),
+ S5P6450_GPIO_I_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_H),
+ S5P6450_GPIO_J_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_I),
+ S5P6450_GPIO_K_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_J),
+ S5P6450_GPIO_N_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_K),
+ S5P6450_GPIO_P_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_N),
+ S5P6450_GPIO_Q_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_P),
+ S5P6450_GPIO_R_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_Q),
+ S5P6450_GPIO_S_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_R),
+};
+
+/* GPIO number definitions */
+
+#define S5P6440_GPA(_nr) (S5P6440_GPIO_A_START + (_nr))
+#define S5P6440_GPB(_nr) (S5P6440_GPIO_B_START + (_nr))
+#define S5P6440_GPC(_nr) (S5P6440_GPIO_C_START + (_nr))
+#define S5P6440_GPF(_nr) (S5P6440_GPIO_F_START + (_nr))
+#define S5P6440_GPG(_nr) (S5P6440_GPIO_G_START + (_nr))
+#define S5P6440_GPH(_nr) (S5P6440_GPIO_H_START + (_nr))
+#define S5P6440_GPI(_nr) (S5P6440_GPIO_I_START + (_nr))
+#define S5P6440_GPJ(_nr) (S5P6440_GPIO_J_START + (_nr))
+#define S5P6440_GPN(_nr) (S5P6440_GPIO_N_START + (_nr))
+#define S5P6440_GPP(_nr) (S5P6440_GPIO_P_START + (_nr))
+#define S5P6440_GPR(_nr) (S5P6440_GPIO_R_START + (_nr))
+
+#define S5P6450_GPA(_nr) (S5P6450_GPIO_A_START + (_nr))
+#define S5P6450_GPB(_nr) (S5P6450_GPIO_B_START + (_nr))
+#define S5P6450_GPC(_nr) (S5P6450_GPIO_C_START + (_nr))
+#define S5P6450_GPD(_nr) (S5P6450_GPIO_D_START + (_nr))
+#define S5P6450_GPF(_nr) (S5P6450_GPIO_F_START + (_nr))
+#define S5P6450_GPG(_nr) (S5P6450_GPIO_G_START + (_nr))
+#define S5P6450_GPH(_nr) (S5P6450_GPIO_H_START + (_nr))
+#define S5P6450_GPI(_nr) (S5P6450_GPIO_I_START + (_nr))
+#define S5P6450_GPJ(_nr) (S5P6450_GPIO_J_START + (_nr))
+#define S5P6450_GPK(_nr) (S5P6450_GPIO_K_START + (_nr))
+#define S5P6450_GPN(_nr) (S5P6450_GPIO_N_START + (_nr))
+#define S5P6450_GPP(_nr) (S5P6450_GPIO_P_START + (_nr))
+#define S5P6450_GPQ(_nr) (S5P6450_GPIO_Q_START + (_nr))
+#define S5P6450_GPR(_nr) (S5P6450_GPIO_R_START + (_nr))
+#define S5P6450_GPS(_nr) (S5P6450_GPIO_S_START + (_nr))
+
+/* the end of the S5P64X0 specific gpios */
+
+#define S5P6440_GPIO_END (S5P6440_GPR(S5P6440_GPIO_R_NR) + 1)
+#define S5P6450_GPIO_END (S5P6450_GPS(S5P6450_GPIO_S_NR) + 1)
+
+#define S5P64X0_GPIO_END (S5P6440_GPIO_END > S5P6450_GPIO_END ? \
+ S5P6440_GPIO_END : S5P6450_GPIO_END)
+
+#define S3C_GPIO_END S5P64X0_GPIO_END
+
+/* define the number of gpios we need to the one after the last GPIO range */
+
+#define ARCH_NR_GPIOS (S5P64X0_GPIO_END + CONFIG_SAMSUNG_GPIO_EXTRA)
+
+#include <asm-generic/gpio.h>
+
+#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-s5p6440/include/mach/hardware.h b/arch/arm/mach-s5p64x0/include/mach/hardware.h
index be8b26e875db..d3e87996dd9a 100644
--- a/arch/arm/mach-s5p6440/include/mach/hardware.h
+++ b/arch/arm/mach-s5p64x0/include/mach/hardware.h
@@ -1,9 +1,9 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/hardware.h
+/* linux/arch/arm/mach-s5p64x0/include/mach/hardware.h
*
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
*
- * S5P6440 - Hardware support
+ * S5P64X0 - Hardware support
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/arch/arm/mach-s5p64x0/include/mach/i2c.h b/arch/arm/mach-s5p64x0/include/mach/i2c.h
new file mode 100644
index 000000000000..887d25209e8e
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/i2c.h
@@ -0,0 +1,17 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/i2c.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P64X0 I2C configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+extern void s5p6440_i2c0_cfg_gpio(struct platform_device *dev);
+extern void s5p6440_i2c1_cfg_gpio(struct platform_device *dev);
+
+extern void s5p6450_i2c0_cfg_gpio(struct platform_device *dev);
+extern void s5p6450_i2c1_cfg_gpio(struct platform_device *dev);
diff --git a/arch/arm/mach-s5p64x0/include/mach/io.h b/arch/arm/mach-s5p64x0/include/mach/io.h
new file mode 100644
index 000000000000..a3e095c02fb5
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/io.h
@@ -0,0 +1,25 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/io.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben-linux@fluff.org>
+ *
+ * Default IO routines for S5P64X0 based
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/* No current ISA/PCI bus support. */
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#define IO_SPACE_LIMIT (0xFFFFFFFF)
+
+#endif
diff --git a/arch/arm/mach-s5p6440/include/mach/irqs.h b/arch/arm/mach-s5p64x0/include/mach/irqs.h
index 16a761270de1..513abffc7604 100644
--- a/arch/arm/mach-s5p6440/include/mach/irqs.h
+++ b/arch/arm/mach-s5p64x0/include/mach/irqs.h
@@ -1,17 +1,17 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/irqs.h
+/* linux/arch/arm/mach-s5p64x0/include/mach/irqs.h
*
- * Copyright 2009 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
+ * Copyright 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
*
- * S5P6440 - IRQ definitions
+ * S5P64X0 - IRQ definitions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-#ifndef __ASM_ARCH_S5P_IRQS_H
-#define __ASM_ARCH_S5P_IRQS_H __FILE__
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H __FILE__
#include <plat/irqs.h>
@@ -20,10 +20,12 @@
#define IRQ_EINT0_3 S5P_IRQ_VIC0(0)
#define IRQ_EINT4_11 S5P_IRQ_VIC0(1)
#define IRQ_RTC_TIC S5P_IRQ_VIC0(2)
+#define IRQ_IIS1 S5P_IRQ_VIC0(3) /* for only S5P6450 */
+#define IRQ_IIS2 S5P_IRQ_VIC0(4) /* for only S5P6450 */
#define IRQ_IIC1 S5P_IRQ_VIC0(5)
#define IRQ_I2SV40 S5P_IRQ_VIC0(6)
-#define IRQ_GPS S5P_IRQ_VIC0(7)
-#define IRQ_POST0 S5P_IRQ_VIC0(9)
+#define IRQ_GPS S5P_IRQ_VIC0(7) /* for only S5P6450 */
+
#define IRQ_2D S5P_IRQ_VIC0(11)
#define IRQ_TIMER0_VIC S5P_IRQ_VIC0(23)
#define IRQ_TIMER1_VIC S5P_IRQ_VIC0(24)
@@ -39,22 +41,26 @@
#define IRQ_EINT12_15 S5P_IRQ_VIC1(0)
#define IRQ_PCM0 S5P_IRQ_VIC1(2)
+#define IRQ_PCM1 S5P_IRQ_VIC1(3) /* for only S5P6450 */
+#define IRQ_PCM2 S5P_IRQ_VIC1(4) /* for only S5P6450 */
#define IRQ_UART0 S5P_IRQ_VIC1(5)
#define IRQ_UART1 S5P_IRQ_VIC1(6)
#define IRQ_UART2 S5P_IRQ_VIC1(7)
#define IRQ_UART3 S5P_IRQ_VIC1(8)
#define IRQ_DMA0 S5P_IRQ_VIC1(9)
+#define IRQ_UART4 S5P_IRQ_VIC1(10) /* S5P6450 */
+#define IRQ_UART5 S5P_IRQ_VIC1(11) /* S5P6450 */
#define IRQ_NFC S5P_IRQ_VIC1(13)
+#define IRQ_USI S5P_IRQ_VIC1(15) /* S5P6450 */
#define IRQ_SPI0 S5P_IRQ_VIC1(16)
#define IRQ_SPI1 S5P_IRQ_VIC1(17)
+#define IRQ_HSMMC2 S5P_IRQ_VIC1(17) /* Shared */
#define IRQ_IIC S5P_IRQ_VIC1(18)
#define IRQ_DISPCON3 S5P_IRQ_VIC1(19)
-#define IRQ_FIMGVG S5P_IRQ_VIC1(20)
#define IRQ_EINT_GROUPS S5P_IRQ_VIC1(21)
-#define IRQ_PMU S5P_IRQ_VIC1(23)
+#define IRQ_PMU S5P_IRQ_VIC1(23) /* S5P6440 */
#define IRQ_HSMMC0 S5P_IRQ_VIC1(24)
#define IRQ_HSMMC1 S5P_IRQ_VIC1(25)
-#define IRQ_HSMMC2 IRQ_SPI1 /* shared with SPI1 */
#define IRQ_OTG S5P_IRQ_VIC1(26)
#define IRQ_DSI S5P_IRQ_VIC1(27)
#define IRQ_RTC_ALARM S5P_IRQ_VIC1(28)
@@ -63,6 +69,24 @@
#define IRQ_TC IRQ_PENDN
#define IRQ_ADC S5P_IRQ_VIC1(31)
+/* UART interrupts, S5P6450 has 5 UARTs */
+#define IRQ_S5P_UART_BASE4 (96)
+#define IRQ_S5P_UART_BASE5 (100)
+
+#define IRQ_S5P_UART_RX4 (IRQ_S5P_UART_BASE4 + UART_IRQ_RXD)
+#define IRQ_S5P_UART_TX4 (IRQ_S5P_UART_BASE4 + UART_IRQ_TXD)
+#define IRQ_S5P_UART_ERR4 (IRQ_S5P_UART_BASE4 + UART_IRQ_ERR)
+
+#define IRQ_S5P_UART_RX5 (IRQ_S5P_UART_BASE5 + UART_IRQ_RXD)
+#define IRQ_S5P_UART_TX5 (IRQ_S5P_UART_BASE5 + UART_IRQ_TXD)
+#define IRQ_S5P_UART_ERR5 (IRQ_S5P_UART_BASE5 + UART_IRQ_ERR)
+
+/* S3C compatibilty defines */
+#define IRQ_S3CUART_RX4 IRQ_S5P_UART_RX4
+#define IRQ_S3CUART_RX5 IRQ_S5P_UART_RX5
+
+/* S5P6450 EINT feature will be added */
+
/*
* Since the IRQ_EINT(x) are a linear mapping on s5p6440 we just defined
* them as an IRQ_EINT(x) macro from S5P_IRQ_EINT_BASE which we place
@@ -115,4 +139,4 @@
#define NR_IRQS (IRQ_EINT_GROUP8_BASE + IRQ_EINT_GROUP8_NR + 1)
-#endif /* __ASM_ARCH_S5P_IRQS_H */
+#endif /* __ASM_ARCH_IRQS_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/map.h b/arch/arm/mach-s5p64x0/include/mach/map.h
new file mode 100644
index 000000000000..31e534156e06
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/map.h
@@ -0,0 +1,83 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/map.h
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P64X0 - Memory map definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MAP_H
+#define __ASM_ARCH_MAP_H __FILE__
+
+#include <plat/map-base.h>
+#include <plat/map-s5p.h>
+
+#define S5P64X0_PA_SDRAM (0x20000000)
+
+#define S5P64X0_PA_CHIPID (0xE0000000)
+#define S5P_PA_CHIPID S5P64X0_PA_CHIPID
+
+#define S5P64X0_PA_SYSCON (0xE0100000)
+#define S5P_PA_SYSCON S5P64X0_PA_SYSCON
+
+#define S5P64X0_PA_GPIO (0xE0308000)
+
+#define S5P64X0_PA_VIC0 (0xE4000000)
+#define S5P64X0_PA_VIC1 (0xE4100000)
+
+#define S5P64X0_PA_PDMA (0xE9000000)
+
+#define S5P64X0_PA_TIMER (0xEA000000)
+#define S5P_PA_TIMER S5P64X0_PA_TIMER
+
+#define S5P64X0_PA_RTC (0xEA100000)
+
+#define S5P64X0_PA_WDT (0xEA200000)
+
+#define S5P6440_PA_UART(x) (0xEC000000 + ((x) * S3C_UART_OFFSET))
+#define S5P6450_PA_UART(x) ((x < 5) ? (0xEC800000 + ((x) * S3C_UART_OFFSET)) : (0xEC000000))
+
+#define S5P_PA_UART0 S5P6450_PA_UART(0)
+#define S5P_PA_UART1 S5P6450_PA_UART(1)
+#define S5P_PA_UART2 S5P6450_PA_UART(2)
+#define S5P_PA_UART3 S5P6450_PA_UART(3)
+#define S5P_PA_UART4 S5P6450_PA_UART(4)
+#define S5P_PA_UART5 S5P6450_PA_UART(5)
+
+#define S5P_SZ_UART SZ_256
+
+#define S5P6440_PA_IIC0 (0xEC104000)
+#define S5P6440_PA_IIC1 (0xEC20F000)
+#define S5P6450_PA_IIC0 (0xEC100000)
+#define S5P6450_PA_IIC1 (0xEC200000)
+
+#define S5P64X0_PA_SPI0 (0xEC400000)
+#define S5P64X0_PA_SPI1 (0xEC500000)
+
+#define S5P64X0_PA_HSOTG (0xED100000)
+
+#define S5P64X0_PA_HSMMC(x) (0xED800000 + ((x) * 0x100000))
+
+#define S5P64X0_PA_I2S (0xF2000000)
+
+#define S5P64X0_PA_PCM (0xF2100000)
+
+#define S5P64X0_PA_ADC (0xF3000000)
+
+/* compatibiltiy defines. */
+
+#define S3C_PA_HSMMC0 S5P64X0_PA_HSMMC(0)
+#define S3C_PA_HSMMC1 S5P64X0_PA_HSMMC(1)
+#define S3C_PA_HSMMC2 S5P64X0_PA_HSMMC(2)
+#define S3C_PA_IIC S5P6440_PA_IIC0
+#define S3C_PA_IIC1 S5P6440_PA_IIC1
+#define S3C_PA_RTC S5P64X0_PA_RTC
+#define S3C_PA_WDT S5P64X0_PA_WDT
+
+#define SAMSUNG_PA_ADC S5P64X0_PA_ADC
+
+#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s5p6440/include/mach/memory.h b/arch/arm/mach-s5p64x0/include/mach/memory.h
index d62910c71b56..1b036b0a24ce 100644
--- a/arch/arm/mach-s5p6440/include/mach/memory.h
+++ b/arch/arm/mach-s5p64x0/include/mach/memory.h
@@ -1,9 +1,9 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/memory.h
+/* linux/arch/arm/mach-s5p64x0/include/mach/memory.h
*
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
*
- * S5P6440 - Memory definitions
+ * S5P64X0 - Memory definitions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -11,9 +11,9 @@
*/
#ifndef __ASM_ARCH_MEMORY_H
-#define __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H __FILE__
-#define PHYS_OFFSET UL(0x20000000)
+#define PHYS_OFFSET UL(0x20000000)
#define CONSISTENT_DMA_SIZE SZ_8M
#endif /* __ASM_ARCH_MEMORY_H */
diff --git a/arch/arm/mach-s5p6440/include/mach/pwm-clock.h b/arch/arm/mach-s5p64x0/include/mach/pwm-clock.h
index 6a2a02fdf12a..19fff8b701c0 100644
--- a/arch/arm/mach-s5p6440/include/mach/pwm-clock.h
+++ b/arch/arm/mach-s5p64x0/include/mach/pwm-clock.h
@@ -1,16 +1,14 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/pwm-clock.h
+/* linux/arch/arm/mach-s5p64x0/include/mach/pwm-clock.h
*
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
- * Based on arch/arm/mach-s3c64xx/include/mach/pwm-clock.h
- *
- * S5P6440 - pwm clock and timer support
+ * S5P64X0 - pwm clock and timer support
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/arch/arm/mach-s5p64x0/include/mach/regs-clock.h b/arch/arm/mach-s5p64x0/include/mach/regs-clock.h
new file mode 100644
index 000000000000..58e1bc813804
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/regs-clock.h
@@ -0,0 +1,63 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/regs-clock.h
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P64X0 - Clock register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_CLOCK_H
+#define __ASM_ARCH_REGS_CLOCK_H __FILE__
+
+#include <mach/map.h>
+
+#define S5P_CLKREG(x) (S3C_VA_SYS + (x))
+
+#define S5P64X0_APLL_CON S5P_CLKREG(0x0C)
+#define S5P64X0_MPLL_CON S5P_CLKREG(0x10)
+#define S5P64X0_EPLL_CON S5P_CLKREG(0x14)
+#define S5P64X0_EPLL_CON_K S5P_CLKREG(0x18)
+
+#define S5P64X0_CLK_SRC0 S5P_CLKREG(0x1C)
+
+#define S5P64X0_CLK_DIV0 S5P_CLKREG(0x20)
+#define S5P64X0_CLK_DIV1 S5P_CLKREG(0x24)
+#define S5P64X0_CLK_DIV2 S5P_CLKREG(0x28)
+
+#define S5P64X0_CLK_GATE_HCLK0 S5P_CLKREG(0x30)
+#define S5P64X0_CLK_GATE_PCLK S5P_CLKREG(0x34)
+#define S5P64X0_CLK_GATE_SCLK0 S5P_CLKREG(0x38)
+#define S5P64X0_CLK_GATE_MEM0 S5P_CLKREG(0x3C)
+
+#define S5P64X0_CLK_DIV3 S5P_CLKREG(0x40)
+
+#define S5P64X0_CLK_GATE_HCLK1 S5P_CLKREG(0x44)
+#define S5P64X0_CLK_GATE_SCLK1 S5P_CLKREG(0x48)
+
+#define S5P6450_DPLL_CON S5P_CLKREG(0x50)
+#define S5P6450_DPLL_CON_K S5P_CLKREG(0x54)
+
+#define S5P64X0_CLK_SRC1 S5P_CLKREG(0x10C)
+
+#define S5P64X0_SYS_ID S5P_CLKREG(0x118)
+#define S5P64X0_SYS_OTHERS S5P_CLKREG(0x11C)
+
+#define S5P64X0_PWR_CFG S5P_CLKREG(0x804)
+#define S5P64X0_OTHERS S5P_CLKREG(0x900)
+
+#define S5P64X0_CLKDIV0_HCLK_SHIFT (8)
+#define S5P64X0_CLKDIV0_HCLK_MASK (0xF << S5P64X0_CLKDIV0_HCLK_SHIFT)
+
+#define S5P64X0_OTHERS_USB_SIG_MASK (1 << 16)
+
+/* Compatibility defines */
+
+#define ARM_CLK_DIV S5P64X0_CLK_DIV0
+#define ARM_DIV_RATIO_SHIFT 0
+#define ARM_DIV_MASK (0xF << ARM_DIV_RATIO_SHIFT)
+
+#endif /* __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-s5p6440/include/mach/regs-gpio.h b/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h
index 82ff753913da..85f448e20a8b 100644
--- a/arch/arm/mach-s5p6440/include/mach/regs-gpio.h
+++ b/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h
@@ -1,21 +1,24 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/regs-gpio.h
+/* linux/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h
*
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
*
- * S5P6440 - GPIO register definitions
+ * S5P64X0 - GPIO register definitions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
- */
+*/
#ifndef __ASM_ARCH_REGS_GPIO_H
#define __ASM_ARCH_REGS_GPIO_H __FILE__
#include <mach/map.h>
+/* Will be implemented S5P6442 GPIOlib */
+
/* Base addresses for each of the banks */
+
#define S5P6440_GPA_BASE (S5P_VA_GPIO + 0x0000)
#define S5P6440_GPB_BASE (S5P_VA_GPIO + 0x0020)
#define S5P6440_GPC_BASE (S5P_VA_GPIO + 0x0040)
@@ -27,6 +30,7 @@
#define S5P6440_GPN_BASE (S5P_VA_GPIO + 0x0830)
#define S5P6440_GPP_BASE (S5P_VA_GPIO + 0x0160)
#define S5P6440_GPR_BASE (S5P_VA_GPIO + 0x0290)
+
#define S5P6440_EINT0CON0 (S5P_VA_GPIO + 0x900)
#define S5P6440_EINT0FLTCON0 (S5P_VA_GPIO + 0x910)
#define S5P6440_EINT0FLTCON1 (S5P_VA_GPIO + 0x914)
@@ -34,19 +38,23 @@
#define S5P6440_EINT0PEND (S5P_VA_GPIO + 0x924)
/* for LCD */
+
#define S5P6440_SPCON_LCD_SEL_RGB (1 << 0)
#define S5P6440_SPCON_LCD_SEL_MASK (3 << 0)
-/* These set of macros are not really useful for the
- * GPF/GPI/GPJ/GPN/GPP,
- * useful for others set of GPIO's (4 bit)
+/*
+ * These set of macros are not really useful for the
+ * GPF/GPI/GPJ/GPN/GPP, useful for others set of GPIO's (4 bit)
*/
+
#define S5P6440_GPIO_CONMASK(__gpio) (0xf << ((__gpio) * 4))
#define S5P6440_GPIO_INPUT(__gpio) (0x0 << ((__gpio) * 4))
#define S5P6440_GPIO_OUTPUT(__gpio) (0x1 << ((__gpio) * 4))
-/* Use these macros for GPF/GPI/GPJ/GPN/GPP set of GPIO (2 bit)
- * */
+/*
+ * Use these macros for GPF/GPI/GPJ/GPN/GPP set of GPIO (2 bit)
+ */
+
#define S5P6440_GPIO2_CONMASK(__gpio) (0x3 << ((__gpio) * 2))
#define S5P6440_GPIO2_INPUT(__gpio) (0x0 << ((__gpio) * 2))
#define S5P6440_GPIO2_OUTPUT(__gpio) (0x1 << ((__gpio) * 2))
diff --git a/arch/arm/mach-s5p6440/include/mach/regs-irq.h b/arch/arm/mach-s5p64x0/include/mach/regs-irq.h
index a961f4beeb0c..4aaebdace55f 100644
--- a/arch/arm/mach-s5p6440/include/mach/regs-irq.h
+++ b/arch/arm/mach-s5p64x0/include/mach/regs-irq.h
@@ -1,9 +1,9 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/regs-irq.h
+/* linux/arch/arm/mach-s5p64x0/include/mach/regs-irq.h
*
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
*
- * S5P6440 - IRQ register definitions
+ * S5P64X0 - IRQ register definitions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h b/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h
new file mode 100644
index 000000000000..ff85b4b6e8d9
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h
@@ -0,0 +1,46 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Header file for s5p64x0 clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_CLOCK_H
+#define __ASM_ARCH_CLOCK_H __FILE__
+
+#include <linux/clk.h>
+
+extern struct clksrc_clk clk_mout_apll;
+extern struct clksrc_clk clk_mout_mpll;
+extern struct clksrc_clk clk_mout_epll;
+
+extern int s5p64x0_epll_enable(struct clk *clk, int enable);
+extern unsigned long s5p64x0_epll_get_rate(struct clk *clk);
+
+extern unsigned long s5p64x0_armclk_get_rate(struct clk *clk);
+extern unsigned long s5p64x0_armclk_round_rate(struct clk *clk, unsigned long rate);
+extern int s5p64x0_armclk_set_rate(struct clk *clk, unsigned long rate);
+
+extern struct clk_ops s5p64x0_clkarm_ops;
+
+extern struct clksrc_clk clk_armclk;
+extern struct clksrc_clk clk_dout_mpll;
+
+extern struct clk *clkset_hclk_low_list[];
+extern struct clksrc_sources clkset_hclk_low;
+
+extern int s5p64x0_pclk_ctrl(struct clk *clk, int enable);
+extern int s5p64x0_hclk0_ctrl(struct clk *clk, int enable);
+extern int s5p64x0_hclk1_ctrl(struct clk *clk, int enable);
+extern int s5p64x0_sclk_ctrl(struct clk *clk, int enable);
+extern int s5p64x0_sclk1_ctrl(struct clk *clk, int enable);
+extern int s5p64x0_mem_ctrl(struct clk *clk, int enable);
+
+extern int s5p64x0_clk48m_ctrl(struct clk *clk, int enable);
+
+#endif /* __ASM_ARCH_CLOCK_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/spi-clocks.h b/arch/arm/mach-s5p64x0/include/mach/spi-clocks.h
new file mode 100644
index 000000000000..170a20a9643a
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/spi-clocks.h
@@ -0,0 +1,20 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/spi-clocks.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Copyright (C) 2010 Samsung Electronics Co. Ltd.
+ * Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_SPI_CLKS_H
+#define __ASM_ARCH_SPI_CLKS_H __FILE__
+
+#define S5P64X0_SPI_SRCCLK_PCLK 0
+#define S5P64X0_SPI_SRCCLK_SCLK 1
+
+#endif /* __ASM_ARCH_SPI_CLKS_H */
diff --git a/arch/arm/mach-s5p6440/include/mach/system.h b/arch/arm/mach-s5p64x0/include/mach/system.h
index a359ee3fa510..60f57532c970 100644
--- a/arch/arm/mach-s5p6440/include/mach/system.h
+++ b/arch/arm/mach-s5p64x0/include/mach/system.h
@@ -1,9 +1,9 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/system.h
+/* linux/arch/arm/mach-s5p64x0/include/mach/system.h
*
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
*
- * S5P6440 - system support header
+ * S5P64X0 - system support header
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/arch/arm/mach-s5p6440/include/mach/tick.h b/arch/arm/mach-s5p64x0/include/mach/tick.h
index 2f25c7f07970..00aa7f1d8e51 100644
--- a/arch/arm/mach-s5p6440/include/mach/tick.h
+++ b/arch/arm/mach-s5p64x0/include/mach/tick.h
@@ -1,9 +1,14 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/tick.h
+/* linux/arch/arm/mach-s5p64x0/include/mach/tick.h
*
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
*
- * S5P6440 - Timer tick support definitions
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S5P64X0 - Timer tick support definitions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/arch/arm/mach-s5p6440/include/mach/timex.h b/arch/arm/mach-s5p64x0/include/mach/timex.h
index fb2e8cd40829..4b91faa195a8 100644
--- a/arch/arm/mach-s5p6440/include/mach/timex.h
+++ b/arch/arm/mach-s5p64x0/include/mach/timex.h
@@ -1,9 +1,12 @@
-/* arch/arm/mach-s3c64xx/include/mach/timex.h
+/* linux/arch/arm/mach-s5p64x0/include/mach/timex.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
*
* Copyright (c) 2003-2005 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
- * S3C6400 - time parameters
+ * S5P64X0 - time parameters
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/arch/arm/mach-s5p64x0/include/mach/uncompress.h b/arch/arm/mach-s5p64x0/include/mach/uncompress.h
new file mode 100644
index 000000000000..c65b229aab23
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/uncompress.h
@@ -0,0 +1,212 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/uncompress.h
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P64X0 - uncompress code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <mach/map.h>
+
+/*
+ * cannot use commonly <plat/uncompress.h>
+ * because uart base of S5P6440 and S5P6450 is different
+ */
+
+typedef unsigned int upf_t; /* cannot include linux/serial_core.h */
+
+/* uart setup */
+
+static unsigned int fifo_mask;
+static unsigned int fifo_max;
+
+/* forward declerations */
+
+static void arch_detect_cpu(void);
+
+/* defines for UART registers */
+
+#include <plat/regs-serial.h>
+#include <plat/regs-watchdog.h>
+
+/* working in physical space... */
+#undef S3C2410_WDOGREG
+#define S3C2410_WDOGREG(x) ((S3C24XX_PA_WATCHDOG + (x)))
+
+/* how many bytes we allow into the FIFO at a time in FIFO mode */
+#define FIFO_MAX (14)
+
+static unsigned long uart_base;
+
+static __inline__ void get_uart_base(void)
+{
+ unsigned int chipid;
+
+ chipid = *(const volatile unsigned int __force *) 0xE0100118;
+
+ uart_base = S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT;
+
+ if ((chipid & 0xff000) == 0x50000)
+ uart_base += 0xEC800000;
+ else
+ uart_base += 0xEC000000;
+}
+
+static __inline__ void uart_wr(unsigned int reg, unsigned int val)
+{
+ volatile unsigned int *ptr;
+
+ get_uart_base();
+ ptr = (volatile unsigned int *)(reg + uart_base);
+ *ptr = val;
+}
+
+static __inline__ unsigned int uart_rd(unsigned int reg)
+{
+ volatile unsigned int *ptr;
+
+ get_uart_base();
+ ptr = (volatile unsigned int *)(reg + uart_base);
+ return *ptr;
+}
+
+/*
+ * we can deal with the case the UARTs are being run
+ * in FIFO mode, so that we don't hold up our execution
+ * waiting for tx to happen...
+ */
+
+static void putc(int ch)
+{
+ if (uart_rd(S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE) {
+ int level;
+
+ while (1) {
+ level = uart_rd(S3C2410_UFSTAT);
+ level &= fifo_mask;
+
+ if (level < fifo_max)
+ break;
+ }
+
+ } else {
+ /* not using fifos */
+
+ while ((uart_rd(S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE) != S3C2410_UTRSTAT_TXE)
+ barrier();
+ }
+
+ /* write byte to transmission register */
+ uart_wr(S3C2410_UTXH, ch);
+}
+
+static inline void flush(void)
+{
+}
+
+#define __raw_writel(d, ad) \
+ do { \
+ *((volatile unsigned int __force *)(ad)) = (d); \
+ } while (0)
+
+/*
+ * CONFIG_S3C_BOOT_WATCHDOG
+ *
+ * Simple boot-time watchdog setup, to reboot the system if there is
+ * any problem with the boot process
+ */
+
+#ifdef CONFIG_S3C_BOOT_WATCHDOG
+
+#define WDOG_COUNT (0xff00)
+
+static inline void arch_decomp_wdog(void)
+{
+ __raw_writel(WDOG_COUNT, S3C2410_WTCNT);
+}
+
+static void arch_decomp_wdog_start(void)
+{
+ __raw_writel(WDOG_COUNT, S3C2410_WTDAT);
+ __raw_writel(WDOG_COUNT, S3C2410_WTCNT);
+ __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x80), S3C2410_WTCON);
+}
+
+#else
+#define arch_decomp_wdog_start()
+#define arch_decomp_wdog()
+#endif
+
+#ifdef CONFIG_S3C_BOOT_ERROR_RESET
+
+static void arch_decomp_error(const char *x)
+{
+ putstr("\n\n");
+ putstr(x);
+ putstr("\n\n -- System resetting\n");
+
+ __raw_writel(0x4000, S3C2410_WTDAT);
+ __raw_writel(0x4000, S3C2410_WTCNT);
+ __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x40), S3C2410_WTCON);
+
+ while(1);
+}
+
+#define arch_error arch_decomp_error
+#endif
+
+#ifdef CONFIG_S3C_BOOT_UART_FORCE_FIFO
+static inline void arch_enable_uart_fifo(void)
+{
+ u32 fifocon = uart_rd(S3C2410_UFCON);
+
+ if (!(fifocon & S3C2410_UFCON_FIFOMODE)) {
+ fifocon |= S3C2410_UFCON_RESETBOTH;
+ uart_wr(S3C2410_UFCON, fifocon);
+
+ /* wait for fifo reset to complete */
+ while (1) {
+ fifocon = uart_rd(S3C2410_UFCON);
+ if (!(fifocon & S3C2410_UFCON_RESETBOTH))
+ break;
+ }
+ }
+}
+#else
+#define arch_enable_uart_fifo() do { } while(0)
+#endif
+
+static void arch_decomp_setup(void)
+{
+ /*
+ * we may need to setup the uart(s) here if we are not running
+ * on an BAST... the BAST will have left the uarts configured
+ * after calling linux.
+ */
+
+ arch_detect_cpu();
+ arch_decomp_wdog_start();
+
+ /*
+ * Enable the UART FIFOs if they where not enabled and our
+ * configuration says we should turn them on.
+ */
+
+ arch_enable_uart_fifo();
+}
+
+
+
+static void arch_detect_cpu(void)
+{
+ /* we do not need to do any cpu detection here at the moment. */
+}
+
+#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-s5p6440/include/mach/vmalloc.h b/arch/arm/mach-s5p64x0/include/mach/vmalloc.h
index e3f0eebf5205..97a9df38f1cf 100644
--- a/arch/arm/mach-s5p6440/include/mach/vmalloc.h
+++ b/arch/arm/mach-s5p64x0/include/mach/vmalloc.h
@@ -1,4 +1,7 @@
-/* arch/arm/mach-s5p6440/include/mach/vmalloc.h
+/* linux/arch/arm/mach-s5p64x0/include/mach/vmalloc.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
*
* Copyright 2010 Ben Dooks <ben-linux@fluff.org>
*
diff --git a/arch/arm/mach-s5p64x0/init.c b/arch/arm/mach-s5p64x0/init.c
new file mode 100644
index 000000000000..79833caf8165
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/init.c
@@ -0,0 +1,73 @@
+/* linux/arch/arm/mach-s5p64x0/init.c
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P64X0 - Init support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+
+#include <mach/map.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/s5p6440.h>
+#include <plat/s5p6450.h>
+#include <plat/regs-serial.h>
+
+static struct s3c24xx_uart_clksrc s5p64x0_serial_clocks[] = {
+ [0] = {
+ .name = "pclk_low",
+ .divisor = 1,
+ .min_baud = 0,
+ .max_baud = 0,
+ },
+ [1] = {
+ .name = "uclk1",
+ .divisor = 1,
+ .min_baud = 0,
+ .max_baud = 0,
+ },
+};
+
+/* uart registration process */
+
+void __init s5p64x0_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+ struct s3c2410_uartcfg *tcfg = cfg;
+ u32 ucnt;
+
+ for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
+ if (!tcfg->clocks) {
+ tcfg->clocks = s5p64x0_serial_clocks;
+ tcfg->clocks_size = ARRAY_SIZE(s5p64x0_serial_clocks);
+ }
+ }
+}
+
+void __init s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+ int uart;
+
+ for (uart = 0; uart < no; uart++) {
+ s5p_uart_resources[uart].resources->start = S5P6440_PA_UART(uart);
+ s5p_uart_resources[uart].resources->end = S5P6440_PA_UART(uart) + S5P_SZ_UART;
+ }
+
+ s5p64x0_common_init_uarts(cfg, no);
+ s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
+}
+
+void __init s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+ s5p64x0_common_init_uarts(cfg, no);
+ s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
+}
diff --git a/arch/arm/mach-s5p6440/mach-smdk6440.c b/arch/arm/mach-s5p64x0/mach-smdk6440.c
index 9202aaac3b56..87c3f03c618c 100644
--- a/arch/arm/mach-s5p6440/mach-smdk6440.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c
@@ -1,7 +1,7 @@
-/* linux/arch/arm/mach-s5p6440/mach-smdk6440.c
+/* linux/arch/arm/mach-s5p64x0/mach-smdk6440.c
*
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -21,21 +21,22 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/clk.h>
+#include <linux/gpio.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
#include <mach/hardware.h>
#include <mach/map.h>
-
-#include <asm/irq.h>
-#include <asm/mach-types.h>
+#include <mach/regs-clock.h>
+#include <mach/i2c.h>
#include <plat/regs-serial.h>
-
+#include <plat/gpio-cfg.h>
#include <plat/s5p6440.h>
#include <plat/clock.h>
-#include <mach/regs-clock.h>
#include <plat/devs.h>
#include <plat/cpu.h>
#include <plat/iic.h>
@@ -58,43 +59,60 @@
static struct s3c2410_uartcfg smdk6440_uartcfgs[] __initdata = {
[0] = {
- .hwport = 0,
- .flags = 0,
- .ucon = SMDK6440_UCON_DEFAULT,
- .ulcon = SMDK6440_ULCON_DEFAULT,
- .ufcon = SMDK6440_UFCON_DEFAULT,
+ .hwport = 0,
+ .flags = 0,
+ .ucon = SMDK6440_UCON_DEFAULT,
+ .ulcon = SMDK6440_ULCON_DEFAULT,
+ .ufcon = SMDK6440_UFCON_DEFAULT,
},
[1] = {
- .hwport = 1,
- .flags = 0,
- .ucon = SMDK6440_UCON_DEFAULT,
- .ulcon = SMDK6440_ULCON_DEFAULT,
- .ufcon = SMDK6440_UFCON_DEFAULT,
+ .hwport = 1,
+ .flags = 0,
+ .ucon = SMDK6440_UCON_DEFAULT,
+ .ulcon = SMDK6440_ULCON_DEFAULT,
+ .ufcon = SMDK6440_UFCON_DEFAULT,
},
[2] = {
- .hwport = 2,
- .flags = 0,
- .ucon = SMDK6440_UCON_DEFAULT,
- .ulcon = SMDK6440_ULCON_DEFAULT,
- .ufcon = SMDK6440_UFCON_DEFAULT,
+ .hwport = 2,
+ .flags = 0,
+ .ucon = SMDK6440_UCON_DEFAULT,
+ .ulcon = SMDK6440_ULCON_DEFAULT,
+ .ufcon = SMDK6440_UFCON_DEFAULT,
},
[3] = {
- .hwport = 3,
- .flags = 0,
- .ucon = SMDK6440_UCON_DEFAULT,
- .ulcon = SMDK6440_ULCON_DEFAULT,
- .ufcon = SMDK6440_UFCON_DEFAULT,
+ .hwport = 3,
+ .flags = 0,
+ .ucon = SMDK6440_UCON_DEFAULT,
+ .ulcon = SMDK6440_ULCON_DEFAULT,
+ .ufcon = SMDK6440_UFCON_DEFAULT,
},
};
static struct platform_device *smdk6440_devices[] __initdata = {
- &s5p6440_device_iis,
&s3c_device_adc,
&s3c_device_rtc,
&s3c_device_i2c0,
&s3c_device_i2c1,
&s3c_device_ts,
&s3c_device_wdt,
+ &s5p6440_device_iis,
+};
+
+static struct s3c2410_platform_i2c s5p6440_i2c0_data __initdata = {
+ .flags = 0,
+ .slave_addr = 0x10,
+ .frequency = 100*1000,
+ .sda_delay = 100,
+ .cfg_gpio = s5p6440_i2c0_cfg_gpio,
+};
+
+static struct s3c2410_platform_i2c s5p6440_i2c1_data __initdata = {
+ .flags = 0,
+ .bus_num = 1,
+ .slave_addr = 0x10,
+ .frequency = 100*1000,
+ .sda_delay = 100,
+ .cfg_gpio = s5p6440_i2c1_cfg_gpio,
};
static struct i2c_board_info smdk6440_i2c_devs0[] __initdata = {
@@ -113,7 +131,7 @@ static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
static void __init smdk6440_map_io(void)
{
- s5p_init_io(NULL, 0, S5P_SYS_ID);
+ s5p_init_io(NULL, 0, S5P64X0_SYS_ID);
s3c24xx_init_clocks(12000000);
s3c24xx_init_uarts(smdk6440_uartcfgs, ARRAY_SIZE(smdk6440_uartcfgs));
}
@@ -122,9 +140,8 @@ static void __init smdk6440_machine_init(void)
{
s3c24xx_ts_set_platdata(&s3c_ts_platform);
- /* I2C */
- s3c_i2c0_set_platdata(NULL);
- s3c_i2c1_set_platdata(NULL);
+ s3c_i2c0_set_platdata(&s5p6440_i2c0_data);
+ s3c_i2c1_set_platdata(&s5p6440_i2c1_data);
i2c_register_board_info(0, smdk6440_i2c_devs0,
ARRAY_SIZE(smdk6440_i2c_devs0));
i2c_register_board_info(1, smdk6440_i2c_devs1,
@@ -135,9 +152,7 @@ static void __init smdk6440_machine_init(void)
MACHINE_START(SMDK6440, "SMDK6440")
/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
- .phys_io = S3C_PA_UART & 0xfff00000,
- .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
- .boot_params = S5P_PA_SDRAM + 0x100,
+ .boot_params = S5P64X0_PA_SDRAM + 0x100,
.init_irq = s5p6440_init_irq,
.map_io = smdk6440_map_io,
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-s5p64x0/mach-smdk6450.c
new file mode 100644
index 000000000000..d609f5af2b98
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c
@@ -0,0 +1,180 @@
+/* linux/arch/arm/mach-s5p64x0/mach-smdk6450.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/i2c.h>
+
+#include <plat/regs-serial.h>
+#include <plat/gpio-cfg.h>
+#include <plat/s5p6450.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/iic.h>
+#include <plat/pll.h>
+#include <plat/adc.h>
+#include <plat/ts.h>
+
+#define SMDK6450_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define SMDK6450_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define SMDK6450_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S3C2440_UFCON_TXTRIG16 | \
+ S3C2410_UFCON_RXTRIG8)
+
+static struct s3c2410_uartcfg smdk6450_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = SMDK6450_UCON_DEFAULT,
+ .ulcon = SMDK6450_ULCON_DEFAULT,
+ .ufcon = SMDK6450_UFCON_DEFAULT,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = SMDK6450_UCON_DEFAULT,
+ .ulcon = SMDK6450_ULCON_DEFAULT,
+ .ufcon = SMDK6450_UFCON_DEFAULT,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = SMDK6450_UCON_DEFAULT,
+ .ulcon = SMDK6450_ULCON_DEFAULT,
+ .ufcon = SMDK6450_UFCON_DEFAULT,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = SMDK6450_UCON_DEFAULT,
+ .ulcon = SMDK6450_ULCON_DEFAULT,
+ .ufcon = SMDK6450_UFCON_DEFAULT,
+ },
+#if CONFIG_SERIAL_SAMSUNG_UARTS > 4
+ [4] = {
+ .hwport = 4,
+ .flags = 0,
+ .ucon = SMDK6450_UCON_DEFAULT,
+ .ulcon = SMDK6450_ULCON_DEFAULT,
+ .ufcon = SMDK6450_UFCON_DEFAULT,
+ },
+#endif
+#if CONFIG_SERIAL_SAMSUNG_UARTS > 5
+ [5] = {
+ .hwport = 5,
+ .flags = 0,
+ .ucon = SMDK6450_UCON_DEFAULT,
+ .ulcon = SMDK6450_ULCON_DEFAULT,
+ .ufcon = SMDK6450_UFCON_DEFAULT,
+ },
+#endif
+};
+
+static struct platform_device *smdk6450_devices[] __initdata = {
+ &s3c_device_adc,
+ &s3c_device_rtc,
+ &s3c_device_i2c0,
+ &s3c_device_i2c1,
+ &s3c_device_ts,
+ &s3c_device_wdt,
+ &s5p6450_device_iis0,
+ /* s5p6450_device_spi0 will be added */
+};
+
+static struct s3c2410_platform_i2c s5p6450_i2c0_data __initdata = {
+ .flags = 0,
+ .slave_addr = 0x10,
+ .frequency = 100*1000,
+ .sda_delay = 100,
+ .cfg_gpio = s5p6450_i2c0_cfg_gpio,
+};
+
+static struct s3c2410_platform_i2c s5p6450_i2c1_data __initdata = {
+ .flags = 0,
+ .bus_num = 1,
+ .slave_addr = 0x10,
+ .frequency = 100*1000,
+ .sda_delay = 100,
+ .cfg_gpio = s5p6450_i2c1_cfg_gpio,
+};
+
+static struct i2c_board_info smdk6450_i2c_devs0[] __initdata = {
+ { I2C_BOARD_INFO("24c08", 0x50), }, /* Samsung KS24C080C EEPROM */
+};
+
+static struct i2c_board_info smdk6450_i2c_devs1[] __initdata = {
+ { I2C_BOARD_INFO("24c128", 0x57), },/* Samsung S524AD0XD1 EEPROM */
+};
+
+static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
+ .delay = 10000,
+ .presc = 49,
+ .oversampling_shift = 2,
+};
+
+static void __init smdk6450_map_io(void)
+{
+ s5p_init_io(NULL, 0, S5P64X0_SYS_ID);
+ s3c24xx_init_clocks(19200000);
+ s3c24xx_init_uarts(smdk6450_uartcfgs, ARRAY_SIZE(smdk6450_uartcfgs));
+}
+
+static void __init smdk6450_machine_init(void)
+{
+ s3c24xx_ts_set_platdata(&s3c_ts_platform);
+
+ s3c_i2c0_set_platdata(&s5p6450_i2c0_data);
+ s3c_i2c1_set_platdata(&s5p6450_i2c1_data);
+ i2c_register_board_info(0, smdk6450_i2c_devs0,
+ ARRAY_SIZE(smdk6450_i2c_devs0));
+ i2c_register_board_info(1, smdk6450_i2c_devs1,
+ ARRAY_SIZE(smdk6450_i2c_devs1));
+
+ platform_add_devices(smdk6450_devices, ARRAY_SIZE(smdk6450_devices));
+}
+
+MACHINE_START(SMDK6450, "SMDK6450")
+ /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+ .boot_params = S5P64X0_PA_SDRAM + 0x100,
+
+ .init_irq = s5p6450_init_irq,
+ .map_io = smdk6450_map_io,
+ .init_machine = smdk6450_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s5p6440/setup-i2c0.c b/arch/arm/mach-s5p64x0/setup-i2c0.c
index 2c99d14f7ac7..dc4cc65a5019 100644
--- a/arch/arm/mach-s5p6440/setup-i2c0.c
+++ b/arch/arm/mach-s5p64x0/setup-i2c0.c
@@ -1,11 +1,11 @@
-/* linux/arch/arm/mach-s5p6440/setup-i2c0.c
+/* linux/arch/arm/mach-s5p64x0/setup-i2c0.c
*
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
*
* I2C0 GPIO configuration.
*
- * Based on plat-s3c64xx/setup-i2c0.c
+ * Based on plat-s3c64x0/setup-i2c0.c
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -14,17 +14,29 @@
#include <linux/kernel.h>
#include <linux/types.h>
+#include <linux/gpio.h>
struct platform_device; /* don't need the contents */
-#include <linux/gpio.h>
#include <plat/gpio-cfg.h>
#include <plat/iic.h>
-void s3c_i2c0_cfg_gpio(struct platform_device *dev)
+#include <mach/i2c.h>
+
+void s5p6440_i2c0_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgpin(S5P6440_GPB(5), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5P6440_GPB(5), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S5P6440_GPB(6), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5P6440_GPB(6), S3C_GPIO_PULL_UP);
}
+
+void s5p6450_i2c0_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgpin(S5P6450_GPB(5), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(S5P6450_GPB(5), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(S5P6450_GPB(6), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(S5P6450_GPB(6), S3C_GPIO_PULL_UP);
+}
+
+void s3c_i2c0_cfg_gpio(struct platform_device *dev) { }
diff --git a/arch/arm/mach-s5p6440/setup-i2c1.c b/arch/arm/mach-s5p64x0/setup-i2c1.c
index 9a1537f786e0..2edd7912f8e4 100644
--- a/arch/arm/mach-s5p6440/setup-i2c1.c
+++ b/arch/arm/mach-s5p64x0/setup-i2c1.c
@@ -1,7 +1,7 @@
-/* linux/arch/arm/mach-s5p6440/setup-i2c1.c
+/* linux/arch/arm/mach-s5p64xx/setup-i2c1.c
*
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
*
* I2C1 GPIO configuration.
*
@@ -21,10 +21,22 @@ struct platform_device; /* don't need the contents */
#include <plat/gpio-cfg.h>
#include <plat/iic.h>
-void s3c_i2c1_cfg_gpio(struct platform_device *dev)
+#include <mach/i2c.h>
+
+void s5p6440_i2c1_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgpin(S5P6440_GPR(9), S3C_GPIO_SFN(6));
s3c_gpio_setpull(S5P6440_GPR(9), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S5P6440_GPR(10), S3C_GPIO_SFN(6));
s3c_gpio_setpull(S5P6440_GPR(10), S3C_GPIO_PULL_UP);
}
+
+void s5p6450_i2c1_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgpin(S5P6450_GPR(9), S3C_GPIO_SFN(6));
+ s3c_gpio_setpull(S5P6450_GPR(9), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(S5P6450_GPR(10), S3C_GPIO_SFN(6));
+ s3c_gpio_setpull(S5P6450_GPR(10), S3C_GPIO_PULL_UP);
+}
+
+void s3c_i2c1_cfg_gpio(struct platform_device *dev) { }
diff --git a/arch/arm/mach-s5pc100/cpu.c b/arch/arm/mach-s5pc100/cpu.c
index 251c92ac5b22..fd2708e7d8a9 100644
--- a/arch/arm/mach-s5pc100/cpu.c
+++ b/arch/arm/mach-s5pc100/cpu.c
@@ -1,5 +1,8 @@
/* linux/arch/arm/mach-s5pc100/cpu.c
*
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
* Copyright 2009 Samsung Electronics Co.
* Byungho Min <bhmin@samsung.com>
*
@@ -21,6 +24,7 @@
#include <linux/sysdev.h>
#include <linux/serial_core.h>
#include <linux/platform_device.h>
+#include <linux/sched.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -56,11 +60,31 @@ static struct map_desc s5pc100_iodesc[] __initdata = {
.length = SZ_16K,
.type = MT_DEVICE,
}, {
+ .virtual = (unsigned long)S5P_VA_GPIO,
+ .pfn = __phys_to_pfn(S5PC100_PA_GPIO),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC0,
+ .pfn = __phys_to_pfn(S5PC100_PA_VIC0),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC1,
+ .pfn = __phys_to_pfn(S5PC100_PA_VIC1),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
.virtual = (unsigned long)VA_VIC2,
- .pfn = __phys_to_pfn(S5P_PA_VIC2),
+ .pfn = __phys_to_pfn(S5PC100_PA_VIC2),
.length = SZ_16K,
.type = MT_DEVICE,
}, {
+ .virtual = (unsigned long)S3C_VA_UART,
+ .pfn = __phys_to_pfn(S3C_PA_UART),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
.virtual = (unsigned long)S5PC100_VA_OTHERS,
.pfn = __phys_to_pfn(S5PC100_PA_OTHERS),
.length = SZ_4K,
diff --git a/arch/arm/mach-s5pc100/include/mach/debug-macro.S b/arch/arm/mach-s5pc100/include/mach/debug-macro.S
index 70e02e91ee3c..b2ba95ddf8e0 100644
--- a/arch/arm/mach-s5pc100/include/mach/debug-macro.S
+++ b/arch/arm/mach-s5pc100/include/mach/debug-macro.S
@@ -22,13 +22,12 @@
* aligned and add in the offset when we load the value here.
*/
- .macro addruart, rx, rtmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1
- ldreq \rx, = S3C_PA_UART
- ldrne \rx, = S3C_VA_UART
+ .macro addruart, rp, rv
+ ldr \rp, = S3C_PA_UART
+ ldr \rv, = S3C_VA_UART
#if CONFIG_DEBUG_S3C_UART != 0
- add \rx, \rx, #(0x400 * CONFIG_DEBUG_S3C_UART)
+ add \rp, \rp, #(0x400 * CONFIG_DEBUG_S3C_UART)
+ add \rv, \rv, #(0x400 * CONFIG_DEBUG_S3C_UART)
#endif
.endm
diff --git a/arch/arm/mach-s5pc100/include/mach/map.h b/arch/arm/mach-s5pc100/include/mach/map.h
index 01b9134feff0..8751ef4a6804 100644
--- a/arch/arm/mach-s5pc100/include/mach/map.h
+++ b/arch/arm/mach-s5pc100/include/mach/map.h
@@ -44,19 +44,16 @@
#define S5PC100_PA_OTHERS (0xE0200000)
#define S5PC100_VA_OTHERS (S3C_VA_SYS + 0x10000)
-#define S5P_PA_GPIO (0xE0300000)
+#define S5PC100_PA_GPIO (0xE0300000)
#define S5PC1XX_VA_GPIO S3C_ADDR(0x00500000)
/* Interrupt */
-#define S5PC100_PA_VIC (0xE4000000)
+#define S5PC100_PA_VIC0 (0xE4000000)
+#define S5PC100_PA_VIC1 (0xE4100000)
+#define S5PC100_PA_VIC2 (0xE4200000)
#define S5PC100_VA_VIC S3C_VA_IRQ
-#define S5PC100_PA_VIC_OFFSET 0x100000
#define S5PC100_VA_VIC_OFFSET 0x10000
-#define S5PC1XX_PA_VIC(x) (S5PC100_PA_VIC + ((x) * S5PC100_PA_VIC_OFFSET))
#define S5PC1XX_VA_VIC(x) (S5PC100_VA_VIC + ((x) * S5PC100_VA_VIC_OFFSET))
-#define S5P_PA_VIC0 S5PC1XX_PA_VIC(0)
-#define S5P_PA_VIC1 S5PC1XX_PA_VIC(1)
-#define S5P_PA_VIC2 S5PC1XX_PA_VIC(2)
#define S5PC100_PA_ONENAND (0xE7100000)
diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c
index 020c3f98f81f..880fb075092c 100644
--- a/arch/arm/mach-s5pc100/mach-smdkc100.c
+++ b/arch/arm/mach-s5pc100/mach-smdkc100.c
@@ -235,8 +235,6 @@ static void __init smdkc100_machine_init(void)
MACHINE_START(SMDKC100, "SMDKC100")
/* Maintainer: Byungho Min <bhmin@samsung.com> */
- .phys_io = S3C_PA_UART & 0xfff00000,
- .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
.boot_params = S5P_PA_SDRAM + 0x100,
.init_irq = s5pc100_init_irq,
.map_io = smdkc100_map_io,
diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index d3a38955c741..5315fec3db86 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -53,11 +53,6 @@ config S5PV210_SETUP_SDHCI_GPIO
help
Common setup code for SDHCI gpio.
-config S5PC110_DEV_ONENAND
- bool
- help
- Compile in platform device definition for OneNAND1 controller
-
menu "S5PC110 Machines"
config MACH_AQUILA
@@ -71,7 +66,7 @@ config MACH_AQUILA
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_HSMMC2
- select S5PC110_DEV_ONENAND
+ select S5P_DEV_ONENAND
select S5PV210_SETUP_FB_24BPP
select S5PV210_SETUP_SDHCI
help
@@ -88,7 +83,7 @@ config MACH_GONI
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_HSMMC2
- select S5PC110_DEV_ONENAND
+ select S5P_DEV_ONENAND
select S5PV210_SETUP_FB_24BPP
select S5PV210_SETUP_SDHCI
help
diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile
index 05048c5aa4c6..704548912408 100644
--- a/arch/arm/mach-s5pv210/Makefile
+++ b/arch/arm/mach-s5pv210/Makefile
@@ -26,7 +26,6 @@ obj-$(CONFIG_MACH_GONI) += mach-goni.o
obj-y += dev-audio.o
obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o
-obj-$(CONFIG_S5PC110_DEV_ONENAND) += dev-onenand.o
obj-$(CONFIG_S5PV210_SETUP_FB_24BPP) += setup-fb-24bpp.o
obj-$(CONFIG_S5PV210_SETUP_I2C1) += setup-i2c1.o
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c
index cfecd70657cb..d562670e1b0b 100644
--- a/arch/arm/mach-s5pv210/clock.c
+++ b/arch/arm/mach-s5pv210/clock.c
@@ -173,11 +173,6 @@ static int s5pv210_clk_ip3_ctrl(struct clk *clk, int enable)
return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable);
}
-static int s5pv210_clk_ip4_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(S5P_CLKGATE_IP4, clk, enable);
-}
-
static int s5pv210_clk_mask0_ctrl(struct clk *clk, int enable)
{
return s5p_gatectrl(S5P_CLK_SRC_MASK0, clk, enable);
diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c
index 77f456c91ad3..2f16bfc0a116 100644
--- a/arch/arm/mach-s5pv210/cpu.c
+++ b/arch/arm/mach-s5pv210/cpu.c
@@ -1,7 +1,7 @@
/* linux/arch/arm/mach-s5pv210/cpu.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
+ * http://www.samsung.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -19,6 +19,7 @@
#include <linux/io.h>
#include <linux/sysdev.h>
#include <linux/platform_device.h>
+#include <linux/sched.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -50,6 +51,21 @@ static struct map_desc s5pv210_iodesc[] __initdata = {
.length = SZ_4K,
.type = MT_DEVICE,
}, {
+ .virtual = (unsigned long)S5P_VA_GPIO,
+ .pfn = __phys_to_pfn(S5PV210_PA_GPIO),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC0,
+ .pfn = __phys_to_pfn(S5PV210_PA_VIC0),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC1,
+ .pfn = __phys_to_pfn(S5PV210_PA_VIC1),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
.virtual = (unsigned long)VA_VIC2,
.pfn = __phys_to_pfn(S5PV210_PA_VIC2),
.length = SZ_16K,
@@ -60,6 +76,11 @@ static struct map_desc s5pv210_iodesc[] __initdata = {
.length = SZ_16K,
.type = MT_DEVICE,
}, {
+ .virtual = (unsigned long)S3C_VA_UART,
+ .pfn = __phys_to_pfn(S3C_PA_UART),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
.virtual = (unsigned long)S5P_VA_SROMC,
.pfn = __phys_to_pfn(S5PV210_PA_SROMC),
.length = SZ_4K,
diff --git a/arch/arm/mach-s5pv210/include/mach/debug-macro.S b/arch/arm/mach-s5pv210/include/mach/debug-macro.S
index 7872f5c3dfc2..169fe654a59e 100644
--- a/arch/arm/mach-s5pv210/include/mach/debug-macro.S
+++ b/arch/arm/mach-s5pv210/include/mach/debug-macro.S
@@ -21,13 +21,12 @@
* aligned and add in the offset when we load the value here.
*/
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1
- ldreq \rx, = S3C_PA_UART
- ldrne \rx, = S3C_VA_UART
+ .macro addruart, rp, rv
+ ldr \rp, = S3C_PA_UART
+ ldr \rv, = S3C_VA_UART
#if CONFIG_DEBUG_S3C_UART != 0
- add \rx, \rx, #(0x400 * CONFIG_DEBUG_S3C_UART)
+ add \rp, \rp, #(0x400 * CONFIG_DEBUG_S3C_UART)
+ add \rv, \rv, #(0x400 * CONFIG_DEBUG_S3C_UART)
#endif
.endm
diff --git a/arch/arm/mach-s5pv210/include/mach/map.h b/arch/arm/mach-s5pv210/include/mach/map.h
index dd4fb6bf14b5..bd9afd52466a 100644
--- a/arch/arm/mach-s5pv210/include/mach/map.h
+++ b/arch/arm/mach-s5pv210/include/mach/map.h
@@ -17,7 +17,10 @@
#include <plat/map-s5p.h>
#define S5PC110_PA_ONENAND (0xB0000000)
+#define S5P_PA_ONENAND S5PC110_PA_ONENAND
+
#define S5PC110_PA_ONENAND_DMA (0xB0600000)
+#define S5P_PA_ONENAND_DMA S5PC110_PA_ONENAND_DMA
#define S5PV210_PA_CHIPID (0xE0000000)
#define S5P_PA_CHIPID S5PV210_PA_CHIPID
@@ -26,7 +29,6 @@
#define S5P_PA_SYSCON S5PV210_PA_SYSCON
#define S5PV210_PA_GPIO (0xE0200000)
-#define S5P_PA_GPIO S5PV210_PA_GPIO
/* SPI */
#define S5PV210_PA_SPI0 0xE1300000
@@ -72,16 +74,9 @@
#define S5PV210_PA_HSMMC(x) (0xEB000000 + ((x) * 0x100000))
#define S5PV210_PA_VIC0 (0xF2000000)
-#define S5P_PA_VIC0 S5PV210_PA_VIC0
-
#define S5PV210_PA_VIC1 (0xF2100000)
-#define S5P_PA_VIC1 S5PV210_PA_VIC1
-
#define S5PV210_PA_VIC2 (0xF2200000)
-#define S5P_PA_VIC2 S5PV210_PA_VIC2
-
#define S5PV210_PA_VIC3 (0xF2300000)
-#define S5P_PA_VIC3 S5PV210_PA_VIC3
#define S5PV210_PA_SDRAM (0x20000000)
#define S5P_PA_SDRAM S5PV210_PA_SDRAM
diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c
index 0dda8012d6b2..00883087363c 100644
--- a/arch/arm/mach-s5pv210/mach-aquila.c
+++ b/arch/arm/mach-s5pv210/mach-aquila.c
@@ -477,7 +477,7 @@ static struct platform_device *aquila_devices[] __initdata = {
&aquila_i2c_gpio_pmic,
&aquila_device_gpiokeys,
&s3c_device_fb,
- &s5pc110_device_onenand,
+ &s5p_device_onenand,
&s3c_device_hsmmc0,
&s3c_device_hsmmc1,
&s3c_device_hsmmc2,
@@ -516,8 +516,6 @@ MACHINE_START(AQUILA, "Aquila")
/* Maintainers:
Marek Szyprowski <m.szyprowski@samsung.com>
Kyungmin Park <kyungmin.park@samsung.com> */
- .phys_io = S3C_PA_UART & 0xfff00000,
- .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
.boot_params = S5P_PA_SDRAM + 0x100,
.init_irq = s5pv210_init_irq,
.map_io = aquila_map_io,
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
index 53754d7d364e..d9ecf57fc2a5 100644
--- a/arch/arm/mach-s5pv210/mach-goni.c
+++ b/arch/arm/mach-s5pv210/mach-goni.c
@@ -456,7 +456,7 @@ static void goni_setup_sdhci(void)
static struct platform_device *goni_devices[] __initdata = {
&s3c_device_fb,
- &s5pc110_device_onenand,
+ &s5p_device_onenand,
&goni_i2c_gpio_pmic,
&goni_device_gpiokeys,
&s5p_device_fimc0,
@@ -491,8 +491,6 @@ static void __init goni_machine_init(void)
MACHINE_START(GONI, "GONI")
/* Maintainers: Kyungmin Park <kyungmin.park@samsung.com> */
- .phys_io = S3C_PA_UART & 0xfff00000,
- .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
.boot_params = S5P_PA_SDRAM + 0x100,
.init_irq = s5pv210_init_irq,
.map_io = goni_map_io,
diff --git a/arch/arm/mach-s5pv210/mach-smdkc110.c b/arch/arm/mach-s5pv210/mach-smdkc110.c
index 8211bb87c54b..cea9bca79d88 100644
--- a/arch/arm/mach-s5pv210/mach-smdkc110.c
+++ b/arch/arm/mach-s5pv210/mach-smdkc110.c
@@ -127,8 +127,6 @@ static void __init smdkc110_machine_init(void)
MACHINE_START(SMDKC110, "SMDKC110")
/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
- .phys_io = S3C_PA_UART & 0xfff00000,
- .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
.boot_params = S5P_PA_SDRAM + 0x100,
.init_irq = s5pv210_init_irq,
.map_io = smdkc110_map_io,
diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c
index fbbc0a3c3738..83189ae9da9a 100644
--- a/arch/arm/mach-s5pv210/mach-smdkv210.c
+++ b/arch/arm/mach-s5pv210/mach-smdkv210.c
@@ -165,8 +165,6 @@ static void __init smdkv210_machine_init(void)
MACHINE_START(SMDKV210, "SMDKV210")
/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
- .phys_io = S3C_PA_UART & 0xfff00000,
- .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
.boot_params = S5P_PA_SDRAM + 0x100,
.init_irq = s5pv210_init_irq,
.map_io = smdkv210_map_io,
diff --git a/arch/arm/mach-s5pv310/cpu.c b/arch/arm/mach-s5pv310/cpu.c
index e5b261a99ab2..4add39853ff9 100644
--- a/arch/arm/mach-s5pv310/cpu.c
+++ b/arch/arm/mach-s5pv310/cpu.c
@@ -31,9 +31,14 @@ extern void combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq);
/* Initial IO mappings */
static struct map_desc s5pv310_iodesc[] __initdata = {
{
- .virtual = (unsigned long)S5P_VA_COREPERI_BASE,
- .pfn = __phys_to_pfn(S5PV310_PA_COREPERI),
- .length = SZ_8K,
+ .virtual = (unsigned long)S5P_VA_SYSRAM,
+ .pfn = __phys_to_pfn(S5PV310_PA_SYSRAM),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_CMU,
+ .pfn = __phys_to_pfn(S5PV310_PA_CMU),
+ .length = SZ_128K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S5P_VA_COMBINER_BASE,
@@ -41,19 +46,24 @@ static struct map_desc s5pv310_iodesc[] __initdata = {
.length = SZ_4K,
.type = MT_DEVICE,
}, {
+ .virtual = (unsigned long)S5P_VA_COREPERI_BASE,
+ .pfn = __phys_to_pfn(S5PV310_PA_COREPERI),
+ .length = SZ_8K,
+ .type = MT_DEVICE,
+ }, {
.virtual = (unsigned long)S5P_VA_L2CC,
.pfn = __phys_to_pfn(S5PV310_PA_L2CC),
.length = SZ_4K,
.type = MT_DEVICE,
}, {
- .virtual = (unsigned long)S5P_VA_SYSRAM,
- .pfn = __phys_to_pfn(S5PV310_PA_SYSRAM),
+ .virtual = (unsigned long)S5P_VA_GPIO,
+ .pfn = __phys_to_pfn(S5PV310_PA_GPIO1),
.length = SZ_4K,
.type = MT_DEVICE,
}, {
- .virtual = (unsigned long)S5P_VA_CMU,
- .pfn = __phys_to_pfn(S5PV310_PA_CMU),
- .length = SZ_128K,
+ .virtual = (unsigned long)S3C_VA_UART,
+ .pfn = __phys_to_pfn(S3C_PA_UART),
+ .length = SZ_512K,
.type = MT_DEVICE,
},
};
diff --git a/arch/arm/mach-s5pv310/include/mach/debug-macro.S b/arch/arm/mach-s5pv310/include/mach/debug-macro.S
index 6fb3893486be..b0d920c474d3 100644
--- a/arch/arm/mach-s5pv310/include/mach/debug-macro.S
+++ b/arch/arm/mach-s5pv310/include/mach/debug-macro.S
@@ -20,13 +20,12 @@
* aligned and add in the offset when we load the value here.
*/
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1
- ldreq \rx, = S3C_PA_UART
- ldrne \rx, = S3C_VA_UART
+ .macro addruart, rp, rv
+ ldreq \rp, = S3C_PA_UART
+ ldrne \rv, = S3C_VA_UART
#if CONFIG_DEBUG_S3C_UART != 0
- add \rx, \rx, #(0x10000 * CONFIG_DEBUG_S3C_UART)
+ add \rp, \rp, #(0x10000 * CONFIG_DEBUG_S3C_UART)
+ add \rv, \rv, #(0x10000 * CONFIG_DEBUG_S3C_UART)
#endif
.endm
diff --git a/arch/arm/mach-s5pv310/include/mach/irqs.h b/arch/arm/mach-s5pv310/include/mach/irqs.h
index 4cdedda6e652..471fc3bb199a 100644
--- a/arch/arm/mach-s5pv310/include/mach/irqs.h
+++ b/arch/arm/mach-s5pv310/include/mach/irqs.h
@@ -68,6 +68,8 @@
#define IRQ_IIC COMBINER_IRQ(27, 0)
+#define IRQ_ONENAND_AUDI COMBINER_IRQ(34, 0)
+
/* Set the default NR_IRQS */
#define NR_IRQS COMBINER_IRQ(MAX_COMBINER_NR, 0)
diff --git a/arch/arm/mach-s5pv310/include/mach/map.h b/arch/arm/mach-s5pv310/include/mach/map.h
index 213e1101a3b3..aff6d23624bb 100644
--- a/arch/arm/mach-s5pv310/include/mach/map.h
+++ b/arch/arm/mach-s5pv310/include/mach/map.h
@@ -25,6 +25,12 @@
#define S5PV310_PA_SYSRAM (0x02025000)
+#define S5PC210_PA_ONENAND (0x0C000000)
+#define S5P_PA_ONENAND S5PC210_PA_ONENAND
+
+#define S5PC210_PA_ONENAND_DMA (0x0C600000)
+#define S5P_PA_ONENAND_DMA S5PC210_PA_ONENAND_DMA
+
#define S5PV310_PA_CHIPID (0x10000000)
#define S5P_PA_CHIPID S5PV310_PA_CHIPID
@@ -46,7 +52,6 @@
#define S5PV310_PA_GPIO1 (0x11400000)
#define S5PV310_PA_GPIO2 (0x11000000)
#define S5PV310_PA_GPIO3 (0x03860000)
-#define S5P_PA_GPIO S5PV310_PA_GPIO1
#define S5PV310_PA_HSMMC(x) (0x12510000 + ((x) * 0x10000))
diff --git a/arch/arm/mach-s5pv310/include/mach/smp.h b/arch/arm/mach-s5pv310/include/mach/smp.h
index 990f3ba88a1f..b7ec252384f4 100644
--- a/arch/arm/mach-s5pv310/include/mach/smp.h
+++ b/arch/arm/mach-s5pv310/include/mach/smp.h
@@ -7,17 +7,10 @@
#define ASM_ARCH_SMP_H __FILE__
#include <asm/hardware/gic.h>
+#include <asm/smp_mpidr.h>
extern void __iomem *gic_cpu_base_addr;
-#define hard_smp_processor_id() \
- ({ \
- unsigned int cpunum; \
- __asm__("mrc p15, 0, %0, c0, c0, 5" \
- : "=r" (cpunum)); \
- cpunum &= 0x03; \
- })
-
/*
* We use IRQ1 as the IPI
*/
diff --git a/arch/arm/mach-s5pv310/mach-smdkv310.c b/arch/arm/mach-s5pv310/mach-smdkv310.c
index 0d6ab77709d2..46215a14b3bb 100644
--- a/arch/arm/mach-s5pv310/mach-smdkv310.c
+++ b/arch/arm/mach-s5pv310/mach-smdkv310.c
@@ -82,8 +82,6 @@ static void __init smdkv310_machine_init(void)
MACHINE_START(SMDKV310, "SMDKV310")
/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
/* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */
- .phys_io = S3C_PA_UART & 0xfff00000,
- .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
.boot_params = S5P_PA_SDRAM + 0x100,
.init_irq = s5pv310_init_irq,
.map_io = smdkv310_map_io,
diff --git a/arch/arm/mach-s5pv310/mach-universal_c210.c b/arch/arm/mach-s5pv310/mach-universal_c210.c
index 2388cb947936..d7c2ec770f88 100644
--- a/arch/arm/mach-s5pv310/mach-universal_c210.c
+++ b/arch/arm/mach-s5pv310/mach-universal_c210.c
@@ -76,8 +76,6 @@ static void __init universal_machine_init(void)
MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210")
/* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
- .phys_io = S3C_PA_UART & 0xfff00000,
- .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
.boot_params = S5P_PA_SDRAM + 0x100,
.init_irq = s5pv310_init_irq,
.map_io = universal_map_io,
diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig
index fd4c52b7ccb6..5da8c35aa0de 100644
--- a/arch/arm/mach-sa1100/Kconfig
+++ b/arch/arm/mach-sa1100/Kconfig
@@ -90,8 +90,8 @@ config SA1100_JORNADA720
# FIXME: select CPU_FREQ_SA11x0
help
Say Y here if you want to build a kernel for the HP Jornada 720
- handheld computer. See <http://www.hp.com/jornada/products/720>
- for details.
+ handheld computer. See
+ <http://h10025.www1.hp.com/ewfrf/wc/product?product=61677&cc=us&lc=en&dlc=en&product=61677#>
config SA1100_JORNADA720_SSP
bool "HP Jornada 720 Extended SSP driver"
@@ -145,7 +145,7 @@ config SA1100_SIMPAD
FLASH. The SL4 version got 64 MB RAM and 32 MB FLASH and a
PCMCIA-Slot. The version for the Germany Telecom (DTAG) is the same
like CL4 in additional it has a PCMCIA-Slot. For more information
- visit <http://www.my-siemens.com/> or <http://www.siemens.ch/>.
+ visit <http://www.usa.siemens.com/> or <http://www.siemens.ch/>.
config SA1100_SSP
tristate "Generic PIO SSP"
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index 169e5b87dbff..5778274a8260 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -447,8 +447,6 @@ static void __init assabet_map_io(void)
MACHINE_START(ASSABET, "Intel-Assabet")
- .phys_io = 0x80000000,
- .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
.boot_params = 0xc0000100,
.fixup = fixup_assabet,
.map_io = assabet_map_io,
diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c
index 259cb2c15fff..4f19ff868b00 100644
--- a/arch/arm/mach-sa1100/badge4.c
+++ b/arch/arm/mach-sa1100/badge4.c
@@ -302,8 +302,6 @@ static void __init badge4_map_io(void)
}
MACHINE_START(BADGE4, "Hewlett-Packard Laboratories BadgePAD 4")
- .phys_io = 0x80000000,
- .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
.boot_params = 0xc0000100,
.map_io = badge4_map_io,
.init_irq = sa1100_init_irq,
diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c
index bc950ef418af..98d780608c7e 100644
--- a/arch/arm/mach-sa1100/cerf.c
+++ b/arch/arm/mach-sa1100/cerf.c
@@ -135,8 +135,6 @@ static void __init cerf_init(void)
MACHINE_START(CERF, "Intrinsyc CerfBoard/CerfCube")
/* Maintainer: support@intrinsyc.com */
- .phys_io = 0x80000000,
- .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
.map_io = cerf_map_io,
.init_irq = cerf_init_irq,
.timer = &sa1100_timer,
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index 16e682d5dbb7..d43c5ef58eb6 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -379,8 +379,6 @@ static void __init collie_map_io(void)
}
MACHINE_START(COLLIE, "Sharp-Collie")
- .phys_io = 0x80000000,
- .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
.map_io = collie_map_io,
.init_irq = sa1100_init_irq,
.timer = &sa1100_timer,
diff --git a/arch/arm/mach-sa1100/cpu-sa1100.c b/arch/arm/mach-sa1100/cpu-sa1100.c
index ef817876a5d6..c0a13ef5436f 100644
--- a/arch/arm/mach-sa1100/cpu-sa1100.c
+++ b/arch/arm/mach-sa1100/cpu-sa1100.c
@@ -13,7 +13,7 @@
* This software has been developed while working on the LART
* computing board (http://www.lartmaker.nl/), which is
* sponsored by the Mobile Multi-media Communications
- * (http://www.mmc.tudelft.nl/) and Ubiquitous Communications
+ * (http://www.mobimedia.org/) and Ubiquitous Communications
* (http://www.ubicom.tudelft.nl/) projects.
*
* The authors can be reached at:
diff --git a/arch/arm/mach-sa1100/h3100.c b/arch/arm/mach-sa1100/h3100.c
index 0c7cea0dc013..03d7376cf8a0 100644
--- a/arch/arm/mach-sa1100/h3100.c
+++ b/arch/arm/mach-sa1100/h3100.c
@@ -84,8 +84,6 @@ static void __init h3100_mach_init(void)
}
MACHINE_START(H3100, "Compaq iPAQ H3100")
- .phys_io = 0x80000000,
- .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
.boot_params = 0xc0000100,
.map_io = h3100_map_io,
.init_irq = sa1100_init_irq,
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
index af3b71459f8d..965f64a836f8 100644
--- a/arch/arm/mach-sa1100/h3600.c
+++ b/arch/arm/mach-sa1100/h3600.c
@@ -125,8 +125,6 @@ static void __init h3600_mach_init(void)
}
MACHINE_START(H3600, "Compaq iPAQ H3600")
- .phys_io = 0x80000000,
- .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
.boot_params = 0xc0000100,
.map_io = h3600_map_io,
.init_irq = sa1100_init_irq,
diff --git a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c
index 51568dfc8e97..db5e434a17db 100644
--- a/arch/arm/mach-sa1100/hackkit.c
+++ b/arch/arm/mach-sa1100/hackkit.c
@@ -195,8 +195,6 @@ static void __init hackkit_init(void)
*/
MACHINE_START(HACKKIT, "HackKit Cpu Board")
- .phys_io = 0x80000000,
- .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
.boot_params = 0xc0000100,
.map_io = hackkit_map_io,
.init_irq = sa1100_init_irq,
diff --git a/arch/arm/mach-sa1100/include/mach/debug-macro.S b/arch/arm/mach-sa1100/include/mach/debug-macro.S
index 336adccea542..0cd0fc9635b6 100644
--- a/arch/arm/mach-sa1100/include/mach/debug-macro.S
+++ b/arch/arm/mach-sa1100/include/mach/debug-macro.S
@@ -12,33 +12,37 @@
*/
#include <mach/hardware.h>
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- moveq \rx, #0x80000000 @ physical base address
- movne \rx, #0xf8000000 @ virtual address
+ .macro addruart, rp, rv
+ mrc p15, 0, \rp, c1, c0
+ tst \rp, #1 @ MMU enabled?
+ moveq \rp, #0x80000000 @ physical base address
+ movne \rp, #0xf8000000 @ virtual address
@ We probe for the active serial port here, coherently with
@ the comment in arch/arm/mach-sa1100/include/mach/uncompress.h.
@ We assume r1 can be clobbered.
@ see if Ser3 is active
- add \rx, \rx, #0x00050000
- ldr r1, [\rx, #UTCR3]
- tst r1, #UTCR3_TXE
+ add \rp, \rp, #0x00050000
+ ldr \rv, [\rp, #UTCR3]
+ tst \rv, #UTCR3_TXE
@ if Ser3 is inactive, then try Ser1
- addeq \rx, \rx, #(0x00010000 - 0x00050000)
- ldreq r1, [\rx, #UTCR3]
- tsteq r1, #UTCR3_TXE
+ addeq \rp, \rp, #(0x00010000 - 0x00050000)
+ ldreq \rv, [\rp, #UTCR3]
+ tsteq \rv, #UTCR3_TXE
@ if Ser1 is inactive, then try Ser2
- addeq \rx, \rx, #(0x00030000 - 0x00010000)
- ldreq r1, [\rx, #UTCR3]
- tsteq r1, #UTCR3_TXE
+ addeq \rp, \rp, #(0x00030000 - 0x00010000)
+ ldreq \rv, [\rp, #UTCR3]
+ tsteq \rv, #UTCR3_TXE
+
+ @ clear top bits, and generate both phys and virt addresses
+ lsl \rp, \rp, #8
+ lsr \rp, \rp, #8
+ orr \rv, \rp, #0xf8000000 @ virtual
+ orr \rp, \rp, #0x80000000 @ physical
- @ if all ports are inactive, then there is nothing we can do
- moveq pc, lr
.endm
.macro senduart,rd,rx
diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c
index d3ec620618f1..491ac9f20fb4 100644
--- a/arch/arm/mach-sa1100/jornada720.c
+++ b/arch/arm/mach-sa1100/jornada720.c
@@ -364,8 +364,6 @@ static void __init jornada720_mach_init(void)
MACHINE_START(JORNADA720, "HP Jornada 720")
/* Maintainer: Kristoffer Ericson <Kristoffer.Ericson@gmail.com> */
- .phys_io = 0x80000000,
- .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
.boot_params = 0xc0000100,
.map_io = jornada720_map_io,
.init_irq = sa1100_init_irq,
diff --git a/arch/arm/mach-sa1100/lart.c b/arch/arm/mach-sa1100/lart.c
index 68069d6dc07a..7b9556b59057 100644
--- a/arch/arm/mach-sa1100/lart.c
+++ b/arch/arm/mach-sa1100/lart.c
@@ -61,8 +61,6 @@ static void __init lart_map_io(void)
}
MACHINE_START(LART, "LART")
- .phys_io = 0x80000000,
- .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
.boot_params = 0xc0000100,
.map_io = lart_map_io,
.init_irq = sa1100_init_irq,
diff --git a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c
index 1ccd6018d3a3..42b80400c100 100644
--- a/arch/arm/mach-sa1100/pleb.c
+++ b/arch/arm/mach-sa1100/pleb.c
@@ -146,8 +146,6 @@ static void __init pleb_map_io(void)
}
MACHINE_START(PLEB, "PLEB")
- .phys_io = 0x80000000,
- .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
.map_io = pleb_map_io,
.init_irq = sa1100_init_irq,
.timer = &sa1100_timer,
diff --git a/arch/arm/mach-sa1100/shannon.c b/arch/arm/mach-sa1100/shannon.c
index 85e82bb73d7e..7917b2405579 100644
--- a/arch/arm/mach-sa1100/shannon.c
+++ b/arch/arm/mach-sa1100/shannon.c
@@ -82,8 +82,6 @@ static void __init shannon_map_io(void)
}
MACHINE_START(SHANNON, "Shannon (AKA: Tuxscreen)")
- .phys_io = 0x80000000,
- .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
.boot_params = 0xc0000100,
.map_io = shannon_map_io,
.init_irq = sa1100_init_irq,
diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
index 49cfd64663ac..27692d0ffbe8 100644
--- a/arch/arm/mach-sa1100/simpad.c
+++ b/arch/arm/mach-sa1100/simpad.c
@@ -228,8 +228,6 @@ arch_initcall(simpad_init);
MACHINE_START(SIMPAD, "Simpad")
/* Maintainer: Holger Freyther */
- .phys_io = 0x80000000,
- .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
.boot_params = 0xc0000100,
.map_io = simpad_map_io,
.init_irq = sa1100_init_irq,
diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c
index 358d875ace14..5cf7f94c1f31 100644
--- a/arch/arm/mach-shark/core.c
+++ b/arch/arm/mach-shark/core.c
@@ -152,8 +152,6 @@ static struct sys_timer shark_timer = {
MACHINE_START(SHARK, "Shark")
/* Maintainer: Alexander Schulz */
- .phys_io = 0x40000000,
- .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc,
.boot_params = 0x08003000,
.map_io = shark_map_io,
.init_irq = shark_init_irq,
diff --git a/arch/arm/mach-shark/include/mach/debug-macro.S b/arch/arm/mach-shark/include/mach/debug-macro.S
index 5ea24d4d1ba6..a473f55dc71f 100644
--- a/arch/arm/mach-shark/include/mach/debug-macro.S
+++ b/arch/arm/mach-shark/include/mach/debug-macro.S
@@ -11,9 +11,10 @@
*
*/
- .macro addruart, rx, tmp
- mov \rx, #0xe0000000
- orr \rx, \rx, #0x000003f8
+ .macro addruart, rp, rv
+ mov \rp, #0xe0000000
+ orr \rp, \rp, #0x000003f8
+ mov \rv, \rp
.endm
.macro senduart,rd,rx
diff --git a/arch/arm/mach-shark/include/mach/vmalloc.h b/arch/arm/mach-shark/include/mach/vmalloc.h
index f6c6837c5451..8e845b6a7cb5 100644
--- a/arch/arm/mach-shark/include/mach/vmalloc.h
+++ b/arch/arm/mach-shark/include/mach/vmalloc.h
@@ -1,4 +1,4 @@
/*
* arch/arm/mach-shark/include/mach/vmalloc.h
*/
-#define VMALLOC_END (PAGE_OFFSET + 0x10000000)
+#define VMALLOC_END 0xd0000000
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index 95935c83c306..14923989ea05 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -1105,8 +1105,6 @@ static struct sys_timer ap4evb_timer = {
};
MACHINE_START(AP4EVB, "ap4evb")
- .phys_io = 0xe6000000,
- .io_pg_offst = ((0xe6000000) >> 18) & 0xfffc,
.map_io = ap4evb_map_io,
.init_irq = sh7372_init_irq,
.init_machine = ap4evb_init,
diff --git a/arch/arm/mach-shmobile/board-g3evm.c b/arch/arm/mach-shmobile/board-g3evm.c
index a5525901e91f..3b83d6320bec 100644
--- a/arch/arm/mach-shmobile/board-g3evm.c
+++ b/arch/arm/mach-shmobile/board-g3evm.c
@@ -365,8 +365,6 @@ static struct sys_timer g3evm_timer = {
};
MACHINE_START(G3EVM, "g3evm")
- .phys_io = 0xe6000000,
- .io_pg_offst = ((0xe6000000) >> 18) & 0xfffc,
.map_io = g3evm_map_io,
.init_irq = sh7367_init_irq,
.init_machine = g3evm_init,
diff --git a/arch/arm/mach-shmobile/board-g4evm.c b/arch/arm/mach-shmobile/board-g4evm.c
index 2c3ff6f7f34c..5b3b582ef3f2 100644
--- a/arch/arm/mach-shmobile/board-g4evm.c
+++ b/arch/arm/mach-shmobile/board-g4evm.c
@@ -392,8 +392,6 @@ static struct sys_timer g4evm_timer = {
};
MACHINE_START(G4EVM, "g4evm")
- .phys_io = 0xe6000000,
- .io_pg_offst = ((0xe6000000) >> 18) & 0xfffc,
.map_io = g4evm_map_io,
.init_irq = sh7377_init_irq,
.init_machine = g4evm_init,
diff --git a/arch/arm/mach-stmp378x/stmp378x_devb.c b/arch/arm/mach-stmp378x/stmp378x_devb.c
index 90d8fe6f10fe..06158848afd9 100644
--- a/arch/arm/mach-stmp378x/stmp378x_devb.c
+++ b/arch/arm/mach-stmp378x/stmp378x_devb.c
@@ -324,8 +324,6 @@ static void __init stmp378x_devb_init(void)
}
MACHINE_START(STMP378X, "STMP378X")
- .phys_io = 0x80000000,
- .io_pg_offst = ((0xf0000000) >> 18) & 0xfffc,
.boot_params = 0x40000100,
.map_io = stmp378x_map_io,
.init_irq = stmp378x_init_irq,
diff --git a/arch/arm/mach-stmp37xx/stmp37xx_devb.c b/arch/arm/mach-stmp37xx/stmp37xx_devb.c
index 394f21ab59e6..311d8552d362 100644
--- a/arch/arm/mach-stmp37xx/stmp37xx_devb.c
+++ b/arch/arm/mach-stmp37xx/stmp37xx_devb.c
@@ -91,8 +91,6 @@ static void __init stmp37xx_devb_init(void)
}
MACHINE_START(STMP37XX, "STMP37XX")
- .phys_io = 0x80000000,
- .io_pg_offst = ((0xf0000000) >> 18) & 0xfffc,
.boot_params = 0x40000100,
.map_io = stmp37xx_map_io,
.init_irq = stmp37xx_init_irq,
diff --git a/arch/arm/mach-tcc8k/Kconfig b/arch/arm/mach-tcc8k/Kconfig
new file mode 100644
index 000000000000..ad86415d1577
--- /dev/null
+++ b/arch/arm/mach-tcc8k/Kconfig
@@ -0,0 +1,11 @@
+if ARCH_TCC8K
+
+comment "TCC8000 systems:"
+
+config MACH_TCC8000_SDK
+ bool "Telechips TCC8000-SDK development kit"
+ default y
+ help
+ Support for the Telechips TCC8000-SDK board.
+
+endif
diff --git a/arch/arm/mach-tcc8k/Makefile b/arch/arm/mach-tcc8k/Makefile
new file mode 100644
index 000000000000..9bacf31e49ba
--- /dev/null
+++ b/arch/arm/mach-tcc8k/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for TCC8K boards and common files.
+#
+
+# Common support
+obj-y += clock.o irq.o time.o io.o devices.o
+
+# Board specific support
+obj-$(CONFIG_MACH_TCC8000_SDK) += board-tcc8000-sdk.o
diff --git a/arch/arm/mach-tcc8k/Makefile.boot b/arch/arm/mach-tcc8k/Makefile.boot
new file mode 100644
index 000000000000..f135c9deae10
--- /dev/null
+++ b/arch/arm/mach-tcc8k/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0x20008000
+params_phys-y := 0x20000100
+initrd_phys-y := 0x20800000
diff --git a/arch/arm/mach-tcc8k/board-tcc8000-sdk.c b/arch/arm/mach-tcc8k/board-tcc8000-sdk.c
new file mode 100644
index 000000000000..7991415e666b
--- /dev/null
+++ b/arch/arm/mach-tcc8k/board-tcc8000-sdk.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+#include <mach/clock.h>
+
+#include "common.h"
+
+#define XI_FREQUENCY 12000000
+#define XTI_FREQUENCY 32768
+
+#ifdef CONFIG_MTD_NAND_TCC
+/* NAND */
+static struct tcc_nand_platform_data tcc8k_sdk_nand_data = {
+ .width = 1,
+ .hw_ecc = 0,
+};
+#endif
+
+static void __init tcc8k_init(void)
+{
+#ifdef CONFIG_MTD_NAND_TCC
+ tcc_nand_device.dev.platform_data = &tcc8k_sdk_nand_data;
+ platform_device_register(&tcc_nand_device);
+#endif
+}
+
+static void __init tcc8k_init_timer(void)
+{
+ tcc_clocks_init(XI_FREQUENCY, XTI_FREQUENCY);
+}
+
+static struct sys_timer tcc8k_timer = {
+ .init = tcc8k_init_timer,
+};
+
+static void __init tcc8k_map_io(void)
+{
+ tcc8k_map_common_io();
+}
+
+MACHINE_START(TCC8000_SDK, "Telechips TCC8000-SDK Demo Board")
+ .boot_params = PHYS_OFFSET + 0x00000100,
+ .map_io = tcc8k_map_io,
+ .init_irq = tcc8k_init_irq,
+ .init_machine = tcc8k_init,
+ .timer = &tcc8k_timer,
+MACHINE_END
diff --git a/arch/arm/mach-tcc8k/clock.c b/arch/arm/mach-tcc8k/clock.c
new file mode 100644
index 000000000000..ba32a15127ab
--- /dev/null
+++ b/arch/arm/mach-tcc8k/clock.c
@@ -0,0 +1,567 @@
+/*
+ * Lowlevel clock handling for Telechips TCC8xxx SoCs
+ *
+ * Copyright (C) 2010 by Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GPL v2
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+
+#include <asm/clkdev.h>
+
+#include <mach/clock.h>
+#include <mach/irqs.h>
+#include <mach/tcc8k-regs.h>
+
+#include "common.h"
+
+#define BCLKCTR0 (CKC_BASE + BCLKCTR0_OFFS)
+#define BCLKCTR1 (CKC_BASE + BCLKCTR1_OFFS)
+
+#define ACLKREF (CKC_BASE + ACLKREF_OFFS)
+#define ACLKUART0 (CKC_BASE + ACLKUART0_OFFS)
+#define ACLKUART1 (CKC_BASE + ACLKUART1_OFFS)
+#define ACLKUART2 (CKC_BASE + ACLKUART2_OFFS)
+#define ACLKUART3 (CKC_BASE + ACLKUART3_OFFS)
+#define ACLKUART4 (CKC_BASE + ACLKUART4_OFFS)
+#define ACLKI2C (CKC_BASE + ACLKI2C_OFFS)
+#define ACLKADC (CKC_BASE + ACLKADC_OFFS)
+#define ACLKUSBH (CKC_BASE + ACLKUSBH_OFFS)
+#define ACLKLCD (CKC_BASE + ACLKLCD_OFFS)
+#define ACLKSDH0 (CKC_BASE + ACLKSDH0_OFFS)
+#define ACLKSDH1 (CKC_BASE + ACLKSDH1_OFFS)
+#define ACLKSPI0 (CKC_BASE + ACLKSPI0_OFFS)
+#define ACLKSPI1 (CKC_BASE + ACLKSPI1_OFFS)
+#define ACLKSPDIF (CKC_BASE + ACLKSPDIF_OFFS)
+#define ACLKC3DEC (CKC_BASE + ACLKC3DEC_OFFS)
+#define ACLKCAN0 (CKC_BASE + ACLKCAN0_OFFS)
+#define ACLKCAN1 (CKC_BASE + ACLKCAN1_OFFS)
+#define ACLKGSB0 (CKC_BASE + ACLKGSB0_OFFS)
+#define ACLKGSB1 (CKC_BASE + ACLKGSB1_OFFS)
+#define ACLKGSB2 (CKC_BASE + ACLKGSB2_OFFS)
+#define ACLKGSB3 (CKC_BASE + ACLKGSB3_OFFS)
+#define ACLKUSBH (CKC_BASE + ACLKUSBH_OFFS)
+#define ACLKTCT (CKC_BASE + ACLKTCT_OFFS)
+#define ACLKTCX (CKC_BASE + ACLKTCX_OFFS)
+#define ACLKTCZ (CKC_BASE + ACLKTCZ_OFFS)
+
+/* Crystal frequencies */
+static unsigned long xi_rate, xti_rate;
+
+static void __iomem *pll_cfg_addr(int pll)
+{
+ switch (pll) {
+ case 0: return (CKC_BASE + PLL0CFG_OFFS);
+ case 1: return (CKC_BASE + PLL1CFG_OFFS);
+ case 2: return (CKC_BASE + PLL2CFG_OFFS);
+ default:
+ BUG();
+ }
+}
+
+static int pll_enable(int pll, int enable)
+{
+ u32 reg;
+ void __iomem *addr = pll_cfg_addr(pll);
+
+ reg = __raw_readl(addr);
+ if (enable)
+ reg &= ~PLLxCFG_PD;
+ else
+ reg |= PLLxCFG_PD;
+
+ __raw_writel(reg, addr);
+ return 0;
+}
+
+static int xi_enable(int enable)
+{
+ u32 reg;
+
+ reg = __raw_readl(CKC_BASE + CLKCTRL_OFFS);
+ if (enable)
+ reg |= CLKCTRL_XE;
+ else
+ reg &= ~CLKCTRL_XE;
+
+ __raw_writel(reg, CKC_BASE + CLKCTRL_OFFS);
+ return 0;
+}
+
+static int root_clk_enable(enum root_clks src)
+{
+ switch (src) {
+ case CLK_SRC_PLL0: return pll_enable(0, 1);
+ case CLK_SRC_PLL1: return pll_enable(1, 1);
+ case CLK_SRC_PLL2: return pll_enable(2, 1);
+ case CLK_SRC_XI: return xi_enable(1);
+ default:
+ BUG();
+ }
+ return 0;
+}
+
+static int root_clk_disable(enum root_clks root_src)
+{
+ switch (root_src) {
+ case CLK_SRC_PLL0: return pll_enable(0, 0);
+ case CLK_SRC_PLL1: return pll_enable(1, 0);
+ case CLK_SRC_PLL2: return pll_enable(2, 0);
+ case CLK_SRC_XI: return xi_enable(0);
+ default:
+ BUG();
+ }
+ return 0;
+}
+
+static int enable_clk(struct clk *clk)
+{
+ u32 reg;
+
+ if (clk->root_id != CLK_SRC_NOROOT)
+ return root_clk_enable(clk->root_id);
+
+ if (clk->aclkreg) {
+ reg = __raw_readl(clk->aclkreg);
+ reg |= ACLK_EN;
+ __raw_writel(reg, clk->aclkreg);
+ }
+ if (clk->bclkctr) {
+ reg = __raw_readl(clk->bclkctr);
+ reg |= 1 << clk->bclk_shift;
+ __raw_writel(reg, clk->bclkctr);
+ }
+ return 0;
+}
+
+static void disable_clk(struct clk *clk)
+{
+ u32 reg;
+
+ if (clk->root_id != CLK_SRC_NOROOT) {
+ root_clk_disable(clk->root_id);
+ return;
+ }
+
+ if (clk->bclkctr) {
+ reg = __raw_readl(clk->bclkctr);
+ reg &= ~(1 << clk->bclk_shift);
+ __raw_writel(reg, clk->bclkctr);
+ }
+ if (clk->aclkreg) {
+ reg = __raw_readl(clk->aclkreg);
+ reg &= ~ACLK_EN;
+ __raw_writel(reg, clk->aclkreg);
+ }
+}
+
+static unsigned long get_rate_pll(int pll)
+{
+ u32 reg;
+ unsigned long s, m, p;
+ void __iomem *addr = pll_cfg_addr(pll);
+
+ reg = __raw_readl(addr);
+ s = (reg >> 16) & 0x07;
+ m = (reg >> 8) & 0xff;
+ p = reg & 0x3f;
+
+ return (m * xi_rate) / (p * (1 << s));
+}
+
+static unsigned long get_rate_pll_div(int pll)
+{
+ u32 reg;
+ unsigned long div = 0;
+ void __iomem *addr;
+
+ switch (pll) {
+ case 0:
+ addr = CKC_BASE + CLKDIVC0_OFFS;
+ reg = __raw_readl(addr);
+ if (reg & CLKDIVC0_P0E)
+ div = (reg >> 24) & 0x3f;
+ break;
+ case 1:
+ addr = CKC_BASE + CLKDIVC0_OFFS;
+ reg = __raw_readl(addr);
+ if (reg & CLKDIVC0_P1E)
+ div = (reg >> 16) & 0x3f;
+ break;
+ case 2:
+ addr = CKC_BASE + CLKDIVC1_OFFS;
+ reg = __raw_readl(addr);
+ if (reg & CLKDIVC1_P2E)
+ div = __raw_readl(addr) & 0x3f;
+ break;
+ }
+ return get_rate_pll(pll) / (div + 1);
+}
+
+static unsigned long get_rate_xi_div(void)
+{
+ unsigned long div = 0;
+ u32 reg = __raw_readl(CKC_BASE + CLKDIVC0_OFFS);
+
+ if (reg & CLKDIVC0_XE)
+ div = (reg >> 8) & 0x3f;
+
+ return xi_rate / (div + 1);
+}
+
+static unsigned long get_rate_xti_div(void)
+{
+ unsigned long div = 0;
+ u32 reg = __raw_readl(CKC_BASE + CLKDIVC0_OFFS);
+
+ if (reg & CLKDIVC0_XTE)
+ div = reg & 0x3f;
+
+ return xti_rate / (div + 1);
+}
+
+static unsigned long root_clk_get_rate(enum root_clks src)
+{
+ switch (src) {
+ case CLK_SRC_PLL0: return get_rate_pll(0);
+ case CLK_SRC_PLL1: return get_rate_pll(1);
+ case CLK_SRC_PLL2: return get_rate_pll(2);
+ case CLK_SRC_PLL0DIV: return get_rate_pll_div(0);
+ case CLK_SRC_PLL1DIV: return get_rate_pll_div(1);
+ case CLK_SRC_PLL2DIV: return get_rate_pll_div(2);
+ case CLK_SRC_XI: return xi_rate;
+ case CLK_SRC_XTI: return xti_rate;
+ case CLK_SRC_XIDIV: return get_rate_xi_div();
+ case CLK_SRC_XTIDIV: return get_rate_xti_div();
+ default: return 0;
+ }
+}
+
+static unsigned long aclk_get_rate(struct clk *clk)
+{
+ u32 reg;
+ unsigned long div;
+ unsigned int src;
+
+ reg = __raw_readl(clk->aclkreg);
+ div = reg & 0x0fff;
+ src = (reg >> ACLK_SEL_SHIFT) & CLK_SRC_MASK;
+ return root_clk_get_rate(src) / (div + 1);
+}
+
+static unsigned long aclk_best_div(struct clk *clk, unsigned long rate)
+{
+ unsigned long div, src, freq, r1, r2;
+
+ src = __raw_readl(clk->aclkreg) >> ACLK_SEL_SHIFT;
+ src &= CLK_SRC_MASK;
+ freq = root_clk_get_rate(src);
+ div = freq / rate + 1;
+ r1 = freq / div;
+ r2 = freq / (div + 1);
+ if (r2 >= rate)
+ return div + 1;
+ if ((rate - r2) < (r1 - rate))
+ return div + 1;
+
+ return div;
+}
+
+static unsigned long aclk_round_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int src;
+
+ src = __raw_readl(clk->aclkreg) >> ACLK_SEL_SHIFT;
+ src &= CLK_SRC_MASK;
+
+ return root_clk_get_rate(src) / aclk_best_div(clk, rate);
+}
+
+static int aclk_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+
+ reg = __raw_readl(clk->aclkreg) & ~ACLK_DIV_MASK;
+ reg |= aclk_best_div(clk, rate);
+ return 0;
+}
+
+static unsigned long get_rate_sys(struct clk *clk)
+{
+ unsigned int src;
+
+ src = __raw_readl(CKC_BASE + CLKCTRL_OFFS) & CLK_SRC_MASK;
+ return root_clk_get_rate(src);
+}
+
+static unsigned long get_rate_bus(struct clk *clk)
+{
+ unsigned int div;
+
+ div = (__raw_readl(CKC_BASE + CLKCTRL_OFFS) >> 4) & 0xff;
+ return get_rate_sys(clk) / (div + 1);
+}
+
+static unsigned long get_rate_cpu(struct clk *clk)
+{
+ unsigned int reg, div, fsys, fbus;
+
+ fbus = get_rate_bus(clk);
+ reg = __raw_readl(CKC_BASE + CLKCTRL_OFFS);
+ if (reg & (1 << 29))
+ return fbus;
+ fsys = get_rate_sys(clk);
+ div = (reg >> 16) & 0x0f;
+ return fbus + ((fsys - fbus) * (div + 1)) / 16;
+}
+
+static unsigned long get_rate_root(struct clk *clk)
+{
+ return root_clk_get_rate(clk->root_id);
+}
+
+static int aclk_set_parent(struct clk *clock, struct clk *parent)
+{
+ u32 reg;
+
+ if (clock->parent == parent)
+ return 0;
+
+ clock->parent = parent;
+
+ if (!parent)
+ return 0;
+
+ if (parent->root_id == CLK_SRC_NOROOT)
+ return 0;
+ reg = __raw_readl(clock->aclkreg);
+ reg &= ~ACLK_SEL_MASK;
+ reg |= (parent->root_id << ACLK_SEL_SHIFT) & ACLK_SEL_MASK;
+ __raw_writel(reg, clock->aclkreg);
+
+ return 0;
+}
+
+#define DEFINE_ROOT_CLOCK(name, ri, p) \
+ static struct clk name = { \
+ .root_id = ri, \
+ .get_rate = get_rate_root, \
+ .enable = enable_clk, \
+ .disable = disable_clk, \
+ .parent = p, \
+ };
+
+#define DEFINE_SPECIAL_CLOCK(name, gr, p) \
+ static struct clk name = { \
+ .root_id = CLK_SRC_NOROOT, \
+ .get_rate = gr, \
+ .parent = p, \
+ };
+
+#define DEFINE_ACLOCK(name, bc, bs, ar) \
+ static struct clk name = { \
+ .root_id = CLK_SRC_NOROOT, \
+ .bclkctr = bc, \
+ .bclk_shift = bs, \
+ .aclkreg = ar, \
+ .get_rate = aclk_get_rate, \
+ .set_rate = aclk_set_rate, \
+ .round_rate = aclk_round_rate, \
+ .enable = enable_clk, \
+ .disable = disable_clk, \
+ .set_parent = aclk_set_parent, \
+ };
+
+#define DEFINE_BCLOCK(name, bc, bs, gr, p) \
+ static struct clk name = { \
+ .root_id = CLK_SRC_NOROOT, \
+ .bclkctr = bc, \
+ .bclk_shift = bs, \
+ .get_rate = gr, \
+ .enable = enable_clk, \
+ .disable = disable_clk, \
+ .parent = p, \
+ };
+
+DEFINE_ROOT_CLOCK(xi, CLK_SRC_XI, NULL)
+DEFINE_ROOT_CLOCK(xti, CLK_SRC_XTI, NULL)
+DEFINE_ROOT_CLOCK(xidiv, CLK_SRC_XIDIV, &xi)
+DEFINE_ROOT_CLOCK(xtidiv, CLK_SRC_XTIDIV, &xti)
+DEFINE_ROOT_CLOCK(pll0, CLK_SRC_PLL0, &xi)
+DEFINE_ROOT_CLOCK(pll1, CLK_SRC_PLL1, &xi)
+DEFINE_ROOT_CLOCK(pll2, CLK_SRC_PLL2, &xi)
+DEFINE_ROOT_CLOCK(pll0div, CLK_SRC_PLL0DIV, &pll0)
+DEFINE_ROOT_CLOCK(pll1div, CLK_SRC_PLL1DIV, &pll1)
+DEFINE_ROOT_CLOCK(pll2div, CLK_SRC_PLL2DIV, &pll2)
+
+/* The following 3 clocks are special and are initialized explicitly later */
+DEFINE_SPECIAL_CLOCK(sys, get_rate_sys, NULL)
+DEFINE_SPECIAL_CLOCK(bus, get_rate_bus, &sys)
+DEFINE_SPECIAL_CLOCK(cpu, get_rate_cpu, &sys)
+
+DEFINE_ACLOCK(tct, NULL, 0, ACLKTCT)
+DEFINE_ACLOCK(tcx, NULL, 0, ACLKTCX)
+DEFINE_ACLOCK(tcz, NULL, 0, ACLKTCZ)
+DEFINE_ACLOCK(ref, NULL, 0, ACLKREF)
+DEFINE_ACLOCK(uart0, BCLKCTR0, 5, ACLKUART0)
+DEFINE_ACLOCK(uart1, BCLKCTR0, 23, ACLKUART1)
+DEFINE_ACLOCK(uart2, BCLKCTR0, 6, ACLKUART2)
+DEFINE_ACLOCK(uart3, BCLKCTR0, 8, ACLKUART3)
+DEFINE_ACLOCK(uart4, BCLKCTR1, 6, ACLKUART4)
+DEFINE_ACLOCK(i2c, BCLKCTR0, 7, ACLKI2C)
+DEFINE_ACLOCK(adc, BCLKCTR0, 10, ACLKADC)
+DEFINE_ACLOCK(usbh0, BCLKCTR0, 11, ACLKUSBH)
+DEFINE_ACLOCK(lcd, BCLKCTR0, 13, ACLKLCD)
+DEFINE_ACLOCK(sd0, BCLKCTR0, 17, ACLKSDH0)
+DEFINE_ACLOCK(sd1, BCLKCTR1, 5, ACLKSDH1)
+DEFINE_ACLOCK(spi0, BCLKCTR0, 24, ACLKSPI0)
+DEFINE_ACLOCK(spi1, BCLKCTR0, 30, ACLKSPI1)
+DEFINE_ACLOCK(spdif, BCLKCTR1, 2, ACLKSPDIF)
+DEFINE_ACLOCK(c3dec, BCLKCTR1, 9, ACLKC3DEC)
+DEFINE_ACLOCK(can0, BCLKCTR1, 10, ACLKCAN0)
+DEFINE_ACLOCK(can1, BCLKCTR1, 11, ACLKCAN1)
+DEFINE_ACLOCK(gsb0, BCLKCTR1, 13, ACLKGSB0)
+DEFINE_ACLOCK(gsb1, BCLKCTR1, 14, ACLKGSB1)
+DEFINE_ACLOCK(gsb2, BCLKCTR1, 15, ACLKGSB2)
+DEFINE_ACLOCK(gsb3, BCLKCTR1, 16, ACLKGSB3)
+DEFINE_ACLOCK(usbh1, BCLKCTR1, 20, ACLKUSBH)
+
+DEFINE_BCLOCK(dai0, BCLKCTR0, 0, NULL, NULL)
+DEFINE_BCLOCK(pic, BCLKCTR0, 1, NULL, NULL)
+DEFINE_BCLOCK(tc, BCLKCTR0, 2, NULL, NULL)
+DEFINE_BCLOCK(gpio, BCLKCTR0, 3, NULL, NULL)
+DEFINE_BCLOCK(usbd, BCLKCTR0, 4, NULL, NULL)
+DEFINE_BCLOCK(ecc, BCLKCTR0, 9, NULL, NULL)
+DEFINE_BCLOCK(gdma0, BCLKCTR0, 12, NULL, NULL)
+DEFINE_BCLOCK(rtc, BCLKCTR0, 15, NULL, NULL)
+DEFINE_BCLOCK(nfc, BCLKCTR0, 16, NULL, NULL)
+DEFINE_BCLOCK(g2d, BCLKCTR0, 18, NULL, NULL)
+DEFINE_BCLOCK(gdma1, BCLKCTR0, 22, NULL, NULL)
+DEFINE_BCLOCK(mscl, BCLKCTR0, 25, NULL, NULL)
+DEFINE_BCLOCK(bdma, BCLKCTR1, 0, NULL, NULL)
+DEFINE_BCLOCK(adma0, BCLKCTR1, 1, NULL, NULL)
+DEFINE_BCLOCK(scfg, BCLKCTR1, 3, NULL, NULL)
+DEFINE_BCLOCK(cid, BCLKCTR1, 4, NULL, NULL)
+DEFINE_BCLOCK(dai1, BCLKCTR1, 7, NULL, NULL)
+DEFINE_BCLOCK(adma1, BCLKCTR1, 8, NULL, NULL)
+DEFINE_BCLOCK(gps, BCLKCTR1, 12, NULL, NULL)
+DEFINE_BCLOCK(gdma2, BCLKCTR1, 17, NULL, NULL)
+DEFINE_BCLOCK(gdma3, BCLKCTR1, 18, NULL, NULL)
+DEFINE_BCLOCK(ddrc, BCLKCTR1, 19, NULL, NULL)
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
+ },
+
+static struct clk_lookup lookups[] = {
+ _REGISTER_CLOCK(NULL, "bus", bus)
+ _REGISTER_CLOCK(NULL, "cpu", cpu)
+ _REGISTER_CLOCK(NULL, "tct", tct)
+ _REGISTER_CLOCK(NULL, "tcx", tcx)
+ _REGISTER_CLOCK(NULL, "tcz", tcz)
+ _REGISTER_CLOCK(NULL, "ref", ref)
+ _REGISTER_CLOCK(NULL, "dai0", dai0)
+ _REGISTER_CLOCK(NULL, "pic", pic)
+ _REGISTER_CLOCK(NULL, "tc", tc)
+ _REGISTER_CLOCK(NULL, "gpio", gpio)
+ _REGISTER_CLOCK(NULL, "usbd", usbd)
+ _REGISTER_CLOCK("tcc-uart.0", NULL, uart0)
+ _REGISTER_CLOCK("tcc-uart.2", NULL, uart2)
+ _REGISTER_CLOCK("tcc-i2c", NULL, i2c)
+ _REGISTER_CLOCK("tcc-uart.3", NULL, uart3)
+ _REGISTER_CLOCK(NULL, "ecc", ecc)
+ _REGISTER_CLOCK(NULL, "adc", adc)
+ _REGISTER_CLOCK("tcc-usbh.0", "usb", usbh0)
+ _REGISTER_CLOCK(NULL, "gdma0", gdma0)
+ _REGISTER_CLOCK(NULL, "lcd", lcd)
+ _REGISTER_CLOCK(NULL, "rtc", rtc)
+ _REGISTER_CLOCK(NULL, "nfc", nfc)
+ _REGISTER_CLOCK("tcc-mmc.0", NULL, sd0)
+ _REGISTER_CLOCK(NULL, "g2d", g2d)
+ _REGISTER_CLOCK(NULL, "gdma1", gdma1)
+ _REGISTER_CLOCK("tcc-uart.1", NULL, uart1)
+ _REGISTER_CLOCK("tcc-spi.0", NULL, spi0)
+ _REGISTER_CLOCK(NULL, "mscl", mscl)
+ _REGISTER_CLOCK("tcc-spi.1", NULL, spi1)
+ _REGISTER_CLOCK(NULL, "bdma", bdma)
+ _REGISTER_CLOCK(NULL, "adma0", adma0)
+ _REGISTER_CLOCK(NULL, "spdif", spdif)
+ _REGISTER_CLOCK(NULL, "scfg", scfg)
+ _REGISTER_CLOCK(NULL, "cid", cid)
+ _REGISTER_CLOCK("tcc-mmc.1", NULL, sd1)
+ _REGISTER_CLOCK("tcc-uart.4", NULL, uart4)
+ _REGISTER_CLOCK(NULL, "dai1", dai1)
+ _REGISTER_CLOCK(NULL, "adma1", adma1)
+ _REGISTER_CLOCK(NULL, "c3dec", c3dec)
+ _REGISTER_CLOCK("tcc-can.0", NULL, can0)
+ _REGISTER_CLOCK("tcc-can.1", NULL, can1)
+ _REGISTER_CLOCK(NULL, "gps", gps)
+ _REGISTER_CLOCK("tcc-gsb.0", NULL, gsb0)
+ _REGISTER_CLOCK("tcc-gsb.1", NULL, gsb1)
+ _REGISTER_CLOCK("tcc-gsb.2", NULL, gsb2)
+ _REGISTER_CLOCK("tcc-gsb.3", NULL, gsb3)
+ _REGISTER_CLOCK(NULL, "gdma2", gdma2)
+ _REGISTER_CLOCK(NULL, "gdma3", gdma3)
+ _REGISTER_CLOCK(NULL, "ddrc", ddrc)
+ _REGISTER_CLOCK("tcc-usbh.1", "usb", usbh1)
+};
+
+static struct clk *root_clk_by_index(enum root_clks src)
+{
+ switch (src) {
+ case CLK_SRC_PLL0: return &pll0;
+ case CLK_SRC_PLL1: return &pll1;
+ case CLK_SRC_PLL2: return &pll2;
+ case CLK_SRC_PLL0DIV: return &pll0div;
+ case CLK_SRC_PLL1DIV: return &pll1div;
+ case CLK_SRC_PLL2DIV: return &pll2div;
+ case CLK_SRC_XI: return &xi;
+ case CLK_SRC_XTI: return &xti;
+ case CLK_SRC_XIDIV: return &xidiv;
+ case CLK_SRC_XTIDIV: return &xtidiv;
+ default: return NULL;
+ }
+}
+
+static void find_aclk_parent(struct clk *clk)
+{
+ unsigned int src;
+ struct clk *clock;
+
+ if (!clk->aclkreg)
+ return;
+
+ src = __raw_readl(clk->aclkreg) >> ACLK_SEL_SHIFT;
+ src &= CLK_SRC_MASK;
+
+ clock = root_clk_by_index(src);
+ if (!clock)
+ return;
+
+ clk->parent = clock;
+ clk->set_parent = aclk_set_parent;
+}
+
+void __init tcc_clocks_init(unsigned long xi_freq, unsigned long xti_freq)
+{
+ int i;
+
+ xi_rate = xi_freq;
+ xti_rate = xti_freq;
+
+ /* fixup parents and add the clock */
+ for (i = 0; i < ARRAY_SIZE(lookups); i++) {
+ find_aclk_parent(lookups[i].clk);
+ clkdev_add(&lookups[i]);
+ }
+ tcc8k_timer_init(&tcz, (void __iomem *)TIMER_BASE, INT_TC32);
+}
diff --git a/arch/arm/mach-tcc8k/common.h b/arch/arm/mach-tcc8k/common.h
new file mode 100644
index 000000000000..705690add395
--- /dev/null
+++ b/arch/arm/mach-tcc8k/common.h
@@ -0,0 +1,15 @@
+#ifndef MACH_TCC8K_COMMON_H
+#define MACH_TCC8K_COMMON_H
+
+#include <linux/platform_device.h>
+
+extern struct platform_device tcc_nand_device;
+
+struct clk;
+
+extern void tcc_clocks_init(unsigned long xi_freq, unsigned long xti_freq);
+extern void tcc8k_timer_init(struct clk *clock, void __iomem *base, int irq);
+extern void tcc8k_init_irq(void);
+extern void tcc8k_map_common_io(void);
+
+#endif
diff --git a/arch/arm/mach-tcc8k/devices.c b/arch/arm/mach-tcc8k/devices.c
new file mode 100644
index 000000000000..6722ad7c2836
--- /dev/null
+++ b/arch/arm/mach-tcc8k/devices.c
@@ -0,0 +1,239 @@
+/*
+ * linux/arch/arm/mach-tcc8k/devices.c
+ *
+ * Copyright (C) Telechips, Inc.
+ * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of GPL v2.
+ *
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/tcc8k-regs.h>
+#include <mach/irqs.h>
+
+#include "common.h"
+
+static u64 tcc8k_dmamask = DMA_BIT_MASK(32);
+
+#ifdef CONFIG_MTD_NAND_TCC
+/* NAND controller */
+static struct resource tcc_nand_resources[] = {
+ {
+ .start = (resource_size_t)NFC_BASE,
+ .end = (resource_size_t)NFC_BASE + 0x7f,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = INT_NFC,
+ .end = INT_NFC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device tcc_nand_device = {
+ .name = "tcc_nand",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(tcc_nand_resources),
+ .resource = tcc_nand_resources,
+};
+#endif
+
+#ifdef CONFIG_MMC_TCC8K
+/* MMC controller */
+static struct resource tcc8k_mmc0_resource[] = {
+ {
+ .start = INT_SD0,
+ .end = INT_SD0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource tcc8k_mmc1_resource[] = {
+ {
+ .start = INT_SD1,
+ .end = INT_SD1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device tcc8k_mmc0_device = {
+ .name = "tcc-mmc",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(tcc8k_mmc0_resource),
+ .resource = tcc8k_mmc0_resource,
+ .dev = {
+ .dma_mask = &tcc8k_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ }
+};
+
+struct platform_device tcc8k_mmc1_device = {
+ .name = "tcc-mmc",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(tcc8k_mmc1_resource),
+ .resource = tcc8k_mmc1_resource,
+ .dev = {
+ .dma_mask = &tcc8k_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ }
+};
+
+static inline void tcc8k_init_mmc(void)
+{
+ u32 reg = __raw_readl(GPIOPS_BASE + GPIOPS_FS1_OFFS);
+
+ reg |= GPIOPS_FS1_SDH0_BITS | GPIOPS_FS1_SDH1_BITS;
+ __raw_writel(reg, GPIOPS_BASE + GPIOPS_FS1_OFFS);
+
+ platform_device_register(&tcc8k_mmc0_device);
+ platform_device_register(&tcc8k_mmc1_device);
+}
+#else
+static inline void tcc8k_init_mmc(void) { }
+#endif
+
+#ifdef CONFIG_USB_OHCI_HCD
+static int tcc8k_ohci_init(struct device *dev)
+{
+ u32 reg;
+
+ /* Use GPIO PK19 as VBUS control output */
+ reg = __raw_readl(GPIOPK_BASE + GPIOPK_FS0_OFFS);
+ reg &= ~(1 << 19);
+ __raw_writel(reg, GPIOPK_BASE + GPIOPK_FS0_OFFS);
+ reg = __raw_readl(GPIOPK_BASE + GPIOPK_FS1_OFFS);
+ reg &= ~(1 << 19);
+ __raw_writel(reg, GPIOPK_BASE + GPIOPK_FS1_OFFS);
+
+ reg = __raw_readl(GPIOPK_BASE + GPIOPK_DOE_OFFS);
+ reg |= (1 << 19);
+ __raw_writel(reg, GPIOPK_BASE + GPIOPK_DOE_OFFS);
+ /* Turn on VBUS */
+ reg = __raw_readl(GPIOPK_BASE + GPIOPK_DAT_OFFS);
+ reg |= (1 << 19);
+ __raw_writel(reg, GPIOPK_BASE + GPIOPK_DAT_OFFS);
+
+ return 0;
+}
+
+static struct resource tcc8k_ohci0_resources[] = {
+ [0] = {
+ .start = (resource_size_t)USBH0_BASE,
+ .end = (resource_size_t)USBH0_BASE + 0x5c,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = INT_USBH0,
+ .end = INT_USBH0,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct resource tcc8k_ohci1_resources[] = {
+ [0] = {
+ .start = (resource_size_t)USBH1_BASE,
+ .end = (resource_size_t)USBH1_BASE + 0x5c,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = INT_USBH1,
+ .end = INT_USBH1,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct tccohci_platform_data tcc8k_ohci0_platform_data = {
+ .controller = 0,
+ .port_mode = PMM_PERPORT_MODE,
+ .init = tcc8k_ohci_init,
+};
+
+static struct tccohci_platform_data tcc8k_ohci1_platform_data = {
+ .controller = 1,
+ .port_mode = PMM_PERPORT_MODE,
+ .init = tcc8k_ohci_init,
+};
+
+static struct platform_device ohci0_device = {
+ .name = "tcc-ohci",
+ .id = 0,
+ .dev = {
+ .dma_mask = &tcc8k_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &tcc8k_ohci0_platform_data,
+ },
+ .num_resources = ARRAY_SIZE(tcc8k_ohci0_resources),
+ .resource = tcc8k_ohci0_resources,
+};
+
+static struct platform_device ohci1_device = {
+ .name = "tcc-ohci",
+ .id = 1,
+ .dev = {
+ .dma_mask = &tcc8k_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &tcc8k_ohci1_platform_data,
+ },
+ .num_resources = ARRAY_SIZE(tcc8k_ohci1_resources),
+ .resource = tcc8k_ohci1_resources,
+};
+
+static void __init tcc8k_init_usbhost(void)
+{
+ platform_device_register(&ohci0_device);
+ platform_device_register(&ohci1_device);
+}
+#else
+static void __init tcc8k_init_usbhost(void) { }
+#endif
+
+/* USB device controller*/
+#ifdef CONFIG_USB_GADGET_TCC8K
+static struct resource udc_resources[] = {
+ [0] = {
+ .start = INT_USBD,
+ .end = INT_USBD,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .start = INT_UDMA,
+ .end = INT_UDMA,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tcc8k_udc_device = {
+ .name = "tcc-udc",
+ .id = 0,
+ .resource = udc_resources,
+ .num_resources = ARRAY_SIZE(udc_resources),
+ .dev = {
+ .dma_mask = &tcc8k_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static void __init tcc8k_init_usb_gadget(void)
+{
+ platform_device_register(&tcc8k_udc_device);
+}
+#else
+static void __init tcc8k_init_usb_gadget(void) { }
+#endif /* CONFIG_USB_GADGET_TCC83X */
+
+static int __init tcc8k_init_devices(void)
+{
+ tcc8k_init_mmc();
+ tcc8k_init_usbhost();
+ tcc8k_init_usb_gadget();
+ return 0;
+}
+
+arch_initcall(tcc8k_init_devices);
diff --git a/arch/arm/mach-tcc8k/io.c b/arch/arm/mach-tcc8k/io.c
new file mode 100644
index 000000000000..9b39d7fa658f
--- /dev/null
+++ b/arch/arm/mach-tcc8k/io.c
@@ -0,0 +1,62 @@
+/*
+ * linux/arch/arm/mach-tcc8k/io.c
+ *
+ * (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * derived from TCC83xx io.c
+ * Copyright (C) Telechips, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/tcc8k-regs.h>
+
+/*
+ * The machine specific code may provide the extra mapping besides the
+ * default mapping provided here.
+ */
+static struct map_desc tcc8k_io_desc[] __initdata = {
+ {
+ .virtual = (unsigned long)CS1_BASE_VIRT,
+ .pfn = __phys_to_pfn(CS1_BASE),
+ .length = CS1_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)AHB_PERI_BASE_VIRT,
+ .pfn = __phys_to_pfn(AHB_PERI_BASE),
+ .length = AHB_PERI_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)APB0_PERI_BASE_VIRT,
+ .pfn = __phys_to_pfn(APB0_PERI_BASE),
+ .length = APB0_PERI_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)APB1_PERI_BASE_VIRT,
+ .pfn = __phys_to_pfn(APB1_PERI_BASE),
+ .length = APB1_PERI_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)EXT_MEM_CTRL_BASE_VIRT,
+ .pfn = __phys_to_pfn(EXT_MEM_CTRL_BASE),
+ .length = EXT_MEM_CTRL_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+/*
+ * Maps common IO regions for tcc8k.
+ *
+ */
+void __init tcc8k_map_common_io(void)
+{
+ iotable_init(tcc8k_io_desc, ARRAY_SIZE(tcc8k_io_desc));
+}
diff --git a/arch/arm/mach-tcc8k/irq.c b/arch/arm/mach-tcc8k/irq.c
new file mode 100644
index 000000000000..34575c4963f0
--- /dev/null
+++ b/arch/arm/mach-tcc8k/irq.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) Telechips, Inc.
+ * Copyright (C) 2009-2010 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GNU GPL version 2.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+
+#include <mach/tcc8k-regs.h>
+#include <mach/irqs.h>
+
+#include "common.h"
+
+/* Disable IRQ */
+static void tcc8000_mask_ack_irq0(unsigned int irq)
+{
+ PIC0_IEN &= ~(1 << irq);
+ PIC0_CREQ |= (1 << irq);
+}
+
+static void tcc8000_mask_ack_irq1(unsigned int irq)
+{
+ PIC1_IEN &= ~(1 << (irq - 32));
+ PIC1_CREQ |= (1 << (irq - 32));
+}
+
+static void tcc8000_mask_irq0(unsigned int irq)
+{
+ PIC0_IEN &= ~(1 << irq);
+}
+
+static void tcc8000_mask_irq1(unsigned int irq)
+{
+ PIC1_IEN &= ~(1 << (irq - 32));
+}
+
+static void tcc8000_ack_irq0(unsigned int irq)
+{
+ PIC0_CREQ |= (1 << irq);
+}
+
+static void tcc8000_ack_irq1(unsigned int irq)
+{
+ PIC1_CREQ |= (1 << (irq - 32));
+}
+
+/* Enable IRQ */
+static void tcc8000_unmask_irq0(unsigned int irq)
+{
+ PIC0_IEN |= (1 << irq);
+ PIC0_INTOEN |= (1 << irq);
+}
+
+static void tcc8000_unmask_irq1(unsigned int irq)
+{
+ PIC1_IEN |= (1 << (irq - 32));
+ PIC1_INTOEN |= (1 << (irq - 32));
+}
+
+static struct irq_chip tcc8000_irq_chip0 = {
+ .name = "tcc_irq0",
+ .mask = tcc8000_mask_irq0,
+ .ack = tcc8000_ack_irq0,
+ .mask_ack = tcc8000_mask_ack_irq0,
+ .unmask = tcc8000_unmask_irq0,
+};
+
+static struct irq_chip tcc8000_irq_chip1 = {
+ .name = "tcc_irq1",
+ .mask = tcc8000_mask_irq1,
+ .ack = tcc8000_ack_irq1,
+ .mask_ack = tcc8000_mask_ack_irq1,
+ .unmask = tcc8000_unmask_irq1,
+};
+
+void __init tcc8k_init_irq(void)
+{
+ int irqno;
+
+ /* Mask and clear all interrupts */
+ PIC0_IEN = 0x00000000;
+ PIC0_CREQ = 0xffffffff;
+ PIC1_IEN = 0x00000000;
+ PIC1_CREQ = 0xffffffff;
+
+ PIC0_MEN0 = 0x00000003;
+ PIC1_MEN1 = 0x00000003;
+ PIC1_MEN = 0x00000003;
+
+ /* let all IRQs be level triggered */
+ PIC0_TMODE = 0xffffffff;
+ PIC1_TMODE = 0xffffffff;
+ /* all IRQs are IRQs (not FIQs) */
+ PIC0_IRQSEL = 0xffffffff;
+ PIC1_IRQSEL = 0xffffffff;
+
+ for (irqno = 0; irqno < NR_IRQS; irqno++) {
+ if (irqno < 32)
+ set_irq_chip(irqno, &tcc8000_irq_chip0);
+ else
+ set_irq_chip(irqno, &tcc8000_irq_chip1);
+ set_irq_handler(irqno, handle_level_irq);
+ set_irq_flags(irqno, IRQF_VALID);
+ }
+}
diff --git a/arch/arm/mach-tcc8k/time.c b/arch/arm/mach-tcc8k/time.c
new file mode 100644
index 000000000000..78d06008841d
--- /dev/null
+++ b/arch/arm/mach-tcc8k/time.c
@@ -0,0 +1,149 @@
+/*
+ * TCC8000 system timer setup
+ *
+ * (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GPL version 2.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+
+#include <asm/mach/time.h>
+
+#include <mach/tcc8k-regs.h>
+#include <mach/irqs.h>
+
+#include "common.h"
+
+static void __iomem *timer_base;
+
+static cycle_t tcc_get_cycles(struct clocksource *cs)
+{
+ return __raw_readl(timer_base + TC32MCNT_OFFS);
+}
+
+static struct clocksource clocksource_tcc = {
+ .name = "tcc_tc32",
+ .rating = 200,
+ .read = tcc_get_cycles,
+ .mask = CLOCKSOURCE_MASK(32),
+ .shift = 28,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int tcc_set_next_event(unsigned long evt,
+ struct clock_event_device *unused)
+{
+ unsigned long reg = __raw_readl(timer_base + TC32MCNT_OFFS);
+
+ __raw_writel(reg + evt, timer_base + TC32CMP0_OFFS);
+ return 0;
+}
+
+static void tcc_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ unsigned long tc32irq;
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_ONESHOT:
+ tc32irq = __raw_readl(timer_base + TC32IRQ_OFFS);
+ tc32irq |= TC32IRQ_IRQEN0;
+ __raw_writel(tc32irq, timer_base + TC32IRQ_OFFS);
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ tc32irq = __raw_readl(timer_base + TC32IRQ_OFFS);
+ tc32irq &= ~TC32IRQ_IRQEN0;
+ __raw_writel(tc32irq, timer_base + TC32IRQ_OFFS);
+ break;
+ case CLOCK_EVT_MODE_PERIODIC:
+ case CLOCK_EVT_MODE_RESUME:
+ break;
+ }
+}
+
+static irqreturn_t tcc8k_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = dev_id;
+
+ /* Acknowledge TC32 interrupt by reading TC32IRQ */
+ __raw_readl(timer_base + TC32IRQ_OFFS);
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct clock_event_device clockevent_tcc = {
+ .name = "tcc_timer1",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .set_mode = tcc_set_mode,
+ .set_next_event = tcc_set_next_event,
+ .rating = 200,
+};
+
+static struct irqaction tcc8k_timer_irq = {
+ .name = "TC32_timer",
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .handler = tcc8k_timer_interrupt,
+ .dev_id = &clockevent_tcc,
+};
+
+static int __init tcc_clockevent_init(struct clk *clock)
+{
+ unsigned int c = clk_get_rate(clock);
+
+ clocksource_tcc.mult = clocksource_hz2mult(c,
+ clocksource_tcc.shift);
+ clocksource_register(&clocksource_tcc);
+
+ clockevent_tcc.mult = div_sc(c, NSEC_PER_SEC,
+ clockevent_tcc.shift);
+ clockevent_tcc.max_delta_ns =
+ clockevent_delta2ns(0xfffffffe, &clockevent_tcc);
+ clockevent_tcc.min_delta_ns =
+ clockevent_delta2ns(0xff, &clockevent_tcc);
+
+ clockevent_tcc.cpumask = cpumask_of(0);
+
+ clockevents_register_device(&clockevent_tcc);
+
+ return 0;
+}
+
+void __init tcc8k_timer_init(struct clk *clock, void __iomem *base, int irq)
+{
+ u32 reg;
+
+ timer_base = base;
+ tcc8k_timer_irq.irq = irq;
+
+ /* Enable clocks */
+ clk_enable(clock);
+
+ /* Initialize 32-bit timer */
+ reg = __raw_readl(timer_base + TC32EN_OFFS);
+ reg &= ~TC32EN_ENABLE; /* Disable timer */
+ __raw_writel(reg, timer_base + TC32EN_OFFS);
+ /* Free running timer, counting from 0 to 0xffffffff */
+ __raw_writel(0, timer_base + TC32EN_OFFS);
+ __raw_writel(0, timer_base + TC32LDV_OFFS);
+ reg = __raw_readl(timer_base + TC32IRQ_OFFS);
+ reg |= TC32IRQ_IRQEN0; /* irq at match with CMP0 */
+ __raw_writel(reg, timer_base + TC32IRQ_OFFS);
+
+ __raw_writel(TC32EN_ENABLE, timer_base + TC32EN_OFFS);
+
+ tcc_clockevent_init(clock);
+ setup_irq(irq, &tcc8k_timer_irq);
+}
diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c
index 9e305de56be9..b9dbdb1289d0 100644
--- a/arch/arm/mach-tegra/board-harmony.c
+++ b/arch/arm/mach-tegra/board-harmony.c
@@ -115,8 +115,6 @@ static void __init tegra_harmony_init(void)
MACHINE_START(HARMONY, "harmony")
.boot_params = 0x00000100,
- .phys_io = IO_APB_PHYS,
- .io_pg_offst = ((IO_APB_VIRT) >> 18) & 0xfffc,
.fixup = tegra_harmony_fixup,
.init_irq = tegra_init_irq,
.init_machine = tegra_harmony_init,
diff --git a/arch/arm/mach-tegra/include/mach/debug-macro.S b/arch/arm/mach-tegra/include/mach/debug-macro.S
index 55a39564b43c..8ea3bffb4e00 100644
--- a/arch/arm/mach-tegra/include/mach/debug-macro.S
+++ b/arch/arm/mach-tegra/include/mach/debug-macro.S
@@ -20,24 +20,28 @@
#include <mach/io.h>
- .macro addruart,rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- ldreq \rx, =IO_APB_PHYS @ physical
- ldrne \rx, =IO_APB_VIRT @ virtual
+ .macro addruart, rp, rv
+ ldreq \rp, =IO_APB_PHYS @ physical
+ ldrne \rv, =IO_APB_VIRT @ virtual
#if defined(CONFIG_TEGRA_DEBUG_UART_NONE)
#error "A debug UART must be selected in the kernel config to use DEBUG_LL"
#elif defined(CONFIG_TEGRA_DEBUG_UARTA)
- orr \rx, \rx, #0x6000
+ orr \rp, \rp, #0x6000
+ orr \rv, \rv, #0x6000
#elif defined(CONFIG_TEGRA_DEBUG_UARTB)
- ldr \tmp, =0x6040
- orr \rx, \rx, \tmp
+ orr \rp, \rp, #0x6000
+ orr \rp, \rp, #0x40
+ orr \rv, \rv, #0x6000
+ orr \rv, \rv, #0x40
#elif defined(CONFIG_TEGRA_DEBUG_UARTC)
- orr \rx, \rx, #0x6200
+ orr \rp, \rp, #0x6200
+ orr \rv, \rv, #0x6200
#elif defined(CONFIG_TEGRA_DEBUG_UARTD)
- orr \rx, \rx, #0x6300
+ orr \rp, \rp, #0x6300
+ orr \rv, \rv, #0x6300
#elif defined(CONFIG_TEGRA_DEBUG_UARTE)
- orr \rx, \rx, #0x6400
+ orr \rp, \rp, #0x6400
+ orr \rv, \rv, #0x6400
#endif
.endm
diff --git a/arch/arm/mach-tegra/include/mach/smp.h b/arch/arm/mach-tegra/include/mach/smp.h
index 8b42dab79a70..e4a34a35a544 100644
--- a/arch/arm/mach-tegra/include/mach/smp.h
+++ b/arch/arm/mach-tegra/include/mach/smp.h
@@ -1,16 +1,8 @@
#ifndef ASMARM_ARCH_SMP_H
#define ASMARM_ARCH_SMP_H
-
#include <asm/hardware/gic.h>
-
-#define hard_smp_processor_id() \
- ({ \
- unsigned int cpunum; \
- __asm__("mrc p15, 0, %0, c0, c0, 5" \
- : "=r" (cpunum)); \
- cpunum &= 0x0F; \
- })
+#include <asm/smp_mpidr.h>
/*
* We use IRQ1 as the IPI
diff --git a/arch/arm/mach-u300/dummyspichip.c b/arch/arm/mach-u300/dummyspichip.c
index 5f55012b7c9e..03f793612594 100644
--- a/arch/arm/mach-u300/dummyspichip.c
+++ b/arch/arm/mach-u300/dummyspichip.c
@@ -46,7 +46,6 @@ static ssize_t dummy_looptest(struct device *dev,
* struct, this is just used here to alter the behaviour of the chip
* in order to perform tests.
*/
- struct pl022_config_chip *chip_info = spi->controller_data;
int status;
u8 txbuf[14] = {0xDE, 0xAD, 0xBE, 0xEF, 0x2B, 0xAD,
0xCA, 0xFE, 0xBA, 0xBE, 0xB1, 0x05,
@@ -72,7 +71,7 @@ static ssize_t dummy_looptest(struct device *dev,
* Force chip to 8 bit mode
* WARNING: NEVER DO THIS IN REAL DRIVER CODE, THIS SHOULD BE STATIC!
*/
- chip_info->data_size = SSP_DATA_BITS_8;
+ spi->bits_per_word = 8;
/* You should NOT DO THIS EITHER */
spi->master->setup(spi);
@@ -159,7 +158,7 @@ static ssize_t dummy_looptest(struct device *dev,
* Force chip to 16 bit mode
* WARNING: NEVER DO THIS IN REAL DRIVER CODE, THIS SHOULD BE STATIC!
*/
- chip_info->data_size = SSP_DATA_BITS_16;
+ spi->bits_per_word = 16;
/* You should NOT DO THIS EITHER */
spi->master->setup(spi);
diff --git a/arch/arm/mach-u300/include/mach/debug-macro.S b/arch/arm/mach-u300/include/mach/debug-macro.S
index 92c12420256f..df715707bead 100644
--- a/arch/arm/mach-u300/include/mach/debug-macro.S
+++ b/arch/arm/mach-u300/include/mach/debug-macro.S
@@ -10,13 +10,12 @@
*/
#include <mach/hardware.h>
- .macro addruart, rx, tmp
+ .macro addruart, rp, rv
/* If we move the address using MMU, use this. */
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- ldreq \rx, = U300_SLOW_PER_PHYS_BASE @ MMU off, physical address
- ldrne \rx, = U300_SLOW_PER_VIRT_BASE @ MMU on, virtual address
- orr \rx, \rx, #0x00003000
+ ldr \rp, = U300_SLOW_PER_PHYS_BASE @ MMU off, physical address
+ ldr \rv, = U300_SLOW_PER_VIRT_BASE @ MMU on, virtual address
+ orr \rp, \rp, #0x00003000
+ orr \rv, \rv, #0x00003000
.endm
#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-u300/spi.c b/arch/arm/mach-u300/spi.c
index f0e887bea30e..edb2c0d255c2 100644
--- a/arch/arm/mach-u300/spi.c
+++ b/arch/arm/mach-u300/spi.c
@@ -30,8 +30,6 @@ static void select_dummy_chip(u32 chipselect)
}
struct pl022_config_chip dummy_chip_info = {
- /* Nominally this is LOOPBACK_DISABLED, but this is our dummy chip! */
- .lbm = LOOPBACK_ENABLED,
/*
* available POLLING_TRANSFER and INTERRUPT_TRANSFER,
* DMA_TRANSFER does not work
@@ -42,14 +40,8 @@ struct pl022_config_chip dummy_chip_info = {
.hierarchy = SSP_MASTER,
/* 0 = drive TX even as slave, 1 = do not drive TX as slave */
.slave_tx_disable = 0,
- /* LSB first */
- .endian_tx = SSP_TX_LSB,
- .endian_rx = SSP_RX_LSB,
- .data_size = SSP_DATA_BITS_8, /* used to be 12 in some default */
.rx_lev_trig = SSP_RX_1_OR_MORE_ELEM,
.tx_lev_trig = SSP_TX_1_OR_MORE_EMPTY_LOC,
- .clk_phase = SSP_CLK_SECOND_EDGE,
- .clk_pol = SSP_CLK_POL_IDLE_LOW,
.ctrl_len = SSP_BITS_12,
.wait_state = SSP_MWIRE_WAIT_ZERO,
.duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX,
@@ -75,7 +67,7 @@ static struct spi_board_info u300_spi_devices[] = {
.bus_num = 0, /* Only one bus on this chip */
.chip_select = 0,
/* Means SPI_CS_HIGH, change if e.g low CS */
- .mode = 0,
+ .mode = SPI_MODE_1 | SPI_LSB_FIRST | SPI_LOOP,
},
#endif
};
diff --git a/arch/arm/mach-u300/u300.c b/arch/arm/mach-u300/u300.c
index bfcda9820888..07c35a846424 100644
--- a/arch/arm/mach-u300/u300.c
+++ b/arch/arm/mach-u300/u300.c
@@ -61,8 +61,6 @@ static void __init u300_init_machine(void)
MACHINE_START(U300, MACH_U300_STRING)
/* Maintainer: Linus Walleij <linus.walleij@stericsson.com> */
- .phys_io = U300_AHB_PER_PHYS_BASE,
- .io_pg_offst = ((U300_AHB_PER_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = BOOT_PARAMS_OFFSET,
.map_io = u300_map_io,
.reserve = u300_reserve,
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig
index 6625e5bbf4d6..2dd44a0b4615 100644
--- a/arch/arm/mach-ux500/Kconfig
+++ b/arch/arm/mach-ux500/Kconfig
@@ -21,9 +21,7 @@ config MACH_U8500_MOP
bool "U8500 Development platform"
select UX500_SOC_DB8500
help
- Include support for mop500 development platform
- based on U8500 architecture. The platform is based
- on early drop silicon version of 8500.
+ Include support for the mop500 development platform.
config MACH_U5500
bool "U5500 Development platform"
@@ -39,4 +37,18 @@ config UX500_DEBUG_UART
Choose the UART on which kernel low-level debug messages should be
output.
+config U5500_MODEM_IRQ
+ bool "Modem IRQ support"
+ depends on MACH_U5500
+ default y
+ help
+ Add support for handling IRQ:s from modem side
+
+config U5500_MBOX
+ bool "Mailbox support"
+ depends on MACH_U5500 && U5500_MODEM_IRQ
+ default y
+ help
+ Add support for U5500 mailbox communication with modem side
+
endif
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile
index 4556aea9c3c5..9e27a84433cb 100644
--- a/arch/arm/mach-ux500/Makefile
+++ b/arch/arm/mach-ux500/Makefile
@@ -4,8 +4,12 @@
obj-y := clock.o cpu.o devices.o
obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o devices-db5500.o
-obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o
-obj-$(CONFIG_MACH_U8500_MOP) += board-mop500.o
+obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o prcmu.o
+obj-$(CONFIG_MACH_U8500_MOP) += board-mop500.o board-mop500-sdi.o
obj-$(CONFIG_MACH_U5500) += board-u5500.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
+obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
+obj-$(CONFIG_REGULATOR_AB8500) += board-mop500-regulators.o
+obj-$(CONFIG_U5500_MODEM_IRQ) += modem_irq.o
+obj-$(CONFIG_U5500_MBOX) += mbox.o
diff --git a/arch/arm/mach-ux500/board-mop500-regulators.c b/arch/arm/mach-ux500/board-mop500-regulators.c
new file mode 100644
index 000000000000..1187f1fc2e53
--- /dev/null
+++ b/arch/arm/mach-ux500/board-mop500-regulators.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License Terms: GNU General Public License v2
+ *
+ * Author: Sundar Iyer <sundar.iyer@stericsson.com>
+ *
+ * MOP500 board specific initialization for regulators
+ */
+#include <linux/kernel.h>
+#include <linux/regulator/machine.h>
+
+/* supplies to the display/camera */
+static struct regulator_init_data ab8500_vaux1_regulator = {
+ .constraints = {
+ .name = "V-DISPLAY",
+ .min_uV = 2500000,
+ .max_uV = 2900000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE|
+ REGULATOR_CHANGE_STATUS,
+ },
+};
+
+/* supplies to the on-board eMMC */
+static struct regulator_init_data ab8500_vaux2_regulator = {
+ .constraints = {
+ .name = "V-eMMC1",
+ .min_uV = 1100000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE|
+ REGULATOR_CHANGE_STATUS,
+ },
+};
+
+/* supply for VAUX3, supplies to SDcard slots */
+static struct regulator_init_data ab8500_vaux3_regulator = {
+ .constraints = {
+ .name = "V-MMC-SD",
+ .min_uV = 1100000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE|
+ REGULATOR_CHANGE_STATUS,
+ },
+};
+
+/* supply for tvout, gpadc, TVOUT LDO */
+static struct regulator_init_data ab8500_vtvout_init = {
+ .constraints = {
+ .name = "V-TVOUT",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+};
+
+/* supply for ab8500-vaudio, VAUDIO LDO */
+static struct regulator_init_data ab8500_vaudio_init = {
+ .constraints = {
+ .name = "V-AUD",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+};
+
+/* supply for v-anamic1 VAMic1-LDO */
+static struct regulator_init_data ab8500_vamic1_init = {
+ .constraints = {
+ .name = "V-AMIC1",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+};
+
+/* supply for v-amic2, VAMIC2 LDO, reuse constants for AMIC1 */
+static struct regulator_init_data ab8500_vamic2_init = {
+ .constraints = {
+ .name = "V-AMIC2",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+};
+
+/* supply for v-dmic, VDMIC LDO */
+static struct regulator_init_data ab8500_vdmic_init = {
+ .constraints = {
+ .name = "V-DMIC",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+};
+
+/* supply for v-intcore12, VINTCORE12 LDO */
+static struct regulator_init_data ab8500_vintcore_init = {
+ .constraints = {
+ .name = "V-INTCORE",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+};
+
+/* supply for U8500 CSI/DSI, VANA LDO */
+static struct regulator_init_data ab8500_vana_init = {
+ .constraints = {
+ .name = "V-CSI/DSI",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+};
+
diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c
new file mode 100644
index 000000000000..bac995665b58
--- /dev/null
+++ b/arch/arm/mach-ux500/board-mop500-sdi.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Hanumath Prasad <hanumath.prasad@stericsson.com>
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/mmci.h>
+#include <linux/mmc/host.h>
+#include <linux/platform_device.h>
+
+#include <plat/pincfg.h>
+#include <mach/devices.h>
+#include <mach/hardware.h>
+
+#include "pins-db8500.h"
+#include "board-mop500.h"
+
+static pin_cfg_t mop500_sdi_pins[] = {
+ /* SDI4 (on-board eMMC) */
+ GPIO197_MC4_DAT3,
+ GPIO198_MC4_DAT2,
+ GPIO199_MC4_DAT1,
+ GPIO200_MC4_DAT0,
+ GPIO201_MC4_CMD,
+ GPIO202_MC4_FBCLK,
+ GPIO203_MC4_CLK,
+ GPIO204_MC4_DAT7,
+ GPIO205_MC4_DAT6,
+ GPIO206_MC4_DAT5,
+ GPIO207_MC4_DAT4,
+};
+
+static pin_cfg_t mop500_sdi2_pins[] = {
+ /* SDI2 (POP eMMC) */
+ GPIO128_MC2_CLK,
+ GPIO129_MC2_CMD,
+ GPIO130_MC2_FBCLK,
+ GPIO131_MC2_DAT0,
+ GPIO132_MC2_DAT1,
+ GPIO133_MC2_DAT2,
+ GPIO134_MC2_DAT3,
+ GPIO135_MC2_DAT4,
+ GPIO136_MC2_DAT5,
+ GPIO137_MC2_DAT6,
+ GPIO138_MC2_DAT7,
+};
+
+/*
+ * SDI 2 (POP eMMC, not on DB8500ed)
+ */
+
+static struct mmci_platform_data mop500_sdi2_data = {
+ .ocr_mask = MMC_VDD_165_195,
+ .f_max = 100000000,
+ .capabilities = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+ .gpio_cd = -1,
+ .gpio_wp = -1,
+};
+
+/*
+ * SDI 4 (on-board eMMC)
+ */
+
+static struct mmci_platform_data mop500_sdi4_data = {
+ .ocr_mask = MMC_VDD_29_30,
+ .f_max = 100000000,
+ .capabilities = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA |
+ MMC_CAP_MMC_HIGHSPEED,
+ .gpio_cd = -1,
+ .gpio_wp = -1,
+};
+
+void mop500_sdi_init(void)
+{
+ nmk_config_pins(mop500_sdi_pins, ARRAY_SIZE(mop500_sdi_pins));
+
+ u8500_sdi2_device.dev.platform_data = &mop500_sdi2_data;
+ u8500_sdi4_device.dev.platform_data = &mop500_sdi4_data;
+
+ if (!cpu_is_u8500ed()) {
+ nmk_config_pins(mop500_sdi2_pins, ARRAY_SIZE(mop500_sdi2_pins));
+ amba_device_register(&u8500_sdi2_device, &iomem_resource);
+ }
+
+ /* On-board eMMC */
+ amba_device_register(&u8500_sdi4_device, &iomem_resource);
+}
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c
index 0e8fd135a57d..cac83a694880 100644
--- a/arch/arm/mach-ux500/board-mop500.c
+++ b/arch/arm/mach-ux500/board-mop500.c
@@ -18,18 +18,22 @@
#include <linux/amba/pl022.h>
#include <linux/spi/spi.h>
#include <linux/mfd/ab8500.h>
+#include <linux/input/matrix_keypad.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <plat/pincfg.h>
#include <plat/i2c.h>
+#include <plat/ske.h>
#include <mach/hardware.h>
#include <mach/setup.h>
#include <mach/devices.h>
+#include <mach/irqs.h>
#include "pins-db8500.h"
+#include "board-mop500.h"
static pin_cfg_t mop500_pins[] = {
/* SSP0 */
@@ -47,6 +51,24 @@ static pin_cfg_t mop500_pins[] = {
GPIO11_I2C2_SCL,
GPIO229_I2C3_SDA,
GPIO230_I2C3_SCL,
+
+ /* SKE keypad */
+ GPIO153_KP_I7,
+ GPIO154_KP_I6,
+ GPIO155_KP_I5,
+ GPIO156_KP_I4,
+ GPIO157_KP_O7,
+ GPIO158_KP_O6,
+ GPIO159_KP_O5,
+ GPIO160_KP_O4,
+ GPIO161_KP_I3,
+ GPIO162_KP_I2,
+ GPIO163_KP_I1,
+ GPIO164_KP_I0,
+ GPIO165_KP_O3,
+ GPIO166_KP_O2,
+ GPIO167_KP_O1,
+ GPIO168_KP_O0,
};
static void ab4500_spi_cs_control(u32 command)
@@ -55,19 +77,13 @@ static void ab4500_spi_cs_control(u32 command)
}
struct pl022_config_chip ab4500_chip_info = {
- .lbm = LOOPBACK_DISABLED,
.com_mode = INTERRUPT_TRANSFER,
.iface = SSP_INTERFACE_MOTOROLA_SPI,
/* we can act as master only */
.hierarchy = SSP_MASTER,
.slave_tx_disable = 0,
- .endian_rx = SSP_RX_MSB,
- .endian_tx = SSP_TX_MSB,
- .data_size = SSP_DATA_BITS_24,
.rx_lev_trig = SSP_RX_1_OR_MORE_ELEM,
.tx_lev_trig = SSP_TX_1_OR_MORE_EMPTY_LOC,
- .clk_phase = SSP_CLK_SECOND_EDGE,
- .clk_pol = SSP_CLK_POL_IDLE_HIGH,
.cs_control = ab4500_spi_cs_control,
};
@@ -75,15 +91,33 @@ static struct ab8500_platform_data ab8500_platdata = {
.irq_base = MOP500_AB8500_IRQ_BASE,
};
-static struct spi_board_info u8500_spi_devices[] = {
+static struct resource ab8500_resources[] = {
+ [0] = {
+ .start = IRQ_AB8500,
+ .end = IRQ_AB8500,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+struct platform_device ab8500_device = {
+ .name = "ab8500-i2c",
+ .id = 0,
+ .dev = {
+ .platform_data = &ab8500_platdata,
+ },
+ .num_resources = 1,
+ .resource = ab8500_resources,
+};
+
+static struct spi_board_info ab8500_spi_devices[] = {
{
- .modalias = "ab8500",
+ .modalias = "ab8500-spi",
.controller_data = &ab4500_chip_info,
.platform_data = &ab8500_platdata,
.max_speed_hz = 12000000,
.bus_num = 0,
.chip_select = 0,
- .mode = SPI_MODE_0,
+ .mode = SPI_MODE_3,
.irq = IRQ_DB8500_AB8500,
},
};
@@ -134,12 +168,120 @@ static struct amba_device *amba_devs[] __initdata = {
&u8500_ssp0_device,
};
+static const unsigned int ux500_keymap[] = {
+ KEY(2, 5, KEY_END),
+ KEY(4, 1, KEY_POWER),
+ KEY(3, 5, KEY_VOLUMEDOWN),
+ KEY(1, 3, KEY_3),
+ KEY(5, 2, KEY_RIGHT),
+ KEY(5, 0, KEY_9),
+
+ KEY(0, 5, KEY_MENU),
+ KEY(7, 6, KEY_ENTER),
+ KEY(4, 5, KEY_0),
+ KEY(6, 7, KEY_2),
+ KEY(3, 4, KEY_UP),
+ KEY(3, 3, KEY_DOWN),
+
+ KEY(6, 4, KEY_SEND),
+ KEY(6, 2, KEY_BACK),
+ KEY(4, 2, KEY_VOLUMEUP),
+ KEY(5, 5, KEY_1),
+ KEY(4, 3, KEY_LEFT),
+ KEY(3, 2, KEY_7),
+};
+
+static const struct matrix_keymap_data ux500_keymap_data = {
+ .keymap = ux500_keymap,
+ .keymap_size = ARRAY_SIZE(ux500_keymap),
+};
+
+/*
+ * Nomadik SKE keypad
+ */
+#define ROW_PIN_I0 164
+#define ROW_PIN_I1 163
+#define ROW_PIN_I2 162
+#define ROW_PIN_I3 161
+#define ROW_PIN_I4 156
+#define ROW_PIN_I5 155
+#define ROW_PIN_I6 154
+#define ROW_PIN_I7 153
+#define COL_PIN_O0 168
+#define COL_PIN_O1 167
+#define COL_PIN_O2 166
+#define COL_PIN_O3 165
+#define COL_PIN_O4 160
+#define COL_PIN_O5 159
+#define COL_PIN_O6 158
+#define COL_PIN_O7 157
+
+#define SKE_KPD_MAX_ROWS 8
+#define SKE_KPD_MAX_COLS 8
+
+static int ske_kp_rows[] = {
+ ROW_PIN_I0, ROW_PIN_I1, ROW_PIN_I2, ROW_PIN_I3,
+ ROW_PIN_I4, ROW_PIN_I5, ROW_PIN_I6, ROW_PIN_I7,
+};
+
+/*
+ * ske_set_gpio_row: request and set gpio rows
+ */
+static int ske_set_gpio_row(int gpio)
+{
+ int ret;
+
+ ret = gpio_request(gpio, "ske-kp");
+ if (ret < 0) {
+ pr_err("ske_set_gpio_row: gpio request failed\n");
+ return ret;
+ }
+
+ ret = gpio_direction_output(gpio, 1);
+ if (ret < 0) {
+ pr_err("ske_set_gpio_row: gpio direction failed\n");
+ gpio_free(gpio);
+ }
+
+ return ret;
+}
+
+/*
+ * ske_kp_init - enable the gpio configuration
+ */
+static int ske_kp_init(void)
+{
+ int ret, i;
+
+ for (i = 0; i < SKE_KPD_MAX_ROWS; i++) {
+ ret = ske_set_gpio_row(ske_kp_rows[i]);
+ if (ret < 0) {
+ pr_err("ske_kp_init: failed init\n");
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static struct ske_keypad_platform_data ske_keypad_board = {
+ .init = ske_kp_init,
+ .keymap_data = &ux500_keymap_data,
+ .no_autorepeat = true,
+ .krow = SKE_KPD_MAX_ROWS, /* 8x8 matrix */
+ .kcol = SKE_KPD_MAX_COLS,
+ .debounce_ms = 40, /* in millsecs */
+};
+
+
+
/* add any platform devices here - TODO */
static struct platform_device *platform_devs[] __initdata = {
&u8500_i2c0_device,
&ux500_i2c1_device,
&ux500_i2c2_device,
&ux500_i2c3_device,
+ &ux500_ske_keypad_device,
};
static void __init u8500_init_machine(void)
@@ -154,6 +296,7 @@ static void __init u8500_init_machine(void)
ux500_i2c1_device.dev.platform_data = &u8500_i2c1_data;
ux500_i2c2_device.dev.platform_data = &u8500_i2c2_data;
ux500_i2c3_device.dev.platform_data = &u8500_i2c3_data;
+ ux500_ske_keypad_device.dev.platform_data = &ske_keypad_board;
u8500_ssp0_device.dev.platform_data = &ssp0_platform_data;
@@ -163,14 +306,18 @@ static void __init u8500_init_machine(void)
platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
- spi_register_board_info(u8500_spi_devices,
- ARRAY_SIZE(u8500_spi_devices));
+ mop500_sdi_init();
+
+ /* If HW is early drop (ED) or V1.0 then use SPI to access AB8500 */
+ if (cpu_is_u8500ed() || cpu_is_u8500v10())
+ spi_register_board_info(ab8500_spi_devices,
+ ARRAY_SIZE(ab8500_spi_devices));
+ else /* If HW is v.1.1 or later use I2C to access AB8500 */
+ platform_device_register(&ab8500_device);
}
MACHINE_START(U8500, "ST-Ericsson MOP500 platform")
/* Maintainer: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> */
- .phys_io = U8500_UART2_BASE,
- .io_pg_offst = (IO_ADDRESS(U8500_UART2_BASE) >> 18) & 0xfffc,
.boot_params = 0x100,
.map_io = u8500_map_io,
.init_irq = ux500_init_irq,
diff --git a/arch/arm/mach-ux500/board-mop500.h b/arch/arm/mach-ux500/board-mop500.h
new file mode 100644
index 000000000000..2d240322fa6f
--- /dev/null
+++ b/arch/arm/mach-ux500/board-mop500.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef __BOARD_MOP500_H
+#define __BOARD_MOP500_H
+
+extern void mop500_sdi_init(void);
+
+#endif
diff --git a/arch/arm/mach-ux500/board-u5500.c b/arch/arm/mach-ux500/board-u5500.c
index 4430e69cf538..1ca094a45e71 100644
--- a/arch/arm/mach-ux500/board-u5500.c
+++ b/arch/arm/mach-ux500/board-u5500.c
@@ -31,8 +31,6 @@ static void __init u5500_init_machine(void)
}
MACHINE_START(U8500, "ST-Ericsson U5500 Platform")
- .phys_io = UX500_UART0_BASE,
- .io_pg_offst = (IO_ADDRESS(UX500_UART0_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.map_io = u5500_map_io,
.init_irq = ux500_init_irq,
diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c
index d8ab7f184fe4..1675047daf20 100644
--- a/arch/arm/mach-ux500/clock.c
+++ b/arch/arm/mach-ux500/clock.c
@@ -477,6 +477,7 @@ static struct clk_lookup u8500_common_clks[] = {
CLK(sdi5, "sdi5", NULL),
CLK(uart2, "uart2", NULL),
CLK(ske, "ske", NULL),
+ CLK(ske, "nmk-ske-keypad", NULL),
CLK(sdi2, "sdi2", NULL),
CLK(i2c0, "nmk-i2c.0", NULL),
CLK(fsmc, "fsmc", NULL),
diff --git a/arch/arm/mach-ux500/cpu-db5500.c b/arch/arm/mach-ux500/cpu-db5500.c
index e9278f6d67aa..2f87075e9d6f 100644
--- a/arch/arm/mach-ux500/cpu-db5500.c
+++ b/arch/arm/mach-ux500/cpu-db5500.c
@@ -14,6 +14,7 @@
#include <mach/hardware.h>
#include <mach/devices.h>
#include <mach/setup.h>
+#include <mach/irqs.h>
static struct map_desc u5500_io_desc[] __initdata = {
__IO_DEV_DESC(U5500_GPIO0_BASE, SZ_4K),
@@ -24,6 +25,90 @@ static struct map_desc u5500_io_desc[] __initdata = {
__IO_DEV_DESC(U5500_PRCMU_BASE, SZ_4K),
};
+static struct resource mbox0_resources[] = {
+ {
+ .name = "mbox_peer",
+ .start = U5500_MBOX0_PEER_START,
+ .end = U5500_MBOX0_PEER_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "mbox_local",
+ .start = U5500_MBOX0_LOCAL_START,
+ .end = U5500_MBOX0_LOCAL_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "mbox_irq",
+ .start = MBOX_PAIR0_VIRT_IRQ,
+ .end = MBOX_PAIR0_VIRT_IRQ,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct resource mbox1_resources[] = {
+ {
+ .name = "mbox_peer",
+ .start = U5500_MBOX1_PEER_START,
+ .end = U5500_MBOX1_PEER_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "mbox_local",
+ .start = U5500_MBOX1_LOCAL_START,
+ .end = U5500_MBOX1_LOCAL_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "mbox_irq",
+ .start = MBOX_PAIR1_VIRT_IRQ,
+ .end = MBOX_PAIR1_VIRT_IRQ,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct resource mbox2_resources[] = {
+ {
+ .name = "mbox_peer",
+ .start = U5500_MBOX2_PEER_START,
+ .end = U5500_MBOX2_PEER_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "mbox_local",
+ .start = U5500_MBOX2_LOCAL_START,
+ .end = U5500_MBOX2_LOCAL_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "mbox_irq",
+ .start = MBOX_PAIR2_VIRT_IRQ,
+ .end = MBOX_PAIR2_VIRT_IRQ,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device mbox0_device = {
+ .id = 0,
+ .name = "mbox",
+ .resource = mbox0_resources,
+ .num_resources = ARRAY_SIZE(mbox0_resources),
+};
+
+static struct platform_device mbox1_device = {
+ .id = 1,
+ .name = "mbox",
+ .resource = mbox1_resources,
+ .num_resources = ARRAY_SIZE(mbox1_resources),
+};
+
+static struct platform_device mbox2_device = {
+ .id = 2,
+ .name = "mbox",
+ .resource = mbox2_resources,
+ .num_resources = ARRAY_SIZE(mbox2_resources),
+};
+
static struct platform_device *u5500_platform_devs[] __initdata = {
&u5500_gpio_devs[0],
&u5500_gpio_devs[1],
@@ -33,6 +118,9 @@ static struct platform_device *u5500_platform_devs[] __initdata = {
&u5500_gpio_devs[5],
&u5500_gpio_devs[6],
&u5500_gpio_devs[7],
+ &mbox0_device,
+ &mbox1_device,
+ &mbox2_device,
};
void __init u5500_map_io(void)
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c
index f21c444edd99..4acab7544b3c 100644
--- a/arch/arm/mach-ux500/cpu-db8500.c
+++ b/arch/arm/mach-ux500/cpu-db8500.c
@@ -38,10 +38,12 @@ static struct platform_device *platform_devs[] __initdata = {
/* minimum static i/o mapping required to boot U8500 platforms */
static struct map_desc u8500_io_desc[] __initdata = {
__IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K),
+ __IO_DEV_DESC(U8500_PRCMU_TCDM_BASE, SZ_4K),
__IO_DEV_DESC(U8500_GPIO0_BASE, SZ_4K),
__IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K),
__IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K),
__IO_DEV_DESC(U8500_GPIO3_BASE, SZ_4K),
+ __MEM_DEV_DESC(U8500_BOOT_ROM_BASE, SZ_1M),
};
static struct map_desc u8500ed_io_desc[] __initdata = {
@@ -53,6 +55,69 @@ static struct map_desc u8500v1_io_desc[] __initdata = {
__IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K),
};
+/*
+ * Functions to differentiate between later ASICs
+ * We look into the end of the ROM to locate the hardcoded ASIC ID.
+ * This is only needed to differentiate between minor revisions and
+ * process variants of an ASIC, the major revisions are encoded in
+ * the cpuid.
+ */
+#define U8500_ASIC_ID_LOC_ED_V1 (U8500_BOOT_ROM_BASE + 0x1FFF4)
+#define U8500_ASIC_ID_LOC_V2 (U8500_BOOT_ROM_BASE + 0x1DBF4)
+#define U8500_ASIC_REV_ED 0x01
+#define U8500_ASIC_REV_V10 0xA0
+#define U8500_ASIC_REV_V11 0xA1
+#define U8500_ASIC_REV_V20 0xB0
+
+/**
+ * struct db8500_asic_id - fields of the ASIC ID
+ * @process: the manufacturing process, 0x40 is 40 nm
+ * 0x00 is "standard"
+ * @partnumber: hithereto 0x8500 for DB8500
+ * @revision: version code in the series
+ * This field definion is not formally defined but makes
+ * sense.
+ */
+struct db8500_asic_id {
+ u8 process;
+ u16 partnumber;
+ u8 revision;
+};
+
+/* This isn't going to change at runtime */
+static struct db8500_asic_id db8500_id;
+
+static void __init get_db8500_asic_id(void)
+{
+ u32 asicid;
+
+ if (cpu_is_u8500v1() || cpu_is_u8500ed())
+ asicid = readl(__io_address(U8500_ASIC_ID_LOC_ED_V1));
+ else if (cpu_is_u8500v2())
+ asicid = readl(__io_address(U8500_ASIC_ID_LOC_V2));
+ else
+ BUG();
+
+ db8500_id.process = (asicid >> 24);
+ db8500_id.partnumber = (asicid >> 16) & 0xFFFFU;
+ db8500_id.revision = asicid & 0xFFU;
+}
+
+bool cpu_is_u8500v10(void)
+{
+ return (db8500_id.revision == U8500_ASIC_REV_V10);
+}
+
+bool cpu_is_u8500v11(void)
+{
+ return (db8500_id.revision == U8500_ASIC_REV_V11);
+}
+
+bool cpu_is_u8500v20(void)
+{
+ return (db8500_id.revision == U8500_ASIC_REV_V20);
+}
+
void __init u8500_map_io(void)
{
ux500_map_io();
@@ -63,6 +128,9 @@ void __init u8500_map_io(void)
iotable_init(u8500ed_io_desc, ARRAY_SIZE(u8500ed_io_desc));
else
iotable_init(u8500v1_io_desc, ARRAY_SIZE(u8500v1_io_desc));
+
+ /* Read out the ASIC ID as early as we can */
+ get_db8500_asic_id();
}
/*
@@ -70,6 +138,20 @@ void __init u8500_map_io(void)
*/
void __init u8500_init_devices(void)
{
+ /* Display some ASIC boilerplate */
+ pr_info("DB8500: process: %02x, revision ID: 0x%02x\n",
+ db8500_id.process, db8500_id.revision);
+ if (cpu_is_u8500ed())
+ pr_info("DB8500: Early Drop (ED)\n");
+ else if (cpu_is_u8500v10())
+ pr_info("DB8500: version 1.0\n");
+ else if (cpu_is_u8500v11())
+ pr_info("DB8500: version 1.1\n");
+ else if (cpu_is_u8500v20())
+ pr_info("DB8500: version 2.0\n");
+ else
+ pr_warning("ASIC: UNKNOWN SILICON VERSION!\n");
+
ux500_init_devices();
if (cpu_is_u8500ed())
diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c
index 9280d2561111..cbbe69a76a7c 100644
--- a/arch/arm/mach-ux500/devices-db8500.c
+++ b/arch/arm/mach-ux500/devices-db8500.c
@@ -110,6 +110,82 @@ struct platform_device u8500_i2c4_device = {
.num_resources = ARRAY_SIZE(u8500_i2c4_resources),
};
+/*
+ * SD/MMC
+ */
+
+struct amba_device u8500_sdi0_device = {
+ .dev = {
+ .init_name = "sdi0",
+ },
+ .res = {
+ .start = U8500_SDI0_BASE,
+ .end = U8500_SDI0_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = {IRQ_DB8500_SDMMC0, NO_IRQ},
+};
+
+struct amba_device u8500_sdi1_device = {
+ .dev = {
+ .init_name = "sdi1",
+ },
+ .res = {
+ .start = U8500_SDI1_BASE,
+ .end = U8500_SDI1_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = {IRQ_DB8500_SDMMC1, NO_IRQ},
+};
+
+struct amba_device u8500_sdi2_device = {
+ .dev = {
+ .init_name = "sdi2",
+ },
+ .res = {
+ .start = U8500_SDI2_BASE,
+ .end = U8500_SDI2_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = {IRQ_DB8500_SDMMC2, NO_IRQ},
+};
+
+struct amba_device u8500_sdi3_device = {
+ .dev = {
+ .init_name = "sdi3",
+ },
+ .res = {
+ .start = U8500_SDI3_BASE,
+ .end = U8500_SDI3_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = {IRQ_DB8500_SDMMC3, NO_IRQ},
+};
+
+struct amba_device u8500_sdi4_device = {
+ .dev = {
+ .init_name = "sdi4",
+ },
+ .res = {
+ .start = U8500_SDI4_BASE,
+ .end = U8500_SDI4_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = {IRQ_DB8500_SDMMC4, NO_IRQ},
+};
+
+struct amba_device u8500_sdi5_device = {
+ .dev = {
+ .init_name = "sdi5",
+ },
+ .res = {
+ .start = U8500_SDI5_BASE,
+ .end = U8500_SDI5_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = {IRQ_DB8500_SDMMC5, NO_IRQ},
+};
+
static struct resource dma40_resources[] = {
[0] = {
.start = U8500_DMA_BASE,
@@ -170,23 +246,23 @@ struct stedma40_chan_cfg dma40_memcpy_conf_log = {
* Mapping between destination event lines and physical device address.
* The event line is tied to a device and therefor the address is constant.
*/
-static const dma_addr_t dma40_tx_map[STEDMA40_NR_DEV];
+static const dma_addr_t dma40_tx_map[DB8500_DMA_NR_DEV];
/* Mapping between source event lines and physical device address */
-static const dma_addr_t dma40_rx_map[STEDMA40_NR_DEV];
+static const dma_addr_t dma40_rx_map[DB8500_DMA_NR_DEV];
/* Reserved event lines for memcpy only */
static int dma40_memcpy_event[] = {
- STEDMA40_MEMCPY_TX_0,
- STEDMA40_MEMCPY_TX_1,
- STEDMA40_MEMCPY_TX_2,
- STEDMA40_MEMCPY_TX_3,
- STEDMA40_MEMCPY_TX_4,
- STEDMA40_MEMCPY_TX_5,
+ DB8500_DMA_MEMCPY_TX_0,
+ DB8500_DMA_MEMCPY_TX_1,
+ DB8500_DMA_MEMCPY_TX_2,
+ DB8500_DMA_MEMCPY_TX_3,
+ DB8500_DMA_MEMCPY_TX_4,
+ DB8500_DMA_MEMCPY_TX_5,
};
static struct stedma40_platform_data dma40_plat_data = {
- .dev_len = STEDMA40_NR_DEV,
+ .dev_len = DB8500_DMA_NR_DEV,
.dev_rx = dma40_rx_map,
.dev_tx = dma40_tx_map,
.memcpy = dma40_memcpy_event,
@@ -216,3 +292,23 @@ void dma40_u8500ed_fixup(void)
dma40_resources[1].start = U8500_DMA_LCPA_BASE_ED;
dma40_resources[1].end = U8500_DMA_LCPA_BASE_ED + 2 * SZ_1K - 1;
}
+
+struct resource keypad_resources[] = {
+ [0] = {
+ .start = U8500_SKE_BASE,
+ .end = U8500_SKE_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_DB8500_KB,
+ .end = IRQ_DB8500_KB,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device ux500_ske_keypad_device = {
+ .name = "nmk-ske-keypad",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(keypad_resources),
+ .resource = keypad_resources,
+};
diff --git a/arch/arm/mach-ux500/hotplug.c b/arch/arm/mach-ux500/hotplug.c
new file mode 100644
index 000000000000..b782a03024be
--- /dev/null
+++ b/arch/arm/mach-ux500/hotplug.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) STMicroelectronics 2009
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License Terms: GNU General Public License v2
+ * Based on ARM realview platform
+ *
+ * Author: Sundar Iyer <sundar.iyer@stericsson.com>
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+#include <linux/completion.h>
+
+#include <asm/cacheflush.h>
+
+extern volatile int pen_release;
+
+static DECLARE_COMPLETION(cpu_killed);
+
+static inline void platform_do_lowpower(unsigned int cpu)
+{
+ flush_cache_all();
+
+ /* we put the platform to just WFI */
+ for (;;) {
+ __asm__ __volatile__("dsb\n\t" "wfi\n\t"
+ : : : "memory");
+ if (pen_release == cpu) {
+ /*
+ * OK, proper wakeup, we're done
+ */
+ break;
+ }
+ }
+}
+
+int platform_cpu_kill(unsigned int cpu)
+{
+ return wait_for_completion_timeout(&cpu_killed, 5000);
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+void platform_cpu_die(unsigned int cpu)
+{
+#ifdef DEBUG
+ unsigned int this_cpu = hard_smp_processor_id();
+
+ if (cpu != this_cpu) {
+ printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n",
+ this_cpu, cpu);
+ BUG();
+ }
+#endif
+
+ printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
+ complete(&cpu_killed);
+
+ /* directly enter low power state, skipping secure registers */
+ platform_do_lowpower(cpu);
+}
+
+int platform_cpu_disable(unsigned int cpu)
+{
+ /*
+ * we don't allow CPU 0 to be shutdown (it is still too special
+ * e.g. clock tick interrupts)
+ */
+ return cpu == 0 ? -EPERM : 0;
+}
diff --git a/arch/arm/mach-ux500/include/mach/db5500-regs.h b/arch/arm/mach-ux500/include/mach/db5500-regs.h
index 545c80fc8024..3eafc0e24ba5 100644
--- a/arch/arm/mach-ux500/include/mach/db5500-regs.h
+++ b/arch/arm/mach-ux500/include/mach/db5500-regs.h
@@ -100,4 +100,18 @@
#define U5500_GPIOBANK6_BASE (U5500_GPIO4_BASE + 0x80)
#define U5500_GPIOBANK7_BASE (U5500_GPIO4_BASE + 0x100)
+#define U5500_MBOX_BASE (U5500_MODEM_BASE + 0xFFD1000)
+#define U5500_MBOX0_PEER_START (U5500_MBOX_BASE + 0x40)
+#define U5500_MBOX0_PEER_END (U5500_MBOX_BASE + 0x5F)
+#define U5500_MBOX0_LOCAL_START (U5500_MBOX_BASE + 0x60)
+#define U5500_MBOX0_LOCAL_END (U5500_MBOX_BASE + 0x7F)
+#define U5500_MBOX1_PEER_START (U5500_MBOX_BASE + 0x80)
+#define U5500_MBOX1_PEER_END (U5500_MBOX_BASE + 0x9F)
+#define U5500_MBOX1_LOCAL_START (U5500_MBOX_BASE + 0xA0)
+#define U5500_MBOX1_LOCAL_END (U5500_MBOX_BASE + 0xBF)
+#define U5500_MBOX2_PEER_START (U5500_MBOX_BASE + 0x00)
+#define U5500_MBOX2_PEER_END (U5500_MBOX_BASE + 0x1F)
+#define U5500_MBOX2_LOCAL_START (U5500_MBOX_BASE + 0x20)
+#define U5500_MBOX2_LOCAL_END (U5500_MBOX_BASE + 0x3F)
+
#endif
diff --git a/arch/arm/mach-ux500/include/mach/db8500-regs.h b/arch/arm/mach-ux500/include/mach/db8500-regs.h
index f000218210c9..f07d0986409d 100644
--- a/arch/arm/mach-ux500/include/mach/db8500-regs.h
+++ b/arch/arm/mach-ux500/include/mach/db8500-regs.h
@@ -30,8 +30,6 @@
#define U8500_ICN_BASE 0x81000000
#define U8500_BOOT_ROM_BASE 0x90000000
-/* ASIC ID is at 0xff4 offset within this region */
-#define U8500_ASIC_ID_BASE 0x9001F000
#define U8500_PER6_BASE 0xa03c0000
#define U8500_PER5_BASE 0xa03e0000
diff --git a/arch/arm/mach-ux500/include/mach/debug-macro.S b/arch/arm/mach-ux500/include/mach/debug-macro.S
index c5203b7ea552..be7c0f14e310 100644
--- a/arch/arm/mach-ux500/include/mach/debug-macro.S
+++ b/arch/arm/mach-ux500/include/mach/debug-macro.S
@@ -18,11 +18,9 @@
#define UX500_UART(n) __UX500_UART(n)
#define UART_BASE UX500_UART(CONFIG_UX500_DEBUG_UART)
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- ldreq \rx, =UART_BASE @ no, physical address
- ldrne \rx, =IO_ADDRESS(UART_BASE) @ yes, virtual address
+ .macro addruart, rp, rv
+ ldr \rp, =UART_BASE @ no, physical address
+ ldr \rv, =IO_ADDRESS(UART_BASE) @ yes, virtual address
.endm
#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-ux500/include/mach/devices.h b/arch/arm/mach-ux500/include/mach/devices.h
index c2b2f2574947..b91a4d1211a2 100644
--- a/arch/arm/mach-ux500/include/mach/devices.h
+++ b/arch/arm/mach-ux500/include/mach/devices.h
@@ -26,6 +26,14 @@ extern struct platform_device ux500_i2c3_device;
extern struct platform_device u8500_i2c0_device;
extern struct platform_device u8500_i2c4_device;
extern struct platform_device u8500_dma40_device;
+extern struct platform_device ux500_ske_keypad_device;
+
+extern struct amba_device u8500_sdi0_device;
+extern struct amba_device u8500_sdi1_device;
+extern struct amba_device u8500_sdi2_device;
+extern struct amba_device u8500_sdi3_device;
+extern struct amba_device u8500_sdi4_device;
+extern struct amba_device u8500_sdi5_device;
void dma40_u8500ed_fixup(void);
diff --git a/arch/arm/mach-ux500/include/mach/hardware.h b/arch/arm/mach-ux500/include/mach/hardware.h
index 8656379a8309..32e883a8f2a2 100644
--- a/arch/arm/mach-ux500/include/mach/hardware.h
+++ b/arch/arm/mach-ux500/include/mach/hardware.h
@@ -104,16 +104,35 @@ static inline bool cpu_is_u8500(void)
#endif
}
+#define CPUID_DB8500ED 0x410fc090
+#define CPUID_DB8500V1 0x411fc091
+#define CPUID_DB8500V2 0x412fc091
+
static inline bool cpu_is_u8500ed(void)
{
- return cpu_is_u8500() && (read_cpuid_id() & 15) == 0;
+ return cpu_is_u8500() && (read_cpuid_id() == CPUID_DB8500ED);
}
static inline bool cpu_is_u8500v1(void)
{
- return cpu_is_u8500() && (read_cpuid_id() & 15) == 1;
+ return cpu_is_u8500() && (read_cpuid_id() == CPUID_DB8500V1);
+}
+
+static inline bool cpu_is_u8500v2(void)
+{
+ return cpu_is_u8500() && (read_cpuid_id() == CPUID_DB8500V2);
}
+#ifdef CONFIG_UX500_SOC_DB8500
+bool cpu_is_u8500v10(void);
+bool cpu_is_u8500v11(void);
+bool cpu_is_u8500v20(void);
+#else
+static inline bool cpu_is_u8500v10(void) { return false; }
+static inline bool cpu_is_u8500v11(void) { return false; }
+static inline bool cpu_is_u8500v20(void) { return false; }
+#endif
+
static inline bool cpu_is_u5500(void)
{
#ifdef CONFIG_UX500_SOC_DB5500
diff --git a/arch/arm/mach-ux500/include/mach/irqs-db5500.h b/arch/arm/mach-ux500/include/mach/irqs-db5500.h
index 6fbfe5e2065a..bfa123dbec3b 100644
--- a/arch/arm/mach-ux500/include/mach/irqs-db5500.h
+++ b/arch/arm/mach-ux500/include/mach/irqs-db5500.h
@@ -61,6 +61,7 @@
#define IRQ_DB5500_SDMMC0 (IRQ_SHPI_START + 60)
#define IRQ_DB5500_HSEM (IRQ_SHPI_START + 61)
#define IRQ_DB5500_SBAG (IRQ_SHPI_START + 63)
+#define IRQ_DB5500_MODEM (IRQ_SHPI_START + 65)
#define IRQ_DB5500_SPI1 (IRQ_SHPI_START + 96)
#define IRQ_DB5500_MSP2 (IRQ_SHPI_START + 98)
#define IRQ_DB5500_SRPTIMER (IRQ_SHPI_START + 101)
diff --git a/arch/arm/mach-ux500/include/mach/irqs.h b/arch/arm/mach-ux500/include/mach/irqs.h
index 10385bdc2b77..693aa57de88d 100644
--- a/arch/arm/mach-ux500/include/mach/irqs.h
+++ b/arch/arm/mach-ux500/include/mach/irqs.h
@@ -40,7 +40,8 @@
#define IRQ_HSIR_CH1_OVRRUN (IRQ_SHPI_START + 33)
#define IRQ_HSIR_CH2_OVRRUN (IRQ_SHPI_START + 34)
#define IRQ_HSIR_CH3_OVRRUN (IRQ_SHPI_START + 35)
-#define IRQ_AB4500 (IRQ_SHPI_START + 40)
+#define IRQ_AB8500 (IRQ_SHPI_START + 40)
+#define IRQ_PRCMU (IRQ_SHPI_START + 47)
#define IRQ_DISP (IRQ_SHPI_START + 48)
#define IRQ_SiPI3 (IRQ_SHPI_START + 49)
#define IRQ_I2C4 (IRQ_SHPI_START + 51)
@@ -83,6 +84,19 @@
#include <mach/irqs-board-mop500.h>
#endif
-#define NR_IRQS IRQ_BOARD_END
+/*
+ * After the board specific IRQ:s we reserve a range of IRQ:s in which virtual
+ * IRQ:s representing modem IRQ:s can be allocated
+ */
+#define IRQ_MODEM_EVENTS_BASE (IRQ_BOARD_END + 1)
+#define IRQ_MODEM_EVENTS_NBR 72
+#define IRQ_MODEM_EVENTS_END (IRQ_MODEM_EVENTS_BASE + IRQ_MODEM_EVENTS_NBR)
+
+/* List of virtual IRQ:s that are allocated from the range above */
+#define MBOX_PAIR0_VIRT_IRQ (IRQ_MODEM_EVENTS_BASE + 43)
+#define MBOX_PAIR1_VIRT_IRQ (IRQ_MODEM_EVENTS_BASE + 45)
+#define MBOX_PAIR2_VIRT_IRQ (IRQ_MODEM_EVENTS_BASE + 41)
+
+#define NR_IRQS IRQ_MODEM_EVENTS_END
#endif /* ASM_ARCH_IRQS_H */
diff --git a/arch/arm/mach-ux500/include/mach/mbox.h b/arch/arm/mach-ux500/include/mach/mbox.h
new file mode 100644
index 000000000000..7f9da4d2fbda
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/mbox.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Author: Stefan Nilsson <stefan.xk.nilsson@stericsson.com> for ST-Ericsson.
+ * Author: Martin Persson <martin.persson@stericsson.com> for ST-Ericsson.
+ * License terms: GNU General Public License (GPL), version 2.
+ */
+
+#ifndef __INC_STE_MBOX_H
+#define __INC_STE_MBOX_H
+
+#define MBOX_BUF_SIZE 16
+#define MBOX_NAME_SIZE 8
+
+/**
+ * mbox_recv_cb_t - Definition of the mailbox callback.
+ * @mbox_msg: The mailbox message.
+ * @priv: The clients private data as specified in the call to mbox_setup.
+ *
+ * This function will be called upon reception of new mailbox messages.
+ */
+typedef void mbox_recv_cb_t (u32 mbox_msg, void *priv);
+
+/**
+ * struct mbox - Mailbox instance struct
+ * @list: Linked list head.
+ * @pdev: Pointer to device struct.
+ * @cb: Callback function. Will be called
+ * when new data is received.
+ * @client_data: Clients private data. Will be sent back
+ * in the callback function.
+ * @virtbase_peer: Virtual address for outgoing mailbox.
+ * @virtbase_local: Virtual address for incoming mailbox.
+ * @buffer: Then internal queue for outgoing messages.
+ * @name: Name of this mailbox.
+ * @buffer_available: Completion variable to achieve "blocking send".
+ * This variable will be signaled when there is
+ * internal buffer space available.
+ * @client_blocked: To keep track if any client is currently
+ * blocked.
+ * @lock: Spinlock to protect this mailbox instance.
+ * @write_index: Index in internal buffer to write to.
+ * @read_index: Index in internal buffer to read from.
+ * @allocated: Indicates whether this particular mailbox
+ * id has been allocated by someone.
+ */
+struct mbox {
+ struct list_head list;
+ struct platform_device *pdev;
+ mbox_recv_cb_t *cb;
+ void *client_data;
+ void __iomem *virtbase_peer;
+ void __iomem *virtbase_local;
+ u32 buffer[MBOX_BUF_SIZE];
+ char name[MBOX_NAME_SIZE];
+ struct completion buffer_available;
+ u8 client_blocked;
+ spinlock_t lock;
+ u8 write_index;
+ u8 read_index;
+ bool allocated;
+};
+
+/**
+ * mbox_setup - Set up a mailbox and return its instance.
+ * @mbox_id: The ID number of the mailbox. 0 or 1 for modem CPU,
+ * 2 for modem DSP.
+ * @mbox_cb: Pointer to the callback function to be called when a new message
+ * is received.
+ * @priv: Client user data which will be returned in the callback.
+ *
+ * Returns a mailbox instance to be specified in subsequent calls to mbox_send.
+ */
+struct mbox *mbox_setup(u8 mbox_id, mbox_recv_cb_t *mbox_cb, void *priv);
+
+/**
+ * mbox_send - Send a mailbox message.
+ * @mbox: Mailbox instance (returned by mbox_setup)
+ * @mbox_msg: The mailbox message to send.
+ * @block: Specifies whether this call will block until send is possible,
+ * or return an error if the mailbox buffer is full.
+ *
+ * Returns 0 on success or a negative error code on error. -ENOMEM indicates
+ * that the internal buffer is full and you have to try again later (or
+ * specify "block" in order to block until send is possible).
+ */
+int mbox_send(struct mbox *mbox, u32 mbox_msg, bool block);
+
+#endif /*INC_STE_MBOX_H*/
diff --git a/arch/arm/mach-ux500/include/mach/prcmu-regs.h b/arch/arm/mach-ux500/include/mach/prcmu-regs.h
new file mode 100644
index 000000000000..8885f39a6421
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/prcmu-regs.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2009 ST-Ericsson SA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ */
+#ifndef __MACH_PRCMU_REGS_H
+#define __MACH_PRCMU_REGS_H
+
+#include <mach/hardware.h>
+
+#define _PRCMU_BASE IO_ADDRESS(U8500_PRCMU_BASE)
+
+#define PRCM_ARM_PLLDIVPS (_PRCMU_BASE + 0x118)
+#define PRCM_ARM_CHGCLKREQ (_PRCMU_BASE + 0x114)
+#define PRCM_PLLARM_ENABLE (_PRCMU_BASE + 0x98)
+#define PRCM_ARMCLKFIX_MGT (_PRCMU_BASE + 0x0)
+#define PRCM_A9_RESETN_CLR (_PRCMU_BASE + 0x1f4)
+#define PRCM_A9_RESETN_SET (_PRCMU_BASE + 0x1f0)
+#define PRCM_ARM_LS_CLAMP (_PRCMU_BASE + 0x30c)
+#define PRCM_SRAM_A9 (_PRCMU_BASE + 0x308)
+
+/* ARM WFI Standby signal register */
+#define PRCM_ARM_WFI_STANDBY (_PRCMU_BASE + 0x130)
+#define PRCMU_IOCR (_PRCMU_BASE + 0x310)
+
+/* CPU mailbox registers */
+#define PRCM_MBOX_CPU_VAL (_PRCMU_BASE + 0x0fc)
+#define PRCM_MBOX_CPU_SET (_PRCMU_BASE + 0x100)
+#define PRCM_MBOX_CPU_CLR (_PRCMU_BASE + 0x104)
+
+/* Dual A9 core interrupt management unit registers */
+#define PRCM_A9_MASK_REQ (_PRCMU_BASE + 0x328)
+#define PRCM_A9_MASK_ACK (_PRCMU_BASE + 0x32c)
+#define PRCM_ARMITMSK31TO0 (_PRCMU_BASE + 0x11c)
+#define PRCM_ARMITMSK63TO32 (_PRCMU_BASE + 0x120)
+#define PRCM_ARMITMSK95TO64 (_PRCMU_BASE + 0x124)
+#define PRCM_ARMITMSK127TO96 (_PRCMU_BASE + 0x128)
+#define PRCM_POWER_STATE_VAL (_PRCMU_BASE + 0x25C)
+#define PRCM_ARMITVAL31TO0 (_PRCMU_BASE + 0x260)
+#define PRCM_ARMITVAL63TO32 (_PRCMU_BASE + 0x264)
+#define PRCM_ARMITVAL95TO64 (_PRCMU_BASE + 0x268)
+#define PRCM_ARMITVAL127TO96 (_PRCMU_BASE + 0x26C)
+
+#define PRCM_HOSTACCESS_REQ (_PRCMU_BASE + 0x334)
+#define ARM_WAKEUP_MODEM 0x1
+
+#define PRCM_ARM_IT1_CLEAR (_PRCMU_BASE + 0x48C)
+#define PRCM_ARM_IT1_VAL (_PRCMU_BASE + 0x494)
+#define PRCM_HOLD_EVT (_PRCMU_BASE + 0x174)
+
+#define PRCM_ITSTATUS0 (_PRCMU_BASE + 0x148)
+#define PRCM_ITSTATUS1 (_PRCMU_BASE + 0x150)
+#define PRCM_ITSTATUS2 (_PRCMU_BASE + 0x158)
+#define PRCM_ITSTATUS3 (_PRCMU_BASE + 0x160)
+#define PRCM_ITSTATUS4 (_PRCMU_BASE + 0x168)
+#define PRCM_ITSTATUS5 (_PRCMU_BASE + 0x484)
+#define PRCM_ITCLEAR5 (_PRCMU_BASE + 0x488)
+#define PRCM_ARMIT_MASKXP70_IT (_PRCMU_BASE + 0x1018)
+
+/* System reset register */
+#define PRCM_APE_SOFTRST (_PRCMU_BASE + 0x228)
+
+/* Level shifter and clamp control registers */
+#define PRCM_MMIP_LS_CLAMP_SET (_PRCMU_BASE + 0x420)
+#define PRCM_MMIP_LS_CLAMP_CLR (_PRCMU_BASE + 0x424)
+
+/* PRCMU clock/PLL/reset registers */
+#define PRCM_PLLDSI_FREQ (_PRCMU_BASE + 0x500)
+#define PRCM_PLLDSI_ENABLE (_PRCMU_BASE + 0x504)
+#define PRCM_LCDCLK_MGT (_PRCMU_BASE + 0x044)
+#define PRCM_MCDECLK_MGT (_PRCMU_BASE + 0x064)
+#define PRCM_HDMICLK_MGT (_PRCMU_BASE + 0x058)
+#define PRCM_TVCLK_MGT (_PRCMU_BASE + 0x07c)
+#define PRCM_DSI_PLLOUT_SEL (_PRCMU_BASE + 0x530)
+#define PRCM_DSITVCLK_DIV (_PRCMU_BASE + 0x52C)
+#define PRCM_APE_RESETN_SET (_PRCMU_BASE + 0x1E4)
+#define PRCM_APE_RESETN_CLR (_PRCMU_BASE + 0x1E8)
+
+/* ePOD and memory power signal control registers */
+#define PRCM_EPOD_C_SET (_PRCMU_BASE + 0x410)
+#define PRCM_SRAM_LS_SLEEP (_PRCMU_BASE + 0x304)
+
+/* Debug power control unit registers */
+#define PRCM_POWER_STATE_SET (_PRCMU_BASE + 0x254)
+
+/* Miscellaneous unit registers */
+#define PRCM_DSI_SW_RESET (_PRCMU_BASE + 0x324)
+
+#endif /* __MACH_PRCMU__REGS_H */
diff --git a/arch/arm/mach-ux500/include/mach/prcmu.h b/arch/arm/mach-ux500/include/mach/prcmu.h
new file mode 100644
index 000000000000..549843ff6dbe
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/prcmu.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) STMicroelectronics 2009
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License Terms: GNU General Public License v2
+ *
+ * PRCMU f/w APIs
+ */
+#ifndef __MACH_PRCMU_H
+#define __MACH_PRCMU_H
+
+int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size);
+int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size);
+
+#endif /* __MACH_PRCMU_H */
diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h
index e978dbd9e210..54bbe648bf58 100644
--- a/arch/arm/mach-ux500/include/mach/setup.h
+++ b/arch/arm/mach-ux500/include/mach/setup.h
@@ -38,4 +38,11 @@ extern struct sys_timer ux500_timer;
.type = MT_DEVICE, \
}
+#define __MEM_DEV_DESC(x, sz) { \
+ .virtual = IO_ADDRESS(x), \
+ .pfn = __phys_to_pfn(x), \
+ .length = sz, \
+ .type = MT_MEMORY, \
+}
+
#endif /* __ASM_ARCH_SETUP_H */
diff --git a/arch/arm/mach-ux500/include/mach/smp.h b/arch/arm/mach-ux500/include/mach/smp.h
index b59f7bc9725d..197e8417375e 100644
--- a/arch/arm/mach-ux500/include/mach/smp.h
+++ b/arch/arm/mach-ux500/include/mach/smp.h
@@ -10,18 +10,11 @@
#define ASMARM_ARCH_SMP_H
#include <asm/hardware/gic.h>
+#include <asm/smp_mpidr.h>
/* This is required to wakeup the secondary core */
extern void u8500_secondary_startup(void);
-#define hard_smp_processor_id() \
- ({ \
- unsigned int cpunum; \
- __asm__("mrc p15, 0, %0, c0, c0, 5" \
- : "=r" (cpunum)); \
- cpunum &= 0x0F; \
- })
-
/*
* We use IRQ1 as the IPI
*/
diff --git a/arch/arm/mach-ux500/mbox.c b/arch/arm/mach-ux500/mbox.c
new file mode 100644
index 000000000000..63435389c544
--- /dev/null
+++ b/arch/arm/mach-ux500/mbox.c
@@ -0,0 +1,567 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Author: Stefan Nilsson <stefan.xk.nilsson@stericsson.com> for ST-Ericsson.
+ * Author: Martin Persson <martin.persson@stericsson.com> for ST-Ericsson.
+ * License terms: GNU General Public License (GPL), version 2.
+ */
+
+/*
+ * Mailbox nomenclature:
+ *
+ * APE MODEM
+ * mbox pairX
+ * ..........................
+ * . .
+ * . peer .
+ * . send ---- .
+ * . --> | | .
+ * . | | .
+ * . ---- .
+ * . .
+ * . local .
+ * . rec ---- .
+ * . | | <-- .
+ * . | | .
+ * . ---- .
+ * .........................
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/completion.h>
+#include <mach/mbox.h>
+
+#define MBOX_NAME "mbox"
+
+#define MBOX_FIFO_DATA 0x000
+#define MBOX_FIFO_ADD 0x004
+#define MBOX_FIFO_REMOVE 0x008
+#define MBOX_FIFO_THRES_FREE 0x00C
+#define MBOX_FIFO_THRES_OCCUP 0x010
+#define MBOX_FIFO_STATUS 0x014
+
+#define MBOX_DISABLE_IRQ 0x4
+#define MBOX_ENABLE_IRQ 0x0
+#define MBOX_LATCH 1
+
+/* Global list of all mailboxes */
+static struct list_head mboxs = LIST_HEAD_INIT(mboxs);
+
+static struct mbox *get_mbox_with_id(u8 id)
+{
+ u8 i;
+ struct list_head *pos = &mboxs;
+ for (i = 0; i <= id; i++)
+ pos = pos->next;
+
+ return (struct mbox *) list_entry(pos, struct mbox, list);
+}
+
+int mbox_send(struct mbox *mbox, u32 mbox_msg, bool block)
+{
+ int res = 0;
+
+ spin_lock(&mbox->lock);
+
+ dev_dbg(&(mbox->pdev->dev),
+ "About to buffer 0x%X to mailbox 0x%X."
+ " ri = %d, wi = %d\n",
+ mbox_msg, (u32)mbox, mbox->read_index,
+ mbox->write_index);
+
+ /* Check if write buffer is full */
+ while (((mbox->write_index + 1) % MBOX_BUF_SIZE) == mbox->read_index) {
+ if (!block) {
+ dev_dbg(&(mbox->pdev->dev),
+ "Buffer full in non-blocking call! "
+ "Returning -ENOMEM!\n");
+ res = -ENOMEM;
+ goto exit;
+ }
+ spin_unlock(&mbox->lock);
+ dev_dbg(&(mbox->pdev->dev),
+ "Buffer full in blocking call! Sleeping...\n");
+ mbox->client_blocked = 1;
+ wait_for_completion(&mbox->buffer_available);
+ dev_dbg(&(mbox->pdev->dev),
+ "Blocking send was woken up! Trying again...\n");
+ spin_lock(&mbox->lock);
+ }
+
+ mbox->buffer[mbox->write_index] = mbox_msg;
+ mbox->write_index = (mbox->write_index + 1) % MBOX_BUF_SIZE;
+
+ /*
+ * Indicate that we want an IRQ as soon as there is a slot
+ * in the FIFO
+ */
+ writel(MBOX_ENABLE_IRQ, mbox->virtbase_peer + MBOX_FIFO_THRES_FREE);
+
+exit:
+ spin_unlock(&mbox->lock);
+ return res;
+}
+EXPORT_SYMBOL(mbox_send);
+
+#if defined(CONFIG_DEBUG_FS)
+/*
+ * Expected input: <value> <nbr sends>
+ * Example: "echo 0xdeadbeef 4 > mbox-node" sends 0xdeadbeef 4 times
+ */
+static ssize_t mbox_write_fifo(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ unsigned long mbox_mess;
+ unsigned long nbr_sends;
+ unsigned long i;
+ char int_buf[16];
+ char *token;
+ char *val;
+
+ struct mbox *mbox = (struct mbox *) dev->platform_data;
+
+ strncpy((char *) &int_buf, buf, sizeof(int_buf));
+ token = (char *) &int_buf;
+
+ /* Parse message */
+ val = strsep(&token, " ");
+ if ((val == NULL) || (strict_strtoul(val, 16, &mbox_mess) != 0))
+ mbox_mess = 0xDEADBEEF;
+
+ val = strsep(&token, " ");
+ if ((val == NULL) || (strict_strtoul(val, 10, &nbr_sends) != 0))
+ nbr_sends = 1;
+
+ dev_dbg(dev, "Will write 0x%lX %ld times using data struct at 0x%X\n",
+ mbox_mess, nbr_sends, (u32) mbox);
+
+ for (i = 0; i < nbr_sends; i++)
+ mbox_send(mbox, mbox_mess, true);
+
+ return count;
+}
+
+static ssize_t mbox_read_fifo(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ int mbox_value;
+ struct mbox *mbox = (struct mbox *) dev->platform_data;
+
+ if ((readl(mbox->virtbase_local + MBOX_FIFO_STATUS) & 0x7) <= 0)
+ return sprintf(buf, "Mailbox is empty\n");
+
+ mbox_value = readl(mbox->virtbase_local + MBOX_FIFO_DATA);
+ writel(MBOX_LATCH, (mbox->virtbase_local + MBOX_FIFO_REMOVE));
+
+ return sprintf(buf, "0x%X\n", mbox_value);
+}
+
+static DEVICE_ATTR(fifo, S_IWUGO | S_IRUGO, mbox_read_fifo, mbox_write_fifo);
+
+static int mbox_show(struct seq_file *s, void *data)
+{
+ struct list_head *pos;
+ u8 mbox_index = 0;
+
+ list_for_each(pos, &mboxs) {
+ struct mbox *m =
+ (struct mbox *) list_entry(pos, struct mbox, list);
+ if (m == NULL) {
+ seq_printf(s,
+ "Unable to retrieve mailbox %d\n",
+ mbox_index);
+ continue;
+ }
+
+ spin_lock(&m->lock);
+ if ((m->virtbase_peer == NULL) || (m->virtbase_local == NULL)) {
+ seq_printf(s, "MAILBOX %d not setup or corrupt\n",
+ mbox_index);
+ spin_unlock(&m->lock);
+ continue;
+ }
+
+ seq_printf(s,
+ "===========================\n"
+ " MAILBOX %d\n"
+ " PEER MAILBOX DUMP\n"
+ "---------------------------\n"
+ "FIFO: 0x%X (%d)\n"
+ "Free Threshold: 0x%.2X (%d)\n"
+ "Occupied Threshold: 0x%.2X (%d)\n"
+ "Status: 0x%.2X (%d)\n"
+ " Free spaces (ot): %d (%d)\n"
+ " Occup spaces (ot): %d (%d)\n"
+ "===========================\n"
+ " LOCAL MAILBOX DUMP\n"
+ "---------------------------\n"
+ "FIFO: 0x%.X (%d)\n"
+ "Free Threshold: 0x%.2X (%d)\n"
+ "Occupied Threshold: 0x%.2X (%d)\n"
+ "Status: 0x%.2X (%d)\n"
+ " Free spaces (ot): %d (%d)\n"
+ " Occup spaces (ot): %d (%d)\n"
+ "===========================\n"
+ "write_index: %d\n"
+ "read_index : %d\n"
+ "===========================\n"
+ "\n",
+ mbox_index,
+ readl(m->virtbase_peer + MBOX_FIFO_DATA),
+ readl(m->virtbase_peer + MBOX_FIFO_DATA),
+ readl(m->virtbase_peer + MBOX_FIFO_THRES_FREE),
+ readl(m->virtbase_peer + MBOX_FIFO_THRES_FREE),
+ readl(m->virtbase_peer + MBOX_FIFO_THRES_OCCUP),
+ readl(m->virtbase_peer + MBOX_FIFO_THRES_OCCUP),
+ readl(m->virtbase_peer + MBOX_FIFO_STATUS),
+ readl(m->virtbase_peer + MBOX_FIFO_STATUS),
+ (readl(m->virtbase_peer + MBOX_FIFO_STATUS) >> 4) & 0x7,
+ (readl(m->virtbase_peer + MBOX_FIFO_STATUS) >> 7) & 0x1,
+ (readl(m->virtbase_peer + MBOX_FIFO_STATUS) >> 0) & 0x7,
+ (readl(m->virtbase_peer + MBOX_FIFO_STATUS) >> 3) & 0x1,
+ readl(m->virtbase_local + MBOX_FIFO_DATA),
+ readl(m->virtbase_local + MBOX_FIFO_DATA),
+ readl(m->virtbase_local + MBOX_FIFO_THRES_FREE),
+ readl(m->virtbase_local + MBOX_FIFO_THRES_FREE),
+ readl(m->virtbase_local + MBOX_FIFO_THRES_OCCUP),
+ readl(m->virtbase_local + MBOX_FIFO_THRES_OCCUP),
+ readl(m->virtbase_local + MBOX_FIFO_STATUS),
+ readl(m->virtbase_local + MBOX_FIFO_STATUS),
+ (readl(m->virtbase_local + MBOX_FIFO_STATUS) >> 4) & 0x7,
+ (readl(m->virtbase_local + MBOX_FIFO_STATUS) >> 7) & 0x1,
+ (readl(m->virtbase_local + MBOX_FIFO_STATUS) >> 0) & 0x7,
+ (readl(m->virtbase_local + MBOX_FIFO_STATUS) >> 3) & 0x1,
+ m->write_index, m->read_index);
+ mbox_index++;
+ spin_unlock(&m->lock);
+ }
+
+ return 0;
+}
+
+static int mbox_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, mbox_show, NULL);
+}
+
+static const struct file_operations mbox_operations = {
+ .owner = THIS_MODULE,
+ .open = mbox_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+#endif
+
+static irqreturn_t mbox_irq(int irq, void *arg)
+{
+ u32 mbox_value;
+ int nbr_occup;
+ int nbr_free;
+ struct mbox *mbox = (struct mbox *) arg;
+
+ spin_lock(&mbox->lock);
+
+ dev_dbg(&(mbox->pdev->dev),
+ "mbox IRQ [%d] received. ri = %d, wi = %d\n",
+ irq, mbox->read_index, mbox->write_index);
+
+ /*
+ * Check if we have any outgoing messages, and if there is space for
+ * them in the FIFO.
+ */
+ if (mbox->read_index != mbox->write_index) {
+ /*
+ * Check by reading FREE for LOCAL since that indicates
+ * OCCUP for PEER
+ */
+ nbr_free = (readl(mbox->virtbase_local + MBOX_FIFO_STATUS)
+ >> 4) & 0x7;
+ dev_dbg(&(mbox->pdev->dev),
+ "Status indicates %d empty spaces in the FIFO!\n",
+ nbr_free);
+
+ while ((nbr_free > 0) &&
+ (mbox->read_index != mbox->write_index)) {
+ /* Write the message and latch it into the FIFO */
+ writel(mbox->buffer[mbox->read_index],
+ (mbox->virtbase_peer + MBOX_FIFO_DATA));
+ writel(MBOX_LATCH,
+ (mbox->virtbase_peer + MBOX_FIFO_ADD));
+ dev_dbg(&(mbox->pdev->dev),
+ "Wrote message 0x%X to addr 0x%X\n",
+ mbox->buffer[mbox->read_index],
+ (u32) (mbox->virtbase_peer + MBOX_FIFO_DATA));
+
+ nbr_free--;
+ mbox->read_index =
+ (mbox->read_index + 1) % MBOX_BUF_SIZE;
+ }
+
+ /*
+ * Check if we still want IRQ:s when there is free
+ * space to send
+ */
+ if (mbox->read_index != mbox->write_index) {
+ dev_dbg(&(mbox->pdev->dev),
+ "Still have messages to send, but FIFO full. "
+ "Request IRQ again!\n");
+ writel(MBOX_ENABLE_IRQ,
+ mbox->virtbase_peer + MBOX_FIFO_THRES_FREE);
+ } else {
+ dev_dbg(&(mbox->pdev->dev),
+ "No more messages to send. "
+ "Do not request IRQ again!\n");
+ writel(MBOX_DISABLE_IRQ,
+ mbox->virtbase_peer + MBOX_FIFO_THRES_FREE);
+ }
+
+ /*
+ * Check if we can signal any blocked clients that it is OK to
+ * start buffering again
+ */
+ if (mbox->client_blocked &&
+ (((mbox->write_index + 1) % MBOX_BUF_SIZE)
+ != mbox->read_index)) {
+ dev_dbg(&(mbox->pdev->dev),
+ "Waking up blocked client\n");
+ complete(&mbox->buffer_available);
+ mbox->client_blocked = 0;
+ }
+ }
+
+ /* Check if we have any incoming messages */
+ nbr_occup = readl(mbox->virtbase_local + MBOX_FIFO_STATUS) & 0x7;
+ if (nbr_occup == 0)
+ goto exit;
+
+ if (mbox->cb == NULL) {
+ dev_dbg(&(mbox->pdev->dev), "No receive callback registered, "
+ "leaving %d incoming messages in fifo!\n", nbr_occup);
+ goto exit;
+ }
+
+ /* Read and acknowledge the message */
+ mbox_value = readl(mbox->virtbase_local + MBOX_FIFO_DATA);
+ writel(MBOX_LATCH, (mbox->virtbase_local + MBOX_FIFO_REMOVE));
+
+ /* Notify consumer of new mailbox message */
+ dev_dbg(&(mbox->pdev->dev), "Calling callback for message 0x%X!\n",
+ mbox_value);
+ mbox->cb(mbox_value, mbox->client_data);
+
+exit:
+ dev_dbg(&(mbox->pdev->dev), "Exit mbox IRQ. ri = %d, wi = %d\n",
+ mbox->read_index, mbox->write_index);
+ spin_unlock(&mbox->lock);
+
+ return IRQ_HANDLED;
+}
+
+/* Setup is executed once for each mbox pair */
+struct mbox *mbox_setup(u8 mbox_id, mbox_recv_cb_t *mbox_cb, void *priv)
+{
+ struct resource *resource;
+ int irq;
+ int res;
+ struct mbox *mbox;
+
+ mbox = get_mbox_with_id(mbox_id);
+ if (mbox == NULL) {
+ dev_err(&(mbox->pdev->dev), "Incorrect mailbox id: %d!\n",
+ mbox_id);
+ goto exit;
+ }
+
+ /*
+ * Check if mailbox has been allocated to someone else,
+ * otherwise allocate it
+ */
+ if (mbox->allocated) {
+ dev_err(&(mbox->pdev->dev), "Mailbox number %d is busy!\n",
+ mbox_id);
+ mbox = NULL;
+ goto exit;
+ }
+ mbox->allocated = true;
+
+ dev_dbg(&(mbox->pdev->dev), "Initiating mailbox number %d: 0x%X...\n",
+ mbox_id, (u32)mbox);
+
+ mbox->client_data = priv;
+ mbox->cb = mbox_cb;
+
+ /* Get addr for peer mailbox and ioremap it */
+ resource = platform_get_resource_byname(mbox->pdev,
+ IORESOURCE_MEM,
+ "mbox_peer");
+ if (resource == NULL) {
+ dev_err(&(mbox->pdev->dev),
+ "Unable to retrieve mbox peer resource\n");
+ mbox = NULL;
+ goto exit;
+ }
+ dev_dbg(&(mbox->pdev->dev),
+ "Resource name: %s start: 0x%X, end: 0x%X\n",
+ resource->name, resource->start, resource->end);
+ mbox->virtbase_peer =
+ ioremap(resource->start, resource->end - resource->start);
+ if (!mbox->virtbase_peer) {
+ dev_err(&(mbox->pdev->dev), "Unable to ioremap peer mbox\n");
+ mbox = NULL;
+ goto exit;
+ }
+ dev_dbg(&(mbox->pdev->dev),
+ "ioremapped peer physical: (0x%X-0x%X) to virtual: 0x%X\n",
+ resource->start, resource->end, (u32) mbox->virtbase_peer);
+
+ /* Get addr for local mailbox and ioremap it */
+ resource = platform_get_resource_byname(mbox->pdev,
+ IORESOURCE_MEM,
+ "mbox_local");
+ if (resource == NULL) {
+ dev_err(&(mbox->pdev->dev),
+ "Unable to retrieve mbox local resource\n");
+ mbox = NULL;
+ goto exit;
+ }
+ dev_dbg(&(mbox->pdev->dev),
+ "Resource name: %s start: 0x%X, end: 0x%X\n",
+ resource->name, resource->start, resource->end);
+ mbox->virtbase_local =
+ ioremap(resource->start, resource->end - resource->start);
+ if (!mbox->virtbase_local) {
+ dev_err(&(mbox->pdev->dev), "Unable to ioremap local mbox\n");
+ mbox = NULL;
+ goto exit;
+ }
+ dev_dbg(&(mbox->pdev->dev),
+ "ioremapped local physical: (0x%X-0x%X) to virtual: 0x%X\n",
+ resource->start, resource->end, (u32) mbox->virtbase_peer);
+
+ init_completion(&mbox->buffer_available);
+ mbox->client_blocked = 0;
+
+ /* Get IRQ for mailbox and allocate it */
+ irq = platform_get_irq_byname(mbox->pdev, "mbox_irq");
+ if (irq < 0) {
+ dev_err(&(mbox->pdev->dev),
+ "Unable to retrieve mbox irq resource\n");
+ mbox = NULL;
+ goto exit;
+ }
+
+ dev_dbg(&(mbox->pdev->dev), "Allocating irq %d...\n", irq);
+ res = request_irq(irq, mbox_irq, 0, mbox->name, (void *) mbox);
+ if (res < 0) {
+ dev_err(&(mbox->pdev->dev),
+ "Unable to allocate mbox irq %d\n", irq);
+ mbox = NULL;
+ goto exit;
+ }
+
+ /* Set up mailbox to not launch IRQ on free space in mailbox */
+ writel(MBOX_DISABLE_IRQ, mbox->virtbase_peer + MBOX_FIFO_THRES_FREE);
+
+ /*
+ * Set up mailbox to launch IRQ on new message if we have
+ * a callback set. If not, do not raise IRQ, but keep message
+ * in FIFO for manual retrieval
+ */
+ if (mbox_cb != NULL)
+ writel(MBOX_ENABLE_IRQ,
+ mbox->virtbase_local + MBOX_FIFO_THRES_OCCUP);
+ else
+ writel(MBOX_DISABLE_IRQ,
+ mbox->virtbase_local + MBOX_FIFO_THRES_OCCUP);
+
+#if defined(CONFIG_DEBUG_FS)
+ res = device_create_file(&(mbox->pdev->dev), &dev_attr_fifo);
+ if (res != 0)
+ dev_warn(&(mbox->pdev->dev),
+ "Unable to create mbox sysfs entry");
+
+ (void) debugfs_create_file("mbox", S_IFREG | S_IRUGO, NULL,
+ NULL, &mbox_operations);
+#endif
+
+ dev_info(&(mbox->pdev->dev),
+ "Mailbox driver with index %d initated!\n", mbox_id);
+
+exit:
+ return mbox;
+}
+EXPORT_SYMBOL(mbox_setup);
+
+
+int __init mbox_probe(struct platform_device *pdev)
+{
+ struct mbox local_mbox;
+ struct mbox *mbox;
+ int res = 0;
+ dev_dbg(&(pdev->dev), "Probing mailbox (pdev = 0x%X)...\n", (u32) pdev);
+
+ memset(&local_mbox, 0x0, sizeof(struct mbox));
+
+ /* Associate our mbox data with the platform device */
+ res = platform_device_add_data(pdev,
+ (void *) &local_mbox,
+ sizeof(struct mbox));
+ if (res != 0) {
+ dev_err(&(pdev->dev),
+ "Unable to allocate driver platform data!\n");
+ goto exit;
+ }
+
+ mbox = (struct mbox *) pdev->dev.platform_data;
+ mbox->pdev = pdev;
+ mbox->write_index = 0;
+ mbox->read_index = 0;
+
+ INIT_LIST_HEAD(&(mbox->list));
+ list_add_tail(&(mbox->list), &mboxs);
+
+ sprintf(mbox->name, "%s", MBOX_NAME);
+ spin_lock_init(&mbox->lock);
+
+ dev_info(&(pdev->dev), "Mailbox driver loaded\n");
+
+exit:
+ return res;
+}
+
+static struct platform_driver mbox_driver = {
+ .driver = {
+ .name = MBOX_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init mbox_init(void)
+{
+ return platform_driver_probe(&mbox_driver, mbox_probe);
+}
+
+module_init(mbox_init);
+
+void __exit mbox_exit(void)
+{
+ platform_driver_unregister(&mbox_driver);
+}
+
+module_exit(mbox_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MBOX driver");
diff --git a/arch/arm/mach-ux500/modem_irq.c b/arch/arm/mach-ux500/modem_irq.c
new file mode 100644
index 000000000000..3187f8871169
--- /dev/null
+++ b/arch/arm/mach-ux500/modem_irq.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Author: Stefan Nilsson <stefan.xk.nilsson@stericsson.com> for ST-Ericsson.
+ * Author: Martin Persson <martin.persson@stericsson.com> for ST-Ericsson.
+ * License terms: GNU General Public License (GPL), version 2.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#define MODEM_INTCON_BASE_ADDR 0xBFFD3000
+#define MODEM_INTCON_SIZE 0xFFF
+
+#define DEST_IRQ41_OFFSET 0x2A4
+#define DEST_IRQ43_OFFSET 0x2AC
+#define DEST_IRQ45_OFFSET 0x2B4
+
+#define PRIO_IRQ41_OFFSET 0x6A4
+#define PRIO_IRQ43_OFFSET 0x6AC
+#define PRIO_IRQ45_OFFSET 0x6B4
+
+#define ALLOW_IRQ_OFFSET 0x104
+
+#define MODEM_INTCON_CPU_NBR 0x1
+#define MODEM_INTCON_PRIO_HIGH 0x0
+
+#define MODEM_INTCON_ALLOW_IRQ41 0x0200
+#define MODEM_INTCON_ALLOW_IRQ43 0x0800
+#define MODEM_INTCON_ALLOW_IRQ45 0x2000
+
+#define MODEM_IRQ_REG_OFFSET 0x4
+
+struct modem_irq {
+ void __iomem *modem_intcon_base;
+};
+
+
+static void setup_modem_intcon(void __iomem *modem_intcon_base)
+{
+ /* IC_DESTINATION_BASE_ARRAY - Which CPU to receive the IRQ */
+ writel(MODEM_INTCON_CPU_NBR, modem_intcon_base + DEST_IRQ41_OFFSET);
+ writel(MODEM_INTCON_CPU_NBR, modem_intcon_base + DEST_IRQ43_OFFSET);
+ writel(MODEM_INTCON_CPU_NBR, modem_intcon_base + DEST_IRQ45_OFFSET);
+
+ /* IC_PRIORITY_BASE_ARRAY - IRQ priority in modem IRQ controller */
+ writel(MODEM_INTCON_PRIO_HIGH, modem_intcon_base + PRIO_IRQ41_OFFSET);
+ writel(MODEM_INTCON_PRIO_HIGH, modem_intcon_base + PRIO_IRQ43_OFFSET);
+ writel(MODEM_INTCON_PRIO_HIGH, modem_intcon_base + PRIO_IRQ45_OFFSET);
+
+ /* IC_ALLOW_ARRAY - IRQ enable */
+ writel(MODEM_INTCON_ALLOW_IRQ41 |
+ MODEM_INTCON_ALLOW_IRQ43 |
+ MODEM_INTCON_ALLOW_IRQ45,
+ modem_intcon_base + ALLOW_IRQ_OFFSET);
+}
+
+static irqreturn_t modem_cpu_irq_handler(int irq, void *data)
+{
+ int real_irq;
+ int virt_irq;
+ struct modem_irq *mi = (struct modem_irq *)data;
+
+ /* Read modem side IRQ number from modem IRQ controller */
+ real_irq = readl(mi->modem_intcon_base + MODEM_IRQ_REG_OFFSET) & 0xFF;
+ virt_irq = IRQ_MODEM_EVENTS_BASE + real_irq;
+
+ pr_debug("modem_irq: Worker read addr 0x%X and got value 0x%X "
+ "which will be 0x%X (%d) which translates to "
+ "virtual IRQ 0x%X (%d)!\n",
+ (u32)mi->modem_intcon_base + MODEM_IRQ_REG_OFFSET,
+ real_irq,
+ real_irq & 0xFF,
+ real_irq & 0xFF,
+ virt_irq,
+ virt_irq);
+
+ if (virt_irq != 0)
+ generic_handle_irq(virt_irq);
+
+ pr_debug("modem_irq: Done handling virtual IRQ %d!\n", virt_irq);
+
+ return IRQ_HANDLED;
+}
+
+static void create_virtual_irq(int irq, struct irq_chip *modem_irq_chip)
+{
+ set_irq_chip(irq, modem_irq_chip);
+ set_irq_handler(irq, handle_simple_irq);
+ set_irq_flags(irq, IRQF_VALID);
+
+ pr_debug("modem_irq: Created virtual IRQ %d\n", irq);
+}
+
+static int modem_irq_init(void)
+{
+ int err;
+ static struct irq_chip modem_irq_chip;
+ struct modem_irq *mi;
+
+ pr_info("modem_irq: Set up IRQ handler for incoming modem IRQ %d\n",
+ IRQ_DB5500_MODEM);
+
+ mi = kmalloc(sizeof(struct modem_irq), GFP_KERNEL);
+ if (!mi) {
+ pr_err("modem_irq: Could not allocate device\n");
+ return -ENOMEM;
+ }
+
+ mi->modem_intcon_base =
+ ioremap(MODEM_INTCON_BASE_ADDR, MODEM_INTCON_SIZE);
+ pr_debug("modem_irq: ioremapped modem_intcon_base from "
+ "phy 0x%x to virt 0x%x\n", MODEM_INTCON_BASE_ADDR,
+ (u32)mi->modem_intcon_base);
+
+ setup_modem_intcon(mi->modem_intcon_base);
+
+ modem_irq_chip = dummy_irq_chip;
+ modem_irq_chip.name = "modem_irq";
+
+ /* Create the virtual IRQ:s needed */
+ create_virtual_irq(MBOX_PAIR0_VIRT_IRQ, &modem_irq_chip);
+ create_virtual_irq(MBOX_PAIR1_VIRT_IRQ, &modem_irq_chip);
+ create_virtual_irq(MBOX_PAIR2_VIRT_IRQ, &modem_irq_chip);
+
+ err = request_threaded_irq(IRQ_DB5500_MODEM, NULL,
+ modem_cpu_irq_handler, IRQF_ONESHOT,
+ "modem_irq", mi);
+ if (err)
+ pr_err("modem_irq: Could not register IRQ %d\n",
+ IRQ_DB5500_MODEM);
+
+ return 0;
+}
+
+arch_initcall(modem_irq_init);
diff --git a/arch/arm/mach-ux500/pins-db5500.h b/arch/arm/mach-ux500/pins-db5500.h
new file mode 100644
index 000000000000..bf50c21fe69d
--- /dev/null
+++ b/arch/arm/mach-ux500/pins-db5500.h
@@ -0,0 +1,620 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License terms: GNU General Public License, version 2
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com>
+ */
+
+#ifndef __MACH_DB5500_PINS_H
+#define __MACH_DB5500_PINS_H
+
+#define GPIO0_GPIO PIN_CFG(0, GPIO)
+#define GPIO0_SM_CS3n PIN_CFG(0, ALT_A)
+
+#define GPIO1_GPIO PIN_CFG(1, GPIO)
+#define GPIO1_SM_A3 PIN_CFG(1, ALT_A)
+
+#define GPIO2_GPIO PIN_CFG(2, GPIO)
+#define GPIO2_SM_A4 PIN_CFG(2, ALT_A)
+#define GPIO2_SM_AVD PIN_CFG(2, ALT_B)
+
+#define GPIO3_GPIO PIN_CFG(3, GPIO)
+#define GPIO3_I2C1_SCL PIN_CFG(3, ALT_A)
+
+#define GPIO4_GPIO PIN_CFG(4, GPIO)
+#define GPIO4_I2C1_SDA PIN_CFG(4, ALT_A)
+
+#define GPIO5_GPIO PIN_CFG(5, GPIO)
+#define GPIO5_MC0_DAT0 PIN_CFG(5, ALT_A)
+#define GPIO5_SM_ADQ8 PIN_CFG(5, ALT_B)
+
+#define GPIO6_GPIO PIN_CFG(6, GPIO)
+#define GPIO6_MC0_DAT1 PIN_CFG(6, ALT_A)
+#define GPIO6_SM_ADQ0 PIN_CFG(6, ALT_B)
+
+#define GPIO7_GPIO PIN_CFG(7, GPIO)
+#define GPIO7_MC0_DAT2 PIN_CFG(7, ALT_A)
+#define GPIO7_SM_ADQ9 PIN_CFG(7, ALT_B)
+
+#define GPIO8_GPIO PIN_CFG(8, GPIO)
+#define GPIO8_MC0_DAT3 PIN_CFG(8, ALT_A)
+#define GPIO8_SM_ADQ1 PIN_CFG(8, ALT_B)
+
+#define GPIO9_GPIO PIN_CFG(9, GPIO)
+#define GPIO9_MC0_DAT4 PIN_CFG(9, ALT_A)
+#define GPIO9_SM_ADQ10 PIN_CFG(9, ALT_B)
+
+#define GPIO10_GPIO PIN_CFG(10, GPIO)
+#define GPIO10_MC0_DAT5 PIN_CFG(10, ALT_A)
+#define GPIO10_SM_ADQ2 PIN_CFG(10, ALT_B)
+
+#define GPIO11_GPIO PIN_CFG(11, GPIO)
+#define GPIO11_MC0_DAT6 PIN_CFG(11, ALT_A)
+#define GPIO11_SM_ADQ11 PIN_CFG(11, ALT_B)
+
+#define GPIO12_GPIO PIN_CFG(12, GPIO)
+#define GPIO12_MC0_DAT7 PIN_CFG(12, ALT_A)
+#define GPIO12_SM_ADQ3 PIN_CFG(12, ALT_B)
+
+#define GPIO13_GPIO PIN_CFG(13, GPIO)
+#define GPIO13_MC0_CMD PIN_CFG(13, ALT_A)
+#define GPIO13_SM_BUSY0n PIN_CFG(13, ALT_B)
+#define GPIO13_SM_WAIT0n PIN_CFG(13, ALT_C)
+
+#define GPIO14_GPIO PIN_CFG(14, GPIO)
+#define GPIO14_MC0_CLK PIN_CFG(14, ALT_A)
+#define GPIO14_SM_CS1n PIN_CFG(14, ALT_B)
+#define GPIO14_SM_CKO PIN_CFG(14, ALT_C)
+
+#define GPIO15_GPIO PIN_CFG(15, GPIO)
+#define GPIO15_SM_A5 PIN_CFG(15, ALT_A)
+#define GPIO15_SM_CLE PIN_CFG(15, ALT_B)
+
+#define GPIO16_GPIO PIN_CFG(16, GPIO)
+#define GPIO16_MC2_CMD PIN_CFG(16, ALT_A)
+#define GPIO16_SM_OEn PIN_CFG(16, ALT_B)
+
+#define GPIO17_GPIO PIN_CFG(17, GPIO)
+#define GPIO17_MC2_CLK PIN_CFG(17, ALT_A)
+#define GPIO17_SM_WEn PIN_CFG(17, ALT_B)
+
+#define GPIO18_GPIO PIN_CFG(18, GPIO)
+#define GPIO18_SM_A6 PIN_CFG(18, ALT_A)
+#define GPIO18_SM_ALE PIN_CFG(18, ALT_B)
+#define GPIO18_SM_AVDn PIN_CFG(18, ALT_C)
+
+#define GPIO19_GPIO PIN_CFG(19, GPIO)
+#define GPIO19_MC2_DAT1 PIN_CFG(19, ALT_A)
+#define GPIO19_SM_ADQ4 PIN_CFG(19, ALT_B)
+
+#define GPIO20_GPIO PIN_CFG(20, GPIO)
+#define GPIO20_MC2_DAT3 PIN_CFG(20, ALT_A)
+#define GPIO20_SM_ADQ5 PIN_CFG(20, ALT_B)
+
+#define GPIO21_GPIO PIN_CFG(21, GPIO)
+#define GPIO21_MC2_DAT5 PIN_CFG(21, ALT_A)
+#define GPIO21_SM_ADQ6 PIN_CFG(21, ALT_B)
+
+#define GPIO22_GPIO PIN_CFG(22, GPIO)
+#define GPIO22_MC2_DAT7 PIN_CFG(22, ALT_A)
+#define GPIO22_SM_ADQ7 PIN_CFG(22, ALT_B)
+
+#define GPIO23_GPIO PIN_CFG(23, GPIO)
+#define GPIO23_MC2_DAT0 PIN_CFG(23, ALT_A)
+#define GPIO23_SM_ADQ12 PIN_CFG(23, ALT_B)
+#define GPIO23_MC0_DAT1 PIN_CFG(23, ALT_C)
+
+#define GPIO24_GPIO PIN_CFG(24, GPIO)
+#define GPIO24_MC2_DAT2 PIN_CFG(24, ALT_A)
+#define GPIO24_SM_ADQ13 PIN_CFG(24, ALT_B)
+#define GPIO24_MC0_DAT3 PIN_CFG(24, ALT_C)
+
+#define GPIO25_GPIO PIN_CFG(25, GPIO)
+#define GPIO25_MC2_DAT4 PIN_CFG(25, ALT_A)
+#define GPIO25_SM_ADQ14 PIN_CFG(25, ALT_B)
+#define GPIO25_MC0_CMD PIN_CFG(25, ALT_C)
+
+#define GPIO26_GPIO PIN_CFG(26, GPIO)
+#define GPIO26_MC2_DAT6 PIN_CFG(26, ALT_A)
+#define GPIO26_SM_ADQ15 PIN_CFG(26, ALT_B)
+
+#define GPIO27_GPIO PIN_CFG(27, GPIO)
+#define GPIO27_SM_CS0n PIN_CFG(27, ALT_A)
+#define GPIO27_SM_PS0n PIN_CFG(27, ALT_B)
+
+#define GPIO28_GPIO PIN_CFG(28, GPIO)
+#define GPIO28_U0_TXD PIN_CFG(28, ALT_A)
+#define GPIO28_SM_A0 PIN_CFG(28, ALT_B)
+
+#define GPIO29_GPIO PIN_CFG(29, GPIO)
+#define GPIO29_U0_RXD PIN_CFG(29, ALT_A)
+#define GPIO29_SM_A1 PIN_CFG(29, ALT_B)
+#define GPIO29_PWM_0 PIN_CFG(29, ALT_C)
+
+#define GPIO30_GPIO PIN_CFG(30, GPIO)
+#define GPIO30_MC0_DAT5 PIN_CFG(30, ALT_A)
+#define GPIO30_SM_A2 PIN_CFG(30, ALT_B)
+#define GPIO30_PWM_1 PIN_CFG(30, ALT_C)
+
+#define GPIO31_GPIO PIN_CFG(31, GPIO)
+#define GPIO31_MC0_DAT7 PIN_CFG(31, ALT_A)
+#define GPIO31_SM_CS2n PIN_CFG(31, ALT_B)
+#define GPIO31_PWM_2 PIN_CFG(31, ALT_C)
+
+#define GPIO32_GPIO PIN_CFG(32, GPIO)
+#define GPIO32_MSP0_TCK PIN_CFG(32, ALT_A)
+#define GPIO32_ACCI2S0_SCK PIN_CFG(32, ALT_B)
+
+#define GPIO33_GPIO PIN_CFG(33, GPIO)
+#define GPIO33_MSP0_TFS PIN_CFG(33, ALT_A)
+#define GPIO33_ACCI2S0_WS PIN_CFG(33, ALT_B)
+
+#define GPIO34_GPIO PIN_CFG(34, GPIO)
+#define GPIO34_MSP0_TXD PIN_CFG(34, ALT_A)
+#define GPIO34_ACCI2S0_DLD PIN_CFG(34, ALT_B)
+
+#define GPIO35_GPIO PIN_CFG(35, GPIO)
+#define GPIO35_MSP0_RXD PIN_CFG(35, ALT_A)
+#define GPIO35_ACCI2S0_ULD PIN_CFG(35, ALT_B)
+
+#define GPIO64_GPIO PIN_CFG(64, GPIO)
+#define GPIO64_USB_DAT0 PIN_CFG(64, ALT_A)
+#define GPIO64_U0_TXD PIN_CFG(64, ALT_B)
+
+#define GPIO65_GPIO PIN_CFG(65, GPIO)
+#define GPIO65_USB_DAT1 PIN_CFG(65, ALT_A)
+#define GPIO65_U0_RXD PIN_CFG(65, ALT_B)
+
+#define GPIO66_GPIO PIN_CFG(66, GPIO)
+#define GPIO66_USB_DAT2 PIN_CFG(66, ALT_A)
+
+#define GPIO67_GPIO PIN_CFG(67, GPIO)
+#define GPIO67_USB_DAT3 PIN_CFG(67, ALT_A)
+
+#define GPIO68_GPIO PIN_CFG(68, GPIO)
+#define GPIO68_USB_DAT4 PIN_CFG(68, ALT_A)
+
+#define GPIO69_GPIO PIN_CFG(69, GPIO)
+#define GPIO69_USB_DAT5 PIN_CFG(69, ALT_A)
+
+#define GPIO70_GPIO PIN_CFG(70, GPIO)
+#define GPIO70_USB_DAT6 PIN_CFG(70, ALT_A)
+
+#define GPIO71_GPIO PIN_CFG(71, GPIO)
+#define GPIO71_USB_DAT7 PIN_CFG(71, ALT_A)
+
+#define GPIO72_GPIO PIN_CFG(72, GPIO)
+#define GPIO72_USB_STP PIN_CFG(72, ALT_A)
+
+#define GPIO73_GPIO PIN_CFG(73, GPIO)
+#define GPIO73_USB_DIR PIN_CFG(73, ALT_A)
+
+#define GPIO74_GPIO PIN_CFG(74, GPIO)
+#define GPIO74_USB_NXT PIN_CFG(74, ALT_A)
+
+#define GPIO75_GPIO PIN_CFG(75, GPIO)
+#define GPIO75_USB_XCLK PIN_CFG(75, ALT_A)
+
+#define GPIO76_GPIO PIN_CFG(76, GPIO)
+
+#define GPIO77_GPIO PIN_CFG(77, GPIO)
+#define GPIO77_ACCTX_ON PIN_CFG(77, ALT_A)
+
+#define GPIO78_GPIO PIN_CFG(78, GPIO)
+#define GPIO78_IRQn PIN_CFG(78, ALT_A)
+
+#define GPIO79_GPIO PIN_CFG(79, GPIO)
+#define GPIO79_ACCSIM_Clk PIN_CFG(79, ALT_A)
+
+#define GPIO80_GPIO PIN_CFG(80, GPIO)
+#define GPIO80_ACCSIM_Da PIN_CFG(80, ALT_A)
+
+#define GPIO81_GPIO PIN_CFG(81, GPIO)
+#define GPIO81_ACCSIM_Reset PIN_CFG(81, ALT_A)
+
+#define GPIO82_GPIO PIN_CFG(82, GPIO)
+#define GPIO82_ACCSIM_DDir PIN_CFG(82, ALT_A)
+
+#define GPIO96_GPIO PIN_CFG(96, GPIO)
+#define GPIO96_MSP1_TCK PIN_CFG(96, ALT_A)
+#define GPIO96_PRCMU_DEBUG3 PIN_CFG(96, ALT_B)
+#define GPIO96_PRCMU_DEBUG7 PIN_CFG(96, ALT_C)
+
+#define GPIO97_GPIO PIN_CFG(97, GPIO)
+#define GPIO97_MSP1_TFS PIN_CFG(97, ALT_A)
+#define GPIO97_PRCMU_DEBUG2 PIN_CFG(97, ALT_B)
+#define GPIO97_PRCMU_DEBUG6 PIN_CFG(97, ALT_C)
+
+#define GPIO98_GPIO PIN_CFG(98, GPIO)
+#define GPIO98_MSP1_TXD PIN_CFG(98, ALT_A)
+#define GPIO98_PRCMU_DEBUG1 PIN_CFG(98, ALT_B)
+#define GPIO98_PRCMU_DEBUG5 PIN_CFG(98, ALT_C)
+
+#define GPIO99_GPIO PIN_CFG(99, GPIO)
+#define GPIO99_MSP1_RXD PIN_CFG(99, ALT_A)
+#define GPIO99_PRCMU_DEBUG0 PIN_CFG(99, ALT_B)
+#define GPIO99_PRCMU_DEBUG4 PIN_CFG(99, ALT_C)
+
+#define GPIO100_GPIO PIN_CFG(100, GPIO)
+#define GPIO100_I2C0_SCL PIN_CFG(100, ALT_A)
+
+#define GPIO101_GPIO PIN_CFG(101, GPIO)
+#define GPIO101_I2C0_SDA PIN_CFG(101, ALT_A)
+
+#define GPIO128_GPIO PIN_CFG(128, GPIO)
+#define GPIO128_KP_I0 PIN_CFG(128, ALT_A)
+#define GPIO128_BUSMON_D0 PIN_CFG(128, ALT_B)
+
+#define GPIO129_GPIO PIN_CFG(129, GPIO)
+#define GPIO129_KP_O0 PIN_CFG(129, ALT_A)
+#define GPIO129_BUSMON_D1 PIN_CFG(129, ALT_B)
+
+#define GPIO130_GPIO PIN_CFG(130, GPIO)
+#define GPIO130_KP_I1 PIN_CFG(130, ALT_A)
+#define GPIO130_BUSMON_D2 PIN_CFG(130, ALT_B)
+
+#define GPIO131_GPIO PIN_CFG(131, GPIO)
+#define GPIO131_KP_O1 PIN_CFG(131, ALT_A)
+#define GPIO131_BUSMON_D3 PIN_CFG(131, ALT_B)
+
+#define GPIO132_GPIO PIN_CFG(132, GPIO)
+#define GPIO132_KP_I2 PIN_CFG(132, ALT_A)
+#define GPIO132_ETM_D15 PIN_CFG(132, ALT_B)
+#define GPIO132_STMAPE_CLK PIN_CFG(132, ALT_C)
+
+#define GPIO133_GPIO PIN_CFG(133, GPIO)
+#define GPIO133_KP_O2 PIN_CFG(133, ALT_A)
+#define GPIO133_ETM_D14 PIN_CFG(133, ALT_B)
+#define GPIO133_U0_RXD PIN_CFG(133, ALT_C)
+
+#define GPIO134_GPIO PIN_CFG(134, GPIO)
+#define GPIO134_KP_I3 PIN_CFG(134, ALT_A)
+#define GPIO134_ETM_D13 PIN_CFG(134, ALT_B)
+#define GPIO134_STMAPE_DAT0 PIN_CFG(134, ALT_C)
+
+#define GPIO135_GPIO PIN_CFG(135, GPIO)
+#define GPIO135_KP_O3 PIN_CFG(135, ALT_A)
+#define GPIO135_ETM_D12 PIN_CFG(135, ALT_B)
+#define GPIO135_STMAPE_DAT1 PIN_CFG(135, ALT_C)
+
+#define GPIO136_GPIO PIN_CFG(136, GPIO)
+#define GPIO136_KP_I4 PIN_CFG(136, ALT_A)
+#define GPIO136_ETM_D11 PIN_CFG(136, ALT_B)
+#define GPIO136_STMAPE_DAT2 PIN_CFG(136, ALT_C)
+
+#define GPIO137_GPIO PIN_CFG(137, GPIO)
+#define GPIO137_KP_O4 PIN_CFG(137, ALT_A)
+#define GPIO137_ETM_D10 PIN_CFG(137, ALT_B)
+#define GPIO137_STMAPE_DAT3 PIN_CFG(137, ALT_C)
+
+#define GPIO138_GPIO PIN_CFG(138, GPIO)
+#define GPIO138_KP_I5 PIN_CFG(138, ALT_A)
+#define GPIO138_ETM_D9 PIN_CFG(138, ALT_B)
+#define GPIO138_U0_TXD PIN_CFG(138, ALT_C)
+
+#define GPIO139_GPIO PIN_CFG(139, GPIO)
+#define GPIO139_KP_O5 PIN_CFG(139, ALT_A)
+#define GPIO139_ETM_D8 PIN_CFG(139, ALT_B)
+#define GPIO139_BUSMON_D11 PIN_CFG(139, ALT_C)
+
+#define GPIO140_GPIO PIN_CFG(140, GPIO)
+#define GPIO140_KP_I6 PIN_CFG(140, ALT_A)
+#define GPIO140_ETM_D7 PIN_CFG(140, ALT_B)
+#define GPIO140_STMAPE_CLK PIN_CFG(140, ALT_C)
+
+#define GPIO141_GPIO PIN_CFG(141, GPIO)
+#define GPIO141_KP_O6 PIN_CFG(141, ALT_A)
+#define GPIO141_ETM_D6 PIN_CFG(141, ALT_B)
+#define GPIO141_U0_RXD PIN_CFG(141, ALT_C)
+
+#define GPIO142_GPIO PIN_CFG(142, GPIO)
+#define GPIO142_KP_I7 PIN_CFG(142, ALT_A)
+#define GPIO142_ETM_D5 PIN_CFG(142, ALT_B)
+#define GPIO142_STMAPE_DAT0 PIN_CFG(142, ALT_C)
+
+#define GPIO143_GPIO PIN_CFG(143, GPIO)
+#define GPIO143_KP_O7 PIN_CFG(143, ALT_A)
+#define GPIO143_ETM_D4 PIN_CFG(143, ALT_B)
+#define GPIO143_STMAPE_DAT1 PIN_CFG(143, ALT_C)
+
+#define GPIO144_GPIO PIN_CFG(144, GPIO)
+#define GPIO144_I2C3_SCL PIN_CFG(144, ALT_A)
+#define GPIO144_ETM_D3 PIN_CFG(144, ALT_B)
+#define GPIO144_STMAPE_DAT2 PIN_CFG(144, ALT_C)
+
+#define GPIO145_GPIO PIN_CFG(145, GPIO)
+#define GPIO145_I2C3_SDA PIN_CFG(145, ALT_A)
+#define GPIO145_ETM_D2 PIN_CFG(145, ALT_B)
+#define GPIO145_STMAPE_DAT3 PIN_CFG(145, ALT_C)
+
+#define GPIO146_GPIO PIN_CFG(146, GPIO)
+#define GPIO146_PWM_0 PIN_CFG(146, ALT_A)
+#define GPIO146_ETM_D1 PIN_CFG(146, ALT_B)
+
+#define GPIO147_GPIO PIN_CFG(147, GPIO)
+#define GPIO147_PWM_1 PIN_CFG(147, ALT_A)
+#define GPIO147_ETM_D0 PIN_CFG(147, ALT_B)
+
+#define GPIO148_GPIO PIN_CFG(148, GPIO)
+#define GPIO148_PWM_2 PIN_CFG(148, ALT_A)
+#define GPIO148_ETM_CLK PIN_CFG(148, ALT_B)
+
+#define GPIO160_GPIO PIN_CFG(160, GPIO)
+#define GPIO160_CLKOUT_REQn PIN_CFG(160, ALT_A)
+
+#define GPIO161_GPIO PIN_CFG(161, GPIO)
+#define GPIO161_CLKOUT_0 PIN_CFG(161, ALT_A)
+
+#define GPIO162_GPIO PIN_CFG(162, GPIO)
+#define GPIO162_CLKOUT_1 PIN_CFG(162, ALT_A)
+
+#define GPIO163_GPIO PIN_CFG(163, GPIO)
+
+#define GPIO164_GPIO PIN_CFG(164, GPIO)
+#define GPIO164_GPS_START PIN_CFG(164, ALT_A)
+
+#define GPIO165_GPIO PIN_CFG(165, GPIO)
+#define GPIO165_SPI1_CS2n PIN_CFG(165, ALT_A)
+#define GPIO165_U3_RXD PIN_CFG(165, ALT_B)
+#define GPIO165_BUSMON_D20 PIN_CFG(165, ALT_C)
+
+#define GPIO166_GPIO PIN_CFG(166, GPIO)
+#define GPIO166_SPI1_CS1n PIN_CFG(166, ALT_A)
+#define GPIO166_U3_TXD PIN_CFG(166, ALT_B)
+#define GPIO166_BUSMON_D21 PIN_CFG(166, ALT_C)
+
+#define GPIO167_GPIO PIN_CFG(167, GPIO)
+#define GPIO167_SPI1_CS0n PIN_CFG(167, ALT_A)
+#define GPIO167_U3_RTSn PIN_CFG(167, ALT_B)
+#define GPIO167_BUSMON_D22 PIN_CFG(167, ALT_C)
+
+#define GPIO168_GPIO PIN_CFG(168, GPIO)
+#define GPIO168_SPI1_RXD PIN_CFG(168, ALT_A)
+#define GPIO168_U3_CTSn PIN_CFG(168, ALT_B)
+#define GPIO168_BUSMON_D23 PIN_CFG(168, ALT_C)
+
+#define GPIO169_GPIO PIN_CFG(169, GPIO)
+#define GPIO169_SPI1_TXD PIN_CFG(169, ALT_A)
+#define GPIO169_DDR_RC PIN_CFG(169, ALT_B)
+#define GPIO169_BUSMON_D24 PIN_CFG(169, ALT_C)
+
+#define GPIO170_GPIO PIN_CFG(170, GPIO)
+#define GPIO170_SPI1_CLK PIN_CFG(170, ALT_A)
+
+#define GPIO171_GPIO PIN_CFG(171, GPIO)
+#define GPIO171_MC3_DAT0 PIN_CFG(171, ALT_A)
+#define GPIO171_SPI3_RXD PIN_CFG(171, ALT_B)
+#define GPIO171_BUSMON_D25 PIN_CFG(171, ALT_C)
+
+#define GPIO172_GPIO PIN_CFG(172, GPIO)
+#define GPIO172_MC3_DAT1 PIN_CFG(172, ALT_A)
+#define GPIO172_SPI3_CS1n PIN_CFG(172, ALT_B)
+#define GPIO172_BUSMON_D26 PIN_CFG(172, ALT_C)
+
+#define GPIO173_GPIO PIN_CFG(173, GPIO)
+#define GPIO173_MC3_DAT2 PIN_CFG(173, ALT_A)
+#define GPIO173_SPI3_CS2n PIN_CFG(173, ALT_B)
+#define GPIO173_BUSMON_D27 PIN_CFG(173, ALT_C)
+
+#define GPIO174_GPIO PIN_CFG(174, GPIO)
+#define GPIO174_MC3_DAT3 PIN_CFG(174, ALT_A)
+#define GPIO174_SPI3_CS0n PIN_CFG(174, ALT_B)
+#define GPIO174_BUSMON_D28 PIN_CFG(174, ALT_C)
+
+#define GPIO175_GPIO PIN_CFG(175, GPIO)
+#define GPIO175_MC3_CMD PIN_CFG(175, ALT_A)
+#define GPIO175_SPI3_TXD PIN_CFG(175, ALT_B)
+#define GPIO175_BUSMON_D29 PIN_CFG(175, ALT_C)
+
+#define GPIO176_GPIO PIN_CFG(176, GPIO)
+#define GPIO176_MC3_CLK PIN_CFG(176, ALT_A)
+#define GPIO176_SPI3_CLK PIN_CFG(176, ALT_B)
+
+#define GPIO177_GPIO PIN_CFG(177, GPIO)
+#define GPIO177_U2_RXD PIN_CFG(177, ALT_A)
+#define GPIO177_I2C3_SCL PIN_CFG(177, ALT_B)
+#define GPIO177_BUSMON_D30 PIN_CFG(177, ALT_C)
+
+#define GPIO178_GPIO PIN_CFG(178, GPIO)
+#define GPIO178_U2_TXD PIN_CFG(178, ALT_A)
+#define GPIO178_I2C3_SDA PIN_CFG(178, ALT_B)
+#define GPIO178_BUSMON_D31 PIN_CFG(178, ALT_C)
+
+#define GPIO179_GPIO PIN_CFG(179, GPIO)
+#define GPIO179_U2_CTSn PIN_CFG(179, ALT_A)
+#define GPIO179_U3_RXD PIN_CFG(179, ALT_B)
+#define GPIO179_BUSMON_D32 PIN_CFG(179, ALT_C)
+
+#define GPIO180_GPIO PIN_CFG(180, GPIO)
+#define GPIO180_U2_RTSn PIN_CFG(180, ALT_A)
+#define GPIO180_U3_TXD PIN_CFG(180, ALT_B)
+#define GPIO180_BUSMON_D33 PIN_CFG(180, ALT_C)
+
+#define GPIO185_GPIO PIN_CFG(185, GPIO)
+#define GPIO185_SPI3_CS2n PIN_CFG(185, ALT_A)
+#define GPIO185_MC4_DAT0 PIN_CFG(185, ALT_B)
+
+#define GPIO186_GPIO PIN_CFG(186, GPIO)
+#define GPIO186_SPI3_CS1n PIN_CFG(186, ALT_A)
+#define GPIO186_MC4_DAT1 PIN_CFG(186, ALT_B)
+
+#define GPIO187_GPIO PIN_CFG(187, GPIO)
+#define GPIO187_SPI3_CS0n PIN_CFG(187, ALT_A)
+#define GPIO187_MC4_DAT2 PIN_CFG(187, ALT_B)
+
+#define GPIO188_GPIO PIN_CFG(188, GPIO)
+#define GPIO188_SPI3_RXD PIN_CFG(188, ALT_A)
+#define GPIO188_MC4_DAT3 PIN_CFG(188, ALT_B)
+
+#define GPIO189_GPIO PIN_CFG(189, GPIO)
+#define GPIO189_SPI3_TXD PIN_CFG(189, ALT_A)
+#define GPIO189_MC4_CMD PIN_CFG(189, ALT_B)
+
+#define GPIO190_GPIO PIN_CFG(190, GPIO)
+#define GPIO190_SPI3_CLK PIN_CFG(190, ALT_A)
+#define GPIO190_MC4_CLK PIN_CFG(190, ALT_B)
+
+#define GPIO191_GPIO PIN_CFG(191, GPIO)
+#define GPIO191_MC1_DAT0 PIN_CFG(191, ALT_A)
+#define GPIO191_MC4_DAT4 PIN_CFG(191, ALT_B)
+#define GPIO191_STMAPE_DAT0 PIN_CFG(191, ALT_C)
+
+#define GPIO192_GPIO PIN_CFG(192, GPIO)
+#define GPIO192_MC1_DAT1 PIN_CFG(192, ALT_A)
+#define GPIO192_MC4_DAT5 PIN_CFG(192, ALT_B)
+#define GPIO192_STMAPE_DAT1 PIN_CFG(192, ALT_C)
+
+#define GPIO193_GPIO PIN_CFG(193, GPIO)
+#define GPIO193_MC1_DAT2 PIN_CFG(193, ALT_A)
+#define GPIO193_MC4_DAT6 PIN_CFG(193, ALT_B)
+#define GPIO193_STMAPE_DAT2 PIN_CFG(193, ALT_C)
+
+#define GPIO194_GPIO PIN_CFG(194, GPIO)
+#define GPIO194_MC1_DAT3 PIN_CFG(194, ALT_A)
+#define GPIO194_MC4_DAT7 PIN_CFG(194, ALT_B)
+#define GPIO194_STMAPE_DAT3 PIN_CFG(194, ALT_C)
+
+#define GPIO195_GPIO PIN_CFG(195, GPIO)
+#define GPIO195_MC1_CLK PIN_CFG(195, ALT_A)
+#define GPIO195_STMAPE_CLK PIN_CFG(195, ALT_B)
+#define GPIO195_BUSMON_CLK PIN_CFG(195, ALT_C)
+
+#define GPIO196_GPIO PIN_CFG(196, GPIO)
+#define GPIO196_MC1_CMD PIN_CFG(196, ALT_A)
+#define GPIO196_U0_RXD PIN_CFG(196, ALT_B)
+#define GPIO196_BUSMON_D38 PIN_CFG(196, ALT_C)
+
+#define GPIO197_GPIO PIN_CFG(197, GPIO)
+#define GPIO197_MC1_CMDDIR PIN_CFG(197, ALT_A)
+#define GPIO197_BUSMON_D39 PIN_CFG(197, ALT_B)
+
+#define GPIO198_GPIO PIN_CFG(198, GPIO)
+#define GPIO198_MC1_FBCLK PIN_CFG(198, ALT_A)
+
+#define GPIO199_GPIO PIN_CFG(199, GPIO)
+#define GPIO199_MC1_DAT0DIR PIN_CFG(199, ALT_A)
+#define GPIO199_BUSMON_D40 PIN_CFG(199, ALT_B)
+
+#define GPIO200_GPIO PIN_CFG(200, GPIO)
+#define GPIO200_U1_TXD PIN_CFG(200, ALT_A)
+#define GPIO200_ACCU0_RTSn PIN_CFG(200, ALT_B)
+
+#define GPIO201_GPIO PIN_CFG(201, GPIO)
+#define GPIO201_U1_RXD PIN_CFG(201, ALT_A)
+#define GPIO201_ACCU0_CTSn PIN_CFG(201, ALT_B)
+
+#define GPIO202_GPIO PIN_CFG(202, GPIO)
+#define GPIO202_U1_CTSn PIN_CFG(202, ALT_A)
+#define GPIO202_ACCU0_RXD PIN_CFG(202, ALT_B)
+
+#define GPIO203_GPIO PIN_CFG(203, GPIO)
+#define GPIO203_U1_RTSn PIN_CFG(203, ALT_A)
+#define GPIO203_ACCU0_TXD PIN_CFG(203, ALT_B)
+
+#define GPIO204_GPIO PIN_CFG(204, GPIO)
+#define GPIO204_SPI0_CS2n PIN_CFG(204, ALT_A)
+#define GPIO204_ACCGPIO_000 PIN_CFG(204, ALT_B)
+#define GPIO204_LCD_VSI1 PIN_CFG(204, ALT_C)
+
+#define GPIO205_GPIO PIN_CFG(205, GPIO)
+#define GPIO205_SPI0_CS1n PIN_CFG(205, ALT_A)
+#define GPIO205_ACCGPIO_001 PIN_CFG(205, ALT_B)
+#define GPIO205_LCD_D3 PIN_CFG(205, ALT_C)
+
+#define GPIO206_GPIO PIN_CFG(206, GPIO)
+#define GPIO206_SPI0_CS0n PIN_CFG(206, ALT_A)
+#define GPIO206_ACCGPIO_002 PIN_CFG(206, ALT_B)
+#define GPIO206_LCD_D2 PIN_CFG(206, ALT_C)
+
+#define GPIO207_GPIO PIN_CFG(207, GPIO)
+#define GPIO207_SPI0_RXD PIN_CFG(207, ALT_A)
+#define GPIO207_ACCGPIO_003 PIN_CFG(207, ALT_B)
+#define GPIO207_LCD_D1 PIN_CFG(207, ALT_C)
+
+#define GPIO208_GPIO PIN_CFG(208, GPIO)
+#define GPIO208_SPI0_TXD PIN_CFG(208, ALT_A)
+#define GPIO208_ACCGPIO_004 PIN_CFG(208, ALT_B)
+#define GPIO208_LCD_D0 PIN_CFG(208, ALT_C)
+
+#define GPIO209_GPIO PIN_CFG(209, GPIO)
+#define GPIO209_SPI0_CLK PIN_CFG(209, ALT_A)
+#define GPIO209_ACCGPIO_005 PIN_CFG(209, ALT_B)
+#define GPIO209_LCD_CLK PIN_CFG(209, ALT_C)
+
+#define GPIO210_GPIO PIN_CFG(210, GPIO)
+#define GPIO210_LCD_VSO PIN_CFG(210, ALT_A)
+#define GPIO210_PRCMU_PWRCTRL1 PIN_CFG(210, ALT_B)
+
+#define GPIO211_GPIO PIN_CFG(211, GPIO)
+#define GPIO211_LCD_VSI0 PIN_CFG(211, ALT_A)
+#define GPIO211_PRCMU_PWRCTRL2 PIN_CFG(211, ALT_B)
+
+#define GPIO212_GPIO PIN_CFG(212, GPIO)
+#define GPIO212_SPI2_CS2n PIN_CFG(212, ALT_A)
+#define GPIO212_LCD_HSO PIN_CFG(212, ALT_B)
+
+#define GPIO213_GPIO PIN_CFG(213, GPIO)
+#define GPIO213_SPI2_CS1n PIN_CFG(213, ALT_A)
+#define GPIO213_LCD_DE PIN_CFG(213, ALT_B)
+#define GPIO213_BUSMON_D16 PIN_CFG(213, ALT_C)
+
+#define GPIO214_GPIO PIN_CFG(214, GPIO)
+#define GPIO214_SPI2_CS0n PIN_CFG(214, ALT_A)
+#define GPIO214_LCD_D7 PIN_CFG(214, ALT_B)
+#define GPIO214_BUSMON_D17 PIN_CFG(214, ALT_C)
+
+#define GPIO215_GPIO PIN_CFG(215, GPIO)
+#define GPIO215_SPI2_RXD PIN_CFG(215, ALT_A)
+#define GPIO215_LCD_D6 PIN_CFG(215, ALT_B)
+#define GPIO215_BUSMON_D18 PIN_CFG(215, ALT_C)
+
+#define GPIO216_GPIO PIN_CFG(216, GPIO)
+#define GPIO216_SPI2_CLK PIN_CFG(216, ALT_A)
+#define GPIO216_LCD_D5 PIN_CFG(216, ALT_B)
+
+#define GPIO217_GPIO PIN_CFG(217, GPIO)
+#define GPIO217_SPI2_TXD PIN_CFG(217, ALT_A)
+#define GPIO217_LCD_D4 PIN_CFG(217, ALT_B)
+#define GPIO217_BUSMON_D19 PIN_CFG(217, ALT_C)
+
+#define GPIO218_GPIO PIN_CFG(218, GPIO)
+#define GPIO218_I2C2_SCL PIN_CFG(218, ALT_A)
+#define GPIO218_LCD_VSO PIN_CFG(218, ALT_B)
+
+#define GPIO219_GPIO PIN_CFG(219, GPIO)
+#define GPIO219_I2C2_SDA PIN_CFG(219, ALT_A)
+#define GPIO219_LCD_D3 PIN_CFG(219, ALT_B)
+
+#define GPIO220_GPIO PIN_CFG(220, GPIO)
+#define GPIO220_MSP2_TCK PIN_CFG(220, ALT_A)
+#define GPIO220_LCD_D2 PIN_CFG(220, ALT_B)
+
+#define GPIO221_GPIO PIN_CFG(221, GPIO)
+#define GPIO221_MSP2_TFS PIN_CFG(221, ALT_A)
+#define GPIO221_LCD_D1 PIN_CFG(221, ALT_B)
+
+#define GPIO222_GPIO PIN_CFG(222, GPIO)
+#define GPIO222_MSP2_TXD PIN_CFG(222, ALT_A)
+#define GPIO222_LCD_D0 PIN_CFG(222, ALT_B)
+
+#define GPIO223_GPIO PIN_CFG(223, GPIO)
+#define GPIO223_MSP2_RXD PIN_CFG(223, ALT_A)
+#define GPIO223_LCD_CLK PIN_CFG(223, ALT_B)
+
+#define GPIO224_GPIO PIN_CFG(224, GPIO)
+#define GPIO224_PRCMU_PWRCTRL0 PIN_CFG(224, ALT_A)
+#define GPIO224_LCD_VSI1 PIN_CFG(224, ALT_B)
+
+#define GPIO225_GPIO PIN_CFG(225, GPIO)
+#define GPIO225_PRCMU_PWRCTRL1 PIN_CFG(225, ALT_A)
+#define GPIO225_IRDA_RXD PIN_CFG(225, ALT_B)
+
+#define GPIO226_GPIO PIN_CFG(226, GPIO)
+#define GPIO226_PRCMU_PWRCTRL2 PIN_CFG(226, ALT_A)
+#define GPIO226_IRRC_DAT PIN_CFG(226, ALT_B)
+
+#define GPIO227_GPIO PIN_CFG(227, GPIO)
+#define GPIO227_IRRC_DAT PIN_CFG(227, ALT_A)
+#define GPIO227_IRDA_TXD PIN_CFG(227, ALT_B)
+
+#endif
diff --git a/arch/arm/mach-ux500/pins-db8500.h b/arch/arm/mach-ux500/pins-db8500.h
index 9055d5d3233c..f923764ee16c 100644
--- a/arch/arm/mach-ux500/pins-db8500.h
+++ b/arch/arm/mach-ux500/pins-db8500.h
@@ -96,57 +96,57 @@
#define GPIO17_SLIM0_CLK PIN_CFG(17, ALT_C)
#define GPIO18_GPIO PIN_CFG(18, GPIO)
-#define GPIO18_MC0_CMDDIR PIN_CFG(18, ALT_A)
+#define GPIO18_MC0_CMDDIR PIN_CFG_PULL(18, ALT_A, UP)
#define GPIO18_U2_RXD PIN_CFG(18, ALT_B)
#define GPIO18_MS_IEP PIN_CFG(18, ALT_C)
#define GPIO19_GPIO PIN_CFG(19, GPIO)
-#define GPIO19_MC0_DAT0DIR PIN_CFG(19, ALT_A)
+#define GPIO19_MC0_DAT0DIR PIN_CFG_PULL(19, ALT_A, UP)
#define GPIO19_U2_TXD PIN_CFG(19, ALT_B)
#define GPIO19_MS_DAT0DIR PIN_CFG(19, ALT_C)
#define GPIO20_GPIO PIN_CFG(20, GPIO)
-#define GPIO20_MC0_DAT2DIR PIN_CFG(20, ALT_A)
+#define GPIO20_MC0_DAT2DIR PIN_CFG_PULL(20, ALT_A, UP)
#define GPIO20_UARTMOD_TXD PIN_CFG(20, ALT_B)
#define GPIO20_IP_TRIGOUT PIN_CFG(20, ALT_C)
#define GPIO21_GPIO PIN_CFG(21, GPIO)
-#define GPIO21_MC0_DAT31DIR PIN_CFG(21, ALT_A)
+#define GPIO21_MC0_DAT31DIR PIN_CFG_PULL(21, ALT_A, UP)
#define GPIO21_MSP0_SCK PIN_CFG(21, ALT_B)
#define GPIO21_MS_DAT31DIR PIN_CFG(21, ALT_C)
#define GPIO22_GPIO PIN_CFG(22, GPIO)
-#define GPIO22_MC0_FBCLK PIN_CFG(22, ALT_A)
+#define GPIO22_MC0_FBCLK PIN_CFG_PULL(22, ALT_A, UP)
#define GPIO22_UARTMOD_RXD PIN_CFG(22, ALT_B)
#define GPIO22_MS_FBCLK PIN_CFG(22, ALT_C)
#define GPIO23_GPIO PIN_CFG(23, GPIO)
-#define GPIO23_MC0_CLK PIN_CFG(23, ALT_A)
+#define GPIO23_MC0_CLK PIN_CFG_PULL(23, ALT_A, UP)
#define GPIO23_STMMOD_CLK PIN_CFG(23, ALT_B)
#define GPIO23_MS_CLK PIN_CFG(23, ALT_C)
#define GPIO24_GPIO PIN_CFG(24, GPIO)
-#define GPIO24_MC0_CMD PIN_CFG(24, ALT_A)
+#define GPIO24_MC0_CMD PIN_CFG_PULL(24, ALT_A, UP)
#define GPIO24_UARTMOD_RXD PIN_CFG(24, ALT_B)
#define GPIO24_MS_BS PIN_CFG(24, ALT_C)
#define GPIO25_GPIO PIN_CFG(25, GPIO)
-#define GPIO25_MC0_DAT0 PIN_CFG(25, ALT_A)
+#define GPIO25_MC0_DAT0 PIN_CFG_PULL(25, ALT_A, UP)
#define GPIO25_STMMOD_DAT0 PIN_CFG(25, ALT_B)
#define GPIO25_MS_DAT0 PIN_CFG(25, ALT_C)
#define GPIO26_GPIO PIN_CFG(26, GPIO)
-#define GPIO26_MC0_DAT1 PIN_CFG(26, ALT_A)
+#define GPIO26_MC0_DAT1 PIN_CFG_PULL(26, ALT_A, UP)
#define GPIO26_STMMOD_DAT1 PIN_CFG(26, ALT_B)
#define GPIO26_MS_DAT1 PIN_CFG(26, ALT_C)
#define GPIO27_GPIO PIN_CFG(27, GPIO)
-#define GPIO27_MC0_DAT2 PIN_CFG(27, ALT_A)
+#define GPIO27_MC0_DAT2 PIN_CFG_PULL(27, ALT_A, UP)
#define GPIO27_STMMOD_DAT2 PIN_CFG(27, ALT_B)
#define GPIO27_MS_DAT2 PIN_CFG(27, ALT_C)
#define GPIO28_GPIO PIN_CFG(28, GPIO)
-#define GPIO28_MC0_DAT3 PIN_CFG(28, ALT_A)
+#define GPIO28_MC0_DAT3 PIN_CFG_PULL(28, ALT_A, UP)
#define GPIO28_STMMOD_DAT3 PIN_CFG(28, ALT_B)
#define GPIO28_MS_DAT3 PIN_CFG(28, ALT_C)
@@ -357,48 +357,48 @@
#define GPIO97_MC5_DAT7 PIN_CFG(97, ALT_C)
#define GPIO128_GPIO PIN_CFG(128, GPIO)
-#define GPIO128_MC2_CLK PIN_CFG(128, ALT_A)
+#define GPIO128_MC2_CLK PIN_CFG_PULL(128, ALT_A, UP)
#define GPIO128_SM_CKO PIN_CFG(128, ALT_B)
#define GPIO129_GPIO PIN_CFG(129, GPIO)
-#define GPIO129_MC2_CMD PIN_CFG(129, ALT_A)
+#define GPIO129_MC2_CMD PIN_CFG_PULL(129, ALT_A, UP)
#define GPIO129_SM_WAIT0n PIN_CFG(129, ALT_B)
#define GPIO130_GPIO PIN_CFG(130, GPIO)
-#define GPIO130_MC2_FBCLK PIN_CFG(130, ALT_A)
+#define GPIO130_MC2_FBCLK PIN_CFG_PULL(130, ALT_A, UP)
#define GPIO130_SM_FBCLK PIN_CFG(130, ALT_B)
#define GPIO130_MC2_RSTN PIN_CFG(130, ALT_C)
#define GPIO131_GPIO PIN_CFG(131, GPIO)
-#define GPIO131_MC2_DAT0 PIN_CFG(131, ALT_A)
+#define GPIO131_MC2_DAT0 PIN_CFG_PULL(131, ALT_A, UP)
#define GPIO131_SM_ADQ8 PIN_CFG(131, ALT_B)
#define GPIO132_GPIO PIN_CFG(132, GPIO)
-#define GPIO132_MC2_DAT1 PIN_CFG(132, ALT_A)
+#define GPIO132_MC2_DAT1 PIN_CFG_PULL(132, ALT_A, UP)
#define GPIO132_SM_ADQ9 PIN_CFG(132, ALT_B)
#define GPIO133_GPIO PIN_CFG(133, GPIO)
-#define GPIO133_MC2_DAT2 PIN_CFG(133, ALT_A)
+#define GPIO133_MC2_DAT2 PIN_CFG_PULL(133, ALT_A, UP)
#define GPIO133_SM_ADQ10 PIN_CFG(133, ALT_B)
#define GPIO134_GPIO PIN_CFG(134, GPIO)
-#define GPIO134_MC2_DAT3 PIN_CFG(134, ALT_A)
+#define GPIO134_MC2_DAT3 PIN_CFG_PULL(134, ALT_A, UP)
#define GPIO134_SM_ADQ11 PIN_CFG(134, ALT_B)
#define GPIO135_GPIO PIN_CFG(135, GPIO)
-#define GPIO135_MC2_DAT4 PIN_CFG(135, ALT_A)
+#define GPIO135_MC2_DAT4 PIN_CFG_PULL(135, ALT_A, UP)
#define GPIO135_SM_ADQ12 PIN_CFG(135, ALT_B)
#define GPIO136_GPIO PIN_CFG(136, GPIO)
-#define GPIO136_MC2_DAT5 PIN_CFG(136, ALT_A)
+#define GPIO136_MC2_DAT5 PIN_CFG_PULL(136, ALT_A, UP)
#define GPIO136_SM_ADQ13 PIN_CFG(136, ALT_B)
#define GPIO137_GPIO PIN_CFG(137, GPIO)
-#define GPIO137_MC2_DAT6 PIN_CFG(137, ALT_A)
+#define GPIO137_MC2_DAT6 PIN_CFG_PULL(137, ALT_A, UP)
#define GPIO137_SM_ADQ14 PIN_CFG(137, ALT_B)
#define GPIO138_GPIO PIN_CFG(138, GPIO)
-#define GPIO138_MC2_DAT7 PIN_CFG(138, ALT_A)
+#define GPIO138_MC2_DAT7 PIN_CFG_PULL(138, ALT_A, UP)
#define GPIO138_SM_ADQ15 PIN_CFG(138, ALT_B)
#define GPIO139_GPIO PIN_CFG(139, GPIO)
@@ -459,82 +459,82 @@
#define GPIO152_KP_O9 PIN_CFG(152, ALT_C)
#define GPIO153_GPIO PIN_CFG(153, GPIO)
-#define GPIO153_KP_I7 PIN_CFG(153, ALT_A)
+#define GPIO153_KP_I7 PIN_CFG_PULL(153, ALT_A, DOWN)
#define GPIO153_LCD_D24 PIN_CFG(153, ALT_B)
#define GPIO153_U2_RXD PIN_CFG(153, ALT_C)
#define GPIO154_GPIO PIN_CFG(154, GPIO)
-#define GPIO154_KP_I6 PIN_CFG(154, ALT_A)
+#define GPIO154_KP_I6 PIN_CFG_PULL(154, ALT_A, DOWN)
#define GPIO154_LCD_D25 PIN_CFG(154, ALT_B)
#define GPIO154_U2_TXD PIN_CFG(154, ALT_C)
#define GPIO155_GPIO PIN_CFG(155, GPIO)
-#define GPIO155_KP_I5 PIN_CFG(155, ALT_A)
+#define GPIO155_KP_I5 PIN_CFG_PULL(155, ALT_A, DOWN)
#define GPIO155_LCD_D26 PIN_CFG(155, ALT_B)
#define GPIO155_STMAPE_CLK PIN_CFG(155, ALT_C)
#define GPIO156_GPIO PIN_CFG(156, GPIO)
-#define GPIO156_KP_I4 PIN_CFG(156, ALT_A)
+#define GPIO156_KP_I4 PIN_CFG_PULL(156, ALT_A, DOWN)
#define GPIO156_LCD_D27 PIN_CFG(156, ALT_B)
#define GPIO156_STMAPE_DAT3 PIN_CFG(156, ALT_C)
#define GPIO157_GPIO PIN_CFG(157, GPIO)
-#define GPIO157_KP_O7 PIN_CFG(157, ALT_A)
+#define GPIO157_KP_O7 PIN_CFG_PULL(157, ALT_A, UP)
#define GPIO157_LCD_D28 PIN_CFG(157, ALT_B)
#define GPIO157_STMAPE_DAT2 PIN_CFG(157, ALT_C)
#define GPIO158_GPIO PIN_CFG(158, GPIO)
-#define GPIO158_KP_O6 PIN_CFG(158, ALT_A)
+#define GPIO158_KP_O6 PIN_CFG_PULL(158, ALT_A, UP)
#define GPIO158_LCD_D29 PIN_CFG(158, ALT_B)
#define GPIO158_STMAPE_DAT1 PIN_CFG(158, ALT_C)
#define GPIO159_GPIO PIN_CFG(159, GPIO)
-#define GPIO159_KP_O5 PIN_CFG(159, ALT_A)
+#define GPIO159_KP_O5 PIN_CFG_PULL(159, ALT_A, UP)
#define GPIO159_LCD_D30 PIN_CFG(159, ALT_B)
#define GPIO159_STMAPE_DAT0 PIN_CFG(159, ALT_C)
#define GPIO160_GPIO PIN_CFG(160, GPIO)
-#define GPIO160_KP_O4 PIN_CFG(160, ALT_A)
+#define GPIO160_KP_O4 PIN_CFG_PULL(160, ALT_A, UP)
#define GPIO160_LCD_D31 PIN_CFG(160, ALT_B)
#define GPIO160_NONE PIN_CFG(160, ALT_C)
#define GPIO161_GPIO PIN_CFG(161, GPIO)
-#define GPIO161_KP_I3 PIN_CFG(161, ALT_A)
+#define GPIO161_KP_I3 PIN_CFG_PULL(161, ALT_A, DOWN)
#define GPIO161_LCD_D32 PIN_CFG(161, ALT_B)
#define GPIO161_UARTMOD_RXD PIN_CFG(161, ALT_C)
#define GPIO162_GPIO PIN_CFG(162, GPIO)
-#define GPIO162_KP_I2 PIN_CFG(162, ALT_A)
+#define GPIO162_KP_I2 PIN_CFG_PULL(162, ALT_A, DOWN)
#define GPIO162_LCD_D33 PIN_CFG(162, ALT_B)
#define GPIO162_UARTMOD_TXD PIN_CFG(162, ALT_C)
#define GPIO163_GPIO PIN_CFG(163, GPIO)
-#define GPIO163_KP_I1 PIN_CFG(163, ALT_A)
+#define GPIO163_KP_I1 PIN_CFG_PULL(163, ALT_A, DOWN)
#define GPIO163_LCD_D34 PIN_CFG(163, ALT_B)
#define GPIO163_STMMOD_CLK PIN_CFG(163, ALT_C)
#define GPIO164_GPIO PIN_CFG(164, GPIO)
-#define GPIO164_KP_I0 PIN_CFG(164, ALT_A)
+#define GPIO164_KP_I0 PIN_CFG_PULL(164, ALT_A, UP)
#define GPIO164_LCD_D35 PIN_CFG(164, ALT_B)
#define GPIO164_STMMOD_DAT3 PIN_CFG(164, ALT_C)
#define GPIO165_GPIO PIN_CFG(165, GPIO)
-#define GPIO165_KP_O3 PIN_CFG(165, ALT_A)
+#define GPIO165_KP_O3 PIN_CFG_PULL(165, ALT_A, UP)
#define GPIO165_LCD_D36 PIN_CFG(165, ALT_B)
#define GPIO165_STMMOD_DAT2 PIN_CFG(165, ALT_C)
#define GPIO166_GPIO PIN_CFG(166, GPIO)
-#define GPIO166_KP_O2 PIN_CFG(166, ALT_A)
+#define GPIO166_KP_O2 PIN_CFG_PULL(166, ALT_A, UP)
#define GPIO166_LCD_D37 PIN_CFG(166, ALT_B)
#define GPIO166_STMMOD_DAT1 PIN_CFG(166, ALT_C)
#define GPIO167_GPIO PIN_CFG(167, GPIO)
-#define GPIO167_KP_O1 PIN_CFG(167, ALT_A)
+#define GPIO167_KP_O1 PIN_CFG_PULL(167, ALT_A, UP)
#define GPIO167_LCD_D38 PIN_CFG(167, ALT_B)
#define GPIO167_STMMOD_DAT0 PIN_CFG(167, ALT_C)
#define GPIO168_GPIO PIN_CFG(168, GPIO)
-#define GPIO168_KP_O0 PIN_CFG(168, ALT_A)
+#define GPIO168_KP_O0 PIN_CFG_PULL(168, ALT_A, UP)
#define GPIO168_LCD_D39 PIN_CFG(168, ALT_B)
#define GPIO168_NONE PIN_CFG(168, ALT_C)
@@ -569,39 +569,39 @@
#define GPIO196_MSP2_RXD PIN_CFG(196, ALT_A)
#define GPIO197_GPIO PIN_CFG(197, GPIO)
-#define GPIO197_MC4_DAT3 PIN_CFG(197, ALT_A)
+#define GPIO197_MC4_DAT3 PIN_CFG_PULL(197, ALT_A, UP)
#define GPIO198_GPIO PIN_CFG(198, GPIO)
-#define GPIO198_MC4_DAT2 PIN_CFG(198, ALT_A)
+#define GPIO198_MC4_DAT2 PIN_CFG_PULL(198, ALT_A, UP)
#define GPIO199_GPIO PIN_CFG(199, GPIO)
-#define GPIO199_MC4_DAT1 PIN_CFG(199, ALT_A)
+#define GPIO199_MC4_DAT1 PIN_CFG_PULL(199, ALT_A, UP)
#define GPIO200_GPIO PIN_CFG(200, GPIO)
-#define GPIO200_MC4_DAT0 PIN_CFG(200, ALT_A)
+#define GPIO200_MC4_DAT0 PIN_CFG_PULL(200, ALT_A, UP)
#define GPIO201_GPIO PIN_CFG(201, GPIO)
-#define GPIO201_MC4_CMD PIN_CFG(201, ALT_A)
+#define GPIO201_MC4_CMD PIN_CFG_PULL(201, ALT_A, UP)
#define GPIO202_GPIO PIN_CFG(202, GPIO)
-#define GPIO202_MC4_FBCLK PIN_CFG(202, ALT_A)
+#define GPIO202_MC4_FBCLK PIN_CFG_PULL(202, ALT_A, UP)
#define GPIO202_PWL PIN_CFG(202, ALT_B)
#define GPIO202_MC4_RSTN PIN_CFG(202, ALT_C)
#define GPIO203_GPIO PIN_CFG(203, GPIO)
-#define GPIO203_MC4_CLK PIN_CFG(203, ALT_A)
+#define GPIO203_MC4_CLK PIN_CFG_PULL(203, ALT_A, UP)
#define GPIO204_GPIO PIN_CFG(204, GPIO)
-#define GPIO204_MC4_DAT7 PIN_CFG(204, ALT_A)
+#define GPIO204_MC4_DAT7 PIN_CFG_PULL(204, ALT_A, UP)
#define GPIO205_GPIO PIN_CFG(205, GPIO)
-#define GPIO205_MC4_DAT6 PIN_CFG(205, ALT_A)
+#define GPIO205_MC4_DAT6 PIN_CFG_PULL(205, ALT_A, UP)
#define GPIO206_GPIO PIN_CFG(206, GPIO)
-#define GPIO206_MC4_DAT5 PIN_CFG(206, ALT_A)
+#define GPIO206_MC4_DAT5 PIN_CFG_PULL(206, ALT_A, UP)
#define GPIO207_GPIO PIN_CFG(207, GPIO)
-#define GPIO207_MC4_DAT4 PIN_CFG(207, ALT_A)
+#define GPIO207_MC4_DAT4 PIN_CFG_PULL(207, ALT_A, UP)
#define GPIO208_GPIO PIN_CFG(208, GPIO)
#define GPIO208_MC1_CLK PIN_CFG(208, ALT_A)
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c
index 438ef16aec90..9e4c678de785 100644
--- a/arch/arm/mach-ux500/platsmp.c
+++ b/arch/arm/mach-ux500/platsmp.c
@@ -78,6 +78,8 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
__cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
outer_clean_range(__pa(&pen_release), __pa(&pen_release) + 1);
+ smp_cross_call(cpumask_of(cpu));
+
timeout = jiffies + (1 * HZ);
while (time_before(jiffies, timeout)) {
if (pen_release == -1)
diff --git a/arch/arm/mach-ux500/prcmu.c b/arch/arm/mach-ux500/prcmu.c
new file mode 100644
index 000000000000..293274d1342a
--- /dev/null
+++ b/arch/arm/mach-ux500/prcmu.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) ST Ericsson SA 2010
+ *
+ * License Terms: GNU General Public License v2
+ * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com>
+ *
+ * U8500 PRCMU driver.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/mutex.h>
+#include <linux/completion.h>
+#include <linux/jiffies.h>
+#include <linux/bitops.h>
+#include <linux/interrupt.h>
+
+#include <mach/hardware.h>
+#include <mach/prcmu-regs.h>
+
+#define PRCMU_TCDM_BASE __io_address(U8500_PRCMU_TCDM_BASE)
+
+#define REQ_MB5 (PRCMU_TCDM_BASE + 0xE44)
+#define ACK_MB5 (PRCMU_TCDM_BASE + 0xDF4)
+
+#define REQ_MB5_I2C_SLAVE_OP (REQ_MB5)
+#define REQ_MB5_I2C_HW_BITS (REQ_MB5 + 1)
+#define REQ_MB5_I2C_REG (REQ_MB5 + 2)
+#define REQ_MB5_I2C_VAL (REQ_MB5 + 3)
+
+#define ACK_MB5_I2C_STATUS (ACK_MB5 + 1)
+#define ACK_MB5_I2C_VAL (ACK_MB5 + 3)
+
+#define I2C_WRITE(slave) ((slave) << 1)
+#define I2C_READ(slave) (((slave) << 1) | BIT(0))
+#define I2C_STOP_EN BIT(3)
+
+enum ack_mb5_status {
+ I2C_WR_OK = 0x01,
+ I2C_RD_OK = 0x02,
+};
+
+#define MBOX_BIT BIT
+#define NUM_MBOX 8
+
+static struct {
+ struct mutex lock;
+ struct completion work;
+ bool failed;
+ struct {
+ u8 status;
+ u8 value;
+ } ack;
+} mb5_transfer;
+
+/**
+ * prcmu_abb_read() - Read register value(s) from the ABB.
+ * @slave: The I2C slave address.
+ * @reg: The (start) register address.
+ * @value: The read out value(s).
+ * @size: The number of registers to read.
+ *
+ * Reads register value(s) from the ABB.
+ * @size has to be 1 for the current firmware version.
+ */
+int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size)
+{
+ int r;
+
+ if (size != 1)
+ return -EINVAL;
+
+ r = mutex_lock_interruptible(&mb5_transfer.lock);
+ if (r)
+ return r;
+
+ while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5))
+ cpu_relax();
+
+ writeb(I2C_READ(slave), REQ_MB5_I2C_SLAVE_OP);
+ writeb(I2C_STOP_EN, REQ_MB5_I2C_HW_BITS);
+ writeb(reg, REQ_MB5_I2C_REG);
+
+ writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET);
+ if (!wait_for_completion_timeout(&mb5_transfer.work,
+ msecs_to_jiffies(500))) {
+ pr_err("prcmu: prcmu_abb_read timed out.\n");
+ r = -EIO;
+ goto unlock_and_return;
+ }
+ r = ((mb5_transfer.ack.status == I2C_RD_OK) ? 0 : -EIO);
+ if (!r)
+ *value = mb5_transfer.ack.value;
+
+unlock_and_return:
+ mutex_unlock(&mb5_transfer.lock);
+ return r;
+}
+EXPORT_SYMBOL(prcmu_abb_read);
+
+/**
+ * prcmu_abb_write() - Write register value(s) to the ABB.
+ * @slave: The I2C slave address.
+ * @reg: The (start) register address.
+ * @value: The value(s) to write.
+ * @size: The number of registers to write.
+ *
+ * Reads register value(s) from the ABB.
+ * @size has to be 1 for the current firmware version.
+ */
+int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)
+{
+ int r;
+
+ if (size != 1)
+ return -EINVAL;
+
+ r = mutex_lock_interruptible(&mb5_transfer.lock);
+ if (r)
+ return r;
+
+
+ while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5))
+ cpu_relax();
+
+ writeb(I2C_WRITE(slave), REQ_MB5_I2C_SLAVE_OP);
+ writeb(I2C_STOP_EN, REQ_MB5_I2C_HW_BITS);
+ writeb(reg, REQ_MB5_I2C_REG);
+ writeb(*value, REQ_MB5_I2C_VAL);
+
+ writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET);
+ if (!wait_for_completion_timeout(&mb5_transfer.work,
+ msecs_to_jiffies(500))) {
+ pr_err("prcmu: prcmu_abb_write timed out.\n");
+ r = -EIO;
+ goto unlock_and_return;
+ }
+ r = ((mb5_transfer.ack.status == I2C_WR_OK) ? 0 : -EIO);
+
+unlock_and_return:
+ mutex_unlock(&mb5_transfer.lock);
+ return r;
+}
+EXPORT_SYMBOL(prcmu_abb_write);
+
+static void read_mailbox_0(void)
+{
+ writel(MBOX_BIT(0), PRCM_ARM_IT1_CLEAR);
+}
+
+static void read_mailbox_1(void)
+{
+ writel(MBOX_BIT(1), PRCM_ARM_IT1_CLEAR);
+}
+
+static void read_mailbox_2(void)
+{
+ writel(MBOX_BIT(2), PRCM_ARM_IT1_CLEAR);
+}
+
+static void read_mailbox_3(void)
+{
+ writel(MBOX_BIT(3), PRCM_ARM_IT1_CLEAR);
+}
+
+static void read_mailbox_4(void)
+{
+ writel(MBOX_BIT(4), PRCM_ARM_IT1_CLEAR);
+}
+
+static void read_mailbox_5(void)
+{
+ mb5_transfer.ack.status = readb(ACK_MB5_I2C_STATUS);
+ mb5_transfer.ack.value = readb(ACK_MB5_I2C_VAL);
+ complete(&mb5_transfer.work);
+ writel(MBOX_BIT(5), PRCM_ARM_IT1_CLEAR);
+}
+
+static void read_mailbox_6(void)
+{
+ writel(MBOX_BIT(6), PRCM_ARM_IT1_CLEAR);
+}
+
+static void read_mailbox_7(void)
+{
+ writel(MBOX_BIT(7), PRCM_ARM_IT1_CLEAR);
+}
+
+static void (* const read_mailbox[NUM_MBOX])(void) = {
+ read_mailbox_0,
+ read_mailbox_1,
+ read_mailbox_2,
+ read_mailbox_3,
+ read_mailbox_4,
+ read_mailbox_5,
+ read_mailbox_6,
+ read_mailbox_7
+};
+
+static irqreturn_t prcmu_irq_handler(int irq, void *data)
+{
+ u32 bits;
+ u8 n;
+
+ bits = (readl(PRCM_ARM_IT1_VAL) & (MBOX_BIT(NUM_MBOX) - 1));
+ if (unlikely(!bits))
+ return IRQ_NONE;
+
+ for (n = 0; bits; n++) {
+ if (bits & MBOX_BIT(n)) {
+ bits -= MBOX_BIT(n);
+ read_mailbox[n]();
+ }
+ }
+ return IRQ_HANDLED;
+}
+
+static int __init prcmu_init(void)
+{
+ mutex_init(&mb5_transfer.lock);
+ init_completion(&mb5_transfer.work);
+
+ /* Clean up the mailbox interrupts after pre-kernel code. */
+ writel((MBOX_BIT(NUM_MBOX) - 1), PRCM_ARM_IT1_CLEAR);
+
+ return request_irq(IRQ_PRCMU, prcmu_irq_handler, 0, "prcmu", NULL);
+}
+
+arch_initcall(prcmu_init);
diff --git a/arch/arm/mach-ux500/ste-dma40-db5500.h b/arch/arm/mach-ux500/ste-dma40-db5500.h
new file mode 100644
index 000000000000..cb2110c32858
--- /dev/null
+++ b/arch/arm/mach-ux500/ste-dma40-db5500.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ *
+ * DB5500-SoC-specific configuration for DMA40
+ */
+
+#ifndef STE_DMA40_DB5500_H
+#define STE_DMA40_DB5500_H
+
+#define DB5500_DMA_NR_DEV 64
+
+enum dma_src_dev_type {
+ DB5500_DMA_DEV0_SPI0_RX = 0,
+ DB5500_DMA_DEV1_SPI1_RX = 1,
+ DB5500_DMA_DEV2_SPI2_RX = 2,
+ DB5500_DMA_DEV3_SPI3_RX = 3,
+ DB5500_DMA_DEV4_USB_OTG_IEP_1_9 = 4,
+ DB5500_DMA_DEV5_USB_OTG_IEP_2_10 = 5,
+ DB5500_DMA_DEV6_USB_OTG_IEP_3_11 = 6,
+ DB5500_DMA_DEV7_IRDA_RFS = 7,
+ DB5500_DMA_DEV8_IRDA_FIFO_RX = 8,
+ DB5500_DMA_DEV9_MSP0_RX = 9,
+ DB5500_DMA_DEV10_MSP1_RX = 10,
+ DB5500_DMA_DEV11_MSP2_RX = 11,
+ DB5500_DMA_DEV12_UART0_RX = 12,
+ DB5500_DMA_DEV13_UART1_RX = 13,
+ DB5500_DMA_DEV14_UART2_RX = 14,
+ DB5500_DMA_DEV15_UART3_RX = 15,
+ DB5500_DMA_DEV16_USB_OTG_IEP_8 = 16,
+ DB5500_DMA_DEV17_USB_OTG_IEP_1_9 = 17,
+ DB5500_DMA_DEV18_USB_OTG_IEP_2_10 = 18,
+ DB5500_DMA_DEV19_USB_OTG_IEP_3_11 = 19,
+ DB5500_DMA_DEV20_USB_OTG_IEP_4_12 = 20,
+ DB5500_DMA_DEV21_USB_OTG_IEP_5_13 = 21,
+ DB5500_DMA_DEV22_USB_OTG_IEP_6_14 = 22,
+ DB5500_DMA_DEV23_USB_OTG_IEP_7_15 = 23,
+ DB5500_DMA_DEV24_SDMMC0_RX = 24,
+ DB5500_DMA_DEV25_SDMMC1_RX = 25,
+ DB5500_DMA_DEV26_SDMMC2_RX = 26,
+ DB5500_DMA_DEV27_SDMMC3_RX = 27,
+ DB5500_DMA_DEV28_SDMMC4_RX = 28,
+ /* 29 - 32 not used */
+ DB5500_DMA_DEV33_SDMMC0_RX = 33,
+ DB5500_DMA_DEV34_SDMMC1_RX = 34,
+ DB5500_DMA_DEV35_SDMMC2_RX = 35,
+ DB5500_DMA_DEV36_SDMMC3_RX = 36,
+ DB5500_DMA_DEV37_SDMMC4_RX = 37,
+ DB5500_DMA_DEV38_USB_OTG_IEP_8 = 38,
+ DB5500_DMA_DEV39_USB_OTG_IEP_1_9 = 39,
+ DB5500_DMA_DEV40_USB_OTG_IEP_2_10 = 40,
+ DB5500_DMA_DEV41_USB_OTG_IEP_3_11 = 41,
+ DB5500_DMA_DEV42_USB_OTG_IEP_4_12 = 42,
+ DB5500_DMA_DEV43_USB_OTG_IEP_5_13 = 43,
+ DB5500_DMA_DEV44_USB_OTG_IEP_6_14 = 44,
+ DB5500_DMA_DEV45_USB_OTG_IEP_7_15 = 45,
+ /* 46 not used */
+ DB5500_DMA_DEV47_MCDE_RX = 47,
+ DB5500_DMA_DEV48_CRYPTO1_RX = 48,
+ /* 49, 50 not used */
+ DB5500_DMA_DEV49_I2C1_RX = 51,
+ DB5500_DMA_DEV50_I2C3_RX = 52,
+ DB5500_DMA_DEV51_I2C2_RX = 53,
+ /* 54 - 60 not used */
+ DB5500_DMA_DEV61_CRYPTO0_RX = 61,
+ /* 62, 63 not used */
+};
+
+enum dma_dest_dev_type {
+ DB5500_DMA_DEV0_SPI0_TX = 0,
+ DB5500_DMA_DEV1_SPI1_TX = 1,
+ DB5500_DMA_DEV2_SPI2_TX = 2,
+ DB5500_DMA_DEV3_SPI3_TX = 3,
+ DB5500_DMA_DEV4_USB_OTG_OEP_1_9 = 4,
+ DB5500_DMA_DEV5_USB_OTG_OEP_2_10 = 5,
+ DB5500_DMA_DEV6_USB_OTG_OEP_3_11 = 6,
+ DB5500_DMA_DEV7_IRRC_TX = 7,
+ DB5500_DMA_DEV8_IRDA_FIFO_TX = 8,
+ DB5500_DMA_DEV9_MSP0_TX = 9,
+ DB5500_DMA_DEV10_MSP1_TX = 10,
+ DB5500_DMA_DEV11_MSP2_TX = 11,
+ DB5500_DMA_DEV12_UART0_TX = 12,
+ DB5500_DMA_DEV13_UART1_TX = 13,
+ DB5500_DMA_DEV14_UART2_TX = 14,
+ DB5500_DMA_DEV15_UART3_TX = 15,
+ DB5500_DMA_DEV16_USB_OTG_OEP_8 = 16,
+ DB5500_DMA_DEV17_USB_OTG_OEP_1_9 = 17,
+ DB5500_DMA_DEV18_USB_OTG_OEP_2_10 = 18,
+ DB5500_DMA_DEV19_USB_OTG_OEP_3_11 = 19,
+ DB5500_DMA_DEV20_USB_OTG_OEP_4_12 = 20,
+ DB5500_DMA_DEV21_USB_OTG_OEP_5_13 = 21,
+ DB5500_DMA_DEV22_USB_OTG_OEP_6_14 = 22,
+ DB5500_DMA_DEV23_USB_OTG_OEP_7_15 = 23,
+ DB5500_DMA_DEV24_SDMMC0_TX = 24,
+ DB5500_DMA_DEV25_SDMMC1_TX = 25,
+ DB5500_DMA_DEV26_SDMMC2_TX = 26,
+ DB5500_DMA_DEV27_SDMMC3_TX = 27,
+ DB5500_DMA_DEV28_SDMMC4_TX = 28,
+ /* 29 - 31 not used */
+ DB5500_DMA_DEV32_FSMC_TX = 32,
+ DB5500_DMA_DEV33_SDMMC0_TX = 33,
+ DB5500_DMA_DEV34_SDMMC1_TX = 34,
+ DB5500_DMA_DEV35_SDMMC2_TX = 35,
+ DB5500_DMA_DEV36_SDMMC3_TX = 36,
+ DB5500_DMA_DEV37_SDMMC4_TX = 37,
+ DB5500_DMA_DEV38_USB_OTG_OEP_8 = 38,
+ DB5500_DMA_DEV39_USB_OTG_OEP_1_9 = 39,
+ DB5500_DMA_DEV40_USB_OTG_OEP_2_10 = 40,
+ DB5500_DMA_DEV41_USB_OTG_OEP_3_11 = 41,
+ DB5500_DMA_DEV42_USB_OTG_OEP_4_12 = 42,
+ DB5500_DMA_DEV43_USB_OTG_OEP_5_13 = 43,
+ DB5500_DMA_DEV44_USB_OTG_OEP_6_14 = 44,
+ DB5500_DMA_DEV45_USB_OTG_OEP_7_15 = 45,
+ /* 46 not used */
+ DB5500_DMA_DEV47_STM_TX = 47,
+ DB5500_DMA_DEV48_CRYPTO1_TX = 48,
+ DB5500_DMA_DEV49_CRYPTO1_TX_HASH1_TX = 49,
+ DB5500_DMA_DEV50_HASH1_TX = 50,
+ DB5500_DMA_DEV51_I2C1_TX = 51,
+ DB5500_DMA_DEV52_I2C3_TX = 52,
+ DB5500_DMA_DEV53_I2C2_TX = 53,
+ /* 54, 55 not used */
+ DB5500_DMA_MEMCPY_TX_1 = 56,
+ DB5500_DMA_MEMCPY_TX_2 = 57,
+ DB5500_DMA_MEMCPY_TX_3 = 58,
+ DB5500_DMA_MEMCPY_TX_4 = 59,
+ DB5500_DMA_MEMCPY_TX_5 = 60,
+ DB5500_DMA_DEV61_CRYPTO0_TX = 61,
+ DB5500_DMA_DEV62_CRYPTO0_TX_HASH0_TX = 62,
+ DB5500_DMA_DEV63_HASH0_TX = 63,
+};
+
+#endif
diff --git a/arch/arm/mach-ux500/ste-dma40-db8500.h b/arch/arm/mach-ux500/ste-dma40-db8500.h
index 9d9d3797b3b0..a616419bea76 100644
--- a/arch/arm/mach-ux500/ste-dma40-db8500.h
+++ b/arch/arm/mach-ux500/ste-dma40-db8500.h
@@ -10,145 +10,135 @@
#ifndef STE_DMA40_DB8500_H
#define STE_DMA40_DB8500_H
-#define STEDMA40_NR_DEV 64
+#define DB8500_DMA_NR_DEV 64
enum dma_src_dev_type {
- STEDMA40_DEV_SPI0_RX = 0,
- STEDMA40_DEV_SD_MMC0_RX = 1,
- STEDMA40_DEV_SD_MMC1_RX = 2,
- STEDMA40_DEV_SD_MMC2_RX = 3,
- STEDMA40_DEV_I2C1_RX = 4,
- STEDMA40_DEV_I2C3_RX = 5,
- STEDMA40_DEV_I2C2_RX = 6,
- STEDMA40_DEV_I2C4_RX = 7, /* Only on V1 */
- STEDMA40_DEV_SSP0_RX = 8,
- STEDMA40_DEV_SSP1_RX = 9,
- STEDMA40_DEV_MCDE_RX = 10,
- STEDMA40_DEV_UART2_RX = 11,
- STEDMA40_DEV_UART1_RX = 12,
- STEDMA40_DEV_UART0_RX = 13,
- STEDMA40_DEV_MSP2_RX = 14,
- STEDMA40_DEV_I2C0_RX = 15,
- STEDMA40_DEV_USB_OTG_IEP_8 = 16,
- STEDMA40_DEV_USB_OTG_IEP_1_9 = 17,
- STEDMA40_DEV_USB_OTG_IEP_2_10 = 18,
- STEDMA40_DEV_USB_OTG_IEP_3_11 = 19,
- STEDMA40_DEV_SLIM0_CH0_RX_HSI_RX_CH0 = 20,
- STEDMA40_DEV_SLIM0_CH1_RX_HSI_RX_CH1 = 21,
- STEDMA40_DEV_SLIM0_CH2_RX_HSI_RX_CH2 = 22,
- STEDMA40_DEV_SLIM0_CH3_RX_HSI_RX_CH3 = 23,
- STEDMA40_DEV_SRC_SXA0_RX_TX = 24,
- STEDMA40_DEV_SRC_SXA1_RX_TX = 25,
- STEDMA40_DEV_SRC_SXA2_RX_TX = 26,
- STEDMA40_DEV_SRC_SXA3_RX_TX = 27,
- STEDMA40_DEV_SD_MM2_RX = 28,
- STEDMA40_DEV_SD_MM0_RX = 29,
- STEDMA40_DEV_MSP1_RX = 30,
- /*
- * This channel is either SlimBus or MSP,
- * never both at the same time.
- */
- STEDMA40_SLIM0_CH0_RX = 31,
- STEDMA40_DEV_MSP0_RX = 31,
- STEDMA40_DEV_SD_MM1_RX = 32,
- STEDMA40_DEV_SPI2_RX = 33,
- STEDMA40_DEV_I2C3_RX2 = 34,
- STEDMA40_DEV_SPI1_RX = 35,
- STEDMA40_DEV_USB_OTG_IEP_4_12 = 36,
- STEDMA40_DEV_USB_OTG_IEP_5_13 = 37,
- STEDMA40_DEV_USB_OTG_IEP_6_14 = 38,
- STEDMA40_DEV_USB_OTG_IEP_7_15 = 39,
- STEDMA40_DEV_SPI3_RX = 40,
- STEDMA40_DEV_SD_MM3_RX = 41,
- STEDMA40_DEV_SD_MM4_RX = 42,
- STEDMA40_DEV_SD_MM5_RX = 43,
- STEDMA40_DEV_SRC_SXA4_RX_TX = 44,
- STEDMA40_DEV_SRC_SXA5_RX_TX = 45,
- STEDMA40_DEV_SRC_SXA6_RX_TX = 46,
- STEDMA40_DEV_SRC_SXA7_RX_TX = 47,
- STEDMA40_DEV_CAC1_RX = 48,
- /* RX channels 49 and 50 are unused */
- STEDMA40_DEV_MSHC_RX = 51,
- STEDMA40_DEV_SLIM1_CH0_RX_HSI_RX_CH4 = 52,
- STEDMA40_DEV_SLIM1_CH1_RX_HSI_RX_CH5 = 53,
- STEDMA40_DEV_SLIM1_CH2_RX_HSI_RX_CH6 = 54,
- STEDMA40_DEV_SLIM1_CH3_RX_HSI_RX_CH7 = 55,
- /* RX channels 56 thru 60 are unused */
- STEDMA40_DEV_CAC0_RX = 61,
- /* RX channels 62 and 63 are unused */
+ DB8500_DMA_DEV0_SPI0_RX = 0,
+ DB8500_DMA_DEV1_SD_MMC0_RX = 1,
+ DB8500_DMA_DEV2_SD_MMC1_RX = 2,
+ DB8500_DMA_DEV3_SD_MMC2_RX = 3,
+ DB8500_DMA_DEV4_I2C1_RX = 4,
+ DB8500_DMA_DEV5_I2C3_RX = 5,
+ DB8500_DMA_DEV6_I2C2_RX = 6,
+ DB8500_DMA_DEV7_I2C4_RX = 7, /* Only on V1 and later */
+ DB8500_DMA_DEV8_SSP0_RX = 8,
+ DB8500_DMA_DEV9_SSP1_RX = 9,
+ DB8500_DMA_DEV10_MCDE_RX = 10,
+ DB8500_DMA_DEV11_UART2_RX = 11,
+ DB8500_DMA_DEV12_UART1_RX = 12,
+ DB8500_DMA_DEV13_UART0_RX = 13,
+ DB8500_DMA_DEV14_MSP2_RX = 14,
+ DB8500_DMA_DEV15_I2C0_RX = 15,
+ DB8500_DMA_DEV16_USB_OTG_IEP_7_15 = 16,
+ DB8500_DMA_DEV17_USB_OTG_IEP_6_14 = 17,
+ DB8500_DMA_DEV18_USB_OTG_IEP_5_13 = 18,
+ DB8500_DMA_DEV19_USB_OTG_IEP_4_12 = 19,
+ DB8500_DMA_DEV20_SLIM0_CH0_RX_HSI_RX_CH0 = 20,
+ DB8500_DMA_DEV21_SLIM0_CH1_RX_HSI_RX_CH1 = 21,
+ DB8500_DMA_DEV22_SLIM0_CH2_RX_HSI_RX_CH2 = 22,
+ DB8500_DMA_DEV23_SLIM0_CH3_RX_HSI_RX_CH3 = 23,
+ DB8500_DMA_DEV24_SRC_SXA0_RX_TX = 24,
+ DB8500_DMA_DEV25_SRC_SXA1_RX_TX = 25,
+ DB8500_DMA_DEV26_SRC_SXA2_RX_TX = 26,
+ DB8500_DMA_DEV27_SRC_SXA3_RX_TX = 27,
+ DB8500_DMA_DEV28_SD_MM2_RX = 28,
+ DB8500_DMA_DEV29_SD_MM0_RX = 29,
+ DB8500_DMA_DEV30_MSP1_RX = 30,
+ /* On DB8500v2, MSP3 RX replaces MSP1 RX */
+ DB8500_DMA_DEV30_MSP3_RX = 30,
+ DB8500_DMA_DEV31_MSP0_RX_SLIM0_CH0_RX = 31,
+ DB8500_DMA_DEV32_SD_MM1_RX = 32,
+ DB8500_DMA_DEV33_SPI2_RX = 33,
+ DB8500_DMA_DEV34_I2C3_RX2 = 34,
+ DB8500_DMA_DEV35_SPI1_RX = 35,
+ DB8500_DMA_DEV36_USB_OTG_IEP_3_11 = 36,
+ DB8500_DMA_DEV37_USB_OTG_IEP_2_10 = 37,
+ DB8500_DMA_DEV38_USB_OTG_IEP_1_9 = 38,
+ DB8500_DMA_DEV39_USB_OTG_IEP_8 = 39,
+ DB8500_DMA_DEV40_SPI3_RX = 40,
+ DB8500_DMA_DEV41_SD_MM3_RX = 41,
+ DB8500_DMA_DEV42_SD_MM4_RX = 42,
+ DB8500_DMA_DEV43_SD_MM5_RX = 43,
+ DB8500_DMA_DEV44_SRC_SXA4_RX_TX = 44,
+ DB8500_DMA_DEV45_SRC_SXA5_RX_TX = 45,
+ DB8500_DMA_DEV46_SLIM0_CH8_RX_SRC_SXA6_RX_TX = 46,
+ DB8500_DMA_DEV47_SLIM0_CH9_RX_SRC_SXA7_RX_TX = 47,
+ DB8500_DMA_DEV48_CAC1_RX = 48,
+ /* 49, 50 and 51 are not used */
+ DB8500_DMA_DEV52_SLIM0_CH4_RX_HSI_RX_CH4 = 52,
+ DB8500_DMA_DEV53_SLIM0_CH5_RX_HSI_RX_CH5 = 53,
+ DB8500_DMA_DEV54_SLIM0_CH6_RX_HSI_RX_CH6 = 54,
+ DB8500_DMA_DEV55_SLIM0_CH7_RX_HSI_RX_CH7 = 55,
+ /* 56, 57, 58, 59 and 60 are not used */
+ DB8500_DMA_DEV61_CAC0_RX = 61,
+ /* 62 and 63 are not used */
};
enum dma_dest_dev_type {
- STEDMA40_DEV_SPI0_TX = 0,
- STEDMA40_DEV_SD_MMC0_TX = 1,
- STEDMA40_DEV_SD_MMC1_TX = 2,
- STEDMA40_DEV_SD_MMC2_TX = 3,
- STEDMA40_DEV_I2C1_TX = 4,
- STEDMA40_DEV_I2C3_TX = 5,
- STEDMA40_DEV_I2C2_TX = 6,
- STEDMA50_DEV_I2C4_TX = 7, /* Only on V1 */
- STEDMA40_DEV_SSP0_TX = 8,
- STEDMA40_DEV_SSP1_TX = 9,
- /* TX channel 10 is unused */
- STEDMA40_DEV_UART2_TX = 11,
- STEDMA40_DEV_UART1_TX = 12,
- STEDMA40_DEV_UART0_TX= 13,
- STEDMA40_DEV_MSP2_TX = 14,
- STEDMA40_DEV_I2C0_TX = 15,
- STEDMA40_DEV_USB_OTG_OEP_8 = 16,
- STEDMA40_DEV_USB_OTG_OEP_1_9 = 17,
- STEDMA40_DEV_USB_OTG_OEP_2_10= 18,
- STEDMA40_DEV_USB_OTG_OEP_3_11 = 19,
- STEDMA40_DEV_SLIM0_CH0_TX_HSI_TX_CH0 = 20,
- STEDMA40_DEV_SLIM0_CH1_TX_HSI_TX_CH1 = 21,
- STEDMA40_DEV_SLIM0_CH2_TX_HSI_TX_CH2 = 22,
- STEDMA40_DEV_SLIM0_CH3_TX_HSI_TX_CH3 = 23,
- STEDMA40_DEV_DST_SXA0_RX_TX = 24,
- STEDMA40_DEV_DST_SXA1_RX_TX = 25,
- STEDMA40_DEV_DST_SXA2_RX_TX = 26,
- STEDMA40_DEV_DST_SXA3_RX_TX = 27,
- STEDMA40_DEV_SD_MM2_TX = 28,
- STEDMA40_DEV_SD_MM0_TX = 29,
- STEDMA40_DEV_MSP1_TX = 30,
- /*
- * This channel is either SlimBus or MSP,
- * never both at the same time.
- */
- STEDMA40_SLIM0_CH0_TX = 31,
- STEDMA40_DEV_MSP0_TX = 31,
- STEDMA40_DEV_SD_MM1_TX = 32,
- STEDMA40_DEV_SPI2_TX = 33,
- /* Secondary I2C3 channel */
- STEDMA40_DEV_I2C3_TX2 = 34,
- STEDMA40_DEV_SPI1_TX = 35,
- STEDMA40_DEV_USB_OTG_OEP_4_12 = 36,
- STEDMA40_DEV_USB_OTG_OEP_5_13 = 37,
- STEDMA40_DEV_USB_OTG_OEP_6_14 = 38,
- STEDMA40_DEV_USB_OTG_OEP_7_15 = 39,
- STEDMA40_DEV_SPI3_TX = 40,
- STEDMA40_DEV_SD_MM3_TX = 41,
- STEDMA40_DEV_SD_MM4_TX = 42,
- STEDMA40_DEV_SD_MM5_TX = 43,
- STEDMA40_DEV_DST_SXA4_RX_TX = 44,
- STEDMA40_DEV_DST_SXA5_RX_TX = 45,
- STEDMA40_DEV_DST_SXA6_RX_TX = 46,
- STEDMA40_DEV_DST_SXA7_RX_TX = 47,
- STEDMA40_DEV_CAC1_TX = 48,
- STEDMA40_DEV_CAC1_TX_HAC1_TX = 49,
- STEDMA40_DEV_HAC1_TX = 50,
- STEDMA40_MEMCPY_TX_0 = 51,
- STEDMA40_DEV_SLIM1_CH0_TX_HSI_TX_CH4 = 52,
- STEDMA40_DEV_SLIM1_CH1_TX_HSI_TX_CH5 = 53,
- STEDMA40_DEV_SLIM1_CH2_TX_HSI_TX_CH6 = 54,
- STEDMA40_DEV_SLIM1_CH3_TX_HSI_TX_CH7 = 55,
- STEDMA40_MEMCPY_TX_1 = 56,
- STEDMA40_MEMCPY_TX_2 = 57,
- STEDMA40_MEMCPY_TX_3 = 58,
- STEDMA40_MEMCPY_TX_4 = 59,
- STEDMA40_MEMCPY_TX_5 = 60,
- STEDMA40_DEV_CAC0_TX = 61,
- STEDMA40_DEV_CAC0_TX_HAC0_TX = 62,
- STEDMA40_DEV_HAC0_TX = 63,
+ DB8500_DMA_DEV0_SPI0_TX = 0,
+ DB8500_DMA_DEV1_SD_MMC0_TX = 1,
+ DB8500_DMA_DEV2_SD_MMC1_TX = 2,
+ DB8500_DMA_DEV3_SD_MMC2_TX = 3,
+ DB8500_DMA_DEV4_I2C1_TX = 4,
+ DB8500_DMA_DEV5_I2C3_TX = 5,
+ DB8500_DMA_DEV6_I2C2_TX = 6,
+ DB8500_DMA_DEV7_I2C4_TX = 7, /* Only on V1 and later */
+ DB8500_DMA_DEV8_SSP0_TX = 8,
+ DB8500_DMA_DEV9_SSP1_TX = 9,
+ /* 10 is not used*/
+ DB8500_DMA_DEV11_UART2_TX = 11,
+ DB8500_DMA_DEV12_UART1_TX = 12,
+ DB8500_DMA_DEV13_UART0_TX = 13,
+ DB8500_DMA_DEV14_MSP2_TX = 14,
+ DB8500_DMA_DEV15_I2C0_TX = 15,
+ DB8500_DMA_DEV16_USB_OTG_OEP_7_15 = 16,
+ DB8500_DMA_DEV17_USB_OTG_OEP_6_14 = 17,
+ DB8500_DMA_DEV18_USB_OTG_OEP_5_13 = 18,
+ DB8500_DMA_DEV19_USB_OTG_OEP_4_12 = 19,
+ DB8500_DMA_DEV20_SLIM0_CH0_TX_HSI_TX_CH0 = 20,
+ DB8500_DMA_DEV21_SLIM0_CH1_TX_HSI_TX_CH1 = 21,
+ DB8500_DMA_DEV22_SLIM0_CH2_TX_HSI_TX_CH2 = 22,
+ DB8500_DMA_DEV23_SLIM0_CH3_TX_HSI_TX_CH3 = 23,
+ DB8500_DMA_DEV24_DST_SXA0_RX_TX = 24,
+ DB8500_DMA_DEV25_DST_SXA1_RX_TX = 25,
+ DB8500_DMA_DEV26_DST_SXA2_RX_TX = 26,
+ DB8500_DMA_DEV27_DST_SXA3_RX_TX = 27,
+ DB8500_DMA_DEV28_SD_MM2_TX = 28,
+ DB8500_DMA_DEV29_SD_MM0_TX = 29,
+ DB8500_DMA_DEV30_MSP1_TX = 30,
+ DB8500_DMA_DEV31_MSP0_TX_SLIM0_CH0_TX = 31,
+ DB8500_DMA_DEV32_SD_MM1_TX = 32,
+ DB8500_DMA_DEV33_SPI2_TX = 33,
+ DB8500_DMA_DEV34_I2C3_TX2 = 34,
+ DB8500_DMA_DEV35_SPI1_TX = 35,
+ DB8500_DMA_DEV36_USB_OTG_OEP_3_11 = 36,
+ DB8500_DMA_DEV37_USB_OTG_OEP_2_10 = 37,
+ DB8500_DMA_DEV38_USB_OTG_OEP_1_9 = 38,
+ DB8500_DMA_DEV39_USB_OTG_OEP_8 = 39,
+ DB8500_DMA_DEV40_SPI3_TX = 40,
+ DB8500_DMA_DEV41_SD_MM3_TX = 41,
+ DB8500_DMA_DEV42_SD_MM4_TX = 42,
+ DB8500_DMA_DEV43_SD_MM5_TX = 43,
+ DB8500_DMA_DEV44_DST_SXA4_RX_TX = 44,
+ DB8500_DMA_DEV45_DST_SXA5_RX_TX = 45,
+ DB8500_DMA_DEV46_SLIM0_CH8_TX_DST_SXA6_RX_TX = 46,
+ DB8500_DMA_DEV47_SLIM0_CH9_TX_DST_SXA7_RX_TX = 47,
+ DB8500_DMA_DEV48_CAC1_TX = 48,
+ DB8500_DMA_DEV49_CAC1_TX_HAC1_TX = 49,
+ DB8500_DMA_DEV50_HAC1_TX = 50,
+ DB8500_DMA_MEMCPY_TX_0 = 51,
+ DB8500_DMA_DEV52_SLIM1_CH4_TX_HSI_TX_CH4 = 52,
+ DB8500_DMA_DEV53_SLIM1_CH5_TX_HSI_TX_CH5 = 53,
+ DB8500_DMA_DEV54_SLIM1_CH6_TX_HSI_TX_CH6 = 54,
+ DB8500_DMA_DEV55_SLIM1_CH7_TX_HSI_TX_CH7 = 55,
+ DB8500_DMA_MEMCPY_TX_1 = 56,
+ DB8500_DMA_MEMCPY_TX_2 = 57,
+ DB8500_DMA_MEMCPY_TX_3 = 58,
+ DB8500_DMA_MEMCPY_TX_4 = 59,
+ DB8500_DMA_MEMCPY_TX_5 = 60,
+ DB8500_DMA_DEV61_CAC0_TX = 61,
+ DB8500_DMA_DEV62_CAC0_TX_HAC0_TX = 62,
+ DB8500_DMA_DEV63_HAC0_TX = 63,
};
#endif
diff --git a/arch/arm/mach-versatile/include/mach/debug-macro.S b/arch/arm/mach-versatile/include/mach/debug-macro.S
index 6fea7199c626..eb2cf7dc5c44 100644
--- a/arch/arm/mach-versatile/include/mach/debug-macro.S
+++ b/arch/arm/mach-versatile/include/mach/debug-macro.S
@@ -11,13 +11,11 @@
*
*/
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- moveq \rx, #0x10000000
- movne \rx, #0xf1000000 @ virtual base
- orr \rx, \rx, #0x001F0000
- orr \rx, \rx, #0x00001000
+ .macro addruart, rp, rv
+ mov \rp, #0x001F0000
+ orr \rp, \rp, #0x00001000
+ orr \rv, \rp, #0xf1000000 @ virtual base
+ orr \rp, \rp, #0x10000000 @ physical base
.endm
#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-versatile/include/mach/vmalloc.h b/arch/arm/mach-versatile/include/mach/vmalloc.h
index 427e3612db5d..ebd8a2543d3b 100644
--- a/arch/arm/mach-versatile/include/mach/vmalloc.h
+++ b/arch/arm/mach-versatile/include/mach/vmalloc.h
@@ -18,4 +18,4 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#define VMALLOC_END (PAGE_OFFSET + 0x18000000)
+#define VMALLOC_END 0xd8000000
diff --git a/arch/arm/mach-versatile/versatile_ab.c b/arch/arm/mach-versatile/versatile_ab.c
index bb8ec7724f79..aa9730fb13bf 100644
--- a/arch/arm/mach-versatile/versatile_ab.c
+++ b/arch/arm/mach-versatile/versatile_ab.c
@@ -35,8 +35,6 @@
MACHINE_START(VERSATILE_AB, "ARM-Versatile AB")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
- .phys_io = 0x101f1000,
- .io_pg_offst = ((0xf11f1000) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.map_io = versatile_map_io,
.init_irq = versatile_init_irq,
diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c
index 239cd30fc4f5..bf469642a3f8 100644
--- a/arch/arm/mach-versatile/versatile_pb.c
+++ b/arch/arm/mach-versatile/versatile_pb.c
@@ -108,8 +108,6 @@ static void __init versatile_pb_init(void)
MACHINE_START(VERSATILE_PB, "ARM-Versatile PB")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
- .phys_io = 0x101f1000,
- .io_pg_offst = ((0xf11f1000) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.map_io = versatile_map_io,
.init_irq = versatile_init_irq,
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
index efb127022d42..c2e405a9e025 100644
--- a/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -68,7 +68,7 @@ static void __init ct_ca9x4_init_irq(void)
}
#if 0
-static void ct_ca9x4_timer_init(void)
+static void __init ct_ca9x4_timer_init(void)
{
writel(0, MMIO_P2V(CT_CA9X4_TIMER0) + TIMER_CTRL);
writel(0, MMIO_P2V(CT_CA9X4_TIMER1) + TIMER_CTRL);
@@ -222,7 +222,7 @@ static struct platform_device pmu_device = {
.resource = pmu_resources,
};
-static void ct_ca9x4_init(void)
+static void __init ct_ca9x4_init(void)
{
int i;
@@ -245,8 +245,6 @@ static void ct_ca9x4_init(void)
}
MACHINE_START(VEXPRESS, "ARM-Versatile Express CA9x4")
- .phys_io = V2M_UART0 & SECTION_MASK,
- .io_pg_offst = (__MMIO_P2V(V2M_UART0) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x00000100,
.map_io = ct_ca9x4_map_io,
.init_irq = ct_ca9x4_init_irq,
diff --git a/arch/arm/mach-vexpress/include/mach/debug-macro.S b/arch/arm/mach-vexpress/include/mach/debug-macro.S
index 5167e2aceeba..050d65e02a42 100644
--- a/arch/arm/mach-vexpress/include/mach/debug-macro.S
+++ b/arch/arm/mach-vexpress/include/mach/debug-macro.S
@@ -12,12 +12,10 @@
#define DEBUG_LL_UART_OFFSET 0x00009000
- .macro addruart,rx,tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- moveq \rx, #0x10000000
- movne \rx, #0xf8000000 @ virtual base
- orr \rx, \rx, #DEBUG_LL_UART_OFFSET
+ .macro addruart,rp,rv
+ mov \rp, #DEBUG_LL_UART_OFFSET
+ orr \rv, \rp, #0xf8000000 @ virtual base
+ orr \rp, \rp, #0x10000000 @ physical base
.endm
#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-vexpress/include/mach/smp.h b/arch/arm/mach-vexpress/include/mach/smp.h
index 72a9621ed087..5a6da4fd247e 100644
--- a/arch/arm/mach-vexpress/include/mach/smp.h
+++ b/arch/arm/mach-vexpress/include/mach/smp.h
@@ -2,14 +2,7 @@
#define __MACH_SMP_H
#include <asm/hardware/gic.h>
-
-#define hard_smp_processor_id() \
- ({ \
- unsigned int cpunum; \
- __asm__("mrc p15, 0, %0, c0, c0, 5" \
- : "=r" (cpunum)); \
- cpunum &= 0x0F; \
- })
+#include <asm/smp_mpidr.h>
/*
* We use IRQ1 as the IPI
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index 817f0ad38a0b..7eaa232180a5 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -48,7 +48,7 @@ void __init v2m_map_io(struct map_desc *tile, size_t num)
}
-static void v2m_timer_init(void)
+static void __init v2m_timer_init(void)
{
writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL);
writel(0, MMIO_P2V(V2M_TIMER1) + TIMER_CTRL);
diff --git a/arch/arm/mach-w90x900/mach-nuc910evb.c b/arch/arm/mach-w90x900/mach-nuc910evb.c
index ec05bda946f3..30fccde94fb8 100644
--- a/arch/arm/mach-w90x900/mach-nuc910evb.c
+++ b/arch/arm/mach-w90x900/mach-nuc910evb.c
@@ -34,8 +34,6 @@ static void __init nuc910evb_init(void)
MACHINE_START(W90P910EVB, "W90P910EVB")
/* Maintainer: Wan ZongShun */
- .phys_io = W90X900_PA_UART,
- .io_pg_offst = (((u32)W90X900_VA_UART) >> 18) & 0xfffc,
.boot_params = 0,
.map_io = nuc910evb_map_io,
.init_irq = nuc900_init_irq,
diff --git a/arch/arm/mach-w90x900/mach-nuc950evb.c b/arch/arm/mach-w90x900/mach-nuc950evb.c
index 04d295f89eb0..590c99b96dc1 100644
--- a/arch/arm/mach-w90x900/mach-nuc950evb.c
+++ b/arch/arm/mach-w90x900/mach-nuc950evb.c
@@ -37,8 +37,6 @@ static void __init nuc950evb_init(void)
MACHINE_START(W90P950EVB, "W90P950EVB")
/* Maintainer: Wan ZongShun */
- .phys_io = W90X900_PA_UART,
- .io_pg_offst = (((u32)W90X900_VA_UART) >> 18) & 0xfffc,
.boot_params = 0,
.map_io = nuc950evb_map_io,
.init_irq = nuc900_init_irq,
diff --git a/arch/arm/mach-w90x900/mach-nuc960evb.c b/arch/arm/mach-w90x900/mach-nuc960evb.c
index e3a46f19f2bc..e09c645d61b6 100644
--- a/arch/arm/mach-w90x900/mach-nuc960evb.c
+++ b/arch/arm/mach-w90x900/mach-nuc960evb.c
@@ -34,8 +34,6 @@ static void __init nuc960evb_init(void)
MACHINE_START(W90N960EVB, "W90N960EVB")
/* Maintainer: Wan ZongShun */
- .phys_io = W90X900_PA_UART,
- .io_pg_offst = (((u32)W90X900_VA_UART) >> 18) & 0xfffc,
.boot_params = 0,
.map_io = nuc960evb_map_io,
.init_irq = nuc900_init_irq,
diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S
index 86aa689ef1aa..99fa688dfadd 100644
--- a/arch/arm/mm/cache-v6.S
+++ b/arch/arm/mm/cache-v6.S
@@ -21,18 +21,22 @@
#define D_CACHE_LINE_SIZE 32
#define BTB_FLUSH_SIZE 8
-#ifdef CONFIG_ARM_ERRATA_411920
/*
- * Invalidate the entire I cache (this code is a workaround for the ARM1136
- * erratum 411920 - Invalidate Instruction Cache operation can fail. This
- * erratum is present in 1136, 1156 and 1176. It does not affect the MPCore.
+ * v6_flush_icache_all()
+ *
+ * Flush the whole I-cache.
*
- * Registers:
- * r0 - set to 0
- * r1 - corrupted
+ * ARM1136 erratum 411920 - Invalidate Instruction Cache operation can fail.
+ * This erratum is present in 1136, 1156 and 1176. It does not affect the
+ * MPCore.
+ *
+ * Registers:
+ * r0 - set to 0
+ * r1 - corrupted
*/
-ENTRY(v6_icache_inval_all)
+ENTRY(v6_flush_icache_all)
mov r0, #0
+#ifdef CONFIG_ARM_ERRATA_411920
mrs r1, cpsr
cpsid ifa @ disable interrupts
mcr p15, 0, r0, c7, c5, 0 @ invalidate entire I-cache
@@ -43,8 +47,11 @@ ENTRY(v6_icache_inval_all)
.rept 11 @ ARM Ltd recommends at least
nop @ 11 NOPs
.endr
- mov pc, lr
+#else
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I-cache
#endif
+ mov pc, lr
+ENDPROC(v6_flush_icache_all)
/*
* v6_flush_cache_all()
@@ -60,7 +67,7 @@ ENTRY(v6_flush_kern_cache_all)
#ifndef CONFIG_ARM_ERRATA_411920
mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate
#else
- b v6_icache_inval_all
+ b v6_flush_icache_all
#endif
#else
mcr p15, 0, r0, c7, c15, 0 @ Cache clean+invalidate
@@ -138,7 +145,7 @@ ENTRY(v6_coherent_user_range)
#ifndef CONFIG_ARM_ERRATA_411920
mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate
#else
- b v6_icache_inval_all
+ b v6_flush_icache_all
#endif
#else
mcr p15, 0, r0, c7, c5, 6 @ invalidate BTB
@@ -312,6 +319,7 @@ ENDPROC(v6_dma_unmap_area)
.type v6_cache_fns, #object
ENTRY(v6_cache_fns)
+ .long v6_flush_icache_all
.long v6_flush_kern_cache_all
.long v6_flush_user_cache_all
.long v6_flush_user_cache_range
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index 37c8157e116e..a3ebf7a4f49b 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -18,6 +18,21 @@
#include "proc-macros.S"
/*
+ * v7_flush_icache_all()
+ *
+ * Flush the whole I-cache.
+ *
+ * Registers:
+ * r0 - set to 0
+ */
+ENTRY(v7_flush_icache_all)
+ mov r0, #0
+ ALT_SMP(mcr p15, 0, r0, c7, c1, 0) @ invalidate I-cache inner shareable
+ ALT_UP(mcr p15, 0, r0, c7, c5, 0) @ I+BTB cache invalidate
+ mov pc, lr
+ENDPROC(v7_flush_icache_all)
+
+/*
* v7_flush_dcache_all()
*
* Flush the whole D-cache.
@@ -91,11 +106,8 @@ ENTRY(v7_flush_kern_cache_all)
THUMB( stmfd sp!, {r4-r7, r9-r11, lr} )
bl v7_flush_dcache_all
mov r0, #0
-#ifdef CONFIG_SMP
- mcr p15, 0, r0, c7, c1, 0 @ invalidate I-cache inner shareable
-#else
- mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate
-#endif
+ ALT_SMP(mcr p15, 0, r0, c7, c1, 0) @ invalidate I-cache inner shareable
+ ALT_UP(mcr p15, 0, r0, c7, c5, 0) @ I+BTB cache invalidate
ARM( ldmfd sp!, {r4-r5, r7, r9-r11, lr} )
THUMB( ldmfd sp!, {r4-r7, r9-r11, lr} )
mov pc, lr
@@ -171,11 +183,8 @@ ENTRY(v7_coherent_user_range)
cmp r0, r1
blo 1b
mov r0, #0
-#ifdef CONFIG_SMP
- mcr p15, 0, r0, c7, c1, 6 @ invalidate BTB Inner Shareable
-#else
- mcr p15, 0, r0, c7, c5, 6 @ invalidate BTB
-#endif
+ ALT_SMP(mcr p15, 0, r0, c7, c1, 6) @ invalidate BTB Inner Shareable
+ ALT_UP(mcr p15, 0, r0, c7, c5, 6) @ invalidate BTB
dsb
isb
mov pc, lr
@@ -309,6 +318,7 @@ ENDPROC(v7_dma_unmap_area)
.type v7_cache_fns, #object
ENTRY(v7_cache_fns)
+ .long v7_flush_icache_all
.long v7_flush_kern_cache_all
.long v7_flush_user_cache_all
.long v7_flush_user_cache_range
diff --git a/arch/arm/mm/copypage-v4mc.c b/arch/arm/mm/copypage-v4mc.c
index 598c51ad5071..b8061519ce77 100644
--- a/arch/arm/mm/copypage-v4mc.c
+++ b/arch/arm/mm/copypage-v4mc.c
@@ -73,7 +73,7 @@ void v4_mc_copy_user_highpage(struct page *to, struct page *from,
{
void *kto = kmap_atomic(to, KM_USER1);
- if (test_and_clear_bit(PG_dcache_dirty, &from->flags))
+ if (!test_and_set_bit(PG_dcache_clean, &from->flags))
__flush_dcache_page(page_mapping(from), from);
spin_lock(&minicache_lock);
diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c
index f55fa1044f72..bdba6c65c901 100644
--- a/arch/arm/mm/copypage-v6.c
+++ b/arch/arm/mm/copypage-v6.c
@@ -79,7 +79,7 @@ static void v6_copy_user_highpage_aliasing(struct page *to,
unsigned int offset = CACHE_COLOUR(vaddr);
unsigned long kfrom, kto;
- if (test_and_clear_bit(PG_dcache_dirty, &from->flags))
+ if (!test_and_set_bit(PG_dcache_clean, &from->flags))
__flush_dcache_page(page_mapping(from), from);
/* FIXME: not highmem safe */
diff --git a/arch/arm/mm/copypage-xscale.c b/arch/arm/mm/copypage-xscale.c
index 9920c0ae2096..649bbcd325bf 100644
--- a/arch/arm/mm/copypage-xscale.c
+++ b/arch/arm/mm/copypage-xscale.c
@@ -95,7 +95,7 @@ void xscale_mc_copy_user_highpage(struct page *to, struct page *from,
{
void *kto = kmap_atomic(to, KM_USER1);
- if (test_and_clear_bit(PG_dcache_dirty, &from->flags))
+ if (!test_and_set_bit(PG_dcache_clean, &from->flags))
__flush_dcache_page(page_mapping(from), from);
spin_lock(&minicache_lock);
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 4bc43e535d3b..e4dd0646e859 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -523,6 +523,12 @@ void ___dma_page_dev_to_cpu(struct page *page, unsigned long off,
outer_inv_range(paddr, paddr + size);
dma_cache_maint_page(page, off, size, dir, dmac_unmap_area);
+
+ /*
+ * Mark the D-cache clean for this page to avoid extra flushing.
+ */
+ if (dir != DMA_TO_DEVICE && off == 0 && size >= PAGE_SIZE)
+ set_bit(PG_dcache_clean, &page->flags);
}
EXPORT_SYMBOL(___dma_page_dev_to_cpu);
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index 9b906dec1ca1..8440d952ba6d 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -28,6 +28,7 @@
static unsigned long shared_pte_mask = L_PTE_MT_BUFFERABLE;
+#if __LINUX_ARM_ARCH__ < 6
/*
* We take the easy way out of this problem - we make the
* PTE uncacheable. However, we leave the write buffer on.
@@ -141,7 +142,7 @@ make_coherent(struct address_space *mapping, struct vm_area_struct *vma,
* a page table, or changing an existing PTE. Basically, there are two
* things that we need to take care of:
*
- * 1. If PG_dcache_dirty is set for the page, we need to ensure
+ * 1. If PG_dcache_clean is not set for the page, we need to ensure
* that any cache entries for the kernels virtual memory
* range are written back to the page.
* 2. If we have multiple shared mappings of the same space in
@@ -168,10 +169,8 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
return;
mapping = page_mapping(page);
-#ifndef CONFIG_SMP
- if (test_and_clear_bit(PG_dcache_dirty, &page->flags))
+ if (!test_and_set_bit(PG_dcache_clean, &page->flags))
__flush_dcache_page(mapping, page);
-#endif
if (mapping) {
if (cache_is_vivt())
make_coherent(mapping, vma, addr, ptep, pfn);
@@ -179,6 +178,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
__flush_icache_all();
}
}
+#endif /* __LINUX_ARM_ARCH__ < 6 */
/*
* Check whether the write buffer has physical address aliasing
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 23b0b03af5ea..1e21e125fe3a 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -581,6 +581,19 @@ static struct fsr_info ifsr_info[] = {
{ do_bad, SIGBUS, 0, "unknown 31" },
};
+void __init
+hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *),
+ int sig, int code, const char *name)
+{
+ if (nr < 0 || nr >= ARRAY_SIZE(ifsr_info))
+ BUG();
+
+ ifsr_info[nr].fn = fn;
+ ifsr_info[nr].sig = sig;
+ ifsr_info[nr].code = code;
+ ifsr_info[nr].name = name;
+}
+
asmlinkage void __exception
do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
{
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index c6844cb9b508..391ffae75098 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -17,6 +17,7 @@
#include <asm/smp_plat.h>
#include <asm/system.h>
#include <asm/tlbflush.h>
+#include <asm/smp_plat.h>
#include "mm.h"
@@ -39,6 +40,18 @@ static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
: "cc");
}
+static void flush_icache_alias(unsigned long pfn, unsigned long vaddr, unsigned long len)
+{
+ unsigned long colour = CACHE_COLOUR(vaddr);
+ unsigned long offset = vaddr & (PAGE_SIZE - 1);
+ unsigned long to;
+
+ set_pte_ext(TOP_PTE(ALIAS_FLUSH_START) + colour, pfn_pte(pfn, PAGE_KERNEL), 0);
+ to = ALIAS_FLUSH_START + (colour << PAGE_SHIFT) + offset;
+ flush_tlb_kernel_page(to);
+ flush_icache_range(to, to + len);
+}
+
void flush_cache_mm(struct mm_struct *mm)
{
if (cache_is_vivt()) {
@@ -89,16 +102,16 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsig
if (vma->vm_flags & VM_EXEC && icache_is_vivt_asid_tagged())
__flush_icache_all();
}
+
#else
-#define flush_pfn_alias(pfn,vaddr) do { } while (0)
+#define flush_pfn_alias(pfn,vaddr) do { } while (0)
+#define flush_icache_alias(pfn,vaddr,len) do { } while (0)
#endif
-#ifdef CONFIG_SMP
static void flush_ptrace_access_other(void *args)
{
__flush_icache_all();
}
-#endif
static
void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
@@ -118,15 +131,16 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
return;
}
- /* VIPT non-aliasing cache */
+ /* VIPT non-aliasing D-cache */
if (vma->vm_flags & VM_EXEC) {
unsigned long addr = (unsigned long)kaddr;
- __cpuc_coherent_kern_range(addr, addr + len);
-#ifdef CONFIG_SMP
+ if (icache_is_vipt_aliasing())
+ flush_icache_alias(page_to_pfn(page), uaddr, len);
+ else
+ __cpuc_coherent_kern_range(addr, addr + len);
if (cache_ops_need_broadcast())
smp_call_function(flush_ptrace_access_other,
NULL, 1);
-#endif
}
}
@@ -215,6 +229,36 @@ static void __flush_dcache_aliases(struct address_space *mapping, struct page *p
flush_dcache_mmap_unlock(mapping);
}
+#if __LINUX_ARM_ARCH__ >= 6
+void __sync_icache_dcache(pte_t pteval)
+{
+ unsigned long pfn;
+ struct page *page;
+ struct address_space *mapping;
+
+ if (!pte_present_user(pteval))
+ return;
+ if (cache_is_vipt_nonaliasing() && !pte_exec(pteval))
+ /* only flush non-aliasing VIPT caches for exec mappings */
+ return;
+ pfn = pte_pfn(pteval);
+ if (!pfn_valid(pfn))
+ return;
+
+ page = pfn_to_page(pfn);
+ if (cache_is_vipt_aliasing())
+ mapping = page_mapping(page);
+ else
+ mapping = NULL;
+
+ if (!test_and_set_bit(PG_dcache_clean, &page->flags))
+ __flush_dcache_page(mapping, page);
+ /* pte_exec() already checked above for non-aliasing VIPT cache */
+ if (cache_is_vipt_nonaliasing() || pte_exec(pteval))
+ __flush_icache_all();
+}
+#endif
+
/*
* Ensure cache coherency between kernel mapping and userspace mapping
* of this page.
@@ -246,17 +290,16 @@ void flush_dcache_page(struct page *page)
mapping = page_mapping(page);
-#ifndef CONFIG_SMP
- if (!PageHighMem(page) && mapping && !mapping_mapped(mapping))
- set_bit(PG_dcache_dirty, &page->flags);
- else
-#endif
- {
+ if (!cache_ops_need_broadcast() &&
+ mapping && !mapping_mapped(mapping))
+ clear_bit(PG_dcache_clean, &page->flags);
+ else {
__flush_dcache_page(mapping, page);
if (mapping && cache_is_vivt())
__flush_dcache_aliases(mapping, page);
else if (mapping)
__flush_icache_all();
+ set_bit(PG_dcache_clean, &page->flags);
}
}
EXPORT_SYMBOL(flush_dcache_page);
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 7185b00650fe..7fd9b5eb177f 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -150,6 +150,7 @@ static void __init find_limits(struct meminfo *mi,
static void __init arm_bootmem_init(struct meminfo *mi,
unsigned long start_pfn, unsigned long end_pfn)
{
+ struct memblock_region *reg;
unsigned int boot_pages;
phys_addr_t bitmap;
pg_data_t *pgdat;
@@ -180,13 +181,13 @@ static void __init arm_bootmem_init(struct meminfo *mi,
/*
* Reserve the memblock reserved regions in bootmem.
*/
- for (i = 0; i < memblock.reserved.cnt; i++) {
- phys_addr_t start = memblock_start_pfn(&memblock.reserved, i);
- if (start >= start_pfn &&
- memblock_end_pfn(&memblock.reserved, i) <= end_pfn)
+ for_each_memblock(reserved, reg) {
+ phys_addr_t start = memblock_region_reserved_base_pfn(reg);
+ phys_addr_t end = memblock_region_reserved_end_pfn(reg);
+ if (start >= start_pfn && end <= end_pfn)
reserve_bootmem_node(pgdat, __pfn_to_phys(start),
- memblock_size_bytes(&memblock.reserved, i),
- BOOTMEM_DEFAULT);
+ (end - start) << PAGE_SHIFT,
+ BOOTMEM_DEFAULT);
}
}
@@ -237,20 +238,7 @@ static void __init arm_bootmem_free(struct meminfo *mi, unsigned long min,
#ifndef CONFIG_SPARSEMEM
int pfn_valid(unsigned long pfn)
{
- struct memblock_region *mem = &memblock.memory;
- unsigned int left = 0, right = mem->cnt;
-
- do {
- unsigned int mid = (right + left) / 2;
-
- if (pfn < memblock_start_pfn(mem, mid))
- right = mid;
- else if (pfn >= memblock_end_pfn(mem, mid))
- left = mid + 1;
- else
- return 1;
- } while (left < right);
- return 0;
+ return memblock_is_memory(pfn << PAGE_SHIFT);
}
EXPORT_SYMBOL(pfn_valid);
@@ -260,10 +248,11 @@ static void arm_memory_present(void)
#else
static void arm_memory_present(void)
{
- int i;
- for (i = 0; i < memblock.memory.cnt; i++)
- memory_present(0, memblock_start_pfn(&memblock.memory, i),
- memblock_end_pfn(&memblock.memory, i));
+ struct memblock_region *reg;
+
+ for_each_memblock(memory, reg)
+ memory_present(0, memblock_region_memory_base_pfn(reg),
+ memblock_region_memory_end_pfn(reg));
}
#endif
@@ -277,7 +266,7 @@ void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc)
/* Register the kernel text, kernel data and initrd with memblock. */
#ifdef CONFIG_XIP_KERNEL
- memblock_reserve(__pa(_data), _end - _data);
+ memblock_reserve(__pa(_sdata), _end - _sdata);
#else
memblock_reserve(__pa(_stext), _end - _stext);
#endif
@@ -545,7 +534,7 @@ void __init mem_init(void)
MLK_ROUNDUP(__init_begin, __init_end),
MLK_ROUNDUP(_text, _etext),
- MLK_ROUNDUP(_data, _edata));
+ MLK_ROUNDUP(_sdata, _edata));
#undef MLK
#undef MLM
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index ab506272b2d3..17e7b0b57e49 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -204,8 +204,12 @@ void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn,
/*
* Don't allow RAM to be mapped - this causes problems with ARMv6+
*/
- if (WARN_ON(pfn_valid(pfn)))
- return NULL;
+ if (pfn_valid(pfn)) {
+ printk(KERN_WARNING "BUG: Your driver calls ioremap() on system memory. This leads\n"
+ KERN_WARNING "to architecturally unpredictable behaviour on ARMv6+, and ioremap()\n"
+ KERN_WARNING "will fail in the next kernel release. Please fix your driver.\n");
+ WARN_ON(1);
+ }
type = get_mem_type(mtype);
if (!type)
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index 4f5b39687df5..b0a98305055c 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -144,3 +144,25 @@ int valid_mmap_phys_addr_range(unsigned long pfn, size_t size)
{
return !(pfn + (size >> PAGE_SHIFT) > 0x00100000);
}
+
+#ifdef CONFIG_STRICT_DEVMEM
+
+#include <linux/ioport.h>
+
+/*
+ * devmem_is_allowed() checks to see if /dev/mem access to a certain
+ * address is valid. The argument is a physical page number.
+ * We mimic x86 here by disallowing access to system RAM as well as
+ * device-exclusive MMIO regions. This effectively disable read()/write()
+ * on /dev/mem.
+ */
+int devmem_is_allowed(unsigned long pfn)
+{
+ if (iomem_is_exclusive(pfn << PAGE_SHIFT))
+ return 0;
+ if (!page_is_ram(pfn))
+ return 1;
+ return 0;
+}
+
+#endif
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 6a3a2d0cd6db..c32f731d56d3 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -248,7 +248,7 @@ static struct mem_type mem_types[] = {
},
[MT_MEMORY] = {
.prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
- L_PTE_USER | L_PTE_EXEC,
+ L_PTE_WRITE | L_PTE_EXEC,
.prot_l1 = PMD_TYPE_TABLE,
.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
.domain = DOMAIN_KERNEL,
@@ -259,7 +259,7 @@ static struct mem_type mem_types[] = {
},
[MT_MEMORY_NONCACHED] = {
.prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
- L_PTE_USER | L_PTE_EXEC | L_PTE_MT_BUFFERABLE,
+ L_PTE_WRITE | L_PTE_EXEC | L_PTE_MT_BUFFERABLE,
.prot_l1 = PMD_TYPE_TABLE,
.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
.domain = DOMAIN_KERNEL,
@@ -310,9 +310,8 @@ static void __init build_mem_type_table(void)
cachepolicy = CPOLICY_WRITEBACK;
ecc_mask = 0;
}
-#ifdef CONFIG_SMP
- cachepolicy = CPOLICY_WRITEALLOC;
-#endif
+ if (is_smp())
+ cachepolicy = CPOLICY_WRITEALLOC;
/*
* Strip out features not present on earlier architectures.
@@ -406,13 +405,11 @@ static void __init build_mem_type_table(void)
cp = &cache_policies[cachepolicy];
vecs_pgprot = kern_pgprot = user_pgprot = cp->pte;
-#ifndef CONFIG_SMP
/*
* Only use write-through for non-SMP systems
*/
- if (cpu_arch >= CPU_ARCH_ARMv5 && cachepolicy > CPOLICY_WRITETHROUGH)
+ if (!is_smp() && cpu_arch >= CPU_ARCH_ARMv5 && cachepolicy > CPOLICY_WRITETHROUGH)
vecs_pgprot = cache_policies[CPOLICY_WRITETHROUGH].pte;
-#endif
/*
* Enable CPU-specific coherency if supported.
@@ -436,22 +433,23 @@ static void __init build_mem_type_table(void)
mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
-#ifdef CONFIG_SMP
- /*
- * Mark memory with the "shared" attribute for SMP systems
- */
- user_pgprot |= L_PTE_SHARED;
- kern_pgprot |= L_PTE_SHARED;
- vecs_pgprot |= L_PTE_SHARED;
- mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_S;
- mem_types[MT_DEVICE_WC].prot_pte |= L_PTE_SHARED;
- mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S;
- mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED;
- mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
- mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED;
- mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S;
- mem_types[MT_MEMORY_NONCACHED].prot_pte |= L_PTE_SHARED;
-#endif
+ if (is_smp()) {
+ /*
+ * Mark memory with the "shared" attribute
+ * for SMP systems
+ */
+ user_pgprot |= L_PTE_SHARED;
+ kern_pgprot |= L_PTE_SHARED;
+ vecs_pgprot |= L_PTE_SHARED;
+ mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_S;
+ mem_types[MT_DEVICE_WC].prot_pte |= L_PTE_SHARED;
+ mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S;
+ mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED;
+ mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
+ mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED;
+ mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S;
+ mem_types[MT_MEMORY_NONCACHED].prot_pte |= L_PTE_SHARED;
+ }
}
/*
@@ -829,8 +827,7 @@ static void __init sanity_check_meminfo(void)
* rather difficult.
*/
reason = "with VIPT aliasing cache";
-#ifdef CONFIG_SMP
- } else if (tlb_ops_need_broadcast()) {
+ } else if (is_smp() && tlb_ops_need_broadcast()) {
/*
* kmap_high needs to occasionally flush TLB entries,
* however, if the TLB entries need to be broadcast
@@ -840,7 +837,6 @@ static void __init sanity_check_meminfo(void)
* (must not be called with irqs off)
*/
reason = "without hardware TLB ops broadcasting";
-#endif
}
if (reason) {
printk(KERN_CRIT "HIGHMEM is not supported %s, ignoring high memory\n",
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
index 203a4e944d9e..a6f5f8475b96 100644
--- a/arch/arm/mm/proc-arm1020.S
+++ b/arch/arm/mm/proc-arm1020.S
@@ -430,7 +430,7 @@ ENTRY(cpu_arm1020_set_pte_ext)
#endif /* CONFIG_MMU */
mov pc, lr
- __INIT
+ __CPUINIT
.type __arm1020_setup, #function
__arm1020_setup:
diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S
index 1a511e765909..afc06b9c3133 100644
--- a/arch/arm/mm/proc-arm1020e.S
+++ b/arch/arm/mm/proc-arm1020e.S
@@ -412,7 +412,7 @@ ENTRY(cpu_arm1020e_set_pte_ext)
#endif /* CONFIG_MMU */
mov pc, lr
- __INIT
+ __CPUINIT
.type __arm1020e_setup, #function
__arm1020e_setup:
diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S
index 1ffa4eb9c34f..8915e0ba3fe5 100644
--- a/arch/arm/mm/proc-arm1022.S
+++ b/arch/arm/mm/proc-arm1022.S
@@ -394,7 +394,7 @@ ENTRY(cpu_arm1022_set_pte_ext)
#endif /* CONFIG_MMU */
mov pc, lr
- __INIT
+ __CPUINIT
.type __arm1022_setup, #function
__arm1022_setup:
diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
index 5697c34b95b0..ff446c5d476f 100644
--- a/arch/arm/mm/proc-arm1026.S
+++ b/arch/arm/mm/proc-arm1026.S
@@ -384,7 +384,7 @@ ENTRY(cpu_arm1026_set_pte_ext)
mov pc, lr
- __INIT
+ __CPUINIT
.type __arm1026_setup, #function
__arm1026_setup:
diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S
index 64e0b327c7c5..6a7be1863edd 100644
--- a/arch/arm/mm/proc-arm6_7.S
+++ b/arch/arm/mm/proc-arm6_7.S
@@ -238,7 +238,7 @@ ENTRY(cpu_arm7_reset)
mcr p15, 0, r1, c1, c0, 0 @ turn off MMU etc
mov pc, r0
- __INIT
+ __CPUINIT
.type __arm6_setup, #function
__arm6_setup: mov r0, #0
diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S
index 9d96824134fc..c285395f44b2 100644
--- a/arch/arm/mm/proc-arm720.S
+++ b/arch/arm/mm/proc-arm720.S
@@ -113,7 +113,7 @@ ENTRY(cpu_arm720_reset)
mcr p15, 0, ip, c1, c0, 0 @ ctrl register
mov pc, r0
- __INIT
+ __CPUINIT
.type __arm710_setup, #function
__arm710_setup:
diff --git a/arch/arm/mm/proc-arm740.S b/arch/arm/mm/proc-arm740.S
index 6c1a9ab059ae..38b27dcba727 100644
--- a/arch/arm/mm/proc-arm740.S
+++ b/arch/arm/mm/proc-arm740.S
@@ -55,7 +55,7 @@ ENTRY(cpu_arm740_reset)
mcr p15, 0, ip, c1, c0, 0 @ ctrl register
mov pc, r0
- __INIT
+ __CPUINIT
.type __arm740_setup, #function
__arm740_setup:
diff --git a/arch/arm/mm/proc-arm7tdmi.S b/arch/arm/mm/proc-arm7tdmi.S
index 6a850dbba22e..0c9786de20af 100644
--- a/arch/arm/mm/proc-arm7tdmi.S
+++ b/arch/arm/mm/proc-arm7tdmi.S
@@ -46,7 +46,7 @@ ENTRY(cpu_arm7tdmi_proc_fin)
ENTRY(cpu_arm7tdmi_reset)
mov pc, r0
- __INIT
+ __CPUINIT
.type __arm7tdmi_setup, #function
__arm7tdmi_setup:
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index 86f80aa56216..fecf570939f3 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -375,7 +375,7 @@ ENTRY(cpu_arm920_set_pte_ext)
#endif
mov pc, lr
- __INIT
+ __CPUINIT
.type __arm920_setup, #function
__arm920_setup:
diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
index f76ce9b62883..e3cbf87c9480 100644
--- a/arch/arm/mm/proc-arm922.S
+++ b/arch/arm/mm/proc-arm922.S
@@ -379,7 +379,7 @@ ENTRY(cpu_arm922_set_pte_ext)
#endif /* CONFIG_MMU */
mov pc, lr
- __INIT
+ __CPUINIT
.type __arm922_setup, #function
__arm922_setup:
diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S
index 657bd3f7c153..572424c867b5 100644
--- a/arch/arm/mm/proc-arm925.S
+++ b/arch/arm/mm/proc-arm925.S
@@ -428,7 +428,7 @@ ENTRY(cpu_arm925_set_pte_ext)
#endif /* CONFIG_MMU */
mov pc, lr
- __INIT
+ __CPUINIT
.type __arm925_setup, #function
__arm925_setup:
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index 73f1f3c68910..63d168b4ebe6 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -389,7 +389,7 @@ ENTRY(cpu_arm926_set_pte_ext)
#endif
mov pc, lr
- __INIT
+ __CPUINIT
.type __arm926_setup, #function
__arm926_setup:
diff --git a/arch/arm/mm/proc-arm940.S b/arch/arm/mm/proc-arm940.S
index fffb061a45a5..f6a62822418e 100644
--- a/arch/arm/mm/proc-arm940.S
+++ b/arch/arm/mm/proc-arm940.S
@@ -264,7 +264,7 @@ ENTRY(arm940_cache_fns)
.long arm940_dma_unmap_area
.long arm940_dma_flush_range
- __INIT
+ __CPUINIT
.type __arm940_setup, #function
__arm940_setup:
diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S
index 249a6053760a..ea2e7f2eb95b 100644
--- a/arch/arm/mm/proc-arm946.S
+++ b/arch/arm/mm/proc-arm946.S
@@ -317,7 +317,7 @@ ENTRY(cpu_arm946_dcache_clean_area)
mcr p15, 0, r0, c7, c10, 4 @ drain WB
mov pc, lr
- __INIT
+ __CPUINIT
.type __arm946_setup, #function
__arm946_setup:
diff --git a/arch/arm/mm/proc-arm9tdmi.S b/arch/arm/mm/proc-arm9tdmi.S
index db475667fac2..db67e3134d7a 100644
--- a/arch/arm/mm/proc-arm9tdmi.S
+++ b/arch/arm/mm/proc-arm9tdmi.S
@@ -46,7 +46,7 @@ ENTRY(cpu_arm9tdmi_proc_fin)
ENTRY(cpu_arm9tdmi_reset)
mov pc, r0
- __INIT
+ __CPUINIT
.type __arm9tdmi_setup, #function
__arm9tdmi_setup:
diff --git a/arch/arm/mm/proc-fa526.S b/arch/arm/mm/proc-fa526.S
index 7803fdf70029..7c9ad621f0e6 100644
--- a/arch/arm/mm/proc-fa526.S
+++ b/arch/arm/mm/proc-fa526.S
@@ -134,7 +134,7 @@ ENTRY(cpu_fa526_set_pte_ext)
#endif
mov pc, lr
- __INIT
+ __CPUINIT
.type __fa526_setup, #function
__fa526_setup:
diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S
index b304d0104a4e..578da69200cf 100644
--- a/arch/arm/mm/proc-feroceon.S
+++ b/arch/arm/mm/proc-feroceon.S
@@ -494,7 +494,7 @@ ENTRY(cpu_feroceon_set_pte_ext)
#endif
mov pc, lr
- __INIT
+ __CPUINIT
.type __feroceon_setup, #function
__feroceon_setup:
diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S
index 5f6892fcc167..4458ee6aa713 100644
--- a/arch/arm/mm/proc-mohawk.S
+++ b/arch/arm/mm/proc-mohawk.S
@@ -338,7 +338,7 @@ ENTRY(cpu_mohawk_set_pte_ext)
mcr p15, 0, r0, c7, c10, 4 @ drain WB
mov pc, lr
- __INIT
+ __CPUINIT
.type __mohawk_setup, #function
__mohawk_setup:
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index a201eb04b5e1..5aa8d59c2e85 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -156,7 +156,7 @@ ENTRY(cpu_sa110_set_pte_ext)
#endif
mov pc, lr
- __INIT
+ __CPUINIT
.type __sa110_setup, #function
__sa110_setup:
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
index 7ddc4805bf97..2ac4e6f10713 100644
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -169,7 +169,7 @@ ENTRY(cpu_sa1100_set_pte_ext)
#endif
mov pc, lr
- __INIT
+ __CPUINIT
.type __sa1100_setup, #function
__sa1100_setup:
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 22aac8515196..59a7e1ffe7bc 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -30,13 +30,10 @@
#define TTB_RGN_WT (2 << 3)
#define TTB_RGN_WB (3 << 3)
-#ifndef CONFIG_SMP
-#define TTB_FLAGS TTB_RGN_WBWA
-#define PMD_FLAGS PMD_SECT_WB
-#else
-#define TTB_FLAGS TTB_RGN_WBWA|TTB_S
-#define PMD_FLAGS PMD_SECT_WBWA|PMD_SECT_S
-#endif
+#define TTB_FLAGS_UP TTB_RGN_WBWA
+#define PMD_FLAGS_UP PMD_SECT_WB
+#define TTB_FLAGS_SMP TTB_RGN_WBWA|TTB_S
+#define PMD_FLAGS_SMP PMD_SECT_WBWA|PMD_SECT_S
ENTRY(cpu_v6_proc_init)
mov pc, lr
@@ -97,7 +94,8 @@ ENTRY(cpu_v6_switch_mm)
#ifdef CONFIG_MMU
mov r2, #0
ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id
- orr r0, r0, #TTB_FLAGS
+ ALT_SMP(orr r0, r0, #TTB_FLAGS_SMP)
+ ALT_UP(orr r0, r0, #TTB_FLAGS_UP)
mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB
mcr p15, 0, r2, c7, c10, 4 @ drain write buffer
mcr p15, 0, r0, c2, c0, 0 @ set TTB 0
@@ -137,7 +135,7 @@ cpu_pj4_name:
.align
- __INIT
+ __CPUINIT
/*
* __v6_setup
@@ -156,9 +154,11 @@ cpu_pj4_name:
*/
__v6_setup:
#ifdef CONFIG_SMP
- mrc p15, 0, r0, c1, c0, 1 @ Enable SMP/nAMP mode
+ ALT_SMP(mrc p15, 0, r0, c1, c0, 1) @ Enable SMP/nAMP mode
+ ALT_UP(nop)
orr r0, r0, #0x20
- mcr p15, 0, r0, c1, c0, 1
+ ALT_SMP(mcr p15, 0, r0, c1, c0, 1)
+ ALT_UP(nop)
#endif
mov r0, #0
@@ -169,7 +169,8 @@ __v6_setup:
#ifdef CONFIG_MMU
mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs
mcr p15, 0, r0, c2, c0, 2 @ TTB control register
- orr r4, r4, #TTB_FLAGS
+ ALT_SMP(orr r4, r4, #TTB_FLAGS_SMP)
+ ALT_UP(orr r4, r4, #TTB_FLAGS_UP)
mcr p15, 0, r4, c2, c0, 1 @ load TTB1
#endif /* CONFIG_MMU */
adr r5, v6_crval
@@ -192,6 +193,8 @@ __v6_setup:
v6_crval:
crval clear=0x01e0fb7f, mmuset=0x00c0387d, ucset=0x00c0187c
+ __INITDATA
+
.type v6_processor_functions, #object
ENTRY(v6_processor_functions)
.word v6_early_abort
@@ -205,6 +208,8 @@ ENTRY(v6_processor_functions)
.word cpu_v6_set_pte_ext
.size v6_processor_functions, . - v6_processor_functions
+ .section ".rodata"
+
.type cpu_arch_name, #object
cpu_arch_name:
.asciz "armv6"
@@ -225,10 +230,16 @@ cpu_elf_name:
__v6_proc_info:
.long 0x0007b000
.long 0x0007f000
- .long PMD_TYPE_SECT | \
+ ALT_SMP(.long \
+ PMD_TYPE_SECT | \
PMD_SECT_AP_WRITE | \
PMD_SECT_AP_READ | \
- PMD_FLAGS
+ PMD_FLAGS_SMP)
+ ALT_UP(.long \
+ PMD_TYPE_SECT | \
+ PMD_SECT_AP_WRITE | \
+ PMD_SECT_AP_READ | \
+ PMD_FLAGS_UP)
.long PMD_TYPE_SECT | \
PMD_SECT_XN | \
PMD_SECT_AP_WRITE | \
@@ -249,10 +260,16 @@ __v6_proc_info:
__pj4_v6_proc_info:
.long 0x560f5810
.long 0xff0ffff0
- .long PMD_TYPE_SECT | \
+ ALT_SMP(.long \
+ PMD_TYPE_SECT | \
+ PMD_SECT_AP_WRITE | \
+ PMD_SECT_AP_READ | \
+ PMD_FLAGS_SMP)
+ ALT_UP(.long \
+ PMD_TYPE_SECT | \
PMD_SECT_AP_WRITE | \
PMD_SECT_AP_READ | \
- PMD_FLAGS
+ PMD_FLAGS_UP)
.long PMD_TYPE_SECT | \
PMD_SECT_XN | \
PMD_SECT_AP_WRITE | \
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 7563ff0141bd..53cbe2225153 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -30,15 +30,13 @@
#define TTB_IRGN_WT ((1 << 0) | (0 << 6))
#define TTB_IRGN_WB ((1 << 0) | (1 << 6))
-#ifndef CONFIG_SMP
/* PTWs cacheable, inner WB not shareable, outer WB not shareable */
-#define TTB_FLAGS TTB_IRGN_WB|TTB_RGN_OC_WB
-#define PMD_FLAGS PMD_SECT_WB
-#else
+#define TTB_FLAGS_UP TTB_IRGN_WB|TTB_RGN_OC_WB
+#define PMD_FLAGS_UP PMD_SECT_WB
+
/* PTWs cacheable, inner WBWA shareable, outer WBWA not shareable */
-#define TTB_FLAGS TTB_IRGN_WBWA|TTB_S|TTB_NOS|TTB_RGN_OC_WBWA
-#define PMD_FLAGS PMD_SECT_WBWA|PMD_SECT_S
-#endif
+#define TTB_FLAGS_SMP TTB_IRGN_WBWA|TTB_S|TTB_NOS|TTB_RGN_OC_WBWA
+#define PMD_FLAGS_SMP PMD_SECT_WBWA|PMD_SECT_S
ENTRY(cpu_v7_proc_init)
mov pc, lr
@@ -105,7 +103,8 @@ ENTRY(cpu_v7_switch_mm)
#ifdef CONFIG_MMU
mov r2, #0
ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id
- orr r0, r0, #TTB_FLAGS
+ ALT_SMP(orr r0, r0, #TTB_FLAGS_SMP)
+ ALT_UP(orr r0, r0, #TTB_FLAGS_UP)
#ifdef CONFIG_ARM_ERRATA_430973
mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB
#endif
@@ -169,7 +168,7 @@ cpu_v7_name:
.ascii "ARMv7 Processor"
.align
- __INIT
+ __CPUINIT
/*
* __v7_setup
@@ -188,7 +187,8 @@ cpu_v7_name:
*/
__v7_ca9mp_setup:
#ifdef CONFIG_SMP
- mrc p15, 0, r0, c1, c0, 1
+ ALT_SMP(mrc p15, 0, r0, c1, c0, 1)
+ ALT_UP(mov r0, #(1 << 6)) @ fake it for UP
tst r0, #(1 << 6) @ SMP/nAMP mode enabled?
orreq r0, r0, #(1 << 6) | (1 << 0) @ Enable SMP/nAMP mode and
mcreq p15, 0, r0, c1, c0, 1 @ TLB ops broadcasting
@@ -253,6 +253,14 @@ __v7_setup:
orreq r10, r10, #1 << 22 @ set bit #22
mcreq p15, 0, r10, c15, c0, 1 @ write diagnostic register
#endif
+#ifdef CONFIG_ARM_ERRATA_743622
+ teq r6, #0x20 @ present in r2p0
+ teqne r6, #0x21 @ present in r2p1
+ teqne r6, #0x22 @ present in r2p2
+ mrceq p15, 0, r10, c15, c0, 1 @ read diagnostic register
+ orreq r10, r10, #1 << 6 @ set bit #6
+ mcreq p15, 0, r10, c15, c0, 1 @ write diagnostic register
+#endif
3: mov r10, #0
#ifdef HARVARD_CACHE
@@ -262,7 +270,8 @@ __v7_setup:
#ifdef CONFIG_MMU
mcr p15, 0, r10, c8, c7, 0 @ invalidate I + D TLBs
mcr p15, 0, r10, c2, c0, 2 @ TTB control register
- orr r4, r4, #TTB_FLAGS
+ ALT_SMP(orr r4, r4, #TTB_FLAGS_SMP)
+ ALT_UP(orr r4, r4, #TTB_FLAGS_UP)
mcr p15, 0, r4, c2, c0, 1 @ load TTB1
mov r10, #0x1f @ domains 0, 1 = manager
mcr p15, 0, r10, c3, c0, 0 @ load domain access register
@@ -324,6 +333,8 @@ v7_crval:
__v7_setup_stack:
.space 4 * 11 @ 11 registers
+ __INITDATA
+
.type v7_processor_functions, #object
ENTRY(v7_processor_functions)
.word v7_early_abort
@@ -337,6 +348,8 @@ ENTRY(v7_processor_functions)
.word cpu_v7_set_pte_ext
.size v7_processor_functions, . - v7_processor_functions
+ .section ".rodata"
+
.type cpu_arch_name, #object
cpu_arch_name:
.asciz "armv7"
@@ -354,10 +367,16 @@ cpu_elf_name:
__v7_ca9mp_proc_info:
.long 0x410fc090 @ Required ID value
.long 0xff0ffff0 @ Mask for ID
- .long PMD_TYPE_SECT | \
+ ALT_SMP(.long \
+ PMD_TYPE_SECT | \
+ PMD_SECT_AP_WRITE | \
+ PMD_SECT_AP_READ | \
+ PMD_FLAGS_SMP)
+ ALT_UP(.long \
+ PMD_TYPE_SECT | \
PMD_SECT_AP_WRITE | \
PMD_SECT_AP_READ | \
- PMD_FLAGS
+ PMD_FLAGS_UP)
.long PMD_TYPE_SECT | \
PMD_SECT_XN | \
PMD_SECT_AP_WRITE | \
@@ -365,7 +384,7 @@ __v7_ca9mp_proc_info:
b __v7_ca9mp_setup
.long cpu_arch_name
.long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
+ .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS
.long cpu_v7_name
.long v7_processor_functions
.long v7wbi_tlb_fns
@@ -380,10 +399,16 @@ __v7_ca9mp_proc_info:
__v7_proc_info:
.long 0x000f0000 @ Required ID value
.long 0x000f0000 @ Mask for ID
- .long PMD_TYPE_SECT | \
+ ALT_SMP(.long \
+ PMD_TYPE_SECT | \
+ PMD_SECT_AP_WRITE | \
+ PMD_SECT_AP_READ | \
+ PMD_FLAGS_SMP)
+ ALT_UP(.long \
+ PMD_TYPE_SECT | \
PMD_SECT_AP_WRITE | \
PMD_SECT_AP_READ | \
- PMD_FLAGS
+ PMD_FLAGS_UP)
.long PMD_TYPE_SECT | \
PMD_SECT_XN | \
PMD_SECT_AP_WRITE | \
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index 361a51e49030..cad07e403044 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -404,7 +404,7 @@ ENTRY(cpu_xsc3_set_pte_ext)
.align
- __INIT
+ __CPUINIT
.type __xsc3_setup, #function
__xsc3_setup:
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index 14075979bcba..cb245edb2c2b 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -506,7 +506,7 @@ ENTRY(cpu_xscale_set_pte_ext)
.align
- __INIT
+ __CPUINIT
.type __xscale_setup, #function
__xscale_setup:
diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S
index f3f288a9546d..53cd5b454673 100644
--- a/arch/arm/mm/tlb-v7.S
+++ b/arch/arm/mm/tlb-v7.S
@@ -13,6 +13,7 @@
*/
#include <linux/init.h>
#include <linux/linkage.h>
+#include <asm/assembler.h>
#include <asm/asm-offsets.h>
#include <asm/page.h>
#include <asm/tlbflush.h>
@@ -41,20 +42,15 @@ ENTRY(v7wbi_flush_user_tlb_range)
orr r0, r3, r0, lsl #PAGE_SHIFT @ Create initial MVA
mov r1, r1, lsl #PAGE_SHIFT
1:
-#ifdef CONFIG_SMP
- mcr p15, 0, r0, c8, c3, 1 @ TLB invalidate U MVA (shareable)
-#else
- mcr p15, 0, r0, c8, c7, 1 @ TLB invalidate U MVA
-#endif
+ ALT_SMP(mcr p15, 0, r0, c8, c3, 1) @ TLB invalidate U MVA (shareable)
+ ALT_UP(mcr p15, 0, r0, c8, c7, 1) @ TLB invalidate U MVA
+
add r0, r0, #PAGE_SZ
cmp r0, r1
blo 1b
mov ip, #0
-#ifdef CONFIG_SMP
- mcr p15, 0, ip, c7, c1, 6 @ flush BTAC/BTB Inner Shareable
-#else
- mcr p15, 0, ip, c7, c5, 6 @ flush BTAC/BTB
-#endif
+ ALT_SMP(mcr p15, 0, ip, c7, c1, 6) @ flush BTAC/BTB Inner Shareable
+ ALT_UP(mcr p15, 0, ip, c7, c5, 6) @ flush BTAC/BTB
dsb
mov pc, lr
ENDPROC(v7wbi_flush_user_tlb_range)
@@ -74,20 +70,14 @@ ENTRY(v7wbi_flush_kern_tlb_range)
mov r0, r0, lsl #PAGE_SHIFT
mov r1, r1, lsl #PAGE_SHIFT
1:
-#ifdef CONFIG_SMP
- mcr p15, 0, r0, c8, c3, 1 @ TLB invalidate U MVA (shareable)
-#else
- mcr p15, 0, r0, c8, c7, 1 @ TLB invalidate U MVA
-#endif
+ ALT_SMP(mcr p15, 0, r0, c8, c3, 1) @ TLB invalidate U MVA (shareable)
+ ALT_UP(mcr p15, 0, r0, c8, c7, 1) @ TLB invalidate U MVA
add r0, r0, #PAGE_SZ
cmp r0, r1
blo 1b
mov r2, #0
-#ifdef CONFIG_SMP
- mcr p15, 0, r2, c7, c1, 6 @ flush BTAC/BTB Inner Shareable
-#else
- mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB
-#endif
+ ALT_SMP(mcr p15, 0, r2, c7, c1, 6) @ flush BTAC/BTB Inner Shareable
+ ALT_UP(mcr p15, 0, r2, c7, c5, 6) @ flush BTAC/BTB
dsb
isb
mov pc, lr
@@ -99,5 +89,6 @@ ENDPROC(v7wbi_flush_kern_tlb_range)
ENTRY(v7wbi_tlb_fns)
.long v7wbi_flush_user_tlb_range
.long v7wbi_flush_kern_tlb_range
- .long v7wbi_tlb_flags
+ ALT_SMP(.long v7wbi_tlb_flags_smp)
+ ALT_UP(.long v7wbi_tlb_flags_up)
.size v7wbi_tlb_fns, . - v7wbi_tlb_fns
diff --git a/arch/arm/nwfpe/milieu.h b/arch/arm/nwfpe/milieu.h
index a3892ab2dca4..09a4f2ddeb77 100644
--- a/arch/arm/nwfpe/milieu.h
+++ b/arch/arm/nwfpe/milieu.h
@@ -12,8 +12,8 @@ National Science Foundation under grant MIP-9311980. The original version
of this code was written as part of a project to build a fixed-point vector
processor in collaboration with the University of California at Berkeley,
overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
-arithmetic/softfloat.html'.
+is available through the Web page
+http://www.jhauser.us/arithmetic/SoftFloat-2b/SoftFloat-source.txt
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
diff --git a/arch/arm/nwfpe/softfloat-macros b/arch/arm/nwfpe/softfloat-macros
index 5a060f95a58f..cf2a6173149e 100644
--- a/arch/arm/nwfpe/softfloat-macros
+++ b/arch/arm/nwfpe/softfloat-macros
@@ -12,8 +12,8 @@ National Science Foundation under grant MIP-9311980. The original version
of this code was written as part of a project to build a fixed-point vector
processor in collaboration with the University of California at Berkeley,
overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
-arithmetic/softfloat.html'.
+is available through the web page
+http://www.jhauser.us/arithmetic/SoftFloat-2b/SoftFloat-source.txt
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
diff --git a/arch/arm/nwfpe/softfloat-specialize b/arch/arm/nwfpe/softfloat-specialize
index d4a4c8e06635..679a0269dd25 100644
--- a/arch/arm/nwfpe/softfloat-specialize
+++ b/arch/arm/nwfpe/softfloat-specialize
@@ -12,8 +12,8 @@ National Science Foundation under grant MIP-9311980. The original version
of this code was written as part of a project to build a fixed-point vector
processor in collaboration with the University of California at Berkeley,
overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
-arithmetic/softfloat.html'.
+is available through the Web page
+http://www.jhauser.us/arithmetic/SoftFloat-2b/SoftFloat-source.txt
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
diff --git a/arch/arm/nwfpe/softfloat.c b/arch/arm/nwfpe/softfloat.c
index 0f9656e482ba..ffa6b438786b 100644
--- a/arch/arm/nwfpe/softfloat.c
+++ b/arch/arm/nwfpe/softfloat.c
@@ -11,8 +11,8 @@ National Science Foundation under grant MIP-9311980. The original version
of this code was written as part of a project to build a fixed-point vector
processor in collaboration with the University of California at Berkeley,
overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
-arithmetic/softfloat.html'.
+is available through the web page
+http://www.jhauser.us/arithmetic/SoftFloat-2b/SoftFloat-source.txt
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
diff --git a/arch/arm/nwfpe/softfloat.h b/arch/arm/nwfpe/softfloat.h
index 13e479c5da57..df4d243a2b7c 100644
--- a/arch/arm/nwfpe/softfloat.h
+++ b/arch/arm/nwfpe/softfloat.h
@@ -12,8 +12,8 @@ National Science Foundation under grant MIP-9311980. The original version
of this code was written as part of a project to build a fixed-point vector
processor in collaboration with the University of California at Berkeley,
overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
-arithmetic/softfloat.html'.
+is available through the Web page
+http://www.jhauser.us/arithmetic/SoftFloat-2b/SoftFloat-source.txt
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
diff --git a/arch/arm/oprofile/Makefile b/arch/arm/oprofile/Makefile
index e666eafed152..b2215c61cdf0 100644
--- a/arch/arm/oprofile/Makefile
+++ b/arch/arm/oprofile/Makefile
@@ -6,4 +6,8 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
oprofilefs.o oprofile_stats.o \
timer_int.o )
+ifeq ($(CONFIG_HW_PERF_EVENTS),y)
+DRIVER_OBJS += $(addprefix ../../../drivers/oprofile/, oprofile_perf.o)
+endif
+
oprofile-y := $(DRIVER_OBJS) common.o
diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c
index 0691176899ff..8aa974491dfc 100644
--- a/arch/arm/oprofile/common.c
+++ b/arch/arm/oprofile/common.c
@@ -25,138 +25,10 @@
#include <asm/ptrace.h>
#ifdef CONFIG_HW_PERF_EVENTS
-/*
- * Per performance monitor configuration as set via oprofilefs.
- */
-struct op_counter_config {
- unsigned long count;
- unsigned long enabled;
- unsigned long event;
- unsigned long unit_mask;
- unsigned long kernel;
- unsigned long user;
- struct perf_event_attr attr;
-};
-
-static int op_arm_enabled;
-static DEFINE_MUTEX(op_arm_mutex);
-
-static struct op_counter_config *counter_config;
-static struct perf_event **perf_events[nr_cpumask_bits];
-static int perf_num_counters;
-
-/*
- * Overflow callback for oprofile.
- */
-static void op_overflow_handler(struct perf_event *event, int unused,
- struct perf_sample_data *data, struct pt_regs *regs)
-{
- int id;
- u32 cpu = smp_processor_id();
-
- for (id = 0; id < perf_num_counters; ++id)
- if (perf_events[cpu][id] == event)
- break;
-
- if (id != perf_num_counters)
- oprofile_add_sample(regs, id);
- else
- pr_warning("oprofile: ignoring spurious overflow "
- "on cpu %u\n", cpu);
-}
-
-/*
- * Called by op_arm_setup to create perf attributes to mirror the oprofile
- * settings in counter_config. Attributes are created as `pinned' events and
- * so are permanently scheduled on the PMU.
- */
-static void op_perf_setup(void)
-{
- int i;
- u32 size = sizeof(struct perf_event_attr);
- struct perf_event_attr *attr;
-
- for (i = 0; i < perf_num_counters; ++i) {
- attr = &counter_config[i].attr;
- memset(attr, 0, size);
- attr->type = PERF_TYPE_RAW;
- attr->size = size;
- attr->config = counter_config[i].event;
- attr->sample_period = counter_config[i].count;
- attr->pinned = 1;
- }
-}
-
-static int op_create_counter(int cpu, int event)
-{
- int ret = 0;
- struct perf_event *pevent;
-
- if (!counter_config[event].enabled || (perf_events[cpu][event] != NULL))
- return ret;
-
- pevent = perf_event_create_kernel_counter(&counter_config[event].attr,
- cpu, -1,
- op_overflow_handler);
-
- if (IS_ERR(pevent)) {
- ret = PTR_ERR(pevent);
- } else if (pevent->state != PERF_EVENT_STATE_ACTIVE) {
- pr_warning("oprofile: failed to enable event %d "
- "on CPU %d\n", event, cpu);
- ret = -EBUSY;
- } else {
- perf_events[cpu][event] = pevent;
- }
-
- return ret;
-}
-
-static void op_destroy_counter(int cpu, int event)
-{
- struct perf_event *pevent = perf_events[cpu][event];
-
- if (pevent) {
- perf_event_release_kernel(pevent);
- perf_events[cpu][event] = NULL;
- }
-}
-
-/*
- * Called by op_arm_start to create active perf events based on the
- * perviously configured attributes.
- */
-static int op_perf_start(void)
-{
- int cpu, event, ret = 0;
-
- for_each_online_cpu(cpu) {
- for (event = 0; event < perf_num_counters; ++event) {
- ret = op_create_counter(cpu, event);
- if (ret)
- goto out;
- }
- }
-
-out:
- return ret;
-}
-
-/*
- * Called by op_arm_stop at the end of a profiling run.
- */
-static void op_perf_stop(void)
+char *op_name_from_perf_id(void)
{
- int cpu, event;
+ enum arm_perf_pmu_ids id = armpmu_get_pmu_id();
- for_each_online_cpu(cpu)
- for (event = 0; event < perf_num_counters; ++event)
- op_destroy_counter(cpu, event);
-}
-
-
-static char *op_name_from_perf_id(enum arm_perf_pmu_ids id)
-{
switch (id) {
case ARM_PERF_PMU_ID_XSCALE1:
return "arm/xscale1";
@@ -175,116 +47,6 @@ static char *op_name_from_perf_id(enum arm_perf_pmu_ids id)
}
}
-static int op_arm_create_files(struct super_block *sb, struct dentry *root)
-{
- unsigned int i;
-
- for (i = 0; i < perf_num_counters; i++) {
- struct dentry *dir;
- char buf[4];
-
- snprintf(buf, sizeof buf, "%d", i);
- dir = oprofilefs_mkdir(sb, root, buf);
- oprofilefs_create_ulong(sb, dir, "enabled", &counter_config[i].enabled);
- oprofilefs_create_ulong(sb, dir, "event", &counter_config[i].event);
- oprofilefs_create_ulong(sb, dir, "count", &counter_config[i].count);
- oprofilefs_create_ulong(sb, dir, "unit_mask", &counter_config[i].unit_mask);
- oprofilefs_create_ulong(sb, dir, "kernel", &counter_config[i].kernel);
- oprofilefs_create_ulong(sb, dir, "user", &counter_config[i].user);
- }
-
- return 0;
-}
-
-static int op_arm_setup(void)
-{
- spin_lock(&oprofilefs_lock);
- op_perf_setup();
- spin_unlock(&oprofilefs_lock);
- return 0;
-}
-
-static int op_arm_start(void)
-{
- int ret = -EBUSY;
-
- mutex_lock(&op_arm_mutex);
- if (!op_arm_enabled) {
- ret = 0;
- op_perf_start();
- op_arm_enabled = 1;
- }
- mutex_unlock(&op_arm_mutex);
- return ret;
-}
-
-static void op_arm_stop(void)
-{
- mutex_lock(&op_arm_mutex);
- if (op_arm_enabled)
- op_perf_stop();
- op_arm_enabled = 0;
- mutex_unlock(&op_arm_mutex);
-}
-
-#ifdef CONFIG_PM
-static int op_arm_suspend(struct platform_device *dev, pm_message_t state)
-{
- mutex_lock(&op_arm_mutex);
- if (op_arm_enabled)
- op_perf_stop();
- mutex_unlock(&op_arm_mutex);
- return 0;
-}
-
-static int op_arm_resume(struct platform_device *dev)
-{
- mutex_lock(&op_arm_mutex);
- if (op_arm_enabled && op_perf_start())
- op_arm_enabled = 0;
- mutex_unlock(&op_arm_mutex);
- return 0;
-}
-
-static struct platform_driver oprofile_driver = {
- .driver = {
- .name = "arm-oprofile",
- },
- .resume = op_arm_resume,
- .suspend = op_arm_suspend,
-};
-
-static struct platform_device *oprofile_pdev;
-
-static int __init init_driverfs(void)
-{
- int ret;
-
- ret = platform_driver_register(&oprofile_driver);
- if (ret)
- goto out;
-
- oprofile_pdev = platform_device_register_simple(
- oprofile_driver.driver.name, 0, NULL, 0);
- if (IS_ERR(oprofile_pdev)) {
- ret = PTR_ERR(oprofile_pdev);
- platform_driver_unregister(&oprofile_driver);
- }
-
-out:
- return ret;
-}
-
-static void exit_driverfs(void)
-{
- platform_device_unregister(oprofile_pdev);
- platform_driver_unregister(&oprofile_driver);
-}
-#else
-static int __init init_driverfs(void) { return 0; }
-#define exit_driverfs() do { } while (0)
-#endif /* CONFIG_PM */
-
static int report_trace(struct stackframe *frame, void *d)
{
unsigned int *depth = d;
@@ -349,72 +111,14 @@ static void arm_backtrace(struct pt_regs * const regs, unsigned int depth)
int __init oprofile_arch_init(struct oprofile_operations *ops)
{
- int cpu, ret = 0;
-
- perf_num_counters = armpmu_get_max_events();
-
- counter_config = kcalloc(perf_num_counters,
- sizeof(struct op_counter_config), GFP_KERNEL);
-
- if (!counter_config) {
- pr_info("oprofile: failed to allocate %d "
- "counters\n", perf_num_counters);
- return -ENOMEM;
- }
-
- ret = init_driverfs();
- if (ret) {
- kfree(counter_config);
- return ret;
- }
-
- for_each_possible_cpu(cpu) {
- perf_events[cpu] = kcalloc(perf_num_counters,
- sizeof(struct perf_event *), GFP_KERNEL);
- if (!perf_events[cpu]) {
- pr_info("oprofile: failed to allocate %d perf events "
- "for cpu %d\n", perf_num_counters, cpu);
- while (--cpu >= 0)
- kfree(perf_events[cpu]);
- return -ENOMEM;
- }
- }
-
ops->backtrace = arm_backtrace;
- ops->create_files = op_arm_create_files;
- ops->setup = op_arm_setup;
- ops->start = op_arm_start;
- ops->stop = op_arm_stop;
- ops->shutdown = op_arm_stop;
- ops->cpu_type = op_name_from_perf_id(armpmu_get_pmu_id());
-
- if (!ops->cpu_type)
- ret = -ENODEV;
- else
- pr_info("oprofile: using %s\n", ops->cpu_type);
- return ret;
+ return oprofile_perf_init(ops);
}
-void oprofile_arch_exit(void)
+void __exit oprofile_arch_exit(void)
{
- int cpu, id;
- struct perf_event *event;
-
- if (*perf_events) {
- exit_driverfs();
- for_each_possible_cpu(cpu) {
- for (id = 0; id < perf_num_counters; ++id) {
- event = perf_events[cpu][id];
- if (event != NULL)
- perf_event_release_kernel(event);
- }
- kfree(perf_events[cpu]);
- }
- }
-
- if (counter_config)
- kfree(counter_config);
+ oprofile_perf_exit();
}
#else
int __init oprofile_arch_init(struct oprofile_operations *ops)
@@ -422,5 +126,5 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
pr_info("oprofile: hardware counters not available\n");
return -ENODEV;
}
-void oprofile_arch_exit(void) {}
+void __exit oprofile_arch_exit(void) {}
#endif /* CONFIG_HW_PERF_EVENTS */
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
index 6785db4179b8..64e3a64520e0 100644
--- a/arch/arm/plat-mxc/Kconfig
+++ b/arch/arm/plat-mxc/Kconfig
@@ -92,6 +92,18 @@ config MXC_DEBUG_BOARD
data/address de-multiplexing and decode, signal level shift,
interrupt control and various board functions.
+config HAVE_EPIT
+ bool
+
+config MXC_USE_EPIT
+ bool "Use EPIT instead of GPT"
+ depends on HAVE_EPIT
+ help
+ Use EPIT as the system timer on systems that have it. Normally you
+ don't have a reason to do so as the EPIT has the same features and
+ uses the same clocks as the GPT. Anyway, on some systems the GPT
+ may be in use for other purposes.
+
config MXC_ULPI
bool
@@ -110,4 +122,8 @@ config ARCH_MXC_AUDMUX_V1
config ARCH_MXC_AUDMUX_V2
bool
+config IRAM_ALLOC
+ bool
+ select GENERIC_ALLOCATOR
+
endif
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
index 78d405ed8616..06875b4dd70f 100644
--- a/arch/arm/plat-mxc/Makefile
+++ b/arch/arm/plat-mxc/Makefile
@@ -10,9 +10,11 @@ obj-$(CONFIG_MXC_TZIC) += tzic.o
obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o
obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
+obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o
obj-$(CONFIG_MXC_PWM) += pwm.o
obj-$(CONFIG_USB_EHCI_MXC) += ehci.o
obj-$(CONFIG_MXC_ULPI) += ulpi.o
+obj-$(CONFIG_MXC_USE_EPIT) += epit.o
obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o
obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o
obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
diff --git a/arch/arm/plat-mxc/audmux-v2.c b/arch/arm/plat-mxc/audmux-v2.c
index f9e7cdbd0005..0be1ac7f421b 100644
--- a/arch/arm/plat-mxc/audmux-v2.c
+++ b/arch/arm/plat-mxc/audmux-v2.c
@@ -137,6 +137,7 @@ static ssize_t audmux_read_file(struct file *file, char __user *user_buf,
static const struct file_operations audmux_debugfs_fops = {
.open = audmux_open_file,
.read = audmux_read_file,
+ .llseek = default_llseek,
};
static void audmux_debugfs_init(void)
@@ -186,7 +187,13 @@ EXPORT_SYMBOL_GPL(mxc_audmux_v2_configure_port);
static int mxc_audmux_v2_init(void)
{
int ret;
-
+#if defined(CONFIG_ARCH_MX5)
+ if (cpu_is_mx51()) {
+ audmux_base = MX51_IO_ADDRESS(MX51_AUDMUX_BASE_ADDR);
+ ret = 0;
+ return ret;
+ }
+#endif
#if defined(CONFIG_ARCH_MX3)
if (cpu_is_mx31())
audmux_base = MX31_IO_ADDRESS(MX31_AUDMUX_BASE_ADDR);
diff --git a/arch/arm/plat-mxc/devices/Kconfig b/arch/arm/plat-mxc/devices/Kconfig
index 9ab784b776f9..404799487f17 100644
--- a/arch/arm/plat-mxc/devices/Kconfig
+++ b/arch/arm/plat-mxc/devices/Kconfig
@@ -1,3 +1,10 @@
+config IMX_HAVE_PLATFORM_ESDHC
+ bool
+
+config IMX_HAVE_PLATFORM_FEC
+ bool
+ default y if ARCH_MX25 || SOC_IMX27 || ARCH_MX35 || ARCH_MX51
+
config IMX_HAVE_PLATFORM_FLEXCAN
select HAVE_CAN_FLEXCAN
bool
@@ -5,6 +12,9 @@ config IMX_HAVE_PLATFORM_FLEXCAN
config IMX_HAVE_PLATFORM_IMX_I2C
bool
+config IMX_HAVE_PLATFORM_IMX_SSI
+ bool
+
config IMX_HAVE_PLATFORM_IMX_UART
bool
diff --git a/arch/arm/plat-mxc/devices/Makefile b/arch/arm/plat-mxc/devices/Makefile
index 347da5161f7e..0a3c1f089413 100644
--- a/arch/arm/plat-mxc/devices/Makefile
+++ b/arch/arm/plat-mxc/devices/Makefile
@@ -1,8 +1,9 @@
-ifdef CONFIG_CAN_FLEXCAN
-# the ifdef can be removed once the flexcan driver has been merged
-obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o
-endif
+obj-$(CONFIG_IMX_HAVE_PLATFORM_ESDHC) += platform-esdhc.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_FEC) += platform-fec.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o
+obj-y += platform-imx-dma.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_I2C) += platform-imx-i2c.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_SSI) += platform-imx-ssi.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_UART) += platform-imx-uart.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_NAND) += platform-mxc_nand.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_SPI_IMX) += platform-spi_imx.o
diff --git a/arch/arm/plat-mxc/devices/platform-esdhc.c b/arch/arm/plat-mxc/devices/platform-esdhc.c
new file mode 100644
index 000000000000..2605bfa0dfb0
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-esdhc.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 Pengutronix, Wolfram Sang <w.sang@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+#include <mach/esdhc.h>
+
+#define imx_esdhc_imx_data_entry_single(soc, _id, hwid) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _ESDHC ## hwid ## _BASE_ADDR, \
+ .irq = soc ## _INT_ESDHC ## hwid, \
+ }
+
+#define imx_esdhc_imx_data_entry(soc, id, hwid) \
+ [id] = imx_esdhc_imx_data_entry_single(soc, id, hwid)
+
+#ifdef CONFIG_ARCH_MX25
+const struct imx_esdhc_imx_data imx25_esdhc_data[] __initconst = {
+#define imx25_esdhc_data_entry(_id, _hwid) \
+ imx_esdhc_imx_data_entry(MX25, _id, _hwid)
+ imx25_esdhc_data_entry(0, 1),
+ imx25_esdhc_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_ARCH_MX25 */
+
+#ifdef CONFIG_ARCH_MX35
+const struct imx_esdhc_imx_data imx35_esdhc_data[] __initconst = {
+#define imx35_esdhc_data_entry(_id, _hwid) \
+ imx_esdhc_imx_data_entry(MX35, _id, _hwid)
+ imx35_esdhc_data_entry(0, 1),
+ imx35_esdhc_data_entry(1, 2),
+ imx35_esdhc_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_ARCH_MX35 */
+
+#ifdef CONFIG_ARCH_MX51
+const struct imx_esdhc_imx_data imx51_esdhc_data[] __initconst = {
+#define imx51_esdhc_data_entry(_id, _hwid) \
+ imx_esdhc_imx_data_entry(MX51, _id, _hwid)
+ imx51_esdhc_data_entry(0, 1),
+ imx51_esdhc_data_entry(1, 2),
+ imx51_esdhc_data_entry(2, 3),
+ imx51_esdhc_data_entry(3, 4),
+};
+#endif /* ifdef CONFIG_ARCH_MX51 */
+
+struct platform_device *__init imx_add_esdhc(
+ const struct imx_esdhc_imx_data *data,
+ const struct esdhc_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("sdhci-esdhc-imx", data->id, res,
+ ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-fec.c b/arch/arm/plat-mxc/devices/platform-fec.c
new file mode 100644
index 000000000000..11d087f4e219
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-fec.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_fec_data_entry_single(soc) \
+ { \
+ .iobase = soc ## _FEC_BASE_ADDR, \
+ .irq = soc ## _INT_FEC, \
+ }
+
+#ifdef CONFIG_ARCH_MX25
+const struct imx_fec_data imx25_fec_data __initconst =
+ imx_fec_data_entry_single(MX25);
+#endif /* ifdef CONFIG_ARCH_MX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_fec_data imx27_fec_data __initconst =
+ imx_fec_data_entry_single(MX27);
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_ARCH_MX35
+const struct imx_fec_data imx35_fec_data __initconst =
+ imx_fec_data_entry_single(MX35);
+#endif
+
+#ifdef CONFIG_ARCH_MX51
+const struct imx_fec_data imx51_fec_data __initconst =
+ imx_fec_data_entry_single(MX51);
+#endif
+
+struct platform_device *__init imx_add_fec(
+ const struct imx_fec_data *data,
+ const struct fec_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_4K,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("fec", 0 /* -1? */,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-dma.c b/arch/arm/plat-mxc/devices/platform-imx-dma.c
new file mode 100644
index 000000000000..02d989018059
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-dma.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <linux/compiler.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+#ifdef SDMA_IS_MERGED
+#include <mach/sdma.h>
+#else
+struct sdma_platform_data {
+ int sdma_version;
+ char *cpu_name;
+ int to_version;
+};
+#endif
+
+struct imx_imx_sdma_data {
+ resource_size_t iobase;
+ resource_size_t irq;
+ struct sdma_platform_data pdata;
+};
+
+#define imx_imx_sdma_data_entry_single(soc, _sdma_version, _cpu_name, _to_version)\
+ { \
+ .iobase = soc ## _SDMA ## _BASE_ADDR, \
+ .irq = soc ## _INT_SDMA, \
+ .pdata = { \
+ .sdma_version = _sdma_version, \
+ .cpu_name = _cpu_name, \
+ .to_version = _to_version, \
+ }, \
+ }
+
+#ifdef CONFIG_ARCH_MX25
+const struct imx_imx_sdma_data imx25_imx_sdma_data __initconst =
+ imx_imx_sdma_data_entry_single(MX25, 1, "imx25", 0);
+#endif /* ifdef CONFIG_ARCH_MX25 */
+
+#ifdef CONFIG_ARCH_MX31
+struct imx_imx_sdma_data imx31_imx_sdma_data __initdata =
+ imx_imx_sdma_data_entry_single(MX31, 1, "imx31", 0);
+#endif /* ifdef CONFIG_ARCH_MX31 */
+
+#ifdef CONFIG_ARCH_MX35
+struct imx_imx_sdma_data imx35_imx_sdma_data __initdata =
+ imx_imx_sdma_data_entry_single(MX35, 2, "imx35", 0);
+#endif /* ifdef CONFIG_ARCH_MX35 */
+
+#ifdef CONFIG_ARCH_MX51
+const struct imx_imx_sdma_data imx51_imx_sdma_data __initconst =
+ imx_imx_sdma_data_entry_single(MX51, 2, "imx51", 0);
+#endif /* ifdef CONFIG_ARCH_MX51 */
+
+static struct platform_device __init __maybe_unused *imx_add_imx_sdma(
+ const struct imx_imx_sdma_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("imx-sdma", -1,
+ res, ARRAY_SIZE(res),
+ &data->pdata, sizeof(data->pdata));
+}
+
+static struct platform_device __init __maybe_unused *imx_add_imx_dma(void)
+{
+ return imx_add_platform_device("imx-dma", -1, NULL, 0, NULL, 0);
+}
+
+static int __init imxXX_add_imx_dma(void)
+{
+ struct platform_device *ret;
+
+#if defined(CONFIG_SOC_IMX21) || defined(CONFIG_SOC_IMX27)
+ if (cpu_is_mx21() || cpu_is_mx27())
+ ret = imx_add_imx_dma();
+ else
+#endif
+
+#if defined(CONFIG_ARCH_MX25)
+ if (cpu_is_mx25())
+ ret = imx_add_imx_sdma(&imx25_imx_sdma_data);
+ else
+#endif
+
+#if defined(CONFIG_ARCH_MX31)
+ if (cpu_is_mx31()) {
+ imx31_imx_sdma_data.pdata.to_version = mx31_revision() >> 4;
+ ret = imx_add_imx_sdma(&imx31_imx_sdma_data);
+ } else
+#endif
+
+#if defined(CONFIG_ARCH_MX35)
+ if (cpu_is_mx35()) {
+ imx35_imx_sdma_data.pdata.to_version = mx35_revision() >> 4;
+ ret = imx_add_imx_sdma(&imx35_imx_sdma_data);
+ } else
+#endif
+
+#if defined(CONFIG_ARCH_MX51)
+ if (cpu_is_mx51())
+ ret = imx_add_imx_sdma(&imx51_imx_sdma_data);
+ else
+#endif
+ ret = ERR_PTR(-ENODEV);
+
+ if (IS_ERR(ret))
+ return PTR_ERR(ret);
+
+ return 0;
+}
+arch_initcall(imxXX_add_imx_dma);
diff --git a/arch/arm/plat-mxc/devices/platform-imx-i2c.c b/arch/arm/plat-mxc/devices/platform-imx-i2c.c
index d0af9f7d8aed..679588453aad 100644
--- a/arch/arm/plat-mxc/devices/platform-imx-i2c.c
+++ b/arch/arm/plat-mxc/devices/platform-imx-i2c.c
@@ -6,24 +6,95 @@
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*/
+#include <mach/hardware.h>
#include <mach/devices-common.h>
-struct platform_device *__init imx_add_imx_i2c(int id,
- resource_size_t iobase, resource_size_t iosize, int irq,
+#define imx_imx_i2c_data_entry_single(soc, _id, _hwid, _size) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _I2C ## _hwid ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_I2C ## _hwid, \
+ }
+
+#define imx_imx_i2c_data_entry(soc, _id, _hwid, _size) \
+ [_id] = imx_imx_i2c_data_entry_single(soc, _id, _hwid, _size)
+
+#ifdef CONFIG_SOC_IMX1
+const struct imx_imx_i2c_data imx1_imx_i2c_data __initconst =
+ imx_imx_i2c_data_entry_single(MX1, 0, , SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX1 */
+
+#ifdef CONFIG_SOC_IMX21
+const struct imx_imx_i2c_data imx21_imx_i2c_data __initconst =
+ imx_imx_i2c_data_entry_single(MX21, 0, , SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX21 */
+
+#ifdef CONFIG_ARCH_MX25
+const struct imx_imx_i2c_data imx25_imx_i2c_data[] __initconst = {
+#define imx25_imx_i2c_data_entry(_id, _hwid) \
+ imx_imx_i2c_data_entry(MX25, _id, _hwid, SZ_16K)
+ imx25_imx_i2c_data_entry(0, 1),
+ imx25_imx_i2c_data_entry(1, 2),
+ imx25_imx_i2c_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_ARCH_MX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_imx_i2c_data imx27_imx_i2c_data[] __initconst = {
+#define imx27_imx_i2c_data_entry(_id, _hwid) \
+ imx_imx_i2c_data_entry(MX27, _id, _hwid, SZ_4K)
+ imx27_imx_i2c_data_entry(0, 1),
+ imx27_imx_i2c_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_ARCH_MX31
+const struct imx_imx_i2c_data imx31_imx_i2c_data[] __initconst = {
+#define imx31_imx_i2c_data_entry(_id, _hwid) \
+ imx_imx_i2c_data_entry(MX31, _id, _hwid, SZ_4K)
+ imx31_imx_i2c_data_entry(0, 1),
+ imx31_imx_i2c_data_entry(1, 2),
+ imx31_imx_i2c_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_ARCH_MX31 */
+
+#ifdef CONFIG_ARCH_MX35
+const struct imx_imx_i2c_data imx35_imx_i2c_data[] __initconst = {
+#define imx35_imx_i2c_data_entry(_id, _hwid) \
+ imx_imx_i2c_data_entry(MX35, _id, _hwid, SZ_4K)
+ imx35_imx_i2c_data_entry(0, 1),
+ imx35_imx_i2c_data_entry(1, 2),
+ imx35_imx_i2c_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_ARCH_MX35 */
+
+#ifdef CONFIG_ARCH_MX51
+const struct imx_imx_i2c_data imx51_imx_i2c_data[] __initconst = {
+#define imx51_imx_i2c_data_entry(_id, _hwid) \
+ imx_imx_i2c_data_entry(MX51, _id, _hwid, SZ_4K)
+ imx51_imx_i2c_data_entry(0, 1),
+ imx51_imx_i2c_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_ARCH_MX51 */
+
+struct platform_device *__init imx_add_imx_i2c(
+ const struct imx_imx_i2c_data *data,
const struct imxi2c_platform_data *pdata)
{
struct resource res[] = {
{
- .start = iobase,
- .end = iobase + iosize - 1,
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
.flags = IORESOURCE_MEM,
}, {
- .start = irq,
- .end = irq,
+ .start = data->irq,
+ .end = data->irq,
.flags = IORESOURCE_IRQ,
},
};
- return imx_add_platform_device("imx-i2c", id, res, ARRAY_SIZE(res),
+ return imx_add_platform_device("imx-i2c", data->id,
+ res, ARRAY_SIZE(res),
pdata, sizeof(*pdata));
}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-ssi.c b/arch/arm/plat-mxc/devices/platform-imx-ssi.c
new file mode 100644
index 000000000000..38a7a0b8f2f1
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-ssi.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_imx_ssi_data_entry(soc, _id, _hwid, _size) \
+ [_id] = { \
+ .id = _id, \
+ .iobase = soc ## _SSI ## _hwid ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_SSI ## _hwid, \
+ .dmatx0 = soc ## _DMA_REQ_SSI ## _hwid ## _TX0, \
+ .dmarx0 = soc ## _DMA_REQ_SSI ## _hwid ## _RX0, \
+ .dmatx1 = soc ## _DMA_REQ_SSI ## _hwid ## _TX1, \
+ .dmarx1 = soc ## _DMA_REQ_SSI ## _hwid ## _RX1, \
+ }
+
+#ifdef CONFIG_SOC_IMX21
+const struct imx_imx_ssi_data imx21_imx_ssi_data[] __initconst = {
+#define imx21_imx_ssi_data_entry(_id, _hwid) \
+ imx_imx_ssi_data_entry(MX21, _id, _hwid, SZ_4K)
+ imx21_imx_ssi_data_entry(0, 1),
+ imx21_imx_ssi_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX21 */
+
+#ifdef CONFIG_ARCH_MX25
+const struct imx_imx_ssi_data imx25_imx_ssi_data[] __initconst = {
+#define imx25_imx_ssi_data_entry(_id, _hwid) \
+ imx_imx_ssi_data_entry(MX25, _id, _hwid, SZ_4K)
+ imx25_imx_ssi_data_entry(0, 1),
+ imx25_imx_ssi_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_ARCH_MX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_imx_ssi_data imx27_imx_ssi_data[] __initconst = {
+#define imx27_imx_ssi_data_entry(_id, _hwid) \
+ imx_imx_ssi_data_entry(MX27, _id, _hwid, SZ_4K)
+ imx27_imx_ssi_data_entry(0, 1),
+ imx27_imx_ssi_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_ARCH_MX31
+const struct imx_imx_ssi_data imx31_imx_ssi_data[] __initconst = {
+#define imx31_imx_ssi_data_entry(_id, _hwid) \
+ imx_imx_ssi_data_entry(MX31, _id, _hwid, SZ_4K)
+ imx31_imx_ssi_data_entry(0, 1),
+ imx31_imx_ssi_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_ARCH_MX31 */
+
+#ifdef CONFIG_ARCH_MX35
+const struct imx_imx_ssi_data imx35_imx_ssi_data[] __initconst = {
+#define imx35_imx_ssi_data_entry(_id, _hwid) \
+ imx_imx_ssi_data_entry(MX35, _id, _hwid, SZ_4K)
+ imx35_imx_ssi_data_entry(0, 1),
+ imx35_imx_ssi_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_ARCH_MX35 */
+
+#ifdef CONFIG_ARCH_MX51
+const struct imx_imx_ssi_data imx51_imx_ssi_data[] __initconst = {
+#define imx51_imx_ssi_data_entry(_id, _hwid) \
+ imx_imx_ssi_data_entry(MX51, _id, _hwid, SZ_4K)
+ imx51_imx_ssi_data_entry(0, 1),
+ imx51_imx_ssi_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_ARCH_MX51 */
+
+struct platform_device *__init imx_add_imx_ssi(
+ const struct imx_imx_ssi_data *data,
+ const struct imx_ssi_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+#define DMARES(_name) { \
+ .name = #_name, \
+ .start = data->dma ## _name, \
+ .end = data->dma ## _name, \
+ .flags = IORESOURCE_DMA, \
+}
+ DMARES(tx0),
+ DMARES(rx0),
+ DMARES(tx1),
+ DMARES(rx1),
+ };
+
+ return imx_add_platform_device("imx-ssi", data->id,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-uart.c b/arch/arm/plat-mxc/devices/platform-imx-uart.c
index fa3dff1433e8..2039640adf27 100644
--- a/arch/arm/plat-mxc/devices/platform-imx-uart.c
+++ b/arch/arm/plat-mxc/devices/platform-imx-uart.c
@@ -6,55 +6,148 @@
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*/
+#include <mach/hardware.h>
#include <mach/devices-common.h>
-struct platform_device *__init imx_add_imx_uart_3irq(int id,
- resource_size_t iobase, resource_size_t iosize,
- resource_size_t irqrx, resource_size_t irqtx,
- resource_size_t irqrts,
+#define imx_imx_uart_3irq_data_entry(soc, _id, _hwid, _size) \
+ [_id] = { \
+ .id = _id, \
+ .iobase = soc ## _UART ## _hwid ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irqrx = soc ## _INT_UART ## _hwid ## RX, \
+ .irqtx = soc ## _INT_UART ## _hwid ## TX, \
+ .irqrts = soc ## _INT_UART ## _hwid ## RTS, \
+ }
+
+#define imx_imx_uart_1irq_data_entry(soc, _id, _hwid, _size) \
+ [_id] = { \
+ .id = _id, \
+ .iobase = soc ## _UART ## _hwid ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_UART ## _hwid, \
+ }
+
+#ifdef CONFIG_SOC_IMX1
+const struct imx_imx_uart_3irq_data imx1_imx_uart_data[] __initconst = {
+#define imx1_imx_uart_data_entry(_id, _hwid) \
+ imx_imx_uart_3irq_data_entry(MX1, _id, _hwid, 0xd0)
+ imx1_imx_uart_data_entry(0, 1),
+ imx1_imx_uart_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX1 */
+
+#ifdef CONFIG_SOC_IMX21
+const struct imx_imx_uart_1irq_data imx21_imx_uart_data[] __initconst = {
+#define imx21_imx_uart_data_entry(_id, _hwid) \
+ imx_imx_uart_1irq_data_entry(MX21, _id, _hwid, SZ_4K)
+ imx21_imx_uart_data_entry(0, 1),
+ imx21_imx_uart_data_entry(1, 2),
+ imx21_imx_uart_data_entry(2, 3),
+ imx21_imx_uart_data_entry(3, 4),
+};
+#endif
+
+#ifdef CONFIG_ARCH_MX25
+const struct imx_imx_uart_1irq_data imx25_imx_uart_data[] __initconst = {
+#define imx25_imx_uart_data_entry(_id, _hwid) \
+ imx_imx_uart_1irq_data_entry(MX25, _id, _hwid, SZ_16K)
+ imx25_imx_uart_data_entry(0, 1),
+ imx25_imx_uart_data_entry(1, 2),
+ imx25_imx_uart_data_entry(2, 3),
+ imx25_imx_uart_data_entry(3, 4),
+ imx25_imx_uart_data_entry(4, 5),
+};
+#endif /* ifdef CONFIG_ARCH_MX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_imx_uart_1irq_data imx27_imx_uart_data[] __initconst = {
+#define imx27_imx_uart_data_entry(_id, _hwid) \
+ imx_imx_uart_1irq_data_entry(MX27, _id, _hwid, SZ_4K)
+ imx27_imx_uart_data_entry(0, 1),
+ imx27_imx_uart_data_entry(1, 2),
+ imx27_imx_uart_data_entry(2, 3),
+ imx27_imx_uart_data_entry(3, 4),
+ imx27_imx_uart_data_entry(4, 5),
+ imx27_imx_uart_data_entry(5, 6),
+};
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_ARCH_MX31
+const struct imx_imx_uart_1irq_data imx31_imx_uart_data[] __initconst = {
+#define imx31_imx_uart_data_entry(_id, _hwid) \
+ imx_imx_uart_1irq_data_entry(MX31, _id, _hwid, SZ_4K)
+ imx31_imx_uart_data_entry(0, 1),
+ imx31_imx_uart_data_entry(1, 2),
+ imx31_imx_uart_data_entry(2, 3),
+ imx31_imx_uart_data_entry(3, 4),
+ imx31_imx_uart_data_entry(4, 5),
+};
+#endif /* ifdef CONFIG_ARCH_MX31 */
+
+#ifdef CONFIG_ARCH_MX35
+const struct imx_imx_uart_1irq_data imx35_imx_uart_data[] __initconst = {
+#define imx35_imx_uart_data_entry(_id, _hwid) \
+ imx_imx_uart_1irq_data_entry(MX31, _id, _hwid, SZ_16K)
+ imx35_imx_uart_data_entry(0, 1),
+ imx35_imx_uart_data_entry(1, 2),
+ imx35_imx_uart_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_ARCH_MX35 */
+
+#ifdef CONFIG_ARCH_MX51
+const struct imx_imx_uart_1irq_data imx51_imx_uart_data[] __initconst = {
+#define imx51_imx_uart_data_entry(_id, _hwid) \
+ imx_imx_uart_1irq_data_entry(MX51, _id, _hwid, SZ_4K)
+ imx51_imx_uart_data_entry(0, 1),
+ imx51_imx_uart_data_entry(1, 2),
+ imx51_imx_uart_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_ARCH_MX51 */
+
+struct platform_device *__init imx_add_imx_uart_3irq(
+ const struct imx_imx_uart_3irq_data *data,
const struct imxuart_platform_data *pdata)
{
struct resource res[] = {
{
- .start = iobase,
- .end = iobase + iosize - 1,
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
.flags = IORESOURCE_MEM,
}, {
- .start = irqrx,
- .end = irqrx,
+ .start = data->irqrx,
+ .end = data->irqrx,
.flags = IORESOURCE_IRQ,
}, {
- .start = irqtx,
- .end = irqtx,
+ .start = data->irqtx,
+ .end = data->irqtx,
.flags = IORESOURCE_IRQ,
}, {
- .start = irqrts,
- .end = irqrx,
+ .start = data->irqrts,
+ .end = data->irqrx,
.flags = IORESOURCE_IRQ,
},
};
- return imx_add_platform_device("imx-uart", id, res, ARRAY_SIZE(res),
- pdata, sizeof(*pdata));
+ return imx_add_platform_device("imx-uart", data->id, res,
+ ARRAY_SIZE(res), pdata, sizeof(*pdata));
}
-struct platform_device *__init imx_add_imx_uart_1irq(int id,
- resource_size_t iobase, resource_size_t iosize,
- resource_size_t irq,
+struct platform_device *__init imx_add_imx_uart_1irq(
+ const struct imx_imx_uart_1irq_data *data,
const struct imxuart_platform_data *pdata)
{
struct resource res[] = {
{
- .start = iobase,
- .end = iobase + iosize - 1,
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
.flags = IORESOURCE_MEM,
}, {
- .start = irq,
- .end = irq,
+ .start = data->irq,
+ .end = data->irq,
.flags = IORESOURCE_IRQ,
},
};
- return imx_add_platform_device("imx-uart", id, res, ARRAY_SIZE(res),
+ return imx_add_platform_device("imx-uart", data->id, res, ARRAY_SIZE(res),
pdata, sizeof(*pdata));
}
diff --git a/arch/arm/plat-mxc/devices/platform-mxc_nand.c b/arch/arm/plat-mxc/devices/platform-mxc_nand.c
index 1c286418d123..3fdcc32e3d67 100644
--- a/arch/arm/plat-mxc/devices/platform-mxc_nand.c
+++ b/arch/arm/plat-mxc/devices/platform-mxc_nand.c
@@ -7,38 +7,77 @@
* Free Software Foundation.
*/
#include <asm/sizes.h>
+#include <mach/hardware.h>
#include <mach/devices-common.h>
-static struct platform_device *__init imx_add_mxc_nand(resource_size_t iobase,
- int irq, const struct mxc_nand_platform_data *pdata,
- resource_size_t iosize)
+#define imx_mxc_nand_data_entry_single(soc, _size) \
+ { \
+ .iobase = soc ## _NFC_BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_NFC \
+ }
+
+#define imx_mxc_nandv3_data_entry_single(soc, _size) \
+ { \
+ .id = -1, \
+ .iobase = soc ## _NFC_BASE_ADDR, \
+ .iosize = _size, \
+ .axibase = soc ## _NFC_AXI_BASE_ADDR, \
+ .irq = soc ## _INT_NFC \
+ }
+
+#ifdef CONFIG_SOC_IMX21
+const struct imx_mxc_nand_data imx21_mxc_nand_data __initconst =
+ imx_mxc_nand_data_entry_single(MX21, SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX21 */
+
+#ifdef CONFIG_ARCH_MX25
+const struct imx_mxc_nand_data imx25_mxc_nand_data __initconst =
+ imx_mxc_nand_data_entry_single(MX25, SZ_8K);
+#endif /* ifdef CONFIG_ARCH_MX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_mxc_nand_data imx27_mxc_nand_data __initconst =
+ imx_mxc_nand_data_entry_single(MX27, SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_ARCH_MX31
+const struct imx_mxc_nand_data imx31_mxc_nand_data __initconst =
+ imx_mxc_nand_data_entry_single(MX31, SZ_4K);
+#endif
+
+#ifdef CONFIG_ARCH_MX35
+const struct imx_mxc_nand_data imx35_mxc_nand_data __initconst =
+ imx_mxc_nand_data_entry_single(MX35, SZ_8K);
+#endif
+
+#ifdef CONFIG_ARCH_MX51
+const struct imx_mxc_nand_data imx51_mxc_nand_data __initconst =
+ imx_mxc_nandv3_data_entry_single(MX51, SZ_16K);
+#endif
+
+struct platform_device *__init imx_add_mxc_nand(
+ const struct imx_mxc_nand_data *data,
+ const struct mxc_nand_platform_data *pdata)
{
- static int id = 0;
-
+ /* AXI has to come first, that's how the mxc_nand driver expect it */
struct resource res[] = {
{
- .start = iobase,
- .end = iobase + iosize - 1,
+ .start = data->axibase,
+ .end = data->axibase + SZ_16K - 1,
.flags = IORESOURCE_MEM,
}, {
- .start = irq,
- .end = irq,
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
.flags = IORESOURCE_IRQ,
},
};
-
- return imx_add_platform_device("mxc_nand", id++, res, ARRAY_SIZE(res),
+ return imx_add_platform_device("mxc_nand", data->id,
+ res + !data->axibase,
+ ARRAY_SIZE(res) - !data->axibase,
pdata, sizeof(*pdata));
}
-
-struct platform_device *__init imx_add_mxc_nand_v1(resource_size_t iobase,
- int irq, const struct mxc_nand_platform_data *pdata)
-{
- return imx_add_mxc_nand(iobase, irq, pdata, SZ_4K);
-}
-
-struct platform_device *__init imx_add_mxc_nand_v21(resource_size_t iobase,
- int irq, const struct mxc_nand_platform_data *pdata)
-{
- return imx_add_mxc_nand(iobase, irq, pdata, SZ_8K);
-}
diff --git a/arch/arm/plat-mxc/devices/platform-spi_imx.c b/arch/arm/plat-mxc/devices/platform-spi_imx.c
index 2831a6d3eb4b..e48340ec331e 100644
--- a/arch/arm/plat-mxc/devices/platform-spi_imx.c
+++ b/arch/arm/plat-mxc/devices/platform-spi_imx.c
@@ -6,25 +6,96 @@
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*/
-#include <asm/sizes.h>
+#include <mach/hardware.h>
#include <mach/devices-common.h>
-struct platform_device *__init imx_add_spi_imx(int id,
- resource_size_t iobase, resource_size_t iosize, int irq,
+#define imx_spi_imx_data_entry_single(soc, type, _devid, _id, hwid, _size) \
+ { \
+ .devid = _devid, \
+ .id = _id, \
+ .iobase = soc ## _ ## type ## hwid ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_ ## type ## hwid, \
+ }
+
+#define imx_spi_imx_data_entry(soc, type, devid, id, hwid, size) \
+ [id] = imx_spi_imx_data_entry_single(soc, type, devid, id, hwid, size)
+
+#ifdef CONFIG_SOC_IMX21
+const struct imx_spi_imx_data imx21_cspi_data[] __initconst = {
+#define imx21_cspi_data_entry(_id, _hwid) \
+ imx_spi_imx_data_entry(MX21, CSPI, "imx21-cspi", _id, _hwid, SZ_4K)
+ imx21_cspi_data_entry(0, 1),
+ imx21_cspi_data_entry(1, 2),
+#endif
+
+#ifdef CONFIG_ARCH_MX25
+const struct imx_spi_imx_data imx25_cspi_data[] __initconst = {
+#define imx25_cspi_data_entry(_id, _hwid) \
+ imx_spi_imx_data_entry(MX25, CSPI, "imx25-cspi", _id, _hwid, SZ_16K)
+ imx25_cspi_data_entry(0, 1),
+ imx25_cspi_data_entry(1, 2),
+ imx25_cspi_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_ARCH_MX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_spi_imx_data imx27_cspi_data[] __initconst = {
+#define imx27_cspi_data_entry(_id, _hwid) \
+ imx_spi_imx_data_entry(MX27, CSPI, "imx27-cspi", _id, _hwid, SZ_4K)
+ imx27_cspi_data_entry(0, 1),
+ imx27_cspi_data_entry(1, 2),
+ imx27_cspi_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_ARCH_MX31
+const struct imx_spi_imx_data imx31_cspi_data[] __initconst = {
+#define imx31_cspi_data_entry(_id, _hwid) \
+ imx_spi_imx_data_entry(MX31, CSPI, "imx31-cspi", _id, _hwid, SZ_4K)
+ imx31_cspi_data_entry(0, 1),
+ imx31_cspi_data_entry(1, 2),
+ imx31_cspi_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_ARCH_MX31 */
+
+#ifdef CONFIG_ARCH_MX35
+const struct imx_spi_imx_data imx35_cspi_data[] __initconst = {
+#define imx35_cspi_data_entry(_id, _hwid) \
+ imx_spi_imx_data_entry(MX35, CSPI, "imx35-cspi", _id, _hwid, SZ_4K)
+ imx35_cspi_data_entry(0, 1),
+ imx35_cspi_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_ARCH_MX35 */
+
+#ifdef CONFIG_ARCH_MX51
+const struct imx_spi_imx_data imx51_cspi_data __initconst =
+ imx_spi_imx_data_entry_single(MX51, CSPI, "imx51-cspi", 0, , SZ_4K);
+
+const struct imx_spi_imx_data imx51_ecspi_data[] __initconst = {
+#define imx51_ecspi_data_entry(_id, _hwid) \
+ imx_spi_imx_data_entry(MX51, ECSPI, "imx51-ecspi", _id, _hwid, SZ_4K)
+ imx51_ecspi_data_entry(0, 1),
+ imx51_ecspi_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_ARCH_MX51 */
+
+struct platform_device *__init imx_add_spi_imx(
+ const struct imx_spi_imx_data *data,
const struct spi_imx_master *pdata)
{
struct resource res[] = {
{
- .start = iobase,
- .end = iobase + iosize - 1,
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
.flags = IORESOURCE_MEM,
}, {
- .start = irq,
- .end = irq,
+ .start = data->irq,
+ .end = data->irq,
.flags = IORESOURCE_IRQ,
},
};
- return imx_add_platform_device("spi_imx", id, res, ARRAY_SIZE(res),
- pdata, sizeof(*pdata));
+ return imx_add_platform_device(data->devid, data->id,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
}
diff --git a/arch/arm/plat-mxc/ehci.c b/arch/arm/plat-mxc/ehci.c
index 35a064ff02ba..9915607683de 100644
--- a/arch/arm/plat-mxc/ehci.c
+++ b/arch/arm/plat-mxc/ehci.c
@@ -249,8 +249,8 @@ int mxc_initialize_usb_hw(int port, unsigned int flags)
#ifdef CONFIG_ARCH_MX51
if (cpu_is_mx51()) {
void __iomem *usb_base;
- u32 usbotg_base;
- u32 usbother_base;
+ void __iomem *usbotg_base;
+ void __iomem *usbother_base;
int ret = 0;
usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
diff --git a/arch/arm/plat-mxc/epit.c b/arch/arm/plat-mxc/epit.c
new file mode 100644
index 000000000000..ee9582f4972e
--- /dev/null
+++ b/arch/arm/plat-mxc/epit.c
@@ -0,0 +1,242 @@
+/*
+ * linux/arch/arm/plat-mxc/epit.c
+ *
+ * Copyright (C) 2010 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#define EPITCR 0x00
+#define EPITSR 0x04
+#define EPITLR 0x08
+#define EPITCMPR 0x0c
+#define EPITCNR 0x10
+
+#define EPITCR_EN (1 << 0)
+#define EPITCR_ENMOD (1 << 1)
+#define EPITCR_OCIEN (1 << 2)
+#define EPITCR_RLD (1 << 3)
+#define EPITCR_PRESC(x) (((x) & 0xfff) << 4)
+#define EPITCR_SWR (1 << 16)
+#define EPITCR_IOVW (1 << 17)
+#define EPITCR_DBGEN (1 << 18)
+#define EPITCR_WAITEN (1 << 19)
+#define EPITCR_RES (1 << 20)
+#define EPITCR_STOPEN (1 << 21)
+#define EPITCR_OM_DISCON (0 << 22)
+#define EPITCR_OM_TOGGLE (1 << 22)
+#define EPITCR_OM_CLEAR (2 << 22)
+#define EPITCR_OM_SET (3 << 22)
+#define EPITCR_CLKSRC_OFF (0 << 24)
+#define EPITCR_CLKSRC_PERIPHERAL (1 << 24)
+#define EPITCR_CLKSRC_REF_HIGH (1 << 24)
+#define EPITCR_CLKSRC_REF_LOW (3 << 24)
+
+#define EPITSR_OCIF (1 << 0)
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+
+#include <mach/hardware.h>
+#include <asm/mach/time.h>
+#include <mach/common.h>
+
+static struct clock_event_device clockevent_epit;
+static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
+
+static void __iomem *timer_base;
+
+static inline void epit_irq_disable(void)
+{
+ u32 val;
+
+ val = __raw_readl(timer_base + EPITCR);
+ val &= ~EPITCR_OCIEN;
+ __raw_writel(val, timer_base + EPITCR);
+}
+
+static inline void epit_irq_enable(void)
+{
+ u32 val;
+
+ val = __raw_readl(timer_base + EPITCR);
+ val |= EPITCR_OCIEN;
+ __raw_writel(val, timer_base + EPITCR);
+}
+
+static void epit_irq_acknowledge(void)
+{
+ __raw_writel(EPITSR_OCIF, timer_base + EPITSR);
+}
+
+static cycle_t epit_read(struct clocksource *cs)
+{
+ return 0 - __raw_readl(timer_base + EPITCNR);
+}
+
+static struct clocksource clocksource_epit = {
+ .name = "epit",
+ .rating = 200,
+ .read = epit_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .shift = 20,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int __init epit_clocksource_init(struct clk *timer_clk)
+{
+ unsigned int c = clk_get_rate(timer_clk);
+
+ clocksource_epit.mult = clocksource_hz2mult(c,
+ clocksource_epit.shift);
+ clocksource_register(&clocksource_epit);
+
+ return 0;
+}
+
+/* clock event */
+
+static int epit_set_next_event(unsigned long evt,
+ struct clock_event_device *unused)
+{
+ unsigned long tcmp;
+
+ tcmp = __raw_readl(timer_base + EPITCNR);
+
+ __raw_writel(tcmp - evt, timer_base + EPITCMPR);
+
+ return 0;
+}
+
+static void epit_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ unsigned long flags;
+
+ /*
+ * The timer interrupt generation is disabled at least
+ * for enough time to call epit_set_next_event()
+ */
+ local_irq_save(flags);
+
+ /* Disable interrupt in GPT module */
+ epit_irq_disable();
+
+ if (mode != clockevent_mode) {
+ /* Set event time into far-far future */
+
+ /* Clear pending interrupt */
+ epit_irq_acknowledge();
+ }
+
+ /* Remember timer mode */
+ clockevent_mode = mode;
+ local_irq_restore(flags);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ printk(KERN_ERR "epit_set_mode: Periodic mode is not "
+ "supported for i.MX EPIT\n");
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ /*
+ * Do not put overhead of interrupt enable/disable into
+ * epit_set_next_event(), the core has about 4 minutes
+ * to call epit_set_next_event() or shutdown clock after
+ * mode switching
+ */
+ local_irq_save(flags);
+ epit_irq_enable();
+ local_irq_restore(flags);
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_RESUME:
+ /* Left event sources disabled, no more interrupts appear */
+ break;
+ }
+}
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t epit_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = &clockevent_epit;
+
+ epit_irq_acknowledge();
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction epit_timer_irq = {
+ .name = "i.MX EPIT Timer Tick",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = epit_timer_interrupt,
+};
+
+static struct clock_event_device clockevent_epit = {
+ .name = "epit",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .set_mode = epit_set_mode,
+ .set_next_event = epit_set_next_event,
+ .rating = 200,
+};
+
+static int __init epit_clockevent_init(struct clk *timer_clk)
+{
+ unsigned int c = clk_get_rate(timer_clk);
+
+ clockevent_epit.mult = div_sc(c, NSEC_PER_SEC,
+ clockevent_epit.shift);
+ clockevent_epit.max_delta_ns =
+ clockevent_delta2ns(0xfffffffe, &clockevent_epit);
+ clockevent_epit.min_delta_ns =
+ clockevent_delta2ns(0x800, &clockevent_epit);
+
+ clockevent_epit.cpumask = cpumask_of(0);
+
+ clockevents_register_device(&clockevent_epit);
+
+ return 0;
+}
+
+void __init epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq)
+{
+ clk_enable(timer_clk);
+
+ timer_base = base;
+
+ /*
+ * Initialise to a known state (all timers off, and timing reset)
+ */
+ __raw_writel(0x0, timer_base + EPITCR);
+
+ __raw_writel(0xffffffff, timer_base + EPITLR);
+ __raw_writel(EPITCR_EN | EPITCR_CLKSRC_REF_HIGH | EPITCR_WAITEN,
+ timer_base + EPITCR);
+
+ /* init and register the timer to the framework */
+ epit_clocksource_init(timer_clk);
+ epit_clockevent_init(timer_clk);
+
+ /* Make irqs happen */
+ setup_irq(irq, &epit_timer_irq);
+}
diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c
index 57ec4a896a5d..9d38da077edb 100644
--- a/arch/arm/plat-mxc/gpio.c
+++ b/arch/arm/plat-mxc/gpio.c
@@ -235,7 +235,7 @@ static void mxc_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
unsigned long flags;
spin_lock_irqsave(&port->lock, flags);
- l = (__raw_readl(reg) & (~(1 << offset))) | (value << offset);
+ l = (__raw_readl(reg) & (~(1 << offset))) | (!!value << offset);
__raw_writel(l, reg);
spin_unlock_irqrestore(&port->lock, flags);
}
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31ads.h b/arch/arm/plat-mxc/include/mach/board-mx31ads.h
new file mode 100644
index 000000000000..94b60dd47137
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/board-mx31ads.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_MXC_BOARD_MX31ADS_H__
+#define __ASM_ARCH_MXC_BOARD_MX31ADS_H__
+
+#include <mach/hardware.h>
+
+/*
+ * These symbols are used by drivers/net/cs89x0.c.
+ * This is ugly as hell, but we have to provide them until
+ * someone fixed the driver.
+ */
+
+/* Base address of PBC controller */
+#define PBC_BASE_ADDRESS MX31_CS4_BASE_ADDR_VIRT
+/* Offsets for the PBC Controller register */
+
+/* Ethernet Controller IO base address */
+#define PBC_CS8900A_IOBASE 0x020000
+
+#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START)
+
+#define EXPIO_INT_ENET_INT (MXC_EXP_IO_BASE + 8)
+
+#endif /* __ASM_ARCH_MXC_BOARD_MX31ADS_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index 2941472582d2..7a1e1f89ff09 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -32,6 +32,7 @@ extern void mx31_init_irq(void);
extern void mx35_init_irq(void);
extern void mx51_init_irq(void);
extern void mxc91231_init_irq(void);
+extern void epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq);
extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int);
extern int mx1_clocks_init(unsigned long fref);
extern int mx21_clocks_init(unsigned long lref, unsigned long fref);
diff --git a/arch/arm/plat-mxc/include/mach/debug-macro.S b/arch/arm/plat-mxc/include/mach/debug-macro.S
index 25606409aabc..d56213fb901b 100644
--- a/arch/arm/plat-mxc/include/mach/debug-macro.S
+++ b/arch/arm/plat-mxc/include/mach/debug-macro.S
@@ -62,11 +62,9 @@
#define UART_PADDR MXC91231_UART2_BASE_ADDR
#define UART_VADDR MXC91231_IO_ADDRESS(MXC91231_UART2_BASE_ADDR)
#endif
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- ldreq \rx, =UART_PADDR @ physical
- ldrne \rx, =UART_VADDR @ virtual
+ .macro addruart, rp, rv
+ ldr \rp, =UART_PADDR @ physical
+ ldr \rv, =UART_VADDR @ virtual
.endm
.macro senduart,rd,rx
diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h
index c5f68c587309..86d7575a564d 100644
--- a/arch/arm/plat-mxc/include/mach/devices-common.h
+++ b/arch/arm/plat-mxc/include/mach/devices-common.h
@@ -14,47 +14,105 @@ struct platform_device *imx_add_platform_device(const char *name, int id,
const struct resource *res, unsigned int num_resources,
const void *data, size_t size_data);
-#if defined (CONFIG_CAN_FLEXCAN) || defined (CONFIG_CAN_FLEXCAN_MODULE)
+#include <linux/fec.h>
+struct imx_fec_data {
+ resource_size_t iobase;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_fec(
+ const struct imx_fec_data *data,
+ const struct fec_platform_data *pdata);
+
#include <linux/can/platform/flexcan.h>
struct platform_device *__init imx_add_flexcan(int id,
resource_size_t iobase, resource_size_t iosize,
resource_size_t irq,
const struct flexcan_platform_data *pdata);
-#else
-/* the ifdef can be removed once the flexcan driver has been merged */
-struct flexcan_platform_data;
-static inline struct platform_device *__init imx_add_flexcan(int id,
- resource_size_t iobase, resource_size_t iosize,
- resource_size_t irq,
- const struct flexcan_platform_data *pdata)
-{
- return NULL;
-}
-#endif
#include <mach/i2c.h>
-struct platform_device *__init imx_add_imx_i2c(int id,
- resource_size_t iobase, resource_size_t iosize, int irq,
+struct imx_imx_i2c_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_imx_i2c(
+ const struct imx_imx_i2c_data *data,
const struct imxi2c_platform_data *pdata);
+#include <mach/ssi.h>
+struct imx_imx_ssi_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+ resource_size_t dmatx0;
+ resource_size_t dmarx0;
+ resource_size_t dmatx1;
+ resource_size_t dmarx1;
+};
+struct platform_device *__init imx_add_imx_ssi(
+ const struct imx_imx_ssi_data *data,
+ const struct imx_ssi_platform_data *pdata);
+
#include <mach/imx-uart.h>
-struct platform_device *__init imx_add_imx_uart_3irq(int id,
- resource_size_t iobase, resource_size_t iosize,
- resource_size_t irqrx, resource_size_t irqtx,
- resource_size_t irqrts,
+struct imx_imx_uart_3irq_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irqrx;
+ resource_size_t irqtx;
+ resource_size_t irqrts;
+};
+struct platform_device *__init imx_add_imx_uart_3irq(
+ const struct imx_imx_uart_3irq_data *data,
const struct imxuart_platform_data *pdata);
-struct platform_device *__init imx_add_imx_uart_1irq(int id,
- resource_size_t iobase, resource_size_t iosize,
- resource_size_t irq,
+
+struct imx_imx_uart_1irq_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_imx_uart_1irq(
+ const struct imx_imx_uart_1irq_data *data,
const struct imxuart_platform_data *pdata);
#include <mach/mxc_nand.h>
-struct platform_device *__init imx_add_mxc_nand_v1(resource_size_t iobase,
- int irq, const struct mxc_nand_platform_data *pdata);
-struct platform_device *__init imx_add_mxc_nand_v21(resource_size_t iobase,
- int irq, const struct mxc_nand_platform_data *pdata);
+struct imx_mxc_nand_data {
+ /*
+ * id is traditionally 0, but -1 is more appropriate. We use -1 for new
+ * machines but don't change existing devices as the nand device usually
+ * appears in the kernel command line to pass its partitioning.
+ */
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t axibase;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_mxc_nand(
+ const struct imx_mxc_nand_data *data,
+ const struct mxc_nand_platform_data *pdata);
#include <mach/spi.h>
-struct platform_device *__init imx_add_spi_imx(int id,
- resource_size_t iobase, resource_size_t iosize, int irq,
+struct imx_spi_imx_data {
+ const char *devid;
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ int irq;
+};
+struct platform_device *__init imx_add_spi_imx(
+ const struct imx_spi_imx_data *data,
const struct spi_imx_master *pdata);
+
+#include <mach/esdhc.h>
+struct imx_esdhc_imx_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_esdhc(
+ const struct imx_esdhc_imx_data *data,
+ const struct esdhc_platform_data *pdata);
diff --git a/arch/arm/plat-mxc/include/mach/esdhc.h b/arch/arm/plat-mxc/include/mach/esdhc.h
new file mode 100644
index 000000000000..a48a9aaa56b1
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/esdhc.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2010 Wolfram Sang <w.sang@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+
+#ifndef __ASM_ARCH_IMX_ESDHC_H
+#define __ASM_ARCH_IMX_ESDHC_H
+
+struct esdhc_platform_data {
+ unsigned int wp_gpio; /* write protect pin */
+};
+#endif /* __ASM_ARCH_IMX_ESDHC_H */
diff --git a/arch/arm/plat-mxc/include/mach/eukrea-baseboards.h b/arch/arm/plat-mxc/include/mach/eukrea-baseboards.h
index 656acb45d434..a21d3313f994 100644
--- a/arch/arm/plat-mxc/include/mach/eukrea-baseboards.h
+++ b/arch/arm/plat-mxc/include/mach/eukrea-baseboards.h
@@ -28,19 +28,22 @@
* its own devices, it calls baseboard's init function.
* TODO: Add your own baseboard init function and call it from
* inside eukrea_cpuimx25_init() eukrea_cpuimx27_init()
- * eukrea_cpuimx35_init() or eukrea_cpuimx51_init().
+ * eukrea_cpuimx35_init() eukrea_cpuimx51_init()
+ * or eukrea_cpuimx51sd_init().
*
* This example here is for the development board. Refer
* mach-mx25/eukrea_mbimxsd-baseboard.c for cpuimx25
* mach-imx/eukrea_mbimx27-baseboard.c for cpuimx27
* mach-mx3/eukrea_mbimxsd-baseboard.c for cpuimx35
* mach-mx5/eukrea_mbimx51-baseboard.c for cpuimx51
+ * mach-mx5/eukrea_mbimxsd-baseboard.c for cpuimx51sd
*/
extern void eukrea_mbimxsd25_baseboard_init(void);
extern void eukrea_mbimx27_baseboard_init(void);
extern void eukrea_mbimxsd35_baseboard_init(void);
extern void eukrea_mbimx51_baseboard_init(void);
+extern void eukrea_mbimxsd51_baseboard_init(void);
#endif
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx51.h b/arch/arm/plat-mxc/include/mach/iomux-mx51.h
index 21bfa46785bb..e46b1c2836d4 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx51.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx51.h
@@ -45,6 +45,18 @@ typedef enum iomux_config {
PAD_CTL_PKE | PAD_CTL_HYS)
#define MX51_GPIO_PAD_CTRL (PAD_CTL_DSE_HIGH | PAD_CTL_PKE | \
PAD_CTL_SRE_FAST)
+#define MX51_ECSPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_DSE_HIGH | \
+ PAD_CTL_SRE_FAST)
+#define MX51_SDHCI_PAD_CTRL (PAD_CTL_DSE_HIGH | PAD_CTL_PUS_47K_UP | \
+ PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_SRE_FAST | \
+ PAD_CTL_DVS)
+
+#define MX51_PAD_CTRL_1 (PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | \
+ PAD_CTL_PUE | PAD_CTL_PKE | PAD_CTL_HYS)
+#define MX51_PAD_CTRL_2 (PAD_CTL_HYS | PAD_CTL_PKE)
+#define MX51_PAD_CTRL_3 (PAD_CTL_PKE | PAD_CTL_PUS_100K_UP)
+#define MX51_PAD_CTRL_4 (PAD_CTL_DVS | PAD_CTL_HYS | PAD_CTL_PKE)
+#define MX51_PAD_CTRL_5 (PAD_CTL_DVS | PAD_CTL_DSE_HIGH)
/*
* The naming convention for the pad modes is MX51_PAD_<padname>__<padmode>
@@ -106,14 +118,20 @@ typedef enum iomux_config {
#define MX51_PAD_EIM_EB0__EIM_EB0 IOMUX_PAD(0x460, 0x0cc, 0, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_EIM_EB1__EIM_EB1 IOMUX_PAD(0x464, 0x0d0, 0, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_EIM_EB2__GPIO_2_22 IOMUX_PAD(0x468, 0x0d4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_EB2__FEC_MDIO IOMUX_PAD(0x468, 0x0d4, 3, 0x0, 0, MX51_PAD_CTRL_1 | PAD_CTL_PUS_22K_UP)
#define MX51_PAD_EIM_EB3__GPIO_2_23 IOMUX_PAD(0x46c, 0x0d8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_EB3__FEC_RDAT1 IOMUX_PAD(0x46c, 0x0d8, 3, 0x0, 0, MX51_PAD_CTRL_2)
#define MX51_PAD_EIM_OE__GPIO_2_24 IOMUX_PAD(0x470, 0x0dc, 1, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_EIM_CS0__GPIO_2_25 IOMUX_PAD(0x474, 0x0e0, 1, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_EIM_CS1__GPIO_2_26 IOMUX_PAD(0x478, 0x0e4, 1, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_EIM_CS2__GPIO_2_27 IOMUX_PAD(0x47c, 0x0e8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_CS2__FEC_RDAT2 IOMUX_PAD(0x47c, 0x0e8, 3, 0x0, 0, MX51_PAD_CTRL_2)
#define MX51_PAD_EIM_CS3__GPIO_2_28 IOMUX_PAD(0x480, 0x0ec, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_CS3__FEC_RDAT3 IOMUX_PAD(0x480, 0x0ec, 3, 0x0, 0, MX51_PAD_CTRL_2)
#define MX51_PAD_EIM_CS4__GPIO_2_29 IOMUX_PAD(0x484, 0x0f0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_CS4__FEC_RX_ER IOMUX_PAD(0x484, 0x0f0, 3, 0x0, 0, MX51_PAD_CTRL_2)
#define MX51_PAD_EIM_CS5__GPIO_2_30 IOMUX_PAD(0x488, 0x0f4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_CS5__FEC_CRS IOMUX_PAD(0x488, 0x0f4, 3, 0x0, 0, MX51_PAD_CTRL_2)
#define MX51_PAD_EIM_DTACK__GPIO_2_31 IOMUX_PAD(0x48c, 0x0f8, 1, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_EIM_LBA__GPIO_3_1 IOMUX_PAD(0x494, 0x0FC, 1, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_EIM_CRE__GPIO_3_2 IOMUX_PAD(0x4A0, 0x100, 1, 0x0, 0, NO_PAD_CTRL)
@@ -126,18 +144,32 @@ typedef enum iomux_config {
#define MX51_PAD_NANDF_RB0__GPIO_3_8 IOMUX_PAD(0x4F8, 0x11C, 3, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_NANDF_RB1__GPIO_3_9 IOMUX_PAD(0x4FC, 0x120, 3, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_NANDF_RB2__GPIO_3_10 IOMUX_PAD(0x500, 0x124, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_RB2__ECSPI2_SCLK IOMUX_PAD(0x500, 0x124, 2, 0x0, 0, MX51_ECSPI_PAD_CTRL)
+#define MX51_PAD_NANDF_RB2__FEC_COL IOMUX_PAD(0x500, 0x124, 1, 0x0, 0, MX51_PAD_CTRL_2)
#define MX51_PAD_NANDF_RB3__GPIO_3_11 IOMUX_PAD(0x504, 0x128, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_RB3__ECSPI2_MISO IOMUX_PAD(0x504, 0x128, 2, 0x0, 0, MX51_ECSPI_PAD_CTRL)
+#define MX51_PAD_NANDF_RB3__FEC_RXCLK IOMUX_PAD(0x504, 0x128, 1, 0x0, 0, MX51_PAD_CTRL_2)
+#define MX51_PAD_NANDF_RB6__FEC_RDAT0 IOMUX_PAD(0x5DC, 0x134, 1, 0x0, 0, MX51_PAD_CTRL_4)
+#define MX51_PAD_NANDF_RB7__FEC_TDAT0 IOMUX_PAD(0x5E0, 0x138, 1, 0x0, 0, MX51_PAD_CTRL_5)
#define MX51_PAD_GPIO_NAND__GPIO_3_12 IOMUX_PAD(0x514, 0x12C, 3, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_NANDF_CS0__GPIO_3_16 IOMUX_PAD(0x518, 0x130, 3, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_NANDF_CS1__GPIO_3_17 IOMUX_PAD(0x51C, 0x134, 3, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_NANDF_CS2__GPIO_3_18 IOMUX_PAD(0x520, 0x138, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_CS2__FEC_TX_ER IOMUX_PAD(0x520, 0x138, 2, 0x0, 0, MX51_PAD_CTRL_5)
#define MX51_PAD_NANDF_CS3__GPIO_3_19 IOMUX_PAD(0x524, 0x13C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_CS3__FEC_MDC IOMUX_PAD(0x524, 0x13C, 2, 0x0, 0, MX51_PAD_CTRL_5)
#define MX51_PAD_NANDF_CS4__GPIO_3_20 IOMUX_PAD(0x528, 0x140, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_CS4__FEC_TDAT1 IOMUX_PAD(0x528, 0x140, 2, 0x0, 0, MX51_PAD_CTRL_5)
#define MX51_PAD_NANDF_CS5__GPIO_3_21 IOMUX_PAD(0x52C, 0x144, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_CS5__FEC_TDAT2 IOMUX_PAD(0x52C, 0x144, 2, 0x0, 0, MX51_PAD_CTRL_5)
#define MX51_PAD_NANDF_CS6__GPIO_3_22 IOMUX_PAD(0x530, 0x148, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_CS6__FEC_TDAT3 IOMUX_PAD(0x530, 0x148, 2, 0x0, 0, MX51_PAD_CTRL_5)
#define MX51_PAD_NANDF_CS7__GPIO_3_23 IOMUX_PAD(0x534, 0x14C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_CS7__FEC_TX_EN IOMUX_PAD(0x534, 0x14C, 1, 0x0, 0, MX51_PAD_CTRL_5)
#define MX51_PAD_NANDF_RDY_INT__GPIO_3_24 IOMUX_PAD(0x538, 0x150, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK IOMUX_PAD(0x538, 0x150, 1, 0x0, 0, MX51_PAD_CTRL_4)
#define MX51_PAD_NANDF_D15__GPIO_3_25 IOMUX_PAD(0x53C, 0x154, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D15__ECSPI2_MOSI IOMUX_PAD(0x53C, 0x154, 2, 0x0, 0, MX51_ECSPI_PAD_CTRL)
#define MX51_PAD_NANDF_D14__GPIO_3_26 IOMUX_PAD(0x540, 0x158, 3, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_NANDF_D13__GPIO_3_27 IOMUX_PAD(0x544, 0x15C, 3, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_NANDF_D12__GPIO_3_28 IOMUX_PAD(0x548, 0x160, 3, 0x0, 0, NO_PAD_CTRL)
@@ -185,15 +217,25 @@ typedef enum iomux_config {
#define MX51_PAD_I2C1_CLK__HSI2C_CLK IOMUX_PAD(0x5E8, 0x1F8, 0, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_I2C1_DAT__GPIO_4_17 IOMUX_PAD(0x5EC, 0x1FC, 3, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_I2C1_DAT__HSI2C_DAT IOMUX_PAD(0x5EC, 0x1FC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_AUD3_BB_TXD__AUD3_BB_TXD IOMUX_PAD(0x5F0, 0x200, IOMUX_CONFIG_SION, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_AUD3_BB_TXD__GPIO_4_18 IOMUX_PAD(0x5F0, 0x200, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_AUD3_BB_RXD__AUD3_BB_RXD IOMUX_PAD(0x5F4, 0x204, IOMUX_CONFIG_SION, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_AUD3_BB_RXD__GPIO_4_19 IOMUX_PAD(0x5F4, 0x204, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_AUD3_BB_CK__AUD3_BB_CK IOMUX_PAD(0x5F8, 0x208, IOMUX_CONFIG_SION, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_AUD3_BB_CK__GPIO_4_20 IOMUX_PAD(0x5F8, 0x208, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_AUD3_BB_FS__AUD3_BB_FS IOMUX_PAD(0x5FC, 0x20C, IOMUX_CONFIG_SION, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_AUD3_BB_FS__GPIO_4_21 IOMUX_PAD(0x5FC, 0x20C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI IOMUX_PAD(0x600, 0x210, 0, 0x0, 0, MX51_ECSPI_PAD_CTRL)
#define MX51_PAD_CSPI1_MOSI__GPIO_4_22 IOMUX_PAD(0x600, 0x210, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSPI1_MISO__ECSPI1_MISO IOMUX_PAD(0x604, 0x214, 0, 0x0, 0, MX51_ECSPI_PAD_CTRL)
#define MX51_PAD_CSPI1_MISO__GPIO_4_23 IOMUX_PAD(0x604, 0x214, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSPI1_SS0__ECSPI1_SS0 IOMUX_PAD(0x608, 0x218, 0, 0x0, 0, MX51_ECSPI_PAD_CTRL)
#define MX51_PAD_CSPI1_SS0__GPIO_4_24 IOMUX_PAD(0x608, 0x218, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSPI1_SS1__ECSPI1_SS1 IOMUX_PAD(0x60C, 0x21C, 0, 0x0, 0, MX51_ECSPI_PAD_CTRL)
#define MX51_PAD_CSPI1_SS1__GPIO_4_25 IOMUX_PAD(0x60C, 0x21C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSPI1_RDY__ECSPI1_RDY IOMUX_PAD(0x610, 0x220, 0, 0x0, 0, MX51_ECSPI_PAD_CTRL)
#define MX51_PAD_CSPI1_RDY__GPIO_4_26 IOMUX_PAD(0x610, 0x220, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK IOMUX_PAD(0x614, 0x224, 0, 0x0, 0, MX51_ECSPI_PAD_CTRL)
#define MX51_PAD_CSPI1_SCLK__GPIO_4_27 IOMUX_PAD(0x614, 0x224, 3, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_UART1_RXD__UART1_RXD IOMUX_PAD(0x618, 0x228, 0, 0x9e4, 0, MX51_UART1_PAD_CTRL | PAD_CTL_SRE_FAST)
#define MX51_PAD_UART1_TXD__UART1_TXD IOMUX_PAD(0x61C, 0x22C, 0, 0x0, 0, MX51_UART1_PAD_CTRL | PAD_CTL_SRE_FAST)
@@ -236,14 +278,14 @@ typedef enum iomux_config {
#define MX51_PAD_USBH1_DATA6__USBH1_DATA6 IOMUX_PAD(0x6A0, 0x2A0, 0, 0x0, 0, MX51_USBH1_PAD_CTRL)
#define MX51_PAD_USBH1_DATA7__USBH1_DATA7 IOMUX_PAD(0x6A4, 0x2A4, 0, 0x0, 0, MX51_USBH1_PAD_CTRL)
#define MX51_PAD_DI1_PIN11__GPIO_3_0 IOMUX_PAD(0x6A8, 0x2A8, 4, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI1_PIN12__GPIO_3_1 IOMUX_PAD(0x6AC, 0x2AC, 4, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI1_PIN13__GPIO_3_2 IOMUX_PAD(0x6B0, 0x2B0, 4, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI1_D0_CS__GPIO_3_3 IOMUX_PAD(0x6B4, 0x2B4, 4, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI1_D1_CS__GPIO_3_4 IOMUX_PAD(0x6B8, 0x2B8, 4, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISPB2_SER_DIN__GPIO_3_5 IOMUX_PAD(0x6BC, 0x2BC, 4, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISPB2_SER_DIO__GPIO_3_6 IOMUX_PAD(0x6C0, 0x2C0, 4, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISPB2_SER_CLK__GPIO_3_7 IOMUX_PAD(0x6C4, 0x2C4, 4, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISPB2_SER_RS__GPIO_3_8 IOMUX_PAD(0x6C8, 0x2C8, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI1_PIN12__GPIO_3_1 IOMUX_PAD(0x6AC, 0x2AC, 4, 0x978, 1, NO_PAD_CTRL)
+#define MX51_PAD_DI1_PIN13__GPIO_3_2 IOMUX_PAD(0x6B0, 0x2B0, 4, 0x97c, 1, NO_PAD_CTRL)
+#define MX51_PAD_DI1_D0_CS__GPIO_3_3 IOMUX_PAD(0x6B4, 0x2B4, 4, 0x980, 1, NO_PAD_CTRL)
+#define MX51_PAD_DI1_D1_CS__GPIO_3_4 IOMUX_PAD(0x6B8, 0x2B8, 4, 0x984, 1, NO_PAD_CTRL)
+#define MX51_PAD_DISPB2_SER_DIN__GPIO_3_5 IOMUX_PAD(0x6BC, 0x2BC, 4, 0x988, 1, NO_PAD_CTRL)
+#define MX51_PAD_DISPB2_SER_DIO__GPIO_3_6 IOMUX_PAD(0x6C0, 0x2C0, 4, 0x98c, 1, NO_PAD_CTRL)
+#define MX51_PAD_DISPB2_SER_CLK__GPIO_3_7 IOMUX_PAD(0x6C4, 0x2C4, 4, 0x990, 1, NO_PAD_CTRL)
+#define MX51_PAD_DISPB2_SER_RS__GPIO_3_8 IOMUX_PAD(0x6C8, 0x2C8, 4, 0x994, 1, NO_PAD_CTRL)
#define MX51_PAD_DISP1_DAT0__DISP1_DAT0 IOMUX_PAD(0x6CC, 0x2CC, 0, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_DISP1_DAT1__DISP1_DAT1 IOMUX_PAD(0x6D0, 0x2D0, 0, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_DISP1_DAT2__DISP1_DAT2 IOMUX_PAD(0x6D4, 0x2D4, 0, 0x0, 0, NO_PAD_CTRL)
@@ -294,32 +336,50 @@ typedef enum iomux_config {
#define MX51_PAD_DISP2_DAT13__DISP2_DAT13 IOMUX_PAD(0x790, 0x388, 0, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_DISP2_DAT14__DISP2_DAT14 IOMUX_PAD(0x794, 0x38C, 0, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_DISP2_DAT15__DISP2_DAT15 IOMUX_PAD(0x798, 0x390, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_SD1_CMD__SD1_CMD IOMUX_PAD(0x79C, 0x394, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_SD1_CLK__SD1_CLK IOMUX_PAD(0x7A0, 0x398, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_SD1_DATA0__SD1_DATA0 IOMUX_PAD(0x7A4, 0x39C, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_SD1_DATA1__SD1_DATA1 IOMUX_PAD(0x7A8, 0x3A0, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_SD1_DATA2__SD1_DATA2 IOMUX_PAD(0x7AC, 0x3A4, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_SD1_DATA3__SD1_DATA3 IOMUX_PAD(0x7B0, 0x3A8, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_0__GPIO_1_0 IOMUX_PAD(0x7B4, 0x3AC, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_1__GPIO_1_1 IOMUX_PAD(0x7B8, 0x3B0, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_SD2_CMD__SD2_CMD IOMUX_PAD(0x7BC, 0x3B4, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_SD2_CLK__SD2_CLK IOMUX_PAD(0x7C0, 0x3B8, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_SD2_DATA0__SD2_DATA0 IOMUX_PAD(0x7C4, 0x3BC, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_SD2_DATA1__SD2_DATA1 IOMUX_PAD(0x7C8, 0x3C0, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_SD2_DATA2__SD2_DATA2 IOMUX_PAD(0x7CC, 0x3C4, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_SD2_DATA3__SD2_DATA3 IOMUX_PAD(0x7D0, 0x3C8, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_2__GPIO_1_2 IOMUX_PAD(0x7D4, 0x3CC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_CMD__SD1_CMD IOMUX_PAD(0x79C, 0x394, IOMUX_CONFIG_SION, 0x0, 0, \
+ MX51_SDHCI_PAD_CTRL)
+#define MX51_PAD_SD1_CMD__AUD5_RXFS IOMUX_PAD(0x79C, 0x394, 1, 0x8e0, 1, NO_PAD_CTRL)
+#define MX51_PAD_SD1_CLK__SD1_CLK IOMUX_PAD(0x7A0, 0x398, IOMUX_CONFIG_SION, 0x0, 0, \
+ MX51_SDHCI_PAD_CTRL | PAD_CTL_HYS)
+#define MX51_PAD_SD1_CLK__AUD5_RXC IOMUX_PAD(0x7A0, 0x398, 1, 0x8dc, 1, NO_PAD_CTRL)
+#define MX51_PAD_SD1_DATA0__SD1_DATA0 IOMUX_PAD(0x7A4, 0x39C, IOMUX_CONFIG_SION, 0x0, 0, \
+ MX51_SDHCI_PAD_CTRL)
+#define MX51_PAD_SD1_DATA0__AUD5_TXD IOMUX_PAD(0x7A4, 0x39C, 1, 0x8d8, 2, NO_PAD_CTRL)
+#define MX51_PAD_SD1_DATA1__SD1_DATA1 IOMUX_PAD(0x7A8, 0x3A0, IOMUX_CONFIG_SION, 0x0, 0, \
+ MX51_SDHCI_PAD_CTRL)
+#define MX51_PAD_SD1_DATA1__AUD5_RXD IOMUX_PAD(0x7A8, 0x3A0, 1, 0x8d4, 2, NO_PAD_CTRL)
+#define MX51_PAD_SD1_DATA2__SD1_DATA2 IOMUX_PAD(0x7AC, 0x3A4, IOMUX_CONFIG_SION, 0x0, 0, \
+ MX51_SDHCI_PAD_CTRL)
+#define MX51_PAD_SD1_DATA2__AUD5_TXC IOMUX_PAD(0x7AC, 0x3A4, 1, 0x8e4, 2, NO_PAD_CTRL)
+#define MX51_PAD_SD1_DATA3__SD1_DATA3 IOMUX_PAD(0x7B0, 0x3A8, IOMUX_CONFIG_SION, 0x0, 0, \
+ MX51_SDHCI_PAD_CTRL)
+#define MX51_PAD_SD1_DATA3__AUD5_TXFS IOMUX_PAD(0x7B0, 0x3A8, 1, 0x8e8, 2, NO_PAD_CTRL)
+#define MX51_PAD_SD2_CMD__SD2_CMD IOMUX_PAD(0x7BC, 0x3B4, IOMUX_CONFIG_SION, 0x0, 1, \
+ MX51_SDHCI_PAD_CTRL)
+#define MX51_PAD_SD2_CLK__SD2_CLK IOMUX_PAD(0x7C0, 0x3B8, IOMUX_CONFIG_SION, 0x0, 0, \
+ MX51_SDHCI_PAD_CTRL | PAD_CTL_HYS)
+#define MX51_PAD_SD2_DATA0__SD2_DATA0 IOMUX_PAD(0x7C4, 0x3BC, IOMUX_CONFIG_SION, 0x0, 0, \
+ MX51_SDHCI_PAD_CTRL)
+#define MX51_PAD_SD2_DATA1__SD2_DATA1 IOMUX_PAD(0x7C8, 0x3C0, IOMUX_CONFIG_SION, 0x0, 0, \
+ MX51_SDHCI_PAD_CTRL)
+#define MX51_PAD_SD2_DATA2__SD2_DATA2 IOMUX_PAD(0x7CC, 0x3C4, IOMUX_CONFIG_SION, 0x0, 0, \
+ MX51_SDHCI_PAD_CTRL)
+#define MX51_PAD_SD2_DATA3__SD2_DATA3 IOMUX_PAD(0x7D0, 0x3C8, IOMUX_CONFIG_SION, 0x0, 0, \
+ MX51_SDHCI_PAD_CTRL)
+#define MX51_PAD_GPIO_1_0__GPIO_1_0 IOMUX_PAD(0x7B4, 0x3AC, 1, 0x0, 0, MX51_GPIO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_1__GPIO_1_1 IOMUX_PAD(0x7B8, 0x3B0, 1, 0x0, 0, MX51_GPIO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_2__GPIO_1_2 IOMUX_PAD(0x7D4, 0x3CC, 1, 0x0, 0, MX51_GPIO_PAD_CTRL)
#define MX51_PAD_GPIO_1_2__I2C2_SCL IOMUX_PAD(0x7D4, 0x3CC, (2 | IOMUX_CONFIG_SION), \
0x9b8, 3, MX51_I2C_PAD_CTRL)
-#define MX51_PAD_GPIO_1_3__GPIO_1_3 IOMUX_PAD(0x7D8, 0x3D0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_3__GPIO_1_3 IOMUX_PAD(0x7D8, 0x3D0, 1, 0x0, 0, MX51_GPIO_PAD_CTRL)
#define MX51_PAD_GPIO_1_3__I2C2_SDA IOMUX_PAD(0x7D8, 0x3D0, (2 | IOMUX_CONFIG_SION), \
0x9bc, 3, MX51_I2C_PAD_CTRL)
#define MX51_PAD_PMIC_INT_REQ__PMIC_INT_REQ IOMUX_PAD(0x7FC, 0x3D4, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_4__GPIO_1_4 IOMUX_PAD(0x804, 0x3D8, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_5__GPIO_1_5 IOMUX_PAD(0x808, 0x3DC, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_6__GPIO_1_6 IOMUX_PAD(0x80C, 0x3E0, 0, 0x0, 0, MX51_GPIO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_7__GPIO_1_7 IOMUX_PAD(0x810, 0x3E4, 0, 0x0, 0, MX51_GPIO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_8__GPIO_1_8 IOMUX_PAD(0x814, 0x3E8, 0, 0x0, 1, MX51_GPIO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_9__GPIO_1_9 IOMUX_PAD(0x818, 0x3EC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_4__GPIO_1_4 IOMUX_PAD(0x804, 0x3D8, 1, 0x0, 0, MX51_GPIO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_5__GPIO_1_5 IOMUX_PAD(0x808, 0x3DC, 1, 0x0, 0, MX51_GPIO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_6__GPIO_1_6 IOMUX_PAD(0x80C, 0x3E0, 1, 0x0, 0, MX51_GPIO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_7__GPIO_1_7 IOMUX_PAD(0x810, 0x3E4, 1, 0x0, 0, MX51_GPIO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_8__GPIO_1_8 IOMUX_PAD(0x814, 0x3E8, 1, 0x0, 0, MX51_GPIO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_9__GPIO_1_9 IOMUX_PAD(0x818, 0x3EC, 1, 0x0, 0, MX51_GPIO_PAD_CTRL)
#endif /* __MACH_IOMUX_MX51_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iram.h b/arch/arm/plat-mxc/include/mach/iram.h
new file mode 100644
index 000000000000..022690c33702
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iram.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+#include <linux/errno.h>
+
+#ifdef CONFIG_IRAM_ALLOC
+
+int __init iram_init(unsigned long base, unsigned long size);
+void __iomem *iram_alloc(unsigned int size, unsigned long *dma_addr);
+void iram_free(unsigned long dma_addr, unsigned int size);
+
+#else
+
+static inline int __init iram_init(unsigned long base, unsigned long size)
+{
+ return -ENOMEM;
+}
+
+static inline void __iomem *iram_alloc(unsigned int size, unsigned long *dma_addr)
+{
+ return NULL;
+}
+
+static inline void iram_free(unsigned long base, unsigned long size) {}
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/mx21.h b/arch/arm/plat-mxc/include/mach/mx21.h
index ed98b9c9f389..8bc59720b6e4 100644
--- a/arch/arm/plat-mxc/include/mach/mx21.h
+++ b/arch/arm/plat-mxc/include/mach/mx21.h
@@ -120,7 +120,7 @@
#define MX21_INT_GPT1 26
#define MX21_INT_WDOG 27
#define MX21_INT_PCMCIA 28
-#define MX21_INT_NANDFC 29
+#define MX21_INT_NFC 29
#define MX21_INT_BMI 30
#define MX21_INT_CSI 31
#define MX21_INT_DMACH0 32
diff --git a/arch/arm/plat-mxc/include/mach/mx25.h b/arch/arm/plat-mxc/include/mach/mx25.h
index 4a6f800990f8..cf46a45b0d4e 100644
--- a/arch/arm/plat-mxc/include/mach/mx25.h
+++ b/arch/arm/plat-mxc/include/mach/mx25.h
@@ -50,8 +50,11 @@
#define MX25_SSI1_BASE_ADDR 0x50034000
#define MX25_NFC_BASE_ADDR 0xbb000000
#define MX25_DRYICE_BASE_ADDR 0x53ffc000
+#define MX25_ESDHC1_BASE_ADDR 0x53fb4000
+#define MX25_ESDHC2_BASE_ADDR 0x53fb8000
#define MX25_LCDC_BASE_ADDR 0x53fbc000
#define MX25_KPP_BASE_ADDR 0x43fa8000
+#define MX25_SDMA_BASE_ADDR 0x53fd4000
#define MX25_OTG_BASE_ADDR 0x53ff4000
#define MX25_CSI_BASE_ADDR 0x53ff8000
@@ -59,6 +62,8 @@
#define MX25_INT_I2C1 3
#define MX25_INT_I2C2 4
#define MX25_INT_UART4 5
+#define MX25_INT_ESDHC2 8
+#define MX25_INT_ESDHC1 9
#define MX25_INT_I2C3 10
#define MX25_INT_SSI2 11
#define MX25_INT_SSI1 12
@@ -69,7 +74,8 @@
#define MX25_INT_KPP 24
#define MX25_INT_DRYICE 25
#define MX25_INT_UART2 32
-#define MX25_INT_NANDFC 33
+#define MX25_INT_NFC 33
+#define MX25_INT_SDMA 34
#define MX25_INT_LCDC 39
#define MX25_INT_UART5 40
#define MX25_INT_CAN1 43
@@ -77,4 +83,13 @@
#define MX25_INT_UART1 45
#define MX25_INT_FEC 57
+#define MX25_DMA_REQ_SSI2_RX1 22
+#define MX25_DMA_REQ_SSI2_TX1 23
+#define MX25_DMA_REQ_SSI2_RX0 24
+#define MX25_DMA_REQ_SSI2_TX0 25
+#define MX25_DMA_REQ_SSI1_RX1 26
+#define MX25_DMA_REQ_SSI1_TX1 27
+#define MX25_DMA_REQ_SSI1_RX0 28
+#define MX25_DMA_REQ_SSI1_TX0 29
+
#endif /* ifndef __MACH_MX25_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx27.h b/arch/arm/plat-mxc/include/mach/mx27.h
index a8ab2e02a8ca..2237ba2e5351 100644
--- a/arch/arm/plat-mxc/include/mach/mx27.h
+++ b/arch/arm/plat-mxc/include/mach/mx27.h
@@ -167,7 +167,7 @@ static inline void mx27_setup_weimcs(size_t cs,
#define MX27_INT_GPT1 26
#define MX27_INT_WDOG 27
#define MX27_INT_PCMCIA 28
-#define MX27_INT_NANDFC 29
+#define MX27_INT_NFC 29
#define MX27_INT_ATA 30
#define MX27_INT_CSI 31
#define MX27_INT_DMACH0 32
diff --git a/arch/arm/plat-mxc/include/mach/mx31.h b/arch/arm/plat-mxc/include/mach/mx31.h
index afee3ab9d62e..03e2afabc9fc 100644
--- a/arch/arm/plat-mxc/include/mach/mx31.h
+++ b/arch/arm/plat-mxc/include/mach/mx31.h
@@ -168,7 +168,7 @@ static inline void mx31_setup_weimcs(size_t cs,
#define MX31_INT_POWER_FAIL 30
#define MX31_INT_CCM_DVFS 31
#define MX31_INT_UART2 32
-#define MX31_INT_NANDFC 33
+#define MX31_INT_NFC 33
#define MX31_INT_SDMA 34
#define MX31_INT_USB1 35
#define MX31_INT_USB2 36
@@ -197,6 +197,15 @@ static inline void mx31_setup_weimcs(size_t cs,
#define MX31_INT_EXT_WDOG 62
#define MX31_INT_EXT_TV 63
+#define MX31_DMA_REQ_SSI2_RX1 22
+#define MX31_DMA_REQ_SSI2_TX1 23
+#define MX31_DMA_REQ_SSI2_RX0 24
+#define MX31_DMA_REQ_SSI2_TX0 25
+#define MX31_DMA_REQ_SSI1_RX1 26
+#define MX31_DMA_REQ_SSI1_TX1 27
+#define MX31_DMA_REQ_SSI1_RX0 28
+#define MX31_DMA_REQ_SSI1_TX0 29
+
#define MX31_PROD_SIGNATURE 0x1 /* For MX31 */
/* silicon revisions specific to i.MX31 */
diff --git a/arch/arm/plat-mxc/include/mach/mx35.h b/arch/arm/plat-mxc/include/mach/mx35.h
index af3038c12e39..ff905cb32458 100644
--- a/arch/arm/plat-mxc/include/mach/mx35.h
+++ b/arch/arm/plat-mxc/include/mach/mx35.h
@@ -1,5 +1,6 @@
#ifndef __MACH_MX35_H__
#define __MACH_MX35_H__
+
/*
* IRAM
*/
@@ -52,6 +53,9 @@
#define MX35_GPIO3_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xa4000)
#define MX35_SCC_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xac000)
#define MX35_RNGA_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xb0000)
+#define MX35_ESDHC1_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xb4000)
+#define MX35_ESDHC2_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xb8000)
+#define MX35_ESDHC3_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xbc000)
#define MX35_IPU_CTRL_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xc0000)
#define MX35_AUDMUX_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xc4000)
#define MX35_GPIO1_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xcc000)
@@ -63,6 +67,8 @@
#define MX35_CAN1_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xe4000)
#define MX35_CAN2_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xe8000)
#define MX35_RTIC_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xec000)
+#define MX35_IIM_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xf0000)
+
#define MX35_OTG_BASE_ADDR 0x53ff4000
#define MX35_ROMP_BASE_ADDR 0x60000000
@@ -122,9 +128,9 @@
#define MX35_INT_I2C3 3
#define MX35_INT_I2C2 4
#define MX35_INT_RTIC 6
-#define MX35_INT_MMC_SDHC1 7
-#define MX35_INT_MMC_SDHC2 8
-#define MX35_INT_MMC_SDHC3 9
+#define MX35_INT_ESDHC1 7
+#define MX35_INT_ESDHC2 8
+#define MX35_INT_ESDHC3 9
#define MX35_INT_I2C1 10
#define MX35_INT_SSI1 11
#define MX35_INT_SSI2 12
@@ -145,7 +151,7 @@
#define MX35_INT_GPT 29
#define MX35_INT_POWER_FAIL 30
#define MX35_INT_UART2 32
-#define MX35_INT_NANDFC 33
+#define MX35_INT_NFC 33
#define MX35_INT_SDMA 34
#define MX35_INT_USBHS 35
#define MX35_INT_USBOTG 37
@@ -173,22 +179,18 @@
#define MX35_INT_EXT_WDOG 62
#define MX35_INT_EXT_TV 63
+#define MX35_DMA_REQ_SSI2_RX1 22
+#define MX35_DMA_REQ_SSI2_TX1 23
+#define MX35_DMA_REQ_SSI2_RX0 24
+#define MX35_DMA_REQ_SSI2_TX0 25
+#define MX35_DMA_REQ_SSI1_RX1 26
+#define MX35_DMA_REQ_SSI1_TX1 27
+#define MX35_DMA_REQ_SSI1_RX0 28
+#define MX35_DMA_REQ_SSI1_TX0 29
+
#define MX35_PROD_SIGNATURE 0x1 /* For MX31 */
-/* silicon revisions specific to i.MX31 */
-#define MX35_CHIP_REV_1_0 0x10
-#define MX35_CHIP_REV_1_1 0x11
-#define MX35_CHIP_REV_1_2 0x12
-#define MX35_CHIP_REV_1_3 0x13
-#define MX35_CHIP_REV_2_0 0x20
-#define MX35_CHIP_REV_2_1 0x21
-#define MX35_CHIP_REV_2_2 0x22
-#define MX35_CHIP_REV_2_3 0x23
-#define MX35_CHIP_REV_3_0 0x30
-#define MX35_CHIP_REV_3_1 0x31
-#define MX35_CHIP_REV_3_2 0x32
-
-#define MX35_SYSTEM_REV_MIN MX35_CHIP_REV_1_0
+#define MX35_SYSTEM_REV_MIN MX3x_CHIP_REV_1_0
#define MX35_SYSTEM_REV_NUM 3
#ifdef IMX_NEEDS_DEPRECATED_SYMBOLS
diff --git a/arch/arm/plat-mxc/include/mach/mx3x.h b/arch/arm/plat-mxc/include/mach/mx3x.h
index 7a356de385f5..d1bd26d7b8a6 100644
--- a/arch/arm/plat-mxc/include/mach/mx3x.h
+++ b/arch/arm/plat-mxc/include/mach/mx3x.h
@@ -240,7 +240,7 @@
#define MX3x_PROD_SIGNATURE 0x1 /* For MX31 */
-/* silicon revisions specific to i.MX31 */
+/* silicon revisions specific to i.MX31 and i.MX35 */
#define MX3x_CHIP_REV_1_0 0x10
#define MX3x_CHIP_REV_1_1 0x11
#define MX3x_CHIP_REV_1_2 0x12
@@ -267,6 +267,14 @@ static inline int mx31_revision(void)
{
return mx31_cpu_rev;
}
+
+extern unsigned int mx35_cpu_rev;
+extern void mx35_read_cpu_rev(void);
+
+static inline int mx35_revision(void)
+{
+ return mx35_cpu_rev;
+}
#endif
#ifdef IMX_NEEDS_DEPRECATED_SYMBOLS
@@ -389,19 +397,6 @@ static inline int mx31_revision(void)
#define MXC_INT_EXT_WDOG MX3x_INT_EXT_WDOG
#define MXC_INT_EXT_TV MX3x_INT_EXT_TV
#define PROD_SIGNATURE MX3x_PROD_SIGNATURE
-#define CHIP_REV_1_0 MX3x_CHIP_REV_1_0
-#define CHIP_REV_1_1 MX3x_CHIP_REV_1_1
-#define CHIP_REV_1_2 MX3x_CHIP_REV_1_2
-#define CHIP_REV_1_3 MX3x_CHIP_REV_1_3
-#define CHIP_REV_2_0 MX3x_CHIP_REV_2_0
-#define CHIP_REV_2_1 MX3x_CHIP_REV_2_1
-#define CHIP_REV_2_2 MX3x_CHIP_REV_2_2
-#define CHIP_REV_2_3 MX3x_CHIP_REV_2_3
-#define CHIP_REV_3_0 MX3x_CHIP_REV_3_0
-#define CHIP_REV_3_1 MX3x_CHIP_REV_3_1
-#define CHIP_REV_3_2 MX3x_CHIP_REV_3_2
-#define SYSTEM_REV_MIN MX3x_SYSTEM_REV_MIN
-#define SYSTEM_REV_NUM MX3x_SYSTEM_REV_NUM
#endif
#endif /* ifndef __MACH_MX3x_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx51.h b/arch/arm/plat-mxc/include/mach/mx51.h
index 5aad344d5651..2af7a1056fc1 100644
--- a/arch/arm/plat-mxc/include/mach/mx51.h
+++ b/arch/arm/plat-mxc/include/mach/mx51.h
@@ -1,5 +1,5 @@
-#ifndef __ASM_ARCH_MXC_MX51_H__
-#define __ASM_ARCH_MXC_MX51_H__
+#ifndef __MACH_MX51_H__
+#define __MACH_MX51_H__
/*
* MX51 memory map:
@@ -7,24 +7,23 @@
*
* Virt Phys Size What
* ---------------------------------------------------------------------------
- * FA3E0000 1FFE0000 128K IRAM (SCCv2 RAM)
+ * fa3e0000 1ffe0000 128K IRAM (SCCv2 RAM)
* 30000000 256M GPU
* 40000000 512M IPU
- * FA200000 60000000 1M DEBUG
- * FB100000 70000000 1M SPBA 0
- * FB000000 73F00000 1M AIPS 1
- * FB200000 83F00000 1M AIPS 2
- * 8FFFC000 16K TZIC (interrupt controller)
+ * fa200000 60000000 1M DEBUG
+ * fb100000 70000000 1M SPBA 0
+ * fb000000 73f00000 1M AIPS 1
+ * fb200000 83f00000 1M AIPS 2
+ * 8fffc000 16K TZIC (interrupt controller)
* 90000000 256M CSD0 SDRAM/DDR
- * A0000000 256M CSD1 SDRAM/DDR
- * B0000000 128M CS0 Flash
- * B8000000 128M CS1 Flash
- * C0000000 128M CS2 Flash
- * C8000000 64M CS3 Flash
- * CC000000 32M CS4 SRAM
- * CE000000 32M CS5 SRAM
- * CFFF0000 64K NFC (NAND Flash AXI)
- *
+ * a0000000 256M CSD1 SDRAM/DDR
+ * b0000000 128M CS0 Flash
+ * b8000000 128M CS1 Flash
+ * c0000000 128M CS2 Flash
+ * c8000000 64M CS3 Flash
+ * cc000000 32M CS4 SRAM
+ * ce000000 32M CS5 SRAM
+ * cfff0000 64K NFC (NAND Flash AXI)
*/
/*
@@ -36,65 +35,151 @@
/*
* IRAM
*/
-#define MX51_IRAM_BASE_ADDR 0x1FFE0000 /* internal ram */
-#define MX51_IRAM_BASE_ADDR_VIRT 0xFA3E0000
+#define MX51_IRAM_BASE_ADDR 0x1ffe0000 /* internal ram */
+#define MX51_IRAM_BASE_ADDR_VIRT 0xfa3e0000
#define MX51_IRAM_PARTITIONS 16
-#define MX51_IRAM_PARTITIONS_TO1 12
#define MX51_IRAM_SIZE (MX51_IRAM_PARTITIONS * SZ_8K) /* 128KB */
+#define MX51_GPU_BASE_ADDR 0x20000000
+#define MX51_GPU_CTRL_BASE_ADDR 0x30000000
+#define MX51_IPU_CTRL_BASE_ADDR 0x40000000
+
+#define MX51_DEBUG_BASE_ADDR 0x60000000
+#define MX51_DEBUG_BASE_ADDR_VIRT 0xfa200000
+#define MX51_DEBUG_SIZE SZ_1M
+
+#define MX51_ETB_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x01000)
+#define MX51_ETM_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x02000)
+#define MX51_TPIU_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x03000)
+#define MX51_CTI0_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x04000)
+#define MX51_CTI1_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x05000)
+#define MX51_CTI2_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x06000)
+#define MX51_CTI3_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x07000)
+#define MX51_CORTEX_DBG_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x08000)
+
/*
- * NFC
+ * SPBA global module enabled #0
*/
-#define MX51_NFC_AXI_BASE_ADDR 0xCFFF0000 /* NAND flash AXI */
-#define MX51_NFC_AXI_SIZE SZ_64K
+#define MX51_SPBA0_BASE_ADDR 0x70000000
+#define MX51_SPBA0_BASE_ADDR_VIRT 0xfb100000
+#define MX51_SPBA0_SIZE SZ_1M
+
+#define MX51_ESDHC1_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x04000)
+#define MX51_ESDHC2_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x08000)
+#define MX51_UART3_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x0c000)
+#define MX51_ECSPI1_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x10000)
+#define MX51_SSI2_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x14000)
+#define MX51_ESDHC3_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x20000)
+#define MX51_ESDHC4_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x24000)
+#define MX51_SPDIF_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x28000)
+#define MX51_ATA_DMA_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x30000)
+#define MX51_SLIM_DMA_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x34000)
+#define MX51_HSI2C_DMA_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x38000)
+#define MX51_SPBA_CTRL_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x3c000)
/*
- * Graphics Memory of GPU
+ * AIPS 1
*/
-#define MX51_GPU_BASE_ADDR 0x20000000
-#define MX51_GPU2D_BASE_ADDR 0xD0000000
+#define MX51_AIPS1_BASE_ADDR 0x73f00000
+#define MX51_AIPS1_BASE_ADDR_VIRT 0xfb000000
+#define MX51_AIPS1_SIZE SZ_1M
+
+#define MX51_OTG_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x80000)
+#define MX51_GPIO1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x84000)
+#define MX51_GPIO2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x88000)
+#define MX51_GPIO3_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x8c000)
+#define MX51_GPIO4_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x90000)
+#define MX51_KPP_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x94000)
+#define MX51_WDOG_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x98000)
+#define MX51_WDOG2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x9c000)
+#define MX51_GPT1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xa0000)
+#define MX51_SRTC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xa4000)
+#define MX51_IOMUXC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xa8000)
+#define MX51_EPIT1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xac000)
+#define MX51_EPIT2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xb0000)
+#define MX51_PWM1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xb4000)
+#define MX51_PWM2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xb8000)
+#define MX51_UART1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xbc000)
+#define MX51_UART2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xc0000)
+#define MX51_SRC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xd0000)
+#define MX51_CCM_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xd4000)
+#define MX51_GPC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xd8000)
-#define MX51_TZIC_BASE_ADDR_TO1 0x8FFFC000
-#define MX51_TZIC_BASE_ADDR 0xE0000000
+/*
+ * AIPS 2
+ */
+#define MX51_AIPS2_BASE_ADDR 0x83f00000
+#define MX51_AIPS2_BASE_ADDR_VIRT 0xfb200000
+#define MX51_AIPS2_SIZE SZ_1M
-#define MX51_DEBUG_BASE_ADDR 0x60000000
-#define MX51_DEBUG_BASE_ADDR_VIRT 0xFA200000
-#define MX51_DEBUG_SIZE SZ_1M
-#define MX51_ETB_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00001000)
-#define MX51_ETM_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00002000)
-#define MX51_TPIU_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00003000)
-#define MX51_CTI0_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00004000)
-#define MX51_CTI1_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00005000)
-#define MX51_CTI2_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00006000)
-#define MX51_CTI3_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00007000)
-#define MX51_CORTEX_DBG_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00008000)
+#define MX51_PLL1_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x80000)
+#define MX51_PLL2_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x84000)
+#define MX51_PLL3_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x88000)
+#define MX51_AHBMAX_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x94000)
+#define MX51_IIM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x98000)
+#define MX51_CSU_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x9c000)
+#define MX51_ARM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xa0000)
+#define MX51_OWIRE_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xa4000)
+#define MX51_FIRI_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xa8000)
+#define MX51_ECSPI2_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xac000)
+#define MX51_SDMA_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xb0000)
+#define MX51_SCC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xb4000)
+#define MX51_ROMCP_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xb8000)
+#define MX51_RTIC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xbc000)
+#define MX51_CSPI_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xc0000)
+#define MX51_I2C2_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xc4000)
+#define MX51_I2C1_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xc8000)
+#define MX51_SSI1_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xcc000)
+#define MX51_AUDMUX_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xd0000)
+#define MX51_M4IF_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xd8000)
+#define MX51_ESDCTL_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xd9000)
+#define MX51_WEIM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xda000)
+#define MX51_NFC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xdb000)
+#define MX51_EMI_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xdbf00)
+#define MX51_MIPI_HSC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xdc000)
+#define MX51_ATA_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xe0000)
+#define MX51_SIM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xe4000)
+#define MX51_SSI3BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xe8000)
+#define MX51_FEC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xec000)
+#define MX51_TVE_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xf0000)
+#define MX51_VPU_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xf4000)
+#define MX51_SAHARA_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xf8000)
+
+#define MX51_CSD0_BASE_ADDR 0x90000000
+#define MX51_CSD1_BASE_ADDR 0xa0000000
+#define MX51_CS0_BASE_ADDR 0xb0000000
+#define MX51_CS1_BASE_ADDR 0xb8000000
+#define MX51_CS2_BASE_ADDR 0xc0000000
+#define MX51_CS3_BASE_ADDR 0xc8000000
+#define MX51_CS4_BASE_ADDR 0xcc000000
+#define MX51_CS5_BASE_ADDR 0xce000000
/*
- * SPBA global module enabled #0
+ * NFC
*/
-#define MX51_SPBA0_BASE_ADDR 0x70000000
-#define MX51_SPBA0_BASE_ADDR_VIRT 0xFB100000
-#define MX51_SPBA0_SIZE SZ_1M
+#define MX51_NFC_AXI_BASE_ADDR 0xcfff0000 /* NAND flash AXI */
+#define MX51_NFC_AXI_SIZE SZ_64K
+
+#define MX51_GPU2D_BASE_ADDR 0xd0000000
+#define MX51_TZIC_BASE_ADDR 0xe0000000
-#define MX51_MMC_SDHC1_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00004000)
-#define MX51_MMC_SDHC2_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00008000)
-#define MX51_UART3_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x0000C000)
-#define MX51_CSPI1_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00010000)
-#define MX51_SSI2_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00014000)
-#define MX51_MMC_SDHC3_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00020000)
-#define MX51_MMC_SDHC4_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00024000)
-#define MX51_SPDIF_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00028000)
-#define MX51_ATA_DMA_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00030000)
-#define MX51_SLIM_DMA_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00034000)
-#define MX51_HSI2C_DMA_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00038000)
-#define MX51_SPBA_CTRL_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x0003C000)
+#define MX51_IO_ADDRESS(x) ( \
+ IMX_IO_ADDRESS(x, MX51_IRAM) ?: \
+ IMX_IO_ADDRESS(x, MX51_DEBUG) ?: \
+ IMX_IO_ADDRESS(x, MX51_SPBA0) ?: \
+ IMX_IO_ADDRESS(x, MX51_AIPS1) ?: \
+ IMX_IO_ADDRESS(x, MX51_AIPS2))
+
+/* This is currently used in <mach/debug-macro.S>, but should go away */
+#define MX51_AIPS1_IO_ADDRESS(x) \
+ (((x) - MX51_AIPS1_BASE_ADDR) + MX51_AIPS1_BASE_ADDR_VIRT)
/*
* defines for SPBA modules
*/
#define MX51_SPBA_SDHC1 0x04
#define MX51_SPBA_SDHC2 0x08
-#define MX51_SPBA_UART3 0x0C
+#define MX51_SPBA_UART3 0x0c
#define MX51_SPBA_CSPI1 0x10
#define MX51_SPBA_SSI2 0x14
#define MX51_SPBA_SDHC3 0x20
@@ -103,35 +188,7 @@
#define MX51_SPBA_ATA 0x30
#define MX51_SPBA_SLIM 0x34
#define MX51_SPBA_HSI2C 0x38
-#define MX51_SPBA_CTRL 0x3C
-
-/*
- * AIPS 1
- */
-#define MX51_AIPS1_BASE_ADDR 0x73F00000
-#define MX51_AIPS1_BASE_ADDR_VIRT 0xFB000000
-#define MX51_AIPS1_SIZE SZ_1M
-
-#define MX51_OTG_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x00080000)
-#define MX51_GPIO1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x00084000)
-#define MX51_GPIO2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x00088000)
-#define MX51_GPIO3_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x0008C000)
-#define MX51_GPIO4_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x00090000)
-#define MX51_KPP_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x00094000)
-#define MX51_WDOG_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x00098000)
-#define MX51_WDOG2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x0009C000)
-#define MX51_GPT1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000A0000)
-#define MX51_SRTC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000A4000)
-#define MX51_IOMUXC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000A8000)
-#define MX51_EPIT1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000AC000)
-#define MX51_EPIT2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000B0000)
-#define MX51_PWM1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000B4000)
-#define MX51_PWM2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000B8000)
-#define MX51_UART1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000BC000)
-#define MX51_UART2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000C0000)
-#define MX51_SRC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000D0000)
-#define MX51_CCM_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000D4000)
-#define MX51_GPC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000D8000)
+#define MX51_SPBA_CTRL 0x3c
/*
* Defines for modules using static and dynamic DMA channels
@@ -164,282 +221,186 @@
#define MX51_MXC_DMA_CHANNEL_ATA_TX MXC_DMA_DYNAMIC_CHANNEL
#define MX51_MXC_DMA_CHANNEL_MEMORY MXC_DMA_DYNAMIC_CHANNEL
-/*
- * AIPS 2
- */
-#define MX51_AIPS2_BASE_ADDR 0x83F00000
-#define MX51_AIPS2_BASE_ADDR_VIRT 0xFB200000
-#define MX51_AIPS2_SIZE SZ_1M
-
-#define MX51_PLL1_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x00080000)
-#define MX51_PLL2_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x00084000)
-#define MX51_PLL3_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x00088000)
-#define MX51_AHBMAX_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x00094000)
-#define MX51_IIM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x00098000)
-#define MX51_CSU_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x0009C000)
-#define MX51_ARM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000A0000)
-#define MX51_OWIRE_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000A4000)
-#define MX51_FIRI_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000A8000)
-#define MX51_CSPI2_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000AC000)
-#define MX51_SDMA_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000B0000)
-#define MX51_SCC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000B4000)
-#define MX51_ROMCP_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000B8000)
-#define MX51_RTIC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000BC000)
-#define MX51_CSPI3_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000C0000)
-#define MX51_I2C2_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000C4000)
-#define MX51_I2C1_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000C8000)
-#define MX51_SSI1_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000CC000)
-#define MX51_AUDMUX_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000D0000)
-#define MX51_M4IF_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000D8000)
-#define MX51_ESDCTL_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000D9000)
-#define MX51_WEIM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000DA000)
-#define MX51_NFC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000DB000)
-#define MX51_EMI_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000DBF00)
-#define MX51_MIPI_HSC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000DC000)
-#define MX51_ATA_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000E0000)
-#define MX51_SIM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000E4000)
-#define MX51_SSI3BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000E8000)
-#define MX51_MXC_FEC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000EC000)
-#define MX51_TVE_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000F0000)
-#define MX51_VPU_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000F4000)
-#define MX51_SAHARA_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000F8000)
-
-/*
- * Memory regions and CS
- */
-#define MX51_GPU_CTRL_BASE_ADDR 0x30000000
-#define MX51_IPU_CTRL_BASE_ADDR 0x40000000
-#define MX51_CSD0_BASE_ADDR 0x90000000
-#define MX51_CSD1_BASE_ADDR 0xA0000000
-#define MX51_CS0_BASE_ADDR 0xB0000000
-#define MX51_CS1_BASE_ADDR 0xB8000000
-#define MX51_CS2_BASE_ADDR 0xC0000000
-#define MX51_CS3_BASE_ADDR 0xC8000000
-#define MX51_CS4_BASE_ADDR 0xCC000000
-#define MX51_CS5_BASE_ADDR 0xCE000000
-
-/* Does given address belongs to the specified memory region? */
-#define ADDRESS_IN_REGION(addr, start, size) \
- (((addr) >= (start)) && ((addr) < (start)+(size)))
-
-/* Does given address belongs to the specified named `module'? */
-#define MX51_IS_MODULE(addr, module) \
- ADDRESS_IN_REGION(addr, MX51_ ## module ## _BASE_ADDR, \
- MX51_ ## module ## _SIZE)
-/*
- * This macro defines the physical to virtual address mapping for all the
- * peripheral modules. It is used by passing in the physical address as x
- * and returning the virtual address. If the physical address is not mapped,
- * it returns 0xDEADBEEF
- */
-
-#define MX51_IO_ADDRESS(x) \
- (void __iomem *) \
- (MX51_IS_MODULE(x, IRAM) ? MX51_IRAM_IO_ADDRESS(x) : \
- MX51_IS_MODULE(x, DEBUG) ? MX51_DEBUG_IO_ADDRESS(x) : \
- MX51_IS_MODULE(x, SPBA0) ? MX51_SPBA0_IO_ADDRESS(x) : \
- MX51_IS_MODULE(x, AIPS1) ? MX51_AIPS1_IO_ADDRESS(x) : \
- MX51_IS_MODULE(x, AIPS2) ? MX51_AIPS2_IO_ADDRESS(x) : \
- 0xDEADBEEF)
-
-/*
- * define the address mapping macros: in physical address order
- */
-#define MX51_IRAM_IO_ADDRESS(x) \
- (((x) - MX51_IRAM_BASE_ADDR) + MX51_IRAM_BASE_ADDR_VIRT)
-
-#define MX51_DEBUG_IO_ADDRESS(x) \
- (((x) - MX51_DEBUG_BASE_ADDR) + MX51_DEBUG_BASE_ADDR_VIRT)
-
-#define MX51_SPBA0_IO_ADDRESS(x) \
- (((x) - MX51_SPBA0_BASE_ADDR) + MX51_SPBA0_BASE_ADDR_VIRT)
-
-#define MX51_AIPS1_IO_ADDRESS(x) \
- (((x) - MX51_AIPS1_BASE_ADDR) + MX51_AIPS1_BASE_ADDR_VIRT)
-
-#define MX51_AIPS2_IO_ADDRESS(x) \
- (((x) - MX51_AIPS2_BASE_ADDR) + MX51_AIPS2_BASE_ADDR_VIRT)
-
#define MX51_IS_MEM_DEVICE_NONSHARED(x) 0
/*
* DMA request assignments
*/
-#define MX51_DMA_REQ_SSI3_TX1 47
-#define MX51_DMA_REQ_SSI3_RX1 46
-#define MX51_DMA_REQ_SPDIF 45
-#define MX51_DMA_REQ_UART3_TX 44
-#define MX51_DMA_REQ_UART3_RX 43
-#define MX51_DMA_REQ_SLIM_B_TX 42
-#define MX51_DMA_REQ_SDHC4 41
-#define MX51_DMA_REQ_SDHC3 40
-#define MX51_DMA_REQ_CSPI_TX 39
-#define MX51_DMA_REQ_CSPI_RX 38
-#define MX51_DMA_REQ_SSI3_TX2 37
-#define MX51_DMA_REQ_IPU 36
-#define MX51_DMA_REQ_SSI3_RX2 35
-#define MX51_DMA_REQ_EPIT2 34
-#define MX51_DMA_REQ_CTI2_1 33
-#define MX51_DMA_REQ_EMI_WR 32
-#define MX51_DMA_REQ_CTI2_0 31
-#define MX51_DMA_REQ_EMI_RD 30
-#define MX51_DMA_REQ_SSI1_TX1 29
-#define MX51_DMA_REQ_SSI1_RX1 28
-#define MX51_DMA_REQ_SSI1_TX2 27
-#define MX51_DMA_REQ_SSI1_RX2 26
-#define MX51_DMA_REQ_SSI2_TX1 25
-#define MX51_DMA_REQ_SSI2_RX1 24
-#define MX51_DMA_REQ_SSI2_TX2 23
-#define MX51_DMA_REQ_SSI2_RX2 22
-#define MX51_DMA_REQ_SDHC2 21
-#define MX51_DMA_REQ_SDHC1 20
-#define MX51_DMA_REQ_UART1_TX 19
-#define MX51_DMA_REQ_UART1_RX 18
-#define MX51_DMA_REQ_UART2_TX 17
-#define MX51_DMA_REQ_UART2_RX 16
-#define MX51_DMA_REQ_GPU 15
-#define MX51_DMA_REQ_EXTREQ1 14
-#define MX51_DMA_REQ_FIRI_TX 13
-#define MX51_DMA_REQ_FIRI_RX 12
-#define MX51_DMA_REQ_HS_I2C_RX 11
-#define MX51_DMA_REQ_HS_I2C_TX 10
-#define MX51_DMA_REQ_CSPI2_TX 9
-#define MX51_DMA_REQ_CSPI2_RX 8
-#define MX51_DMA_REQ_CSPI1_TX 7
-#define MX51_DMA_REQ_CSPI1_RX 6
-#define MX51_DMA_REQ_SLIM_B 5
-#define MX51_DMA_REQ_ATA_TX_END 4
-#define MX51_DMA_REQ_ATA_TX 3
-#define MX51_DMA_REQ_ATA_RX 2
-#define MX51_DMA_REQ_GPC 1
-#define MX51_DMA_REQ_VPU 0
+#define MX51_DMA_REQ_VPU 0
+#define MX51_DMA_REQ_GPC 1
+#define MX51_DMA_REQ_ATA_RX 2
+#define MX51_DMA_REQ_ATA_TX 3
+#define MX51_DMA_REQ_ATA_TX_END 4
+#define MX51_DMA_REQ_SLIM_B 5
+#define MX51_DMA_REQ_CSPI1_RX 6
+#define MX51_DMA_REQ_CSPI1_TX 7
+#define MX51_DMA_REQ_CSPI2_RX 8
+#define MX51_DMA_REQ_CSPI2_TX 9
+#define MX51_DMA_REQ_HS_I2C_TX 10
+#define MX51_DMA_REQ_HS_I2C_RX 11
+#define MX51_DMA_REQ_FIRI_RX 12
+#define MX51_DMA_REQ_FIRI_TX 13
+#define MX51_DMA_REQ_EXTREQ1 14
+#define MX51_DMA_REQ_GPU 15
+#define MX51_DMA_REQ_UART2_RX 16
+#define MX51_DMA_REQ_UART2_TX 17
+#define MX51_DMA_REQ_UART1_RX 18
+#define MX51_DMA_REQ_UART1_TX 19
+#define MX51_DMA_REQ_SDHC1 20
+#define MX51_DMA_REQ_SDHC2 21
+#define MX51_DMA_REQ_SSI2_RX1 22
+#define MX51_DMA_REQ_SSI2_TX1 23
+#define MX51_DMA_REQ_SSI2_RX0 24
+#define MX51_DMA_REQ_SSI2_TX0 25
+#define MX51_DMA_REQ_SSI1_RX1 26
+#define MX51_DMA_REQ_SSI1_TX1 27
+#define MX51_DMA_REQ_SSI1_RX0 28
+#define MX51_DMA_REQ_SSI1_TX0 29
+#define MX51_DMA_REQ_EMI_RD 30
+#define MX51_DMA_REQ_CTI2_0 31
+#define MX51_DMA_REQ_EMI_WR 32
+#define MX51_DMA_REQ_CTI2_1 33
+#define MX51_DMA_REQ_EPIT2 34
+#define MX51_DMA_REQ_SSI3_RX2 35
+#define MX51_DMA_REQ_IPU 36
+#define MX51_DMA_REQ_SSI3_TX2 37
+#define MX51_DMA_REQ_CSPI_RX 38
+#define MX51_DMA_REQ_CSPI_TX 39
+#define MX51_DMA_REQ_SDHC3 40
+#define MX51_DMA_REQ_SDHC4 41
+#define MX51_DMA_REQ_SLIM_B_TX 42
+#define MX51_DMA_REQ_UART3_RX 43
+#define MX51_DMA_REQ_UART3_TX 44
+#define MX51_DMA_REQ_SPDIF 45
+#define MX51_DMA_REQ_SSI3_RX1 46
+#define MX51_DMA_REQ_SSI3_TX1 47
/*
* Interrupt numbers
*/
-#define MX51_MXC_INT_BASE 0
-#define MX51_MXC_INT_RESV0 0
-#define MX51_MXC_INT_MMC_SDHC1 1
-#define MX51_MXC_INT_MMC_SDHC2 2
-#define MX51_MXC_INT_MMC_SDHC3 3
-#define MX51_MXC_INT_MMC_SDHC4 4
-#define MX51_MXC_INT_RESV5 5
-#define MX51_MXC_INT_SDMA 6
-#define MX51_MXC_INT_IOMUX 7
-#define MX51_MXC_INT_NFC 8
-#define MX51_MXC_INT_VPU 9
-#define MX51_MXC_INT_IPU_ERR 10
-#define MX51_MXC_INT_IPU_SYN 11
-#define MX51_MXC_INT_GPU 12
-#define MX51_MXC_INT_RESV13 13
-#define MX51_MXC_INT_USB_H1 14
-#define MX51_MXC_INT_EMI 15
-#define MX51_MXC_INT_USB_H2 16
-#define MX51_MXC_INT_USB_H3 17
-#define MX51_MXC_INT_USB_OTG 18
-#define MX51_MXC_INT_SAHARA_H0 19
-#define MX51_MXC_INT_SAHARA_H1 20
-#define MX51_MXC_INT_SCC_SMN 21
-#define MX51_MXC_INT_SCC_STZ 22
-#define MX51_MXC_INT_SCC_SCM 23
-#define MX51_MXC_INT_SRTC_NTZ 24
-#define MX51_MXC_INT_SRTC_TZ 25
-#define MX51_MXC_INT_RTIC 26
-#define MX51_MXC_INT_CSU 27
-#define MX51_MXC_INT_SLIM_B 28
-#define MX51_MXC_INT_SSI1 29
-#define MX51_MXC_INT_SSI2 30
-#define MX51_MXC_INT_UART1 31
-#define MX51_MXC_INT_UART2 32
-#define MX51_MXC_INT_UART3 33
-#define MX51_MXC_INT_RESV34 34
-#define MX51_MXC_INT_RESV35 35
-#define MX51_MXC_INT_CSPI1 36
-#define MX51_MXC_INT_CSPI2 37
-#define MX51_MXC_INT_CSPI 38
-#define MX51_MXC_INT_GPT 39
-#define MX51_MXC_INT_EPIT1 40
-#define MX51_MXC_INT_EPIT2 41
-#define MX51_MXC_INT_GPIO1_INT7 42
-#define MX51_MXC_INT_GPIO1_INT6 43
-#define MX51_MXC_INT_GPIO1_INT5 44
-#define MX51_MXC_INT_GPIO1_INT4 45
-#define MX51_MXC_INT_GPIO1_INT3 46
-#define MX51_MXC_INT_GPIO1_INT2 47
-#define MX51_MXC_INT_GPIO1_INT1 48
-#define MX51_MXC_INT_GPIO1_INT0 49
-#define MX51_MXC_INT_GPIO1_LOW 50
-#define MX51_MXC_INT_GPIO1_HIGH 51
-#define MX51_MXC_INT_GPIO2_LOW 52
-#define MX51_MXC_INT_GPIO2_HIGH 53
-#define MX51_MXC_INT_GPIO3_LOW 54
-#define MX51_MXC_INT_GPIO3_HIGH 55
-#define MX51_MXC_INT_GPIO4_LOW 56
-#define MX51_MXC_INT_GPIO4_HIGH 57
-#define MX51_MXC_INT_WDOG1 58
-#define MX51_MXC_INT_WDOG2 59
-#define MX51_MXC_INT_KPP 60
-#define MX51_MXC_INT_PWM1 61
-#define MX51_MXC_INT_I2C1 62
-#define MX51_MXC_INT_I2C2 63
-#define MX51_MXC_INT_HS_I2C 64
-#define MX51_MXC_INT_RESV65 65
-#define MX51_MXC_INT_RESV66 66
-#define MX51_MXC_INT_SIM_IPB 67
-#define MX51_MXC_INT_SIM_DAT 68
-#define MX51_MXC_INT_IIM 69
-#define MX51_MXC_INT_ATA 70
-#define MX51_MXC_INT_CCM1 71
-#define MX51_MXC_INT_CCM2 72
-#define MX51_MXC_INT_GPC1 73
-#define MX51_MXC_INT_GPC2 74
-#define MX51_MXC_INT_SRC 75
-#define MX51_MXC_INT_NM 76
-#define MX51_MXC_INT_PMU 77
-#define MX51_MXC_INT_CTI_IRQ 78
-#define MX51_MXC_INT_CTI1_TG0 79
-#define MX51_MXC_INT_CTI1_TG1 80
-#define MX51_MXC_INT_MCG_ERR 81
-#define MX51_MXC_INT_MCG_TMR 82
-#define MX51_MXC_INT_MCG_FUNC 83
-#define MX51_MXC_INT_GPU2_IRQ 84
-#define MX51_MXC_INT_GPU2_BUSY 85
-#define MX51_MXC_INT_RESV86 86
-#define MX51_MXC_INT_FEC 87
-#define MX51_MXC_INT_OWIRE 88
-#define MX51_MXC_INT_CTI1_TG2 89
-#define MX51_MXC_INT_SJC 90
-#define MX51_MXC_INT_SPDIF 91
-#define MX51_MXC_INT_TVE 92
-#define MX51_MXC_INT_FIRI 93
-#define MX51_MXC_INT_PWM2 94
-#define MX51_MXC_INT_SLIM_EXP 95
-#define MX51_MXC_INT_SSI3 96
-#define MX51_MXC_INT_EMI_BOOT 97
-#define MX51_MXC_INT_CTI1_TG3 98
-#define MX51_MXC_INT_SMC_RX 99
-#define MX51_MXC_INT_VPU_IDLE 100
-#define MX51_MXC_INT_EMI_NFC 101
-#define MX51_MXC_INT_GPU_IDLE 102
+#define MX51_MXC_INT_BASE 0
+#define MX51_MXC_INT_RESV0 0
+#define MX51_INT_ESDHC1 1
+#define MX51_INT_ESDHC2 2
+#define MX51_INT_ESDHC3 3
+#define MX51_INT_ESDHC4 4
+#define MX51_MXC_INT_RESV5 5
+#define MX51_INT_SDMA 6
+#define MX51_MXC_INT_IOMUX 7
+#define MX51_INT_NFC 8
+#define MX51_MXC_INT_VPU 9
+#define MX51_MXC_INT_IPU_ERR 10
+#define MX51_MXC_INT_IPU_SYN 11
+#define MX51_MXC_INT_GPU 12
+#define MX51_MXC_INT_RESV13 13
+#define MX51_MXC_INT_USB_H1 14
+#define MX51_MXC_INT_EMI 15
+#define MX51_MXC_INT_USB_H2 16
+#define MX51_MXC_INT_USB_H3 17
+#define MX51_MXC_INT_USB_OTG 18
+#define MX51_MXC_INT_SAHARA_H0 19
+#define MX51_MXC_INT_SAHARA_H1 20
+#define MX51_MXC_INT_SCC_SMN 21
+#define MX51_MXC_INT_SCC_STZ 22
+#define MX51_MXC_INT_SCC_SCM 23
+#define MX51_MXC_INT_SRTC_NTZ 24
+#define MX51_MXC_INT_SRTC_TZ 25
+#define MX51_MXC_INT_RTIC 26
+#define MX51_MXC_INT_CSU 27
+#define MX51_MXC_INT_SLIM_B 28
+#define MX51_INT_SSI1 29
+#define MX51_INT_SSI2 30
+#define MX51_INT_UART1 31
+#define MX51_INT_UART2 32
+#define MX51_INT_UART3 33
+#define MX51_MXC_INT_RESV34 34
+#define MX51_MXC_INT_RESV35 35
+#define MX51_INT_ECSPI1 36
+#define MX51_INT_ECSPI2 37
+#define MX51_INT_CSPI 38
+#define MX51_MXC_INT_GPT 39
+#define MX51_MXC_INT_EPIT1 40
+#define MX51_MXC_INT_EPIT2 41
+#define MX51_MXC_INT_GPIO1_INT7 42
+#define MX51_MXC_INT_GPIO1_INT6 43
+#define MX51_MXC_INT_GPIO1_INT5 44
+#define MX51_MXC_INT_GPIO1_INT4 45
+#define MX51_MXC_INT_GPIO1_INT3 46
+#define MX51_MXC_INT_GPIO1_INT2 47
+#define MX51_MXC_INT_GPIO1_INT1 48
+#define MX51_MXC_INT_GPIO1_INT0 49
+#define MX51_MXC_INT_GPIO1_LOW 50
+#define MX51_MXC_INT_GPIO1_HIGH 51
+#define MX51_MXC_INT_GPIO2_LOW 52
+#define MX51_MXC_INT_GPIO2_HIGH 53
+#define MX51_MXC_INT_GPIO3_LOW 54
+#define MX51_MXC_INT_GPIO3_HIGH 55
+#define MX51_MXC_INT_GPIO4_LOW 56
+#define MX51_MXC_INT_GPIO4_HIGH 57
+#define MX51_MXC_INT_WDOG1 58
+#define MX51_MXC_INT_WDOG2 59
+#define MX51_MXC_INT_KPP 60
+#define MX51_MXC_INT_PWM1 61
+#define MX51_INT_I2C1 62
+#define MX51_INT_I2C2 63
+#define MX51_MXC_INT_HS_I2C 64
+#define MX51_MXC_INT_RESV65 65
+#define MX51_MXC_INT_RESV66 66
+#define MX51_MXC_INT_SIM_IPB 67
+#define MX51_MXC_INT_SIM_DAT 68
+#define MX51_MXC_INT_IIM 69
+#define MX51_MXC_INT_ATA 70
+#define MX51_MXC_INT_CCM1 71
+#define MX51_MXC_INT_CCM2 72
+#define MX51_MXC_INT_GPC1 73
+#define MX51_MXC_INT_GPC2 74
+#define MX51_MXC_INT_SRC 75
+#define MX51_MXC_INT_NM 76
+#define MX51_MXC_INT_PMU 77
+#define MX51_MXC_INT_CTI_IRQ 78
+#define MX51_MXC_INT_CTI1_TG0 79
+#define MX51_MXC_INT_CTI1_TG1 80
+#define MX51_MXC_INT_MCG_ERR 81
+#define MX51_MXC_INT_MCG_TMR 82
+#define MX51_MXC_INT_MCG_FUNC 83
+#define MX51_MXC_INT_GPU2_IRQ 84
+#define MX51_MXC_INT_GPU2_BUSY 85
+#define MX51_MXC_INT_RESV86 86
+#define MX51_INT_FEC 87
+#define MX51_MXC_INT_OWIRE 88
+#define MX51_MXC_INT_CTI1_TG2 89
+#define MX51_MXC_INT_SJC 90
+#define MX51_MXC_INT_SPDIF 91
+#define MX51_MXC_INT_TVE 92
+#define MX51_MXC_INT_FIRI 93
+#define MX51_MXC_INT_PWM2 94
+#define MX51_MXC_INT_SLIM_EXP 95
+#define MX51_MXC_INT_SSI3 96
+#define MX51_MXC_INT_EMI_BOOT 97
+#define MX51_MXC_INT_CTI1_TG3 98
+#define MX51_MXC_INT_SMC_RX 99
+#define MX51_MXC_INT_VPU_IDLE 100
+#define MX51_MXC_INT_EMI_NFC 101
+#define MX51_MXC_INT_GPU_IDLE 102
/* silicon revisions specific to i.MX51 */
-#define MX51_CHIP_REV_1_0 0x10
-#define MX51_CHIP_REV_1_1 0x11
-#define MX51_CHIP_REV_1_2 0x12
-#define MX51_CHIP_REV_1_3 0x13
-#define MX51_CHIP_REV_2_0 0x20
-#define MX51_CHIP_REV_2_1 0x21
-#define MX51_CHIP_REV_2_2 0x22
-#define MX51_CHIP_REV_2_3 0x23
-#define MX51_CHIP_REV_3_0 0x30
-#define MX51_CHIP_REV_3_1 0x31
-#define MX51_CHIP_REV_3_2 0x32
-
-/* Mandatory defines used globally */
+#define MX51_CHIP_REV_1_0 0x10
+#define MX51_CHIP_REV_1_1 0x11
+#define MX51_CHIP_REV_1_2 0x12
+#define MX51_CHIP_REV_1_3 0x13
+#define MX51_CHIP_REV_2_0 0x20
+#define MX51_CHIP_REV_2_1 0x21
+#define MX51_CHIP_REV_2_2 0x22
+#define MX51_CHIP_REV_2_3 0x23
+#define MX51_CHIP_REV_3_0 0x30
+#define MX51_CHIP_REV_3_1 0x31
+#define MX51_CHIP_REV_3_2 0x32
#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
-
extern int mx51_revision(void);
#endif
-#endif /* __ASM_ARCH_MXC_MX51_H__ */
+/* tape-out 1 defines */
+#define MX51_TZIC_BASE_ADDR_TO1 0x8fffc000
+
+#endif /* ifndef __MACH_MX51_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/system.h b/arch/arm/plat-mxc/include/mach/system.h
index 4acd1143a9bd..95be51bfe9a9 100644
--- a/arch/arm/plat-mxc/include/mach/system.h
+++ b/arch/arm/plat-mxc/include/mach/system.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999 ARM Limited
* Copyright (C) 2000 Deep Blue Solutions Ltd
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,8 +28,34 @@ static inline void arch_idle(void)
mxc91231_prepare_idle();
}
#endif
-
- cpu_do_idle();
+ /* fix i.MX31 errata TLSbo65953 and i.MX35 errata ENGcm09472 */
+ if (cpu_is_mx31() || cpu_is_mx35()) {
+ unsigned long reg = 0;
+ __asm__ __volatile__(
+ /* disable I and D cache */
+ "mrc p15, 0, %0, c1, c0, 0\n"
+ "bic %0, %0, #0x00001000\n"
+ "bic %0, %0, #0x00000004\n"
+ "mcr p15, 0, %0, c1, c0, 0\n"
+ /* invalidate I cache */
+ "mov %0, #0\n"
+ "mcr p15, 0, %0, c7, c5, 0\n"
+ /* clear and invalidate D cache */
+ "mov %0, #0\n"
+ "mcr p15, 0, %0, c7, c14, 0\n"
+ /* WFI */
+ "mov %0, #0\n"
+ "mcr p15, 0, %0, c7, c0, 4\n"
+ "nop\n" "nop\n" "nop\n" "nop\n"
+ "nop\n" "nop\n" "nop\n"
+ /* enable I and D cache */
+ "mrc p15, 0, %0, c1, c0, 0\n"
+ "orr %0, %0, #0x00001000\n"
+ "orr %0, %0, #0x00000004\n"
+ "mcr p15, 0, %0, c1, c0, 0\n"
+ : "=r" (reg));
+ } else
+ cpu_do_idle();
}
void arch_reset(char mode, const char *cmd);
diff --git a/arch/arm/plat-mxc/include/mach/uncompress.h b/arch/arm/plat-mxc/include/mach/uncompress.h
index d9bd37e4667a..9dd9c2085aad 100644
--- a/arch/arm/plat-mxc/include/mach/uncompress.h
+++ b/arch/arm/plat-mxc/include/mach/uncompress.h
@@ -99,6 +99,7 @@ static __inline__ void __arch_decomp_setup(unsigned long arch_id)
uart_base = MX3X_UART2_BASE_ADDR;
break;
case MACH_TYPE_MX51_BABBAGE:
+ case MACH_TYPE_EUKREA_CPUIMX51SD:
uart_base = MX51_UART1_BASE_ADDR;
break;
default:
diff --git a/arch/arm/plat-mxc/iram_alloc.c b/arch/arm/plat-mxc/iram_alloc.c
new file mode 100644
index 000000000000..074c3869626a
--- /dev/null
+++ b/arch/arm/plat-mxc/iram_alloc.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/genalloc.h>
+#include <mach/iram.h>
+
+static unsigned long iram_phys_base;
+static void __iomem *iram_virt_base;
+static struct gen_pool *iram_pool;
+
+static inline void __iomem *iram_phys_to_virt(unsigned long p)
+{
+ return iram_virt_base + (p - iram_phys_base);
+}
+
+void __iomem *iram_alloc(unsigned int size, unsigned long *dma_addr)
+{
+ if (!iram_pool)
+ return NULL;
+
+ *dma_addr = gen_pool_alloc(iram_pool, size);
+ pr_debug("iram alloc - %dB@0x%lX\n", size, *dma_addr);
+ if (!*dma_addr)
+ return NULL;
+ return iram_phys_to_virt(*dma_addr);
+}
+EXPORT_SYMBOL(iram_alloc);
+
+void iram_free(unsigned long addr, unsigned int size)
+{
+ if (!iram_pool)
+ return;
+
+ gen_pool_free(iram_pool, addr, size);
+}
+EXPORT_SYMBOL(iram_free);
+
+int __init iram_init(unsigned long base, unsigned long size)
+{
+ iram_phys_base = base;
+
+ iram_pool = gen_pool_create(PAGE_SHIFT, -1);
+ if (!iram_pool)
+ return -ENOMEM;
+
+ gen_pool_add(iram_pool, base, size, -1);
+ iram_virt_base = ioremap(iram_phys_base, size);
+ if (!iram_virt_base)
+ return -EIO;
+
+ pr_debug("i.MX IRAM pool: %ld KB@0x%p\n", size / 1024, iram_virt_base);
+ return 0;
+}
diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c
index 977c8f9a07a2..85e6fd212a41 100644
--- a/arch/arm/plat-nomadik/gpio.c
+++ b/arch/arm/plat-nomadik/gpio.c
@@ -102,6 +102,22 @@ static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip,
writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC);
}
+static void __nmk_gpio_set_output(struct nmk_gpio_chip *nmk_chip,
+ unsigned offset, int val)
+{
+ if (val)
+ writel(1 << offset, nmk_chip->addr + NMK_GPIO_DATS);
+ else
+ writel(1 << offset, nmk_chip->addr + NMK_GPIO_DATC);
+}
+
+static void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip,
+ unsigned offset, int val)
+{
+ writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS);
+ __nmk_gpio_set_output(nmk_chip, offset, val);
+}
+
static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset,
pin_cfg_t cfg)
{
@@ -118,20 +134,29 @@ static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset,
[3] /* illegal */ = "??"
};
static const char *slpmnames[] = {
- [NMK_GPIO_SLPM_INPUT] = "input",
- [NMK_GPIO_SLPM_NOCHANGE] = "no-change",
+ [NMK_GPIO_SLPM_INPUT] = "input/wakeup",
+ [NMK_GPIO_SLPM_NOCHANGE] = "no-change/no-wakeup",
};
int pin = PIN_NUM(cfg);
int pull = PIN_PULL(cfg);
int af = PIN_ALT(cfg);
int slpm = PIN_SLPM(cfg);
+ int output = PIN_DIR(cfg);
+ int val = PIN_VAL(cfg);
- dev_dbg(nmk_chip->chip.dev, "pin %d: af %s, pull %s, slpm %s\n",
- pin, afnames[af], pullnames[pull], slpmnames[slpm]);
+ dev_dbg(nmk_chip->chip.dev, "pin %d: af %s, pull %s, slpm %s (%s%s)\n",
+ pin, afnames[af], pullnames[pull], slpmnames[slpm],
+ output ? "output " : "input",
+ output ? (val ? "high" : "low") : "");
+
+ if (output)
+ __nmk_gpio_make_output(nmk_chip, offset, val);
+ else {
+ __nmk_gpio_make_input(nmk_chip, offset);
+ __nmk_gpio_set_pull(nmk_chip, offset, pull);
+ }
- __nmk_gpio_make_input(nmk_chip, offset);
- __nmk_gpio_set_pull(nmk_chip, offset, pull);
__nmk_gpio_set_slpm(nmk_chip, offset, slpm);
__nmk_gpio_set_mode(nmk_chip, offset, af);
}
@@ -200,6 +225,10 @@ EXPORT_SYMBOL(nmk_config_pins);
* changed to an input (with pullup/down enabled) in sleep and deep sleep. If
* @mode is NMK_GPIO_SLPM_NOCHANGE, the pin remains in the state it was
* configured even when in sleep and deep sleep.
+ *
+ * On DB8500v2 onwards, this setting loses the previous meaning and instead
+ * indicates if wakeup detection is enabled on the pin. Note that
+ * enable_irq_wake() will automatically enable wakeup detection.
*/
int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode)
{
@@ -367,7 +396,27 @@ static void nmk_gpio_irq_unmask(unsigned int irq)
static int nmk_gpio_irq_set_wake(unsigned int irq, unsigned int on)
{
- return nmk_gpio_irq_modify(irq, WAKE, on);
+ struct nmk_gpio_chip *nmk_chip;
+ unsigned long flags;
+ int gpio;
+
+ gpio = NOMADIK_IRQ_TO_GPIO(irq);
+ nmk_chip = get_irq_chip_data(irq);
+ if (!nmk_chip)
+ return -EINVAL;
+
+ spin_lock_irqsave(&nmk_chip->lock, flags);
+#ifdef CONFIG_ARCH_U8500
+ if (cpu_is_u8500v2()) {
+ __nmk_gpio_set_slpm(nmk_chip, gpio,
+ on ? NMK_GPIO_SLPM_WAKEUP_ENABLE
+ : NMK_GPIO_SLPM_WAKEUP_DISABLE);
+ }
+#endif
+ __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, on);
+ spin_unlock_irqrestore(&nmk_chip->lock, flags);
+
+ return 0;
}
static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type)
@@ -495,12 +544,8 @@ static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset,
{
struct nmk_gpio_chip *nmk_chip =
container_of(chip, struct nmk_gpio_chip, chip);
- u32 bit = 1 << offset;
- if (val)
- writel(bit, nmk_chip->addr + NMK_GPIO_DATS);
- else
- writel(bit, nmk_chip->addr + NMK_GPIO_DATC);
+ __nmk_gpio_set_output(nmk_chip, offset, val);
}
static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset,
@@ -509,8 +554,7 @@ static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset,
struct nmk_gpio_chip *nmk_chip =
container_of(chip, struct nmk_gpio_chip, chip);
- writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS);
- nmk_gpio_set_output(chip, offset, val);
+ __nmk_gpio_make_output(nmk_chip, offset, val);
return 0;
}
@@ -534,7 +578,7 @@ static struct gpio_chip nmk_gpio_template = {
.can_sleep = 0,
};
-static int __init nmk_gpio_probe(struct platform_device *dev)
+static int __devinit nmk_gpio_probe(struct platform_device *dev)
{
struct nmk_gpio_platform_data *pdata = dev->dev.platform_data;
struct nmk_gpio_chip *nmk_chip;
diff --git a/arch/arm/plat-nomadik/include/plat/gpio.h b/arch/arm/plat-nomadik/include/plat/gpio.h
index aba355101f49..67b113d639d8 100644
--- a/arch/arm/plat-nomadik/include/plat/gpio.h
+++ b/arch/arm/plat-nomadik/include/plat/gpio.h
@@ -65,7 +65,9 @@ enum nmk_gpio_pull {
/* Sleep mode */
enum nmk_gpio_slpm {
NMK_GPIO_SLPM_INPUT,
+ NMK_GPIO_SLPM_WAKEUP_ENABLE = NMK_GPIO_SLPM_INPUT,
NMK_GPIO_SLPM_NOCHANGE,
+ NMK_GPIO_SLPM_WAKEUP_DISABLE = NMK_GPIO_SLPM_NOCHANGE,
};
extern int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode);
diff --git a/arch/arm/plat-nomadik/include/plat/pincfg.h b/arch/arm/plat-nomadik/include/plat/pincfg.h
index 7eed11c1038d..8c5ae3f2acf8 100644
--- a/arch/arm/plat-nomadik/include/plat/pincfg.h
+++ b/arch/arm/plat-nomadik/include/plat/pincfg.h
@@ -19,12 +19,16 @@
* bit 9..10 - Alternate Function Selection
* bit 11..12 - Pull up/down state
* bit 13 - Sleep mode behaviour
+ * bit 14 - (sleep mode) Direction
+ * bit 15 - (sleep mode) Value (if output)
*
* to facilitate the definition, the following macros are provided
*
* PIN_CFG_DEFAULT - default config (0):
* pull up/down = disabled
- * sleep mode = input
+ * sleep mode = input/wakeup
+ * (sleep mode) direction = input
+ * (sleep mode) value = low
*
* PIN_CFG - default config with alternate function
* PIN_CFG_PULL - default config with alternate function and pull up/down
@@ -53,8 +57,36 @@ typedef unsigned long pin_cfg_t;
#define PIN_SLPM_SHIFT 13
#define PIN_SLPM_MASK (0x1 << PIN_SLPM_SHIFT)
#define PIN_SLPM(x) (((x) & PIN_SLPM_MASK) >> PIN_SLPM_SHIFT)
-#define PIN_SLPM_INPUT (NMK_GPIO_SLPM_INPUT << PIN_SLPM_SHIFT)
+#define PIN_SLPM_MAKE_INPUT (NMK_GPIO_SLPM_INPUT << PIN_SLPM_SHIFT)
#define PIN_SLPM_NOCHANGE (NMK_GPIO_SLPM_NOCHANGE << PIN_SLPM_SHIFT)
+/* These two replace the above in DB8500v2+ */
+#define PIN_SLPM_WAKEUP_ENABLE (NMK_GPIO_SLPM_WAKEUP_ENABLE << PIN_SLPM_SHIFT)
+#define PIN_SLPM_WAKEUP_DISABLE (NMK_GPIO_SLPM_WAKEUP_DISABLE << PIN_SLPM_SHIFT)
+
+#define PIN_DIR_SHIFT 14
+#define PIN_DIR_MASK (0x1 << PIN_DIR_SHIFT)
+#define PIN_DIR(x) (((x) & PIN_DIR_MASK) >> PIN_DIR_SHIFT)
+#define PIN_DIR_INPUT (0 << PIN_DIR_SHIFT)
+#define PIN_DIR_OUTPUT (1 << PIN_DIR_SHIFT)
+
+#define PIN_VAL_SHIFT 15
+#define PIN_VAL_MASK (0x1 << PIN_VAL_SHIFT)
+#define PIN_VAL(x) (((x) & PIN_VAL_MASK) >> PIN_VAL_SHIFT)
+#define PIN_VAL_LOW (0 << PIN_VAL_SHIFT)
+#define PIN_VAL_HIGH (1 << PIN_VAL_SHIFT)
+
+/* Shortcuts. Use these instead of separate DIR and VAL. */
+#define PIN_INPUT PIN_DIR_INPUT
+#define PIN_OUTPUT_LOW (PIN_DIR_OUTPUT | PIN_VAL_LOW)
+#define PIN_OUTPUT_HIGH (PIN_DIR_OUTPUT | PIN_VAL_HIGH)
+
+/*
+ * These are the same as the ones above, but should make more sense to the
+ * reader when seen along with a setting a pin to AF mode.
+ */
+#define PIN_SLPM_INPUT PIN_INPUT
+#define PIN_SLPM_OUTPUT_LOW PIN_OUTPUT_LOW
+#define PIN_SLPM_OUTPUT_HIGH PIN_OUTPUT_HIGH
#define PIN_CFG_DEFAULT (PIN_PULL_NONE | PIN_SLPM_INPUT)
diff --git a/arch/arm/plat-nomadik/include/plat/ske.h b/arch/arm/plat-nomadik/include/plat/ske.h
new file mode 100644
index 000000000000..31382fbc07dc
--- /dev/null
+++ b/arch/arm/plat-nomadik/include/plat/ske.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License Terms: GNU General Public License v2
+ * Author: Naveen Kumar Gaddipati <naveen.gaddipati@stericsson.com>
+ *
+ * ux500 Scroll key and Keypad Encoder (SKE) header
+ */
+
+#ifndef __SKE_H
+#define __SKE_H
+
+#include <linux/input/matrix_keypad.h>
+
+/* register definitions for SKE peripheral */
+#define SKE_CR 0x00
+#define SKE_VAL0 0x04
+#define SKE_VAL1 0x08
+#define SKE_DBCR 0x0C
+#define SKE_IMSC 0x10
+#define SKE_RIS 0x14
+#define SKE_MIS 0x18
+#define SKE_ICR 0x1C
+
+/*
+ * Keypad module
+ */
+
+/**
+ * struct keypad_platform_data - structure for platform specific data
+ * @init: pointer to keypad init function
+ * @exit: pointer to keypad deinitialisation function
+ * @keymap_data: matrix scan code table for keycodes
+ * @krow: maximum number of rows
+ * @kcol: maximum number of columns
+ * @debounce_ms: platform specific debounce time
+ * @no_autorepeat: flag for auto repetition
+ * @wakeup_enable: allow waking up the system
+ */
+struct ske_keypad_platform_data {
+ int (*init)(void);
+ int (*exit)(void);
+ const struct matrix_keymap_data *keymap_data;
+ u8 krow;
+ u8 kcol;
+ u8 debounce_ms;
+ bool no_autorepeat;
+ bool wakeup_enable;
+};
+#endif /*__SKE_KPD_H*/
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index e39a417a368d..a92cb499313f 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -33,7 +33,7 @@ config OMAP_DEBUG_DEVICES
config OMAP_DEBUG_LEDS
bool
depends on OMAP_DEBUG_DEVICES
- default y if LEDS
+ default y if LEDS_CLASS
config OMAP_RESET_CLOCKS
bool "Reset unused clocks during boot"
diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c
index 0054b9501a53..71934817e172 100644
--- a/arch/arm/plat-omap/fb.c
+++ b/arch/arm/plat-omap/fb.c
@@ -173,11 +173,7 @@ static int check_fbmem_region(int region_idx, struct omapfb_mem_region *rg,
static int valid_sdram(unsigned long addr, unsigned long size)
{
- struct memblock_property res;
-
- res.base = addr;
- res.size = size;
- return !memblock_find(&res) && res.base == addr && res.size == size;
+ return memblock_is_region_memory(addr, size);
}
static int reserve_sdram(unsigned long addr, unsigned long size)
diff --git a/arch/arm/plat-omap/include/plat/omap4-keypad.h b/arch/arm/plat-omap/include/plat/omap4-keypad.h
new file mode 100644
index 000000000000..2b1d9bc1eebb
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/omap4-keypad.h
@@ -0,0 +1,14 @@
+#ifndef ARCH_ARM_PLAT_OMAP4_KEYPAD_H
+#define ARCH_ARM_PLAT_OMAP4_KEYPAD_H
+
+#include <linux/input/matrix_keypad.h>
+
+struct omap4_keypad_platform_data {
+ const struct matrix_keymap_data *keymap_data;
+
+ u8 rows;
+ u8 cols;
+};
+
+extern int omap4_keyboard_init(struct omap4_keypad_platform_data *);
+#endif
diff --git a/arch/arm/plat-omap/include/plat/smp.h b/arch/arm/plat-omap/include/plat/smp.h
index 5177a9c5a25a..ecd6a488c497 100644
--- a/arch/arm/plat-omap/include/plat/smp.h
+++ b/arch/arm/plat-omap/include/plat/smp.h
@@ -18,6 +18,7 @@
#define OMAP_ARCH_SMP_H
#include <asm/hardware/gic.h>
+#include <asm/smp_mpidr.h>
/* Needed for secondary core boot */
extern void omap_secondary_startup(void);
@@ -33,15 +34,4 @@ static inline void smp_cross_call(const struct cpumask *mask)
gic_raise_softirq(mask, 1);
}
-/*
- * Read MPIDR: Multiprocessor affinity register
- */
-#define hard_smp_processor_id() \
- ({ \
- unsigned int cpunum; \
- __asm__("mrc p15, 0, %0, c0, c0, 5" \
- : "=r" (cpunum)); \
- cpunum &= 0x0F; \
- })
-
#endif
diff --git a/arch/arm/plat-omap/include/plat/usb.h b/arch/arm/plat-omap/include/plat/usb.h
index 2a9427c8cc48..9feddacfe850 100644
--- a/arch/arm/plat-omap/include/plat/usb.h
+++ b/arch/arm/plat-omap/include/plat/usb.h
@@ -218,6 +218,27 @@ static inline omap2_usbfs_init(struct omap_usb_config *pdata)
# define USBT2TLL5PI (1 << 17)
# define USB0PUENACTLOI (1 << 16)
# define USBSTANDBYCTRL (1 << 15)
+/* AM35x */
+/* USB 2.0 PHY Control */
+#define CONF2_PHY_GPIOMODE (1 << 23)
+#define CONF2_OTGMODE (3 << 14)
+#define CONF2_NO_OVERRIDE (0 << 14)
+#define CONF2_FORCE_HOST (1 << 14)
+#define CONF2_FORCE_DEVICE (2 << 14)
+#define CONF2_FORCE_HOST_VBUS_LOW (3 << 14)
+#define CONF2_SESENDEN (1 << 13)
+#define CONF2_VBDTCTEN (1 << 12)
+#define CONF2_REFFREQ_24MHZ (2 << 8)
+#define CONF2_REFFREQ_26MHZ (7 << 8)
+#define CONF2_REFFREQ_13MHZ (6 << 8)
+#define CONF2_REFFREQ (0xf << 8)
+#define CONF2_PHYCLKGD (1 << 7)
+#define CONF2_VBUSSENSE (1 << 6)
+#define CONF2_PHY_PLLON (1 << 5)
+#define CONF2_RESET (1 << 4)
+#define CONF2_PHYPWRDN (1 << 3)
+#define CONF2_OTGPWRDN (1 << 2)
+#define CONF2_DATPOL (1 << 1)
#if defined(CONFIG_ARCH_OMAP1) && defined(CONFIG_USB)
u32 omap1_usb0_init(unsigned nwires, unsigned is_device);
diff --git a/arch/arm/plat-omap/iommu-debug.c b/arch/arm/plat-omap/iommu-debug.c
index e6c0d536899c..f07cf2f08e09 100644
--- a/arch/arm/plat-omap/iommu-debug.c
+++ b/arch/arm/plat-omap/iommu-debug.c
@@ -328,12 +328,14 @@ static int debug_open_generic(struct inode *inode, struct file *file)
.open = debug_open_generic, \
.read = debug_read_##name, \
.write = debug_write_##name, \
+ .llseek = generic_file_llseek, \
};
#define DEBUG_FOPS_RO(name) \
static const struct file_operations debug_##name##_fops = { \
.open = debug_open_generic, \
.read = debug_read_##name, \
+ .llseek = generic_file_llseek, \
};
DEBUG_FOPS_RO(ver);
diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c
index a202a2ce6e3d..6cd151b31bc5 100644
--- a/arch/arm/plat-omap/iommu.c
+++ b/arch/arm/plat-omap/iommu.c
@@ -320,6 +320,7 @@ void flush_iotlb_page(struct iommu *obj, u32 da)
if ((start <= da) && (da < start + bytes)) {
dev_dbg(obj->dev, "%s: %08x<=%08x(%x)\n",
__func__, start, da, bytes);
+ iotlb_load_cr(obj, &cr);
iommu_write_reg(obj, 1, MMU_FLUSH_ENTRY);
}
}
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index e31496e35b0f..0c8612fd8312 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -156,7 +156,7 @@ static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id)
/* Writing zero to RSYNC_ERR clears the IRQ */
MCBSP_WRITE(mcbsp_rx, SPCR1, MCBSP_READ_CACHE(mcbsp_rx, SPCR1));
} else {
- complete(&mcbsp_rx->tx_irq_completion);
+ complete(&mcbsp_rx->rx_irq_completion);
}
return IRQ_HANDLED;
diff --git a/arch/arm/mach-pxa/include/mach/pxa27x_keypad.h b/arch/arm/plat-pxa/include/plat/pxa27x_keypad.h
index 7b4eadc6df3a..abcc36eb1242 100644
--- a/arch/arm/mach-pxa/include/mach/pxa27x_keypad.h
+++ b/arch/arm/plat-pxa/include/plat/pxa27x_keypad.h
@@ -25,6 +25,13 @@
*
* 4. matrix key and direct key will use the same debounce_interval by
* default, which should be sufficient in most cases
+ *
+ * pxa168 keypad platform specific parameter
+ *
+ * NOTE:
+ * clear_wakeup_event callback is a workaround required to clear the
+ * keypad interrupt. The keypad wake must be cleared in addition to
+ * reading the MI/DI bits in the KPC register.
*/
struct pxa27x_keypad_platform_data {
@@ -52,6 +59,9 @@ struct pxa27x_keypad_platform_data {
/* key debounce interval */
unsigned int debounce_interval;
+
+ /* clear wakeup event requirement for pxa168 */
+ void (*clear_wakeup_event)(void);
};
extern void pxa_set_keypad_info(struct pxa27x_keypad_platform_data *info);
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
index c6a855db2fb6..25960966af7c 100644
--- a/arch/arm/plat-s5p/Kconfig
+++ b/arch/arm/plat-s5p/Kconfig
@@ -7,7 +7,7 @@
config PLAT_S5P
bool
- depends on (ARCH_S5P6440 || ARCH_S5P6442 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5PV310)
+ depends on (ARCH_S5P64X0 || ARCH_S5P6442 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5PV310)
default y
select ARM_VIC if !ARCH_S5PV310
select ARM_GIC if ARCH_S5PV310
@@ -30,7 +30,7 @@ config S5P_EXT_INT
bool
help
Use the external interrupts (other than GPIO interrupts.)
- Note: Do not choose this for S5P6440.
+ Note: Do not choose this for S5P6440 and S5P6450.
config S5P_DEV_FIMC0
bool
@@ -46,3 +46,8 @@ config S5P_DEV_FIMC2
bool
help
Compile in platform device definitions for FIMC controller 2
+
+config S5P_DEV_ONENAND
+ bool
+ help
+ Compile in platform device definition for OneNAND controller
diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
index b2e029673950..f3e917e27da8 100644
--- a/arch/arm/plat-s5p/Makefile
+++ b/arch/arm/plat-s5p/Makefile
@@ -24,3 +24,4 @@ obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o
obj-$(CONFIG_S5P_DEV_FIMC0) += dev-fimc0.o
obj-$(CONFIG_S5P_DEV_FIMC1) += dev-fimc1.o
obj-$(CONFIG_S5P_DEV_FIMC2) += dev-fimc2.o
+obj-$(CONFIG_S5P_DEV_ONENAND) += dev-onenand.o
diff --git a/arch/arm/plat-s5p/clock.c b/arch/arm/plat-s5p/clock.c
index b5e255265f20..8aaf4e6b60c3 100644
--- a/arch/arm/plat-s5p/clock.c
+++ b/arch/arm/plat-s5p/clock.c
@@ -74,6 +74,13 @@ struct clk clk_fout_epll = {
.ctrlbit = (1 << 31),
};
+/* DPLL clock output */
+struct clk clk_fout_dpll = {
+ .name = "fout_dpll",
+ .id = -1,
+ .ctrlbit = (1 << 31),
+};
+
/* VPLL clock output */
struct clk clk_fout_vpll = {
.name = "fout_vpll",
@@ -122,6 +129,17 @@ struct clksrc_sources clk_src_epll = {
.nr_sources = ARRAY_SIZE(clk_src_epll_list),
};
+/* Possible clock sources for DPLL Mux */
+static struct clk *clk_src_dpll_list[] = {
+ [0] = &clk_fin_dpll,
+ [1] = &clk_fout_dpll,
+};
+
+struct clksrc_sources clk_src_dpll = {
+ .sources = clk_src_dpll_list,
+ .nr_sources = ARRAY_SIZE(clk_src_dpll_list),
+};
+
struct clk clk_vpll = {
.name = "vpll",
.id = -1,
@@ -145,6 +163,7 @@ static struct clk *s5p_clks[] __initdata = {
&clk_fout_apll,
&clk_fout_mpll,
&clk_fout_epll,
+ &clk_fout_dpll,
&clk_fout_vpll,
&clk_arm,
&clk_vpll,
diff --git a/arch/arm/plat-s5p/cpu.c b/arch/arm/plat-s5p/cpu.c
index b07a078fd284..74f7f5a5446c 100644
--- a/arch/arm/plat-s5p/cpu.c
+++ b/arch/arm/plat-s5p/cpu.c
@@ -19,6 +19,7 @@
#include <plat/cpu.h>
#include <plat/s5p6440.h>
#include <plat/s5p6442.h>
+#include <plat/s5p6450.h>
#include <plat/s5pc100.h>
#include <plat/s5pv210.h>
#include <plat/s5pv310.h>
@@ -27,6 +28,7 @@
static const char name_s5p6440[] = "S5P6440";
static const char name_s5p6442[] = "S5P6442";
+static const char name_s5p6450[] = "S5P6450";
static const char name_s5pc100[] = "S5PC100";
static const char name_s5pv210[] = "S5PV210/S5PC110";
static const char name_s5pv310[] = "S5PV310";
@@ -38,7 +40,7 @@ static struct cpu_table cpu_ids[] __initdata = {
.map_io = s5p6440_map_io,
.init_clocks = s5p6440_init_clocks,
.init_uarts = s5p6440_init_uarts,
- .init = s5p6440_init,
+ .init = s5p64x0_init,
.name = name_s5p6440,
}, {
.idcode = 0x36442000,
@@ -49,6 +51,14 @@ static struct cpu_table cpu_ids[] __initdata = {
.init = s5p6442_init,
.name = name_s5p6442,
}, {
+ .idcode = 0x36450000,
+ .idmask = 0xffffff00,
+ .map_io = s5p6450_map_io,
+ .init_clocks = s5p6450_init_clocks,
+ .init_uarts = s5p6450_init_uarts,
+ .init = s5p64x0_init,
+ .name = name_s5p6450,
+ }, {
.idcode = 0x43100000,
.idmask = 0xfffff000,
.map_io = s5pc100_map_io,
@@ -89,33 +99,11 @@ static struct map_desc s5p_iodesc[] __initdata = {
.length = SZ_64K,
.type = MT_DEVICE,
}, {
- .virtual = (unsigned long)S3C_VA_UART,
- .pfn = __phys_to_pfn(S3C_PA_UART),
- .length = SZ_512K,
- .type = MT_DEVICE,
-#ifdef CONFIG_ARM_VIC
- }, {
- .virtual = (unsigned long)VA_VIC0,
- .pfn = __phys_to_pfn(S5P_PA_VIC0),
- .length = SZ_16K,
- .type = MT_DEVICE,
- }, {
- .virtual = (unsigned long)VA_VIC1,
- .pfn = __phys_to_pfn(S5P_PA_VIC1),
- .length = SZ_16K,
- .type = MT_DEVICE,
-#endif
- }, {
.virtual = (unsigned long)S3C_VA_TIMER,
.pfn = __phys_to_pfn(S5P_PA_TIMER),
.length = SZ_16K,
.type = MT_DEVICE,
}, {
- .virtual = (unsigned long)S5P_VA_GPIO,
- .pfn = __phys_to_pfn(S5P_PA_GPIO),
- .length = SZ_4K,
- .type = MT_DEVICE,
- }, {
.virtual = (unsigned long)S3C_VA_WATCHDOG,
.pfn = __phys_to_pfn(S3C_PA_WDT),
.length = SZ_4K,
diff --git a/arch/arm/mach-s5pv210/dev-onenand.c b/arch/arm/plat-s5p/dev-onenand.c
index f8ede33ee82b..6db926202caa 100644
--- a/arch/arm/mach-s5pv210/dev-onenand.c
+++ b/arch/arm/plat-s5p/dev-onenand.c
@@ -1,10 +1,12 @@
-/*
- * linux/arch/arm/mach-s5pv210/dev-onenand.c
+/* linux/arch/arm/plat-s5p/dev-onenand.c
+ *
+ * Copyright 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
*
* Copyright (c) 2008-2010 Samsung Electronics
* Kyungmin Park <kyungmin.park@samsung.com>
*
- * S5PC110 series device definition for OneNAND devices
+ * S5P series device definition for OneNAND devices
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -19,15 +21,15 @@
#include <mach/irqs.h>
#include <mach/map.h>
-static struct resource s5pc110_onenand_resources[] = {
+static struct resource s5p_onenand_resources[] = {
[0] = {
- .start = S5PC110_PA_ONENAND,
- .end = S5PC110_PA_ONENAND + SZ_128K - 1,
+ .start = S5P_PA_ONENAND,
+ .end = S5P_PA_ONENAND + SZ_128K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = S5PC110_PA_ONENAND_DMA,
- .end = S5PC110_PA_ONENAND_DMA + SZ_8K - 1,
+ .start = S5P_PA_ONENAND_DMA,
+ .end = S5P_PA_ONENAND_DMA + SZ_8K - 1,
.flags = IORESOURCE_MEM,
},
[2] = {
@@ -37,19 +39,19 @@ static struct resource s5pc110_onenand_resources[] = {
},
};
-struct platform_device s5pc110_device_onenand = {
+struct platform_device s5p_device_onenand = {
.name = "s5pc110-onenand",
.id = -1,
- .num_resources = ARRAY_SIZE(s5pc110_onenand_resources),
- .resource = s5pc110_onenand_resources,
+ .num_resources = ARRAY_SIZE(s5p_onenand_resources),
+ .resource = s5p_onenand_resources,
};
-void s5pc110_onenand_set_platdata(struct onenand_platform_data *pdata)
+void s5p_onenand_set_platdata(struct onenand_platform_data *pdata)
{
struct onenand_platform_data *pd;
pd = kmemdup(pdata, sizeof(struct onenand_platform_data), GFP_KERNEL);
if (!pd)
printk(KERN_ERR "%s: no memory for platform data\n", __func__);
- s5pc110_device_onenand.dev.platform_data = pd;
+ s5p_device_onenand.dev.platform_data = pd;
}
diff --git a/arch/arm/plat-s5p/dev-uart.c b/arch/arm/plat-s5p/dev-uart.c
index a89331ef4ae1..6a7342886171 100644
--- a/arch/arm/plat-s5p/dev-uart.c
+++ b/arch/arm/plat-s5p/dev-uart.c
@@ -119,6 +119,56 @@ static struct resource s5p_uart3_resource[] = {
#endif
};
+static struct resource s5p_uart4_resource[] = {
+#if CONFIG_SERIAL_SAMSUNG_UARTS > 4
+ [0] = {
+ .start = S5P_PA_UART4,
+ .end = S5P_PA_UART4 + S5P_SZ_UART,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_S5P_UART_RX4,
+ .end = IRQ_S5P_UART_RX4,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_S5P_UART_TX4,
+ .end = IRQ_S5P_UART_TX4,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = IRQ_S5P_UART_ERR4,
+ .end = IRQ_S5P_UART_ERR4,
+ .flags = IORESOURCE_IRQ,
+ },
+#endif
+};
+
+static struct resource s5p_uart5_resource[] = {
+#if CONFIG_SERIAL_SAMSUNG_UARTS > 5
+ [0] = {
+ .start = S5P_PA_UART5,
+ .end = S5P_PA_UART5 + S5P_SZ_UART,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_S5P_UART_RX5,
+ .end = IRQ_S5P_UART_RX5,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_S5P_UART_TX5,
+ .end = IRQ_S5P_UART_TX5,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = IRQ_S5P_UART_ERR5,
+ .end = IRQ_S5P_UART_ERR5,
+ .flags = IORESOURCE_IRQ,
+ },
+#endif
+};
+
struct s3c24xx_uart_resources s5p_uart_resources[] __initdata = {
[0] = {
.resources = s5p_uart0_resource,
@@ -136,4 +186,12 @@ struct s3c24xx_uart_resources s5p_uart_resources[] __initdata = {
.resources = s5p_uart3_resource,
.nr_resources = ARRAY_SIZE(s5p_uart3_resource),
},
+ [4] = {
+ .resources = s5p_uart4_resource,
+ .nr_resources = ARRAY_SIZE(s5p_uart4_resource),
+ },
+ [5] = {
+ .resources = s5p_uart5_resource,
+ .nr_resources = ARRAY_SIZE(s5p_uart5_resource),
+ },
};
diff --git a/arch/arm/plat-s5p/include/plat/pll.h b/arch/arm/plat-s5p/include/plat/pll.h
index 4e8fe08cb70d..bf28fadee7ae 100644
--- a/arch/arm/plat-s5p/include/plat/pll.h
+++ b/arch/arm/plat-s5p/include/plat/pll.h
@@ -47,6 +47,7 @@ static inline unsigned long s5p_get_pll45xx(unsigned long baseclk, u32 pll_con,
}
#define PLL46XX_KDIV_MASK (0xFFFF)
+#define PLL4650C_KDIV_MASK (0xFFF)
#define PLL46XX_MDIV_MASK (0x1FF)
#define PLL46XX_PDIV_MASK (0x3F)
#define PLL46XX_SDIV_MASK (0x7)
@@ -57,6 +58,7 @@ static inline unsigned long s5p_get_pll45xx(unsigned long baseclk, u32 pll_con,
enum pll46xx_type_t {
pll_4600,
pll_4650,
+ pll_4650c,
};
static inline unsigned long s5p_get_pll46xx(unsigned long baseclk,
@@ -72,6 +74,11 @@ static inline unsigned long s5p_get_pll46xx(unsigned long baseclk,
sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
kdiv = pll_con1 & PLL46XX_KDIV_MASK;
+ if (pll_type == pll_4650c)
+ kdiv = pll_con1 & PLL4650C_KDIV_MASK;
+ else
+ kdiv = pll_con1 & PLL46XX_KDIV_MASK;
+
tmp = baseclk;
if (pll_type == pll_4600) {
diff --git a/arch/arm/plat-s5p/include/plat/s5p-clock.h b/arch/arm/plat-s5p/include/plat/s5p-clock.h
index 09418b1101fe..17036c898409 100644
--- a/arch/arm/plat-s5p/include/plat/s5p-clock.h
+++ b/arch/arm/plat-s5p/include/plat/s5p-clock.h
@@ -1,7 +1,7 @@
/* linux/arch/arm/plat-s5p/include/plat/s5p-clock.h
*
- * Copyright 2009 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
*
* Header file for s5p clock support
*
@@ -20,6 +20,7 @@
#define clk_fin_apll clk_ext_xtal_mux
#define clk_fin_mpll clk_ext_xtal_mux
#define clk_fin_epll clk_ext_xtal_mux
+#define clk_fin_dpll clk_ext_xtal_mux
#define clk_fin_vpll clk_ext_xtal_mux
#define clk_fin_hpll clk_ext_xtal_mux
@@ -30,6 +31,7 @@ extern struct clk s5p_clk_27m;
extern struct clk clk_fout_apll;
extern struct clk clk_fout_mpll;
extern struct clk clk_fout_epll;
+extern struct clk clk_fout_dpll;
extern struct clk clk_fout_vpll;
extern struct clk clk_arm;
extern struct clk clk_vpll;
@@ -37,8 +39,8 @@ extern struct clk clk_vpll;
extern struct clksrc_sources clk_src_apll;
extern struct clksrc_sources clk_src_mpll;
extern struct clksrc_sources clk_src_epll;
+extern struct clksrc_sources clk_src_dpll;
-extern int s5p6440_clk48m_ctrl(struct clk *clk, int enable);
extern int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable);
#endif /* __ASM_PLAT_S5P_CLOCK_H */
diff --git a/arch/arm/plat-s5p/include/plat/s5p6440.h b/arch/arm/plat-s5p/include/plat/s5p6440.h
index a4cd75afeb3b..528585d2cafc 100644
--- a/arch/arm/plat-s5p/include/plat/s5p6440.h
+++ b/arch/arm/plat-s5p/include/plat/s5p6440.h
@@ -12,24 +12,23 @@
/* Common init code for S5P6440 related SoCs */
-extern void s5p6440_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
extern void s5p6440_register_clocks(void);
extern void s5p6440_setup_clocks(void);
#ifdef CONFIG_CPU_S5P6440
-extern int s5p6440_init(void);
+extern int s5p64x0_init(void);
extern void s5p6440_init_irq(void);
extern void s5p6440_map_io(void);
extern void s5p6440_init_clocks(int xtal);
-#define s5p6440_init_uarts s5p6440_common_init_uarts
+extern void s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no);
#else
#define s5p6440_init_clocks NULL
#define s5p6440_init_uarts NULL
#define s5p6440_map_io NULL
-#define s5p6440_init NULL
+#define s5p64x0_init NULL
#endif
/* S5P6440 timer */
diff --git a/arch/arm/plat-s5p/include/plat/s5p6450.h b/arch/arm/plat-s5p/include/plat/s5p6450.h
new file mode 100644
index 000000000000..640a41c26be3
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/s5p6450.h
@@ -0,0 +1,36 @@
+/* arch/arm/plat-s5p/include/plat/s5p6450.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Header file for s5p6450 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* Common init code for S5P6450 related SoCs */
+
+extern void s5p6450_register_clocks(void);
+extern void s5p6450_setup_clocks(void);
+
+#ifdef CONFIG_CPU_S5P6450
+
+extern int s5p64x0_init(void);
+extern void s5p6450_init_irq(void);
+extern void s5p6450_map_io(void);
+extern void s5p6450_init_clocks(int xtal);
+
+extern void s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+#else
+#define s5p6450_init_clocks NULL
+#define s5p6450_init_uarts NULL
+#define s5p6450_map_io NULL
+#define s5p64x0_init NULL
+#endif
+
+/* S5P6450 timer */
+
+extern struct sys_timer s5p6450_timer;
diff --git a/arch/arm/plat-samsung/adc.c b/arch/arm/plat-samsung/adc.c
index 04d9521ddc9f..e8f2be2d67f2 100644
--- a/arch/arm/plat-samsung/adc.c
+++ b/arch/arm/plat-samsung/adc.c
@@ -435,7 +435,6 @@ static int s3c_adc_suspend(struct platform_device *pdev, pm_message_t state)
static int s3c_adc_resume(struct platform_device *pdev)
{
struct adc_device *adc = platform_get_drvdata(pdev);
- unsigned long flags;
clk_enable(adc->clk);
enable_irq(adc->irq);
diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c
index 90a20512d68d..e8d20b0bc50e 100644
--- a/arch/arm/plat-samsung/clock.c
+++ b/arch/arm/plat-samsung/clock.c
@@ -48,6 +48,9 @@
#include <plat/clock.h>
#include <plat/cpu.h>
+#include <linux/serial_core.h>
+#include <plat/regs-serial.h> /* for s3c24xx_uart_devs */
+
/* clock information */
static LIST_HEAD(clocks);
@@ -65,6 +68,28 @@ static int clk_null_enable(struct clk *clk, int enable)
return 0;
}
+static int dev_is_s3c_uart(struct device *dev)
+{
+ struct platform_device **pdev = s3c24xx_uart_devs;
+ int i;
+ for (i = 0; i < ARRAY_SIZE(s3c24xx_uart_devs); i++, pdev++)
+ if (*pdev && dev == &(*pdev)->dev)
+ return 1;
+ return 0;
+}
+
+/*
+ * Serial drivers call get_clock() very early, before platform bus
+ * has been set up, this requires a special check to let them get
+ * a proper clock
+ */
+
+static int dev_is_platform_device(struct device *dev)
+{
+ return dev->bus == &platform_bus_type ||
+ (dev->bus == NULL && dev_is_s3c_uart(dev));
+}
+
/* Clock API calls */
struct clk *clk_get(struct device *dev, const char *id)
@@ -73,7 +98,7 @@ struct clk *clk_get(struct device *dev, const char *id)
struct clk *clk = ERR_PTR(-ENOENT);
int idno;
- if (dev == NULL || dev->bus != &platform_bus_type)
+ if (dev == NULL || !dev_is_platform_device(dev))
idno = -1;
else
idno = to_platform_device(dev)->id;
diff --git a/arch/arm/plat-samsung/include/plat/adc.h b/arch/arm/plat-samsung/include/plat/adc.h
index e8382c7be10b..b258a08de591 100644
--- a/arch/arm/plat-samsung/include/plat/adc.h
+++ b/arch/arm/plat-samsung/include/plat/adc.h
@@ -1,7 +1,7 @@
/* arch/arm/plat-samsung/include/plat/adc.h
*
* Copyright (c) 2008 Simtec Electronics
- * http://armlinux.simnte.co.uk/
+ * http://armlinux.simtec.co.uk/
* Ben Dooks <ben@simtec.co.uk>
*
* S3C ADC driver information
diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h
index 6412933d6fbb..9addb3dfb4bc 100644
--- a/arch/arm/plat-samsung/include/plat/cpu.h
+++ b/arch/arm/plat-samsung/include/plat/cpu.h
@@ -79,7 +79,7 @@ extern struct sysdev_class s3c2442_sysclass;
extern struct sysdev_class s3c2443_sysclass;
extern struct sysdev_class s3c6410_sysclass;
extern struct sysdev_class s3c64xx_sysclass;
-extern struct sysdev_class s5p6440_sysclass;
+extern struct sysdev_class s5p64x0_sysclass;
extern struct sysdev_class s5p6442_sysclass;
extern struct sysdev_class s5pv210_sysclass;
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index 85f6f23a510f..7d448e138792 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -67,13 +67,15 @@ extern struct platform_device s5pv210_device_spi0;
extern struct platform_device s5pv210_device_spi1;
extern struct platform_device s5p6440_device_spi0;
extern struct platform_device s5p6440_device_spi1;
+extern struct platform_device s5p6450_device_spi0;
+extern struct platform_device s5p6450_device_spi1;
extern struct platform_device s3c_device_hwmon;
extern struct platform_device s3c_device_nand;
extern struct platform_device s3c_device_onenand;
extern struct platform_device s3c64xx_device_onenand1;
-extern struct platform_device s5pc110_device_onenand;
+extern struct platform_device s5p_device_onenand;
extern struct platform_device s3c_device_usbgadget;
extern struct platform_device s3c_device_usb_hsotg;
@@ -95,6 +97,9 @@ extern struct platform_device s5p6442_device_spi;
extern struct platform_device s5p6440_device_pcm;
extern struct platform_device s5p6440_device_iis;
+extern struct platform_device s5p6450_device_iis0;
+extern struct platform_device s5p6450_device_pcm0;
+
extern struct platform_device s5pc100_device_ac97;
extern struct platform_device s5pc100_device_pcm0;
extern struct platform_device s5pc100_device_pcm1;
diff --git a/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h b/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h
index 5fe6721b57f7..810744213120 100644
--- a/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h
+++ b/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h
@@ -32,6 +32,12 @@ enum dma_ch {
DMACH_UART2_TX,
DMACH_UART3_RX,
DMACH_UART3_TX,
+ DMACH_UART4_RX,
+ DMACH_UART4_TX,
+ DMACH_UART5_RX,
+ DMACH_UART5_TX,
+ DMACH_USI_RX,
+ DMACH_USI_TX,
DMACH_IRDA,
DMACH_I2S0_RX,
DMACH_I2S0_TX,
@@ -64,6 +70,20 @@ enum dma_ch {
DMACH_MSM_REQ2,
DMACH_MSM_REQ1,
DMACH_MSM_REQ0,
+ DMACH_SLIMBUS0_RX,
+ DMACH_SLIMBUS0_TX,
+ DMACH_SLIMBUS0AUX_RX,
+ DMACH_SLIMBUS0AUX_TX,
+ DMACH_SLIMBUS1_RX,
+ DMACH_SLIMBUS1_TX,
+ DMACH_SLIMBUS2_RX,
+ DMACH_SLIMBUS2_TX,
+ DMACH_SLIMBUS3_RX,
+ DMACH_SLIMBUS3_TX,
+ DMACH_SLIMBUS4_RX,
+ DMACH_SLIMBUS4_TX,
+ DMACH_SLIMBUS5_RX,
+ DMACH_SLIMBUS5_TX,
/* END Marker, also used to denote a reserved channel */
DMACH_MAX,
};
diff --git a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
index e5aba8f95b79..ff1a561b326e 100644
--- a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
+++ b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
@@ -32,6 +32,8 @@ struct s3c64xx_spi_csinfo {
* struct s3c64xx_spi_info - SPI Controller defining structure
* @src_clk_nr: Clock source index for the CLK_CFG[SPI_CLKSEL] field.
* @src_clk_name: Platform name of the corresponding clock.
+ * @clk_from_cmu: If the SPI clock/prescalar control block is present
+ * by the platform's clock-management-unit and not in SPI controller.
* @num_cs: Number of CS this controller emulates.
* @cfg_gpio: Configure pins for this SPI controller.
* @fifo_lvl_mask: All tx fifo_lvl fields start at offset-6
@@ -41,6 +43,7 @@ struct s3c64xx_spi_csinfo {
struct s3c64xx_spi_info {
int src_clk_nr;
char *src_clk_name;
+ bool clk_from_cmu;
int num_cs;
@@ -65,7 +68,7 @@ struct s3c64xx_spi_info {
extern void s3c64xx_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
extern void s5pc100_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
extern void s5pv210_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
-extern void s5p6440_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
+extern void s5p64x0_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
extern void s5p6442_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
#endif /* __S3C64XX_PLAT_SPI_H */
diff --git a/arch/arm/plat-spear/include/plat/debug-macro.S b/arch/arm/plat-spear/include/plat/debug-macro.S
index 37fa593884ee..e91270e4f640 100644
--- a/arch/arm/plat-spear/include/plat/debug-macro.S
+++ b/arch/arm/plat-spear/include/plat/debug-macro.S
@@ -14,11 +14,9 @@
#include <linux/amba/serial.h>
#include <mach/spear.h>
- .macro addruart, rx
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- moveq \rx, #SPEAR_DBG_UART_BASE @ Physical base
- movne \rx, #VA_SPEAR_DBG_UART_BASE @ Virtual base
+ .macro addruart, rp, rv
+ mov \rp, #SPEAR_DBG_UART_BASE @ Physical base
+ mov \rv, #VA_SPEAR_DBG_UART_BASE @ Virtual base
.endm
.macro senduart, rd, rx
diff --git a/arch/arm/plat-stmp3xxx/include/mach/debug-macro.S b/arch/arm/plat-stmp3xxx/include/mach/debug-macro.S
index 1b9348bf0e49..d3a0985c9681 100644
--- a/arch/arm/plat-stmp3xxx/include/mach/debug-macro.S
+++ b/arch/arm/plat-stmp3xxx/include/mach/debug-macro.S
@@ -16,13 +16,10 @@
* http://www.gnu.org/copyleft/gpl.html
*/
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- moveq \rx, #0x80000000 @ physical base address
- addeq \rx, \rx, #0x00070000
- movne \rx, #0xf0000000 @ virtual base
- addne \rx, \rx, #0x00070000
+ .macro addruart, rp, rv
+ mov \rp, #0x00070000
+ add \rv, \rp, #0xf0000000 @ virtual base
+ add \rp, \rp, #0x80000000 @ physical base
.endm
.macro senduart,rd,rx
diff --git a/arch/arm/plat-tcc/Kconfig b/arch/arm/plat-tcc/Kconfig
new file mode 100644
index 000000000000..1bf499570f42
--- /dev/null
+++ b/arch/arm/plat-tcc/Kconfig
@@ -0,0 +1,20 @@
+if ARCH_TCC_926
+
+menu "Telechips ARM926-based CPUs"
+
+choice
+ prompt "Telechips CPU type:"
+ default ARCH_TCC8K
+
+config ARCH_TCC8K
+ bool TCC8000
+ select USB_ARCH_HAS_OHCI
+ help
+ Support for Telechips TCC8000 systems
+
+endchoice
+
+source "arch/arm/mach-tcc8k/Kconfig"
+
+endmenu
+endif
diff --git a/arch/arm/plat-tcc/Makefile b/arch/arm/plat-tcc/Makefile
new file mode 100644
index 000000000000..eceabc869b8f
--- /dev/null
+++ b/arch/arm/plat-tcc/Makefile
@@ -0,0 +1,3 @@
+# "Telechips Platform Common Modules"
+
+obj-y := clock.o system.o
diff --git a/arch/arm/plat-tcc/clock.c b/arch/arm/plat-tcc/clock.c
new file mode 100644
index 000000000000..f3ced10d5271
--- /dev/null
+++ b/arch/arm/plat-tcc/clock.c
@@ -0,0 +1,179 @@
+/*
+ * Clock framework for Telechips SoCs
+ * Based on arch/arm/plat-mxc/clock.c
+ *
+ * Copyright (C) 2004 - 2005 Nokia corporation
+ * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ * Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ * Copyright 2010 Hans J. Koch, hjk@linutronix.de
+ *
+ * Licensed under the terms of the GPL v2.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/string.h>
+
+#include <mach/clock.h>
+#include <mach/hardware.h>
+
+static DEFINE_MUTEX(clocks_mutex);
+
+/*-------------------------------------------------------------------------
+ * Standard clock functions defined in include/linux/clk.h
+ *-------------------------------------------------------------------------*/
+
+static void __clk_disable(struct clk *clk)
+{
+ BUG_ON(clk->refcount == 0);
+
+ if (!(--clk->refcount) && clk->disable) {
+ /* Unconditionally disable the clock in hardware */
+ clk->disable(clk);
+ /* recursively disable parents */
+ if (clk->parent)
+ __clk_disable(clk->parent);
+ }
+}
+
+static int __clk_enable(struct clk *clk)
+{
+ int ret = 0;
+
+ if (clk->refcount++ == 0 && clk->enable) {
+ if (clk->parent)
+ ret = __clk_enable(clk->parent);
+ if (ret)
+ return ret;
+ else
+ return clk->enable(clk);
+ }
+
+ return 0;
+}
+
+/* This function increments the reference count on the clock and enables the
+ * clock if not already enabled. The parent clock tree is recursively enabled
+ */
+int clk_enable(struct clk *clk)
+{
+ int ret = 0;
+
+ if (!clk)
+ return -EINVAL;
+
+ mutex_lock(&clocks_mutex);
+ ret = __clk_enable(clk);
+ mutex_unlock(&clocks_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(clk_enable);
+
+/* This function decrements the reference count on the clock and disables
+ * the clock when reference count is 0. The parent clock tree is
+ * recursively disabled
+ */
+void clk_disable(struct clk *clk)
+{
+ if (!clk)
+ return;
+
+ mutex_lock(&clocks_mutex);
+ __clk_disable(clk);
+ mutex_unlock(&clocks_mutex);
+}
+EXPORT_SYMBOL_GPL(clk_disable);
+
+/* Retrieve the *current* clock rate. If the clock itself
+ * does not provide a special calculation routine, ask
+ * its parent and so on, until one is able to return
+ * a valid clock rate
+ */
+unsigned long clk_get_rate(struct clk *clk)
+{
+ if (!clk)
+ return 0UL;
+
+ if (clk->get_rate)
+ return clk->get_rate(clk);
+
+ return clk_get_rate(clk->parent);
+}
+EXPORT_SYMBOL_GPL(clk_get_rate);
+
+/* Round the requested clock rate to the nearest supported
+ * rate that is less than or equal to the requested rate.
+ * This is dependent on the clock's current parent.
+ */
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ if (!clk)
+ return 0;
+ if (!clk->round_rate)
+ return 0;
+
+ return clk->round_rate(clk, rate);
+}
+EXPORT_SYMBOL_GPL(clk_round_rate);
+
+/* Set the clock to the requested clock rate. The rate must
+ * match a supported rate exactly based on what clk_round_rate returns
+ */
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret = -EINVAL;
+
+ if (!clk)
+ return ret;
+ if (!clk->set_rate || !rate)
+ return ret;
+
+ mutex_lock(&clocks_mutex);
+ ret = clk->set_rate(clk, rate);
+ mutex_unlock(&clocks_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(clk_set_rate);
+
+/* Set the clock's parent to another clock source */
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ struct clk *old;
+ int ret = -EINVAL;
+
+ if (!clk)
+ return ret;
+ if (!clk->set_parent || !parent)
+ return ret;
+
+ mutex_lock(&clocks_mutex);
+ old = clk->parent;
+ if (clk->refcount)
+ __clk_enable(parent);
+ ret = clk->set_parent(clk, parent);
+ if (ret)
+ old = parent;
+ if (clk->refcount)
+ __clk_disable(old);
+ mutex_unlock(&clocks_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(clk_set_parent);
+
+/* Retrieve the clock's parent clock source */
+struct clk *clk_get_parent(struct clk *clk)
+{
+ if (!clk)
+ return NULL;
+
+ return clk->parent;
+}
+EXPORT_SYMBOL_GPL(clk_get_parent);
diff --git a/arch/arm/plat-tcc/include/mach/clkdev.h b/arch/arm/plat-tcc/include/mach/clkdev.h
new file mode 100644
index 000000000000..04b37a89801c
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/plat-tcc/include/mach/clock.h b/arch/arm/plat-tcc/include/mach/clock.h
new file mode 100644
index 000000000000..a12f58ad71a8
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/clock.h
@@ -0,0 +1,48 @@
+/*
+ * Low level clock header file for Telechips TCC architecture
+ * (C) 2010 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the GPL v2.
+ */
+
+#ifndef __ASM_ARCH_TCC_CLOCK_H__
+#define __ASM_ARCH_TCC_CLOCK_H__
+
+#ifndef __ASSEMBLY__
+
+struct clk {
+ struct clk *parent;
+ /* id number of a root clock, 0 for normal clocks */
+ int root_id;
+ /* Reference count of clock enable/disable */
+ int refcount;
+ /* Address of associated BCLKCTRx register. Must be set. */
+ void __iomem *bclkctr;
+ /* Bit position for BCLKCTRx. Must be set. */
+ int bclk_shift;
+ /* Address of ACLKxxx register, if any. */
+ void __iomem *aclkreg;
+ /* get the current clock rate (always a fresh value) */
+ unsigned long (*get_rate) (struct clk *);
+ /* Function ptr to set the clock to a new rate. The rate must match a
+ supported rate returned from round_rate. Leave blank if clock is not
+ programmable */
+ int (*set_rate) (struct clk *, unsigned long);
+ /* Function ptr to round the requested clock rate to the nearest
+ supported rate that is less than or equal to the requested rate. */
+ unsigned long (*round_rate) (struct clk *, unsigned long);
+ /* Function ptr to enable the clock. Leave blank if clock can not
+ be gated. */
+ int (*enable) (struct clk *);
+ /* Function ptr to disable the clock. Leave blank if clock can not
+ be gated. */
+ void (*disable) (struct clk *);
+ /* Function ptr to set the parent clock of the clock. */
+ int (*set_parent) (struct clk *, struct clk *);
+};
+
+int clk_register(struct clk *clk);
+void clk_unregister(struct clk *clk);
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ASM_ARCH_MXC_CLOCK_H__ */
diff --git a/arch/arm/plat-tcc/include/mach/debug-macro.S b/arch/arm/plat-tcc/include/mach/debug-macro.S
new file mode 100644
index 000000000000..7662f736e42b
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/debug-macro.S
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 1994-1999 Russell King
+ * Copyright (C) 2008-2009 Telechips
+ * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+ .macro addruart, rp, rv
+ moveq \rp, #0x90000000 @ physical base address
+ movne \rv, #0xF1000000 @ virtual base
+ orr \rp, \rp, #0x00007000 @ UART0
+ orr \rv, \rv, #0x00007000 @ UART0
+ .endm
+
+ .macro senduart,rd,rx
+ strb \rd, [\rx, #0x44]
+ .endm
+
+ .macro waituart,rd,rx
+ .endm
+
+ .macro busyuart,rd,rx
+1001:
+ ldr \rd, [\rx, #0x14]
+ tst \rd, #0x20
+
+ beq 1001b
+ .endm
diff --git a/arch/arm/plat-tcc/include/mach/entry-macro.S b/arch/arm/plat-tcc/include/mach/entry-macro.S
new file mode 100644
index 000000000000..748f401e4b6d
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/entry-macro.S
@@ -0,0 +1,68 @@
+/*
+ * include/asm-arm/arch-tcc83x/entry-macro.S
+ *
+ * Author : <linux@telechips.com>
+ * Created: June 10, 2008
+ * Description: Low-level IRQ helper macros for Telechips-based platforms
+ *
+ * Copyright (C) 2008-2009 Telechips
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+ ldr \base, =0xF2003000 @ base address of PIC registers
+
+ @@ read MREQ register of PIC0
+
+ mov \irqnr, #0
+ ldr \irqstat, [\base, #0x00000014 ] @ lower 32 interrupts
+ cmp \irqstat, #0
+ bne 1001f
+
+ @@ read MREQ register of PIC1
+
+ ldr \irqstat, [\base, #0x00000094] @ upper 32 interrupts
+ cmp \irqstat, #0
+ beq 1002f
+ mov \irqnr, #0x20
+
+1001:
+ movs \tmp, \irqstat, lsl #16
+ movne \irqstat, \tmp
+ addeq \irqnr, \irqnr, #16
+
+ movs \tmp, \irqstat, lsl #8
+ movne \irqstat, \tmp
+ addeq \irqnr, \irqnr, #8
+
+ movs \tmp, \irqstat, lsl #4
+ movne \irqstat, \tmp
+ addeq \irqnr, \irqnr, #4
+
+ movs \tmp, \irqstat, lsl #2
+ movne \irqstat, \tmp
+ addeq \irqnr, \irqnr, #2
+
+ movs \tmp, \irqstat, lsl #1
+ addeq \irqnr, \irqnr, #1
+ orrs \base, \base, #1
+1002:
+ @@ exit here, Z flag unset if IRQ
+
+ .endm
diff --git a/arch/arm/plat-tcc/include/mach/hardware.h b/arch/arm/plat-tcc/include/mach/hardware.h
new file mode 100644
index 000000000000..e70d126ccaf3
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/hardware.h
@@ -0,0 +1,43 @@
+/*
+ * Author: RidgeRun, Inc. Greg Lonnon <glonnon@ridgerun.com>
+ * Reorganized for Linux-2.6 by Tony Lindgren <tony@atomide.com>
+ * and Dirk Behme <dirk.behme@de.bosch.com>
+ * Rewritten by: <linux@telechips.com>
+ * Description: Hardware definitions for TCC8300 processors and boards
+ *
+ * Copyright (C) 2001 RidgeRun, Inc.
+ * Copyright (C) 2008-2009 Telechips
+ *
+ * Modifications for mainline (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GNU Pulic License version 2.
+ */
+
+#ifndef __ASM_ARCH_TCC_HARDWARE_H
+#define __ASM_ARCH_TCC_HARDWARE_H
+
+#include <asm/sizes.h>
+#ifndef __ASSEMBLER__
+#include <asm/types.h>
+#endif
+#include <mach/io.h>
+
+/*
+ * ----------------------------------------------------------------------------
+ * Clocks
+ * ----------------------------------------------------------------------------
+ */
+#define CLKGEN_REG_BASE 0xfffece00
+#define ARM_CKCTL (CLKGEN_REG_BASE + 0x0)
+#define ARM_IDLECT1 (CLKGEN_REG_BASE + 0x4)
+#define ARM_IDLECT2 (CLKGEN_REG_BASE + 0x8)
+#define ARM_EWUPCT (CLKGEN_REG_BASE + 0xC)
+#define ARM_RSTCT1 (CLKGEN_REG_BASE + 0x10)
+#define ARM_RSTCT2 (CLKGEN_REG_BASE + 0x14)
+#define ARM_SYSST (CLKGEN_REG_BASE + 0x18)
+#define ARM_IDLECT3 (CLKGEN_REG_BASE + 0x24)
+
+/* DPLL control registers */
+#define DPLL_CTL 0xfffecf00
+
+#endif /* __ASM_ARCH_TCC_HARDWARE_H */
diff --git a/arch/arm/plat-tcc/include/mach/io.h b/arch/arm/plat-tcc/include/mach/io.h
new file mode 100644
index 000000000000..3e911d3ea0f1
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/io.h
@@ -0,0 +1,23 @@
+/*
+ * IO definitions for TCC8000 processors and boards
+ *
+ * Copyright (C) 1997-1999 Russell King
+ * Copyright (C) 2008-2009 Telechips
+ * Copyright (C) 2010 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GNU Public License version 2.
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * We don't actually have real ISA nor PCI buses, but there is so many
+ * drivers out there that might just work if we fake them...
+ */
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#endif
diff --git a/arch/arm/plat-tcc/include/mach/irqs.h b/arch/arm/plat-tcc/include/mach/irqs.h
new file mode 100644
index 000000000000..da863894d498
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/irqs.h
@@ -0,0 +1,83 @@
+/*
+ * IRQ definitions for TCC8xxx
+ *
+ * Copyright (C) 2008-2009 Telechips
+ * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GPL v2.
+ *
+ */
+
+#ifndef __ASM_ARCH_TCC_IRQS_H
+#define __ASM_ARCH_TCC_IRQS_H
+
+#define NR_IRQS 64
+
+/* PIC0 interrupts */
+#define INT_ADMA1 0
+#define INT_BDMA 1
+#define INT_ADMA0 2
+#define INT_GDMA1 3
+#define INT_I2S0RX 4
+#define INT_I2S0TX 5
+#define INT_TC 6
+#define INT_UART0 7
+#define INT_USBD 8
+#define INT_SPI0TX 9
+#define INT_UDMA 10
+#define INT_LIRQ 11
+#define INT_GDMA2 12
+#define INT_GDMA0 13
+#define INT_TC32 14
+#define INT_LCD 15
+#define INT_ADC 16
+#define INT_I2C 17
+#define INT_RTCP 18
+#define INT_RTCA 19
+#define INT_NFC 20
+#define INT_SD0 21
+#define INT_GSB0 22
+#define INT_PK 23
+#define INT_USBH0 24
+#define INT_USBH1 25
+#define INT_G2D 26
+#define INT_ECC 27
+#define INT_SPI0RX 28
+#define INT_UART1 29
+#define INT_MSCL 30
+#define INT_GSB1 31
+/* PIC1 interrupts */
+#define INT_E0 32
+#define INT_E1 33
+#define INT_E2 34
+#define INT_E3 35
+#define INT_E4 36
+#define INT_E5 37
+#define INT_E6 38
+#define INT_E7 39
+#define INT_UART2 40
+#define INT_UART3 41
+#define INT_SPI1TX 42
+#define INT_SPI1RX 43
+#define INT_GSB2 44
+#define INT_SPDIF 45
+#define INT_CDIF 46
+#define INT_VBON 47
+#define INT_VBOFF 48
+#define INT_SD1 49
+#define INT_UART4 50
+#define INT_GDMA3 51
+#define INT_I2S1RX 52
+#define INT_I2S1TX 53
+#define INT_CAN0 54
+#define INT_CAN1 55
+#define INT_GSB3 56
+#define INT_KRST 57
+#define INT_UNUSED 58
+#define INT_SD0D3 59
+#define INT_SD1D3 60
+#define INT_GPS0 61
+#define INT_GPS1 62
+#define INT_GPS2 63
+
+#endif /* ASM_ARCH_TCC_IRQS_H */
diff --git a/arch/arm/plat-tcc/include/mach/memory.h b/arch/arm/plat-tcc/include/mach/memory.h
new file mode 100644
index 000000000000..cd91ba8a670b
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/memory.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Copyright (C) 2008-2009 Telechips
+ * Copyright (C) 2010 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GPL v2.
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#define PHYS_OFFSET UL(0x20000000)
+
+#endif
diff --git a/arch/arm/plat-tcc/include/mach/system.h b/arch/arm/plat-tcc/include/mach/system.h
new file mode 100644
index 000000000000..909e6035d843
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/system.h
@@ -0,0 +1,31 @@
+/*
+ * Author: <linux@telechips.com>
+ * Created: June 10, 2008
+ * Description: LINUX SYSTEM FUNCTIONS for TCC83x
+ *
+ * Copyright (C) 2008-2009 Telechips
+ *
+ * Licensed under the terms of the GPL v2.
+ *
+ */
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+#include <linux/clk.h>
+
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+
+extern void plat_tcc_reboot(void);
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ plat_tcc_reboot();
+}
+
+#endif
diff --git a/arch/arm/plat-tcc/include/mach/tcc8k-regs.h b/arch/arm/plat-tcc/include/mach/tcc8k-regs.h
new file mode 100644
index 000000000000..1d9428295332
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/tcc8k-regs.h
@@ -0,0 +1,807 @@
+/*
+ * Telechips TCC8000 register definitions
+ *
+ * (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GPLv2.
+ */
+
+#ifndef TCC8K_REGS_H
+#define TCC8K_REGS_H
+
+#include <linux/types.h>
+
+#define EXT_SDRAM_BASE 0x20000000
+#define INT_SRAM_BASE 0x30000000
+#define INT_SRAM_SIZE SZ_32K
+#define CS0_BASE 0x40000000
+#define CS1_BASE 0x50000000
+#define CS1_SIZE SZ_64K
+#define CS2_BASE 0x60000000
+#define CS3_BASE 0x70000000
+#define AHB_PERI_BASE 0x80000000
+#define AHB_PERI_SIZE SZ_64K
+#define APB0_PERI_BASE 0x90000000
+#define APB0_PERI_SIZE SZ_128K
+#define APB1_PERI_BASE 0x98000000
+#define APB1_PERI_SIZE SZ_128K
+#define DATA_TCM_BASE 0xa0000000
+#define DATA_TCM_SIZE SZ_8K
+#define EXT_MEM_CTRL_BASE 0xf0000000
+#define EXT_MEM_CTRL_SIZE SZ_4K
+
+#define CS1_BASE_VIRT (void __iomem *)0xf7000000
+#define AHB_PERI_BASE_VIRT (void __iomem *)0xf4000000
+#define APB0_PERI_BASE_VIRT (void __iomem *)0xf1000000
+#define APB1_PERI_BASE_VIRT (void __iomem *)0xf2000000
+#define EXT_MEM_CTRL_BASE_VIRT (void __iomem *)0xf3000000
+#define INT_SRAM_BASE_VIRT (void __iomem *)0xf5000000
+#define DATA_TCM_BASE_VIRT (void __iomem *)0xf6000000
+
+#define __REG(x) (*((volatile u32 *)(x)))
+
+/* USB Device Controller Registers */
+#define UDC_BASE (AHB_PERI_BASE_VIRT + 0x8000)
+#define UDC_BASE_PHYS (AHB_PERI_BASE + 0x8000)
+
+#define UDC_IR_OFFS 0x00
+#define UDC_EIR_OFFS 0x04
+#define UDC_EIER_OFFS 0x08
+#define UDC_FAR_OFFS 0x0c
+#define UDC_FNR_OFFS 0x10
+#define UDC_EDR_OFFS 0x14
+#define UDC_RT_OFFS 0x18
+#define UDC_SSR_OFFS 0x1c
+#define UDC_SCR_OFFS 0x20
+#define UDC_EP0SR_OFFS 0x24
+#define UDC_EP0CR_OFFS 0x28
+
+#define UDC_ESR_OFFS 0x2c
+#define UDC_ECR_OFFS 0x30
+#define UDC_BRCR_OFFS 0x34
+#define UDC_BWCR_OFFS 0x38
+#define UDC_MPR_OFFS 0x3c
+#define UDC_DCR_OFFS 0x40
+#define UDC_DTCR_OFFS 0x44
+#define UDC_DFCR_OFFS 0x48
+#define UDC_DTTCR1_OFFS 0x4c
+#define UDC_DTTCR2_OFFS 0x50
+#define UDC_ESR2_OFFS 0x54
+
+#define UDC_SCR2_OFFS 0x58
+#define UDC_EP0BUF_OFFS 0x60
+#define UDC_EP1BUF_OFFS 0x64
+#define UDC_EP2BUF_OFFS 0x68
+#define UDC_EP3BUF_OFFS 0x6c
+#define UDC_PLICR_OFFS 0xa0
+#define UDC_PCR_OFFS 0xa4
+
+#define UDC_UPCR0_OFFS 0xc8
+#define UDC_UPCR1_OFFS 0xcc
+#define UDC_UPCR2_OFFS 0xd0
+#define UDC_UPCR3_OFFS 0xd4
+
+/* Bits in UDC_EIR */
+#define UDC_EIR_EP0I (1 << 0)
+#define UDC_EIR_EP1I (1 << 1)
+#define UDC_EIR_EP2I (1 << 2)
+#define UDC_EIR_EP3I (1 << 3)
+#define UDC_EIR_EPI_MASK 0x0f
+
+/* Bits in UDC_EIER */
+#define UDC_EIER_EP0IE (1 << 0)
+#define UDC_EIER_EP1IE (1 << 1)
+#define UDC_EIER_EP2IE (1 << 2)
+#define UDC_EIER_EP3IE (1 << 3)
+
+/* Bits in UDC_FNR */
+#define UDC_FNR_FN_MASK 0x7ff
+#define UDC_FNR_SM (1 << 13)
+#define UDC_FNR_FTL (1 << 14)
+
+/* Bits in UDC_SSR */
+#define UDC_SSR_HFRES (1 << 0)
+#define UDC_SSR_HFSUSP (1 << 1)
+#define UDC_SSR_HFRM (1 << 2)
+#define UDC_SSR_SDE (1 << 3)
+#define UDC_SSR_HSP (1 << 4)
+#define UDC_SSR_DM (1 << 5)
+#define UDC_SSR_DP (1 << 6)
+#define UDC_SSR_TBM (1 << 7)
+#define UDC_SSR_VBON (1 << 8)
+#define UDC_SSR_VBOFF (1 << 9)
+#define UDC_SSR_EOERR (1 << 10)
+#define UDC_SSR_DCERR (1 << 11)
+#define UDC_SSR_TCERR (1 << 12)
+#define UDC_SSR_BSERR (1 << 13)
+#define UDC_SSR_TMERR (1 << 14)
+#define UDC_SSR_BAERR (1 << 15)
+
+/* Bits in UDC_SCR */
+#define UDC_SCR_HRESE (1 << 0)
+#define UDC_SCR_HSSPE (1 << 1)
+#define UDC_SCR_RRDE (1 << 5)
+#define UDC_SCR_SPDEN (1 << 6)
+#define UDC_SCR_DIEN (1 << 12)
+
+/* Bits in UDC_EP0SR */
+#define UDC_EP0SR_RSR (1 << 0)
+#define UDC_EP0SR_TST (1 << 1)
+#define UDC_EP0SR_SHT (1 << 4)
+#define UDC_EP0SR_LWO (1 << 6)
+
+/* Bits in UDC_EP0CR */
+#define UDC_EP0CR_ESS (1 << 1)
+
+/* Bits in UDC_ESR */
+#define UDC_ESR_RPS (1 << 0)
+#define UDC_ESR_TPS (1 << 1)
+#define UDC_ESR_LWO (1 << 4)
+#define UDC_ESR_FFS (1 << 6)
+
+/* Bits in UDC_ECR */
+#define UDC_ECR_ESS (1 << 1)
+#define UDC_ECR_CDP (1 << 2)
+
+#define UDC_ECR_FLUSH (1 << 6)
+#define UDC_ECR_DUEN (1 << 7)
+
+/* Bits in UDC_UPCR0 */
+#define UDC_UPCR0_VBD (1 << 1)
+#define UDC_UPCR0_VBDS (1 << 6)
+#define UDC_UPCR0_RCD_12 (0x0 << 9)
+#define UDC_UPCR0_RCD_24 (0x1 << 9)
+#define UDC_UPCR0_RCD_48 (0x2 << 9)
+#define UDC_UPCR0_RCS_EXT (0x1 << 11)
+#define UDC_UPCR0_RCS_XTAL (0x0 << 11)
+
+/* Bits in UDC_UPCR1 */
+#define UDC_UPCR1_CDT(x) ((x) << 0)
+#define UDC_UPCR1_OTGT(x) ((x) << 3)
+#define UDC_UPCR1_SQRXT(x) ((x) << 8)
+#define UDC_UPCR1_TXFSLST(x) ((x) << 12)
+
+/* Bits in UDC_UPCR2 */
+#define UDC_UPCR2_TP (1 << 0)
+#define UDC_UPCR2_TXRT(x) ((x) << 2)
+#define UDC_UPCR2_TXVRT(x) ((x) << 5)
+#define UDC_UPCR2_OPMODE(x) ((x) << 9)
+#define UDC_UPCR2_XCVRSEL(x) ((x) << 12)
+#define UDC_UPCR2_TM (1 << 14)
+
+/* USB Host Controller registers */
+#define USBH0_BASE (AHB_PERI_BASE_VIRT + 0xb000)
+#define USBH1_BASE (AHB_PERI_BASE_VIRT + 0xb800)
+
+#define OHCI_INT_ENABLE_OFFS 0x10
+
+#define RH_DESCRIPTOR_A_OFFS 0x48
+#define RH_DESCRIPTOR_B_OFFS 0x4c
+
+#define USBHTCFG0_OFFS 0x100
+#define USBHHCFG0_OFFS 0x104
+#define USBHHCFG1_OFFS 0x104
+
+/* DMA controller registers */
+#define DMAC0_BASE (AHB_PERI_BASE + 0x4000)
+#define DMAC1_BASE (AHB_PERI_BASE + 0xa000)
+#define DMAC2_BASE (AHB_PERI_BASE + 0x4800)
+#define DMAC3_BASE (AHB_PERI_BASE + 0xa800)
+
+#define DMAC_CH_OFFSET(ch) (ch * 0x30)
+
+#define ST_SADR_OFFS 0x00
+#define SPARAM_OFFS 0x04
+#define C_SADR_OFFS 0x0c
+#define ST_DADR_OFFS 0x10
+#define DPARAM_OFFS 0x14
+#define C_DADR_OFFS 0x1c
+#define HCOUNT_OFFS 0x20
+#define CHCTRL_OFFS 0x24
+#define RPTCTRL_OFFS 0x28
+#define EXTREQ_A_OFFS 0x2c
+
+/* Bits in CHCTRL register */
+#define CHCTRL_EN (1 << 0)
+
+#define CHCTRL_IEN (1 << 2)
+#define CHCTRL_FLAG (1 << 3)
+#define CHCTRL_WSIZE8 (0 << 4)
+#define CHCTRL_WSIZE16 (1 << 4)
+#define CHCTRL_WSIZE32 (2 << 4)
+
+#define CHCTRL_BSIZE1 (0 << 6)
+#define CHCTRL_BSIZE2 (1 << 6)
+#define CHCTRL_BSIZE4 (2 << 6)
+#define CHCTRL_BSIZE8 (3 << 6)
+
+#define CHCTRL_TYPE_SINGLE_E (0 << 8)
+#define CHCTRL_TYPE_HW (1 << 8)
+#define CHCTRL_TYPE_SW (2 << 8)
+#define CHCTRL_TYPE_SINGLE_L (3 << 8)
+
+#define CHCTRL_BST (1 << 10)
+
+/* Use DMA controller 0, channel 2 for USB */
+#define USB_DMA_BASE (DMAC0_BASE + DMAC_CH_OFFSET(2))
+
+/* NAND flash controller registers */
+#define NFC_BASE (AHB_PERI_BASE_VIRT + 0xd000)
+#define NFC_BASE_PHYS (AHB_PERI_BASE + 0xd000)
+
+#define NFC_CMD_OFFS 0x00
+#define NFC_LADDR_OFFS 0x04
+#define NFC_BADDR_OFFS 0x08
+#define NFC_SADDR_OFFS 0x0c
+#define NFC_WDATA_OFFS 0x10
+#define NFC_LDATA_OFFS 0x20
+#define NFC_SDATA_OFFS 0x40
+#define NFC_CTRL_OFFS 0x50
+#define NFC_PSTART_OFFS 0x54
+#define NFC_RSTART_OFFS 0x58
+#define NFC_DSIZE_OFFS 0x5c
+#define NFC_IREQ_OFFS 0x60
+#define NFC_RST_OFFS 0x64
+#define NFC_CTRL1_OFFS 0x68
+#define NFC_MDATA_OFFS 0x70
+
+#define NFC_WDATA_PHYS_ADDR (NFC_BASE_PHYS + NFC_WDATA_OFFS)
+
+/* Bits in NFC_CTRL */
+#define NFC_CTRL_BHLD_MASK (0xf << 0)
+#define NFC_CTRL_BPW_MASK (0xf << 4)
+#define NFC_CTRL_BSTP_MASK (0xf << 8)
+#define NFC_CTRL_CADDR_MASK (0x7 << 12)
+#define NFC_CTRL_CADDR_1 (0x0 << 12)
+#define NFC_CTRL_CADDR_2 (0x1 << 12)
+#define NFC_CTRL_CADDR_3 (0x2 << 12)
+#define NFC_CTRL_CADDR_4 (0x3 << 12)
+#define NFC_CTRL_CADDR_5 (0x4 << 12)
+#define NFC_CTRL_MSK (1 << 15)
+#define NFC_CTRL_PSIZE256 (0 << 16)
+#define NFC_CTRL_PSIZE512 (1 << 16)
+#define NFC_CTRL_PSIZE1024 (2 << 16)
+#define NFC_CTRL_PSIZE2048 (3 << 16)
+#define NFC_CTRL_PSIZE4096 (4 << 16)
+#define NFC_CTRL_PSIZE_MASK (7 << 16)
+#define NFC_CTRL_BSIZE1 (0 << 19)
+#define NFC_CTRL_BSIZE2 (1 << 19)
+#define NFC_CTRL_BSIZE4 (2 << 19)
+#define NFC_CTRL_BSIZE8 (3 << 19)
+#define NFC_CTRL_BSIZE_MASK (3 << 19)
+#define NFC_CTRL_RDY (1 << 21)
+#define NFC_CTRL_CS0SEL (1 << 22)
+#define NFC_CTRL_CS1SEL (1 << 23)
+#define NFC_CTRL_CS2SEL (1 << 24)
+#define NFC_CTRL_CS3SEL (1 << 25)
+#define NFC_CTRL_CSMASK (0xf << 22)
+#define NFC_CTRL_BW (1 << 26)
+#define NFC_CTRL_FS (1 << 27)
+#define NFC_CTRL_DEN (1 << 28)
+#define NFC_CTRL_READ_IEN (1 << 29)
+#define NFC_CTRL_PROG_IEN (1 << 30)
+#define NFC_CTRL_RDY_IEN (1 << 31)
+
+/* Bits in NFC_IREQ */
+#define NFC_IREQ_IRQ0 (1 << 0)
+#define NFC_IREQ_IRQ1 (1 << 1)
+#define NFC_IREQ_IRQ2 (1 << 2)
+
+#define NFC_IREQ_FLAG0 (1 << 4)
+#define NFC_IREQ_FLAG1 (1 << 5)
+#define NFC_IREQ_FLAG2 (1 << 6)
+
+/* MMC controller registers */
+#define MMC0_BASE (AHB_PERI_BASE_VIRT + 0xe000)
+#define MMC1_BASE (AHB_PERI_BASE_VIRT + 0xe800)
+
+/* UART base addresses */
+
+#define UART0_BASE (APB0_PERI_BASE_VIRT + 0x07000)
+#define UART0_BASE_PHYS (APB0_PERI_BASE + 0x07000)
+#define UART1_BASE (APB0_PERI_BASE_VIRT + 0x08000)
+#define UART1_BASE_PHYS (APB0_PERI_BASE + 0x08000)
+#define UART2_BASE (APB0_PERI_BASE_VIRT + 0x09000)
+#define UART2_BASE_PHYS (APB0_PERI_BASE + 0x09000)
+#define UART3_BASE (APB0_PERI_BASE_VIRT + 0x0a000)
+#define UART3_BASE_PHYS (APB0_PERI_BASE + 0x0a000)
+#define UART4_BASE (APB0_PERI_BASE_VIRT + 0x15000)
+#define UART4_BASE_PHYS (APB0_PERI_BASE + 0x15000)
+
+#define UART_BASE UART0_BASE
+#define UART_BASE_PHYS UART0_BASE_PHYS
+
+/* ECC controller */
+#define ECC_CTR_BASE (APB0_PERI_BASE_VIRT + 0xd000)
+
+#define ECC_CTRL_OFFS 0x00
+#define ECC_BASE_OFFS 0x04
+#define ECC_MASK_OFFS 0x08
+#define ECC_CLEAR_OFFS 0x0c
+#define ECC4_0_OFFS 0x10
+#define ECC4_1_OFFS 0x14
+
+#define ECC_EADDR0_OFFS 0x50
+
+#define ECC_ERRNUM_OFFS 0x90
+#define ECC_IREQ_OFFS 0x94
+
+/* Bits in ECC_CTRL */
+#define ECC_CTRL_ECC4_DIEN (1 << 28)
+#define ECC_CTRL_ECC8_DIEN (1 << 29)
+#define ECC_CTRL_ECC12_DIEN (1 << 30)
+#define ECC_CTRL_ECC_DISABLE 0x0
+#define ECC_CTRL_ECC_SLC_ENC 0x8
+#define ECC_CTRL_ECC_SLC_DEC 0x9
+#define ECC_CTRL_ECC4_ENC 0xa
+#define ECC_CTRL_ECC4_DEC 0xb
+#define ECC_CTRL_ECC8_ENC 0xc
+#define ECC_CTRL_ECC8_DEC 0xd
+#define ECC_CTRL_ECC12_ENC 0xe
+#define ECC_CTRL_ECC12_DEC 0xf
+
+/* Bits in ECC_IREQ */
+#define ECC_IREQ_E4DI (1 << 4)
+
+#define ECC_IREQ_E4DF (1 << 20)
+#define ECC_IREQ_E4EF (1 << 21)
+
+/* Interrupt controller */
+
+#define PIC0_BASE (APB1_PERI_BASE_VIRT + 0x3000)
+#define PIC0_BASE_PHYS (APB1_PERI_BASE + 0x3000)
+
+#define PIC0_IEN_OFFS 0x00
+#define PIC0_CREQ_OFFS 0x04
+#define PIC0_IREQ_OFFS 0x08
+#define PIC0_IRQSEL_OFFS 0x0c
+#define PIC0_SRC_OFFS 0x10
+#define PIC0_MREQ_OFFS 0x14
+#define PIC0_TSTREQ_OFFS 0x18
+#define PIC0_POL_OFFS 0x1c
+#define PIC0_IRQ_OFFS 0x20
+#define PIC0_FIQ_OFFS 0x24
+#define PIC0_MIRQ_OFFS 0x28
+#define PIC0_MFIQ_OFFS 0x2c
+#define PIC0_TMODE_OFFS 0x30
+#define PIC0_SYNC_OFFS 0x34
+#define PIC0_WKUP_OFFS 0x38
+#define PIC0_TMODEA_OFFS 0x3c
+#define PIC0_INTOEN_OFFS 0x40
+#define PIC0_MEN0_OFFS 0x44
+#define PIC0_MEN_OFFS 0x48
+
+#define PIC0_IEN __REG(PIC0_BASE + PIC0_IEN_OFFS)
+#define PIC0_IEN_PHYS __REG(PIC0_BASE_PHYS + PIC0_IEN_OFFS)
+#define PIC0_CREQ __REG(PIC0_BASE + PIC0_CREQ_OFFS)
+#define PIC0_CREQ_PHYS __REG(PIC0_BASE_PHYS + PIC0_CREQ_OFFS)
+#define PIC0_IREQ __REG(PIC0_BASE + PIC0_IREQ_OFFS)
+#define PIC0_IRQSEL __REG(PIC0_BASE + PIC0_IRQSEL_OFFS)
+#define PIC0_IRQSEL_PHYS __REG(PIC0_BASE_PHYS + PIC0_IRQSEL_OFFS)
+#define PIC0_SRC __REG(PIC0_BASE + PIC0_SRC_OFFS)
+#define PIC0_MREQ __REG(PIC0_BASE + PIC0_MREQ_OFFS)
+#define PIC0_TSTREQ __REG(PIC0_BASE + PIC0_TSTREQ_OFFS)
+#define PIC0_POL __REG(PIC0_BASE + PIC0_POL_OFFS)
+#define PIC0_IRQ __REG(PIC0_BASE + PIC0_IRQ_OFFS)
+#define PIC0_FIQ __REG(PIC0_BASE + PIC0_FIQ_OFFS)
+#define PIC0_MIRQ __REG(PIC0_BASE + PIC0_MIRQ_OFFS)
+#define PIC0_MFIQ __REG(PIC0_BASE + PIC0_MFIQ_OFFS)
+#define PIC0_TMODE __REG(PIC0_BASE + PIC0_TMODE_OFFS)
+#define PIC0_TMODE_PHYS __REG(PIC0_BASE_PHYS + PIC0_TMODE_OFFS)
+#define PIC0_SYNC __REG(PIC0_BASE + PIC0_SYNC_OFFS)
+#define PIC0_WKUP __REG(PIC0_BASE + PIC0_WKUP_OFFS)
+#define PIC0_TMODEA __REG(PIC0_BASE + PIC0_TMODEA_OFFS)
+#define PIC0_INTOEN __REG(PIC0_BASE + PIC0_INTOEN_OFFS)
+#define PIC0_MEN0 __REG(PIC0_BASE + PIC0_MEN0_OFFS)
+#define PIC0_MEN __REG(PIC0_BASE + PIC0_MEN_OFFS)
+
+#define PIC1_BASE (APB1_PERI_BASE_VIRT + 0x3080)
+
+#define PIC1_IEN_OFFS 0x00
+#define PIC1_CREQ_OFFS 0x04
+#define PIC1_IREQ_OFFS 0x08
+#define PIC1_IRQSEL_OFFS 0x0c
+#define PIC1_SRC_OFFS 0x10
+#define PIC1_MREQ_OFFS 0x14
+#define PIC1_TSTREQ_OFFS 0x18
+#define PIC1_POL_OFFS 0x1c
+#define PIC1_IRQ_OFFS 0x20
+#define PIC1_FIQ_OFFS 0x24
+#define PIC1_MIRQ_OFFS 0x28
+#define PIC1_MFIQ_OFFS 0x2c
+#define PIC1_TMODE_OFFS 0x30
+#define PIC1_SYNC_OFFS 0x34
+#define PIC1_WKUP_OFFS 0x38
+#define PIC1_TMODEA_OFFS 0x3c
+#define PIC1_INTOEN_OFFS 0x40
+#define PIC1_MEN1_OFFS 0x44
+#define PIC1_MEN_OFFS 0x48
+
+#define PIC1_IEN __REG(PIC1_BASE + PIC1_IEN_OFFS)
+#define PIC1_CREQ __REG(PIC1_BASE + PIC1_CREQ_OFFS)
+#define PIC1_IREQ __REG(PIC1_BASE + PIC1_IREQ_OFFS)
+#define PIC1_IRQSEL __REG(PIC1_BASE + PIC1_IRQSEL_OFFS)
+#define PIC1_SRC __REG(PIC1_BASE + PIC1_SRC_OFFS)
+#define PIC1_MREQ __REG(PIC1_BASE + PIC1_MREQ_OFFS)
+#define PIC1_TSTREQ __REG(PIC1_BASE + PIC1_TSTREQ_OFFS)
+#define PIC1_POL __REG(PIC1_BASE + PIC1_POL_OFFS)
+#define PIC1_IRQ __REG(PIC1_BASE + PIC1_IRQ_OFFS)
+#define PIC1_FIQ __REG(PIC1_BASE + PIC1_FIQ_OFFS)
+#define PIC1_MIRQ __REG(PIC1_BASE + PIC1_MIRQ_OFFS)
+#define PIC1_MFIQ __REG(PIC1_BASE + PIC1_MFIQ_OFFS)
+#define PIC1_TMODE __REG(PIC1_BASE + PIC1_TMODE_OFFS)
+#define PIC1_SYNC __REG(PIC1_BASE + PIC1_SYNC_OFFS)
+#define PIC1_WKUP __REG(PIC1_BASE + PIC1_WKUP_OFFS)
+#define PIC1_TMODEA __REG(PIC1_BASE + PIC1_TMODEA_OFFS)
+#define PIC1_INTOEN __REG(PIC1_BASE + PIC1_INTOEN_OFFS)
+#define PIC1_MEN1 __REG(PIC1_BASE + PIC1_MEN1_OFFS)
+#define PIC1_MEN __REG(PIC1_BASE + PIC1_MEN_OFFS)
+
+/* Timer registers */
+#define TIMER_BASE (APB1_PERI_BASE_VIRT + 0x4000)
+#define TIMER_BASE_PHYS (APB1_PERI_BASE + 0x4000)
+
+#define TWDCFG_OFFS 0x70
+
+#define TC32EN_OFFS 0x80
+#define TC32LDV_OFFS 0x84
+#define TC32CMP0_OFFS 0x88
+#define TC32CMP1_OFFS 0x8c
+#define TC32PCNT_OFFS 0x90
+#define TC32MCNT_OFFS 0x94
+#define TC32IRQ_OFFS 0x98
+
+/* Bits in TC32EN */
+#define TC32EN_PRESCALE_MASK 0x00ffffff
+#define TC32EN_ENABLE (1 << 24)
+#define TC32EN_LOADZERO (1 << 25)
+#define TC32EN_STOPMODE (1 << 26)
+#define TC32EN_LDM0 (1 << 28)
+#define TC32EN_LDM1 (1 << 29)
+
+/* Bits in TC32IRQ */
+#define TC32IRQ_MSTAT_MASK 0x0000001f
+#define TC32IRQ_RSTAT_MASK (0x1f << 8)
+#define TC32IRQ_IRQEN0 (1 << 16)
+#define TC32IRQ_IRQEN1 (1 << 17)
+#define TC32IRQ_IRQEN2 (1 << 18)
+#define TC32IRQ_IRQEN3 (1 << 19)
+#define TC32IRQ_IRQEN4 (1 << 20)
+#define TC32IRQ_RSYNC (1 << 30)
+#define TC32IRQ_IRQCLR (1 << 31)
+
+/* GPIO registers */
+#define GPIOPD_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOPD_DAT_OFFS 0x00
+#define GPIOPD_DOE_OFFS 0x04
+#define GPIOPD_FS0_OFFS 0x08
+#define GPIOPD_FS1_OFFS 0x0c
+#define GPIOPD_FS2_OFFS 0x10
+#define GPIOPD_RPU_OFFS 0x30
+#define GPIOPD_RPD_OFFS 0x34
+#define GPIOPD_DV0_OFFS 0x38
+#define GPIOPD_DV1_OFFS 0x3c
+
+#define GPIOPS_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOPS_DAT_OFFS 0x40
+#define GPIOPS_DOE_OFFS 0x44
+#define GPIOPS_FS0_OFFS 0x48
+#define GPIOPS_FS1_OFFS 0x4c
+#define GPIOPS_FS2_OFFS 0x50
+#define GPIOPS_FS3_OFFS 0x54
+#define GPIOPS_RPU_OFFS 0x70
+#define GPIOPS_RPD_OFFS 0x74
+#define GPIOPS_DV0_OFFS 0x78
+#define GPIOPS_DV1_OFFS 0x7c
+
+#define GPIOPS_FS1_SDH0_BITS 0x000000ff
+#define GPIOPS_FS1_SDH1_BITS 0x0000ff00
+
+#define GPIOPU_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOPU_DAT_OFFS 0x80
+#define GPIOPU_DOE_OFFS 0x84
+#define GPIOPU_FS0_OFFS 0x88
+#define GPIOPU_FS1_OFFS 0x8c
+#define GPIOPU_FS2_OFFS 0x90
+#define GPIOPU_RPU_OFFS 0xb0
+#define GPIOPU_RPD_OFFS 0xb4
+#define GPIOPU_DV0_OFFS 0xb8
+#define GPIOPU_DV1_OFFS 0xbc
+
+#define GPIOPU_FS0_TXD0 (1 << 0)
+#define GPIOPU_FS0_RXD0 (1 << 1)
+#define GPIOPU_FS0_CTS0 (1 << 2)
+#define GPIOPU_FS0_RTS0 (1 << 3)
+#define GPIOPU_FS0_TXD1 (1 << 4)
+#define GPIOPU_FS0_RXD1 (1 << 5)
+#define GPIOPU_FS0_CTS1 (1 << 6)
+#define GPIOPU_FS0_RTS1 (1 << 7)
+#define GPIOPU_FS0_TXD2 (1 << 8)
+#define GPIOPU_FS0_RXD2 (1 << 9)
+#define GPIOPU_FS0_CTS2 (1 << 10)
+#define GPIOPU_FS0_RTS2 (1 << 11)
+#define GPIOPU_FS0_TXD3 (1 << 12)
+#define GPIOPU_FS0_RXD3 (1 << 13)
+#define GPIOPU_FS0_CTS3 (1 << 14)
+#define GPIOPU_FS0_RTS3 (1 << 15)
+#define GPIOPU_FS0_TXD4 (1 << 16)
+#define GPIOPU_FS0_RXD4 (1 << 17)
+#define GPIOPU_FS0_CTS4 (1 << 18)
+#define GPIOPU_FS0_RTS4 (1 << 19)
+
+#define GPIOFC_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOFC_DAT_OFFS 0xc0
+#define GPIOFC_DOE_OFFS 0xc4
+#define GPIOFC_FS0_OFFS 0xc8
+#define GPIOFC_FS1_OFFS 0xcc
+#define GPIOFC_FS2_OFFS 0xd0
+#define GPIOFC_FS3_OFFS 0xd4
+#define GPIOFC_RPU_OFFS 0xf0
+#define GPIOFC_RPD_OFFS 0xf4
+#define GPIOFC_DV0_OFFS 0xf8
+#define GPIOFC_DV1_OFFS 0xfc
+
+#define GPIOFD_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOFD_DAT_OFFS 0x100
+#define GPIOFD_DOE_OFFS 0x104
+#define GPIOFD_FS0_OFFS 0x108
+#define GPIOFD_FS1_OFFS 0x10c
+#define GPIOFD_FS2_OFFS 0x110
+#define GPIOFD_RPU_OFFS 0x130
+#define GPIOFD_RPD_OFFS 0x134
+#define GPIOFD_DV0_OFFS 0x138
+#define GPIOFD_DV1_OFFS 0x13c
+
+#define GPIOLC_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOLC_DAT_OFFS 0x140
+#define GPIOLC_DOE_OFFS 0x144
+#define GPIOLC_FS0_OFFS 0x148
+#define GPIOLC_FS1_OFFS 0x14c
+#define GPIOLC_RPU_OFFS 0x170
+#define GPIOLC_RPD_OFFS 0x174
+#define GPIOLC_DV0_OFFS 0x178
+#define GPIOLC_DV1_OFFS 0x17c
+
+#define GPIOLD_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOLD_DAT_OFFS 0x180
+#define GPIOLD_DOE_OFFS 0x184
+#define GPIOLD_FS0_OFFS 0x188
+#define GPIOLD_FS1_OFFS 0x18c
+#define GPIOLD_FS2_OFFS 0x190
+#define GPIOLD_RPU_OFFS 0x1b0
+#define GPIOLD_RPD_OFFS 0x1b4
+#define GPIOLD_DV0_OFFS 0x1b8
+#define GPIOLD_DV1_OFFS 0x1bc
+
+#define GPIOAD_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOAD_DAT_OFFS 0x1c0
+#define GPIOAD_DOE_OFFS 0x1c4
+#define GPIOAD_FS0_OFFS 0x1c8
+#define GPIOAD_RPU_OFFS 0x1f0
+#define GPIOAD_RPD_OFFS 0x1f4
+#define GPIOAD_DV0_OFFS 0x1f8
+#define GPIOAD_DV1_OFFS 0x1fc
+
+#define GPIOXC_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOXC_DAT_OFFS 0x200
+#define GPIOXC_DOE_OFFS 0x204
+#define GPIOXC_FS0_OFFS 0x208
+#define GPIOXC_RPU_OFFS 0x230
+#define GPIOXC_RPD_OFFS 0x234
+#define GPIOXC_DV0_OFFS 0x238
+#define GPIOXC_DV1_OFFS 0x23c
+
+#define GPIOXC_FS0 __REG(GPIOXC_BASE + GPIOXC_FS0_OFFS)
+
+#define GPIOXC_FS0_CS0 (1 << 26)
+#define GPIOXC_FS0_CS1 (1 << 27)
+
+#define GPIOXD_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOXD_DAT_OFFS 0x240
+#define GPIOXD_FS0_OFFS 0x248
+#define GPIOXD_RPU_OFFS 0x270
+#define GPIOXD_RPD_OFFS 0x274
+#define GPIOXD_DV0_OFFS 0x278
+#define GPIOXD_DV1_OFFS 0x27c
+
+#define GPIOPK_BASE (APB1_PERI_BASE_VIRT + 0x1c000)
+
+#define GPIOPK_RST_OFFS 0x008
+#define GPIOPK_DAT_OFFS 0x100
+#define GPIOPK_DOE_OFFS 0x104
+#define GPIOPK_FS0_OFFS 0x108
+#define GPIOPK_FS1_OFFS 0x10c
+#define GPIOPK_FS2_OFFS 0x110
+#define GPIOPK_IRQST_OFFS 0x210
+#define GPIOPK_IRQEN_OFFS 0x214
+#define GPIOPK_IRQPOL_OFFS 0x218
+#define GPIOPK_IRQTM0_OFFS 0x21c
+#define GPIOPK_IRQTM1_OFFS 0x220
+#define GPIOPK_CTL_OFFS 0x22c
+
+#define PMGPIO_BASE (APB1_PERI_BASE_VIRT + 0x10000)
+#define BACKUP_RAM_BASE PMGPIO_BASE
+
+#define PMGPIO_DAT_OFFS 0x800
+#define PMGPIO_DOE_OFFS 0x804
+#define PMGPIO_FS0_OFFS 0x808
+#define PMGPIO_RPU_OFFS 0x810
+#define PMGPIO_RPD_OFFS 0x814
+#define PMGPIO_DV0_OFFS 0x818
+#define PMGPIO_DV1_OFFS 0x81c
+#define PMGPIO_EE0_OFFS 0x820
+#define PMGPIO_EE1_OFFS 0x824
+#define PMGPIO_CTL_OFFS 0x828
+#define PMGPIO_DI_OFFS 0x82c
+#define PMGPIO_STR_OFFS 0x830
+#define PMGPIO_STF_OFFS 0x834
+#define PMGPIO_POL_OFFS 0x838
+#define PMGPIO_APB_OFFS 0x800
+
+/* Clock controller registers */
+#define CKC_BASE ((void __iomem *)(APB1_PERI_BASE_VIRT + 0x6000))
+
+#define CLKCTRL_OFFS 0x00
+#define PLL0CFG_OFFS 0x04
+#define PLL1CFG_OFFS 0x08
+#define CLKDIVC0_OFFS 0x0c
+
+#define BCLKCTR0_OFFS 0x14
+#define SWRESET0_OFFS 0x18
+
+#define BCLKCTR1_OFFS 0x60
+#define SWRESET1_OFFS 0x64
+#define PWDCTL_OFFS 0x68
+#define PLL2CFG_OFFS 0x6c
+#define CLKDIVC1_OFFS 0x70
+
+#define ACLKREF_OFFS 0x80
+#define ACLKI2C_OFFS 0x84
+#define ACLKSPI0_OFFS 0x88
+#define ACLKSPI1_OFFS 0x8c
+#define ACLKUART0_OFFS 0x90
+#define ACLKUART1_OFFS 0x94
+#define ACLKUART2_OFFS 0x98
+#define ACLKUART3_OFFS 0x9c
+#define ACLKUART4_OFFS 0xa0
+#define ACLKTCT_OFFS 0xa4
+#define ACLKTCX_OFFS 0xa8
+#define ACLKTCZ_OFFS 0xac
+#define ACLKADC_OFFS 0xb0
+#define ACLKDAI0_OFFS 0xb4
+#define ACLKDAI1_OFFS 0xb8
+#define ACLKLCD_OFFS 0xbc
+#define ACLKSPDIF_OFFS 0xc0
+#define ACLKUSBH_OFFS 0xc4
+#define ACLKSDH0_OFFS 0xc8
+#define ACLKSDH1_OFFS 0xcc
+#define ACLKC3DEC_OFFS 0xd0
+#define ACLKEXT_OFFS 0xd4
+#define ACLKCAN0_OFFS 0xd8
+#define ACLKCAN1_OFFS 0xdc
+#define ACLKGSB0_OFFS 0xe0
+#define ACLKGSB1_OFFS 0xe4
+#define ACLKGSB2_OFFS 0xe8
+#define ACLKGSB3_OFFS 0xec
+
+#define PLLxCFG_PD (1 << 31)
+
+/* CLKCTRL bits */
+#define CLKCTRL_XE (1 << 31)
+
+/* CLKDIVCx bits */
+#define CLKDIVC0_XTE (1 << 7)
+#define CLKDIVC0_XE (1 << 15)
+#define CLKDIVC0_P1E (1 << 23)
+#define CLKDIVC0_P0E (1 << 31)
+
+#define CLKDIVC1_P2E (1 << 7)
+
+/* BCLKCTR0 clock bits */
+#define BCLKCTR0_USBD (1 << 4)
+#define BCLKCTR0_ECC (1 << 9)
+#define BCLKCTR0_USBH0 (1 << 11)
+#define BCLKCTR0_NFC (1 << 16)
+
+/* BCLKCTR1 clock bits */
+#define BCLKCTR1_USBH1 (1 << 20)
+
+/* SWRESET0 bits */
+#define SWRESET0_USBD (1 << 4)
+#define SWRESET0_USBH0 (1 << 11)
+
+/* SWRESET1 bits */
+#define SWRESET1_USBH1 (1 << 20)
+
+/* System clock sources.
+ * Note: These are the clock sources that serve as parents for
+ * all other clocks. They have no parents themselves.
+ *
+ * These values are used for struct clk->root_id. All clocks
+ * that are not system clock sources have this value set to
+ * CLK_SRC_NOROOT.
+ * The values for system clocks start with CLK_SRC_PLL0 == 0
+ * because this gives us exactly the values needed for the lower
+ * 4 bits of ACLK_* registers. Therefore, CLK_SRC_NOROOT is
+ * defined as -1 to not disturb the order.
+ */
+enum root_clks {
+ CLK_SRC_NOROOT = -1,
+ CLK_SRC_PLL0 = 0,
+ CLK_SRC_PLL1,
+ CLK_SRC_PLL0DIV,
+ CLK_SRC_PLL1DIV,
+ CLK_SRC_XI,
+ CLK_SRC_XIDIV,
+ CLK_SRC_XTI,
+ CLK_SRC_XTIDIV,
+ CLK_SRC_PLL2,
+ CLK_SRC_PLL2DIV,
+ CLK_SRC_PK0,
+ CLK_SRC_PK1,
+ CLK_SRC_PK2,
+ CLK_SRC_PK3,
+ CLK_SRC_PK4,
+ CLK_SRC_48MHZ
+};
+
+#define CLK_SRC_MASK 0xf
+
+/* Bits in ACLK* registers */
+#define ACLK_EN (1 << 28)
+#define ACLK_SEL_SHIFT 24
+#define ACLK_SEL_MASK 0x0f000000
+#define ACLK_DIV_MASK 0x00000fff
+
+/* System configuration registers */
+
+#define SCFG_BASE (APB1_PERI_BASE_VIRT + 0x13000)
+
+#define BMI_OFFS 0x00
+#define AHBCON0_OFFS 0x04
+#define APBPWE_OFFS 0x08
+#define DTCMWAIT_OFFS 0x0c
+#define ECCSEL_OFFS 0x10
+#define AHBCON1_OFFS 0x14
+#define SDHCFG_OFFS 0x18
+#define REMAP_OFFS 0x20
+#define LCDSIAE_OFFS 0x24
+#define XMCCFG_OFFS 0xe0
+#define IMCCFG_OFFS 0xe4
+
+/* Values for ECCSEL */
+#define ECCSEL_EXTMEM 0x0
+#define ECCSEL_DTCM 0x1
+#define ECCSEL_INT_SRAM 0x2
+#define ECCSEL_AHB 0x3
+
+/* Bits in XMCCFG */
+#define XMCCFG_NFCE (1 << 1)
+#define XMCCFG_FDXD (1 << 2)
+
+/* External memory controller registers */
+
+#define EMC_BASE EXT_MEM_CTRL_BASE
+
+#define SDCFG_OFFS 0x00
+#define SDFSM_OFFS 0x04
+#define MCFG_OFFS 0x08
+
+#define CSCFG0_OFFS 0x10
+#define CSCFG1_OFFS 0x14
+#define CSCFG2_OFFS 0x18
+#define CSCFG3_OFFS 0x1c
+
+#define MCFG_SDEN (1 << 4)
+
+#endif /* TCC8K_REGS_H */
diff --git a/arch/arm/plat-tcc/include/mach/timex.h b/arch/arm/plat-tcc/include/mach/timex.h
new file mode 100644
index 000000000000..057acbe651d9
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/timex.h
@@ -0,0 +1,5 @@
+/*
+ * A definition needed by arch core code.
+ *
+ */
+#define CLOCK_TICK_RATE (HZ * 100000UL)
diff --git a/arch/arm/plat-tcc/include/mach/uncompress.h b/arch/arm/plat-tcc/include/mach/uncompress.h
new file mode 100644
index 000000000000..7a3e33a27a30
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/uncompress.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * This file is licensed under the terms of the GPL version 2.
+ */
+
+#include <linux/serial_reg.h>
+#include <linux/types.h>
+
+#include <mach/tcc8k-regs.h>
+
+unsigned int system_rev;
+
+#define ID_MASK 0x7fff
+
+static void putc(int c)
+{
+ u32 *uart_lsr = (u32 *)(UART_BASE_PHYS + (UART_LSR << 2));
+ u32 *uart_tx = (u32 *)(UART_BASE_PHYS + (UART_TX << 2));
+
+ while (!(*uart_lsr & UART_LSR_THRE))
+ barrier();
+ *uart_tx = c;
+}
+
+static inline void flush(void)
+{
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/plat-tcc/include/mach/vmalloc.h b/arch/arm/plat-tcc/include/mach/vmalloc.h
new file mode 100644
index 000000000000..99414d9c2b94
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/vmalloc.h
@@ -0,0 +1,10 @@
+/*
+ * Author: <linux@telechips.com>
+ * Created: June 10, 2008
+ *
+ * Copyright (C) 2000 Russell King.
+ * Copyright (C) 2008-2009 Telechips
+ *
+ * Licensed under the terms of the GPL v2.
+ */
+#define VMALLOC_END 0xf0000000UL
diff --git a/arch/arm/plat-tcc/system.c b/arch/arm/plat-tcc/system.c
new file mode 100644
index 000000000000..cc208fae3e7a
--- /dev/null
+++ b/arch/arm/plat-tcc/system.c
@@ -0,0 +1,25 @@
+/*
+ * System functions for Telechips TCCxxxx SoCs
+ *
+ * Copyright (C) Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GPL v2.
+ *
+ */
+
+#include <linux/io.h>
+
+#include <mach/tcc8k-regs.h>
+
+/* System reboot */
+void plat_tcc_reboot(void)
+{
+ /* Make sure clocks are on */
+ __raw_writel(0xffffffff, CKC_BASE + BCLKCTR0_OFFS);
+
+ /* Enable watchdog reset */
+ __raw_writel(0x49, TIMER_BASE + TWDCFG_OFFS);
+ /* Wait for reset */
+ while(1)
+ ;
+}
diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig
index f51572772e21..f0dc5b8075a7 100644
--- a/arch/avr32/Kconfig
+++ b/arch/avr32/Kconfig
@@ -90,6 +90,7 @@ config PLATFORM_AT32AP
select ARCH_REQUIRE_GPIOLIB
select GENERIC_ALLOCATOR
select HAVE_FB_ATMEL
+ select HAVE_NET_MACB
#
# CPU types
@@ -145,7 +146,7 @@ config BOARD_HAMMERHEAD
will cover even the most exceptional need of memory bandwidth. Together with the onboard
video decoder the board is ready for video processing.
- For more information see: http://www.miromico.com/hammerhead
+ For more information see: http://www.miromico.ch/index.php/hammerhead.html
config BOARD_FAVR_32
bool "Favr-32 LCD-board"
diff --git a/arch/avr32/boards/mimc200/fram.c b/arch/avr32/boards/mimc200/fram.c
index 54fbd95cee9b..9764a1a1073e 100644
--- a/arch/avr32/boards/mimc200/fram.c
+++ b/arch/avr32/boards/mimc200/fram.c
@@ -41,6 +41,7 @@ static int fram_mmap(struct file *filp, struct vm_area_struct *vma)
static const struct file_operations fram_fops = {
.owner = THIS_MODULE,
.mmap = fram_mmap,
+ .llseek = noop_llseek,
};
#define FRAM_MINOR 0
diff --git a/arch/avr32/include/asm/ioctls.h b/arch/avr32/include/asm/ioctls.h
index b7dd324b46a9..909cf66feaf5 100644
--- a/arch/avr32/include/asm/ioctls.h
+++ b/arch/avr32/include/asm/ioctls.h
@@ -1,90 +1,6 @@
#ifndef __ASM_AVR32_IOCTLS_H
#define __ASM_AVR32_IOCTLS_H
-#include <asm/ioctl.h>
-
-/* 0x54 is just a magic number to make these relatively unique ('T') */
-
-#define TCGETS 0x5401
-#define TCSETS 0x5402 /* Clashes with SNDCTL_TMR_START sound ioctl */
-#define TCSETSW 0x5403
-#define TCSETSF 0x5404
-#define TCGETA 0x5405
-#define TCSETA 0x5406
-#define TCSETAW 0x5407
-#define TCSETAF 0x5408
-#define TCSBRK 0x5409
-#define TCXONC 0x540A
-#define TCFLSH 0x540B
-#define TIOCEXCL 0x540C
-#define TIOCNXCL 0x540D
-#define TIOCSCTTY 0x540E
-#define TIOCGPGRP 0x540F
-#define TIOCSPGRP 0x5410
-#define TIOCOUTQ 0x5411
-#define TIOCSTI 0x5412
-#define TIOCGWINSZ 0x5413
-#define TIOCSWINSZ 0x5414
-#define TIOCMGET 0x5415
-#define TIOCMBIS 0x5416
-#define TIOCMBIC 0x5417
-#define TIOCMSET 0x5418
-#define TIOCGSOFTCAR 0x5419
-#define TIOCSSOFTCAR 0x541A
-#define FIONREAD 0x541B
-#define TIOCINQ FIONREAD
-#define TIOCLINUX 0x541C
-#define TIOCCONS 0x541D
-#define TIOCGSERIAL 0x541E
-#define TIOCSSERIAL 0x541F
-#define TIOCPKT 0x5420
-#define FIONBIO 0x5421
-#define TIOCNOTTY 0x5422
-#define TIOCSETD 0x5423
-#define TIOCGETD 0x5424
-#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
-/* #define TIOCTTYGSTRUCT 0x5426 - Former debugging-only ioctl */
-#define TIOCSBRK 0x5427 /* BSD compatibility */
-#define TIOCCBRK 0x5428 /* BSD compatibility */
-#define TIOCGSID 0x5429 /* Return the session ID of FD */
-#define TCGETS2 _IOR('T',0x2A, struct termios2)
-#define TCSETS2 _IOW('T',0x2B, struct termios2)
-#define TCSETSW2 _IOW('T',0x2C, struct termios2)
-#define TCSETSF2 _IOW('T',0x2D, struct termios2)
-#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
-#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
-#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */
-
-#define TIOCGRS485 0x542E
-#define TIOCSRS485 0x542F
-
-#define FIONCLEX 0x5450
-#define FIOCLEX 0x5451
-#define FIOASYNC 0x5452
-#define TIOCSERCONFIG 0x5453
-#define TIOCSERGWILD 0x5454
-#define TIOCSERSWILD 0x5455
-#define TIOCGLCKTRMIOS 0x5456
-#define TIOCSLCKTRMIOS 0x5457
-#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
-#define TIOCSERGETLSR 0x5459 /* Get line status register */
-#define TIOCSERGETMULTI 0x545A /* Get multiport config */
-#define TIOCSERSETMULTI 0x545B /* Set multiport config */
-
-#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
-#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
-#define FIOQSIZE 0x5460
-
-/* Used for packet mode */
-#define TIOCPKT_DATA 0
-#define TIOCPKT_FLUSHREAD 1
-#define TIOCPKT_FLUSHWRITE 2
-#define TIOCPKT_STOP 4
-#define TIOCPKT_START 8
-#define TIOCPKT_NOSTOP 16
-#define TIOCPKT_DOSTOP 32
-#define TIOCPKT_IOCTL 64
-
-#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
+#include <asm-generic/ioctls.h>
#endif /* __ASM_AVR32_IOCTLS_H */
diff --git a/arch/avr32/include/asm/irqflags.h b/arch/avr32/include/asm/irqflags.h
index 93570daac38a..006e9487372d 100644
--- a/arch/avr32/include/asm/irqflags.h
+++ b/arch/avr32/include/asm/irqflags.h
@@ -8,16 +8,14 @@
#ifndef __ASM_AVR32_IRQFLAGS_H
#define __ASM_AVR32_IRQFLAGS_H
+#include <linux/types.h>
#include <asm/sysreg.h>
-static inline unsigned long __raw_local_save_flags(void)
+static inline unsigned long arch_local_save_flags(void)
{
return sysreg_read(SR);
}
-#define raw_local_save_flags(x) \
- do { (x) = __raw_local_save_flags(); } while (0)
-
/*
* This will restore ALL status register flags, not only the interrupt
* mask flag.
@@ -25,44 +23,39 @@ static inline unsigned long __raw_local_save_flags(void)
* The empty asm statement informs the compiler of this fact while
* also serving as a barrier.
*/
-static inline void raw_local_irq_restore(unsigned long flags)
+static inline void arch_local_irq_restore(unsigned long flags)
{
sysreg_write(SR, flags);
asm volatile("" : : : "memory", "cc");
}
-static inline void raw_local_irq_disable(void)
+static inline void arch_local_irq_disable(void)
{
asm volatile("ssrf %0" : : "n"(SYSREG_GM_OFFSET) : "memory");
}
-static inline void raw_local_irq_enable(void)
+static inline void arch_local_irq_enable(void)
{
asm volatile("csrf %0" : : "n"(SYSREG_GM_OFFSET) : "memory");
}
-static inline int raw_irqs_disabled_flags(unsigned long flags)
+static inline bool arch_irqs_disabled_flags(unsigned long flags)
{
return (flags & SYSREG_BIT(GM)) != 0;
}
-static inline int raw_irqs_disabled(void)
+static inline bool arch_irqs_disabled(void)
{
- unsigned long flags = __raw_local_save_flags();
-
- return raw_irqs_disabled_flags(flags);
+ return arch_irqs_disabled_flags(arch_local_save_flags());
}
-static inline unsigned long __raw_local_irq_save(void)
+static inline unsigned long arch_local_irq_save(void)
{
- unsigned long flags = __raw_local_save_flags();
+ unsigned long flags = arch_local_save_flags();
- raw_local_irq_disable();
+ arch_local_irq_disable();
return flags;
}
-#define raw_local_irq_save(flags) \
- do { (flags) = __raw_local_irq_save(); } while (0)
-
#endif /* __ASM_AVR32_IRQFLAGS_H */
diff --git a/arch/avr32/kernel/module.c b/arch/avr32/kernel/module.c
index 98f94d041d9c..a727f54d64d6 100644
--- a/arch/avr32/kernel/module.c
+++ b/arch/avr32/kernel/module.c
@@ -314,10 +314,9 @@ int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
vfree(module->arch.syminfo);
module->arch.syminfo = NULL;
- return module_bug_finalize(hdr, sechdrs, module);
+ return 0;
}
void module_arch_cleanup(struct module *module)
{
- module_bug_cleanup(module);
}
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index 5a3152b75cdb..d9a1cb7ec30a 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -300,7 +300,7 @@ config BF_REV_0_1
config BF_REV_0_2
bool "0.2"
- depends on (BF52x || BF537 || BF536 || BF534 || (BF54x && !BF54xM))
+ depends on (BF51x || BF52x || BF537 || BF536 || BF534 || (BF54x && !BF54xM))
config BF_REV_0_3
bool "0.3"
@@ -356,7 +356,7 @@ config MEM_MT48LC8M32B2B5_7
config MEM_MT48LC32M16A2TG_75
bool
- depends on (BFIN527_EZKIT || BFIN527_EZKIT_V2 || BFIN532_IP0X || BLACKSTAMP)
+ depends on (BFIN527_EZKIT || BFIN527_EZKIT_V2 || BFIN532_IP0X || BLACKSTAMP || BFIN527_AD7160EVAL)
default y
config MEM_MT48H32M16LFCJ_75
@@ -426,6 +426,7 @@ config CLKIN_HZ
default "25000000" # most people use this
default "27000000" if BFIN533_EZKIT
default "30000000" if BFIN561_EZKIT
+ default "24000000" if BFIN527_AD7160EVAL
help
The frequency of CLKIN crystal oscillator on the board in Hz.
Warning: This value should match the crystal on the board. Otherwise,
@@ -463,6 +464,7 @@ config VCO_MULT
default "20" if (BFIN537_BLUETECHNIX_CM_E || BFIN537_BLUETECHNIX_CM_U || BFIN527_BLUETECHNIX_CM || BFIN561_BLUETECHNIX_CM)
default "20" if BFIN561_EZKIT
default "16" if (H8606_HVSISTEMAS || BLACKSTAMP || BFIN526_EZBRD || BFIN518F_EZBRD)
+ default "25" if BFIN527_AD7160EVAL
help
This controls the frequency of the on-chip PLL. This can be between 1 and 64.
PLL Frequency = (Crystal Frequency) * (this setting)
@@ -926,6 +928,12 @@ config ROMKERNEL
endchoice
+# Common code uses "ROMKERNEL" or "XIP_KERNEL", so define both
+config XIP_KERNEL
+ bool
+ default y
+ depends on ROMKERNEL
+
source "mm/Kconfig"
config BFIN_GPTIMERS
diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile
index 3e65b0ffe084..46738d49b7c8 100644
--- a/arch/blackfin/Makefile
+++ b/arch/blackfin/Makefile
@@ -101,9 +101,8 @@ KBUILD_CFLAGS += -mcpu=$(cpu-y)-$(rev-y)
KBUILD_AFLAGS += -mcpu=$(cpu-y)-$(rev-y)
# - we utilize the silicon rev from the toolchain, so move it over to the checkflags
-# - the l1_text attribute is Blackfin specific, so fake it out as used to kill warnings
CHECKFLAGS_SILICON = $(shell echo "" | $(CPP) $(KBUILD_CFLAGS) -dD - 2>/dev/null | awk '$$2 == "__SILICON_REVISION__" { print $$3 }')
-CHECKFLAGS += -D__SILICON_REVISION__=$(CHECKFLAGS_SILICON) -Dl1_text=__used__
+CHECKFLAGS += -D__SILICON_REVISION__=$(CHECKFLAGS_SILICON) -D__bfin__
head-y := arch/$(ARCH)/kernel/init_task.o
diff --git a/arch/blackfin/configs/BF527-AD7160-EVAL_defconfig b/arch/blackfin/configs/BF527-AD7160-EVAL_defconfig
new file mode 100644
index 000000000000..08c55f6b8b7a
--- /dev/null
+++ b/arch/blackfin/configs/BF527-AD7160-EVAL_defconfig
@@ -0,0 +1,105 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EMBEDDED=y
+# CONFIG_ELF_CORE is not set
+# CONFIG_AIO is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_PREEMPT=y
+CONFIG_BF527=y
+CONFIG_BF_REV_0_2=y
+CONFIG_IRQ_TWI=7
+CONFIG_IRQ_PORTH_INTA=7
+CONFIG_IRQ_PORTH_INTB=7
+CONFIG_BFIN527_AD7160EVAL=y
+CONFIG_BF527_SPORT0_PORTF=y
+CONFIG_BF527_UART1_PORTG=y
+CONFIG_IRQ_USB_INT0=11
+CONFIG_IRQ_USB_INT1=11
+CONFIG_IRQ_USB_INT2=11
+CONFIG_IRQ_USB_DMA=11
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="bootargs=root=/dev/mtdblock0 rw clkin_hz=24000000 earlyprintk=serial,uart0,57600 console=tty0 console=ttyBF0,57600"
+CONFIG_CLKIN_HZ=24000000
+CONFIG_HZ_300=y
+# CONFIG_CYCLES_CLOCKSOURCE is not set
+CONFIG_IP_CHECKSUM_L1=y
+CONFIG_SYSCALL_TAB_L1=y
+CONFIG_CPLB_SWITCH_TAB_L1=y
+CONFIG_BFIN_GPTIMERS=y
+CONFIG_C_CDPRIO=y
+CONFIG_BANK_1=0x5554
+CONFIG_BANK_3=0xFFC0
+CONFIG_BINFMT_FLAT=y
+CONFIG_BINFMT_ZFLAT=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+# CONFIG_WIRELESS is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+# CONFIG_MISC_DEVICES is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_AD7160=y
+CONFIG_TOUCHSCREEN_AD7160_FW=y
+# CONFIG_SERIO is not set
+# CONFIG_BFIN_DMA_INTERFACE is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_BFIN=y
+CONFIG_SERIAL_BFIN_CONSOLE=y
+CONFIG_SERIAL_BFIN_UART0=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_BFIN_OTP is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_I2C_ALGOBIT=y
+CONFIG_I2C_BLACKFIN_TWI=y
+CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=400
+CONFIG_SPI=y
+CONFIG_SPI_BFIN=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+CONFIG_FB=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+# CONFIG_LOGO_BLACKFIN_VGA16 is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_GADGET_MUSB_HDRC=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_VBUS_DRAW=500
+CONFIG_USB_G_SERIAL=y
+CONFIG_MMC=y
+CONFIG_MMC_SPI=y
+CONFIG_EXT2_FS=y
+# CONFIG_DNOTIFY is not set
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_CPLB_INFO=y
+CONFIG_SECURITY=y
+CONFIG_CRC_CCITT=m
diff --git a/arch/blackfin/configs/BF527-TLL6527M_defconfig b/arch/blackfin/configs/BF527-TLL6527M_defconfig
new file mode 100644
index 000000000000..92ded5edc86c
--- /dev/null
+++ b/arch/blackfin/configs/BF527-TLL6527M_defconfig
@@ -0,0 +1,180 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION="DEV_0-1_pre2010"
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_ELF_CORE is not set
+# CONFIG_FUTEX is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
+CONFIG_SLAB=y
+CONFIG_MMAP_ALLOW_UNINITIALIZED=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+CONFIG_BF527=y
+CONFIG_BF_REV_0_2=y
+CONFIG_BFIN527_TLL6527M=y
+CONFIG_BF527_UART1_PORTG=y
+CONFIG_IRQ_USB_INT0=11
+CONFIG_IRQ_USB_INT1=11
+CONFIG_IRQ_USB_INT2=11
+CONFIG_IRQ_USB_DMA=11
+CONFIG_BOOT_LOAD=0x400000
+# CONFIG_CYCLES_CLOCKSOURCE is not set
+# CONFIG_SCHEDULE_L1 is not set
+# CONFIG_MEMSET_L1 is not set
+# CONFIG_MEMCPY_L1 is not set
+# CONFIG_SYS_BFIN_SPINLOCK_L1 is not set
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
+CONFIG_BFIN_GPTIMERS=y
+CONFIG_DMA_UNCACHED_2M=y
+CONFIG_C_CDPRIO=y
+CONFIG_BANK_0=0xFFC2
+CONFIG_BANK_1=0xFFC2
+CONFIG_BANK_2=0xFFC2
+CONFIG_BANK_3=0xFFC2
+CONFIG_BINFMT_FLAT=y
+CONFIG_BINFMT_ZFLAT=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+CONFIG_IRDA=m
+CONFIG_IRLAN=m
+CONFIG_IRCOMM=m
+CONFIG_IRTTY_SIR=m
+CONFIG_BFIN_SIR=m
+CONFIG_BFIN_SIR0=y
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FW_LOADER is not set
+CONFIG_MTD=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_RAM=y
+CONFIG_MTD_ROM=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_GPIO_ADDR=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_SCSI=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=m
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_BFIN_MAC=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_AD7879=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_AD714X=y
+CONFIG_INPUT_ADXL34X=y
+# CONFIG_SERIO is not set
+CONFIG_BFIN_PPI=m
+CONFIG_BFIN_SIMPLE_TIMER=m
+CONFIG_BFIN_SPORT=m
+# CONFIG_CONSOLE_TRANSLATIONS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_BFIN_JTAG_COMM=m
+CONFIG_SERIAL_BFIN=y
+CONFIG_SERIAL_BFIN_CONSOLE=y
+CONFIG_SERIAL_BFIN_UART1=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_I2C_SMBUS=y
+CONFIG_I2C_BLACKFIN_TWI=y
+CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_BFIN_WDT=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_VIDEO_DEV=y
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+CONFIG_VIDEO_BLACKFIN_CAM=m
+CONFIG_OV9655=y
+CONFIG_FB=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_6x11=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+# CONFIG_LOGO_BLACKFIN_VGA16 is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_SOC=y
+CONFIG_SND_BF5XX_I2S=y
+CONFIG_SND_BF5XX_SOC_SSM2602=y
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=m
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_BFIN=y
+CONFIG_EXT2_FS=y
+# CONFIG_DNOTIFY is not set
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_UTF8=m
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_MMRS=y
+CONFIG_DEBUG_HWERR=y
+CONFIG_EXACT_HWERR=y
+CONFIG_DEBUG_DOUBLEFAULT=y
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_CPLB_INFO=y
+CONFIG_SECURITY=y
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRC7=m
diff --git a/arch/blackfin/include/asm/Kbuild b/arch/blackfin/include/asm/Kbuild
index d9eb29e2555c..9e7c5379d3ff 100644
--- a/arch/blackfin/include/asm/Kbuild
+++ b/arch/blackfin/include/asm/Kbuild
@@ -1,4 +1,5 @@
include include/asm-generic/Kbuild.asm
header-y += bfin_sport.h
+header-y += cachectl.h
header-y += fixed_code.h
diff --git a/arch/blackfin/include/asm/bfin5xx_spi.h b/arch/blackfin/include/asm/bfin5xx_spi.h
index ed4f8c6db0cd..0b5136e334b5 100644
--- a/arch/blackfin/include/asm/bfin5xx_spi.h
+++ b/arch/blackfin/include/asm/bfin5xx_spi.h
@@ -11,26 +11,17 @@
#define MIN_SPI_BAUD_VAL 2
-#define SPI_READ 0
-#define SPI_WRITE 1
-
-#define SPI_CTRL_OFF 0x0
-#define SPI_FLAG_OFF 0x4
-#define SPI_STAT_OFF 0x8
-#define SPI_TXBUFF_OFF 0xc
-#define SPI_RXBUFF_OFF 0x10
-#define SPI_BAUD_OFF 0x14
-#define SPI_SHAW_OFF 0x18
-
-
#define BIT_CTL_ENABLE 0x4000
#define BIT_CTL_OPENDRAIN 0x2000
#define BIT_CTL_MASTER 0x1000
-#define BIT_CTL_POLAR 0x0800
-#define BIT_CTL_PHASE 0x0400
-#define BIT_CTL_BITORDER 0x0200
+#define BIT_CTL_CPOL 0x0800
+#define BIT_CTL_CPHA 0x0400
+#define BIT_CTL_LSBF 0x0200
#define BIT_CTL_WORDSIZE 0x0100
-#define BIT_CTL_MISOENABLE 0x0020
+#define BIT_CTL_EMISO 0x0020
+#define BIT_CTL_PSSE 0x0010
+#define BIT_CTL_GM 0x0008
+#define BIT_CTL_SZ 0x0004
#define BIT_CTL_RXMOD 0x0000
#define BIT_CTL_TXMOD 0x0001
#define BIT_CTL_TIMOD_DMA_TX 0x0003
@@ -50,61 +41,26 @@
#define BIT_STU_SENDOVER 0x0001
#define BIT_STU_RECVFULL 0x0020
-#define CFG_SPI_ENABLE 1
-#define CFG_SPI_DISABLE 0
-
-#define CFG_SPI_OUTENABLE 1
-#define CFG_SPI_OUTDISABLE 0
-
-#define CFG_SPI_ACTLOW 1
-#define CFG_SPI_ACTHIGH 0
-
-#define CFG_SPI_PHASESTART 1
-#define CFG_SPI_PHASEMID 0
-
-#define CFG_SPI_MASTER 1
-#define CFG_SPI_SLAVE 0
-
-#define CFG_SPI_SENELAST 0
-#define CFG_SPI_SENDZERO 1
-
-#define CFG_SPI_RCVFLUSH 1
-#define CFG_SPI_RCVDISCARD 0
-
-#define CFG_SPI_LSBFIRST 1
-#define CFG_SPI_MSBFIRST 0
-
-#define CFG_SPI_WORDSIZE16 1
-#define CFG_SPI_WORDSIZE8 0
-
-#define CFG_SPI_MISOENABLE 1
-#define CFG_SPI_MISODISABLE 0
-
-#define CFG_SPI_READ 0x00
-#define CFG_SPI_WRITE 0x01
-#define CFG_SPI_DMAREAD 0x02
-#define CFG_SPI_DMAWRITE 0x03
-
-#define CFG_SPI_CSCLEARALL 0
-#define CFG_SPI_CHIPSEL1 1
-#define CFG_SPI_CHIPSEL2 2
-#define CFG_SPI_CHIPSEL3 3
-#define CFG_SPI_CHIPSEL4 4
-#define CFG_SPI_CHIPSEL5 5
-#define CFG_SPI_CHIPSEL6 6
-#define CFG_SPI_CHIPSEL7 7
+/*
+ * All Blackfin system MMRs are padded to 32bits even if the register
+ * itself is only 16bits. So use a helper macro to streamline this.
+ */
+#define __BFP(m) u16 m; u16 __pad_##m
-#define CFG_SPI_CS1VALUE 1
-#define CFG_SPI_CS2VALUE 2
-#define CFG_SPI_CS3VALUE 3
-#define CFG_SPI_CS4VALUE 4
-#define CFG_SPI_CS5VALUE 5
-#define CFG_SPI_CS6VALUE 6
-#define CFG_SPI_CS7VALUE 7
+/*
+ * bfin spi registers layout
+ */
+struct bfin_spi_regs {
+ __BFP(ctl);
+ __BFP(flg);
+ __BFP(stat);
+ __BFP(tdbr);
+ __BFP(rdbr);
+ __BFP(baud);
+ __BFP(shadow);
+};
-#define CMD_SPI_SET_BAUDRATE 2
-#define CMD_SPI_GET_SYSTEMCLOCK 25
-#define CMD_SPI_SET_WRITECONTINUOUS 26
+#define MAX_CTRL_CS 8 /* cs in spi controller */
/* device.platform_data for SSP controller devices */
struct bfin5xx_spi_master {
@@ -120,9 +76,7 @@ struct bfin5xx_spi_chip {
u16 ctl_reg;
u8 enable_dma;
u8 bits_per_word;
- u8 cs_change_per_word;
u16 cs_chg_udelay; /* Some devices require 16-bit delays */
- u32 cs_gpio;
/* Value to send if no TX value is supplied, usually 0x0 or 0xFFFF */
u16 idle_tx_val;
u8 pio_interrupt; /* Enable spi data irq */
diff --git a/arch/blackfin/include/asm/bfin_can.h b/arch/blackfin/include/asm/bfin_can.h
index eec0076a385b..b1492e0bcabb 100644
--- a/arch/blackfin/include/asm/bfin_can.h
+++ b/arch/blackfin/include/asm/bfin_can.h
@@ -34,6 +34,7 @@ struct bfin_can_mask_regs {
};
struct bfin_can_channel_regs {
+ /* data[0,2,4,6] -> data{0,1,2,3} while data[1,3,5,7] is padding */
u16 data[8];
__BFP(dlc);
__BFP(tsv);
@@ -83,16 +84,18 @@ struct bfin_can_regs {
__BFP(gif); /* offset 0x9c */
__BFP(control); /* offset 0xa0 */
__BFP(intr); /* offset 0xa4 */
- u32 __pad3[1];
+ __BFP(version); /* offset 0xa8 */
__BFP(mbtd); /* offset 0xac */
__BFP(ewr); /* offset 0xb0 */
__BFP(esr); /* offset 0xb4 */
- u32 __pad4[2];
+ u32 __pad3[2];
__BFP(ucreg); /* offset 0xc0 */
__BFP(uccnt); /* offset 0xc4 */
__BFP(ucrc); /* offset 0xc8 */
__BFP(uccnf); /* offset 0xcc */
- u32 __pad5[12];
+ u32 __pad4[1];
+ __BFP(version2); /* offset 0xd4 */
+ u32 __pad5[10];
/*
* channel(mailbox) mask and message registers
diff --git a/arch/blackfin/include/asm/bfin_ppi.h b/arch/blackfin/include/asm/bfin_ppi.h
new file mode 100644
index 000000000000..003900886f97
--- /dev/null
+++ b/arch/blackfin/include/asm/bfin_ppi.h
@@ -0,0 +1,51 @@
+/*
+ * bfin_ppi.h - interface to Blackfin PPIs
+ *
+ * Copyright 2005-2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __ASM_BFIN_PPI_H__
+#define __ASM_BFIN_PPI_H__
+
+#include <linux/types.h>
+
+/*
+ * All Blackfin system MMRs are padded to 32bits even if the register
+ * itself is only 16bits. So use a helper macro to streamline this.
+ */
+#define __BFP(m) u16 m; u16 __pad_##m
+
+/*
+ * bfin ppi registers layout
+ */
+struct bfin_ppi_regs {
+ __BFP(control);
+ __BFP(status);
+ __BFP(count);
+ __BFP(delay);
+ __BFP(frame);
+};
+
+/*
+ * bfin eppi registers layout
+ */
+struct bfin_eppi_regs {
+ __BFP(status);
+ __BFP(hcount);
+ __BFP(hdelay);
+ __BFP(vcount);
+ __BFP(vdelay);
+ __BFP(frame);
+ __BFP(line);
+ __BFP(clkdiv);
+ u32 control;
+ u32 fs1w_hbl;
+ u32 fs1p_avpl;
+ u32 fs2w_lvb;
+ u32 fs2p_lavf;
+ u32 clip;
+};
+
+#endif
diff --git a/arch/blackfin/include/asm/cachectl.h b/arch/blackfin/include/asm/cachectl.h
new file mode 100644
index 000000000000..03255df6c1ea
--- /dev/null
+++ b/arch/blackfin/include/asm/cachectl.h
@@ -0,0 +1,20 @@
+/*
+ * based on the mips/cachectl.h
+ *
+ * Copyright 2010 Analog Devices Inc.
+ * Copyright (C) 1994, 1995, 1996 by Ralf Baechle
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef _ASM_CACHECTL
+#define _ASM_CACHECTL
+
+/*
+ * Options for cacheflush system call
+ */
+#define ICACHE (1<<0) /* flush instruction cache */
+#define DCACHE (1<<1) /* writeback and flush data cache */
+#define BCACHE (ICACHE|DCACHE) /* flush both caches */
+
+#endif /* _ASM_CACHECTL */
diff --git a/arch/blackfin/include/asm/cdef_LPBlackfin.h b/arch/blackfin/include/asm/cdef_LPBlackfin.h
index 6c39d94b44d0..a1f6817687e8 100644
--- a/arch/blackfin/include/asm/cdef_LPBlackfin.h
+++ b/arch/blackfin/include/asm/cdef_LPBlackfin.h
@@ -172,16 +172,19 @@
#define bfin_write_ICPLB_DATA14(val) bfin_write32(ICPLB_DATA14,val)
#define bfin_read_ICPLB_DATA15() bfin_read32(ICPLB_DATA15)
#define bfin_write_ICPLB_DATA15(val) bfin_write32(ICPLB_DATA15,val)
-#define bfin_read_ITEST_COMMAND() bfin_read32(ITEST_COMMAND)
#define bfin_write_ITEST_COMMAND(val) bfin_write32(ITEST_COMMAND,val)
#if 0
#define ITEST_INDEX 0xFFE01304 /* Instruction Test Index Register */
#endif
-#define bfin_read_ITEST_DATA0() bfin_read32(ITEST_DATA0)
#define bfin_write_ITEST_DATA0(val) bfin_write32(ITEST_DATA0,val)
-#define bfin_read_ITEST_DATA1() bfin_read32(ITEST_DATA1)
#define bfin_write_ITEST_DATA1(val) bfin_write32(ITEST_DATA1,val)
+#if ANOMALY_05000481
+#define bfin_read_ITEST_COMMAND() bfin_read32(ITEST_COMMAND)
+#define bfin_read_ITEST_DATA0() bfin_read32(ITEST_DATA0)
+#define bfin_read_ITEST_DATA1() bfin_read32(ITEST_DATA1)
+#endif
+
/* Event/Interrupt Registers*/
#define bfin_read_EVT0() bfin_read32(EVT0)
diff --git a/arch/blackfin/include/asm/ipipe.h b/arch/blackfin/include/asm/ipipe.h
index d3b40449ca0e..40f94a704c02 100644
--- a/arch/blackfin/include/asm/ipipe.h
+++ b/arch/blackfin/include/asm/ipipe.h
@@ -49,7 +49,7 @@
#define prepare_arch_switch(next) \
do { \
ipipe_schedule_notify(current, next); \
- local_irq_disable_hw(); \
+ hard_local_irq_disable(); \
} while (0)
#define task_hijacked(p) \
@@ -57,7 +57,7 @@ do { \
int __x__ = __ipipe_root_domain_p; \
__clear_bit(IPIPE_SYNC_FLAG, &ipipe_root_cpudom_var(status)); \
if (__x__) \
- local_irq_enable_hw(); \
+ hard_local_irq_enable(); \
!__x__; \
})
@@ -167,7 +167,7 @@ static inline unsigned long __ipipe_ffnz(unsigned long ul)
#define __ipipe_run_isr(ipd, irq) \
do { \
if (!__ipipe_pipeline_head_p(ipd)) \
- local_irq_enable_hw(); \
+ hard_local_irq_enable(); \
if (ipd == ipipe_root_domain) { \
if (unlikely(ipipe_virtual_irq_p(irq))) { \
irq_enter(); \
@@ -183,7 +183,7 @@ static inline unsigned long __ipipe_ffnz(unsigned long ul)
__ipipe_run_irqtail(); \
__set_bit(IPIPE_SYNC_FLAG, &ipipe_cpudom_var(ipd, status)); \
} \
- local_irq_disable_hw(); \
+ hard_local_irq_disable(); \
} while (0)
#define __ipipe_syscall_watched_p(p, sc) \
diff --git a/arch/blackfin/include/asm/irqflags.h b/arch/blackfin/include/asm/irqflags.h
index 813a1af3e865..41c4d70544ef 100644
--- a/arch/blackfin/include/asm/irqflags.h
+++ b/arch/blackfin/include/asm/irqflags.h
@@ -8,6 +8,8 @@
#ifndef __ASM_BFIN_IRQFLAGS_H__
#define __ASM_BFIN_IRQFLAGS_H__
+#include <mach/blackfin.h>
+
#ifdef CONFIG_SMP
# include <asm/pda.h>
# include <asm/processor.h>
@@ -31,54 +33,108 @@ static inline unsigned long bfin_cli(void)
return flags;
}
-#ifdef CONFIG_IPIPE
-
-#include <linux/compiler.h>
-#include <linux/ipipe_base.h>
-#include <linux/ipipe_trace.h>
-
#ifdef CONFIG_DEBUG_HWERR
# define bfin_no_irqs 0x3f
#else
# define bfin_no_irqs 0x1f
#endif
-#define raw_local_irq_disable() \
- do { \
- ipipe_check_context(ipipe_root_domain); \
- __ipipe_stall_root(); \
- barrier(); \
- } while (0)
+/*****************************************************************************/
+/*
+ * Hard, untraced CPU interrupt flag manipulation and access.
+ */
+static inline void __hard_local_irq_disable(void)
+{
+ bfin_cli();
+}
+
+static inline void __hard_local_irq_enable(void)
+{
+ bfin_sti(bfin_irq_flags);
+}
+
+static inline unsigned long hard_local_save_flags(void)
+{
+ return bfin_read_IMASK();
+}
-#define raw_local_irq_enable() \
- do { \
- barrier(); \
- ipipe_check_context(ipipe_root_domain); \
- __ipipe_unstall_root(); \
- } while (0)
+static inline unsigned long __hard_local_irq_save(void)
+{
+ unsigned long flags;
+ flags = bfin_cli();
+#ifdef CONFIG_DEBUG_HWERR
+ bfin_sti(0x3f);
+#endif
+ return flags;
+}
+
+static inline int hard_irqs_disabled_flags(unsigned long flags)
+{
+ return (flags & ~0x3f) == 0;
+}
+
+static inline int hard_irqs_disabled(void)
+{
+ unsigned long flags = hard_local_save_flags();
+ return hard_irqs_disabled_flags(flags);
+}
+
+static inline void __hard_local_irq_restore(unsigned long flags)
+{
+ if (!hard_irqs_disabled_flags(flags))
+ __hard_local_irq_enable();
+}
+
+/*****************************************************************************/
+/*
+ * Interrupt pipe handling.
+ */
+#ifdef CONFIG_IPIPE
+
+#include <linux/compiler.h>
+#include <linux/ipipe_base.h>
+#include <linux/ipipe_trace.h>
+
+/*
+ * Interrupt pipe interface to linux/irqflags.h.
+ */
+static inline void arch_local_irq_disable(void)
+{
+ ipipe_check_context(ipipe_root_domain);
+ __ipipe_stall_root();
+ barrier();
+}
-#define raw_local_save_flags_ptr(x) \
- do { \
- *(x) = __ipipe_test_root() ? bfin_no_irqs : bfin_irq_flags; \
- } while (0)
+static inline void arch_local_irq_enable(void)
+{
+ barrier();
+ ipipe_check_context(ipipe_root_domain);
+ __ipipe_unstall_root();
+}
-#define raw_local_save_flags(x) raw_local_save_flags_ptr(&(x))
+static inline unsigned long arch_local_save_flags(void)
+{
+ return __ipipe_test_root() ? bfin_no_irqs : bfin_irq_flags;
+}
-#define raw_irqs_disabled_flags(x) ((x) == bfin_no_irqs)
+static inline int arch_irqs_disabled_flags(unsigned long flags)
+{
+ return flags == bfin_no_irqs;
+}
-#define raw_local_irq_save_ptr(x) \
- do { \
- *(x) = __ipipe_test_and_stall_root() ? bfin_no_irqs : bfin_irq_flags; \
- barrier(); \
- } while (0)
+static inline void arch_local_irq_save_ptr(unsigned long *_flags)
+{
+ x = __ipipe_test_and_stall_root() ? bfin_no_irqs : bfin_irq_flags;
+ barrier();
+}
-#define raw_local_irq_save(x) \
- do { \
- ipipe_check_context(ipipe_root_domain); \
- raw_local_irq_save_ptr(&(x)); \
- } while (0)
+static inline unsigned long arch_local_irq_save(void)
+{
+ ipipe_check_context(ipipe_root_domain);
+ return __hard_local_irq_save();
+}
-static inline unsigned long raw_mangle_irq_bits(int virt, unsigned long real)
+static inline unsigned long arch_mangle_irq_bits(int virt, unsigned long real)
{
/*
* Merge virtual and real interrupt mask bits into a single
@@ -87,130 +143,79 @@ static inline unsigned long raw_mangle_irq_bits(int virt, unsigned long real)
return (real & ~(1 << 31)) | ((virt != 0) << 31);
}
-static inline int raw_demangle_irq_bits(unsigned long *x)
+static inline int arch_demangle_irq_bits(unsigned long *x)
{
int virt = (*x & (1 << 31)) != 0;
*x &= ~(1L << 31);
return virt;
}
-static inline void local_irq_disable_hw_notrace(void)
+/*
+ * Interface to various arch routines that may be traced.
+ */
+#ifdef CONFIG_IPIPE_TRACE_IRQSOFF
+static inline void hard_local_irq_disable(void)
{
- bfin_cli();
+ if (!hard_irqs_disabled()) {
+ __hard_local_irq_disable();
+ ipipe_trace_begin(0x80000000);
+ }
}
-static inline void local_irq_enable_hw_notrace(void)
+static inline void hard_local_irq_enable(void)
{
- bfin_sti(bfin_irq_flags);
+ if (hard_irqs_disabled()) {
+ ipipe_trace_end(0x80000000);
+ __hard_local_irq_enable();
+ }
}
-#define local_save_flags_hw(flags) \
- do { \
- (flags) = bfin_read_IMASK(); \
- } while (0)
-
-#define irqs_disabled_flags_hw(flags) (((flags) & ~0x3f) == 0)
-
-#define irqs_disabled_hw() \
- ({ \
- unsigned long flags; \
- local_save_flags_hw(flags); \
- irqs_disabled_flags_hw(flags); \
- })
-
-static inline void local_irq_save_ptr_hw(unsigned long *flags)
+static inline unsigned long hard_local_irq_save(void)
{
- *flags = bfin_cli();
-#ifdef CONFIG_DEBUG_HWERR
- bfin_sti(0x3f);
-#endif
+ unsigned long flags = hard_local_save_flags();
+ if (!hard_irqs_disabled_flags(flags)) {
+ __hard_local_irq_disable();
+ ipipe_trace_begin(0x80000001);
+ }
+ return flags;
}
-#define local_irq_save_hw_notrace(flags) \
- do { \
- local_irq_save_ptr_hw(&(flags)); \
- } while (0)
-
-static inline void local_irq_restore_hw_notrace(unsigned long flags)
+static inline void hard_local_irq_restore(unsigned long flags)
{
- if (!irqs_disabled_flags_hw(flags))
- local_irq_enable_hw_notrace();
+ if (!hard_irqs_disabled_flags(flags)) {
+ ipipe_trace_end(0x80000001);
+ __hard_local_irq_enable();
+ }
}
-#ifdef CONFIG_IPIPE_TRACE_IRQSOFF
-# define local_irq_disable_hw() \
- do { \
- if (!irqs_disabled_hw()) { \
- local_irq_disable_hw_notrace(); \
- ipipe_trace_begin(0x80000000); \
- } \
- } while (0)
-# define local_irq_enable_hw() \
- do { \
- if (irqs_disabled_hw()) { \
- ipipe_trace_end(0x80000000); \
- local_irq_enable_hw_notrace(); \
- } \
- } while (0)
-# define local_irq_save_hw(flags) \
- do { \
- local_save_flags_hw(flags); \
- if (!irqs_disabled_flags_hw(flags)) { \
- local_irq_disable_hw_notrace(); \
- ipipe_trace_begin(0x80000001); \
- } \
- } while (0)
-# define local_irq_restore_hw(flags) \
- do { \
- if (!irqs_disabled_flags_hw(flags)) { \
- ipipe_trace_end(0x80000001); \
- local_irq_enable_hw_notrace(); \
- } \
- } while (0)
#else /* !CONFIG_IPIPE_TRACE_IRQSOFF */
-# define local_irq_disable_hw() local_irq_disable_hw_notrace()
-# define local_irq_enable_hw() local_irq_enable_hw_notrace()
-# define local_irq_save_hw(flags) local_irq_save_hw_notrace(flags)
-# define local_irq_restore_hw(flags) local_irq_restore_hw_notrace(flags)
+# define hard_local_irq_disable() __hard_local_irq_disable()
+# define hard_local_irq_enable() __hard_local_irq_enable()
+# define hard_local_irq_save() __hard_local_irq_save()
+# define hard_local_irq_restore(flags) __hard_local_irq_restore(flags)
#endif /* !CONFIG_IPIPE_TRACE_IRQSOFF */
#else /* CONFIG_IPIPE */
-static inline void raw_local_irq_disable(void)
-{
- bfin_cli();
-}
-static inline void raw_local_irq_enable(void)
-{
- bfin_sti(bfin_irq_flags);
-}
-
-#define raw_local_save_flags(flags) do { (flags) = bfin_read_IMASK(); } while (0)
-
-#define raw_irqs_disabled_flags(flags) (((flags) & ~0x3f) == 0)
+/*
+ * Direct interface to linux/irqflags.h.
+ */
+#define arch_local_save_flags() hard_local_save_flags()
+#define arch_local_irq_save(flags) __hard_local_irq_save()
+#define arch_local_irq_restore(flags) __hard_local_irq_restore(flags)
+#define arch_local_irq_enable() __hard_local_irq_enable()
+#define arch_local_irq_disable() __hard_local_irq_disable()
+#define arch_irqs_disabled_flags(flags) hard_irqs_disabled_flags(flags)
+#define arch_irqs_disabled() hard_irqs_disabled()
-static inline unsigned long __raw_local_irq_save(void)
-{
- unsigned long flags = bfin_cli();
-#ifdef CONFIG_DEBUG_HWERR
- bfin_sti(0x3f);
-#endif
- return flags;
-}
-#define raw_local_irq_save(flags) do { (flags) = __raw_local_irq_save(); } while (0)
+/*
+ * Interface to various arch routines that may be traced.
+ */
+#define hard_local_irq_save() __hard_local_irq_save()
+#define hard_local_irq_restore(flags) __hard_local_irq_restore(flags)
+#define hard_local_irq_enable() __hard_local_irq_enable()
+#define hard_local_irq_disable() __hard_local_irq_disable()
-#define local_irq_save_hw(flags) raw_local_irq_save(flags)
-#define local_irq_restore_hw(flags) raw_local_irq_restore(flags)
-#define local_irq_enable_hw() raw_local_irq_enable()
-#define local_irq_disable_hw() raw_local_irq_disable()
-#define irqs_disabled_hw() irqs_disabled()
#endif /* !CONFIG_IPIPE */
-
-static inline void raw_local_irq_restore(unsigned long flags)
-{
- if (!raw_irqs_disabled_flags(flags))
- raw_local_irq_enable();
-}
-
#endif
diff --git a/arch/blackfin/include/asm/mmu_context.h b/arch/blackfin/include/asm/mmu_context.h
index e1a9b4624f91..3828c70e7a2e 100644
--- a/arch/blackfin/include/asm/mmu_context.h
+++ b/arch/blackfin/include/asm/mmu_context.h
@@ -97,8 +97,8 @@ static inline void __switch_mm(struct mm_struct *prev_mm, struct mm_struct *next
}
#ifdef CONFIG_IPIPE
-#define lock_mm_switch(flags) local_irq_save_hw_cond(flags)
-#define unlock_mm_switch(flags) local_irq_restore_hw_cond(flags)
+#define lock_mm_switch(flags) flags = hard_local_irq_save_cond()
+#define unlock_mm_switch(flags) hard_local_irq_restore_cond(flags)
#else
#define lock_mm_switch(flags) do { (void)(flags); } while (0)
#define unlock_mm_switch(flags) do { (void)(flags); } while (0)
@@ -205,9 +205,9 @@ static inline void destroy_context(struct mm_struct *mm)
}
#define ipipe_mm_switch_protect(flags) \
- local_irq_save_hw_cond(flags)
+ flags = hard_local_irq_save_cond()
#define ipipe_mm_switch_unprotect(flags) \
- local_irq_restore_hw_cond(flags)
+ hard_local_irq_restore_cond(flags)
#endif
diff --git a/arch/blackfin/include/asm/ptrace.h b/arch/blackfin/include/asm/ptrace.h
index aaa1c6c2bc19..832d7c009a2c 100644
--- a/arch/blackfin/include/asm/ptrace.h
+++ b/arch/blackfin/include/asm/ptrace.h
@@ -113,6 +113,9 @@ extern void user_disable_single_step(struct task_struct *child);
/* common code demands this function */
#define ptrace_disable(child) user_disable_single_step(child)
+extern int is_user_addr_valid(struct task_struct *child,
+ unsigned long start, unsigned long len);
+
/*
* Get the address of the live pt_regs for the specified task.
* These are saved onto the top kernel stack when the process
diff --git a/arch/blackfin/include/asm/serial.h b/arch/blackfin/include/asm/serial.h
index 94a4a12e3bf2..a0cb0caff152 100644
--- a/arch/blackfin/include/asm/serial.h
+++ b/arch/blackfin/include/asm/serial.h
@@ -1,2 +1 @@
#include <asm-generic/serial.h>
-#define SERIAL_EXTRA_IRQ_FLAGS IRQF_TRIGGER_HIGH
diff --git a/arch/blackfin/include/asm/system.h b/arch/blackfin/include/asm/system.h
index dde19b1d25f5..19e2c7c3e63a 100644
--- a/arch/blackfin/include/asm/system.h
+++ b/arch/blackfin/include/asm/system.h
@@ -117,7 +117,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
unsigned long tmp = 0;
unsigned long flags;
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
switch (size) {
case 1:
@@ -139,7 +139,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
: "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
break;
}
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
return tmp;
}
diff --git a/arch/blackfin/include/asm/unistd.h b/arch/blackfin/include/asm/unistd.h
index 14fcd254b185..928ae975b87e 100644
--- a/arch/blackfin/include/asm/unistd.h
+++ b/arch/blackfin/include/asm/unistd.h
@@ -392,8 +392,9 @@
#define __NR_fanotify_init 371
#define __NR_fanotify_mark 372
#define __NR_prlimit64 373
+#define __NR_cacheflush 374
-#define __NR_syscall 374
+#define __NR_syscall 375
#define NR_syscalls __NR_syscall
/* Old optional stuff no one actually uses */
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c
index dc07ed08b37f..170cf90735ba 100644
--- a/arch/blackfin/kernel/bfin_gpio.c
+++ b/arch/blackfin/kernel/bfin_gpio.c
@@ -1,7 +1,7 @@
/*
* GPIO Abstraction Layer
*
- * Copyright 2006-2009 Analog Devices Inc.
+ * Copyright 2006-2010 Analog Devices Inc.
*
* Licensed under the GPL-2 or later
*/
@@ -215,82 +215,91 @@ static void port_setup(unsigned gpio, unsigned short usage)
}
#ifdef BF537_FAMILY
-static struct {
- unsigned short res;
- unsigned short offset;
-} port_mux_lut[] = {
- {.res = P_PPI0_D13, .offset = 11},
- {.res = P_PPI0_D14, .offset = 11},
- {.res = P_PPI0_D15, .offset = 11},
- {.res = P_SPORT1_TFS, .offset = 11},
- {.res = P_SPORT1_TSCLK, .offset = 11},
- {.res = P_SPORT1_DTPRI, .offset = 11},
- {.res = P_PPI0_D10, .offset = 10},
- {.res = P_PPI0_D11, .offset = 10},
- {.res = P_PPI0_D12, .offset = 10},
- {.res = P_SPORT1_RSCLK, .offset = 10},
- {.res = P_SPORT1_RFS, .offset = 10},
- {.res = P_SPORT1_DRPRI, .offset = 10},
- {.res = P_PPI0_D8, .offset = 9},
- {.res = P_PPI0_D9, .offset = 9},
- {.res = P_SPORT1_DRSEC, .offset = 9},
- {.res = P_SPORT1_DTSEC, .offset = 9},
- {.res = P_TMR2, .offset = 8},
- {.res = P_PPI0_FS3, .offset = 8},
- {.res = P_TMR3, .offset = 7},
- {.res = P_SPI0_SSEL4, .offset = 7},
- {.res = P_TMR4, .offset = 6},
- {.res = P_SPI0_SSEL5, .offset = 6},
- {.res = P_TMR5, .offset = 5},
- {.res = P_SPI0_SSEL6, .offset = 5},
- {.res = P_UART1_RX, .offset = 4},
- {.res = P_UART1_TX, .offset = 4},
- {.res = P_TMR6, .offset = 4},
- {.res = P_TMR7, .offset = 4},
- {.res = P_UART0_RX, .offset = 3},
- {.res = P_UART0_TX, .offset = 3},
- {.res = P_DMAR0, .offset = 3},
- {.res = P_DMAR1, .offset = 3},
- {.res = P_SPORT0_DTSEC, .offset = 1},
- {.res = P_SPORT0_DRSEC, .offset = 1},
- {.res = P_CAN0_RX, .offset = 1},
- {.res = P_CAN0_TX, .offset = 1},
- {.res = P_SPI0_SSEL7, .offset = 1},
- {.res = P_SPORT0_TFS, .offset = 0},
- {.res = P_SPORT0_DTPRI, .offset = 0},
- {.res = P_SPI0_SSEL2, .offset = 0},
- {.res = P_SPI0_SSEL3, .offset = 0},
+static const s8 port_mux[] = {
+ [GPIO_PF0] = 3,
+ [GPIO_PF1] = 3,
+ [GPIO_PF2] = 4,
+ [GPIO_PF3] = 4,
+ [GPIO_PF4] = 5,
+ [GPIO_PF5] = 6,
+ [GPIO_PF6] = 7,
+ [GPIO_PF7] = 8,
+ [GPIO_PF8 ... GPIO_PF15] = -1,
+ [GPIO_PG0 ... GPIO_PG7] = -1,
+ [GPIO_PG8] = 9,
+ [GPIO_PG9] = 9,
+ [GPIO_PG10] = 10,
+ [GPIO_PG11] = 10,
+ [GPIO_PG12] = 10,
+ [GPIO_PG13] = 11,
+ [GPIO_PG14] = 11,
+ [GPIO_PG15] = 11,
+ [GPIO_PH0 ... GPIO_PH15] = -1,
+ [PORT_PJ0 ... PORT_PJ3] = -1,
+ [PORT_PJ4] = 1,
+ [PORT_PJ5] = 1,
+ [PORT_PJ6 ... PORT_PJ9] = -1,
+ [PORT_PJ10] = 0,
+ [PORT_PJ11] = 0,
};
-static void portmux_setup(unsigned short per)
+static int portmux_group_check(unsigned short per)
{
- u16 y, offset, muxreg;
+ u16 ident = P_IDENT(per);
u16 function = P_FUNCT2MUX(per);
+ s8 offset = port_mux[ident];
+ u16 m, pmux, pfunc;
- for (y = 0; y < ARRAY_SIZE(port_mux_lut); y++) {
- if (port_mux_lut[y].res == per) {
-
- /* SET PORTMUX REG */
-
- offset = port_mux_lut[y].offset;
- muxreg = bfin_read_PORT_MUX();
+ if (offset < 0)
+ return 0;
- if (offset != 1)
- muxreg &= ~(1 << offset);
- else
- muxreg &= ~(3 << 1);
+ pmux = bfin_read_PORT_MUX();
+ for (m = 0; m < ARRAY_SIZE(port_mux); ++m) {
+ if (m == ident)
+ continue;
+ if (port_mux[m] != offset)
+ continue;
+ if (!is_reserved(peri, m, 1))
+ continue;
- muxreg |= (function << offset);
- bfin_write_PORT_MUX(muxreg);
+ if (offset == 1)
+ pfunc = (pmux >> offset) & 3;
+ else
+ pfunc = (pmux >> offset) & 1;
+ if (pfunc != function) {
+ pr_err("pin group conflict! request pin %d func %d conflict with pin %d func %d\n",
+ ident, function, m, pfunc);
+ return -EINVAL;
}
}
+
+ return 0;
+}
+
+static void portmux_setup(unsigned short per)
+{
+ u16 ident = P_IDENT(per);
+ u16 function = P_FUNCT2MUX(per);
+ s8 offset = port_mux[ident];
+ u16 pmux;
+
+ if (offset == -1)
+ return;
+
+ pmux = bfin_read_PORT_MUX();
+ if (offset != 1)
+ pmux &= ~(1 << offset);
+ else
+ pmux &= ~(3 << 1);
+ pmux |= (function << offset);
+ bfin_write_PORT_MUX(pmux);
}
#elif defined(CONFIG_BF54x)
inline void portmux_setup(unsigned short per)
{
- u32 pmux;
u16 ident = P_IDENT(per);
u16 function = P_FUNCT2MUX(per);
+ u32 pmux;
pmux = gpio_array[gpio_bank(ident)]->port_mux;
@@ -302,20 +311,54 @@ inline void portmux_setup(unsigned short per)
inline u16 get_portmux(unsigned short per)
{
- u32 pmux;
u16 ident = P_IDENT(per);
-
- pmux = gpio_array[gpio_bank(ident)]->port_mux;
-
+ u32 pmux = gpio_array[gpio_bank(ident)]->port_mux;
return (pmux >> (2 * gpio_sub_n(ident)) & 0x3);
}
+static int portmux_group_check(unsigned short per)
+{
+ return 0;
+}
#elif defined(CONFIG_BF52x) || defined(CONFIG_BF51x)
+static int portmux_group_check(unsigned short per)
+{
+ u16 ident = P_IDENT(per);
+ u16 function = P_FUNCT2MUX(per);
+ u8 offset = pmux_offset[gpio_bank(ident)][gpio_sub_n(ident)];
+ u16 pin, gpiopin, pfunc;
+
+ for (pin = 0; pin < GPIO_BANKSIZE; ++pin) {
+ if (offset != pmux_offset[gpio_bank(ident)][pin])
+ continue;
+
+ gpiopin = gpio_bank(ident) * GPIO_BANKSIZE + pin;
+ if (gpiopin == ident)
+ continue;
+ if (!is_reserved(peri, gpiopin, 1))
+ continue;
+
+ pfunc = *port_mux[gpio_bank(ident)];
+ pfunc = (pfunc >> offset) & 3;
+ if (pfunc != function) {
+ pr_err("pin group conflict! request pin %d func %d conflict with pin %d func %d\n",
+ ident, function, gpiopin, pfunc);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
inline void portmux_setup(unsigned short per)
{
- u16 pmux, ident = P_IDENT(per), function = P_FUNCT2MUX(per);
+ u16 ident = P_IDENT(per);
+ u16 function = P_FUNCT2MUX(per);
u8 offset = pmux_offset[gpio_bank(ident)][gpio_sub_n(ident)];
+ u16 pmux;
pmux = *port_mux[gpio_bank(ident)];
+ if (((pmux >> offset) & 3) == function)
+ return;
pmux &= ~(3 << offset);
pmux |= (function & 3) << offset;
*port_mux[gpio_bank(ident)] = pmux;
@@ -323,6 +366,10 @@ inline void portmux_setup(unsigned short per)
}
#else
# define portmux_setup(...) do { } while (0)
+static int portmux_group_check(unsigned short per)
+{
+ return 0;
+}
#endif
#ifndef CONFIG_BF54x
@@ -349,13 +396,13 @@ inline void portmux_setup(unsigned short per)
void set_gpio_ ## name(unsigned gpio, unsigned short arg) \
{ \
unsigned long flags; \
- local_irq_save_hw(flags); \
+ flags = hard_local_irq_save(); \
if (arg) \
gpio_array[gpio_bank(gpio)]->name |= gpio_bit(gpio); \
else \
gpio_array[gpio_bank(gpio)]->name &= ~gpio_bit(gpio); \
AWA_DUMMY_READ(name); \
- local_irq_restore_hw(flags); \
+ hard_local_irq_restore(flags); \
} \
EXPORT_SYMBOL(set_gpio_ ## name);
@@ -371,14 +418,14 @@ void set_gpio_ ## name(unsigned gpio, unsigned short arg) \
{ \
unsigned long flags; \
if (ANOMALY_05000311 || ANOMALY_05000323) \
- local_irq_save_hw(flags); \
+ flags = hard_local_irq_save(); \
if (arg) \
gpio_array[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \
else \
gpio_array[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \
if (ANOMALY_05000311 || ANOMALY_05000323) { \
AWA_DUMMY_READ(name); \
- local_irq_restore_hw(flags); \
+ hard_local_irq_restore(flags); \
} \
} \
EXPORT_SYMBOL(set_gpio_ ## name);
@@ -391,11 +438,11 @@ void set_gpio_toggle(unsigned gpio)
{
unsigned long flags;
if (ANOMALY_05000311 || ANOMALY_05000323)
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
gpio_array[gpio_bank(gpio)]->toggle = gpio_bit(gpio);
if (ANOMALY_05000311 || ANOMALY_05000323) {
AWA_DUMMY_READ(toggle);
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
}
}
EXPORT_SYMBOL(set_gpio_toggle);
@@ -408,11 +455,11 @@ void set_gpiop_ ## name(unsigned gpio, unsigned short arg) \
{ \
unsigned long flags; \
if (ANOMALY_05000311 || ANOMALY_05000323) \
- local_irq_save_hw(flags); \
+ flags = hard_local_irq_save(); \
gpio_array[gpio_bank(gpio)]->name = arg; \
if (ANOMALY_05000311 || ANOMALY_05000323) { \
AWA_DUMMY_READ(name); \
- local_irq_restore_hw(flags); \
+ hard_local_irq_restore(flags); \
} \
} \
EXPORT_SYMBOL(set_gpiop_ ## name);
@@ -433,11 +480,11 @@ unsigned short get_gpio_ ## name(unsigned gpio) \
unsigned long flags; \
unsigned short ret; \
if (ANOMALY_05000311 || ANOMALY_05000323) \
- local_irq_save_hw(flags); \
+ flags = hard_local_irq_save(); \
ret = 0x01 & (gpio_array[gpio_bank(gpio)]->name >> gpio_sub_n(gpio)); \
if (ANOMALY_05000311 || ANOMALY_05000323) { \
AWA_DUMMY_READ(name); \
- local_irq_restore_hw(flags); \
+ hard_local_irq_restore(flags); \
} \
return ret; \
} \
@@ -460,11 +507,11 @@ unsigned short get_gpiop_ ## name(unsigned gpio) \
unsigned long flags; \
unsigned short ret; \
if (ANOMALY_05000311 || ANOMALY_05000323) \
- local_irq_save_hw(flags); \
+ flags = hard_local_irq_save(); \
ret = (gpio_array[gpio_bank(gpio)]->name); \
if (ANOMALY_05000311 || ANOMALY_05000323) { \
AWA_DUMMY_READ(name); \
- local_irq_restore_hw(flags); \
+ hard_local_irq_restore(flags); \
} \
return ret; \
} \
@@ -525,14 +572,14 @@ int gpio_pm_wakeup_ctrl(unsigned gpio, unsigned ctrl)
if (check_gpio(gpio) < 0)
return -EINVAL;
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
if (ctrl)
reserve(wakeup, gpio);
else
unreserve(wakeup, gpio);
set_gpio_maskb(gpio, ctrl);
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
return 0;
}
@@ -690,7 +737,7 @@ int peripheral_request(unsigned short per, const char *label)
BUG_ON(ident >= MAX_RESOURCES);
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
/* If a pin can be muxed as either GPIO or peripheral, make
* sure it is not already a GPIO pin when we request it.
@@ -701,7 +748,7 @@ int peripheral_request(unsigned short per, const char *label)
printk(KERN_ERR
"%s: Peripheral %d is already reserved as GPIO by %s !\n",
__func__, ident, get_label(ident));
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
return -EBUSY;
}
@@ -730,18 +777,22 @@ int peripheral_request(unsigned short per, const char *label)
printk(KERN_ERR
"%s: Peripheral %d function %d is already reserved by %s !\n",
__func__, ident, P_FUNCT2MUX(per), get_label(ident));
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
return -EBUSY;
}
}
+ if (unlikely(portmux_group_check(per))) {
+ hard_local_irq_restore(flags);
+ return -EBUSY;
+ }
anyway:
reserve(peri, ident);
portmux_setup(per);
port_setup(ident, PERIPHERAL_USAGE);
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
set_label(ident, label);
return 0;
@@ -780,10 +831,10 @@ void peripheral_free(unsigned short per)
if (!(per & P_DEFINED))
return;
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
if (unlikely(!is_reserved(peri, ident, 0))) {
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
return;
}
@@ -794,7 +845,7 @@ void peripheral_free(unsigned short per)
set_label(ident, "free");
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
}
EXPORT_SYMBOL(peripheral_free);
@@ -828,7 +879,7 @@ int bfin_gpio_request(unsigned gpio, const char *label)
if (check_gpio(gpio) < 0)
return -EINVAL;
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
/*
* Allow that the identical GPIO can
@@ -837,7 +888,7 @@ int bfin_gpio_request(unsigned gpio, const char *label)
*/
if (cmp_label(gpio, label) == 0) {
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
return 0;
}
@@ -846,7 +897,7 @@ int bfin_gpio_request(unsigned gpio, const char *label)
dump_stack();
printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved by %s !\n",
gpio, get_label(gpio));
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
return -EBUSY;
}
if (unlikely(is_reserved(peri, gpio, 1))) {
@@ -855,7 +906,7 @@ int bfin_gpio_request(unsigned gpio, const char *label)
printk(KERN_ERR
"bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n",
gpio, get_label(gpio));
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
return -EBUSY;
}
if (unlikely(is_reserved(gpio_irq, gpio, 1))) {
@@ -871,7 +922,7 @@ int bfin_gpio_request(unsigned gpio, const char *label)
reserve(gpio, gpio);
set_label(gpio, label);
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
port_setup(gpio, GPIO_USAGE);
@@ -888,13 +939,13 @@ void bfin_gpio_free(unsigned gpio)
might_sleep();
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
if (unlikely(!is_reserved(gpio, gpio, 0))) {
if (system_state == SYSTEM_BOOTING)
dump_stack();
gpio_error(gpio);
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
return;
}
@@ -902,7 +953,7 @@ void bfin_gpio_free(unsigned gpio)
set_label(gpio, "free");
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
}
EXPORT_SYMBOL(bfin_gpio_free);
@@ -913,7 +964,7 @@ int bfin_special_gpio_request(unsigned gpio, const char *label)
{
unsigned long flags;
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
/*
* Allow that the identical GPIO can
@@ -922,19 +973,19 @@ int bfin_special_gpio_request(unsigned gpio, const char *label)
*/
if (cmp_label(gpio, label) == 0) {
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
return 0;
}
if (unlikely(is_reserved(special_gpio, gpio, 1))) {
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved by %s !\n",
gpio, get_label(gpio));
return -EBUSY;
}
if (unlikely(is_reserved(peri, gpio, 1))) {
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
printk(KERN_ERR
"bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n",
gpio, get_label(gpio));
@@ -946,7 +997,7 @@ int bfin_special_gpio_request(unsigned gpio, const char *label)
reserve(peri, gpio);
set_label(gpio, label);
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
port_setup(gpio, GPIO_USAGE);
return 0;
@@ -959,18 +1010,18 @@ void bfin_special_gpio_free(unsigned gpio)
might_sleep();
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
if (unlikely(!is_reserved(special_gpio, gpio, 0))) {
gpio_error(gpio);
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
return;
}
unreserve(special_gpio, gpio);
unreserve(peri, gpio);
set_label(gpio, "free");
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
}
EXPORT_SYMBOL(bfin_special_gpio_free);
#endif
@@ -983,7 +1034,7 @@ int bfin_gpio_irq_request(unsigned gpio, const char *label)
if (check_gpio(gpio) < 0)
return -EINVAL;
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
if (unlikely(is_reserved(peri, gpio, 1))) {
if (system_state == SYSTEM_BOOTING)
@@ -991,7 +1042,7 @@ int bfin_gpio_irq_request(unsigned gpio, const char *label)
printk(KERN_ERR
"bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n",
gpio, get_label(gpio));
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
return -EBUSY;
}
if (unlikely(is_reserved(gpio, gpio, 1)))
@@ -1002,7 +1053,7 @@ int bfin_gpio_irq_request(unsigned gpio, const char *label)
reserve(gpio_irq, gpio);
set_label(gpio, label);
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
port_setup(gpio, GPIO_USAGE);
@@ -1016,13 +1067,13 @@ void bfin_gpio_irq_free(unsigned gpio)
if (check_gpio(gpio) < 0)
return;
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
if (unlikely(!is_reserved(gpio_irq, gpio, 0))) {
if (system_state == SYSTEM_BOOTING)
dump_stack();
gpio_error(gpio);
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
return;
}
@@ -1030,7 +1081,7 @@ void bfin_gpio_irq_free(unsigned gpio)
set_label(gpio, "free");
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
}
static inline void __bfin_gpio_direction_input(unsigned gpio)
@@ -1052,10 +1103,10 @@ int bfin_gpio_direction_input(unsigned gpio)
return -EINVAL;
}
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
__bfin_gpio_direction_input(gpio);
AWA_DUMMY_READ(inen);
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
return 0;
}
@@ -1070,9 +1121,9 @@ void bfin_gpio_irq_prepare(unsigned gpio)
port_setup(gpio, GPIO_USAGE);
#ifdef CONFIG_BF54x
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
__bfin_gpio_direction_input(gpio);
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
#endif
}
@@ -1094,7 +1145,7 @@ int bfin_gpio_direction_output(unsigned gpio, int value)
return -EINVAL;
}
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio);
gpio_set_value(gpio, value);
@@ -1105,7 +1156,7 @@ int bfin_gpio_direction_output(unsigned gpio, int value)
#endif
AWA_DUMMY_READ(dir);
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
return 0;
}
@@ -1120,11 +1171,11 @@ int bfin_gpio_get_value(unsigned gpio)
if (unlikely(get_gpio_edge(gpio))) {
int ret;
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
set_gpio_edge(gpio, 0);
ret = get_gpio_data(gpio);
set_gpio_edge(gpio, 1);
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
return ret;
} else
return get_gpio_data(gpio);
diff --git a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
index 87b25b1b30ed..8de92299b3ee 100644
--- a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
+++ b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
@@ -318,7 +318,7 @@ void flush_switched_cplbs(unsigned int cpu)
nr_cplb_flush[cpu]++;
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
_disable_icplb();
for (i = first_switched_icplb; i < MAX_CPLBS; i++) {
icplb_tbl[cpu][i].data = 0;
@@ -332,7 +332,7 @@ void flush_switched_cplbs(unsigned int cpu)
bfin_write32(DCPLB_DATA0 + i * 4, 0);
}
_enable_dcplb();
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
}
@@ -348,7 +348,7 @@ void set_mask_dcplbs(unsigned long *masks, unsigned int cpu)
return;
}
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
current_rwx_mask[cpu] = masks;
if (L2_LENGTH && addr >= L2_START && addr < L2_START + L2_LENGTH) {
@@ -373,5 +373,5 @@ void set_mask_dcplbs(unsigned long *masks, unsigned int cpu)
addr += PAGE_SIZE;
}
_enable_dcplb();
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
}
diff --git a/arch/blackfin/kernel/ipipe.c b/arch/blackfin/kernel/ipipe.c
index 1a496cd71ba2..3b1da4aff2a1 100644
--- a/arch/blackfin/kernel/ipipe.c
+++ b/arch/blackfin/kernel/ipipe.c
@@ -219,10 +219,10 @@ int __ipipe_syscall_root(struct pt_regs *regs)
ret = __ipipe_dispatch_event(IPIPE_EVENT_SYSCALL, regs);
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
if (!__ipipe_root_domain_p) {
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
return 1;
}
@@ -230,7 +230,7 @@ int __ipipe_syscall_root(struct pt_regs *regs)
if ((p->irqpend_himask & IPIPE_IRQMASK_VIRT) != 0)
__ipipe_sync_pipeline(IPIPE_IRQMASK_VIRT);
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
return -ret;
}
@@ -239,14 +239,14 @@ unsigned long ipipe_critical_enter(void (*syncfn) (void))
{
unsigned long flags;
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
return flags;
}
void ipipe_critical_exit(unsigned long flags)
{
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
}
static void __ipipe_no_irqtail(void)
@@ -279,9 +279,9 @@ int ipipe_trigger_irq(unsigned irq)
return -EINVAL;
#endif
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
__ipipe_handle_irq(irq, NULL);
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
return 1;
}
@@ -293,7 +293,7 @@ asmlinkage void __ipipe_sync_root(void)
BUG_ON(irqs_disabled());
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
if (irq_tail_hook)
irq_tail_hook();
@@ -303,7 +303,7 @@ asmlinkage void __ipipe_sync_root(void)
if (ipipe_root_cpudom_var(irqpend_himask) != 0)
__ipipe_sync_pipeline(IPIPE_IRQMASK_ANY);
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
}
void ___ipipe_sync_pipeline(unsigned long syncmask)
@@ -344,10 +344,10 @@ void __ipipe_stall_root(void)
{
unsigned long *p, flags;
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
p = &__ipipe_root_status;
__set_bit(IPIPE_STALL_FLAG, p);
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
}
EXPORT_SYMBOL(__ipipe_stall_root);
@@ -356,10 +356,10 @@ unsigned long __ipipe_test_and_stall_root(void)
unsigned long *p, flags;
int x;
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
p = &__ipipe_root_status;
x = __test_and_set_bit(IPIPE_STALL_FLAG, p);
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
return x;
}
@@ -371,10 +371,10 @@ unsigned long __ipipe_test_root(void)
unsigned long flags;
int x;
- local_irq_save_hw_smp(flags);
+ flags = hard_local_irq_save_smp();
p = &__ipipe_root_status;
x = test_bit(IPIPE_STALL_FLAG, p);
- local_irq_restore_hw_smp(flags);
+ hard_local_irq_restore_smp(flags);
return x;
}
@@ -384,10 +384,10 @@ void __ipipe_lock_root(void)
{
unsigned long *p, flags;
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
p = &__ipipe_root_status;
__set_bit(IPIPE_SYNCDEFER_FLAG, p);
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
}
EXPORT_SYMBOL(__ipipe_lock_root);
@@ -395,9 +395,9 @@ void __ipipe_unlock_root(void)
{
unsigned long *p, flags;
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
p = &__ipipe_root_status;
__clear_bit(IPIPE_SYNCDEFER_FLAG, p);
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
}
EXPORT_SYMBOL(__ipipe_unlock_root);
diff --git a/arch/blackfin/kernel/kgdb_test.c b/arch/blackfin/kernel/kgdb_test.c
index 9a4b07594389..08c0236acf3c 100644
--- a/arch/blackfin/kernel/kgdb_test.c
+++ b/arch/blackfin/kernel/kgdb_test.c
@@ -88,6 +88,7 @@ static const struct file_operations kgdb_test_proc_fops = {
.owner = THIS_MODULE,
.read = kgdb_test_proc_read,
.write = kgdb_test_proc_write,
+ .llseek = noop_llseek,
};
static int __init kgdbtest_init(void)
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c
index 01f98cb964d2..cd0c090ebc54 100644
--- a/arch/blackfin/kernel/process.c
+++ b/arch/blackfin/kernel/process.c
@@ -65,11 +65,11 @@ static void default_idle(void)
#ifdef CONFIG_IPIPE
ipipe_suspend_domain();
#endif
- local_irq_disable_hw();
+ hard_local_irq_disable();
if (!need_resched())
idle_with_irq_disabled();
- local_irq_enable_hw();
+ hard_local_irq_enable();
}
/*
@@ -493,6 +493,11 @@ int _access_ok(unsigned long addr, unsigned long size)
return 1;
#endif
+#ifndef CONFIG_EXCEPTION_L1_SCRATCH
+ if (in_mem_const(addr, size, (unsigned long)l1_stack_base, l1_stack_len))
+ return 1;
+#endif
+
aret = in_async(addr, size);
if (aret < 2)
return aret;
diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c
index 6ec77685df52..b35839354130 100644
--- a/arch/blackfin/kernel/ptrace.c
+++ b/arch/blackfin/kernel/ptrace.c
@@ -27,6 +27,7 @@
#include <asm/fixed_code.h>
#include <asm/cacheflush.h>
#include <asm/mem_map.h>
+#include <asm/mmu_context.h>
/*
* does not yet catch signals sent when the child dies.
@@ -113,8 +114,8 @@ put_reg(struct task_struct *task, long regno, unsigned long data)
/*
* check that an address falls within the bounds of the target process's memory mappings
*/
-static inline int is_user_addr_valid(struct task_struct *child,
- unsigned long start, unsigned long len)
+int
+is_user_addr_valid(struct task_struct *child, unsigned long start, unsigned long len)
{
struct vm_area_struct *vma;
struct sram_list_struct *sraml;
@@ -135,6 +136,13 @@ static inline int is_user_addr_valid(struct task_struct *child,
if (start >= FIXED_CODE_START && start + len < FIXED_CODE_END)
return 0;
+#ifdef CONFIG_APP_STACK_L1
+ if (child->mm->context.l1_stack_save)
+ if (start >= (unsigned long)l1_stack_base &&
+ start + len < (unsigned long)l1_stack_base + l1_stack_len)
+ return 0;
+#endif
+
return -EIO;
}
diff --git a/arch/blackfin/kernel/sys_bfin.c b/arch/blackfin/kernel/sys_bfin.c
index bdc1e2f0da32..89448ed7065d 100644
--- a/arch/blackfin/kernel/sys_bfin.c
+++ b/arch/blackfin/kernel/sys_bfin.c
@@ -21,6 +21,8 @@
#include <asm/cacheflush.h>
#include <asm/dma.h>
+#include <asm/cachectl.h>
+#include <asm/ptrace.h>
asmlinkage void *sys_sram_alloc(size_t size, unsigned long flags)
{
@@ -70,3 +72,16 @@ asmlinkage int sys_bfin_spinlock(int *p)
return ret;
}
+
+SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, len, int, op)
+{
+ if (is_user_addr_valid(current, addr, len) != 0)
+ return -EINVAL;
+
+ if (op & DCACHE)
+ blackfin_dcache_flush_range(addr, addr + len);
+ if (op & ICACHE)
+ blackfin_icache_flush_range(addr, addr + len);
+
+ return 0;
+}
diff --git a/arch/blackfin/kernel/trace.c b/arch/blackfin/kernel/trace.c
index 59fcdf6b0138..05b550891ce5 100644
--- a/arch/blackfin/kernel/trace.c
+++ b/arch/blackfin/kernel/trace.c
@@ -15,6 +15,7 @@
#include <linux/kallsyms.h>
#include <linux/err.h>
#include <linux/fs.h>
+#include <linux/irq.h>
#include <asm/dma.h>
#include <asm/trace.h>
#include <asm/fixed_code.h>
diff --git a/arch/blackfin/mach-bf518/boards/ezbrd.c b/arch/blackfin/mach-bf518/boards/ezbrd.c
index 44d6d5299022..f95e6096719b 100644
--- a/arch/blackfin/mach-bf518/boards/ezbrd.c
+++ b/arch/blackfin/mach-bf518/boards/ezbrd.c
@@ -312,7 +312,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
/* SPI (0) */
static struct bfin5xx_spi_master bfin_spi0_info = {
- .num_chipselect = 5,
+ .num_chipselect = 6,
.enable_dma = 1, /* master has the ability to do dma transfer */
.pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0},
};
@@ -347,7 +347,7 @@ static struct platform_device bfin_spi0_device = {
/* SPI (1) */
static struct bfin5xx_spi_master bfin_spi1_info = {
- .num_chipselect = 5,
+ .num_chipselect = 6,
.enable_dma = 1, /* master has the ability to do dma transfer */
.pin_req = {P_SPI1_SCK, P_SPI1_MISO, P_SPI1_MOSI, 0},
};
@@ -525,6 +525,14 @@ static struct platform_device bfin_sir1_device = {
#endif
#endif
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+static struct platform_device bfin_i2s = {
+ .name = "bfin-i2s",
+ .id = CONFIG_SND_BF5XX_SPORT_NUM,
+ /* TODO: add platform data here */
+};
+#endif
+
#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
static struct resource bfin_twi0_resource[] = {
[0] = {
@@ -559,6 +567,11 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
.irq = IRQ_PF8,
},
#endif
+#if defined(CONFIG_SND_SOC_SSM2602) || defined(CONFIG_SND_SOC_SSM2602_MODULE)
+ {
+ I2C_BOARD_INFO("ssm2602", 0x1b),
+ },
+#endif
};
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
@@ -736,6 +749,10 @@ static struct platform_device *stamp_devices[] __initdata = {
&i2c_bfin_twi_device,
#endif
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+ &bfin_i2s,
+#endif
+
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
&bfin_sport0_uart_device,
diff --git a/arch/blackfin/mach-bf518/boards/tcm-bf518.c b/arch/blackfin/mach-bf518/boards/tcm-bf518.c
index 9b72e5cb21fe..bead810a6546 100644
--- a/arch/blackfin/mach-bf518/boards/tcm-bf518.c
+++ b/arch/blackfin/mach-bf518/boards/tcm-bf518.c
@@ -291,7 +291,7 @@ static struct platform_device bfin_spi0_device = {
/* SPI (1) */
static struct bfin5xx_spi_master bfin_spi1_info = {
- .num_chipselect = 5,
+ .num_chipselect = 6,
.enable_dma = 1, /* master has the ability to do dma transfer */
.pin_req = {P_SPI1_SCK, P_SPI1_MISO, P_SPI1_MOSI, 0},
};
diff --git a/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h b/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h
index e548e9d1d6fa..e16969f24ffd 100644
--- a/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h
+++ b/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h
@@ -262,14 +262,14 @@
#define bfin_write_SPORT0_TX(val) bfin_write32(SPORT0_TX, val)
#define bfin_read_SPORT0_RX() bfin_read32(SPORT0_RX)
#define bfin_write_SPORT0_RX(val) bfin_write32(SPORT0_RX, val)
-#define bfin_read_SPORT0_TX32() bfin_read32(SPORT0_TX32)
-#define bfin_write_SPORT0_TX32(val) bfin_write32(SPORT0_TX32, val)
-#define bfin_read_SPORT0_RX32() bfin_read32(SPORT0_RX32)
-#define bfin_write_SPORT0_RX32(val) bfin_write32(SPORT0_RX32, val)
-#define bfin_read_SPORT0_TX16() bfin_read16(SPORT0_TX16)
-#define bfin_write_SPORT0_TX16(val) bfin_write16(SPORT0_TX16, val)
-#define bfin_read_SPORT0_RX16() bfin_read16(SPORT0_RX16)
-#define bfin_write_SPORT0_RX16(val) bfin_write16(SPORT0_RX16, val)
+#define bfin_read_SPORT0_TX32() bfin_read32(SPORT0_TX)
+#define bfin_write_SPORT0_TX32(val) bfin_write32(SPORT0_TX, val)
+#define bfin_read_SPORT0_RX32() bfin_read32(SPORT0_RX)
+#define bfin_write_SPORT0_RX32(val) bfin_write32(SPORT0_RX, val)
+#define bfin_read_SPORT0_TX16() bfin_read16(SPORT0_TX)
+#define bfin_write_SPORT0_TX16(val) bfin_write16(SPORT0_TX, val)
+#define bfin_read_SPORT0_RX16() bfin_read16(SPORT0_RX)
+#define bfin_write_SPORT0_RX16(val) bfin_write16(SPORT0_RX, val)
#define bfin_read_SPORT0_RCR1() bfin_read16(SPORT0_RCR1)
#define bfin_write_SPORT0_RCR1(val) bfin_write16(SPORT0_RCR1, val)
#define bfin_read_SPORT0_RCR2() bfin_read16(SPORT0_RCR2)
@@ -317,14 +317,14 @@
#define bfin_write_SPORT1_TX(val) bfin_write32(SPORT1_TX, val)
#define bfin_read_SPORT1_RX() bfin_read32(SPORT1_RX)
#define bfin_write_SPORT1_RX(val) bfin_write32(SPORT1_RX, val)
-#define bfin_read_SPORT1_TX32() bfin_read32(SPORT1_TX32)
-#define bfin_write_SPORT1_TX32(val) bfin_write32(SPORT1_TX32, val)
-#define bfin_read_SPORT1_RX32() bfin_read32(SPORT1_RX32)
-#define bfin_write_SPORT1_RX32(val) bfin_write32(SPORT1_RX32, val)
-#define bfin_read_SPORT1_TX16() bfin_read16(SPORT1_TX16)
-#define bfin_write_SPORT1_TX16(val) bfin_write16(SPORT1_TX16, val)
-#define bfin_read_SPORT1_RX16() bfin_read16(SPORT1_RX16)
-#define bfin_write_SPORT1_RX16(val) bfin_write16(SPORT1_RX16, val)
+#define bfin_read_SPORT1_TX32() bfin_read32(SPORT1_TX)
+#define bfin_write_SPORT1_TX32(val) bfin_write32(SPORT1_TX, val)
+#define bfin_read_SPORT1_RX32() bfin_read32(SPORT1_RX)
+#define bfin_write_SPORT1_RX32(val) bfin_write32(SPORT1_RX, val)
+#define bfin_read_SPORT1_TX16() bfin_read16(SPORT1_TX)
+#define bfin_write_SPORT1_TX16(val) bfin_write16(SPORT1_TX, val)
+#define bfin_read_SPORT1_RX16() bfin_read16(SPORT1_RX)
+#define bfin_write_SPORT1_RX16(val) bfin_write16(SPORT1_RX, val)
#define bfin_read_SPORT1_RCR1() bfin_read16(SPORT1_RCR1)
#define bfin_write_SPORT1_RCR1(val) bfin_write16(SPORT1_RCR1, val)
#define bfin_read_SPORT1_RCR2() bfin_read16(SPORT1_RCR2)
@@ -1058,54 +1058,4 @@
/* These need to be last due to the cdef/linux inter-dependencies */
#include <asm/irq.h>
-/* Writing to PLL_CTL initiates a PLL relock sequence. */
-static __inline__ void bfin_write_PLL_CTL(unsigned int val)
-{
- unsigned long flags, iwr0, iwr1;
-
- if (val == bfin_read_PLL_CTL())
- return;
-
- local_irq_save_hw(flags);
- /* Enable the PLL Wakeup bit in SIC IWR */
- iwr0 = bfin_read32(SIC_IWR0);
- iwr1 = bfin_read32(SIC_IWR1);
- /* Only allow PPL Wakeup) */
- bfin_write32(SIC_IWR0, IWR_ENABLE(0));
- bfin_write32(SIC_IWR1, 0);
-
- bfin_write16(PLL_CTL, val);
- SSYNC();
- asm("IDLE;");
-
- bfin_write32(SIC_IWR0, iwr0);
- bfin_write32(SIC_IWR1, iwr1);
- local_irq_restore_hw(flags);
-}
-
-/* Writing to VR_CTL initiates a PLL relock sequence. */
-static __inline__ void bfin_write_VR_CTL(unsigned int val)
-{
- unsigned long flags, iwr0, iwr1;
-
- if (val == bfin_read_VR_CTL())
- return;
-
- local_irq_save_hw(flags);
- /* Enable the PLL Wakeup bit in SIC IWR */
- iwr0 = bfin_read32(SIC_IWR0);
- iwr1 = bfin_read32(SIC_IWR1);
- /* Only allow PPL Wakeup) */
- bfin_write32(SIC_IWR0, IWR_ENABLE(0));
- bfin_write32(SIC_IWR1, 0);
-
- bfin_write16(VR_CTL, val);
- SSYNC();
- asm("IDLE;");
-
- bfin_write32(SIC_IWR0, iwr0);
- bfin_write32(SIC_IWR1, iwr1);
- local_irq_restore_hw(flags);
-}
-
#endif /* _CDEF_BF52X_H */
diff --git a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h b/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h
index 037a51fd8e93..5f84913dcd91 100644
--- a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h
+++ b/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h
@@ -748,51 +748,6 @@
#define FFE 0x20 /* Force Framing Error On Transmit */
-/* *********** SERIAL PERIPHERAL INTERFACE (SPI) MASKS ****************************/
-/* SPI_CTL Masks */
-#define TIMOD 0x0003 /* Transfer Initiate Mode */
-#define RDBR_CORE 0x0000 /* RDBR Read Initiates, IRQ When RDBR Full */
-#define TDBR_CORE 0x0001 /* TDBR Write Initiates, IRQ When TDBR Empty */
-#define RDBR_DMA 0x0002 /* DMA Read, DMA Until FIFO Empty */
-#define TDBR_DMA 0x0003 /* DMA Write, DMA Until FIFO Full */
-#define SZ 0x0004 /* Send Zero (When TDBR Empty, Send Zero/Last*) */
-#define GM 0x0008 /* Get More (When RDBR Full, Overwrite/Discard*) */
-#define PSSE 0x0010 /* Slave-Select Input Enable */
-#define EMISO 0x0020 /* Enable MISO As Output */
-#define SIZE 0x0100 /* Size of Words (16/8* Bits) */
-#define LSBF 0x0200 /* LSB First */
-#define CPHA 0x0400 /* Clock Phase */
-#define CPOL 0x0800 /* Clock Polarity */
-#define MSTR 0x1000 /* Master/Slave* */
-#define WOM 0x2000 /* Write Open Drain Master */
-#define SPE 0x4000 /* SPI Enable */
-
-/* SPI_FLG Masks */
-#define FLS1 0x0002 /* Enables SPI_FLOUT1 as SPI Slave-Select Output */
-#define FLS2 0x0004 /* Enables SPI_FLOUT2 as SPI Slave-Select Output */
-#define FLS3 0x0008 /* Enables SPI_FLOUT3 as SPI Slave-Select Output */
-#define FLS4 0x0010 /* Enables SPI_FLOUT4 as SPI Slave-Select Output */
-#define FLS5 0x0020 /* Enables SPI_FLOUT5 as SPI Slave-Select Output */
-#define FLS6 0x0040 /* Enables SPI_FLOUT6 as SPI Slave-Select Output */
-#define FLS7 0x0080 /* Enables SPI_FLOUT7 as SPI Slave-Select Output */
-#define FLG1 0xFDFF /* Activates SPI_FLOUT1 */
-#define FLG2 0xFBFF /* Activates SPI_FLOUT2 */
-#define FLG3 0xF7FF /* Activates SPI_FLOUT3 */
-#define FLG4 0xEFFF /* Activates SPI_FLOUT4 */
-#define FLG5 0xDFFF /* Activates SPI_FLOUT5 */
-#define FLG6 0xBFFF /* Activates SPI_FLOUT6 */
-#define FLG7 0x7FFF /* Activates SPI_FLOUT7 */
-
-/* SPI_STAT Masks */
-#define SPIF 0x0001 /* SPI Finished (Single-Word Transfer Complete) */
-#define MODF 0x0002 /* Mode Fault Error (Another Device Tried To Become Master) */
-#define TXE 0x0004 /* Transmission Error (Data Sent With No New Data In TDBR) */
-#define TXS 0x0008 /* SPI_TDBR Data Buffer Status (Full/Empty*) */
-#define RBSY 0x0010 /* Receive Error (Data Received With RDBR Full) */
-#define RXS 0x0020 /* SPI_RDBR Data Buffer Status (Full/Empty*) */
-#define TXCOL 0x0040 /* Transmit Collision Error (Corrupt Data May Have Been Sent) */
-
-
/* **************** GENERAL PURPOSE TIMER MASKS **********************/
/* TIMER_ENABLE Masks */
#define TIMEN0 0x0001 /* Enable Timer 0 */
diff --git a/arch/blackfin/mach-bf518/include/mach/pll.h b/arch/blackfin/mach-bf518/include/mach/pll.h
new file mode 100644
index 000000000000..d5502988896b
--- /dev/null
+++ b/arch/blackfin/mach-bf518/include/mach/pll.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later
+ */
+
+#ifndef _MACH_PLL_H
+#define _MACH_PLL_H
+
+#include <asm/blackfin.h>
+#include <asm/irqflags.h>
+
+/* Writing to PLL_CTL initiates a PLL relock sequence. */
+static __inline__ void bfin_write_PLL_CTL(unsigned int val)
+{
+ unsigned long flags, iwr0, iwr1;
+
+ if (val == bfin_read_PLL_CTL())
+ return;
+
+ flags = hard_local_irq_save();
+ /* Enable the PLL Wakeup bit in SIC IWR */
+ iwr0 = bfin_read32(SIC_IWR0);
+ iwr1 = bfin_read32(SIC_IWR1);
+ /* Only allow PPL Wakeup) */
+ bfin_write32(SIC_IWR0, IWR_ENABLE(0));
+ bfin_write32(SIC_IWR1, 0);
+
+ bfin_write16(PLL_CTL, val);
+ SSYNC();
+ asm("IDLE;");
+
+ bfin_write32(SIC_IWR0, iwr0);
+ bfin_write32(SIC_IWR1, iwr1);
+ hard_local_irq_restore(flags);
+}
+
+/* Writing to VR_CTL initiates a PLL relock sequence. */
+static __inline__ void bfin_write_VR_CTL(unsigned int val)
+{
+ unsigned long flags, iwr0, iwr1;
+
+ if (val == bfin_read_VR_CTL())
+ return;
+
+ flags = hard_local_irq_save();
+ /* Enable the PLL Wakeup bit in SIC IWR */
+ iwr0 = bfin_read32(SIC_IWR0);
+ iwr1 = bfin_read32(SIC_IWR1);
+ /* Only allow PPL Wakeup) */
+ bfin_write32(SIC_IWR0, IWR_ENABLE(0));
+ bfin_write32(SIC_IWR1, 0);
+
+ bfin_write16(VR_CTL, val);
+ SSYNC();
+ asm("IDLE;");
+
+ bfin_write32(SIC_IWR0, iwr0);
+ bfin_write32(SIC_IWR1, iwr1);
+ hard_local_irq_restore(flags);
+}
+
+#endif /* _MACH_PLL_H */
diff --git a/arch/blackfin/mach-bf527/boards/Kconfig b/arch/blackfin/mach-bf527/boards/Kconfig
index b14c28810a44..1cc2667c10f1 100644
--- a/arch/blackfin/mach-bf527/boards/Kconfig
+++ b/arch/blackfin/mach-bf527/boards/Kconfig
@@ -24,4 +24,14 @@ config BFIN526_EZBRD
help
BF526-EZBRD/EZKIT Lite board support.
+config BFIN527_AD7160EVAL
+ bool "BF527-AD7160-EVAL"
+ help
+ BF527-AD7160-EVAL board support.
+
+config BFIN527_TLL6527M
+ bool "The Learning Labs TLL6527M"
+ help
+ TLL6527M V1.0 platform support
+
endchoice
diff --git a/arch/blackfin/mach-bf527/boards/Makefile b/arch/blackfin/mach-bf527/boards/Makefile
index 51a5817c4a90..1d67da9f05ac 100644
--- a/arch/blackfin/mach-bf527/boards/Makefile
+++ b/arch/blackfin/mach-bf527/boards/Makefile
@@ -6,3 +6,5 @@ obj-$(CONFIG_BFIN527_EZKIT) += ezkit.o
obj-$(CONFIG_BFIN527_EZKIT_V2) += ezkit.o
obj-$(CONFIG_BFIN527_BLUETECHNIX_CM) += cm_bf527.o
obj-$(CONFIG_BFIN526_EZBRD) += ezbrd.o
+obj-$(CONFIG_BFIN527_AD7160EVAL) += ad7160eval.o
+obj-$(CONFIG_BFIN527_TLL6527M) += tll6527m.o
diff --git a/arch/blackfin/mach-bf527/boards/ad7160eval.c b/arch/blackfin/mach-bf527/boards/ad7160eval.c
new file mode 100644
index 000000000000..fc767ac76381
--- /dev/null
+++ b/arch/blackfin/mach-bf527/boards/ad7160eval.c
@@ -0,0 +1,870 @@
+/*
+ * Copyright 2004-20010 Analog Devices Inc.
+ * 2005 National ICT Australia (NICTA)
+ * Aidan Williams <aidan@nicta.com.au>
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/usb/musb.h>
+#include <linux/leds.h>
+#include <linux/input.h>
+#include <asm/dma.h>
+#include <asm/bfin5xx_spi.h>
+#include <asm/reboot.h>
+#include <asm/nand.h>
+#include <asm/portmux.h>
+#include <asm/dpmc.h>
+
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+const char bfin_board_name[] = "ADI BF527-AD7160EVAL";
+
+/*
+ * Driver needs to know address, irq and flag pin.
+ */
+
+#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE)
+static struct resource musb_resources[] = {
+ [0] = {
+ .start = 0xffc03800,
+ .end = 0xffc03cff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = { /* general IRQ */
+ .start = IRQ_USB_INT0,
+ .end = IRQ_USB_INT0,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+ [2] = { /* DMA IRQ */
+ .start = IRQ_USB_DMA,
+ .end = IRQ_USB_DMA,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct musb_hdrc_config musb_config = {
+ .multipoint = 0,
+ .dyn_fifo = 0,
+ .soft_con = 1,
+ .dma = 1,
+ .num_eps = 8,
+ .dma_channels = 8,
+ .gpio_vrsel = GPIO_PG13,
+ /* Some custom boards need to be active low, just set it to "0"
+ * if it is the case.
+ */
+ .gpio_vrsel_active = 1,
+};
+
+static struct musb_hdrc_platform_data musb_plat = {
+#if defined(CONFIG_USB_MUSB_OTG)
+ .mode = MUSB_OTG,
+#elif defined(CONFIG_USB_MUSB_HDRC_HCD)
+ .mode = MUSB_HOST,
+#elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
+ .mode = MUSB_PERIPHERAL,
+#endif
+ .config = &musb_config,
+};
+
+static u64 musb_dmamask = ~(u32)0;
+
+static struct platform_device musb_device = {
+ .name = "musb_hdrc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &musb_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &musb_plat,
+ },
+ .num_resources = ARRAY_SIZE(musb_resources),
+ .resource = musb_resources,
+};
+#endif
+
+#if defined(CONFIG_FB_BFIN_RA158Z) || defined(CONFIG_FB_BFIN_RA158Z_MODULE)
+static struct resource bf52x_ra158z_resources[] = {
+ {
+ .start = IRQ_PPI_ERROR,
+ .end = IRQ_PPI_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bf52x_ra158z_device = {
+ .name = "bfin-ra158z",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(bf52x_ra158z_resources),
+ .resource = bf52x_ra158z_resources,
+};
+#endif
+
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct mtd_partition ad7160eval_partitions[] = {
+ {
+ .name = "bootloader(nor)",
+ .size = 0x40000,
+ .offset = 0,
+ }, {
+ .name = "linux kernel(nor)",
+ .size = 0x1C0000,
+ .offset = MTDPART_OFS_APPEND,
+ }, {
+ .name = "file system(nor)",
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
+ }
+};
+
+static struct physmap_flash_data ad7160eval_flash_data = {
+ .width = 2,
+ .parts = ad7160eval_partitions,
+ .nr_parts = ARRAY_SIZE(ad7160eval_partitions),
+};
+
+static struct resource ad7160eval_flash_resource = {
+ .start = 0x20000000,
+ .end = 0x203fffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device ad7160eval_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &ad7160eval_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &ad7160eval_flash_resource,
+};
+#endif
+
+#if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE)
+static struct mtd_partition partition_info[] = {
+ {
+ .name = "linux kernel(nand)",
+ .offset = 0,
+ .size = 4 * 1024 * 1024,
+ },
+ {
+ .name = "file system(nand)",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct bf5xx_nand_platform bf5xx_nand_platform = {
+ .data_width = NFC_NWIDTH_8,
+ .partitions = partition_info,
+ .nr_partitions = ARRAY_SIZE(partition_info),
+ .rd_dly = 3,
+ .wr_dly = 3,
+};
+
+static struct resource bf5xx_nand_resources[] = {
+ {
+ .start = NFC_CTL,
+ .end = NFC_DATA_RD + 2,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = CH_NFC,
+ .end = CH_NFC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bf5xx_nand_device = {
+ .name = "bf5xx-nand",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bf5xx_nand_resources),
+ .resource = bf5xx_nand_resources,
+ .dev = {
+ .platform_data = &bf5xx_nand_platform,
+ },
+};
+#endif
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+static struct platform_device rtc_device = {
+ .name = "rtc-bfin",
+ .id = -1,
+};
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+#include <linux/bfin_mac.h>
+static const unsigned short bfin_mac_peripherals[] = P_RMII0;
+
+static struct bfin_phydev_platform_data bfin_phydev_data[] = {
+ {
+ .addr = 1,
+ .irq = IRQ_MAC_PHYINT,
+ },
+};
+
+static struct bfin_mii_bus_platform_data bfin_mii_bus_data = {
+ .phydev_number = 1,
+ .phydev_data = bfin_phydev_data,
+ .phy_mode = PHY_INTERFACE_MODE_RMII,
+ .mac_peripherals = bfin_mac_peripherals,
+};
+
+static struct platform_device bfin_mii_bus = {
+ .name = "bfin_mii_bus",
+ .dev = {
+ .platform_data = &bfin_mii_bus_data,
+ }
+};
+
+static struct platform_device bfin_mac_device = {
+ .name = "bfin_mac",
+ .dev = {
+ .platform_data = &bfin_mii_bus,
+ }
+};
+#endif
+
+
+#if defined(CONFIG_MTD_M25P80) \
+ || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition bfin_spi_flash_partitions[] = {
+ {
+ .name = "bootloader(spi)",
+ .size = 0x00040000,
+ .offset = 0,
+ .mask_flags = MTD_CAP_ROM
+ }, {
+ .name = "linux kernel(spi)",
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
+ }
+};
+
+static struct flash_platform_data bfin_spi_flash_data = {
+ .name = "m25p80",
+ .parts = bfin_spi_flash_partitions,
+ .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
+ .type = "m25p16",
+};
+
+/* SPI flash chip (m25p64) */
+static struct bfin5xx_spi_chip spi_flash_chip_info = {
+ .enable_dma = 0, /* use dma transfer with this chip*/
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) \
+ || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
+static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
+static struct bfin5xx_spi_chip mmc_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
+static struct bfin5xx_spi_chip spidev_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+static struct platform_device bfin_i2s = {
+ .name = "bfin-i2s",
+ .id = CONFIG_SND_BF5XX_SPORT_NUM,
+ /* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+static struct platform_device bfin_tdm = {
+ .name = "bfin-tdm",
+ .id = CONFIG_SND_BF5XX_SPORT_NUM,
+ /* TODO: add platform data here */
+};
+#endif
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80) \
+ || defined(CONFIG_MTD_M25P80_MODULE)
+ {
+ /* the modalias must be the same as spi device driver name */
+ .modalias = "m25p80", /* Name of spi_driver for this device */
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0, /* Framework bus number */
+ .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/
+ .platform_data = &bfin_spi_flash_data,
+ .controller_data = &spi_flash_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) \
+ || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
+ {
+ .modalias = "ad183x",
+ .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 4,
+ .controller_data = &ad1836_spi_chip_info,
+ },
+#endif
+#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
+ {
+ .modalias = "mmc_spi",
+ .max_speed_hz = 30000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = GPIO_PH3 + MAX_CTRL_CS,
+ .controller_data = &mmc_spi_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
+ {
+ .modalias = "spidev",
+ .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 1,
+ .controller_data = &spidev_chip_info,
+ },
+#endif
+};
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* SPI controller data */
+static struct bfin5xx_spi_master bfin_spi0_info = {
+ .num_chipselect = MAX_CTRL_CS + MAX_BLACKFIN_GPIOS,
+ .enable_dma = 1, /* master has the ability to do dma transfer */
+ .pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0},
+};
+
+/* SPI (0) */
+static struct resource bfin_spi0_resource[] = {
+ [0] = {
+ .start = SPI0_REGBASE,
+ .end = SPI0_REGBASE + 0xFF,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = CH_SPI,
+ .end = CH_SPI,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = IRQ_SPI,
+ .end = IRQ_SPI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bfin_spi0_device = {
+ .name = "bfin-spi",
+ .id = 0, /* Bus number */
+ .num_resources = ARRAY_SIZE(bfin_spi0_resource),
+ .resource = bfin_spi0_resource,
+ .dev = {
+ .platform_data = &bfin_spi0_info, /* Passed to driver */
+ },
+};
+#endif /* spi master and devices */
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
+ {
+ .start = UART0_THR,
+ .end = UART0_GCTL+2,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_UART0_RX,
+ .end = IRQ_UART0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART0_ERROR,
+ .end = IRQ_UART0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART0_TX,
+ .end = CH_UART0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART0_RX,
+ .end = CH_UART0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+ P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+ .name = "bfin-uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+ .resource = bfin_uart0_resources,
+ .dev = {
+ .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
+ {
+ .start = UART1_THR,
+ .end = UART1_GCTL+2,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_UART1_RX,
+ .end = IRQ_UART1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART1_ERROR,
+ .end = IRQ_UART1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART1_TX,
+ .end = CH_UART1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART1_RX,
+ .end = CH_UART1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+ { /* CTS pin */
+ .start = GPIO_PF9,
+ .end = GPIO_PF9,
+ .flags = IORESOURCE_IO,
+ },
+ { /* RTS pin */
+ .start = GPIO_PF10,
+ .end = GPIO_PF10,
+ .flags = IORESOURCE_IO,
+ },
+#endif
+};
+
+unsigned short bfin_uart1_peripherals[] = {
+ P_UART1_TX, P_UART1_RX, 0
+};
+
+static struct platform_device bfin_uart1_device = {
+ .name = "bfin-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_uart1_resources),
+ .resource = bfin_uart1_resources,
+ .dev = {
+ .platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#endif
+
+#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
+#ifdef CONFIG_BFIN_SIR0
+static struct resource bfin_sir0_resources[] = {
+ {
+ .start = 0xFFC00400,
+ .end = 0xFFC004FF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_UART0_RX,
+ .end = IRQ_UART0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART0_RX,
+ .end = CH_UART0_RX+1,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device bfin_sir0_device = {
+ .name = "bfin_sir",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_sir0_resources),
+ .resource = bfin_sir0_resources,
+};
+#endif
+#ifdef CONFIG_BFIN_SIR1
+static struct resource bfin_sir1_resources[] = {
+ {
+ .start = 0xFFC02000,
+ .end = 0xFFC020FF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_UART1_RX,
+ .end = IRQ_UART1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART1_RX,
+ .end = CH_UART1_RX+1,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device bfin_sir1_device = {
+ .name = "bfin_sir",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_sir1_resources),
+ .resource = bfin_sir1_resources,
+};
+#endif
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_AD7160) || defined(CONFIG_TOUCHSCREEN_AD7160_MODULE)
+#include <linux/input/ad7160.h>
+static const struct ad7160_platform_data bfin_ad7160_ts_info = {
+ .sensor_x_res = 854,
+ .sensor_y_res = 480,
+ .pressure = 100,
+ .filter_coef = 3,
+ .coord_pref = AD7160_ORIG_TOP_LEFT,
+ .first_touch_window = 5,
+ .move_window = 3,
+ .event_cabs = AD7160_EMIT_ABS_MT_TRACKING_ID |
+ AD7160_EMIT_ABS_MT_PRESSURE |
+ AD7160_TRACKING_ID_ASCENDING,
+ .finger_act_ctrl = 0x64,
+ .haptic_effect1_ctrl = AD7160_HAPTIC_SLOT_A(60) |
+ AD7160_HAPTIC_SLOT_A_LVL_HIGH |
+ AD7160_HAPTIC_SLOT_B(60) |
+ AD7160_HAPTIC_SLOT_B_LVL_LOW,
+
+ .haptic_effect2_ctrl = AD7160_HAPTIC_SLOT_A(20) |
+ AD7160_HAPTIC_SLOT_A_LVL_HIGH |
+ AD7160_HAPTIC_SLOT_B(80) |
+ AD7160_HAPTIC_SLOT_B_LVL_LOW |
+ AD7160_HAPTIC_SLOT_C(120) |
+ AD7160_HAPTIC_SLOT_C_LVL_HIGH |
+ AD7160_HAPTIC_SLOT_D(30) |
+ AD7160_HAPTIC_SLOT_D_LVL_LOW,
+};
+#endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+static struct resource bfin_twi0_resource[] = {
+ [0] = {
+ .start = TWI0_REGBASE,
+ .end = TWI0_REGBASE,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_TWI,
+ .end = IRQ_TWI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device i2c_bfin_twi_device = {
+ .name = "i2c-bfin-twi",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_twi0_resource),
+ .resource = bfin_twi0_resource,
+};
+#endif
+
+static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
+#if defined(CONFIG_TOUCHSCREEN_AD7160) || defined(CONFIG_TOUCHSCREEN_AD7160_MODULE)
+ {
+ I2C_BOARD_INFO("ad7160", 0x33),
+ .irq = IRQ_PH1,
+ .platform_data = (void *)&bfin_ad7160_ts_info,
+ },
+#endif
+};
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+ {
+ .start = SPORT0_TCR1,
+ .end = SPORT0_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT0_RX,
+ .end = IRQ_SPORT0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT0_ERROR,
+ .end = IRQ_SPORT0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+ P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+ P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
+static struct platform_device bfin_sport0_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+ .resource = bfin_sport0_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+ {
+ .start = SPORT1_TCR1,
+ .end = SPORT1_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT1_RX,
+ .end = IRQ_SPORT1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT1_ERROR,
+ .end = IRQ_SPORT1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+ P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+ P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+ .resource = bfin_sport1_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#endif
+
+#if defined(CONFIG_INPUT_BFIN_ROTARY) || defined(CONFIG_INPUT_BFIN_ROTARY_MODULE)
+#include <asm/bfin_rotary.h>
+
+static struct bfin_rotary_platform_data bfin_rotary_data = {
+ /*.rotary_up_key = KEY_UP,*/
+ /*.rotary_down_key = KEY_DOWN,*/
+ .rotary_rel_code = REL_WHEEL,
+ .rotary_button_key = KEY_ENTER,
+ .debounce = 10, /* 0..17 */
+ .mode = ROT_QUAD_ENC | ROT_DEBE,
+};
+
+static struct resource bfin_rotary_resources[] = {
+ {
+ .start = IRQ_CNT,
+ .end = IRQ_CNT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bfin_rotary_device = {
+ .name = "bfin-rotary",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(bfin_rotary_resources),
+ .resource = bfin_rotary_resources,
+ .dev = {
+ .platform_data = &bfin_rotary_data,
+ },
+};
+#endif
+
+static const unsigned int cclk_vlev_datasheet[] = {
+ VRPAIR(VLEV_100, 400000000),
+ VRPAIR(VLEV_105, 426000000),
+ VRPAIR(VLEV_110, 500000000),
+ VRPAIR(VLEV_115, 533000000),
+ VRPAIR(VLEV_120, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+ .tuple_tab = cclk_vlev_datasheet,
+ .tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+ .vr_settling_time = 25 /* us */,
+};
+
+static struct platform_device bfin_dpmc = {
+ .name = "bfin dpmc",
+ .dev = {
+ .platform_data = &bfin_dmpc_vreg_data,
+ },
+};
+
+static struct platform_device *stamp_devices[] __initdata = {
+
+ &bfin_dpmc,
+
+#if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE)
+ &bf5xx_nand_device,
+#endif
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+ &rtc_device,
+#endif
+
+#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE)
+ &musb_device,
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+ &bfin_mii_bus,
+ &bfin_mac_device,
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ &bfin_spi0_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_FB_BFIN_RA158Z) || defined(CONFIG_FB_BFIN_RA158Z_MODULE)
+ &bf52x_ra158z_device,
+#endif
+
+#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
+#ifdef CONFIG_BFIN_SIR0
+ &bfin_sir0_device,
+#endif
+#ifdef CONFIG_BFIN_SIR1
+ &bfin_sir1_device,
+#endif
+#endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+ &i2c_bfin_twi_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+ &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+ &bfin_sport1_uart_device,
+#endif
+#endif
+
+#if defined(CONFIG_INPUT_BFIN_ROTARY) || defined(CONFIG_INPUT_BFIN_ROTARY_MODULE)
+ &bfin_rotary_device,
+#endif
+
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+ &ad7160eval_flash_device,
+#endif
+
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+ &bfin_i2s,
+#endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+ &bfin_tdm,
+#endif
+};
+
+static int __init ad7160eval_init(void)
+{
+ printk(KERN_INFO "%s(): registering device resources\n", __func__);
+ i2c_register_board_info(0, bfin_i2c_board_info,
+ ARRAY_SIZE(bfin_i2c_board_info));
+ platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
+ spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
+ return 0;
+}
+
+arch_initcall(ad7160eval_init);
+
+static struct platform_device *ad7160eval_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+ &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+ &bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+ printk(KERN_INFO "register early platform devices\n");
+ early_platform_add_devices(ad7160eval_early_devices,
+ ARRAY_SIZE(ad7160eval_early_devices));
+}
+
+void native_machine_restart(char *cmd)
+{
+ /* workaround reboot hang when booting from SPI */
+ if ((bfin_read_SYSCR() & 0x7) == 0x3)
+ bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS);
+}
+
+void bfin_get_ether_addr(char *addr)
+{
+ /* the MAC is stored in OTP memory page 0xDF */
+ u32 ret;
+ u64 otp_mac;
+ u32 (*otp_read)(u32 page, u32 flags, u64 *page_content) = (void *)0xEF00001A;
+
+ ret = otp_read(0xDF, 0x00, &otp_mac);
+ if (!(ret & 0x1)) {
+ char *otp_mac_p = (char *)&otp_mac;
+ for (ret = 0; ret < 6; ++ret)
+ addr[ret] = otp_mac_p[5 - ret];
+ }
+}
+EXPORT_SYMBOL(bfin_get_ether_addr);
diff --git a/arch/blackfin/mach-bf527/boards/cm_bf527.c b/arch/blackfin/mach-bf527/boards/cm_bf527.c
index 645ba5c8077b..38037c7e125a 100644
--- a/arch/blackfin/mach-bf527/boards/cm_bf527.c
+++ b/arch/blackfin/mach-bf527/boards/cm_bf527.c
@@ -342,8 +342,8 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
};
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD183X) \
- || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) \
+ || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
.enable_dma = 0,
.bits_per_word = 16,
@@ -420,13 +420,13 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
},
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD183X) \
- || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) \
+ || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
{
- .modalias = "ad1836",
+ .modalias = "ad183x",
.max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
.bus_num = 0,
- .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .chip_select = 4,
.controller_data = &ad1836_spi_chip_info,
},
#endif
diff --git a/arch/blackfin/mach-bf527/boards/ezbrd.c b/arch/blackfin/mach-bf527/boards/ezbrd.c
index c975fe88eba3..6cc64a1e78b9 100644
--- a/arch/blackfin/mach-bf527/boards/ezbrd.c
+++ b/arch/blackfin/mach-bf527/boards/ezbrd.c
@@ -137,8 +137,12 @@ static struct platform_device ezbrd_flash_device = {
#if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE)
static struct mtd_partition partition_info[] = {
{
- .name = "linux kernel(nand)",
+ .name = "bootloader(nand)",
.offset = 0,
+ .size = 0x40000,
+ }, {
+ .name = "linux kernel(nand)",
+ .offset = MTDPART_OFS_APPEND,
.size = 4 * 1024 * 1024,
},
{
diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c
index 87b41e994ba3..df82723fb504 100644
--- a/arch/blackfin/mach-bf527/boards/ezkit.c
+++ b/arch/blackfin/mach-bf527/boards/ezkit.c
@@ -222,8 +222,12 @@ static struct platform_device ezkit_flash_device = {
#if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE)
static struct mtd_partition partition_info[] = {
{
- .name = "linux kernel(nand)",
+ .name = "bootloader(nand)",
.offset = 0,
+ .size = 0x40000,
+ }, {
+ .name = "linux kernel(nand)",
+ .offset = MTDPART_OFS_APPEND,
.size = 4 * 1024 * 1024,
},
{
@@ -431,8 +435,8 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
};
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD183X) \
- || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) \
+ || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
.enable_dma = 0,
.bits_per_word = 16,
@@ -547,13 +551,13 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
},
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD183X) \
- || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) \
+ || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
{
- .modalias = "ad1836",
+ .modalias = "ad183x",
.max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
.bus_num = 0,
- .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .chip_select = 4,
.controller_data = &ad1836_spi_chip_info,
},
#endif
@@ -883,7 +887,7 @@ static struct adp5520_keys_platform_data adp5520_keys_data = {
};
/*
- * ADP5520/5501 Multifuction Device Init Data
+ * ADP5520/5501 Multifunction Device Init Data
*/
static struct adp5520_platform_data adp5520_pdev_data = {
@@ -929,6 +933,11 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
I2C_BOARD_INFO("ssm2602", 0x1b),
},
#endif
+#if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE)
+ {
+ I2C_BOARD_INFO("ad5252", 0x2f),
+ },
+#endif
};
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
diff --git a/arch/blackfin/mach-bf527/boards/tll6527m.c b/arch/blackfin/mach-bf527/boards/tll6527m.c
new file mode 100644
index 000000000000..ae4130e97c01
--- /dev/null
+++ b/arch/blackfin/mach-bf527/boards/tll6527m.c
@@ -0,0 +1,986 @@
+/* File: arch/blackfin/mach-bf527/boards/tll6527m.c
+ * Based on: arch/blackfin/mach-bf527/boards/ezkit.c
+ * Author: Ashish Gupta
+ *
+ * Copyright: 2010 - The Learning Labs Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/usb/musb.h>
+#include <linux/leds.h>
+#include <linux/input.h>
+#include <asm/dma.h>
+#include <asm/bfin5xx_spi.h>
+#include <asm/reboot.h>
+#include <asm/nand.h>
+#include <asm/portmux.h>
+#include <asm/dpmc.h>
+
+#if defined(CONFIG_TOUCHSCREEN_AD7879) \
+ || defined(CONFIG_TOUCHSCREEN_AD7879_MODULE)
+#include <linux/spi/ad7879.h>
+#define LCD_BACKLIGHT_GPIO 0x40
+/* TLL6527M uses TLL7UIQ35 / ADI LCD EZ Extender. AD7879 AUX GPIO is used for
+ * LCD Backlight Enable
+ */
+#endif
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+const char bfin_board_name[] = "TLL6527M";
+/*
+ * Driver needs to know address, irq and flag pin.
+ */
+
+#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE)
+static struct resource musb_resources[] = {
+ [0] = {
+ .start = 0xffc03800,
+ .end = 0xffc03cff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = { /* general IRQ */
+ .start = IRQ_USB_INT0,
+ .end = IRQ_USB_INT0,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+ [2] = { /* DMA IRQ */
+ .start = IRQ_USB_DMA,
+ .end = IRQ_USB_DMA,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct musb_hdrc_config musb_config = {
+ .multipoint = 0,
+ .dyn_fifo = 0,
+ .soft_con = 1,
+ .dma = 1,
+ .num_eps = 8,
+ .dma_channels = 8,
+ /*.gpio_vrsel = GPIO_PG13,*/
+ /* Some custom boards need to be active low, just set it to "0"
+ * if it is the case.
+ */
+ .gpio_vrsel_active = 1,
+};
+
+static struct musb_hdrc_platform_data musb_plat = {
+#if defined(CONFIG_USB_MUSB_OTG)
+ .mode = MUSB_OTG,
+#elif defined(CONFIG_USB_MUSB_HDRC_HCD)
+ .mode = MUSB_HOST,
+#elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
+ .mode = MUSB_PERIPHERAL,
+#endif
+ .config = &musb_config,
+};
+
+static u64 musb_dmamask = ~(u32)0;
+
+static struct platform_device musb_device = {
+ .name = "musb_hdrc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &musb_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &musb_plat,
+ },
+ .num_resources = ARRAY_SIZE(musb_resources),
+ .resource = musb_resources,
+};
+#endif
+
+#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE)
+#include <asm/bfin-lq035q1.h>
+
+static struct bfin_lq035q1fb_disp_info bfin_lq035q1_data = {
+ .mode = LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB,
+ .ppi_mode = USE_RGB565_16_BIT_PPI,
+ .use_bl = 1,
+ .gpio_bl = LCD_BACKLIGHT_GPIO,
+};
+
+static struct resource bfin_lq035q1_resources[] = {
+ {
+ .start = IRQ_PPI_ERROR,
+ .end = IRQ_PPI_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bfin_lq035q1_device = {
+ .name = "bfin-lq035q1",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(bfin_lq035q1_resources),
+ .resource = bfin_lq035q1_resources,
+ .dev = {
+ .platform_data = &bfin_lq035q1_data,
+ },
+};
+#endif
+
+#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
+static struct mtd_partition tll6527m_partitions[] = {
+ {
+ .name = "bootloader(nor)",
+ .size = 0xA0000,
+ .offset = 0,
+ }, {
+ .name = "linux kernel(nor)",
+ .size = 0xD00000,
+ .offset = MTDPART_OFS_APPEND,
+ }, {
+ .name = "file system(nor)",
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
+ }
+};
+
+static struct physmap_flash_data tll6527m_flash_data = {
+ .width = 2,
+ .parts = tll6527m_partitions,
+ .nr_parts = ARRAY_SIZE(tll6527m_partitions),
+};
+
+static unsigned tll6527m_flash_gpios[] = { GPIO_PG11, GPIO_PH11, GPIO_PH12 };
+
+static struct resource tll6527m_flash_resource[] = {
+ {
+ .name = "cfi_probe",
+ .start = 0x20000000,
+ .end = 0x201fffff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = (unsigned long)tll6527m_flash_gpios,
+ .end = ARRAY_SIZE(tll6527m_flash_gpios),
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device tll6527m_flash_device = {
+ .name = "gpio-addr-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &tll6527m_flash_data,
+ },
+ .num_resources = ARRAY_SIZE(tll6527m_flash_resource),
+ .resource = tll6527m_flash_resource,
+};
+#endif
+
+#if defined(CONFIG_GPIO_DECODER) || defined(CONFIG_GPIO_DECODER_MODULE)
+/* An SN74LVC138A 3:8 decoder chip has been used to generate 7 augmented
+ * outputs used as SPI CS lines for all SPI SLAVE devices on TLL6527v1-0.
+ * EXP_GPIO_SPISEL_BASE is the base number for the expanded outputs being
+ * used as SPI CS lines, this should be > MAX_BLACKFIN_GPIOS
+ */
+#include <linux/gpio-decoder.h>
+#define EXP_GPIO_SPISEL_BASE 0x64
+static unsigned gpio_addr_inputs[] = {
+ GPIO_PG1, GPIO_PH9, GPIO_PH10
+};
+
+static struct gpio_decoder_platfrom_data spi_decoded_cs = {
+ .base = EXP_GPIO_SPISEL_BASE,
+ .input_addrs = gpio_addr_inputs,
+ .nr_input_addrs = ARRAY_SIZE(gpio_addr_inputs),
+ .default_output = 0,
+/* .default_output = (1 << ARRAY_SIZE(gpio_addr_inputs)) - 1 */
+};
+
+static struct platform_device spi_decoded_gpio = {
+ .name = "gpio-decoder",
+ .id = 0,
+ .dev = {
+ .platform_data = &spi_decoded_cs,
+ },
+};
+
+#else
+#define EXP_GPIO_SPISEL_BASE 0x0
+
+#endif
+
+#if defined(CONFIG_INPUT_ADXL34X) || defined(CONFIG_INPUT_ADXL34X_MODULE)
+#include <linux/input/adxl34x.h>
+static const struct adxl34x_platform_data adxl345_info = {
+ .x_axis_offset = 0,
+ .y_axis_offset = 0,
+ .z_axis_offset = 0,
+ .tap_threshold = 0x31,
+ .tap_duration = 0x10,
+ .tap_latency = 0x60,
+ .tap_window = 0xF0,
+ .tap_axis_control = ADXL_TAP_X_EN | ADXL_TAP_Y_EN | ADXL_TAP_Z_EN,
+ .act_axis_control = 0xFF,
+ .activity_threshold = 5,
+ .inactivity_threshold = 2,
+ .inactivity_time = 2,
+ .free_fall_threshold = 0x7,
+ .free_fall_time = 0x20,
+ .data_rate = 0x8,
+ .data_range = ADXL_FULL_RES,
+
+ .ev_type = EV_ABS,
+ .ev_code_x = ABS_X, /* EV_REL */
+ .ev_code_y = ABS_Y, /* EV_REL */
+ .ev_code_z = ABS_Z, /* EV_REL */
+
+ .ev_code_tap = {BTN_TOUCH, BTN_TOUCH, BTN_TOUCH}, /* EV_KEY x,y,z */
+
+/* .ev_code_ff = KEY_F,*/ /* EV_KEY */
+ .ev_code_act_inactivity = KEY_A, /* EV_KEY */
+ .use_int2 = 1,
+ .power_mode = ADXL_AUTO_SLEEP | ADXL_LINK,
+ .fifo_mode = ADXL_FIFO_STREAM,
+};
+#endif
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+static struct platform_device rtc_device = {
+ .name = "rtc-bfin",
+ .id = -1,
+};
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static struct platform_device bfin_mii_bus = {
+ .name = "bfin_mii_bus",
+};
+
+static struct platform_device bfin_mac_device = {
+ .name = "bfin_mac",
+ .dev.platform_data = &bfin_mii_bus,
+};
+#endif
+
+#if defined(CONFIG_MTD_M25P80) \
+ || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition bfin_spi_flash_partitions[] = {
+ {
+ .name = "bootloader(spi)",
+ .size = 0x00040000,
+ .offset = 0,
+ .mask_flags = MTD_CAP_ROM
+ }, {
+ .name = "linux kernel(spi)",
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
+ }
+};
+
+static struct flash_platform_data bfin_spi_flash_data = {
+ .name = "m25p80",
+ .parts = bfin_spi_flash_partitions,
+ .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
+ .type = "m25p16",
+};
+
+/* SPI flash chip (m25p64) */
+static struct bfin5xx_spi_chip spi_flash_chip_info = {
+ .enable_dma = 0, /* use dma transfer with this chip*/
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_BFIN_SPI_ADC) \
+ || defined(CONFIG_BFIN_SPI_ADC_MODULE)
+/* SPI ADC chip */
+static struct bfin5xx_spi_chip spi_adc_chip_info = {
+ .enable_dma = 0, /* use dma transfer with this chip*/
+/*
+ * tll6527m V1.0 does not support native spi slave selects
+ * hence DMA mode will not be useful since the ADC needs
+ * CS to toggle for each sample and cs_change_per_word
+ * seems to be removed from spi_bfin5xx.c
+ */
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
+static struct bfin5xx_spi_chip mmc_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_AD7879) \
+ || defined(CONFIG_TOUCHSCREEN_AD7879_MODULE)
+static const struct ad7879_platform_data bfin_ad7879_ts_info = {
+ .model = 7879, /* Model = AD7879 */
+ .x_plate_ohms = 620, /* 620 Ohm from the touch datasheet */
+ .pressure_max = 10000,
+ .pressure_min = 0,
+ .first_conversion_delay = 3,
+ /* wait 512us before do a first conversion */
+ .acquisition_time = 1, /* 4us acquisition time per sample */
+ .median = 2, /* do 8 measurements */
+ .averaging = 1,
+ /* take the average of 4 middle samples */
+ .pen_down_acc_interval = 255, /* 9.4 ms */
+ .gpio_export = 1, /* configure AUX as GPIO output*/
+ .gpio_base = LCD_BACKLIGHT_GPIO,
+};
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) \
+ || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE)
+static struct bfin5xx_spi_chip spi_ad7879_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
+static struct bfin5xx_spi_chip spidev_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+static struct platform_device bfin_i2s = {
+ .name = "bfin-i2s",
+ .id = CONFIG_SND_BF5XX_SPORT_NUM,
+ /* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE)
+static struct bfin5xx_spi_chip lq035q1_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_GPIO_MCP23S08) || defined(CONFIG_GPIO_MCP23S08_MODULE)
+static struct bfin5xx_spi_chip spi_mcp23s08_sys_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 8,
+};
+
+static struct bfin5xx_spi_chip spi_mcp23s08_usr_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 8,
+};
+
+#include <linux/spi/mcp23s08.h>
+static const struct mcp23s08_platform_data bfin_mcp23s08_sys_gpio_info = {
+ .chip[0].is_present = true,
+ .base = 0x30,
+};
+static const struct mcp23s08_platform_data bfin_mcp23s08_usr_gpio_info = {
+ .chip[2].is_present = true,
+ .base = 0x38,
+};
+#endif
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80) \
+ || defined(CONFIG_MTD_M25P80_MODULE)
+ {
+ /* the modalias must be the same as spi device driver name */
+ .modalias = "m25p80", /* Name of spi_driver for this device */
+ .max_speed_hz = 25000000,
+ /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0, /* Framework bus number */
+ .chip_select = EXP_GPIO_SPISEL_BASE + 0x04 + MAX_CTRL_CS,
+ /* Can be connected to TLL6527M GPIO connector */
+ /* Either SPI_ADC or M25P80 FLASH can be installed at a time */
+ .platform_data = &bfin_spi_flash_data,
+ .controller_data = &spi_flash_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+
+#if defined(CONFIG_BFIN_SPI_ADC)
+ || defined(CONFIG_BFIN_SPI_ADC_MODULE)
+ {
+ .modalias = "bfin_spi_adc",
+ /* Name of spi_driver for this device */
+ .max_speed_hz = 10000000,
+ /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0, /* Framework bus number */
+ .chip_select = EXP_GPIO_SPISEL_BASE + 0x04 + MAX_CTRL_CS,
+ /* Framework chip select. */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .controller_data = &spi_adc_chip_info,
+ .mode = SPI_MODE_0,
+ },
+#endif
+
+#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
+ {
+ .modalias = "mmc_spi",
+/*
+ * TLL6527M V1.0 does not support SD Card at SPI Clock > 10 MHz due to
+ * SPI buffer limitations
+ */
+ .max_speed_hz = 10000000,
+ /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = EXP_GPIO_SPISEL_BASE + 0x05 + MAX_CTRL_CS,
+ .controller_data = &mmc_spi_chip_info,
+ .mode = SPI_MODE_0,
+ },
+#endif
+#if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) \
+ || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE)
+ {
+ .modalias = "ad7879",
+ .platform_data = &bfin_ad7879_ts_info,
+ .irq = IRQ_PH14,
+ .max_speed_hz = 5000000,
+ /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = EXP_GPIO_SPISEL_BASE + 0x07 + MAX_CTRL_CS,
+ .controller_data = &spi_ad7879_chip_info,
+ .mode = SPI_CPHA | SPI_CPOL,
+ },
+#endif
+#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
+ {
+ .modalias = "spidev",
+ .max_speed_hz = 10000000,
+ /* TLL6527Mv1-0 supports max spi clock (SCK) speed = 10 MHz */
+ .bus_num = 0,
+ .chip_select = EXP_GPIO_SPISEL_BASE + 0x03 + MAX_CTRL_CS,
+ .mode = SPI_CPHA | SPI_CPOL,
+ .controller_data = &spidev_chip_info,
+ },
+#endif
+#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE)
+ {
+ .modalias = "bfin-lq035q1-spi",
+ .max_speed_hz = 20000000,
+ .bus_num = 0,
+ .chip_select = EXP_GPIO_SPISEL_BASE + 0x06 + MAX_CTRL_CS,
+ .controller_data = &lq035q1_spi_chip_info,
+ .mode = SPI_CPHA | SPI_CPOL,
+ },
+#endif
+#if defined(CONFIG_GPIO_MCP23S08) || defined(CONFIG_GPIO_MCP23S08_MODULE)
+ {
+ .modalias = "mcp23s08",
+ .platform_data = &bfin_mcp23s08_sys_gpio_info,
+ .max_speed_hz = 5000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = EXP_GPIO_SPISEL_BASE + 0x01 + MAX_CTRL_CS,
+ .controller_data = &spi_mcp23s08_sys_chip_info,
+ .mode = SPI_CPHA | SPI_CPOL,
+ },
+ {
+ .modalias = "mcp23s08",
+ .platform_data = &bfin_mcp23s08_usr_gpio_info,
+ .max_speed_hz = 5000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = EXP_GPIO_SPISEL_BASE + 0x02 + MAX_CTRL_CS,
+ .controller_data = &spi_mcp23s08_usr_chip_info,
+ .mode = SPI_CPHA | SPI_CPOL,
+ },
+#endif
+};
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* SPI controller data */
+static struct bfin5xx_spi_master bfin_spi0_info = {
+ .num_chipselect = EXP_GPIO_SPISEL_BASE + 8 + MAX_CTRL_CS,
+ /* EXP_GPIO_SPISEL_BASE will be > MAX_BLACKFIN_GPIOS */
+ .enable_dma = 1, /* master has the ability to do dma transfer */
+ .pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0},
+};
+
+/* SPI (0) */
+static struct resource bfin_spi0_resource[] = {
+ [0] = {
+ .start = SPI0_REGBASE,
+ .end = SPI0_REGBASE + 0xFF,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = CH_SPI,
+ .end = CH_SPI,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = IRQ_SPI,
+ .end = IRQ_SPI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bfin_spi0_device = {
+ .name = "bfin-spi",
+ .id = 0, /* Bus number */
+ .num_resources = ARRAY_SIZE(bfin_spi0_resource),
+ .resource = bfin_spi0_resource,
+ .dev = {
+ .platform_data = &bfin_spi0_info, /* Passed to driver */
+ },
+};
+#endif /* spi master and devices */
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
+ {
+ .start = UART0_THR,
+ .end = UART0_GCTL+2,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_UART0_RX,
+ .end = IRQ_UART0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART0_ERROR,
+ .end = IRQ_UART0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART0_TX,
+ .end = CH_UART0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART0_RX,
+ .end = CH_UART0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+ P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+ .name = "bfin-uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+ .resource = bfin_uart0_resources,
+ .dev = {
+ .platform_data = &bfin_uart0_peripherals,
+ /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
+ {
+ .start = UART1_THR,
+ .end = UART1_GCTL+2,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_UART1_RX,
+ .end = IRQ_UART1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART1_ERROR,
+ .end = IRQ_UART1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART1_TX,
+ .end = CH_UART1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART1_RX,
+ .end = CH_UART1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+ { /* CTS pin */
+ .start = GPIO_PF9,
+ .end = GPIO_PF9,
+ .flags = IORESOURCE_IO,
+ },
+ { /* RTS pin */
+ .start = GPIO_PF10,
+ .end = GPIO_PF10,
+ .flags = IORESOURCE_IO,
+ },
+#endif
+};
+
+unsigned short bfin_uart1_peripherals[] = {
+ P_UART1_TX, P_UART1_RX, 0
+};
+
+static struct platform_device bfin_uart1_device = {
+ .name = "bfin-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_uart1_resources),
+ .resource = bfin_uart1_resources,
+ .dev = {
+ .platform_data = &bfin_uart1_peripherals,
+ /* Passed to driver */
+ },
+};
+#endif
+#endif
+
+#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
+#ifdef CONFIG_BFIN_SIR0
+static struct resource bfin_sir0_resources[] = {
+ {
+ .start = 0xFFC00400,
+ .end = 0xFFC004FF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_UART0_RX,
+ .end = IRQ_UART0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART0_RX,
+ .end = CH_UART0_RX+1,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device bfin_sir0_device = {
+ .name = "bfin_sir",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_sir0_resources),
+ .resource = bfin_sir0_resources,
+};
+#endif
+#ifdef CONFIG_BFIN_SIR1
+static struct resource bfin_sir1_resources[] = {
+ {
+ .start = 0xFFC02000,
+ .end = 0xFFC020FF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_UART1_RX,
+ .end = IRQ_UART1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART1_RX,
+ .end = CH_UART1_RX+1,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device bfin_sir1_device = {
+ .name = "bfin_sir",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_sir1_resources),
+ .resource = bfin_sir1_resources,
+};
+#endif
+#endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+static struct resource bfin_twi0_resource[] = {
+ [0] = {
+ .start = TWI0_REGBASE,
+ .end = TWI0_REGBASE,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_TWI,
+ .end = IRQ_TWI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device i2c_bfin_twi_device = {
+ .name = "i2c-bfin-twi",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_twi0_resource),
+ .resource = bfin_twi0_resource,
+};
+#endif
+
+static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
+#if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE)
+ {
+ I2C_BOARD_INFO("pcf8574_lcd", 0x22),
+ },
+#endif
+
+#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
+ {
+ I2C_BOARD_INFO("bfin-adv7393", 0x2B),
+ },
+#endif
+#if defined(CONFIG_TOUCHSCREEN_AD7879_I2C) \
+ || defined(CONFIG_TOUCHSCREEN_AD7879_I2C_MODULE)
+ {
+ I2C_BOARD_INFO("ad7879", 0x2C),
+ .irq = IRQ_PH14,
+ .platform_data = (void *)&bfin_ad7879_ts_info,
+ },
+#endif
+#if defined(CONFIG_SND_SOC_SSM2602) || defined(CONFIG_SND_SOC_SSM2602_MODULE)
+ {
+ I2C_BOARD_INFO("ssm2602", 0x1b),
+ },
+#endif
+ {
+ I2C_BOARD_INFO("adm1192", 0x2e),
+ },
+
+ {
+ I2C_BOARD_INFO("ltc3576", 0x09),
+ },
+#if defined(CONFIG_INPUT_ADXL34X_I2C) \
+ || defined(CONFIG_INPUT_ADXL34X_I2C_MODULE)
+ {
+ I2C_BOARD_INFO("adxl34x", 0x53),
+ .irq = IRQ_PH13,
+ .platform_data = (void *)&adxl345_info,
+ },
+#endif
+};
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) \
+ || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+ {
+ .start = SPORT0_TCR1,
+ .end = SPORT0_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT0_RX,
+ .end = IRQ_SPORT0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT0_ERROR,
+ .end = IRQ_SPORT0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+ P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+ P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
+static struct platform_device bfin_sport0_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+ .resource = bfin_sport0_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport0_peripherals,
+ /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+ {
+ .start = SPORT1_TCR1,
+ .end = SPORT1_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT1_RX,
+ .end = IRQ_SPORT1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT1_ERROR,
+ .end = IRQ_SPORT1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+ P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+ P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+ .resource = bfin_sport1_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport1_peripherals,
+ /* Passed to driver */
+ },
+};
+#endif
+#endif
+
+static const unsigned int cclk_vlev_datasheet[] = {
+ VRPAIR(VLEV_100, 400000000),
+ VRPAIR(VLEV_105, 426000000),
+ VRPAIR(VLEV_110, 500000000),
+ VRPAIR(VLEV_115, 533000000),
+ VRPAIR(VLEV_120, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+ .tuple_tab = cclk_vlev_datasheet,
+ .tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+ .vr_settling_time = 25 /* us */,
+};
+
+static struct platform_device bfin_dpmc = {
+ .name = "bfin dpmc",
+ .dev = {
+ .platform_data = &bfin_dmpc_vreg_data,
+ },
+};
+
+static struct platform_device *tll6527m_devices[] __initdata = {
+
+ &bfin_dpmc,
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+ &rtc_device,
+#endif
+
+#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE)
+ &musb_device,
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+ &bfin_mii_bus,
+ &bfin_mac_device,
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ &bfin_spi0_device,
+#endif
+
+#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE)
+ &bfin_lq035q1_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
+#ifdef CONFIG_BFIN_SIR0
+ &bfin_sir0_device,
+#endif
+#ifdef CONFIG_BFIN_SIR1
+ &bfin_sir1_device,
+#endif
+#endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+ &i2c_bfin_twi_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) \
+ || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+ &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+ &bfin_sport1_uart_device,
+#endif
+#endif
+
+#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
+ &tll6527m_flash_device,
+#endif
+
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+ &bfin_i2s,
+#endif
+
+#if defined(CONFIG_GPIO_DECODER) || defined(CONFIG_GPIO_DECODER_MODULE)
+ &spi_decoded_gpio,
+#endif
+};
+
+static int __init tll6527m_init(void)
+{
+ printk(KERN_INFO "%s(): registering device resources\n", __func__);
+ i2c_register_board_info(0, bfin_i2c_board_info,
+ ARRAY_SIZE(bfin_i2c_board_info));
+ platform_add_devices(tll6527m_devices, ARRAY_SIZE(tll6527m_devices));
+ spi_register_board_info(bfin_spi_board_info,
+ ARRAY_SIZE(bfin_spi_board_info));
+ return 0;
+}
+
+arch_initcall(tll6527m_init);
+
+static struct platform_device *tll6527m_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+ &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+ &bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+ printk(KERN_INFO "register early platform devices\n");
+ early_platform_add_devices(tll6527m_early_devices,
+ ARRAY_SIZE(tll6527m_early_devices));
+}
+
+void native_machine_restart(char *cmd)
+{
+ /* workaround reboot hang when booting from SPI */
+ if ((bfin_read_SYSCR() & 0x7) == 0x3)
+ bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS);
+}
+
+void bfin_get_ether_addr(char *addr)
+{
+ /* the MAC is stored in OTP memory page 0xDF */
+ u32 ret;
+ u64 otp_mac;
+ u32 (*otp_read)(u32 page, u32 flags,
+ u64 *page_content) = (void *)0xEF00001A;
+
+ ret = otp_read(0xDF, 0x00, &otp_mac);
+ if (!(ret & 0x1)) {
+ char *otp_mac_p = (char *)&otp_mac;
+ for (ret = 0; ret < 6; ++ret)
+ addr[ret] = otp_mac_p[5 - ret];
+ }
+}
+EXPORT_SYMBOL(bfin_get_ether_addr);
diff --git a/arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h b/arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h
index 12f2ad45314e..3048b52bf46a 100644
--- a/arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h
+++ b/arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h
@@ -279,14 +279,14 @@
#define bfin_write_SPORT0_TX(val) bfin_write32(SPORT0_TX, val)
#define bfin_read_SPORT0_RX() bfin_read32(SPORT0_RX)
#define bfin_write_SPORT0_RX(val) bfin_write32(SPORT0_RX, val)
-#define bfin_read_SPORT0_TX32() bfin_read32(SPORT0_TX32)
-#define bfin_write_SPORT0_TX32(val) bfin_write32(SPORT0_TX32, val)
-#define bfin_read_SPORT0_RX32() bfin_read32(SPORT0_RX32)
-#define bfin_write_SPORT0_RX32(val) bfin_write32(SPORT0_RX32, val)
-#define bfin_read_SPORT0_TX16() bfin_read16(SPORT0_TX16)
-#define bfin_write_SPORT0_TX16(val) bfin_write16(SPORT0_TX16, val)
-#define bfin_read_SPORT0_RX16() bfin_read16(SPORT0_RX16)
-#define bfin_write_SPORT0_RX16(val) bfin_write16(SPORT0_RX16, val)
+#define bfin_read_SPORT0_TX32() bfin_read32(SPORT0_TX)
+#define bfin_write_SPORT0_TX32(val) bfin_write32(SPORT0_TX, val)
+#define bfin_read_SPORT0_RX32() bfin_read32(SPORT0_RX)
+#define bfin_write_SPORT0_RX32(val) bfin_write32(SPORT0_RX, val)
+#define bfin_read_SPORT0_TX16() bfin_read16(SPORT0_TX)
+#define bfin_write_SPORT0_TX16(val) bfin_write16(SPORT0_TX, val)
+#define bfin_read_SPORT0_RX16() bfin_read16(SPORT0_RX)
+#define bfin_write_SPORT0_RX16(val) bfin_write16(SPORT0_RX, val)
#define bfin_read_SPORT0_RCR1() bfin_read16(SPORT0_RCR1)
#define bfin_write_SPORT0_RCR1(val) bfin_write16(SPORT0_RCR1, val)
#define bfin_read_SPORT0_RCR2() bfin_read16(SPORT0_RCR2)
@@ -334,14 +334,14 @@
#define bfin_write_SPORT1_TX(val) bfin_write32(SPORT1_TX, val)
#define bfin_read_SPORT1_RX() bfin_read32(SPORT1_RX)
#define bfin_write_SPORT1_RX(val) bfin_write32(SPORT1_RX, val)
-#define bfin_read_SPORT1_TX32() bfin_read32(SPORT1_TX32)
-#define bfin_write_SPORT1_TX32(val) bfin_write32(SPORT1_TX32, val)
-#define bfin_read_SPORT1_RX32() bfin_read32(SPORT1_RX32)
-#define bfin_write_SPORT1_RX32(val) bfin_write32(SPORT1_RX32, val)
-#define bfin_read_SPORT1_TX16() bfin_read16(SPORT1_TX16)
-#define bfin_write_SPORT1_TX16(val) bfin_write16(SPORT1_TX16, val)
-#define bfin_read_SPORT1_RX16() bfin_read16(SPORT1_RX16)
-#define bfin_write_SPORT1_RX16(val) bfin_write16(SPORT1_RX16, val)
+#define bfin_read_SPORT1_TX32() bfin_read32(SPORT1_TX)
+#define bfin_write_SPORT1_TX32(val) bfin_write32(SPORT1_TX, val)
+#define bfin_read_SPORT1_RX32() bfin_read32(SPORT1_RX)
+#define bfin_write_SPORT1_RX32(val) bfin_write32(SPORT1_RX, val)
+#define bfin_read_SPORT1_TX16() bfin_read16(SPORT1_TX)
+#define bfin_write_SPORT1_TX16(val) bfin_write16(SPORT1_TX, val)
+#define bfin_read_SPORT1_RX16() bfin_read16(SPORT1_RX)
+#define bfin_write_SPORT1_RX16(val) bfin_write16(SPORT1_RX, val)
#define bfin_read_SPORT1_RCR1() bfin_read16(SPORT1_RCR1)
#define bfin_write_SPORT1_RCR1(val) bfin_write16(SPORT1_RCR1, val)
#define bfin_read_SPORT1_RCR2() bfin_read16(SPORT1_RCR2)
@@ -1110,54 +1110,4 @@
/* These need to be last due to the cdef/linux inter-dependencies */
#include <asm/irq.h>
-/* Writing to PLL_CTL initiates a PLL relock sequence. */
-static __inline__ void bfin_write_PLL_CTL(unsigned int val)
-{
- unsigned long flags, iwr0, iwr1;
-
- if (val == bfin_read_PLL_CTL())
- return;
-
- local_irq_save_hw(flags);
- /* Enable the PLL Wakeup bit in SIC IWR */
- iwr0 = bfin_read32(SIC_IWR0);
- iwr1 = bfin_read32(SIC_IWR1);
- /* Only allow PPL Wakeup) */
- bfin_write32(SIC_IWR0, IWR_ENABLE(0));
- bfin_write32(SIC_IWR1, 0);
-
- bfin_write16(PLL_CTL, val);
- SSYNC();
- asm("IDLE;");
-
- bfin_write32(SIC_IWR0, iwr0);
- bfin_write32(SIC_IWR1, iwr1);
- local_irq_restore_hw(flags);
-}
-
-/* Writing to VR_CTL initiates a PLL relock sequence. */
-static __inline__ void bfin_write_VR_CTL(unsigned int val)
-{
- unsigned long flags, iwr0, iwr1;
-
- if (val == bfin_read_VR_CTL())
- return;
-
- local_irq_save_hw(flags);
- /* Enable the PLL Wakeup bit in SIC IWR */
- iwr0 = bfin_read32(SIC_IWR0);
- iwr1 = bfin_read32(SIC_IWR1);
- /* Only allow PPL Wakeup) */
- bfin_write32(SIC_IWR0, IWR_ENABLE(0));
- bfin_write32(SIC_IWR1, 0);
-
- bfin_write16(VR_CTL, val);
- SSYNC();
- asm("IDLE;");
-
- bfin_write32(SIC_IWR0, iwr0);
- bfin_write32(SIC_IWR1, iwr1);
- local_irq_restore_hw(flags);
-}
-
#endif /* _CDEF_BF52X_H */
diff --git a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h
index 3e000756aacd..09475034c6a1 100644
--- a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h
+++ b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h
@@ -749,51 +749,6 @@
#define FFE 0x20 /* Force Framing Error On Transmit */
-/* *********** SERIAL PERIPHERAL INTERFACE (SPI) MASKS ****************************/
-/* SPI_CTL Masks */
-#define TIMOD 0x0003 /* Transfer Initiate Mode */
-#define RDBR_CORE 0x0000 /* RDBR Read Initiates, IRQ When RDBR Full */
-#define TDBR_CORE 0x0001 /* TDBR Write Initiates, IRQ When TDBR Empty */
-#define RDBR_DMA 0x0002 /* DMA Read, DMA Until FIFO Empty */
-#define TDBR_DMA 0x0003 /* DMA Write, DMA Until FIFO Full */
-#define SZ 0x0004 /* Send Zero (When TDBR Empty, Send Zero/Last*) */
-#define GM 0x0008 /* Get More (When RDBR Full, Overwrite/Discard*) */
-#define PSSE 0x0010 /* Slave-Select Input Enable */
-#define EMISO 0x0020 /* Enable MISO As Output */
-#define SIZE 0x0100 /* Size of Words (16/8* Bits) */
-#define LSBF 0x0200 /* LSB First */
-#define CPHA 0x0400 /* Clock Phase */
-#define CPOL 0x0800 /* Clock Polarity */
-#define MSTR 0x1000 /* Master/Slave* */
-#define WOM 0x2000 /* Write Open Drain Master */
-#define SPE 0x4000 /* SPI Enable */
-
-/* SPI_FLG Masks */
-#define FLS1 0x0002 /* Enables SPI_FLOUT1 as SPI Slave-Select Output */
-#define FLS2 0x0004 /* Enables SPI_FLOUT2 as SPI Slave-Select Output */
-#define FLS3 0x0008 /* Enables SPI_FLOUT3 as SPI Slave-Select Output */
-#define FLS4 0x0010 /* Enables SPI_FLOUT4 as SPI Slave-Select Output */
-#define FLS5 0x0020 /* Enables SPI_FLOUT5 as SPI Slave-Select Output */
-#define FLS6 0x0040 /* Enables SPI_FLOUT6 as SPI Slave-Select Output */
-#define FLS7 0x0080 /* Enables SPI_FLOUT7 as SPI Slave-Select Output */
-#define FLG1 0xFDFF /* Activates SPI_FLOUT1 */
-#define FLG2 0xFBFF /* Activates SPI_FLOUT2 */
-#define FLG3 0xF7FF /* Activates SPI_FLOUT3 */
-#define FLG4 0xEFFF /* Activates SPI_FLOUT4 */
-#define FLG5 0xDFFF /* Activates SPI_FLOUT5 */
-#define FLG6 0xBFFF /* Activates SPI_FLOUT6 */
-#define FLG7 0x7FFF /* Activates SPI_FLOUT7 */
-
-/* SPI_STAT Masks */
-#define SPIF 0x0001 /* SPI Finished (Single-Word Transfer Complete) */
-#define MODF 0x0002 /* Mode Fault Error (Another Device Tried To Become Master) */
-#define TXE 0x0004 /* Transmission Error (Data Sent With No New Data In TDBR) */
-#define TXS 0x0008 /* SPI_TDBR Data Buffer Status (Full/Empty*) */
-#define RBSY 0x0010 /* Receive Error (Data Received With RDBR Full) */
-#define RXS 0x0020 /* SPI_RDBR Data Buffer Status (Full/Empty*) */
-#define TXCOL 0x0040 /* Transmit Collision Error (Corrupt Data May Have Been Sent) */
-
-
/* **************** GENERAL PURPOSE TIMER MASKS **********************/
/* TIMER_ENABLE Masks */
#define TIMEN0 0x0001 /* Enable Timer 0 */
diff --git a/arch/blackfin/mach-bf527/include/mach/pll.h b/arch/blackfin/mach-bf527/include/mach/pll.h
new file mode 100644
index 000000000000..24f1d7c02325
--- /dev/null
+++ b/arch/blackfin/mach-bf527/include/mach/pll.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2007-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later
+ */
+
+#ifndef _MACH_PLL_H
+#define _MACH_PLL_H
+
+#include <asm/blackfin.h>
+#include <asm/irqflags.h>
+
+/* Writing to PLL_CTL initiates a PLL relock sequence. */
+static __inline__ void bfin_write_PLL_CTL(unsigned int val)
+{
+ unsigned long flags, iwr0, iwr1;
+
+ if (val == bfin_read_PLL_CTL())
+ return;
+
+ flags = hard_local_irq_save();
+ /* Enable the PLL Wakeup bit in SIC IWR */
+ iwr0 = bfin_read32(SIC_IWR0);
+ iwr1 = bfin_read32(SIC_IWR1);
+ /* Only allow PPL Wakeup) */
+ bfin_write32(SIC_IWR0, IWR_ENABLE(0));
+ bfin_write32(SIC_IWR1, 0);
+
+ bfin_write16(PLL_CTL, val);
+ SSYNC();
+ asm("IDLE;");
+
+ bfin_write32(SIC_IWR0, iwr0);
+ bfin_write32(SIC_IWR1, iwr1);
+ hard_local_irq_restore(flags);
+}
+
+/* Writing to VR_CTL initiates a PLL relock sequence. */
+static __inline__ void bfin_write_VR_CTL(unsigned int val)
+{
+ unsigned long flags, iwr0, iwr1;
+
+ if (val == bfin_read_VR_CTL())
+ return;
+
+ flags = hard_local_irq_save();
+ /* Enable the PLL Wakeup bit in SIC IWR */
+ iwr0 = bfin_read32(SIC_IWR0);
+ iwr1 = bfin_read32(SIC_IWR1);
+ /* Only allow PPL Wakeup) */
+ bfin_write32(SIC_IWR0, IWR_ENABLE(0));
+ bfin_write32(SIC_IWR1, 0);
+
+ bfin_write16(VR_CTL, val);
+ SSYNC();
+ asm("IDLE;");
+
+ bfin_write32(SIC_IWR0, iwr0);
+ bfin_write32(SIC_IWR1, iwr1);
+ hard_local_irq_restore(flags);
+}
+
+#endif /* _MACH_PLL_H */
diff --git a/arch/blackfin/mach-bf533/boards/H8606.c b/arch/blackfin/mach-bf533/boards/H8606.c
index 175371af0692..2ce7b16faee1 100644
--- a/arch/blackfin/mach-bf533/boards/H8606.c
+++ b/arch/blackfin/mach-bf533/boards/H8606.c
@@ -171,7 +171,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
};
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
.enable_dma = 0,
.bits_per_word = 16,
@@ -206,12 +206,12 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
},
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
{
- .modalias = "ad1836",
+ .modalias = "ad183x",
.max_speed_hz = 16,
.bus_num = 1,
- .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .chip_select = 4,
.controller_data = &ad1836_spi_chip_info,
},
#endif
@@ -347,6 +347,7 @@ static struct plat_serial8250_port serial8250_platform_data [] = {
.membase = (void *)0x20200000,
.mapbase = 0x20200000,
.irq = IRQ_PF8,
+ .irqflags = IRQF_TRIGGER_HIGH,
.flags = UPF_BOOT_AUTOCONF | UART_CONFIG_TYPE,
.iotype = UPIO_MEM,
.regshift = 1,
@@ -355,6 +356,7 @@ static struct plat_serial8250_port serial8250_platform_data [] = {
.membase = (void *)0x20200010,
.mapbase = 0x20200010,
.irq = IRQ_PF8,
+ .irqflags = IRQF_TRIGGER_HIGH,
.flags = UPF_BOOT_AUTOCONF | UART_CONFIG_TYPE,
.iotype = UPIO_MEM,
.regshift = 1,
diff --git a/arch/blackfin/mach-bf533/boards/blackstamp.c b/arch/blackfin/mach-bf533/boards/blackstamp.c
index 842b4fa76ea9..20c102285bef 100644
--- a/arch/blackfin/mach-bf533/boards/blackstamp.c
+++ b/arch/blackfin/mach-bf533/boards/blackstamp.c
@@ -25,6 +25,7 @@
#include <asm/bfin5xx_spi.h>
#include <asm/portmux.h>
#include <asm/dpmc.h>
+#include <mach/fio_flag.h>
/*
* Name the Board for the /proc/cpuinfo
@@ -367,8 +368,8 @@ static struct platform_device bfin_device_gpiokeys = {
#include <linux/i2c-gpio.h>
static struct i2c_gpio_platform_data i2c_gpio_data = {
- .sda_pin = 8,
- .scl_pin = 9,
+ .sda_pin = GPIO_PF8,
+ .scl_pin = GPIO_PF9,
.sda_is_open_drain = 0,
.scl_is_open_drain = 0,
.udelay = 40,
diff --git a/arch/blackfin/mach-bf533/boards/cm_bf533.c b/arch/blackfin/mach-bf533/boards/cm_bf533.c
index fdcde61906dc..adbe62a81e25 100644
--- a/arch/blackfin/mach-bf533/boards/cm_bf533.c
+++ b/arch/blackfin/mach-bf533/boards/cm_bf533.c
@@ -71,7 +71,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
};
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
.enable_dma = 0,
.bits_per_word = 16,
@@ -110,12 +110,12 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
},
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
{
- .modalias = "ad1836",
+ .modalias = "ad183x",
.max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
.bus_num = 0,
- .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .chip_select = 4,
.controller_data = &ad1836_spi_chip_info,
},
#endif
@@ -400,7 +400,7 @@ static struct resource isp1362_hcd_resources[] = {
}, {
.start = IRQ_PF4,
.end = IRQ_PF4,
- .flags = IORESOURCE_IRQ,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
},
};
diff --git a/arch/blackfin/mach-bf533/boards/ezkit.c b/arch/blackfin/mach-bf533/boards/ezkit.c
index 739773cb7fc6..a1cb8e7c1010 100644
--- a/arch/blackfin/mach-bf533/boards/ezkit.c
+++ b/arch/blackfin/mach-bf533/boards/ezkit.c
@@ -222,7 +222,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
};
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
.enable_dma = 0,
.bits_per_word = 16,
@@ -261,12 +261,12 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
},
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
{
- .modalias = "ad1836",
+ .modalias = "ad183x",
.max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
.bus_num = 0,
- .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .chip_select = 4,
.controller_data = &ad1836_spi_chip_info,
},
#endif
@@ -422,8 +422,8 @@ static struct platform_device bfin_device_gpiokeys = {
#include <linux/i2c-gpio.h>
static struct i2c_gpio_platform_data i2c_gpio_data = {
- .sda_pin = 1,
- .scl_pin = 0,
+ .sda_pin = GPIO_PF1,
+ .scl_pin = GPIO_PF0,
.sda_is_open_drain = 0,
.scl_is_open_drain = 0,
.udelay = 40,
diff --git a/arch/blackfin/mach-bf533/boards/ip0x.c b/arch/blackfin/mach-bf533/boards/ip0x.c
index 7349970db978..5ba4b02a12eb 100644
--- a/arch/blackfin/mach-bf533/boards/ip0x.c
+++ b/arch/blackfin/mach-bf533/boards/ip0x.c
@@ -22,6 +22,7 @@
#include <asm/dma.h>
#include <asm/bfin5xx_spi.h>
#include <asm/portmux.h>
+#include <mach/fio_flag.h>
/*
* Name the Board for the /proc/cpuinfo
@@ -231,7 +232,7 @@ static struct resource isp1362_hcd_resources[] = {
},{
.start = IRQ_PF11,
.end = IRQ_PF11,
- .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
},
};
diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c
index c457eaa60239..b3b1cdea2703 100644
--- a/arch/blackfin/mach-bf533/boards/stamp.c
+++ b/arch/blackfin/mach-bf533/boards/stamp.c
@@ -24,6 +24,7 @@
#include <asm/reboot.h>
#include <asm/portmux.h>
#include <asm/dpmc.h>
+#include <mach/fio_flag.h>
/*
* Name the Board for the /proc/cpuinfo
@@ -184,7 +185,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
};
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
.enable_dma = 0,
.bits_per_word = 16,
@@ -251,13 +252,15 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
},
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
{
- .modalias = "ad1836",
+ .modalias = "ad183x",
.max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
.bus_num = 0,
- .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .chip_select = 4,
+ .platform_data = "ad1836", /* only includes chip name for the moment */
.controller_data = &ad1836_spi_chip_info,
+ .mode = SPI_MODE_3,
},
#endif
@@ -494,8 +497,8 @@ static struct platform_device bfin_device_gpiokeys = {
#include <linux/i2c-gpio.h>
static struct i2c_gpio_platform_data i2c_gpio_data = {
- .sda_pin = 2,
- .scl_pin = 3,
+ .sda_pin = GPIO_PF2,
+ .scl_pin = GPIO_PF3,
.sda_is_open_drain = 0,
.scl_is_open_drain = 0,
.udelay = 40,
@@ -533,6 +536,11 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
I2C_BOARD_INFO("bfin-adv7393", 0x2B),
},
#endif
+#if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE)
+ {
+ I2C_BOARD_INFO("ad5252", 0x2f),
+ },
+#endif
};
static const unsigned int cclk_vlev_datasheet[] =
diff --git a/arch/blackfin/mach-bf533/include/mach/cdefBF532.h b/arch/blackfin/mach-bf533/include/mach/cdefBF532.h
index feb2392c43ea..401e524f5321 100644
--- a/arch/blackfin/mach-bf533/include/mach/cdefBF532.h
+++ b/arch/blackfin/mach-bf533/include/mach/cdefBF532.h
@@ -7,11 +7,6 @@
#ifndef _CDEF_BF532_H
#define _CDEF_BF532_H
-#include <asm/blackfin.h>
-
-/*include all Core registers and bit definitions*/
-#include "defBF532.h"
-
/*include core specific register pointer definitions*/
#include <asm/cdef_LPBlackfin.h>
@@ -655,90 +650,4 @@
/* These need to be last due to the cdef/linux inter-dependencies */
#include <asm/irq.h>
-#if ANOMALY_05000311
-#define BFIN_WRITE_FIO_FLAG(name) \
-static inline void bfin_write_FIO_FLAG_##name(unsigned short val) \
-{ \
- unsigned long flags; \
- local_irq_save_hw(flags); \
- bfin_write16(FIO_FLAG_##name, val); \
- bfin_read_CHIPID(); \
- local_irq_restore_hw(flags); \
-}
-BFIN_WRITE_FIO_FLAG(D)
-BFIN_WRITE_FIO_FLAG(C)
-BFIN_WRITE_FIO_FLAG(S)
-BFIN_WRITE_FIO_FLAG(T)
-
-#define BFIN_READ_FIO_FLAG(name) \
-static inline u16 bfin_read_FIO_FLAG_##name(void) \
-{ \
- unsigned long flags; \
- u16 ret; \
- local_irq_save_hw(flags); \
- ret = bfin_read16(FIO_FLAG_##name); \
- bfin_read_CHIPID(); \
- local_irq_restore_hw(flags); \
- return ret; \
-}
-BFIN_READ_FIO_FLAG(D)
-BFIN_READ_FIO_FLAG(C)
-BFIN_READ_FIO_FLAG(S)
-BFIN_READ_FIO_FLAG(T)
-
-#else
-#define bfin_write_FIO_FLAG_D(val) bfin_write16(FIO_FLAG_D, val)
-#define bfin_write_FIO_FLAG_C(val) bfin_write16(FIO_FLAG_C, val)
-#define bfin_write_FIO_FLAG_S(val) bfin_write16(FIO_FLAG_S, val)
-#define bfin_write_FIO_FLAG_T(val) bfin_write16(FIO_FLAG_T, val)
-#define bfin_read_FIO_FLAG_T() bfin_read16(FIO_FLAG_T)
-#define bfin_read_FIO_FLAG_C() bfin_read16(FIO_FLAG_C)
-#define bfin_read_FIO_FLAG_S() bfin_read16(FIO_FLAG_S)
-#define bfin_read_FIO_FLAG_D() bfin_read16(FIO_FLAG_D)
-#endif
-
-/* Writing to PLL_CTL initiates a PLL relock sequence. */
-static __inline__ void bfin_write_PLL_CTL(unsigned int val)
-{
- unsigned long flags, iwr;
-
- if (val == bfin_read_PLL_CTL())
- return;
-
- local_irq_save_hw(flags);
- /* Enable the PLL Wakeup bit in SIC IWR */
- iwr = bfin_read32(SIC_IWR);
- /* Only allow PPL Wakeup) */
- bfin_write32(SIC_IWR, IWR_ENABLE(0));
-
- bfin_write16(PLL_CTL, val);
- SSYNC();
- asm("IDLE;");
-
- bfin_write32(SIC_IWR, iwr);
- local_irq_restore_hw(flags);
-}
-
-/* Writing to VR_CTL initiates a PLL relock sequence. */
-static __inline__ void bfin_write_VR_CTL(unsigned int val)
-{
- unsigned long flags, iwr;
-
- if (val == bfin_read_VR_CTL())
- return;
-
- local_irq_save_hw(flags);
- /* Enable the PLL Wakeup bit in SIC IWR */
- iwr = bfin_read32(SIC_IWR);
- /* Only allow PPL Wakeup) */
- bfin_write32(SIC_IWR, IWR_ENABLE(0));
-
- bfin_write16(VR_CTL, val);
- SSYNC();
- asm("IDLE;");
-
- bfin_write32(SIC_IWR, iwr);
- local_irq_restore_hw(flags);
-}
-
#endif /* _CDEF_BF532_H */
diff --git a/arch/blackfin/mach-bf533/include/mach/defBF532.h b/arch/blackfin/mach-bf533/include/mach/defBF532.h
index 04acf1ed10f9..3adb0b44e597 100644
--- a/arch/blackfin/mach-bf533/include/mach/defBF532.h
+++ b/arch/blackfin/mach-bf533/include/mach/defBF532.h
@@ -681,76 +681,6 @@
#define PF14_P 14
#define PF15_P 15
-/* *********** SERIAL PERIPHERAL INTERFACE (SPI) MASKS **************** */
-
-/* SPI_CTL Masks */
-#define TIMOD 0x00000003 /* Transfer initiation mode and interrupt generation */
-#define RDBR_CORE 0x0000 /* RDBR Read Initiates, IRQ When RDBR Full */
-#define TDBR_CORE 0x0001 /* TDBR Write Initiates, IRQ When TDBR Empty */
-#define RDBR_DMA 0x0002 /* DMA Read, DMA Until FIFO Empty */
-#define TDBR_DMA 0x0003 /* DMA Write, DMA Until FIFO Full */
-#define SZ 0x00000004 /* Send Zero (=0) or last (=1) word when TDBR empty. */
-#define GM 0x00000008 /* When RDBR full, get more (=1) data or discard (=0) incoming Data */
-#define PSSE 0x00000010 /* Enable (=1) Slave-Select input for Master. */
-#define EMISO 0x00000020 /* Enable (=1) MISO pin as an output. */
-#define SIZE 0x00000100 /* Word length (0 => 8 bits, 1 => 16 bits) */
-#define LSBF 0x00000200 /* Data format (0 => MSB sent/received first 1 => LSB sent/received first) */
-#define CPHA 0x00000400 /* Clock phase (0 => SPICLK starts toggling in middle of xfer, 1 => SPICLK toggles at the beginning of xfer. */
-#define CPOL 0x00000800 /* Clock polarity (0 => active-high, 1 => active-low) */
-#define MSTR 0x00001000 /* Configures SPI as master (=1) or slave (=0) */
-#define WOM 0x00002000 /* Open drain (=1) data output enable (for MOSI and MISO) */
-#define SPE 0x00004000 /* SPI module enable (=1), disable (=0) */
-
-/* SPI_FLG Masks */
-#define FLS1 0x00000002 /* Enables (=1) SPI_FLOUT1 as flag output for SPI Slave-select */
-#define FLS2 0x00000004 /* Enables (=1) SPI_FLOUT2 as flag output for SPI Slave-select */
-#define FLS3 0x00000008 /* Enables (=1) SPI_FLOUT3 as flag output for SPI Slave-select */
-#define FLS4 0x00000010 /* Enables (=1) SPI_FLOUT4 as flag output for SPI Slave-select */
-#define FLS5 0x00000020 /* Enables (=1) SPI_FLOUT5 as flag output for SPI Slave-select */
-#define FLS6 0x00000040 /* Enables (=1) SPI_FLOUT6 as flag output for SPI Slave-select */
-#define FLS7 0x00000080 /* Enables (=1) SPI_FLOUT7 as flag output for SPI Slave-select */
-#define FLG1 0x00000200 /* Activates (=0) SPI_FLOUT1 as flag output for SPI Slave-select */
-#define FLG2 0x00000400 /* Activates (=0) SPI_FLOUT2 as flag output for SPI Slave-select */
-#define FLG3 0x00000800 /* Activates (=0) SPI_FLOUT3 as flag output for SPI Slave-select */
-#define FLG4 0x00001000 /* Activates (=0) SPI_FLOUT4 as flag output for SPI Slave-select */
-#define FLG5 0x00002000 /* Activates (=0) SPI_FLOUT5 as flag output for SPI Slave-select */
-#define FLG6 0x00004000 /* Activates (=0) SPI_FLOUT6 as flag output for SPI Slave-select */
-#define FLG7 0x00008000 /* Activates (=0) SPI_FLOUT7 as flag output for SPI Slave-select */
-
-/* SPI_FLG Bit Positions */
-#define FLS1_P 0x00000001 /* Enables (=1) SPI_FLOUT1 as flag output for SPI Slave-select */
-#define FLS2_P 0x00000002 /* Enables (=1) SPI_FLOUT2 as flag output for SPI Slave-select */
-#define FLS3_P 0x00000003 /* Enables (=1) SPI_FLOUT3 as flag output for SPI Slave-select */
-#define FLS4_P 0x00000004 /* Enables (=1) SPI_FLOUT4 as flag output for SPI Slave-select */
-#define FLS5_P 0x00000005 /* Enables (=1) SPI_FLOUT5 as flag output for SPI Slave-select */
-#define FLS6_P 0x00000006 /* Enables (=1) SPI_FLOUT6 as flag output for SPI Slave-select */
-#define FLS7_P 0x00000007 /* Enables (=1) SPI_FLOUT7 as flag output for SPI Slave-select */
-#define FLG1_P 0x00000009 /* Activates (=0) SPI_FLOUT1 as flag output for SPI Slave-select */
-#define FLG2_P 0x0000000A /* Activates (=0) SPI_FLOUT2 as flag output for SPI Slave-select */
-#define FLG3_P 0x0000000B /* Activates (=0) SPI_FLOUT3 as flag output for SPI Slave-select */
-#define FLG4_P 0x0000000C /* Activates (=0) SPI_FLOUT4 as flag output for SPI Slave-select */
-#define FLG5_P 0x0000000D /* Activates (=0) SPI_FLOUT5 as flag output for SPI Slave-select */
-#define FLG6_P 0x0000000E /* Activates (=0) SPI_FLOUT6 as flag output for SPI Slave-select */
-#define FLG7_P 0x0000000F /* Activates (=0) SPI_FLOUT7 as flag output for SPI Slave-select */
-
-/* SPI_STAT Masks */
-#define SPIF 0x00000001 /* Set (=1) when SPI single-word transfer complete */
-#define MODF 0x00000002 /* Set (=1) in a master device when some other device tries to become master */
-#define TXE 0x00000004 /* Set (=1) when transmission occurs with no new data in SPI_TDBR */
-#define TXS 0x00000008 /* SPI_TDBR Data Buffer Status (0=Empty, 1=Full) */
-#define RBSY 0x00000010 /* Set (=1) when data is received with RDBR full */
-#define RXS 0x00000020 /* SPI_RDBR Data Buffer Status (0=Empty, 1=Full) */
-#define TXCOL 0x00000040 /* When set (=1), corrupt data may have been transmitted */
-
-/* SPIx_FLG Masks */
-#define FLG1E 0xFDFF /* Activates SPI_FLOUT1 */
-#define FLG2E 0xFBFF /* Activates SPI_FLOUT2 */
-#define FLG3E 0xF7FF /* Activates SPI_FLOUT3 */
-#define FLG4E 0xEFFF /* Activates SPI_FLOUT4 */
-#define FLG5E 0xDFFF /* Activates SPI_FLOUT5 */
-#define FLG6E 0xBFFF /* Activates SPI_FLOUT6 */
-#define FLG7E 0x7FFF /* Activates SPI_FLOUT7 */
-
/* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS ************* */
/* AMGCTL Masks */
diff --git a/arch/blackfin/mach-bf533/include/mach/fio_flag.h b/arch/blackfin/mach-bf533/include/mach/fio_flag.h
new file mode 100644
index 000000000000..d0bfba0b083b
--- /dev/null
+++ b/arch/blackfin/mach-bf533/include/mach/fio_flag.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2005-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later
+ */
+
+#ifndef _MACH_FIO_FLAG_H
+#define _MACH_FIO_FLAG_H
+
+#include <asm/blackfin.h>
+#include <asm/irqflags.h>
+
+#if ANOMALY_05000311
+#define BFIN_WRITE_FIO_FLAG(name) \
+static inline void bfin_write_FIO_FLAG_##name(unsigned short val) \
+{ \
+ unsigned long flags; \
+ flags = hard_local_irq_save(); \
+ bfin_write16(FIO_FLAG_##name, val); \
+ bfin_read_CHIPID(); \
+ hard_local_irq_restore(flags); \
+}
+BFIN_WRITE_FIO_FLAG(D)
+BFIN_WRITE_FIO_FLAG(C)
+BFIN_WRITE_FIO_FLAG(S)
+BFIN_WRITE_FIO_FLAG(T)
+
+#define BFIN_READ_FIO_FLAG(name) \
+static inline u16 bfin_read_FIO_FLAG_##name(void) \
+{ \
+ unsigned long flags; \
+ u16 ret; \
+ flags = hard_local_irq_save(); \
+ ret = bfin_read16(FIO_FLAG_##name); \
+ bfin_read_CHIPID(); \
+ hard_local_irq_restore(flags); \
+ return ret; \
+}
+BFIN_READ_FIO_FLAG(D)
+BFIN_READ_FIO_FLAG(C)
+BFIN_READ_FIO_FLAG(S)
+BFIN_READ_FIO_FLAG(T)
+
+#else
+#define bfin_write_FIO_FLAG_D(val) bfin_write16(FIO_FLAG_D, val)
+#define bfin_write_FIO_FLAG_C(val) bfin_write16(FIO_FLAG_C, val)
+#define bfin_write_FIO_FLAG_S(val) bfin_write16(FIO_FLAG_S, val)
+#define bfin_write_FIO_FLAG_T(val) bfin_write16(FIO_FLAG_T, val)
+#define bfin_read_FIO_FLAG_T() bfin_read16(FIO_FLAG_T)
+#define bfin_read_FIO_FLAG_C() bfin_read16(FIO_FLAG_C)
+#define bfin_read_FIO_FLAG_S() bfin_read16(FIO_FLAG_S)
+#define bfin_read_FIO_FLAG_D() bfin_read16(FIO_FLAG_D)
+#endif
+
+#endif /* _MACH_FIO_FLAG_H */
diff --git a/arch/blackfin/mach-bf533/include/mach/pll.h b/arch/blackfin/mach-bf533/include/mach/pll.h
new file mode 100644
index 000000000000..169c106d0edb
--- /dev/null
+++ b/arch/blackfin/mach-bf533/include/mach/pll.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2005-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later
+ */
+
+#ifndef _MACH_PLL_H
+#define _MACH_PLL_H
+
+#include <asm/blackfin.h>
+#include <asm/irqflags.h>
+
+/* Writing to PLL_CTL initiates a PLL relock sequence. */
+static __inline__ void bfin_write_PLL_CTL(unsigned int val)
+{
+ unsigned long flags, iwr;
+
+ if (val == bfin_read_PLL_CTL())
+ return;
+
+ flags = hard_local_irq_save();
+ /* Enable the PLL Wakeup bit in SIC IWR */
+ iwr = bfin_read32(SIC_IWR);
+ /* Only allow PPL Wakeup) */
+ bfin_write32(SIC_IWR, IWR_ENABLE(0));
+
+ bfin_write16(PLL_CTL, val);
+ SSYNC();
+ asm("IDLE;");
+
+ bfin_write32(SIC_IWR, iwr);
+ hard_local_irq_restore(flags);
+}
+
+/* Writing to VR_CTL initiates a PLL relock sequence. */
+static __inline__ void bfin_write_VR_CTL(unsigned int val)
+{
+ unsigned long flags, iwr;
+
+ if (val == bfin_read_VR_CTL())
+ return;
+
+ flags = hard_local_irq_save();
+ /* Enable the PLL Wakeup bit in SIC IWR */
+ iwr = bfin_read32(SIC_IWR);
+ /* Only allow PPL Wakeup) */
+ bfin_write32(SIC_IWR, IWR_ENABLE(0));
+
+ bfin_write16(VR_CTL, val);
+ SSYNC();
+ asm("IDLE;");
+
+ bfin_write32(SIC_IWR, iwr);
+ hard_local_irq_restore(flags);
+}
+
+#endif /* _MACH_PLL_H */
diff --git a/arch/blackfin/mach-bf537/Kconfig b/arch/blackfin/mach-bf537/Kconfig
index d81224f9d723..08b2b343ccec 100644
--- a/arch/blackfin/mach-bf537/Kconfig
+++ b/arch/blackfin/mach-bf537/Kconfig
@@ -14,8 +14,8 @@ config IRQ_DMA_ERROR
int "IRQ_DMA_ERROR Generic"
default 7
config IRQ_ERROR
- int "IRQ_ERROR: CAN MAC SPORT0 SPORT1 SPI UART0 UART1"
- default 7
+ int "IRQ_ERROR: PPI CAN MAC SPORT0 SPORT1 SPI UART0 UART1"
+ default 11
config IRQ_RTC
int "IRQ_RTC"
default 8
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537e.c b/arch/blackfin/mach-bf537/boards/cm_bf537e.c
index d35fc5fe4c2b..e2e7be40ef44 100644
--- a/arch/blackfin/mach-bf537/boards/cm_bf537e.c
+++ b/arch/blackfin/mach-bf537/boards/cm_bf537e.c
@@ -73,7 +73,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
};
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
.enable_dma = 0,
.bits_per_word = 16,
@@ -112,12 +112,12 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
},
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
{
- .modalias = "ad1836",
+ .modalias = "ad183x",
.max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
.bus_num = 0,
- .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .chip_select = 4,
.controller_data = &ad1836_spi_chip_info,
},
#endif
@@ -229,7 +229,7 @@ static struct resource isp1362_hcd_resources[] = {
}, {
.start = IRQ_PG15,
.end = IRQ_PG15,
- .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
},
};
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537u.c b/arch/blackfin/mach-bf537/boards/cm_bf537u.c
index d464ad5b72b2..752c833f7ca8 100644
--- a/arch/blackfin/mach-bf537/boards/cm_bf537u.c
+++ b/arch/blackfin/mach-bf537/boards/cm_bf537u.c
@@ -74,7 +74,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
};
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
.enable_dma = 0,
.bits_per_word = 16,
@@ -113,12 +113,12 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
},
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
{
- .modalias = "ad1836",
+ .modalias = "ad183x",
.max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
.bus_num = 0,
- .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .chip_select = 4,
.controller_data = &ad1836_spi_chip_info,
},
#endif
@@ -230,7 +230,7 @@ static struct resource isp1362_hcd_resources[] = {
}, {
.start = IRQ_PG15,
.end = IRQ_PG15,
- .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
},
};
diff --git a/arch/blackfin/mach-bf537/boards/pnav10.c b/arch/blackfin/mach-bf537/boards/pnav10.c
index 812e8f991601..6b03808800a6 100644
--- a/arch/blackfin/mach-bf537/boards/pnav10.c
+++ b/arch/blackfin/mach-bf537/boards/pnav10.c
@@ -175,8 +175,8 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
};
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD183X) \
- || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) \
+ || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
.enable_dma = 0,
.bits_per_word = 16,
@@ -238,13 +238,13 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
},
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD183X) \
- || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) \
+ || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
{
- .modalias = "ad1836",
+ .modalias = "ad183x",
.max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
.bus_num = 0,
- .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .chip_select = 4,
.controller_data = &ad1836_spi_chip_info,
},
#endif
diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c
index 68a27bccc7d4..cd2c797c8c9f 100644
--- a/arch/blackfin/mach-bf537/boards/stamp.c
+++ b/arch/blackfin/mach-bf537/boards/stamp.c
@@ -35,12 +35,10 @@
#include <asm/reboot.h>
#include <asm/portmux.h>
#include <asm/dpmc.h>
-#ifdef CONFIG_REGULATOR_ADP_SWITCH
-#include <linux/regulator/adp_switch.h>
-#endif
-#ifdef CONFIG_REGULATOR_AD5398
-#include <linux/regulator/ad5398.h>
+#ifdef CONFIG_REGULATOR_FIXED_VOLTAGE
+#include <linux/regulator/fixed.h>
#endif
+#include <linux/regulator/machine.h>
#include <linux/regulator/consumer.h>
#include <linux/regulator/userspace-consumer.h>
@@ -264,7 +262,7 @@ static struct resource isp1362_hcd_resources[] = {
}, {
.start = IRQ_PF3,
.end = IRQ_PF3,
- .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
},
};
@@ -418,7 +416,7 @@ static struct platform_nand_data bfin_plat_nand_data = {
static struct resource bfin_plat_nand_resources = {
.start = 0x20212000,
.end = 0x20212000 + (1 << MAX(BFIN_NAND_PLAT_CLE, BFIN_NAND_PLAT_ALE)),
- .flags = IORESOURCE_IO,
+ .flags = IORESOURCE_MEM,
};
static struct platform_device bfin_async_nand_device = {
@@ -545,6 +543,14 @@ static struct bfin5xx_spi_chip ad1938_spi_chip_info = {
};
#endif
+#if defined(CONFIG_SND_BF5XX_SOC_ADAV80X) \
+ || defined(CONFIG_SND_BF5XX_SOC_ADAV80X_MODULE)
+static struct bfin5xx_spi_chip adav801_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 8,
+};
+#endif
+
#if defined(CONFIG_INPUT_AD714X_SPI) || defined(CONFIG_INPUT_AD714X_SPI_MODULE)
#include <linux/input/ad714x.h>
static struct bfin5xx_spi_chip ad7147_spi_chip_info = {
@@ -693,6 +699,65 @@ static struct bfin5xx_spi_chip ad2s1210_spi_chip_info = {
};
#endif
+#if defined(CONFIG_AD7314) || defined(CONFIG_AD7314_MODULE)
+static struct bfin5xx_spi_chip ad7314_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_AD7816) || defined(CONFIG_AD7816_MODULE)
+static unsigned short ad7816_platform_data[] = {
+ GPIO_PF4, /* rdwr_pin */
+ GPIO_PF5, /* convert_pin */
+ GPIO_PF7, /* busy_pin */
+ 0,
+};
+
+static struct bfin5xx_spi_chip ad7816_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_ADT7310) || defined(CONFIG_ADT7310_MODULE)
+static unsigned long adt7310_platform_data[3] = {
+/* INT bound temperature alarm event. line 1 */
+ IRQ_PG4, IRQF_TRIGGER_LOW,
+/* CT bound temperature alarm event irq_flags. line 0 */
+ IRQF_TRIGGER_LOW,
+};
+
+static struct bfin5xx_spi_chip adt7310_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_AD7298) || defined(CONFIG_AD7298_MODULE)
+static unsigned short ad7298_platform_data[] = {
+ GPIO_PF7, /* busy_pin */
+ 0,
+};
+
+static struct bfin5xx_spi_chip ad7298_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_ADT7316_SPI) || defined(CONFIG_ADT7316_SPI_MODULE)
+static unsigned long adt7316_spi_data[2] = {
+ IRQF_TRIGGER_LOW, /* interrupt flags */
+ GPIO_PF7, /* ldac_pin, 0 means DAC/LDAC registers control DAC update */
+};
+
+static struct bfin5xx_spi_chip adt7316_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 8,
+};
+#endif
+
#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
#define MMC_SPI_CARD_DETECT_INT IRQ_PF5
@@ -824,14 +889,12 @@ static struct bfin5xx_spi_chip lq035q1_spi_chip_info = {
static struct bfin5xx_spi_chip enc28j60_spi_chip_info = {
.enable_dma = 1,
.bits_per_word = 8,
- .cs_gpio = GPIO_PF10,
};
#endif
#if defined(CONFIG_ADF702X) || defined(CONFIG_ADF702X_MODULE)
static struct bfin5xx_spi_chip adf7021_spi_chip_info = {
.bits_per_word = 16,
- .cs_gpio = GPIO_PF10,
};
#include <linux/spi/adf702x.h>
@@ -938,6 +1001,13 @@ static struct bfin5xx_spi_chip spi_adxl34x_chip_info = {
};
#endif
+#if defined(CONFIG_AD7476) || defined(CONFIG_AD7476_MODULE)
+static struct bfin5xx_spi_chip spi_ad7476_chip_info = {
+ .enable_dma = 0, /* use dma transfer with this chip*/
+ .bits_per_word = 8,
+};
+#endif
+
static struct spi_board_info bfin_spi_board_info[] __initdata = {
#if defined(CONFIG_MTD_M25P80) \
|| defined(CONFIG_MTD_M25P80_MODULE)
@@ -982,7 +1052,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
.modalias = "ad183x",
.max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
.bus_num = 0,
- .chip_select = 4,/* CONFIG_SND_BLACKFIN_SPI_PFBIT */
+ .chip_select = 4,
.platform_data = "ad1836", /* only includes chip name for the moment */
.controller_data = &ad1836_spi_chip_info,
.mode = SPI_MODE_3,
@@ -1000,6 +1070,17 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
},
#endif
+#if defined(CONFIG_SND_BF5XX_SOC_ADAV80X) || defined(CONFIG_SND_BF5XX_SOC_ADAV80X_MODULE)
+ {
+ .modalias = "adav80x",
+ .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 1,
+ .controller_data = &adav801_spi_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+
#if defined(CONFIG_INPUT_AD714X_SPI) || defined(CONFIG_INPUT_AD714X_SPI_MODULE)
{
.modalias = "ad714x_captouch",
@@ -1018,6 +1099,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
.modalias = "ad2s90",
.bus_num = 0,
.chip_select = 3, /* change it for your board */
+ .mode = SPI_MODE_3,
.platform_data = NULL,
.controller_data = &ad2s90_spi_chip_info,
},
@@ -1044,6 +1126,67 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
},
#endif
+#if defined(CONFIG_AD7314) || defined(CONFIG_AD7314_MODULE)
+ {
+ .modalias = "ad7314",
+ .max_speed_hz = 1000000,
+ .bus_num = 0,
+ .chip_select = 4, /* CS, change it for your board */
+ .controller_data = &ad7314_spi_chip_info,
+ .mode = SPI_MODE_1,
+ },
+#endif
+
+#if defined(CONFIG_AD7816) || defined(CONFIG_AD7816_MODULE)
+ {
+ .modalias = "ad7818",
+ .max_speed_hz = 1000000,
+ .bus_num = 0,
+ .chip_select = 4, /* CS, change it for your board */
+ .platform_data = ad7816_platform_data,
+ .controller_data = &ad7816_spi_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+
+#if defined(CONFIG_ADT7310) || defined(CONFIG_ADT7310_MODULE)
+ {
+ .modalias = "adt7310",
+ .max_speed_hz = 1000000,
+ .irq = IRQ_PG5, /* CT alarm event. Line 0 */
+ .bus_num = 0,
+ .chip_select = 4, /* CS, change it for your board */
+ .platform_data = adt7310_platform_data,
+ .controller_data = &adt7310_spi_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+
+#if defined(CONFIG_AD7298) || defined(CONFIG_AD7298_MODULE)
+ {
+ .modalias = "ad7298",
+ .max_speed_hz = 1000000,
+ .bus_num = 0,
+ .chip_select = 4, /* CS, change it for your board */
+ .platform_data = ad7298_platform_data,
+ .controller_data = &ad7298_spi_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+
+#if defined(CONFIG_ADT7316_SPI) || defined(CONFIG_ADT7316_SPI_MODULE)
+ {
+ .modalias = "adt7316",
+ .max_speed_hz = 1000000,
+ .irq = IRQ_PG5, /* interrupt line */
+ .bus_num = 0,
+ .chip_select = 4, /* CS, change it for your board */
+ .platform_data = adt7316_spi_data,
+ .controller_data = &adt7316_spi_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+
#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
{
.modalias = "mmc_spi",
@@ -1103,7 +1246,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
.max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */
.irq = IRQ_PF6,
.bus_num = 0,
- .chip_select = 0, /* GPIO controlled SSEL */
+ .chip_select = GPIO_PF10 + MAX_CTRL_CS, /* GPIO controlled SSEL */
.controller_data = &enc28j60_spi_chip_info,
.mode = SPI_MODE_0,
},
@@ -1125,7 +1268,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
.modalias = "adf702x",
.max_speed_hz = 16000000, /* max spi clock (SCK) speed in HZ */
.bus_num = 0,
- .chip_select = 0, /* GPIO controlled SSEL */
+ .chip_select = GPIO_PF10 + MAX_CTRL_CS, /* GPIO controlled SSEL */
.controller_data = &adf7021_spi_chip_info,
.platform_data = &adf7021_platform_data,
.mode = SPI_MODE_0,
@@ -1143,12 +1286,239 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
.mode = SPI_MODE_0,
},
#endif
+#if defined(CONFIG_AD7476) \
+ || defined(CONFIG_AD7476_MODULE)
+ {
+ .modalias = "ad7476", /* Name of spi_driver for this device */
+ .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0, /* Framework bus number */
+ .chip_select = 1, /* Framework chip select. */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .controller_data = &spi_ad7476_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+#if defined(CONFIG_ADE7753) \
+ || defined(CONFIG_ADE7753_MODULE)
+ {
+ .modalias = "ade7753",
+ .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 1, /* CS, change it for your board */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .mode = SPI_MODE_1,
+ },
+#endif
+#if defined(CONFIG_ADE7754) \
+ || defined(CONFIG_ADE7754_MODULE)
+ {
+ .modalias = "ade7754",
+ .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 1, /* CS, change it for your board */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .mode = SPI_MODE_1,
+ },
+#endif
+#if defined(CONFIG_ADE7758) \
+ || defined(CONFIG_ADE7758_MODULE)
+ {
+ .modalias = "ade7758",
+ .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 1, /* CS, change it for your board */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .mode = SPI_MODE_1,
+ },
+#endif
+#if defined(CONFIG_ADE7759) \
+ || defined(CONFIG_ADE7759_MODULE)
+ {
+ .modalias = "ade7759",
+ .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 1, /* CS, change it for your board */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .mode = SPI_MODE_1,
+ },
+#endif
+#if defined(CONFIG_ADE7854_SPI) \
+ || defined(CONFIG_ADE7854_SPI_MODULE)
+ {
+ .modalias = "ade7854",
+ .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 1, /* CS, change it for your board */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .mode = SPI_MODE_3,
+ },
+#endif
+#if defined(CONFIG_ADIS16060) \
+ || defined(CONFIG_ADIS16060_MODULE)
+ {
+ .modalias = "adis16060_r",
+ .max_speed_hz = 2900000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = MAX_CTRL_CS + 1, /* CS for read, change it for your board */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .mode = SPI_MODE_0,
+ },
+ {
+ .modalias = "adis16060_w",
+ .max_speed_hz = 2900000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 2, /* CS for write, change it for your board */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .mode = SPI_MODE_1,
+ },
+#endif
+#if defined(CONFIG_ADIS16130) \
+ || defined(CONFIG_ADIS16130_MODULE)
+ {
+ .modalias = "adis16130",
+ .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 1, /* CS for read, change it for your board */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .mode = SPI_MODE_3,
+ },
+#endif
+#if defined(CONFIG_ADIS16201) \
+ || defined(CONFIG_ADIS16201_MODULE)
+ {
+ .modalias = "adis16201",
+ .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 5, /* CS, change it for your board */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .mode = SPI_MODE_3,
+ .irq = IRQ_PF4,
+ },
+#endif
+#if defined(CONFIG_ADIS16203) \
+ || defined(CONFIG_ADIS16203_MODULE)
+ {
+ .modalias = "adis16203",
+ .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 5, /* CS, change it for your board */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .mode = SPI_MODE_3,
+ .irq = IRQ_PF4,
+ },
+#endif
+#if defined(CONFIG_ADIS16204) \
+ || defined(CONFIG_ADIS16204_MODULE)
+ {
+ .modalias = "adis16204",
+ .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 5, /* CS, change it for your board */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .mode = SPI_MODE_3,
+ .irq = IRQ_PF4,
+ },
+#endif
+#if defined(CONFIG_ADIS16209) \
+ || defined(CONFIG_ADIS16209_MODULE)
+ {
+ .modalias = "adis16209",
+ .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 5, /* CS, change it for your board */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .mode = SPI_MODE_3,
+ .irq = IRQ_PF4,
+ },
+#endif
+#if defined(CONFIG_ADIS16220) \
+ || defined(CONFIG_ADIS16220_MODULE)
+ {
+ .modalias = "adis16220",
+ .max_speed_hz = 2000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 5, /* CS, change it for your board */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .mode = SPI_MODE_3,
+ .irq = IRQ_PF4,
+ },
+#endif
+#if defined(CONFIG_ADIS16240) \
+ || defined(CONFIG_ADIS16240_MODULE)
+ {
+ .modalias = "adis16240",
+ .max_speed_hz = 1500000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 5, /* CS, change it for your board */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .mode = SPI_MODE_3,
+ .irq = IRQ_PF4,
+ },
+#endif
+#if defined(CONFIG_ADIS16260) \
+ || defined(CONFIG_ADIS16260_MODULE)
+ {
+ .modalias = "adis16260",
+ .max_speed_hz = 1500000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 5, /* CS, change it for your board */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .mode = SPI_MODE_3,
+ .irq = IRQ_PF4,
+ },
+#endif
+#if defined(CONFIG_ADIS16261) \
+ || defined(CONFIG_ADIS16261_MODULE)
+ {
+ .modalias = "adis16261",
+ .max_speed_hz = 2500000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 1, /* CS, change it for your board */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .mode = SPI_MODE_3,
+ },
+#endif
+#if defined(CONFIG_ADIS16300) \
+ || defined(CONFIG_ADIS16300_MODULE)
+ {
+ .modalias = "adis16300",
+ .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 5, /* CS, change it for your board */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .mode = SPI_MODE_3,
+ .irq = IRQ_PF4,
+ },
+#endif
+#if defined(CONFIG_ADIS16350) \
+ || defined(CONFIG_ADIS16350_MODULE)
+ {
+ .modalias = "adis16364",
+ .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 5, /* CS, change it for your board */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .mode = SPI_MODE_3,
+ .irq = IRQ_PF4,
+ },
+#endif
+#if defined(CONFIG_ADIS16400) \
+ || defined(CONFIG_ADIS16400_MODULE)
+ {
+ .modalias = "adis16400",
+ .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 1, /* CS, change it for your board */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .mode = SPI_MODE_3,
+ },
+#endif
};
#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
/* SPI controller data */
static struct bfin5xx_spi_master bfin_spi0_info = {
- .num_chipselect = 8,
+ .num_chipselect = MAX_CTRL_CS + MAX_BLACKFIN_GPIOS,
.enable_dma = 1, /* master has the ability to do dma transfer */
.pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0},
};
@@ -1645,7 +2015,7 @@ static struct adp5520_keys_platform_data adp5520_keys_data = {
};
/*
- * ADP5520/5501 Multifuction Device Init Data
+ * ADP5520/5501 Multifunction Device Init Data
*/
static struct adp5520_platform_data adp5520_pdev_data = {
@@ -1773,12 +2143,6 @@ static struct regulator_init_data ad5398_regulator_data = {
.consumer_supplies = &ad5398_consumer,
};
-static struct ad5398_platform_data ad5398_i2c_platform_data = {
- .current_bits = 10,
- .current_offset = 4,
- .regulator_data = &ad5398_regulator_data,
-};
-
#if defined(CONFIG_REGULATOR_VIRTUAL_CONSUMER) || \
defined(CONFIG_REGULATOR_VIRTUAL_CONSUMER_MODULE)
static struct platform_device ad5398_virt_consumer_device = {
@@ -1811,7 +2175,34 @@ static struct platform_device ad5398_userspace_consumer_device = {
#endif
#endif
+#if defined(CONFIG_ADT7410) || defined(CONFIG_ADT7410_MODULE)
+/* INT bound temperature alarm event. line 1 */
+static unsigned long adt7410_platform_data[2] = {
+ IRQ_PG4, IRQF_TRIGGER_LOW,
+};
+#endif
+
+#if defined(CONFIG_ADT7316_I2C) || defined(CONFIG_ADT7316_I2C_MODULE)
+/* INT bound temperature alarm event. line 1 */
+static unsigned long adt7316_i2c_data[2] = {
+ IRQF_TRIGGER_LOW, /* interrupt flags */
+ GPIO_PF4, /* ldac_pin, 0 means DAC/LDAC registers control DAC update */
+};
+#endif
+
static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
+#if defined(CONFIG_SND_BF5XX_SOC_AD193X) || defined(CONFIG_SND_BF5XX_SOC_AD193X_MODULE)
+ {
+ I2C_BOARD_INFO("ad1937", 0x04),
+ },
+#endif
+
+#if defined(CONFIG_SND_BF5XX_SOC_ADAV80X) || defined(CONFIG_SND_BF5XX_SOC_ADAV80X_MODULE)
+ {
+ I2C_BOARD_INFO("adav803", 0x10),
+ },
+#endif
+
#if defined(CONFIG_INPUT_AD714X_I2C) || defined(CONFIG_INPUT_AD714X_I2C_MODULE)
{
I2C_BOARD_INFO("ad7142_captouch", 0x2C),
@@ -1843,12 +2234,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
{
I2C_BOARD_INFO("ad7414", 0x9),
.irq = IRQ_PG5,
- /*
- * platform_data pointer is borrwoed by the driver to
- * store custimer defined IRQ ALART level mode.
- * only IRQF_TRIGGER_HIGH and IRQF_TRIGGER_LOW are valid.
- */
- .platform_data = (void *)IRQF_TRIGGER_LOW,
+ .irq_flags = IRQF_TRIGGER_LOW,
},
#endif
@@ -1856,12 +2242,56 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
{
I2C_BOARD_INFO("ad7417", 0xb),
.irq = IRQ_PG5,
- /*
- * platform_data pointer is borrwoed by the driver to
- * store custimer defined IRQ ALART level mode.
- * only IRQF_TRIGGER_HIGH and IRQF_TRIGGER_LOW are valid.
- */
- .platform_data = (void *)IRQF_TRIGGER_LOW,
+ .irq_flags = IRQF_TRIGGER_LOW,
+ .platform_data = (void *)GPIO_PF4,
+ },
+#endif
+
+#if defined(CONFIG_ADE7854_I2C) || defined(CONFIG_ADE7854_I2C_MODULE)
+ {
+ I2C_BOARD_INFO("ade7854", 0x38),
+ },
+#endif
+
+#if defined(CONFIG_ADT75) || defined(CONFIG_ADT75_MODULE)
+ {
+ I2C_BOARD_INFO("adt75", 0x9),
+ .irq = IRQ_PG5,
+ .irq_flags = IRQF_TRIGGER_LOW,
+ },
+#endif
+
+#if defined(CONFIG_ADT7408) || defined(CONFIG_ADT7408_MODULE)
+ {
+ I2C_BOARD_INFO("adt7408", 0x18),
+ .irq = IRQ_PG5,
+ .irq_flags = IRQF_TRIGGER_LOW,
+ },
+#endif
+
+#if defined(CONFIG_ADT7410) || defined(CONFIG_ADT7410_MODULE)
+ {
+ I2C_BOARD_INFO("adt7410", 0x48),
+ /* CT critical temperature event. line 0 */
+ .irq = IRQ_PG5,
+ .irq_flags = IRQF_TRIGGER_LOW,
+ .platform_data = (void *)&adt7410_platform_data,
+ },
+#endif
+
+#if defined(CONFIG_AD7291) || defined(CONFIG_AD7291_MODULE)
+ {
+ I2C_BOARD_INFO("ad7291", 0x20),
+ .irq = IRQ_PG5,
+ .irq_flags = IRQF_TRIGGER_LOW,
+ },
+#endif
+
+#if defined(CONFIG_ADT7316_I2C) || defined(CONFIG_ADT7316_I2C_MODULE)
+ {
+ I2C_BOARD_INFO("adt7316", 0x48),
+ .irq = IRQ_PG6,
+ .platform_data = (void *)&adt7316_i2c_data,
},
#endif
@@ -1917,7 +2347,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
#endif
#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
{
- I2C_BOARD_INFO("bf537-lq035-ad5280", 0x2C),
+ I2C_BOARD_INFO("bf537-lq035-ad5280", 0x2F),
},
#endif
#if defined(CONFIG_BACKLIGHT_ADP8870) || defined(CONFIG_BACKLIGHT_ADP8870_MODULE)
@@ -1954,7 +2384,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
#if defined(CONFIG_REGULATOR_AD5398) || defined(CONFIG_REGULATOR_AD5398_MODULE)
{
I2C_BOARD_INFO("ad5398", 0xC),
- .platform_data = (void *)&ad5398_i2c_platform_data,
+ .platform_data = (void *)&ad5398_regulator_data,
},
#endif
#if defined(CONFIG_BACKLIGHT_ADP8860) || defined(CONFIG_BACKLIGHT_ADP8860_MODULE)
@@ -1963,6 +2393,16 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
.platform_data = (void *)&adp8860_pdata,
},
#endif
+#if defined(CONFIG_SND_SOC_ADAU1373) || defined(CONFIG_SND_SOC_ADAU1373_MODULE)
+ {
+ I2C_BOARD_INFO("adau1373", 0x1A),
+ },
+#endif
+#if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE)
+ {
+ I2C_BOARD_INFO("ad5252", 0x2e),
+ },
+#endif
};
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
@@ -2147,50 +2587,38 @@ static struct platform_device bfin_ac97 = {
};
#endif
-#if defined(CONFIG_REGULATOR_ADP_SWITCH) || defined(CONFIG_REGULATOR_ADP_SWITCH_MODULE)
-#define REGULATOR_ADP122 "adp122"
-#define REGULATOR_ADP150 "adp150"
+#if defined(CONFIG_REGULATOR_FIXED_VOLTAGE) || defined(CONFIG_REGULATOR_FIXED_VOLTAGE_MODULE)
+#define REGULATOR_ADP122 "adp122"
+#define REGULATOR_ADP122_UV 2500000
static struct regulator_consumer_supply adp122_consumers = {
.supply = REGULATOR_ADP122,
};
-static struct regulator_consumer_supply adp150_consumers = {
- .supply = REGULATOR_ADP150,
-};
-
-static struct regulator_init_data adp_switch_regulator_data[] = {
- {
- .constraints = {
- .name = REGULATOR_ADP122,
- .valid_ops_mask = REGULATOR_CHANGE_STATUS,
- .min_uA = 0,
- .max_uA = 300000,
- },
- .num_consumer_supplies = 1, /* only 1 */
- .consumer_supplies = &adp122_consumers,
- .driver_data = (void *)GPIO_PF2, /* gpio port only */
- },
- {
- .constraints = {
- .name = REGULATOR_ADP150,
- .valid_ops_mask = REGULATOR_CHANGE_STATUS,
- .min_uA = 0,
- .max_uA = 150000,
- },
- .num_consumer_supplies = 1, /* only 1 */
- .consumer_supplies = &adp150_consumers,
- .driver_data = (void *)GPIO_PF3, /* gpio port only */
+static struct regulator_init_data adp_switch_regulator_data = {
+ .constraints = {
+ .name = REGULATOR_ADP122,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .min_uV = REGULATOR_ADP122_UV,
+ .max_uV = REGULATOR_ADP122_UV,
+ .min_uA = 0,
+ .max_uA = 300000,
},
+ .num_consumer_supplies = 1, /* only 1 */
+ .consumer_supplies = &adp122_consumers,
};
-static struct adp_switch_platform_data adp_switch_pdata = {
- .regulator_num = ARRAY_SIZE(adp_switch_regulator_data),
- .regulator_data = adp_switch_regulator_data,
+static struct fixed_voltage_config adp_switch_pdata = {
+ .supply_name = REGULATOR_ADP122,
+ .microvolts = REGULATOR_ADP122_UV,
+ .gpio = GPIO_PF2,
+ .enable_high = 1,
+ .enabled_at_boot = 0,
+ .init_data = &adp_switch_regulator_data,
};
static struct platform_device adp_switch_device = {
- .name = "adp_switch",
+ .name = "reg-fixed-voltage",
.id = 0,
.dev = {
.platform_data = &adp_switch_pdata,
@@ -2216,27 +2644,26 @@ static struct platform_device adp122_userspace_consumer_device = {
.platform_data = &adp122_userspace_comsumer_data,
},
};
+#endif
+#endif
-static struct regulator_bulk_data adp150_bulk_data = {
- .supply = REGULATOR_ADP150,
-};
+#if defined(CONFIG_IIO_GPIO_TRIGGER) || \
+ defined(CONFIG_IIO_GPIO_TRIGGER_MODULE)
-static struct regulator_userspace_consumer_data adp150_userspace_comsumer_data = {
- .name = REGULATOR_ADP150,
- .num_supplies = 1,
- .supplies = &adp150_bulk_data,
+static struct resource iio_gpio_trigger_resources[] = {
+ [0] = {
+ .start = IRQ_PF5,
+ .end = IRQ_PF5,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
+ },
};
-static struct platform_device adp150_userspace_consumer_device = {
- .name = "reg-userspace-consumer",
- .id = 1,
- .dev = {
- .platform_data = &adp150_userspace_comsumer_data,
- },
+static struct platform_device iio_gpio_trigger = {
+ .name = "iio_gpio_trigger",
+ .num_resources = ARRAY_SIZE(iio_gpio_trigger_resources),
+ .resource = iio_gpio_trigger_resources,
};
#endif
-#endif
-
static struct platform_device *stamp_devices[] __initdata = {
@@ -2369,14 +2796,18 @@ static struct platform_device *stamp_devices[] __initdata = {
#endif
#endif
-#if defined(CONFIG_REGULATOR_ADP_SWITCH) || defined(CONFIG_REGULATOR_ADP_SWITCH_MODULE)
+#if defined(CONFIG_REGULATOR_FIXED_VOLTAGE) || defined(CONFIG_REGULATOR_FIXED_VOLTAGE_MODULE)
&adp_switch_device,
#if defined(CONFIG_REGULATOR_USERSPACE_CONSUMER) || \
defined(CONFIG_REGULATOR_USERSPACE_CONSUMER_MODULE)
&adp122_userspace_consumer_device,
- &adp150_userspace_consumer_device,
#endif
#endif
+
+#if defined(CONFIG_IIO_GPIO_TRIGGER) || \
+ defined(CONFIG_IIO_GPIO_TRIGGER_MODULE)
+ &iio_gpio_trigger,
+#endif
};
static int __init stamp_init(void)
diff --git a/arch/blackfin/mach-bf537/boards/tcm_bf537.c b/arch/blackfin/mach-bf537/boards/tcm_bf537.c
index 4f0a2e72ce4c..a4d62b5fc7ba 100644
--- a/arch/blackfin/mach-bf537/boards/tcm_bf537.c
+++ b/arch/blackfin/mach-bf537/boards/tcm_bf537.c
@@ -74,7 +74,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
};
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
.enable_dma = 0,
.bits_per_word = 16,
@@ -113,12 +113,12 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
},
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
{
- .modalias = "ad1836",
+ .modalias = "ad183x",
.max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
.bus_num = 0,
- .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .chip_select = 4,
.controller_data = &ad1836_spi_chip_info,
},
#endif
@@ -230,7 +230,7 @@ static struct resource isp1362_hcd_resources[] = {
}, {
.start = IRQ_PG15,
.end = IRQ_PG15,
- .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
},
};
diff --git a/arch/blackfin/mach-bf537/include/mach/cdefBF534.h b/arch/blackfin/mach-bf537/include/mach/cdefBF534.h
index 91825c9bd226..fbeb35e14135 100644
--- a/arch/blackfin/mach-bf537/include/mach/cdefBF534.h
+++ b/arch/blackfin/mach-bf537/include/mach/cdefBF534.h
@@ -1750,48 +1750,4 @@
/* These need to be last due to the cdef/linux inter-dependencies */
#include <asm/irq.h>
-/* Writing to PLL_CTL initiates a PLL relock sequence. */
-static __inline__ void bfin_write_PLL_CTL(unsigned int val)
-{
- unsigned long flags, iwr;
-
- if (val == bfin_read_PLL_CTL())
- return;
-
- local_irq_save_hw(flags);
- /* Enable the PLL Wakeup bit in SIC IWR */
- iwr = bfin_read32(SIC_IWR);
- /* Only allow PPL Wakeup) */
- bfin_write32(SIC_IWR, IWR_ENABLE(0));
-
- bfin_write16(PLL_CTL, val);
- SSYNC();
- asm("IDLE;");
-
- bfin_write32(SIC_IWR, iwr);
- local_irq_restore_hw(flags);
-}
-
-/* Writing to VR_CTL initiates a PLL relock sequence. */
-static __inline__ void bfin_write_VR_CTL(unsigned int val)
-{
- unsigned long flags, iwr;
-
- if (val == bfin_read_VR_CTL())
- return;
-
- local_irq_save_hw(flags);
- /* Enable the PLL Wakeup bit in SIC IWR */
- iwr = bfin_read32(SIC_IWR);
- /* Only allow PPL Wakeup) */
- bfin_write32(SIC_IWR, IWR_ENABLE(0));
-
- bfin_write16(VR_CTL, val);
- SSYNC();
- asm("IDLE;");
-
- bfin_write32(SIC_IWR, iwr);
- local_irq_restore_hw(flags);
-}
-
#endif /* _CDEF_BF534_H */
diff --git a/arch/blackfin/mach-bf537/include/mach/defBF534.h b/arch/blackfin/mach-bf537/include/mach/defBF534.h
index 6f56907a18c0..0323e6bacdae 100644
--- a/arch/blackfin/mach-bf537/include/mach/defBF534.h
+++ b/arch/blackfin/mach-bf537/include/mach/defBF534.h
@@ -1071,50 +1071,6 @@
#define FPE 0x10 /* Force Parity Error On Transmit */
#define FFE 0x20 /* Force Framing Error On Transmit */
-/* *********** SERIAL PERIPHERAL INTERFACE (SPI) MASKS ****************************/
-/* SPI_CTL Masks */
-#define TIMOD 0x0003 /* Transfer Initiate Mode */
-#define RDBR_CORE 0x0000 /* RDBR Read Initiates, IRQ When RDBR Full */
-#define TDBR_CORE 0x0001 /* TDBR Write Initiates, IRQ When TDBR Empty */
-#define RDBR_DMA 0x0002 /* DMA Read, DMA Until FIFO Empty */
-#define TDBR_DMA 0x0003 /* DMA Write, DMA Until FIFO Full */
-#define SZ 0x0004 /* Send Zero (When TDBR Empty, Send Zero/Last*) */
-#define GM 0x0008 /* Get More (When RDBR Full, Overwrite/Discard*) */
-#define PSSE 0x0010 /* Slave-Select Input Enable */
-#define EMISO 0x0020 /* Enable MISO As Output */
-#define SIZE 0x0100 /* Size of Words (16/8* Bits) */
-#define LSBF 0x0200 /* LSB First */
-#define CPHA 0x0400 /* Clock Phase */
-#define CPOL 0x0800 /* Clock Polarity */
-#define MSTR 0x1000 /* Master/Slave* */
-#define WOM 0x2000 /* Write Open Drain Master */
-#define SPE 0x4000 /* SPI Enable */
-
-/* SPI_FLG Masks */
-#define FLS1 0x0002 /* Enables SPI_FLOUT1 as SPI Slave-Select Output */
-#define FLS2 0x0004 /* Enables SPI_FLOUT2 as SPI Slave-Select Output */
-#define FLS3 0x0008 /* Enables SPI_FLOUT3 as SPI Slave-Select Output */
-#define FLS4 0x0010 /* Enables SPI_FLOUT4 as SPI Slave-Select Output */
-#define FLS5 0x0020 /* Enables SPI_FLOUT5 as SPI Slave-Select Output */
-#define FLS6 0x0040 /* Enables SPI_FLOUT6 as SPI Slave-Select Output */
-#define FLS7 0x0080 /* Enables SPI_FLOUT7 as SPI Slave-Select Output */
-#define FLG1 0xFDFF /* Activates SPI_FLOUT1 */
-#define FLG2 0xFBFF /* Activates SPI_FLOUT2 */
-#define FLG3 0xF7FF /* Activates SPI_FLOUT3 */
-#define FLG4 0xEFFF /* Activates SPI_FLOUT4 */
-#define FLG5 0xDFFF /* Activates SPI_FLOUT5 */
-#define FLG6 0xBFFF /* Activates SPI_FLOUT6 */
-#define FLG7 0x7FFF /* Activates SPI_FLOUT7 */
-
-/* SPI_STAT Masks */
-#define SPIF 0x0001 /* SPI Finished (Single-Word Transfer Complete) */
-#define MODF 0x0002 /* Mode Fault Error (Another Device Tried To Become Master) */
-#define TXE 0x0004 /* Transmission Error (Data Sent With No New Data In TDBR) */
-#define TXS 0x0008 /* SPI_TDBR Data Buffer Status (Full/Empty*) */
-#define RBSY 0x0010 /* Receive Error (Data Received With RDBR Full) */
-#define RXS 0x0020 /* SPI_RDBR Data Buffer Status (Full/Empty*) */
-#define TXCOL 0x0040 /* Transmit Collision Error (Corrupt Data May Have Been Sent) */
-
/* **************** GENERAL PURPOSE TIMER MASKS **********************/
/* TIMER_ENABLE Masks */
#define TIMEN0 0x0001 /* Enable Timer 0 */
diff --git a/arch/blackfin/mach-bf537/include/mach/pll.h b/arch/blackfin/mach-bf537/include/mach/pll.h
new file mode 100644
index 000000000000..169c106d0edb
--- /dev/null
+++ b/arch/blackfin/mach-bf537/include/mach/pll.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2005-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later
+ */
+
+#ifndef _MACH_PLL_H
+#define _MACH_PLL_H
+
+#include <asm/blackfin.h>
+#include <asm/irqflags.h>
+
+/* Writing to PLL_CTL initiates a PLL relock sequence. */
+static __inline__ void bfin_write_PLL_CTL(unsigned int val)
+{
+ unsigned long flags, iwr;
+
+ if (val == bfin_read_PLL_CTL())
+ return;
+
+ flags = hard_local_irq_save();
+ /* Enable the PLL Wakeup bit in SIC IWR */
+ iwr = bfin_read32(SIC_IWR);
+ /* Only allow PPL Wakeup) */
+ bfin_write32(SIC_IWR, IWR_ENABLE(0));
+
+ bfin_write16(PLL_CTL, val);
+ SSYNC();
+ asm("IDLE;");
+
+ bfin_write32(SIC_IWR, iwr);
+ hard_local_irq_restore(flags);
+}
+
+/* Writing to VR_CTL initiates a PLL relock sequence. */
+static __inline__ void bfin_write_VR_CTL(unsigned int val)
+{
+ unsigned long flags, iwr;
+
+ if (val == bfin_read_VR_CTL())
+ return;
+
+ flags = hard_local_irq_save();
+ /* Enable the PLL Wakeup bit in SIC IWR */
+ iwr = bfin_read32(SIC_IWR);
+ /* Only allow PPL Wakeup) */
+ bfin_write32(SIC_IWR, IWR_ENABLE(0));
+
+ bfin_write16(VR_CTL, val);
+ SSYNC();
+ asm("IDLE;");
+
+ bfin_write32(SIC_IWR, iwr);
+ hard_local_irq_restore(flags);
+}
+
+#endif /* _MACH_PLL_H */
diff --git a/arch/blackfin/mach-bf538/boards/ezkit.c b/arch/blackfin/mach-bf538/boards/ezkit.c
index 1a1f65855b03..c6fb0a52f849 100644
--- a/arch/blackfin/mach-bf538/boards/ezkit.c
+++ b/arch/blackfin/mach-bf538/boards/ezkit.c
@@ -695,7 +695,7 @@ static struct platform_device bf538_spi_master0 = {
};
static struct bfin5xx_spi_master bf538_spi_master_info1 = {
- .num_chipselect = 8,
+ .num_chipselect = 2,
.enable_dma = 1, /* master has the ability to do dma transfer */
.pin_req = {P_SPI1_SCK, P_SPI1_MISO, P_SPI1_MOSI, 0},
};
@@ -711,7 +711,7 @@ static struct platform_device bf538_spi_master1 = {
};
static struct bfin5xx_spi_master bf538_spi_master_info2 = {
- .num_chipselect = 8,
+ .num_chipselect = 2,
.enable_dma = 1, /* master has the ability to do dma transfer */
.pin_req = {P_SPI2_SCK, P_SPI2_MISO, P_SPI2_MOSI, 0},
};
diff --git a/arch/blackfin/mach-bf538/include/mach/cdefBF538.h b/arch/blackfin/mach-bf538/include/mach/cdefBF538.h
index 66aa722cf6c8..085b06b8c0a5 100644
--- a/arch/blackfin/mach-bf538/include/mach/cdefBF538.h
+++ b/arch/blackfin/mach-bf538/include/mach/cdefBF538.h
@@ -2027,54 +2027,4 @@
/* These need to be last due to the cdef/linux inter-dependencies */
#include <asm/irq.h>
-/* Writing to PLL_CTL initiates a PLL relock sequence. */
-static __inline__ void bfin_write_PLL_CTL(unsigned int val)
-{
- unsigned long flags, iwr0, iwr1;
-
- if (val == bfin_read_PLL_CTL())
- return;
-
- local_irq_save_hw(flags);
- /* Enable the PLL Wakeup bit in SIC IWR */
- iwr0 = bfin_read32(SIC_IWR0);
- iwr1 = bfin_read32(SIC_IWR1);
- /* Only allow PPL Wakeup) */
- bfin_write32(SIC_IWR0, IWR_ENABLE(0));
- bfin_write32(SIC_IWR1, 0);
-
- bfin_write16(PLL_CTL, val);
- SSYNC();
- asm("IDLE;");
-
- bfin_write32(SIC_IWR0, iwr0);
- bfin_write32(SIC_IWR1, iwr1);
- local_irq_restore_hw(flags);
-}
-
-/* Writing to VR_CTL initiates a PLL relock sequence. */
-static __inline__ void bfin_write_VR_CTL(unsigned int val)
-{
- unsigned long flags, iwr0, iwr1;
-
- if (val == bfin_read_VR_CTL())
- return;
-
- local_irq_save_hw(flags);
- /* Enable the PLL Wakeup bit in SIC IWR */
- iwr0 = bfin_read32(SIC_IWR0);
- iwr1 = bfin_read32(SIC_IWR1);
- /* Only allow PPL Wakeup) */
- bfin_write32(SIC_IWR0, IWR_ENABLE(0));
- bfin_write32(SIC_IWR1, 0);
-
- bfin_write16(VR_CTL, val);
- SSYNC();
- asm("IDLE;");
-
- bfin_write32(SIC_IWR0, iwr0);
- bfin_write32(SIC_IWR1, iwr1);
- local_irq_restore_hw(flags);
-}
-
#endif
diff --git a/arch/blackfin/mach-bf538/include/mach/defBF539.h b/arch/blackfin/mach-bf538/include/mach/defBF539.h
index fe43062b4975..7a8ac5f44204 100644
--- a/arch/blackfin/mach-bf538/include/mach/defBF539.h
+++ b/arch/blackfin/mach-bf538/include/mach/defBF539.h
@@ -32,6 +32,7 @@
/* System Interrupt Controller (0xFFC00100 - 0xFFC001FF) */
#define SWRST 0xFFC00100 /* Software Reset Register (16-bit) */
#define SYSCR 0xFFC00104 /* System Configuration registe */
+#define SIC_RVECT 0xFFC00108
#define SIC_IMASK0 0xFFC0010C /* Interrupt Mask Register */
#define SIC_IAR0 0xFFC00110 /* Interrupt Assignment Register 0 */
#define SIC_IAR1 0xFFC00114 /* Interrupt Assignment Register 1 */
@@ -1894,78 +1895,6 @@
#define PE14_P 0xE
#define PE15_P 0xF
-
-/* *********** SERIAL PERIPHERAL INTERFACE (SPI) MASKS **************** */
-/* SPIx_CTL Masks */
-#define TIMOD 0x0003 /* Transfer Initiate Mode */
-#define RDBR_CORE 0x0000 /* RDBR Read Initiates, IRQ When RDBR Full */
-#define TDBR_CORE 0x0001 /* TDBR Write Initiates, IRQ When TDBR Empty */
-#define RDBR_DMA 0x0002 /* DMA Read, DMA Until FIFO Empty */
-#define TDBR_DMA 0x0003 /* DMA Write, DMA Until FIFO Full */
-#define SZ 0x0004 /* Send Zero (When TDBR Empty, Send Zero/Last*) */
-#define GM 0x0008 /* Get More (When RDBR Full, Overwrite/Discard*) */
-#define PSSE 0x0010 /* Slave-Select Input Enable */
-#define EMISO 0x0020 /* Enable MISO As Output */
-#define SIZE 0x0100 /* Size of Words (16/8* Bits) */
-#define LSBF 0x0200 /* LSB First */
-#define CPHA 0x0400 /* Clock Phase */
-#define CPOL 0x0800 /* Clock Polarity */
-#define MSTR 0x1000 /* Master/Slave* */
-#define WOM 0x2000 /* Write Open Drain Master */
-#define SPE 0x4000 /* SPI Enable */
-
-/* SPIx_FLG Masks */
-#define FLS1 0x0002 /* Enables (=1) SPI_FLOUT1 as flag output for SPI Slave-select */
-#define FLS2 0x0004 /* Enables (=1) SPI_FLOUT2 as flag output for SPI Slave-select */
-#define FLS3 0x0008 /* Enables (=1) SPI_FLOUT3 as flag output for SPI Slave-select */
-#define FLS4 0x0010 /* Enables (=1) SPI_FLOUT4 as flag output for SPI Slave-select */
-#define FLS5 0x0020 /* Enables (=1) SPI_FLOUT5 as flag output for SPI Slave-select */
-#define FLS6 0x0040 /* Enables (=1) SPI_FLOUT6 as flag output for SPI Slave-select */
-#define FLS7 0x0080 /* Enables (=1) SPI_FLOUT7 as flag output for SPI Slave-select */
-
-#define FLG1 0x0200 /* Activates (=0) SPI_FLOUT1 as flag output for SPI Slave-select */
-#define FLG2 0x0400 /* Activates (=0) SPI_FLOUT2 as flag output for SPI Slave-select */
-#define FLG3 0x0800 /* Activates (=0) SPI_FLOUT3 as flag output for SPI Slave-select */
-#define FLG4 0x1000 /* Activates (=0) SPI_FLOUT4 as flag output for SPI Slave-select */
-#define FLG5 0x2000 /* Activates (=0) SPI_FLOUT5 as flag output for SPI Slave-select */
-#define FLG6 0x4000 /* Activates (=0) SPI_FLOUT6 as flag output for SPI Slave-select */
-#define FLG7 0x8000 /* Activates (=0) SPI_FLOUT7 as flag output for SPI Slave-select */
-
-/* SPIx_FLG Bit Positions */
-#define FLS1_P 0x0001 /* Enables (=1) SPI_FLOUT1 as flag output for SPI Slave-select */
-#define FLS2_P 0x0002 /* Enables (=1) SPI_FLOUT2 as flag output for SPI Slave-select */
-#define FLS3_P 0x0003 /* Enables (=1) SPI_FLOUT3 as flag output for SPI Slave-select */
-#define FLS4_P 0x0004 /* Enables (=1) SPI_FLOUT4 as flag output for SPI Slave-select */
-#define FLS5_P 0x0005 /* Enables (=1) SPI_FLOUT5 as flag output for SPI Slave-select */
-#define FLS6_P 0x0006 /* Enables (=1) SPI_FLOUT6 as flag output for SPI Slave-select */
-#define FLS7_P 0x0007 /* Enables (=1) SPI_FLOUT7 as flag output for SPI Slave-select */
-#define FLG1_P 0x0009 /* Activates (=0) SPI_FLOUT1 as flag output for SPI Slave-select */
-#define FLG2_P 0x000A /* Activates (=0) SPI_FLOUT2 as flag output for SPI Slave-select */
-#define FLG3_P 0x000B /* Activates (=0) SPI_FLOUT3 as flag output for SPI Slave-select */
-#define FLG4_P 0x000C /* Activates (=0) SPI_FLOUT4 as flag output for SPI Slave-select */
-#define FLG5_P 0x000D /* Activates (=0) SPI_FLOUT5 as flag output for SPI Slave-select */
-#define FLG6_P 0x000E /* Activates (=0) SPI_FLOUT6 as flag output for SPI Slave-select */
-#define FLG7_P 0x000F /* Activates (=0) SPI_FLOUT7 as flag output for SPI Slave-select */
-
-/* SPIx_STAT Masks */
-#define SPIF 0x0001 /* Set (=1) when SPI single-word transfer complete */
-#define MODF 0x0002 /* Set (=1) in a master device when some other device tries to become master */
-#define TXE 0x0004 /* Set (=1) when transmission occurs with no new data in SPI_TDBR */
-#define TXS 0x0008 /* SPI_TDBR Data Buffer Status (0=Empty, 1=Full) */
-#define RBSY 0x0010 /* Set (=1) when data is received with RDBR full */
-#define RXS 0x0020 /* SPI_RDBR Data Buffer Status (0=Empty, 1=Full) */
-#define TXCOL 0x0040 /* When set (=1), corrupt data may have been transmitted */
-
-/* SPIx_FLG Masks */
-#define FLG1E 0xFDFF /* Activates SPI_FLOUT1 */
-#define FLG2E 0xFBFF /* Activates SPI_FLOUT2 */
-#define FLG3E 0xF7FF /* Activates SPI_FLOUT3 */
-#define FLG4E 0xEFFF /* Activates SPI_FLOUT4 */
-#define FLG5E 0xDFFF /* Activates SPI_FLOUT5 */
-#define FLG6E 0xBFFF /* Activates SPI_FLOUT6 */
-#define FLG7E 0x7FFF /* Activates SPI_FLOUT7 */
-
-
/* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS ************* */
/* EBIU_AMGCTL Masks */
#define AMCKEN 0x0001 /* Enable CLKOUT */
diff --git a/arch/blackfin/mach-bf538/include/mach/pll.h b/arch/blackfin/mach-bf538/include/mach/pll.h
new file mode 100644
index 000000000000..b30bbcd412a7
--- /dev/null
+++ b/arch/blackfin/mach-bf538/include/mach/pll.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2008-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef _MACH_PLL_H
+#define _MACH_PLL_H
+
+#include <asm/blackfin.h>
+#include <asm/irqflags.h>
+
+/* Writing to PLL_CTL initiates a PLL relock sequence. */
+static __inline__ void bfin_write_PLL_CTL(unsigned int val)
+{
+ unsigned long flags, iwr0, iwr1;
+
+ if (val == bfin_read_PLL_CTL())
+ return;
+
+ flags = hard_local_irq_save();
+ /* Enable the PLL Wakeup bit in SIC IWR */
+ iwr0 = bfin_read32(SIC_IWR0);
+ iwr1 = bfin_read32(SIC_IWR1);
+ /* Only allow PPL Wakeup) */
+ bfin_write32(SIC_IWR0, IWR_ENABLE(0));
+ bfin_write32(SIC_IWR1, 0);
+
+ bfin_write16(PLL_CTL, val);
+ SSYNC();
+ asm("IDLE;");
+
+ bfin_write32(SIC_IWR0, iwr0);
+ bfin_write32(SIC_IWR1, iwr1);
+ hard_local_irq_restore(flags);
+}
+
+/* Writing to VR_CTL initiates a PLL relock sequence. */
+static __inline__ void bfin_write_VR_CTL(unsigned int val)
+{
+ unsigned long flags, iwr0, iwr1;
+
+ if (val == bfin_read_VR_CTL())
+ return;
+
+ flags = hard_local_irq_save();
+ /* Enable the PLL Wakeup bit in SIC IWR */
+ iwr0 = bfin_read32(SIC_IWR0);
+ iwr1 = bfin_read32(SIC_IWR1);
+ /* Only allow PPL Wakeup) */
+ bfin_write32(SIC_IWR0, IWR_ENABLE(0));
+ bfin_write32(SIC_IWR1, 0);
+
+ bfin_write16(VR_CTL, val);
+ SSYNC();
+ asm("IDLE;");
+
+ bfin_write32(SIC_IWR0, iwr0);
+ bfin_write32(SIC_IWR1, iwr1);
+ hard_local_irq_restore(flags);
+}
+
+#endif /* _MACH_PLL_H */
diff --git a/arch/blackfin/mach-bf548/boards/cm_bf548.c b/arch/blackfin/mach-bf548/boards/cm_bf548.c
index 0c38eec9ade1..f0c0eef95ba8 100644
--- a/arch/blackfin/mach-bf548/boards/cm_bf548.c
+++ b/arch/blackfin/mach-bf548/boards/cm_bf548.c
@@ -753,6 +753,44 @@ static struct platform_device bf54x_sdh_device = {
};
#endif
+#if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE)
+unsigned short bfin_can_peripherals[] = {
+ P_CAN0_RX, P_CAN0_TX, 0
+};
+
+static struct resource bfin_can_resources[] = {
+ {
+ .start = 0xFFC02A00,
+ .end = 0xFFC02FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_CAN0_RX,
+ .end = IRQ_CAN0_RX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_CAN0_TX,
+ .end = IRQ_CAN0_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_CAN0_ERROR,
+ .end = IRQ_CAN0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bfin_can_device = {
+ .name = "bfin_can",
+ .num_resources = ARRAY_SIZE(bfin_can_resources),
+ .resource = bfin_can_resources,
+ .dev = {
+ .platform_data = &bfin_can_peripherals, /* Passed to driver */
+ },
+};
+#endif
+
#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
static struct mtd_partition para_partitions[] = {
{
@@ -928,7 +966,7 @@ static struct resource bfin_spi1_resource[] = {
/* SPI controller data */
static struct bfin5xx_spi_master bf54x_spi_master_info0 = {
- .num_chipselect = 3,
+ .num_chipselect = 4,
.enable_dma = 1, /* master has the ability to do dma transfer */
.pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0},
};
@@ -944,7 +982,7 @@ static struct platform_device bf54x_spi_master0 = {
};
static struct bfin5xx_spi_master bf54x_spi_master_info1 = {
- .num_chipselect = 3,
+ .num_chipselect = 4,
.enable_dma = 1, /* master has the ability to do dma transfer */
.pin_req = {P_SPI1_SCK, P_SPI1_MISO, P_SPI1_MOSI, 0},
};
@@ -1152,6 +1190,11 @@ static struct platform_device *cm_bf548_devices[] __initdata = {
#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
&para_flash_device,
#endif
+
+#if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE)
+ &bfin_can_device,
+#endif
+
};
static int __init cm_bf548_init(void)
diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c
index 56682a36e42d..216e26999af9 100644
--- a/arch/blackfin/mach-bf548/boards/ezkit.c
+++ b/arch/blackfin/mach-bf548/boards/ezkit.c
@@ -837,8 +837,12 @@ static struct platform_device bfin_atapi_device = {
#if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE)
static struct mtd_partition partition_info[] = {
{
- .name = "linux kernel(nand)",
+ .name = "bootloader(nand)",
.offset = 0,
+ .size = 0x80000,
+ }, {
+ .name = "linux kernel(nand)",
+ .offset = MTDPART_OFS_APPEND,
.size = 4 * 1024 * 1024,
},
{
@@ -901,7 +905,7 @@ static struct platform_device bf54x_sdh_device = {
static struct mtd_partition ezkit_partitions[] = {
{
.name = "bootloader(nor)",
- .size = 0x40000,
+ .size = 0x80000,
.offset = 0,
}, {
.name = "linux kernel(nor)",
@@ -943,7 +947,7 @@ static struct platform_device ezkit_flash_device = {
static struct mtd_partition bfin_spi_flash_partitions[] = {
{
.name = "bootloader(spi)",
- .size = 0x00040000,
+ .size = 0x00080000,
.offset = 0,
.mask_flags = MTD_CAP_ROM
}, {
@@ -966,8 +970,8 @@ static struct bfin5xx_spi_chip spi_flash_chip_info = {
};
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD183X) \
- || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) \
+ || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
.enable_dma = 0,
.bits_per_word = 16,
@@ -1023,13 +1027,13 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
.mode = SPI_MODE_3,
},
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD183X) \
- || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) \
+ || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
{
- .modalias = "ad1836",
+ .modalias = "ad183x",
.max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
.bus_num = 1,
- .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .chip_select = 4,
.controller_data = &ad1836_spi_chip_info,
},
#endif
@@ -1107,7 +1111,7 @@ static struct resource bfin_spi1_resource[] = {
/* SPI controller data */
static struct bfin5xx_spi_master bf54x_spi_master_info0 = {
- .num_chipselect = 3,
+ .num_chipselect = 4,
.enable_dma = 1, /* master has the ability to do dma transfer */
.pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0},
};
@@ -1123,7 +1127,7 @@ static struct platform_device bf54x_spi_master0 = {
};
static struct bfin5xx_spi_master bf54x_spi_master_info1 = {
- .num_chipselect = 3,
+ .num_chipselect = 4,
.enable_dma = 1, /* master has the ability to do dma transfer */
.pin_req = {P_SPI1_SCK, P_SPI1_MISO, P_SPI1_MOSI, 0},
};
@@ -1206,6 +1210,11 @@ static struct i2c_board_info __initdata bfin_i2c_board_info1[] = {
.platform_data = (void *)&adxl34x_info,
},
#endif
+#if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE)
+ {
+ I2C_BOARD_INFO("ad5252", 0x2f),
+ },
+#endif
};
#endif
diff --git a/arch/blackfin/mach-bf548/dma.c b/arch/blackfin/mach-bf548/dma.c
index 039a6d9d38f3..888b9cc0b822 100644
--- a/arch/blackfin/mach-bf548/dma.c
+++ b/arch/blackfin/mach-bf548/dma.c
@@ -63,6 +63,7 @@ int channel2irq(unsigned int channel)
break;
case CH_SPORT1_TX:
ret_irq = IRQ_SPORT1_TX;
+ break;
case CH_SPI0:
ret_irq = IRQ_SPI0;
break;
diff --git a/arch/blackfin/mach-bf548/include/mach/cdefBF54x_base.h b/arch/blackfin/mach-bf548/include/mach/cdefBF54x_base.h
index ea3ec4ea9e2b..deaf5d6542d5 100644
--- a/arch/blackfin/mach-bf548/include/mach/cdefBF54x_base.h
+++ b/arch/blackfin/mach-bf548/include/mach/cdefBF54x_base.h
@@ -40,6 +40,8 @@
/* SIC Registers */
+#define bfin_read_SIC_RVECT() bfin_read32(SIC_RVECT)
+#define bfin_write_SIC_RVECT(val) bfin_write32(SIC_RVECT, val)
#define bfin_read_SIC_IMASK0() bfin_read32(SIC_IMASK0)
#define bfin_write_SIC_IMASK0(val) bfin_write32(SIC_IMASK0, val)
#define bfin_read_SIC_IMASK1() bfin_read32(SIC_IMASK1)
@@ -2648,61 +2650,5 @@
/* These need to be last due to the cdef/linux inter-dependencies */
#include <asm/irq.h>
-/* Writing to PLL_CTL initiates a PLL relock sequence. */
-static __inline__ void bfin_write_PLL_CTL(unsigned int val)
-{
- unsigned long flags, iwr0, iwr1, iwr2;
-
- if (val == bfin_read_PLL_CTL())
- return;
-
- local_irq_save_hw(flags);
- /* Enable the PLL Wakeup bit in SIC IWR */
- iwr0 = bfin_read32(SIC_IWR0);
- iwr1 = bfin_read32(SIC_IWR1);
- iwr2 = bfin_read32(SIC_IWR2);
- /* Only allow PPL Wakeup) */
- bfin_write32(SIC_IWR0, IWR_ENABLE(0));
- bfin_write32(SIC_IWR1, 0);
- bfin_write32(SIC_IWR2, 0);
-
- bfin_write16(PLL_CTL, val);
- SSYNC();
- asm("IDLE;");
-
- bfin_write32(SIC_IWR0, iwr0);
- bfin_write32(SIC_IWR1, iwr1);
- bfin_write32(SIC_IWR2, iwr2);
- local_irq_restore_hw(flags);
-}
-
-/* Writing to VR_CTL initiates a PLL relock sequence. */
-static __inline__ void bfin_write_VR_CTL(unsigned int val)
-{
- unsigned long flags, iwr0, iwr1, iwr2;
-
- if (val == bfin_read_VR_CTL())
- return;
-
- local_irq_save_hw(flags);
- /* Enable the PLL Wakeup bit in SIC IWR */
- iwr0 = bfin_read32(SIC_IWR0);
- iwr1 = bfin_read32(SIC_IWR1);
- iwr2 = bfin_read32(SIC_IWR2);
- /* Only allow PPL Wakeup) */
- bfin_write32(SIC_IWR0, IWR_ENABLE(0));
- bfin_write32(SIC_IWR1, 0);
- bfin_write32(SIC_IWR2, 0);
-
- bfin_write16(VR_CTL, val);
- SSYNC();
- asm("IDLE;");
-
- bfin_write32(SIC_IWR0, iwr0);
- bfin_write32(SIC_IWR1, iwr1);
- bfin_write32(SIC_IWR2, iwr2);
- local_irq_restore_hw(flags);
-}
-
#endif /* _CDEF_BF54X_H */
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h
index 7866197f5485..78f91103f175 100644
--- a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h
+++ b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h
@@ -35,6 +35,7 @@
/* SIC Registers */
+#define SIC_RVECT 0xffc00108
#define SIC_IMASK0 0xffc0010c /* System Interrupt Mask Register 0 */
#define SIC_IMASK1 0xffc00110 /* System Interrupt Mask Register 1 */
#define SIC_IMASK2 0xffc00114 /* System Interrupt Mask Register 2 */
@@ -2061,56 +2062,6 @@
#define LOW_EVEN 0xff0000 /* Lower Limit for Even Bytes (Luma) */
#define HIGH_EVEN 0xff000000 /* Upper Limit for Even Bytes (Luma) */
-/* Bit masks for SPIx_BAUD */
-
-#define SPI_BAUD 0xffff /* Baud Rate */
-
-/* Bit masks for SPIx_CTL */
-
-#define SPE 0x4000 /* SPI Enable */
-#define WOM 0x2000 /* Write Open Drain Master */
-#define MSTR 0x1000 /* Master Mode */
-#define CPOL 0x800 /* Clock Polarity */
-#define CPHA 0x400 /* Clock Phase */
-#define LSBF 0x200 /* LSB First */
-#define SIZE 0x100 /* Size of Words */
-#define EMISO 0x20 /* Enable MISO Output */
-#define PSSE 0x10 /* Slave-Select Enable */
-#define GM 0x8 /* Get More Data */
-#define SZ 0x4 /* Send Zero */
-#define TIMOD 0x3 /* Transfer Initiation Mode */
-
-/* Bit masks for SPIx_FLG */
-
-#define FLS1 0x2 /* Slave Select Enable 1 */
-#define FLS2 0x4 /* Slave Select Enable 2 */
-#define FLS3 0x8 /* Slave Select Enable 3 */
-#define FLG1 0x200 /* Slave Select Value 1 */
-#define FLG2 0x400 /* Slave Select Value 2 */
-#define FLG3 0x800 /* Slave Select Value 3 */
-
-/* Bit masks for SPIx_STAT */
-
-#define TXCOL 0x40 /* Transmit Collision Error */
-#define RXS 0x20 /* RDBR Data Buffer Status */
-#define RBSY 0x10 /* Receive Error */
-#define TXS 0x8 /* TDBR Data Buffer Status */
-#define TXE 0x4 /* Transmission Error */
-#define MODF 0x2 /* Mode Fault Error */
-#define SPIF 0x1 /* SPI Finished */
-
-/* Bit masks for SPIx_TDBR */
-
-#define TDBR 0xffff /* Transmit Data Buffer */
-
-/* Bit masks for SPIx_RDBR */
-
-#define RDBR 0xffff /* Receive Data Buffer */
-
-/* Bit masks for SPIx_SHADOW */
-
-#define SHADOW 0xffff /* RDBR Shadow */
-
/* ************************************************ */
/* The TWI bit masks fields are from the ADSP-BF538 */
/* and they have not been verified as the final */
diff --git a/arch/blackfin/mach-bf548/include/mach/pll.h b/arch/blackfin/mach-bf548/include/mach/pll.h
new file mode 100644
index 000000000000..7865a090d333
--- /dev/null
+++ b/arch/blackfin/mach-bf548/include/mach/pll.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2007-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef _MACH_PLL_H
+#define _MACH_PLL_H
+
+#include <asm/blackfin.h>
+#include <asm/irqflags.h>
+
+/* Writing to PLL_CTL initiates a PLL relock sequence. */
+static __inline__ void bfin_write_PLL_CTL(unsigned int val)
+{
+ unsigned long flags, iwr0, iwr1, iwr2;
+
+ if (val == bfin_read_PLL_CTL())
+ return;
+
+ flags = hard_local_irq_save();
+ /* Enable the PLL Wakeup bit in SIC IWR */
+ iwr0 = bfin_read32(SIC_IWR0);
+ iwr1 = bfin_read32(SIC_IWR1);
+ iwr2 = bfin_read32(SIC_IWR2);
+ /* Only allow PPL Wakeup) */
+ bfin_write32(SIC_IWR0, IWR_ENABLE(0));
+ bfin_write32(SIC_IWR1, 0);
+ bfin_write32(SIC_IWR2, 0);
+
+ bfin_write16(PLL_CTL, val);
+ SSYNC();
+ asm("IDLE;");
+
+ bfin_write32(SIC_IWR0, iwr0);
+ bfin_write32(SIC_IWR1, iwr1);
+ bfin_write32(SIC_IWR2, iwr2);
+ hard_local_irq_restore(flags);
+}
+
+/* Writing to VR_CTL initiates a PLL relock sequence. */
+static __inline__ void bfin_write_VR_CTL(unsigned int val)
+{
+ unsigned long flags, iwr0, iwr1, iwr2;
+
+ if (val == bfin_read_VR_CTL())
+ return;
+
+ flags = hard_local_irq_save();
+ /* Enable the PLL Wakeup bit in SIC IWR */
+ iwr0 = bfin_read32(SIC_IWR0);
+ iwr1 = bfin_read32(SIC_IWR1);
+ iwr2 = bfin_read32(SIC_IWR2);
+ /* Only allow PPL Wakeup) */
+ bfin_write32(SIC_IWR0, IWR_ENABLE(0));
+ bfin_write32(SIC_IWR1, 0);
+ bfin_write32(SIC_IWR2, 0);
+
+ bfin_write16(VR_CTL, val);
+ SSYNC();
+ asm("IDLE;");
+
+ bfin_write32(SIC_IWR0, iwr0);
+ bfin_write32(SIC_IWR1, iwr1);
+ bfin_write32(SIC_IWR2, iwr2);
+ hard_local_irq_restore(flags);
+}
+
+#endif /* _MACH_PLL_H */
diff --git a/arch/blackfin/mach-bf561/boards/acvilon.c b/arch/blackfin/mach-bf561/boards/acvilon.c
index 35b6d124c1e3..0b1c20f14fe0 100644
--- a/arch/blackfin/mach-bf561/boards/acvilon.c
+++ b/arch/blackfin/mach-bf561/boards/acvilon.c
@@ -302,7 +302,7 @@ static struct platform_nand_data bfin_plat_nand_data = {
static struct resource bfin_plat_nand_resources = {
.start = 0x24000000,
.end = 0x24000000 + (1 << MAX(BFIN_NAND_PLAT_CLE, BFIN_NAND_PLAT_ALE)),
- .flags = IORESOURCE_IO,
+ .flags = IORESOURCE_MEM,
};
static struct platform_device bfin_async_nand_device = {
diff --git a/arch/blackfin/mach-bf561/boards/cm_bf561.c b/arch/blackfin/mach-bf561/boards/cm_bf561.c
index e127aedc1d7f..087b6b05cc73 100644
--- a/arch/blackfin/mach-bf561/boards/cm_bf561.c
+++ b/arch/blackfin/mach-bf561/boards/cm_bf561.c
@@ -72,7 +72,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
};
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
.enable_dma = 0,
.bits_per_word = 16,
@@ -111,12 +111,12 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
},
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
{
- .modalias = "ad1836",
+ .modalias = "ad183x",
.max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
.bus_num = 0,
- .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .chip_select = 4,
.controller_data = &ad1836_spi_chip_info,
},
#endif
@@ -278,7 +278,7 @@ static struct resource isp1362_hcd_resources[] = {
}, {
.start = IRQ_PF47,
.end = IRQ_PF47,
- .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
},
};
diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c
index 9b93e2f95791..ab7a487975fd 100644
--- a/arch/blackfin/mach-bf561/boards/ezkit.c
+++ b/arch/blackfin/mach-bf561/boards/ezkit.c
@@ -14,6 +14,7 @@
#include <linux/spi/spi.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
+#include <linux/delay.h>
#include <asm/dma.h>
#include <asm/bfin5xx_spi.h>
#include <asm/portmux.h>
@@ -74,7 +75,7 @@ static struct resource isp1362_hcd_resources[] = {
}, {
.start = IRQ_PF8,
.end = IRQ_PF8,
- .flags = IORESOURCE_IRQ,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
},
};
@@ -274,8 +275,8 @@ static struct platform_device ezkit_flash_device = {
};
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD183X) \
- || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) \
+ || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
.enable_dma = 0,
.bits_per_word = 16,
@@ -328,14 +329,16 @@ static struct platform_device bfin_spi0_device = {
#endif
static struct spi_board_info bfin_spi_board_info[] __initdata = {
-#if defined(CONFIG_SND_BLACKFIN_AD183X) \
- || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) \
+ || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
{
- .modalias = "ad1836",
+ .modalias = "ad183x",
.max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
.bus_num = 0,
- .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .chip_select = 4,
+ .platform_data = "ad1836", /* only includes chip name for the moment */
.controller_data = &ad1836_spi_chip_info,
+ .mode = SPI_MODE_3,
},
#endif
#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
@@ -377,8 +380,8 @@ static struct platform_device bfin_device_gpiokeys = {
#include <linux/i2c-gpio.h>
static struct i2c_gpio_platform_data i2c_gpio_data = {
- .sda_pin = 1,
- .scl_pin = 0,
+ .sda_pin = GPIO_PF1,
+ .scl_pin = GPIO_PF0,
.sda_is_open_drain = 0,
.scl_is_open_drain = 0,
.udelay = 40,
@@ -420,6 +423,30 @@ static struct platform_device bfin_dpmc = {
},
};
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+static struct platform_device bfin_i2s = {
+ .name = "bfin-i2s",
+ .id = CONFIG_SND_BF5XX_SPORT_NUM,
+ /* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+static struct platform_device bfin_tdm = {
+ .name = "bfin-tdm",
+ .id = CONFIG_SND_BF5XX_SPORT_NUM,
+ /* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+static struct platform_device bfin_ac97 = {
+ .name = "bfin-ac97",
+ .id = CONFIG_SND_BF5XX_SPORT_NUM,
+ /* TODO: add platform data here */
+};
+#endif
+
static struct platform_device *ezkit_devices[] __initdata = {
&bfin_dpmc,
@@ -467,6 +494,18 @@ static struct platform_device *ezkit_devices[] __initdata = {
#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
&ezkit_flash_device,
#endif
+
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+ &bfin_i2s,
+#endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+ &bfin_tdm,
+#endif
+
+#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+ &bfin_ac97,
+#endif
};
static int __init ezkit_init(void)
@@ -484,6 +523,17 @@ static int __init ezkit_init(void)
SSYNC();
#endif
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
+ bfin_write_FIO0_DIR(bfin_read_FIO0_DIR() | (1 << 15));
+ bfin_write_FIO0_FLAG_S(1 << 15);
+ SSYNC();
+ /*
+ * This initialization lasts for approximately 4500 MCLKs.
+ * MCLK = 12.288MHz
+ */
+ udelay(400);
+#endif
+
spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
return 0;
}
diff --git a/arch/blackfin/mach-bf561/coreb.c b/arch/blackfin/mach-bf561/coreb.c
index deb2271d09a3..78ecb50bafc8 100644
--- a/arch/blackfin/mach-bf561/coreb.c
+++ b/arch/blackfin/mach-bf561/coreb.c
@@ -18,9 +18,9 @@
#include <linux/miscdevice.h>
#include <linux/module.h>
-#define CMD_COREB_START 2
-#define CMD_COREB_STOP 3
-#define CMD_COREB_RESET 4
+#define CMD_COREB_START _IO('b', 0)
+#define CMD_COREB_STOP _IO('b', 1)
+#define CMD_COREB_RESET _IO('b', 2)
static long
coreb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
@@ -29,10 +29,10 @@ coreb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
switch (cmd) {
case CMD_COREB_START:
- bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() & ~0x0020);
+ bfin_write_SYSCR(bfin_read_SYSCR() & ~0x0020);
break;
case CMD_COREB_STOP:
- bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() | 0x0020);
+ bfin_write_SYSCR(bfin_read_SYSCR() | 0x0020);
bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | 0x0080);
break;
case CMD_COREB_RESET:
@@ -51,6 +51,7 @@ coreb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
static const struct file_operations coreb_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = coreb_ioctl,
+ .llseek = noop_llseek,
};
static struct miscdevice coreb_dev = {
@@ -73,3 +74,4 @@ module_exit(bf561_coreb_exit);
MODULE_AUTHOR("Bas Vermeulen <bvermeul@blackstar.xs4all.nl>");
MODULE_DESCRIPTION("BF561 Core B Support");
+MODULE_LICENSE("GPL");
diff --git a/arch/blackfin/mach-bf561/include/mach/blackfin.h b/arch/blackfin/mach-bf561/include/mach/blackfin.h
index 67d6bdcd3fa8..6c7dc58c018c 100644
--- a/arch/blackfin/mach-bf561/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf561/include/mach/blackfin.h
@@ -24,29 +24,16 @@
#define bfin_read_FIO_INEN() bfin_read_FIO0_INEN()
#define bfin_write_FIO_INEN(val) bfin_write_FIO0_INEN(val)
-#define SIC_IWR0 SICA_IWR0
-#define SIC_IWR1 SICA_IWR1
-#define SIC_IAR0 SICA_IAR0
-#define bfin_write_SIC_IMASK0 bfin_write_SICA_IMASK0
-#define bfin_write_SIC_IMASK1 bfin_write_SICA_IMASK1
-#define bfin_write_SIC_IWR0 bfin_write_SICA_IWR0
-#define bfin_write_SIC_IWR1 bfin_write_SICA_IWR1
-
-#define bfin_read_SIC_IMASK0 bfin_read_SICA_IMASK0
-#define bfin_read_SIC_IMASK1 bfin_read_SICA_IMASK1
-#define bfin_read_SIC_IWR0 bfin_read_SICA_IWR0
-#define bfin_read_SIC_IWR1 bfin_read_SICA_IWR1
-#define bfin_read_SIC_ISR0 bfin_read_SICA_ISR0
-#define bfin_read_SIC_ISR1 bfin_read_SICA_ISR1
-
-#define bfin_read_SIC_IMASK(x) bfin_read32(SICA_IMASK0 + (x << 2))
-#define bfin_write_SIC_IMASK(x, val) bfin_write32((SICA_IMASK0 + (x << 2)), val)
-#define bfin_read_SICB_IMASK(x) bfin_read32(SICB_IMASK0 + (x << 2))
-#define bfin_write_SICB_IMASK(x, val) bfin_write32((SICB_IMASK0 + (x << 2)), val)
-#define bfin_read_SIC_ISR(x) bfin_read32(SICA_ISR0 + (x << 2))
-#define bfin_write_SIC_ISR(x, val) bfin_write32((SICA_ISR0 + (x << 2)), val)
-#define bfin_read_SICB_ISR(x) bfin_read32(SICB_ISR0 + (x << 2))
-#define bfin_write_SICB_ISR(x, val) bfin_write32((SICB_ISR0 + (x << 2)), val)
+/* Weird muxer funcs which pick SIC regs from IMASK base */
+#define __SIC_MUX(base, x) ((base) + ((x) << 2))
+#define bfin_read_SIC_IMASK(x) bfin_read32(__SIC_MUX(SIC_IMASK0, x))
+#define bfin_write_SIC_IMASK(x, val) bfin_write32(__SIC_MUX(SIC_IMASK0, x), val)
+#define bfin_read_SICB_IMASK(x) bfin_read32(__SIC_MUX(SICB_IMASK0, x))
+#define bfin_write_SICB_IMASK(x, val) bfin_write32(__SIC_MUX(SICB_IMASK0, x), val)
+#define bfin_read_SIC_ISR(x) bfin_read32(__SIC_MUX(SIC_ISR0, x))
+#define bfin_write_SIC_ISR(x, val) bfin_write32(__SIC_MUX(SIC_ISR0, x), val)
+#define bfin_read_SICB_ISR(x) bfin_read32(__SIC_MUX(SICB_ISR0, x))
+#define bfin_write_SICB_ISR(x, val) bfin_write32(__SIC_MUX(SICB_ISR0, x), val)
#define BFIN_UART_NR_PORTS 1
diff --git a/arch/blackfin/mach-bf561/include/mach/cdefBF561.h b/arch/blackfin/mach-bf561/include/mach/cdefBF561.h
index 81ecdb71c6af..2bab99152495 100644
--- a/arch/blackfin/mach-bf561/include/mach/cdefBF561.h
+++ b/arch/blackfin/mach-bf561/include/mach/cdefBF561.h
@@ -30,49 +30,41 @@
#define bfin_write_PLL_LOCKCNT(val) bfin_write16(PLL_LOCKCNT,val)
#define bfin_read_CHIPID() bfin_read32(CHIPID)
-/* For MMR's that are reserved on Core B, set up defines to better integrate with other ports */
-#define bfin_read_SWRST() bfin_read_SICA_SWRST()
-#define bfin_write_SWRST(val) bfin_write_SICA_SWRST(val)
-#define bfin_read_SYSCR() bfin_read_SICA_SYSCR()
-#define bfin_write_SYSCR(val) bfin_write_SICA_SYSCR(val)
-
/* System Reset and Interrupt Controller registers for core A (0xFFC0 0100-0xFFC0 01FF) */
-#define bfin_read_SICA_SWRST() bfin_read16(SICA_SWRST)
-#define bfin_write_SICA_SWRST(val) bfin_write16(SICA_SWRST,val)
-#define bfin_read_SICA_SYSCR() bfin_read16(SICA_SYSCR)
-#define bfin_write_SICA_SYSCR(val) bfin_write16(SICA_SYSCR,val)
-#define bfin_read_SICA_RVECT() bfin_read16(SICA_RVECT)
-#define bfin_write_SICA_RVECT(val) bfin_write16(SICA_RVECT,val)
-#define bfin_read_SICA_IMASK() bfin_read32(SICA_IMASK)
-#define bfin_write_SICA_IMASK(val) bfin_write32(SICA_IMASK,val)
-#define bfin_read_SICA_IMASK0() bfin_read32(SICA_IMASK0)
-#define bfin_write_SICA_IMASK0(val) bfin_write32(SICA_IMASK0,val)
-#define bfin_read_SICA_IMASK1() bfin_read32(SICA_IMASK1)
-#define bfin_write_SICA_IMASK1(val) bfin_write32(SICA_IMASK1,val)
-#define bfin_read_SICA_IAR0() bfin_read32(SICA_IAR0)
-#define bfin_write_SICA_IAR0(val) bfin_write32(SICA_IAR0,val)
-#define bfin_read_SICA_IAR1() bfin_read32(SICA_IAR1)
-#define bfin_write_SICA_IAR1(val) bfin_write32(SICA_IAR1,val)
-#define bfin_read_SICA_IAR2() bfin_read32(SICA_IAR2)
-#define bfin_write_SICA_IAR2(val) bfin_write32(SICA_IAR2,val)
-#define bfin_read_SICA_IAR3() bfin_read32(SICA_IAR3)
-#define bfin_write_SICA_IAR3(val) bfin_write32(SICA_IAR3,val)
-#define bfin_read_SICA_IAR4() bfin_read32(SICA_IAR4)
-#define bfin_write_SICA_IAR4(val) bfin_write32(SICA_IAR4,val)
-#define bfin_read_SICA_IAR5() bfin_read32(SICA_IAR5)
-#define bfin_write_SICA_IAR5(val) bfin_write32(SICA_IAR5,val)
-#define bfin_read_SICA_IAR6() bfin_read32(SICA_IAR6)
-#define bfin_write_SICA_IAR6(val) bfin_write32(SICA_IAR6,val)
-#define bfin_read_SICA_IAR7() bfin_read32(SICA_IAR7)
-#define bfin_write_SICA_IAR7(val) bfin_write32(SICA_IAR7,val)
-#define bfin_read_SICA_ISR0() bfin_read32(SICA_ISR0)
-#define bfin_write_SICA_ISR0(val) bfin_write32(SICA_ISR0,val)
-#define bfin_read_SICA_ISR1() bfin_read32(SICA_ISR1)
-#define bfin_write_SICA_ISR1(val) bfin_write32(SICA_ISR1,val)
-#define bfin_read_SICA_IWR0() bfin_read32(SICA_IWR0)
-#define bfin_write_SICA_IWR0(val) bfin_write32(SICA_IWR0,val)
-#define bfin_read_SICA_IWR1() bfin_read32(SICA_IWR1)
-#define bfin_write_SICA_IWR1(val) bfin_write32(SICA_IWR1,val)
+#define bfin_read_SWRST() bfin_read16(SWRST)
+#define bfin_write_SWRST(val) bfin_write16(SWRST,val)
+#define bfin_read_SYSCR() bfin_read16(SYSCR)
+#define bfin_write_SYSCR(val) bfin_write16(SYSCR,val)
+#define bfin_read_SIC_RVECT() bfin_read16(SIC_RVECT)
+#define bfin_write_SIC_RVECT(val) bfin_write16(SIC_RVECT,val)
+#define bfin_read_SIC_IMASK0() bfin_read32(SIC_IMASK0)
+#define bfin_write_SIC_IMASK0(val) bfin_write32(SIC_IMASK0,val)
+#define bfin_read_SIC_IMASK1() bfin_read32(SIC_IMASK1)
+#define bfin_write_SIC_IMASK1(val) bfin_write32(SIC_IMASK1,val)
+#define bfin_read_SIC_IAR0() bfin_read32(SIC_IAR0)
+#define bfin_write_SIC_IAR0(val) bfin_write32(SIC_IAR0,val)
+#define bfin_read_SIC_IAR1() bfin_read32(SIC_IAR1)
+#define bfin_write_SIC_IAR1(val) bfin_write32(SIC_IAR1,val)
+#define bfin_read_SIC_IAR2() bfin_read32(SIC_IAR2)
+#define bfin_write_SIC_IAR2(val) bfin_write32(SIC_IAR2,val)
+#define bfin_read_SIC_IAR3() bfin_read32(SIC_IAR3)
+#define bfin_write_SIC_IAR3(val) bfin_write32(SIC_IAR3,val)
+#define bfin_read_SIC_IAR4() bfin_read32(SIC_IAR4)
+#define bfin_write_SIC_IAR4(val) bfin_write32(SIC_IAR4,val)
+#define bfin_read_SIC_IAR5() bfin_read32(SIC_IAR5)
+#define bfin_write_SIC_IAR5(val) bfin_write32(SIC_IAR5,val)
+#define bfin_read_SIC_IAR6() bfin_read32(SIC_IAR6)
+#define bfin_write_SIC_IAR6(val) bfin_write32(SIC_IAR6,val)
+#define bfin_read_SIC_IAR7() bfin_read32(SIC_IAR7)
+#define bfin_write_SIC_IAR7(val) bfin_write32(SIC_IAR7,val)
+#define bfin_read_SIC_ISR0() bfin_read32(SIC_ISR0)
+#define bfin_write_SIC_ISR0(val) bfin_write32(SIC_ISR0,val)
+#define bfin_read_SIC_ISR1() bfin_read32(SIC_ISR1)
+#define bfin_write_SIC_ISR1(val) bfin_write32(SIC_ISR1,val)
+#define bfin_read_SIC_IWR0() bfin_read32(SIC_IWR0)
+#define bfin_write_SIC_IWR0(val) bfin_write32(SIC_IWR0,val)
+#define bfin_read_SIC_IWR1() bfin_read32(SIC_IWR1)
+#define bfin_write_SIC_IWR1(val) bfin_write32(SIC_IWR1,val)
/* System Reset and Interrupt Controller registers for Core B (0xFFC0 1100-0xFFC0 11FF) */
#define bfin_read_SICB_SWRST() bfin_read16(SICB_SWRST)
@@ -1534,54 +1526,4 @@
/* These need to be last due to the cdef/linux inter-dependencies */
#include <asm/irq.h>
-/* Writing to PLL_CTL initiates a PLL relock sequence. */
-static __inline__ void bfin_write_PLL_CTL(unsigned int val)
-{
- unsigned long flags, iwr0, iwr1;
-
- if (val == bfin_read_PLL_CTL())
- return;
-
- local_irq_save_hw(flags);
- /* Enable the PLL Wakeup bit in SIC IWR */
- iwr0 = bfin_read32(SICA_IWR0);
- iwr1 = bfin_read32(SICA_IWR1);
- /* Only allow PPL Wakeup) */
- bfin_write32(SICA_IWR0, IWR_ENABLE(0));
- bfin_write32(SICA_IWR1, 0);
-
- bfin_write16(PLL_CTL, val);
- SSYNC();
- asm("IDLE;");
-
- bfin_write32(SICA_IWR0, iwr0);
- bfin_write32(SICA_IWR1, iwr1);
- local_irq_restore_hw(flags);
-}
-
-/* Writing to VR_CTL initiates a PLL relock sequence. */
-static __inline__ void bfin_write_VR_CTL(unsigned int val)
-{
- unsigned long flags, iwr0, iwr1;
-
- if (val == bfin_read_VR_CTL())
- return;
-
- local_irq_save_hw(flags);
- /* Enable the PLL Wakeup bit in SIC IWR */
- iwr0 = bfin_read32(SICA_IWR0);
- iwr1 = bfin_read32(SICA_IWR1);
- /* Only allow PPL Wakeup) */
- bfin_write32(SICA_IWR0, IWR_ENABLE(0));
- bfin_write32(SICA_IWR1, 0);
-
- bfin_write16(VR_CTL, val);
- SSYNC();
- asm("IDLE;");
-
- bfin_write32(SICA_IWR0, iwr0);
- bfin_write32(SICA_IWR1, iwr1);
- local_irq_restore_hw(flags);
-}
-
#endif /* _CDEF_BF561_H */
diff --git a/arch/blackfin/mach-bf561/include/mach/defBF561.h b/arch/blackfin/mach-bf561/include/mach/defBF561.h
index 2674f0097576..79e048d452e0 100644
--- a/arch/blackfin/mach-bf561/include/mach/defBF561.h
+++ b/arch/blackfin/mach-bf561/include/mach/defBF561.h
@@ -28,32 +28,29 @@
#define CHIPID 0xFFC00014 /* Chip ID Register */
/* For MMR's that are reserved on Core B, set up defines to better integrate with other ports */
-#define SWRST SICA_SWRST
-#define SYSCR SICA_SYSCR
#define DOUBLE_FAULT (DOUBLE_FAULT_B|DOUBLE_FAULT_A)
#define RESET_DOUBLE (SWRST_DBL_FAULT_B|SWRST_DBL_FAULT_A)
#define RESET_WDOG (SWRST_WDT_B|SWRST_WDT_A)
#define RESET_SOFTWARE (SWRST_OCCURRED)
/* System Reset and Interrupt Controller registers for core A (0xFFC0 0100-0xFFC0 01FF) */
-#define SICA_SWRST 0xFFC00100 /* Software Reset register */
-#define SICA_SYSCR 0xFFC00104 /* System Reset Configuration register */
-#define SICA_RVECT 0xFFC00108 /* SIC Reset Vector Address Register */
-#define SICA_IMASK 0xFFC0010C /* SIC Interrupt Mask register 0 - hack to fix old tests */
-#define SICA_IMASK0 0xFFC0010C /* SIC Interrupt Mask register 0 */
-#define SICA_IMASK1 0xFFC00110 /* SIC Interrupt Mask register 1 */
-#define SICA_IAR0 0xFFC00124 /* SIC Interrupt Assignment Register 0 */
-#define SICA_IAR1 0xFFC00128 /* SIC Interrupt Assignment Register 1 */
-#define SICA_IAR2 0xFFC0012C /* SIC Interrupt Assignment Register 2 */
-#define SICA_IAR3 0xFFC00130 /* SIC Interrupt Assignment Register 3 */
-#define SICA_IAR4 0xFFC00134 /* SIC Interrupt Assignment Register 4 */
-#define SICA_IAR5 0xFFC00138 /* SIC Interrupt Assignment Register 5 */
-#define SICA_IAR6 0xFFC0013C /* SIC Interrupt Assignment Register 6 */
-#define SICA_IAR7 0xFFC00140 /* SIC Interrupt Assignment Register 7 */
-#define SICA_ISR0 0xFFC00114 /* SIC Interrupt Status register 0 */
-#define SICA_ISR1 0xFFC00118 /* SIC Interrupt Status register 1 */
-#define SICA_IWR0 0xFFC0011C /* SIC Interrupt Wakeup-Enable register 0 */
-#define SICA_IWR1 0xFFC00120 /* SIC Interrupt Wakeup-Enable register 1 */
+#define SWRST 0xFFC00100 /* Software Reset register */
+#define SYSCR 0xFFC00104 /* System Reset Configuration register */
+#define SIC_RVECT 0xFFC00108 /* SIC Reset Vector Address Register */
+#define SIC_IMASK0 0xFFC0010C /* SIC Interrupt Mask register 0 */
+#define SIC_IMASK1 0xFFC00110 /* SIC Interrupt Mask register 1 */
+#define SIC_IAR0 0xFFC00124 /* SIC Interrupt Assignment Register 0 */
+#define SIC_IAR1 0xFFC00128 /* SIC Interrupt Assignment Register 1 */
+#define SIC_IAR2 0xFFC0012C /* SIC Interrupt Assignment Register 2 */
+#define SIC_IAR3 0xFFC00130 /* SIC Interrupt Assignment Register 3 */
+#define SIC_IAR4 0xFFC00134 /* SIC Interrupt Assignment Register 4 */
+#define SIC_IAR5 0xFFC00138 /* SIC Interrupt Assignment Register 5 */
+#define SIC_IAR6 0xFFC0013C /* SIC Interrupt Assignment Register 6 */
+#define SIC_IAR7 0xFFC00140 /* SIC Interrupt Assignment Register 7 */
+#define SIC_ISR0 0xFFC00114 /* SIC Interrupt Status register 0 */
+#define SIC_ISR1 0xFFC00118 /* SIC Interrupt Status register 1 */
+#define SIC_IWR0 0xFFC0011C /* SIC Interrupt Wakeup-Enable register 0 */
+#define SIC_IWR1 0xFFC00120 /* SIC Interrupt Wakeup-Enable register 1 */
/* System Reset and Interrupt Controller registers for Core B (0xFFC0 1100-0xFFC0 11FF) */
#define SICB_SWRST 0xFFC01100 /* reserved */
@@ -1271,63 +1268,6 @@
#define PF14_P 14
#define PF15_P 15
-/* *********** SERIAL PERIPHERAL INTERFACE (SPI) MASKS **************** */
-
-/* SPI_CTL Masks */
-#define TIMOD 0x00000003 /* Transfer initiation mode and interrupt generation */
-#define SZ 0x00000004 /* Send Zero (=0) or last (=1) word when TDBR empty. */
-#define GM 0x00000008 /* When RDBR full, get more (=1) data or discard (=0) incoming Data */
-#define PSSE 0x00000010 /* Enable (=1) Slave-Select input for Master. */
-#define EMISO 0x00000020 /* Enable (=1) MISO pin as an output. */
-#define SIZE 0x00000100 /* Word length (0 => 8 bits, 1 => 16 bits) */
-#define LSBF 0x00000200 /* Data format (0 => MSB sent/received first 1 => LSB sent/received first) */
-#define CPHA 0x00000400 /* Clock phase (0 => SPICLK starts toggling in middle of xfer, 1 => SPICLK toggles at the beginning of xfer. */
-#define CPOL 0x00000800 /* Clock polarity (0 => active-high, 1 => active-low) */
-#define MSTR 0x00001000 /* Configures SPI as master (=1) or slave (=0) */
-#define WOM 0x00002000 /* Open drain (=1) data output enable (for MOSI and MISO) */
-#define SPE 0x00004000 /* SPI module enable (=1), disable (=0) */
-
-/* SPI_FLG Masks */
-#define FLS1 0x00000002 /* Enables (=1) SPI_FLOUT1 as flag output for SPI Slave-select */
-#define FLS2 0x00000004 /* Enables (=1) SPI_FLOUT2 as flag output for SPI Slave-select */
-#define FLS3 0x00000008 /* Enables (=1) SPI_FLOUT3 as flag output for SPI Slave-select */
-#define FLS4 0x00000010 /* Enables (=1) SPI_FLOUT4 as flag output for SPI Slave-select */
-#define FLS5 0x00000020 /* Enables (=1) SPI_FLOUT5 as flag output for SPI Slave-select */
-#define FLS6 0x00000040 /* Enables (=1) SPI_FLOUT6 as flag output for SPI Slave-select */
-#define FLS7 0x00000080 /* Enables (=1) SPI_FLOUT7 as flag output for SPI Slave-select */
-#define FLG1 0x00000200 /* Activates (=0) SPI_FLOUT1 as flag output for SPI Slave-select */
-#define FLG2 0x00000400 /* Activates (=0) SPI_FLOUT2 as flag output for SPI Slave-select */
-#define FLG3 0x00000800 /* Activates (=0) SPI_FLOUT3 as flag output for SPI Slave-select */
-#define FLG4 0x00001000 /* Activates (=0) SPI_FLOUT4 as flag output for SPI Slave-select */
-#define FLG5 0x00002000 /* Activates (=0) SPI_FLOUT5 as flag output for SPI Slave-select */
-#define FLG6 0x00004000 /* Activates (=0) SPI_FLOUT6 as flag output for SPI Slave-select */
-#define FLG7 0x00008000 /* Activates (=0) SPI_FLOUT7 as flag output for SPI Slave-select */
-
-/* SPI_FLG Bit Positions */
-#define FLS1_P 0x00000001 /* Enables (=1) SPI_FLOUT1 as flag output for SPI Slave-select */
-#define FLS2_P 0x00000002 /* Enables (=1) SPI_FLOUT2 as flag output for SPI Slave-select */
-#define FLS3_P 0x00000003 /* Enables (=1) SPI_FLOUT3 as flag output for SPI Slave-select */
-#define FLS4_P 0x00000004 /* Enables (=1) SPI_FLOUT4 as flag output for SPI Slave-select */
-#define FLS5_P 0x00000005 /* Enables (=1) SPI_FLOUT5 as flag output for SPI Slave-select */
-#define FLS6_P 0x00000006 /* Enables (=1) SPI_FLOUT6 as flag output for SPI Slave-select */
-#define FLS7_P 0x00000007 /* Enables (=1) SPI_FLOUT7 as flag output for SPI Slave-select */
-#define FLG1_P 0x00000009 /* Activates (=0) SPI_FLOUT1 as flag output for SPI Slave-select */
-#define FLG2_P 0x0000000A /* Activates (=0) SPI_FLOUT2 as flag output for SPI Slave-select */
-#define FLG3_P 0x0000000B /* Activates (=0) SPI_FLOUT3 as flag output for SPI Slave-select */
-#define FLG4_P 0x0000000C /* Activates (=0) SPI_FLOUT4 as flag output for SPI Slave-select */
-#define FLG5_P 0x0000000D /* Activates (=0) SPI_FLOUT5 as flag output for SPI Slave-select */
-#define FLG6_P 0x0000000E /* Activates (=0) SPI_FLOUT6 as flag output for SPI Slave-select */
-#define FLG7_P 0x0000000F /* Activates (=0) SPI_FLOUT7 as flag output for SPI Slave-select */
-
-/* SPI_STAT Masks */
-#define SPIF 0x00000001 /* Set (=1) when SPI single-word transfer complete */
-#define MODF 0x00000002 /* Set (=1) in a master device when some other device tries to become master */
-#define TXE 0x00000004 /* Set (=1) when transmission occurs with no new data in SPI_TDBR */
-#define TXS 0x00000008 /* SPI_TDBR Data Buffer Status (0=Empty, 1=Full) */
-#define RBSY 0x00000010 /* Set (=1) when data is received with RDBR full */
-#define RXS 0x00000020 /* SPI_RDBR Data Buffer Status (0=Empty, 1=Full) */
-#define TXCOL 0x00000040 /* When set (=1), corrupt data may have been transmitted */
-
/* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS ************* */
/* AMGCTL Masks */
diff --git a/arch/blackfin/mach-bf561/include/mach/pll.h b/arch/blackfin/mach-bf561/include/mach/pll.h
new file mode 100644
index 000000000000..f2b1fbdb8e72
--- /dev/null
+++ b/arch/blackfin/mach-bf561/include/mach/pll.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2005-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef _MACH_PLL_H
+#define _MACH_PLL_H
+
+#include <asm/blackfin.h>
+#include <asm/irqflags.h>
+
+/* Writing to PLL_CTL initiates a PLL relock sequence. */
+static __inline__ void bfin_write_PLL_CTL(unsigned int val)
+{
+ unsigned long flags, iwr0, iwr1;
+
+ if (val == bfin_read_PLL_CTL())
+ return;
+
+ flags = hard_local_irq_save();
+ /* Enable the PLL Wakeup bit in SIC IWR */
+ iwr0 = bfin_read32(SICA_IWR0);
+ iwr1 = bfin_read32(SICA_IWR1);
+ /* Only allow PPL Wakeup) */
+ bfin_write32(SICA_IWR0, IWR_ENABLE(0));
+ bfin_write32(SICA_IWR1, 0);
+
+ bfin_write16(PLL_CTL, val);
+ SSYNC();
+ asm("IDLE;");
+
+ bfin_write32(SICA_IWR0, iwr0);
+ bfin_write32(SICA_IWR1, iwr1);
+ hard_local_irq_restore(flags);
+}
+
+/* Writing to VR_CTL initiates a PLL relock sequence. */
+static __inline__ void bfin_write_VR_CTL(unsigned int val)
+{
+ unsigned long flags, iwr0, iwr1;
+
+ if (val == bfin_read_VR_CTL())
+ return;
+
+ flags = hard_local_irq_save();
+ /* Enable the PLL Wakeup bit in SIC IWR */
+ iwr0 = bfin_read32(SICA_IWR0);
+ iwr1 = bfin_read32(SICA_IWR1);
+ /* Only allow PPL Wakeup) */
+ bfin_write32(SICA_IWR0, IWR_ENABLE(0));
+ bfin_write32(SICA_IWR1, 0);
+
+ bfin_write16(VR_CTL, val);
+ SSYNC();
+ asm("IDLE;");
+
+ bfin_write32(SICA_IWR0, iwr0);
+ bfin_write32(SICA_IWR1, iwr1);
+ hard_local_irq_restore(flags);
+}
+
+#endif /* _MACH_PLL_H */
diff --git a/arch/blackfin/mach-bf561/ints-priority.c b/arch/blackfin/mach-bf561/ints-priority.c
index b4424172ad9e..7ee9262fe132 100644
--- a/arch/blackfin/mach-bf561/ints-priority.c
+++ b/arch/blackfin/mach-bf561/ints-priority.c
@@ -13,7 +13,7 @@
void __init program_IAR(void)
{
/* Program the IAR0 Register with the configured priority */
- bfin_write_SICA_IAR0(((CONFIG_IRQ_PLL_WAKEUP - 7) << IRQ_PLL_WAKEUP_POS) |
+ bfin_write_SIC_IAR0(((CONFIG_IRQ_PLL_WAKEUP - 7) << IRQ_PLL_WAKEUP_POS) |
((CONFIG_IRQ_DMA1_ERROR - 7) << IRQ_DMA1_ERROR_POS) |
((CONFIG_IRQ_DMA2_ERROR - 7) << IRQ_DMA2_ERROR_POS) |
((CONFIG_IRQ_IMDMA_ERROR - 7) << IRQ_IMDMA_ERROR_POS) |
@@ -22,7 +22,7 @@ void __init program_IAR(void)
((CONFIG_IRQ_SPORT0_ERROR - 7) << IRQ_SPORT0_ERROR_POS) |
((CONFIG_IRQ_SPORT1_ERROR - 7) << IRQ_SPORT1_ERROR_POS));
- bfin_write_SICA_IAR1(((CONFIG_IRQ_SPI_ERROR - 7) << IRQ_SPI_ERROR_POS) |
+ bfin_write_SIC_IAR1(((CONFIG_IRQ_SPI_ERROR - 7) << IRQ_SPI_ERROR_POS) |
((CONFIG_IRQ_UART_ERROR - 7) << IRQ_UART_ERROR_POS) |
((CONFIG_IRQ_RESERVED_ERROR - 7) << IRQ_RESERVED_ERROR_POS) |
((CONFIG_IRQ_DMA1_0 - 7) << IRQ_DMA1_0_POS) |
@@ -31,7 +31,7 @@ void __init program_IAR(void)
((CONFIG_IRQ_DMA1_3 - 7) << IRQ_DMA1_3_POS) |
((CONFIG_IRQ_DMA1_4 - 7) << IRQ_DMA1_4_POS));
- bfin_write_SICA_IAR2(((CONFIG_IRQ_DMA1_5 - 7) << IRQ_DMA1_5_POS) |
+ bfin_write_SIC_IAR2(((CONFIG_IRQ_DMA1_5 - 7) << IRQ_DMA1_5_POS) |
((CONFIG_IRQ_DMA1_6 - 7) << IRQ_DMA1_6_POS) |
((CONFIG_IRQ_DMA1_7 - 7) << IRQ_DMA1_7_POS) |
((CONFIG_IRQ_DMA1_8 - 7) << IRQ_DMA1_8_POS) |
@@ -40,7 +40,7 @@ void __init program_IAR(void)
((CONFIG_IRQ_DMA1_11 - 7) << IRQ_DMA1_11_POS) |
((CONFIG_IRQ_DMA2_0 - 7) << IRQ_DMA2_0_POS));
- bfin_write_SICA_IAR3(((CONFIG_IRQ_DMA2_1 - 7) << IRQ_DMA2_1_POS) |
+ bfin_write_SIC_IAR3(((CONFIG_IRQ_DMA2_1 - 7) << IRQ_DMA2_1_POS) |
((CONFIG_IRQ_DMA2_2 - 7) << IRQ_DMA2_2_POS) |
((CONFIG_IRQ_DMA2_3 - 7) << IRQ_DMA2_3_POS) |
((CONFIG_IRQ_DMA2_4 - 7) << IRQ_DMA2_4_POS) |
@@ -49,7 +49,7 @@ void __init program_IAR(void)
((CONFIG_IRQ_DMA2_7 - 7) << IRQ_DMA2_7_POS) |
((CONFIG_IRQ_DMA2_8 - 7) << IRQ_DMA2_8_POS));
- bfin_write_SICA_IAR4(((CONFIG_IRQ_DMA2_9 - 7) << IRQ_DMA2_9_POS) |
+ bfin_write_SIC_IAR4(((CONFIG_IRQ_DMA2_9 - 7) << IRQ_DMA2_9_POS) |
((CONFIG_IRQ_DMA2_10 - 7) << IRQ_DMA2_10_POS) |
((CONFIG_IRQ_DMA2_11 - 7) << IRQ_DMA2_11_POS) |
((CONFIG_IRQ_TIMER0 - 7) << IRQ_TIMER0_POS) |
@@ -58,7 +58,7 @@ void __init program_IAR(void)
((CONFIG_IRQ_TIMER3 - 7) << IRQ_TIMER3_POS) |
((CONFIG_IRQ_TIMER4 - 7) << IRQ_TIMER4_POS));
- bfin_write_SICA_IAR5(((CONFIG_IRQ_TIMER5 - 7) << IRQ_TIMER5_POS) |
+ bfin_write_SIC_IAR5(((CONFIG_IRQ_TIMER5 - 7) << IRQ_TIMER5_POS) |
((CONFIG_IRQ_TIMER6 - 7) << IRQ_TIMER6_POS) |
((CONFIG_IRQ_TIMER7 - 7) << IRQ_TIMER7_POS) |
((CONFIG_IRQ_TIMER8 - 7) << IRQ_TIMER8_POS) |
@@ -67,7 +67,7 @@ void __init program_IAR(void)
((CONFIG_IRQ_TIMER11 - 7) << IRQ_TIMER11_POS) |
((CONFIG_IRQ_PROG0_INTA - 7) << IRQ_PROG0_INTA_POS));
- bfin_write_SICA_IAR6(((CONFIG_IRQ_PROG0_INTB - 7) << IRQ_PROG0_INTB_POS) |
+ bfin_write_SIC_IAR6(((CONFIG_IRQ_PROG0_INTB - 7) << IRQ_PROG0_INTB_POS) |
((CONFIG_IRQ_PROG1_INTA - 7) << IRQ_PROG1_INTA_POS) |
((CONFIG_IRQ_PROG1_INTB - 7) << IRQ_PROG1_INTB_POS) |
((CONFIG_IRQ_PROG2_INTA - 7) << IRQ_PROG2_INTA_POS) |
@@ -76,7 +76,7 @@ void __init program_IAR(void)
((CONFIG_IRQ_DMA1_WRRD1 - 7) << IRQ_DMA1_WRRD1_POS) |
((CONFIG_IRQ_DMA2_WRRD0 - 7) << IRQ_DMA2_WRRD0_POS));
- bfin_write_SICA_IAR7(((CONFIG_IRQ_DMA2_WRRD1 - 7) << IRQ_DMA2_WRRD1_POS) |
+ bfin_write_SIC_IAR7(((CONFIG_IRQ_DMA2_WRRD1 - 7) << IRQ_DMA2_WRRD1_POS) |
((CONFIG_IRQ_IMDMA_WRRD0 - 7) << IRQ_IMDMA_WRRD0_POS) |
((CONFIG_IRQ_IMDMA_WRRD1 - 7) << IRQ_IMDMA_WRRD1_POS) |
((CONFIG_IRQ_WDTIMER - 7) << IRQ_WDTIMER_POS) |
diff --git a/arch/blackfin/mach-bf561/smp.c b/arch/blackfin/mach-bf561/smp.c
index 3b9a4bf7dacc..f540ed1257d6 100644
--- a/arch/blackfin/mach-bf561/smp.c
+++ b/arch/blackfin/mach-bf561/smp.c
@@ -52,19 +52,19 @@ int __init setup_profiling_timer(unsigned int multiplier) /* not supported */
void __cpuinit platform_secondary_init(unsigned int cpu)
{
/* Clone setup for peripheral interrupt sources from CoreA. */
- bfin_write_SICB_IMASK0(bfin_read_SICA_IMASK0());
- bfin_write_SICB_IMASK1(bfin_read_SICA_IMASK1());
+ bfin_write_SICB_IMASK0(bfin_read_SIC_IMASK0());
+ bfin_write_SICB_IMASK1(bfin_read_SIC_IMASK1());
SSYNC();
/* Clone setup for IARs from CoreA. */
- bfin_write_SICB_IAR0(bfin_read_SICA_IAR0());
- bfin_write_SICB_IAR1(bfin_read_SICA_IAR1());
- bfin_write_SICB_IAR2(bfin_read_SICA_IAR2());
- bfin_write_SICB_IAR3(bfin_read_SICA_IAR3());
- bfin_write_SICB_IAR4(bfin_read_SICA_IAR4());
- bfin_write_SICB_IAR5(bfin_read_SICA_IAR5());
- bfin_write_SICB_IAR6(bfin_read_SICA_IAR6());
- bfin_write_SICB_IAR7(bfin_read_SICA_IAR7());
+ bfin_write_SICB_IAR0(bfin_read_SIC_IAR0());
+ bfin_write_SICB_IAR1(bfin_read_SIC_IAR1());
+ bfin_write_SICB_IAR2(bfin_read_SIC_IAR2());
+ bfin_write_SICB_IAR3(bfin_read_SIC_IAR3());
+ bfin_write_SICB_IAR4(bfin_read_SIC_IAR4());
+ bfin_write_SICB_IAR5(bfin_read_SIC_IAR5());
+ bfin_write_SICB_IAR6(bfin_read_SIC_IAR6());
+ bfin_write_SICB_IAR7(bfin_read_SIC_IAR7());
bfin_write_SICB_IWR0(IWR_DISABLE_ALL);
bfin_write_SICB_IWR1(IWR_DISABLE_ALL);
SSYNC();
@@ -86,12 +86,12 @@ int __cpuinit platform_boot_secondary(unsigned int cpu, struct task_struct *idle
spin_lock(&boot_lock);
- if ((bfin_read_SICA_SYSCR() & COREB_SRAM_INIT) == 0) {
+ if ((bfin_read_SIC_SYSCR() & COREB_SRAM_INIT) == 0) {
/* CoreB already running, sending ipi to wakeup it */
platform_send_ipi_cpu(cpu, IRQ_SUPPLE_0);
} else {
/* Kick CoreB, which should start execution from CORE_SRAM_BASE. */
- bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() & ~COREB_SRAM_INIT);
+ bfin_write_SIC_SYSCR(bfin_read_SIC_SYSCR() & ~COREB_SRAM_INIT);
SSYNC();
}
diff --git a/arch/blackfin/mach-common/cpufreq.c b/arch/blackfin/mach-common/cpufreq.c
index 4391d03dc845..f4cf11d362e1 100644
--- a/arch/blackfin/mach-common/cpufreq.c
+++ b/arch/blackfin/mach-common/cpufreq.c
@@ -134,7 +134,7 @@ static int bfin_target(struct cpufreq_policy *poli,
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
if (cpu == CPUFREQ_CPU) {
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
plldiv = (bfin_read_PLL_DIV() & SSEL) |
dpm_state_table[index].csel;
bfin_write_PLL_DIV(plldiv);
@@ -155,7 +155,7 @@ static int bfin_target(struct cpufreq_policy *poli,
loops_per_jiffy = cpufreq_scale(lpj_ref,
lpj_ref_freq, freqs.new);
}
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
}
/* TODO: just test case for cycles clock source, remove later */
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
diff --git a/arch/blackfin/mach-common/dpmc_modes.S b/arch/blackfin/mach-common/dpmc_modes.S
index 5969d86836a5..9cfdd49a3127 100644
--- a/arch/blackfin/mach-common/dpmc_modes.S
+++ b/arch/blackfin/mach-common/dpmc_modes.S
@@ -292,13 +292,7 @@ ENTRY(_do_hibernate)
#ifdef SIC_IMASK
PM_SYS_PUSH(SIC_IMASK)
#endif
-#ifdef SICA_IMASK0
- PM_SYS_PUSH(SICA_IMASK0)
-#endif
-#ifdef SICA_IMASK1
- PM_SYS_PUSH(SICA_IMASK1)
-#endif
-#ifdef SIC_IAR2
+#ifdef SIC_IAR0
PM_SYS_PUSH(SIC_IAR0)
PM_SYS_PUSH(SIC_IAR1)
PM_SYS_PUSH(SIC_IAR2)
@@ -321,17 +315,6 @@ ENTRY(_do_hibernate)
PM_SYS_PUSH(SIC_IAR11)
#endif
-#ifdef SICA_IAR0
- PM_SYS_PUSH(SICA_IAR0)
- PM_SYS_PUSH(SICA_IAR1)
- PM_SYS_PUSH(SICA_IAR2)
- PM_SYS_PUSH(SICA_IAR3)
- PM_SYS_PUSH(SICA_IAR4)
- PM_SYS_PUSH(SICA_IAR5)
- PM_SYS_PUSH(SICA_IAR6)
- PM_SYS_PUSH(SICA_IAR7)
-#endif
-
#ifdef SIC_IWR
PM_SYS_PUSH(SIC_IWR)
#endif
@@ -344,12 +327,6 @@ ENTRY(_do_hibernate)
#ifdef SIC_IWR2
PM_SYS_PUSH(SIC_IWR2)
#endif
-#ifdef SICA_IWR0
- PM_SYS_PUSH(SICA_IWR0)
-#endif
-#ifdef SICA_IWR1
- PM_SYS_PUSH(SICA_IWR1)
-#endif
#ifdef PINT0_ASSIGN
PM_SYS_PUSH(PINT0_MASK_SET)
@@ -750,12 +727,6 @@ ENTRY(_do_hibernate)
PM_SYS_POP(PINT0_MASK_SET)
#endif
-#ifdef SICA_IWR1
- PM_SYS_POP(SICA_IWR1)
-#endif
-#ifdef SICA_IWR0
- PM_SYS_POP(SICA_IWR0)
-#endif
#ifdef SIC_IWR2
PM_SYS_POP(SIC_IWR2)
#endif
@@ -769,17 +740,6 @@ ENTRY(_do_hibernate)
PM_SYS_POP(SIC_IWR)
#endif
-#ifdef SICA_IAR0
- PM_SYS_POP(SICA_IAR7)
- PM_SYS_POP(SICA_IAR6)
- PM_SYS_POP(SICA_IAR5)
- PM_SYS_POP(SICA_IAR4)
- PM_SYS_POP(SICA_IAR3)
- PM_SYS_POP(SICA_IAR2)
- PM_SYS_POP(SICA_IAR1)
- PM_SYS_POP(SICA_IAR0)
-#endif
-
#ifdef SIC_IAR8
PM_SYS_POP(SIC_IAR11)
PM_SYS_POP(SIC_IAR10)
@@ -797,17 +757,11 @@ ENTRY(_do_hibernate)
#ifdef SIC_IAR3
PM_SYS_POP(SIC_IAR3)
#endif
-#ifdef SIC_IAR2
+#ifdef SIC_IAR0
PM_SYS_POP(SIC_IAR2)
PM_SYS_POP(SIC_IAR1)
PM_SYS_POP(SIC_IAR0)
#endif
-#ifdef SICA_IMASK1
- PM_SYS_POP(SICA_IMASK1)
-#endif
-#ifdef SICA_IMASK0
- PM_SYS_POP(SICA_IMASK0)
-#endif
#ifdef SIC_IMASK
PM_SYS_POP(SIC_IMASK)
#endif
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index af1bffa21dc1..2ca915ee181f 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -889,6 +889,66 @@ ENTRY(_ret_from_exception)
rts;
ENDPROC(_ret_from_exception)
+#if defined(CONFIG_PREEMPT)
+
+ENTRY(_up_to_irq14)
+#if ANOMALY_05000281 || ANOMALY_05000461
+ r0.l = lo(SAFE_USER_INSTRUCTION);
+ r0.h = hi(SAFE_USER_INSTRUCTION);
+ reti = r0;
+#endif
+
+#ifdef CONFIG_DEBUG_HWERR
+ /* enable irq14 & hwerr interrupt, until we transition to _evt_evt14 */
+ r0 = (EVT_IVG14 | EVT_IVHW | EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU);
+#else
+ /* Only enable irq14 interrupt, until we transition to _evt_evt14 */
+ r0 = (EVT_IVG14 | EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU);
+#endif
+ sti r0;
+
+ p0.l = lo(EVT14);
+ p0.h = hi(EVT14);
+ p1.l = _evt_up_evt14;
+ p1.h = _evt_up_evt14;
+ [p0] = p1;
+ csync;
+
+ raise 14;
+1:
+ jump 1b;
+ENDPROC(_up_to_irq14)
+
+ENTRY(_evt_up_evt14)
+#ifdef CONFIG_DEBUG_HWERR
+ r0 = (EVT_IVHW | EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU);
+ sti r0;
+#else
+ cli r0;
+#endif
+#ifdef CONFIG_TRACE_IRQFLAGS
+ [--sp] = rets;
+ sp += -12;
+ call _trace_hardirqs_off;
+ sp += 12;
+ rets = [sp++];
+#endif
+ [--sp] = RETI;
+ SP += 4;
+
+ /* restore normal evt14 */
+ p0.l = lo(EVT14);
+ p0.h = hi(EVT14);
+ p1.l = _evt_evt14;
+ p1.h = _evt_evt14;
+ [p0] = p1;
+ csync;
+
+ rts;
+ENDPROC(_evt_up_evt14)
+
+#endif
+
#ifdef CONFIG_IPIPE
_resume_kernel_from_int:
@@ -902,8 +962,54 @@ _resume_kernel_from_int:
( r7:4, p5:3 ) = [sp++];
rets = [sp++];
rts
+#elif defined(CONFIG_PREEMPT)
+
+_resume_kernel_from_int:
+ /* check preempt_count */
+ r7 = sp;
+ r4.l = lo(ALIGN_PAGE_MASK);
+ r4.h = hi(ALIGN_PAGE_MASK);
+ r7 = r7 & r4;
+ p5 = r7;
+ r7 = [p5 + TI_PREEMPT];
+ cc = r7 == 0x0;
+ if !cc jump .Lreturn_to_kernel;
+.Lneed_schedule:
+ r7 = [p5 + TI_FLAGS];
+ r4.l = lo(_TIF_WORK_MASK);
+ r4.h = hi(_TIF_WORK_MASK);
+ r7 = r7 & r4;
+ cc = BITTST(r7, TIF_NEED_RESCHED);
+ if !cc jump .Lreturn_to_kernel;
+ /*
+ * let schedule done at level 15, otherwise sheduled process will run
+ * at high level and block low level interrupt
+ */
+ r6 = reti; /* save reti */
+ r5.l = .Lkernel_schedule;
+ r5.h = .Lkernel_schedule;
+ reti = r5;
+ rti;
+.Lkernel_schedule:
+ [--sp] = rets;
+ sp += -12;
+ pseudo_long_call _preempt_schedule_irq, p4;
+ sp += 12;
+ rets = [sp++];
+
+ [--sp] = rets;
+ sp += -12;
+ /* up to irq14 so that reti after restore_all can return to irq15(kernel) */
+ pseudo_long_call _up_to_irq14, p4;
+ sp += 12;
+ rets = [sp++];
+
+ reti = r6; /* restore reti so that origin process can return to interrupted point */
+
+ jump .Lneed_schedule;
#else
-#define _resume_kernel_from_int 2f
+
+#define _resume_kernel_from_int .Lreturn_to_kernel
#endif
ENTRY(_return_from_int)
@@ -913,7 +1019,7 @@ ENTRY(_return_from_int)
p2.h = hi(ILAT);
r0 = [p2];
cc = bittst (r0, EVT_IVG15_P);
- if cc jump 2f;
+ if cc jump .Lreturn_to_kernel;
/* if not return to user mode, get out */
p2.l = lo(IPEND);
@@ -945,7 +1051,7 @@ ENTRY(_return_from_int)
STI r0;
raise 15; /* raise evt15 to do signal or reschedule */
rti;
-2:
+.Lreturn_to_kernel:
rts;
ENDPROC(_return_from_int)
@@ -1631,6 +1737,7 @@ ENTRY(_sys_call_table)
.long _sys_fanotify_init
.long _sys_fanotify_mark
.long _sys_prlimit64
+ .long _sys_cacheflush
.rept NR_syscalls-(.-_sys_call_table)/4
.long _sys_ni_syscall
diff --git a/arch/blackfin/mach-common/interrupt.S b/arch/blackfin/mach-common/interrupt.S
index cee62cf4acd4..2df37db3b49b 100644
--- a/arch/blackfin/mach-common/interrupt.S
+++ b/arch/blackfin/mach-common/interrupt.S
@@ -116,7 +116,24 @@ __common_int_entry:
cc = r0 == 0;
if cc jump .Lcommon_restore_context;
#else /* CONFIG_IPIPE */
+
+#ifdef CONFIG_PREEMPT
+ r7 = sp;
+ r4.l = lo(ALIGN_PAGE_MASK);
+ r4.h = hi(ALIGN_PAGE_MASK);
+ r7 = r7 & r4;
+ p5 = r7;
+ r7 = [p5 + TI_PREEMPT]; /* get preempt count */
+ r7 += 1; /* increment it */
+ [p5 + TI_PREEMPT] = r7;
+#endif
pseudo_long_call _do_irq, p2;
+
+#ifdef CONFIG_PREEMPT
+ r7 += -1;
+ [p5 + TI_PREEMPT] = r7; /* restore preempt count */
+#endif
+
SP += 12;
#endif /* CONFIG_IPIPE */
pseudo_long_call _return_from_int, p2;
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c
index 1c8c4c7245c3..da7e3c63746b 100644
--- a/arch/blackfin/mach-common/ints-priority.c
+++ b/arch/blackfin/mach-common/ints-priority.c
@@ -132,8 +132,8 @@ static void bfin_ack_noop(unsigned int irq)
static void bfin_core_mask_irq(unsigned int irq)
{
bfin_irq_flags &= ~(1 << irq);
- if (!irqs_disabled_hw())
- local_irq_enable_hw();
+ if (!hard_irqs_disabled())
+ hard_local_irq_enable();
}
static void bfin_core_unmask_irq(unsigned int irq)
@@ -148,8 +148,8 @@ static void bfin_core_unmask_irq(unsigned int irq)
* local_irq_enable just does "STI bfin_irq_flags", so it's exactly
* what we need.
*/
- if (!irqs_disabled_hw())
- local_irq_enable_hw();
+ if (!hard_irqs_disabled())
+ hard_local_irq_enable();
return;
}
@@ -158,12 +158,12 @@ static void bfin_internal_mask_irq(unsigned int irq)
unsigned long flags;
#ifdef CONFIG_BF53x
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() &
~(1 << SIC_SYSIRQ(irq)));
#else
unsigned mask_bank, mask_bit;
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
mask_bank = SIC_SYSIRQ(irq) / 32;
mask_bit = SIC_SYSIRQ(irq) % 32;
bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) &
@@ -173,7 +173,7 @@ static void bfin_internal_mask_irq(unsigned int irq)
~(1 << mask_bit));
#endif
#endif
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
}
#ifdef CONFIG_SMP
@@ -186,12 +186,12 @@ static void bfin_internal_unmask_irq(unsigned int irq)
unsigned long flags;
#ifdef CONFIG_BF53x
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() |
(1 << SIC_SYSIRQ(irq)));
#else
unsigned mask_bank, mask_bit;
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
mask_bank = SIC_SYSIRQ(irq) / 32;
mask_bit = SIC_SYSIRQ(irq) % 32;
#ifdef CONFIG_SMP
@@ -207,7 +207,7 @@ static void bfin_internal_unmask_irq(unsigned int irq)
(1 << mask_bit));
#endif
#endif
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
}
#ifdef CONFIG_SMP
@@ -264,7 +264,7 @@ int bfin_internal_set_wake(unsigned int irq, unsigned int state)
break;
}
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
if (state) {
bfin_sic_iwr[bank] |= (1 << bit);
@@ -275,7 +275,7 @@ int bfin_internal_set_wake(unsigned int irq, unsigned int state)
vr_wakeup &= ~wakeup;
}
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
return 0;
}
@@ -511,7 +511,7 @@ static void bfin_demux_mac_status_irq(unsigned int int_err_irq,
int i, irq = 0;
u32 status = bfin_read_EMAC_SYSTAT();
- for (i = 0; i < (IRQ_MAC_STMDONE - IRQ_MAC_PHYINT); i++)
+ for (i = 0; i <= (IRQ_MAC_STMDONE - IRQ_MAC_PHYINT); i++)
if (status & (1L << i)) {
irq = IRQ_MAC_PHYINT + i;
break;
@@ -529,8 +529,9 @@ static void bfin_demux_mac_status_irq(unsigned int int_err_irq,
} else
printk(KERN_ERR
"%s : %s : LINE %d :\nIRQ ?: MAC ERROR"
- " INTERRUPT ASSERTED BUT NO SOURCE FOUND\n",
- __func__, __FILE__, __LINE__);
+ " INTERRUPT ASSERTED BUT NO SOURCE FOUND"
+ "(EMAC_SYSTAT=0x%X)\n",
+ __func__, __FILE__, __LINE__, status);
}
#endif
@@ -1298,7 +1299,7 @@ void do_irq(int vec, struct pt_regs *fp)
} else {
struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst;
struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop;
-#if defined(SIC_ISR0) || defined(SICA_ISR0)
+#if defined(SIC_ISR0)
unsigned long sic_status[3];
if (smp_processor_id()) {
@@ -1378,7 +1379,7 @@ asmlinkage int __ipipe_grab_irq(int vec, struct pt_regs *regs)
if (likely(vec == EVT_IVTMR_P))
irq = IRQ_CORETMR;
else {
-#if defined(SIC_ISR0) || defined(SICA_ISR0)
+#if defined(SIC_ISR0)
unsigned long sic_status[3];
sic_status[0] = bfin_read_SIC_ISR0() & bfin_read_SIC_IMASK0();
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c
index 09c1fb410748..80884b136a0c 100644
--- a/arch/blackfin/mach-common/pm.c
+++ b/arch/blackfin/mach-common/pm.c
@@ -25,7 +25,7 @@ void bfin_pm_suspend_standby_enter(void)
{
unsigned long flags;
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
bfin_pm_standby_setup();
#ifdef CONFIG_PM_BFIN_SLEEP_DEEPER
@@ -56,7 +56,7 @@ void bfin_pm_suspend_standby_enter(void)
bfin_write_SIC_IWR(IWR_DISABLE_ALL);
#endif
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
}
int bf53x_suspend_l1_mem(unsigned char *memptr)
@@ -149,12 +149,12 @@ int bfin_pm_suspend_mem_enter(void)
wakeup |= GPWE;
#endif
- local_irq_save_hw(flags);
+ flags = hard_local_irq_save();
ret = blackfin_dma_suspend();
if (ret) {
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
kfree(memptr);
return ret;
}
@@ -178,7 +178,7 @@ int bfin_pm_suspend_mem_enter(void)
bfin_gpio_pm_hibernate_restore();
blackfin_dma_resume();
- local_irq_restore_hw(flags);
+ hard_local_irq_restore(flags);
kfree(memptr);
return 0;
diff --git a/arch/blackfin/mm/init.c b/arch/blackfin/mm/init.c
index bb4e8fff4b55..f8435cd36c7c 100644
--- a/arch/blackfin/mm/init.c
+++ b/arch/blackfin/mm/init.c
@@ -158,5 +158,8 @@ void __init_refok free_initmem(void)
free_init_pages("unused kernel memory",
(unsigned long)(&__init_begin),
(unsigned long)(&__init_end));
+
+ if (memory_start == (unsigned long)(&__init_end))
+ memory_start = (unsigned long)(&__init_begin);
#endif
}
diff --git a/arch/cris/arch-v10/drivers/ds1302.c b/arch/cris/arch-v10/drivers/ds1302.c
index 884275629ef7..3d655dcc65da 100644
--- a/arch/cris/arch-v10/drivers/ds1302.c
+++ b/arch/cris/arch-v10/drivers/ds1302.c
@@ -19,7 +19,7 @@
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/bcd.h>
#include <linux/capability.h>
@@ -34,6 +34,7 @@
#define RTC_MAJOR_NR 121 /* local major, change later */
+static DEFINE_MUTEX(ds1302_mutex);
static const char ds1302_name[] = "ds1302";
/* The DS1302 might be connected to different bits on different products.
@@ -357,9 +358,9 @@ static long rtc_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned lon
{
int ret;
- lock_kernel();
+ mutex_lock(&ds1302_mutex);
ret = rtc_ioctl(file, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&ds1302_mutex);
return ret;
}
@@ -387,6 +388,7 @@ print_rtc_status(void)
static const struct file_operations rtc_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = rtc_unlocked_ioctl,
+ .llseek = noop_llseek,
};
/* Probe for the chip by writing something to its RAM and try reading it back. */
diff --git a/arch/cris/arch-v10/drivers/gpio.c b/arch/cris/arch-v10/drivers/gpio.c
index a07b6d25b0c7..a276f0811731 100644
--- a/arch/cris/arch-v10/drivers/gpio.c
+++ b/arch/cris/arch-v10/drivers/gpio.c
@@ -745,6 +745,7 @@ static const struct file_operations gpio_fops = {
.write = gpio_write,
.open = gpio_open,
.release = gpio_release,
+ .llseek = noop_llseek,
};
static void ioif_watcher(const unsigned int gpio_in_available,
diff --git a/arch/cris/arch-v10/drivers/i2c.c b/arch/cris/arch-v10/drivers/i2c.c
index 77a941813819..c413539d4205 100644
--- a/arch/cris/arch-v10/drivers/i2c.c
+++ b/arch/cris/arch-v10/drivers/i2c.c
@@ -617,6 +617,7 @@ static const struct file_operations i2c_fops = {
.unlocked_ioctl = i2c_ioctl,
.open = i2c_open,
.release = i2c_release,
+ .llseek = noop_llseek,
};
int __init
diff --git a/arch/cris/arch-v10/drivers/pcf8563.c b/arch/cris/arch-v10/drivers/pcf8563.c
index 7dcb1f85f42b..ea69faba9b62 100644
--- a/arch/cris/arch-v10/drivers/pcf8563.c
+++ b/arch/cris/arch-v10/drivers/pcf8563.c
@@ -27,7 +27,6 @@
#include <linux/delay.h>
#include <linux/bcd.h>
#include <linux/mutex.h>
-#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/system.h>
@@ -49,6 +48,7 @@
#define rtc_read(x) i2c_readreg(RTC_I2C_READ, x)
#define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y)
+static DEFINE_MUTEX(pcf8563_mutex);
static DEFINE_MUTEX(rtc_lock); /* Protect state etc */
static const unsigned char days_in_month[] =
@@ -64,6 +64,7 @@ static int voltage_low;
static const struct file_operations pcf8563_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = pcf8563_unlocked_ioctl,
+ .llseek = noop_llseek,
};
unsigned char
@@ -343,9 +344,9 @@ static long pcf8563_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned
{
int ret;
- lock_kernel();
+ mutex_lock(&pcf8563_mutex);
return pcf8563_ioctl(filp, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&pcf8563_mutex);
return ret;
}
diff --git a/arch/cris/arch-v10/drivers/sync_serial.c b/arch/cris/arch-v10/drivers/sync_serial.c
index ee2dd4323daf..399dc1ec8e6f 100644
--- a/arch/cris/arch-v10/drivers/sync_serial.c
+++ b/arch/cris/arch-v10/drivers/sync_serial.c
@@ -20,7 +20,7 @@
#include <linux/interrupt.h>
#include <linux/poll.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/timer.h>
#include <asm/irq.h>
#include <asm/dma.h>
@@ -149,6 +149,7 @@ struct sync_port {
};
+static DEFINE_MUTEX(sync_serial_mutex);
static int etrax_sync_serial_init(void);
static void initialize_port(int portnbr);
static inline int sync_data_avail(struct sync_port *port);
@@ -250,7 +251,8 @@ static const struct file_operations sync_serial_fops = {
.poll = sync_serial_poll,
.unlocked_ioctl = sync_serial_ioctl,
.open = sync_serial_open,
- .release = sync_serial_release
+ .release = sync_serial_release,
+ .llseek = noop_llseek,
};
static int __init etrax_sync_serial_init(void)
@@ -445,7 +447,7 @@ static int sync_serial_open(struct inode *inode, struct file *file)
int mode;
int err = -EBUSY;
- lock_kernel();
+ mutex_lock(&sync_serial_mutex);
DEBUG(printk(KERN_DEBUG "Open sync serial port %d\n", dev));
if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) {
@@ -626,7 +628,7 @@ static int sync_serial_open(struct inode *inode, struct file *file)
ret = 0;
out:
- unlock_kernel();
+ mutex_unlock(&sync_serial_mutex);
return ret;
}
@@ -961,9 +963,9 @@ static long sync_serial_ioctl(struct file *file,
{
long ret;
- lock_kernel();
+ mutex_lock(&sync_serial_mutex);
ret = sync_serial_ioctl_unlocked(file, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&sync_serial_mutex);
return ret;
}
diff --git a/arch/cris/arch-v32/drivers/cryptocop.c b/arch/cris/arch-v32/drivers/cryptocop.c
index b07646a30509..c03bc3bc30c2 100644
--- a/arch/cris/arch-v32/drivers/cryptocop.c
+++ b/arch/cris/arch-v32/drivers/cryptocop.c
@@ -281,7 +281,8 @@ const struct file_operations cryptocop_fops = {
.owner = THIS_MODULE,
.open = cryptocop_open,
.release = cryptocop_release,
- .unlocked_ioctl = cryptocop_ioctl
+ .unlocked_ioctl = cryptocop_ioctl,
+ .llseek = noop_llseek,
};
@@ -3139,9 +3140,9 @@ cryptocop_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
struct inode *inode = file->f_path.dentry->d_inode;
long ret;
- lock_kernel();
+ mutex_lock(&cryptocop_mutex);
ret = cryptocop_ioctl_unlocked(inode, filp, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&cryptocop_mutex);
return ret;
}
diff --git a/arch/cris/arch-v32/drivers/i2c.c b/arch/cris/arch-v32/drivers/i2c.c
index 5a3e900c9a78..ddb23996f11a 100644
--- a/arch/cris/arch-v32/drivers/i2c.c
+++ b/arch/cris/arch-v32/drivers/i2c.c
@@ -698,6 +698,7 @@ static const struct file_operations i2c_fops = {
.unlocked_ioctl = i2c_ioctl,
.open = i2c_open,
.release = i2c_release,
+ .llseek = noop_llseek,
};
static int __init i2c_init(void)
diff --git a/arch/cris/arch-v32/drivers/mach-a3/gpio.c b/arch/cris/arch-v32/drivers/mach-a3/gpio.c
index 2dcd27adbad4..c845831e2225 100644
--- a/arch/cris/arch-v32/drivers/mach-a3/gpio.c
+++ b/arch/cris/arch-v32/drivers/mach-a3/gpio.c
@@ -23,7 +23,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <asm/etraxgpio.h>
#include <hwregs/reg_map.h>
@@ -66,6 +66,7 @@ static int dp_cnt;
#define DP(x)
#endif
+static DEFINE_MUTEX(gpio_mutex);
static char gpio_name[] = "etrax gpio";
#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
@@ -391,7 +392,7 @@ static int gpio_open(struct inode *inode, struct file *filp)
if (!priv)
return -ENOMEM;
- lock_kernel();
+ mutex_lock(&gpio_mutex);
memset(priv, 0, sizeof(*priv));
priv->minor = p;
@@ -414,7 +415,7 @@ static int gpio_open(struct inode *inode, struct file *filp)
spin_unlock_irq(&gpio_lock);
}
- unlock_kernel();
+ mutex_unlock(&gpio_mutex);
return 0;
}
@@ -667,9 +668,9 @@ static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
long ret;
- lock_kernel();
+ mutex_lock(&gpio_mutex);
ret = gpio_ioctl_unlocked(file, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&gpio_mutex);
return ret;
}
@@ -893,6 +894,7 @@ static const struct file_operations gpio_fops = {
.write = gpio_write,
.open = gpio_open,
.release = gpio_release,
+ .llseek = noop_llseek,
};
#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
diff --git a/arch/cris/arch-v32/drivers/mach-fs/gpio.c b/arch/cris/arch-v32/drivers/mach-fs/gpio.c
index 5ec8a7d4e7d7..ee90d2659be7 100644
--- a/arch/cris/arch-v32/drivers/mach-fs/gpio.c
+++ b/arch/cris/arch-v32/drivers/mach-fs/gpio.c
@@ -22,7 +22,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <asm/etraxgpio.h>
#include <hwregs/reg_map.h>
@@ -64,6 +64,7 @@ static int dp_cnt;
#define DP(x)
#endif
+static DEFINE_MUTEX(gpio_mutex);
static char gpio_name[] = "etrax gpio";
#if 0
@@ -429,7 +430,7 @@ gpio_open(struct inode *inode, struct file *filp)
if (!priv)
return -ENOMEM;
- lock_kernel();
+ mutex_lock(&gpio_mutex);
memset(priv, 0, sizeof(*priv));
priv->minor = p;
@@ -450,7 +451,7 @@ gpio_open(struct inode *inode, struct file *filp)
alarmlist = priv;
spin_unlock_irq(&alarm_lock);
- unlock_kernel();
+ mutex_unlock(&gpio_mutex);
return 0;
}
@@ -708,9 +709,9 @@ static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
long ret;
- lock_kernel();
+ mutex_lock(&gpio_mutex);
ret = gpio_ioctl_unlocked(file, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&gpio_mutex);
return ret;
}
@@ -870,6 +871,7 @@ static const struct file_operations gpio_fops = {
.write = gpio_write,
.open = gpio_open,
.release = gpio_release,
+ .llseek = noop_llseek,
};
#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
diff --git a/arch/cris/arch-v32/drivers/pcf8563.c b/arch/cris/arch-v32/drivers/pcf8563.c
index bef6eb53b153..b6e4fc0aad42 100644
--- a/arch/cris/arch-v32/drivers/pcf8563.c
+++ b/arch/cris/arch-v32/drivers/pcf8563.c
@@ -24,7 +24,6 @@
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/ioctl.h>
-#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/bcd.h>
#include <linux/mutex.h>
@@ -45,6 +44,7 @@
#define rtc_read(x) i2c_readreg(RTC_I2C_READ, x)
#define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y)
+static DEFINE_MUTEX(pcf8563_mutex);
static DEFINE_MUTEX(rtc_lock); /* Protect state etc */
static const unsigned char days_in_month[] =
@@ -60,6 +60,7 @@ static int voltage_low;
static const struct file_operations pcf8563_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = pcf8563_unlocked_ioctl,
+ .llseek = noop_llseek,
};
unsigned char
@@ -339,9 +340,9 @@ static long pcf8563_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned
{
int ret;
- lock_kernel();
+ mutex_lock(&pcf8563_mutex);
return pcf8563_ioctl(filp, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&pcf8563_mutex);
return ret;
}
diff --git a/arch/cris/arch-v32/drivers/sync_serial.c b/arch/cris/arch-v32/drivers/sync_serial.c
index ca248f3adb80..c8637a9195ea 100644
--- a/arch/cris/arch-v32/drivers/sync_serial.c
+++ b/arch/cris/arch-v32/drivers/sync_serial.c
@@ -13,7 +13,7 @@
#include <linux/errno.h>
#include <linux/major.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/interrupt.h>
#include <linux/poll.h>
#include <linux/init.h>
@@ -145,6 +145,7 @@ typedef struct sync_port
spinlock_t lock;
} sync_port;
+static DEFINE_MUTEX(sync_serial_mutex);
static int etrax_sync_serial_init(void);
static void initialize_port(int portnbr);
static inline int sync_data_avail(struct sync_port *port);
@@ -247,7 +248,8 @@ static const struct file_operations sync_serial_fops = {
.poll = sync_serial_poll,
.unlocked_ioctl = sync_serial_ioctl,
.open = sync_serial_open,
- .release = sync_serial_release
+ .release = sync_serial_release,
+ .llseek = noop_llseek,
};
static int __init etrax_sync_serial_init(void)
@@ -434,7 +436,7 @@ static int sync_serial_open(struct inode *inode, struct file *file)
reg_dma_rw_cfg cfg = {.en = regk_dma_yes};
reg_dma_rw_intr_mask intr_mask = {.data = regk_dma_yes};
- lock_kernel();
+ mutex_lock(&sync_serial_mutex);
DEBUG(printk(KERN_DEBUG "Open sync serial port %d\n", dev));
if (dev < 0 || dev >= NBR_PORTS || !ports[dev].enabled)
@@ -583,7 +585,7 @@ static int sync_serial_open(struct inode *inode, struct file *file)
port->busy++;
ret = 0;
out:
- unlock_kernel();
+ mutex_unlock(&sync_serial_mutex);
return ret;
}
@@ -966,9 +968,9 @@ static long sync_serial_ioctl(struct file *file,
{
long ret;
- lock_kernel();
+ mutex_lock(&sync_serial_mutex);
ret = sync_serial_ioctl_unlocked(file, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&sync_serial_mutex);
return ret;
}
diff --git a/arch/cris/include/arch-v10/arch/irqflags.h b/arch/cris/include/arch-v10/arch/irqflags.h
new file mode 100644
index 000000000000..75ef18991240
--- /dev/null
+++ b/arch/cris/include/arch-v10/arch/irqflags.h
@@ -0,0 +1,45 @@
+#ifndef __ASM_CRIS_ARCH_IRQFLAGS_H
+#define __ASM_CRIS_ARCH_IRQFLAGS_H
+
+#include <linux/types.h>
+
+static inline unsigned long arch_local_save_flags(void)
+{
+ unsigned long flags;
+ asm volatile("move $ccr,%0" : "=rm" (flags) : : "memory");
+ return flags;
+}
+
+static inline void arch_local_irq_disable(void)
+{
+ asm volatile("di" : : : "memory");
+}
+
+static inline void arch_local_irq_enable(void)
+{
+ asm volatile("ei" : : : "memory");
+}
+
+static inline unsigned long arch_local_irq_save(void)
+{
+ unsigned long flags = arch_local_save_flags();
+ arch_local_irq_disable();
+ return flags;
+}
+
+static inline void arch_local_irq_restore(unsigned long flags)
+{
+ asm volatile("move %0,$ccr" : : "rm" (flags) : "memory");
+}
+
+static inline bool arch_irqs_disabled_flags(unsigned long flags)
+{
+ return !(flags & (1 << 5));
+}
+
+static inline bool arch_irqs_disabled(void)
+{
+ return arch_irqs_disabled_flags(arch_local_save_flags());
+}
+
+#endif /* __ASM_CRIS_ARCH_IRQFLAGS_H */
diff --git a/arch/cris/include/arch-v10/arch/system.h b/arch/cris/include/arch-v10/arch/system.h
index 4a9cd36c9e16..935fde34aa15 100644
--- a/arch/cris/include/arch-v10/arch/system.h
+++ b/arch/cris/include/arch-v10/arch/system.h
@@ -44,20 +44,4 @@ static inline unsigned long _get_base(char * addr)
struct __xchg_dummy { unsigned long a[100]; };
#define __xg(x) ((struct __xchg_dummy *)(x))
-/* interrupt control.. */
-#define local_save_flags(x) __asm__ __volatile__ ("move $ccr,%0" : "=rm" (x) : : "memory");
-#define local_irq_restore(x) __asm__ __volatile__ ("move %0,$ccr" : : "rm" (x) : "memory");
-#define local_irq_disable() __asm__ __volatile__ ( "di" : : :"memory");
-#define local_irq_enable() __asm__ __volatile__ ( "ei" : : :"memory");
-
-#define irqs_disabled() \
-({ \
- unsigned long flags; \
- local_save_flags(flags); \
- !(flags & (1<<5)); \
-})
-
-/* For spinlocks etc */
-#define local_irq_save(x) __asm__ __volatile__ ("move $ccr,%0\n\tdi" : "=rm" (x) : : "memory");
-
#endif
diff --git a/arch/cris/include/arch-v32/arch/irqflags.h b/arch/cris/include/arch-v32/arch/irqflags.h
new file mode 100644
index 000000000000..041851f8ec6f
--- /dev/null
+++ b/arch/cris/include/arch-v32/arch/irqflags.h
@@ -0,0 +1,46 @@
+#ifndef __ASM_CRIS_ARCH_IRQFLAGS_H
+#define __ASM_CRIS_ARCH_IRQFLAGS_H
+
+#include <linux/types.h>
+#include <arch/ptrace.h>
+
+static inline unsigned long arch_local_save_flags(void)
+{
+ unsigned long flags;
+ asm volatile("move $ccs,%0" : "=rm" (flags) : : "memory");
+ return flags;
+}
+
+static inline void arch_local_irq_disable(void)
+{
+ asm volatile("di" : : : "memory");
+}
+
+static inline void arch_local_irq_enable(void)
+{
+ asm volatile("ei" : : : "memory");
+}
+
+static inline unsigned long arch_local_irq_save(void)
+{
+ unsigned long flags = arch_local_save_flags();
+ arch_local_irq_disable();
+ return flags;
+}
+
+static inline void arch_local_irq_restore(unsigned long flags)
+{
+ asm volatile("move %0,$ccs" : : "rm" (flags) : "memory");
+}
+
+static inline bool arch_irqs_disabled_flags(unsigned long flags)
+{
+ return !(flags & (1 << I_CCS_BITNR));
+}
+
+static inline bool arch_irqs_disabled(void)
+{
+ return arch_irqs_disabled_flags(arch_local_save_flags());
+}
+
+#endif /* __ASM_CRIS_ARCH_IRQFLAGS_H */
diff --git a/arch/cris/include/arch-v32/arch/system.h b/arch/cris/include/arch-v32/arch/system.h
index 6ca90f1f110a..76cea99eaa60 100644
--- a/arch/cris/include/arch-v32/arch/system.h
+++ b/arch/cris/include/arch-v32/arch/system.h
@@ -44,26 +44,4 @@ static inline unsigned long rdsp(void)
struct __xchg_dummy { unsigned long a[100]; };
#define __xg(x) ((struct __xchg_dummy *)(x))
-/* Used for interrupt control. */
-#define local_save_flags(x) \
- __asm__ __volatile__ ("move $ccs, %0" : "=rm" (x) : : "memory");
-
-#define local_irq_restore(x) \
- __asm__ __volatile__ ("move %0, $ccs" : : "rm" (x) : "memory");
-
-#define local_irq_disable() __asm__ __volatile__ ("di" : : : "memory");
-#define local_irq_enable() __asm__ __volatile__ ("ei" : : : "memory");
-
-#define irqs_disabled() \
-({ \
- unsigned long flags; \
- \
- local_save_flags(flags);\
- !(flags & (1 << I_CCS_BITNR)); \
-})
-
-/* Used for spinlocks, etc. */
-#define local_irq_save(x) \
- __asm__ __volatile__ ("move $ccs, %0\n\tdi" : "=rm" (x) : : "memory");
-
#endif /* _ASM_CRIS_ARCH_SYSTEM_H */
diff --git a/arch/cris/include/asm/ioctls.h b/arch/cris/include/asm/ioctls.h
index c9129ed37443..488fbb3f5e84 100644
--- a/arch/cris/include/asm/ioctls.h
+++ b/arch/cris/include/asm/ioctls.h
@@ -1,93 +1,11 @@
#ifndef __ARCH_CRIS_IOCTLS_H__
#define __ARCH_CRIS_IOCTLS_H__
-/* verbatim copy of asm-i386/ioctls.h */
-
-#include <asm/ioctl.h>
-
-/* 0x54 is just a magic number to make these relatively unique ('T') */
-
-#define TCGETS 0x5401
-#define TCSETS 0x5402
-#define TCSETSW 0x5403
-#define TCSETSF 0x5404
-#define TCGETA 0x5405
-#define TCSETA 0x5406
-#define TCSETAW 0x5407
-#define TCSETAF 0x5408
-#define TCSBRK 0x5409
-#define TCXONC 0x540A
-#define TCFLSH 0x540B
-#define TIOCEXCL 0x540C
-#define TIOCNXCL 0x540D
-#define TIOCSCTTY 0x540E
-#define TIOCGPGRP 0x540F
-#define TIOCSPGRP 0x5410
-#define TIOCOUTQ 0x5411
-#define TIOCSTI 0x5412
-#define TIOCGWINSZ 0x5413
-#define TIOCSWINSZ 0x5414
-#define TIOCMGET 0x5415
-#define TIOCMBIS 0x5416
-#define TIOCMBIC 0x5417
-#define TIOCMSET 0x5418
-#define TIOCGSOFTCAR 0x5419
-#define TIOCSSOFTCAR 0x541A
-#define FIONREAD 0x541B
-#define TIOCINQ FIONREAD
-#define TIOCLINUX 0x541C
-#define TIOCCONS 0x541D
-#define TIOCGSERIAL 0x541E
-#define TIOCSSERIAL 0x541F
-#define TIOCPKT 0x5420
-#define FIONBIO 0x5421
-#define TIOCNOTTY 0x5422
-#define TIOCSETD 0x5423
-#define TIOCGETD 0x5424
-#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
-#define TIOCSBRK 0x5427 /* BSD compatibility */
-#define TIOCCBRK 0x5428 /* BSD compatibility */
-#define TIOCGSID 0x5429 /* Return the session ID of FD */
-#define TCGETS2 _IOR('T',0x2A, struct termios2)
-#define TCSETS2 _IOW('T',0x2B, struct termios2)
-#define TCSETSW2 _IOW('T',0x2C, struct termios2)
-#define TCSETSF2 _IOW('T',0x2D, struct termios2)
-#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
-#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
-#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */
-
-#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */
-#define FIOCLEX 0x5451
-#define FIOASYNC 0x5452
-#define TIOCSERCONFIG 0x5453
-#define TIOCSERGWILD 0x5454
-#define TIOCSERSWILD 0x5455
-#define TIOCGLCKTRMIOS 0x5456
-#define TIOCSLCKTRMIOS 0x5457
#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
-#define TIOCSERGETLSR 0x5459 /* Get line status register */
-#define TIOCSERGETMULTI 0x545A /* Get multiport config */
-#define TIOCSERSETMULTI 0x545B /* Set multiport config */
-
-#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
-#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
-#define FIOQSIZE 0x5460
-
#define TIOCSERSETRS485 0x5461 /* enable rs-485 (deprecated) */
#define TIOCSERWRRS485 0x5462 /* write rs-485 */
#define TIOCSRS485 0x5463 /* enable rs-485 */
-#define TIOCGRS485 0x542E /* get rs-485 */
-
-/* Used for packet mode */
-#define TIOCPKT_DATA 0
-#define TIOCPKT_FLUSHREAD 1
-#define TIOCPKT_FLUSHWRITE 2
-#define TIOCPKT_STOP 4
-#define TIOCPKT_START 8
-#define TIOCPKT_NOSTOP 16
-#define TIOCPKT_DOSTOP 32
-#define TIOCPKT_IOCTL 64
-#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
+#include <asm-generic/ioctls.h>
#endif
diff --git a/arch/cris/include/asm/irqflags.h b/arch/cris/include/asm/irqflags.h
new file mode 100644
index 000000000000..943ba5ca6d2c
--- /dev/null
+++ b/arch/cris/include/asm/irqflags.h
@@ -0,0 +1 @@
+#include <arch/irqflags.h>
diff --git a/arch/cris/include/asm/system.h b/arch/cris/include/asm/system.h
index 8657b084a922..ea10592f7d75 100644
--- a/arch/cris/include/asm/system.h
+++ b/arch/cris/include/asm/system.h
@@ -1,6 +1,7 @@
#ifndef __ASM_CRIS_SYSTEM_H
#define __ASM_CRIS_SYSTEM_H
+#include <linux/irqflags.h>
#include <arch/system.h>
/* the switch_to macro calls resume, an asm function in entry.S which does the actual
diff --git a/arch/cris/kernel/profile.c b/arch/cris/kernel/profile.c
index 195ec5fa0dd2..b82e08615d1b 100644
--- a/arch/cris/kernel/profile.c
+++ b/arch/cris/kernel/profile.c
@@ -59,6 +59,7 @@ write_cris_profile(struct file *file, const char __user *buf,
static const struct file_operations cris_proc_profile_operations = {
.read = read_cris_profile,
.write = write_cris_profile,
+ .llseek = default_llseek,
};
static int __init init_cris_profile(void)
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index 16399bd24993..0f2417df6323 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -7,6 +7,7 @@ config FRV
default y
select HAVE_IDE
select HAVE_ARCH_TRACEHOOK
+ select HAVE_IRQ_WORK
select HAVE_PERF_EVENTS
config ZONE_DMA
diff --git a/arch/frv/include/asm/ioctls.h b/arch/frv/include/asm/ioctls.h
index a993e3759ccf..2f9fb436ec3c 100644
--- a/arch/frv/include/asm/ioctls.h
+++ b/arch/frv/include/asm/ioctls.h
@@ -1,88 +1,10 @@
#ifndef __ASM_IOCTLS_H__
#define __ASM_IOCTLS_H__
-#include <asm/ioctl.h>
-
-/* 0x54 is just a magic number to make these relatively unique ('T') */
-
-#define TCGETS 0x5401
-#define TCSETS 0x5402
-#define TCSETSW 0x5403
-#define TCSETSF 0x5404
-#define TCGETA 0x5405
-#define TCSETA 0x5406
-#define TCSETAW 0x5407
-#define TCSETAF 0x5408
-#define TCSBRK 0x5409
-#define TCXONC 0x540A
-#define TCFLSH 0x540B
-#define TIOCEXCL 0x540C
-#define TIOCNXCL 0x540D
-#define TIOCSCTTY 0x540E
-#define TIOCGPGRP 0x540F
-#define TIOCSPGRP 0x5410
-#define TIOCOUTQ 0x5411
-#define TIOCSTI 0x5412
-#define TIOCGWINSZ 0x5413
-#define TIOCSWINSZ 0x5414
-#define TIOCMGET 0x5415
-#define TIOCMBIS 0x5416
-#define TIOCMBIC 0x5417
-#define TIOCMSET 0x5418
-#define TIOCGSOFTCAR 0x5419
-#define TIOCSSOFTCAR 0x541A
-#define FIONREAD 0x541B
-#define TIOCINQ FIONREAD
-#define TIOCLINUX 0x541C
-#define TIOCCONS 0x541D
-#define TIOCGSERIAL 0x541E
-#define TIOCSSERIAL 0x541F
-#define TIOCPKT 0x5420
-#define FIONBIO 0x5421
-#define TIOCNOTTY 0x5422
-#define TIOCSETD 0x5423
-#define TIOCGETD 0x5424
-#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */
-#define TIOCSBRK 0x5427 /* BSD compatibility */
-#define TIOCCBRK 0x5428 /* BSD compatibility */
-#define TIOCGSID 0x5429 /* Return the session ID of FD */
-#define TCGETS2 _IOR('T',0x2A, struct termios2)
-#define TCSETS2 _IOW('T',0x2B, struct termios2)
-#define TCSETSW2 _IOW('T',0x2C, struct termios2)
-#define TCSETSF2 _IOW('T',0x2D, struct termios2)
-#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
-#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
-#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */
-
-#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */
-#define FIOCLEX 0x5451
-#define FIOASYNC 0x5452
-#define TIOCSERCONFIG 0x5453
-#define TIOCSERGWILD 0x5454
-#define TIOCSERSWILD 0x5455
-#define TIOCGLCKTRMIOS 0x5456
-#define TIOCSLCKTRMIOS 0x5457
-#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
-#define TIOCSERGETLSR 0x5459 /* Get line status register */
-#define TIOCSERGETMULTI 0x545A /* Get multiport config */
-#define TIOCSERSETMULTI 0x545B /* Set multiport config */
-
-#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
-#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
#define FIOQSIZE 0x545E
-/* Used for packet mode */
-#define TIOCPKT_DATA 0
-#define TIOCPKT_FLUSHREAD 1
-#define TIOCPKT_FLUSHWRITE 2
-#define TIOCPKT_STOP 4
-#define TIOCPKT_START 8
-#define TIOCPKT_NOSTOP 16
-#define TIOCPKT_DOSTOP 32
-#define TIOCPKT_IOCTL 64
-
-#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
+#include <asm-generic/ioctls.h>
#endif /* __ASM_IOCTLS_H__ */
diff --git a/arch/frv/include/asm/irqflags.h b/arch/frv/include/asm/irqflags.h
new file mode 100644
index 000000000000..82f0b5363f42
--- /dev/null
+++ b/arch/frv/include/asm/irqflags.h
@@ -0,0 +1,158 @@
+/* FR-V interrupt handling
+ *
+ * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _ASM_IRQFLAGS_H
+#define _ASM_IRQFLAGS_H
+
+/*
+ * interrupt flag manipulation
+ * - use virtual interrupt management since touching the PSR is slow
+ * - ICC2.Z: T if interrupts virtually disabled
+ * - ICC2.C: F if interrupts really disabled
+ * - if Z==1 upon interrupt:
+ * - C is set to 0
+ * - interrupts are really disabled
+ * - entry.S returns immediately
+ * - uses TIHI (TRAP if Z==0 && C==0) #2 to really reenable interrupts
+ * - if taken, the trap:
+ * - sets ICC2.C
+ * - enables interrupts
+ */
+static inline void arch_local_irq_disable(void)
+{
+ /* set Z flag, but don't change the C flag */
+ asm volatile(" andcc gr0,gr0,gr0,icc2 \n"
+ :
+ :
+ : "memory", "icc2"
+ );
+}
+
+static inline void arch_local_irq_enable(void)
+{
+ /* clear Z flag and then test the C flag */
+ asm volatile(" oricc gr0,#1,gr0,icc2 \n"
+ " tihi icc2,gr0,#2 \n"
+ :
+ :
+ : "memory", "icc2"
+ );
+}
+
+static inline unsigned long arch_local_save_flags(void)
+{
+ unsigned long flags;
+
+ asm volatile("movsg ccr,%0"
+ : "=r"(flags)
+ :
+ : "memory");
+
+ /* shift ICC2.Z to bit 0 */
+ flags >>= 26;
+
+ /* make flags 1 if interrupts disabled, 0 otherwise */
+ return flags & 1UL;
+
+}
+
+static inline unsigned long arch_local_irq_save(void)
+{
+ unsigned long flags = arch_local_save_flags();
+ arch_local_irq_disable();
+ return flags;
+}
+
+static inline void arch_local_irq_restore(unsigned long flags)
+{
+ /* load the Z flag by turning 1 if disabled into 0 if disabled
+ * and thus setting the Z flag but not the C flag */
+ asm volatile(" xoricc %0,#1,gr0,icc2 \n"
+ /* then trap if Z=0 and C=0 */
+ " tihi icc2,gr0,#2 \n"
+ :
+ : "r"(flags)
+ : "memory", "icc2"
+ );
+
+}
+
+static inline bool arch_irqs_disabled_flags(unsigned long flags)
+{
+ return flags;
+}
+
+static inline bool arch_irqs_disabled(void)
+{
+ return arch_irqs_disabled_flags(arch_local_save_flags());
+}
+
+/*
+ * real interrupt flag manipulation
+ */
+#define __arch_local_irq_disable() \
+do { \
+ unsigned long psr; \
+ asm volatile(" movsg psr,%0 \n" \
+ " andi %0,%2,%0 \n" \
+ " ori %0,%1,%0 \n" \
+ " movgs %0,psr \n" \
+ : "=r"(psr) \
+ : "i" (PSR_PIL_14), "i" (~PSR_PIL) \
+ : "memory"); \
+} while (0)
+
+#define __arch_local_irq_enable() \
+do { \
+ unsigned long psr; \
+ asm volatile(" movsg psr,%0 \n" \
+ " andi %0,%1,%0 \n" \
+ " movgs %0,psr \n" \
+ : "=r"(psr) \
+ : "i" (~PSR_PIL) \
+ : "memory"); \
+} while (0)
+
+#define __arch_local_save_flags(flags) \
+do { \
+ typecheck(unsigned long, flags); \
+ asm("movsg psr,%0" \
+ : "=r"(flags) \
+ : \
+ : "memory"); \
+} while (0)
+
+#define __arch_local_irq_save(flags) \
+do { \
+ unsigned long npsr; \
+ typecheck(unsigned long, flags); \
+ asm volatile(" movsg psr,%0 \n" \
+ " andi %0,%3,%1 \n" \
+ " ori %1,%2,%1 \n" \
+ " movgs %1,psr \n" \
+ : "=r"(flags), "=r"(npsr) \
+ : "i" (PSR_PIL_14), "i" (~PSR_PIL) \
+ : "memory"); \
+} while (0)
+
+#define __arch_local_irq_restore(flags) \
+do { \
+ typecheck(unsigned long, flags); \
+ asm volatile(" movgs %0,psr \n" \
+ : \
+ : "r" (flags) \
+ : "memory"); \
+} while (0)
+
+#define __arch_irqs_disabled() \
+ ((__get_PSR() & PSR_PIL) >= PSR_PIL_14)
+
+#endif /* _ASM_IRQFLAGS_H */
diff --git a/arch/frv/include/asm/system.h b/arch/frv/include/asm/system.h
index efd22d9077ac..0a6d8d9ca45b 100644
--- a/arch/frv/include/asm/system.h
+++ b/arch/frv/include/asm/system.h
@@ -37,142 +37,6 @@ do { \
} while(0)
/*
- * interrupt flag manipulation
- * - use virtual interrupt management since touching the PSR is slow
- * - ICC2.Z: T if interrupts virtually disabled
- * - ICC2.C: F if interrupts really disabled
- * - if Z==1 upon interrupt:
- * - C is set to 0
- * - interrupts are really disabled
- * - entry.S returns immediately
- * - uses TIHI (TRAP if Z==0 && C==0) #2 to really reenable interrupts
- * - if taken, the trap:
- * - sets ICC2.C
- * - enables interrupts
- */
-#define local_irq_disable() \
-do { \
- /* set Z flag, but don't change the C flag */ \
- asm volatile(" andcc gr0,gr0,gr0,icc2 \n" \
- : \
- : \
- : "memory", "icc2" \
- ); \
-} while(0)
-
-#define local_irq_enable() \
-do { \
- /* clear Z flag and then test the C flag */ \
- asm volatile(" oricc gr0,#1,gr0,icc2 \n" \
- " tihi icc2,gr0,#2 \n" \
- : \
- : \
- : "memory", "icc2" \
- ); \
-} while(0)
-
-#define local_save_flags(flags) \
-do { \
- typecheck(unsigned long, flags); \
- asm volatile("movsg ccr,%0" \
- : "=r"(flags) \
- : \
- : "memory"); \
- \
- /* shift ICC2.Z to bit 0 */ \
- flags >>= 26; \
- \
- /* make flags 1 if interrupts disabled, 0 otherwise */ \
- flags &= 1UL; \
-} while(0)
-
-#define irqs_disabled() \
- ({unsigned long flags; local_save_flags(flags); !!flags; })
-
-#define local_irq_save(flags) \
-do { \
- typecheck(unsigned long, flags); \
- local_save_flags(flags); \
- local_irq_disable(); \
-} while(0)
-
-#define local_irq_restore(flags) \
-do { \
- typecheck(unsigned long, flags); \
- \
- /* load the Z flag by turning 1 if disabled into 0 if disabled \
- * and thus setting the Z flag but not the C flag */ \
- asm volatile(" xoricc %0,#1,gr0,icc2 \n" \
- /* then test Z=0 and C=0 */ \
- " tihi icc2,gr0,#2 \n" \
- : \
- : "r"(flags) \
- : "memory", "icc2" \
- ); \
- \
-} while(0)
-
-/*
- * real interrupt flag manipulation
- */
-#define __local_irq_disable() \
-do { \
- unsigned long psr; \
- asm volatile(" movsg psr,%0 \n" \
- " andi %0,%2,%0 \n" \
- " ori %0,%1,%0 \n" \
- " movgs %0,psr \n" \
- : "=r"(psr) \
- : "i" (PSR_PIL_14), "i" (~PSR_PIL) \
- : "memory"); \
-} while(0)
-
-#define __local_irq_enable() \
-do { \
- unsigned long psr; \
- asm volatile(" movsg psr,%0 \n" \
- " andi %0,%1,%0 \n" \
- " movgs %0,psr \n" \
- : "=r"(psr) \
- : "i" (~PSR_PIL) \
- : "memory"); \
-} while(0)
-
-#define __local_save_flags(flags) \
-do { \
- typecheck(unsigned long, flags); \
- asm("movsg psr,%0" \
- : "=r"(flags) \
- : \
- : "memory"); \
-} while(0)
-
-#define __local_irq_save(flags) \
-do { \
- unsigned long npsr; \
- typecheck(unsigned long, flags); \
- asm volatile(" movsg psr,%0 \n" \
- " andi %0,%3,%1 \n" \
- " ori %1,%2,%1 \n" \
- " movgs %1,psr \n" \
- : "=r"(flags), "=r"(npsr) \
- : "i" (PSR_PIL_14), "i" (~PSR_PIL) \
- : "memory"); \
-} while(0)
-
-#define __local_irq_restore(flags) \
-do { \
- typecheck(unsigned long, flags); \
- asm volatile(" movgs %0,psr \n" \
- : \
- : "r" (flags) \
- : "memory"); \
-} while(0)
-
-#define __irqs_disabled() \
- ((__get_PSR() & PSR_PIL) >= PSR_PIL_14)
-
-/*
* Force strict CPU ordering.
*/
#define nop() asm volatile ("nop"::)
diff --git a/arch/frv/lib/Makefile b/arch/frv/lib/Makefile
index f4709756d0d9..4ff2fb1e6b16 100644
--- a/arch/frv/lib/Makefile
+++ b/arch/frv/lib/Makefile
@@ -5,4 +5,4 @@
lib-y := \
__ashldi3.o __lshrdi3.o __muldi3.o __ashrdi3.o __negdi2.o __ucmpdi2.o \
checksum.o memcpy.o memset.o atomic-ops.o atomic64-ops.o \
- outsl_ns.o outsl_sw.o insl_ns.o insl_sw.o cache.o perf_event.o
+ outsl_ns.o outsl_sw.o insl_ns.o insl_sw.o cache.o
diff --git a/arch/frv/lib/perf_event.c b/arch/frv/lib/perf_event.c
deleted file mode 100644
index 9ac5acfd2e91..000000000000
--- a/arch/frv/lib/perf_event.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Performance event handling
- *
- * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-
-#include <linux/perf_event.h>
-
-/*
- * mark the performance event as pending
- */
-void set_perf_event_pending(void)
-{
-}
diff --git a/arch/h8300/Kconfig.cpu b/arch/h8300/Kconfig.cpu
index 6e2ecff199c5..d236ab4232ca 100644
--- a/arch/h8300/Kconfig.cpu
+++ b/arch/h8300/Kconfig.cpu
@@ -17,7 +17,7 @@ config H8300H_AKI3068NET
help
AKI-H8/3068F / AKI-H8/3069F Flashmicom LAN Board Support
More Information. (Japanese Only)
- <http://akizukidensi.com/catalog/h8.html>
+ <http://akizukidenshi.com/catalog/default.aspx>
AE-3068/69 Evaluation Board Support
More Information.
<http://www.microtronique.com/ae3069lan.htm>
@@ -36,7 +36,7 @@ config H8300H_SIM
help
GDB Simulator Support
More Information.
- arch/h8300/Doc/simulator.txt
+ <http://sourceware.org/sid/>
config H8S_GENERIC
bool "H8S Generic"
@@ -50,14 +50,14 @@ config H8S_EDOSK2674
Renesas EDOSK-2674 Evaluation Board Support
More Information.
<http://www.azpower.com/H8-uClinux/index.html>
- <http://www.eu.renesas.com/tools/edk/support/edosk2674.html>
+ <http://www.renesas.eu/products/tools/introductory_evaluation_tools/evaluation_development_os_kits/edosk2674r/edosk2674r_software_tools_root.jsp>
config H8S_SIM
bool "H8S Simulator"
help
GDB Simulator Support
More Information.
- arch/h8300/Doc/simulator.txt
+ <http://sourceware.org/sid/>
endchoice
diff --git a/arch/h8300/README b/arch/h8300/README
index 2fd6f6d7a019..637f5a02f311 100644
--- a/arch/h8300/README
+++ b/arch/h8300/README
@@ -18,6 +18,7 @@ H8/300H and H8S
4.EDOSK2674
see http://www.eu.renesas.com/products/mpumcu/tool/edk/support/edosk2674.html
+ http://www.uclinux.org/pub/uClinux/ports/h8/HITACHI-EDOSK2674-HOWTO
http://www.azpower.com/H8-uClinux/
* Toolchain Version
diff --git a/arch/h8300/include/asm/ioctls.h b/arch/h8300/include/asm/ioctls.h
index b6b249f9f308..30eaed2facdb 100644
--- a/arch/h8300/include/asm/ioctls.h
+++ b/arch/h8300/include/asm/ioctls.h
@@ -1,87 +1,8 @@
#ifndef __ARCH_H8300_IOCTLS_H__
#define __ARCH_H8300_IOCTLS_H__
-#include <asm/ioctl.h>
-
-/* 0x54 is just a magic number to make these relatively unique ('T') */
-
-#define TCGETS 0x5401
-#define TCSETS 0x5402
-#define TCSETSW 0x5403
-#define TCSETSF 0x5404
-#define TCGETA 0x5405
-#define TCSETA 0x5406
-#define TCSETAW 0x5407
-#define TCSETAF 0x5408
-#define TCSBRK 0x5409
-#define TCXONC 0x540A
-#define TCFLSH 0x540B
-#define TIOCEXCL 0x540C
-#define TIOCNXCL 0x540D
-#define TIOCSCTTY 0x540E
-#define TIOCGPGRP 0x540F
-#define TIOCSPGRP 0x5410
-#define TIOCOUTQ 0x5411
-#define TIOCSTI 0x5412
-#define TIOCGWINSZ 0x5413
-#define TIOCSWINSZ 0x5414
-#define TIOCMGET 0x5415
-#define TIOCMBIS 0x5416
-#define TIOCMBIC 0x5417
-#define TIOCMSET 0x5418
-#define TIOCGSOFTCAR 0x5419
-#define TIOCSSOFTCAR 0x541A
-#define FIONREAD 0x541B
-#define TIOCINQ FIONREAD
-#define TIOCLINUX 0x541C
-#define TIOCCONS 0x541D
-#define TIOCGSERIAL 0x541E
-#define TIOCSSERIAL 0x541F
-#define TIOCPKT 0x5420
-#define FIONBIO 0x5421
-#define TIOCNOTTY 0x5422
-#define TIOCSETD 0x5423
-#define TIOCGETD 0x5424
-#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
-#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */
-#define TIOCSBRK 0x5427 /* BSD compatibility */
-#define TIOCCBRK 0x5428 /* BSD compatibility */
-#define TIOCGSID 0x5429 /* Return the session ID of FD */
-#define TCGETS2 _IOR('T',0x2A, struct termios2)
-#define TCSETS2 _IOW('T',0x2B, struct termios2)
-#define TCSETSW2 _IOW('T',0x2C, struct termios2)
-#define TCSETSF2 _IOW('T',0x2D, struct termios2)
-#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
-#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
-#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */
-
-#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */
-#define FIOCLEX 0x5451
-#define FIOASYNC 0x5452
-#define TIOCSERCONFIG 0x5453
-#define TIOCSERGWILD 0x5454
-#define TIOCSERSWILD 0x5455
-#define TIOCGLCKTRMIOS 0x5456
-#define TIOCSLCKTRMIOS 0x5457
-#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
-#define TIOCSERGETLSR 0x5459 /* Get line status register */
-#define TIOCSERGETMULTI 0x545A /* Get multiport config */
-#define TIOCSERSETMULTI 0x545B /* Set multiport config */
-
-#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
-#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
#define FIOQSIZE 0x545E
-/* Used for packet mode */
-#define TIOCPKT_DATA 0
-#define TIOCPKT_FLUSHREAD 1
-#define TIOCPKT_FLUSHWRITE 2
-#define TIOCPKT_STOP 4
-#define TIOCPKT_START 8
-#define TIOCPKT_NOSTOP 16
-#define TIOCPKT_DOSTOP 32
-#define TIOCPKT_IOCTL 64
-
-#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
+#include <asm-generic/ioctls.h>
#endif /* __ARCH_H8300_IOCTLS_H__ */
diff --git a/arch/h8300/include/asm/irqflags.h b/arch/h8300/include/asm/irqflags.h
new file mode 100644
index 000000000000..9617cd57aebd
--- /dev/null
+++ b/arch/h8300/include/asm/irqflags.h
@@ -0,0 +1,43 @@
+#ifndef _H8300_IRQFLAGS_H
+#define _H8300_IRQFLAGS_H
+
+static inline unsigned long arch_local_save_flags(void)
+{
+ unsigned long flags;
+ asm volatile ("stc ccr,%w0" : "=r" (flags));
+ return flags;
+}
+
+static inline void arch_local_irq_disable(void)
+{
+ asm volatile ("orc #0x80,ccr" : : : "memory");
+}
+
+static inline void arch_local_irq_enable(void)
+{
+ asm volatile ("andc #0x7f,ccr" : : : "memory");
+}
+
+static inline unsigned long arch_local_irq_save(void)
+{
+ unsigned long flags = arch_local_save_flags();
+ arch_local_irq_disable();
+ return flags;
+}
+
+static inline void arch_local_irq_restore(unsigned long flags)
+{
+ asm volatile ("ldc %w0,ccr" : : "r" (flags) : "memory");
+}
+
+static inline bool arch_irqs_disabled_flags(unsigned long flags)
+{
+ return (flags & 0x80) == 0x80;
+}
+
+static inline bool arch_irqs_disabled(void)
+{
+ return arch_irqs_disabled_flags(arch_local_save_flags());
+}
+
+#endif /* _H8300_IRQFLAGS_H */
diff --git a/arch/h8300/include/asm/system.h b/arch/h8300/include/asm/system.h
index 16bf1560ff68..2c2382e50d93 100644
--- a/arch/h8300/include/asm/system.h
+++ b/arch/h8300/include/asm/system.h
@@ -2,6 +2,7 @@
#define _H8300_SYSTEM_H
#include <linux/linkage.h>
+#include <linux/irqflags.h>
struct pt_regs;
@@ -51,31 +52,8 @@ asmlinkage void resume(void);
(last) = _last; \
}
-#define __sti() asm volatile ("andc #0x7f,ccr")
-#define __cli() asm volatile ("orc #0x80,ccr")
-
-#define __save_flags(x) \
- asm volatile ("stc ccr,%w0":"=r" (x))
-
-#define __restore_flags(x) \
- asm volatile ("ldc %w0,ccr": :"r" (x))
-
-#define irqs_disabled() \
-({ \
- unsigned char flags; \
- __save_flags(flags); \
- ((flags & 0x80) == 0x80); \
-})
-
#define iret() __asm__ __volatile__ ("rte": : :"memory", "sp", "cc")
-/* For spinlocks etc */
-#define local_irq_disable() __cli()
-#define local_irq_enable() __sti()
-#define local_irq_save(x) ({ __save_flags(x); local_irq_disable(); })
-#define local_irq_restore(x) __restore_flags(x)
-#define local_save_flags(x) __save_flags(x)
-
/*
* Force strict CPU ordering.
* Not really required on H8...
diff --git a/arch/h8300/kernel/module.c b/arch/h8300/kernel/module.c
index 0865e291c20d..db4953dc4e1b 100644
--- a/arch/h8300/kernel/module.c
+++ b/arch/h8300/kernel/module.c
@@ -112,10 +112,9 @@ int module_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs,
struct module *me)
{
- return module_bug_finalize(hdr, sechdrs, me);
+ return 0;
}
void module_arch_cleanup(struct module *mod)
{
- module_bug_cleanup(mod);
}
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index ba22849ee3ec..7c82fa1fc911 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -53,6 +53,9 @@ config MMU
bool
default y
+config ARCH_DMA_ADDR_T_64BIT
+ def_bool y
+
config NEED_DMA_MAP_STATE
def_bool y
@@ -62,6 +65,9 @@ config NEED_SG_DMA_LENGTH
config SWIOTLB
bool
+config STACKTRACE_SUPPORT
+ def_bool y
+
config GENERIC_LOCKBREAK
def_bool n
@@ -683,8 +689,10 @@ source "lib/Kconfig"
# Use the generic interrupt handling code in kernel/irq/:
#
config GENERIC_HARDIRQS
- bool
- default y
+ def_bool y
+
+config GENERIC_HARDIRQS_NO__DO_IRQ
+ def_bool y
config GENERIC_IRQ_PROBE
bool
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c
index 1e8d71ad93ef..13633da0d3de 100644
--- a/arch/ia64/hp/sim/simserial.c
+++ b/arch/ia64/hp/sim/simserial.c
@@ -395,7 +395,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
{
if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
(cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
- (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
+ (cmd != TIOCMIWAIT)) {
if (tty->flags & (1 << TTY_IO_ERROR))
return -EIO;
}
@@ -433,16 +433,6 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
case TIOCMIWAIT:
printk(KERN_INFO "rs_ioctl: TIOCMIWAIT: called\n");
return 0;
- /*
- * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
- * Return: write counters to the user passed counter struct
- * NB: both 1->0 and 0->1 transitions are counted except for
- * RI where only 0->1 is counted.
- */
- case TIOCGICOUNT:
- printk(KERN_INFO "rs_ioctl: TIOCGICOUNT called\n");
- return 0;
-
case TIOCSERGWILD:
case TIOCSERSWILD:
/* "setserial -W" is called in Debian boot */
diff --git a/arch/ia64/include/asm/compat.h b/arch/ia64/include/asm/compat.h
deleted file mode 100644
index 9301a2821615..000000000000
--- a/arch/ia64/include/asm/compat.h
+++ /dev/null
@@ -1,208 +0,0 @@
-#ifndef _ASM_IA64_COMPAT_H
-#define _ASM_IA64_COMPAT_H
-/*
- * Architecture specific compatibility types
- */
-#include <linux/types.h>
-
-#define COMPAT_USER_HZ 100
-#define COMPAT_UTS_MACHINE "i686\0\0\0"
-
-typedef u32 compat_size_t;
-typedef s32 compat_ssize_t;
-typedef s32 compat_time_t;
-typedef s32 compat_clock_t;
-typedef s32 compat_key_t;
-typedef s32 compat_pid_t;
-typedef u16 __compat_uid_t;
-typedef u16 __compat_gid_t;
-typedef u32 __compat_uid32_t;
-typedef u32 __compat_gid32_t;
-typedef u16 compat_mode_t;
-typedef u32 compat_ino_t;
-typedef u16 compat_dev_t;
-typedef s32 compat_off_t;
-typedef s64 compat_loff_t;
-typedef u16 compat_nlink_t;
-typedef u16 compat_ipc_pid_t;
-typedef s32 compat_daddr_t;
-typedef u32 compat_caddr_t;
-typedef __kernel_fsid_t compat_fsid_t;
-typedef s32 compat_timer_t;
-
-typedef s32 compat_int_t;
-typedef s32 compat_long_t;
-typedef s64 __attribute__((aligned(4))) compat_s64;
-typedef u32 compat_uint_t;
-typedef u32 compat_ulong_t;
-typedef u64 __attribute__((aligned(4))) compat_u64;
-
-struct compat_timespec {
- compat_time_t tv_sec;
- s32 tv_nsec;
-};
-
-struct compat_timeval {
- compat_time_t tv_sec;
- s32 tv_usec;
-};
-
-struct compat_stat {
- compat_dev_t st_dev;
- u16 __pad1;
- compat_ino_t st_ino;
- compat_mode_t st_mode;
- compat_nlink_t st_nlink;
- __compat_uid_t st_uid;
- __compat_gid_t st_gid;
- compat_dev_t st_rdev;
- u16 __pad2;
- u32 st_size;
- u32 st_blksize;
- u32 st_blocks;
- u32 st_atime;
- u32 st_atime_nsec;
- u32 st_mtime;
- u32 st_mtime_nsec;
- u32 st_ctime;
- u32 st_ctime_nsec;
- u32 __unused4;
- u32 __unused5;
-};
-
-struct compat_flock {
- short l_type;
- short l_whence;
- compat_off_t l_start;
- compat_off_t l_len;
- compat_pid_t l_pid;
-};
-
-#define F_GETLK64 12
-#define F_SETLK64 13
-#define F_SETLKW64 14
-
-/*
- * IA32 uses 4 byte alignment for 64 bit quantities,
- * so we need to pack this structure.
- */
-struct compat_flock64 {
- short l_type;
- short l_whence;
- compat_loff_t l_start;
- compat_loff_t l_len;
- compat_pid_t l_pid;
-} __attribute__((packed));
-
-struct compat_statfs {
- int f_type;
- int f_bsize;
- int f_blocks;
- int f_bfree;
- int f_bavail;
- int f_files;
- int f_ffree;
- compat_fsid_t f_fsid;
- int f_namelen; /* SunOS ignores this field. */
- int f_frsize;
- int f_spare[5];
-};
-
-#define COMPAT_RLIM_OLD_INFINITY 0x7fffffff
-#define COMPAT_RLIM_INFINITY 0xffffffff
-
-typedef u32 compat_old_sigset_t; /* at least 32 bits */
-
-#define _COMPAT_NSIG 64
-#define _COMPAT_NSIG_BPW 32
-
-typedef u32 compat_sigset_word;
-
-#define COMPAT_OFF_T_MAX 0x7fffffff
-#define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL
-
-struct compat_ipc64_perm {
- compat_key_t key;
- __compat_uid32_t uid;
- __compat_gid32_t gid;
- __compat_uid32_t cuid;
- __compat_gid32_t cgid;
- unsigned short mode;
- unsigned short __pad1;
- unsigned short seq;
- unsigned short __pad2;
- compat_ulong_t unused1;
- compat_ulong_t unused2;
-};
-
-struct compat_semid64_ds {
- struct compat_ipc64_perm sem_perm;
- compat_time_t sem_otime;
- compat_ulong_t __unused1;
- compat_time_t sem_ctime;
- compat_ulong_t __unused2;
- compat_ulong_t sem_nsems;
- compat_ulong_t __unused3;
- compat_ulong_t __unused4;
-};
-
-struct compat_msqid64_ds {
- struct compat_ipc64_perm msg_perm;
- compat_time_t msg_stime;
- compat_ulong_t __unused1;
- compat_time_t msg_rtime;
- compat_ulong_t __unused2;
- compat_time_t msg_ctime;
- compat_ulong_t __unused3;
- compat_ulong_t msg_cbytes;
- compat_ulong_t msg_qnum;
- compat_ulong_t msg_qbytes;
- compat_pid_t msg_lspid;
- compat_pid_t msg_lrpid;
- compat_ulong_t __unused4;
- compat_ulong_t __unused5;
-};
-
-struct compat_shmid64_ds {
- struct compat_ipc64_perm shm_perm;
- compat_size_t shm_segsz;
- compat_time_t shm_atime;
- compat_ulong_t __unused1;
- compat_time_t shm_dtime;
- compat_ulong_t __unused2;
- compat_time_t shm_ctime;
- compat_ulong_t __unused3;
- compat_pid_t shm_cpid;
- compat_pid_t shm_lpid;
- compat_ulong_t shm_nattch;
- compat_ulong_t __unused4;
- compat_ulong_t __unused5;
-};
-
-/*
- * A pointer passed in from user mode. This should not be used for syscall parameters,
- * just declare them as pointers because the syscall entry code will have appropriately
- * converted them already.
- */
-typedef u32 compat_uptr_t;
-
-static inline void __user *
-compat_ptr (compat_uptr_t uptr)
-{
- return (void __user *) (unsigned long) uptr;
-}
-
-static inline compat_uptr_t
-ptr_to_compat(void __user *uptr)
-{
- return (u32)(unsigned long)uptr;
-}
-
-static __inline__ void __user *
-arch_compat_alloc_user_space (long len)
-{
- struct pt_regs *regs = task_pt_regs(current);
- return (void __user *) (((regs->r12 & 0xffffffff) & -16) - len);
-}
-
-#endif /* _ASM_IA64_COMPAT_H */
diff --git a/arch/ia64/include/asm/hardirq.h b/arch/ia64/include/asm/hardirq.h
index d514cd9edb49..8fb7d33a661f 100644
--- a/arch/ia64/include/asm/hardirq.h
+++ b/arch/ia64/include/asm/hardirq.h
@@ -6,12 +6,6 @@
* David Mosberger-Tang <davidm@hpl.hp.com>
*/
-
-#include <linux/threads.h>
-#include <linux/irq.h>
-
-#include <asm/processor.h>
-
/*
* No irq_cpustat_t for IA-64. The data is held in the per-CPU data structure.
*/
@@ -20,6 +14,11 @@
#define local_softirq_pending() (local_cpu_data->softirq_pending)
+#include <linux/threads.h>
+#include <linux/irq.h>
+
+#include <asm/processor.h>
+
extern void __iomem *ipi_base_addr;
void ack_bad_irq(unsigned int irq);
diff --git a/arch/ia64/include/asm/ioctls.h b/arch/ia64/include/asm/ioctls.h
index b79c385114ef..f3aab5512e98 100644
--- a/arch/ia64/include/asm/ioctls.h
+++ b/arch/ia64/include/asm/ioctls.h
@@ -1,93 +1,6 @@
#ifndef _ASM_IA64_IOCTLS_H
#define _ASM_IA64_IOCTLS_H
-/*
- * Based on <asm-i386/ioctls.h>
- *
- * Modified 1998, 1999, 2002
- * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
- */
-
-#include <asm/ioctl.h>
-
-/* 0x54 is just a magic number to make these relatively unique ('T') */
-
-#define TCGETS 0x5401
-#define TCSETS 0x5402 /* Clashes with SNDCTL_TMR_START sound ioctl */
-#define TCSETSW 0x5403
-#define TCSETSF 0x5404
-#define TCGETA 0x5405
-#define TCSETA 0x5406
-#define TCSETAW 0x5407
-#define TCSETAF 0x5408
-#define TCSBRK 0x5409
-#define TCXONC 0x540A
-#define TCFLSH 0x540B
-#define TIOCEXCL 0x540C
-#define TIOCNXCL 0x540D
-#define TIOCSCTTY 0x540E
-#define TIOCGPGRP 0x540F
-#define TIOCSPGRP 0x5410
-#define TIOCOUTQ 0x5411
-#define TIOCSTI 0x5412
-#define TIOCGWINSZ 0x5413
-#define TIOCSWINSZ 0x5414
-#define TIOCMGET 0x5415
-#define TIOCMBIS 0x5416
-#define TIOCMBIC 0x5417
-#define TIOCMSET 0x5418
-#define TIOCGSOFTCAR 0x5419
-#define TIOCSSOFTCAR 0x541A
-#define FIONREAD 0x541B
-#define TIOCINQ FIONREAD
-#define TIOCLINUX 0x541C
-#define TIOCCONS 0x541D
-#define TIOCGSERIAL 0x541E
-#define TIOCSSERIAL 0x541F
-#define TIOCPKT 0x5420
-#define FIONBIO 0x5421
-#define TIOCNOTTY 0x5422
-#define TIOCSETD 0x5423
-#define TIOCGETD 0x5424
-#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
-#define TIOCSBRK 0x5427 /* BSD compatibility */
-#define TIOCCBRK 0x5428 /* BSD compatibility */
-#define TIOCGSID 0x5429 /* Return the session ID of FD */
-#define TCGETS2 _IOR('T',0x2A, struct termios2)
-#define TCSETS2 _IOW('T',0x2B, struct termios2)
-#define TCSETSW2 _IOW('T',0x2C, struct termios2)
-#define TCSETSF2 _IOW('T',0x2D, struct termios2)
-#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
-#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
-#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */
-
-#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */
-#define FIOCLEX 0x5451
-#define FIOASYNC 0x5452
-#define TIOCSERCONFIG 0x5453
-#define TIOCSERGWILD 0x5454
-#define TIOCSERSWILD 0x5455
-#define TIOCGLCKTRMIOS 0x5456
-#define TIOCSLCKTRMIOS 0x5457
-#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
-#define TIOCSERGETLSR 0x5459 /* Get line status register */
-#define TIOCSERGETMULTI 0x545A /* Get multiport config */
-#define TIOCSERSETMULTI 0x545B /* Set multiport config */
-
-#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
-#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
-#define FIOQSIZE 0x5460
-
-/* Used for packet mode */
-#define TIOCPKT_DATA 0
-#define TIOCPKT_FLUSHREAD 1
-#define TIOCPKT_FLUSHWRITE 2
-#define TIOCPKT_STOP 4
-#define TIOCPKT_START 8
-#define TIOCPKT_NOSTOP 16
-#define TIOCPKT_DOSTOP 32
-#define TIOCPKT_IOCTL 64
-
-#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
+#include <asm-generic/ioctls.h>
#endif /* _ASM_IA64_IOCTLS_H */
diff --git a/arch/ia64/include/asm/iommu_table.h b/arch/ia64/include/asm/iommu_table.h
new file mode 100644
index 000000000000..92c8d36ae5ae
--- /dev/null
+++ b/arch/ia64/include/asm/iommu_table.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_IA64_IOMMU_TABLE_H
+#define _ASM_IA64_IOMMU_TABLE_H
+
+#define IOMMU_INIT_POST(_detect)
+
+#endif /* _ASM_IA64_IOMMU_TABLE_H */
diff --git a/arch/ia64/include/asm/irqflags.h b/arch/ia64/include/asm/irqflags.h
new file mode 100644
index 000000000000..f82d6be2ecd2
--- /dev/null
+++ b/arch/ia64/include/asm/irqflags.h
@@ -0,0 +1,94 @@
+/*
+ * IRQ flags defines.
+ *
+ * Copyright (C) 1998-2003 Hewlett-Packard Co
+ * David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
+ * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
+ */
+
+#ifndef _ASM_IA64_IRQFLAGS_H
+#define _ASM_IA64_IRQFLAGS_H
+
+#ifdef CONFIG_IA64_DEBUG_IRQ
+extern unsigned long last_cli_ip;
+static inline void arch_maybe_save_ip(unsigned long flags)
+{
+ if (flags & IA64_PSR_I)
+ last_cli_ip = ia64_getreg(_IA64_REG_IP);
+}
+#else
+#define arch_maybe_save_ip(flags) do {} while (0)
+#endif
+
+/*
+ * - clearing psr.i is implicitly serialized (visible by next insn)
+ * - setting psr.i requires data serialization
+ * - we need a stop-bit before reading PSR because we sometimes
+ * write a floating-point register right before reading the PSR
+ * and that writes to PSR.mfl
+ */
+
+static inline unsigned long arch_local_save_flags(void)
+{
+ ia64_stop();
+#ifdef CONFIG_PARAVIRT
+ return ia64_get_psr_i();
+#else
+ return ia64_getreg(_IA64_REG_PSR);
+#endif
+}
+
+static inline unsigned long arch_local_irq_save(void)
+{
+ unsigned long flags = arch_local_save_flags();
+
+ ia64_stop();
+ ia64_rsm(IA64_PSR_I);
+ arch_maybe_save_ip(flags);
+ return flags;
+}
+
+static inline void arch_local_irq_disable(void)
+{
+#ifdef CONFIG_IA64_DEBUG_IRQ
+ arch_local_irq_save();
+#else
+ ia64_stop();
+ ia64_rsm(IA64_PSR_I);
+#endif
+}
+
+static inline void arch_local_irq_enable(void)
+{
+ ia64_stop();
+ ia64_ssm(IA64_PSR_I);
+ ia64_srlz_d();
+}
+
+static inline void arch_local_irq_restore(unsigned long flags)
+{
+#ifdef CONFIG_IA64_DEBUG_IRQ
+ unsigned long old_psr = arch_local_save_flags();
+#endif
+ ia64_intrin_local_irq_restore(flags & IA64_PSR_I);
+ arch_maybe_save_ip(old_psr & ~flags);
+}
+
+static inline bool arch_irqs_disabled_flags(unsigned long flags)
+{
+ return (flags & IA64_PSR_I) == 0;
+}
+
+static inline bool arch_irqs_disabled(void)
+{
+ return arch_irqs_disabled_flags(arch_local_save_flags());
+}
+
+static inline void arch_safe_halt(void)
+{
+ ia64_pal_halt_light(); /* PAL_HALT_LIGHT */
+}
+
+
+#endif /* _ASM_IA64_IRQFLAGS_H */
diff --git a/arch/ia64/include/asm/system.h b/arch/ia64/include/asm/system.h
index 9f342a574ce8..6cca30705d50 100644
--- a/arch/ia64/include/asm/system.h
+++ b/arch/ia64/include/asm/system.h
@@ -107,87 +107,11 @@ extern struct ia64_boot_param {
*/
#define set_mb(var, value) do { (var) = (value); mb(); } while (0)
-#define safe_halt() ia64_pal_halt_light() /* PAL_HALT_LIGHT */
-
/*
* The group barrier in front of the rsm & ssm are necessary to ensure
* that none of the previous instructions in the same group are
* affected by the rsm/ssm.
*/
-/* For spinlocks etc */
-
-/*
- * - clearing psr.i is implicitly serialized (visible by next insn)
- * - setting psr.i requires data serialization
- * - we need a stop-bit before reading PSR because we sometimes
- * write a floating-point register right before reading the PSR
- * and that writes to PSR.mfl
- */
-#ifdef CONFIG_PARAVIRT
-#define __local_save_flags() ia64_get_psr_i()
-#else
-#define __local_save_flags() ia64_getreg(_IA64_REG_PSR)
-#endif
-
-#define __local_irq_save(x) \
-do { \
- ia64_stop(); \
- (x) = __local_save_flags(); \
- ia64_stop(); \
- ia64_rsm(IA64_PSR_I); \
-} while (0)
-
-#define __local_irq_disable() \
-do { \
- ia64_stop(); \
- ia64_rsm(IA64_PSR_I); \
-} while (0)
-
-#define __local_irq_restore(x) ia64_intrin_local_irq_restore((x) & IA64_PSR_I)
-
-#ifdef CONFIG_IA64_DEBUG_IRQ
-
- extern unsigned long last_cli_ip;
-
-# define __save_ip() last_cli_ip = ia64_getreg(_IA64_REG_IP)
-
-# define local_irq_save(x) \
-do { \
- unsigned long __psr; \
- \
- __local_irq_save(__psr); \
- if (__psr & IA64_PSR_I) \
- __save_ip(); \
- (x) = __psr; \
-} while (0)
-
-# define local_irq_disable() do { unsigned long __x; local_irq_save(__x); } while (0)
-
-# define local_irq_restore(x) \
-do { \
- unsigned long __old_psr, __psr = (x); \
- \
- local_save_flags(__old_psr); \
- __local_irq_restore(__psr); \
- if ((__old_psr & IA64_PSR_I) && !(__psr & IA64_PSR_I)) \
- __save_ip(); \
-} while (0)
-
-#else /* !CONFIG_IA64_DEBUG_IRQ */
-# define local_irq_save(x) __local_irq_save(x)
-# define local_irq_disable() __local_irq_disable()
-# define local_irq_restore(x) __local_irq_restore(x)
-#endif /* !CONFIG_IA64_DEBUG_IRQ */
-
-#define local_irq_enable() ({ ia64_stop(); ia64_ssm(IA64_PSR_I); ia64_srlz_d(); })
-#define local_save_flags(flags) ({ ia64_stop(); (flags) = __local_save_flags(); })
-
-#define irqs_disabled() \
-({ \
- unsigned long __ia64_id_flags; \
- local_save_flags(__ia64_id_flags); \
- (__ia64_id_flags & IA64_PSR_I) == 0; \
-})
#ifdef __KERNEL__
@@ -272,10 +196,6 @@ void cpu_idle_wait(void);
void default_idle(void);
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING
-extern void account_system_vtime(struct task_struct *);
-#endif
-
#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
index db10b1e378b0..395c2f216dd8 100644
--- a/arch/ia64/kernel/Makefile
+++ b/arch/ia64/kernel/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_AUDIT) += audit.o
obj-$(CONFIG_PCI_MSI) += msi_ia64.o
mca_recovery-y += mca_drv.o mca_drv_asm.o
obj-$(CONFIG_IA64_MC_ERR_INJECT)+= err_inject.o
+obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-$(CONFIG_PARAVIRT) += paravirt.o paravirtentry.o \
paravirt_patch.o
diff --git a/arch/ia64/kernel/cyclone.c b/arch/ia64/kernel/cyclone.c
index 71e35864d2e2..d52f1f78eff2 100644
--- a/arch/ia64/kernel/cyclone.c
+++ b/arch/ia64/kernel/cyclone.c
@@ -59,13 +59,13 @@ int __init init_cyclone_clock(void)
return -ENODEV;
}
base = readq(reg);
+ iounmap(reg);
if(!base){
printk(KERN_ERR "Summit chipset: Could not find valid CBAR"
" value.\n");
use_cyclone = 0;
return -ENODEV;
}
- iounmap(reg);
/* setup PMCC */
offset = (base + CYCLONE_PMCC_OFFSET);
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index 7ded76658d2d..22c38404f539 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -108,10 +108,6 @@
#define DBG(fmt...)
#endif
-#define NR_PREALLOCATE_RTE_ENTRIES \
- (PAGE_SIZE / sizeof(struct iosapic_rte_info))
-#define RTE_PREALLOCATED (1)
-
static DEFINE_SPINLOCK(iosapic_lock);
/*
@@ -136,7 +132,6 @@ struct iosapic_rte_info {
struct list_head rte_list; /* RTEs sharing the same vector */
char rte_index; /* IOSAPIC RTE index */
int refcnt; /* reference counter */
- unsigned int flags; /* flags */
struct iosapic *iosapic;
} ____cacheline_aligned;
@@ -155,9 +150,6 @@ static struct iosapic_intr_info {
static unsigned char pcat_compat __devinitdata; /* 8259 compatibility flag */
-static int iosapic_kmalloc_ok;
-static LIST_HEAD(free_rte_list);
-
static inline void
iosapic_write(struct iosapic *iosapic, unsigned int reg, u32 val)
{
@@ -394,7 +386,7 @@ iosapic_startup_level_irq (unsigned int irq)
}
static void
-iosapic_end_level_irq (unsigned int irq)
+iosapic_unmask_level_irq (unsigned int irq)
{
ia64_vector vec = irq_to_vector(irq);
struct iosapic_rte_info *rte;
@@ -404,7 +396,8 @@ iosapic_end_level_irq (unsigned int irq)
if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING)) {
do_unmask_irq = 1;
mask_irq(irq);
- }
+ } else
+ unmask_irq(irq);
list_for_each_entry(rte, &iosapic_intr_info[irq].rtes, rte_list)
iosapic_eoi(rte->iosapic->addr, vec);
@@ -427,9 +420,8 @@ static struct irq_chip irq_type_iosapic_level = {
.enable = iosapic_enable_level_irq,
.disable = iosapic_disable_level_irq,
.ack = iosapic_ack_level_irq,
- .end = iosapic_end_level_irq,
.mask = mask_irq,
- .unmask = unmask_irq,
+ .unmask = iosapic_unmask_level_irq,
.set_affinity = iosapic_set_affinity
};
@@ -552,37 +544,6 @@ iosapic_reassign_vector (int irq)
}
}
-static struct iosapic_rte_info * __init_refok iosapic_alloc_rte (void)
-{
- int i;
- struct iosapic_rte_info *rte;
- int preallocated = 0;
-
- if (!iosapic_kmalloc_ok && list_empty(&free_rte_list)) {
- rte = alloc_bootmem(sizeof(struct iosapic_rte_info) *
- NR_PREALLOCATE_RTE_ENTRIES);
- for (i = 0; i < NR_PREALLOCATE_RTE_ENTRIES; i++, rte++)
- list_add(&rte->rte_list, &free_rte_list);
- }
-
- if (!list_empty(&free_rte_list)) {
- rte = list_entry(free_rte_list.next, struct iosapic_rte_info,
- rte_list);
- list_del(&rte->rte_list);
- preallocated++;
- } else {
- rte = kmalloc(sizeof(struct iosapic_rte_info), GFP_ATOMIC);
- if (!rte)
- return NULL;
- }
-
- memset(rte, 0, sizeof(struct iosapic_rte_info));
- if (preallocated)
- rte->flags |= RTE_PREALLOCATED;
-
- return rte;
-}
-
static inline int irq_is_shared (int irq)
{
return (iosapic_intr_info[irq].count > 1);
@@ -615,7 +576,7 @@ register_intr (unsigned int gsi, int irq, unsigned char delivery,
rte = find_rte(irq, gsi);
if (!rte) {
- rte = iosapic_alloc_rte();
+ rte = kzalloc(sizeof (*rte), GFP_ATOMIC);
if (!rte) {
printk(KERN_WARNING "%s: cannot allocate memory\n",
__func__);
@@ -658,6 +619,10 @@ register_intr (unsigned int gsi, int irq, unsigned char delivery,
idesc->chip->name, irq_type->name);
idesc->chip = irq_type;
}
+ if (trigger == IOSAPIC_EDGE)
+ __set_irq_handler_unlocked(irq, handle_edge_irq);
+ else
+ __set_irq_handler_unlocked(irq, handle_level_irq);
return 0;
}
@@ -1161,10 +1126,3 @@ map_iosapic_to_node(unsigned int gsi_base, int node)
return;
}
#endif
-
-static int __init iosapic_enable_kmalloc (void)
-{
- iosapic_kmalloc_ok = 1;
- return 0;
-}
-core_initcall (iosapic_enable_kmalloc);
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
index f14c35f9b03a..9a26015c3e50 100644
--- a/arch/ia64/kernel/irq_ia64.c
+++ b/arch/ia64/kernel/irq_ia64.c
@@ -30,6 +30,7 @@
#include <linux/bitops.h>
#include <linux/irq.h>
#include <linux/ratelimit.h>
+#include <linux/acpi.h>
#include <asm/delay.h>
#include <asm/intrinsics.h>
@@ -635,6 +636,7 @@ ia64_native_register_percpu_irq (ia64_vector vec, struct irqaction *action)
desc->chip = &irq_type_ia64_lsapic;
if (action)
setup_irq(irq, action);
+ set_irq_handler(irq, handle_percpu_irq);
}
void __init
@@ -650,6 +652,9 @@ ia64_native_register_ipi(void)
void __init
init_IRQ (void)
{
+#ifdef CONFIG_ACPI
+ acpi_boot_init();
+#endif
ia64_register_ipi();
register_percpu_irq(IA64_SPURIOUS_INT_VECTOR, NULL);
#ifdef CONFIG_SMP
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index a0220dc5ff42..1753f6a30d55 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -2055,25 +2055,6 @@ ia64_mca_init(void)
IA64_MCA_DEBUG("%s: registered OS INIT handler with SAL\n", __func__);
- /*
- * Configure the CMCI/P vector and handler. Interrupts for CMC are
- * per-processor, so AP CMC interrupts are setup in smp_callin() (smpboot.c).
- */
- register_percpu_irq(IA64_CMC_VECTOR, &cmci_irqaction);
- register_percpu_irq(IA64_CMCP_VECTOR, &cmcp_irqaction);
- ia64_mca_cmc_vector_setup(); /* Setup vector on BSP */
-
- /* Setup the MCA rendezvous interrupt vector */
- register_percpu_irq(IA64_MCA_RENDEZ_VECTOR, &mca_rdzv_irqaction);
-
- /* Setup the MCA wakeup interrupt vector */
- register_percpu_irq(IA64_MCA_WAKEUP_VECTOR, &mca_wkup_irqaction);
-
-#ifdef CONFIG_ACPI
- /* Setup the CPEI/P handler */
- register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction);
-#endif
-
/* Initialize the areas set aside by the OS to buffer the
* platform/processor error states for MCA/INIT/CMC
* handling.
@@ -2103,6 +2084,25 @@ ia64_mca_late_init(void)
if (!mca_init)
return 0;
+ /*
+ * Configure the CMCI/P vector and handler. Interrupts for CMC are
+ * per-processor, so AP CMC interrupts are setup in smp_callin() (smpboot.c).
+ */
+ register_percpu_irq(IA64_CMC_VECTOR, &cmci_irqaction);
+ register_percpu_irq(IA64_CMCP_VECTOR, &cmcp_irqaction);
+ ia64_mca_cmc_vector_setup(); /* Setup vector on BSP */
+
+ /* Setup the MCA rendezvous interrupt vector */
+ register_percpu_irq(IA64_MCA_RENDEZ_VECTOR, &mca_rdzv_irqaction);
+
+ /* Setup the MCA wakeup interrupt vector */
+ register_percpu_irq(IA64_MCA_WAKEUP_VECTOR, &mca_wkup_irqaction);
+
+#ifdef CONFIG_ACPI
+ /* Setup the CPEI/P handler */
+ register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction);
+#endif
+
register_hotcpu_notifier(&mca_cpu_notifier);
/* Setup the CMCI/P vector and handler */
diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c
index 4a746ea838ff..00b19a416eab 100644
--- a/arch/ia64/kernel/msi_ia64.c
+++ b/arch/ia64/kernel/msi_ia64.c
@@ -104,8 +104,8 @@ static int ia64_msi_retrigger_irq(unsigned int irq)
*/
static struct irq_chip ia64_msi_chip = {
.name = "PCI-MSI",
- .mask = mask_msi_irq,
- .unmask = unmask_msi_irq,
+ .irq_mask = mask_msi_irq,
+ .irq_unmask = unmask_msi_irq,
.ack = ia64_ack_msi_irq,
#ifdef CONFIG_SMP
.set_affinity = ia64_set_msi_irq_affinity,
@@ -160,8 +160,8 @@ static int dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
static struct irq_chip dmar_msi_type = {
.name = "DMAR_MSI",
- .unmask = dmar_msi_unmask,
- .mask = dmar_msi_mask,
+ .irq_unmask = dmar_msi_unmask,
+ .irq_mask = dmar_msi_mask,
.ack = ia64_ack_msi_irq,
#ifdef CONFIG_SMP
.set_affinity = dmar_msi_set_affinity,
diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c
index fdf6f9d013e5..77597e5ea60a 100644
--- a/arch/ia64/kernel/palinfo.c
+++ b/arch/ia64/kernel/palinfo.c
@@ -434,7 +434,7 @@ register_info(char *page)
unsigned long phys_stacked;
pal_hints_u_t hints;
unsigned long iregs, dregs;
- char *info_type[]={
+ static const char * const info_type[] = {
"Implemented AR(s)",
"AR(s) with read side-effects",
"Implemented CR(s)",
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index cce050e85c73..6b1852f7f972 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -1573,7 +1573,7 @@ pfm_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
return -EINVAL;
}
- ctx = (pfm_context_t *)filp->private_data;
+ ctx = filp->private_data;
if (ctx == NULL) {
printk(KERN_ERR "perfmon: pfm_read: NULL ctx [%d]\n", task_pid_nr(current));
return -EINVAL;
@@ -1673,7 +1673,7 @@ pfm_poll(struct file *filp, poll_table * wait)
return 0;
}
- ctx = (pfm_context_t *)filp->private_data;
+ ctx = filp->private_data;
if (ctx == NULL) {
printk(KERN_ERR "perfmon: pfm_poll: NULL ctx [%d]\n", task_pid_nr(current));
return 0;
@@ -1733,7 +1733,7 @@ pfm_fasync(int fd, struct file *filp, int on)
return -EBADF;
}
- ctx = (pfm_context_t *)filp->private_data;
+ ctx = filp->private_data;
if (ctx == NULL) {
printk(KERN_ERR "perfmon: pfm_fasync NULL ctx [%d]\n", task_pid_nr(current));
return -EBADF;
@@ -1841,7 +1841,7 @@ pfm_flush(struct file *filp, fl_owner_t id)
return -EBADF;
}
- ctx = (pfm_context_t *)filp->private_data;
+ ctx = filp->private_data;
if (ctx == NULL) {
printk(KERN_ERR "perfmon: pfm_flush: NULL ctx [%d]\n", task_pid_nr(current));
return -EBADF;
@@ -1984,7 +1984,7 @@ pfm_close(struct inode *inode, struct file *filp)
return -EBADF;
}
- ctx = (pfm_context_t *)filp->private_data;
+ ctx = filp->private_data;
if (ctx == NULL) {
printk(KERN_ERR "perfmon: pfm_close: NULL ctx [%d]\n", task_pid_nr(current));
return -EBADF;
@@ -4907,7 +4907,7 @@ restart_args:
goto error_args;
}
- ctx = (pfm_context_t *)file->private_data;
+ ctx = file->private_data;
if (unlikely(ctx == NULL)) {
DPRINT(("no context for fd %d\n", fd));
goto error_args;
diff --git a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c
index aa8b5fa1a8de..79802e540e53 100644
--- a/arch/ia64/kernel/salinfo.c
+++ b/arch/ia64/kernel/salinfo.c
@@ -354,6 +354,7 @@ retry:
static const struct file_operations salinfo_event_fops = {
.open = salinfo_event_open,
.read = salinfo_event_read,
+ .llseek = noop_llseek,
};
static int
@@ -571,6 +572,7 @@ static const struct file_operations salinfo_data_fops = {
.release = salinfo_log_release,
.read = salinfo_log_read,
.write = salinfo_log_write,
+ .llseek = default_llseek,
};
static int __cpuinit
@@ -642,7 +644,7 @@ salinfo_init(void)
for (i = 0; i < ARRAY_SIZE(salinfo_log_name); i++) {
data = salinfo_data + i;
data->type = i;
- init_MUTEX(&data->mutex);
+ sema_init(&data->mutex, 1);
dir = proc_mkdir(salinfo_log_name[i], salinfo_dir);
if (!dir)
continue;
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 8fb958abf8d0..911cf9749700 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -594,10 +594,6 @@ setup_arch (char **cmdline_p)
cpu_init(); /* initialize the bootstrap CPU */
mmu_context_init(); /* initialize context_id bitmap */
-#ifdef CONFIG_ACPI
- acpi_boot_init();
-#endif
-
paravirt_banner();
paravirt_arch_setup_console(cmdline_p);
diff --git a/arch/ia64/kernel/stacktrace.c b/arch/ia64/kernel/stacktrace.c
new file mode 100644
index 000000000000..5af2783a87f4
--- /dev/null
+++ b/arch/ia64/kernel/stacktrace.c
@@ -0,0 +1,39 @@
+/*
+ * arch/ia64/kernel/stacktrace.c
+ *
+ * Stack trace management functions
+ *
+ */
+#include <linux/sched.h>
+#include <linux/stacktrace.h>
+#include <linux/module.h>
+
+static void
+ia64_do_save_stack(struct unw_frame_info *info, void *arg)
+{
+ struct stack_trace *trace = arg;
+ unsigned long ip;
+ int skip = trace->skip;
+
+ trace->nr_entries = 0;
+ do {
+ unw_get_ip(info, &ip);
+ if (ip == 0)
+ break;
+ if (skip == 0) {
+ trace->entries[trace->nr_entries++] = ip;
+ if (trace->nr_entries == trace->max_entries)
+ break;
+ } else
+ skip--;
+ } while (unw_unwind(info) >= 0);
+}
+
+/*
+ * Save stack-backtrace addresses into a stack_trace buffer.
+ */
+void save_stack_trace(struct stack_trace *trace)
+{
+ unw_init_running(ia64_do_save_stack, trace);
+}
+EXPORT_SYMBOL(save_stack_trace);
diff --git a/arch/ia64/kernel/unwind.c b/arch/ia64/kernel/unwind.c
index b6c0e63a0bf6..fed6afa2e8a9 100644
--- a/arch/ia64/kernel/unwind.c
+++ b/arch/ia64/kernel/unwind.c
@@ -1204,10 +1204,10 @@ desc_spill_sprel_p (unsigned char qp, unw_word t, unsigned char abreg, unw_word
static inline unw_hash_index_t
hash (unsigned long ip)
{
-# define hashmagic 0x9e3779b97f4a7c16UL /* based on (sqrt(5)/2-1)*2^64 */
+ /* magic number = ((sqrt(5)-1)/2)*2^64 */
+ static const unsigned long hashmagic = 0x9e3779b97f4a7c16UL;
- return (ip >> 4)*hashmagic >> (64 - UNW_LOG_HASH_SIZE);
-#undef hashmagic
+ return (ip >> 4) * hashmagic >> (64 - UNW_LOG_HASH_SIZE);
}
static inline long
@@ -1531,7 +1531,7 @@ build_script (struct unw_frame_info *info)
struct unw_labeled_state *ls, *next;
unsigned long ip = info->ip;
struct unw_state_record sr;
- struct unw_table *table;
+ struct unw_table *table, *prev;
struct unw_reg_info *r;
struct unw_insn insn;
u8 *dp, *desc_end;
@@ -1560,11 +1560,26 @@ build_script (struct unw_frame_info *info)
STAT(parse_start = ia64_get_itc());
+ prev = NULL;
for (table = unw.tables; table; table = table->next) {
if (ip >= table->start && ip < table->end) {
+ /*
+ * Leave the kernel unwind table at the very front,
+ * lest moving it breaks some assumption elsewhere.
+ * Otherwise, move the matching table to the second
+ * position in the list so that traversals can benefit
+ * from commonality in backtrace paths.
+ */
+ if (prev && prev != unw.tables) {
+ /* unw is safe - we're already spinlocked */
+ prev->next = table->next;
+ table->next = unw.tables->next;
+ unw.tables->next = table;
+ }
e = lookup(table, ip - table->segment_base);
break;
}
+ prev = table;
}
if (!e) {
/* no info, return default unwinder (leaf proc, no mem stack, no saved regs) */
diff --git a/arch/ia64/kvm/lapic.h b/arch/ia64/kvm/lapic.h
index ee541cebcd78..c5f92a926a9a 100644
--- a/arch/ia64/kvm/lapic.h
+++ b/arch/ia64/kvm/lapic.h
@@ -25,5 +25,6 @@ int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source,
int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2);
int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq);
#define kvm_apic_present(x) (true)
+#define kvm_lapic_enabled(x) (true)
#endif
diff --git a/arch/ia64/sn/kernel/msi_sn.c b/arch/ia64/sn/kernel/msi_sn.c
index 0c72dd463831..a5e500f02853 100644
--- a/arch/ia64/sn/kernel/msi_sn.c
+++ b/arch/ia64/sn/kernel/msi_sn.c
@@ -228,8 +228,8 @@ static int sn_msi_retrigger_irq(unsigned int irq)
static struct irq_chip sn_msi_chip = {
.name = "PCI-MSI",
- .mask = mask_msi_irq,
- .unmask = unmask_msi_irq,
+ .irq_mask = mask_msi_irq,
+ .irq_unmask = unmask_msi_irq,
.ack = sn_ack_msi_irq,
#ifdef CONFIG_SMP
.set_affinity = sn_set_msi_irq_affinity,
diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
index fa1eceed0d23..30862c0358cd 100644
--- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c
+++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
@@ -860,6 +860,7 @@ error:
static const struct file_operations sn_hwperf_fops = {
.unlocked_ioctl = sn_hwperf_ioctl,
+ .llseek = noop_llseek,
};
static struct miscdevice sn_hwperf_dev = {
diff --git a/arch/ia64/xen/xen_pv_ops.c b/arch/ia64/xen/xen_pv_ops.c
index 8adc6a14272a..3e8d350fdf39 100644
--- a/arch/ia64/xen/xen_pv_ops.c
+++ b/arch/ia64/xen/xen_pv_ops.c
@@ -1136,7 +1136,6 @@ __initconst = {
static void __init
xen_patch_branch(unsigned long tag, unsigned long type)
{
- const unsigned long nelem =
- sizeof(xen_branch_target) / sizeof(xen_branch_target[0]);
- __paravirt_patch_apply_branch(tag, type, xen_branch_target, nelem);
+ __paravirt_patch_apply_branch(tag, type, xen_branch_target,
+ ARRAY_SIZE(xen_branch_target));
}
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig
index 836abbbc9c04..3867fd21f333 100644
--- a/arch/m32r/Kconfig
+++ b/arch/m32r/Kconfig
@@ -315,7 +315,7 @@ config SMP
Management" code will be disabled if you say Y here.
See also the SMP-HOWTO available at
- <http://www.linuxdoc.org/docs.html#howto>.
+ <http://tldp.org/HOWTO/SMP-HOWTO.html>.
If you don't know what to do here, say N.
diff --git a/arch/m32r/include/asm/elf.h b/arch/m32r/include/asm/elf.h
index 2f85412ef730..b8da7d0574d2 100644
--- a/arch/m32r/include/asm/elf.h
+++ b/arch/m32r/include/asm/elf.h
@@ -82,9 +82,9 @@ typedef elf_fpreg_t elf_fpregset_t;
* These are used to set parameters in the core dumps.
*/
#define ELF_CLASS ELFCLASS32
-#if defined(__LITTLE_ENDIAN)
+#if defined(__LITTLE_ENDIAN__)
#define ELF_DATA ELFDATA2LSB
-#elif defined(__BIG_ENDIAN)
+#elif defined(__BIG_ENDIAN__)
#define ELF_DATA ELFDATA2MSB
#else
#error no endian defined
diff --git a/arch/m32r/include/asm/ioctls.h b/arch/m32r/include/asm/ioctls.h
index 66288063a4c0..349bf87bfbd0 100644
--- a/arch/m32r/include/asm/ioctls.h
+++ b/arch/m32r/include/asm/ioctls.h
@@ -1,87 +1,6 @@
#ifndef __ARCH_M32R_IOCTLS_H__
#define __ARCH_M32R_IOCTLS_H__
-#include <asm/ioctl.h>
-
-/* 0x54 is just a magic number to make these relatively unique ('T') */
-
-#define TCGETS 0x5401
-#define TCSETS 0x5402 /* Clashes with SNDCTL_TMR_START sound ioctl */
-#define TCSETSW 0x5403
-#define TCSETSF 0x5404
-#define TCGETA 0x5405
-#define TCSETA 0x5406
-#define TCSETAW 0x5407
-#define TCSETAF 0x5408
-#define TCSBRK 0x5409
-#define TCXONC 0x540A
-#define TCFLSH 0x540B
-#define TIOCEXCL 0x540C
-#define TIOCNXCL 0x540D
-#define TIOCSCTTY 0x540E
-#define TIOCGPGRP 0x540F
-#define TIOCSPGRP 0x5410
-#define TIOCOUTQ 0x5411
-#define TIOCSTI 0x5412
-#define TIOCGWINSZ 0x5413
-#define TIOCSWINSZ 0x5414
-#define TIOCMGET 0x5415
-#define TIOCMBIS 0x5416
-#define TIOCMBIC 0x5417
-#define TIOCMSET 0x5418
-#define TIOCGSOFTCAR 0x5419
-#define TIOCSSOFTCAR 0x541A
-#define FIONREAD 0x541B
-#define TIOCINQ FIONREAD
-#define TIOCLINUX 0x541C
-#define TIOCCONS 0x541D
-#define TIOCGSERIAL 0x541E
-#define TIOCSSERIAL 0x541F
-#define TIOCPKT 0x5420
-#define FIONBIO 0x5421
-#define TIOCNOTTY 0x5422
-#define TIOCSETD 0x5423
-#define TIOCGETD 0x5424
-#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
-/* #define TIOCTTYGSTRUCT 0x5426 - Former debugging-only ioctl */
-#define TIOCSBRK 0x5427 /* BSD compatibility */
-#define TIOCCBRK 0x5428 /* BSD compatibility */
-#define TIOCGSID 0x5429 /* Return the session ID of FD */
-#define TCGETS2 _IOR('T',0x2A, struct termios2)
-#define TCSETS2 _IOW('T',0x2B, struct termios2)
-#define TCSETSW2 _IOW('T',0x2C, struct termios2)
-#define TCSETSF2 _IOW('T',0x2D, struct termios2)
-#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
-#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
-#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */
-
-#define FIONCLEX 0x5450
-#define FIOCLEX 0x5451
-#define FIOASYNC 0x5452
-#define TIOCSERCONFIG 0x5453
-#define TIOCSERGWILD 0x5454
-#define TIOCSERSWILD 0x5455
-#define TIOCGLCKTRMIOS 0x5456
-#define TIOCSLCKTRMIOS 0x5457
-#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
-#define TIOCSERGETLSR 0x5459 /* Get line status register */
-#define TIOCSERGETMULTI 0x545A /* Get multiport config */
-#define TIOCSERSETMULTI 0x545B /* Set multiport config */
-
-#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
-#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
-#define FIOQSIZE 0x5460
-
-/* Used for packet mode */
-#define TIOCPKT_DATA 0
-#define TIOCPKT_FLUSHREAD 1
-#define TIOCPKT_FLUSHWRITE 2
-#define TIOCPKT_STOP 4
-#define TIOCPKT_START 8
-#define TIOCPKT_NOSTOP 16
-#define TIOCPKT_DOSTOP 32
-#define TIOCPKT_IOCTL 64
-
-#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
+#include <asm-generic/ioctls.h>
#endif /* __ARCH_M32R_IOCTLS_H__ */
diff --git a/arch/m32r/include/asm/irqflags.h b/arch/m32r/include/asm/irqflags.h
new file mode 100644
index 000000000000..1f92d29982ae
--- /dev/null
+++ b/arch/m32r/include/asm/irqflags.h
@@ -0,0 +1,104 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 Hiroyuki Kondo, Hirokazu Takata, and Hitoshi Yamamoto
+ * Copyright (C) 2004, 2006 Hirokazu Takata <takata at linux-m32r.org>
+ */
+
+#ifndef _ASM_M32R_IRQFLAGS_H
+#define _ASM_M32R_IRQFLAGS_H
+
+#include <linux/types.h>
+
+static inline unsigned long arch_local_save_flags(void)
+{
+ unsigned long flags;
+ asm volatile("mvfc %0,psw" : "=r"(flags));
+ return flags;
+}
+
+static inline void arch_local_irq_disable(void)
+{
+#if !defined(CONFIG_CHIP_M32102) && !defined(CONFIG_CHIP_M32104)
+ asm volatile (
+ "clrpsw #0x40 -> nop"
+ : : : "memory");
+#else
+ unsigned long tmpreg0, tmpreg1;
+ asm volatile (
+ "ld24 %0, #0 ; Use 32-bit insn. \n\t"
+ "mvfc %1, psw ; No interrupt can be accepted here. \n\t"
+ "mvtc %0, psw \n\t"
+ "and3 %0, %1, #0xffbf \n\t"
+ "mvtc %0, psw \n\t"
+ : "=&r" (tmpreg0), "=&r" (tmpreg1)
+ :
+ : "cbit", "memory");
+#endif
+}
+
+static inline void arch_local_irq_enable(void)
+{
+#if !defined(CONFIG_CHIP_M32102) && !defined(CONFIG_CHIP_M32104)
+ asm volatile (
+ "setpsw #0x40 -> nop"
+ : : : "memory");
+#else
+ unsigned long tmpreg;
+ asm volatile (
+ "mvfc %0, psw; \n\t"
+ "or3 %0, %0, #0x0040; \n\t"
+ "mvtc %0, psw; \n\t"
+ : "=&r" (tmpreg)
+ :
+ : "cbit", "memory");
+#endif
+}
+
+static inline unsigned long arch_local_irq_save(void)
+{
+ unsigned long flags;
+
+#if !(defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_M32104))
+ asm volatile (
+ "mvfc %0, psw; \n\t"
+ "clrpsw #0x40 -> nop; \n\t"
+ : "=r" (flags)
+ :
+ : "memory");
+#else
+ unsigned long tmpreg;
+ asm volatile (
+ "ld24 %1, #0 \n\t"
+ "mvfc %0, psw \n\t"
+ "mvtc %1, psw \n\t"
+ "and3 %1, %0, #0xffbf \n\t"
+ "mvtc %1, psw \n\t"
+ : "=r" (flags), "=&r" (tmpreg)
+ :
+ : "cbit", "memory");
+#endif
+ return flags;
+}
+
+static inline void arch_local_irq_restore(unsigned long flags)
+{
+ asm volatile("mvtc %0,psw"
+ :
+ : "r" (flags)
+ : "cbit", "memory");
+}
+
+static inline bool arch_irqs_disabled_flags(unsigned long flags)
+{
+ return !(flags & 0x40);
+}
+
+static inline bool arch_irqs_disabled(void)
+{
+ return arch_irqs_disabled_flags(arch_local_save_flags());
+}
+
+#endif /* _ASM_M32R_IRQFLAGS_H */
diff --git a/arch/m32r/include/asm/system.h b/arch/m32r/include/asm/system.h
index c980f5ba8de7..13c46794ccb1 100644
--- a/arch/m32r/include/asm/system.h
+++ b/arch/m32r/include/asm/system.h
@@ -11,6 +11,7 @@
*/
#include <linux/compiler.h>
+#include <linux/irqflags.h>
#include <asm/assembler.h>
#ifdef __KERNEL__
@@ -54,71 +55,6 @@
); \
} while(0)
-/* Interrupt Control */
-#if !defined(CONFIG_CHIP_M32102) && !defined(CONFIG_CHIP_M32104)
-#define local_irq_enable() \
- __asm__ __volatile__ ("setpsw #0x40 -> nop": : :"memory")
-#define local_irq_disable() \
- __asm__ __volatile__ ("clrpsw #0x40 -> nop": : :"memory")
-#else /* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
-static inline void local_irq_enable(void)
-{
- unsigned long tmpreg;
- __asm__ __volatile__(
- "mvfc %0, psw; \n\t"
- "or3 %0, %0, #0x0040; \n\t"
- "mvtc %0, psw; \n\t"
- : "=&r" (tmpreg) : : "cbit", "memory");
-}
-
-static inline void local_irq_disable(void)
-{
- unsigned long tmpreg0, tmpreg1;
- __asm__ __volatile__(
- "ld24 %0, #0 ; Use 32-bit insn. \n\t"
- "mvfc %1, psw ; No interrupt can be accepted here. \n\t"
- "mvtc %0, psw \n\t"
- "and3 %0, %1, #0xffbf \n\t"
- "mvtc %0, psw \n\t"
- : "=&r" (tmpreg0), "=&r" (tmpreg1) : : "cbit", "memory");
-}
-#endif /* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
-
-#define local_save_flags(x) \
- __asm__ __volatile__("mvfc %0,psw" : "=r"(x) : /* no input */)
-
-#define local_irq_restore(x) \
- __asm__ __volatile__("mvtc %0,psw" : /* no outputs */ \
- : "r" (x) : "cbit", "memory")
-
-#if !(defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_M32104))
-#define local_irq_save(x) \
- __asm__ __volatile__( \
- "mvfc %0, psw; \n\t" \
- "clrpsw #0x40 -> nop; \n\t" \
- : "=r" (x) : /* no input */ : "memory")
-#else /* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
-#define local_irq_save(x) \
- ({ \
- unsigned long tmpreg; \
- __asm__ __volatile__( \
- "ld24 %1, #0 \n\t" \
- "mvfc %0, psw \n\t" \
- "mvtc %1, psw \n\t" \
- "and3 %1, %0, #0xffbf \n\t" \
- "mvtc %1, psw \n\t" \
- : "=r" (x), "=&r" (tmpreg) \
- : : "cbit", "memory"); \
- })
-#endif /* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
-
-#define irqs_disabled() \
- ({ \
- unsigned long flags; \
- local_save_flags(flags); \
- !(flags & 0x40); \
- })
-
#define nop() __asm__ __volatile__ ("nop" : : )
#define xchg(ptr, x) \
diff --git a/arch/m32r/kernel/.gitignore b/arch/m32r/kernel/.gitignore
new file mode 100644
index 000000000000..c5f676c3c224
--- /dev/null
+++ b/arch/m32r/kernel/.gitignore
@@ -0,0 +1 @@
+vmlinux.lds
diff --git a/arch/m32r/kernel/irq.c b/arch/m32r/kernel/irq.c
index 3c71f776872c..7db26f1f082d 100644
--- a/arch/m32r/kernel/irq.c
+++ b/arch/m32r/kernel/irq.c
@@ -51,7 +51,7 @@ int show_interrupts(struct seq_file *p, void *v)
for_each_online_cpu(j)
seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
#endif
- seq_printf(p, " %14s", irq_desc[i].chip->typename);
+ seq_printf(p, " %14s", irq_desc[i].chip->name);
seq_printf(p, " %s", action->name);
for (action=action->next; action; action = action->next)
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c
index 7bbe38645ed5..a08697f0886d 100644
--- a/arch/m32r/kernel/signal.c
+++ b/arch/m32r/kernel/signal.c
@@ -28,6 +28,8 @@
#define DEBUG_SIG 0
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
asmlinkage int
sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
unsigned long r2, unsigned long r3, unsigned long r4,
@@ -254,7 +256,7 @@ give_sigsegv:
static int prev_insn(struct pt_regs *regs)
{
u16 inst;
- if (get_user(&inst, (u16 __user *)(regs->bpc - 2)))
+ if (get_user(inst, (u16 __user *)(regs->bpc - 2)))
return -EFAULT;
if ((inst & 0xfff0) == 0x10f0) /* trap ? */
regs->bpc -= 2;
diff --git a/arch/m32r/platforms/m32104ut/setup.c b/arch/m32r/platforms/m32104ut/setup.c
index 922fdfdadeaa..402a59d7219b 100644
--- a/arch/m32r/platforms/m32104ut/setup.c
+++ b/arch/m32r/platforms/m32104ut/setup.c
@@ -65,7 +65,7 @@ static void shutdown_m32104ut_irq(unsigned int irq)
static struct irq_chip m32104ut_irq_type =
{
- .typename = "M32104UT-IRQ",
+ .name = "M32104UT-IRQ",
.startup = startup_m32104ut_irq,
.shutdown = shutdown_m32104ut_irq,
.enable = enable_m32104ut_irq,
diff --git a/arch/m32r/platforms/m32700ut/setup.c b/arch/m32r/platforms/m32700ut/setup.c
index 9c1bc7487c1e..80b1a026795a 100644
--- a/arch/m32r/platforms/m32700ut/setup.c
+++ b/arch/m32r/platforms/m32700ut/setup.c
@@ -71,7 +71,7 @@ static void shutdown_m32700ut_irq(unsigned int irq)
static struct irq_chip m32700ut_irq_type =
{
- .typename = "M32700UT-IRQ",
+ .name = "M32700UT-IRQ",
.startup = startup_m32700ut_irq,
.shutdown = shutdown_m32700ut_irq,
.enable = enable_m32700ut_irq,
@@ -148,7 +148,7 @@ static void shutdown_m32700ut_pld_irq(unsigned int irq)
static struct irq_chip m32700ut_pld_irq_type =
{
- .typename = "M32700UT-PLD-IRQ",
+ .name = "M32700UT-PLD-IRQ",
.startup = startup_m32700ut_pld_irq,
.shutdown = shutdown_m32700ut_pld_irq,
.enable = enable_m32700ut_pld_irq,
@@ -217,7 +217,7 @@ static void shutdown_m32700ut_lanpld_irq(unsigned int irq)
static struct irq_chip m32700ut_lanpld_irq_type =
{
- .typename = "M32700UT-PLD-LAN-IRQ",
+ .name = "M32700UT-PLD-LAN-IRQ",
.startup = startup_m32700ut_lanpld_irq,
.shutdown = shutdown_m32700ut_lanpld_irq,
.enable = enable_m32700ut_lanpld_irq,
@@ -286,7 +286,7 @@ static void shutdown_m32700ut_lcdpld_irq(unsigned int irq)
static struct irq_chip m32700ut_lcdpld_irq_type =
{
- .typename = "M32700UT-PLD-LCD-IRQ",
+ .name = "M32700UT-PLD-LCD-IRQ",
.startup = startup_m32700ut_lcdpld_irq,
.shutdown = shutdown_m32700ut_lcdpld_irq,
.enable = enable_m32700ut_lcdpld_irq,
diff --git a/arch/m32r/platforms/mappi/setup.c b/arch/m32r/platforms/mappi/setup.c
index fb4b17799b66..ea00c84d6b1b 100644
--- a/arch/m32r/platforms/mappi/setup.c
+++ b/arch/m32r/platforms/mappi/setup.c
@@ -65,7 +65,7 @@ static void shutdown_mappi_irq(unsigned int irq)
static struct irq_chip mappi_irq_type =
{
- .typename = "MAPPI-IRQ",
+ .name = "MAPPI-IRQ",
.startup = startup_mappi_irq,
.shutdown = shutdown_mappi_irq,
.enable = enable_mappi_irq,
diff --git a/arch/m32r/platforms/mappi2/setup.c b/arch/m32r/platforms/mappi2/setup.c
index 6a65eda0a056..c049376d0270 100644
--- a/arch/m32r/platforms/mappi2/setup.c
+++ b/arch/m32r/platforms/mappi2/setup.c
@@ -72,7 +72,7 @@ static void shutdown_mappi2_irq(unsigned int irq)
static struct irq_chip mappi2_irq_type =
{
- .typename = "MAPPI2-IRQ",
+ .name = "MAPPI2-IRQ",
.startup = startup_mappi2_irq,
.shutdown = shutdown_mappi2_irq,
.enable = enable_mappi2_irq,
diff --git a/arch/m32r/platforms/mappi3/setup.c b/arch/m32r/platforms/mappi3/setup.c
index 9c337aeac94b..882de25c6e8c 100644
--- a/arch/m32r/platforms/mappi3/setup.c
+++ b/arch/m32r/platforms/mappi3/setup.c
@@ -72,7 +72,7 @@ static void shutdown_mappi3_irq(unsigned int irq)
static struct irq_chip mappi3_irq_type =
{
- .typename = "MAPPI3-IRQ",
+ .name = "MAPPI3-IRQ",
.startup = startup_mappi3_irq,
.shutdown = shutdown_mappi3_irq,
.enable = enable_mappi3_irq,
diff --git a/arch/m32r/platforms/oaks32r/setup.c b/arch/m32r/platforms/oaks32r/setup.c
index ed865741c38d..d11d93bf74f5 100644
--- a/arch/m32r/platforms/oaks32r/setup.c
+++ b/arch/m32r/platforms/oaks32r/setup.c
@@ -63,7 +63,7 @@ static void shutdown_oaks32r_irq(unsigned int irq)
static struct irq_chip oaks32r_irq_type =
{
- .typename = "OAKS32R-IRQ",
+ .name = "OAKS32R-IRQ",
.startup = startup_oaks32r_irq,
.shutdown = shutdown_oaks32r_irq,
.enable = enable_oaks32r_irq,
diff --git a/arch/m32r/platforms/opsput/setup.c b/arch/m32r/platforms/opsput/setup.c
index 80d680657019..5f3402a2fbaf 100644
--- a/arch/m32r/platforms/opsput/setup.c
+++ b/arch/m32r/platforms/opsput/setup.c
@@ -72,7 +72,7 @@ static void shutdown_opsput_irq(unsigned int irq)
static struct irq_chip opsput_irq_type =
{
- .typename = "OPSPUT-IRQ",
+ .name = "OPSPUT-IRQ",
.startup = startup_opsput_irq,
.shutdown = shutdown_opsput_irq,
.enable = enable_opsput_irq,
@@ -149,7 +149,7 @@ static void shutdown_opsput_pld_irq(unsigned int irq)
static struct irq_chip opsput_pld_irq_type =
{
- .typename = "OPSPUT-PLD-IRQ",
+ .name = "OPSPUT-PLD-IRQ",
.startup = startup_opsput_pld_irq,
.shutdown = shutdown_opsput_pld_irq,
.enable = enable_opsput_pld_irq,
@@ -218,7 +218,7 @@ static void shutdown_opsput_lanpld_irq(unsigned int irq)
static struct irq_chip opsput_lanpld_irq_type =
{
- .typename = "OPSPUT-PLD-LAN-IRQ",
+ .name = "OPSPUT-PLD-LAN-IRQ",
.startup = startup_opsput_lanpld_irq,
.shutdown = shutdown_opsput_lanpld_irq,
.enable = enable_opsput_lanpld_irq,
diff --git a/arch/m32r/platforms/usrv/setup.c b/arch/m32r/platforms/usrv/setup.c
index 757302660af8..1beac7a51ed4 100644
--- a/arch/m32r/platforms/usrv/setup.c
+++ b/arch/m32r/platforms/usrv/setup.c
@@ -63,7 +63,7 @@ static void shutdown_mappi_irq(unsigned int irq)
static struct irq_chip mappi_irq_type =
{
- .typename = "M32700-IRQ",
+ .name = "M32700-IRQ",
.startup = startup_mappi_irq,
.shutdown = shutdown_mappi_irq,
.enable = enable_mappi_irq,
@@ -136,7 +136,7 @@ static void shutdown_m32700ut_pld_irq(unsigned int irq)
static struct irq_chip m32700ut_pld_irq_type =
{
- .typename = "USRV-PLD-IRQ",
+ .name = "USRV-PLD-IRQ",
.startup = startup_m32700ut_pld_irq,
.shutdown = shutdown_m32700ut_pld_irq,
.enable = enable_m32700ut_pld_irq,
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 8030e2481d97..77bb0d6baa62 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -434,7 +434,7 @@ config PROC_HARDWARE
config ISA
bool
- depends on Q40 || AMIGA_PCMCIA || GG2
+ depends on Q40 || AMIGA_PCMCIA
default y
help
Find out whether you have ISA slots on your motherboard. ISA is the
@@ -445,7 +445,7 @@ config ISA
config GENERIC_ISA_DMA
bool
- depends on Q40 || AMIGA_PCMCIA || GG2
+ depends on Q40 || AMIGA_PCMCIA
default y
config ZONE_DMA
diff --git a/arch/m68k/bvme6000/rtc.c b/arch/m68k/bvme6000/rtc.c
index cb8617bb194b..1c4d4c7bf4d4 100644
--- a/arch/m68k/bvme6000/rtc.c
+++ b/arch/m68k/bvme6000/rtc.c
@@ -155,6 +155,7 @@ static const struct file_operations rtc_fops = {
.unlocked_ioctl = rtc_ioctl,
.open = rtc_open,
.release = rtc_release,
+ .llseek = noop_llseek,
};
static struct miscdevice rtc_dev = {
diff --git a/arch/m68k/include/asm/amigahw.h b/arch/m68k/include/asm/amigahw.h
index 5ca5dd951a4a..7a19b5686a4a 100644
--- a/arch/m68k/include/asm/amigahw.h
+++ b/arch/m68k/include/asm/amigahw.h
@@ -102,7 +102,6 @@ struct amiga_hw_present {
AMIGAHW_DECLARE(ALICE_NTSC); /* NTSC Alice (8374) */
AMIGAHW_DECLARE(MAGIC_REKICK); /* A3000 Magic Hard Rekick */
AMIGAHW_DECLARE(PCMCIA); /* PCMCIA Slot */
- AMIGAHW_DECLARE(GG2_ISA); /* GG2 Zorro2ISA Bridge */
AMIGAHW_DECLARE(ZORRO); /* Zorro AutoConfig */
AMIGAHW_DECLARE(ZORRO3); /* Zorro III */
};
diff --git a/arch/m68k/include/asm/atomic.h b/arch/m68k/include/asm/atomic.h
index eab36dcacf6c..03ae3d14cd4a 100644
--- a/arch/m68k/include/asm/atomic.h
+++ b/arch/m68k/include/asm/atomic.h
@@ -1,7 +1,211 @@
-#ifdef __uClinux__
-#include "atomic_no.h"
+#ifndef __ARCH_M68K_ATOMIC__
+#define __ARCH_M68K_ATOMIC__
+
+#include <linux/types.h>
+#include <asm/system.h>
+
+/*
+ * Atomic operations that C can't guarantee us. Useful for
+ * resource counting etc..
+ */
+
+/*
+ * We do not have SMP m68k systems, so we don't have to deal with that.
+ */
+
+#define ATOMIC_INIT(i) { (i) }
+
+#define atomic_read(v) (*(volatile int *)&(v)->counter)
+#define atomic_set(v, i) (((v)->counter) = i)
+
+/*
+ * The ColdFire parts cannot do some immediate to memory operations,
+ * so for them we do not specify the "i" asm constraint.
+ */
+#ifdef CONFIG_COLDFIRE
+#define ASM_DI "d"
#else
-#include "atomic_mm.h"
+#define ASM_DI "di"
#endif
+static inline void atomic_add(int i, atomic_t *v)
+{
+ __asm__ __volatile__("addl %1,%0" : "+m" (*v) : ASM_DI (i));
+}
+
+static inline void atomic_sub(int i, atomic_t *v)
+{
+ __asm__ __volatile__("subl %1,%0" : "+m" (*v) : ASM_DI (i));
+}
+
+static inline void atomic_inc(atomic_t *v)
+{
+ __asm__ __volatile__("addql #1,%0" : "+m" (*v));
+}
+
+static inline void atomic_dec(atomic_t *v)
+{
+ __asm__ __volatile__("subql #1,%0" : "+m" (*v));
+}
+
+static inline int atomic_dec_and_test(atomic_t *v)
+{
+ char c;
+ __asm__ __volatile__("subql #1,%1; seq %0" : "=d" (c), "+m" (*v));
+ return c != 0;
+}
+
+static inline int atomic_inc_and_test(atomic_t *v)
+{
+ char c;
+ __asm__ __volatile__("addql #1,%1; seq %0" : "=d" (c), "+m" (*v));
+ return c != 0;
+}
+
+#ifdef CONFIG_RMW_INSNS
+
+static inline int atomic_add_return(int i, atomic_t *v)
+{
+ int t, tmp;
+
+ __asm__ __volatile__(
+ "1: movel %2,%1\n"
+ " addl %3,%1\n"
+ " casl %2,%1,%0\n"
+ " jne 1b"
+ : "+m" (*v), "=&d" (t), "=&d" (tmp)
+ : "g" (i), "2" (atomic_read(v)));
+ return t;
+}
+
+static inline int atomic_sub_return(int i, atomic_t *v)
+{
+ int t, tmp;
+
+ __asm__ __volatile__(
+ "1: movel %2,%1\n"
+ " subl %3,%1\n"
+ " casl %2,%1,%0\n"
+ " jne 1b"
+ : "+m" (*v), "=&d" (t), "=&d" (tmp)
+ : "g" (i), "2" (atomic_read(v)));
+ return t;
+}
+
+#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+
+#else /* !CONFIG_RMW_INSNS */
+
+static inline int atomic_add_return(int i, atomic_t * v)
+{
+ unsigned long flags;
+ int t;
+
+ local_irq_save(flags);
+ t = atomic_read(v);
+ t += i;
+ atomic_set(v, t);
+ local_irq_restore(flags);
+
+ return t;
+}
+
+static inline int atomic_sub_return(int i, atomic_t * v)
+{
+ unsigned long flags;
+ int t;
+
+ local_irq_save(flags);
+ t = atomic_read(v);
+ t -= i;
+ atomic_set(v, t);
+ local_irq_restore(flags);
+
+ return t;
+}
+
+static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
+{
+ unsigned long flags;
+ int prev;
+
+ local_irq_save(flags);
+ prev = atomic_read(v);
+ if (prev == old)
+ atomic_set(v, new);
+ local_irq_restore(flags);
+ return prev;
+}
+
+static inline int atomic_xchg(atomic_t *v, int new)
+{
+ unsigned long flags;
+ int prev;
+
+ local_irq_save(flags);
+ prev = atomic_read(v);
+ atomic_set(v, new);
+ local_irq_restore(flags);
+ return prev;
+}
+
+#endif /* !CONFIG_RMW_INSNS */
+
+#define atomic_dec_return(v) atomic_sub_return(1, (v))
+#define atomic_inc_return(v) atomic_add_return(1, (v))
+
+static inline int atomic_sub_and_test(int i, atomic_t *v)
+{
+ char c;
+ __asm__ __volatile__("subl %2,%1; seq %0"
+ : "=d" (c), "+m" (*v)
+ : ASM_DI (i));
+ return c != 0;
+}
+
+static inline int atomic_add_negative(int i, atomic_t *v)
+{
+ char c;
+ __asm__ __volatile__("addl %2,%1; smi %0"
+ : "=d" (c), "+m" (*v)
+ : "id" (i));
+ return c != 0;
+}
+
+static inline void atomic_clear_mask(unsigned long mask, unsigned long *v)
+{
+ __asm__ __volatile__("andl %1,%0" : "+m" (*v) : "id" (~(mask)));
+}
+
+static inline void atomic_set_mask(unsigned long mask, unsigned long *v)
+{
+ __asm__ __volatile__("orl %1,%0" : "+m" (*v) : "id" (mask));
+}
+
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+ c = atomic_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
+/* Atomic operations are already serializing */
+#define smp_mb__before_atomic_dec() barrier()
+#define smp_mb__after_atomic_dec() barrier()
+#define smp_mb__before_atomic_inc() barrier()
+#define smp_mb__after_atomic_inc() barrier()
+
+#include <asm-generic/atomic-long.h>
#include <asm-generic/atomic64.h>
+#endif /* __ARCH_M68K_ATOMIC __ */
diff --git a/arch/m68k/include/asm/atomic_mm.h b/arch/m68k/include/asm/atomic_mm.h
deleted file mode 100644
index 6a223b3f7e74..000000000000
--- a/arch/m68k/include/asm/atomic_mm.h
+++ /dev/null
@@ -1,200 +0,0 @@
-#ifndef __ARCH_M68K_ATOMIC__
-#define __ARCH_M68K_ATOMIC__
-
-#include <linux/types.h>
-#include <asm/system.h>
-
-/*
- * Atomic operations that C can't guarantee us. Useful for
- * resource counting etc..
- */
-
-/*
- * We do not have SMP m68k systems, so we don't have to deal with that.
- */
-
-#define ATOMIC_INIT(i) { (i) }
-
-#define atomic_read(v) (*(volatile int *)&(v)->counter)
-#define atomic_set(v, i) (((v)->counter) = i)
-
-static inline void atomic_add(int i, atomic_t *v)
-{
- __asm__ __volatile__("addl %1,%0" : "+m" (*v) : "id" (i));
-}
-
-static inline void atomic_sub(int i, atomic_t *v)
-{
- __asm__ __volatile__("subl %1,%0" : "+m" (*v) : "id" (i));
-}
-
-static inline void atomic_inc(atomic_t *v)
-{
- __asm__ __volatile__("addql #1,%0" : "+m" (*v));
-}
-
-static inline void atomic_dec(atomic_t *v)
-{
- __asm__ __volatile__("subql #1,%0" : "+m" (*v));
-}
-
-static inline int atomic_dec_and_test(atomic_t *v)
-{
- char c;
- __asm__ __volatile__("subql #1,%1; seq %0" : "=d" (c), "+m" (*v));
- return c != 0;
-}
-
-static inline int atomic_inc_and_test(atomic_t *v)
-{
- char c;
- __asm__ __volatile__("addql #1,%1; seq %0" : "=d" (c), "+m" (*v));
- return c != 0;
-}
-
-#ifdef CONFIG_RMW_INSNS
-
-static inline int atomic_add_return(int i, atomic_t *v)
-{
- int t, tmp;
-
- __asm__ __volatile__(
- "1: movel %2,%1\n"
- " addl %3,%1\n"
- " casl %2,%1,%0\n"
- " jne 1b"
- : "+m" (*v), "=&d" (t), "=&d" (tmp)
- : "g" (i), "2" (atomic_read(v)));
- return t;
-}
-
-static inline int atomic_sub_return(int i, atomic_t *v)
-{
- int t, tmp;
-
- __asm__ __volatile__(
- "1: movel %2,%1\n"
- " subl %3,%1\n"
- " casl %2,%1,%0\n"
- " jne 1b"
- : "+m" (*v), "=&d" (t), "=&d" (tmp)
- : "g" (i), "2" (atomic_read(v)));
- return t;
-}
-
-#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
-#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
-
-#else /* !CONFIG_RMW_INSNS */
-
-static inline int atomic_add_return(int i, atomic_t * v)
-{
- unsigned long flags;
- int t;
-
- local_irq_save(flags);
- t = atomic_read(v);
- t += i;
- atomic_set(v, t);
- local_irq_restore(flags);
-
- return t;
-}
-
-static inline int atomic_sub_return(int i, atomic_t * v)
-{
- unsigned long flags;
- int t;
-
- local_irq_save(flags);
- t = atomic_read(v);
- t -= i;
- atomic_set(v, t);
- local_irq_restore(flags);
-
- return t;
-}
-
-static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
-{
- unsigned long flags;
- int prev;
-
- local_irq_save(flags);
- prev = atomic_read(v);
- if (prev == old)
- atomic_set(v, new);
- local_irq_restore(flags);
- return prev;
-}
-
-static inline int atomic_xchg(atomic_t *v, int new)
-{
- unsigned long flags;
- int prev;
-
- local_irq_save(flags);
- prev = atomic_read(v);
- atomic_set(v, new);
- local_irq_restore(flags);
- return prev;
-}
-
-#endif /* !CONFIG_RMW_INSNS */
-
-#define atomic_dec_return(v) atomic_sub_return(1, (v))
-#define atomic_inc_return(v) atomic_add_return(1, (v))
-
-static inline int atomic_sub_and_test(int i, atomic_t *v)
-{
- char c;
- __asm__ __volatile__("subl %2,%1; seq %0"
- : "=d" (c), "+m" (*v)
- : "id" (i));
- return c != 0;
-}
-
-static inline int atomic_add_negative(int i, atomic_t *v)
-{
- char c;
- __asm__ __volatile__("addl %2,%1; smi %0"
- : "=d" (c), "+m" (*v)
- : "id" (i));
- return c != 0;
-}
-
-static inline void atomic_clear_mask(unsigned long mask, unsigned long *v)
-{
- __asm__ __volatile__("andl %1,%0" : "+m" (*v) : "id" (~(mask)));
-}
-
-static inline void atomic_set_mask(unsigned long mask, unsigned long *v)
-{
- __asm__ __volatile__("orl %1,%0" : "+m" (*v) : "id" (mask));
-}
-
-static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
-{
- int c, old;
- c = atomic_read(v);
- for (;;) {
- if (unlikely(c == (u)))
- break;
- old = atomic_cmpxchg((v), c, c + (a));
- if (likely(old == c))
- break;
- c = old;
- }
- return c != (u);
-}
-
-#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
-
-/* Atomic operations are already serializing */
-#define smp_mb__before_atomic_dec() barrier()
-#define smp_mb__after_atomic_dec() barrier()
-#define smp_mb__before_atomic_inc() barrier()
-#define smp_mb__after_atomic_inc() barrier()
-
-#include <asm-generic/atomic-long.h>
-#endif /* __ARCH_M68K_ATOMIC __ */
diff --git a/arch/m68k/include/asm/atomic_no.h b/arch/m68k/include/asm/atomic_no.h
deleted file mode 100644
index 289310c63a8a..000000000000
--- a/arch/m68k/include/asm/atomic_no.h
+++ /dev/null
@@ -1,155 +0,0 @@
-#ifndef __ARCH_M68KNOMMU_ATOMIC__
-#define __ARCH_M68KNOMMU_ATOMIC__
-
-#include <linux/types.h>
-#include <asm/system.h>
-
-/*
- * Atomic operations that C can't guarantee us. Useful for
- * resource counting etc..
- */
-
-/*
- * We do not have SMP m68k systems, so we don't have to deal with that.
- */
-
-#define ATOMIC_INIT(i) { (i) }
-
-#define atomic_read(v) (*(volatile int *)&(v)->counter)
-#define atomic_set(v, i) (((v)->counter) = i)
-
-static __inline__ void atomic_add(int i, atomic_t *v)
-{
-#ifdef CONFIG_COLDFIRE
- __asm__ __volatile__("addl %1,%0" : "+m" (*v) : "d" (i));
-#else
- __asm__ __volatile__("addl %1,%0" : "+m" (*v) : "di" (i));
-#endif
-}
-
-static __inline__ void atomic_sub(int i, atomic_t *v)
-{
-#ifdef CONFIG_COLDFIRE
- __asm__ __volatile__("subl %1,%0" : "+m" (*v) : "d" (i));
-#else
- __asm__ __volatile__("subl %1,%0" : "+m" (*v) : "di" (i));
-#endif
-}
-
-static __inline__ int atomic_sub_and_test(int i, atomic_t * v)
-{
- char c;
-#ifdef CONFIG_COLDFIRE
- __asm__ __volatile__("subl %2,%1; seq %0"
- : "=d" (c), "+m" (*v)
- : "d" (i));
-#else
- __asm__ __volatile__("subl %2,%1; seq %0"
- : "=d" (c), "+m" (*v)
- : "di" (i));
-#endif
- return c != 0;
-}
-
-static __inline__ void atomic_inc(volatile atomic_t *v)
-{
- __asm__ __volatile__("addql #1,%0" : "+m" (*v));
-}
-
-/*
- * atomic_inc_and_test - increment and test
- * @v: pointer of type atomic_t
- *
- * Atomically increments @v by 1
- * and returns true if the result is zero, or false for all
- * other cases.
- */
-
-static __inline__ int atomic_inc_and_test(volatile atomic_t *v)
-{
- char c;
- __asm__ __volatile__("addql #1,%1; seq %0" : "=d" (c), "+m" (*v));
- return c != 0;
-}
-
-static __inline__ void atomic_dec(volatile atomic_t *v)
-{
- __asm__ __volatile__("subql #1,%0" : "+m" (*v));
-}
-
-static __inline__ int atomic_dec_and_test(volatile atomic_t *v)
-{
- char c;
- __asm__ __volatile__("subql #1,%1; seq %0" : "=d" (c), "+m" (*v));
- return c != 0;
-}
-
-static __inline__ void atomic_clear_mask(unsigned long mask, unsigned long *v)
-{
- __asm__ __volatile__("andl %1,%0" : "+m" (*v) : "id" (~(mask)));
-}
-
-static __inline__ void atomic_set_mask(unsigned long mask, unsigned long *v)
-{
- __asm__ __volatile__("orl %1,%0" : "+m" (*v) : "id" (mask));
-}
-
-/* Atomic operations are already serializing */
-#define smp_mb__before_atomic_dec() barrier()
-#define smp_mb__after_atomic_dec() barrier()
-#define smp_mb__before_atomic_inc() barrier()
-#define smp_mb__after_atomic_inc() barrier()
-
-static inline int atomic_add_return(int i, atomic_t * v)
-{
- unsigned long temp, flags;
-
- local_irq_save(flags);
- temp = *(long *)v;
- temp += i;
- *(long *)v = temp;
- local_irq_restore(flags);
-
- return temp;
-}
-
-#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
-
-static inline int atomic_sub_return(int i, atomic_t * v)
-{
- unsigned long temp, flags;
-
- local_irq_save(flags);
- temp = *(long *)v;
- temp -= i;
- *(long *)v = temp;
- local_irq_restore(flags);
-
- return temp;
-}
-
-#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
-#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
-
-static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
-{
- int c, old;
- c = atomic_read(v);
- for (;;) {
- if (unlikely(c == (u)))
- break;
- old = atomic_cmpxchg((v), c, c + (a));
- if (likely(old == c))
- break;
- c = old;
- }
- return c != (u);
-}
-
-#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
-
-#define atomic_dec_return(v) atomic_sub_return(1,(v))
-#define atomic_inc_return(v) atomic_add_return(1,(v))
-
-#include <asm-generic/atomic-long.h>
-#endif /* __ARCH_M68KNOMMU_ATOMIC __ */
diff --git a/arch/m68k/include/asm/cacheflush_no.h b/arch/m68k/include/asm/cacheflush_no.h
index 89f195656be7..7085bd51668b 100644
--- a/arch/m68k/include/asm/cacheflush_no.h
+++ b/arch/m68k/include/asm/cacheflush_no.h
@@ -29,7 +29,7 @@
static inline void __flush_cache_all(void)
{
-#ifdef CONFIG_M5407
+#if defined(CONFIG_M5407) || defined(CONFIG_M548x)
/*
* Use cpushl to push and invalidate all cache lines.
* Gas doesn't seem to know how to generate the ColdFire
diff --git a/arch/m68k/include/asm/coldfire.h b/arch/m68k/include/asm/coldfire.h
index 83a9fa4e618a..3b0a34d0fe33 100644
--- a/arch/m68k/include/asm/coldfire.h
+++ b/arch/m68k/include/asm/coldfire.h
@@ -32,7 +32,9 @@
*/
#define MCF_MBAR 0x10000000
#define MCF_MBAR2 0x80000000
-#if defined(CONFIG_M520x)
+#if defined(CONFIG_M548x)
+#define MCF_IPSBAR MCF_MBAR
+#elif defined(CONFIG_M520x)
#define MCF_IPSBAR 0xFC000000
#else
#define MCF_IPSBAR 0x40000000
diff --git a/arch/m68k/include/asm/entry_mm.h b/arch/m68k/include/asm/entry_mm.h
index 474125886218..e41fea399bfe 100644
--- a/arch/m68k/include/asm/entry_mm.h
+++ b/arch/m68k/include/asm/entry_mm.h
@@ -3,6 +3,9 @@
#include <asm/setup.h>
#include <asm/page.h>
+#ifdef __ASSEMBLY__
+#include <asm/thread_info.h>
+#endif
/*
* Stack layout in 'ret_from_exception':
diff --git a/arch/m68k/include/asm/entry_no.h b/arch/m68k/include/asm/entry_no.h
index 907ed03d792f..80e41492aa2a 100644
--- a/arch/m68k/include/asm/entry_no.h
+++ b/arch/m68k/include/asm/entry_no.h
@@ -28,7 +28,7 @@
* M68K COLDFIRE
*/
-#define ALLOWINT 0xf8ff
+#define ALLOWINT (~0x700)
#ifdef __ASSEMBLY__
diff --git a/arch/m68k/include/asm/gpio.h b/arch/m68k/include/asm/gpio.h
index 283214dc65a7..1b57adbafad5 100644
--- a/arch/m68k/include/asm/gpio.h
+++ b/arch/m68k/include/asm/gpio.h
@@ -36,7 +36,8 @@
*/
#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
defined(CONFIG_M520x) || defined(CONFIG_M523x) || \
- defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x)
+ defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
+ defined(CONFIG_M532x) || defined(CONFIG_M548x)
/* These parts have GPIO organized by 8 bit ports */
@@ -136,6 +137,8 @@ static inline u32 __mcf_gpio_ppdr(unsigned gpio)
#endif
else
return MCFGPIO_PPDR + mcfgpio_port(gpio - MCFGPIO_SCR_START);
+#else
+ return 0;
#endif
}
@@ -173,6 +176,8 @@ static inline u32 __mcf_gpio_podr(unsigned gpio)
#endif
else
return MCFGPIO_PODR + mcfgpio_port(gpio - MCFGPIO_SCR_START);
+#else
+ return 0;
#endif
}
diff --git a/arch/m68k/include/asm/io_mm.h b/arch/m68k/include/asm/io_mm.h
index 9e673e3bd434..0fb3468000e7 100644
--- a/arch/m68k/include/asm/io_mm.h
+++ b/arch/m68k/include/asm/io_mm.h
@@ -49,23 +49,6 @@
#define MULTI_ISA 0
#endif /* Q40 */
-/* GG-II Zorro to ISA bridge */
-#ifdef CONFIG_GG2
-
-extern unsigned long gg2_isa_base;
-#define GG2_ISA_IO_B(ioaddr) (gg2_isa_base+1+((unsigned long)(ioaddr)*4))
-#define GG2_ISA_IO_W(ioaddr) (gg2_isa_base+ ((unsigned long)(ioaddr)*4))
-#define GG2_ISA_MEM_B(madr) (gg2_isa_base+1+(((unsigned long)(madr)*4) & 0xfffff))
-#define GG2_ISA_MEM_W(madr) (gg2_isa_base+ (((unsigned long)(madr)*4) & 0xfffff))
-
-#ifndef MULTI_ISA
-#define MULTI_ISA 0
-#else
-#undef MULTI_ISA
-#define MULTI_ISA 1
-#endif
-#endif /* GG2 */
-
#ifdef CONFIG_AMIGA_PCMCIA
#include <asm/amigayle.h>
@@ -89,8 +72,7 @@ extern unsigned long gg2_isa_base;
#endif
#define ISA_TYPE_Q40 (1)
-#define ISA_TYPE_GG2 (2)
-#define ISA_TYPE_AG (3)
+#define ISA_TYPE_AG (2)
#if defined(CONFIG_Q40) && !defined(MULTI_ISA)
#define ISA_TYPE ISA_TYPE_Q40
@@ -100,10 +82,6 @@ extern unsigned long gg2_isa_base;
#define ISA_TYPE ISA_TYPE_AG
#define ISA_SEX 1
#endif
-#if defined(CONFIG_GG2) && !defined(MULTI_ISA)
-#define ISA_TYPE ISA_TYPE_GG2
-#define ISA_SEX 0
-#endif
#ifdef MULTI_ISA
extern int isa_type;
@@ -125,9 +103,6 @@ static inline u8 __iomem *isa_itb(unsigned long addr)
#ifdef CONFIG_Q40
case ISA_TYPE_Q40: return (u8 __iomem *)Q40_ISA_IO_B(addr);
#endif
-#ifdef CONFIG_GG2
- case ISA_TYPE_GG2: return (u8 __iomem *)GG2_ISA_IO_B(addr);
-#endif
#ifdef CONFIG_AMIGA_PCMCIA
case ISA_TYPE_AG: return (u8 __iomem *)AG_ISA_IO_B(addr);
#endif
@@ -141,9 +116,6 @@ static inline u16 __iomem *isa_itw(unsigned long addr)
#ifdef CONFIG_Q40
case ISA_TYPE_Q40: return (u16 __iomem *)Q40_ISA_IO_W(addr);
#endif
-#ifdef CONFIG_GG2
- case ISA_TYPE_GG2: return (u16 __iomem *)GG2_ISA_IO_W(addr);
-#endif
#ifdef CONFIG_AMIGA_PCMCIA
case ISA_TYPE_AG: return (u16 __iomem *)AG_ISA_IO_W(addr);
#endif
@@ -167,9 +139,6 @@ static inline u8 __iomem *isa_mtb(unsigned long addr)
#ifdef CONFIG_Q40
case ISA_TYPE_Q40: return (u8 __iomem *)Q40_ISA_MEM_B(addr);
#endif
-#ifdef CONFIG_GG2
- case ISA_TYPE_GG2: return (u8 __iomem *)GG2_ISA_MEM_B(addr);
-#endif
#ifdef CONFIG_AMIGA_PCMCIA
case ISA_TYPE_AG: return (u8 __iomem *)addr;
#endif
@@ -183,9 +152,6 @@ static inline u16 __iomem *isa_mtw(unsigned long addr)
#ifdef CONFIG_Q40
case ISA_TYPE_Q40: return (u16 __iomem *)Q40_ISA_MEM_W(addr);
#endif
-#ifdef CONFIG_GG2
- case ISA_TYPE_GG2: return (u16 __iomem *)GG2_ISA_MEM_W(addr);
-#endif
#ifdef CONFIG_AMIGA_PCMCIA
case ISA_TYPE_AG: return (u16 __iomem *)addr;
#endif
@@ -217,9 +183,6 @@ static inline void isa_delay(void)
#ifdef CONFIG_Q40
case ISA_TYPE_Q40: isa_outb(0,0x80); break;
#endif
-#ifdef CONFIG_GG2
- case ISA_TYPE_GG2: break;
-#endif
#ifdef CONFIG_AMIGA_PCMCIA
case ISA_TYPE_AG: break;
#endif
@@ -287,9 +250,13 @@ static inline void isa_delay(void)
#define outb(val,port) ((void)0)
#define outb_p(val,port) ((void)0)
#define inw(port) 0xffff
+#define inw_p(port) 0xffff
#define outw(val,port) ((void)0)
+#define outw_p(val,port) ((void)0)
#define inl(port) 0xffffffffUL
+#define inl_p(port) 0xffffffffUL
#define outl(val,port) ((void)0)
+#define outl_p(val,port) ((void)0)
#define insb(port,buf,nr) ((void)0)
#define outsb(port,buf,nr) ((void)0)
diff --git a/arch/m68k/include/asm/ioctls.h b/arch/m68k/include/asm/ioctls.h
index 91a57d665460..1332bb4ca5b0 100644
--- a/arch/m68k/include/asm/ioctls.h
+++ b/arch/m68k/include/asm/ioctls.h
@@ -1,86 +1,8 @@
#ifndef __ARCH_M68K_IOCTLS_H__
#define __ARCH_M68K_IOCTLS_H__
-#include <asm/ioctl.h>
-
-/* 0x54 is just a magic number to make these relatively unique ('T') */
-
-#define TCGETS 0x5401
-#define TCSETS 0x5402
-#define TCSETSW 0x5403
-#define TCSETSF 0x5404
-#define TCGETA 0x5405
-#define TCSETA 0x5406
-#define TCSETAW 0x5407
-#define TCSETAF 0x5408
-#define TCSBRK 0x5409
-#define TCXONC 0x540A
-#define TCFLSH 0x540B
-#define TIOCEXCL 0x540C
-#define TIOCNXCL 0x540D
-#define TIOCSCTTY 0x540E
-#define TIOCGPGRP 0x540F
-#define TIOCSPGRP 0x5410
-#define TIOCOUTQ 0x5411
-#define TIOCSTI 0x5412
-#define TIOCGWINSZ 0x5413
-#define TIOCSWINSZ 0x5414
-#define TIOCMGET 0x5415
-#define TIOCMBIS 0x5416
-#define TIOCMBIC 0x5417
-#define TIOCMSET 0x5418
-#define TIOCGSOFTCAR 0x5419
-#define TIOCSSOFTCAR 0x541A
-#define FIONREAD 0x541B
-#define TIOCINQ FIONREAD
-#define TIOCLINUX 0x541C
-#define TIOCCONS 0x541D
-#define TIOCGSERIAL 0x541E
-#define TIOCSSERIAL 0x541F
-#define TIOCPKT 0x5420
-#define FIONBIO 0x5421
-#define TIOCNOTTY 0x5422
-#define TIOCSETD 0x5423
-#define TIOCGETD 0x5424
-#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
-#define TIOCSBRK 0x5427 /* BSD compatibility */
-#define TIOCCBRK 0x5428 /* BSD compatibility */
-#define TIOCGSID 0x5429 /* Return the session ID of FD */
-#define TCGETS2 _IOR('T',0x2A, struct termios2)
-#define TCSETS2 _IOW('T',0x2B, struct termios2)
-#define TCSETSW2 _IOW('T',0x2C, struct termios2)
-#define TCSETSF2 _IOW('T',0x2D, struct termios2)
-#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
-#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
-#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */
-
-#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */
-#define FIOCLEX 0x5451
-#define FIOASYNC 0x5452
-#define TIOCSERCONFIG 0x5453
-#define TIOCSERGWILD 0x5454
-#define TIOCSERSWILD 0x5455
-#define TIOCGLCKTRMIOS 0x5456
-#define TIOCSLCKTRMIOS 0x5457
-#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
-#define TIOCSERGETLSR 0x5459 /* Get line status register */
-#define TIOCSERGETMULTI 0x545A /* Get multiport config */
-#define TIOCSERSETMULTI 0x545B /* Set multiport config */
-
-#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
-#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
#define FIOQSIZE 0x545E
-/* Used for packet mode */
-#define TIOCPKT_DATA 0
-#define TIOCPKT_FLUSHREAD 1
-#define TIOCPKT_FLUSHWRITE 2
-#define TIOCPKT_STOP 4
-#define TIOCPKT_START 8
-#define TIOCPKT_NOSTOP 16
-#define TIOCPKT_DOSTOP 32
-#define TIOCPKT_IOCTL 64
-
-#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
+#include <asm-generic/ioctls.h>
#endif /* __ARCH_M68K_IOCTLS_H__ */
diff --git a/arch/m68k/include/asm/irqflags.h b/arch/m68k/include/asm/irqflags.h
new file mode 100644
index 000000000000..4a5b284a1550
--- /dev/null
+++ b/arch/m68k/include/asm/irqflags.h
@@ -0,0 +1,76 @@
+#ifndef _M68K_IRQFLAGS_H
+#define _M68K_IRQFLAGS_H
+
+#include <linux/types.h>
+#include <linux/hardirq.h>
+#include <linux/preempt.h>
+#include <asm/thread_info.h>
+#include <asm/entry.h>
+
+static inline unsigned long arch_local_save_flags(void)
+{
+ unsigned long flags;
+ asm volatile ("movew %%sr,%0" : "=d" (flags) : : "memory");
+ return flags;
+}
+
+static inline void arch_local_irq_disable(void)
+{
+#ifdef CONFIG_COLDFIRE
+ asm volatile (
+ "move %/sr,%%d0 \n\t"
+ "ori.l #0x0700,%%d0 \n\t"
+ "move %%d0,%/sr \n"
+ : /* no outputs */
+ :
+ : "cc", "%d0", "memory");
+#else
+ asm volatile ("oriw #0x0700,%%sr" : : : "memory");
+#endif
+}
+
+static inline void arch_local_irq_enable(void)
+{
+#if defined(CONFIG_COLDFIRE)
+ asm volatile (
+ "move %/sr,%%d0 \n\t"
+ "andi.l #0xf8ff,%%d0 \n\t"
+ "move %%d0,%/sr \n"
+ : /* no outputs */
+ :
+ : "cc", "%d0", "memory");
+#else
+# if defined(CONFIG_MMU)
+ if (MACH_IS_Q40 || !hardirq_count())
+# endif
+ asm volatile (
+ "andiw %0,%%sr"
+ :
+ : "i" (ALLOWINT)
+ : "memory");
+#endif
+}
+
+static inline unsigned long arch_local_irq_save(void)
+{
+ unsigned long flags = arch_local_save_flags();
+ arch_local_irq_disable();
+ return flags;
+}
+
+static inline void arch_local_irq_restore(unsigned long flags)
+{
+ asm volatile ("movew %0,%%sr" : : "d" (flags) : "memory");
+}
+
+static inline bool arch_irqs_disabled_flags(unsigned long flags)
+{
+ return (flags & ~ALLOWINT) != 0;
+}
+
+static inline bool arch_irqs_disabled(void)
+{
+ return arch_irqs_disabled_flags(arch_local_save_flags());
+}
+
+#endif /* _M68K_IRQFLAGS_H */
diff --git a/arch/m68k/include/asm/m548xgpt.h b/arch/m68k/include/asm/m548xgpt.h
new file mode 100644
index 000000000000..c8ef158a1c4e
--- /dev/null
+++ b/arch/m68k/include/asm/m548xgpt.h
@@ -0,0 +1,88 @@
+/*
+ * File: m548xgpt.h
+ * Purpose: Register and bit definitions for the MCF548X
+ *
+ * Notes:
+ *
+ */
+
+#ifndef m548xgpt_h
+#define m548xgpt_h
+
+/*********************************************************************
+*
+* General Purpose Timers (GPT)
+*
+*********************************************************************/
+
+/* Register read/write macros */
+#define MCF_GPT_GMS0 0x000800
+#define MCF_GPT_GCIR0 0x000804
+#define MCF_GPT_GPWM0 0x000808
+#define MCF_GPT_GSR0 0x00080C
+#define MCF_GPT_GMS1 0x000810
+#define MCF_GPT_GCIR1 0x000814
+#define MCF_GPT_GPWM1 0x000818
+#define MCF_GPT_GSR1 0x00081C
+#define MCF_GPT_GMS2 0x000820
+#define MCF_GPT_GCIR2 0x000824
+#define MCF_GPT_GPWM2 0x000828
+#define MCF_GPT_GSR2 0x00082C
+#define MCF_GPT_GMS3 0x000830
+#define MCF_GPT_GCIR3 0x000834
+#define MCF_GPT_GPWM3 0x000838
+#define MCF_GPT_GSR3 0x00083C
+#define MCF_GPT_GMS(x) (0x000800+((x)*0x010))
+#define MCF_GPT_GCIR(x) (0x000804+((x)*0x010))
+#define MCF_GPT_GPWM(x) (0x000808+((x)*0x010))
+#define MCF_GPT_GSR(x) (0x00080C+((x)*0x010))
+
+/* Bit definitions and macros for MCF_GPT_GMS */
+#define MCF_GPT_GMS_TMS(x) (((x)&0x00000007)<<0)
+#define MCF_GPT_GMS_GPIO(x) (((x)&0x00000003)<<4)
+#define MCF_GPT_GMS_IEN (0x00000100)
+#define MCF_GPT_GMS_OD (0x00000200)
+#define MCF_GPT_GMS_SC (0x00000400)
+#define MCF_GPT_GMS_CE (0x00001000)
+#define MCF_GPT_GMS_WDEN (0x00008000)
+#define MCF_GPT_GMS_ICT(x) (((x)&0x00000003)<<16)
+#define MCF_GPT_GMS_OCT(x) (((x)&0x00000003)<<20)
+#define MCF_GPT_GMS_OCPW(x) (((x)&0x000000FF)<<24)
+#define MCF_GPT_GMS_OCT_FRCLOW (0x00000000)
+#define MCF_GPT_GMS_OCT_PULSEHI (0x00100000)
+#define MCF_GPT_GMS_OCT_PULSELO (0x00200000)
+#define MCF_GPT_GMS_OCT_TOGGLE (0x00300000)
+#define MCF_GPT_GMS_ICT_ANY (0x00000000)
+#define MCF_GPT_GMS_ICT_RISE (0x00010000)
+#define MCF_GPT_GMS_ICT_FALL (0x00020000)
+#define MCF_GPT_GMS_ICT_PULSE (0x00030000)
+#define MCF_GPT_GMS_GPIO_INPUT (0x00000000)
+#define MCF_GPT_GMS_GPIO_OUTLO (0x00000020)
+#define MCF_GPT_GMS_GPIO_OUTHI (0x00000030)
+#define MCF_GPT_GMS_TMS_DISABLE (0x00000000)
+#define MCF_GPT_GMS_TMS_INCAPT (0x00000001)
+#define MCF_GPT_GMS_TMS_OUTCAPT (0x00000002)
+#define MCF_GPT_GMS_TMS_PWM (0x00000003)
+#define MCF_GPT_GMS_TMS_GPIO (0x00000004)
+
+/* Bit definitions and macros for MCF_GPT_GCIR */
+#define MCF_GPT_GCIR_CNT(x) (((x)&0x0000FFFF)<<0)
+#define MCF_GPT_GCIR_PRE(x) (((x)&0x0000FFFF)<<16)
+
+/* Bit definitions and macros for MCF_GPT_GPWM */
+#define MCF_GPT_GPWM_LOAD (0x00000001)
+#define MCF_GPT_GPWM_PWMOP (0x00000100)
+#define MCF_GPT_GPWM_WIDTH(x) (((x)&0x0000FFFF)<<16)
+
+/* Bit definitions and macros for MCF_GPT_GSR */
+#define MCF_GPT_GSR_CAPT (0x00000001)
+#define MCF_GPT_GSR_COMP (0x00000002)
+#define MCF_GPT_GSR_PWMP (0x00000004)
+#define MCF_GPT_GSR_TEXP (0x00000008)
+#define MCF_GPT_GSR_PIN (0x00000100)
+#define MCF_GPT_GSR_OVF(x) (((x)&0x00000007)<<12)
+#define MCF_GPT_GSR_CAPTURE(x) (((x)&0x0000FFFF)<<16)
+
+/********************************************************************/
+
+#endif /* m548xgpt_h */
diff --git a/arch/m68k/include/asm/m548xsim.h b/arch/m68k/include/asm/m548xsim.h
new file mode 100644
index 000000000000..149135ef30d2
--- /dev/null
+++ b/arch/m68k/include/asm/m548xsim.h
@@ -0,0 +1,55 @@
+/*
+ * m548xsim.h -- ColdFire 547x/548x System Integration Unit support.
+ */
+
+#ifndef m548xsim_h
+#define m548xsim_h
+
+#define MCFINT_VECBASE 64
+
+/*
+ * Interrupt Controller Registers
+ */
+#define MCFICM_INTC0 0x0700 /* Base for Interrupt Ctrl 0 */
+#define MCFINTC_IPRH 0x00 /* Interrupt pending 32-63 */
+#define MCFINTC_IPRL 0x04 /* Interrupt pending 1-31 */
+#define MCFINTC_IMRH 0x08 /* Interrupt mask 32-63 */
+#define MCFINTC_IMRL 0x0c /* Interrupt mask 1-31 */
+#define MCFINTC_INTFRCH 0x10 /* Interrupt force 32-63 */
+#define MCFINTC_INTFRCL 0x14 /* Interrupt force 1-31 */
+#define MCFINTC_IRLR 0x18 /* */
+#define MCFINTC_IACKL 0x19 /* */
+#define MCFINTC_ICR0 0x40 /* Base ICR register */
+
+/*
+ * Define system peripheral IRQ usage.
+ */
+#define MCF_IRQ_TIMER (64 + 54) /* Slice Timer 0 */
+#define MCF_IRQ_PROFILER (64 + 53) /* Slice Timer 1 */
+
+/*
+ * Generic GPIO support
+ */
+#define MCFGPIO_PIN_MAX 0 /* I am too lazy to count */
+#define MCFGPIO_IRQ_MAX -1
+#define MCFGPIO_IRQ_VECBASE -1
+
+/*
+ * Some PSC related definitions
+ */
+#define MCF_PAR_PSC(x) (0x000A4F-((x)&0x3))
+#define MCF_PAR_SDA (0x0008)
+#define MCF_PAR_SCL (0x0004)
+#define MCF_PAR_PSC_TXD (0x04)
+#define MCF_PAR_PSC_RXD (0x08)
+#define MCF_PAR_PSC_RTS(x) (((x)&0x03)<<4)
+#define MCF_PAR_PSC_CTS(x) (((x)&0x03)<<6)
+#define MCF_PAR_PSC_CTS_GPIO (0x00)
+#define MCF_PAR_PSC_CTS_BCLK (0x80)
+#define MCF_PAR_PSC_CTS_CTS (0xC0)
+#define MCF_PAR_PSC_RTS_GPIO (0x00)
+#define MCF_PAR_PSC_RTS_FSYNC (0x20)
+#define MCF_PAR_PSC_RTS_RTS (0x30)
+#define MCF_PAR_PSC_CANRX (0x40)
+
+#endif /* m548xsim_h */
diff --git a/arch/m68k/include/asm/machdep.h b/arch/m68k/include/asm/machdep.h
index fc24b6fc5508..789f3b2de0e9 100644
--- a/arch/m68k/include/asm/machdep.h
+++ b/arch/m68k/include/asm/machdep.h
@@ -1,5 +1,44 @@
-#ifdef __uClinux__
-#include "machdep_no.h"
-#else
-#include "machdep_mm.h"
-#endif
+#ifndef _M68K_MACHDEP_H
+#define _M68K_MACHDEP_H
+
+#include <linux/seq_file.h>
+#include <linux/interrupt.h>
+
+struct pt_regs;
+struct mktime;
+struct rtc_time;
+struct rtc_pll_info;
+struct buffer_head;
+
+extern void (*mach_sched_init) (irq_handler_t handler);
+/* machine dependent irq functions */
+extern void (*mach_init_IRQ) (void);
+extern void (*mach_get_model) (char *model);
+extern void (*mach_get_hardware_list) (struct seq_file *m);
+/* machine dependent timer functions */
+extern unsigned long (*mach_gettimeoffset)(void);
+extern int (*mach_hwclk)(int, struct rtc_time*);
+extern unsigned int (*mach_get_ss)(void);
+extern int (*mach_get_rtc_pll)(struct rtc_pll_info *);
+extern int (*mach_set_rtc_pll)(struct rtc_pll_info *);
+extern int (*mach_set_clock_mmss)(unsigned long);
+extern void (*mach_gettod)(int *year, int *mon, int *day, int *hour,
+ int *min, int *sec);
+extern void (*mach_reset)( void );
+extern void (*mach_halt)( void );
+extern void (*mach_power_off)( void );
+extern unsigned long (*mach_hd_init) (unsigned long, unsigned long);
+extern void (*mach_hd_setup)(char *, int *);
+extern long mach_max_dma_address;
+extern void (*mach_heartbeat) (int);
+extern void (*mach_l2_flush) (int);
+extern void (*mach_beep) (unsigned int, unsigned int);
+
+/* Hardware clock functions */
+extern void hw_timer_init(void);
+extern unsigned long hw_timer_offset(void);
+extern irqreturn_t arch_timer_interrupt(int irq, void *dummy);
+
+extern void config_BSP(char *command, int len);
+
+#endif /* _M68K_MACHDEP_H */
diff --git a/arch/m68k/include/asm/machdep_mm.h b/arch/m68k/include/asm/machdep_mm.h
deleted file mode 100644
index 5637dcef314e..000000000000
--- a/arch/m68k/include/asm/machdep_mm.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef _M68K_MACHDEP_H
-#define _M68K_MACHDEP_H
-
-#include <linux/seq_file.h>
-#include <linux/interrupt.h>
-
-struct pt_regs;
-struct mktime;
-struct rtc_time;
-struct rtc_pll_info;
-struct buffer_head;
-
-extern void (*mach_sched_init) (irq_handler_t handler);
-/* machine dependent irq functions */
-extern void (*mach_init_IRQ) (void);
-extern void (*mach_get_model) (char *model);
-extern void (*mach_get_hardware_list) (struct seq_file *m);
-/* machine dependent timer functions */
-extern unsigned long (*mach_gettimeoffset)(void);
-extern int (*mach_hwclk)(int, struct rtc_time*);
-extern unsigned int (*mach_get_ss)(void);
-extern int (*mach_get_rtc_pll)(struct rtc_pll_info *);
-extern int (*mach_set_rtc_pll)(struct rtc_pll_info *);
-extern int (*mach_set_clock_mmss)(unsigned long);
-extern void (*mach_reset)( void );
-extern void (*mach_halt)( void );
-extern void (*mach_power_off)( void );
-extern unsigned long (*mach_hd_init) (unsigned long, unsigned long);
-extern void (*mach_hd_setup)(char *, int *);
-extern long mach_max_dma_address;
-extern void (*mach_heartbeat) (int);
-extern void (*mach_l2_flush) (int);
-extern void (*mach_beep) (unsigned int, unsigned int);
-
-#endif /* _M68K_MACHDEP_H */
diff --git a/arch/m68k/include/asm/machdep_no.h b/arch/m68k/include/asm/machdep_no.h
deleted file mode 100644
index de9f47a51cc2..000000000000
--- a/arch/m68k/include/asm/machdep_no.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef _M68KNOMMU_MACHDEP_H
-#define _M68KNOMMU_MACHDEP_H
-
-#include <linux/interrupt.h>
-
-/* Hardware clock functions */
-extern void hw_timer_init(void);
-extern unsigned long hw_timer_offset(void);
-
-extern irqreturn_t arch_timer_interrupt(int irq, void *dummy);
-
-/* Machine dependent time handling */
-extern void (*mach_gettod)(int *year, int *mon, int *day, int *hour,
- int *min, int *sec);
-extern int (*mach_set_clock_mmss)(unsigned long);
-
-/* machine dependent power off functions */
-extern void (*mach_reset)( void );
-extern void (*mach_halt)( void );
-extern void (*mach_power_off)( void );
-
-extern void config_BSP(char *command, int len);
-
-extern void do_IRQ(int irq, struct pt_regs *fp);
-
-#endif /* _M68KNOMMU_MACHDEP_H */
diff --git a/arch/m68k/include/asm/mcfcache.h b/arch/m68k/include/asm/mcfcache.h
index c042634fadaa..f49dfc09f70a 100644
--- a/arch/m68k/include/asm/mcfcache.h
+++ b/arch/m68k/include/asm/mcfcache.h
@@ -107,7 +107,7 @@
.endm
#endif /* CONFIG_M532x */
-#if defined(CONFIG_M5407)
+#if defined(CONFIG_M5407) || defined(CONFIG_M548x)
/*
* Version 4 cores have a true harvard style separate instruction
* and data cache. Invalidate and enable cache, also enable write
diff --git a/arch/m68k/include/asm/mcfsim.h b/arch/m68k/include/asm/mcfsim.h
index 9c70a67bf85f..6901fd68165b 100644
--- a/arch/m68k/include/asm/mcfsim.h
+++ b/arch/m68k/include/asm/mcfsim.h
@@ -41,6 +41,8 @@
#elif defined(CONFIG_M5407)
#include <asm/m5407sim.h>
#include <asm/mcfintc.h>
+#elif defined(CONFIG_M548x)
+#include <asm/m548xsim.h>
#endif
/****************************************************************************/
diff --git a/arch/m68k/include/asm/mcfslt.h b/arch/m68k/include/asm/mcfslt.h
new file mode 100644
index 000000000000..d0d0ecba5333
--- /dev/null
+++ b/arch/m68k/include/asm/mcfslt.h
@@ -0,0 +1,44 @@
+/****************************************************************************/
+
+/*
+ * mcfslt.h -- ColdFire internal Slice (SLT) timer support defines.
+ *
+ * (C) Copyright 2004, Greg Ungerer (gerg@snapgear.com)
+ * (C) Copyright 2009, Philippe De Muyter (phdm@macqel.be)
+ */
+
+/****************************************************************************/
+#ifndef mcfslt_h
+#define mcfslt_h
+/****************************************************************************/
+
+/*
+ * Get address specific defines for the 547x.
+ */
+#define MCFSLT_TIMER0 0x900 /* Base address of TIMER0 */
+#define MCFSLT_TIMER1 0x910 /* Base address of TIMER1 */
+
+
+/*
+ * Define the SLT timer register set addresses.
+ */
+#define MCFSLT_STCNT 0x00 /* Terminal count */
+#define MCFSLT_SCR 0x04 /* Control */
+#define MCFSLT_SCNT 0x08 /* Current count */
+#define MCFSLT_SSR 0x0C /* Status */
+
+/*
+ * Bit definitions for the SCR control register.
+ */
+#define MCFSLT_SCR_RUN 0x04000000 /* Run mode (continuous) */
+#define MCFSLT_SCR_IEN 0x02000000 /* Interrupt enable */
+#define MCFSLT_SCR_TEN 0x01000000 /* Timer enable */
+
+/*
+ * Bit definitions for the SSR status register.
+ */
+#define MCFSLT_SSR_BE 0x02000000 /* Bus error condition */
+#define MCFSLT_SSR_TE 0x01000000 /* Timeout condition */
+
+/****************************************************************************/
+#endif /* mcfslt_h */
diff --git a/arch/m68k/include/asm/mcfuart.h b/arch/m68k/include/asm/mcfuart.h
index 01a8716c5fc5..db72e2b889ca 100644
--- a/arch/m68k/include/asm/mcfuart.h
+++ b/arch/m68k/include/asm/mcfuart.h
@@ -47,6 +47,11 @@
#define MCFUART_BASE1 0xfc060000 /* Base address of UART1 */
#define MCFUART_BASE2 0xfc064000 /* Base address of UART2 */
#define MCFUART_BASE3 0xfc068000 /* Base address of UART3 */
+#elif defined(CONFIG_M548x)
+#define MCFUART_BASE1 0x8600 /* on M548x */
+#define MCFUART_BASE2 0x8700 /* on M548x */
+#define MCFUART_BASE3 0x8800 /* on M548x */
+#define MCFUART_BASE4 0x8900 /* on M548x */
#endif
@@ -212,7 +217,9 @@ struct mcf_platform_uart {
#define MCFUART_URF_RXS 0xc0 /* Receiver status */
#endif
-#if defined(CONFIG_M5272)
+#if defined(CONFIG_M548x)
+#define MCFUART_TXFIFOSIZE 512
+#elif defined(CONFIG_M5272)
#define MCFUART_TXFIFOSIZE 25
#else
#define MCFUART_TXFIFOSIZE 1
diff --git a/arch/m68k/include/asm/page.h b/arch/m68k/include/asm/page.h
index f2b4480cc98a..dfebb7c1e379 100644
--- a/arch/m68k/include/asm/page.h
+++ b/arch/m68k/include/asm/page.h
@@ -1,5 +1,49 @@
-#ifdef __uClinux__
-#include "page_no.h"
+#ifndef _M68K_PAGE_H
+#define _M68K_PAGE_H
+
+#include <linux/const.h>
+#include <asm/setup.h>
+#include <asm/page_offset.h>
+
+/* PAGE_SHIFT determines the page size */
+#ifndef CONFIG_SUN3
+#define PAGE_SHIFT (12)
#else
+#define PAGE_SHIFT (13)
+#endif
+#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
+#define PAGE_MASK (~(PAGE_SIZE-1))
+#define PAGE_OFFSET (PAGE_OFFSET_RAW)
+
+#ifndef __ASSEMBLY__
+
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { unsigned long pte; } pte_t;
+typedef struct { unsigned long pmd[16]; } pmd_t;
+typedef struct { unsigned long pgd; } pgd_t;
+typedef struct { unsigned long pgprot; } pgprot_t;
+typedef struct page *pgtable_t;
+
+#define pte_val(x) ((x).pte)
+#define pmd_val(x) ((&x)->pmd[0])
+#define pgd_val(x) ((x).pgd)
+#define pgprot_val(x) ((x).pgprot)
+
+#define __pte(x) ((pte_t) { (x) } )
+#define __pmd(x) ((pmd_t) { (x) } )
+#define __pgd(x) ((pgd_t) { (x) } )
+#define __pgprot(x) ((pgprot_t) { (x) } )
+
+#endif /* !__ASSEMBLY__ */
+
+#ifdef CONFIG_MMU
#include "page_mm.h"
+#else
+#include "page_no.h"
#endif
+
+#include <asm-generic/getorder.h>
+
+#endif /* _M68K_PAGE_H */
diff --git a/arch/m68k/include/asm/page_mm.h b/arch/m68k/include/asm/page_mm.h
index d009f3ea39ab..31d5570d6567 100644
--- a/arch/m68k/include/asm/page_mm.h
+++ b/arch/m68k/include/asm/page_mm.h
@@ -1,29 +1,9 @@
-#ifndef _M68K_PAGE_H
-#define _M68K_PAGE_H
-
-#include <linux/const.h>
-
-/* PAGE_SHIFT determines the page size */
-#ifndef CONFIG_SUN3
-#define PAGE_SHIFT (12)
-#else
-#define PAGE_SHIFT (13)
-#endif
-#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
-#define PAGE_MASK (~(PAGE_SIZE-1))
-
-#include <asm/setup.h>
-
-#if PAGE_SHIFT < 13
-#define THREAD_SIZE (8192)
-#else
-#define THREAD_SIZE PAGE_SIZE
-#endif
+#ifndef _M68K_PAGE_MM_H
+#define _M68K_PAGE_MM_H
#ifndef __ASSEMBLY__
#include <linux/compiler.h>
-
#include <asm/module.h>
#define get_user_page(vaddr) __get_free_page(GFP_KERNEL)
@@ -84,33 +64,6 @@ static inline void clear_page(void *page)
flush_dcache_page(page); \
} while (0)
-/*
- * These are used to make use of C type-checking..
- */
-typedef struct { unsigned long pte; } pte_t;
-typedef struct { unsigned long pmd[16]; } pmd_t;
-typedef struct { unsigned long pgd; } pgd_t;
-typedef struct { unsigned long pgprot; } pgprot_t;
-typedef struct page *pgtable_t;
-
-#define pte_val(x) ((x).pte)
-#define pmd_val(x) ((&x)->pmd[0])
-#define pgd_val(x) ((x).pgd)
-#define pgprot_val(x) ((x).pgprot)
-
-#define __pte(x) ((pte_t) { (x) } )
-#define __pmd(x) ((pmd_t) { (x) } )
-#define __pgd(x) ((pgd_t) { (x) } )
-#define __pgprot(x) ((pgprot_t) { (x) } )
-
-#endif /* !__ASSEMBLY__ */
-
-#include <asm/page_offset.h>
-
-#define PAGE_OFFSET (PAGE_OFFSET_RAW)
-
-#ifndef __ASSEMBLY__
-
extern unsigned long m68k_memoffset;
#ifndef CONFIG_SUN3
@@ -127,7 +80,7 @@ static inline unsigned long ___pa(void *vaddr)
: "0" (vaddr), "i" (m68k_fixup_memoffset));
return paddr;
}
-#define __pa(vaddr) ___pa((void *)(vaddr))
+#define __pa(vaddr) ___pa((void *)(long)(vaddr))
static inline void *__va(unsigned long paddr)
{
void *vaddr;
@@ -223,6 +176,4 @@ static inline __attribute_const__ int __virt_to_node_shift(void)
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-#include <asm-generic/getorder.h>
-
-#endif /* _M68K_PAGE_H */
+#endif /* _M68K_PAGE_MM_H */
diff --git a/arch/m68k/include/asm/page_no.h b/arch/m68k/include/asm/page_no.h
index 8029a33e03c3..90595721185f 100644
--- a/arch/m68k/include/asm/page_no.h
+++ b/arch/m68k/include/asm/page_no.h
@@ -1,18 +1,11 @@
-#ifndef _M68KNOMMU_PAGE_H
-#define _M68KNOMMU_PAGE_H
-
-#include <linux/const.h>
-
-/* PAGE_SHIFT determines the page size */
-
-#define PAGE_SHIFT (12)
-#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
-#define PAGE_MASK (~(PAGE_SIZE-1))
-
-#include <asm/setup.h>
+#ifndef _M68K_PAGE_NO_H
+#define _M68K_PAGE_NO_H
#ifndef __ASSEMBLY__
+extern unsigned long memory_start;
+extern unsigned long memory_end;
+
#define get_user_page(vaddr) __get_free_page(GFP_KERNEL)
#define free_user_page(page, addr) free_page(addr)
@@ -26,36 +19,6 @@
alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr)
#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
-/*
- * These are used to make use of C type-checking..
- */
-typedef struct { unsigned long pte; } pte_t;
-typedef struct { unsigned long pmd[16]; } pmd_t;
-typedef struct { unsigned long pgd; } pgd_t;
-typedef struct { unsigned long pgprot; } pgprot_t;
-typedef struct page *pgtable_t;
-
-#define pte_val(x) ((x).pte)
-#define pmd_val(x) ((&x)->pmd[0])
-#define pgd_val(x) ((x).pgd)
-#define pgprot_val(x) ((x).pgprot)
-
-#define __pte(x) ((pte_t) { (x) } )
-#define __pmd(x) ((pmd_t) { (x) } )
-#define __pgd(x) ((pgd_t) { (x) } )
-#define __pgprot(x) ((pgprot_t) { (x) } )
-
-extern unsigned long memory_start;
-extern unsigned long memory_end;
-
-#endif /* !__ASSEMBLY__ */
-
-#include <asm/page_offset.h>
-
-#define PAGE_OFFSET (PAGE_OFFSET_RAW)
-
-#ifndef __ASSEMBLY__
-
#define __pa(vaddr) ((unsigned long)(vaddr))
#define __va(paddr) ((void *)(paddr))
@@ -74,6 +37,4 @@ extern unsigned long memory_end;
#endif /* __ASSEMBLY__ */
-#include <asm-generic/getorder.h>
-
-#endif /* _M68KNOMMU_PAGE_H */
+#endif /* _M68K_PAGE_NO_H */
diff --git a/arch/m68k/include/asm/string.h b/arch/m68k/include/asm/string.h
index 2c356f90f171..2936dda938d7 100644
--- a/arch/m68k/include/asm/string.h
+++ b/arch/m68k/include/asm/string.h
@@ -1,5 +1,133 @@
-#ifdef __uClinux__
-#include "string_no.h"
+#ifndef _M68K_STRING_H_
+#define _M68K_STRING_H_
+
+#include <linux/types.h>
+#include <linux/compiler.h>
+
+static inline size_t __kernel_strlen(const char *s)
+{
+ const char *sc;
+
+ for (sc = s; *sc++; )
+ ;
+ return sc - s - 1;
+}
+
+static inline char *__kernel_strcpy(char *dest, const char *src)
+{
+ char *xdest = dest;
+
+ asm volatile ("\n"
+ "1: move.b (%1)+,(%0)+\n"
+ " jne 1b"
+ : "+a" (dest), "+a" (src)
+ : : "memory");
+ return xdest;
+}
+
+#ifndef __IN_STRING_C
+
+#define __HAVE_ARCH_STRLEN
+#define strlen(s) (__builtin_constant_p(s) ? \
+ __builtin_strlen(s) : \
+ __kernel_strlen(s))
+
+#define __HAVE_ARCH_STRNLEN
+static inline size_t strnlen(const char *s, size_t count)
+{
+ const char *sc = s;
+
+ asm volatile ("\n"
+ "1: subq.l #1,%1\n"
+ " jcs 2f\n"
+ " tst.b (%0)+\n"
+ " jne 1b\n"
+ " subq.l #1,%0\n"
+ "2:"
+ : "+a" (sc), "+d" (count));
+ return sc - s;
+}
+
+#define __HAVE_ARCH_STRCPY
+#if __GNUC__ >= 4
+#define strcpy(d, s) (__builtin_constant_p(s) && \
+ __builtin_strlen(s) <= 32 ? \
+ __builtin_strcpy(d, s) : \
+ __kernel_strcpy(d, s))
#else
-#include "string_mm.h"
+#define strcpy(d, s) __kernel_strcpy(d, s)
#endif
+
+#define __HAVE_ARCH_STRNCPY
+static inline char *strncpy(char *dest, const char *src, size_t n)
+{
+ char *xdest = dest;
+
+ asm volatile ("\n"
+ " jra 2f\n"
+ "1: move.b (%1),(%0)+\n"
+ " jeq 2f\n"
+ " addq.l #1,%1\n"
+ "2: subq.l #1,%2\n"
+ " jcc 1b\n"
+ : "+a" (dest), "+a" (src), "+d" (n)
+ : : "memory");
+ return xdest;
+}
+
+#define __HAVE_ARCH_STRCAT
+#define strcat(d, s) ({ \
+ char *__d = (d); \
+ strcpy(__d + strlen(__d), (s)); \
+})
+
+#define __HAVE_ARCH_STRCHR
+static inline char *strchr(const char *s, int c)
+{
+ char sc, ch = c;
+
+ for (; (sc = *s++) != ch; ) {
+ if (!sc)
+ return NULL;
+ }
+ return (char *)s - 1;
+}
+
+#ifndef CONFIG_COLDFIRE
+#define __HAVE_ARCH_STRCMP
+static inline int strcmp(const char *cs, const char *ct)
+{
+ char res;
+
+ asm ("\n"
+ "1: move.b (%0)+,%2\n" /* get *cs */
+ " cmp.b (%1)+,%2\n" /* compare a byte */
+ " jne 2f\n" /* not equal, break out */
+ " tst.b %2\n" /* at end of cs? */
+ " jne 1b\n" /* no, keep going */
+ " jra 3f\n" /* strings are equal */
+ "2: sub.b -(%1),%2\n" /* *cs - *ct */
+ "3:"
+ : "+a" (cs), "+a" (ct), "=d" (res));
+ return res;
+}
+
+#define __HAVE_ARCH_MEMMOVE
+extern void *memmove(void *, const void *, __kernel_size_t);
+
+#define __HAVE_ARCH_MEMCMP
+extern int memcmp(const void *, const void *, __kernel_size_t);
+#define memcmp(d, s, n) __builtin_memcmp(d, s, n)
+#endif /* CONFIG_COLDFIRE */
+
+#define __HAVE_ARCH_MEMSET
+extern void *memset(void *, int, __kernel_size_t);
+#define memset(d, c, n) __builtin_memset(d, c, n)
+
+#define __HAVE_ARCH_MEMCPY
+extern void *memcpy(void *, const void *, __kernel_size_t);
+#define memcpy(d, s, n) __builtin_memcpy(d, s, n)
+
+#endif
+
+#endif /* _M68K_STRING_H_ */
diff --git a/arch/m68k/include/asm/string_mm.h b/arch/m68k/include/asm/string_mm.h
deleted file mode 100644
index 2eb7df1e0f5d..000000000000
--- a/arch/m68k/include/asm/string_mm.h
+++ /dev/null
@@ -1,131 +0,0 @@
-#ifndef _M68K_STRING_H_
-#define _M68K_STRING_H_
-
-#include <linux/types.h>
-#include <linux/compiler.h>
-
-static inline size_t __kernel_strlen(const char *s)
-{
- const char *sc;
-
- for (sc = s; *sc++; )
- ;
- return sc - s - 1;
-}
-
-static inline char *__kernel_strcpy(char *dest, const char *src)
-{
- char *xdest = dest;
-
- asm volatile ("\n"
- "1: move.b (%1)+,(%0)+\n"
- " jne 1b"
- : "+a" (dest), "+a" (src)
- : : "memory");
- return xdest;
-}
-
-#ifndef __IN_STRING_C
-
-#define __HAVE_ARCH_STRLEN
-#define strlen(s) (__builtin_constant_p(s) ? \
- __builtin_strlen(s) : \
- __kernel_strlen(s))
-
-#define __HAVE_ARCH_STRNLEN
-static inline size_t strnlen(const char *s, size_t count)
-{
- const char *sc = s;
-
- asm volatile ("\n"
- "1: subq.l #1,%1\n"
- " jcs 2f\n"
- " tst.b (%0)+\n"
- " jne 1b\n"
- " subq.l #1,%0\n"
- "2:"
- : "+a" (sc), "+d" (count));
- return sc - s;
-}
-
-#define __HAVE_ARCH_STRCPY
-#if __GNUC__ >= 4
-#define strcpy(d, s) (__builtin_constant_p(s) && \
- __builtin_strlen(s) <= 32 ? \
- __builtin_strcpy(d, s) : \
- __kernel_strcpy(d, s))
-#else
-#define strcpy(d, s) __kernel_strcpy(d, s)
-#endif
-
-#define __HAVE_ARCH_STRNCPY
-static inline char *strncpy(char *dest, const char *src, size_t n)
-{
- char *xdest = dest;
-
- asm volatile ("\n"
- " jra 2f\n"
- "1: move.b (%1),(%0)+\n"
- " jeq 2f\n"
- " addq.l #1,%1\n"
- "2: subq.l #1,%2\n"
- " jcc 1b\n"
- : "+a" (dest), "+a" (src), "+d" (n)
- : : "memory");
- return xdest;
-}
-
-#define __HAVE_ARCH_STRCAT
-#define strcat(d, s) ({ \
- char *__d = (d); \
- strcpy(__d + strlen(__d), (s)); \
-})
-
-#define __HAVE_ARCH_STRCHR
-static inline char *strchr(const char *s, int c)
-{
- char sc, ch = c;
-
- for (; (sc = *s++) != ch; ) {
- if (!sc)
- return NULL;
- }
- return (char *)s - 1;
-}
-
-#define __HAVE_ARCH_STRCMP
-static inline int strcmp(const char *cs, const char *ct)
-{
- char res;
-
- asm ("\n"
- "1: move.b (%0)+,%2\n" /* get *cs */
- " cmp.b (%1)+,%2\n" /* compare a byte */
- " jne 2f\n" /* not equal, break out */
- " tst.b %2\n" /* at end of cs? */
- " jne 1b\n" /* no, keep going */
- " jra 3f\n" /* strings are equal */
- "2: sub.b -(%1),%2\n" /* *cs - *ct */
- "3:"
- : "+a" (cs), "+a" (ct), "=d" (res));
- return res;
-}
-
-#define __HAVE_ARCH_MEMSET
-extern void *memset(void *, int, __kernel_size_t);
-#define memset(d, c, n) __builtin_memset(d, c, n)
-
-#define __HAVE_ARCH_MEMCPY
-extern void *memcpy(void *, const void *, __kernel_size_t);
-#define memcpy(d, s, n) __builtin_memcpy(d, s, n)
-
-#define __HAVE_ARCH_MEMMOVE
-extern void *memmove(void *, const void *, __kernel_size_t);
-
-#define __HAVE_ARCH_MEMCMP
-extern int memcmp(const void *, const void *, __kernel_size_t);
-#define memcmp(d, s, n) __builtin_memcmp(d, s, n)
-
-#endif
-
-#endif /* _M68K_STRING_H_ */
diff --git a/arch/m68k/include/asm/string_no.h b/arch/m68k/include/asm/string_no.h
deleted file mode 100644
index af09e17000fc..000000000000
--- a/arch/m68k/include/asm/string_no.h
+++ /dev/null
@@ -1,126 +0,0 @@
-#ifndef _M68KNOMMU_STRING_H_
-#define _M68KNOMMU_STRING_H_
-
-#ifdef __KERNEL__ /* only set these up for kernel code */
-
-#include <asm/setup.h>
-#include <asm/page.h>
-
-#define __HAVE_ARCH_STRCPY
-static inline char * strcpy(char * dest,const char *src)
-{
- char *xdest = dest;
-
- __asm__ __volatile__
- ("1:\tmoveb %1@+,%0@+\n\t"
- "jne 1b"
- : "=a" (dest), "=a" (src)
- : "0" (dest), "1" (src) : "memory");
- return xdest;
-}
-
-#define __HAVE_ARCH_STRNCPY
-static inline char * strncpy(char *dest, const char *src, size_t n)
-{
- char *xdest = dest;
-
- if (n == 0)
- return xdest;
-
- __asm__ __volatile__
- ("1:\tmoveb %1@+,%0@+\n\t"
- "jeq 2f\n\t"
- "subql #1,%2\n\t"
- "jne 1b\n\t"
- "2:"
- : "=a" (dest), "=a" (src), "=d" (n)
- : "0" (dest), "1" (src), "2" (n)
- : "memory");
- return xdest;
-}
-
-
-#ifndef CONFIG_COLDFIRE
-
-#define __HAVE_ARCH_STRCMP
-static inline int strcmp(const char * cs,const char * ct)
-{
- char __res;
-
- __asm__
- ("1:\tmoveb %0@+,%2\n\t" /* get *cs */
- "cmpb %1@+,%2\n\t" /* compare a byte */
- "jne 2f\n\t" /* not equal, break out */
- "tstb %2\n\t" /* at end of cs? */
- "jne 1b\n\t" /* no, keep going */
- "jra 3f\n\t" /* strings are equal */
- "2:\tsubb %1@-,%2\n\t" /* *cs - *ct */
- "3:"
- : "=a" (cs), "=a" (ct), "=d" (__res)
- : "0" (cs), "1" (ct));
-
- return __res;
-}
-
-#define __HAVE_ARCH_STRNCMP
-static inline int strncmp(const char * cs,const char * ct,size_t count)
-{
- char __res;
-
- if (!count)
- return 0;
- __asm__
- ("1:\tmovb %0@+,%3\n\t" /* get *cs */
- "cmpb %1@+,%3\n\t" /* compare a byte */
- "jne 3f\n\t" /* not equal, break out */
- "tstb %3\n\t" /* at end of cs? */
- "jeq 4f\n\t" /* yes, all done */
- "subql #1,%2\n\t" /* no, adjust count */
- "jne 1b\n\t" /* more to do, keep going */
- "2:\tmoveq #0,%3\n\t" /* strings are equal */
- "jra 4f\n\t"
- "3:\tsubb %1@-,%3\n\t" /* *cs - *ct */
- "4:"
- : "=a" (cs), "=a" (ct), "=d" (count), "=d" (__res)
- : "0" (cs), "1" (ct), "2" (count));
- return __res;
-}
-
-#endif /* CONFIG_COLDFIRE */
-
-#define __HAVE_ARCH_MEMSET
-extern void * memset(void * s, int c, size_t count);
-
-#define __HAVE_ARCH_MEMCPY
-extern void * memcpy(void *d, const void *s, size_t count);
-
-#else /* KERNEL */
-
-/*
- * let user libraries deal with these,
- * IMHO the kernel has no place defining these functions for user apps
- */
-
-#define __HAVE_ARCH_STRCPY 1
-#define __HAVE_ARCH_STRNCPY 1
-#define __HAVE_ARCH_STRCAT 1
-#define __HAVE_ARCH_STRNCAT 1
-#define __HAVE_ARCH_STRCMP 1
-#define __HAVE_ARCH_STRNCMP 1
-#define __HAVE_ARCH_STRNICMP 1
-#define __HAVE_ARCH_STRCHR 1
-#define __HAVE_ARCH_STRRCHR 1
-#define __HAVE_ARCH_STRSTR 1
-#define __HAVE_ARCH_STRLEN 1
-#define __HAVE_ARCH_STRNLEN 1
-#define __HAVE_ARCH_MEMSET 1
-#define __HAVE_ARCH_MEMCPY 1
-#define __HAVE_ARCH_MEMMOVE 1
-#define __HAVE_ARCH_MEMSCAN 1
-#define __HAVE_ARCH_MEMCMP 1
-#define __HAVE_ARCH_MEMCHR 1
-#define __HAVE_ARCH_STRTOK 1
-
-#endif /* KERNEL */
-
-#endif /* _M68K_STRING_H_ */
diff --git a/arch/m68k/include/asm/system_mm.h b/arch/m68k/include/asm/system_mm.h
index dbb6515ffd5b..47b01f4726bc 100644
--- a/arch/m68k/include/asm/system_mm.h
+++ b/arch/m68k/include/asm/system_mm.h
@@ -3,6 +3,7 @@
#include <linux/linkage.h>
#include <linux/kernel.h>
+#include <linux/irqflags.h>
#include <asm/segment.h>
#include <asm/entry.h>
@@ -62,30 +63,6 @@ asmlinkage void resume(void);
#define smp_wmb() barrier()
#define smp_read_barrier_depends() ((void)0)
-/* interrupt control.. */
-#if 0
-#define local_irq_enable() asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory")
-#else
-#include <linux/hardirq.h>
-#define local_irq_enable() ({ \
- if (MACH_IS_Q40 || !hardirq_count()) \
- asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory"); \
-})
-#endif
-#define local_irq_disable() asm volatile ("oriw #0x0700,%%sr": : : "memory")
-#define local_save_flags(x) asm volatile ("movew %%sr,%0":"=d" (x) : : "memory")
-#define local_irq_restore(x) asm volatile ("movew %0,%%sr": :"d" (x) : "memory")
-
-static inline int irqs_disabled(void)
-{
- unsigned long flags;
- local_save_flags(flags);
- return flags & ~ALLOWINT;
-}
-
-/* For spinlocks etc */
-#define local_irq_save(x) ({ local_save_flags(x); local_irq_disable(); })
-
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
struct __xchg_dummy { unsigned long a[100]; };
@@ -205,9 +182,7 @@ static inline unsigned long __cmpxchg(volatile void *p, unsigned long old,
((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\
(unsigned long)(n), sizeof(*(ptr))))
-#ifndef CONFIG_SMP
#include <asm-generic/cmpxchg.h>
-#endif
#endif
diff --git a/arch/m68k/include/asm/system_no.h b/arch/m68k/include/asm/system_no.h
index 3c0718d74398..6fe9f93bc3ff 100644
--- a/arch/m68k/include/asm/system_no.h
+++ b/arch/m68k/include/asm/system_no.h
@@ -2,6 +2,7 @@
#define _M68KNOMMU_SYSTEM_H
#include <linux/linkage.h>
+#include <linux/irqflags.h>
#include <asm/segment.h>
#include <asm/entry.h>
@@ -46,54 +47,6 @@ asmlinkage void resume(void);
(last) = _last; \
}
-#ifdef CONFIG_COLDFIRE
-#define local_irq_enable() __asm__ __volatile__ ( \
- "move %/sr,%%d0\n\t" \
- "andi.l #0xf8ff,%%d0\n\t" \
- "move %%d0,%/sr\n" \
- : /* no outputs */ \
- : \
- : "cc", "%d0", "memory")
-#define local_irq_disable() __asm__ __volatile__ ( \
- "move %/sr,%%d0\n\t" \
- "ori.l #0x0700,%%d0\n\t" \
- "move %%d0,%/sr\n" \
- : /* no outputs */ \
- : \
- : "cc", "%d0", "memory")
-/* For spinlocks etc */
-#define local_irq_save(x) __asm__ __volatile__ ( \
- "movew %%sr,%0\n\t" \
- "movew #0x0700,%%d0\n\t" \
- "or.l %0,%%d0\n\t" \
- "movew %%d0,%/sr" \
- : "=d" (x) \
- : \
- : "cc", "%d0", "memory")
-#else
-
-/* portable version */ /* FIXME - see entry.h*/
-#define ALLOWINT 0xf8ff
-
-#define local_irq_enable() asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory")
-#define local_irq_disable() asm volatile ("oriw #0x0700,%%sr": : : "memory")
-#endif
-
-#define local_save_flags(x) asm volatile ("movew %%sr,%0":"=d" (x) : : "memory")
-#define local_irq_restore(x) asm volatile ("movew %0,%%sr": :"d" (x) : "memory")
-
-/* For spinlocks etc */
-#ifndef local_irq_save
-#define local_irq_save(x) do { local_save_flags(x); local_irq_disable(); } while (0)
-#endif
-
-#define irqs_disabled() \
-({ \
- unsigned long flags; \
- local_save_flags(flags); \
- ((flags & 0x0700) == 0x0700); \
-})
-
#define iret() __asm__ __volatile__ ("rte": : :"memory", "sp", "cc")
/*
@@ -106,17 +59,10 @@ asmlinkage void resume(void);
#define wmb() asm volatile ("" : : :"memory")
#define set_mb(var, value) ({ (var) = (value); wmb(); })
-#ifdef CONFIG_SMP
-#define smp_mb() mb()
-#define smp_rmb() rmb()
-#define smp_wmb() wmb()
-#define smp_read_barrier_depends() read_barrier_depends()
-#else
#define smp_mb() barrier()
#define smp_rmb() barrier()
#define smp_wmb() barrier()
#define smp_read_barrier_depends() do { } while(0)
-#endif
#define read_barrier_depends() ((void)0)
@@ -199,19 +145,9 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz
(unsigned long)(n), sizeof(*(ptr))))
#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
-#ifndef CONFIG_SMP
#include <asm-generic/cmpxchg.h>
-#endif
#define arch_align_stack(x) (x)
-static inline int irqs_disabled_flags(unsigned long flags)
-{
- if (flags & 0x0700)
- return 0;
- else
- return 1;
-}
-
#endif /* _M68KNOMMU_SYSTEM_H */
diff --git a/arch/m68k/include/asm/thread_info.h b/arch/m68k/include/asm/thread_info.h
index f31a3f42b7b3..1da5d53a00eb 100644
--- a/arch/m68k/include/asm/thread_info.h
+++ b/arch/m68k/include/asm/thread_info.h
@@ -1,5 +1,108 @@
-#ifdef __uClinux__
-#include "thread_info_no.h"
+#ifndef _ASM_M68K_THREAD_INFO_H
+#define _ASM_M68K_THREAD_INFO_H
+
+#include <asm/types.h>
+#include <asm/page.h>
+
+/*
+ * On machines with 4k pages we default to an 8k thread size, though we
+ * allow a 4k with config option. Any other machine page size then
+ * the thread size must match the page size (which is 8k and larger here).
+ */
+#if PAGE_SHIFT < 13
+#ifdef CONFIG_4KSTACKS
+#define THREAD_SIZE 4096
#else
-#include "thread_info_mm.h"
+#define THREAD_SIZE 8192
#endif
+#else
+#define THREAD_SIZE PAGE_SIZE
+#endif
+#define THREAD_SIZE_ORDER ((THREAD_SIZE / PAGE_SIZE) - 1)
+
+#ifndef __ASSEMBLY__
+
+struct thread_info {
+ struct task_struct *task; /* main task structure */
+ unsigned long flags;
+ struct exec_domain *exec_domain; /* execution domain */
+ int preempt_count; /* 0 => preemptable, <0 => BUG */
+ __u32 cpu; /* should always be 0 on m68k */
+ unsigned long tp_value; /* thread pointer */
+ struct restart_block restart_block;
+};
+#endif /* __ASSEMBLY__ */
+
+#define PREEMPT_ACTIVE 0x4000000
+
+#define INIT_THREAD_INFO(tsk) \
+{ \
+ .task = &tsk, \
+ .exec_domain = &default_exec_domain, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
+ .restart_block = { \
+ .fn = do_no_restart_syscall, \
+ }, \
+}
+
+#define init_stack (init_thread_union.stack)
+
+#ifdef CONFIG_MMU
+
+#ifndef __ASSEMBLY__
+#include <asm/current.h>
+#endif
+
+#ifdef ASM_OFFSETS_C
+#define task_thread_info(tsk) ((struct thread_info *) NULL)
+#else
+#include <asm/asm-offsets.h>
+#define task_thread_info(tsk) ((struct thread_info *)((char *)tsk+TASK_TINFO))
+#endif
+
+#define init_thread_info (init_task.thread.info)
+#define task_stack_page(tsk) ((tsk)->stack)
+#define current_thread_info() task_thread_info(current)
+
+#define __HAVE_THREAD_FUNCTIONS
+
+#define setup_thread_stack(p, org) ({ \
+ *(struct task_struct **)(p)->stack = (p); \
+ task_thread_info(p)->task = (p); \
+})
+
+#define end_of_stack(p) ((unsigned long *)(p)->stack + 1)
+
+#else /* !CONFIG_MMU */
+
+#ifndef __ASSEMBLY__
+/* how to get the thread information struct from C */
+static inline struct thread_info *current_thread_info(void)
+{
+ struct thread_info *ti;
+ __asm__(
+ "move.l %%sp, %0 \n\t"
+ "and.l %1, %0"
+ : "=&d"(ti)
+ : "di" (~(THREAD_SIZE-1))
+ );
+ return ti;
+}
+#endif
+
+#define init_thread_info (init_thread_union.thread_info)
+
+#endif /* CONFIG_MMU */
+
+/* entry.S relies on these definitions!
+ * bits 0-7 are tested at every exception exit
+ * bits 8-15 are also tested at syscall exit
+ */
+#define TIF_SIGPENDING 6 /* signal pending */
+#define TIF_NEED_RESCHED 7 /* rescheduling necessary */
+#define TIF_DELAYED_TRACE 14 /* single step a syscall */
+#define TIF_SYSCALL_TRACE 15 /* syscall trace active */
+#define TIF_MEMDIE 16 /* is terminating due to OOM killer */
+#define TIF_FREEZE 17 /* thread is freezing for suspend */
+
+#endif /* _ASM_M68K_THREAD_INFO_H */
diff --git a/arch/m68k/include/asm/thread_info_mm.h b/arch/m68k/include/asm/thread_info_mm.h
deleted file mode 100644
index 3bf31dc51b12..000000000000
--- a/arch/m68k/include/asm/thread_info_mm.h
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef _ASM_M68K_THREAD_INFO_H
-#define _ASM_M68K_THREAD_INFO_H
-
-#ifndef ASM_OFFSETS_C
-#include <asm/asm-offsets.h>
-#endif
-#include <asm/types.h>
-#include <asm/page.h>
-
-#ifndef __ASSEMBLY__
-#include <asm/current.h>
-
-struct thread_info {
- struct task_struct *task; /* main task structure */
- unsigned long flags;
- struct exec_domain *exec_domain; /* execution domain */
- int preempt_count; /* 0 => preemptable, <0 => BUG */
- __u32 cpu; /* should always be 0 on m68k */
- unsigned long tp_value; /* thread pointer */
- struct restart_block restart_block;
-};
-#endif /* __ASSEMBLY__ */
-
-#define PREEMPT_ACTIVE 0x4000000
-
-#define INIT_THREAD_INFO(tsk) \
-{ \
- .task = &tsk, \
- .exec_domain = &default_exec_domain, \
- .preempt_count = INIT_PREEMPT_COUNT, \
- .restart_block = { \
- .fn = do_no_restart_syscall, \
- }, \
-}
-
-/* THREAD_SIZE should be 8k, so handle differently for 4k and 8k machines */
-#define THREAD_SIZE_ORDER (13 - PAGE_SHIFT)
-
-#define init_thread_info (init_task.thread.info)
-#define init_stack (init_thread_union.stack)
-
-#ifdef ASM_OFFSETS_C
-#define task_thread_info(tsk) ((struct thread_info *) NULL)
-#else
-#define task_thread_info(tsk) ((struct thread_info *)((char *)tsk+TASK_TINFO))
-#endif
-
-#define task_stack_page(tsk) ((tsk)->stack)
-#define current_thread_info() task_thread_info(current)
-
-#define __HAVE_THREAD_FUNCTIONS
-
-#define setup_thread_stack(p, org) ({ \
- *(struct task_struct **)(p)->stack = (p); \
- task_thread_info(p)->task = (p); \
-})
-
-#define end_of_stack(p) ((unsigned long *)(p)->stack + 1)
-
-/* entry.S relies on these definitions!
- * bits 0-7 are tested at every exception exit
- * bits 8-15 are also tested at syscall exit
- */
-#define TIF_SIGPENDING 6 /* signal pending */
-#define TIF_NEED_RESCHED 7 /* rescheduling necessary */
-#define TIF_DELAYED_TRACE 14 /* single step a syscall */
-#define TIF_SYSCALL_TRACE 15 /* syscall trace active */
-#define TIF_MEMDIE 16 /* is terminating due to OOM killer */
-#define TIF_FREEZE 17 /* thread is freezing for suspend */
-
-#endif /* _ASM_M68K_THREAD_INFO_H */
diff --git a/arch/m68k/include/asm/thread_info_no.h b/arch/m68k/include/asm/thread_info_no.h
deleted file mode 100644
index 51f354b672e6..000000000000
--- a/arch/m68k/include/asm/thread_info_no.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/* thread_info.h: m68knommu low-level thread information
- * adapted from the i386 and PPC versions by Greg Ungerer (gerg@snapgear.com)
- *
- * Copyright (C) 2002 David Howells (dhowells@redhat.com)
- * - Incorporating suggestions made by Linus Torvalds and Dave Miller
- */
-
-#ifndef _ASM_THREAD_INFO_H
-#define _ASM_THREAD_INFO_H
-
-#include <asm/page.h>
-
-#ifdef __KERNEL__
-
-/*
- * Size of kernel stack for each process. This must be a power of 2...
- */
-#ifdef CONFIG_4KSTACKS
-#define THREAD_SIZE_ORDER (0)
-#else
-#define THREAD_SIZE_ORDER (1)
-#endif
-
-/*
- * for asm files, THREAD_SIZE is now generated by asm-offsets.c
- */
-#define THREAD_SIZE (PAGE_SIZE<<THREAD_SIZE_ORDER)
-
-#ifndef __ASSEMBLY__
-
-/*
- * low level task data.
- */
-struct thread_info {
- struct task_struct *task; /* main task structure */
- struct exec_domain *exec_domain; /* execution domain */
- unsigned long flags; /* low level flags */
- int cpu; /* cpu we're on */
- int preempt_count; /* 0 => preemptable, <0 => BUG */
- unsigned long tp_value; /* thread pointer */
- struct restart_block restart_block;
-};
-
-/*
- * macros/functions for gaining access to the thread information structure
- */
-#define INIT_THREAD_INFO(tsk) \
-{ \
- .task = &tsk, \
- .exec_domain = &default_exec_domain, \
- .flags = 0, \
- .cpu = 0, \
- .preempt_count = INIT_PREEMPT_COUNT, \
- .restart_block = { \
- .fn = do_no_restart_syscall, \
- }, \
-}
-
-#define init_thread_info (init_thread_union.thread_info)
-#define init_stack (init_thread_union.stack)
-
-
-/* how to get the thread information struct from C */
-static inline struct thread_info *current_thread_info(void)
-{
- struct thread_info *ti;
- __asm__(
- "move.l %%sp, %0 \n\t"
- "and.l %1, %0"
- : "=&d"(ti)
- : "di" (~(THREAD_SIZE-1))
- );
- return ti;
-}
-
-#endif /* __ASSEMBLY__ */
-
-#define PREEMPT_ACTIVE 0x4000000
-
-/*
- * thread information flag bit numbers
- */
-#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
-#define TIF_SIGPENDING 1 /* signal pending */
-#define TIF_NEED_RESCHED 2 /* rescheduling necessary */
-#define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling
- TIF_NEED_RESCHED */
-#define TIF_MEMDIE 4 /* is terminating due to OOM killer */
-#define TIF_FREEZE 16 /* is freezing for suspend */
-
-/* as above, but as bit values */
-#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
-#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
-#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
-#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
-#define _TIF_FREEZE (1<<TIF_FREEZE)
-
-#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */
-
-#endif /* __KERNEL__ */
-
-#endif /* _ASM_THREAD_INFO_H */
diff --git a/arch/m68k/include/asm/traps.h b/arch/m68k/include/asm/traps.h
index 3011ec0f5365..0bffb17d5db7 100644
--- a/arch/m68k/include/asm/traps.h
+++ b/arch/m68k/include/asm/traps.h
@@ -1,5 +1,272 @@
-#ifdef __uClinux__
-#include "traps_no.h"
-#else
-#include "traps_mm.h"
+/*
+ * linux/include/asm/traps.h
+ *
+ * Copyright (C) 1993 Hamish Macdonald
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _M68K_TRAPS_H
+#define _M68K_TRAPS_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/linkage.h>
+#include <asm/ptrace.h>
+
+typedef void (*e_vector)(void);
+extern e_vector vectors[];
+
+asmlinkage void auto_inthandler(void);
+asmlinkage void user_inthandler(void);
+asmlinkage void bad_inthandler(void);
+extern void init_vectors(void);
+
#endif
+
+#define VEC_RESETSP (0)
+#define VEC_RESETPC (1)
+#define VEC_BUSERR (2)
+#define VEC_ADDRERR (3)
+#define VEC_ILLEGAL (4)
+#define VEC_ZERODIV (5)
+#define VEC_CHK (6)
+#define VEC_TRAP (7)
+#define VEC_PRIV (8)
+#define VEC_TRACE (9)
+#define VEC_LINE10 (10)
+#define VEC_LINE11 (11)
+#define VEC_RESV12 (12)
+#define VEC_COPROC (13)
+#define VEC_FORMAT (14)
+#define VEC_UNINT (15)
+#define VEC_RESV16 (16)
+#define VEC_RESV17 (17)
+#define VEC_RESV18 (18)
+#define VEC_RESV19 (19)
+#define VEC_RESV20 (20)
+#define VEC_RESV21 (21)
+#define VEC_RESV22 (22)
+#define VEC_RESV23 (23)
+#define VEC_SPUR (24)
+#define VEC_INT1 (25)
+#define VEC_INT2 (26)
+#define VEC_INT3 (27)
+#define VEC_INT4 (28)
+#define VEC_INT5 (29)
+#define VEC_INT6 (30)
+#define VEC_INT7 (31)
+#define VEC_SYS (32)
+#define VEC_TRAP1 (33)
+#define VEC_TRAP2 (34)
+#define VEC_TRAP3 (35)
+#define VEC_TRAP4 (36)
+#define VEC_TRAP5 (37)
+#define VEC_TRAP6 (38)
+#define VEC_TRAP7 (39)
+#define VEC_TRAP8 (40)
+#define VEC_TRAP9 (41)
+#define VEC_TRAP10 (42)
+#define VEC_TRAP11 (43)
+#define VEC_TRAP12 (44)
+#define VEC_TRAP13 (45)
+#define VEC_TRAP14 (46)
+#define VEC_TRAP15 (47)
+#define VEC_FPBRUC (48)
+#define VEC_FPIR (49)
+#define VEC_FPDIVZ (50)
+#define VEC_FPUNDER (51)
+#define VEC_FPOE (52)
+#define VEC_FPOVER (53)
+#define VEC_FPNAN (54)
+#define VEC_FPUNSUP (55)
+#define VEC_MMUCFG (56)
+#define VEC_MMUILL (57)
+#define VEC_MMUACC (58)
+#define VEC_RESV59 (59)
+#define VEC_UNIMPEA (60)
+#define VEC_UNIMPII (61)
+#define VEC_RESV62 (62)
+#define VEC_RESV63 (63)
+#define VEC_USER (64)
+
+#define VECOFF(vec) ((vec)<<2)
+
+#ifndef __ASSEMBLY__
+
+/* Status register bits */
+#define PS_T (0x8000)
+#define PS_S (0x2000)
+#define PS_M (0x1000)
+#define PS_C (0x0001)
+
+/* bits for 68020/68030 special status word */
+
+#define FC (0x8000)
+#define FB (0x4000)
+#define RC (0x2000)
+#define RB (0x1000)
+#define DF (0x0100)
+#define RM (0x0080)
+#define RW (0x0040)
+#define SZ (0x0030)
+#define DFC (0x0007)
+
+/* bits for 68030 MMU status register (mmusr,psr) */
+
+#define MMU_B (0x8000) /* bus error */
+#define MMU_L (0x4000) /* limit violation */
+#define MMU_S (0x2000) /* supervisor violation */
+#define MMU_WP (0x0800) /* write-protected */
+#define MMU_I (0x0400) /* invalid descriptor */
+#define MMU_M (0x0200) /* ATC entry modified */
+#define MMU_T (0x0040) /* transparent translation */
+#define MMU_NUM (0x0007) /* number of levels traversed */
+
+
+/* bits for 68040 special status word */
+#define CP_040 (0x8000)
+#define CU_040 (0x4000)
+#define CT_040 (0x2000)
+#define CM_040 (0x1000)
+#define MA_040 (0x0800)
+#define ATC_040 (0x0400)
+#define LK_040 (0x0200)
+#define RW_040 (0x0100)
+#define SIZ_040 (0x0060)
+#define TT_040 (0x0018)
+#define TM_040 (0x0007)
+
+/* bits for 68040 write back status word */
+#define WBV_040 (0x80)
+#define WBSIZ_040 (0x60)
+#define WBBYT_040 (0x20)
+#define WBWRD_040 (0x40)
+#define WBLNG_040 (0x00)
+#define WBTT_040 (0x18)
+#define WBTM_040 (0x07)
+
+/* bus access size codes */
+#define BA_SIZE_BYTE (0x20)
+#define BA_SIZE_WORD (0x40)
+#define BA_SIZE_LONG (0x00)
+#define BA_SIZE_LINE (0x60)
+
+/* bus access transfer type codes */
+#define BA_TT_MOVE16 (0x08)
+
+/* bits for 68040 MMU status register (mmusr) */
+#define MMU_B_040 (0x0800)
+#define MMU_G_040 (0x0400)
+#define MMU_S_040 (0x0080)
+#define MMU_CM_040 (0x0060)
+#define MMU_M_040 (0x0010)
+#define MMU_WP_040 (0x0004)
+#define MMU_T_040 (0x0002)
+#define MMU_R_040 (0x0001)
+
+/* bits in the 68060 fault status long word (FSLW) */
+#define MMU060_MA (0x08000000) /* misaligned */
+#define MMU060_LK (0x02000000) /* locked transfer */
+#define MMU060_RW (0x01800000) /* read/write */
+# define MMU060_RW_W (0x00800000) /* write */
+# define MMU060_RW_R (0x01000000) /* read */
+# define MMU060_RW_RMW (0x01800000) /* read/modify/write */
+# define MMU060_W (0x00800000) /* general write, includes rmw */
+#define MMU060_SIZ (0x00600000) /* transfer size */
+#define MMU060_TT (0x00180000) /* transfer type (TT) bits */
+#define MMU060_TM (0x00070000) /* transfer modifier (TM) bits */
+#define MMU060_IO (0x00008000) /* instruction or operand */
+#define MMU060_PBE (0x00004000) /* push buffer bus error */
+#define MMU060_SBE (0x00002000) /* store buffer bus error */
+#define MMU060_PTA (0x00001000) /* pointer A fault */
+#define MMU060_PTB (0x00000800) /* pointer B fault */
+#define MMU060_IL (0x00000400) /* double indirect descr fault */
+#define MMU060_PF (0x00000200) /* page fault (invalid descr) */
+#define MMU060_SP (0x00000100) /* supervisor protection */
+#define MMU060_WP (0x00000080) /* write protection */
+#define MMU060_TWE (0x00000040) /* bus error on table search */
+#define MMU060_RE (0x00000020) /* bus error on read */
+#define MMU060_WE (0x00000010) /* bus error on write */
+#define MMU060_TTR (0x00000008) /* error caused by TTR translation */
+#define MMU060_BPE (0x00000004) /* branch prediction error */
+#define MMU060_SEE (0x00000001) /* software emulated error */
+
+/* cases of missing or invalid descriptors */
+#define MMU060_DESC_ERR (MMU060_PTA | MMU060_PTB | \
+ MMU060_IL | MMU060_PF)
+/* bits that indicate real errors */
+#define MMU060_ERR_BITS (MMU060_PBE | MMU060_SBE | MMU060_DESC_ERR | MMU060_SP | \
+ MMU060_WP | MMU060_TWE | MMU060_RE | MMU060_WE)
+
+/* structure for stack frames */
+
+struct frame {
+ struct pt_regs ptregs;
+ union {
+ struct {
+ unsigned long iaddr; /* instruction address */
+ } fmt2;
+ struct {
+ unsigned long effaddr; /* effective address */
+ } fmt3;
+ struct {
+ unsigned long effaddr; /* effective address */
+ unsigned long pc; /* pc of faulted instr */
+ } fmt4;
+ struct {
+ unsigned long effaddr; /* effective address */
+ unsigned short ssw; /* special status word */
+ unsigned short wb3s; /* write back 3 status */
+ unsigned short wb2s; /* write back 2 status */
+ unsigned short wb1s; /* write back 1 status */
+ unsigned long faddr; /* fault address */
+ unsigned long wb3a; /* write back 3 address */
+ unsigned long wb3d; /* write back 3 data */
+ unsigned long wb2a; /* write back 2 address */
+ unsigned long wb2d; /* write back 2 data */
+ unsigned long wb1a; /* write back 1 address */
+ unsigned long wb1dpd0; /* write back 1 data/push data 0*/
+ unsigned long pd1; /* push data 1*/
+ unsigned long pd2; /* push data 2*/
+ unsigned long pd3; /* push data 3*/
+ } fmt7;
+ struct {
+ unsigned long iaddr; /* instruction address */
+ unsigned short int1[4]; /* internal registers */
+ } fmt9;
+ struct {
+ unsigned short int1;
+ unsigned short ssw; /* special status word */
+ unsigned short isc; /* instruction stage c */
+ unsigned short isb; /* instruction stage b */
+ unsigned long daddr; /* data cycle fault address */
+ unsigned short int2[2];
+ unsigned long dobuf; /* data cycle output buffer */
+ unsigned short int3[2];
+ } fmta;
+ struct {
+ unsigned short int1;
+ unsigned short ssw; /* special status word */
+ unsigned short isc; /* instruction stage c */
+ unsigned short isb; /* instruction stage b */
+ unsigned long daddr; /* data cycle fault address */
+ unsigned short int2[2];
+ unsigned long dobuf; /* data cycle output buffer */
+ unsigned short int3[4];
+ unsigned long baddr; /* stage B address */
+ unsigned short int4[2];
+ unsigned long dibuf; /* data cycle input buffer */
+ unsigned short int5[3];
+ unsigned ver : 4; /* stack frame version # */
+ unsigned int6:12;
+ unsigned short int7[18];
+ } fmtb;
+ } un;
+};
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _M68K_TRAPS_H */
diff --git a/arch/m68k/include/asm/traps_mm.h b/arch/m68k/include/asm/traps_mm.h
deleted file mode 100644
index 8caef25624c7..000000000000
--- a/arch/m68k/include/asm/traps_mm.h
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * linux/include/asm/traps.h
- *
- * Copyright (C) 1993 Hamish Macdonald
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive
- * for more details.
- */
-
-#ifndef _M68K_TRAPS_H
-#define _M68K_TRAPS_H
-
-#ifndef __ASSEMBLY__
-
-#include <linux/linkage.h>
-#include <asm/ptrace.h>
-
-typedef void (*e_vector)(void);
-
-asmlinkage void auto_inthandler(void);
-asmlinkage void user_inthandler(void);
-asmlinkage void bad_inthandler(void);
-
-extern e_vector vectors[];
-
-#endif
-
-#define VEC_RESETSP (0)
-#define VEC_RESETPC (1)
-#define VEC_BUSERR (2)
-#define VEC_ADDRERR (3)
-#define VEC_ILLEGAL (4)
-#define VEC_ZERODIV (5)
-#define VEC_CHK (6)
-#define VEC_TRAP (7)
-#define VEC_PRIV (8)
-#define VEC_TRACE (9)
-#define VEC_LINE10 (10)
-#define VEC_LINE11 (11)
-#define VEC_RESV12 (12)
-#define VEC_COPROC (13)
-#define VEC_FORMAT (14)
-#define VEC_UNINT (15)
-#define VEC_RESV16 (16)
-#define VEC_RESV17 (17)
-#define VEC_RESV18 (18)
-#define VEC_RESV19 (19)
-#define VEC_RESV20 (20)
-#define VEC_RESV21 (21)
-#define VEC_RESV22 (22)
-#define VEC_RESV23 (23)
-#define VEC_SPUR (24)
-#define VEC_INT1 (25)
-#define VEC_INT2 (26)
-#define VEC_INT3 (27)
-#define VEC_INT4 (28)
-#define VEC_INT5 (29)
-#define VEC_INT6 (30)
-#define VEC_INT7 (31)
-#define VEC_SYS (32)
-#define VEC_TRAP1 (33)
-#define VEC_TRAP2 (34)
-#define VEC_TRAP3 (35)
-#define VEC_TRAP4 (36)
-#define VEC_TRAP5 (37)
-#define VEC_TRAP6 (38)
-#define VEC_TRAP7 (39)
-#define VEC_TRAP8 (40)
-#define VEC_TRAP9 (41)
-#define VEC_TRAP10 (42)
-#define VEC_TRAP11 (43)
-#define VEC_TRAP12 (44)
-#define VEC_TRAP13 (45)
-#define VEC_TRAP14 (46)
-#define VEC_TRAP15 (47)
-#define VEC_FPBRUC (48)
-#define VEC_FPIR (49)
-#define VEC_FPDIVZ (50)
-#define VEC_FPUNDER (51)
-#define VEC_FPOE (52)
-#define VEC_FPOVER (53)
-#define VEC_FPNAN (54)
-#define VEC_FPUNSUP (55)
-#define VEC_MMUCFG (56)
-#define VEC_MMUILL (57)
-#define VEC_MMUACC (58)
-#define VEC_RESV59 (59)
-#define VEC_UNIMPEA (60)
-#define VEC_UNIMPII (61)
-#define VEC_RESV62 (62)
-#define VEC_RESV63 (63)
-#define VEC_USER (64)
-
-#define VECOFF(vec) ((vec)<<2)
-
-#ifndef __ASSEMBLY__
-
-/* Status register bits */
-#define PS_T (0x8000)
-#define PS_S (0x2000)
-#define PS_M (0x1000)
-#define PS_C (0x0001)
-
-/* bits for 68020/68030 special status word */
-
-#define FC (0x8000)
-#define FB (0x4000)
-#define RC (0x2000)
-#define RB (0x1000)
-#define DF (0x0100)
-#define RM (0x0080)
-#define RW (0x0040)
-#define SZ (0x0030)
-#define DFC (0x0007)
-
-/* bits for 68030 MMU status register (mmusr,psr) */
-
-#define MMU_B (0x8000) /* bus error */
-#define MMU_L (0x4000) /* limit violation */
-#define MMU_S (0x2000) /* supervisor violation */
-#define MMU_WP (0x0800) /* write-protected */
-#define MMU_I (0x0400) /* invalid descriptor */
-#define MMU_M (0x0200) /* ATC entry modified */
-#define MMU_T (0x0040) /* transparent translation */
-#define MMU_NUM (0x0007) /* number of levels traversed */
-
-
-/* bits for 68040 special status word */
-#define CP_040 (0x8000)
-#define CU_040 (0x4000)
-#define CT_040 (0x2000)
-#define CM_040 (0x1000)
-#define MA_040 (0x0800)
-#define ATC_040 (0x0400)
-#define LK_040 (0x0200)
-#define RW_040 (0x0100)
-#define SIZ_040 (0x0060)
-#define TT_040 (0x0018)
-#define TM_040 (0x0007)
-
-/* bits for 68040 write back status word */
-#define WBV_040 (0x80)
-#define WBSIZ_040 (0x60)
-#define WBBYT_040 (0x20)
-#define WBWRD_040 (0x40)
-#define WBLNG_040 (0x00)
-#define WBTT_040 (0x18)
-#define WBTM_040 (0x07)
-
-/* bus access size codes */
-#define BA_SIZE_BYTE (0x20)
-#define BA_SIZE_WORD (0x40)
-#define BA_SIZE_LONG (0x00)
-#define BA_SIZE_LINE (0x60)
-
-/* bus access transfer type codes */
-#define BA_TT_MOVE16 (0x08)
-
-/* bits for 68040 MMU status register (mmusr) */
-#define MMU_B_040 (0x0800)
-#define MMU_G_040 (0x0400)
-#define MMU_S_040 (0x0080)
-#define MMU_CM_040 (0x0060)
-#define MMU_M_040 (0x0010)
-#define MMU_WP_040 (0x0004)
-#define MMU_T_040 (0x0002)
-#define MMU_R_040 (0x0001)
-
-/* bits in the 68060 fault status long word (FSLW) */
-#define MMU060_MA (0x08000000) /* misaligned */
-#define MMU060_LK (0x02000000) /* locked transfer */
-#define MMU060_RW (0x01800000) /* read/write */
-# define MMU060_RW_W (0x00800000) /* write */
-# define MMU060_RW_R (0x01000000) /* read */
-# define MMU060_RW_RMW (0x01800000) /* read/modify/write */
-# define MMU060_W (0x00800000) /* general write, includes rmw */
-#define MMU060_SIZ (0x00600000) /* transfer size */
-#define MMU060_TT (0x00180000) /* transfer type (TT) bits */
-#define MMU060_TM (0x00070000) /* transfer modifier (TM) bits */
-#define MMU060_IO (0x00008000) /* instruction or operand */
-#define MMU060_PBE (0x00004000) /* push buffer bus error */
-#define MMU060_SBE (0x00002000) /* store buffer bus error */
-#define MMU060_PTA (0x00001000) /* pointer A fault */
-#define MMU060_PTB (0x00000800) /* pointer B fault */
-#define MMU060_IL (0x00000400) /* double indirect descr fault */
-#define MMU060_PF (0x00000200) /* page fault (invalid descr) */
-#define MMU060_SP (0x00000100) /* supervisor protection */
-#define MMU060_WP (0x00000080) /* write protection */
-#define MMU060_TWE (0x00000040) /* bus error on table search */
-#define MMU060_RE (0x00000020) /* bus error on read */
-#define MMU060_WE (0x00000010) /* bus error on write */
-#define MMU060_TTR (0x00000008) /* error caused by TTR translation */
-#define MMU060_BPE (0x00000004) /* branch prediction error */
-#define MMU060_SEE (0x00000001) /* software emulated error */
-
-/* cases of missing or invalid descriptors */
-#define MMU060_DESC_ERR (MMU060_PTA | MMU060_PTB | \
- MMU060_IL | MMU060_PF)
-/* bits that indicate real errors */
-#define MMU060_ERR_BITS (MMU060_PBE | MMU060_SBE | MMU060_DESC_ERR | MMU060_SP | \
- MMU060_WP | MMU060_TWE | MMU060_RE | MMU060_WE)
-
-/* structure for stack frames */
-
-struct frame {
- struct pt_regs ptregs;
- union {
- struct {
- unsigned long iaddr; /* instruction address */
- } fmt2;
- struct {
- unsigned long effaddr; /* effective address */
- } fmt3;
- struct {
- unsigned long effaddr; /* effective address */
- unsigned long pc; /* pc of faulted instr */
- } fmt4;
- struct {
- unsigned long effaddr; /* effective address */
- unsigned short ssw; /* special status word */
- unsigned short wb3s; /* write back 3 status */
- unsigned short wb2s; /* write back 2 status */
- unsigned short wb1s; /* write back 1 status */
- unsigned long faddr; /* fault address */
- unsigned long wb3a; /* write back 3 address */
- unsigned long wb3d; /* write back 3 data */
- unsigned long wb2a; /* write back 2 address */
- unsigned long wb2d; /* write back 2 data */
- unsigned long wb1a; /* write back 1 address */
- unsigned long wb1dpd0; /* write back 1 data/push data 0*/
- unsigned long pd1; /* push data 1*/
- unsigned long pd2; /* push data 2*/
- unsigned long pd3; /* push data 3*/
- } fmt7;
- struct {
- unsigned long iaddr; /* instruction address */
- unsigned short int1[4]; /* internal registers */
- } fmt9;
- struct {
- unsigned short int1;
- unsigned short ssw; /* special status word */
- unsigned short isc; /* instruction stage c */
- unsigned short isb; /* instruction stage b */
- unsigned long daddr; /* data cycle fault address */
- unsigned short int2[2];
- unsigned long dobuf; /* data cycle output buffer */
- unsigned short int3[2];
- } fmta;
- struct {
- unsigned short int1;
- unsigned short ssw; /* special status word */
- unsigned short isc; /* instruction stage c */
- unsigned short isb; /* instruction stage b */
- unsigned long daddr; /* data cycle fault address */
- unsigned short int2[2];
- unsigned long dobuf; /* data cycle output buffer */
- unsigned short int3[4];
- unsigned long baddr; /* stage B address */
- unsigned short int4[2];
- unsigned long dibuf; /* data cycle input buffer */
- unsigned short int5[3];
- unsigned ver : 4; /* stack frame version # */
- unsigned int6:12;
- unsigned short int7[18];
- } fmtb;
- } un;
-};
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* _M68K_TRAPS_H */
diff --git a/arch/m68k/include/asm/traps_no.h b/arch/m68k/include/asm/traps_no.h
deleted file mode 100644
index d0671e5f8e29..000000000000
--- a/arch/m68k/include/asm/traps_no.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * linux/include/asm/traps.h
- *
- * Copyright (C) 1993 Hamish Macdonald
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive
- * for more details.
- */
-
-#ifndef _M68KNOMMU_TRAPS_H
-#define _M68KNOMMU_TRAPS_H
-
-#ifndef __ASSEMBLY__
-
-typedef void (*e_vector)(void);
-
-extern e_vector vectors[];
-extern void init_vectors(void);
-extern void enable_vector(unsigned int irq);
-extern void disable_vector(unsigned int irq);
-extern void ack_vector(unsigned int irq);
-
-#endif
-
-#define VEC_BUSERR (2)
-#define VEC_ADDRERR (3)
-#define VEC_ILLEGAL (4)
-#define VEC_ZERODIV (5)
-#define VEC_CHK (6)
-#define VEC_TRAP (7)
-#define VEC_PRIV (8)
-#define VEC_TRACE (9)
-#define VEC_LINE10 (10)
-#define VEC_LINE11 (11)
-#define VEC_RESV1 (12)
-#define VEC_COPROC (13)
-#define VEC_FORMAT (14)
-#define VEC_UNINT (15)
-#define VEC_SPUR (24)
-#define VEC_INT1 (25)
-#define VEC_INT2 (26)
-#define VEC_INT3 (27)
-#define VEC_INT4 (28)
-#define VEC_INT5 (29)
-#define VEC_INT6 (30)
-#define VEC_INT7 (31)
-#define VEC_SYS (32)
-#define VEC_TRAP1 (33)
-#define VEC_TRAP2 (34)
-#define VEC_TRAP3 (35)
-#define VEC_TRAP4 (36)
-#define VEC_TRAP5 (37)
-#define VEC_TRAP6 (38)
-#define VEC_TRAP7 (39)
-#define VEC_TRAP8 (40)
-#define VEC_TRAP9 (41)
-#define VEC_TRAP10 (42)
-#define VEC_TRAP11 (43)
-#define VEC_TRAP12 (44)
-#define VEC_TRAP13 (45)
-#define VEC_TRAP14 (46)
-#define VEC_TRAP15 (47)
-#define VEC_FPBRUC (48)
-#define VEC_FPIR (49)
-#define VEC_FPDIVZ (50)
-#define VEC_FPUNDER (51)
-#define VEC_FPOE (52)
-#define VEC_FPOVER (53)
-#define VEC_FPNAN (54)
-#define VEC_FPUNSUP (55)
-#define VEC_UNIMPEA (60)
-#define VEC_UNIMPII (61)
-#define VEC_USER (64)
-
-#define VECOFF(vec) ((vec)<<2)
-
-#ifndef __ASSEMBLY__
-
-/* Status register bits */
-#define PS_T (0x8000)
-#define PS_S (0x2000)
-#define PS_M (0x1000)
-#define PS_C (0x0001)
-
-/* structure for stack frames */
-
-struct frame {
- struct pt_regs ptregs;
- union {
- struct {
- unsigned long iaddr; /* instruction address */
- } fmt2;
- struct {
- unsigned long effaddr; /* effective address */
- } fmt3;
- struct {
- unsigned long effaddr; /* effective address */
- unsigned long pc; /* pc of faulted instr */
- } fmt4;
- struct {
- unsigned long effaddr; /* effective address */
- unsigned short ssw; /* special status word */
- unsigned short wb3s; /* write back 3 status */
- unsigned short wb2s; /* write back 2 status */
- unsigned short wb1s; /* write back 1 status */
- unsigned long faddr; /* fault address */
- unsigned long wb3a; /* write back 3 address */
- unsigned long wb3d; /* write back 3 data */
- unsigned long wb2a; /* write back 2 address */
- unsigned long wb2d; /* write back 2 data */
- unsigned long wb1a; /* write back 1 address */
- unsigned long wb1dpd0; /* write back 1 data/push data 0*/
- unsigned long pd1; /* push data 1*/
- unsigned long pd2; /* push data 2*/
- unsigned long pd3; /* push data 3*/
- } fmt7;
- struct {
- unsigned long iaddr; /* instruction address */
- unsigned short int1[4]; /* internal registers */
- } fmt9;
- struct {
- unsigned short int1;
- unsigned short ssw; /* special status word */
- unsigned short isc; /* instruction stage c */
- unsigned short isb; /* instruction stage b */
- unsigned long daddr; /* data cycle fault address */
- unsigned short int2[2];
- unsigned long dobuf; /* data cycle output buffer */
- unsigned short int3[2];
- } fmta;
- struct {
- unsigned short int1;
- unsigned short ssw; /* special status word */
- unsigned short isc; /* instruction stage c */
- unsigned short isb; /* instruction stage b */
- unsigned long daddr; /* data cycle fault address */
- unsigned short int2[2];
- unsigned long dobuf; /* data cycle output buffer */
- unsigned short int3[4];
- unsigned long baddr; /* stage B address */
- unsigned short int4[2];
- unsigned long dibuf; /* data cycle input buffer */
- unsigned short int5[3];
- unsigned ver : 4; /* stack frame version # */
- unsigned int6:12;
- unsigned short int7[18];
- } fmtb;
- } un;
-};
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* _M68KNOMMU_TRAPS_H */
diff --git a/arch/m68k/kernel/asm-offsets.c b/arch/m68k/kernel/asm-offsets.c
index 73e5e581245b..78e59b82ebc3 100644
--- a/arch/m68k/kernel/asm-offsets.c
+++ b/arch/m68k/kernel/asm-offsets.c
@@ -22,13 +22,9 @@
int main(void)
{
/* offsets into the task struct */
- DEFINE(TASK_STATE, offsetof(struct task_struct, state));
- DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
- DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
DEFINE(TASK_INFO, offsetof(struct task_struct, thread.info));
DEFINE(TASK_MM, offsetof(struct task_struct, mm));
- DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
#ifdef CONFIG_MMU
DEFINE(TASK_TINFO, offsetof(struct task_struct, thread.info));
#endif
@@ -64,14 +60,6 @@ int main(void)
/* bitfields are a bit difficult */
DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, pc) + 4);
- /* offsets into the irq_handler struct */
- DEFINE(IRQ_HANDLER, offsetof(struct irq_node, handler));
- DEFINE(IRQ_DEVID, offsetof(struct irq_node, dev_id));
- DEFINE(IRQ_NEXT, offsetof(struct irq_node, next));
-
- /* offsets into the kernel_stat struct */
- DEFINE(STAT_IRQ, offsetof(struct kernel_stat, irqs));
-
/* offsets into the irq_cpustat_t struct */
DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));
diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c
index 303730afb1c9..b3963ab3d149 100644
--- a/arch/m68k/kernel/setup.c
+++ b/arch/m68k/kernel/setup.c
@@ -359,12 +359,6 @@ void __init setup_arch(char **cmdline_p)
isa_type = ISA_TYPE_Q40;
isa_sex = 0;
}
-#ifdef CONFIG_GG2
- if (MACH_IS_AMIGA && AMIGAHW_PRESENT(GG2_ISA)) {
- isa_type = ISA_TYPE_GG2;
- isa_sex = 0;
- }
-#endif
#ifdef CONFIG_AMIGA_PCMCIA
if (MACH_IS_AMIGA && AMIGAHW_PRESENT(PCMCIA)) {
isa_type = ISA_TYPE_AG;
diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c
index 2f431ece7b5f..3db2e7f902aa 100644
--- a/arch/m68k/kernel/sys_m68k.c
+++ b/arch/m68k/kernel/sys_m68k.c
@@ -12,7 +12,6 @@
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
@@ -377,7 +376,6 @@ sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
struct vm_area_struct *vma;
int ret = -EINVAL;
- lock_kernel();
if (scope < FLUSH_SCOPE_LINE || scope > FLUSH_SCOPE_ALL ||
cache & ~FLUSH_CACHE_BOTH)
goto out;
@@ -446,7 +444,6 @@ sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
}
}
out:
- unlock_kernel();
return ret;
}
diff --git a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c
index 4926b3856c15..06438dac08ff 100644
--- a/arch/m68k/kernel/time.c
+++ b/arch/m68k/kernel/time.c
@@ -42,9 +42,7 @@ static inline int set_rtc_mmss(unsigned long nowtime)
static irqreturn_t timer_interrupt(int irq, void *dummy)
{
do_timer(1);
-#ifndef CONFIG_SMP
update_process_times(user_mode(get_irq_regs()));
-#endif
profile_tick(CPU_PROFILING);
#ifdef CONFIG_HEARTBEAT
diff --git a/arch/m68k/mac/macboing.c b/arch/m68k/mac/macboing.c
index 8f0640847ad2..ffaa1f6439ae 100644
--- a/arch/m68k/mac/macboing.c
+++ b/arch/m68k/mac/macboing.c
@@ -114,7 +114,8 @@ static void mac_init_asc( void )
* 16-bit I/O functionality. The PowerBook 500 series computers
* support 16-bit stereo output, but only mono input."
*
- * http://til.info.apple.com/techinfo.nsf/artnum/n16405
+ * Technical Information Library (TIL) article number 16405.
+ * http://support.apple.com/kb/TA32601
*
* --David Kilzer
*/
@@ -162,7 +163,7 @@ static void mac_init_asc( void )
void mac_mksound( unsigned int freq, unsigned int length )
{
__u32 cfreq = ( freq << 5 ) / 468;
- __u32 flags;
+ unsigned long flags;
int i;
if ( mac_special_bell == NULL )
@@ -224,7 +225,7 @@ static void mac_nosound( unsigned long ignored )
*/
static void mac_quadra_start_bell( unsigned int freq, unsigned int length, unsigned int volume )
{
- __u32 flags;
+ unsigned long flags;
/* if the bell is already ringing, ring longer */
if ( mac_bell_duration > 0 )
@@ -271,7 +272,7 @@ static void mac_quadra_start_bell( unsigned int freq, unsigned int length, unsig
static void mac_quadra_ring_bell( unsigned long ignored )
{
int i, count = mac_asc_samplespersec / HZ;
- __u32 flags;
+ unsigned long flags;
/*
* we neither want a sound buffer overflow nor underflow, so we need to match
diff --git a/arch/m68k/mvme16x/rtc.c b/arch/m68k/mvme16x/rtc.c
index 11ac6f63967a..39c79ebcd18a 100644
--- a/arch/m68k/mvme16x/rtc.c
+++ b/arch/m68k/mvme16x/rtc.c
@@ -144,6 +144,7 @@ static const struct file_operations rtc_fops = {
.unlocked_ioctl = rtc_ioctl,
.open = rtc_open,
.release = rtc_release,
+ .llseek = noop_llseek,
};
static struct miscdevice rtc_dev=
diff --git a/arch/m68k/q40/README b/arch/m68k/q40/README
index 6bdbf4879570..f877b7249790 100644
--- a/arch/m68k/q40/README
+++ b/arch/m68k/q40/README
@@ -3,7 +3,7 @@ Linux for the Q40
You may try http://www.geocities.com/SiliconValley/Bay/2602/ for
some up to date information. Booter and other tools will be also
-available from this place or ftp.uni-erlangen.de/linux/680x0/q40/
+available from this place or http://ftp.uni-erlangen.de/pub/unix/Linux/680x0/q40/
and mirrors.
Hints to documentation usually refer to the linux source tree in
diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c
index ad90393a3361..2d9e21bd313a 100644
--- a/arch/m68k/sun3/sun3ints.c
+++ b/arch/m68k/sun3/sun3ints.c
@@ -67,9 +67,7 @@ static irqreturn_t sun3_int5(int irq, void *dev_id)
intersil_clear();
#endif
do_timer(1);
-#ifndef CONFIG_SMP
update_process_times(user_mode(get_irq_regs()));
-#endif
if (!(kstat_cpu(0).irqs[irq] % 20))
sun3_leds(led_pattern[(kstat_cpu(0).irqs[irq] % 160) / 20]);
return IRQ_HANDLED;
diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
index 2609c394e1df..9287150e5fb0 100644
--- a/arch/m68knommu/Kconfig
+++ b/arch/m68knommu/Kconfig
@@ -59,6 +59,10 @@ config GENERIC_HARDIRQS
bool
default y
+config GENERIC_HARDIRQS_NO__DO_IRQ
+ bool
+ default y
+
config GENERIC_CALIBRATE_DELAY
bool
default y
@@ -171,6 +175,11 @@ config M5407
help
Motorola ColdFire 5407 processor support.
+config M548x
+ bool "MCF548x"
+ help
+ Freescale ColdFire 5480/5481/5482/5483/5484/5485 processor support.
+
endchoice
config M527x
@@ -181,7 +190,7 @@ config M527x
config COLDFIRE
bool
- depends on (M5206 || M5206e || M520x || M523x || M5249 || M527x || M5272 || M528x || M5307 || M532x || M5407)
+ depends on (M5206 || M5206e || M520x || M523x || M5249 || M527x || M5272 || M528x || M5307 || M532x || M5407 || M548x)
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
default y
diff --git a/arch/m68knommu/Makefile b/arch/m68knommu/Makefile
index 14042574ac21..026ef16fa68e 100644
--- a/arch/m68knommu/Makefile
+++ b/arch/m68knommu/Makefile
@@ -25,6 +25,7 @@ platform-$(CONFIG_M528x) := 528x
platform-$(CONFIG_M5307) := 5307
platform-$(CONFIG_M532x) := 532x
platform-$(CONFIG_M5407) := 5407
+platform-$(CONFIG_M548x) := 548x
PLATFORM := $(platform-y)
board-$(CONFIG_PILOT) := pilot
@@ -73,6 +74,7 @@ cpuclass-$(CONFIG_M528x) := coldfire
cpuclass-$(CONFIG_M5307) := coldfire
cpuclass-$(CONFIG_M532x) := coldfire
cpuclass-$(CONFIG_M5407) := coldfire
+cpuclass-$(CONFIG_M548x) := coldfire
cpuclass-$(CONFIG_M68328) := 68328
cpuclass-$(CONFIG_M68EZ328) := 68328
cpuclass-$(CONFIG_M68VZ328) := 68328
@@ -100,6 +102,7 @@ cflags-$(CONFIG_M528x) := $(call cc-option,-m528x,-m5307)
cflags-$(CONFIG_M5307) := $(call cc-option,-m5307,-m5200)
cflags-$(CONFIG_M532x) := $(call cc-option,-mcpu=532x,-m5307)
cflags-$(CONFIG_M5407) := $(call cc-option,-m5407,-m5200)
+cflags-$(CONFIG_M548x) := $(call cc-option,-m5407,-m5200)
cflags-$(CONFIG_M68328) := -m68000
cflags-$(CONFIG_M68EZ328) := -m68000
cflags-$(CONFIG_M68VZ328) := -m68000
diff --git a/arch/m68knommu/kernel/.gitignore b/arch/m68knommu/kernel/.gitignore
new file mode 100644
index 000000000000..c5f676c3c224
--- /dev/null
+++ b/arch/m68knommu/kernel/.gitignore
@@ -0,0 +1 @@
+vmlinux.lds
diff --git a/arch/m68knommu/kernel/asm-offsets.c b/arch/m68knommu/kernel/asm-offsets.c
index 9a8876f715d8..ffe02f41ad46 100644
--- a/arch/m68knommu/kernel/asm-offsets.c
+++ b/arch/m68knommu/kernel/asm-offsets.c
@@ -21,14 +21,8 @@
int main(void)
{
/* offsets into the task struct */
- DEFINE(TASK_STATE, offsetof(struct task_struct, state));
- DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
- DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
- DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked));
DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
- DEFINE(TASK_THREAD_INFO, offsetof(struct task_struct, stack));
DEFINE(TASK_MM, offsetof(struct task_struct, mm));
- DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
/* offsets into the irq_cpustat_t struct */
DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));
@@ -63,7 +57,7 @@ int main(void)
DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, sr) - 2);
#else
/* bitfields are a bit difficult */
- DEFINE(PT_OFF_VECTOR, offsetof(struct pt_regs, pc) + 4);
+ DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, pc) + 4);
#endif
/* signal defines */
@@ -74,14 +68,9 @@ int main(void)
DEFINE(PT_PTRACED, PT_PTRACED);
- DEFINE(THREAD_SIZE, THREAD_SIZE);
-
/* Offsets in thread_info structure */
- DEFINE(TI_TASK, offsetof(struct thread_info, task));
- DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain));
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
DEFINE(TI_PREEMPTCOUNT, offsetof(struct thread_info, preempt_count));
- DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
return 0;
}
diff --git a/arch/m68knommu/kernel/ptrace.c b/arch/m68knommu/kernel/ptrace.c
index f6be1248d216..6fe7c38cd556 100644
--- a/arch/m68knommu/kernel/ptrace.c
+++ b/arch/m68knommu/kernel/ptrace.c
@@ -18,6 +18,7 @@
#include <linux/ptrace.h>
#include <linux/user.h>
#include <linux/signal.h>
+#include <linux/tracehook.h>
#include <asm/uaccess.h>
#include <asm/page.h>
@@ -134,14 +135,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
tmp >>= 16;
} else if (addr >= 21 && addr < 49) {
tmp = child->thread.fp[addr - 21];
-#ifdef CONFIG_M68KFPU_EMU
- /* Convert internal fpu reg representation
- * into long double format
- */
- if (FPU_IS_EMU && (addr < 45) && !(addr % 3))
- tmp = ((tmp & 0xffff0000) << 15) |
- ((tmp & 0x0000ffff) << 16);
-#endif
} else if (addr == 49) {
tmp = child->mm->start_code;
} else if (addr == 50) {
@@ -175,16 +168,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
}
if (addr >= 21 && addr < 48)
{
-#ifdef CONFIG_M68KFPU_EMU
- /* Convert long double format
- * into internal fpu reg representation
- */
- if (FPU_IS_EMU && (addr < 45) && !(addr % 3)) {
- data = (unsigned long)data << 15;
- data = (data & 0xffff0000) |
- ((data & 0x0000ffff) >> 1);
- }
-#endif
child->thread.fp[addr - 21] = data;
ret = 0;
}
@@ -259,21 +242,17 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
return ret;
}
-asmlinkage void syscall_trace(void)
+asmlinkage int syscall_trace_enter(void)
{
- if (!test_thread_flag(TIF_SYSCALL_TRACE))
- return;
- if (!(current->ptrace & PT_PTRACED))
- return;
- ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
- ? 0x80 : 0));
- /*
- * this isn't the same as continuing with a signal, but it will do
- * for normal use. strace only continues with a signal if the
- * stopping signal is not SIGTRAP. -brl
- */
- if (current->exit_code) {
- send_sig(current->exit_code, current, 1);
- current->exit_code = 0;
- }
+ int ret = 0;
+
+ if (test_thread_flag(TIF_SYSCALL_TRACE))
+ ret = tracehook_report_syscall_entry(task_pt_regs(current));
+ return ret;
+}
+
+asmlinkage void syscall_trace_leave(void)
+{
+ if (test_thread_flag(TIF_SYSCALL_TRACE))
+ tracehook_report_syscall_exit(task_pt_regs(current), 0);
}
diff --git a/arch/m68knommu/kernel/setup.c b/arch/m68knommu/kernel/setup.c
index ba92b90d5fbc..c684adf5dc40 100644
--- a/arch/m68knommu/kernel/setup.c
+++ b/arch/m68knommu/kernel/setup.c
@@ -54,9 +54,6 @@ void (*mach_reset)(void);
void (*mach_halt)(void);
void (*mach_power_off)(void);
-#ifdef CONFIG_M68000
- #define CPU "MC68000"
-#endif
#ifdef CONFIG_M68328
#define CPU "MC68328"
#endif
diff --git a/arch/m68knommu/kernel/time.c b/arch/m68knommu/kernel/time.c
index a90acf5b0cde..d6ac2a43453c 100644
--- a/arch/m68knommu/kernel/time.c
+++ b/arch/m68knommu/kernel/time.c
@@ -50,9 +50,8 @@ irqreturn_t arch_timer_interrupt(int irq, void *dummy)
write_sequnlock(&xtime_lock);
-#ifndef CONFIG_SMP
update_process_times(user_mode(get_irq_regs()));
-#endif
+
return(IRQ_HANDLED);
}
#endif
@@ -61,13 +60,16 @@ static unsigned long read_rtc_mmss(void)
{
unsigned int year, mon, day, hour, min, sec;
- if (mach_gettod)
+ if (mach_gettod) {
mach_gettod(&year, &mon, &day, &hour, &min, &sec);
- else
- year = mon = day = hour = min = sec = 0;
+ if ((year += 1900) < 1970)
+ year += 100;
+ } else {
+ year = 1970;
+ mon = day = 1;
+ hour = min = sec = 0;
+ }
- if ((year += 1900) < 1970)
- year += 100;
return mktime(year, mon, day, hour, min, sec);
}
diff --git a/arch/m68knommu/kernel/traps.c b/arch/m68knommu/kernel/traps.c
index 3739c8f657d7..a768008dfd06 100644
--- a/arch/m68knommu/kernel/traps.c
+++ b/arch/m68knommu/kernel/traps.c
@@ -179,14 +179,16 @@ static void __show_stack(struct task_struct *task, unsigned long *stack)
void bad_super_trap(struct frame *fp)
{
+ int vector = (fp->ptregs.vector >> 2) & 0xff;
+
console_verbose();
- if (fp->ptregs.vector < 4 * ARRAY_SIZE(vec_names))
+ if (vector < ARRAY_SIZE(vec_names))
printk (KERN_WARNING "*** %s *** FORMAT=%X\n",
- vec_names[(fp->ptregs.vector) >> 2],
+ vec_names[vector],
fp->ptregs.format);
else
printk (KERN_WARNING "*** Exception %d *** FORMAT=%X\n",
- (fp->ptregs.vector) >> 2,
+ vector,
fp->ptregs.format);
printk (KERN_WARNING "Current process id is %d\n", current->pid);
die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0);
@@ -195,10 +197,11 @@ void bad_super_trap(struct frame *fp)
asmlinkage void trap_c(struct frame *fp)
{
int sig;
+ int vector = (fp->ptregs.vector >> 2) & 0xff;
siginfo_t info;
if (fp->ptregs.sr & PS_S) {
- if ((fp->ptregs.vector >> 2) == VEC_TRACE) {
+ if (vector == VEC_TRACE) {
/* traced a trapping instruction */
} else
bad_super_trap(fp);
@@ -206,7 +209,7 @@ asmlinkage void trap_c(struct frame *fp)
}
/* send the appropriate signal to the user program */
- switch ((fp->ptregs.vector) >> 2) {
+ switch (vector) {
case VEC_ADDRERR:
info.si_code = BUS_ADRALN;
sig = SIGBUS;
@@ -360,16 +363,3 @@ void show_stack(struct task_struct *task, unsigned long *stack)
else
__show_stack(task, stack);
}
-
-#ifdef CONFIG_M68KFPU_EMU
-asmlinkage void fpemu_signal(int signal, int code, void *addr)
-{
- siginfo_t info;
-
- info.si_signo = signal;
- info.si_errno = 0;
- info.si_code = code;
- info.si_addr = addr;
- force_sig_info(signal, &info, current);
-}
-#endif
diff --git a/arch/m68knommu/platform/5206/Makefile b/arch/m68knommu/platform/5206/Makefile
index 113c33390064..b5db05625cfa 100644
--- a/arch/m68knommu/platform/5206/Makefile
+++ b/arch/m68knommu/platform/5206/Makefile
@@ -8,8 +8,8 @@
# on the console port whenever a DBG interrupt occurs. You have to
# set up you HW breakpoints to trigger a DBG interrupt:
#
-# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
-# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
+# ccflags-y := -DTRAP_DBG_INTERRUPT
+# asflags-y := -DTRAP_DBG_INTERRUPT
#
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
diff --git a/arch/m68knommu/platform/5206e/Makefile b/arch/m68knommu/platform/5206e/Makefile
index 113c33390064..b5db05625cfa 100644
--- a/arch/m68knommu/platform/5206e/Makefile
+++ b/arch/m68knommu/platform/5206e/Makefile
@@ -8,8 +8,8 @@
# on the console port whenever a DBG interrupt occurs. You have to
# set up you HW breakpoints to trigger a DBG interrupt:
#
-# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
-# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
+# ccflags-y := -DTRAP_DBG_INTERRUPT
+# asflags-y := -DTRAP_DBG_INTERRUPT
#
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
diff --git a/arch/m68knommu/platform/520x/Makefile b/arch/m68knommu/platform/520x/Makefile
index 435ab3483dc1..ad3f4e5a57ce 100644
--- a/arch/m68knommu/platform/520x/Makefile
+++ b/arch/m68knommu/platform/520x/Makefile
@@ -8,8 +8,8 @@
# on the console port whenever a DBG interrupt occurs. You have to
# set up you HW breakpoints to trigger a DBG interrupt:
#
-# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
-# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
+# ccflags-y := -DTRAP_DBG_INTERRUPT
+# asflags-y := -DTRAP_DBG_INTERRUPT
#
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
diff --git a/arch/m68knommu/platform/523x/Makefile b/arch/m68knommu/platform/523x/Makefile
index b8f9b45440c2..c04b8f71c88c 100644
--- a/arch/m68knommu/platform/523x/Makefile
+++ b/arch/m68knommu/platform/523x/Makefile
@@ -8,8 +8,8 @@
# on the console port whenever a DBG interrupt occurs. You have to
# set up you HW breakpoints to trigger a DBG interrupt:
#
-# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
-# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
+# ccflags-y := -DTRAP_DBG_INTERRUPT
+# asflags-y := -DTRAP_DBG_INTERRUPT
#
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
diff --git a/arch/m68knommu/platform/5249/Makefile b/arch/m68knommu/platform/5249/Makefile
index f56225d1582f..4bed30fd0073 100644
--- a/arch/m68knommu/platform/5249/Makefile
+++ b/arch/m68knommu/platform/5249/Makefile
@@ -8,8 +8,8 @@
# on the console port whenever a DBG interrupt occurs. You have to
# set up you HW breakpoints to trigger a DBG interrupt:
#
-# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
-# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
+# ccflags-y := -DTRAP_DBG_INTERRUPT
+# asflags-y := -DTRAP_DBG_INTERRUPT
#
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
diff --git a/arch/m68knommu/platform/5272/Makefile b/arch/m68knommu/platform/5272/Makefile
index 93673ef8e2c1..34110fc14301 100644
--- a/arch/m68knommu/platform/5272/Makefile
+++ b/arch/m68knommu/platform/5272/Makefile
@@ -8,8 +8,8 @@
# on the console port whenever a DBG interrupt occurs. You have to
# set up you HW breakpoints to trigger a DBG interrupt:
#
-# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
-# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
+# ccflags-y := -DTRAP_DBG_INTERRUPT
+# asflags-y := -DTRAP_DBG_INTERRUPT
#
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
diff --git a/arch/m68knommu/platform/5272/config.c b/arch/m68knommu/platform/5272/config.c
index 59278c0887d0..65bb582734e1 100644
--- a/arch/m68knommu/platform/5272/config.c
+++ b/arch/m68knommu/platform/5272/config.c
@@ -13,6 +13,8 @@
#include <linux/param.h>
#include <linux/init.h>
#include <linux/io.h>
+#include <linux/phy.h>
+#include <linux/phy_fixed.h>
#include <asm/machdep.h>
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
@@ -148,9 +150,23 @@ void __init config_BSP(char *commandp, int size)
/***************************************************************************/
+/*
+ * Some 5272 based boards have the FEC ethernet diectly connected to
+ * an ethernet switch. In this case we need to use the fixed phy type,
+ * and we need to declare it early in boot.
+ */
+static struct fixed_phy_status nettel_fixed_phy_status __initdata = {
+ .link = 1,
+ .speed = 100,
+ .duplex = 0,
+};
+
+/***************************************************************************/
+
static int __init init_BSP(void)
{
m5272_uarts_init();
+ fixed_phy_add(PHY_POLL, 0, &nettel_fixed_phy_status);
platform_add_devices(m5272_devices, ARRAY_SIZE(m5272_devices));
return 0;
}
diff --git a/arch/m68knommu/platform/5272/intc.c b/arch/m68knommu/platform/5272/intc.c
index 7081e0a9720e..3cf681c177aa 100644
--- a/arch/m68knommu/platform/5272/intc.c
+++ b/arch/m68knommu/platform/5272/intc.c
@@ -12,6 +12,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <asm/coldfire.h>
@@ -29,6 +30,10 @@
* via a set of 4 "Interrupt Controller Registers" (ICR). There is a
* loose mapping of vector number to register and internal bits, but
* a table is the easiest and quickest way to map them.
+ *
+ * Note that the external interrupts are edge triggered (unlike the
+ * internal interrupt sources which are level triggered). Which means
+ * they also need acknowledgeing via acknowledge bits.
*/
struct irqmap {
unsigned char icr;
@@ -68,6 +73,11 @@ static struct irqmap intc_irqmap[MCFINT_VECMAX - MCFINT_VECBASE] = {
/*MCF_IRQ_SWTO*/ { .icr = MCFSIM_ICR4, .index = 16, .ack = 0, },
};
+/*
+ * The act of masking the interrupt also has a side effect of 'ack'ing
+ * an interrupt on this irq (for the external irqs). So this mask function
+ * is also an ack_mask function.
+ */
static void intc_irq_mask(unsigned int irq)
{
if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) {
@@ -95,7 +105,9 @@ static void intc_irq_ack(unsigned int irq)
irq -= MCFINT_VECBASE;
if (intc_irqmap[irq].ack) {
u32 v;
- v = 0xd << intc_irqmap[irq].index;
+ v = readl(MCF_MBAR + intc_irqmap[irq].icr);
+ v &= (0x7 << intc_irqmap[irq].index);
+ v |= (0x8 << intc_irqmap[irq].index);
writel(v, MCF_MBAR + intc_irqmap[irq].icr);
}
}
@@ -103,21 +115,47 @@ static void intc_irq_ack(unsigned int irq)
static int intc_irq_set_type(unsigned int irq, unsigned int type)
{
- /* We can set the edge type here for external interrupts */
+ if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) {
+ irq -= MCFINT_VECBASE;
+ if (intc_irqmap[irq].ack) {
+ u32 v;
+ v = readl(MCF_MBAR + MCFSIM_PITR);
+ if (type == IRQ_TYPE_EDGE_FALLING)
+ v &= ~(0x1 << (32 - irq));
+ else
+ v |= (0x1 << (32 - irq));
+ writel(v, MCF_MBAR + MCFSIM_PITR);
+ }
+ }
return 0;
}
+/*
+ * Simple flow handler to deal with the external edge triggered interrupts.
+ * We need to be careful with the masking/acking due to the side effects
+ * of masking an interrupt.
+ */
+static void intc_external_irq(unsigned int irq, struct irq_desc *desc)
+{
+ kstat_incr_irqs_this_cpu(irq, desc);
+ desc->status |= IRQ_INPROGRESS;
+ desc->chip->ack(irq);
+ handle_IRQ_event(irq, desc->action);
+ desc->status &= ~IRQ_INPROGRESS;
+}
+
static struct irq_chip intc_irq_chip = {
.name = "CF-INTC",
.mask = intc_irq_mask,
.unmask = intc_irq_unmask,
+ .mask_ack = intc_irq_mask,
.ack = intc_irq_ack,
.set_type = intc_irq_set_type,
};
void __init init_IRQ(void)
{
- int irq;
+ int irq, edge;
init_vectors();
@@ -128,11 +166,17 @@ void __init init_IRQ(void)
writel(0x88888888, MCF_MBAR + MCFSIM_ICR4);
for (irq = 0; (irq < NR_IRQS); irq++) {
- irq_desc[irq].status = IRQ_DISABLED;
- irq_desc[irq].action = NULL;
- irq_desc[irq].depth = 1;
- irq_desc[irq].chip = &intc_irq_chip;
- intc_irq_set_type(irq, 0);
+ set_irq_chip(irq, &intc_irq_chip);
+ edge = 0;
+ if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX))
+ edge = intc_irqmap[irq - MCFINT_VECBASE].ack;
+ if (edge) {
+ set_irq_type(irq, IRQ_TYPE_EDGE_RISING);
+ set_irq_handler(irq, intc_external_irq);
+ } else {
+ set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH);
+ set_irq_handler(irq, handle_level_irq);
+ }
}
}
diff --git a/arch/m68knommu/platform/527x/Makefile b/arch/m68knommu/platform/527x/Makefile
index 3d90e6d92459..6ac4b57370ea 100644
--- a/arch/m68knommu/platform/527x/Makefile
+++ b/arch/m68knommu/platform/527x/Makefile
@@ -8,8 +8,8 @@
# on the console port whenever a DBG interrupt occurs. You have to
# set up you HW breakpoints to trigger a DBG interrupt:
#
-# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
-# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
+# ccflags-y := -DTRAP_DBG_INTERRUPT
+# asflags-y := -DTRAP_DBG_INTERRUPT
#
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
diff --git a/arch/m68knommu/platform/528x/Makefile b/arch/m68knommu/platform/528x/Makefile
index 3d90e6d92459..6ac4b57370ea 100644
--- a/arch/m68knommu/platform/528x/Makefile
+++ b/arch/m68knommu/platform/528x/Makefile
@@ -8,8 +8,8 @@
# on the console port whenever a DBG interrupt occurs. You have to
# set up you HW breakpoints to trigger a DBG interrupt:
#
-# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
-# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
+# ccflags-y := -DTRAP_DBG_INTERRUPT
+# asflags-y := -DTRAP_DBG_INTERRUPT
#
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
diff --git a/arch/m68knommu/platform/5307/Makefile b/arch/m68knommu/platform/5307/Makefile
index 6de526976828..d4293b791f2e 100644
--- a/arch/m68knommu/platform/5307/Makefile
+++ b/arch/m68knommu/platform/5307/Makefile
@@ -8,8 +8,8 @@
# on the console port whenever a DBG interrupt occurs. You have to
# set up you HW breakpoints to trigger a DBG interrupt:
#
-# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
-# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
+# ccflags-y := -DTRAP_DBG_INTERRUPT
+# asflags-y := -DTRAP_DBG_INTERRUPT
#
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
diff --git a/arch/m68knommu/platform/532x/Makefile b/arch/m68knommu/platform/532x/Makefile
index 4cc23245bcd1..ce01669399c6 100644
--- a/arch/m68knommu/platform/532x/Makefile
+++ b/arch/m68knommu/platform/532x/Makefile
@@ -8,8 +8,8 @@
# on the console port whenever a DBG interrupt occurs. You have to
# set up you HW breakpoints to trigger a DBG interrupt:
#
-# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
-# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
+# ccflags-y := -DTRAP_DBG_INTERRUPT
+# asflags-y := -DTRAP_DBG_INTERRUPT
#
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
diff --git a/arch/m68knommu/platform/5407/Makefile b/arch/m68knommu/platform/5407/Makefile
index dee62c5dbaa6..e83fe148eddc 100644
--- a/arch/m68knommu/platform/5407/Makefile
+++ b/arch/m68knommu/platform/5407/Makefile
@@ -8,8 +8,8 @@
# on the console port whenever a DBG interrupt occurs. You have to
# set up you HW breakpoints to trigger a DBG interrupt:
#
-# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
-# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
+# ccflags-y := -DTRAP_DBG_INTERRUPT
+# asflags-y := -DTRAP_DBG_INTERRUPT
#
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
diff --git a/arch/m68knommu/platform/548x/Makefile b/arch/m68knommu/platform/548x/Makefile
new file mode 100644
index 000000000000..e6035e7a2d3f
--- /dev/null
+++ b/arch/m68knommu/platform/548x/Makefile
@@ -0,0 +1,18 @@
+#
+# Makefile for the m68knommu linux kernel.
+#
+
+#
+# If you want to play with the HW breakpoints then you will
+# need to add define this, which will give you a stack backtrace
+# on the console port whenever a DBG interrupt occurs. You have to
+# set up you HW breakpoints to trigger a DBG interrupt:
+#
+# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
+# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
+#
+
+asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
+
+obj-y := config.o
+
diff --git a/arch/m68knommu/platform/548x/config.c b/arch/m68knommu/platform/548x/config.c
new file mode 100644
index 000000000000..9888846bd1cf
--- /dev/null
+++ b/arch/m68knommu/platform/548x/config.c
@@ -0,0 +1,115 @@
+/***************************************************************************/
+
+/*
+ * linux/arch/m68knommu/platform/548x/config.c
+ *
+ * Copyright (C) 2010, Philippe De Muyter <phdm@macqel.be>
+ */
+
+/***************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <asm/machdep.h>
+#include <asm/coldfire.h>
+#include <asm/m548xsim.h>
+#include <asm/mcfuart.h>
+#include <asm/m548xgpt.h>
+
+/***************************************************************************/
+
+static struct mcf_platform_uart m548x_uart_platform[] = {
+ {
+ .mapbase = MCF_MBAR + MCFUART_BASE1,
+ .irq = 64 + 35,
+ },
+ {
+ .mapbase = MCF_MBAR + MCFUART_BASE2,
+ .irq = 64 + 34,
+ },
+ {
+ .mapbase = MCF_MBAR + MCFUART_BASE3,
+ .irq = 64 + 33,
+ },
+ {
+ .mapbase = MCF_MBAR + MCFUART_BASE4,
+ .irq = 64 + 32,
+ },
+};
+
+static struct platform_device m548x_uart = {
+ .name = "mcfuart",
+ .id = 0,
+ .dev.platform_data = m548x_uart_platform,
+};
+
+static struct platform_device *m548x_devices[] __initdata = {
+ &m548x_uart,
+};
+
+
+/***************************************************************************/
+
+static void __init m548x_uart_init_line(int line, int irq)
+{
+ int rts_cts;
+
+ /* enable io pins */
+ switch (line) {
+ case 0:
+ rts_cts = 0; break;
+ case 1:
+ rts_cts = MCF_PAR_PSC_RTS_RTS; break;
+ case 2:
+ rts_cts = MCF_PAR_PSC_RTS_RTS | MCF_PAR_PSC_CTS_CTS; break;
+ case 3:
+ rts_cts = 0; break;
+ }
+ __raw_writeb(MCF_PAR_PSC_TXD | rts_cts | MCF_PAR_PSC_RXD,
+ MCF_MBAR + MCF_PAR_PSC(line));
+}
+
+static void __init m548x_uarts_init(void)
+{
+ const int nrlines = ARRAY_SIZE(m548x_uart_platform);
+ int line;
+
+ for (line = 0; (line < nrlines); line++)
+ m548x_uart_init_line(line, m548x_uart_platform[line].irq);
+}
+
+/***************************************************************************/
+
+static void mcf548x_reset(void)
+{
+ /* disable interrupts and enable the watchdog */
+ asm("movew #0x2700, %sr\n");
+ __raw_writel(0, MCF_MBAR + MCF_GPT_GMS0);
+ __raw_writel(MCF_GPT_GCIR_CNT(1), MCF_MBAR + MCF_GPT_GCIR0);
+ __raw_writel(MCF_GPT_GMS_WDEN | MCF_GPT_GMS_CE | MCF_GPT_GMS_TMS(4),
+ MCF_MBAR + MCF_GPT_GMS0);
+}
+
+/***************************************************************************/
+
+void __init config_BSP(char *commandp, int size)
+{
+ mach_reset = mcf548x_reset;
+ m548x_uarts_init();
+}
+
+/***************************************************************************/
+
+static int __init init_BSP(void)
+{
+
+ platform_add_devices(m548x_devices, ARRAY_SIZE(m548x_devices));
+ return 0;
+}
+
+arch_initcall(init_BSP);
+
+/***************************************************************************/
diff --git a/arch/m68knommu/platform/68328/entry.S b/arch/m68knommu/platform/68328/entry.S
index 9d80d2c42866..27241e16a526 100644
--- a/arch/m68knommu/platform/68328/entry.S
+++ b/arch/m68knommu/platform/68328/entry.S
@@ -43,10 +43,10 @@ badsys:
jra ret_from_exception
do_trace:
- movel #-ENOSYS,%sp@(PT_OFF_D0) /* needed for strace*/
+ movel #-ENOSYS,%sp@(PT_OFF_D0) /* needed for strace*/
subql #4,%sp
SAVE_SWITCH_STACK
- jbsr syscall_trace
+ jbsr syscall_trace_enter
RESTORE_SWITCH_STACK
addql #4,%sp
movel %sp@(PT_OFF_ORIG_D0),%d1
@@ -57,10 +57,10 @@ do_trace:
lea sys_call_table, %a0
jbsr %a0@(%d1)
-1: movel %d0,%sp@(PT_OFF_D0) /* save the return value */
+1: movel %d0,%sp@(PT_OFF_D0) /* save the return value */
subql #4,%sp /* dummy return address */
SAVE_SWITCH_STACK
- jbsr syscall_trace
+ jbsr syscall_trace_leave
ret_from_signal:
RESTORE_SWITCH_STACK
@@ -71,16 +71,16 @@ ENTRY(system_call)
SAVE_ALL
/* save top of frame*/
- pea %sp@
- jbsr set_esp0
- addql #4,%sp
+ pea %sp@
+ jbsr set_esp0
+ addql #4,%sp
movel %sp@(PT_OFF_ORIG_D0),%d0
movel %sp,%d1 /* get thread_info pointer */
andl #-THREAD_SIZE,%d1
movel %d1,%a2
- btst #TIF_SYSCALL_TRACE,%a2@(TI_FLAGS)
+ btst #(TIF_SYSCALL_TRACE%8),%a2@(TI_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
jne do_trace
cmpl #NR_syscalls,%d0
jcc badsys
@@ -88,10 +88,10 @@ ENTRY(system_call)
lea sys_call_table,%a0
movel %a0@(%d0), %a0
jbsr %a0@
- movel %d0,%sp@(PT_OFF_D0) /* save the return value*/
+ movel %d0,%sp@(PT_OFF_D0) /* save the return value*/
ret_from_exception:
- btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel*/
+ btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel*/
jeq Luser_return /* if so, skip resched, signals*/
Lkernel_return:
@@ -133,7 +133,7 @@ Lreturn:
*/
inthandler1:
SAVE_ALL
- movew %sp@(PT_OFF_VECTOR), %d0
+ movew %sp@(PT_OFF_FORMATVEC), %d0
and #0x3ff, %d0
movel %sp,%sp@-
@@ -144,7 +144,7 @@ inthandler1:
inthandler2:
SAVE_ALL
- movew %sp@(PT_OFF_VECTOR), %d0
+ movew %sp@(PT_OFF_FORMATVEC), %d0
and #0x3ff, %d0
movel %sp,%sp@-
@@ -155,7 +155,7 @@ inthandler2:
inthandler3:
SAVE_ALL
- movew %sp@(PT_OFF_VECTOR), %d0
+ movew %sp@(PT_OFF_FORMATVEC), %d0
and #0x3ff, %d0
movel %sp,%sp@-
@@ -166,7 +166,7 @@ inthandler3:
inthandler4:
SAVE_ALL
- movew %sp@(PT_OFF_VECTOR), %d0
+ movew %sp@(PT_OFF_FORMATVEC), %d0
and #0x3ff, %d0
movel %sp,%sp@-
@@ -177,7 +177,7 @@ inthandler4:
inthandler5:
SAVE_ALL
- movew %sp@(PT_OFF_VECTOR), %d0
+ movew %sp@(PT_OFF_FORMATVEC), %d0
and #0x3ff, %d0
movel %sp,%sp@-
@@ -188,7 +188,7 @@ inthandler5:
inthandler6:
SAVE_ALL
- movew %sp@(PT_OFF_VECTOR), %d0
+ movew %sp@(PT_OFF_FORMATVEC), %d0
and #0x3ff, %d0
movel %sp,%sp@-
@@ -199,7 +199,7 @@ inthandler6:
inthandler7:
SAVE_ALL
- movew %sp@(PT_OFF_VECTOR), %d0
+ movew %sp@(PT_OFF_FORMATVEC), %d0
and #0x3ff, %d0
movel %sp,%sp@-
@@ -210,7 +210,7 @@ inthandler7:
inthandler:
SAVE_ALL
- movew %sp@(PT_OFF_VECTOR), %d0
+ movew %sp@(PT_OFF_FORMATVEC), %d0
and #0x3ff, %d0
movel %sp,%sp@-
diff --git a/arch/m68knommu/platform/68328/head-de2.S b/arch/m68knommu/platform/68328/head-de2.S
index 92d96456d363..f632fdcb93e9 100644
--- a/arch/m68knommu/platform/68328/head-de2.S
+++ b/arch/m68knommu/platform/68328/head-de2.S
@@ -1,11 +1,5 @@
-#if defined(CONFIG_RAM32MB)
-#define MEM_END 0x02000000 /* Memory size 32Mb */
-#elif defined(CONFIG_RAM16MB)
-#define MEM_END 0x01000000 /* Memory size 16Mb */
-#else
#define MEM_END 0x00800000 /* Memory size 8Mb */
-#endif
#undef CRT_DEBUG
diff --git a/arch/m68knommu/platform/68328/head-ram.S b/arch/m68knommu/platform/68328/head-ram.S
index 252b80b02038..7f1aeeacb219 100644
--- a/arch/m68knommu/platform/68328/head-ram.S
+++ b/arch/m68knommu/platform/68328/head-ram.S
@@ -67,33 +67,6 @@ pclp1:
beq pclp1
#endif /* DEBUG */
-#ifdef CONFIG_RELOCATE
- /* Copy me to RAM */
- moveal #__rom_start, %a0
- moveal #_stext, %a1
- moveal #_edata, %a2
-
- /* Copy %a0 to %a1 until %a1 == %a2 */
-LD1:
- movel %a0@+, %d0
- movel %d0, %a1@+
- cmpal %a1, %a2
- bhi LD1
-
-#ifdef DEBUG
- moveq #74, %d7 /* 'J' */
- moveb %d7,0xfffff907 /* No absolute addresses */
-pclp2:
- movew 0xfffff906, %d7
- andw #0x2000, %d7
- beq pclp2
-#endif /* DEBUG */
- /* jump into the RAM copy */
- jmp ram_jump
-ram_jump:
-
-#endif /* CONFIG_RELOCATE */
-
#ifdef DEBUG
moveq #82, %d7 /* 'R' */
moveb %d7,0xfffff907 /* No absolute addresses */
diff --git a/arch/m68knommu/platform/68328/ints.c b/arch/m68knommu/platform/68328/ints.c
index b91ee85d4b5d..865852806a17 100644
--- a/arch/m68knommu/platform/68328/ints.c
+++ b/arch/m68knommu/platform/68328/ints.c
@@ -179,10 +179,8 @@ void __init init_IRQ(void)
IMR = ~0;
for (i = 0; (i < NR_IRQS); i++) {
- irq_desc[i].status = IRQ_DISABLED;
- irq_desc[i].action = NULL;
- irq_desc[i].depth = 1;
- irq_desc[i].chip = &intc_irq_chip;
+ set_irq_chip(irq, &intc_irq_chip);
+ set_irq_handler(irq, handle_level_irq);
}
}
diff --git a/arch/m68knommu/platform/68360/entry.S b/arch/m68knommu/platform/68360/entry.S
index 6d3460a39cac..c131c6e1d92d 100644
--- a/arch/m68knommu/platform/68360/entry.S
+++ b/arch/m68knommu/platform/68360/entry.S
@@ -42,7 +42,7 @@ do_trace:
movel #-ENOSYS,%sp@(PT_OFF_D0) /* needed for strace*/
subql #4,%sp
SAVE_SWITCH_STACK
- jbsr syscall_trace
+ jbsr syscall_trace_enter
RESTORE_SWITCH_STACK
addql #4,%sp
movel %sp@(PT_OFF_ORIG_D0),%d1
@@ -56,7 +56,7 @@ do_trace:
1: movel %d0,%sp@(PT_OFF_D0) /* save the return value */
subql #4,%sp /* dummy return address */
SAVE_SWITCH_STACK
- jbsr syscall_trace
+ jbsr syscall_trace_leave
ret_from_signal:
RESTORE_SWITCH_STACK
@@ -71,7 +71,12 @@ ENTRY(system_call)
jbsr set_esp0
addql #4,%sp
- btst #PF_TRACESYS_BIT,%a2@(TASK_FLAGS+PF_TRACESYS_OFF)
+ movel %sp@(PT_OFF_ORIG_D0),%d0
+
+ movel %sp,%d1 /* get thread_info pointer */
+ andl #-THREAD_SIZE,%d1
+ movel %d1,%a2
+ btst #(TIF_SYSCALL_TRACE%8),%a2@(TI_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
jne do_trace
cmpl #NR_syscalls,%d0
jcc badsys
@@ -124,7 +129,7 @@ Lreturn:
*/
inthandler:
SAVE_ALL
- movew %sp@(PT_OFF_VECTOR), %d0
+ movew %sp@(PT_OFF_FORMATVEC), %d0
and.l #0x3ff, %d0
lsr.l #0x02, %d0
diff --git a/arch/m68knommu/platform/68360/ints.c b/arch/m68knommu/platform/68360/ints.c
index 6f22970d8c20..ad96ab1051f0 100644
--- a/arch/m68knommu/platform/68360/ints.c
+++ b/arch/m68knommu/platform/68360/ints.c
@@ -132,10 +132,8 @@ void init_IRQ(void)
pquicc->intr_cimr = 0x00000000;
for (i = 0; (i < NR_IRQS); i++) {
- irq_desc[i].status = IRQ_DISABLED;
- irq_desc[i].action = NULL;
- irq_desc[i].depth = 1;
- irq_desc[i].chip = &intc_irq_chip;
+ set_irq_chip(irq, &intc_irq_chip);
+ set_irq_handler(irq, handle_level_irq);
}
}
diff --git a/arch/m68knommu/platform/68VZ328/config.c b/arch/m68knommu/platform/68VZ328/config.c
index fc5c63054e98..eabaabe8af36 100644
--- a/arch/m68knommu/platform/68VZ328/config.c
+++ b/arch/m68knommu/platform/68VZ328/config.c
@@ -90,11 +90,6 @@ static void init_hardware(char *command, int size)
PDIQEG &= ~PD(1);
PDIRQEN |= PD(1); /* IRQ enabled */
-#ifdef CONFIG_68328_SERIAL_UART2
- /* Enable RXD TXD port bits to enable UART2 */
- PJSEL &= ~(PJ(5) | PJ(4));
-#endif
-
#ifdef CONFIG_INIT_LCD
/* initialize LCD controller */
LSSA = (long) screen_bits;
diff --git a/arch/m68knommu/platform/coldfire/Makefile b/arch/m68knommu/platform/coldfire/Makefile
index f72a0e5d9996..45f501fa4525 100644
--- a/arch/m68knommu/platform/coldfire/Makefile
+++ b/arch/m68knommu/platform/coldfire/Makefile
@@ -8,8 +8,8 @@
# on the console port whenever a DBG interrupt occurs. You have to
# set up you HW breakpoints to trigger a DBG interrupt:
#
-# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
-# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
+# ccflags-y := -DTRAP_DBG_INTERRUPT
+# asflags-y := -DTRAP_DBG_INTERRUPT
#
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
@@ -26,6 +26,7 @@ obj-$(CONFIG_M528x) += pit.o intc-2.o
obj-$(CONFIG_M5307) += timers.o intc.o
obj-$(CONFIG_M532x) += timers.o intc-simr.o
obj-$(CONFIG_M5407) += timers.o intc.o
+obj-$(CONFIG_M548x) += sltimers.o intc-2.o
obj-y += pinmux.o gpio.o
extra-y := head.o
diff --git a/arch/m68knommu/platform/coldfire/entry.S b/arch/m68knommu/platform/coldfire/entry.S
index dd7d591f70ea..5e92bed94b7e 100644
--- a/arch/m68knommu/platform/coldfire/entry.S
+++ b/arch/m68knommu/platform/coldfire/entry.S
@@ -88,7 +88,7 @@ ENTRY(system_call)
movel %d2,PT_OFF_D0(%sp) /* on syscall entry */
subql #4,%sp
SAVE_SWITCH_STACK
- jbsr syscall_trace
+ jbsr syscall_trace_enter
RESTORE_SWITCH_STACK
addql #4,%sp
movel %d3,%a0
@@ -96,7 +96,7 @@ ENTRY(system_call)
movel %d0,%sp@(PT_OFF_D0) /* save the return value */
subql #4,%sp /* dummy return address */
SAVE_SWITCH_STACK
- jbsr syscall_trace
+ jbsr syscall_trace_leave
ret_from_signal:
RESTORE_SWITCH_STACK
@@ -112,7 +112,7 @@ ret_from_exception:
andl #-THREAD_SIZE,%d1 /* at base of kernel stack */
movel %d1,%a0
movel %a0@(TI_FLAGS),%d1 /* get thread_info->flags */
- andl #_TIF_NEED_RESCHED,%d1
+ andl #(1<<TIF_NEED_RESCHED),%d1
jeq Lkernel_return
movel %a0@(TI_PREEMPTCOUNT),%d1
@@ -136,7 +136,7 @@ Luser_return:
andl #-THREAD_SIZE,%d1 /* at base of kernel stack */
movel %d1,%a0
movel %a0@(TI_FLAGS),%d1 /* get thread_info->flags */
- andl #_TIF_WORK_MASK,%d1
+ andl #0xefff,%d1
jne Lwork_to_do /* still work to do */
Lreturn:
diff --git a/arch/m68knommu/platform/coldfire/head.S b/arch/m68knommu/platform/coldfire/head.S
index 4b91aa24eb00..0b2d7c7adf79 100644
--- a/arch/m68knommu/platform/coldfire/head.S
+++ b/arch/m68knommu/platform/coldfire/head.S
@@ -15,6 +15,7 @@
#include <asm/coldfire.h>
#include <asm/mcfcache.h>
#include <asm/mcfsim.h>
+#include <asm/thread_info.h>
/*****************************************************************************/
diff --git a/arch/m68knommu/platform/coldfire/intc-2.c b/arch/m68knommu/platform/coldfire/intc-2.c
index 5598c8b8661f..85daa2b3001a 100644
--- a/arch/m68knommu/platform/coldfire/intc-2.c
+++ b/arch/m68knommu/platform/coldfire/intc-2.c
@@ -1,5 +1,11 @@
/*
- * intc-1.c
+ * intc-2.c
+ *
+ * General interrupt controller code for the many ColdFire cores that use
+ * interrupt controllers with 63 interrupt sources, organized as 56 fully-
+ * programmable + 7 fixed-level interrupt sources. This includes the 523x
+ * family, the 5270, 5271, 5274, 5275, and the 528x family which have two such
+ * controllers, and the 547x and 548x families which have only one of them.
*
* (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
*
@@ -19,21 +25,37 @@
#include <asm/traps.h>
/*
- * Each vector needs a unique priority and level asscoiated with it.
+ * Bit definitions for the ICR family of registers.
+ */
+#define MCFSIM_ICR_LEVEL(l) ((l)<<3) /* Level l intr */
+#define MCFSIM_ICR_PRI(p) (p) /* Priority p intr */
+
+/*
+ * Each vector needs a unique priority and level associated with it.
* We don't really care so much what they are, we don't rely on the
- * tranditional priority interrupt scheme of the m68k/ColdFire.
+ * traditional priority interrupt scheme of the m68k/ColdFire.
*/
-static u8 intc_intpri = 0x36;
+static u8 intc_intpri = MCFSIM_ICR_LEVEL(6) | MCFSIM_ICR_PRI(6);
+
+#ifdef MCFICM_INTC1
+#define NR_VECS 128
+#else
+#define NR_VECS 64
+#endif
static void intc_irq_mask(unsigned int irq)
{
- if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECBASE + 128)) {
+ if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECBASE + NR_VECS)) {
unsigned long imraddr;
u32 val, imrbit;
irq -= MCFINT_VECBASE;
imraddr = MCF_IPSBAR;
+#ifdef MCFICM_INTC1
imraddr += (irq & 0x40) ? MCFICM_INTC1 : MCFICM_INTC0;
+#else
+ imraddr += MCFICM_INTC0;
+#endif
imraddr += (irq & 0x20) ? MCFINTC_IMRH : MCFINTC_IMRL;
imrbit = 0x1 << (irq & 0x1f);
@@ -44,13 +66,17 @@ static void intc_irq_mask(unsigned int irq)
static void intc_irq_unmask(unsigned int irq)
{
- if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECBASE + 128)) {
+ if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECBASE + NR_VECS)) {
unsigned long intaddr, imraddr, icraddr;
u32 val, imrbit;
irq -= MCFINT_VECBASE;
intaddr = MCF_IPSBAR;
+#ifdef MCFICM_INTC1
intaddr += (irq & 0x40) ? MCFICM_INTC1 : MCFICM_INTC0;
+#else
+ intaddr += MCFICM_INTC0;
+#endif
imraddr = intaddr + ((irq & 0x20) ? MCFINTC_IMRH : MCFINTC_IMRL);
icraddr = intaddr + MCFINTC_ICR0 + (irq & 0x3f);
imrbit = 0x1 << (irq & 0x1f);
@@ -67,10 +93,16 @@ static void intc_irq_unmask(unsigned int irq)
}
}
+static int intc_irq_set_type(unsigned int irq, unsigned int type)
+{
+ return 0;
+}
+
static struct irq_chip intc_irq_chip = {
.name = "CF-INTC",
.mask = intc_irq_mask,
.unmask = intc_irq_unmask,
+ .set_type = intc_irq_set_type,
};
void __init init_IRQ(void)
@@ -81,13 +113,14 @@ void __init init_IRQ(void)
/* Mask all interrupt sources */
__raw_writel(0x1, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
+#ifdef MCFICM_INTC1
__raw_writel(0x1, MCF_IPSBAR + MCFICM_INTC1 + MCFINTC_IMRL);
+#endif
for (irq = 0; (irq < NR_IRQS); irq++) {
- irq_desc[irq].status = IRQ_DISABLED;
- irq_desc[irq].action = NULL;
- irq_desc[irq].depth = 1;
- irq_desc[irq].chip = &intc_irq_chip;
+ set_irq_chip(irq, &intc_irq_chip);
+ set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH);
+ set_irq_handler(irq, handle_level_irq);
}
}
diff --git a/arch/m68knommu/platform/coldfire/intc-simr.c b/arch/m68knommu/platform/coldfire/intc-simr.c
index 1b01e79c2f63..bb7048636140 100644
--- a/arch/m68knommu/platform/coldfire/intc-simr.c
+++ b/arch/m68knommu/platform/coldfire/intc-simr.c
@@ -1,6 +1,8 @@
/*
* intc-simr.c
*
+ * Interrupt controller code for the ColdFire 5208, 5207 & 532x parts.
+ *
* (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
*
* This file is subject to the terms and conditions of the GNU General Public
@@ -68,11 +70,9 @@ void __init init_IRQ(void)
__raw_writeb(0xff, MCFINTC1_SIMR);
for (irq = 0; (irq < NR_IRQS); irq++) {
- irq_desc[irq].status = IRQ_DISABLED;
- irq_desc[irq].action = NULL;
- irq_desc[irq].depth = 1;
- irq_desc[irq].chip = &intc_irq_chip;
- intc_irq_set_type(irq, 0);
+ set_irq_chip(irq, &intc_irq_chip);
+ set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH);
+ set_irq_handler(irq, handle_level_irq);
}
}
diff --git a/arch/m68knommu/platform/coldfire/intc.c b/arch/m68knommu/platform/coldfire/intc.c
index a4560c86db71..60d2fcbe182b 100644
--- a/arch/m68knommu/platform/coldfire/intc.c
+++ b/arch/m68knommu/platform/coldfire/intc.c
@@ -143,11 +143,9 @@ void __init init_IRQ(void)
mcf_maskimr(0xffffffff);
for (irq = 0; (irq < NR_IRQS); irq++) {
- irq_desc[irq].status = IRQ_DISABLED;
- irq_desc[irq].action = NULL;
- irq_desc[irq].depth = 1;
- irq_desc[irq].chip = &intc_irq_chip;
- intc_irq_set_type(irq, 0);
+ set_irq_chip(irq, &intc_irq_chip);
+ set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH);
+ set_irq_handler(irq, handle_level_irq);
}
}
diff --git a/arch/m68knommu/platform/coldfire/sltimers.c b/arch/m68knommu/platform/coldfire/sltimers.c
new file mode 100644
index 000000000000..0a1b937c3e18
--- /dev/null
+++ b/arch/m68knommu/platform/coldfire/sltimers.c
@@ -0,0 +1,145 @@
+/***************************************************************************/
+
+/*
+ * sltimers.c -- generic ColdFire slice timer support.
+ *
+ * Copyright (C) 2009-2010, Philippe De Muyter <phdm@macqel.be>
+ * based on
+ * timers.c -- generic ColdFire hardware timer support.
+ * Copyright (C) 1999-2008, Greg Ungerer <gerg@snapgear.com>
+ */
+
+/***************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/profile.h>
+#include <linux/clocksource.h>
+#include <asm/io.h>
+#include <asm/traps.h>
+#include <asm/machdep.h>
+#include <asm/coldfire.h>
+#include <asm/mcfslt.h>
+#include <asm/mcfsim.h>
+
+/***************************************************************************/
+
+#ifdef CONFIG_HIGHPROFILE
+
+/*
+ * By default use Slice Timer 1 as the profiler clock timer.
+ */
+#define PA(a) (MCF_MBAR + MCFSLT_TIMER1 + (a))
+
+/*
+ * Choose a reasonably fast profile timer. Make it an odd value to
+ * try and get good coverage of kernel operations.
+ */
+#define PROFILEHZ 1013
+
+irqreturn_t mcfslt_profile_tick(int irq, void *dummy)
+{
+ /* Reset Slice Timer 1 */
+ __raw_writel(MCFSLT_SSR_BE | MCFSLT_SSR_TE, PA(MCFSLT_SSR));
+ if (current->pid)
+ profile_tick(CPU_PROFILING);
+ return IRQ_HANDLED;
+}
+
+static struct irqaction mcfslt_profile_irq = {
+ .name = "profile timer",
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .handler = mcfslt_profile_tick,
+};
+
+void mcfslt_profile_init(void)
+{
+ printk(KERN_INFO "PROFILE: lodging TIMER 1 @ %dHz as profile timer\n",
+ PROFILEHZ);
+
+ setup_irq(MCF_IRQ_PROFILER, &mcfslt_profile_irq);
+
+ /* Set up TIMER 2 as high speed profile clock */
+ __raw_writel(MCF_BUSCLK / PROFILEHZ - 1, PA(MCFSLT_STCNT));
+ __raw_writel(MCFSLT_SCR_RUN | MCFSLT_SCR_IEN | MCFSLT_SCR_TEN,
+ PA(MCFSLT_SCR));
+
+}
+
+#endif /* CONFIG_HIGHPROFILE */
+
+/***************************************************************************/
+
+/*
+ * By default use Slice Timer 0 as the system clock timer.
+ */
+#define TA(a) (MCF_MBAR + MCFSLT_TIMER0 + (a))
+
+static u32 mcfslt_cycles_per_jiffy;
+static u32 mcfslt_cnt;
+
+static irqreturn_t mcfslt_tick(int irq, void *dummy)
+{
+ /* Reset Slice Timer 0 */
+ __raw_writel(MCFSLT_SSR_BE | MCFSLT_SSR_TE, TA(MCFSLT_SSR));
+ mcfslt_cnt += mcfslt_cycles_per_jiffy;
+ return arch_timer_interrupt(irq, dummy);
+}
+
+static struct irqaction mcfslt_timer_irq = {
+ .name = "timer",
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .handler = mcfslt_tick,
+};
+
+static cycle_t mcfslt_read_clk(struct clocksource *cs)
+{
+ unsigned long flags;
+ u32 cycles;
+ u16 scnt;
+
+ local_irq_save(flags);
+ scnt = __raw_readl(TA(MCFSLT_SCNT));
+ cycles = mcfslt_cnt;
+ local_irq_restore(flags);
+
+ /* substract because slice timers count down */
+ return cycles - scnt;
+}
+
+static struct clocksource mcfslt_clk = {
+ .name = "slt",
+ .rating = 250,
+ .read = mcfslt_read_clk,
+ .shift = 20,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+void hw_timer_init(void)
+{
+ mcfslt_cycles_per_jiffy = MCF_BUSCLK / HZ;
+ /*
+ * The coldfire slice timer (SLT) runs from STCNT to 0 included,
+ * then STCNT again and so on. It counts thus actually
+ * STCNT + 1 steps for 1 tick, not STCNT. So if you want
+ * n cycles, initialize STCNT with n - 1.
+ */
+ __raw_writel(mcfslt_cycles_per_jiffy - 1, TA(MCFSLT_STCNT));
+ __raw_writel(MCFSLT_SCR_RUN | MCFSLT_SCR_IEN | MCFSLT_SCR_TEN,
+ TA(MCFSLT_SCR));
+ /* initialize mcfslt_cnt knowing that slice timers count down */
+ mcfslt_cnt = mcfslt_cycles_per_jiffy;
+
+ setup_irq(MCF_IRQ_TIMER, &mcfslt_timer_irq);
+
+ mcfslt_clk.mult = clocksource_hz2mult(MCF_BUSCLK, mcfslt_clk.shift);
+ clocksource_register(&mcfslt_clk);
+
+#ifdef CONFIG_HIGHPROFILE
+ mcfslt_profile_init();
+#endif
+}
diff --git a/arch/microblaze/include/asm/irqflags.h b/arch/microblaze/include/asm/irqflags.h
index 2c38c6d80176..5fd31905775d 100644
--- a/arch/microblaze/include/asm/irqflags.h
+++ b/arch/microblaze/include/asm/irqflags.h
@@ -9,103 +9,114 @@
#ifndef _ASM_MICROBLAZE_IRQFLAGS_H
#define _ASM_MICROBLAZE_IRQFLAGS_H
-#include <linux/irqflags.h>
+#include <linux/types.h>
#include <asm/registers.h>
-# if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
-
-# define raw_local_irq_save(flags) \
- do { \
- asm volatile (" msrclr %0, %1; \
- nop;" \
- : "=r"(flags) \
- : "i"(MSR_IE) \
- : "memory"); \
- } while (0)
-
-# define raw_local_irq_disable() \
- do { \
- asm volatile (" msrclr r0, %0; \
- nop;" \
- : \
- : "i"(MSR_IE) \
- : "memory"); \
- } while (0)
-
-# define raw_local_irq_enable() \
- do { \
- asm volatile (" msrset r0, %0; \
- nop;" \
- : \
- : "i"(MSR_IE) \
- : "memory"); \
- } while (0)
-
-# else /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR == 0 */
-
-# define raw_local_irq_save(flags) \
- do { \
- register unsigned tmp; \
- asm volatile (" mfs %0, rmsr; \
- nop; \
- andi %1, %0, %2; \
- mts rmsr, %1; \
- nop;" \
- : "=r"(flags), "=r" (tmp) \
- : "i"(~MSR_IE) \
- : "memory"); \
- } while (0)
-
-# define raw_local_irq_disable() \
- do { \
- register unsigned tmp; \
- asm volatile (" mfs %0, rmsr; \
- nop; \
- andi %0, %0, %1; \
- mts rmsr, %0; \
- nop;" \
- : "=r"(tmp) \
- : "i"(~MSR_IE) \
- : "memory"); \
- } while (0)
-
-# define raw_local_irq_enable() \
- do { \
- register unsigned tmp; \
- asm volatile (" mfs %0, rmsr; \
- nop; \
- ori %0, %0, %1; \
- mts rmsr, %0; \
- nop;" \
- : "=r"(tmp) \
- : "i"(MSR_IE) \
- : "memory"); \
- } while (0)
-
-# endif /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
-
-#define raw_local_irq_restore(flags) \
- do { \
- asm volatile (" mts rmsr, %0; \
- nop;" \
- : \
- : "r"(flags) \
- : "memory"); \
- } while (0)
-
-static inline unsigned long get_msr(void)
+#ifdef CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+
+static inline unsigned long arch_local_irq_save(void)
+{
+ unsigned long flags;
+ asm volatile(" msrclr %0, %1 \n"
+ " nop \n"
+ : "=r"(flags)
+ : "i"(MSR_IE)
+ : "memory");
+ return flags;
+}
+
+static inline void arch_local_irq_disable(void)
+{
+ /* this uses r0 without declaring it - is that correct? */
+ asm volatile(" msrclr r0, %0 \n"
+ " nop \n"
+ :
+ : "i"(MSR_IE)
+ : "memory");
+}
+
+static inline void arch_local_irq_enable(void)
+{
+ /* this uses r0 without declaring it - is that correct? */
+ asm volatile(" msrset r0, %0 \n"
+ " nop \n"
+ :
+ : "i"(MSR_IE)
+ : "memory");
+}
+
+#else /* !CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
+
+static inline unsigned long arch_local_irq_save(void)
+{
+ unsigned long flags, tmp;
+ asm volatile (" mfs %0, rmsr \n"
+ " nop \n"
+ " andi %1, %0, %2 \n"
+ " mts rmsr, %1 \n"
+ " nop \n"
+ : "=r"(flags), "=r"(tmp)
+ : "i"(~MSR_IE)
+ : "memory");
+ return flags;
+}
+
+static inline void arch_local_irq_disable(void)
+{
+ unsigned long tmp;
+ asm volatile(" mfs %0, rmsr \n"
+ " nop \n"
+ " andi %0, %0, %1 \n"
+ " mts rmsr, %0 \n"
+ " nop \n"
+ : "=r"(tmp)
+ : "i"(~MSR_IE)
+ : "memory");
+}
+
+static inline void arch_local_irq_enable(void)
+{
+ unsigned long tmp;
+ asm volatile(" mfs %0, rmsr \n"
+ " nop \n"
+ " ori %0, %0, %1 \n"
+ " mts rmsr, %0 \n"
+ " nop \n"
+ : "=r"(tmp)
+ : "i"(MSR_IE)
+ : "memory");
+}
+
+#endif /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
+
+static inline unsigned long arch_local_save_flags(void)
{
unsigned long flags;
- asm volatile (" mfs %0, rmsr; \
- nop;" \
- : "=r"(flags) \
- : \
- : "memory"); \
+ asm volatile(" mfs %0, rmsr \n"
+ " nop \n"
+ : "=r"(flags)
+ :
+ : "memory");
return flags;
}
-#define raw_local_save_flags(flags) ((flags) = get_msr())
-#define raw_irqs_disabled() ((get_msr() & MSR_IE) == 0)
-#define raw_irqs_disabled_flags(flags) ((flags & MSR_IE) == 0)
+static inline void arch_local_irq_restore(unsigned long flags)
+{
+ asm volatile(" mts rmsr, %0 \n"
+ " nop \n"
+ :
+ : "r"(flags)
+ : "memory");
+}
+
+static inline bool arch_irqs_disabled_flags(unsigned long flags)
+{
+ return (flags & MSR_IE) == 0;
+}
+
+static inline bool arch_irqs_disabled(void)
+{
+ return arch_irqs_disabled_flags(arch_local_save_flags());
+}
#endif /* _ASM_MICROBLAZE_IRQFLAGS_H */
diff --git a/arch/microblaze/include/asm/memblock.h b/arch/microblaze/include/asm/memblock.h
index f9c2fa331d2a..20a8e257c77f 100644
--- a/arch/microblaze/include/asm/memblock.h
+++ b/arch/microblaze/include/asm/memblock.h
@@ -9,9 +9,6 @@
#ifndef _ASM_MICROBLAZE_MEMBLOCK_H
#define _ASM_MICROBLAZE_MEMBLOCK_H
-/* MEMBLOCK limit is OFF */
-#define MEMBLOCK_REAL_LIMIT 0xFFFFFFFF
-
#endif /* _ASM_MICROBLAZE_MEMBLOCK_H */
diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
index 427b13b4740f..bacbd3d41ec7 100644
--- a/arch/microblaze/kernel/prom.c
+++ b/arch/microblaze/kernel/prom.c
@@ -42,11 +42,6 @@
#include <asm/sections.h>
#include <asm/pci-bridge.h>
-void __init early_init_dt_scan_chosen_arch(unsigned long node)
-{
- /* No Microblaze specific code here */
-}
-
void __init early_init_dt_add_memory_arch(u64 base, u64 size)
{
memblock_add(base, size);
diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c
index 65eb00419d19..c8437866d3b7 100644
--- a/arch/microblaze/mm/init.c
+++ b/arch/microblaze/mm/init.c
@@ -70,16 +70,16 @@ static void __init paging_init(void)
void __init setup_memory(void)
{
- int i;
unsigned long map_size;
+ struct memblock_region *reg;
+
#ifndef CONFIG_MMU
u32 kernel_align_start, kernel_align_size;
/* Find main memory where is the kernel */
- for (i = 0; i < memblock.memory.cnt; i++) {
- memory_start = (u32) memblock.memory.region[i].base;
- memory_end = (u32) memblock.memory.region[i].base
- + (u32) memblock.memory.region[i].size;
+ for_each_memblock(memory, reg) {
+ memory_start = (u32)reg->base;
+ memory_end = (u32) reg->base + reg->size;
if ((memory_start <= (u32)_text) &&
((u32)_text <= memory_end)) {
memory_size = memory_end - memory_start;
@@ -142,12 +142,10 @@ void __init setup_memory(void)
free_bootmem(memory_start, memory_size);
/* reserve allocate blocks */
- for (i = 0; i < memblock.reserved.cnt; i++) {
- pr_debug("reserved %d - 0x%08x-0x%08x\n", i,
- (u32) memblock.reserved.region[i].base,
- (u32) memblock_size_bytes(&memblock.reserved, i));
- reserve_bootmem(memblock.reserved.region[i].base,
- memblock_size_bytes(&memblock.reserved, i) - 1, BOOTMEM_DEFAULT);
+ for_each_memblock(reserved, reg) {
+ pr_debug("reserved - 0x%08x-0x%08x\n",
+ (u32) reg->base, (u32) reg->size);
+ reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT);
}
#ifdef CONFIG_MMU
init_bootmem_done = 1;
@@ -230,7 +228,7 @@ static void mm_cmdline_setup(void)
if (maxmem && memory_size > maxmem) {
memory_size = maxmem;
memory_end = memory_start + memory_size;
- memblock.memory.region[0].size = memory_size;
+ memblock.memory.regions[0].size = memory_size;
}
}
}
@@ -273,14 +271,14 @@ asmlinkage void __init mmu_init(void)
machine_restart(NULL);
}
- if ((u32) memblock.memory.region[0].size < 0x1000000) {
+ if ((u32) memblock.memory.regions[0].size < 0x1000000) {
printk(KERN_EMERG "Memory must be greater than 16MB\n");
machine_restart(NULL);
}
/* Find main memory where the kernel is */
- memory_start = (u32) memblock.memory.region[0].base;
- memory_end = (u32) memblock.memory.region[0].base +
- (u32) memblock.memory.region[0].size;
+ memory_start = (u32) memblock.memory.regions[0].base;
+ memory_end = (u32) memblock.memory.regions[0].base +
+ (u32) memblock.memory.regions[0].size;
memory_size = memory_end - memory_start;
mm_cmdline_setup(); /* FIXME parse args from command line - not used */
diff --git a/arch/mips/Kbuild b/arch/mips/Kbuild
index e322d65f33a4..7dd65cfae837 100644
--- a/arch/mips/Kbuild
+++ b/arch/mips/Kbuild
@@ -7,6 +7,10 @@ subdir-ccflags-y := -Werror
include arch/mips/Kbuild.platforms
obj-y := $(platform-y)
+# make clean traverses $(obj-) without having included .config, so
+# everything ends up here
+obj- := $(platform-)
+
# mips object files
# The object files are linked as core-y files would be linked
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 3ad59dde4852..46cae2b163e4 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -13,6 +13,7 @@ config MIPS
select HAVE_KPROBES
select HAVE_KRETPROBES
select RTC_LIB if !MACH_LOONGSON
+ select GENERIC_ATOMIC64 if !64BIT
mainmenu "Linux/MIPS Kernel Configuration"
@@ -880,11 +881,15 @@ config NO_IOPORT
config GENERIC_ISA_DMA
bool
select ZONE_DMA if GENERIC_ISA_DMA_SUPPORT_BROKEN=n
+ select ISA_DMA_API
config GENERIC_ISA_DMA_SUPPORT_BROKEN
bool
select GENERIC_ISA_DMA
+config ISA_DMA_API
+ bool
+
config GENERIC_GPIO
bool
@@ -1646,8 +1651,16 @@ config MIPS_MT_SMP
select SYS_SUPPORTS_SMP
select SMP_UP
help
- This is a kernel model which is also known a VSMP or lately
- has been marketesed into SMVP.
+ This is a kernel model which is known a VSMP but lately has been
+ marketesed into SMVP.
+ Virtual SMP uses the processor's VPEs to implement virtual
+ processors. In currently available configuration of the 34K processor
+ this allows for a dual processor. Both processors will share the same
+ primary caches; each will obtain the half of the TLB for it's own
+ exclusive use. For a layman this model can be described as similar to
+ what Intel calls Hyperthreading.
+
+ For further information see http://www.linux-mips.org/wiki/34K#VSMP
config MIPS_MT_SMTC
bool "SMTC: Use all TCs on all VPEs for SMP"
@@ -1664,6 +1677,14 @@ config MIPS_MT_SMTC
help
This is a kernel model which is known a SMTC or lately has been
marketesed into SMVP.
+ is presenting the available TC's of the core as processors to Linux.
+ On currently available 34K processors this means a Linux system will
+ see up to 5 processors. The implementation of the SMTC kernel differs
+ significantly from VSMP and cannot efficiently coexist in the same
+ kernel binary so the choice between VSMP and SMTC is a compile time
+ decision.
+
+ For further information see http://www.linux-mips.org/wiki/34K#SMTC
endchoice
@@ -2107,6 +2128,13 @@ config SECCOMP
If unsure, say Y. Only embedded should say N here.
+config USE_OF
+ bool "Flattened Device Tree support"
+ select OF
+ select OF_FLATTREE
+ help
+ Include support for flattened device tree machine descriptions.
+
endmenu
config LOCKDEP_SUPPORT
@@ -2175,10 +2203,14 @@ config TC
bool "TURBOchannel support"
depends on MACH_DECSTATION
help
- TurboChannel is a DEC (now Compaq (now HP)) bus for Alpha and MIPS
- processors. Documentation on writing device drivers for TurboChannel
- is available at:
- <http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/AA-PS3HD-TET1_html/TITLE.html>.
+ TURBOchannel is a DEC (now Compaq (now HP)) bus for Alpha and MIPS
+ processors. TURBOchannel programming specifications are available
+ at:
+ <ftp://ftp.hp.com/pub/alphaserver/archive/triadd/>
+ and:
+ <http://www.computer-refuge.org/classiccmp/ftp.digital.com/pub/DEC/TriAdd/>
+ Linux driver support status is documented at:
+ <http://www.linux-mips.org/wiki/DECstation>
#config ACCESSBUS
# bool "Access.Bus support"
diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c
index 1dc55ee2681b..3691630931d6 100644
--- a/arch/mips/alchemy/common/platform.c
+++ b/arch/mips/alchemy/common/platform.c
@@ -24,6 +24,33 @@
#include <prom.h>
+static void alchemy_8250_pm(struct uart_port *port, unsigned int state,
+ unsigned int old_state)
+{
+ switch (state) {
+ case 0:
+ if ((__raw_readl(port->membase + UART_MOD_CNTRL) & 3) != 3) {
+ /* power-on sequence as suggested in the databooks */
+ __raw_writel(0, port->membase + UART_MOD_CNTRL);
+ wmb();
+ __raw_writel(1, port->membase + UART_MOD_CNTRL);
+ wmb();
+ }
+ __raw_writel(3, port->membase + UART_MOD_CNTRL); /* full on */
+ wmb();
+ serial8250_do_pm(port, state, old_state);
+ break;
+ case 3: /* power off */
+ serial8250_do_pm(port, state, old_state);
+ __raw_writel(0, port->membase + UART_MOD_CNTRL);
+ wmb();
+ break;
+ default:
+ serial8250_do_pm(port, state, old_state);
+ break;
+ }
+}
+
#define PORT(_base, _irq) \
{ \
.mapbase = _base, \
@@ -33,6 +60,7 @@
.flags = UPF_SKIP_TEST | UPF_IOREMAP | \
UPF_FIXED_TYPE, \
.type = PORT_16550A, \
+ .pm = alchemy_8250_pm, \
}
static struct plat_serial8250_port au1x00_uart_data[] = {
diff --git a/arch/mips/alchemy/common/power.c b/arch/mips/alchemy/common/power.c
index 5ef06a164a82..e5916a516e58 100644
--- a/arch/mips/alchemy/common/power.c
+++ b/arch/mips/alchemy/common/power.c
@@ -49,11 +49,6 @@
* We only have to save/restore registers that aren't otherwise
* done as part of a driver pm_* function.
*/
-static unsigned int sleep_uart0_inten;
-static unsigned int sleep_uart0_fifoctl;
-static unsigned int sleep_uart0_linectl;
-static unsigned int sleep_uart0_clkdiv;
-static unsigned int sleep_uart0_enable;
static unsigned int sleep_usb[2];
static unsigned int sleep_sys_clocks[5];
static unsigned int sleep_sys_pinfunc;
@@ -62,22 +57,6 @@ static unsigned int sleep_static_memctlr[4][3];
static void save_core_regs(void)
{
- extern void save_au1xxx_intctl(void);
- extern void pm_eth0_shutdown(void);
-
- /*
- * Do the serial ports.....these really should be a pm_*
- * registered function by the driver......but of course the
- * standard serial driver doesn't understand our Au1xxx
- * unique registers.
- */
- sleep_uart0_inten = au_readl(UART0_ADDR + UART_IER);
- sleep_uart0_fifoctl = au_readl(UART0_ADDR + UART_FCR);
- sleep_uart0_linectl = au_readl(UART0_ADDR + UART_LCR);
- sleep_uart0_clkdiv = au_readl(UART0_ADDR + UART_CLK);
- sleep_uart0_enable = au_readl(UART0_ADDR + UART_MOD_CNTRL);
- au_sync();
-
#ifndef CONFIG_SOC_AU1200
/* Shutdown USB host/device. */
sleep_usb[0] = au_readl(USB_HOST_CONFIG);
@@ -175,20 +154,6 @@ static void restore_core_regs(void)
au_writel(sleep_static_memctlr[3][0], MEM_STCFG3);
au_writel(sleep_static_memctlr[3][1], MEM_STTIME3);
au_writel(sleep_static_memctlr[3][2], MEM_STADDR3);
-
- /*
- * Enable the UART if it was enabled before sleep.
- * I guess I should define module control bits........
- */
- if (sleep_uart0_enable & 0x02) {
- au_writel(0, UART0_ADDR + UART_MOD_CNTRL); au_sync();
- au_writel(1, UART0_ADDR + UART_MOD_CNTRL); au_sync();
- au_writel(3, UART0_ADDR + UART_MOD_CNTRL); au_sync();
- au_writel(sleep_uart0_inten, UART0_ADDR + UART_IER); au_sync();
- au_writel(sleep_uart0_fifoctl, UART0_ADDR + UART_FCR); au_sync();
- au_writel(sleep_uart0_linectl, UART0_ADDR + UART_LCR); au_sync();
- au_writel(sleep_uart0_clkdiv, UART0_ADDR + UART_CLK); au_sync();
- }
}
void au_sleep(void)
diff --git a/arch/mips/alchemy/common/prom.c b/arch/mips/alchemy/common/prom.c
index c29511b11d44..534021059629 100644
--- a/arch/mips/alchemy/common/prom.c
+++ b/arch/mips/alchemy/common/prom.c
@@ -43,7 +43,7 @@ int prom_argc;
char **prom_argv;
char **prom_envp;
-void prom_init_cmdline(void)
+void __init prom_init_cmdline(void)
{
int i;
@@ -104,7 +104,7 @@ static inline void str2eaddr(unsigned char *ea, unsigned char *str)
}
}
-int prom_get_ethernet_addr(char *ethernet_addr)
+int __init prom_get_ethernet_addr(char *ethernet_addr)
{
char *ethaddr_str;
@@ -123,7 +123,6 @@ int prom_get_ethernet_addr(char *ethernet_addr)
return 0;
}
-EXPORT_SYMBOL(prom_get_ethernet_addr);
void __init prom_free_prom_memory(void)
{
diff --git a/arch/mips/alchemy/devboards/bcsr.c b/arch/mips/alchemy/devboards/bcsr.c
index 3bc4fd2155d7..c52af8821da0 100644
--- a/arch/mips/alchemy/devboards/bcsr.c
+++ b/arch/mips/alchemy/devboards/bcsr.c
@@ -10,6 +10,7 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/spinlock.h>
+#include <linux/irq.h>
#include <asm/addrspace.h>
#include <asm/io.h>
#include <asm/mach-db1x00/bcsr.h>
diff --git a/arch/mips/ar7/irq.c b/arch/mips/ar7/irq.c
index c781556c44e4..4ec2642c568f 100644
--- a/arch/mips/ar7/irq.c
+++ b/arch/mips/ar7/irq.c
@@ -19,6 +19,7 @@
#include <linux/interrupt.h>
#include <linux/io.h>
+#include <linux/irq.h>
#include <asm/irq_cpu.h>
#include <asm/mipsregs.h>
diff --git a/arch/mips/bcm63xx/irq.c b/arch/mips/bcm63xx/irq.c
index a0c5cd18c192..3be87f2422f0 100644
--- a/arch/mips/bcm63xx/irq.c
+++ b/arch/mips/bcm63xx/irq.c
@@ -11,6 +11,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/module.h>
+#include <linux/irq.h>
#include <asm/irq_cpu.h>
#include <asm/mipsregs.h>
#include <bcm63xx_cpu.h>
diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile
index ed9bb709c9a3..5042d51b0512 100644
--- a/arch/mips/boot/compressed/Makefile
+++ b/arch/mips/boot/compressed/Makefile
@@ -59,7 +59,7 @@ $(obj)/piggy.o: $(obj)/dummy.o $(obj)/vmlinux.bin.z FORCE
hostprogs-y := calc_vmlinuz_load_addr
VMLINUZ_LOAD_ADDRESS = $(shell $(obj)/calc_vmlinuz_load_addr \
- $(objtree)/$(KBUILD_IMAGE) $(VMLINUX_LOAD_ADDRESS))
+ $(obj)/vmlinux.bin $(VMLINUX_LOAD_ADDRESS))
vmlinuzobjs-y += $(obj)/piggy.o
@@ -105,4 +105,4 @@ OBJCOPYFLAGS_vmlinuz.srec := $(OBJCOPYFLAGS) -S -O srec
vmlinuz.srec: vmlinuz
$(call cmd,objcopy)
-clean-files := $(objtree)/vmlinuz.*
+clean-files := $(objtree)/vmlinuz $(objtree)/vmlinuz.{32,ecoff,bin,srec}
diff --git a/arch/mips/cavium-octeon/Kconfig b/arch/mips/cavium-octeon/Kconfig
index 094c17e38e16..47323ca452dc 100644
--- a/arch/mips/cavium-octeon/Kconfig
+++ b/arch/mips/cavium-octeon/Kconfig
@@ -83,3 +83,7 @@ config ARCH_SPARSEMEM_ENABLE
def_bool y
select SPARSEMEM_STATIC
depends on CPU_CAVIUM_OCTEON
+
+config CAVIUM_OCTEON_HELPER
+ def_bool y
+ depends on OCTEON_ETHERNET || PCI
diff --git a/arch/mips/cavium-octeon/cpu.c b/arch/mips/cavium-octeon/cpu.c
index c664c8cc2b42..a5b427909b5c 100644
--- a/arch/mips/cavium-octeon/cpu.c
+++ b/arch/mips/cavium-octeon/cpu.c
@@ -41,7 +41,7 @@ static int cnmips_cu2_call(struct notifier_block *nfb, unsigned long action,
return NOTIFY_OK; /* Let default notifier send signals */
}
-static int cnmips_cu2_setup(void)
+static int __init cnmips_cu2_setup(void)
{
return cu2_notifier(cnmips_cu2_call, 0);
}
diff --git a/arch/mips/cavium-octeon/executive/Makefile b/arch/mips/cavium-octeon/executive/Makefile
index 2fd66db6939e..7f41c5be2190 100644
--- a/arch/mips/cavium-octeon/executive/Makefile
+++ b/arch/mips/cavium-octeon/executive/Makefile
@@ -11,4 +11,4 @@
obj-y += cvmx-bootmem.o cvmx-l2c.o cvmx-sysinfo.o octeon-model.o
-obj-$(CONFIG_PCI) += cvmx-helper-errata.o cvmx-helper-jtag.o
+obj-$(CONFIG_CAVIUM_OCTEON_HELPER) += cvmx-helper-errata.o cvmx-helper-jtag.o
diff --git a/arch/mips/cavium-octeon/serial.c b/arch/mips/cavium-octeon/serial.c
index 638adab02842..12dbf533b77d 100644
--- a/arch/mips/cavium-octeon/serial.c
+++ b/arch/mips/cavium-octeon/serial.c
@@ -13,6 +13,7 @@
#include <linux/serial_8250.h>
#include <linux/serial_reg.h>
#include <linux/tty.h>
+#include <linux/irq.h>
#include <asm/time.h>
diff --git a/arch/mips/dec/Platform b/arch/mips/dec/Platform
index 3adbcbd95db1..cf55a6f4e720 100644
--- a/arch/mips/dec/Platform
+++ b/arch/mips/dec/Platform
@@ -1,7 +1,7 @@
#
# DECstation family
#
-platform-$(CONFIG_MACH_DECSTATION) = dec/
+platform-$(CONFIG_MACH_DECSTATION) += dec/
cflags-$(CONFIG_MACH_DECSTATION) += \
-I$(srctree)/arch/mips/include/asm/mach-dec
libs-$(CONFIG_MACH_DECSTATION) += arch/mips/dec/prom/
diff --git a/arch/mips/dec/setup.c b/arch/mips/dec/setup.c
index bd5431e1f408..fa45e924be05 100644
--- a/arch/mips/dec/setup.c
+++ b/arch/mips/dec/setup.c
@@ -18,6 +18,7 @@
#include <linux/spinlock.h>
#include <linux/types.h>
#include <linux/pm.h>
+#include <linux/irq.h>
#include <asm/bootinfo.h>
#include <asm/cpu.h>
diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h
index c63c56bfd184..47d87da379f9 100644
--- a/arch/mips/include/asm/atomic.h
+++ b/arch/mips/include/asm/atomic.h
@@ -782,6 +782,10 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
*/
#define atomic64_add_negative(i, v) (atomic64_add_return(i, (v)) < 0)
+#else /* !CONFIG_64BIT */
+
+#include <asm-generic/atomic64.h>
+
#endif /* CONFIG_64BIT */
/*
diff --git a/arch/mips/include/asm/cop2.h b/arch/mips/include/asm/cop2.h
index 2cb2f0c2c4f8..3532e2c5f098 100644
--- a/arch/mips/include/asm/cop2.h
+++ b/arch/mips/include/asm/cop2.h
@@ -24,7 +24,7 @@ extern int cu2_notifier_call_chain(unsigned long val, void *v);
#define cu2_notifier(fn, pri) \
({ \
- static struct notifier_block fn##_nb __cpuinitdata = { \
+ static struct notifier_block fn##_nb = { \
.notifier_call = fn, \
.priority = pri \
}; \
diff --git a/arch/mips/include/asm/fcntl.h b/arch/mips/include/asm/fcntl.h
index e482fe90fe88..75eddedcfc3e 100644
--- a/arch/mips/include/asm/fcntl.h
+++ b/arch/mips/include/asm/fcntl.h
@@ -56,6 +56,7 @@
*/
#ifdef CONFIG_32BIT
+#include <linux/types.h>
struct flock {
short l_type;
diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h
index 9b9436a4d816..86548da650e7 100644
--- a/arch/mips/include/asm/gic.h
+++ b/arch/mips/include/asm/gic.h
@@ -321,6 +321,7 @@ struct gic_intrmask_regs {
*/
struct gic_intr_map {
unsigned int cpunum; /* Directed to this CPU */
+#define GIC_UNUSED 0xdead /* Dummy data */
unsigned int pin; /* Directed to this Pin */
unsigned int polarity; /* Polarity : +/- */
unsigned int trigtype; /* Trigger : Edge/Levl */
diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h
index dea4aed6478f..b003ed52ed17 100644
--- a/arch/mips/include/asm/irq.h
+++ b/arch/mips/include/asm/irq.h
@@ -16,6 +16,11 @@
#include <irq.h>
+static inline void irq_dispose_mapping(unsigned int virq)
+{
+ return;
+}
+
#ifdef CONFIG_I8259
static inline int irq_canonicalize(int irq)
{
diff --git a/arch/mips/include/asm/irqflags.h b/arch/mips/include/asm/irqflags.h
index 701ec0ba8fa9..9ef3b0d17896 100644
--- a/arch/mips/include/asm/irqflags.h
+++ b/arch/mips/include/asm/irqflags.h
@@ -17,7 +17,7 @@
#include <asm/hazards.h>
__asm__(
- " .macro raw_local_irq_enable \n"
+ " .macro arch_local_irq_enable \n"
" .set push \n"
" .set reorder \n"
" .set noat \n"
@@ -40,7 +40,7 @@ __asm__(
extern void smtc_ipi_replay(void);
-static inline void raw_local_irq_enable(void)
+static inline void arch_local_irq_enable(void)
{
#ifdef CONFIG_MIPS_MT_SMTC
/*
@@ -50,7 +50,7 @@ static inline void raw_local_irq_enable(void)
smtc_ipi_replay();
#endif
__asm__ __volatile__(
- "raw_local_irq_enable"
+ "arch_local_irq_enable"
: /* no outputs */
: /* no inputs */
: "memory");
@@ -76,7 +76,7 @@ static inline void raw_local_irq_enable(void)
* Workaround: mask EXL bit of the result or place a nop before mfc0.
*/
__asm__(
- " .macro raw_local_irq_disable\n"
+ " .macro arch_local_irq_disable\n"
" .set push \n"
" .set noat \n"
#ifdef CONFIG_MIPS_MT_SMTC
@@ -97,17 +97,17 @@ __asm__(
" .set pop \n"
" .endm \n");
-static inline void raw_local_irq_disable(void)
+static inline void arch_local_irq_disable(void)
{
__asm__ __volatile__(
- "raw_local_irq_disable"
+ "arch_local_irq_disable"
: /* no outputs */
: /* no inputs */
: "memory");
}
__asm__(
- " .macro raw_local_save_flags flags \n"
+ " .macro arch_local_save_flags flags \n"
" .set push \n"
" .set reorder \n"
#ifdef CONFIG_MIPS_MT_SMTC
@@ -118,13 +118,15 @@ __asm__(
" .set pop \n"
" .endm \n");
-#define raw_local_save_flags(x) \
-__asm__ __volatile__( \
- "raw_local_save_flags %0" \
- : "=r" (x))
+static inline unsigned long arch_local_save_flags(void)
+{
+ unsigned long flags;
+ asm volatile("arch_local_save_flags %0" : "=r" (flags));
+ return flags;
+}
__asm__(
- " .macro raw_local_irq_save result \n"
+ " .macro arch_local_irq_save result \n"
" .set push \n"
" .set reorder \n"
" .set noat \n"
@@ -148,15 +150,18 @@ __asm__(
" .set pop \n"
" .endm \n");
-#define raw_local_irq_save(x) \
-__asm__ __volatile__( \
- "raw_local_irq_save\t%0" \
- : "=r" (x) \
- : /* no inputs */ \
- : "memory")
+static inline unsigned long arch_local_irq_save(void)
+{
+ unsigned long flags;
+ asm volatile("arch_local_irq_save\t%0"
+ : "=r" (flags)
+ : /* no inputs */
+ : "memory");
+ return flags;
+}
__asm__(
- " .macro raw_local_irq_restore flags \n"
+ " .macro arch_local_irq_restore flags \n"
" .set push \n"
" .set noreorder \n"
" .set noat \n"
@@ -196,7 +201,7 @@ __asm__(
" .endm \n");
-static inline void raw_local_irq_restore(unsigned long flags)
+static inline void arch_local_irq_restore(unsigned long flags)
{
unsigned long __tmp1;
@@ -211,24 +216,24 @@ static inline void raw_local_irq_restore(unsigned long flags)
#endif
__asm__ __volatile__(
- "raw_local_irq_restore\t%0"
+ "arch_local_irq_restore\t%0"
: "=r" (__tmp1)
: "0" (flags)
: "memory");
}
-static inline void __raw_local_irq_restore(unsigned long flags)
+static inline void __arch_local_irq_restore(unsigned long flags)
{
unsigned long __tmp1;
__asm__ __volatile__(
- "raw_local_irq_restore\t%0"
+ "arch_local_irq_restore\t%0"
: "=r" (__tmp1)
: "0" (flags)
: "memory");
}
-static inline int raw_irqs_disabled_flags(unsigned long flags)
+static inline int arch_irqs_disabled_flags(unsigned long flags)
{
#ifdef CONFIG_MIPS_MT_SMTC
/*
diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h
index cb6985f24303..1e29b9dd1d73 100644
--- a/arch/mips/include/asm/mach-loongson/loongson.h
+++ b/arch/mips/include/asm/mach-loongson/loongson.h
@@ -13,6 +13,7 @@
#include <linux/io.h>
#include <linux/init.h>
+#include <linux/irq.h>
/* loongson internal northbridge initialization */
extern void bonito_irq_init(void);
diff --git a/arch/mips/include/asm/mach-tx49xx/kmalloc.h b/arch/mips/include/asm/mach-tx49xx/kmalloc.h
index b74caf65482b..ff9a8b86cb93 100644
--- a/arch/mips/include/asm/mach-tx49xx/kmalloc.h
+++ b/arch/mips/include/asm/mach-tx49xx/kmalloc.h
@@ -1,6 +1,6 @@
#ifndef __ASM_MACH_TX49XX_KMALLOC_H
#define __ASM_MACH_TX49XX_KMALLOC_H
-#define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES
+#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
#endif /* __ASM_MACH_TX49XX_KMALLOC_H */
diff --git a/arch/mips/include/asm/mips-boards/maltaint.h b/arch/mips/include/asm/mips-boards/maltaint.h
index cea872fc6f5c..d11aa02a956a 100644
--- a/arch/mips/include/asm/mips-boards/maltaint.h
+++ b/arch/mips/include/asm/mips-boards/maltaint.h
@@ -88,9 +88,6 @@
#define GIC_EXT_INTR(x) x
-/* Dummy data */
-#define X 0xdead
-
/* External Interrupts used for IPI */
#define GIC_IPI_EXT_INTR_RESCHED_VPE0 16
#define GIC_IPI_EXT_INTR_CALLFNC_VPE0 17
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h
index a16beafcea91..e59cd1ac09c2 100644
--- a/arch/mips/include/asm/page.h
+++ b/arch/mips/include/asm/page.h
@@ -150,6 +150,20 @@ typedef struct { unsigned long pgprot; } pgprot_t;
((unsigned long)(x) - PAGE_OFFSET + PHYS_OFFSET)
#endif
#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET - PHYS_OFFSET))
+
+/*
+ * RELOC_HIDE was originally added by 6007b903dfe5f1d13e0c711ac2894bdd4a61b1ad
+ * (lmo) rsp. 8431fd094d625b94d364fe393076ccef88e6ce18 (kernel.org). The
+ * discussion can be found in lkml posting
+ * <a2ebde260608230500o3407b108hc03debb9da6e62c@mail.gmail.com> which is
+ * archived at http://lists.linuxcoding.com/kernel/2006-q3/msg17360.html
+ *
+ * It is unclear if the misscompilations mentioned in
+ * http://lkml.org/lkml/2010/8/8/138 also affect MIPS so we keep this one
+ * until GCC 3.x has been retired before we can apply
+ * https://patchwork.linux-mips.org/patch/1541/
+ */
+
#define __pa_symbol(x) __pa(RELOC_HIDE((unsigned long)(x), 0))
#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
diff --git a/arch/mips/include/asm/prom.h b/arch/mips/include/asm/prom.h
new file mode 100644
index 000000000000..f29b862d9db3
--- /dev/null
+++ b/arch/mips/include/asm/prom.h
@@ -0,0 +1,31 @@
+/*
+ * arch/mips/include/asm/prom.h
+ *
+ * Copyright (C) 2010 Cisco Systems Inc. <dediao@cisco.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#ifndef __ASM_MIPS_PROM_H
+#define __ASM_MIPS_PROM_H
+
+#ifdef CONFIG_OF
+#include <asm/bootinfo.h>
+
+/* which is compatible with the flattened device tree (FDT) */
+#define cmd_line arcs_cmdline
+
+extern int early_init_dt_scan_memory_arch(unsigned long node,
+ const char *uname, int depth, void *data);
+
+extern int reserve_mem_mach(unsigned long addr, unsigned long size);
+extern void free_mem_mach(unsigned long addr, unsigned long size);
+
+extern void device_tree_init(void);
+#else /* CONFIG_OF */
+static inline void device_tree_init(void) { }
+#endif /* CONFIG_OF */
+
+#endif /* _ASM_MIPS_PROM_H */
diff --git a/arch/mips/include/asm/siginfo.h b/arch/mips/include/asm/siginfo.h
index 96e28f18dad1..1ca64b4d33d9 100644
--- a/arch/mips/include/asm/siginfo.h
+++ b/arch/mips/include/asm/siginfo.h
@@ -88,6 +88,7 @@ typedef struct siginfo {
#ifdef __ARCH_SI_TRAPNO
int _trapno; /* TRAP # which caused the signal */
#endif
+ short _addr_lsb;
} _sigfault;
/* SIGPOLL, SIGXFSZ (To do ...) */
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h
index 2376f2e06e47..70df9c0d3c5b 100644
--- a/arch/mips/include/asm/thread_info.h
+++ b/arch/mips/include/asm/thread_info.h
@@ -146,7 +146,8 @@ register struct thread_info *__current_thread_info __asm__("$28");
#define _TIF_LOAD_WATCH (1<<TIF_LOAD_WATCH)
/* work to do on interrupt/exception return */
-#define _TIF_WORK_MASK (0x0000ffef & ~_TIF_SECCOMP)
+#define _TIF_WORK_MASK (0x0000ffef & \
+ ~(_TIF_SECCOMP | _TIF_SYSCALL_AUDIT))
/* work to do on any return to u-space */
#define _TIF_ALLWORK_MASK (0x8000ffff & ~_TIF_SECCOMP)
diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h
index baa318a59c97..550725b881d5 100644
--- a/arch/mips/include/asm/unistd.h
+++ b/arch/mips/include/asm/unistd.h
@@ -356,16 +356,19 @@
#define __NR_perf_event_open (__NR_Linux + 333)
#define __NR_accept4 (__NR_Linux + 334)
#define __NR_recvmmsg (__NR_Linux + 335)
+#define __NR_fanotify_init (__NR_Linux + 336)
+#define __NR_fanotify_mark (__NR_Linux + 337)
+#define __NR_prlimit64 (__NR_Linux + 338)
/*
* Offset of the last Linux o32 flavoured syscall
*/
-#define __NR_Linux_syscalls 335
+#define __NR_Linux_syscalls 338
#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
#define __NR_O32_Linux 4000
-#define __NR_O32_Linux_syscalls 335
+#define __NR_O32_Linux_syscalls 338
#if _MIPS_SIM == _MIPS_SIM_ABI64
@@ -668,16 +671,19 @@
#define __NR_perf_event_open (__NR_Linux + 292)
#define __NR_accept4 (__NR_Linux + 293)
#define __NR_recvmmsg (__NR_Linux + 294)
+#define __NR_fanotify_init (__NR_Linux + 295)
+#define __NR_fanotify_mark (__NR_Linux + 296)
+#define __NR_prlimit64 (__NR_Linux + 297)
/*
* Offset of the last Linux 64-bit flavoured syscall
*/
-#define __NR_Linux_syscalls 294
+#define __NR_Linux_syscalls 297
#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
#define __NR_64_Linux 5000
-#define __NR_64_Linux_syscalls 294
+#define __NR_64_Linux_syscalls 297
#if _MIPS_SIM == _MIPS_SIM_NABI32
@@ -985,16 +991,19 @@
#define __NR_accept4 (__NR_Linux + 297)
#define __NR_recvmmsg (__NR_Linux + 298)
#define __NR_getdents64 (__NR_Linux + 299)
+#define __NR_fanotify_init (__NR_Linux + 300)
+#define __NR_fanotify_mark (__NR_Linux + 301)
+#define __NR_prlimit64 (__NR_Linux + 302)
/*
* Offset of the last N32 flavoured syscall
*/
-#define __NR_Linux_syscalls 299
+#define __NR_Linux_syscalls 302
#endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
#define __NR_N32_Linux 6000
-#define __NR_N32_Linux_syscalls 299
+#define __NR_N32_Linux_syscalls 302
#ifdef __KERNEL__
diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c
index ee18028efe92..35b3e2f0af04 100644
--- a/arch/mips/jazz/irq.c
+++ b/arch/mips/jazz/irq.c
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/smp.h>
#include <linux/spinlock.h>
+#include <linux/irq.h>
#include <asm/irq_cpu.h>
#include <asm/i8253.h>
diff --git a/arch/mips/jz4740/Platform b/arch/mips/jz4740/Platform
index 6a97230e3d05..ba91be9c21ef 100644
--- a/arch/mips/jz4740/Platform
+++ b/arch/mips/jz4740/Platform
@@ -1,3 +1,3 @@
-core-$(CONFIG_MACH_JZ4740) += arch/mips/jz4740/
+platform-$(CONFIG_MACH_JZ4740) += jz4740/
cflags-$(CONFIG_MACH_JZ4740) += -I$(srctree)/arch/mips/include/asm/mach-jz4740
load-$(CONFIG_MACH_JZ4740) += 0xffffffff80010000
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 06f848299785..80884983270d 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -96,6 +96,8 @@ obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_SPINLOCK_TEST) += spinlock_test.o
+obj-$(CONFIG_OF) += prom.o
+
CFLAGS_cpu-bugs64.o = $(shell if $(CC) $(KBUILD_CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi)
obj-$(CONFIG_HAVE_STD_PC_SERIAL_PORT) += 8250-platform.o
diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c
index 0176ed015c89..32103cc2a257 100644
--- a/arch/mips/kernel/branch.c
+++ b/arch/mips/kernel/branch.c
@@ -40,7 +40,6 @@ int __compute_return_epc(struct pt_regs *regs)
return -EFAULT;
}
- regs->regs[0] = 0;
switch (insn.i_format.opcode) {
/*
* jr and jalr are in r_format format.
diff --git a/arch/mips/kernel/cevt-bcm1480.c b/arch/mips/kernel/cevt-bcm1480.c
index bfea327c636c..36c3898b76db 100644
--- a/arch/mips/kernel/cevt-bcm1480.c
+++ b/arch/mips/kernel/cevt-bcm1480.c
@@ -19,6 +19,7 @@
#include <linux/interrupt.h>
#include <linux/percpu.h>
#include <linux/smp.h>
+#include <linux/irq.h>
#include <asm/addrspace.h>
#include <asm/io.h>
diff --git a/arch/mips/kernel/cevt-ds1287.c b/arch/mips/kernel/cevt-ds1287.c
index 00a4da277cbb..939157e397b9 100644
--- a/arch/mips/kernel/cevt-ds1287.c
+++ b/arch/mips/kernel/cevt-ds1287.c
@@ -21,6 +21,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/mc146818rtc.h>
+#include <linux/irq.h>
#include <asm/time.h>
diff --git a/arch/mips/kernel/cevt-gt641xx.c b/arch/mips/kernel/cevt-gt641xx.c
index 392ef3756c56..339f3639b90e 100644
--- a/arch/mips/kernel/cevt-gt641xx.c
+++ b/arch/mips/kernel/cevt-gt641xx.c
@@ -21,6 +21,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
+#include <linux/irq.h>
#include <asm/gt64120.h>
#include <asm/time.h>
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c
index 2a4d50ff5e2c..2f4d7a99bcc2 100644
--- a/arch/mips/kernel/cevt-r4k.c
+++ b/arch/mips/kernel/cevt-r4k.c
@@ -10,6 +10,7 @@
#include <linux/interrupt.h>
#include <linux/percpu.h>
#include <linux/smp.h>
+#include <linux/irq.h>
#include <asm/smtc_ipi.h>
#include <asm/time.h>
diff --git a/arch/mips/kernel/cevt-sb1250.c b/arch/mips/kernel/cevt-sb1250.c
index da78eeaea6e8..590c54f28a81 100644
--- a/arch/mips/kernel/cevt-sb1250.c
+++ b/arch/mips/kernel/cevt-sb1250.c
@@ -17,6 +17,7 @@
*/
#include <linux/clockchips.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/percpu.h>
#include <linux/smp.h>
diff --git a/arch/mips/kernel/cevt-smtc.c b/arch/mips/kernel/cevt-smtc.c
index b102e4f1630e..2e72d30b2f05 100644
--- a/arch/mips/kernel/cevt-smtc.c
+++ b/arch/mips/kernel/cevt-smtc.c
@@ -11,6 +11,7 @@
#include <linux/interrupt.h>
#include <linux/percpu.h>
#include <linux/smp.h>
+#include <linux/irq.h>
#include <asm/smtc_ipi.h>
#include <asm/time.h>
diff --git a/arch/mips/kernel/cevt-txx9.c b/arch/mips/kernel/cevt-txx9.c
index 218ee6bda935..0b7377361e22 100644
--- a/arch/mips/kernel/cevt-txx9.c
+++ b/arch/mips/kernel/cevt-txx9.c
@@ -13,6 +13,7 @@
*/
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <asm/time.h>
#include <asm/txx9tmr.h>
diff --git a/arch/mips/kernel/i8253.c b/arch/mips/kernel/i8253.c
index 94794062a177..2392a7a296d4 100644
--- a/arch/mips/kernel/i8253.c
+++ b/arch/mips/kernel/i8253.c
@@ -9,6 +9,7 @@
#include <linux/module.h>
#include <linux/smp.h>
#include <linux/spinlock.h>
+#include <linux/irq.h>
#include <asm/delay.h>
#include <asm/i8253.h>
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c
index 27799113332c..c58176cc796b 100644
--- a/arch/mips/kernel/i8259.c
+++ b/arch/mips/kernel/i8259.c
@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/sysdev.h>
+#include <linux/irq.h>
#include <asm/i8259.h>
#include <asm/io.h>
diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c
index b181f2f0ea8e..1774271af848 100644
--- a/arch/mips/kernel/irq-gic.c
+++ b/arch/mips/kernel/irq-gic.c
@@ -3,12 +3,11 @@
#include <linux/bitmap.h>
#include <linux/init.h>
#include <linux/smp.h>
+#include <linux/irq.h>
#include <asm/io.h>
#include <asm/gic.h>
#include <asm/gcmpregs.h>
-#include <asm/mips-boards/maltaint.h>
-#include <asm/irq.h>
#include <linux/hardirq.h>
#include <asm-generic/bitops/find.h>
@@ -131,7 +130,7 @@ static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
int i;
irq -= _irqbase;
- pr_debug(KERN_DEBUG "%s(%d) called\n", __func__, irq);
+ pr_debug("%s(%d) called\n", __func__, irq);
cpumask_and(&tmp, cpumask, cpu_online_mask);
if (cpus_empty(tmp))
return -1;
@@ -222,7 +221,7 @@ static void __init gic_basic_init(int numintrs, int numvpes,
/* Setup specifics */
for (i = 0; i < mapsize; i++) {
cpu = intrmap[i].cpunum;
- if (cpu == X)
+ if (cpu == GIC_UNUSED)
continue;
if (cpu == 0 && i != 0 && intrmap[i].flags == 0)
continue;
diff --git a/arch/mips/kernel/irq-rm7000.c b/arch/mips/kernel/irq-rm7000.c
index fb50cc78b28b..9731e8b47862 100644
--- a/arch/mips/kernel/irq-rm7000.c
+++ b/arch/mips/kernel/irq-rm7000.c
@@ -11,6 +11,7 @@
*/
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/kernel.h>
#include <asm/irq_cpu.h>
diff --git a/arch/mips/kernel/irq-rm9000.c b/arch/mips/kernel/irq-rm9000.c
index b47e4615ec12..b7e4025b58a8 100644
--- a/arch/mips/kernel/irq-rm9000.c
+++ b/arch/mips/kernel/irq-rm9000.c
@@ -11,6 +11,7 @@
*/
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/module.h>
diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c
index 55c8a3ca507b..0262abe09121 100644
--- a/arch/mips/kernel/irq_cpu.c
+++ b/arch/mips/kernel/irq_cpu.c
@@ -30,6 +30,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
+#include <linux/irq.h>
#include <asm/irq_cpu.h>
#include <asm/mipsregs.h>
diff --git a/arch/mips/kernel/irq_txx9.c b/arch/mips/kernel/irq_txx9.c
index 9b78029bea70..95a96f69172d 100644
--- a/arch/mips/kernel/irq_txx9.c
+++ b/arch/mips/kernel/irq_txx9.c
@@ -16,6 +16,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/types.h>
+#include <linux/irq.h>
#include <asm/txx9irq.h>
struct txx9_irc_reg {
diff --git a/arch/mips/kernel/kgdb.c b/arch/mips/kernel/kgdb.c
index 1f4e2fa64140..f4546e97c60d 100644
--- a/arch/mips/kernel/kgdb.c
+++ b/arch/mips/kernel/kgdb.c
@@ -283,7 +283,7 @@ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd,
struct pt_regs *regs = args->regs;
int trap = (regs->cp0_cause & 0x7c) >> 2;
- /* Userpace events, ignore. */
+ /* Userspace events, ignore. */
if (user_mode(regs))
return NOTIFY_DONE;
diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c
index 80e2ba694bab..29811f043399 100644
--- a/arch/mips/kernel/kspd.c
+++ b/arch/mips/kernel/kspd.c
@@ -251,7 +251,7 @@ void sp_work_handle_request(void)
memset(&tz, 0, sizeof(tz));
if ((ret.retval = sp_syscall(__NR_gettimeofday, (int)&tv,
(int)&tz, 0, 0)) == 0)
- ret.retval = tv.tv_sec;
+ ret.retval = tv.tv_sec;
break;
case MTSP_SYSCALL_EXIT:
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index c2dab140dc98..6343b4a5b835 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -341,3 +341,10 @@ asmlinkage long sys32_lookup_dcookie(u32 a0, u32 a1, char __user *buf,
{
return sys_lookup_dcookie(merge_64(a0, a1), buf, len);
}
+
+SYSCALL_DEFINE6(32_fanotify_mark, int, fanotify_fd, unsigned int, flags,
+ u64, a3, u64, a4, int, dfd, const char __user *, pathname)
+{
+ return sys_fanotify_mark(fanotify_fd, flags, merge_64(a3, a4),
+ dfd, pathname);
+}
diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c
index 2340f11dc29c..802e6160f37e 100644
--- a/arch/mips/kernel/mips-mt-fpaff.c
+++ b/arch/mips/kernel/mips-mt-fpaff.c
@@ -103,7 +103,7 @@ asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len,
if (!check_same_owner(p) && !capable(CAP_SYS_NICE))
goto out_unlock;
- retval = security_task_setscheduler(p, 0, NULL);
+ retval = security_task_setscheduler(p);
if (retval)
goto out_unlock;
diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c
new file mode 100644
index 000000000000..e000b278f024
--- /dev/null
+++ b/arch/mips/kernel/prom.c
@@ -0,0 +1,112 @@
+/*
+ * MIPS support for CONFIG_OF device tree support
+ *
+ * Copyright (C) 2010 Cisco Systems Inc. <dediao@cisco.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/bootmem.h>
+#include <linux/initrd.h>
+#include <linux/debugfs.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+
+#include <asm/page.h>
+#include <asm/prom.h>
+
+int __init early_init_dt_scan_memory_arch(unsigned long node,
+ const char *uname, int depth,
+ void *data)
+{
+ return early_init_dt_scan_memory(node, uname, depth, data);
+}
+
+void __init early_init_dt_add_memory_arch(u64 base, u64 size)
+{
+ return add_memory_region(base, size, BOOT_MEM_RAM);
+}
+
+int __init reserve_mem_mach(unsigned long addr, unsigned long size)
+{
+ return reserve_bootmem(addr, size, BOOTMEM_DEFAULT);
+}
+
+void __init free_mem_mach(unsigned long addr, unsigned long size)
+{
+ return free_bootmem(addr, size);
+}
+
+u64 __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
+{
+ return virt_to_phys(
+ __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS))
+ );
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void __init early_init_dt_setup_initrd_arch(unsigned long start,
+ unsigned long end)
+{
+ initrd_start = (unsigned long)__va(start);
+ initrd_end = (unsigned long)__va(end);
+ initrd_below_start_ok = 1;
+}
+#endif
+
+/*
+ * irq_create_of_mapping - Hook to resolve OF irq specifier into a Linux irq#
+ *
+ * Currently the mapping mechanism is trivial; simple flat hwirq numbers are
+ * mapped 1:1 onto Linux irq numbers. Cascaded irq controllers are not
+ * supported.
+ */
+unsigned int irq_create_of_mapping(struct device_node *controller,
+ const u32 *intspec, unsigned int intsize)
+{
+ return intspec[0];
+}
+EXPORT_SYMBOL_GPL(irq_create_of_mapping);
+
+void __init early_init_devtree(void *params)
+{
+ /* Setup flat device-tree pointer */
+ initial_boot_params = params;
+
+ /* Retrieve various informations from the /chosen node of the
+ * device-tree, including the platform type, initrd location and
+ * size, and more ...
+ */
+ of_scan_flat_dt(early_init_dt_scan_chosen, NULL);
+
+ /* Scan memory nodes */
+ of_scan_flat_dt(early_init_dt_scan_root, NULL);
+ of_scan_flat_dt(early_init_dt_scan_memory_arch, NULL);
+}
+
+void __init device_tree_init(void)
+{
+ unsigned long base, size;
+
+ if (!initial_boot_params)
+ return;
+
+ base = virt_to_phys((void *)initial_boot_params);
+ size = initial_boot_params->totalsize;
+
+ /* Before we do anything, lets reserve the dt blob */
+ reserve_mem_mach(base, size);
+
+ unflatten_device_tree();
+
+ /* free the space reserved for the dt blob */
+ free_mem_mach(base, size);
+}
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index c51b95ff8644..c8777333e198 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -536,7 +536,7 @@ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
{
/* do the secure computing check first */
if (!entryexit)
- secure_computing(regs->regs[0]);
+ secure_computing(regs->regs[2]);
if (unlikely(current->audit_context) && entryexit)
audit_syscall_exit(AUDITSC_RESULT(regs->regs[2]),
@@ -565,7 +565,7 @@ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
out:
if (unlikely(current->audit_context) && !entryexit)
- audit_syscall_entry(audit_arch(), regs->regs[0],
+ audit_syscall_entry(audit_arch(), regs->regs[2],
regs->regs[4], regs->regs[5],
regs->regs[6], regs->regs[7]);
}
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c
index 26f9b9ab19cc..557ef72472e0 100644
--- a/arch/mips/kernel/rtlx.c
+++ b/arch/mips/kernel/rtlx.c
@@ -468,7 +468,8 @@ static const struct file_operations rtlx_fops = {
.release = file_release,
.write = file_write,
.read = file_read,
- .poll = file_poll
+ .poll = file_poll,
+ .llseek = noop_llseek,
};
static struct irqaction rtlx_irq = {
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index 17202bbe843f..fbaabad0e6e2 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -63,9 +63,9 @@ stack_done:
sw t0, PT_R7(sp) # set error flag
beqz t0, 1f
+ lw t1, PT_R2(sp) # syscall number
negu v0 # error
- sw v0, PT_R0(sp) # set flag for syscall
- # restarting
+ sw t1, PT_R0(sp) # save it for syscall restarting
1: sw v0, PT_R2(sp) # result
o32_syscall_exit:
@@ -104,9 +104,9 @@ syscall_trace_entry:
sw t0, PT_R7(sp) # set error flag
beqz t0, 1f
+ lw t1, PT_R2(sp) # syscall number
negu v0 # error
- sw v0, PT_R0(sp) # set flag for syscall
- # restarting
+ sw t1, PT_R0(sp) # save it for syscall restarting
1: sw v0, PT_R2(sp) # result
j syscall_exit
@@ -169,8 +169,7 @@ stackargs:
* We probably should handle this case a bit more drastic.
*/
bad_stack:
- negu v0 # error
- sw v0, PT_R0(sp)
+ li v0, EFAULT
sw v0, PT_R2(sp)
li t0, 1 # set error flag
sw t0, PT_R7(sp)
@@ -583,7 +582,10 @@ einval: li v0, -ENOSYS
sys sys_rt_tgsigqueueinfo 4
sys sys_perf_event_open 5
sys sys_accept4 4
- sys sys_recvmmsg 5
+ sys sys_recvmmsg 5 /* 4335 */
+ sys sys_fanotify_init 2
+ sys sys_fanotify_mark 6
+ sys sys_prlimit64 4
.endm
/* We pre-compute the number of _instruction_ bytes needed to
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
index a8a6c596eb04..3f4179283207 100644
--- a/arch/mips/kernel/scall64-64.S
+++ b/arch/mips/kernel/scall64-64.S
@@ -66,9 +66,9 @@ NESTED(handle_sys64, PT_SIZE, sp)
sd t0, PT_R7(sp) # set error flag
beqz t0, 1f
+ ld t1, PT_R2(sp) # syscall number
dnegu v0 # error
- sd v0, PT_R0(sp) # set flag for syscall
- # restarting
+ sd t1, PT_R0(sp) # save it for syscall restarting
1: sd v0, PT_R2(sp) # result
n64_syscall_exit:
@@ -109,8 +109,9 @@ syscall_trace_entry:
sd t0, PT_R7(sp) # set error flag
beqz t0, 1f
+ ld t1, PT_R2(sp) # syscall number
dnegu v0 # error
- sd v0, PT_R0(sp) # set flag for syscall restarting
+ sd t1, PT_R0(sp) # save it for syscall restarting
1: sd v0, PT_R2(sp) # result
j syscall_exit
@@ -416,9 +417,12 @@ sys_call_table:
PTR sys_pipe2
PTR sys_inotify_init1
PTR sys_preadv
- PTR sys_pwritev /* 5390 */
+ PTR sys_pwritev /* 5290 */
PTR sys_rt_tgsigqueueinfo
PTR sys_perf_event_open
PTR sys_accept4
- PTR sys_recvmmsg
+ PTR sys_recvmmsg
+ PTR sys_fanotify_init /* 5295 */
+ PTR sys_fanotify_mark
+ PTR sys_prlimit64
.size sys_call_table,.-sys_call_table
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index a3d66137731a..f08ece6d8acc 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -65,8 +65,9 @@ NESTED(handle_sysn32, PT_SIZE, sp)
sd t0, PT_R7(sp) # set error flag
beqz t0, 1f
+ ld t1, PT_R2(sp) # syscall number
dnegu v0 # error
- sd v0, PT_R0(sp) # set flag for syscall restarting
+ sd t1, PT_R0(sp) # save it for syscall restarting
1: sd v0, PT_R2(sp) # result
local_irq_disable # make sure need_resched and
@@ -106,8 +107,9 @@ n32_syscall_trace_entry:
sd t0, PT_R7(sp) # set error flag
beqz t0, 1f
+ ld t1, PT_R2(sp) # syscall number
dnegu v0 # error
- sd v0, PT_R0(sp) # set flag for syscall restarting
+ sd t1, PT_R0(sp) # save it for syscall restarting
1: sd v0, PT_R2(sp) # result
j syscall_exit
@@ -320,10 +322,10 @@ EXPORT(sysn32_call_table)
PTR sys_cacheflush
PTR sys_cachectl
PTR sys_sysmips
- PTR sys_io_setup /* 6200 */
+ PTR compat_sys_io_setup /* 6200 */
PTR sys_io_destroy
- PTR sys_io_getevents
- PTR sys_io_submit
+ PTR compat_sys_io_getevents
+ PTR compat_sys_io_submit
PTR sys_io_cancel
PTR sys_exit_group /* 6205 */
PTR sys_lookup_dcookie
@@ -419,5 +421,8 @@ EXPORT(sysn32_call_table)
PTR sys_perf_event_open
PTR sys_accept4
PTR compat_sys_recvmmsg
- PTR sys_getdents
+ PTR sys_getdents64
+ PTR sys_fanotify_init /* 6300 */
+ PTR sys_fanotify_mark
+ PTR sys_prlimit64
.size sysn32_call_table,.-sysn32_call_table
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index 813689ef2384..78d768a3e19d 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -93,8 +93,9 @@ NESTED(handle_sys, PT_SIZE, sp)
sd t0, PT_R7(sp) # set error flag
beqz t0, 1f
+ ld t1, PT_R2(sp) # syscall number
dnegu v0 # error
- sd v0, PT_R0(sp) # flag for syscall restarting
+ sd t1, PT_R0(sp) # save it for syscall restarting
1: sd v0, PT_R2(sp) # result
o32_syscall_exit:
@@ -142,8 +143,9 @@ trace_a_syscall:
sd t0, PT_R7(sp) # set error flag
beqz t0, 1f
+ ld t1, PT_R2(sp) # syscall number
dnegu v0 # error
- sd v0, PT_R0(sp) # set flag for syscall restarting
+ sd t1, PT_R0(sp) # save it for syscall restarting
1: sd v0, PT_R2(sp) # result
j syscall_exit
@@ -154,8 +156,7 @@ trace_a_syscall:
* The stackpointer for a call with more than 4 arguments is bad.
*/
bad_stack:
- dnegu v0 # error
- sd v0, PT_R0(sp)
+ li v0, EFAULT
sd v0, PT_R2(sp)
li t0, 1 # set error flag
sd t0, PT_R7(sp)
@@ -444,10 +445,10 @@ sys_call_table:
PTR compat_sys_futex
PTR compat_sys_sched_setaffinity
PTR compat_sys_sched_getaffinity /* 4240 */
- PTR sys_io_setup
+ PTR compat_sys_io_setup
PTR sys_io_destroy
- PTR sys_io_getevents
- PTR sys_io_submit
+ PTR compat_sys_io_getevents
+ PTR compat_sys_io_submit
PTR sys_io_cancel /* 4245 */
PTR sys_exit_group
PTR sys32_lookup_dcookie
@@ -538,5 +539,8 @@ sys_call_table:
PTR compat_sys_rt_tgsigqueueinfo
PTR sys_perf_event_open
PTR sys_accept4
- PTR compat_sys_recvmmsg
+ PTR compat_sys_recvmmsg /* 4335 */
+ PTR sys_fanotify_init
+ PTR sys_32_fanotify_mark
+ PTR sys_prlimit64
.size sys_call_table,.-sys_call_table
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 85aef3fc6716..a6b900f2962b 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -31,6 +31,7 @@
#include <asm/setup.h>
#include <asm/smp-ops.h>
#include <asm/system.h>
+#include <asm/prom.h>
struct cpuinfo_mips cpu_data[NR_CPUS] __read_mostly;
@@ -487,6 +488,7 @@ static void __init arch_mem_init(char **cmdline_p)
}
bootmem_init();
+ device_tree_init();
sparse_init();
paging_init();
}
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 2099d5a4c4b7..5922342bca39 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -390,7 +390,6 @@ asmlinkage void sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
{
struct rt_sigframe __user *frame;
sigset_t set;
- stack_t st;
int sig;
frame = (struct rt_sigframe __user *) regs.regs[29];
@@ -411,11 +410,9 @@ asmlinkage void sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
else if (sig)
force_sig(sig, current);
- if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st)))
- goto badframe;
/* It is more difficult to avoid calling this function than to
call it and ignore errors. */
- do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
+ do_sigaltstack(&frame->rs_uc.uc_stack, NULL, regs.regs[29]);
/*
* Don't let your children do this ...
@@ -550,23 +547,26 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
struct mips_abi *abi = current->thread.abi;
void *vdso = current->mm->context.vdso;
- switch(regs->regs[0]) {
- case ERESTART_RESTARTBLOCK:
- case ERESTARTNOHAND:
- regs->regs[2] = EINTR;
- break;
- case ERESTARTSYS:
- if (!(ka->sa.sa_flags & SA_RESTART)) {
+ if (regs->regs[0]) {
+ switch(regs->regs[2]) {
+ case ERESTART_RESTARTBLOCK:
+ case ERESTARTNOHAND:
regs->regs[2] = EINTR;
break;
+ case ERESTARTSYS:
+ if (!(ka->sa.sa_flags & SA_RESTART)) {
+ regs->regs[2] = EINTR;
+ break;
+ }
+ /* fallthrough */
+ case ERESTARTNOINTR:
+ regs->regs[7] = regs->regs[26];
+ regs->regs[2] = regs->regs[0];
+ regs->cp0_epc -= 4;
}
- /* fallthrough */
- case ERESTARTNOINTR: /* Userland will reload $v0. */
- regs->regs[7] = regs->regs[26];
- regs->cp0_epc -= 8;
- }
- regs->regs[0] = 0; /* Don't deal with this again. */
+ regs->regs[0] = 0; /* Don't deal with this again. */
+ }
if (sig_uses_siginfo(ka))
ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset,
@@ -575,6 +575,9 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
ret = abi->setup_frame(vdso + abi->signal_return_offset,
ka, regs, sig, oldset);
+ if (ret)
+ return ret;
+
spin_lock_irq(&current->sighand->siglock);
sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
if (!(ka->sa.sa_flags & SA_NODEFER))
@@ -622,17 +625,13 @@ static void do_signal(struct pt_regs *regs)
return;
}
- /*
- * Who's code doesn't conform to the restartable syscall convention
- * dies here!!! The li instruction, a single machine instruction,
- * must directly be followed by the syscall instruction.
- */
if (regs->regs[0]) {
if (regs->regs[2] == ERESTARTNOHAND ||
regs->regs[2] == ERESTARTSYS ||
regs->regs[2] == ERESTARTNOINTR) {
+ regs->regs[2] = regs->regs[0];
regs->regs[7] = regs->regs[26];
- regs->cp0_epc -= 8;
+ regs->cp0_epc -= 4;
}
if (regs->regs[2] == ERESTART_RESTARTBLOCK) {
regs->regs[2] = current->thread.abi->restart;
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
index 2c5df818c65a..ee24d814d5b9 100644
--- a/arch/mips/kernel/signal_n32.c
+++ b/arch/mips/kernel/signal_n32.c
@@ -109,6 +109,7 @@ asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
{
struct rt_sigframe_n32 __user *frame;
+ mm_segment_t old_fs;
sigset_t set;
stack_t st;
s32 sp;
@@ -143,7 +144,11 @@ asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
/* It is more difficult to avoid calling this function than to
call it and ignore errors. */
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
+ set_fs(old_fs);
+
/*
* Don't let your children do this ...
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
index cfeb2c155896..39c08254b0f1 100644
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -1038,7 +1038,7 @@ void deferred_smtc_ipi(void)
* but it's more efficient, given that we're already
* running down the IPI queue.
*/
- __raw_local_irq_restore(flags);
+ __arch_local_irq_restore(flags);
}
}
@@ -1190,7 +1190,7 @@ void smtc_ipi_replay(void)
/*
** But use a raw restore here to avoid recursion.
*/
- __raw_local_irq_restore(flags);
+ __arch_local_irq_restore(flags);
if (pipi) {
self_ipi(pipi);
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 03ec0019032b..d053bf4759e4 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -28,6 +28,7 @@
#include <linux/kprobes.h>
#include <linux/notifier.h>
#include <linux/kdb.h>
+#include <linux/irq.h>
#include <asm/bootinfo.h>
#include <asm/branch.h>
@@ -51,7 +52,6 @@
#include <asm/mmu_context.h>
#include <asm/types.h>
#include <asm/stacktrace.h>
-#include <asm/irq.h>
#include <asm/uasm.h>
extern void check_wait(void);
diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c
index 69b039ca8d83..33d5a5ce4a29 100644
--- a/arch/mips/kernel/unaligned.c
+++ b/arch/mips/kernel/unaligned.c
@@ -109,8 +109,6 @@ static void emulate_load_store_insn(struct pt_regs *regs,
unsigned long value;
unsigned int res;
- regs->regs[0] = 0;
-
/*
* This load never faults.
*/
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index 2bd2151c586a..3eb3cde2f661 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -1192,7 +1192,8 @@ static const struct file_operations vpe_fops = {
.owner = THIS_MODULE,
.open = vpe_open,
.release = vpe_release,
- .write = vpe_write
+ .write = vpe_write,
+ .llseek = noop_llseek,
};
/* module wrapper entry points */
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index 47842b7d26ae..ec3faa413f3b 100644
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -3,7 +3,6 @@
*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
* Copyright (C) 2000 MIPS Technologies, Inc.
diff --git a/arch/mips/math-emu/dp_add.c b/arch/mips/math-emu/dp_add.c
index bcf73bb5c33a..b422fcad852a 100644
--- a/arch/mips/math-emu/dp_add.c
+++ b/arch/mips/math-emu/dp_add.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/dp_cmp.c b/arch/mips/math-emu/dp_cmp.c
index 8ab4f320a478..0f32486b0ed9 100644
--- a/arch/mips/math-emu/dp_cmp.c
+++ b/arch/mips/math-emu/dp_cmp.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/dp_div.c b/arch/mips/math-emu/dp_div.c
index 6acedce3b32d..a1bce1b7c09c 100644
--- a/arch/mips/math-emu/dp_div.c
+++ b/arch/mips/math-emu/dp_div.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/dp_fint.c b/arch/mips/math-emu/dp_fint.c
index 39a71de16f47..88571288c9e0 100644
--- a/arch/mips/math-emu/dp_fint.c
+++ b/arch/mips/math-emu/dp_fint.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/dp_flong.c b/arch/mips/math-emu/dp_flong.c
index f08f223e488a..14fc01ec742d 100644
--- a/arch/mips/math-emu/dp_flong.c
+++ b/arch/mips/math-emu/dp_flong.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/dp_frexp.c b/arch/mips/math-emu/dp_frexp.c
index e650cb10c947..cb15a5eaecbb 100644
--- a/arch/mips/math-emu/dp_frexp.c
+++ b/arch/mips/math-emu/dp_frexp.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/dp_fsp.c b/arch/mips/math-emu/dp_fsp.c
index 494d19ac7049..1dfbd92ba9d0 100644
--- a/arch/mips/math-emu/dp_fsp.c
+++ b/arch/mips/math-emu/dp_fsp.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/dp_logb.c b/arch/mips/math-emu/dp_logb.c
index 603388621ca5..151127e59f5c 100644
--- a/arch/mips/math-emu/dp_logb.c
+++ b/arch/mips/math-emu/dp_logb.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/dp_modf.c b/arch/mips/math-emu/dp_modf.c
index a8570e5c3efc..b01f9cf6d402 100644
--- a/arch/mips/math-emu/dp_modf.c
+++ b/arch/mips/math-emu/dp_modf.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/dp_mul.c b/arch/mips/math-emu/dp_mul.c
index 48908a809c17..aa566e785f5a 100644
--- a/arch/mips/math-emu/dp_mul.c
+++ b/arch/mips/math-emu/dp_mul.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/dp_scalb.c b/arch/mips/math-emu/dp_scalb.c
index b84e6338330e..6f5df438dda8 100644
--- a/arch/mips/math-emu/dp_scalb.c
+++ b/arch/mips/math-emu/dp_scalb.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/dp_simple.c b/arch/mips/math-emu/dp_simple.c
index b90974246e5b..79ce2673a714 100644
--- a/arch/mips/math-emu/dp_simple.c
+++ b/arch/mips/math-emu/dp_simple.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/dp_sqrt.c b/arch/mips/math-emu/dp_sqrt.c
index 032328c49888..a2a51b87ae8f 100644
--- a/arch/mips/math-emu/dp_sqrt.c
+++ b/arch/mips/math-emu/dp_sqrt.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/dp_sub.c b/arch/mips/math-emu/dp_sub.c
index a2127d685a0d..0de098cbc77b 100644
--- a/arch/mips/math-emu/dp_sub.c
+++ b/arch/mips/math-emu/dp_sub.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/dp_tint.c b/arch/mips/math-emu/dp_tint.c
index 24478623c117..0ebe8598b94a 100644
--- a/arch/mips/math-emu/dp_tint.c
+++ b/arch/mips/math-emu/dp_tint.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/dp_tlong.c b/arch/mips/math-emu/dp_tlong.c
index 0f07ec2be3f9..133ce2ba0012 100644
--- a/arch/mips/math-emu/dp_tlong.c
+++ b/arch/mips/math-emu/dp_tlong.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/ieee754.c b/arch/mips/math-emu/ieee754.c
index cb1b6822711a..30554e1c67b4 100644
--- a/arch/mips/math-emu/ieee754.c
+++ b/arch/mips/math-emu/ieee754.c
@@ -9,7 +9,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/ieee754.h b/arch/mips/math-emu/ieee754.h
index dd917332792c..22796e012060 100644
--- a/arch/mips/math-emu/ieee754.h
+++ b/arch/mips/math-emu/ieee754.h
@@ -1,7 +1,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* This program is free software; you can distribute it and/or modify it
* under the terms of the GNU General Public License (Version 2) as
diff --git a/arch/mips/math-emu/ieee754d.c b/arch/mips/math-emu/ieee754d.c
index a0325337b76c..9599bdd32585 100644
--- a/arch/mips/math-emu/ieee754d.c
+++ b/arch/mips/math-emu/ieee754d.c
@@ -4,7 +4,6 @@
* MIPS floating point support
*
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* This program is free software; you can distribute it and/or modify it
* under the terms of the GNU General Public License (Version 2) as
diff --git a/arch/mips/math-emu/ieee754dp.c b/arch/mips/math-emu/ieee754dp.c
index 2f22fd7fd784..080b5ca03fc6 100644
--- a/arch/mips/math-emu/ieee754dp.c
+++ b/arch/mips/math-emu/ieee754dp.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/ieee754dp.h b/arch/mips/math-emu/ieee754dp.h
index 762786538449..f139c724c59a 100644
--- a/arch/mips/math-emu/ieee754dp.h
+++ b/arch/mips/math-emu/ieee754dp.h
@@ -5,7 +5,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/ieee754int.h b/arch/mips/math-emu/ieee754int.h
index 1a846c5425cd..2701d9500959 100644
--- a/arch/mips/math-emu/ieee754int.h
+++ b/arch/mips/math-emu/ieee754int.h
@@ -5,7 +5,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/ieee754m.c b/arch/mips/math-emu/ieee754m.c
index d66896cd8f21..24190f3c9dd6 100644
--- a/arch/mips/math-emu/ieee754m.c
+++ b/arch/mips/math-emu/ieee754m.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/ieee754sp.c b/arch/mips/math-emu/ieee754sp.c
index a19b72185ab9..271d00d6113a 100644
--- a/arch/mips/math-emu/ieee754sp.c
+++ b/arch/mips/math-emu/ieee754sp.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/ieee754sp.h b/arch/mips/math-emu/ieee754sp.h
index d9e3586b5bce..754fd54649b5 100644
--- a/arch/mips/math-emu/ieee754sp.h
+++ b/arch/mips/math-emu/ieee754sp.h
@@ -5,7 +5,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/ieee754xcpt.c b/arch/mips/math-emu/ieee754xcpt.c
index e02423a0ae23..b99a693c05af 100644
--- a/arch/mips/math-emu/ieee754xcpt.c
+++ b/arch/mips/math-emu/ieee754xcpt.c
@@ -1,7 +1,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/sp_add.c b/arch/mips/math-emu/sp_add.c
index d8c4211bcfbe..ae1a327ccac0 100644
--- a/arch/mips/math-emu/sp_add.c
+++ b/arch/mips/math-emu/sp_add.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/sp_cmp.c b/arch/mips/math-emu/sp_cmp.c
index d3eff6b04b5a..716cf37e2465 100644
--- a/arch/mips/math-emu/sp_cmp.c
+++ b/arch/mips/math-emu/sp_cmp.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/sp_div.c b/arch/mips/math-emu/sp_div.c
index 2b437fcfdad9..d7747928c954 100644
--- a/arch/mips/math-emu/sp_div.c
+++ b/arch/mips/math-emu/sp_div.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/sp_fdp.c b/arch/mips/math-emu/sp_fdp.c
index 4093723d1aa5..e1515aae0166 100644
--- a/arch/mips/math-emu/sp_fdp.c
+++ b/arch/mips/math-emu/sp_fdp.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/sp_fint.c b/arch/mips/math-emu/sp_fint.c
index e88e125e01c2..9694d6c016cb 100644
--- a/arch/mips/math-emu/sp_fint.c
+++ b/arch/mips/math-emu/sp_fint.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/sp_flong.c b/arch/mips/math-emu/sp_flong.c
index 26d6919a269a..16a651f29865 100644
--- a/arch/mips/math-emu/sp_flong.c
+++ b/arch/mips/math-emu/sp_flong.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/sp_frexp.c b/arch/mips/math-emu/sp_frexp.c
index 359c6483dbfa..5bc993c30044 100644
--- a/arch/mips/math-emu/sp_frexp.c
+++ b/arch/mips/math-emu/sp_frexp.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/sp_logb.c b/arch/mips/math-emu/sp_logb.c
index 3c337219ca32..9c14e0c75bd2 100644
--- a/arch/mips/math-emu/sp_logb.c
+++ b/arch/mips/math-emu/sp_logb.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/sp_modf.c b/arch/mips/math-emu/sp_modf.c
index 76568946b4c0..25a0fbaa0556 100644
--- a/arch/mips/math-emu/sp_modf.c
+++ b/arch/mips/math-emu/sp_modf.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/sp_mul.c b/arch/mips/math-emu/sp_mul.c
index 3f070f82212f..c06bb4022be5 100644
--- a/arch/mips/math-emu/sp_mul.c
+++ b/arch/mips/math-emu/sp_mul.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/sp_scalb.c b/arch/mips/math-emu/sp_scalb.c
index 44ceb87ea944..dd76196984c8 100644
--- a/arch/mips/math-emu/sp_scalb.c
+++ b/arch/mips/math-emu/sp_scalb.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/sp_simple.c b/arch/mips/math-emu/sp_simple.c
index 2fd53c920e99..ae4fcfafd853 100644
--- a/arch/mips/math-emu/sp_simple.c
+++ b/arch/mips/math-emu/sp_simple.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/sp_sqrt.c b/arch/mips/math-emu/sp_sqrt.c
index 8a934b9f7eb8..fed20175f5fb 100644
--- a/arch/mips/math-emu/sp_sqrt.c
+++ b/arch/mips/math-emu/sp_sqrt.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/sp_sub.c b/arch/mips/math-emu/sp_sub.c
index dbb802c1a086..886ed5bcfefb 100644
--- a/arch/mips/math-emu/sp_sub.c
+++ b/arch/mips/math-emu/sp_sub.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/sp_tint.c b/arch/mips/math-emu/sp_tint.c
index 352dc3a5f1af..0fe9acc7716e 100644
--- a/arch/mips/math-emu/sp_tint.c
+++ b/arch/mips/math-emu/sp_tint.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/math-emu/sp_tlong.c b/arch/mips/math-emu/sp_tlong.c
index 92cd9c511a10..d0ca6e22be29 100644
--- a/arch/mips/math-emu/sp_tlong.c
+++ b/arch/mips/math-emu/sp_tlong.c
@@ -4,7 +4,6 @@
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
- * http://www.algor.co.uk
*
* ########################################################################
*
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 7ba890860d98..469d4019f795 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -44,27 +44,39 @@ static inline int cpu_is_noncoherent_r10000(struct device *dev)
static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp)
{
+ gfp_t dma_flag;
+
/* ignore region specifiers */
gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM);
-#ifdef CONFIG_ZONE_DMA
+#ifdef CONFIG_ISA
if (dev == NULL)
- gfp |= __GFP_DMA;
- else if (dev->coherent_dma_mask < DMA_BIT_MASK(24))
- gfp |= __GFP_DMA;
+ dma_flag = __GFP_DMA;
else
#endif
-#ifdef CONFIG_ZONE_DMA32
+#if defined(CONFIG_ZONE_DMA32) && defined(CONFIG_ZONE_DMA)
if (dev->coherent_dma_mask < DMA_BIT_MASK(32))
- gfp |= __GFP_DMA32;
+ dma_flag = __GFP_DMA;
+ else if (dev->coherent_dma_mask < DMA_BIT_MASK(64))
+ dma_flag = __GFP_DMA32;
+ else
+#endif
+#if defined(CONFIG_ZONE_DMA32) && !defined(CONFIG_ZONE_DMA)
+ if (dev->coherent_dma_mask < DMA_BIT_MASK(64))
+ dma_flag = __GFP_DMA32;
+ else
+#endif
+#if defined(CONFIG_ZONE_DMA) && !defined(CONFIG_ZONE_DMA32)
+ if (dev->coherent_dma_mask < DMA_BIT_MASK(64))
+ dma_flag = __GFP_DMA;
else
#endif
- ;
+ dma_flag = 0;
/* Don't invoke OOM killer */
gfp |= __GFP_NORETRY;
- return gfp;
+ return gfp | dma_flag;
}
void *dma_alloc_noncoherent(struct device *dev, size_t size,
diff --git a/arch/mips/mm/sc-rm7k.c b/arch/mips/mm/sc-rm7k.c
index 1ef75cd80a0d..274af3be1442 100644
--- a/arch/mips/mm/sc-rm7k.c
+++ b/arch/mips/mm/sc-rm7k.c
@@ -30,7 +30,7 @@
#define tc_lsize 32
extern unsigned long icache_way_size, dcache_way_size;
-unsigned long tcache_size;
+static unsigned long tcache_size;
#include <asm/r4kcache.h>
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c
index 15949b0be811..b79b24afe3a2 100644
--- a/arch/mips/mti-malta/malta-int.c
+++ b/arch/mips/mti-malta/malta-int.c
@@ -385,6 +385,8 @@ static int __initdata msc_nr_eicirqs = ARRAY_SIZE(msc_eicirqmap);
*/
#define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK
+#define X GIC_UNUSED
+
static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = {
{ X, X, X, X, 0 },
{ X, X, X, X, 0 },
@@ -404,6 +406,7 @@ static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = {
{ X, X, X, X, 0 },
/* The remainder of this table is initialised by fill_ipi_map */
};
+#undef X
/*
* GCMP needs to be detected before any SMP initialisation
diff --git a/arch/mips/mti-malta/malta-platform.c b/arch/mips/mti-malta/malta-platform.c
index 72e32a7715be..4c35301720e7 100644
--- a/arch/mips/mti-malta/malta-platform.c
+++ b/arch/mips/mti-malta/malta-platform.c
@@ -25,6 +25,7 @@
#include <linux/serial_8250.h>
#include <linux/mc146818rtc.h>
#include <linux/module.h>
+#include <linux/irq.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/platform_device.h>
diff --git a/arch/mips/pci/fixup-fuloong2e.c b/arch/mips/pci/fixup-fuloong2e.c
index 4f6d8da07f93..d5d4c018fb04 100644
--- a/arch/mips/pci/fixup-fuloong2e.c
+++ b/arch/mips/pci/fixup-fuloong2e.c
@@ -52,7 +52,7 @@ static void __init loongson2e_nec_fixup(struct pci_dev *pdev)
{
unsigned int val;
- /* Configues port 1, 2, 3, 4 to be validate*/
+ /* Configures port 1, 2, 3, 4 to be validate*/
pci_read_config_dword(pdev, 0xe0, &val);
pci_write_config_dword(pdev, 0xe0, (val & ~7) | 0x4);
diff --git a/arch/mips/pci/ops-tx3927.c b/arch/mips/pci/ops-tx3927.c
index 31c150196595..6a3bdb5ffa80 100644
--- a/arch/mips/pci/ops-tx3927.c
+++ b/arch/mips/pci/ops-tx3927.c
@@ -38,6 +38,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <asm/addrspace.h>
#include <asm/txx9irq.h>
diff --git a/arch/mips/pci/ops-tx4927.c b/arch/mips/pci/ops-tx4927.c
index 5989e747527f..a1e7e6d80c8c 100644
--- a/arch/mips/pci/ops-tx4927.c
+++ b/arch/mips/pci/ops-tx4927.c
@@ -17,6 +17,7 @@
*/
#include <linux/kernel.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <asm/txx9/pci.h>
#include <asm/txx9/tx4927pcic.h>
diff --git a/arch/mips/pci/pci-rc32434.c b/arch/mips/pci/pci-rc32434.c
index 71f7d27b0d4c..f31218e17d3c 100644
--- a/arch/mips/pci/pci-rc32434.c
+++ b/arch/mips/pci/pci-rc32434.c
@@ -118,7 +118,7 @@ static int __init rc32434_pcibridge_init(void)
if (!((pcicvalue == PCIM_H_EA) ||
(pcicvalue == PCIM_H_IA_FIX) ||
(pcicvalue == PCIM_H_IA_RR))) {
- pr_err(KERN_ERR "PCI init error!!!\n");
+ pr_err("PCI init error!!!\n");
/* Not in Host Mode, return ERROR */
return -1;
}
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c b/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c
index 94c9c2c9fbc1..07e71ff2433f 100644
--- a/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c
+++ b/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c
@@ -14,6 +14,7 @@
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/bitops.h>
+#include <linux/irq.h>
#include <asm/system.h>
diff --git a/arch/mips/pnx8550/common/reset.c b/arch/mips/pnx8550/common/reset.c
index fadd8744a6bc..e7a12ff304b9 100644
--- a/arch/mips/pnx8550/common/reset.c
+++ b/arch/mips/pnx8550/common/reset.c
@@ -22,29 +22,19 @@
*/
#include <linux/kernel.h>
+#include <asm/processor.h>
#include <asm/reboot.h>
#include <glb.h>
void pnx8550_machine_restart(char *command)
{
- char head[] = "************* Machine restart *************";
- char foot[] = "*******************************************";
-
- printk("\n\n");
- printk("%s\n", head);
- if (command != NULL)
- printk("* %s\n", command);
- printk("%s\n", foot);
-
PNX8550_RST_CTL = PNX8550_RST_DO_SW_RST;
}
void pnx8550_machine_halt(void)
{
- printk("*** Machine halt. (Not implemented) ***\n");
-}
-
-void pnx8550_machine_power_off(void)
-{
- printk("*** Machine power off. (Not implemented) ***\n");
+ while (1) {
+ if (cpu_wait)
+ cpu_wait();
+ }
}
diff --git a/arch/mips/pnx8550/common/setup.c b/arch/mips/pnx8550/common/setup.c
index 64246c9c875c..43cb3945fdbf 100644
--- a/arch/mips/pnx8550/common/setup.c
+++ b/arch/mips/pnx8550/common/setup.c
@@ -44,7 +44,6 @@
extern void __init board_setup(void);
extern void pnx8550_machine_restart(char *);
extern void pnx8550_machine_halt(void);
-extern void pnx8550_machine_power_off(void);
extern struct resource ioport_resource;
extern struct resource iomem_resource;
extern char *prom_getcmdline(void);
@@ -100,7 +99,7 @@ void __init plat_mem_setup(void)
_machine_restart = pnx8550_machine_restart;
_machine_halt = pnx8550_machine_halt;
- pm_power_off = pnx8550_machine_power_off;
+ pm_power_off = pnx8550_machine_halt;
/* Clear the Global 2 Register, PCI Inta Output Enable Registers
Bit 1:Enable DAC Powerdown
diff --git a/arch/mips/powertv/asic/irq_asic.c b/arch/mips/powertv/asic/irq_asic.c
index b54d24499b06..e55382434155 100644
--- a/arch/mips/powertv/asic/irq_asic.c
+++ b/arch/mips/powertv/asic/irq_asic.c
@@ -13,6 +13,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
+#include <linux/irq.h>
#include <asm/irq_cpu.h>
#include <asm/mipsregs.h>
diff --git a/arch/mips/rb532/serial.c b/arch/mips/rb532/serial.c
index 00ed19f0bdb5..70482540b3db 100644
--- a/arch/mips/rb532/serial.c
+++ b/arch/mips/rb532/serial.c
@@ -29,6 +29,7 @@
#include <linux/tty.h>
#include <linux/serial_core.h>
#include <linux/serial_8250.h>
+#include <linux/irq.h>
#include <asm/serial.h>
#include <asm/mach-rc32434/rb.h>
diff --git a/arch/mips/sibyte/common/sb_tbprof.c b/arch/mips/sibyte/common/sb_tbprof.c
index d4ed7a9156f5..87ccdb4b5ac9 100644
--- a/arch/mips/sibyte/common/sb_tbprof.c
+++ b/arch/mips/sibyte/common/sb_tbprof.c
@@ -43,7 +43,7 @@
#include <asm/sibyte/sb1250_scd.h>
#include <asm/sibyte/sb1250_int.h>
#else
-#error invalid SiByte UART configuation
+#error invalid SiByte UART configuration
#endif
#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
@@ -545,6 +545,7 @@ static const struct file_operations sbprof_tb_fops = {
.unlocked_ioctl = sbprof_tb_ioctl,
.compat_ioctl = sbprof_tb_ioctl,
.mmap = NULL,
+ .llseek = default_llseek,
};
static struct class *tb_class;
diff --git a/arch/mips/sni/a20r.c b/arch/mips/sni/a20r.c
index e6980892834a..bbe7187879fa 100644
--- a/arch/mips/sni/a20r.c
+++ b/arch/mips/sni/a20r.c
@@ -10,6 +10,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/serial_8250.h>
diff --git a/arch/mips/sni/pcimt.c b/arch/mips/sni/pcimt.c
index 51e62bbaa23b..8c92c73bc717 100644
--- a/arch/mips/sni/pcimt.c
+++ b/arch/mips/sni/pcimt.c
@@ -11,6 +11,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/pci.h>
#include <linux/serial_8250.h>
diff --git a/arch/mips/sni/pcit.c b/arch/mips/sni/pcit.c
index f4699d35858b..dc9874553bec 100644
--- a/arch/mips/sni/pcit.c
+++ b/arch/mips/sni/pcit.c
@@ -10,6 +10,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/pci.h>
#include <linux/serial_8250.h>
diff --git a/arch/mips/sni/rm200.c b/arch/mips/sni/rm200.c
index 90c558f7c0fa..0e6f42c2bbc8 100644
--- a/arch/mips/sni/rm200.c
+++ b/arch/mips/sni/rm200.c
@@ -13,6 +13,7 @@
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/serial_8250.h>
#include <linux/io.h>
diff --git a/arch/mips/sni/time.c b/arch/mips/sni/time.c
index f3b60e671207..c76151b56568 100644
--- a/arch/mips/sni/time.c
+++ b/arch/mips/sni/time.c
@@ -1,5 +1,6 @@
#include <linux/types.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/smp.h>
#include <linux/time.h>
#include <linux/clockchips.h>
diff --git a/arch/mips/txx9/generic/irq_tx4927.c b/arch/mips/txx9/generic/irq_tx4927.c
index ad2870def8f1..e1828e8bcaef 100644
--- a/arch/mips/txx9/generic/irq_tx4927.c
+++ b/arch/mips/txx9/generic/irq_tx4927.c
@@ -25,6 +25,7 @@
*/
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <asm/irq_cpu.h>
#include <asm/txx9/tx4927.h>
diff --git a/arch/mips/txx9/generic/irq_tx4938.c b/arch/mips/txx9/generic/irq_tx4938.c
index 025ae11359a8..a6e6e805097a 100644
--- a/arch/mips/txx9/generic/irq_tx4938.c
+++ b/arch/mips/txx9/generic/irq_tx4938.c
@@ -13,6 +13,7 @@
*/
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <asm/irq_cpu.h>
#include <asm/txx9/tx4938.h>
diff --git a/arch/mips/txx9/generic/irq_tx4939.c b/arch/mips/txx9/generic/irq_tx4939.c
index 013213a8706b..3886ad77cbad 100644
--- a/arch/mips/txx9/generic/irq_tx4939.c
+++ b/arch/mips/txx9/generic/irq_tx4939.c
@@ -19,6 +19,7 @@
*/
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/types.h>
#include <asm/irq_cpu.h>
#include <asm/txx9irq.h>
diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c
index 575d219b8001..812816c45662 100644
--- a/arch/mips/txx9/generic/setup.c
+++ b/arch/mips/txx9/generic/setup.c
@@ -24,6 +24,7 @@
#include <linux/leds.h>
#include <linux/sysdev.h>
#include <linux/slab.h>
+#include <linux/irq.h>
#include <asm/bootinfo.h>
#include <asm/time.h>
#include <asm/reboot.h>
diff --git a/arch/mips/txx9/jmr3927/irq.c b/arch/mips/txx9/jmr3927/irq.c
index 6ec626c9473f..0a7f8e3b9fd7 100644
--- a/arch/mips/txx9/jmr3927/irq.c
+++ b/arch/mips/txx9/jmr3927/irq.c
@@ -32,6 +32,7 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <asm/io.h>
#include <asm/mipsregs.h>
diff --git a/arch/mips/txx9/rbtx4927/irq.c b/arch/mips/txx9/rbtx4927/irq.c
index 9c14ebb26cb4..c4b54d20efd3 100644
--- a/arch/mips/txx9/rbtx4927/irq.c
+++ b/arch/mips/txx9/rbtx4927/irq.c
@@ -111,6 +111,7 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <asm/io.h>
#include <asm/mipsregs.h>
#include <asm/txx9/generic.h>
diff --git a/arch/mips/txx9/rbtx4938/irq.c b/arch/mips/txx9/rbtx4938/irq.c
index 7d21befb8932..67a73a8065ec 100644
--- a/arch/mips/txx9/rbtx4938/irq.c
+++ b/arch/mips/txx9/rbtx4938/irq.c
@@ -64,6 +64,7 @@
*/
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <asm/mipsregs.h>
#include <asm/txx9/generic.h>
#include <asm/txx9/rbtx4938.h>
diff --git a/arch/mips/txx9/rbtx4939/irq.c b/arch/mips/txx9/rbtx4939/irq.c
index 500cc0a908e6..57fa740a7205 100644
--- a/arch/mips/txx9/rbtx4939/irq.c
+++ b/arch/mips/txx9/rbtx4939/irq.c
@@ -11,6 +11,7 @@
*/
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <asm/mipsregs.h>
#include <asm/txx9/rbtx4939.h>
diff --git a/arch/mips/vr41xx/common/irq.c b/arch/mips/vr41xx/common/irq.c
index bef06872f012..0975eb72d385 100644
--- a/arch/mips/vr41xx/common/irq.c
+++ b/arch/mips/vr41xx/common/irq.c
@@ -19,6 +19,7 @@
*/
#include <linux/interrupt.h>
#include <linux/module.h>
+#include <linux/irq.h>
#include <asm/irq_cpu.h>
#include <asm/system.h>
diff --git a/arch/mips/vr41xx/common/siu.c b/arch/mips/vr41xx/common/siu.c
index 54eae56108fb..bbd45d2559d6 100644
--- a/arch/mips/vr41xx/common/siu.c
+++ b/arch/mips/vr41xx/common/siu.c
@@ -22,6 +22,7 @@
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/serial_core.h>
+#include <linux/irq.h>
#include <asm/cpu.h>
#include <asm/vr41xx/siu.h>
diff --git a/arch/mn10300/include/asm/ioctls.h b/arch/mn10300/include/asm/ioctls.h
index cb8cf1902234..0212f4b22557 100644
--- a/arch/mn10300/include/asm/ioctls.h
+++ b/arch/mn10300/include/asm/ioctls.h
@@ -1,88 +1,6 @@
#ifndef _ASM_IOCTLS_H
#define _ASM_IOCTLS_H
-#include <asm/ioctl.h>
-
-/* 0x54 is just a magic number to make these relatively unique ('T') */
-
-#define TCGETS 0x5401
-#define TCSETS 0x5402
-#define TCSETSW 0x5403
-#define TCSETSF 0x5404
-#define TCGETA 0x5405
-#define TCSETA 0x5406
-#define TCSETAW 0x5407
-#define TCSETAF 0x5408
-#define TCSBRK 0x5409
-#define TCXONC 0x540A
-#define TCFLSH 0x540B
-#define TIOCEXCL 0x540C
-#define TIOCNXCL 0x540D
-#define TIOCSCTTY 0x540E
-#define TIOCGPGRP 0x540F
-#define TIOCSPGRP 0x5410
-#define TIOCOUTQ 0x5411
-#define TIOCSTI 0x5412
-#define TIOCGWINSZ 0x5413
-#define TIOCSWINSZ 0x5414
-#define TIOCMGET 0x5415
-#define TIOCMBIS 0x5416
-#define TIOCMBIC 0x5417
-#define TIOCMSET 0x5418
-#define TIOCGSOFTCAR 0x5419
-#define TIOCSSOFTCAR 0x541A
-#define FIONREAD 0x541B
-#define TIOCINQ FIONREAD
-#define TIOCLINUX 0x541C
-#define TIOCCONS 0x541D
-#define TIOCGSERIAL 0x541E
-#define TIOCSSERIAL 0x541F
-#define TIOCPKT 0x5420
-#define FIONBIO 0x5421
-#define TIOCNOTTY 0x5422
-#define TIOCSETD 0x5423
-#define TIOCGETD 0x5424
-#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
-/* #define TIOCTTYGSTRUCT 0x5426 - Former debugging-only ioctl */
-#define TIOCSBRK 0x5427 /* BSD compatibility */
-#define TIOCCBRK 0x5428 /* BSD compatibility */
-#define TIOCGSID 0x5429 /* Return the session ID of FD */
-#define TCGETS2 _IOR('T', 0x2A, struct termios2)
-#define TCSETS2 _IOW('T', 0x2B, struct termios2)
-#define TCSETSW2 _IOW('T', 0x2C, struct termios2)
-#define TCSETSF2 _IOW('T', 0x2D, struct termios2)
-#define TIOCGPTN _IOR('T', 0x30, unsigned int) /* Get Pty Number
- * (of pty-mux device) */
-#define TIOCSPTLCK _IOW('T', 0x31, int) /* Lock/unlock Pty */
-#define TIOCSIG _IOW('T', 0x36, int) /* Generate signal on Pty slave */
-
-#define FIONCLEX 0x5450
-#define FIOCLEX 0x5451
-#define FIOASYNC 0x5452
-#define TIOCSERCONFIG 0x5453
-#define TIOCSERGWILD 0x5454
-#define TIOCSERSWILD 0x5455
-#define TIOCGLCKTRMIOS 0x5456
-#define TIOCSLCKTRMIOS 0x5457
-#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
-#define TIOCSERGETLSR 0x5459 /* Get line status register */
-#define TIOCSERGETMULTI 0x545A /* Get multiport config */
-#define TIOCSERSETMULTI 0x545B /* Set multiport config */
-
-#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
-#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
-#define FIOQSIZE 0x5460
-
-/* Used for packet mode */
-#define TIOCPKT_DATA 0
-#define TIOCPKT_FLUSHREAD 1
-#define TIOCPKT_FLUSHWRITE 2
-#define TIOCPKT_STOP 4
-#define TIOCPKT_START 8
-#define TIOCPKT_NOSTOP 16
-#define TIOCPKT_DOSTOP 32
-#define TIOCPKT_IOCTL 64
-
-#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
+#include <asm-generic/ioctls.h>
#endif /* _ASM_IOCTLS_H */
diff --git a/arch/mn10300/include/asm/irqflags.h b/arch/mn10300/include/asm/irqflags.h
new file mode 100644
index 000000000000..5e529a117cb2
--- /dev/null
+++ b/arch/mn10300/include/asm/irqflags.h
@@ -0,0 +1,123 @@
+/* MN10300 IRQ flag handling
+ *
+ * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _ASM_IRQFLAGS_H
+#define _ASM_IRQFLAGS_H
+
+#include <asm/cpu-regs.h>
+
+/*
+ * interrupt control
+ * - "disabled": run in IM1/2
+ * - level 0 - GDB stub
+ * - level 1 - virtual serial DMA (if present)
+ * - level 5 - normal interrupt priority
+ * - level 6 - timer interrupt
+ * - "enabled": run in IM7
+ */
+#ifdef CONFIG_MN10300_TTYSM
+#define MN10300_CLI_LEVEL EPSW_IM_2
+#else
+#define MN10300_CLI_LEVEL EPSW_IM_1
+#endif
+
+#ifndef __ASSEMBLY__
+
+static inline unsigned long arch_local_save_flags(void)
+{
+ unsigned long flags;
+
+ asm volatile("mov epsw,%0" : "=d"(flags));
+ return flags;
+}
+
+static inline void arch_local_irq_disable(void)
+{
+ asm volatile(
+ " and %0,epsw \n"
+ " or %1,epsw \n"
+ " nop \n"
+ " nop \n"
+ " nop \n"
+ :
+ : "i"(~EPSW_IM), "i"(EPSW_IE | MN10300_CLI_LEVEL)
+ : "memory");
+}
+
+static inline unsigned long arch_local_irq_save(void)
+{
+ unsigned long flags;
+
+ flags = arch_local_save_flags();
+ arch_local_irq_disable();
+ return flags;
+}
+
+/*
+ * we make sure arch_irq_enable() doesn't cause priority inversion
+ */
+extern unsigned long __mn10300_irq_enabled_epsw;
+
+static inline void arch_local_irq_enable(void)
+{
+ unsigned long tmp;
+
+ asm volatile(
+ " mov epsw,%0 \n"
+ " and %1,%0 \n"
+ " or %2,%0 \n"
+ " mov %0,epsw \n"
+ : "=&d"(tmp)
+ : "i"(~EPSW_IM), "r"(__mn10300_irq_enabled_epsw)
+ : "memory");
+}
+
+static inline void arch_local_irq_restore(unsigned long flags)
+{
+ asm volatile(
+ " mov %0,epsw \n"
+ " nop \n"
+ " nop \n"
+ " nop \n"
+ :
+ : "d"(flags)
+ : "memory", "cc");
+}
+
+static inline bool arch_irqs_disabled_flags(unsigned long flags)
+{
+ return (flags & EPSW_IM) <= MN10300_CLI_LEVEL;
+}
+
+static inline bool arch_irqs_disabled(void)
+{
+ return arch_irqs_disabled_flags(arch_local_save_flags());
+}
+
+/*
+ * Hook to save power by halting the CPU
+ * - called from the idle loop
+ * - must reenable interrupts (which takes three instruction cycles to complete)
+ */
+static inline void arch_safe_halt(void)
+{
+ asm volatile(
+ " or %0,epsw \n"
+ " nop \n"
+ " nop \n"
+ " bset %2,(%1) \n"
+ :
+ : "i"(EPSW_IE|EPSW_IM), "n"(&CPUM), "i"(CPUM_SLEEP)
+ : "cc");
+}
+
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_IRQFLAGS_H */
diff --git a/arch/mn10300/include/asm/system.h b/arch/mn10300/include/asm/system.h
index 3636c054dcd5..9f7c7e17c01e 100644
--- a/arch/mn10300/include/asm/system.h
+++ b/arch/mn10300/include/asm/system.h
@@ -17,6 +17,7 @@
#ifndef __ASSEMBLY__
#include <linux/kernel.h>
+#include <linux/irqflags.h>
struct task_struct;
struct thread_struct;
@@ -81,114 +82,6 @@ do { \
/*****************************************************************************/
/*
- * interrupt control
- * - "disabled": run in IM1/2
- * - level 0 - GDB stub
- * - level 1 - virtual serial DMA (if present)
- * - level 5 - normal interrupt priority
- * - level 6 - timer interrupt
- * - "enabled": run in IM7
- */
-#ifdef CONFIG_MN10300_TTYSM
-#define MN10300_CLI_LEVEL EPSW_IM_2
-#else
-#define MN10300_CLI_LEVEL EPSW_IM_1
-#endif
-
-#define local_save_flags(x) \
-do { \
- typecheck(unsigned long, x); \
- asm volatile( \
- " mov epsw,%0 \n" \
- : "=d"(x) \
- ); \
-} while (0)
-
-#define local_irq_disable() \
-do { \
- asm volatile( \
- " and %0,epsw \n" \
- " or %1,epsw \n" \
- " nop \n" \
- " nop \n" \
- " nop \n" \
- : \
- : "i"(~EPSW_IM), "i"(EPSW_IE | MN10300_CLI_LEVEL) \
- ); \
-} while (0)
-
-#define local_irq_save(x) \
-do { \
- local_save_flags(x); \
- local_irq_disable(); \
-} while (0)
-
-/*
- * we make sure local_irq_enable() doesn't cause priority inversion
- */
-#ifndef __ASSEMBLY__
-
-extern unsigned long __mn10300_irq_enabled_epsw;
-
-#endif
-
-#define local_irq_enable() \
-do { \
- unsigned long tmp; \
- \
- asm volatile( \
- " mov epsw,%0 \n" \
- " and %1,%0 \n" \
- " or %2,%0 \n" \
- " mov %0,epsw \n" \
- : "=&d"(tmp) \
- : "i"(~EPSW_IM), "r"(__mn10300_irq_enabled_epsw) \
- : "cc" \
- ); \
-} while (0)
-
-#define local_irq_restore(x) \
-do { \
- typecheck(unsigned long, x); \
- asm volatile( \
- " mov %0,epsw \n" \
- " nop \n" \
- " nop \n" \
- " nop \n" \
- : \
- : "d"(x) \
- : "memory", "cc" \
- ); \
-} while (0)
-
-#define irqs_disabled() \
-({ \
- unsigned long flags; \
- local_save_flags(flags); \
- (flags & EPSW_IM) <= MN10300_CLI_LEVEL; \
-})
-
-/* hook to save power by halting the CPU
- * - called from the idle loop
- * - must reenable interrupts (which takes three instruction cycles to complete)
- */
-#define safe_halt() \
-do { \
- asm volatile(" or %0,epsw \n" \
- " nop \n" \
- " nop \n" \
- " bset %2,(%1) \n" \
- : \
- : "i"(EPSW_IE|EPSW_IM), "n"(&CPUM), "i"(CPUM_SLEEP)\
- : "cc" \
- ); \
-} while (0)
-
-#define STI or EPSW_IE|EPSW_IM,epsw
-#define CLI and ~EPSW_IM,epsw; or EPSW_IE|MN10300_CLI_LEVEL,epsw; nop; nop; nop
-
-/*****************************************************************************/
-/*
* MN10300 doesn't actually have an exchange instruction
*/
#ifndef __ASSEMBLY__
diff --git a/arch/mn10300/kernel/entry.S b/arch/mn10300/kernel/entry.S
index d9ed5a15c547..3d394b4eefba 100644
--- a/arch/mn10300/kernel/entry.S
+++ b/arch/mn10300/kernel/entry.S
@@ -16,6 +16,7 @@
#include <linux/linkage.h>
#include <asm/smp.h>
#include <asm/system.h>
+#include <asm/irqflags.h>
#include <asm/thread_info.h>
#include <asm/intctl-regs.h>
#include <asm/busctl-regs.h>
diff --git a/arch/mn10300/kernel/module.c b/arch/mn10300/kernel/module.c
index 6aea7fd76993..196a111e2e29 100644
--- a/arch/mn10300/kernel/module.c
+++ b/arch/mn10300/kernel/module.c
@@ -206,7 +206,7 @@ int module_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs,
struct module *me)
{
- return module_bug_finalize(hdr, sechdrs, me);
+ return 0;
}
/*
@@ -214,5 +214,4 @@ int module_finalize(const Elf_Ehdr *hdr,
*/
void module_arch_cleanup(struct module *mod)
{
- module_bug_cleanup(mod);
}
diff --git a/arch/mn10300/mm/cache.c b/arch/mn10300/mm/cache.c
index 1b76719ec1c3..9261217e8d2c 100644
--- a/arch/mn10300/mm/cache.c
+++ b/arch/mn10300/mm/cache.c
@@ -54,13 +54,30 @@ EXPORT_SYMBOL(flush_icache_page);
void flush_icache_range(unsigned long start, unsigned long end)
{
#ifdef CONFIG_MN10300_CACHE_WBACK
- unsigned long addr, size, off;
+ unsigned long addr, size, base, off;
struct page *page;
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *ppte, pte;
+ if (end > 0x80000000UL) {
+ /* addresses above 0xa0000000 do not go through the cache */
+ if (end > 0xa0000000UL) {
+ end = 0xa0000000UL;
+ if (start >= end)
+ return;
+ }
+
+ /* kernel addresses between 0x80000000 and 0x9fffffff do not
+ * require page tables, so we just map such addresses directly */
+ base = (start >= 0x80000000UL) ? start : 0x80000000UL;
+ mn10300_dcache_flush_range(base, end);
+ if (base == start)
+ goto invalidate;
+ end = base;
+ }
+
for (; start < end; start += size) {
/* work out how much of the page to flush */
off = start & (PAGE_SIZE - 1);
@@ -104,6 +121,7 @@ void flush_icache_range(unsigned long start, unsigned long end)
}
#endif
+invalidate:
mn10300_icache_inv();
}
EXPORT_SYMBOL(flush_icache_range);
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 907417d187e1..79a04a9394d5 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -16,6 +16,7 @@ config PARISC
select RTC_DRV_GENERIC
select INIT_ALL_POSSIBLE
select BUG
+ select HAVE_IRQ_WORK
select HAVE_PERF_EVENTS
select GENERIC_ATOMIC64 if !64BIT
help
diff --git a/arch/parisc/include/asm/irqflags.h b/arch/parisc/include/asm/irqflags.h
new file mode 100644
index 000000000000..34f9cb9b4754
--- /dev/null
+++ b/arch/parisc/include/asm/irqflags.h
@@ -0,0 +1,46 @@
+#ifndef __PARISC_IRQFLAGS_H
+#define __PARISC_IRQFLAGS_H
+
+#include <linux/types.h>
+#include <asm/psw.h>
+
+static inline unsigned long arch_local_save_flags(void)
+{
+ unsigned long flags;
+ asm volatile("ssm 0, %0" : "=r" (flags) : : "memory");
+ return flags;
+}
+
+static inline void arch_local_irq_disable(void)
+{
+ asm volatile("rsm %0,%%r0\n" : : "i" (PSW_I) : "memory");
+}
+
+static inline void arch_local_irq_enable(void)
+{
+ asm volatile("ssm %0,%%r0\n" : : "i" (PSW_I) : "memory");
+}
+
+static inline unsigned long arch_local_irq_save(void)
+{
+ unsigned long flags;
+ asm volatile("rsm %1,%0" : "=r" (flags) : "i" (PSW_I) : "memory");
+ return flags;
+}
+
+static inline void arch_local_irq_restore(unsigned long flags)
+{
+ asm volatile("mtsm %0" : : "r" (flags) : "memory");
+}
+
+static inline bool arch_irqs_disabled_flags(unsigned long flags)
+{
+ return (flags & PSW_I) == 0;
+}
+
+static inline bool arch_irqs_disabled(void)
+{
+ return arch_irqs_disabled_flags(arch_local_save_flags());
+}
+
+#endif /* __PARISC_IRQFLAGS_H */
diff --git a/arch/parisc/include/asm/perf_event.h b/arch/parisc/include/asm/perf_event.h
index cc146427d8f9..1e0fd8ba6c03 100644
--- a/arch/parisc/include/asm/perf_event.h
+++ b/arch/parisc/include/asm/perf_event.h
@@ -1,7 +1,6 @@
#ifndef __ASM_PARISC_PERF_EVENT_H
#define __ASM_PARISC_PERF_EVENT_H
-/* parisc only supports software events through this interface. */
-static inline void set_perf_event_pending(void) { }
+/* Empty, just to avoid compiling error */
#endif /* __ASM_PARISC_PERF_EVENT_H */
diff --git a/arch/parisc/include/asm/system.h b/arch/parisc/include/asm/system.h
index 2ab4af58ecb9..b19e63a8e848 100644
--- a/arch/parisc/include/asm/system.h
+++ b/arch/parisc/include/asm/system.h
@@ -1,7 +1,7 @@
#ifndef __PARISC_SYSTEM_H
#define __PARISC_SYSTEM_H
-#include <asm/psw.h>
+#include <linux/irqflags.h>
/* The program status word as bitfields. */
struct pa_psw {
@@ -48,23 +48,6 @@ extern struct task_struct *_switch_to(struct task_struct *, struct task_struct *
(last) = _switch_to(prev, next); \
} while(0)
-/* interrupt control */
-#define local_save_flags(x) __asm__ __volatile__("ssm 0, %0" : "=r" (x) : : "memory")
-#define local_irq_disable() __asm__ __volatile__("rsm %0,%%r0\n" : : "i" (PSW_I) : "memory" )
-#define local_irq_enable() __asm__ __volatile__("ssm %0,%%r0\n" : : "i" (PSW_I) : "memory" )
-
-#define local_irq_save(x) \
- __asm__ __volatile__("rsm %1,%0" : "=r" (x) :"i" (PSW_I) : "memory" )
-#define local_irq_restore(x) \
- __asm__ __volatile__("mtsm %0" : : "r" (x) : "memory" )
-
-#define irqs_disabled() \
-({ \
- unsigned long flags; \
- local_save_flags(flags); \
- (flags & PSW_I) == 0; \
-})
-
#define mfctl(reg) ({ \
unsigned long cr; \
__asm__ __volatile__( \
diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c
index 159a2b81e90c..6e81bb596e5b 100644
--- a/arch/parisc/kernel/module.c
+++ b/arch/parisc/kernel/module.c
@@ -941,11 +941,10 @@ int module_finalize(const Elf_Ehdr *hdr,
nsyms = newptr - (Elf_Sym *)symhdr->sh_addr;
DEBUGP("NEW num_symtab %lu\n", nsyms);
symhdr->sh_size = nsyms * sizeof(Elf_Sym);
- return module_bug_finalize(hdr, sechdrs, me);
+ return 0;
}
void module_arch_cleanup(struct module *mod)
{
deregister_unwind_table(mod);
- module_bug_cleanup(mod);
}
diff --git a/arch/parisc/kernel/perf.c b/arch/parisc/kernel/perf.c
index f9f6783e4bdd..ba0c053e25ae 100644
--- a/arch/parisc/kernel/perf.c
+++ b/arch/parisc/kernel/perf.c
@@ -46,7 +46,6 @@
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/miscdevice.h>
-#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <asm/uaccess.h>
@@ -261,16 +260,13 @@ printk("Preparing to start counters\n");
*/
static int perf_open(struct inode *inode, struct file *file)
{
- lock_kernel();
spin_lock(&perf_lock);
if (perf_enabled) {
spin_unlock(&perf_lock);
- unlock_kernel();
return -EBUSY;
}
perf_enabled = 1;
spin_unlock(&perf_lock);
- unlock_kernel();
return 0;
}
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 44df1bac9701..29158913a66b 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -138,6 +138,7 @@ config PPC
select HAVE_OPROFILE
select HAVE_SYSCALL_WRAPPERS if PPC64
select GENERIC_ATOMIC64 if PPC32
+ select HAVE_IRQ_WORK
select HAVE_PERF_EVENTS
select HAVE_REGS_AND_STACK_ACCESS_API
select HAVE_HW_BREAKPOINT if PERF_EVENTS && PPC_BOOK3S_64
diff --git a/arch/powerpc/boot/addnote.c b/arch/powerpc/boot/addnote.c
index b1e5611b2ab1..349b5530d2c4 100644
--- a/arch/powerpc/boot/addnote.c
+++ b/arch/powerpc/boot/addnote.c
@@ -20,7 +20,7 @@
#include <string.h>
/* CHRP note section */
-char arch[] = "PowerPC";
+static const char arch[] = "PowerPC";
#define N_DESCR 6
unsigned int descr[N_DESCR] = {
@@ -33,7 +33,7 @@ unsigned int descr[N_DESCR] = {
};
/* RPA note section */
-char rpaname[] = "IBM,RPA-Client-Config";
+static const char rpaname[] = "IBM,RPA-Client-Config";
/*
* Note: setting ignore_my_client_config *should* mean that OF ignores
diff --git a/arch/powerpc/boot/dts/bluestone.dts b/arch/powerpc/boot/dts/bluestone.dts
new file mode 100644
index 000000000000..9bb3d72c0e5a
--- /dev/null
+++ b/arch/powerpc/boot/dts/bluestone.dts
@@ -0,0 +1,254 @@
+/*
+ * Device Tree for Bluestone (APM821xx) board.
+ *
+ * Copyright (c) 2010, Applied Micro Circuits Corporation
+ * Author: Tirumala R Marri <tmarri@apm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+/dts-v1/;
+
+/ {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ model = "apm,bluestone";
+ compatible = "apm,bluestone";
+ dcr-parent = <&{/cpus/cpu@0}>;
+
+ aliases {
+ ethernet0 = &EMAC0;
+ serial0 = &UART0;
+ serial1 = &UART1;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ model = "PowerPC,apm821xx";
+ reg = <0x00000000>;
+ clock-frequency = <0>; /* Filled in by U-Boot */
+ timebase-frequency = <0>; /* Filled in by U-Boot */
+ i-cache-line-size = <32>;
+ d-cache-line-size = <32>;
+ i-cache-size = <32768>;
+ d-cache-size = <32768>;
+ dcr-controller;
+ dcr-access-method = "native";
+ next-level-cache = <&L2C0>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x00000000 0x00000000>; /* Filled in by U-Boot */
+ };
+
+ UIC0: interrupt-controller0 {
+ compatible = "ibm,uic";
+ interrupt-controller;
+ cell-index = <0>;
+ dcr-reg = <0x0c0 0x009>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ #interrupt-cells = <2>;
+ };
+
+ UIC1: interrupt-controller1 {
+ compatible = "ibm,uic";
+ interrupt-controller;
+ cell-index = <1>;
+ dcr-reg = <0x0d0 0x009>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ #interrupt-cells = <2>;
+ interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */
+ interrupt-parent = <&UIC0>;
+ };
+
+ UIC2: interrupt-controller2 {
+ compatible = "ibm,uic";
+ interrupt-controller;
+ cell-index = <2>;
+ dcr-reg = <0x0e0 0x009>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ #interrupt-cells = <2>;
+ interrupts = <0xa 0x4 0xb 0x4>; /* cascade */
+ interrupt-parent = <&UIC0>;
+ };
+
+ UIC3: interrupt-controller3 {
+ compatible = "ibm,uic";
+ interrupt-controller;
+ cell-index = <3>;
+ dcr-reg = <0x0f0 0x009>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ #interrupt-cells = <2>;
+ interrupts = <0x10 0x4 0x11 0x4>; /* cascade */
+ interrupt-parent = <&UIC0>;
+ };
+
+ SDR0: sdr {
+ compatible = "ibm,sdr-apm821xx";
+ dcr-reg = <0x00e 0x002>;
+ };
+
+ CPR0: cpr {
+ compatible = "ibm,cpr-apm821xx";
+ dcr-reg = <0x00c 0x002>;
+ };
+
+ plb {
+ compatible = "ibm,plb4";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges;
+ clock-frequency = <0>; /* Filled in by U-Boot */
+
+ SDRAM0: sdram {
+ compatible = "ibm,sdram-apm821xx";
+ dcr-reg = <0x010 0x002>;
+ };
+
+ MAL0: mcmal {
+ compatible = "ibm,mcmal2";
+ descriptor-memory = "ocm";
+ dcr-reg = <0x180 0x062>;
+ num-tx-chans = <1>;
+ num-rx-chans = <1>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ interrupt-parent = <&UIC2>;
+ interrupts = < /*TXEOB*/ 0x6 0x4
+ /*RXEOB*/ 0x7 0x4
+ /*SERR*/ 0x3 0x4
+ /*TXDE*/ 0x4 0x4
+ /*RXDE*/ 0x5 0x4
+ };
+
+ POB0: opb {
+ compatible = "ibm,opb";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0xb0000000 0x00000004 0xb0000000 0x50000000>;
+ clock-frequency = <0>; /* Filled in by U-Boot */
+
+ EBC0: ebc {
+ compatible = "ibm,ebc";
+ dcr-reg = <0x012 0x002>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ clock-frequency = <0>; /* Filled in by U-Boot */
+ /* ranges property is supplied by U-Boot */
+ ranges = < 0x00000003 0x00000000 0xe0000000 0x8000000>;
+ interrupts = <0x6 0x4>;
+ interrupt-parent = <&UIC1>;
+
+ nor_flash@0,0 {
+ compatible = "amd,s29gl512n", "cfi-flash";
+ bank-width = <2>;
+ reg = <0x00000000 0x00000000 0x00400000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ label = "kernel";
+ reg = <0x00000000 0x00180000>;
+ };
+ partition@180000 {
+ label = "env";
+ reg = <0x00180000 0x00020000>;
+ };
+ partition@1a0000 {
+ label = "u-boot";
+ reg = <0x001a0000 0x00060000>;
+ };
+ };
+ }
+
+ UART0: serial@ef600300 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0xef600300 0x00000008>;
+ virtual-reg = <0xef600300>;
+ clock-frequency = <0>; /* Filled in by U-Boot */
+ current-speed = <0>; /* Filled in by U-Boot */
+ interrupt-parent = <&UIC1>;
+ interrupts = <0x1 0x4>;
+ };
+
+ IIC0: i2c@ef600700 {
+ compatible = "ibm,iic";
+ reg = <0xef600700 0x00000014>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <0x2 0x4>;
+ };
+
+ IIC1: i2c@ef600800 {
+ compatible = "ibm,iic";
+ reg = <0xef600800 0x00000014>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <0x3 0x4>;
+ };
+
+ RGMII0: emac-rgmii@ef601500 {
+ compatible = "ibm,rgmii";
+ reg = <0xef601500 0x00000008>;
+ has-mdio;
+ };
+
+ TAH0: emac-tah@ef601350 {
+ compatible = "ibm,tah";
+ reg = <0xef601350 0x00000030>;
+ };
+
+ EMAC0: ethernet@ef600c00 {
+ device_type = "network";
+ compatible = "ibm,emac4sync";
+ interrupt-parent = <&EMAC0>;
+ interrupts = <0x0 0x1>;
+ #interrupt-cells = <1>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ interrupt-map = </*Status*/ 0x0 &UIC2 0x10 0x4
+ /*Wake*/ 0x1 &UIC2 0x14 0x4>;
+ reg = <0xef600c00 0x000000c4>;
+ local-mac-address = [000000000000]; /* Filled in by U-Boot */
+ mal-device = <&MAL0>;
+ mal-tx-channel = <0>;
+ mal-rx-channel = <0>;
+ cell-index = <0>;
+ max-frame-size = <9000>;
+ rx-fifo-size = <16384>;
+ tx-fifo-size = <2048>;
+ phy-mode = "rgmii";
+ phy-map = <0x00000000>;
+ rgmii-device = <&RGMII0>;
+ rgmii-channel = <0>;
+ tah-device = <&TAH0>;
+ tah-channel = <0>;
+ has-inverted-stacr-oc;
+ has-new-stacr-staopc;
+ };
+ };
+
+ };
+};
diff --git a/arch/powerpc/boot/dts/mpc8308_p1m.dts b/arch/powerpc/boot/dts/mpc8308_p1m.dts
new file mode 100644
index 000000000000..05a76ccfd499
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc8308_p1m.dts
@@ -0,0 +1,332 @@
+/*
+ * mpc8308_p1m Device Tree Source
+ *
+ * Copyright 2010 Ilya Yanok, Emcraft Systems, yanok@emcraft.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/dts-v1/;
+
+/ {
+ compatible = "denx,mpc8308_p1m";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ pci0 = &pci0;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,8308@0 {
+ device_type = "cpu";
+ reg = <0x0>;
+ d-cache-line-size = <32>;
+ i-cache-line-size = <32>;
+ d-cache-size = <16384>;
+ i-cache-size = <16384>;
+ timebase-frequency = <0>; // from bootloader
+ bus-frequency = <0>; // from bootloader
+ clock-frequency = <0>; // from bootloader
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x08000000>; // 128MB at 0
+ };
+
+ localbus@e0005000 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8315-elbc", "fsl,elbc", "simple-bus";
+ reg = <0xe0005000 0x1000>;
+ interrupts = <77 0x8>;
+ interrupt-parent = <&ipic>;
+
+ ranges = <0x0 0x0 0xfc000000 0x04000000
+ 0x1 0x0 0xfbff0000 0x00008000
+ 0x2 0x0 0xfbff8000 0x00008000>;
+
+ flash@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x4000000>;
+ bank-width = <2>;
+ device-width = <1>;
+
+ u-boot@0 {
+ reg = <0x0 0x60000>;
+ read-only;
+ };
+ env@60000 {
+ reg = <0x60000 0x20000>;
+ };
+ env1@80000 {
+ reg = <0x80000 0x20000>;
+ };
+ kernel@a0000 {
+ reg = <0xa0000 0x200000>;
+ };
+ dtb@2a0000 {
+ reg = <0x2a0000 0x20000>;
+ };
+ ramdisk@2c0000 {
+ reg = <0x2c0000 0x640000>;
+ };
+ user@700000 {
+ reg = <0x700000 0x3900000>;
+ };
+ };
+
+ can@1,0 {
+ compatible = "nxp,sja1000";
+ reg = <0x1 0x0 0x80>;
+ interrupts = <18 0x8>;
+ interrups-parent = <&ipic>;
+ };
+
+ cpld@2,0 {
+ compatible = "denx,mpc8308_p1m-cpld";
+ reg = <0x2 0x0 0x8>;
+ interrupts = <48 0x8>;
+ interrups-parent = <&ipic>;
+ };
+ };
+
+ immr@e0000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "soc";
+ compatible = "fsl,mpc8308-immr", "simple-bus";
+ ranges = <0 0xe0000000 0x00100000>;
+ reg = <0xe0000000 0x00000200>;
+ bus-frequency = <0>;
+
+ i2c@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x3000 0x100>;
+ interrupts = <14 0x8>;
+ interrupt-parent = <&ipic>;
+ dfsrr;
+ fram@50 {
+ compatible = "ramtron,24c64";
+ reg = <0x50>;
+ };
+ };
+
+ i2c@3100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x3100 0x100>;
+ interrupts = <15 0x8>;
+ interrupt-parent = <&ipic>;
+ dfsrr;
+ pwm@28 {
+ compatible = "maxim,ds1050";
+ reg = <0x28>;
+ };
+ sensor@48 {
+ compatible = "maxim,max6625";
+ reg = <0x48>;
+ };
+ sensor@49 {
+ compatible = "maxim,max6625";
+ reg = <0x49>;
+ };
+ sensor@4b {
+ compatible = "maxim,max6625";
+ reg = <0x4b>;
+ };
+ };
+
+ usb@23000 {
+ compatible = "fsl-usb2-dr";
+ reg = <0x23000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupt-parent = <&ipic>;
+ interrupts = <38 0x8>;
+ dr_mode = "peripheral";
+ phy_type = "ulpi";
+ };
+
+ enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x24000 0x1000>;
+
+ cell-index = <0>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "gianfar";
+ reg = <0x24000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <32 0x8 33 0x8 34 0x8>;
+ interrupt-parent = <&ipic>;
+ phy-handle = < &phy1 >;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&ipic>;
+ interrupts = <17 0x8>;
+ reg = <0x1>;
+ device_type = "ethernet-phy";
+ };
+ phy2: ethernet-phy@2 {
+ interrupt-parent = <&ipic>;
+ interrupts = <19 0x8>;
+ reg = <0x2>;
+ device_type = "ethernet-phy";
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <1>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "gianfar";
+ reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <35 0x8 36 0x8 37 0x8>;
+ interrupt-parent = <&ipic>;
+ phy-handle = < &phy2 >;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ serial0: serial@4500 {
+ cell-index = <0>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x4500 0x100>;
+ clock-frequency = <133333333>;
+ interrupts = <9 0x8>;
+ interrupt-parent = <&ipic>;
+ };
+
+ serial1: serial@4600 {
+ cell-index = <1>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x4600 0x100>;
+ clock-frequency = <133333333>;
+ interrupts = <10 0x8>;
+ interrupt-parent = <&ipic>;
+ };
+
+ gpio@c00 {
+ #gpio-cells = <2>;
+ compatible = "fsl,mpc8308-gpio", "fsl,mpc8349-gpio";
+ reg = <0xc00 0x18>;
+ interrupts = <74 0x8>;
+ interrupt-parent = <&ipic>;
+ gpio-controller;
+ };
+
+ timer@500 {
+ compatible = "fsl,mpc8308-gtm", "fsl,gtm";
+ reg = <0x500 0x100>;
+ interrupts = <90 8 78 8 84 8 72 8>;
+ interrupt-parent = <&ipic>;
+ clock-frequency = <133333333>;
+ };
+
+ /* IPIC
+ * interrupts cell = <intr #, sense>
+ * sense values match linux IORESOURCE_IRQ_* defines:
+ * sense == 8: Level, low assertion
+ * sense == 2: Edge, high-to-low change
+ */
+ ipic: interrupt-controller@700 {
+ compatible = "fsl,ipic";
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ reg = <0x700 0x100>;
+ device_type = "ipic";
+ };
+
+ ipic-msi@7c0 {
+ compatible = "fsl,ipic-msi";
+ reg = <0x7c0 0x40>;
+ msi-available-ranges = <0x0 0x100>;
+ interrupts = < 0x43 0x8
+ 0x4 0x8
+ 0x51 0x8
+ 0x52 0x8
+ 0x56 0x8
+ 0x57 0x8
+ 0x58 0x8
+ 0x59 0x8 >;
+ interrupt-parent = < &ipic >;
+ };
+
+ };
+
+ pci0: pcie@e0009000 {
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ device_type = "pci";
+ compatible = "fsl,mpc8308-pcie", "fsl,mpc8314-pcie";
+ reg = <0xe0009000 0x00001000
+ 0xb0000000 0x01000000>;
+ ranges = <0x02000000 0 0xa0000000 0xa0000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xb1000000 0 0x00800000>;
+ bus-range = <0 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &ipic 1 8>;
+ interrupts = <0x1 0x8>;
+ interrupt-parent = <&ipic>;
+ clock-frequency = <0>;
+
+ pcie@0 {
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ reg = <0 0 0 0 0>;
+ ranges = <0x02000000 0 0xa0000000
+ 0x02000000 0 0xa0000000
+ 0 0x10000000
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00800000>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/mpc8536ds.dts b/arch/powerpc/boot/dts/mpc8536ds.dts
index 815cebb2e3e5..a75c10eed269 100644
--- a/arch/powerpc/boot/dts/mpc8536ds.dts
+++ b/arch/powerpc/boot/dts/mpc8536ds.dts
@@ -108,6 +108,58 @@
};
};
+ spi@7000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,mpc8536-espi";
+ reg = <0x7000 0x1000>;
+ interrupts = <59 0x2>;
+ interrupt-parent = <&mpic>;
+ fsl,espi-num-chipselects = <4>;
+
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25sl12801";
+ reg = <0>;
+ spi-max-frequency = <40000000>;
+ partition@u-boot {
+ label = "u-boot";
+ reg = <0x00000000 0x00100000>;
+ read-only;
+ };
+ partition@kernel {
+ label = "kernel";
+ reg = <0x00100000 0x00500000>;
+ read-only;
+ };
+ partition@dtb {
+ label = "dtb";
+ reg = <0x00600000 0x00100000>;
+ read-only;
+ };
+ partition@fs {
+ label = "file system";
+ reg = <0x00700000 0x00900000>;
+ };
+ };
+ flash@1 {
+ compatible = "spansion,s25sl12801";
+ reg = <1>;
+ spi-max-frequency = <40000000>;
+ };
+ flash@2 {
+ compatible = "spansion,s25sl12801";
+ reg = <2>;
+ spi-max-frequency = <40000000>;
+ };
+ flash@3 {
+ compatible = "spansion,s25sl12801";
+ reg = <3>;
+ spi-max-frequency = <40000000>;
+ };
+ };
+
dma@21300 {
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/powerpc/boot/dts/p1022ds.dts b/arch/powerpc/boot/dts/p1022ds.dts
index 8bcb10b92677..2bbecbb4cbf9 100644
--- a/arch/powerpc/boot/dts/p1022ds.dts
+++ b/arch/powerpc/boot/dts/p1022ds.dts
@@ -148,6 +148,17 @@
label = "reserved-nand";
};
};
+
+ board-control@3,0 {
+ compatible = "fsl,p1022ds-pixis";
+ reg = <3 0 0x30>;
+ interrupt-parent = <&mpic>;
+ /*
+ * IRQ8 is generated if the "EVENT" switch is pressed
+ * and PX_CTL[EVESEL] is set to 00.
+ */
+ interrupts = <8 8>;
+ };
};
soc@fffe00000 {
diff --git a/arch/powerpc/boot/dts/p4080ds.dts b/arch/powerpc/boot/dts/p4080ds.dts
index 2f0de24e3822..5b7fc29dd6cf 100644
--- a/arch/powerpc/boot/dts/p4080ds.dts
+++ b/arch/powerpc/boot/dts/p4080ds.dts
@@ -236,22 +236,19 @@
};
spi@110000 {
- cell-index = <0>;
#address-cells = <1>;
#size-cells = <0>;
- compatible = "fsl,espi";
+ compatible = "fsl,p4080-espi", "fsl,mpc8536-espi";
reg = <0x110000 0x1000>;
interrupts = <53 0x2>;
interrupt-parent = <&mpic>;
- espi,num-ss-bits = <4>;
- mode = "cpu";
+ fsl,espi-num-chipselects = <4>;
- fsl_m25p80@0 {
+ flash@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "fsl,espi-flash";
+ compatible = "spansion,s25sl12801";
reg = <0>;
- linux,modalias = "fsl_m25p80";
spi-max-frequency = <40000000>; /* input clock */
partition@u-boot {
label = "u-boot";
diff --git a/arch/powerpc/configs/44x/bluestone_defconfig b/arch/powerpc/configs/44x/bluestone_defconfig
new file mode 100644
index 000000000000..ac65b48b8ccd
--- /dev/null
+++ b/arch/powerpc/configs/44x/bluestone_defconfig
@@ -0,0 +1,68 @@
+CONFIG_44x=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EMBEDDED=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_PCI_QUIRKS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_BLUESTONE=y
+# CONFIG_EBONY is not set
+# CONFIG_KVM_GUEST is not set
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE=""
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_CONNECTOR=y
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_OF_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_PROC_DEVICETREE=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=35000
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_IBM_NEW_EMAC=y
+CONFIG_IBM_NEW_EMAC_RXB=256
+CONFIG_IBM_NEW_EMAC_TXB=256
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_IBM_IIC=y
+CONFIG_SENSORS_AD7414=y
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_M41T80=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS=y
diff --git a/arch/powerpc/configs/e55xx_smp_defconfig b/arch/powerpc/configs/e55xx_smp_defconfig
new file mode 100644
index 000000000000..94d120ef99cf
--- /dev/null
+++ b/arch/powerpc/configs/e55xx_smp_defconfig
@@ -0,0 +1,84 @@
+CONFIG_PPC64=y
+CONFIG_PPC_BOOK3E_64=y
+# CONFIG_VIRT_CPU_ACCOUNTING is not set
+CONFIG_SMP=y
+CONFIG_NR_CPUS=2
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_P5020_DS=y
+# CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BINFMT_MISC=m
+CONFIG_SPARSE_IRQ=y
+# CONFIG_PCI is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_PROC_DEVICETREE=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=131072
+CONFIG_EEPROM_LEGACY=y
+CONFIG_INPUT_FF_MEMLESS=m
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+CONFIG_I2C=y
+# CONFIG_HWMON is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=y
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_DMADEVICES=y
+CONFIG_FSL_DMA=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_MAC_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_UTF8=m
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC_ITU_T=m
+CONFIG_LIBCRC32C=m
+CONFIG_FRAME_WARN=1024
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_VIRQ_DEBUG=y
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_DEV_TALITOS=y
diff --git a/arch/powerpc/configs/ppc44x_defconfig b/arch/powerpc/configs/ppc44x_defconfig
index cd446fba3fae..2fa05f7be4cb 100644
--- a/arch/powerpc/configs/ppc44x_defconfig
+++ b/arch/powerpc/configs/ppc44x_defconfig
@@ -12,6 +12,7 @@ CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_BAMBOO=y
+CONFIG_BLUESTONE=y
CONFIG_SAM440EP=y
CONFIG_SEQUOIA=y
CONFIG_TAISHAN=y
@@ -97,14 +98,17 @@ CONFIG_USB_STORAGE=m
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=m
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_INOTIFY=y
CONFIG_VFAT_FS=m
CONFIG_PROC_KCORE=y
CONFIG_TMPFS=y
CONFIG_JFFS2_FS=y
CONFIG_UBIFS_FS=m
CONFIG_UBIFS_FS_XATTR=y
+CONFIG_LOGFS=m
CONFIG_CRAMFS=y
+CONFIG_SQUASHFS=m
+CONFIG_SQUASHFS_XATTR=y
+CONFIG_SQUASHFS_LZO=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_ROOT_NFS=y
@@ -116,11 +120,8 @@ CONFIG_DEBUG_KERNEL=y
CONFIG_DETECT_HUNG_TASK=y
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_PCBC=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_HW is not set
CONFIG_VIRTUALIZATION=y
diff --git a/arch/powerpc/configs/ppc64e_defconfig b/arch/powerpc/configs/ppc64e_defconfig
index 04ae0740b6d0..7bd1763877ba 100644
--- a/arch/powerpc/configs/ppc64e_defconfig
+++ b/arch/powerpc/configs/ppc64e_defconfig
@@ -18,6 +18,7 @@ CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODVERSIONS=y
CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_P5020_DS=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
@@ -256,7 +257,6 @@ CONFIG_HID_ZEROPLUS=y
CONFIG_USB=y
CONFIG_USB_DEVICEFS=y
CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_TT_NEWSCHED=y
# CONFIG_USB_EHCI_HCD_PPC_OF is not set
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_STORAGE=m
@@ -290,7 +290,6 @@ CONFIG_JFS_POSIX_ACL=y
CONFIG_JFS_SECURITY=y
CONFIG_XFS_FS=m
CONFIG_XFS_POSIX_ACL=y
-CONFIG_INOTIFY=y
CONFIG_AUTOFS4_FS=m
CONFIG_ISO9660_FS=y
CONFIG_UDF_FS=m
@@ -384,7 +383,6 @@ CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_AES=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_KHAZAD=m
diff --git a/arch/powerpc/include/asm/checksum.h b/arch/powerpc/include/asm/checksum.h
index 7cdf358337cf..ce0c28495f9a 100644
--- a/arch/powerpc/include/asm/checksum.h
+++ b/arch/powerpc/include/asm/checksum.h
@@ -52,12 +52,22 @@ extern __wsum csum_partial(const void *buff, int len, __wsum sum);
extern __wsum csum_partial_copy_generic(const void *src, void *dst,
int len, __wsum sum,
int *src_err, int *dst_err);
+
+#ifdef __powerpc64__
+#define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER
+extern __wsum csum_and_copy_from_user(const void __user *src, void *dst,
+ int len, __wsum sum, int *err_ptr);
+#define HAVE_CSUM_COPY_USER
+extern __wsum csum_and_copy_to_user(const void *src, void __user *dst,
+ int len, __wsum sum, int *err_ptr);
+#else
/*
* the same as csum_partial, but copies from src to dst while it
* checksums.
*/
#define csum_partial_copy_from_user(src, dst, len, sum, errp) \
csum_partial_copy_generic((__force const void *)(src), (dst), (len), (sum), (errp), NULL)
+#endif
#define csum_partial_copy_nocheck(src, dst, len, sum) \
csum_partial_copy_generic((src), (dst), (len), (sum), NULL, NULL)
diff --git a/arch/powerpc/include/asm/compat.h b/arch/powerpc/include/asm/compat.h
index a11d4eac4f97..2296112e247b 100644
--- a/arch/powerpc/include/asm/compat.h
+++ b/arch/powerpc/include/asm/compat.h
@@ -143,7 +143,7 @@ static inline void __user *arch_compat_alloc_user_space(long len)
* We cant access below the stack pointer in the 32bit ABI and
* can access 288 bytes in the 64bit ABI
*/
- if (!(test_thread_flag(TIF_32BIT)))
+ if (!is_32bit_task())
usp -= 288;
return (void __user *) (usp - len);
@@ -213,7 +213,7 @@ struct compat_shmid64_ds {
static inline int is_compat_task(void)
{
- return test_thread_flag(TIF_32BIT);
+ return is_32bit_task();
}
#endif /* __KERNEL__ */
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index 3a40a992e594..f3a1fdd9cf08 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -198,6 +198,7 @@ extern const char *powerpc_base_platform;
#define CPU_FTR_CP_USE_DCBTZ LONG_ASM_CONST(0x0040000000000000)
#define CPU_FTR_UNALIGNED_LD_STD LONG_ASM_CONST(0x0080000000000000)
#define CPU_FTR_ASYM_SMT LONG_ASM_CONST(0x0100000000000000)
+#define CPU_FTR_STCX_CHECKS_ADDRESS LONG_ASM_CONST(0x0200000000000000)
#ifndef __ASSEMBLY__
@@ -392,28 +393,31 @@ extern const char *powerpc_base_platform;
CPU_FTR_MMCRA | CPU_FTR_CTRL)
#define CPU_FTRS_POWER4 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
- CPU_FTR_MMCRA | CPU_FTR_CP_USE_DCBTZ)
+ CPU_FTR_MMCRA | CPU_FTR_CP_USE_DCBTZ | \
+ CPU_FTR_STCX_CHECKS_ADDRESS)
#define CPU_FTRS_PPC970 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | CPU_FTR_MMCRA | \
- CPU_FTR_CP_USE_DCBTZ)
+ CPU_FTR_CP_USE_DCBTZ | CPU_FTR_STCX_CHECKS_ADDRESS)
#define CPU_FTRS_POWER5 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_MMCRA | CPU_FTR_SMT | \
CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
- CPU_FTR_PURR)
+ CPU_FTR_PURR | CPU_FTR_STCX_CHECKS_ADDRESS)
#define CPU_FTRS_POWER6 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_MMCRA | CPU_FTR_SMT | \
CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
- CPU_FTR_DSCR | CPU_FTR_UNALIGNED_LD_STD)
+ CPU_FTR_DSCR | CPU_FTR_UNALIGNED_LD_STD | \
+ CPU_FTR_STCX_CHECKS_ADDRESS)
#define CPU_FTRS_POWER7 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_MMCRA | CPU_FTR_SMT | \
CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
- CPU_FTR_DSCR | CPU_FTR_SAO | CPU_FTR_ASYM_SMT)
+ CPU_FTR_DSCR | CPU_FTR_SAO | CPU_FTR_ASYM_SMT | \
+ CPU_FTR_STCX_CHECKS_ADDRESS)
#define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h
index 8c9c6ad2004e..6d2416a85709 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -127,19 +127,7 @@ static inline int dma_supported(struct device *dev, u64 mask)
return dma_ops->dma_supported(dev, mask);
}
-static inline int dma_set_mask(struct device *dev, u64 dma_mask)
-{
- struct dma_map_ops *dma_ops = get_dma_ops(dev);
-
- if (unlikely(dma_ops == NULL))
- return -EIO;
- if (dma_ops->set_dma_mask != NULL)
- return dma_ops->set_dma_mask(dev, dma_mask);
- if (!dev->dma_mask || !dma_supported(dev, dma_mask))
- return -EIO;
- *dev->dma_mask = dma_mask;
- return 0;
-}
+extern int dma_set_mask(struct device *dev, u64 dma_mask);
static inline void *dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag)
diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
index c376eda15313..2b917c69ed15 100644
--- a/arch/powerpc/include/asm/elf.h
+++ b/arch/powerpc/include/asm/elf.h
@@ -250,7 +250,7 @@ do { \
* the 64bit ABI has never had these issues dont enable the workaround
* even if we have an executable stack.
*/
-# define elf_read_implies_exec(ex, exec_stk) (test_thread_flag(TIF_32BIT) ? \
+# define elf_read_implies_exec(ex, exec_stk) (is_32bit_task() ? \
(exec_stk == EXSTACK_DEFAULT) : 0)
#else
# define SET_PERSONALITY(ex) \
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index 57c400071995..7778d6f0c878 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -137,7 +137,8 @@
li r10,0; \
ld r11,exception_marker@toc(r2); \
std r10,RESULT(r1); /* clear regs->result */ \
- std r11,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame */
+ std r11,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame */ \
+ ACCOUNT_STOLEN_TIME
/*
* Exception vectors.
diff --git a/arch/powerpc/include/asm/fsl_85xx_cache_sram.h b/arch/powerpc/include/asm/fsl_85xx_cache_sram.h
new file mode 100644
index 000000000000..2af2bdc37b2e
--- /dev/null
+++ b/arch/powerpc/include/asm/fsl_85xx_cache_sram.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2009 Freescale Semiconductor, Inc.
+ *
+ * Cache SRAM handling for QorIQ platform
+ *
+ * Author: Vivek Mahajan <vivek.mahajan@freescale.com>
+
+ * This file is derived from the original work done
+ * by Sylvain Munaut for the Bestcomm SRAM allocator.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ASM_POWERPC_FSL_85XX_CACHE_SRAM_H__
+#define __ASM_POWERPC_FSL_85XX_CACHE_SRAM_H__
+
+#include <asm/rheap.h>
+#include <linux/spinlock.h>
+
+/*
+ * Cache-SRAM
+ */
+
+struct mpc85xx_cache_sram {
+ phys_addr_t base_phys;
+ void *base_virt;
+ unsigned int size;
+ rh_info_t *rh;
+ spinlock_t lock;
+};
+
+extern void mpc85xx_cache_sram_free(void *ptr);
+extern void *mpc85xx_cache_sram_alloc(unsigned int size,
+ phys_addr_t *phys, unsigned int align);
+
+#endif /* __AMS_POWERPC_FSL_85XX_CACHE_SRAM_H__ */
diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h
index bd100fcf40d0..ff08b70b36d4 100644
--- a/arch/powerpc/include/asm/hw_irq.h
+++ b/arch/powerpc/include/asm/hw_irq.h
@@ -16,42 +16,57 @@ extern void timer_interrupt(struct pt_regs *);
#ifdef CONFIG_PPC64
#include <asm/paca.h>
-static inline unsigned long local_get_flags(void)
+static inline unsigned long arch_local_save_flags(void)
{
unsigned long flags;
- __asm__ __volatile__("lbz %0,%1(13)"
- : "=r" (flags)
- : "i" (offsetof(struct paca_struct, soft_enabled)));
+ asm volatile(
+ "lbz %0,%1(13)"
+ : "=r" (flags)
+ : "i" (offsetof(struct paca_struct, soft_enabled)));
return flags;
}
-static inline unsigned long raw_local_irq_disable(void)
+static inline unsigned long arch_local_irq_disable(void)
{
unsigned long flags, zero;
- __asm__ __volatile__("li %1,0; lbz %0,%2(13); stb %1,%2(13)"
- : "=r" (flags), "=&r" (zero)
- : "i" (offsetof(struct paca_struct, soft_enabled))
- : "memory");
+ asm volatile(
+ "li %1,0; lbz %0,%2(13); stb %1,%2(13)"
+ : "=r" (flags), "=&r" (zero)
+ : "i" (offsetof(struct paca_struct, soft_enabled))
+ : "memory");
return flags;
}
-extern void raw_local_irq_restore(unsigned long);
+extern void arch_local_irq_restore(unsigned long);
extern void iseries_handle_interrupts(void);
-#define raw_local_irq_enable() raw_local_irq_restore(1)
-#define raw_local_save_flags(flags) ((flags) = local_get_flags())
-#define raw_local_irq_save(flags) ((flags) = raw_local_irq_disable())
+static inline void arch_local_irq_enable(void)
+{
+ arch_local_irq_restore(1);
+}
+
+static inline unsigned long arch_local_irq_save(void)
+{
+ return arch_local_irq_disable();
+}
+
+static inline bool arch_irqs_disabled_flags(unsigned long flags)
+{
+ return flags == 0;
+}
-#define raw_irqs_disabled() (local_get_flags() == 0)
-#define raw_irqs_disabled_flags(flags) ((flags) == 0)
+static inline bool arch_irqs_disabled(void)
+{
+ return arch_irqs_disabled_flags(arch_local_save_flags());
+}
#ifdef CONFIG_PPC_BOOK3E
-#define __hard_irq_enable() __asm__ __volatile__("wrteei 1": : :"memory");
-#define __hard_irq_disable() __asm__ __volatile__("wrteei 0": : :"memory");
+#define __hard_irq_enable() asm volatile("wrteei 1" : : : "memory");
+#define __hard_irq_disable() asm volatile("wrteei 0" : : : "memory");
#else
#define __hard_irq_enable() __mtmsrd(mfmsr() | MSR_EE, 1)
#define __hard_irq_disable() __mtmsrd(mfmsr() & ~MSR_EE, 1)
@@ -64,64 +79,66 @@ extern void iseries_handle_interrupts(void);
get_paca()->hard_enabled = 0; \
} while(0)
-#else
+#else /* CONFIG_PPC64 */
-#if defined(CONFIG_BOOKE)
#define SET_MSR_EE(x) mtmsr(x)
-#define raw_local_irq_restore(flags) __asm__ __volatile__("wrtee %0" : : "r" (flags) : "memory")
+
+static inline unsigned long arch_local_save_flags(void)
+{
+ return mfmsr();
+}
+
+static inline void arch_local_irq_restore(unsigned long flags)
+{
+#if defined(CONFIG_BOOKE)
+ asm volatile("wrtee %0" : : "r" (flags) : "memory");
#else
-#define SET_MSR_EE(x) mtmsr(x)
-#define raw_local_irq_restore(flags) mtmsr(flags)
+ mtmsr(flags);
#endif
+}
-static inline void raw_local_irq_disable(void)
+static inline unsigned long arch_local_irq_save(void)
{
+ unsigned long flags = arch_local_save_flags();
#ifdef CONFIG_BOOKE
- __asm__ __volatile__("wrteei 0": : :"memory");
+ asm volatile("wrteei 0" : : : "memory");
#else
- unsigned long msr;
-
- msr = mfmsr();
- SET_MSR_EE(msr & ~MSR_EE);
+ SET_MSR_EE(flags & ~MSR_EE);
#endif
+ return flags;
}
-static inline void raw_local_irq_enable(void)
+static inline void arch_local_irq_disable(void)
{
#ifdef CONFIG_BOOKE
- __asm__ __volatile__("wrteei 1": : :"memory");
+ asm volatile("wrteei 0" : : : "memory");
#else
- unsigned long msr;
-
- msr = mfmsr();
- SET_MSR_EE(msr | MSR_EE);
+ arch_local_irq_save();
#endif
}
-static inline void raw_local_irq_save_ptr(unsigned long *flags)
+static inline void arch_local_irq_enable(void)
{
- unsigned long msr;
- msr = mfmsr();
- *flags = msr;
#ifdef CONFIG_BOOKE
- __asm__ __volatile__("wrteei 0": : :"memory");
+ asm volatile("wrteei 1" : : : "memory");
#else
- SET_MSR_EE(msr & ~MSR_EE);
+ unsigned long msr = mfmsr();
+ SET_MSR_EE(msr | MSR_EE);
#endif
}
-#define raw_local_save_flags(flags) ((flags) = mfmsr())
-#define raw_local_irq_save(flags) raw_local_irq_save_ptr(&flags)
-#define raw_irqs_disabled() ((mfmsr() & MSR_EE) == 0)
-#define raw_irqs_disabled_flags(flags) (((flags) & MSR_EE) == 0)
-
-#define hard_irq_disable() raw_local_irq_disable()
-
-static inline int irqs_disabled_flags(unsigned long flags)
+static inline bool arch_irqs_disabled_flags(unsigned long flags)
{
return (flags & MSR_EE) == 0;
}
+static inline bool arch_irqs_disabled(void)
+{
+ return arch_irqs_disabled_flags(arch_local_save_flags());
+}
+
+#define hard_irq_disable() arch_local_irq_disable()
+
#endif /* CONFIG_PPC64 */
/*
diff --git a/arch/powerpc/include/asm/hydra.h b/arch/powerpc/include/asm/hydra.h
index 1ad4eed07fbe..5b0c98bd46ab 100644
--- a/arch/powerpc/include/asm/hydra.h
+++ b/arch/powerpc/include/asm/hydra.h
@@ -10,7 +10,7 @@
*
* © Copyright 1995 Apple Computer, Inc. All rights reserved.
*
- * It's available online from http://chrp.apple.com/MacTech.pdf.
+ * It's available online from http://www.cpu.lu/~mlan/ftp/MacTech.pdf
* You can obtain paper copies of this book from computer bookstores or by
* writing Morgan Kaufmann Publishers, Inc., 340 Pine Street, Sixth Floor, San
* Francisco, CA 94104. Reference ISBN 1-55860-393-X.
diff --git a/arch/powerpc/include/asm/irqflags.h b/arch/powerpc/include/asm/irqflags.h
index 5f68ecfdf516..b85d8ddbb666 100644
--- a/arch/powerpc/include/asm/irqflags.h
+++ b/arch/powerpc/include/asm/irqflags.h
@@ -6,7 +6,7 @@
#ifndef __ASSEMBLY__
/*
- * Get definitions for raw_local_save_flags(x), etc.
+ * Get definitions for arch_local_save_flags(x), etc.
*/
#include <asm/hw_irq.h>
diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h
index 076327f2eff7..f54408d995b5 100644
--- a/arch/powerpc/include/asm/kexec.h
+++ b/arch/powerpc/include/asm/kexec.h
@@ -91,6 +91,7 @@ extern void machine_kexec_simple(struct kimage *image);
extern void crash_kexec_secondary(struct pt_regs *regs);
extern int overlaps_crashkernel(unsigned long start, unsigned long size);
extern void reserve_crashkernel(void);
+extern void machine_kexec_mask_interrupts(void);
#else /* !CONFIG_KEXEC */
static inline int kexec_sr_activated(int cpu) { return 0; }
diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h
index 6c5547d82bbe..18ea6963ad77 100644
--- a/arch/powerpc/include/asm/kvm.h
+++ b/arch/powerpc/include/asm/kvm.h
@@ -86,5 +86,6 @@ struct kvm_guest_debug_arch {
#define KVM_INTERRUPT_SET -1U
#define KVM_INTERRUPT_UNSET -2U
+#define KVM_INTERRUPT_SET_LEVEL -3U
#endif /* __LINUX_KVM_POWERPC_H */
diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h
index c5ea4cda34b3..5b7504674397 100644
--- a/arch/powerpc/include/asm/kvm_asm.h
+++ b/arch/powerpc/include/asm/kvm_asm.h
@@ -58,6 +58,7 @@
#define BOOK3S_INTERRUPT_INST_STORAGE 0x400
#define BOOK3S_INTERRUPT_INST_SEGMENT 0x480
#define BOOK3S_INTERRUPT_EXTERNAL 0x500
+#define BOOK3S_INTERRUPT_EXTERNAL_LEVEL 0x501
#define BOOK3S_INTERRUPT_ALIGNMENT 0x600
#define BOOK3S_INTERRUPT_PROGRAM 0x700
#define BOOK3S_INTERRUPT_FP_UNAVAIL 0x800
@@ -84,7 +85,8 @@
#define BOOK3S_IRQPRIO_EXTERNAL 13
#define BOOK3S_IRQPRIO_DECREMENTER 14
#define BOOK3S_IRQPRIO_PERFORMANCE_MONITOR 15
-#define BOOK3S_IRQPRIO_MAX 16
+#define BOOK3S_IRQPRIO_EXTERNAL_LEVEL 16
+#define BOOK3S_IRQPRIO_MAX 17
#define BOOK3S_HFLAG_DCBZ32 0x1
#define BOOK3S_HFLAG_SLB 0x2
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h
index 8274a2d43925..d62e703f1214 100644
--- a/arch/powerpc/include/asm/kvm_book3s.h
+++ b/arch/powerpc/include/asm/kvm_book3s.h
@@ -38,15 +38,6 @@ struct kvmppc_slb {
bool class : 1;
};
-struct kvmppc_sr {
- u32 raw;
- u32 vsid;
- bool Ks : 1;
- bool Kp : 1;
- bool nx : 1;
- bool valid : 1;
-};
-
struct kvmppc_bat {
u64 raw;
u32 bepi;
@@ -69,6 +60,13 @@ struct kvmppc_sid_map {
#define SID_MAP_NUM (1 << SID_MAP_BITS)
#define SID_MAP_MASK (SID_MAP_NUM - 1)
+#ifdef CONFIG_PPC_BOOK3S_64
+#define SID_CONTEXTS 1
+#else
+#define SID_CONTEXTS 128
+#define VSID_POOL_SIZE (SID_CONTEXTS * 16)
+#endif
+
struct kvmppc_vcpu_book3s {
struct kvm_vcpu vcpu;
struct kvmppc_book3s_shadow_vcpu *shadow_vcpu;
@@ -79,20 +77,22 @@ struct kvmppc_vcpu_book3s {
u64 vsid;
} slb_shadow[64];
u8 slb_shadow_max;
- struct kvmppc_sr sr[16];
struct kvmppc_bat ibat[8];
struct kvmppc_bat dbat[8];
u64 hid[6];
u64 gqr[8];
int slb_nr;
- u32 dsisr;
u64 sdr1;
u64 hior;
u64 msr_mask;
- u64 vsid_first;
u64 vsid_next;
+#ifdef CONFIG_PPC_BOOK3S_32
+ u32 vsid_pool[VSID_POOL_SIZE];
+#else
+ u64 vsid_first;
u64 vsid_max;
- int context_id;
+#endif
+ int context_id[SID_CONTEXTS];
ulong prog_flags; /* flags to inject when giving a 700 trap */
};
@@ -131,9 +131,10 @@ extern void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat,
bool upper, u32 val);
extern void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr);
extern int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu);
+extern pfn_t kvmppc_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn);
-extern u32 kvmppc_trampoline_lowmem;
-extern u32 kvmppc_trampoline_enter;
+extern ulong kvmppc_trampoline_lowmem;
+extern ulong kvmppc_trampoline_enter;
extern void kvmppc_rmcall(ulong srr0, ulong srr1);
extern void kvmppc_load_up_fpu(void);
extern void kvmppc_load_up_altivec(void);
diff --git a/arch/powerpc/include/asm/kvm_fpu.h b/arch/powerpc/include/asm/kvm_fpu.h
index c3d4f0518a67..92daae132492 100644
--- a/arch/powerpc/include/asm/kvm_fpu.h
+++ b/arch/powerpc/include/asm/kvm_fpu.h
@@ -82,7 +82,7 @@ FPD_THREE_IN(fmadd)
FPD_THREE_IN(fnmsub)
FPD_THREE_IN(fnmadd)
-extern void kvm_cvt_fd(u32 *from, u64 *to, u64 *fpscr);
-extern void kvm_cvt_df(u64 *from, u32 *to, u64 *fpscr);
+extern void kvm_cvt_fd(u32 *from, u64 *to);
+extern void kvm_cvt_df(u64 *from, u32 *to);
#endif
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index b0b23c007d6e..bba3b9b72a39 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -25,6 +25,7 @@
#include <linux/interrupt.h>
#include <linux/types.h>
#include <linux/kvm_types.h>
+#include <linux/kvm_para.h>
#include <asm/kvm_asm.h>
#define KVM_MAX_VCPUS 1
@@ -41,12 +42,17 @@
#define HPTEG_CACHE_NUM (1 << 15)
#define HPTEG_HASH_BITS_PTE 13
+#define HPTEG_HASH_BITS_PTE_LONG 12
#define HPTEG_HASH_BITS_VPTE 13
#define HPTEG_HASH_BITS_VPTE_LONG 5
#define HPTEG_HASH_NUM_PTE (1 << HPTEG_HASH_BITS_PTE)
+#define HPTEG_HASH_NUM_PTE_LONG (1 << HPTEG_HASH_BITS_PTE_LONG)
#define HPTEG_HASH_NUM_VPTE (1 << HPTEG_HASH_BITS_VPTE)
#define HPTEG_HASH_NUM_VPTE_LONG (1 << HPTEG_HASH_BITS_VPTE_LONG)
+/* Physical Address Mask - allowed range of real mode RAM access */
+#define KVM_PAM 0x0fffffffffffffffULL
+
struct kvm;
struct kvm_run;
struct kvm_vcpu;
@@ -159,8 +165,10 @@ struct kvmppc_mmu {
struct hpte_cache {
struct hlist_node list_pte;
+ struct hlist_node list_pte_long;
struct hlist_node list_vpte;
struct hlist_node list_vpte_long;
+ struct rcu_head rcu_head;
u64 host_va;
u64 pfn;
ulong slot;
@@ -210,28 +218,20 @@ struct kvm_vcpu_arch {
u32 cr;
#endif
- ulong msr;
#ifdef CONFIG_PPC_BOOK3S
ulong shadow_msr;
ulong hflags;
ulong guest_owned_ext;
#endif
u32 mmucr;
- ulong sprg0;
- ulong sprg1;
- ulong sprg2;
- ulong sprg3;
ulong sprg4;
ulong sprg5;
ulong sprg6;
ulong sprg7;
- ulong srr0;
- ulong srr1;
ulong csrr0;
ulong csrr1;
ulong dsrr0;
ulong dsrr1;
- ulong dear;
ulong esr;
u32 dec;
u32 decar;
@@ -290,12 +290,17 @@ struct kvm_vcpu_arch {
struct tasklet_struct tasklet;
u64 dec_jiffies;
unsigned long pending_exceptions;
+ struct kvm_vcpu_arch_shared *shared;
+ unsigned long magic_page_pa; /* phys addr to map the magic page to */
+ unsigned long magic_page_ea; /* effect. addr to map the magic page to */
#ifdef CONFIG_PPC_BOOK3S
struct hlist_head hpte_hash_pte[HPTEG_HASH_NUM_PTE];
+ struct hlist_head hpte_hash_pte_long[HPTEG_HASH_NUM_PTE_LONG];
struct hlist_head hpte_hash_vpte[HPTEG_HASH_NUM_VPTE];
struct hlist_head hpte_hash_vpte_long[HPTEG_HASH_NUM_VPTE_LONG];
int hpte_cache_count;
+ spinlock_t mmu_lock;
#endif
};
diff --git a/arch/powerpc/include/asm/kvm_para.h b/arch/powerpc/include/asm/kvm_para.h
index 2d48f6a63d0b..50533f9adf40 100644
--- a/arch/powerpc/include/asm/kvm_para.h
+++ b/arch/powerpc/include/asm/kvm_para.h
@@ -20,16 +20,153 @@
#ifndef __POWERPC_KVM_PARA_H__
#define __POWERPC_KVM_PARA_H__
+#include <linux/types.h>
+
+struct kvm_vcpu_arch_shared {
+ __u64 scratch1;
+ __u64 scratch2;
+ __u64 scratch3;
+ __u64 critical; /* Guest may not get interrupts if == r1 */
+ __u64 sprg0;
+ __u64 sprg1;
+ __u64 sprg2;
+ __u64 sprg3;
+ __u64 srr0;
+ __u64 srr1;
+ __u64 dar;
+ __u64 msr;
+ __u32 dsisr;
+ __u32 int_pending; /* Tells the guest if we have an interrupt */
+ __u32 sr[16];
+};
+
+#define KVM_SC_MAGIC_R0 0x4b564d21 /* "KVM!" */
+#define HC_VENDOR_KVM (42 << 16)
+#define HC_EV_SUCCESS 0
+#define HC_EV_UNIMPLEMENTED 12
+
+#define KVM_FEATURE_MAGIC_PAGE 1
+
+#define KVM_MAGIC_FEAT_SR (1 << 0)
+
#ifdef __KERNEL__
+#ifdef CONFIG_KVM_GUEST
+
+#include <linux/of.h>
+
+static inline int kvm_para_available(void)
+{
+ struct device_node *hyper_node;
+
+ hyper_node = of_find_node_by_path("/hypervisor");
+ if (!hyper_node)
+ return 0;
+
+ if (!of_device_is_compatible(hyper_node, "linux,kvm"))
+ return 0;
+
+ return 1;
+}
+
+extern unsigned long kvm_hypercall(unsigned long *in,
+ unsigned long *out,
+ unsigned long nr);
+
+#else
+
static inline int kvm_para_available(void)
{
return 0;
}
+static unsigned long kvm_hypercall(unsigned long *in,
+ unsigned long *out,
+ unsigned long nr)
+{
+ return HC_EV_UNIMPLEMENTED;
+}
+
+#endif
+
+static inline long kvm_hypercall0_1(unsigned int nr, unsigned long *r2)
+{
+ unsigned long in[8];
+ unsigned long out[8];
+ unsigned long r;
+
+ r = kvm_hypercall(in, out, nr | HC_VENDOR_KVM);
+ *r2 = out[0];
+
+ return r;
+}
+
+static inline long kvm_hypercall0(unsigned int nr)
+{
+ unsigned long in[8];
+ unsigned long out[8];
+
+ return kvm_hypercall(in, out, nr | HC_VENDOR_KVM);
+}
+
+static inline long kvm_hypercall1(unsigned int nr, unsigned long p1)
+{
+ unsigned long in[8];
+ unsigned long out[8];
+
+ in[0] = p1;
+ return kvm_hypercall(in, out, nr | HC_VENDOR_KVM);
+}
+
+static inline long kvm_hypercall2(unsigned int nr, unsigned long p1,
+ unsigned long p2)
+{
+ unsigned long in[8];
+ unsigned long out[8];
+
+ in[0] = p1;
+ in[1] = p2;
+ return kvm_hypercall(in, out, nr | HC_VENDOR_KVM);
+}
+
+static inline long kvm_hypercall3(unsigned int nr, unsigned long p1,
+ unsigned long p2, unsigned long p3)
+{
+ unsigned long in[8];
+ unsigned long out[8];
+
+ in[0] = p1;
+ in[1] = p2;
+ in[2] = p3;
+ return kvm_hypercall(in, out, nr | HC_VENDOR_KVM);
+}
+
+static inline long kvm_hypercall4(unsigned int nr, unsigned long p1,
+ unsigned long p2, unsigned long p3,
+ unsigned long p4)
+{
+ unsigned long in[8];
+ unsigned long out[8];
+
+ in[0] = p1;
+ in[1] = p2;
+ in[2] = p3;
+ in[3] = p4;
+ return kvm_hypercall(in, out, nr | HC_VENDOR_KVM);
+}
+
+
static inline unsigned int kvm_arch_para_features(void)
{
- return 0;
+ unsigned long r;
+
+ if (!kvm_para_available())
+ return 0;
+
+ if(kvm_hypercall0_1(KVM_HC_FEATURES, &r))
+ return 0;
+
+ return r;
}
#endif /* __KERNEL__ */
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index 18d139ec2d22..ecb3bc74c344 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -107,6 +107,7 @@ extern int kvmppc_booke_init(void);
extern void kvmppc_booke_exit(void);
extern void kvmppc_core_destroy_mmu(struct kvm_vcpu *vcpu);
+extern int kvmppc_kvm_pv(struct kvm_vcpu *vcpu);
/*
* Cuts out inst bits with ordering according to spec.
diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h
index 14b592dfb4e8..7f5e0fefebb0 100644
--- a/arch/powerpc/include/asm/lppaca.h
+++ b/arch/powerpc/include/asm/lppaca.h
@@ -153,6 +153,8 @@ struct lppaca {
extern struct lppaca lppaca[];
+#define lppaca_of(cpu) (*paca[cpu].lppaca_ptr)
+
/*
* SLB shadow buffer structure as defined in the PAPR. The save_area
* contains adjacent ESID and VSID pairs for each shadowed SLB. The
@@ -170,6 +172,33 @@ struct slb_shadow {
extern struct slb_shadow slb_shadow[];
+/*
+ * Layout of entries in the hypervisor's dispatch trace log buffer.
+ */
+struct dtl_entry {
+ u8 dispatch_reason;
+ u8 preempt_reason;
+ u16 processor_id;
+ u32 enqueue_to_dispatch_time;
+ u32 ready_to_enqueue_time;
+ u32 waiting_to_ready_time;
+ u64 timebase;
+ u64 fault_addr;
+ u64 srr0;
+ u64 srr1;
+};
+
+#define DISPATCH_LOG_BYTES 4096 /* bytes per cpu */
+#define N_DISPATCH_LOG (DISPATCH_LOG_BYTES / sizeof(struct dtl_entry))
+
+/*
+ * When CONFIG_VIRT_CPU_ACCOUNTING = y, the cpu accounting code controls
+ * reading from the dispatch trace log. If other code wants to consume
+ * DTL entries, it can set this pointer to a function that will get
+ * called once for each DTL entry that gets processed.
+ */
+extern void (*dtl_consumer)(struct dtl_entry *entry, u64 index);
+
#endif /* CONFIG_PPC_BOOK3S */
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_LPPACA_H */
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index adc8e6cdf339..d045b0145537 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -102,6 +102,9 @@ struct machdep_calls {
void (*pci_dma_dev_setup)(struct pci_dev *dev);
void (*pci_dma_bus_setup)(struct pci_bus *bus);
+ /* Platform set_dma_mask override */
+ int (*dma_set_mask)(struct device *dev, u64 dma_mask);
+
int (*probe)(void);
void (*setup_arch)(void); /* Optional, may be NULL */
void (*init_early)(void);
diff --git a/arch/powerpc/include/asm/memblock.h b/arch/powerpc/include/asm/memblock.h
index 3c29728b56b1..43efc345065e 100644
--- a/arch/powerpc/include/asm/memblock.h
+++ b/arch/powerpc/include/asm/memblock.h
@@ -5,11 +5,4 @@
#define MEMBLOCK_DBG(fmt...) udbg_printf(fmt)
-#ifdef CONFIG_PPC32
-extern phys_addr_t lowmem_end_addr;
-#define MEMBLOCK_REAL_LIMIT lowmem_end_addr
-#else
-#define MEMBLOCK_REAL_LIMIT 0
-#endif
-
#endif /* _ASM_POWERPC_MEMBLOCK_H */
diff --git a/arch/powerpc/include/asm/mmu-book3e.h b/arch/powerpc/include/asm/mmu-book3e.h
index 87a1d787c5b6..8eaed81ea642 100644
--- a/arch/powerpc/include/asm/mmu-book3e.h
+++ b/arch/powerpc/include/asm/mmu-book3e.h
@@ -114,6 +114,17 @@
#define MAS7_RPN 0xFFFFFFFF
+/* Bit definitions for MMUCFG */
+#define MMUCFG_MAVN 0x00000003 /* MMU Architecture Version Number */
+#define MMUCFG_MAVN_V1 0x00000000 /* v1.0 */
+#define MMUCFG_MAVN_V2 0x00000001 /* v2.0 */
+#define MMUCFG_NTLBS 0x0000000c /* Number of TLBs */
+#define MMUCFG_PIDSIZE 0x000007c0 /* PID Reg Size */
+#define MMUCFG_TWC 0x00008000 /* TLB Write Conditional (v2.0) */
+#define MMUCFG_LRAT 0x00010000 /* LRAT Supported (v2.0) */
+#define MMUCFG_RASIZE 0x00fe0000 /* Real Addr Size */
+#define MMUCFG_LPIDSIZE 0x0f000000 /* LPID Reg Size */
+
/* Bit definitions for MMUCSR0 */
#define MMUCSR0_TLB1FI 0x00000002 /* TLB1 Flash invalidate */
#define MMUCSR0_TLB0FI 0x00000004 /* TLB0 Flash invalidate */
@@ -133,6 +144,10 @@
#define TLBnCFG_GTWE 0x00010000 /* Guest can write */
#define TLBnCFG_IND 0x00020000 /* IND entries supported */
#define TLBnCFG_PT 0x00040000 /* Can load from page table */
+#define TLBnCFG_MINSIZE 0x00f00000 /* Minimum Page Size (v1.0) */
+#define TLBnCFG_MINSIZE_SHIFT 20
+#define TLBnCFG_MAXSIZE 0x000f0000 /* Maximum Page Size (v1.0) */
+#define TLBnCFG_MAXSIZE_SHIFT 16
#define TLBnCFG_ASSOC 0xff000000 /* Associativity */
/* TLBnPS encoding */
diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
index 7ebf42ed84a2..bb40a06d3b77 100644
--- a/arch/powerpc/include/asm/mmu.h
+++ b/arch/powerpc/include/asm/mmu.h
@@ -2,6 +2,8 @@
#define _ASM_POWERPC_MMU_H_
#ifdef __KERNEL__
+#include <linux/types.h>
+
#include <asm/asm-compat.h>
#include <asm/feature-fixups.h>
@@ -82,6 +84,16 @@ extern unsigned int __start___mmu_ftr_fixup, __stop___mmu_ftr_fixup;
extern void early_init_mmu(void);
extern void early_init_mmu_secondary(void);
+extern void setup_initial_memory_limit(phys_addr_t first_memblock_base,
+ phys_addr_t first_memblock_size);
+
+#ifdef CONFIG_PPC64
+/* This is our real memory area size on ppc64 server, on embedded, we
+ * make it match the size our of bolted TLB area
+ */
+extern u64 ppc64_rma_size;
+#endif /* CONFIG_PPC64 */
+
#endif /* !__ASSEMBLY__ */
/* The kernel use the constants below to index in the page sizes array.
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
index 1ff6662f7faf..ec57540cd7af 100644
--- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -85,6 +85,8 @@ struct paca_struct {
u8 kexec_state; /* set when kexec down has irqs off */
#ifdef CONFIG_PPC_STD_MMU_64
struct slb_shadow *slb_shadow_ptr;
+ struct dtl_entry *dispatch_log;
+ struct dtl_entry *dispatch_log_end;
/*
* Now, starting in cacheline 2, the exception save areas
@@ -129,13 +131,19 @@ struct paca_struct {
u8 soft_enabled; /* irq soft-enable flag */
u8 hard_enabled; /* set if irqs are enabled in MSR */
u8 io_sync; /* writel() needs spin_unlock sync */
- u8 perf_event_pending; /* PM interrupt while soft-disabled */
+ u8 irq_work_pending; /* IRQ_WORK interrupt while soft-disable */
/* Stuff for accurate time accounting */
u64 user_time; /* accumulated usermode TB ticks */
u64 system_time; /* accumulated system TB ticks */
- u64 startpurr; /* PURR/TB value snapshot */
+ u64 user_time_scaled; /* accumulated usermode SPURR ticks */
+ u64 starttime; /* TB value snapshot */
+ u64 starttime_user; /* TB value on exit to usermode */
u64 startspurr; /* SPURR value snapshot */
+ u64 utime_sspurr; /* ->user_time when ->startspurr set */
+ u64 stolen_time; /* TB ticks taken by hypervisor */
+ u64 dtl_ridx; /* read index in dispatch log */
+ struct dtl_entry *dtl_curr; /* pointer corresponding to dtl_ridx */
#ifdef CONFIG_KVM_BOOK3S_HANDLER
/* We use this to store guest state in */
diff --git a/arch/powerpc/include/asm/page_64.h b/arch/powerpc/include/asm/page_64.h
index 358ff14ea25e..932f88dcf6fa 100644
--- a/arch/powerpc/include/asm/page_64.h
+++ b/arch/powerpc/include/asm/page_64.h
@@ -163,7 +163,7 @@ do { \
#endif /* !CONFIG_HUGETLB_PAGE */
#define VM_DATA_DEFAULT_FLAGS \
- (test_thread_flag(TIF_32BIT) ? \
+ (is_32bit_task() ? \
VM_DATA_DEFAULT_FLAGS32 : VM_DATA_DEFAULT_FLAGS64)
/*
@@ -179,7 +179,7 @@ do { \
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
#define VM_STACK_DEFAULT_FLAGS \
- (test_thread_flag(TIF_32BIT) ? \
+ (is_32bit_task() ? \
VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
#include <asm-generic/getorder.h>
diff --git a/arch/powerpc/include/asm/ppc-pci.h b/arch/powerpc/include/asm/ppc-pci.h
index 42fdff0e4b32..43268f15004e 100644
--- a/arch/powerpc/include/asm/ppc-pci.h
+++ b/arch/powerpc/include/asm/ppc-pci.h
@@ -28,8 +28,8 @@ extern void find_and_init_phbs(void);
extern struct pci_dev *isa_bridge_pcidev; /* may be NULL if no ISA bus */
/** Bus Unit ID macros; get low and hi 32-bits of the 64-bit BUID */
-#define BUID_HI(buid) ((buid) >> 32)
-#define BUID_LO(buid) ((buid) & 0xffffffff)
+#define BUID_HI(buid) upper_32_bits(buid)
+#define BUID_LO(buid) lower_32_bits(buid)
/* PCI device_node operations */
struct device_node;
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
index 498fe09263d3..98210067c1cc 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -9,6 +9,7 @@
#include <asm/asm-compat.h>
#include <asm/processor.h>
#include <asm/ppc-opcode.h>
+#include <asm/firmware.h>
#ifndef __ASSEMBLY__
#error __FILE__ should only be used in assembler files
@@ -26,17 +27,13 @@
#ifndef CONFIG_VIRT_CPU_ACCOUNTING
#define ACCOUNT_CPU_USER_ENTRY(ra, rb)
#define ACCOUNT_CPU_USER_EXIT(ra, rb)
+#define ACCOUNT_STOLEN_TIME
#else
#define ACCOUNT_CPU_USER_ENTRY(ra, rb) \
beq 2f; /* if from kernel mode */ \
-BEGIN_FTR_SECTION; \
- mfspr ra,SPRN_PURR; /* get processor util. reg */ \
-END_FTR_SECTION_IFSET(CPU_FTR_PURR); \
-BEGIN_FTR_SECTION; \
- MFTB(ra); /* or get TB if no PURR */ \
-END_FTR_SECTION_IFCLR(CPU_FTR_PURR); \
- ld rb,PACA_STARTPURR(r13); \
- std ra,PACA_STARTPURR(r13); \
+ MFTB(ra); /* get timebase */ \
+ ld rb,PACA_STARTTIME_USER(r13); \
+ std ra,PACA_STARTTIME(r13); \
subf rb,rb,ra; /* subtract start value */ \
ld ra,PACA_USER_TIME(r13); \
add ra,ra,rb; /* add on to user time */ \
@@ -44,19 +41,34 @@ END_FTR_SECTION_IFCLR(CPU_FTR_PURR); \
2:
#define ACCOUNT_CPU_USER_EXIT(ra, rb) \
-BEGIN_FTR_SECTION; \
- mfspr ra,SPRN_PURR; /* get processor util. reg */ \
-END_FTR_SECTION_IFSET(CPU_FTR_PURR); \
-BEGIN_FTR_SECTION; \
- MFTB(ra); /* or get TB if no PURR */ \
-END_FTR_SECTION_IFCLR(CPU_FTR_PURR); \
- ld rb,PACA_STARTPURR(r13); \
- std ra,PACA_STARTPURR(r13); \
+ MFTB(ra); /* get timebase */ \
+ ld rb,PACA_STARTTIME(r13); \
+ std ra,PACA_STARTTIME_USER(r13); \
subf rb,rb,ra; /* subtract start value */ \
ld ra,PACA_SYSTEM_TIME(r13); \
- add ra,ra,rb; /* add on to user time */ \
- std ra,PACA_SYSTEM_TIME(r13);
-#endif
+ add ra,ra,rb; /* add on to system time */ \
+ std ra,PACA_SYSTEM_TIME(r13)
+
+#ifdef CONFIG_PPC_SPLPAR
+#define ACCOUNT_STOLEN_TIME \
+BEGIN_FW_FTR_SECTION; \
+ beq 33f; \
+ /* from user - see if there are any DTL entries to process */ \
+ ld r10,PACALPPACAPTR(r13); /* get ptr to VPA */ \
+ ld r11,PACA_DTL_RIDX(r13); /* get log read index */ \
+ ld r10,LPPACA_DTLIDX(r10); /* get log write index */ \
+ cmpd cr1,r11,r10; \
+ beq+ cr1,33f; \
+ bl .accumulate_stolen_time; \
+33: \
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR)
+
+#else /* CONFIG_PPC_SPLPAR */
+#define ACCOUNT_STOLEN_TIME
+
+#endif /* CONFIG_PPC_SPLPAR */
+
+#endif /* CONFIG_VIRT_CPU_ACCOUNTING */
/*
* Macros for storing registers into and loading registers from
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index 19c05b0f74be..4c14187ba02d 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -118,7 +118,7 @@ extern struct task_struct *last_task_used_spe;
#define TASK_UNMAPPED_BASE_USER32 (PAGE_ALIGN(TASK_SIZE_USER32 / 4))
#define TASK_UNMAPPED_BASE_USER64 (PAGE_ALIGN(TASK_SIZE_USER64 / 4))
-#define TASK_UNMAPPED_BASE ((test_thread_flag(TIF_32BIT)) ? \
+#define TASK_UNMAPPED_BASE ((is_32bit_task()) ? \
TASK_UNMAPPED_BASE_USER32 : TASK_UNMAPPED_BASE_USER64 )
#endif
@@ -128,7 +128,7 @@ extern struct task_struct *last_task_used_spe;
#define STACK_TOP_USER64 TASK_SIZE_USER64
#define STACK_TOP_USER32 TASK_SIZE_USER32
-#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
+#define STACK_TOP (is_32bit_task() ? \
STACK_TOP_USER32 : STACK_TOP_USER64)
#define STACK_TOP_MAX STACK_TOP_USER64
diff --git a/arch/powerpc/include/asm/pte-common.h b/arch/powerpc/include/asm/pte-common.h
index f2b370180a09..76bb195e4f24 100644
--- a/arch/powerpc/include/asm/pte-common.h
+++ b/arch/powerpc/include/asm/pte-common.h
@@ -171,6 +171,13 @@ extern unsigned long bad_call_to_PMD_PAGE_SIZE(void);
/* Make modules code happy. We don't set RO yet */
#define PAGE_KERNEL_EXEC PAGE_KERNEL_X
+/*
+ * Don't just check for any non zero bits in __PAGE_USER, since for book3e
+ * and PTE_64BIT, PAGE_KERNEL_X contains _PAGE_BAP_SR which is also in
+ * _PAGE_USER. Need to explictly match _PAGE_BAP_UR bit in that case too.
+ */
+#define pte_user(val) ((val & _PAGE_USER) == _PAGE_USER)
+
/* Advertise special mapping type for AGP */
#define PAGE_AGP (PAGE_KERNEL_NC)
#define HAVE_PAGE_AGP
diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index 3d35f8ae377e..9a1193e30f26 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -187,6 +187,7 @@ extern void rtas_progress(char *s, unsigned short hex);
extern void rtas_initialize(void);
extern int rtas_suspend_cpu(struct rtas_suspend_me_data *data);
extern int rtas_suspend_last_cpu(struct rtas_suspend_me_data *data);
+extern int rtas_ibm_suspend_me(struct rtas_args *);
struct rtc_time;
extern unsigned long rtas_get_boot_time(void);
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h
index 3d212669a130..aa0f1ebb4aaf 100644
--- a/arch/powerpc/include/asm/systbl.h
+++ b/arch/powerpc/include/asm/systbl.h
@@ -329,3 +329,22 @@ COMPAT_SYS(rt_tgsigqueueinfo)
SYSCALL(fanotify_init)
COMPAT_SYS(fanotify_mark)
SYSCALL_SPU(prlimit64)
+SYSCALL_SPU(socket)
+SYSCALL_SPU(bind)
+SYSCALL_SPU(connect)
+SYSCALL_SPU(listen)
+SYSCALL_SPU(accept)
+SYSCALL_SPU(getsockname)
+SYSCALL_SPU(getpeername)
+SYSCALL_SPU(socketpair)
+SYSCALL_SPU(send)
+SYSCALL_SPU(sendto)
+COMPAT_SYS_SPU(recv)
+COMPAT_SYS_SPU(recvfrom)
+SYSCALL_SPU(shutdown)
+COMPAT_SYS_SPU(setsockopt)
+COMPAT_SYS_SPU(getsockopt)
+COMPAT_SYS_SPU(sendmsg)
+COMPAT_SYS_SPU(recvmsg)
+COMPAT_SYS_SPU(recvmmsg)
+SYSCALL_SPU(accept4)
diff --git a/arch/powerpc/include/asm/system.h b/arch/powerpc/include/asm/system.h
index 6c294acac848..5e474ddd2273 100644
--- a/arch/powerpc/include/asm/system.h
+++ b/arch/powerpc/include/asm/system.h
@@ -154,8 +154,8 @@ extern void enable_kernel_spe(void);
extern void giveup_spe(struct task_struct *);
extern void load_up_spe(struct task_struct *);
extern int fix_alignment(struct pt_regs *);
-extern void cvt_fd(float *from, double *to, struct thread_struct *thread);
-extern void cvt_df(double *from, float *to, struct thread_struct *thread);
+extern void cvt_fd(float *from, double *to);
+extern void cvt_df(double *from, float *to);
#ifndef CONFIG_SMP
extern void discard_lazy_cpu_state(void);
@@ -542,10 +542,6 @@ extern void reloc_got2(unsigned long);
#define PTRRELOC(x) ((typeof(x)) add_reloc_offset((unsigned long)(x)))
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING
-extern void account_system_vtime(struct task_struct *);
-#endif
-
extern struct dentry *powerpc_debugfs_root;
#endif /* __KERNEL__ */
diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h
index dc779dfcf258..fe6f7c2c9c68 100644
--- a/arch/powerpc/include/asm/time.h
+++ b/arch/powerpc/include/asm/time.h
@@ -34,7 +34,6 @@ extern void to_tm(int tim, struct rtc_time * tm);
extern void GregorianDay(struct rtc_time *tm);
extern void generic_calibrate_decr(void);
-extern void snapshot_timebase(void);
extern void set_dec_cpu6(unsigned int val);
@@ -212,12 +211,8 @@ struct cpu_usage {
DECLARE_PER_CPU(struct cpu_usage, cpu_usage_array);
#if defined(CONFIG_VIRT_CPU_ACCOUNTING)
-extern void calculate_steal_time(void);
-extern void snapshot_timebases(void);
#define account_process_vtime(tsk) account_process_tick(tsk, 0)
#else
-#define calculate_steal_time() do { } while (0)
-#define snapshot_timebases() do { } while (0)
#define account_process_vtime(tsk) do { } while (0)
#endif
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
index 597e6f9d094a..6151937657f6 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -348,10 +348,29 @@
#define __NR_fanotify_init 323
#define __NR_fanotify_mark 324
#define __NR_prlimit64 325
+#define __NR_socket 326
+#define __NR_bind 327
+#define __NR_connect 328
+#define __NR_listen 329
+#define __NR_accept 330
+#define __NR_getsockname 331
+#define __NR_getpeername 332
+#define __NR_socketpair 333
+#define __NR_send 334
+#define __NR_sendto 335
+#define __NR_recv 336
+#define __NR_recvfrom 337
+#define __NR_shutdown 338
+#define __NR_setsockopt 339
+#define __NR_getsockopt 340
+#define __NR_sendmsg 341
+#define __NR_recvmsg 342
+#define __NR_recvmmsg 343
+#define __NR_accept4 344
#ifdef __KERNEL__
-#define __NR_syscalls 326
+#define __NR_syscalls 345
#define __NR__exit __NR_exit
#define NR_syscalls __NR_syscalls
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 1dda70129141..36c30f31ec93 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -55,7 +55,9 @@ obj-$(CONFIG_IBMVIO) += vio.o
obj-$(CONFIG_IBMEBUS) += ibmebus.o
obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
+ifeq ($(CONFIG_PPC32),y)
obj-$(CONFIG_E500) += idle_e500.o
+endif
obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o
obj-$(CONFIG_TAU) += tau_6xx.o
obj-$(CONFIG_HIBERNATION) += swsusp.o suspend.o
@@ -67,7 +69,7 @@ endif
obj64-$(CONFIG_HIBERNATION) += swsusp_asm64.o
obj-$(CONFIG_MODULES) += module.o module_$(CONFIG_WORD_SIZE).o
obj-$(CONFIG_44x) += cpu_setup_44x.o
-obj-$(CONFIG_FSL_BOOKE) += cpu_setup_fsl_booke.o dbell.o
+obj-$(CONFIG_PPC_FSL_BOOK3E) += cpu_setup_fsl_booke.o dbell.o
obj-$(CONFIG_PPC_BOOK3E_64) += dbell.o
extra-y := head_$(CONFIG_WORD_SIZE).o
@@ -127,6 +129,8 @@ ifneq ($(CONFIG_XMON)$(CONFIG_KEXEC),)
obj-y += ppc_save_regs.o
endif
+obj-$(CONFIG_KVM_GUEST) += kvm.o kvm_emul.o
+
# Disable GCOV in odd or sensitive code
GCOV_PROFILE_prom_init.o := n
GCOV_PROFILE_ftrace.o := n
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
index b876e989220b..8184ee97e484 100644
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -889,7 +889,7 @@ int fix_alignment(struct pt_regs *regs)
#ifdef CONFIG_PPC_FPU
preempt_disable();
enable_kernel_fp();
- cvt_df(&data.dd, (float *)&data.v[4], &current->thread);
+ cvt_df(&data.dd, (float *)&data.v[4]);
preempt_enable();
#else
return 0;
@@ -933,7 +933,7 @@ int fix_alignment(struct pt_regs *regs)
#ifdef CONFIG_PPC_FPU
preempt_disable();
enable_kernel_fp();
- cvt_fd((float *)&data.v[4], &data.dd, &current->thread);
+ cvt_fd((float *)&data.v[4], &data.dd);
preempt_enable();
#else
return 0;
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 1c0607ddccc0..bd0df2e6aa8f 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -48,11 +48,11 @@
#ifdef CONFIG_PPC_ISERIES
#include <asm/iseries/alpaca.h>
#endif
-#ifdef CONFIG_KVM
+#if defined(CONFIG_KVM) || defined(CONFIG_KVM_GUEST)
#include <linux/kvm_host.h>
-#ifndef CONFIG_BOOKE
-#include <asm/kvm_book3s.h>
#endif
+#if defined(CONFIG_KVM) && defined(CONFIG_PPC_BOOK3S)
+#include <asm/kvm_book3s.h>
#endif
#ifdef CONFIG_PPC32
@@ -61,7 +61,7 @@
#endif
#endif
-#if defined(CONFIG_FSL_BOOKE)
+#if defined(CONFIG_PPC_FSL_BOOK3E)
#include "../mm/mmu_decl.h"
#endif
@@ -181,17 +181,19 @@ int main(void)
offsetof(struct slb_shadow, save_area[SLB_NUM_BOLTED - 1].vsid));
DEFINE(SLBSHADOW_STACKESID,
offsetof(struct slb_shadow, save_area[SLB_NUM_BOLTED - 1].esid));
+ DEFINE(SLBSHADOW_SAVEAREA, offsetof(struct slb_shadow, save_area));
DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0));
DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1));
DEFINE(LPPACAANYINT, offsetof(struct lppaca, int_dword.any_int));
DEFINE(LPPACADECRINT, offsetof(struct lppaca, int_dword.fields.decr_int));
- DEFINE(SLBSHADOW_SAVEAREA, offsetof(struct slb_shadow, save_area));
+ DEFINE(LPPACA_DTLIDX, offsetof(struct lppaca, dtl_idx));
+ DEFINE(PACA_DTL_RIDX, offsetof(struct paca_struct, dtl_ridx));
#endif /* CONFIG_PPC_STD_MMU_64 */
DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp));
DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
DEFINE(PACAKEXECSTATE, offsetof(struct paca_struct, kexec_state));
- DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr));
- DEFINE(PACA_STARTSPURR, offsetof(struct paca_struct, startspurr));
+ DEFINE(PACA_STARTTIME, offsetof(struct paca_struct, starttime));
+ DEFINE(PACA_STARTTIME_USER, offsetof(struct paca_struct, starttime_user));
DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time));
DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save));
@@ -394,12 +396,13 @@ int main(void)
DEFINE(VCPU_HOST_STACK, offsetof(struct kvm_vcpu, arch.host_stack));
DEFINE(VCPU_HOST_PID, offsetof(struct kvm_vcpu, arch.host_pid));
DEFINE(VCPU_GPRS, offsetof(struct kvm_vcpu, arch.gpr));
- DEFINE(VCPU_MSR, offsetof(struct kvm_vcpu, arch.msr));
DEFINE(VCPU_SPRG4, offsetof(struct kvm_vcpu, arch.sprg4));
DEFINE(VCPU_SPRG5, offsetof(struct kvm_vcpu, arch.sprg5));
DEFINE(VCPU_SPRG6, offsetof(struct kvm_vcpu, arch.sprg6));
DEFINE(VCPU_SPRG7, offsetof(struct kvm_vcpu, arch.sprg7));
DEFINE(VCPU_SHADOW_PID, offsetof(struct kvm_vcpu, arch.shadow_pid));
+ DEFINE(VCPU_SHARED, offsetof(struct kvm_vcpu, arch.shared));
+ DEFINE(VCPU_SHARED_MSR, offsetof(struct kvm_vcpu_arch_shared, msr));
/* book3s */
#ifdef CONFIG_PPC_BOOK3S
@@ -464,11 +467,27 @@ int main(void)
DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr));
#endif /* CONFIG_PPC_BOOK3S */
#endif
+
+#ifdef CONFIG_KVM_GUEST
+ DEFINE(KVM_MAGIC_SCRATCH1, offsetof(struct kvm_vcpu_arch_shared,
+ scratch1));
+ DEFINE(KVM_MAGIC_SCRATCH2, offsetof(struct kvm_vcpu_arch_shared,
+ scratch2));
+ DEFINE(KVM_MAGIC_SCRATCH3, offsetof(struct kvm_vcpu_arch_shared,
+ scratch3));
+ DEFINE(KVM_MAGIC_INT, offsetof(struct kvm_vcpu_arch_shared,
+ int_pending));
+ DEFINE(KVM_MAGIC_MSR, offsetof(struct kvm_vcpu_arch_shared, msr));
+ DEFINE(KVM_MAGIC_CRITICAL, offsetof(struct kvm_vcpu_arch_shared,
+ critical));
+ DEFINE(KVM_MAGIC_SR, offsetof(struct kvm_vcpu_arch_shared, sr));
+#endif
+
#ifdef CONFIG_44x
DEFINE(PGD_T_LOG2, PGD_T_LOG2);
DEFINE(PTE_T_LOG2, PTE_T_LOG2);
#endif
-#ifdef CONFIG_FSL_BOOKE
+#ifdef CONFIG_PPC_FSL_BOOK3E
DEFINE(TLBCAM_SIZE, sizeof(struct tlbcam));
DEFINE(TLBCAM_MAS0, offsetof(struct tlbcam, MAS0));
DEFINE(TLBCAM_MAS1, offsetof(struct tlbcam, MAS1));
diff --git a/arch/powerpc/kernel/cpu_setup_44x.S b/arch/powerpc/kernel/cpu_setup_44x.S
index 7d606f89a839..e32b4a9a2c22 100644
--- a/arch/powerpc/kernel/cpu_setup_44x.S
+++ b/arch/powerpc/kernel/cpu_setup_44x.S
@@ -35,6 +35,7 @@ _GLOBAL(__setup_cpu_440grx)
_GLOBAL(__setup_cpu_460ex)
_GLOBAL(__setup_cpu_460gt)
_GLOBAL(__setup_cpu_460sx)
+_GLOBAL(__setup_cpu_apm821xx)
mflr r4
bl __init_fpu_44x
bl __fixup_440A_mcheck
diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
index 0adb50ad8031..894e64fa481e 100644
--- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S
+++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
@@ -51,6 +51,7 @@ _GLOBAL(__e500_dcache_setup)
isync
blr
+#ifdef CONFIG_PPC32
_GLOBAL(__setup_cpu_e200)
/* enable dedicated debug exception handling resources (Debug APU) */
mfspr r3,SPRN_HID0
@@ -72,3 +73,17 @@ _GLOBAL(__setup_cpu_e500mc)
bl __setup_e500mc_ivors
mtlr r4
blr
+#endif
+/* Right now, restore and setup are the same thing */
+_GLOBAL(__restore_cpu_e5500)
+_GLOBAL(__setup_cpu_e5500)
+ mflr r4
+ bl __e500_icache_setup
+ bl __e500_dcache_setup
+#ifdef CONFIG_PPC_BOOK3E_64
+ bl .__setup_base_ivors
+#else
+ bl __setup_e500mc_ivors
+#endif
+ mtlr r4
+ blr
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 1f9123f412ec..96a908f1cd87 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -48,6 +48,7 @@ extern void __setup_cpu_440x5(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_460ex(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_460gt(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_460sx(unsigned long offset, struct cpu_spec *spec);
+extern void __setup_cpu_apm821xx(unsigned long offset, struct cpu_spec *spec);
extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec);
@@ -66,6 +67,10 @@ extern void __restore_cpu_ppc970(void);
extern void __setup_cpu_power7(unsigned long offset, struct cpu_spec* spec);
extern void __restore_cpu_power7(void);
#endif /* CONFIG_PPC64 */
+#if defined(CONFIG_E500)
+extern void __setup_cpu_e5500(unsigned long offset, struct cpu_spec* spec);
+extern void __restore_cpu_e5500(void);
+#endif /* CONFIG_E500 */
/* This table only contains "desktop" CPUs, it need to be filled with embedded
* ones as well...
@@ -1805,6 +1810,20 @@ static struct cpu_spec __initdata cpu_specs[] = {
.machine_check = machine_check_440A,
.platform = "ppc440",
},
+ { /* 464 in APM821xx */
+ .pvr_mask = 0xffffff00,
+ .pvr_value = 0x12C41C80,
+ .cpu_name = "APM821XX",
+ .cpu_features = CPU_FTRS_44X,
+ .cpu_user_features = COMMON_USER_BOOKE |
+ PPC_FEATURE_HAS_FPU,
+ .mmu_features = MMU_FTR_TYPE_44x,
+ .icache_bsize = 32,
+ .dcache_bsize = 32,
+ .cpu_setup = __setup_cpu_apm821xx,
+ .machine_check = machine_check_440A,
+ .platform = "ppc440",
+ },
{ /* 476 core */
.pvr_mask = 0xffff0000,
.pvr_value = 0x11a50000,
@@ -1891,7 +1910,9 @@ static struct cpu_spec __initdata cpu_specs[] = {
.platform = "ppc5554",
}
#endif /* CONFIG_E200 */
+#endif /* CONFIG_PPC32 */
#ifdef CONFIG_E500
+#ifdef CONFIG_PPC32
{ /* e500 */
.pvr_mask = 0xffff0000,
.pvr_value = 0x80200000,
@@ -1946,6 +1967,26 @@ static struct cpu_spec __initdata cpu_specs[] = {
.machine_check = machine_check_e500mc,
.platform = "ppce500mc",
},
+#endif /* CONFIG_PPC32 */
+ { /* e5500 */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x80240000,
+ .cpu_name = "e5500",
+ .cpu_features = CPU_FTRS_E500MC,
+ .cpu_user_features = COMMON_USER_BOOKE,
+ .mmu_features = MMU_FTR_TYPE_FSL_E | MMU_FTR_BIG_PHYS |
+ MMU_FTR_USE_TLBILX,
+ .icache_bsize = 64,
+ .dcache_bsize = 64,
+ .num_pmcs = 4,
+ .oprofile_cpu_type = "ppc/e500mc",
+ .oprofile_type = PPC_OPROFILE_FSL_EMB,
+ .cpu_setup = __setup_cpu_e5500,
+ .cpu_restore = __restore_cpu_e5500,
+ .machine_check = machine_check_e500mc,
+ .platform = "ppce5500",
+ },
+#ifdef CONFIG_PPC32
{ /* default match */
.pvr_mask = 0x00000000,
.pvr_value = 0x00000000,
@@ -1960,8 +2001,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
.machine_check = machine_check_e500,
.platform = "powerpc",
}
-#endif /* CONFIG_E500 */
#endif /* CONFIG_PPC32 */
+#endif /* CONFIG_E500 */
#ifdef CONFIG_PPC_BOOK3E_64
{ /* This is a default entry to get going, to be replaced by
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c
index 4457382f8667..832c8c4db254 100644
--- a/arch/powerpc/kernel/crash.c
+++ b/arch/powerpc/kernel/crash.c
@@ -414,18 +414,7 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
crash_kexec_wait_realmode(crashing_cpu);
#endif
- for_each_irq(i) {
- struct irq_desc *desc = irq_to_desc(i);
-
- if (!desc || !desc->chip || !desc->chip->eoi)
- continue;
-
- if (desc->status & IRQ_INPROGRESS)
- desc->chip->eoi(i);
-
- if (!(desc->status & IRQ_DISABLED))
- desc->chip->shutdown(i);
- }
+ machine_kexec_mask_interrupts();
/*
* Call registered shutdown routines savely. Swap out
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c
index 37771a518119..6e54a0fd31aa 100644
--- a/arch/powerpc/kernel/dma-iommu.c
+++ b/arch/powerpc/kernel/dma-iommu.c
@@ -74,16 +74,17 @@ static int dma_iommu_dma_supported(struct device *dev, u64 mask)
{
struct iommu_table *tbl = get_iommu_table_base(dev);
- if (!tbl || tbl->it_offset > mask) {
- printk(KERN_INFO
- "Warning: IOMMU offset too big for device mask\n");
- if (tbl)
- printk(KERN_INFO
- "mask: 0x%08llx, table offset: 0x%08lx\n",
- mask, tbl->it_offset);
- else
- printk(KERN_INFO "mask: 0x%08llx, table unavailable\n",
- mask);
+ if (!tbl) {
+ dev_info(dev, "Warning: IOMMU dma not supported: mask 0x%08llx"
+ ", table unavailable\n", mask);
+ return 0;
+ }
+
+ if ((tbl->it_offset + tbl->it_size) > (mask >> IOMMU_PAGE_SHIFT)) {
+ dev_info(dev, "Warning: IOMMU window too big for device mask\n");
+ dev_info(dev, "mask: 0x%08llx, table end: 0x%08lx\n",
+ mask, (tbl->it_offset + tbl->it_size) <<
+ IOMMU_PAGE_SHIFT);
return 0;
} else
return 1;
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index 84d6367ec003..cf02cad62d9a 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -12,6 +12,7 @@
#include <linux/memblock.h>
#include <asm/bug.h>
#include <asm/abs_addr.h>
+#include <asm/machdep.h>
/*
* Generic direct DMA implementation
@@ -89,7 +90,7 @@ static int dma_direct_dma_supported(struct device *dev, u64 mask)
/* Could be improved so platforms can set the limit in case
* they have limited DMA windows
*/
- return mask >= (memblock_end_of_DRAM() - 1);
+ return mask >= get_dma_offset(dev) + (memblock_end_of_DRAM() - 1);
#else
return 1;
#endif
@@ -154,6 +155,23 @@ EXPORT_SYMBOL(dma_direct_ops);
#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
+int dma_set_mask(struct device *dev, u64 dma_mask)
+{
+ struct dma_map_ops *dma_ops = get_dma_ops(dev);
+
+ if (ppc_md.dma_set_mask)
+ return ppc_md.dma_set_mask(dev, dma_mask);
+ if (unlikely(dma_ops == NULL))
+ return -EIO;
+ if (dma_ops->set_dma_mask != NULL)
+ return dma_ops->set_dma_mask(dev, dma_mask);
+ if (!dev->dma_mask || !dma_supported(dev, dma_mask))
+ return -EIO;
+ *dev->dma_mask = dma_mask;
+ return 0;
+}
+EXPORT_SYMBOL(dma_set_mask);
+
static int __init dma_init(void)
{
dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 42e9d908914a..d82878c4daa6 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -97,6 +97,24 @@ system_call_common:
addi r9,r1,STACK_FRAME_OVERHEAD
ld r11,exception_marker@toc(r2)
std r11,-16(r9) /* "regshere" marker */
+#if defined(CONFIG_VIRT_CPU_ACCOUNTING) && defined(CONFIG_PPC_SPLPAR)
+BEGIN_FW_FTR_SECTION
+ beq 33f
+ /* if from user, see if there are any DTL entries to process */
+ ld r10,PACALPPACAPTR(r13) /* get ptr to VPA */
+ ld r11,PACA_DTL_RIDX(r13) /* get log read index */
+ ld r10,LPPACA_DTLIDX(r10) /* get log write index */
+ cmpd cr1,r11,r10
+ beq+ cr1,33f
+ bl .accumulate_stolen_time
+ REST_GPR(0,r1)
+ REST_4GPRS(3,r1)
+ REST_2GPRS(7,r1)
+ addi r9,r1,STACK_FRAME_OVERHEAD
+33:
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR)
+#endif /* CONFIG_VIRT_CPU_ACCOUNTING && CONFIG_PPC_SPLPAR */
+
#ifdef CONFIG_TRACE_IRQFLAGS
bl .trace_hardirqs_on
REST_GPR(0,r1)
@@ -202,7 +220,9 @@ syscall_exit:
bge- syscall_error
syscall_error_cont:
ld r7,_NIP(r1)
+BEGIN_FTR_SECTION
stdcx. r0,0,r1 /* to clear the reservation */
+END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
andi. r6,r8,MSR_PR
ld r4,_LINK(r1)
/*
@@ -419,6 +439,17 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
sync
#endif /* CONFIG_SMP */
+ /*
+ * If we optimise away the clear of the reservation in system
+ * calls because we know the CPU tracks the address of the
+ * reservation, then we need to clear it here to cover the
+ * case that the kernel context switch path has no larx
+ * instructions.
+ */
+BEGIN_FTR_SECTION
+ ldarx r6,0,r1
+END_FTR_SECTION_IFSET(CPU_FTR_STCX_CHECKS_ADDRESS)
+
addi r6,r4,-THREAD /* Convert THREAD to 'current' */
std r6,PACACURRENT(r13) /* Set new 'current' */
@@ -576,7 +607,16 @@ ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES)
andi. r0,r3,MSR_RI
beq- unrecov_restore
+ /*
+ * Clear the reservation. If we know the CPU tracks the address of
+ * the reservation then we can potentially save some cycles and use
+ * a larx. On POWER6 and POWER7 this is significantly faster.
+ */
+BEGIN_FTR_SECTION
stdcx. r0,0,r1 /* to clear the reservation */
+FTR_SECTION_ELSE
+ ldarx r4,0,r1
+ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
/*
* Clear RI before restoring r13. If we are returning to
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index f53029a01554..9f8b01d6466f 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -299,6 +299,12 @@ slb_miss_user_pseries:
b . /* prevent spec. execution */
#endif /* __DISABLED__ */
+/* KVM's trampoline code needs to be close to the interrupt handlers */
+
+#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
+#include "../kvm/book3s_rmhandlers.S"
+#endif
+
.align 7
.globl __end_interrupts
__end_interrupts:
@@ -818,12 +824,12 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
/*
* hash_page couldn't handle it, set soft interrupt enable back
- * to what it was before the trap. Note that .raw_local_irq_restore
+ * to what it was before the trap. Note that .arch_local_irq_restore
* handles any interrupts pending at this point.
*/
ld r3,SOFTE(r1)
TRACE_AND_RESTORE_IRQ_PARTIAL(r3, 11f)
- bl .raw_local_irq_restore
+ bl .arch_local_irq_restore
b 11f
/* We have a data breakpoint exception - handle it */
diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S
index fc8f5b14019c..e86c040ae585 100644
--- a/arch/powerpc/kernel/fpu.S
+++ b/arch/powerpc/kernel/fpu.S
@@ -163,24 +163,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
/*
* These are used in the alignment trap handler when emulating
* single-precision loads and stores.
- * We restore and save the fpscr so the task gets the same result
- * and exceptions as if the cpu had performed the load or store.
*/
_GLOBAL(cvt_fd)
- lfd 0,THREAD_FPSCR(r5) /* load up fpscr value */
- MTFSF_L(0)
lfs 0,0(r3)
stfd 0,0(r4)
- mffs 0
- stfd 0,THREAD_FPSCR(r5) /* save new fpscr value */
blr
_GLOBAL(cvt_df)
- lfd 0,THREAD_FPSCR(r5) /* load up fpscr value */
- MTFSF_L(0)
lfd 0,0(r3)
stfs 0,0(r4)
- mffs 0
- stfd 0,THREAD_FPSCR(r5) /* save new fpscr value */
blr
diff --git a/arch/powerpc/kernel/head_40x.S b/arch/powerpc/kernel/head_40x.S
index a90625f9b485..8278e8bad5a0 100644
--- a/arch/powerpc/kernel/head_40x.S
+++ b/arch/powerpc/kernel/head_40x.S
@@ -923,11 +923,7 @@ initial_mmu:
mtspr SPRN_PID,r0
sync
- /* Configure and load two entries into TLB slots 62 and 63.
- * In case we are pinning TLBs, these are reserved in by the
- * other TLB functions. If not reserving, then it doesn't
- * matter where they are loaded.
- */
+ /* Configure and load one entry into TLB slots 63 */
clrrwi r4,r4,10 /* Mask off the real page number */
ori r4,r4,(TLB_WR | TLB_EX) /* Set the write and execute bits */
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index c571cd3c1453..f0dd577e4a5b 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -166,12 +166,6 @@ exception_marker:
#include "exceptions-64s.S"
#endif
-/* KVM trampoline code needs to be close to the interrupt handlers */
-
-#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
-#include "../kvm/book3s_rmhandlers.S"
-#endif
-
_GLOBAL(generic_secondary_thread_init)
mr r24,r3
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index 4faeba247854..529b817f473b 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -152,8 +152,11 @@ _ENTRY(__early_start)
/* Check to see if we're the second processor, and jump
* to the secondary_start code if so
*/
- mfspr r24,SPRN_PIR
- cmpwi r24,0
+ lis r24, boot_cpuid@h
+ ori r24, r24, boot_cpuid@l
+ lwz r24, 0(r24)
+ cmpwi r24, -1
+ mfspr r24,SPRN_PIR
bne __secondary_start
#endif
@@ -175,6 +178,9 @@ _ENTRY(__early_start)
li r0,0
stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
+ rlwinm r22,r1,0,0,31-THREAD_SHIFT /* current thread_info */
+ stw r24, TI_CPU(r22)
+
bl early_init
#ifdef CONFIG_RELOCATABLE
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index 9b626cfffce1..f62efdfd1769 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -162,13 +162,10 @@ static int ibmebus_create_device(struct device_node *dn)
dev->dev.bus = &ibmebus_bus_type;
dev->dev.archdata.dma_ops = &ibmebus_dma_ops;
- ret = of_device_register(dev);
- if (ret) {
- of_device_free(dev);
- return ret;
- }
-
- return 0;
+ ret = of_device_add(dev);
+ if (ret)
+ platform_device_put(dev);
+ return ret;
}
static int ibmebus_create_devices(const struct of_device_id *matches)
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 4a65386995d7..ce557f6f00fc 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -116,7 +116,7 @@ static inline notrace void set_soft_enabled(unsigned long enable)
: : "r" (enable), "i" (offsetof(struct paca_struct, soft_enabled)));
}
-notrace void raw_local_irq_restore(unsigned long en)
+notrace void arch_local_irq_restore(unsigned long en)
{
/*
* get_paca()->soft_enabled = en;
@@ -192,7 +192,7 @@ notrace void raw_local_irq_restore(unsigned long en)
__hard_irq_enable();
}
-EXPORT_SYMBOL(raw_local_irq_restore);
+EXPORT_SYMBOL(arch_local_irq_restore);
#endif /* CONFIG_PPC64 */
static int show_other_interrupts(struct seq_file *p, int prec)
@@ -587,8 +587,10 @@ struct irq_host *irq_alloc_host(struct device_node *of_node,
* this will be fixed once slab is made available early
* instead of the current cruft
*/
- if (mem_init_done)
+ if (mem_init_done) {
+ of_node_put(host->of_node);
kfree(host);
+ }
return NULL;
}
irq_map[0].host = host;
@@ -1143,7 +1145,7 @@ static int virq_debug_show(struct seq_file *m, void *private)
unsigned long flags;
struct irq_desc *desc;
const char *p;
- char none[] = "none";
+ static const char none[] = "none";
int i;
seq_printf(m, "%-5s %-7s %-15s %s\n", "virq", "hwirq",
diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c
new file mode 100644
index 000000000000..428d0e538aec
--- /dev/null
+++ b/arch/powerpc/kernel/kvm.c
@@ -0,0 +1,596 @@
+/*
+ * Copyright (C) 2010 SUSE Linux Products GmbH. All rights reserved.
+ *
+ * Authors:
+ * Alexander Graf <agraf@suse.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/kvm_host.h>
+#include <linux/init.h>
+#include <linux/kvm_para.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+
+#include <asm/reg.h>
+#include <asm/sections.h>
+#include <asm/cacheflush.h>
+#include <asm/disassemble.h>
+
+#define KVM_MAGIC_PAGE (-4096L)
+#define magic_var(x) KVM_MAGIC_PAGE + offsetof(struct kvm_vcpu_arch_shared, x)
+
+#define KVM_INST_LWZ 0x80000000
+#define KVM_INST_STW 0x90000000
+#define KVM_INST_LD 0xe8000000
+#define KVM_INST_STD 0xf8000000
+#define KVM_INST_NOP 0x60000000
+#define KVM_INST_B 0x48000000
+#define KVM_INST_B_MASK 0x03ffffff
+#define KVM_INST_B_MAX 0x01ffffff
+
+#define KVM_MASK_RT 0x03e00000
+#define KVM_RT_30 0x03c00000
+#define KVM_MASK_RB 0x0000f800
+#define KVM_INST_MFMSR 0x7c0000a6
+#define KVM_INST_MFSPR_SPRG0 0x7c1042a6
+#define KVM_INST_MFSPR_SPRG1 0x7c1142a6
+#define KVM_INST_MFSPR_SPRG2 0x7c1242a6
+#define KVM_INST_MFSPR_SPRG3 0x7c1342a6
+#define KVM_INST_MFSPR_SRR0 0x7c1a02a6
+#define KVM_INST_MFSPR_SRR1 0x7c1b02a6
+#define KVM_INST_MFSPR_DAR 0x7c1302a6
+#define KVM_INST_MFSPR_DSISR 0x7c1202a6
+
+#define KVM_INST_MTSPR_SPRG0 0x7c1043a6
+#define KVM_INST_MTSPR_SPRG1 0x7c1143a6
+#define KVM_INST_MTSPR_SPRG2 0x7c1243a6
+#define KVM_INST_MTSPR_SPRG3 0x7c1343a6
+#define KVM_INST_MTSPR_SRR0 0x7c1a03a6
+#define KVM_INST_MTSPR_SRR1 0x7c1b03a6
+#define KVM_INST_MTSPR_DAR 0x7c1303a6
+#define KVM_INST_MTSPR_DSISR 0x7c1203a6
+
+#define KVM_INST_TLBSYNC 0x7c00046c
+#define KVM_INST_MTMSRD_L0 0x7c000164
+#define KVM_INST_MTMSRD_L1 0x7c010164
+#define KVM_INST_MTMSR 0x7c000124
+
+#define KVM_INST_WRTEEI_0 0x7c000146
+#define KVM_INST_WRTEEI_1 0x7c008146
+
+#define KVM_INST_MTSRIN 0x7c0001e4
+
+static bool kvm_patching_worked = true;
+static char kvm_tmp[1024 * 1024];
+static int kvm_tmp_index;
+
+static inline void kvm_patch_ins(u32 *inst, u32 new_inst)
+{
+ *inst = new_inst;
+ flush_icache_range((ulong)inst, (ulong)inst + 4);
+}
+
+static void kvm_patch_ins_ll(u32 *inst, long addr, u32 rt)
+{
+#ifdef CONFIG_64BIT
+ kvm_patch_ins(inst, KVM_INST_LD | rt | (addr & 0x0000fffc));
+#else
+ kvm_patch_ins(inst, KVM_INST_LWZ | rt | (addr & 0x0000fffc));
+#endif
+}
+
+static void kvm_patch_ins_ld(u32 *inst, long addr, u32 rt)
+{
+#ifdef CONFIG_64BIT
+ kvm_patch_ins(inst, KVM_INST_LD | rt | (addr & 0x0000fffc));
+#else
+ kvm_patch_ins(inst, KVM_INST_LWZ | rt | ((addr + 4) & 0x0000fffc));
+#endif
+}
+
+static void kvm_patch_ins_lwz(u32 *inst, long addr, u32 rt)
+{
+ kvm_patch_ins(inst, KVM_INST_LWZ | rt | (addr & 0x0000ffff));
+}
+
+static void kvm_patch_ins_std(u32 *inst, long addr, u32 rt)
+{
+#ifdef CONFIG_64BIT
+ kvm_patch_ins(inst, KVM_INST_STD | rt | (addr & 0x0000fffc));
+#else
+ kvm_patch_ins(inst, KVM_INST_STW | rt | ((addr + 4) & 0x0000fffc));
+#endif
+}
+
+static void kvm_patch_ins_stw(u32 *inst, long addr, u32 rt)
+{
+ kvm_patch_ins(inst, KVM_INST_STW | rt | (addr & 0x0000fffc));
+}
+
+static void kvm_patch_ins_nop(u32 *inst)
+{
+ kvm_patch_ins(inst, KVM_INST_NOP);
+}
+
+static void kvm_patch_ins_b(u32 *inst, int addr)
+{
+#ifdef CONFIG_RELOCATABLE
+ /* On relocatable kernels interrupts handlers and our code
+ can be in different regions, so we don't patch them */
+
+ extern u32 __end_interrupts;
+ if ((ulong)inst < (ulong)&__end_interrupts)
+ return;
+#endif
+
+ kvm_patch_ins(inst, KVM_INST_B | (addr & KVM_INST_B_MASK));
+}
+
+static u32 *kvm_alloc(int len)
+{
+ u32 *p;
+
+ if ((kvm_tmp_index + len) > ARRAY_SIZE(kvm_tmp)) {
+ printk(KERN_ERR "KVM: No more space (%d + %d)\n",
+ kvm_tmp_index, len);
+ kvm_patching_worked = false;
+ return NULL;
+ }
+
+ p = (void*)&kvm_tmp[kvm_tmp_index];
+ kvm_tmp_index += len;
+
+ return p;
+}
+
+extern u32 kvm_emulate_mtmsrd_branch_offs;
+extern u32 kvm_emulate_mtmsrd_reg_offs;
+extern u32 kvm_emulate_mtmsrd_orig_ins_offs;
+extern u32 kvm_emulate_mtmsrd_len;
+extern u32 kvm_emulate_mtmsrd[];
+
+static void kvm_patch_ins_mtmsrd(u32 *inst, u32 rt)
+{
+ u32 *p;
+ int distance_start;
+ int distance_end;
+ ulong next_inst;
+
+ p = kvm_alloc(kvm_emulate_mtmsrd_len * 4);
+ if (!p)
+ return;
+
+ /* Find out where we are and put everything there */
+ distance_start = (ulong)p - (ulong)inst;
+ next_inst = ((ulong)inst + 4);
+ distance_end = next_inst - (ulong)&p[kvm_emulate_mtmsrd_branch_offs];
+
+ /* Make sure we only write valid b instructions */
+ if (distance_start > KVM_INST_B_MAX) {
+ kvm_patching_worked = false;
+ return;
+ }
+
+ /* Modify the chunk to fit the invocation */
+ memcpy(p, kvm_emulate_mtmsrd, kvm_emulate_mtmsrd_len * 4);
+ p[kvm_emulate_mtmsrd_branch_offs] |= distance_end & KVM_INST_B_MASK;
+ switch (get_rt(rt)) {
+ case 30:
+ kvm_patch_ins_ll(&p[kvm_emulate_mtmsrd_reg_offs],
+ magic_var(scratch2), KVM_RT_30);
+ break;
+ case 31:
+ kvm_patch_ins_ll(&p[kvm_emulate_mtmsrd_reg_offs],
+ magic_var(scratch1), KVM_RT_30);
+ break;
+ default:
+ p[kvm_emulate_mtmsrd_reg_offs] |= rt;
+ break;
+ }
+
+ p[kvm_emulate_mtmsrd_orig_ins_offs] = *inst;
+ flush_icache_range((ulong)p, (ulong)p + kvm_emulate_mtmsrd_len * 4);
+
+ /* Patch the invocation */
+ kvm_patch_ins_b(inst, distance_start);
+}
+
+extern u32 kvm_emulate_mtmsr_branch_offs;
+extern u32 kvm_emulate_mtmsr_reg1_offs;
+extern u32 kvm_emulate_mtmsr_reg2_offs;
+extern u32 kvm_emulate_mtmsr_orig_ins_offs;
+extern u32 kvm_emulate_mtmsr_len;
+extern u32 kvm_emulate_mtmsr[];
+
+static void kvm_patch_ins_mtmsr(u32 *inst, u32 rt)
+{
+ u32 *p;
+ int distance_start;
+ int distance_end;
+ ulong next_inst;
+
+ p = kvm_alloc(kvm_emulate_mtmsr_len * 4);
+ if (!p)
+ return;
+
+ /* Find out where we are and put everything there */
+ distance_start = (ulong)p - (ulong)inst;
+ next_inst = ((ulong)inst + 4);
+ distance_end = next_inst - (ulong)&p[kvm_emulate_mtmsr_branch_offs];
+
+ /* Make sure we only write valid b instructions */
+ if (distance_start > KVM_INST_B_MAX) {
+ kvm_patching_worked = false;
+ return;
+ }
+
+ /* Modify the chunk to fit the invocation */
+ memcpy(p, kvm_emulate_mtmsr, kvm_emulate_mtmsr_len * 4);
+ p[kvm_emulate_mtmsr_branch_offs] |= distance_end & KVM_INST_B_MASK;
+
+ /* Make clobbered registers work too */
+ switch (get_rt(rt)) {
+ case 30:
+ kvm_patch_ins_ll(&p[kvm_emulate_mtmsr_reg1_offs],
+ magic_var(scratch2), KVM_RT_30);
+ kvm_patch_ins_ll(&p[kvm_emulate_mtmsr_reg2_offs],
+ magic_var(scratch2), KVM_RT_30);
+ break;
+ case 31:
+ kvm_patch_ins_ll(&p[kvm_emulate_mtmsr_reg1_offs],
+ magic_var(scratch1), KVM_RT_30);
+ kvm_patch_ins_ll(&p[kvm_emulate_mtmsr_reg2_offs],
+ magic_var(scratch1), KVM_RT_30);
+ break;
+ default:
+ p[kvm_emulate_mtmsr_reg1_offs] |= rt;
+ p[kvm_emulate_mtmsr_reg2_offs] |= rt;
+ break;
+ }
+
+ p[kvm_emulate_mtmsr_orig_ins_offs] = *inst;
+ flush_icache_range((ulong)p, (ulong)p + kvm_emulate_mtmsr_len * 4);
+
+ /* Patch the invocation */
+ kvm_patch_ins_b(inst, distance_start);
+}
+
+#ifdef CONFIG_BOOKE
+
+extern u32 kvm_emulate_wrteei_branch_offs;
+extern u32 kvm_emulate_wrteei_ee_offs;
+extern u32 kvm_emulate_wrteei_len;
+extern u32 kvm_emulate_wrteei[];
+
+static void kvm_patch_ins_wrteei(u32 *inst)
+{
+ u32 *p;
+ int distance_start;
+ int distance_end;
+ ulong next_inst;
+
+ p = kvm_alloc(kvm_emulate_wrteei_len * 4);
+ if (!p)
+ return;
+
+ /* Find out where we are and put everything there */
+ distance_start = (ulong)p - (ulong)inst;
+ next_inst = ((ulong)inst + 4);
+ distance_end = next_inst - (ulong)&p[kvm_emulate_wrteei_branch_offs];
+
+ /* Make sure we only write valid b instructions */
+ if (distance_start > KVM_INST_B_MAX) {
+ kvm_patching_worked = false;
+ return;
+ }
+
+ /* Modify the chunk to fit the invocation */
+ memcpy(p, kvm_emulate_wrteei, kvm_emulate_wrteei_len * 4);
+ p[kvm_emulate_wrteei_branch_offs] |= distance_end & KVM_INST_B_MASK;
+ p[kvm_emulate_wrteei_ee_offs] |= (*inst & MSR_EE);
+ flush_icache_range((ulong)p, (ulong)p + kvm_emulate_wrteei_len * 4);
+
+ /* Patch the invocation */
+ kvm_patch_ins_b(inst, distance_start);
+}
+
+#endif
+
+#ifdef CONFIG_PPC_BOOK3S_32
+
+extern u32 kvm_emulate_mtsrin_branch_offs;
+extern u32 kvm_emulate_mtsrin_reg1_offs;
+extern u32 kvm_emulate_mtsrin_reg2_offs;
+extern u32 kvm_emulate_mtsrin_orig_ins_offs;
+extern u32 kvm_emulate_mtsrin_len;
+extern u32 kvm_emulate_mtsrin[];
+
+static void kvm_patch_ins_mtsrin(u32 *inst, u32 rt, u32 rb)
+{
+ u32 *p;
+ int distance_start;
+ int distance_end;
+ ulong next_inst;
+
+ p = kvm_alloc(kvm_emulate_mtsrin_len * 4);
+ if (!p)
+ return;
+
+ /* Find out where we are and put everything there */
+ distance_start = (ulong)p - (ulong)inst;
+ next_inst = ((ulong)inst + 4);
+ distance_end = next_inst - (ulong)&p[kvm_emulate_mtsrin_branch_offs];
+
+ /* Make sure we only write valid b instructions */
+ if (distance_start > KVM_INST_B_MAX) {
+ kvm_patching_worked = false;
+ return;
+ }
+
+ /* Modify the chunk to fit the invocation */
+ memcpy(p, kvm_emulate_mtsrin, kvm_emulate_mtsrin_len * 4);
+ p[kvm_emulate_mtsrin_branch_offs] |= distance_end & KVM_INST_B_MASK;
+ p[kvm_emulate_mtsrin_reg1_offs] |= (rb << 10);
+ p[kvm_emulate_mtsrin_reg2_offs] |= rt;
+ p[kvm_emulate_mtsrin_orig_ins_offs] = *inst;
+ flush_icache_range((ulong)p, (ulong)p + kvm_emulate_mtsrin_len * 4);
+
+ /* Patch the invocation */
+ kvm_patch_ins_b(inst, distance_start);
+}
+
+#endif
+
+static void kvm_map_magic_page(void *data)
+{
+ u32 *features = data;
+
+ ulong in[8];
+ ulong out[8];
+
+ in[0] = KVM_MAGIC_PAGE;
+ in[1] = KVM_MAGIC_PAGE;
+
+ kvm_hypercall(in, out, HC_VENDOR_KVM | KVM_HC_PPC_MAP_MAGIC_PAGE);
+
+ *features = out[0];
+}
+
+static void kvm_check_ins(u32 *inst, u32 features)
+{
+ u32 _inst = *inst;
+ u32 inst_no_rt = _inst & ~KVM_MASK_RT;
+ u32 inst_rt = _inst & KVM_MASK_RT;
+
+ switch (inst_no_rt) {
+ /* Loads */
+ case KVM_INST_MFMSR:
+ kvm_patch_ins_ld(inst, magic_var(msr), inst_rt);
+ break;
+ case KVM_INST_MFSPR_SPRG0:
+ kvm_patch_ins_ld(inst, magic_var(sprg0), inst_rt);
+ break;
+ case KVM_INST_MFSPR_SPRG1:
+ kvm_patch_ins_ld(inst, magic_var(sprg1), inst_rt);
+ break;
+ case KVM_INST_MFSPR_SPRG2:
+ kvm_patch_ins_ld(inst, magic_var(sprg2), inst_rt);
+ break;
+ case KVM_INST_MFSPR_SPRG3:
+ kvm_patch_ins_ld(inst, magic_var(sprg3), inst_rt);
+ break;
+ case KVM_INST_MFSPR_SRR0:
+ kvm_patch_ins_ld(inst, magic_var(srr0), inst_rt);
+ break;
+ case KVM_INST_MFSPR_SRR1:
+ kvm_patch_ins_ld(inst, magic_var(srr1), inst_rt);
+ break;
+ case KVM_INST_MFSPR_DAR:
+ kvm_patch_ins_ld(inst, magic_var(dar), inst_rt);
+ break;
+ case KVM_INST_MFSPR_DSISR:
+ kvm_patch_ins_lwz(inst, magic_var(dsisr), inst_rt);
+ break;
+
+ /* Stores */
+ case KVM_INST_MTSPR_SPRG0:
+ kvm_patch_ins_std(inst, magic_var(sprg0), inst_rt);
+ break;
+ case KVM_INST_MTSPR_SPRG1:
+ kvm_patch_ins_std(inst, magic_var(sprg1), inst_rt);
+ break;
+ case KVM_INST_MTSPR_SPRG2:
+ kvm_patch_ins_std(inst, magic_var(sprg2), inst_rt);
+ break;
+ case KVM_INST_MTSPR_SPRG3:
+ kvm_patch_ins_std(inst, magic_var(sprg3), inst_rt);
+ break;
+ case KVM_INST_MTSPR_SRR0:
+ kvm_patch_ins_std(inst, magic_var(srr0), inst_rt);
+ break;
+ case KVM_INST_MTSPR_SRR1:
+ kvm_patch_ins_std(inst, magic_var(srr1), inst_rt);
+ break;
+ case KVM_INST_MTSPR_DAR:
+ kvm_patch_ins_std(inst, magic_var(dar), inst_rt);
+ break;
+ case KVM_INST_MTSPR_DSISR:
+ kvm_patch_ins_stw(inst, magic_var(dsisr), inst_rt);
+ break;
+
+ /* Nops */
+ case KVM_INST_TLBSYNC:
+ kvm_patch_ins_nop(inst);
+ break;
+
+ /* Rewrites */
+ case KVM_INST_MTMSRD_L1:
+ kvm_patch_ins_mtmsrd(inst, inst_rt);
+ break;
+ case KVM_INST_MTMSR:
+ case KVM_INST_MTMSRD_L0:
+ kvm_patch_ins_mtmsr(inst, inst_rt);
+ break;
+ }
+
+ switch (inst_no_rt & ~KVM_MASK_RB) {
+#ifdef CONFIG_PPC_BOOK3S_32
+ case KVM_INST_MTSRIN:
+ if (features & KVM_MAGIC_FEAT_SR) {
+ u32 inst_rb = _inst & KVM_MASK_RB;
+ kvm_patch_ins_mtsrin(inst, inst_rt, inst_rb);
+ }
+ break;
+ break;
+#endif
+ }
+
+ switch (_inst) {
+#ifdef CONFIG_BOOKE
+ case KVM_INST_WRTEEI_0:
+ case KVM_INST_WRTEEI_1:
+ kvm_patch_ins_wrteei(inst);
+ break;
+#endif
+ }
+}
+
+static void kvm_use_magic_page(void)
+{
+ u32 *p;
+ u32 *start, *end;
+ u32 tmp;
+ u32 features;
+
+ /* Tell the host to map the magic page to -4096 on all CPUs */
+ on_each_cpu(kvm_map_magic_page, &features, 1);
+
+ /* Quick self-test to see if the mapping works */
+ if (__get_user(tmp, (u32*)KVM_MAGIC_PAGE)) {
+ kvm_patching_worked = false;
+ return;
+ }
+
+ /* Now loop through all code and find instructions */
+ start = (void*)_stext;
+ end = (void*)_etext;
+
+ for (p = start; p < end; p++)
+ kvm_check_ins(p, features);
+
+ printk(KERN_INFO "KVM: Live patching for a fast VM %s\n",
+ kvm_patching_worked ? "worked" : "failed");
+}
+
+unsigned long kvm_hypercall(unsigned long *in,
+ unsigned long *out,
+ unsigned long nr)
+{
+ unsigned long register r0 asm("r0");
+ unsigned long register r3 asm("r3") = in[0];
+ unsigned long register r4 asm("r4") = in[1];
+ unsigned long register r5 asm("r5") = in[2];
+ unsigned long register r6 asm("r6") = in[3];
+ unsigned long register r7 asm("r7") = in[4];
+ unsigned long register r8 asm("r8") = in[5];
+ unsigned long register r9 asm("r9") = in[6];
+ unsigned long register r10 asm("r10") = in[7];
+ unsigned long register r11 asm("r11") = nr;
+ unsigned long register r12 asm("r12");
+
+ asm volatile("bl kvm_hypercall_start"
+ : "=r"(r0), "=r"(r3), "=r"(r4), "=r"(r5), "=r"(r6),
+ "=r"(r7), "=r"(r8), "=r"(r9), "=r"(r10), "=r"(r11),
+ "=r"(r12)
+ : "r"(r3), "r"(r4), "r"(r5), "r"(r6), "r"(r7), "r"(r8),
+ "r"(r9), "r"(r10), "r"(r11)
+ : "memory", "cc", "xer", "ctr", "lr");
+
+ out[0] = r4;
+ out[1] = r5;
+ out[2] = r6;
+ out[3] = r7;
+ out[4] = r8;
+ out[5] = r9;
+ out[6] = r10;
+ out[7] = r11;
+
+ return r3;
+}
+EXPORT_SYMBOL_GPL(kvm_hypercall);
+
+static int kvm_para_setup(void)
+{
+ extern u32 kvm_hypercall_start;
+ struct device_node *hyper_node;
+ u32 *insts;
+ int len, i;
+
+ hyper_node = of_find_node_by_path("/hypervisor");
+ if (!hyper_node)
+ return -1;
+
+ insts = (u32*)of_get_property(hyper_node, "hcall-instructions", &len);
+ if (len % 4)
+ return -1;
+ if (len > (4 * 4))
+ return -1;
+
+ for (i = 0; i < (len / 4); i++)
+ kvm_patch_ins(&(&kvm_hypercall_start)[i], insts[i]);
+
+ return 0;
+}
+
+static __init void kvm_free_tmp(void)
+{
+ unsigned long start, end;
+
+ start = (ulong)&kvm_tmp[kvm_tmp_index + (PAGE_SIZE - 1)] & PAGE_MASK;
+ end = (ulong)&kvm_tmp[ARRAY_SIZE(kvm_tmp)] & PAGE_MASK;
+
+ /* Free the tmp space we don't need */
+ for (; start < end; start += PAGE_SIZE) {
+ ClearPageReserved(virt_to_page(start));
+ init_page_count(virt_to_page(start));
+ free_page(start);
+ totalram_pages++;
+ }
+}
+
+static int __init kvm_guest_init(void)
+{
+ if (!kvm_para_available())
+ goto free_tmp;
+
+ if (kvm_para_setup())
+ goto free_tmp;
+
+ if (kvm_para_has_feature(KVM_FEATURE_MAGIC_PAGE))
+ kvm_use_magic_page();
+
+#ifdef CONFIG_PPC_BOOK3S_64
+ /* Enable napping */
+ powersave_nap = 1;
+#endif
+
+free_tmp:
+ kvm_free_tmp();
+
+ return 0;
+}
+
+postcore_initcall(kvm_guest_init);
diff --git a/arch/powerpc/kernel/kvm_emul.S b/arch/powerpc/kernel/kvm_emul.S
new file mode 100644
index 000000000000..f2b1b2523e61
--- /dev/null
+++ b/arch/powerpc/kernel/kvm_emul.S
@@ -0,0 +1,302 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright SUSE Linux Products GmbH 2010
+ *
+ * Authors: Alexander Graf <agraf@suse.de>
+ */
+
+#include <asm/ppc_asm.h>
+#include <asm/kvm_asm.h>
+#include <asm/reg.h>
+#include <asm/page.h>
+#include <asm/asm-offsets.h>
+
+/* Hypercall entry point. Will be patched with device tree instructions. */
+
+.global kvm_hypercall_start
+kvm_hypercall_start:
+ li r3, -1
+ nop
+ nop
+ nop
+ blr
+
+#define KVM_MAGIC_PAGE (-4096)
+
+#ifdef CONFIG_64BIT
+#define LL64(reg, offs, reg2) ld reg, (offs)(reg2)
+#define STL64(reg, offs, reg2) std reg, (offs)(reg2)
+#else
+#define LL64(reg, offs, reg2) lwz reg, (offs + 4)(reg2)
+#define STL64(reg, offs, reg2) stw reg, (offs + 4)(reg2)
+#endif
+
+#define SCRATCH_SAVE \
+ /* Enable critical section. We are critical if \
+ shared->critical == r1 */ \
+ STL64(r1, KVM_MAGIC_PAGE + KVM_MAGIC_CRITICAL, 0); \
+ \
+ /* Save state */ \
+ PPC_STL r31, (KVM_MAGIC_PAGE + KVM_MAGIC_SCRATCH1)(0); \
+ PPC_STL r30, (KVM_MAGIC_PAGE + KVM_MAGIC_SCRATCH2)(0); \
+ mfcr r31; \
+ stw r31, (KVM_MAGIC_PAGE + KVM_MAGIC_SCRATCH3)(0);
+
+#define SCRATCH_RESTORE \
+ /* Restore state */ \
+ PPC_LL r31, (KVM_MAGIC_PAGE + KVM_MAGIC_SCRATCH1)(0); \
+ lwz r30, (KVM_MAGIC_PAGE + KVM_MAGIC_SCRATCH3)(0); \
+ mtcr r30; \
+ PPC_LL r30, (KVM_MAGIC_PAGE + KVM_MAGIC_SCRATCH2)(0); \
+ \
+ /* Disable critical section. We are critical if \
+ shared->critical == r1 and r2 is always != r1 */ \
+ STL64(r2, KVM_MAGIC_PAGE + KVM_MAGIC_CRITICAL, 0);
+
+.global kvm_emulate_mtmsrd
+kvm_emulate_mtmsrd:
+
+ SCRATCH_SAVE
+
+ /* Put MSR & ~(MSR_EE|MSR_RI) in r31 */
+ LL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
+ lis r30, (~(MSR_EE | MSR_RI))@h
+ ori r30, r30, (~(MSR_EE | MSR_RI))@l
+ and r31, r31, r30
+
+ /* OR the register's (MSR_EE|MSR_RI) on MSR */
+kvm_emulate_mtmsrd_reg:
+ ori r30, r0, 0
+ andi. r30, r30, (MSR_EE|MSR_RI)
+ or r31, r31, r30
+
+ /* Put MSR back into magic page */
+ STL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
+
+ /* Check if we have to fetch an interrupt */
+ lwz r31, (KVM_MAGIC_PAGE + KVM_MAGIC_INT)(0)
+ cmpwi r31, 0
+ beq+ no_check
+
+ /* Check if we may trigger an interrupt */
+ andi. r30, r30, MSR_EE
+ beq no_check
+
+ SCRATCH_RESTORE
+
+ /* Nag hypervisor */
+kvm_emulate_mtmsrd_orig_ins:
+ tlbsync
+
+ b kvm_emulate_mtmsrd_branch
+
+no_check:
+
+ SCRATCH_RESTORE
+
+ /* Go back to caller */
+kvm_emulate_mtmsrd_branch:
+ b .
+kvm_emulate_mtmsrd_end:
+
+.global kvm_emulate_mtmsrd_branch_offs
+kvm_emulate_mtmsrd_branch_offs:
+ .long (kvm_emulate_mtmsrd_branch - kvm_emulate_mtmsrd) / 4
+
+.global kvm_emulate_mtmsrd_reg_offs
+kvm_emulate_mtmsrd_reg_offs:
+ .long (kvm_emulate_mtmsrd_reg - kvm_emulate_mtmsrd) / 4
+
+.global kvm_emulate_mtmsrd_orig_ins_offs
+kvm_emulate_mtmsrd_orig_ins_offs:
+ .long (kvm_emulate_mtmsrd_orig_ins - kvm_emulate_mtmsrd) / 4
+
+.global kvm_emulate_mtmsrd_len
+kvm_emulate_mtmsrd_len:
+ .long (kvm_emulate_mtmsrd_end - kvm_emulate_mtmsrd) / 4
+
+
+#define MSR_SAFE_BITS (MSR_EE | MSR_CE | MSR_ME | MSR_RI)
+#define MSR_CRITICAL_BITS ~MSR_SAFE_BITS
+
+.global kvm_emulate_mtmsr
+kvm_emulate_mtmsr:
+
+ SCRATCH_SAVE
+
+ /* Fetch old MSR in r31 */
+ LL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
+
+ /* Find the changed bits between old and new MSR */
+kvm_emulate_mtmsr_reg1:
+ ori r30, r0, 0
+ xor r31, r30, r31
+
+ /* Check if we need to really do mtmsr */
+ LOAD_REG_IMMEDIATE(r30, MSR_CRITICAL_BITS)
+ and. r31, r31, r30
+
+ /* No critical bits changed? Maybe we can stay in the guest. */
+ beq maybe_stay_in_guest
+
+do_mtmsr:
+
+ SCRATCH_RESTORE
+
+ /* Just fire off the mtmsr if it's critical */
+kvm_emulate_mtmsr_orig_ins:
+ mtmsr r0
+
+ b kvm_emulate_mtmsr_branch
+
+maybe_stay_in_guest:
+
+ /* Get the target register in r30 */
+kvm_emulate_mtmsr_reg2:
+ ori r30, r0, 0
+
+ /* Check if we have to fetch an interrupt */
+ lwz r31, (KVM_MAGIC_PAGE + KVM_MAGIC_INT)(0)
+ cmpwi r31, 0
+ beq+ no_mtmsr
+
+ /* Check if we may trigger an interrupt */
+ andi. r31, r30, MSR_EE
+ beq no_mtmsr
+
+ b do_mtmsr
+
+no_mtmsr:
+
+ /* Put MSR into magic page because we don't call mtmsr */
+ STL64(r30, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
+
+ SCRATCH_RESTORE
+
+ /* Go back to caller */
+kvm_emulate_mtmsr_branch:
+ b .
+kvm_emulate_mtmsr_end:
+
+.global kvm_emulate_mtmsr_branch_offs
+kvm_emulate_mtmsr_branch_offs:
+ .long (kvm_emulate_mtmsr_branch - kvm_emulate_mtmsr) / 4
+
+.global kvm_emulate_mtmsr_reg1_offs
+kvm_emulate_mtmsr_reg1_offs:
+ .long (kvm_emulate_mtmsr_reg1 - kvm_emulate_mtmsr) / 4
+
+.global kvm_emulate_mtmsr_reg2_offs
+kvm_emulate_mtmsr_reg2_offs:
+ .long (kvm_emulate_mtmsr_reg2 - kvm_emulate_mtmsr) / 4
+
+.global kvm_emulate_mtmsr_orig_ins_offs
+kvm_emulate_mtmsr_orig_ins_offs:
+ .long (kvm_emulate_mtmsr_orig_ins - kvm_emulate_mtmsr) / 4
+
+.global kvm_emulate_mtmsr_len
+kvm_emulate_mtmsr_len:
+ .long (kvm_emulate_mtmsr_end - kvm_emulate_mtmsr) / 4
+
+
+
+.global kvm_emulate_wrteei
+kvm_emulate_wrteei:
+
+ SCRATCH_SAVE
+
+ /* Fetch old MSR in r31 */
+ LL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
+
+ /* Remove MSR_EE from old MSR */
+ li r30, 0
+ ori r30, r30, MSR_EE
+ andc r31, r31, r30
+
+ /* OR new MSR_EE onto the old MSR */
+kvm_emulate_wrteei_ee:
+ ori r31, r31, 0
+
+ /* Write new MSR value back */
+ STL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
+
+ SCRATCH_RESTORE
+
+ /* Go back to caller */
+kvm_emulate_wrteei_branch:
+ b .
+kvm_emulate_wrteei_end:
+
+.global kvm_emulate_wrteei_branch_offs
+kvm_emulate_wrteei_branch_offs:
+ .long (kvm_emulate_wrteei_branch - kvm_emulate_wrteei) / 4
+
+.global kvm_emulate_wrteei_ee_offs
+kvm_emulate_wrteei_ee_offs:
+ .long (kvm_emulate_wrteei_ee - kvm_emulate_wrteei) / 4
+
+.global kvm_emulate_wrteei_len
+kvm_emulate_wrteei_len:
+ .long (kvm_emulate_wrteei_end - kvm_emulate_wrteei) / 4
+
+
+.global kvm_emulate_mtsrin
+kvm_emulate_mtsrin:
+
+ SCRATCH_SAVE
+
+ LL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
+ andi. r31, r31, MSR_DR | MSR_IR
+ beq kvm_emulate_mtsrin_reg1
+
+ SCRATCH_RESTORE
+
+kvm_emulate_mtsrin_orig_ins:
+ nop
+ b kvm_emulate_mtsrin_branch
+
+kvm_emulate_mtsrin_reg1:
+ /* rX >> 26 */
+ rlwinm r30,r0,6,26,29
+
+kvm_emulate_mtsrin_reg2:
+ stw r0, (KVM_MAGIC_PAGE + KVM_MAGIC_SR)(r30)
+
+ SCRATCH_RESTORE
+
+ /* Go back to caller */
+kvm_emulate_mtsrin_branch:
+ b .
+kvm_emulate_mtsrin_end:
+
+.global kvm_emulate_mtsrin_branch_offs
+kvm_emulate_mtsrin_branch_offs:
+ .long (kvm_emulate_mtsrin_branch - kvm_emulate_mtsrin) / 4
+
+.global kvm_emulate_mtsrin_reg1_offs
+kvm_emulate_mtsrin_reg1_offs:
+ .long (kvm_emulate_mtsrin_reg1 - kvm_emulate_mtsrin) / 4
+
+.global kvm_emulate_mtsrin_reg2_offs
+kvm_emulate_mtsrin_reg2_offs:
+ .long (kvm_emulate_mtsrin_reg2 - kvm_emulate_mtsrin) / 4
+
+.global kvm_emulate_mtsrin_orig_ins_offs
+kvm_emulate_mtsrin_orig_ins_offs:
+ .long (kvm_emulate_mtsrin_orig_ins - kvm_emulate_mtsrin) / 4
+
+.global kvm_emulate_mtsrin_len
+kvm_emulate_mtsrin_len:
+ .long (kvm_emulate_mtsrin_end - kvm_emulate_mtsrin) / 4
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
index c1fd0f9658fd..c834757bebc0 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -52,14 +52,14 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
phys_addr_t taddr, unsigned long irq,
upf_t flags, int irq_check_parent)
{
- const u32 *clk, *spd;
+ const __be32 *clk, *spd;
u32 clock = BASE_BAUD * 16;
int index;
/* get clock freq. if present */
clk = of_get_property(np, "clock-frequency", NULL);
if (clk && *clk)
- clock = *clk;
+ clock = be32_to_cpup(clk);
/* get default speed if present */
spd = of_get_property(np, "current-speed", NULL);
@@ -109,7 +109,7 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
legacy_serial_infos[index].taddr = taddr;
legacy_serial_infos[index].np = of_node_get(np);
legacy_serial_infos[index].clock = clock;
- legacy_serial_infos[index].speed = spd ? *spd : 0;
+ legacy_serial_infos[index].speed = spd ? be32_to_cpup(spd) : 0;
legacy_serial_infos[index].irq_check_parent = irq_check_parent;
printk(KERN_DEBUG "Found legacy serial port %d for %s\n",
@@ -168,7 +168,7 @@ static int __init add_legacy_soc_port(struct device_node *np,
static int __init add_legacy_isa_port(struct device_node *np,
struct device_node *isa_brg)
{
- const u32 *reg;
+ const __be32 *reg;
const char *typep;
int index = -1;
u64 taddr;
@@ -181,7 +181,7 @@ static int __init add_legacy_isa_port(struct device_node *np,
return -1;
/* Verify it's an IO port, we don't support anything else */
- if (!(reg[0] & 0x00000001))
+ if (!(be32_to_cpu(reg[0]) & 0x00000001))
return -1;
/* Now look for an "ibm,aix-loc" property that gives us ordering
@@ -202,7 +202,7 @@ static int __init add_legacy_isa_port(struct device_node *np,
taddr = 0;
/* Add port, irq will be dealt with later */
- return add_legacy_port(np, index, UPIO_PORT, reg[1], taddr,
+ return add_legacy_port(np, index, UPIO_PORT, be32_to_cpu(reg[1]), taddr,
NO_IRQ, UPF_BOOT_AUTOCONF, 0);
}
@@ -251,9 +251,9 @@ static int __init add_legacy_pci_port(struct device_node *np,
* we get to their "reg" property
*/
if (np != pci_dev) {
- const u32 *reg = of_get_property(np, "reg", NULL);
- if (reg && (*reg < 4))
- index = lindex = *reg;
+ const __be32 *reg = of_get_property(np, "reg", NULL);
+ if (reg && (be32_to_cpup(reg) < 4))
+ index = lindex = be32_to_cpup(reg);
}
/* Local index means it's the Nth port in the PCI chip. Unfortunately
@@ -507,7 +507,7 @@ static int __init check_legacy_serial_console(void)
struct device_node *prom_stdout = NULL;
int i, speed = 0, offset = 0;
const char *name;
- const u32 *spd;
+ const __be32 *spd;
DBG(" -> check_legacy_serial_console()\n");
@@ -547,7 +547,7 @@ static int __init check_legacy_serial_console(void)
}
spd = of_get_property(prom_stdout, "current-speed", NULL);
if (spd)
- speed = *spd;
+ speed = be32_to_cpup(spd);
if (strcmp(name, "serial") != 0)
goto not_found;
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c
index 50362b6ef6e9..16468362ad57 100644
--- a/arch/powerpc/kernel/lparcfg.c
+++ b/arch/powerpc/kernel/lparcfg.c
@@ -56,7 +56,7 @@ static unsigned long get_purr(void)
for_each_possible_cpu(cpu) {
if (firmware_has_feature(FW_FEATURE_ISERIES))
- sum_purr += lppaca[cpu].emulated_time_base;
+ sum_purr += lppaca_of(cpu).emulated_time_base;
else {
struct cpu_usage *cu;
@@ -263,7 +263,7 @@ static void parse_ppp_data(struct seq_file *m)
ppp_data.active_system_procs);
/* pool related entries are apropriate for shared configs */
- if (lppaca[0].shared_proc) {
+ if (lppaca_of(0).shared_proc) {
unsigned long pool_idle_time, pool_procs;
seq_printf(m, "pool=%d\n", ppp_data.pool_num);
@@ -460,8 +460,8 @@ static void pseries_cmo_data(struct seq_file *m)
return;
for_each_possible_cpu(cpu) {
- cmo_faults += lppaca[cpu].cmo_faults;
- cmo_fault_time += lppaca[cpu].cmo_fault_time;
+ cmo_faults += lppaca_of(cpu).cmo_faults;
+ cmo_fault_time += lppaca_of(cpu).cmo_fault_time;
}
seq_printf(m, "cmo_faults=%lu\n", cmo_faults);
@@ -479,8 +479,8 @@ static void splpar_dispatch_data(struct seq_file *m)
unsigned long dispatch_dispersions = 0;
for_each_possible_cpu(cpu) {
- dispatches += lppaca[cpu].yield_count;
- dispatch_dispersions += lppaca[cpu].dispersion_count;
+ dispatches += lppaca_of(cpu).yield_count;
+ dispatch_dispersions += lppaca_of(cpu).dispersion_count;
}
seq_printf(m, "dispatches=%lu\n", dispatches);
@@ -545,7 +545,7 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v)
seq_printf(m, "partition_potential_processors=%d\n",
partition_potential_processors);
- seq_printf(m, "shared_processor_mode=%d\n", lppaca[0].shared_proc);
+ seq_printf(m, "shared_processor_mode=%d\n", lppaca_of(0).shared_proc);
seq_printf(m, "slb_size=%d\n", mmu_slb_size);
@@ -780,6 +780,7 @@ static const struct file_operations lparcfg_fops = {
.write = lparcfg_write,
.open = lparcfg_open,
.release = single_release,
+ .llseek = seq_lseek,
};
static int __init lparcfg_init(void)
diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c
index dd6c141f1662..df7e20c191cd 100644
--- a/arch/powerpc/kernel/machine_kexec.c
+++ b/arch/powerpc/kernel/machine_kexec.c
@@ -14,10 +14,34 @@
#include <linux/threads.h>
#include <linux/memblock.h>
#include <linux/of.h>
+#include <linux/irq.h>
+
#include <asm/machdep.h>
#include <asm/prom.h>
#include <asm/sections.h>
+void machine_kexec_mask_interrupts(void) {
+ unsigned int i;
+
+ for_each_irq(i) {
+ struct irq_desc *desc = irq_to_desc(i);
+
+ if (!desc || !desc->chip)
+ continue;
+
+ if (desc->chip->eoi &&
+ desc->status & IRQ_INPROGRESS)
+ desc->chip->eoi(i);
+
+ if (desc->chip->mask)
+ desc->chip->mask(i);
+
+ if (desc->chip->disable &&
+ !(desc->status & IRQ_DISABLED))
+ desc->chip->disable(i);
+ }
+}
+
void machine_crash_shutdown(struct pt_regs *regs)
{
if (ppc_md.machine_crash_shutdown)
diff --git a/arch/powerpc/kernel/machine_kexec_32.c b/arch/powerpc/kernel/machine_kexec_32.c
index ae63a964b858..e63f2e7d2efb 100644
--- a/arch/powerpc/kernel/machine_kexec_32.c
+++ b/arch/powerpc/kernel/machine_kexec_32.c
@@ -39,6 +39,10 @@ void default_machine_kexec(struct kimage *image)
/* Interrupts aren't acceptable while we reboot */
local_irq_disable();
+ /* mask each interrupt so we are in a more sane state for the
+ * kexec kernel */
+ machine_kexec_mask_interrupts();
+
page_list = image->head;
/* we need both effective and real address here */
diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c
index 477c663e0140..49cee9df225b 100644
--- a/arch/powerpc/kernel/module.c
+++ b/arch/powerpc/kernel/module.c
@@ -63,11 +63,6 @@ int module_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs, struct module *me)
{
const Elf_Shdr *sect;
- int err;
-
- err = module_bug_finalize(hdr, sechdrs, me);
- if (err)
- return err;
/* Apply feature fixups */
sect = find_section(hdr, sechdrs, "__ftr_fixup");
@@ -101,5 +96,4 @@ int module_finalize(const Elf_Ehdr *hdr,
void module_arch_cleanup(struct module *mod)
{
- module_bug_cleanup(mod);
}
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index d0a26f1770fe..ebf9846f3c3b 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -27,6 +27,20 @@ extern unsigned long __toc_start;
#ifdef CONFIG_PPC_BOOK3S
/*
+ * We only have to have statically allocated lppaca structs on
+ * legacy iSeries, which supports at most 64 cpus.
+ */
+#ifdef CONFIG_PPC_ISERIES
+#if NR_CPUS < 64
+#define NR_LPPACAS NR_CPUS
+#else
+#define NR_LPPACAS 64
+#endif
+#else /* not iSeries */
+#define NR_LPPACAS 1
+#endif
+
+/*
* The structure which the hypervisor knows about - this structure
* should not cross a page boundary. The vpa_init/register_vpa call
* is now known to fail if the lppaca structure crosses a page
@@ -36,7 +50,7 @@ extern unsigned long __toc_start;
* will suffice to ensure that it doesn't cross a page boundary.
*/
struct lppaca lppaca[] = {
- [0 ... (NR_CPUS-1)] = {
+ [0 ... (NR_LPPACAS-1)] = {
.desc = 0xd397d781, /* "LpPa" */
.size = sizeof(struct lppaca),
.dyn_proc_status = 2,
@@ -49,6 +63,54 @@ struct lppaca lppaca[] = {
},
};
+static struct lppaca *extra_lppacas;
+static long __initdata lppaca_size;
+
+static void allocate_lppacas(int nr_cpus, unsigned long limit)
+{
+ if (nr_cpus <= NR_LPPACAS)
+ return;
+
+ lppaca_size = PAGE_ALIGN(sizeof(struct lppaca) *
+ (nr_cpus - NR_LPPACAS));
+ extra_lppacas = __va(memblock_alloc_base(lppaca_size,
+ PAGE_SIZE, limit));
+}
+
+static struct lppaca *new_lppaca(int cpu)
+{
+ struct lppaca *lp;
+
+ if (cpu < NR_LPPACAS)
+ return &lppaca[cpu];
+
+ lp = extra_lppacas + (cpu - NR_LPPACAS);
+ *lp = lppaca[0];
+
+ return lp;
+}
+
+static void free_lppacas(void)
+{
+ long new_size = 0, nr;
+
+ if (!lppaca_size)
+ return;
+ nr = num_possible_cpus() - NR_LPPACAS;
+ if (nr > 0)
+ new_size = PAGE_ALIGN(nr * sizeof(struct lppaca));
+ if (new_size >= lppaca_size)
+ return;
+
+ memblock_free(__pa(extra_lppacas) + new_size, lppaca_size - new_size);
+ lppaca_size = new_size;
+}
+
+#else
+
+static inline void allocate_lppacas(int nr_cpus, unsigned long limit) { }
+static inline void free_lppacas(void) { }
+
#endif /* CONFIG_PPC_BOOK3S */
#ifdef CONFIG_PPC_STD_MMU_64
@@ -88,7 +150,7 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu)
unsigned long kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL;
#ifdef CONFIG_PPC_BOOK3S
- new_paca->lppaca_ptr = &lppaca[cpu];
+ new_paca->lppaca_ptr = new_lppaca(cpu);
#else
new_paca->kernel_pgd = swapper_pg_dir;
#endif
@@ -127,7 +189,7 @@ void __init allocate_pacas(void)
* the first segment. On iSeries they must be within the area mapped
* by the HV, which is HvPagesToMap * HVPAGESIZE bytes.
*/
- limit = min(0x10000000ULL, memblock.rmo_size);
+ limit = min(0x10000000ULL, ppc64_rma_size);
if (firmware_has_feature(FW_FEATURE_ISERIES))
limit = min(limit, HvPagesToMap * HVPAGESIZE);
@@ -144,6 +206,8 @@ void __init allocate_pacas(void)
printk(KERN_DEBUG "Allocated %u bytes for %d pacas at %p\n",
paca_size, nr_cpus, paca);
+ allocate_lppacas(nr_cpus, limit);
+
/* Can't use for_each_*_cpu, as they aren't functional yet */
for (cpu = 0; cpu < nr_cpus; cpu++)
initialise_paca(&paca[cpu], cpu);
@@ -164,4 +228,6 @@ void __init free_unused_pacas(void)
paca_size - new_size);
paca_size = new_size;
+
+ free_lppacas();
}
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 9021c4ad4bbd..10a44e68ef11 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1090,8 +1090,6 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
bus->number, bus->self ? pci_name(bus->self) : "PHB");
list_for_each_entry(dev, &bus->devices, bus_list) {
- struct dev_archdata *sd = &dev->dev.archdata;
-
/* Cardbus can call us to add new devices to a bus, so ignore
* those who are already fully discovered
*/
@@ -1107,7 +1105,7 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
set_dev_node(&dev->dev, pcibus_to_node(dev->bus));
/* Hook up default DMA ops */
- sd->dma_ops = pci_dma_ops;
+ set_dma_ops(&dev->dev, pci_dma_ops);
set_dma_offset(&dev->dev, PCI_DRAM_OFFSET);
/* Additional platform DMA/iommu setup */
diff --git a/arch/powerpc/kernel/perf_callchain.c b/arch/powerpc/kernel/perf_callchain.c
index 95ad9dad298e..d05ae4204bbf 100644
--- a/arch/powerpc/kernel/perf_callchain.c
+++ b/arch/powerpc/kernel/perf_callchain.c
@@ -23,18 +23,6 @@
#include "ppc32.h"
#endif
-/*
- * Store another value in a callchain_entry.
- */
-static inline void callchain_store(struct perf_callchain_entry *entry, u64 ip)
-{
- unsigned int nr = entry->nr;
-
- if (nr < PERF_MAX_STACK_DEPTH) {
- entry->ip[nr] = ip;
- entry->nr = nr + 1;
- }
-}
/*
* Is sp valid as the address of the next kernel stack frame after prev_sp?
@@ -58,8 +46,8 @@ static int valid_next_sp(unsigned long sp, unsigned long prev_sp)
return 0;
}
-static void perf_callchain_kernel(struct pt_regs *regs,
- struct perf_callchain_entry *entry)
+void
+perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs)
{
unsigned long sp, next_sp;
unsigned long next_ip;
@@ -69,8 +57,7 @@ static void perf_callchain_kernel(struct pt_regs *regs,
lr = regs->link;
sp = regs->gpr[1];
- callchain_store(entry, PERF_CONTEXT_KERNEL);
- callchain_store(entry, regs->nip);
+ perf_callchain_store(entry, regs->nip);
if (!validate_sp(sp, current, STACK_FRAME_OVERHEAD))
return;
@@ -89,7 +76,7 @@ static void perf_callchain_kernel(struct pt_regs *regs,
next_ip = regs->nip;
lr = regs->link;
level = 0;
- callchain_store(entry, PERF_CONTEXT_KERNEL);
+ perf_callchain_store(entry, PERF_CONTEXT_KERNEL);
} else {
if (level == 0)
@@ -111,7 +98,7 @@ static void perf_callchain_kernel(struct pt_regs *regs,
++level;
}
- callchain_store(entry, next_ip);
+ perf_callchain_store(entry, next_ip);
if (!valid_next_sp(next_sp, sp))
return;
sp = next_sp;
@@ -233,8 +220,8 @@ static int sane_signal_64_frame(unsigned long sp)
puc == (unsigned long) &sf->uc;
}
-static void perf_callchain_user_64(struct pt_regs *regs,
- struct perf_callchain_entry *entry)
+static void perf_callchain_user_64(struct perf_callchain_entry *entry,
+ struct pt_regs *regs)
{
unsigned long sp, next_sp;
unsigned long next_ip;
@@ -246,8 +233,7 @@ static void perf_callchain_user_64(struct pt_regs *regs,
next_ip = regs->nip;
lr = regs->link;
sp = regs->gpr[1];
- callchain_store(entry, PERF_CONTEXT_USER);
- callchain_store(entry, next_ip);
+ perf_callchain_store(entry, next_ip);
for (;;) {
fp = (unsigned long __user *) sp;
@@ -276,14 +262,14 @@ static void perf_callchain_user_64(struct pt_regs *regs,
read_user_stack_64(&uregs[PT_R1], &sp))
return;
level = 0;
- callchain_store(entry, PERF_CONTEXT_USER);
- callchain_store(entry, next_ip);
+ perf_callchain_store(entry, PERF_CONTEXT_USER);
+ perf_callchain_store(entry, next_ip);
continue;
}
if (level == 0)
next_ip = lr;
- callchain_store(entry, next_ip);
+ perf_callchain_store(entry, next_ip);
++level;
sp = next_sp;
}
@@ -315,8 +301,8 @@ static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
return __get_user_inatomic(*ret, ptr);
}
-static inline void perf_callchain_user_64(struct pt_regs *regs,
- struct perf_callchain_entry *entry)
+static inline void perf_callchain_user_64(struct perf_callchain_entry *entry,
+ struct pt_regs *regs)
{
}
@@ -435,8 +421,8 @@ static unsigned int __user *signal_frame_32_regs(unsigned int sp,
return mctx->mc_gregs;
}
-static void perf_callchain_user_32(struct pt_regs *regs,
- struct perf_callchain_entry *entry)
+static void perf_callchain_user_32(struct perf_callchain_entry *entry,
+ struct pt_regs *regs)
{
unsigned int sp, next_sp;
unsigned int next_ip;
@@ -447,8 +433,7 @@ static void perf_callchain_user_32(struct pt_regs *regs,
next_ip = regs->nip;
lr = regs->link;
sp = regs->gpr[1];
- callchain_store(entry, PERF_CONTEXT_USER);
- callchain_store(entry, next_ip);
+ perf_callchain_store(entry, next_ip);
while (entry->nr < PERF_MAX_STACK_DEPTH) {
fp = (unsigned int __user *) (unsigned long) sp;
@@ -470,45 +455,24 @@ static void perf_callchain_user_32(struct pt_regs *regs,
read_user_stack_32(&uregs[PT_R1], &sp))
return;
level = 0;
- callchain_store(entry, PERF_CONTEXT_USER);
- callchain_store(entry, next_ip);
+ perf_callchain_store(entry, PERF_CONTEXT_USER);
+ perf_callchain_store(entry, next_ip);
continue;
}
if (level == 0)
next_ip = lr;
- callchain_store(entry, next_ip);
+ perf_callchain_store(entry, next_ip);
++level;
sp = next_sp;
}
}
-/*
- * Since we can't get PMU interrupts inside a PMU interrupt handler,
- * we don't need separate irq and nmi entries here.
- */
-static DEFINE_PER_CPU(struct perf_callchain_entry, cpu_perf_callchain);
-
-struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
+void
+perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
{
- struct perf_callchain_entry *entry = &__get_cpu_var(cpu_perf_callchain);
-
- entry->nr = 0;
-
- if (!user_mode(regs)) {
- perf_callchain_kernel(regs, entry);
- if (current->mm)
- regs = task_pt_regs(current);
- else
- regs = NULL;
- }
-
- if (regs) {
- if (current_is_64bit())
- perf_callchain_user_64(regs, entry);
- else
- perf_callchain_user_32(regs, entry);
- }
-
- return entry;
+ if (current_is_64bit())
+ perf_callchain_user_64(entry, regs);
+ else
+ perf_callchain_user_32(entry, regs);
}
diff --git a/arch/powerpc/kernel/perf_event.c b/arch/powerpc/kernel/perf_event.c
index d301a30445e0..3129c855933c 100644
--- a/arch/powerpc/kernel/perf_event.c
+++ b/arch/powerpc/kernel/perf_event.c
@@ -402,6 +402,9 @@ static void power_pmu_read(struct perf_event *event)
{
s64 val, delta, prev;
+ if (event->hw.state & PERF_HES_STOPPED)
+ return;
+
if (!event->hw.idx)
return;
/*
@@ -517,7 +520,7 @@ static void write_mmcr0(struct cpu_hw_events *cpuhw, unsigned long mmcr0)
* Disable all events to prevent PMU interrupts and to allow
* events to be added or removed.
*/
-void hw_perf_disable(void)
+static void power_pmu_disable(struct pmu *pmu)
{
struct cpu_hw_events *cpuhw;
unsigned long flags;
@@ -565,7 +568,7 @@ void hw_perf_disable(void)
* If we were previously disabled and events were added, then
* put the new config on the PMU.
*/
-void hw_perf_enable(void)
+static void power_pmu_enable(struct pmu *pmu)
{
struct perf_event *event;
struct cpu_hw_events *cpuhw;
@@ -672,6 +675,8 @@ void hw_perf_enable(void)
}
local64_set(&event->hw.prev_count, val);
event->hw.idx = idx;
+ if (event->hw.state & PERF_HES_STOPPED)
+ val = 0;
write_pmc(idx, val);
perf_event_update_userpage(event);
}
@@ -727,7 +732,7 @@ static int collect_events(struct perf_event *group, int max_count,
* re-enable the PMU in order to get hw_perf_enable to do the
* actual work of reconfiguring the PMU.
*/
-static int power_pmu_enable(struct perf_event *event)
+static int power_pmu_add(struct perf_event *event, int ef_flags)
{
struct cpu_hw_events *cpuhw;
unsigned long flags;
@@ -735,7 +740,7 @@ static int power_pmu_enable(struct perf_event *event)
int ret = -EAGAIN;
local_irq_save(flags);
- perf_disable();
+ perf_pmu_disable(event->pmu);
/*
* Add the event to the list (if there is room)
@@ -749,6 +754,9 @@ static int power_pmu_enable(struct perf_event *event)
cpuhw->events[n0] = event->hw.config;
cpuhw->flags[n0] = event->hw.event_base;
+ if (!(ef_flags & PERF_EF_START))
+ event->hw.state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
+
/*
* If group events scheduling transaction was started,
* skip the schedulability test here, it will be peformed
@@ -769,7 +777,7 @@ nocheck:
ret = 0;
out:
- perf_enable();
+ perf_pmu_enable(event->pmu);
local_irq_restore(flags);
return ret;
}
@@ -777,14 +785,14 @@ nocheck:
/*
* Remove a event from the PMU.
*/
-static void power_pmu_disable(struct perf_event *event)
+static void power_pmu_del(struct perf_event *event, int ef_flags)
{
struct cpu_hw_events *cpuhw;
long i;
unsigned long flags;
local_irq_save(flags);
- perf_disable();
+ perf_pmu_disable(event->pmu);
power_pmu_read(event);
@@ -821,34 +829,60 @@ static void power_pmu_disable(struct perf_event *event)
cpuhw->mmcr[0] &= ~(MMCR0_PMXE | MMCR0_FCECE);
}
- perf_enable();
+ perf_pmu_enable(event->pmu);
local_irq_restore(flags);
}
/*
- * Re-enable interrupts on a event after they were throttled
- * because they were coming too fast.
+ * POWER-PMU does not support disabling individual counters, hence
+ * program their cycle counter to their max value and ignore the interrupts.
*/
-static void power_pmu_unthrottle(struct perf_event *event)
+
+static void power_pmu_start(struct perf_event *event, int ef_flags)
+{
+ unsigned long flags;
+ s64 left;
+
+ if (!event->hw.idx || !event->hw.sample_period)
+ return;
+
+ if (!(event->hw.state & PERF_HES_STOPPED))
+ return;
+
+ if (ef_flags & PERF_EF_RELOAD)
+ WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE));
+
+ local_irq_save(flags);
+ perf_pmu_disable(event->pmu);
+
+ event->hw.state = 0;
+ left = local64_read(&event->hw.period_left);
+ write_pmc(event->hw.idx, left);
+
+ perf_event_update_userpage(event);
+ perf_pmu_enable(event->pmu);
+ local_irq_restore(flags);
+}
+
+static void power_pmu_stop(struct perf_event *event, int ef_flags)
{
- s64 val, left;
unsigned long flags;
if (!event->hw.idx || !event->hw.sample_period)
return;
+
+ if (event->hw.state & PERF_HES_STOPPED)
+ return;
+
local_irq_save(flags);
- perf_disable();
+ perf_pmu_disable(event->pmu);
+
power_pmu_read(event);
- left = event->hw.sample_period;
- event->hw.last_period = left;
- val = 0;
- if (left < 0x80000000L)
- val = 0x80000000L - left;
- write_pmc(event->hw.idx, val);
- local64_set(&event->hw.prev_count, val);
- local64_set(&event->hw.period_left, left);
+ event->hw.state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
+ write_pmc(event->hw.idx, 0);
+
perf_event_update_userpage(event);
- perf_enable();
+ perf_pmu_enable(event->pmu);
local_irq_restore(flags);
}
@@ -857,10 +891,11 @@ static void power_pmu_unthrottle(struct perf_event *event)
* Set the flag to make pmu::enable() not perform the
* schedulability test, it will be performed at commit time
*/
-void power_pmu_start_txn(const struct pmu *pmu)
+void power_pmu_start_txn(struct pmu *pmu)
{
struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
+ perf_pmu_disable(pmu);
cpuhw->group_flag |= PERF_EVENT_TXN;
cpuhw->n_txn_start = cpuhw->n_events;
}
@@ -870,11 +905,12 @@ void power_pmu_start_txn(const struct pmu *pmu)
* Clear the flag and pmu::enable() will perform the
* schedulability test.
*/
-void power_pmu_cancel_txn(const struct pmu *pmu)
+void power_pmu_cancel_txn(struct pmu *pmu)
{
struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
cpuhw->group_flag &= ~PERF_EVENT_TXN;
+ perf_pmu_enable(pmu);
}
/*
@@ -882,7 +918,7 @@ void power_pmu_cancel_txn(const struct pmu *pmu)
* Perform the group schedulability test as a whole
* Return 0 if success
*/
-int power_pmu_commit_txn(const struct pmu *pmu)
+int power_pmu_commit_txn(struct pmu *pmu)
{
struct cpu_hw_events *cpuhw;
long i, n;
@@ -901,19 +937,10 @@ int power_pmu_commit_txn(const struct pmu *pmu)
cpuhw->event[i]->hw.config = cpuhw->events[i];
cpuhw->group_flag &= ~PERF_EVENT_TXN;
+ perf_pmu_enable(pmu);
return 0;
}
-struct pmu power_pmu = {
- .enable = power_pmu_enable,
- .disable = power_pmu_disable,
- .read = power_pmu_read,
- .unthrottle = power_pmu_unthrottle,
- .start_txn = power_pmu_start_txn,
- .cancel_txn = power_pmu_cancel_txn,
- .commit_txn = power_pmu_commit_txn,
-};
-
/*
* Return 1 if we might be able to put event on a limited PMC,
* or 0 if not.
@@ -1014,7 +1041,7 @@ static int hw_perf_cache_event(u64 config, u64 *eventp)
return 0;
}
-const struct pmu *hw_perf_event_init(struct perf_event *event)
+static int power_pmu_event_init(struct perf_event *event)
{
u64 ev;
unsigned long flags;
@@ -1026,25 +1053,27 @@ const struct pmu *hw_perf_event_init(struct perf_event *event)
struct cpu_hw_events *cpuhw;
if (!ppmu)
- return ERR_PTR(-ENXIO);
+ return -ENOENT;
+
switch (event->attr.type) {
case PERF_TYPE_HARDWARE:
ev = event->attr.config;
if (ev >= ppmu->n_generic || ppmu->generic_events[ev] == 0)
- return ERR_PTR(-EOPNOTSUPP);
+ return -EOPNOTSUPP;
ev = ppmu->generic_events[ev];
break;
case PERF_TYPE_HW_CACHE:
err = hw_perf_cache_event(event->attr.config, &ev);
if (err)
- return ERR_PTR(err);
+ return err;
break;
case PERF_TYPE_RAW:
ev = event->attr.config;
break;
default:
- return ERR_PTR(-EINVAL);
+ return -ENOENT;
}
+
event->hw.config_base = ev;
event->hw.idx = 0;
@@ -1063,7 +1092,7 @@ const struct pmu *hw_perf_event_init(struct perf_event *event)
* XXX we should check if the task is an idle task.
*/
flags = 0;
- if (event->ctx->task)
+ if (event->attach_state & PERF_ATTACH_TASK)
flags |= PPMU_ONLY_COUNT_RUN;
/*
@@ -1081,7 +1110,7 @@ const struct pmu *hw_perf_event_init(struct perf_event *event)
*/
ev = normal_pmc_alternative(ev, flags);
if (!ev)
- return ERR_PTR(-EINVAL);
+ return -EINVAL;
}
}
@@ -1095,19 +1124,19 @@ const struct pmu *hw_perf_event_init(struct perf_event *event)
n = collect_events(event->group_leader, ppmu->n_counter - 1,
ctrs, events, cflags);
if (n < 0)
- return ERR_PTR(-EINVAL);
+ return -EINVAL;
}
events[n] = ev;
ctrs[n] = event;
cflags[n] = flags;
if (check_excludes(ctrs, cflags, n, 1))
- return ERR_PTR(-EINVAL);
+ return -EINVAL;
cpuhw = &get_cpu_var(cpu_hw_events);
err = power_check_constraints(cpuhw, events, cflags, n + 1);
put_cpu_var(cpu_hw_events);
if (err)
- return ERR_PTR(-EINVAL);
+ return -EINVAL;
event->hw.config = events[n];
event->hw.event_base = cflags[n];
@@ -1132,11 +1161,23 @@ const struct pmu *hw_perf_event_init(struct perf_event *event)
}
event->destroy = hw_perf_event_destroy;
- if (err)
- return ERR_PTR(err);
- return &power_pmu;
+ return err;
}
+struct pmu power_pmu = {
+ .pmu_enable = power_pmu_enable,
+ .pmu_disable = power_pmu_disable,
+ .event_init = power_pmu_event_init,
+ .add = power_pmu_add,
+ .del = power_pmu_del,
+ .start = power_pmu_start,
+ .stop = power_pmu_stop,
+ .read = power_pmu_read,
+ .start_txn = power_pmu_start_txn,
+ .cancel_txn = power_pmu_cancel_txn,
+ .commit_txn = power_pmu_commit_txn,
+};
+
/*
* A counter has overflowed; update its count and record
* things if requested. Note that interrupts are hard-disabled
@@ -1149,6 +1190,11 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
s64 prev, delta, left;
int record = 0;
+ if (event->hw.state & PERF_HES_STOPPED) {
+ write_pmc(event->hw.idx, 0);
+ return;
+ }
+
/* we don't have to worry about interrupts here */
prev = local64_read(&event->hw.prev_count);
delta = (val - prev) & 0xfffffffful;
@@ -1171,6 +1217,11 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
val = 0x80000000LL - left;
}
+ write_pmc(event->hw.idx, val);
+ local64_set(&event->hw.prev_count, val);
+ local64_set(&event->hw.period_left, left);
+ perf_event_update_userpage(event);
+
/*
* Finally record data if requested.
*/
@@ -1183,23 +1234,9 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
if (event->attr.sample_type & PERF_SAMPLE_ADDR)
perf_get_data_addr(regs, &data.addr);
- if (perf_event_overflow(event, nmi, &data, regs)) {
- /*
- * Interrupts are coming too fast - throttle them
- * by setting the event to 0, so it will be
- * at least 2^30 cycles until the next interrupt
- * (assuming each event counts at most 2 counts
- * per cycle).
- */
- val = 0;
- left = ~0ULL >> 1;
- }
+ if (perf_event_overflow(event, nmi, &data, regs))
+ power_pmu_stop(event, 0);
}
-
- write_pmc(event->hw.idx, val);
- local64_set(&event->hw.prev_count, val);
- local64_set(&event->hw.period_left, left);
- perf_event_update_userpage(event);
}
/*
@@ -1342,6 +1379,7 @@ int register_power_pmu(struct power_pmu *pmu)
freeze_events_kernel = MMCR0_FCHV;
#endif /* CONFIG_PPC64 */
+ perf_pmu_register(&power_pmu);
perf_cpu_notifier(power_pmu_notifier);
return 0;
diff --git a/arch/powerpc/kernel/perf_event_fsl_emb.c b/arch/powerpc/kernel/perf_event_fsl_emb.c
index 1ba45471ae43..7ecca59ddf77 100644
--- a/arch/powerpc/kernel/perf_event_fsl_emb.c
+++ b/arch/powerpc/kernel/perf_event_fsl_emb.c
@@ -156,6 +156,9 @@ static void fsl_emb_pmu_read(struct perf_event *event)
{
s64 val, delta, prev;
+ if (event->hw.state & PERF_HES_STOPPED)
+ return;
+
/*
* Performance monitor interrupts come even when interrupts
* are soft-disabled, as long as interrupts are hard-enabled.
@@ -177,7 +180,7 @@ static void fsl_emb_pmu_read(struct perf_event *event)
* Disable all events to prevent PMU interrupts and to allow
* events to be added or removed.
*/
-void hw_perf_disable(void)
+static void fsl_emb_pmu_disable(struct pmu *pmu)
{
struct cpu_hw_events *cpuhw;
unsigned long flags;
@@ -216,7 +219,7 @@ void hw_perf_disable(void)
* If we were previously disabled and events were added, then
* put the new config on the PMU.
*/
-void hw_perf_enable(void)
+static void fsl_emb_pmu_enable(struct pmu *pmu)
{
struct cpu_hw_events *cpuhw;
unsigned long flags;
@@ -262,8 +265,8 @@ static int collect_events(struct perf_event *group, int max_count,
return n;
}
-/* perf must be disabled, context locked on entry */
-static int fsl_emb_pmu_enable(struct perf_event *event)
+/* context locked on entry */
+static int fsl_emb_pmu_add(struct perf_event *event, int flags)
{
struct cpu_hw_events *cpuhw;
int ret = -EAGAIN;
@@ -271,6 +274,7 @@ static int fsl_emb_pmu_enable(struct perf_event *event)
u64 val;
int i;
+ perf_pmu_disable(event->pmu);
cpuhw = &get_cpu_var(cpu_hw_events);
if (event->hw.config & FSL_EMB_EVENT_RESTRICTED)
@@ -301,6 +305,12 @@ static int fsl_emb_pmu_enable(struct perf_event *event)
val = 0x80000000L - left;
}
local64_set(&event->hw.prev_count, val);
+
+ if (!(flags & PERF_EF_START)) {
+ event->hw.state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
+ val = 0;
+ }
+
write_pmc(i, val);
perf_event_update_userpage(event);
@@ -310,15 +320,17 @@ static int fsl_emb_pmu_enable(struct perf_event *event)
ret = 0;
out:
put_cpu_var(cpu_hw_events);
+ perf_pmu_enable(event->pmu);
return ret;
}
-/* perf must be disabled, context locked on entry */
-static void fsl_emb_pmu_disable(struct perf_event *event)
+/* context locked on entry */
+static void fsl_emb_pmu_del(struct perf_event *event, int flags)
{
struct cpu_hw_events *cpuhw;
int i = event->hw.idx;
+ perf_pmu_disable(event->pmu);
if (i < 0)
goto out;
@@ -346,44 +358,57 @@ static void fsl_emb_pmu_disable(struct perf_event *event)
cpuhw->n_events--;
out:
+ perf_pmu_enable(event->pmu);
put_cpu_var(cpu_hw_events);
}
-/*
- * Re-enable interrupts on a event after they were throttled
- * because they were coming too fast.
- *
- * Context is locked on entry, but perf is not disabled.
- */
-static void fsl_emb_pmu_unthrottle(struct perf_event *event)
+static void fsl_emb_pmu_start(struct perf_event *event, int ef_flags)
{
- s64 val, left;
unsigned long flags;
+ s64 left;
if (event->hw.idx < 0 || !event->hw.sample_period)
return;
+
+ if (!(event->hw.state & PERF_HES_STOPPED))
+ return;
+
+ if (ef_flags & PERF_EF_RELOAD)
+ WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE));
+
local_irq_save(flags);
- perf_disable();
- fsl_emb_pmu_read(event);
- left = event->hw.sample_period;
- event->hw.last_period = left;
- val = 0;
- if (left < 0x80000000L)
- val = 0x80000000L - left;
- write_pmc(event->hw.idx, val);
- local64_set(&event->hw.prev_count, val);
- local64_set(&event->hw.period_left, left);
+ perf_pmu_disable(event->pmu);
+
+ event->hw.state = 0;
+ left = local64_read(&event->hw.period_left);
+ write_pmc(event->hw.idx, left);
+
perf_event_update_userpage(event);
- perf_enable();
+ perf_pmu_enable(event->pmu);
local_irq_restore(flags);
}
-static struct pmu fsl_emb_pmu = {
- .enable = fsl_emb_pmu_enable,
- .disable = fsl_emb_pmu_disable,
- .read = fsl_emb_pmu_read,
- .unthrottle = fsl_emb_pmu_unthrottle,
-};
+static void fsl_emb_pmu_stop(struct perf_event *event, int ef_flags)
+{
+ unsigned long flags;
+
+ if (event->hw.idx < 0 || !event->hw.sample_period)
+ return;
+
+ if (event->hw.state & PERF_HES_STOPPED)
+ return;
+
+ local_irq_save(flags);
+ perf_pmu_disable(event->pmu);
+
+ fsl_emb_pmu_read(event);
+ event->hw.state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
+ write_pmc(event->hw.idx, 0);
+
+ perf_event_update_userpage(event);
+ perf_pmu_enable(event->pmu);
+ local_irq_restore(flags);
+}
/*
* Release the PMU if this is the last perf_event.
@@ -428,7 +453,7 @@ static int hw_perf_cache_event(u64 config, u64 *eventp)
return 0;
}
-const struct pmu *hw_perf_event_init(struct perf_event *event)
+static int fsl_emb_pmu_event_init(struct perf_event *event)
{
u64 ev;
struct perf_event *events[MAX_HWEVENTS];
@@ -441,14 +466,14 @@ const struct pmu *hw_perf_event_init(struct perf_event *event)
case PERF_TYPE_HARDWARE:
ev = event->attr.config;
if (ev >= ppmu->n_generic || ppmu->generic_events[ev] == 0)
- return ERR_PTR(-EOPNOTSUPP);
+ return -EOPNOTSUPP;
ev = ppmu->generic_events[ev];
break;
case PERF_TYPE_HW_CACHE:
err = hw_perf_cache_event(event->attr.config, &ev);
if (err)
- return ERR_PTR(err);
+ return err;
break;
case PERF_TYPE_RAW:
@@ -456,12 +481,12 @@ const struct pmu *hw_perf_event_init(struct perf_event *event)
break;
default:
- return ERR_PTR(-EINVAL);
+ return -ENOENT;
}
event->hw.config = ppmu->xlate_event(ev);
if (!(event->hw.config & FSL_EMB_EVENT_VALID))
- return ERR_PTR(-EINVAL);
+ return -EINVAL;
/*
* If this is in a group, check if it can go on with all the
@@ -473,7 +498,7 @@ const struct pmu *hw_perf_event_init(struct perf_event *event)
n = collect_events(event->group_leader,
ppmu->n_counter - 1, events);
if (n < 0)
- return ERR_PTR(-EINVAL);
+ return -EINVAL;
}
if (event->hw.config & FSL_EMB_EVENT_RESTRICTED) {
@@ -484,7 +509,7 @@ const struct pmu *hw_perf_event_init(struct perf_event *event)
}
if (num_restricted >= ppmu->n_restricted)
- return ERR_PTR(-EINVAL);
+ return -EINVAL;
}
event->hw.idx = -1;
@@ -497,7 +522,7 @@ const struct pmu *hw_perf_event_init(struct perf_event *event)
if (event->attr.exclude_kernel)
event->hw.config_base |= PMLCA_FCS;
if (event->attr.exclude_idle)
- return ERR_PTR(-ENOTSUPP);
+ return -ENOTSUPP;
event->hw.last_period = event->hw.sample_period;
local64_set(&event->hw.period_left, event->hw.last_period);
@@ -523,11 +548,20 @@ const struct pmu *hw_perf_event_init(struct perf_event *event)
}
event->destroy = hw_perf_event_destroy;
- if (err)
- return ERR_PTR(err);
- return &fsl_emb_pmu;
+ return err;
}
+static struct pmu fsl_emb_pmu = {
+ .pmu_enable = fsl_emb_pmu_enable,
+ .pmu_disable = fsl_emb_pmu_disable,
+ .event_init = fsl_emb_pmu_event_init,
+ .add = fsl_emb_pmu_add,
+ .del = fsl_emb_pmu_del,
+ .start = fsl_emb_pmu_start,
+ .stop = fsl_emb_pmu_stop,
+ .read = fsl_emb_pmu_read,
+};
+
/*
* A counter has overflowed; update its count and record
* things if requested. Note that interrupts are hard-disabled
@@ -540,6 +574,11 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
s64 prev, delta, left;
int record = 0;
+ if (event->hw.state & PERF_HES_STOPPED) {
+ write_pmc(event->hw.idx, 0);
+ return;
+ }
+
/* we don't have to worry about interrupts here */
prev = local64_read(&event->hw.prev_count);
delta = (val - prev) & 0xfffffffful;
@@ -562,6 +601,11 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
val = 0x80000000LL - left;
}
+ write_pmc(event->hw.idx, val);
+ local64_set(&event->hw.prev_count, val);
+ local64_set(&event->hw.period_left, left);
+ perf_event_update_userpage(event);
+
/*
* Finally record data if requested.
*/
@@ -571,23 +615,9 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
perf_sample_data_init(&data, 0);
data.period = event->hw.last_period;
- if (perf_event_overflow(event, nmi, &data, regs)) {
- /*
- * Interrupts are coming too fast - throttle them
- * by setting the event to 0, so it will be
- * at least 2^30 cycles until the next interrupt
- * (assuming each event counts at most 2 counts
- * per cycle).
- */
- val = 0;
- left = ~0ULL >> 1;
- }
+ if (perf_event_overflow(event, nmi, &data, regs))
+ fsl_emb_pmu_stop(event, 0);
}
-
- write_pmc(event->hw.idx, val);
- local64_set(&event->hw.prev_count, val);
- local64_set(&event->hw.period_left, left);
- perf_event_update_userpage(event);
}
static void perf_event_interrupt(struct pt_regs *regs)
@@ -651,5 +681,7 @@ int register_fsl_emb_pmu(struct fsl_emb_pmu *pmu)
pr_info("%s performance monitor hardware support registered\n",
pmu->name);
+ perf_pmu_register(&fsl_emb_pmu);
+
return 0;
}
diff --git a/arch/powerpc/kernel/ppc970-pmu.c b/arch/powerpc/kernel/ppc970-pmu.c
index 8eff48e20dba..3fee685de4df 100644
--- a/arch/powerpc/kernel/ppc970-pmu.c
+++ b/arch/powerpc/kernel/ppc970-pmu.c
@@ -169,9 +169,11 @@ static int p970_marked_instr_event(u64 event)
switch (unit) {
case PM_VPU:
mask = 0x4c; /* byte 0 bits 2,3,6 */
+ break;
case PM_LSU0:
/* byte 2 bits 0,2,3,4,6; all of byte 1 */
mask = 0x085dff00;
+ break;
case PM_LSU1L:
mask = 0x50 << 24; /* byte 3 bits 4,6 */
break;
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index b1c648a36b03..84906d3fc860 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -517,7 +517,6 @@ struct task_struct *__switch_to(struct task_struct *prev,
account_system_vtime(current);
account_process_vtime(current);
- calculate_steal_time();
/*
* We can't take a PMU exception inside _switch() since there is a
@@ -1298,14 +1297,3 @@ unsigned long randomize_et_dyn(unsigned long base)
return ret;
}
-
-#ifdef CONFIG_SMP
-int arch_sd_sibling_asym_packing(void)
-{
- if (cpu_has_feature(CPU_FTR_ASYM_SMT)) {
- printk_once(KERN_INFO "Enabling Asymmetric SMT scheduling\n");
- return SD_ASYM_PACKING;
- }
- return 0;
-}
-#endif
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index fed9bf6187d1..9e3132db718b 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -66,6 +66,7 @@
int __initdata iommu_is_off;
int __initdata iommu_force_on;
unsigned long tce_alloc_start, tce_alloc_end;
+u64 ppc64_rma_size;
#endif
static int __init early_parse_mem(char *p)
@@ -98,7 +99,7 @@ static void __init move_device_tree(void)
if ((memory_limit && (start + size) > memory_limit) ||
overlaps_crashkernel(start, size)) {
- p = __va(memblock_alloc_base(size, PAGE_SIZE, memblock.rmo_size));
+ p = __va(memblock_alloc(size, PAGE_SIZE));
memcpy(p, initial_boot_params, size);
initial_boot_params = (struct boot_param_header *)p;
DBG("Moved device tree to 0x%p\n", p);
@@ -363,10 +364,15 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
return 0;
}
-void __init early_init_dt_scan_chosen_arch(unsigned long node)
+int __init early_init_dt_scan_chosen_ppc(unsigned long node, const char *uname,
+ int depth, void *data)
{
unsigned long *lprop;
+ /* Use common scan routine to determine if this is the chosen node */
+ if (early_init_dt_scan_chosen(node, uname, depth, data) == 0)
+ return 0;
+
#ifdef CONFIG_PPC64
/* check if iommu is forced on or off */
if (of_get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL)
@@ -398,6 +404,9 @@ void __init early_init_dt_scan_chosen_arch(unsigned long node)
if (lprop)
crashk_res.end = crashk_res.start + *lprop - 1;
#endif
+
+ /* break now */
+ return 1;
}
#ifdef CONFIG_PPC_PSERIES
@@ -492,7 +501,7 @@ static int __init early_init_dt_scan_memory_ppc(unsigned long node,
void __init early_init_dt_add_memory_arch(u64 base, u64 size)
{
-#if defined(CONFIG_PPC64)
+#ifdef CONFIG_PPC64
if (iommu_is_off) {
if (base >= 0x80000000ul)
return;
@@ -501,9 +510,13 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
}
#endif
- memblock_add(base, size);
-
+ /* First MEMBLOCK added, do some special initializations */
+ if (memstart_addr == ~(phys_addr_t)0)
+ setup_initial_memory_limit(base, size);
memstart_addr = min((u64)memstart_addr, base);
+
+ /* Add the chunk to the MEMBLOCK list */
+ memblock_add(base, size);
}
u64 __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
@@ -655,7 +668,6 @@ static void __init phyp_dump_reserve_mem(void)
static inline void __init phyp_dump_reserve_mem(void) {}
#endif /* CONFIG_PHYP_DUMP && CONFIG_PPC_RTAS */
-
void __init early_init_devtree(void *params)
{
phys_addr_t limit;
@@ -679,10 +691,11 @@ void __init early_init_devtree(void *params)
* device-tree, including the platform type, initrd location and
* size, TCE reserve, and more ...
*/
- of_scan_flat_dt(early_init_dt_scan_chosen, NULL);
+ of_scan_flat_dt(early_init_dt_scan_chosen_ppc, NULL);
/* Scan memory nodes and rebuild MEMBLOCKs */
memblock_init();
+
of_scan_flat_dt(early_init_dt_scan_root, NULL);
of_scan_flat_dt(early_init_dt_scan_memory_ppc, NULL);
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 11f3cd9c832f..286d9783d93f 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1681,7 +1681,7 @@ long do_syscall_trace_enter(struct pt_regs *regs)
if (unlikely(current->audit_context)) {
#ifdef CONFIG_PPC64
- if (!test_thread_flag(TIF_32BIT))
+ if (!is_32bit_task())
audit_syscall_entry(AUDIT_ARCH_PPC64,
regs->gpr[0],
regs->gpr[3], regs->gpr[4],
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 41048de3c6c3..8fe8bc61c10a 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -805,7 +805,7 @@ static void rtas_percpu_suspend_me(void *info)
__rtas_suspend_cpu((struct rtas_suspend_me_data *)info, 1);
}
-static int rtas_ibm_suspend_me(struct rtas_args *args)
+int rtas_ibm_suspend_me(struct rtas_args *args)
{
long state;
long rc;
@@ -855,7 +855,7 @@ static int rtas_ibm_suspend_me(struct rtas_args *args)
return atomic_read(&data.error);
}
#else /* CONFIG_PPC_PSERIES */
-static int rtas_ibm_suspend_me(struct rtas_args *args)
+int rtas_ibm_suspend_me(struct rtas_args *args)
{
return -ENOSYS;
}
@@ -969,7 +969,7 @@ void __init rtas_initialize(void)
*/
#ifdef CONFIG_PPC64
if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR)) {
- rtas_region = min(memblock.rmo_size, RTAS_INSTANTIATE_MAX);
+ rtas_region = min(ppc64_rma_size, RTAS_INSTANTIATE_MAX);
ibm_suspend_me_token = rtas_token("ibm,suspend-me");
}
#endif
diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c
index 67a84d8f118d..2b442e6c21e6 100644
--- a/arch/powerpc/kernel/rtas_flash.c
+++ b/arch/powerpc/kernel/rtas_flash.c
@@ -716,6 +716,7 @@ static const struct file_operations rtas_flash_operations = {
.write = rtas_flash_write,
.open = rtas_excl_open,
.release = rtas_flash_release,
+ .llseek = default_llseek,
};
static const struct file_operations manage_flash_operations = {
@@ -724,6 +725,7 @@ static const struct file_operations manage_flash_operations = {
.write = manage_flash_write,
.open = rtas_excl_open,
.release = rtas_excl_release,
+ .llseek = default_llseek,
};
static const struct file_operations validate_flash_operations = {
@@ -732,6 +734,7 @@ static const struct file_operations validate_flash_operations = {
.write = validate_flash_write,
.open = rtas_excl_open,
.release = validate_flash_release,
+ .llseek = default_llseek,
};
static int __init rtas_flash_init(void)
diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c
index 638883e23e3a..0438f819fe6b 100644
--- a/arch/powerpc/kernel/rtasd.c
+++ b/arch/powerpc/kernel/rtasd.c
@@ -354,6 +354,7 @@ static const struct file_operations proc_rtas_log_operations = {
.poll = rtas_log_poll,
.open = rtas_log_open,
.release = rtas_log_release,
+ .llseek = noop_llseek,
};
static int enable_surveillance(int timeout)
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 93666f9cabf1..1d2fbc905303 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -46,7 +46,7 @@
extern void bootx_init(unsigned long r4, unsigned long phys);
-int boot_cpuid;
+int boot_cpuid = -1;
EXPORT_SYMBOL_GPL(boot_cpuid);
int boot_cpuid_phys;
@@ -246,7 +246,7 @@ static void __init irqstack_early_init(void)
unsigned int i;
/* interrupt stacks must be in lowmem, we get that for free on ppc32
- * as the memblock is limited to lowmem by MEMBLOCK_REAL_LIMIT */
+ * as the memblock is limited to lowmem by default */
for_each_possible_cpu(i) {
softirq_ctx[i] = (struct thread_info *)
__va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index e72690ec9b87..2a178b0ebcdf 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -486,7 +486,7 @@ static void __init emergency_stack_init(void)
* bringup, we need to get at them in real mode. This means they
* must also be within the RMO region.
*/
- limit = min(slb0_limit(), memblock.rmo_size);
+ limit = min(slb0_limit(), ppc64_rma_size);
for_each_possible_cpu(i) {
unsigned long sp;
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 0008bc58e826..68034bbf2e4f 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -508,9 +508,6 @@ int __devinit start_secondary(void *unused)
if (smp_ops->take_timebase)
smp_ops->take_timebase();
- if (system_state > SYSTEM_BOOTING)
- snapshot_timebase();
-
secondary_cpu_time_init();
ipi_call_lock();
@@ -575,11 +572,18 @@ void __init smp_cpus_done(unsigned int max_cpus)
free_cpumask_var(old_mask);
- snapshot_timebases();
-
dump_numa_cpu_topology();
}
+int arch_sd_sibling_asym_packing(void)
+{
+ if (cpu_has_feature(CPU_FTR_ASYM_SMT)) {
+ printk_once(KERN_INFO "Enabling Asymmetric SMT scheduling\n");
+ return SD_ASYM_PACKING;
+ }
+ return 0;
+}
+
#ifdef CONFIG_HOTPLUG_CPU
int __cpu_disable(void)
{
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 8533b3b83f5d..010406958d97 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -53,7 +53,7 @@
#include <linux/posix-timers.h>
#include <linux/irq.h>
#include <linux/delay.h>
-#include <linux/perf_event.h>
+#include <linux/irq_work.h>
#include <asm/trace.h>
#include <asm/io.h>
@@ -161,10 +161,9 @@ extern struct timezone sys_tz;
static long timezone_offset;
unsigned long ppc_proc_freq;
-EXPORT_SYMBOL(ppc_proc_freq);
+EXPORT_SYMBOL_GPL(ppc_proc_freq);
unsigned long ppc_tb_freq;
-
-static DEFINE_PER_CPU(u64, last_jiffy);
+EXPORT_SYMBOL_GPL(ppc_tb_freq);
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
/*
@@ -185,6 +184,8 @@ DEFINE_PER_CPU(unsigned long, cputime_scaled_last_delta);
cputime_t cputime_one_jiffy;
+void (*dtl_consumer)(struct dtl_entry *, u64);
+
static void calc_cputime_factors(void)
{
struct div_result res;
@@ -200,62 +201,153 @@ static void calc_cputime_factors(void)
}
/*
- * Read the PURR on systems that have it, otherwise the timebase.
+ * Read the SPURR on systems that have it, otherwise the PURR,
+ * or if that doesn't exist return the timebase value passed in.
*/
-static u64 read_purr(void)
+static u64 read_spurr(u64 tb)
{
+ if (cpu_has_feature(CPU_FTR_SPURR))
+ return mfspr(SPRN_SPURR);
if (cpu_has_feature(CPU_FTR_PURR))
return mfspr(SPRN_PURR);
- return mftb();
+ return tb;
}
+#ifdef CONFIG_PPC_SPLPAR
+
/*
- * Read the SPURR on systems that have it, otherwise the purr
+ * Scan the dispatch trace log and count up the stolen time.
+ * Should be called with interrupts disabled.
*/
-static u64 read_spurr(u64 purr)
+static u64 scan_dispatch_log(u64 stop_tb)
{
- /*
- * cpus without PURR won't have a SPURR
- * We already know the former when we use this, so tell gcc
- */
- if (cpu_has_feature(CPU_FTR_PURR) && cpu_has_feature(CPU_FTR_SPURR))
- return mfspr(SPRN_SPURR);
- return purr;
+ u64 i = local_paca->dtl_ridx;
+ struct dtl_entry *dtl = local_paca->dtl_curr;
+ struct dtl_entry *dtl_end = local_paca->dispatch_log_end;
+ struct lppaca *vpa = local_paca->lppaca_ptr;
+ u64 tb_delta;
+ u64 stolen = 0;
+ u64 dtb;
+
+ if (i == vpa->dtl_idx)
+ return 0;
+ while (i < vpa->dtl_idx) {
+ if (dtl_consumer)
+ dtl_consumer(dtl, i);
+ dtb = dtl->timebase;
+ tb_delta = dtl->enqueue_to_dispatch_time +
+ dtl->ready_to_enqueue_time;
+ barrier();
+ if (i + N_DISPATCH_LOG < vpa->dtl_idx) {
+ /* buffer has overflowed */
+ i = vpa->dtl_idx - N_DISPATCH_LOG;
+ dtl = local_paca->dispatch_log + (i % N_DISPATCH_LOG);
+ continue;
+ }
+ if (dtb > stop_tb)
+ break;
+ stolen += tb_delta;
+ ++i;
+ ++dtl;
+ if (dtl == dtl_end)
+ dtl = local_paca->dispatch_log;
+ }
+ local_paca->dtl_ridx = i;
+ local_paca->dtl_curr = dtl;
+ return stolen;
}
/*
+ * Accumulate stolen time by scanning the dispatch trace log.
+ * Called on entry from user mode.
+ */
+void accumulate_stolen_time(void)
+{
+ u64 sst, ust;
+
+ sst = scan_dispatch_log(get_paca()->starttime_user);
+ ust = scan_dispatch_log(get_paca()->starttime);
+ get_paca()->system_time -= sst;
+ get_paca()->user_time -= ust;
+ get_paca()->stolen_time += ust + sst;
+}
+
+static inline u64 calculate_stolen_time(u64 stop_tb)
+{
+ u64 stolen = 0;
+
+ if (get_paca()->dtl_ridx != get_paca()->lppaca_ptr->dtl_idx) {
+ stolen = scan_dispatch_log(stop_tb);
+ get_paca()->system_time -= stolen;
+ }
+
+ stolen += get_paca()->stolen_time;
+ get_paca()->stolen_time = 0;
+ return stolen;
+}
+
+#else /* CONFIG_PPC_SPLPAR */
+static inline u64 calculate_stolen_time(u64 stop_tb)
+{
+ return 0;
+}
+
+#endif /* CONFIG_PPC_SPLPAR */
+
+/*
* Account time for a transition between system, hard irq
* or soft irq state.
*/
void account_system_vtime(struct task_struct *tsk)
{
- u64 now, nowscaled, delta, deltascaled, sys_time;
+ u64 now, nowscaled, delta, deltascaled;
unsigned long flags;
+ u64 stolen, udelta, sys_scaled, user_scaled;
local_irq_save(flags);
- now = read_purr();
+ now = mftb();
nowscaled = read_spurr(now);
- delta = now - get_paca()->startpurr;
+ get_paca()->system_time += now - get_paca()->starttime;
+ get_paca()->starttime = now;
deltascaled = nowscaled - get_paca()->startspurr;
- get_paca()->startpurr = now;
get_paca()->startspurr = nowscaled;
- if (!in_interrupt()) {
- /* deltascaled includes both user and system time.
- * Hence scale it based on the purr ratio to estimate
- * the system time */
- sys_time = get_paca()->system_time;
- if (get_paca()->user_time)
- deltascaled = deltascaled * sys_time /
- (sys_time + get_paca()->user_time);
- delta += sys_time;
- get_paca()->system_time = 0;
+
+ stolen = calculate_stolen_time(now);
+
+ delta = get_paca()->system_time;
+ get_paca()->system_time = 0;
+ udelta = get_paca()->user_time - get_paca()->utime_sspurr;
+ get_paca()->utime_sspurr = get_paca()->user_time;
+
+ /*
+ * Because we don't read the SPURR on every kernel entry/exit,
+ * deltascaled includes both user and system SPURR ticks.
+ * Apportion these ticks to system SPURR ticks and user
+ * SPURR ticks in the same ratio as the system time (delta)
+ * and user time (udelta) values obtained from the timebase
+ * over the same interval. The system ticks get accounted here;
+ * the user ticks get saved up in paca->user_time_scaled to be
+ * used by account_process_tick.
+ */
+ sys_scaled = delta;
+ user_scaled = udelta;
+ if (deltascaled != delta + udelta) {
+ if (udelta) {
+ sys_scaled = deltascaled * delta / (delta + udelta);
+ user_scaled = deltascaled - sys_scaled;
+ } else {
+ sys_scaled = deltascaled;
+ }
+ }
+ get_paca()->user_time_scaled += user_scaled;
+
+ if (in_irq() || idle_task(smp_processor_id()) != tsk) {
+ account_system_time(tsk, 0, delta, sys_scaled);
+ if (stolen)
+ account_steal_time(stolen);
+ } else {
+ account_idle_time(delta + stolen);
}
- if (in_irq() || idle_task(smp_processor_id()) != tsk)
- account_system_time(tsk, 0, delta, deltascaled);
- else
- account_idle_time(delta);
- __get_cpu_var(cputime_last_delta) = delta;
- __get_cpu_var(cputime_scaled_last_delta) = deltascaled;
local_irq_restore(flags);
}
EXPORT_SYMBOL_GPL(account_system_vtime);
@@ -265,125 +357,26 @@ EXPORT_SYMBOL_GPL(account_system_vtime);
* by the exception entry and exit code to the generic process
* user and system time records.
* Must be called with interrupts disabled.
+ * Assumes that account_system_vtime() has been called recently
+ * (i.e. since the last entry from usermode) so that
+ * get_paca()->user_time_scaled is up to date.
*/
void account_process_tick(struct task_struct *tsk, int user_tick)
{
cputime_t utime, utimescaled;
utime = get_paca()->user_time;
+ utimescaled = get_paca()->user_time_scaled;
get_paca()->user_time = 0;
- utimescaled = cputime_to_scaled(utime);
+ get_paca()->user_time_scaled = 0;
+ get_paca()->utime_sspurr = 0;
account_user_time(tsk, utime, utimescaled);
}
-/*
- * Stuff for accounting stolen time.
- */
-struct cpu_purr_data {
- int initialized; /* thread is running */
- u64 tb; /* last TB value read */
- u64 purr; /* last PURR value read */
- u64 spurr; /* last SPURR value read */
-};
-
-/*
- * Each entry in the cpu_purr_data array is manipulated only by its
- * "owner" cpu -- usually in the timer interrupt but also occasionally
- * in process context for cpu online. As long as cpus do not touch
- * each others' cpu_purr_data, disabling local interrupts is
- * sufficient to serialize accesses.
- */
-static DEFINE_PER_CPU(struct cpu_purr_data, cpu_purr_data);
-
-static void snapshot_tb_and_purr(void *data)
-{
- unsigned long flags;
- struct cpu_purr_data *p = &__get_cpu_var(cpu_purr_data);
-
- local_irq_save(flags);
- p->tb = get_tb_or_rtc();
- p->purr = mfspr(SPRN_PURR);
- wmb();
- p->initialized = 1;
- local_irq_restore(flags);
-}
-
-/*
- * Called during boot when all cpus have come up.
- */
-void snapshot_timebases(void)
-{
- if (!cpu_has_feature(CPU_FTR_PURR))
- return;
- on_each_cpu(snapshot_tb_and_purr, NULL, 1);
-}
-
-/*
- * Must be called with interrupts disabled.
- */
-void calculate_steal_time(void)
-{
- u64 tb, purr;
- s64 stolen;
- struct cpu_purr_data *pme;
-
- pme = &__get_cpu_var(cpu_purr_data);
- if (!pme->initialized)
- return; /* !CPU_FTR_PURR or early in early boot */
- tb = mftb();
- purr = mfspr(SPRN_PURR);
- stolen = (tb - pme->tb) - (purr - pme->purr);
- if (stolen > 0) {
- if (idle_task(smp_processor_id()) != current)
- account_steal_time(stolen);
- else
- account_idle_time(stolen);
- }
- pme->tb = tb;
- pme->purr = purr;
-}
-
-#ifdef CONFIG_PPC_SPLPAR
-/*
- * Must be called before the cpu is added to the online map when
- * a cpu is being brought up at runtime.
- */
-static void snapshot_purr(void)
-{
- struct cpu_purr_data *pme;
- unsigned long flags;
-
- if (!cpu_has_feature(CPU_FTR_PURR))
- return;
- local_irq_save(flags);
- pme = &__get_cpu_var(cpu_purr_data);
- pme->tb = mftb();
- pme->purr = mfspr(SPRN_PURR);
- pme->initialized = 1;
- local_irq_restore(flags);
-}
-
-#endif /* CONFIG_PPC_SPLPAR */
-
#else /* ! CONFIG_VIRT_CPU_ACCOUNTING */
#define calc_cputime_factors()
-#define calculate_steal_time() do { } while (0)
#endif
-#if !(defined(CONFIG_VIRT_CPU_ACCOUNTING) && defined(CONFIG_PPC_SPLPAR))
-#define snapshot_purr() do { } while (0)
-#endif
-
-/*
- * Called when a cpu comes up after the system has finished booting,
- * i.e. as a result of a hotplug cpu action.
- */
-void snapshot_timebase(void)
-{
- __get_cpu_var(last_jiffy) = get_tb_or_rtc();
- snapshot_purr();
-}
-
void __delay(unsigned long loops)
{
unsigned long start;
@@ -493,60 +486,60 @@ void __init iSeries_time_init_early(void)
}
#endif /* CONFIG_PPC_ISERIES */
-#ifdef CONFIG_PERF_EVENTS
+#ifdef CONFIG_IRQ_WORK
/*
* 64-bit uses a byte in the PACA, 32-bit uses a per-cpu variable...
*/
#ifdef CONFIG_PPC64
-static inline unsigned long test_perf_event_pending(void)
+static inline unsigned long test_irq_work_pending(void)
{
unsigned long x;
asm volatile("lbz %0,%1(13)"
: "=r" (x)
- : "i" (offsetof(struct paca_struct, perf_event_pending)));
+ : "i" (offsetof(struct paca_struct, irq_work_pending)));
return x;
}
-static inline void set_perf_event_pending_flag(void)
+static inline void set_irq_work_pending_flag(void)
{
asm volatile("stb %0,%1(13)" : :
"r" (1),
- "i" (offsetof(struct paca_struct, perf_event_pending)));
+ "i" (offsetof(struct paca_struct, irq_work_pending)));
}
-static inline void clear_perf_event_pending(void)
+static inline void clear_irq_work_pending(void)
{
asm volatile("stb %0,%1(13)" : :
"r" (0),
- "i" (offsetof(struct paca_struct, perf_event_pending)));
+ "i" (offsetof(struct paca_struct, irq_work_pending)));
}
#else /* 32-bit */
-DEFINE_PER_CPU(u8, perf_event_pending);
+DEFINE_PER_CPU(u8, irq_work_pending);
-#define set_perf_event_pending_flag() __get_cpu_var(perf_event_pending) = 1
-#define test_perf_event_pending() __get_cpu_var(perf_event_pending)
-#define clear_perf_event_pending() __get_cpu_var(perf_event_pending) = 0
+#define set_irq_work_pending_flag() __get_cpu_var(irq_work_pending) = 1
+#define test_irq_work_pending() __get_cpu_var(irq_work_pending)
+#define clear_irq_work_pending() __get_cpu_var(irq_work_pending) = 0
#endif /* 32 vs 64 bit */
-void set_perf_event_pending(void)
+void set_irq_work_pending(void)
{
preempt_disable();
- set_perf_event_pending_flag();
+ set_irq_work_pending_flag();
set_dec(1);
preempt_enable();
}
-#else /* CONFIG_PERF_EVENTS */
+#else /* CONFIG_IRQ_WORK */
-#define test_perf_event_pending() 0
-#define clear_perf_event_pending()
+#define test_irq_work_pending() 0
+#define clear_irq_work_pending()
-#endif /* CONFIG_PERF_EVENTS */
+#endif /* CONFIG_IRQ_WORK */
/*
* For iSeries shared processors, we have to let the hypervisor
@@ -585,11 +578,9 @@ void timer_interrupt(struct pt_regs * regs)
old_regs = set_irq_regs(regs);
irq_enter();
- calculate_steal_time();
-
- if (test_perf_event_pending()) {
- clear_perf_event_pending();
- perf_event_do_pending();
+ if (test_irq_work_pending()) {
+ clear_irq_work_pending();
+ irq_work_run();
}
#ifdef CONFIG_PPC_ISERIES
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index a45a63c3a0c7..1b2cdc8eec90 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -538,6 +538,11 @@ int machine_check_e500(struct pt_regs *regs)
return 0;
}
+
+int machine_check_generic(struct pt_regs *regs)
+{
+ return 0;
+}
#elif defined(CONFIG_E200)
int machine_check_e200(struct pt_regs *regs)
{
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index 13002fe206e7..fd8728729abc 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -159,7 +159,7 @@ static void dump_vdso_pages(struct vm_area_struct * vma)
{
int i;
- if (!vma || test_thread_flag(TIF_32BIT)) {
+ if (!vma || is_32bit_task()) {
printk("vDSO32 @ %016lx:\n", (unsigned long)vdso32_kbase);
for (i=0; i<vdso32_pages; i++) {
struct page *pg = virt_to_page(vdso32_kbase +
@@ -170,7 +170,7 @@ static void dump_vdso_pages(struct vm_area_struct * vma)
dump_one_vdso_page(pg, upg);
}
}
- if (!vma || !test_thread_flag(TIF_32BIT)) {
+ if (!vma || !is_32bit_task()) {
printk("vDSO64 @ %016lx:\n", (unsigned long)vdso64_kbase);
for (i=0; i<vdso64_pages; i++) {
struct page *pg = virt_to_page(vdso64_kbase +
@@ -200,7 +200,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
return 0;
#ifdef CONFIG_PPC64
- if (test_thread_flag(TIF_32BIT)) {
+ if (is_32bit_task()) {
vdso_pagelist = vdso32_pagelist;
vdso_pages = vdso32_pages;
vdso_base = VDSO32_MBASE;
diff --git a/arch/powerpc/kernel/vdso32/Makefile b/arch/powerpc/kernel/vdso32/Makefile
index 51ead52141bd..9a7946c41738 100644
--- a/arch/powerpc/kernel/vdso32/Makefile
+++ b/arch/powerpc/kernel/vdso32/Makefile
@@ -14,10 +14,10 @@ obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32))
GCOV_PROFILE := n
-EXTRA_CFLAGS := -shared -fno-common -fno-builtin
-EXTRA_CFLAGS += -nostdlib -Wl,-soname=linux-vdso32.so.1 \
+ccflags-y := -shared -fno-common -fno-builtin
+ccflags-y += -nostdlib -Wl,-soname=linux-vdso32.so.1 \
$(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
-EXTRA_AFLAGS := -D__VDSO32__ -s
+asflags-y := -D__VDSO32__ -s
obj-y += vdso32_wrapper.o
extra-y += vdso32.lds
diff --git a/arch/powerpc/kernel/vdso64/Makefile b/arch/powerpc/kernel/vdso64/Makefile
index 79da65d44a2a..8c500d8622e4 100644
--- a/arch/powerpc/kernel/vdso64/Makefile
+++ b/arch/powerpc/kernel/vdso64/Makefile
@@ -9,10 +9,10 @@ obj-vdso64 := $(addprefix $(obj)/, $(obj-vdso64))
GCOV_PROFILE := n
-EXTRA_CFLAGS := -shared -fno-common -fno-builtin
-EXTRA_CFLAGS += -nostdlib -Wl,-soname=linux-vdso64.so.1 \
+ccflags-y := -shared -fno-common -fno-builtin
+ccflags-y += -nostdlib -Wl,-soname=linux-vdso64.so.1 \
$(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
-EXTRA_AFLAGS := -D__VDSO64__ -s
+asflags-y := -D__VDSO64__ -s
obj-y += vdso64_wrapper.o
extra-y += vdso64.lds
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index fa3469ddaef8..d692989a4318 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -1184,7 +1184,12 @@ EXPORT_SYMBOL(vio_unregister_driver);
/* vio_dev refcount hit 0 */
static void __devinit vio_dev_release(struct device *dev)
{
- /* XXX should free TCE table */
+ struct iommu_table *tbl = get_iommu_table_base(dev);
+
+ /* iSeries uses a common table for all vio devices */
+ if (!firmware_has_feature(FW_FEATURE_ISERIES) && tbl)
+ iommu_free_table(tbl, dev->of_node ?
+ dev->of_node->full_name : dev_name(dev));
of_node_put(dev->of_node);
kfree(to_vio_dev(dev));
}
@@ -1254,8 +1259,7 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node)
if (device_register(&viodev->dev)) {
printk(KERN_ERR "%s: failed to register device %s\n",
__func__, dev_name(&viodev->dev));
- /* XXX free TCE table */
- kfree(viodev);
+ put_device(&viodev->dev);
return NULL;
}
diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c
index 73c0a3f64ed1..74d0e7421143 100644
--- a/arch/powerpc/kvm/44x.c
+++ b/arch/powerpc/kvm/44x.c
@@ -43,7 +43,7 @@ int kvmppc_core_check_processor_compat(void)
{
int r;
- if (strcmp(cur_cpu_spec->platform, "ppc440") == 0)
+ if (strncmp(cur_cpu_spec->platform, "ppc440", 6) == 0)
r = 0;
else
r = -ENOTSUPP;
@@ -72,6 +72,7 @@ int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu)
/* Since the guest can directly access the timebase, it must know the
* real timebase frequency. Accordingly, it must see the state of
* CCR1[TCS]. */
+ /* XXX CCR1 doesn't exist on all 440 SoCs. */
vcpu->arch.ccr1 = mfspr(SPRN_CCR1);
for (i = 0; i < ARRAY_SIZE(vcpu_44x->shadow_refs); i++)
@@ -123,8 +124,14 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
if (err)
goto free_vcpu;
+ vcpu->arch.shared = (void*)__get_free_page(GFP_KERNEL|__GFP_ZERO);
+ if (!vcpu->arch.shared)
+ goto uninit_vcpu;
+
return vcpu;
+uninit_vcpu:
+ kvm_vcpu_uninit(vcpu);
free_vcpu:
kmem_cache_free(kvm_vcpu_cache, vcpu_44x);
out:
@@ -135,6 +142,7 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
{
struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu);
+ free_page((unsigned long)vcpu->arch.shared);
kvm_vcpu_uninit(vcpu);
kmem_cache_free(kvm_vcpu_cache, vcpu_44x);
}
diff --git a/arch/powerpc/kvm/44x_tlb.c b/arch/powerpc/kvm/44x_tlb.c
index 9b9b5cdea840..5f3cff83e089 100644
--- a/arch/powerpc/kvm/44x_tlb.c
+++ b/arch/powerpc/kvm/44x_tlb.c
@@ -47,6 +47,7 @@
#ifdef DEBUG
void kvmppc_dump_tlbs(struct kvm_vcpu *vcpu)
{
+ struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu);
struct kvmppc_44x_tlbe *tlbe;
int i;
@@ -221,14 +222,14 @@ gpa_t kvmppc_mmu_xlate(struct kvm_vcpu *vcpu, unsigned int gtlb_index,
int kvmppc_mmu_itlb_index(struct kvm_vcpu *vcpu, gva_t eaddr)
{
- unsigned int as = !!(vcpu->arch.msr & MSR_IS);
+ unsigned int as = !!(vcpu->arch.shared->msr & MSR_IS);
return kvmppc_44x_tlb_index(vcpu, eaddr, vcpu->arch.pid, as);
}
int kvmppc_mmu_dtlb_index(struct kvm_vcpu *vcpu, gva_t eaddr)
{
- unsigned int as = !!(vcpu->arch.msr & MSR_DS);
+ unsigned int as = !!(vcpu->arch.shared->msr & MSR_DS);
return kvmppc_44x_tlb_index(vcpu, eaddr, vcpu->arch.pid, as);
}
@@ -354,7 +355,7 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gpa_t gpaddr,
stlbe.word1 = (hpaddr & 0xfffffc00) | ((hpaddr >> 32) & 0xf);
stlbe.word2 = kvmppc_44x_tlb_shadow_attrib(flags,
- vcpu->arch.msr & MSR_PR);
+ vcpu->arch.shared->msr & MSR_PR);
stlbe.tid = !(asid & 0xff);
/* Keep track of the reference so we can properly release it later. */
@@ -423,7 +424,7 @@ static int tlbe_is_host_safe(const struct kvm_vcpu *vcpu,
/* Does it match current guest AS? */
/* XXX what about IS != DS? */
- if (get_tlb_ts(tlbe) != !!(vcpu->arch.msr & MSR_IS))
+ if (get_tlb_ts(tlbe) != !!(vcpu->arch.shared->msr & MSR_IS))
return 0;
gpa = get_tlb_raddr(tlbe);
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile
index d45c818a384c..4d6863823f69 100644
--- a/arch/powerpc/kvm/Makefile
+++ b/arch/powerpc/kvm/Makefile
@@ -4,7 +4,7 @@
subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
-EXTRA_CFLAGS += -Ivirt/kvm -Iarch/powerpc/kvm
+ccflags-y := -Ivirt/kvm -Iarch/powerpc/kvm
common-objs-y = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o)
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index a3cef30d1d42..e316847c08c0 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -17,6 +17,7 @@
#include <linux/kvm_host.h>
#include <linux/err.h>
#include <linux/slab.h>
+#include "trace.h"
#include <asm/reg.h>
#include <asm/cputable.h>
@@ -35,7 +36,6 @@
#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
/* #define EXIT_DEBUG */
-/* #define EXIT_DEBUG_SIMPLE */
/* #define DEBUG_EXT */
static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr,
@@ -105,65 +105,71 @@ void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu)
kvmppc_giveup_ext(vcpu, MSR_VSX);
}
-#if defined(EXIT_DEBUG)
-static u32 kvmppc_get_dec(struct kvm_vcpu *vcpu)
-{
- u64 jd = mftb() - vcpu->arch.dec_jiffies;
- return vcpu->arch.dec - jd;
-}
-#endif
-
static void kvmppc_recalc_shadow_msr(struct kvm_vcpu *vcpu)
{
- vcpu->arch.shadow_msr = vcpu->arch.msr;
+ ulong smsr = vcpu->arch.shared->msr;
+
/* Guest MSR values */
- vcpu->arch.shadow_msr &= MSR_FE0 | MSR_FE1 | MSR_SF | MSR_SE |
- MSR_BE | MSR_DE;
+ smsr &= MSR_FE0 | MSR_FE1 | MSR_SF | MSR_SE | MSR_BE | MSR_DE;
/* Process MSR values */
- vcpu->arch.shadow_msr |= MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_PR |
- MSR_EE;
+ smsr |= MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_PR | MSR_EE;
/* External providers the guest reserved */
- vcpu->arch.shadow_msr |= (vcpu->arch.msr & vcpu->arch.guest_owned_ext);
+ smsr |= (vcpu->arch.shared->msr & vcpu->arch.guest_owned_ext);
/* 64-bit Process MSR values */
#ifdef CONFIG_PPC_BOOK3S_64
- vcpu->arch.shadow_msr |= MSR_ISF | MSR_HV;
+ smsr |= MSR_ISF | MSR_HV;
#endif
+ vcpu->arch.shadow_msr = smsr;
}
void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 msr)
{
- ulong old_msr = vcpu->arch.msr;
+ ulong old_msr = vcpu->arch.shared->msr;
#ifdef EXIT_DEBUG
printk(KERN_INFO "KVM: Set MSR to 0x%llx\n", msr);
#endif
msr &= to_book3s(vcpu)->msr_mask;
- vcpu->arch.msr = msr;
+ vcpu->arch.shared->msr = msr;
kvmppc_recalc_shadow_msr(vcpu);
- if (msr & (MSR_WE|MSR_POW)) {
+ if (msr & MSR_POW) {
if (!vcpu->arch.pending_exceptions) {
kvm_vcpu_block(vcpu);
vcpu->stat.halt_wakeup++;
+
+ /* Unset POW bit after we woke up */
+ msr &= ~MSR_POW;
+ vcpu->arch.shared->msr = msr;
}
}
- if ((vcpu->arch.msr & (MSR_PR|MSR_IR|MSR_DR)) !=
+ if ((vcpu->arch.shared->msr & (MSR_PR|MSR_IR|MSR_DR)) !=
(old_msr & (MSR_PR|MSR_IR|MSR_DR))) {
kvmppc_mmu_flush_segments(vcpu);
kvmppc_mmu_map_segment(vcpu, kvmppc_get_pc(vcpu));
+
+ /* Preload magic page segment when in kernel mode */
+ if (!(msr & MSR_PR) && vcpu->arch.magic_page_pa) {
+ struct kvm_vcpu_arch *a = &vcpu->arch;
+
+ if (msr & MSR_DR)
+ kvmppc_mmu_map_segment(vcpu, a->magic_page_ea);
+ else
+ kvmppc_mmu_map_segment(vcpu, a->magic_page_pa);
+ }
}
/* Preload FPU if it's enabled */
- if (vcpu->arch.msr & MSR_FP)
+ if (vcpu->arch.shared->msr & MSR_FP)
kvmppc_handle_ext(vcpu, BOOK3S_INTERRUPT_FP_UNAVAIL, MSR_FP);
}
void kvmppc_inject_interrupt(struct kvm_vcpu *vcpu, int vec, u64 flags)
{
- vcpu->arch.srr0 = kvmppc_get_pc(vcpu);
- vcpu->arch.srr1 = vcpu->arch.msr | flags;
+ vcpu->arch.shared->srr0 = kvmppc_get_pc(vcpu);
+ vcpu->arch.shared->srr1 = vcpu->arch.shared->msr | flags;
kvmppc_set_pc(vcpu, to_book3s(vcpu)->hior + vec);
vcpu->arch.mmu.reset_msr(vcpu);
}
@@ -180,6 +186,7 @@ static int kvmppc_book3s_vec2irqprio(unsigned int vec)
case 0x400: prio = BOOK3S_IRQPRIO_INST_STORAGE; break;
case 0x480: prio = BOOK3S_IRQPRIO_INST_SEGMENT; break;
case 0x500: prio = BOOK3S_IRQPRIO_EXTERNAL; break;
+ case 0x501: prio = BOOK3S_IRQPRIO_EXTERNAL_LEVEL; break;
case 0x600: prio = BOOK3S_IRQPRIO_ALIGNMENT; break;
case 0x700: prio = BOOK3S_IRQPRIO_PROGRAM; break;
case 0x800: prio = BOOK3S_IRQPRIO_FP_UNAVAIL; break;
@@ -199,6 +206,9 @@ static void kvmppc_book3s_dequeue_irqprio(struct kvm_vcpu *vcpu,
{
clear_bit(kvmppc_book3s_vec2irqprio(vec),
&vcpu->arch.pending_exceptions);
+
+ if (!vcpu->arch.pending_exceptions)
+ vcpu->arch.shared->int_pending = 0;
}
void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec)
@@ -237,13 +247,19 @@ void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu)
void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
struct kvm_interrupt *irq)
{
- kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_EXTERNAL);
+ unsigned int vec = BOOK3S_INTERRUPT_EXTERNAL;
+
+ if (irq->irq == KVM_INTERRUPT_SET_LEVEL)
+ vec = BOOK3S_INTERRUPT_EXTERNAL_LEVEL;
+
+ kvmppc_book3s_queue_irqprio(vcpu, vec);
}
void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu,
struct kvm_interrupt *irq)
{
kvmppc_book3s_dequeue_irqprio(vcpu, BOOK3S_INTERRUPT_EXTERNAL);
+ kvmppc_book3s_dequeue_irqprio(vcpu, BOOK3S_INTERRUPT_EXTERNAL_LEVEL);
}
int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority)
@@ -251,14 +267,29 @@ int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority)
int deliver = 1;
int vec = 0;
ulong flags = 0ULL;
+ ulong crit_raw = vcpu->arch.shared->critical;
+ ulong crit_r1 = kvmppc_get_gpr(vcpu, 1);
+ bool crit;
+
+ /* Truncate crit indicators in 32 bit mode */
+ if (!(vcpu->arch.shared->msr & MSR_SF)) {
+ crit_raw &= 0xffffffff;
+ crit_r1 &= 0xffffffff;
+ }
+
+ /* Critical section when crit == r1 */
+ crit = (crit_raw == crit_r1);
+ /* ... and we're in supervisor mode */
+ crit = crit && !(vcpu->arch.shared->msr & MSR_PR);
switch (priority) {
case BOOK3S_IRQPRIO_DECREMENTER:
- deliver = vcpu->arch.msr & MSR_EE;
+ deliver = (vcpu->arch.shared->msr & MSR_EE) && !crit;
vec = BOOK3S_INTERRUPT_DECREMENTER;
break;
case BOOK3S_IRQPRIO_EXTERNAL:
- deliver = vcpu->arch.msr & MSR_EE;
+ case BOOK3S_IRQPRIO_EXTERNAL_LEVEL:
+ deliver = (vcpu->arch.shared->msr & MSR_EE) && !crit;
vec = BOOK3S_INTERRUPT_EXTERNAL;
break;
case BOOK3S_IRQPRIO_SYSTEM_RESET:
@@ -320,9 +351,27 @@ int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority)
return deliver;
}
+/*
+ * This function determines if an irqprio should be cleared once issued.
+ */
+static bool clear_irqprio(struct kvm_vcpu *vcpu, unsigned int priority)
+{
+ switch (priority) {
+ case BOOK3S_IRQPRIO_DECREMENTER:
+ /* DEC interrupts get cleared by mtdec */
+ return false;
+ case BOOK3S_IRQPRIO_EXTERNAL_LEVEL:
+ /* External interrupts get cleared by userspace */
+ return false;
+ }
+
+ return true;
+}
+
void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu)
{
unsigned long *pending = &vcpu->arch.pending_exceptions;
+ unsigned long old_pending = vcpu->arch.pending_exceptions;
unsigned int priority;
#ifdef EXIT_DEBUG
@@ -332,8 +381,7 @@ void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu)
priority = __ffs(*pending);
while (priority < BOOK3S_IRQPRIO_MAX) {
if (kvmppc_book3s_irqprio_deliver(vcpu, priority) &&
- (priority != BOOK3S_IRQPRIO_DECREMENTER)) {
- /* DEC interrupts get cleared by mtdec */
+ clear_irqprio(vcpu, priority)) {
clear_bit(priority, &vcpu->arch.pending_exceptions);
break;
}
@@ -342,6 +390,12 @@ void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu)
BITS_PER_BYTE * sizeof(*pending),
priority + 1);
}
+
+ /* Tell the guest about our interrupt status */
+ if (*pending)
+ vcpu->arch.shared->int_pending = 1;
+ else if (old_pending)
+ vcpu->arch.shared->int_pending = 0;
}
void kvmppc_set_pvr(struct kvm_vcpu *vcpu, u32 pvr)
@@ -398,6 +452,25 @@ void kvmppc_set_pvr(struct kvm_vcpu *vcpu, u32 pvr)
}
}
+pfn_t kvmppc_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn)
+{
+ ulong mp_pa = vcpu->arch.magic_page_pa;
+
+ /* Magic page override */
+ if (unlikely(mp_pa) &&
+ unlikely(((gfn << PAGE_SHIFT) & KVM_PAM) ==
+ ((mp_pa & PAGE_MASK) & KVM_PAM))) {
+ ulong shared_page = ((ulong)vcpu->arch.shared) & PAGE_MASK;
+ pfn_t pfn;
+
+ pfn = (pfn_t)virt_to_phys((void*)shared_page) >> PAGE_SHIFT;
+ get_page(pfn_to_page(pfn));
+ return pfn;
+ }
+
+ return gfn_to_pfn(vcpu->kvm, gfn);
+}
+
/* Book3s_32 CPUs always have 32 bytes cache line size, which Linux assumes. To
* make Book3s_32 Linux work on Book3s_64, we have to make sure we trap dcbz to
* emulate 32 bytes dcbz length.
@@ -415,8 +488,10 @@ static void kvmppc_patch_dcbz(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte)
int i;
hpage = gfn_to_page(vcpu->kvm, pte->raddr >> PAGE_SHIFT);
- if (is_error_page(hpage))
+ if (is_error_page(hpage)) {
+ kvm_release_page_clean(hpage);
return;
+ }
hpage_offset = pte->raddr & ~PAGE_MASK;
hpage_offset &= ~0xFFFULL;
@@ -437,14 +512,14 @@ static void kvmppc_patch_dcbz(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte)
static int kvmppc_xlate(struct kvm_vcpu *vcpu, ulong eaddr, bool data,
struct kvmppc_pte *pte)
{
- int relocated = (vcpu->arch.msr & (data ? MSR_DR : MSR_IR));
+ int relocated = (vcpu->arch.shared->msr & (data ? MSR_DR : MSR_IR));
int r;
if (relocated) {
r = vcpu->arch.mmu.xlate(vcpu, eaddr, pte, data);
} else {
pte->eaddr = eaddr;
- pte->raddr = eaddr & 0xffffffff;
+ pte->raddr = eaddr & KVM_PAM;
pte->vpage = VSID_REAL | eaddr >> 12;
pte->may_read = true;
pte->may_write = true;
@@ -533,6 +608,13 @@ mmio:
static int kvmppc_visible_gfn(struct kvm_vcpu *vcpu, gfn_t gfn)
{
+ ulong mp_pa = vcpu->arch.magic_page_pa;
+
+ if (unlikely(mp_pa) &&
+ unlikely((mp_pa & KVM_PAM) >> PAGE_SHIFT == gfn)) {
+ return 1;
+ }
+
return kvm_is_visible_gfn(vcpu->kvm, gfn);
}
@@ -545,8 +627,8 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu,
int page_found = 0;
struct kvmppc_pte pte;
bool is_mmio = false;
- bool dr = (vcpu->arch.msr & MSR_DR) ? true : false;
- bool ir = (vcpu->arch.msr & MSR_IR) ? true : false;
+ bool dr = (vcpu->arch.shared->msr & MSR_DR) ? true : false;
+ bool ir = (vcpu->arch.shared->msr & MSR_IR) ? true : false;
u64 vsid;
relocated = data ? dr : ir;
@@ -558,12 +640,12 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu,
pte.may_execute = true;
pte.may_read = true;
pte.may_write = true;
- pte.raddr = eaddr & 0xffffffff;
+ pte.raddr = eaddr & KVM_PAM;
pte.eaddr = eaddr;
pte.vpage = eaddr >> 12;
}
- switch (vcpu->arch.msr & (MSR_DR|MSR_IR)) {
+ switch (vcpu->arch.shared->msr & (MSR_DR|MSR_IR)) {
case 0:
pte.vpage |= ((u64)VSID_REAL << (SID_SHIFT - 12));
break;
@@ -571,7 +653,7 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu,
case MSR_IR:
vcpu->arch.mmu.esid_to_vsid(vcpu, eaddr >> SID_SHIFT, &vsid);
- if ((vcpu->arch.msr & (MSR_DR|MSR_IR)) == MSR_DR)
+ if ((vcpu->arch.shared->msr & (MSR_DR|MSR_IR)) == MSR_DR)
pte.vpage |= ((u64)VSID_REAL_DR << (SID_SHIFT - 12));
else
pte.vpage |= ((u64)VSID_REAL_IR << (SID_SHIFT - 12));
@@ -594,20 +676,23 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu,
if (page_found == -ENOENT) {
/* Page not found in guest PTE entries */
- vcpu->arch.dear = kvmppc_get_fault_dar(vcpu);
- to_book3s(vcpu)->dsisr = to_svcpu(vcpu)->fault_dsisr;
- vcpu->arch.msr |= (to_svcpu(vcpu)->shadow_srr1 & 0x00000000f8000000ULL);
+ vcpu->arch.shared->dar = kvmppc_get_fault_dar(vcpu);
+ vcpu->arch.shared->dsisr = to_svcpu(vcpu)->fault_dsisr;
+ vcpu->arch.shared->msr |=
+ (to_svcpu(vcpu)->shadow_srr1 & 0x00000000f8000000ULL);
kvmppc_book3s_queue_irqprio(vcpu, vec);
} else if (page_found == -EPERM) {
/* Storage protection */
- vcpu->arch.dear = kvmppc_get_fault_dar(vcpu);
- to_book3s(vcpu)->dsisr = to_svcpu(vcpu)->fault_dsisr & ~DSISR_NOHPTE;
- to_book3s(vcpu)->dsisr |= DSISR_PROTFAULT;
- vcpu->arch.msr |= (to_svcpu(vcpu)->shadow_srr1 & 0x00000000f8000000ULL);
+ vcpu->arch.shared->dar = kvmppc_get_fault_dar(vcpu);
+ vcpu->arch.shared->dsisr =
+ to_svcpu(vcpu)->fault_dsisr & ~DSISR_NOHPTE;
+ vcpu->arch.shared->dsisr |= DSISR_PROTFAULT;
+ vcpu->arch.shared->msr |=
+ (to_svcpu(vcpu)->shadow_srr1 & 0x00000000f8000000ULL);
kvmppc_book3s_queue_irqprio(vcpu, vec);
} else if (page_found == -EINVAL) {
/* Page not found in guest SLB */
- vcpu->arch.dear = kvmppc_get_fault_dar(vcpu);
+ vcpu->arch.shared->dar = kvmppc_get_fault_dar(vcpu);
kvmppc_book3s_queue_irqprio(vcpu, vec + 0x80);
} else if (!is_mmio &&
kvmppc_visible_gfn(vcpu, pte.raddr >> PAGE_SHIFT)) {
@@ -695,9 +780,11 @@ static int kvmppc_read_inst(struct kvm_vcpu *vcpu)
ret = kvmppc_ld(vcpu, &srr0, sizeof(u32), &last_inst, false);
if (ret == -ENOENT) {
- vcpu->arch.msr = kvmppc_set_field(vcpu->arch.msr, 33, 33, 1);
- vcpu->arch.msr = kvmppc_set_field(vcpu->arch.msr, 34, 36, 0);
- vcpu->arch.msr = kvmppc_set_field(vcpu->arch.msr, 42, 47, 0);
+ ulong msr = vcpu->arch.shared->msr;
+
+ msr = kvmppc_set_field(msr, 33, 33, 1);
+ msr = kvmppc_set_field(msr, 34, 36, 0);
+ vcpu->arch.shared->msr = kvmppc_set_field(msr, 42, 47, 0);
kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_INST_STORAGE);
return EMULATE_AGAIN;
}
@@ -736,7 +823,7 @@ static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr,
if (vcpu->arch.hflags & BOOK3S_HFLAG_PAIRED_SINGLE)
return RESUME_GUEST;
- if (!(vcpu->arch.msr & msr)) {
+ if (!(vcpu->arch.shared->msr & msr)) {
kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
return RESUME_GUEST;
}
@@ -796,16 +883,8 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
run->exit_reason = KVM_EXIT_UNKNOWN;
run->ready_for_interrupt_injection = 1;
-#ifdef EXIT_DEBUG
- printk(KERN_EMERG "exit_nr=0x%x | pc=0x%lx | dar=0x%lx | dec=0x%x | msr=0x%lx\n",
- exit_nr, kvmppc_get_pc(vcpu), kvmppc_get_fault_dar(vcpu),
- kvmppc_get_dec(vcpu), to_svcpu(vcpu)->shadow_srr1);
-#elif defined (EXIT_DEBUG_SIMPLE)
- if ((exit_nr != 0x900) && (exit_nr != 0x500))
- printk(KERN_EMERG "exit_nr=0x%x | pc=0x%lx | dar=0x%lx | msr=0x%lx\n",
- exit_nr, kvmppc_get_pc(vcpu), kvmppc_get_fault_dar(vcpu),
- vcpu->arch.msr);
-#endif
+
+ trace_kvm_book3s_exit(exit_nr, vcpu);
kvm_resched(vcpu);
switch (exit_nr) {
case BOOK3S_INTERRUPT_INST_STORAGE:
@@ -836,9 +915,9 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
kvmppc_mmu_pte_flush(vcpu, kvmppc_get_pc(vcpu), ~0xFFFUL);
r = RESUME_GUEST;
} else {
- vcpu->arch.msr |= to_svcpu(vcpu)->shadow_srr1 & 0x58000000;
+ vcpu->arch.shared->msr |=
+ to_svcpu(vcpu)->shadow_srr1 & 0x58000000;
kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
- kvmppc_mmu_pte_flush(vcpu, kvmppc_get_pc(vcpu), ~0xFFFUL);
r = RESUME_GUEST;
}
break;
@@ -861,17 +940,16 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
if (to_svcpu(vcpu)->fault_dsisr & DSISR_NOHPTE) {
r = kvmppc_handle_pagefault(run, vcpu, dar, exit_nr);
} else {
- vcpu->arch.dear = dar;
- to_book3s(vcpu)->dsisr = to_svcpu(vcpu)->fault_dsisr;
+ vcpu->arch.shared->dar = dar;
+ vcpu->arch.shared->dsisr = to_svcpu(vcpu)->fault_dsisr;
kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
- kvmppc_mmu_pte_flush(vcpu, vcpu->arch.dear, ~0xFFFUL);
r = RESUME_GUEST;
}
break;
}
case BOOK3S_INTERRUPT_DATA_SEGMENT:
if (kvmppc_mmu_map_segment(vcpu, kvmppc_get_fault_dar(vcpu)) < 0) {
- vcpu->arch.dear = kvmppc_get_fault_dar(vcpu);
+ vcpu->arch.shared->dar = kvmppc_get_fault_dar(vcpu);
kvmppc_book3s_queue_irqprio(vcpu,
BOOK3S_INTERRUPT_DATA_SEGMENT);
}
@@ -904,7 +982,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
program_interrupt:
flags = to_svcpu(vcpu)->shadow_srr1 & 0x1f0000ull;
- if (vcpu->arch.msr & MSR_PR) {
+ if (vcpu->arch.shared->msr & MSR_PR) {
#ifdef EXIT_DEBUG
printk(KERN_INFO "Userspace triggered 0x700 exception at 0x%lx (0x%x)\n", kvmppc_get_pc(vcpu), kvmppc_get_last_inst(vcpu));
#endif
@@ -941,10 +1019,10 @@ program_interrupt:
break;
}
case BOOK3S_INTERRUPT_SYSCALL:
- // XXX make user settable
if (vcpu->arch.osi_enabled &&
(((u32)kvmppc_get_gpr(vcpu, 3)) == OSI_SC_MAGIC_R3) &&
(((u32)kvmppc_get_gpr(vcpu, 4)) == OSI_SC_MAGIC_R4)) {
+ /* MOL hypercalls */
u64 *gprs = run->osi.gprs;
int i;
@@ -953,8 +1031,13 @@ program_interrupt:
gprs[i] = kvmppc_get_gpr(vcpu, i);
vcpu->arch.osi_needed = 1;
r = RESUME_HOST_NV;
-
+ } else if (!(vcpu->arch.shared->msr & MSR_PR) &&
+ (((u32)kvmppc_get_gpr(vcpu, 0)) == KVM_SC_MAGIC_R0)) {
+ /* KVM PV hypercalls */
+ kvmppc_set_gpr(vcpu, 3, kvmppc_kvm_pv(vcpu));
+ r = RESUME_GUEST;
} else {
+ /* Guest syscalls */
vcpu->stat.syscall_exits++;
kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
r = RESUME_GUEST;
@@ -989,9 +1072,9 @@ program_interrupt:
}
case BOOK3S_INTERRUPT_ALIGNMENT:
if (kvmppc_read_inst(vcpu) == EMULATE_DONE) {
- to_book3s(vcpu)->dsisr = kvmppc_alignment_dsisr(vcpu,
+ vcpu->arch.shared->dsisr = kvmppc_alignment_dsisr(vcpu,
kvmppc_get_last_inst(vcpu));
- vcpu->arch.dear = kvmppc_alignment_dar(vcpu,
+ vcpu->arch.shared->dar = kvmppc_alignment_dar(vcpu,
kvmppc_get_last_inst(vcpu));
kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
}
@@ -1031,9 +1114,7 @@ program_interrupt:
}
}
-#ifdef EXIT_DEBUG
- printk(KERN_EMERG "KVM exit: vcpu=0x%p pc=0x%lx r=0x%x\n", vcpu, kvmppc_get_pc(vcpu), r);
-#endif
+ trace_kvm_book3s_reenter(r, vcpu);
return r;
}
@@ -1052,14 +1133,14 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
regs->ctr = kvmppc_get_ctr(vcpu);
regs->lr = kvmppc_get_lr(vcpu);
regs->xer = kvmppc_get_xer(vcpu);
- regs->msr = vcpu->arch.msr;
- regs->srr0 = vcpu->arch.srr0;
- regs->srr1 = vcpu->arch.srr1;
+ regs->msr = vcpu->arch.shared->msr;
+ regs->srr0 = vcpu->arch.shared->srr0;
+ regs->srr1 = vcpu->arch.shared->srr1;
regs->pid = vcpu->arch.pid;
- regs->sprg0 = vcpu->arch.sprg0;
- regs->sprg1 = vcpu->arch.sprg1;
- regs->sprg2 = vcpu->arch.sprg2;
- regs->sprg3 = vcpu->arch.sprg3;
+ regs->sprg0 = vcpu->arch.shared->sprg0;
+ regs->sprg1 = vcpu->arch.shared->sprg1;
+ regs->sprg2 = vcpu->arch.shared->sprg2;
+ regs->sprg3 = vcpu->arch.shared->sprg3;
regs->sprg5 = vcpu->arch.sprg4;
regs->sprg6 = vcpu->arch.sprg5;
regs->sprg7 = vcpu->arch.sprg6;
@@ -1080,12 +1161,12 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
kvmppc_set_lr(vcpu, regs->lr);
kvmppc_set_xer(vcpu, regs->xer);
kvmppc_set_msr(vcpu, regs->msr);
- vcpu->arch.srr0 = regs->srr0;
- vcpu->arch.srr1 = regs->srr1;
- vcpu->arch.sprg0 = regs->sprg0;
- vcpu->arch.sprg1 = regs->sprg1;
- vcpu->arch.sprg2 = regs->sprg2;
- vcpu->arch.sprg3 = regs->sprg3;
+ vcpu->arch.shared->srr0 = regs->srr0;
+ vcpu->arch.shared->srr1 = regs->srr1;
+ vcpu->arch.shared->sprg0 = regs->sprg0;
+ vcpu->arch.shared->sprg1 = regs->sprg1;
+ vcpu->arch.shared->sprg2 = regs->sprg2;
+ vcpu->arch.shared->sprg3 = regs->sprg3;
vcpu->arch.sprg5 = regs->sprg4;
vcpu->arch.sprg6 = regs->sprg5;
vcpu->arch.sprg7 = regs->sprg6;
@@ -1111,10 +1192,9 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
sregs->u.s.ppc64.slb[i].slbv = vcpu3s->slb[i].origv;
}
} else {
- for (i = 0; i < 16; i++) {
- sregs->u.s.ppc32.sr[i] = vcpu3s->sr[i].raw;
- sregs->u.s.ppc32.sr[i] = vcpu3s->sr[i].raw;
- }
+ for (i = 0; i < 16; i++)
+ sregs->u.s.ppc32.sr[i] = vcpu->arch.shared->sr[i];
+
for (i = 0; i < 8; i++) {
sregs->u.s.ppc32.ibat[i] = vcpu3s->ibat[i].raw;
sregs->u.s.ppc32.dbat[i] = vcpu3s->dbat[i].raw;
@@ -1225,6 +1305,7 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
struct kvmppc_vcpu_book3s *vcpu_book3s;
struct kvm_vcpu *vcpu;
int err = -ENOMEM;
+ unsigned long p;
vcpu_book3s = vmalloc(sizeof(struct kvmppc_vcpu_book3s));
if (!vcpu_book3s)
@@ -1242,6 +1323,12 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
if (err)
goto free_shadow_vcpu;
+ p = __get_free_page(GFP_KERNEL|__GFP_ZERO);
+ /* the real shared page fills the last 4k of our page */
+ vcpu->arch.shared = (void*)(p + PAGE_SIZE - 4096);
+ if (!p)
+ goto uninit_vcpu;
+
vcpu->arch.host_retip = kvm_return_point;
vcpu->arch.host_msr = mfmsr();
#ifdef CONFIG_PPC_BOOK3S_64
@@ -1268,10 +1355,12 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
err = kvmppc_mmu_init(vcpu);
if (err < 0)
- goto free_shadow_vcpu;
+ goto uninit_vcpu;
return vcpu;
+uninit_vcpu:
+ kvm_vcpu_uninit(vcpu);
free_shadow_vcpu:
kfree(vcpu_book3s->shadow_vcpu);
free_vcpu:
@@ -1284,6 +1373,7 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
{
struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
+ free_page((unsigned long)vcpu->arch.shared & PAGE_MASK);
kvm_vcpu_uninit(vcpu);
kfree(vcpu_book3s->shadow_vcpu);
vfree(vcpu_book3s);
@@ -1346,7 +1436,7 @@ int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
local_irq_enable();
/* Preload FPU if it's enabled */
- if (vcpu->arch.msr & MSR_FP)
+ if (vcpu->arch.shared->msr & MSR_FP)
kvmppc_handle_ext(vcpu, BOOK3S_INTERRUPT_FP_UNAVAIL, MSR_FP);
ret = __kvmppc_vcpu_entry(kvm_run, vcpu);
diff --git a/arch/powerpc/kvm/book3s_32_mmu.c b/arch/powerpc/kvm/book3s_32_mmu.c
index 3292d76101d2..c8cefdd15fd8 100644
--- a/arch/powerpc/kvm/book3s_32_mmu.c
+++ b/arch/powerpc/kvm/book3s_32_mmu.c
@@ -58,14 +58,39 @@ static inline bool check_debug_ip(struct kvm_vcpu *vcpu)
#endif
}
+static inline u32 sr_vsid(u32 sr_raw)
+{
+ return sr_raw & 0x0fffffff;
+}
+
+static inline bool sr_valid(u32 sr_raw)
+{
+ return (sr_raw & 0x80000000) ? false : true;
+}
+
+static inline bool sr_ks(u32 sr_raw)
+{
+ return (sr_raw & 0x40000000) ? true: false;
+}
+
+static inline bool sr_kp(u32 sr_raw)
+{
+ return (sr_raw & 0x20000000) ? true: false;
+}
+
+static inline bool sr_nx(u32 sr_raw)
+{
+ return (sr_raw & 0x10000000) ? true: false;
+}
+
static int kvmppc_mmu_book3s_32_xlate_bat(struct kvm_vcpu *vcpu, gva_t eaddr,
struct kvmppc_pte *pte, bool data);
static int kvmppc_mmu_book3s_32_esid_to_vsid(struct kvm_vcpu *vcpu, ulong esid,
u64 *vsid);
-static struct kvmppc_sr *find_sr(struct kvmppc_vcpu_book3s *vcpu_book3s, gva_t eaddr)
+static u32 find_sr(struct kvm_vcpu *vcpu, gva_t eaddr)
{
- return &vcpu_book3s->sr[(eaddr >> 28) & 0xf];
+ return vcpu->arch.shared->sr[(eaddr >> 28) & 0xf];
}
static u64 kvmppc_mmu_book3s_32_ea_to_vp(struct kvm_vcpu *vcpu, gva_t eaddr,
@@ -87,7 +112,7 @@ static void kvmppc_mmu_book3s_32_reset_msr(struct kvm_vcpu *vcpu)
}
static hva_t kvmppc_mmu_book3s_32_get_pteg(struct kvmppc_vcpu_book3s *vcpu_book3s,
- struct kvmppc_sr *sre, gva_t eaddr,
+ u32 sre, gva_t eaddr,
bool primary)
{
u32 page, hash, pteg, htabmask;
@@ -96,7 +121,7 @@ static hva_t kvmppc_mmu_book3s_32_get_pteg(struct kvmppc_vcpu_book3s *vcpu_book3
page = (eaddr & 0x0FFFFFFF) >> 12;
htabmask = ((vcpu_book3s->sdr1 & 0x1FF) << 16) | 0xFFC0;
- hash = ((sre->vsid ^ page) << 6);
+ hash = ((sr_vsid(sre) ^ page) << 6);
if (!primary)
hash = ~hash;
hash &= htabmask;
@@ -104,8 +129,8 @@ static hva_t kvmppc_mmu_book3s_32_get_pteg(struct kvmppc_vcpu_book3s *vcpu_book3
pteg = (vcpu_book3s->sdr1 & 0xffff0000) | hash;
dprintk("MMU: pc=0x%lx eaddr=0x%lx sdr1=0x%llx pteg=0x%x vsid=0x%x\n",
- vcpu_book3s->vcpu.arch.pc, eaddr, vcpu_book3s->sdr1, pteg,
- sre->vsid);
+ kvmppc_get_pc(&vcpu_book3s->vcpu), eaddr, vcpu_book3s->sdr1, pteg,
+ sr_vsid(sre));
r = gfn_to_hva(vcpu_book3s->vcpu.kvm, pteg >> PAGE_SHIFT);
if (kvm_is_error_hva(r))
@@ -113,10 +138,9 @@ static hva_t kvmppc_mmu_book3s_32_get_pteg(struct kvmppc_vcpu_book3s *vcpu_book3
return r | (pteg & ~PAGE_MASK);
}
-static u32 kvmppc_mmu_book3s_32_get_ptem(struct kvmppc_sr *sre, gva_t eaddr,
- bool primary)
+static u32 kvmppc_mmu_book3s_32_get_ptem(u32 sre, gva_t eaddr, bool primary)
{
- return ((eaddr & 0x0fffffff) >> 22) | (sre->vsid << 7) |
+ return ((eaddr & 0x0fffffff) >> 22) | (sr_vsid(sre) << 7) |
(primary ? 0 : 0x40) | 0x80000000;
}
@@ -133,7 +157,7 @@ static int kvmppc_mmu_book3s_32_xlate_bat(struct kvm_vcpu *vcpu, gva_t eaddr,
else
bat = &vcpu_book3s->ibat[i];
- if (vcpu->arch.msr & MSR_PR) {
+ if (vcpu->arch.shared->msr & MSR_PR) {
if (!bat->vp)
continue;
} else {
@@ -180,17 +204,17 @@ static int kvmppc_mmu_book3s_32_xlate_pte(struct kvm_vcpu *vcpu, gva_t eaddr,
bool primary)
{
struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
- struct kvmppc_sr *sre;
+ u32 sre;
hva_t ptegp;
u32 pteg[16];
u32 ptem = 0;
int i;
int found = 0;
- sre = find_sr(vcpu_book3s, eaddr);
+ sre = find_sr(vcpu, eaddr);
dprintk_pte("SR 0x%lx: vsid=0x%x, raw=0x%x\n", eaddr >> 28,
- sre->vsid, sre->raw);
+ sr_vsid(sre), sre);
pte->vpage = kvmppc_mmu_book3s_32_ea_to_vp(vcpu, eaddr, data);
@@ -214,8 +238,8 @@ static int kvmppc_mmu_book3s_32_xlate_pte(struct kvm_vcpu *vcpu, gva_t eaddr,
pte->raddr = (pteg[i+1] & ~(0xFFFULL)) | (eaddr & 0xFFF);
pp = pteg[i+1] & 3;
- if ((sre->Kp && (vcpu->arch.msr & MSR_PR)) ||
- (sre->Ks && !(vcpu->arch.msr & MSR_PR)))
+ if ((sr_kp(sre) && (vcpu->arch.shared->msr & MSR_PR)) ||
+ (sr_ks(sre) && !(vcpu->arch.shared->msr & MSR_PR)))
pp |= 4;
pte->may_write = false;
@@ -269,7 +293,7 @@ no_page_found:
dprintk_pte("KVM MMU: No PTE found (sdr1=0x%llx ptegp=0x%lx)\n",
to_book3s(vcpu)->sdr1, ptegp);
for (i=0; i<16; i+=2) {
- dprintk_pte(" %02d: 0x%x - 0x%x (0x%llx)\n",
+ dprintk_pte(" %02d: 0x%x - 0x%x (0x%x)\n",
i, pteg[i], pteg[i+1], ptem);
}
}
@@ -281,8 +305,24 @@ static int kvmppc_mmu_book3s_32_xlate(struct kvm_vcpu *vcpu, gva_t eaddr,
struct kvmppc_pte *pte, bool data)
{
int r;
+ ulong mp_ea = vcpu->arch.magic_page_ea;
pte->eaddr = eaddr;
+
+ /* Magic page override */
+ if (unlikely(mp_ea) &&
+ unlikely((eaddr & ~0xfffULL) == (mp_ea & ~0xfffULL)) &&
+ !(vcpu->arch.shared->msr & MSR_PR)) {
+ pte->vpage = kvmppc_mmu_book3s_32_ea_to_vp(vcpu, eaddr, data);
+ pte->raddr = vcpu->arch.magic_page_pa | (pte->raddr & 0xfff);
+ pte->raddr &= KVM_PAM;
+ pte->may_execute = true;
+ pte->may_read = true;
+ pte->may_write = true;
+
+ return 0;
+ }
+
r = kvmppc_mmu_book3s_32_xlate_bat(vcpu, eaddr, pte, data);
if (r < 0)
r = kvmppc_mmu_book3s_32_xlate_pte(vcpu, eaddr, pte, data, true);
@@ -295,30 +335,13 @@ static int kvmppc_mmu_book3s_32_xlate(struct kvm_vcpu *vcpu, gva_t eaddr,
static u32 kvmppc_mmu_book3s_32_mfsrin(struct kvm_vcpu *vcpu, u32 srnum)
{
- return to_book3s(vcpu)->sr[srnum].raw;
+ return vcpu->arch.shared->sr[srnum];
}
static void kvmppc_mmu_book3s_32_mtsrin(struct kvm_vcpu *vcpu, u32 srnum,
ulong value)
{
- struct kvmppc_sr *sre;
-
- sre = &to_book3s(vcpu)->sr[srnum];
-
- /* Flush any left-over shadows from the previous SR */
-
- /* XXX Not necessary? */
- /* kvmppc_mmu_pte_flush(vcpu, ((u64)sre->vsid) << 28, 0xf0000000ULL); */
-
- /* And then put in the new SR */
- sre->raw = value;
- sre->vsid = (value & 0x0fffffff);
- sre->valid = (value & 0x80000000) ? false : true;
- sre->Ks = (value & 0x40000000) ? true : false;
- sre->Kp = (value & 0x20000000) ? true : false;
- sre->nx = (value & 0x10000000) ? true : false;
-
- /* Map the new segment */
+ vcpu->arch.shared->sr[srnum] = value;
kvmppc_mmu_map_segment(vcpu, srnum << SID_SHIFT);
}
@@ -331,19 +354,19 @@ static int kvmppc_mmu_book3s_32_esid_to_vsid(struct kvm_vcpu *vcpu, ulong esid,
u64 *vsid)
{
ulong ea = esid << SID_SHIFT;
- struct kvmppc_sr *sr;
+ u32 sr;
u64 gvsid = esid;
- if (vcpu->arch.msr & (MSR_DR|MSR_IR)) {
- sr = find_sr(to_book3s(vcpu), ea);
- if (sr->valid)
- gvsid = sr->vsid;
+ if (vcpu->arch.shared->msr & (MSR_DR|MSR_IR)) {
+ sr = find_sr(vcpu, ea);
+ if (sr_valid(sr))
+ gvsid = sr_vsid(sr);
}
/* In case we only have one of MSR_IR or MSR_DR set, let's put
that in the real-mode context (and hope RM doesn't access
high memory) */
- switch (vcpu->arch.msr & (MSR_DR|MSR_IR)) {
+ switch (vcpu->arch.shared->msr & (MSR_DR|MSR_IR)) {
case 0:
*vsid = VSID_REAL | esid;
break;
@@ -354,8 +377,8 @@ static int kvmppc_mmu_book3s_32_esid_to_vsid(struct kvm_vcpu *vcpu, ulong esid,
*vsid = VSID_REAL_DR | gvsid;
break;
case MSR_DR|MSR_IR:
- if (sr->valid)
- *vsid = sr->vsid;
+ if (sr_valid(sr))
+ *vsid = sr_vsid(sr);
else
*vsid = VSID_BAT | gvsid;
break;
@@ -363,7 +386,7 @@ static int kvmppc_mmu_book3s_32_esid_to_vsid(struct kvm_vcpu *vcpu, ulong esid,
BUG();
}
- if (vcpu->arch.msr & MSR_PR)
+ if (vcpu->arch.shared->msr & MSR_PR)
*vsid |= VSID_PR;
return 0;
diff --git a/arch/powerpc/kvm/book3s_32_mmu_host.c b/arch/powerpc/kvm/book3s_32_mmu_host.c
index 0b51ef872c1e..9fecbfbce773 100644
--- a/arch/powerpc/kvm/book3s_32_mmu_host.c
+++ b/arch/powerpc/kvm/book3s_32_mmu_host.c
@@ -19,7 +19,6 @@
*/
#include <linux/kvm_host.h>
-#include <linux/hash.h>
#include <asm/kvm_ppc.h>
#include <asm/kvm_book3s.h>
@@ -77,7 +76,14 @@ void kvmppc_mmu_invalidate_pte(struct kvm_vcpu *vcpu, struct hpte_cache *pte)
* a hash, so we don't waste cycles on looping */
static u16 kvmppc_sid_hash(struct kvm_vcpu *vcpu, u64 gvsid)
{
- return hash_64(gvsid, SID_MAP_BITS);
+ return (u16)(((gvsid >> (SID_MAP_BITS * 7)) & SID_MAP_MASK) ^
+ ((gvsid >> (SID_MAP_BITS * 6)) & SID_MAP_MASK) ^
+ ((gvsid >> (SID_MAP_BITS * 5)) & SID_MAP_MASK) ^
+ ((gvsid >> (SID_MAP_BITS * 4)) & SID_MAP_MASK) ^
+ ((gvsid >> (SID_MAP_BITS * 3)) & SID_MAP_MASK) ^
+ ((gvsid >> (SID_MAP_BITS * 2)) & SID_MAP_MASK) ^
+ ((gvsid >> (SID_MAP_BITS * 1)) & SID_MAP_MASK) ^
+ ((gvsid >> (SID_MAP_BITS * 0)) & SID_MAP_MASK));
}
@@ -86,7 +92,7 @@ static struct kvmppc_sid_map *find_sid_vsid(struct kvm_vcpu *vcpu, u64 gvsid)
struct kvmppc_sid_map *map;
u16 sid_map_mask;
- if (vcpu->arch.msr & MSR_PR)
+ if (vcpu->arch.shared->msr & MSR_PR)
gvsid |= VSID_PR;
sid_map_mask = kvmppc_sid_hash(vcpu, gvsid);
@@ -147,8 +153,8 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte)
struct hpte_cache *pte;
/* Get host physical address for gpa */
- hpaddr = gfn_to_pfn(vcpu->kvm, orig_pte->raddr >> PAGE_SHIFT);
- if (kvm_is_error_hva(hpaddr)) {
+ hpaddr = kvmppc_gfn_to_pfn(vcpu, orig_pte->raddr >> PAGE_SHIFT);
+ if (is_error_pfn(hpaddr)) {
printk(KERN_INFO "Couldn't get guest page for gfn %lx!\n",
orig_pte->eaddr);
return -EINVAL;
@@ -253,7 +259,7 @@ static struct kvmppc_sid_map *create_sid_map(struct kvm_vcpu *vcpu, u64 gvsid)
u16 sid_map_mask;
static int backwards_map = 0;
- if (vcpu->arch.msr & MSR_PR)
+ if (vcpu->arch.shared->msr & MSR_PR)
gvsid |= VSID_PR;
/* We might get collisions that trap in preceding order, so let's
@@ -269,18 +275,15 @@ static struct kvmppc_sid_map *create_sid_map(struct kvm_vcpu *vcpu, u64 gvsid)
backwards_map = !backwards_map;
/* Uh-oh ... out of mappings. Let's flush! */
- if (vcpu_book3s->vsid_next >= vcpu_book3s->vsid_max) {
- vcpu_book3s->vsid_next = vcpu_book3s->vsid_first;
+ if (vcpu_book3s->vsid_next >= VSID_POOL_SIZE) {
+ vcpu_book3s->vsid_next = 0;
memset(vcpu_book3s->sid_map, 0,
sizeof(struct kvmppc_sid_map) * SID_MAP_NUM);
kvmppc_mmu_pte_flush(vcpu, 0, 0);
kvmppc_mmu_flush_segments(vcpu);
}
- map->host_vsid = vcpu_book3s->vsid_next;
-
- /* Would have to be 111 to be completely aligned with the rest of
- Linux, but that is just way too little space! */
- vcpu_book3s->vsid_next+=1;
+ map->host_vsid = vcpu_book3s->vsid_pool[vcpu_book3s->vsid_next];
+ vcpu_book3s->vsid_next++;
map->guest_vsid = gvsid;
map->valid = true;
@@ -327,40 +330,38 @@ void kvmppc_mmu_flush_segments(struct kvm_vcpu *vcpu)
void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu)
{
+ int i;
+
kvmppc_mmu_hpte_destroy(vcpu);
preempt_disable();
- __destroy_context(to_book3s(vcpu)->context_id);
+ for (i = 0; i < SID_CONTEXTS; i++)
+ __destroy_context(to_book3s(vcpu)->context_id[i]);
preempt_enable();
}
/* From mm/mmu_context_hash32.c */
-#define CTX_TO_VSID(ctx) (((ctx) * (897 * 16)) & 0xffffff)
+#define CTX_TO_VSID(c, id) ((((c) * (897 * 16)) + (id * 0x111)) & 0xffffff)
int kvmppc_mmu_init(struct kvm_vcpu *vcpu)
{
struct kvmppc_vcpu_book3s *vcpu3s = to_book3s(vcpu);
int err;
ulong sdr1;
+ int i;
+ int j;
- err = __init_new_context();
- if (err < 0)
- return -1;
- vcpu3s->context_id = err;
-
- vcpu3s->vsid_max = CTX_TO_VSID(vcpu3s->context_id + 1) - 1;
- vcpu3s->vsid_first = CTX_TO_VSID(vcpu3s->context_id);
-
-#if 0 /* XXX still doesn't guarantee uniqueness */
- /* We could collide with the Linux vsid space because the vsid
- * wraps around at 24 bits. We're safe if we do our own space
- * though, so let's always set the highest bit. */
+ for (i = 0; i < SID_CONTEXTS; i++) {
+ err = __init_new_context();
+ if (err < 0)
+ goto init_fail;
+ vcpu3s->context_id[i] = err;
- vcpu3s->vsid_max |= 0x00800000;
- vcpu3s->vsid_first |= 0x00800000;
-#endif
- BUG_ON(vcpu3s->vsid_max < vcpu3s->vsid_first);
+ /* Remember context id for this combination */
+ for (j = 0; j < 16; j++)
+ vcpu3s->vsid_pool[(i * 16) + j] = CTX_TO_VSID(err, j);
+ }
- vcpu3s->vsid_next = vcpu3s->vsid_first;
+ vcpu3s->vsid_next = 0;
/* Remember where the HTAB is */
asm ( "mfsdr1 %0" : "=r"(sdr1) );
@@ -370,4 +371,14 @@ int kvmppc_mmu_init(struct kvm_vcpu *vcpu)
kvmppc_mmu_hpte_init(vcpu);
return 0;
+
+init_fail:
+ for (j = 0; j < i; j++) {
+ if (!vcpu3s->context_id[j])
+ continue;
+
+ __destroy_context(to_book3s(vcpu)->context_id[j]);
+ }
+
+ return -1;
}
diff --git a/arch/powerpc/kvm/book3s_64_mmu.c b/arch/powerpc/kvm/book3s_64_mmu.c
index 4025ea26b3c1..d7889ef3211e 100644
--- a/arch/powerpc/kvm/book3s_64_mmu.c
+++ b/arch/powerpc/kvm/book3s_64_mmu.c
@@ -163,6 +163,22 @@ static int kvmppc_mmu_book3s_64_xlate(struct kvm_vcpu *vcpu, gva_t eaddr,
bool found = false;
bool perm_err = false;
int second = 0;
+ ulong mp_ea = vcpu->arch.magic_page_ea;
+
+ /* Magic page override */
+ if (unlikely(mp_ea) &&
+ unlikely((eaddr & ~0xfffULL) == (mp_ea & ~0xfffULL)) &&
+ !(vcpu->arch.shared->msr & MSR_PR)) {
+ gpte->eaddr = eaddr;
+ gpte->vpage = kvmppc_mmu_book3s_64_ea_to_vp(vcpu, eaddr, data);
+ gpte->raddr = vcpu->arch.magic_page_pa | (gpte->raddr & 0xfff);
+ gpte->raddr &= KVM_PAM;
+ gpte->may_execute = true;
+ gpte->may_read = true;
+ gpte->may_write = true;
+
+ return 0;
+ }
slbe = kvmppc_mmu_book3s_64_find_slbe(vcpu_book3s, eaddr);
if (!slbe)
@@ -180,9 +196,9 @@ do_second:
goto no_page_found;
}
- if ((vcpu->arch.msr & MSR_PR) && slbe->Kp)
+ if ((vcpu->arch.shared->msr & MSR_PR) && slbe->Kp)
key = 4;
- else if (!(vcpu->arch.msr & MSR_PR) && slbe->Ks)
+ else if (!(vcpu->arch.shared->msr & MSR_PR) && slbe->Ks)
key = 4;
for (i=0; i<16; i+=2) {
@@ -381,7 +397,7 @@ static void kvmppc_mmu_book3s_64_slbia(struct kvm_vcpu *vcpu)
for (i = 1; i < vcpu_book3s->slb_nr; i++)
vcpu_book3s->slb[i].valid = false;
- if (vcpu->arch.msr & MSR_IR) {
+ if (vcpu->arch.shared->msr & MSR_IR) {
kvmppc_mmu_flush_segments(vcpu);
kvmppc_mmu_map_segment(vcpu, kvmppc_get_pc(vcpu));
}
@@ -445,14 +461,15 @@ static int kvmppc_mmu_book3s_64_esid_to_vsid(struct kvm_vcpu *vcpu, ulong esid,
ulong ea = esid << SID_SHIFT;
struct kvmppc_slb *slb;
u64 gvsid = esid;
+ ulong mp_ea = vcpu->arch.magic_page_ea;
- if (vcpu->arch.msr & (MSR_DR|MSR_IR)) {
+ if (vcpu->arch.shared->msr & (MSR_DR|MSR_IR)) {
slb = kvmppc_mmu_book3s_64_find_slbe(to_book3s(vcpu), ea);
if (slb)
gvsid = slb->vsid;
}
- switch (vcpu->arch.msr & (MSR_DR|MSR_IR)) {
+ switch (vcpu->arch.shared->msr & (MSR_DR|MSR_IR)) {
case 0:
*vsid = VSID_REAL | esid;
break;
@@ -464,7 +481,7 @@ static int kvmppc_mmu_book3s_64_esid_to_vsid(struct kvm_vcpu *vcpu, ulong esid,
break;
case MSR_DR|MSR_IR:
if (!slb)
- return -ENOENT;
+ goto no_slb;
*vsid = gvsid;
break;
@@ -473,10 +490,21 @@ static int kvmppc_mmu_book3s_64_esid_to_vsid(struct kvm_vcpu *vcpu, ulong esid,
break;
}
- if (vcpu->arch.msr & MSR_PR)
+ if (vcpu->arch.shared->msr & MSR_PR)
*vsid |= VSID_PR;
return 0;
+
+no_slb:
+ /* Catch magic page case */
+ if (unlikely(mp_ea) &&
+ unlikely(esid == (mp_ea >> SID_SHIFT)) &&
+ !(vcpu->arch.shared->msr & MSR_PR)) {
+ *vsid = VSID_REAL | esid;
+ return 0;
+ }
+
+ return -EINVAL;
}
static bool kvmppc_mmu_book3s_64_is_dcbz32(struct kvm_vcpu *vcpu)
diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c
index 384179a5002b..fa2f08434ba5 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_host.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_host.c
@@ -20,7 +20,6 @@
*/
#include <linux/kvm_host.h>
-#include <linux/hash.h>
#include <asm/kvm_ppc.h>
#include <asm/kvm_book3s.h>
@@ -28,24 +27,9 @@
#include <asm/machdep.h>
#include <asm/mmu_context.h>
#include <asm/hw_irq.h>
+#include "trace.h"
#define PTE_SIZE 12
-#define VSID_ALL 0
-
-/* #define DEBUG_MMU */
-/* #define DEBUG_SLB */
-
-#ifdef DEBUG_MMU
-#define dprintk_mmu(a, ...) printk(KERN_INFO a, __VA_ARGS__)
-#else
-#define dprintk_mmu(a, ...) do { } while(0)
-#endif
-
-#ifdef DEBUG_SLB
-#define dprintk_slb(a, ...) printk(KERN_INFO a, __VA_ARGS__)
-#else
-#define dprintk_slb(a, ...) do { } while(0)
-#endif
void kvmppc_mmu_invalidate_pte(struct kvm_vcpu *vcpu, struct hpte_cache *pte)
{
@@ -58,34 +42,39 @@ void kvmppc_mmu_invalidate_pte(struct kvm_vcpu *vcpu, struct hpte_cache *pte)
* a hash, so we don't waste cycles on looping */
static u16 kvmppc_sid_hash(struct kvm_vcpu *vcpu, u64 gvsid)
{
- return hash_64(gvsid, SID_MAP_BITS);
+ return (u16)(((gvsid >> (SID_MAP_BITS * 7)) & SID_MAP_MASK) ^
+ ((gvsid >> (SID_MAP_BITS * 6)) & SID_MAP_MASK) ^
+ ((gvsid >> (SID_MAP_BITS * 5)) & SID_MAP_MASK) ^
+ ((gvsid >> (SID_MAP_BITS * 4)) & SID_MAP_MASK) ^
+ ((gvsid >> (SID_MAP_BITS * 3)) & SID_MAP_MASK) ^
+ ((gvsid >> (SID_MAP_BITS * 2)) & SID_MAP_MASK) ^
+ ((gvsid >> (SID_MAP_BITS * 1)) & SID_MAP_MASK) ^
+ ((gvsid >> (SID_MAP_BITS * 0)) & SID_MAP_MASK));
}
+
static struct kvmppc_sid_map *find_sid_vsid(struct kvm_vcpu *vcpu, u64 gvsid)
{
struct kvmppc_sid_map *map;
u16 sid_map_mask;
- if (vcpu->arch.msr & MSR_PR)
+ if (vcpu->arch.shared->msr & MSR_PR)
gvsid |= VSID_PR;
sid_map_mask = kvmppc_sid_hash(vcpu, gvsid);
map = &to_book3s(vcpu)->sid_map[sid_map_mask];
- if (map->guest_vsid == gvsid) {
- dprintk_slb("SLB: Searching: 0x%llx -> 0x%llx\n",
- gvsid, map->host_vsid);
+ if (map->valid && (map->guest_vsid == gvsid)) {
+ trace_kvm_book3s_slb_found(gvsid, map->host_vsid);
return map;
}
map = &to_book3s(vcpu)->sid_map[SID_MAP_MASK - sid_map_mask];
- if (map->guest_vsid == gvsid) {
- dprintk_slb("SLB: Searching 0x%llx -> 0x%llx\n",
- gvsid, map->host_vsid);
+ if (map->valid && (map->guest_vsid == gvsid)) {
+ trace_kvm_book3s_slb_found(gvsid, map->host_vsid);
return map;
}
- dprintk_slb("SLB: Searching %d/%d: 0x%llx -> not found\n",
- sid_map_mask, SID_MAP_MASK - sid_map_mask, gvsid);
+ trace_kvm_book3s_slb_fail(sid_map_mask, gvsid);
return NULL;
}
@@ -101,18 +90,13 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte)
struct kvmppc_sid_map *map;
/* Get host physical address for gpa */
- hpaddr = gfn_to_pfn(vcpu->kvm, orig_pte->raddr >> PAGE_SHIFT);
- if (kvm_is_error_hva(hpaddr)) {
+ hpaddr = kvmppc_gfn_to_pfn(vcpu, orig_pte->raddr >> PAGE_SHIFT);
+ if (is_error_pfn(hpaddr)) {
printk(KERN_INFO "Couldn't get guest page for gfn %lx!\n", orig_pte->eaddr);
return -EINVAL;
}
hpaddr <<= PAGE_SHIFT;
-#if PAGE_SHIFT == 12
-#elif PAGE_SHIFT == 16
- hpaddr |= orig_pte->raddr & 0xf000;
-#else
-#error Unknown page size
-#endif
+ hpaddr |= orig_pte->raddr & (~0xfffULL & ~PAGE_MASK);
/* and write the mapping ea -> hpa into the pt */
vcpu->arch.mmu.esid_to_vsid(vcpu, orig_pte->eaddr >> SID_SHIFT, &vsid);
@@ -161,10 +145,7 @@ map_again:
} else {
struct hpte_cache *pte = kvmppc_mmu_hpte_cache_next(vcpu);
- dprintk_mmu("KVM: %c%c Map 0x%lx: [%lx] 0x%lx (0x%llx) -> %lx\n",
- ((rflags & HPTE_R_PP) == 3) ? '-' : 'w',
- (rflags & HPTE_R_N) ? '-' : 'x',
- orig_pte->eaddr, hpteg, va, orig_pte->vpage, hpaddr);
+ trace_kvm_book3s_64_mmu_map(rflags, hpteg, va, hpaddr, orig_pte);
/* The ppc_md code may give us a secondary entry even though we
asked for a primary. Fix up. */
@@ -191,7 +172,7 @@ static struct kvmppc_sid_map *create_sid_map(struct kvm_vcpu *vcpu, u64 gvsid)
u16 sid_map_mask;
static int backwards_map = 0;
- if (vcpu->arch.msr & MSR_PR)
+ if (vcpu->arch.shared->msr & MSR_PR)
gvsid |= VSID_PR;
/* We might get collisions that trap in preceding order, so let's
@@ -219,8 +200,7 @@ static struct kvmppc_sid_map *create_sid_map(struct kvm_vcpu *vcpu, u64 gvsid)
map->guest_vsid = gvsid;
map->valid = true;
- dprintk_slb("SLB: New mapping at %d: 0x%llx -> 0x%llx\n",
- sid_map_mask, gvsid, map->host_vsid);
+ trace_kvm_book3s_slb_map(sid_map_mask, gvsid, map->host_vsid);
return map;
}
@@ -292,7 +272,7 @@ int kvmppc_mmu_map_segment(struct kvm_vcpu *vcpu, ulong eaddr)
to_svcpu(vcpu)->slb[slb_index].esid = slb_esid;
to_svcpu(vcpu)->slb[slb_index].vsid = slb_vsid;
- dprintk_slb("slbmte %#llx, %#llx\n", slb_vsid, slb_esid);
+ trace_kvm_book3s_slbmte(slb_vsid, slb_esid);
return 0;
}
@@ -306,7 +286,7 @@ void kvmppc_mmu_flush_segments(struct kvm_vcpu *vcpu)
void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu)
{
kvmppc_mmu_hpte_destroy(vcpu);
- __destroy_context(to_book3s(vcpu)->context_id);
+ __destroy_context(to_book3s(vcpu)->context_id[0]);
}
int kvmppc_mmu_init(struct kvm_vcpu *vcpu)
@@ -317,10 +297,10 @@ int kvmppc_mmu_init(struct kvm_vcpu *vcpu)
err = __init_new_context();
if (err < 0)
return -1;
- vcpu3s->context_id = err;
+ vcpu3s->context_id[0] = err;
- vcpu3s->vsid_max = ((vcpu3s->context_id + 1) << USER_ESID_BITS) - 1;
- vcpu3s->vsid_first = vcpu3s->context_id << USER_ESID_BITS;
+ vcpu3s->vsid_max = ((vcpu3s->context_id[0] + 1) << USER_ESID_BITS) - 1;
+ vcpu3s->vsid_first = vcpu3s->context_id[0] << USER_ESID_BITS;
vcpu3s->vsid_next = vcpu3s->vsid_first;
kvmppc_mmu_hpte_init(vcpu);
diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c
index c85f906038ce..466846557089 100644
--- a/arch/powerpc/kvm/book3s_emulate.c
+++ b/arch/powerpc/kvm/book3s_emulate.c
@@ -73,8 +73,8 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
switch (get_xop(inst)) {
case OP_19_XOP_RFID:
case OP_19_XOP_RFI:
- kvmppc_set_pc(vcpu, vcpu->arch.srr0);
- kvmppc_set_msr(vcpu, vcpu->arch.srr1);
+ kvmppc_set_pc(vcpu, vcpu->arch.shared->srr0);
+ kvmppc_set_msr(vcpu, vcpu->arch.shared->srr1);
*advance = 0;
break;
@@ -86,14 +86,15 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
case 31:
switch (get_xop(inst)) {
case OP_31_XOP_MFMSR:
- kvmppc_set_gpr(vcpu, get_rt(inst), vcpu->arch.msr);
+ kvmppc_set_gpr(vcpu, get_rt(inst),
+ vcpu->arch.shared->msr);
break;
case OP_31_XOP_MTMSRD:
{
ulong rs = kvmppc_get_gpr(vcpu, get_rs(inst));
if (inst & 0x10000) {
- vcpu->arch.msr &= ~(MSR_RI | MSR_EE);
- vcpu->arch.msr |= rs & (MSR_RI | MSR_EE);
+ vcpu->arch.shared->msr &= ~(MSR_RI | MSR_EE);
+ vcpu->arch.shared->msr |= rs & (MSR_RI | MSR_EE);
} else
kvmppc_set_msr(vcpu, rs);
break;
@@ -204,14 +205,14 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
ra = kvmppc_get_gpr(vcpu, get_ra(inst));
addr = (ra + rb) & ~31ULL;
- if (!(vcpu->arch.msr & MSR_SF))
+ if (!(vcpu->arch.shared->msr & MSR_SF))
addr &= 0xffffffff;
vaddr = addr;
r = kvmppc_st(vcpu, &addr, 32, zeros, true);
if ((r == -ENOENT) || (r == -EPERM)) {
*advance = 0;
- vcpu->arch.dear = vaddr;
+ vcpu->arch.shared->dar = vaddr;
to_svcpu(vcpu)->fault_dar = vaddr;
dsisr = DSISR_ISSTORE;
@@ -220,7 +221,7 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
else if (r == -EPERM)
dsisr |= DSISR_PROTFAULT;
- to_book3s(vcpu)->dsisr = dsisr;
+ vcpu->arch.shared->dsisr = dsisr;
to_svcpu(vcpu)->fault_dsisr = dsisr;
kvmppc_book3s_queue_irqprio(vcpu,
@@ -263,7 +264,7 @@ void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat, bool upper,
}
}
-static u32 kvmppc_read_bat(struct kvm_vcpu *vcpu, int sprn)
+static struct kvmppc_bat *kvmppc_find_bat(struct kvm_vcpu *vcpu, int sprn)
{
struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
struct kvmppc_bat *bat;
@@ -285,35 +286,7 @@ static u32 kvmppc_read_bat(struct kvm_vcpu *vcpu, int sprn)
BUG();
}
- if (sprn % 2)
- return bat->raw >> 32;
- else
- return bat->raw;
-}
-
-static void kvmppc_write_bat(struct kvm_vcpu *vcpu, int sprn, u32 val)
-{
- struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
- struct kvmppc_bat *bat;
-
- switch (sprn) {
- case SPRN_IBAT0U ... SPRN_IBAT3L:
- bat = &vcpu_book3s->ibat[(sprn - SPRN_IBAT0U) / 2];
- break;
- case SPRN_IBAT4U ... SPRN_IBAT7L:
- bat = &vcpu_book3s->ibat[4 + ((sprn - SPRN_IBAT4U) / 2)];
- break;
- case SPRN_DBAT0U ... SPRN_DBAT3L:
- bat = &vcpu_book3s->dbat[(sprn - SPRN_DBAT0U) / 2];
- break;
- case SPRN_DBAT4U ... SPRN_DBAT7L:
- bat = &vcpu_book3s->dbat[4 + ((sprn - SPRN_DBAT4U) / 2)];
- break;
- default:
- BUG();
- }
-
- kvmppc_set_bat(vcpu, bat, !(sprn % 2), val);
+ return bat;
}
int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
@@ -326,10 +299,10 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
to_book3s(vcpu)->sdr1 = spr_val;
break;
case SPRN_DSISR:
- to_book3s(vcpu)->dsisr = spr_val;
+ vcpu->arch.shared->dsisr = spr_val;
break;
case SPRN_DAR:
- vcpu->arch.dear = spr_val;
+ vcpu->arch.shared->dar = spr_val;
break;
case SPRN_HIOR:
to_book3s(vcpu)->hior = spr_val;
@@ -338,12 +311,16 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
case SPRN_IBAT4U ... SPRN_IBAT7L:
case SPRN_DBAT0U ... SPRN_DBAT3L:
case SPRN_DBAT4U ... SPRN_DBAT7L:
- kvmppc_write_bat(vcpu, sprn, (u32)spr_val);
+ {
+ struct kvmppc_bat *bat = kvmppc_find_bat(vcpu, sprn);
+
+ kvmppc_set_bat(vcpu, bat, !(sprn % 2), (u32)spr_val);
/* BAT writes happen so rarely that we're ok to flush
* everything here */
kvmppc_mmu_pte_flush(vcpu, 0, 0);
kvmppc_mmu_flush_segments(vcpu);
break;
+ }
case SPRN_HID0:
to_book3s(vcpu)->hid[0] = spr_val;
break;
@@ -433,16 +410,24 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
case SPRN_IBAT4U ... SPRN_IBAT7L:
case SPRN_DBAT0U ... SPRN_DBAT3L:
case SPRN_DBAT4U ... SPRN_DBAT7L:
- kvmppc_set_gpr(vcpu, rt, kvmppc_read_bat(vcpu, sprn));
+ {
+ struct kvmppc_bat *bat = kvmppc_find_bat(vcpu, sprn);
+
+ if (sprn % 2)
+ kvmppc_set_gpr(vcpu, rt, bat->raw >> 32);
+ else
+ kvmppc_set_gpr(vcpu, rt, bat->raw);
+
break;
+ }
case SPRN_SDR1:
kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->sdr1);
break;
case SPRN_DSISR:
- kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->dsisr);
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->dsisr);
break;
case SPRN_DAR:
- kvmppc_set_gpr(vcpu, rt, vcpu->arch.dear);
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->dar);
break;
case SPRN_HIOR:
kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hior);
diff --git a/arch/powerpc/kvm/book3s_mmu_hpte.c b/arch/powerpc/kvm/book3s_mmu_hpte.c
index 4868d4a7ebc5..79751d8dd131 100644
--- a/arch/powerpc/kvm/book3s_mmu_hpte.c
+++ b/arch/powerpc/kvm/book3s_mmu_hpte.c
@@ -21,6 +21,7 @@
#include <linux/kvm_host.h>
#include <linux/hash.h>
#include <linux/slab.h>
+#include "trace.h"
#include <asm/kvm_ppc.h>
#include <asm/kvm_book3s.h>
@@ -30,14 +31,6 @@
#define PTE_SIZE 12
-/* #define DEBUG_MMU */
-
-#ifdef DEBUG_MMU
-#define dprintk_mmu(a, ...) printk(KERN_INFO a, __VA_ARGS__)
-#else
-#define dprintk_mmu(a, ...) do { } while(0)
-#endif
-
static struct kmem_cache *hpte_cache;
static inline u64 kvmppc_mmu_hash_pte(u64 eaddr)
@@ -45,6 +38,12 @@ static inline u64 kvmppc_mmu_hash_pte(u64 eaddr)
return hash_64(eaddr >> PTE_SIZE, HPTEG_HASH_BITS_PTE);
}
+static inline u64 kvmppc_mmu_hash_pte_long(u64 eaddr)
+{
+ return hash_64((eaddr & 0x0ffff000) >> PTE_SIZE,
+ HPTEG_HASH_BITS_PTE_LONG);
+}
+
static inline u64 kvmppc_mmu_hash_vpte(u64 vpage)
{
return hash_64(vpage & 0xfffffffffULL, HPTEG_HASH_BITS_VPTE);
@@ -60,77 +59,128 @@ void kvmppc_mmu_hpte_cache_map(struct kvm_vcpu *vcpu, struct hpte_cache *pte)
{
u64 index;
+ trace_kvm_book3s_mmu_map(pte);
+
+ spin_lock(&vcpu->arch.mmu_lock);
+
/* Add to ePTE list */
index = kvmppc_mmu_hash_pte(pte->pte.eaddr);
- hlist_add_head(&pte->list_pte, &vcpu->arch.hpte_hash_pte[index]);
+ hlist_add_head_rcu(&pte->list_pte, &vcpu->arch.hpte_hash_pte[index]);
+
+ /* Add to ePTE_long list */
+ index = kvmppc_mmu_hash_pte_long(pte->pte.eaddr);
+ hlist_add_head_rcu(&pte->list_pte_long,
+ &vcpu->arch.hpte_hash_pte_long[index]);
/* Add to vPTE list */
index = kvmppc_mmu_hash_vpte(pte->pte.vpage);
- hlist_add_head(&pte->list_vpte, &vcpu->arch.hpte_hash_vpte[index]);
+ hlist_add_head_rcu(&pte->list_vpte, &vcpu->arch.hpte_hash_vpte[index]);
/* Add to vPTE_long list */
index = kvmppc_mmu_hash_vpte_long(pte->pte.vpage);
- hlist_add_head(&pte->list_vpte_long,
- &vcpu->arch.hpte_hash_vpte_long[index]);
+ hlist_add_head_rcu(&pte->list_vpte_long,
+ &vcpu->arch.hpte_hash_vpte_long[index]);
+
+ spin_unlock(&vcpu->arch.mmu_lock);
+}
+
+static void free_pte_rcu(struct rcu_head *head)
+{
+ struct hpte_cache *pte = container_of(head, struct hpte_cache, rcu_head);
+ kmem_cache_free(hpte_cache, pte);
}
static void invalidate_pte(struct kvm_vcpu *vcpu, struct hpte_cache *pte)
{
- dprintk_mmu("KVM: Flushing SPT: 0x%lx (0x%llx) -> 0x%llx\n",
- pte->pte.eaddr, pte->pte.vpage, pte->host_va);
+ trace_kvm_book3s_mmu_invalidate(pte);
/* Different for 32 and 64 bit */
kvmppc_mmu_invalidate_pte(vcpu, pte);
+ spin_lock(&vcpu->arch.mmu_lock);
+
+ /* pte already invalidated in between? */
+ if (hlist_unhashed(&pte->list_pte)) {
+ spin_unlock(&vcpu->arch.mmu_lock);
+ return;
+ }
+
+ hlist_del_init_rcu(&pte->list_pte);
+ hlist_del_init_rcu(&pte->list_pte_long);
+ hlist_del_init_rcu(&pte->list_vpte);
+ hlist_del_init_rcu(&pte->list_vpte_long);
+
if (pte->pte.may_write)
kvm_release_pfn_dirty(pte->pfn);
else
kvm_release_pfn_clean(pte->pfn);
- hlist_del(&pte->list_pte);
- hlist_del(&pte->list_vpte);
- hlist_del(&pte->list_vpte_long);
+ spin_unlock(&vcpu->arch.mmu_lock);
vcpu->arch.hpte_cache_count--;
- kmem_cache_free(hpte_cache, pte);
+ call_rcu(&pte->rcu_head, free_pte_rcu);
}
static void kvmppc_mmu_pte_flush_all(struct kvm_vcpu *vcpu)
{
struct hpte_cache *pte;
- struct hlist_node *node, *tmp;
+ struct hlist_node *node;
int i;
+ rcu_read_lock();
+
for (i = 0; i < HPTEG_HASH_NUM_VPTE_LONG; i++) {
struct hlist_head *list = &vcpu->arch.hpte_hash_vpte_long[i];
- hlist_for_each_entry_safe(pte, node, tmp, list, list_vpte_long)
+ hlist_for_each_entry_rcu(pte, node, list, list_vpte_long)
invalidate_pte(vcpu, pte);
}
+
+ rcu_read_unlock();
}
static void kvmppc_mmu_pte_flush_page(struct kvm_vcpu *vcpu, ulong guest_ea)
{
struct hlist_head *list;
- struct hlist_node *node, *tmp;
+ struct hlist_node *node;
struct hpte_cache *pte;
/* Find the list of entries in the map */
list = &vcpu->arch.hpte_hash_pte[kvmppc_mmu_hash_pte(guest_ea)];
+ rcu_read_lock();
+
/* Check the list for matching entries and invalidate */
- hlist_for_each_entry_safe(pte, node, tmp, list, list_pte)
+ hlist_for_each_entry_rcu(pte, node, list, list_pte)
if ((pte->pte.eaddr & ~0xfffUL) == guest_ea)
invalidate_pte(vcpu, pte);
+
+ rcu_read_unlock();
}
-void kvmppc_mmu_pte_flush(struct kvm_vcpu *vcpu, ulong guest_ea, ulong ea_mask)
+static void kvmppc_mmu_pte_flush_long(struct kvm_vcpu *vcpu, ulong guest_ea)
{
- u64 i;
+ struct hlist_head *list;
+ struct hlist_node *node;
+ struct hpte_cache *pte;
- dprintk_mmu("KVM: Flushing %d Shadow PTEs: 0x%lx & 0x%lx\n",
- vcpu->arch.hpte_cache_count, guest_ea, ea_mask);
+ /* Find the list of entries in the map */
+ list = &vcpu->arch.hpte_hash_pte_long[
+ kvmppc_mmu_hash_pte_long(guest_ea)];
+ rcu_read_lock();
+
+ /* Check the list for matching entries and invalidate */
+ hlist_for_each_entry_rcu(pte, node, list, list_pte_long)
+ if ((pte->pte.eaddr & 0x0ffff000UL) == guest_ea)
+ invalidate_pte(vcpu, pte);
+
+ rcu_read_unlock();
+}
+
+void kvmppc_mmu_pte_flush(struct kvm_vcpu *vcpu, ulong guest_ea, ulong ea_mask)
+{
+ trace_kvm_book3s_mmu_flush("", vcpu, guest_ea, ea_mask);
guest_ea &= ea_mask;
switch (ea_mask) {
@@ -138,9 +188,7 @@ void kvmppc_mmu_pte_flush(struct kvm_vcpu *vcpu, ulong guest_ea, ulong ea_mask)
kvmppc_mmu_pte_flush_page(vcpu, guest_ea);
break;
case 0x0ffff000:
- /* 32-bit flush w/o segment, go through all possible segments */
- for (i = 0; i < 0x100000000ULL; i += 0x10000000ULL)
- kvmppc_mmu_pte_flush(vcpu, guest_ea | i, ~0xfffUL);
+ kvmppc_mmu_pte_flush_long(vcpu, guest_ea);
break;
case 0:
/* Doing a complete flush -> start from scratch */
@@ -156,39 +204,46 @@ void kvmppc_mmu_pte_flush(struct kvm_vcpu *vcpu, ulong guest_ea, ulong ea_mask)
static void kvmppc_mmu_pte_vflush_short(struct kvm_vcpu *vcpu, u64 guest_vp)
{
struct hlist_head *list;
- struct hlist_node *node, *tmp;
+ struct hlist_node *node;
struct hpte_cache *pte;
u64 vp_mask = 0xfffffffffULL;
list = &vcpu->arch.hpte_hash_vpte[kvmppc_mmu_hash_vpte(guest_vp)];
+ rcu_read_lock();
+
/* Check the list for matching entries and invalidate */
- hlist_for_each_entry_safe(pte, node, tmp, list, list_vpte)
+ hlist_for_each_entry_rcu(pte, node, list, list_vpte)
if ((pte->pte.vpage & vp_mask) == guest_vp)
invalidate_pte(vcpu, pte);
+
+ rcu_read_unlock();
}
/* Flush with mask 0xffffff000 */
static void kvmppc_mmu_pte_vflush_long(struct kvm_vcpu *vcpu, u64 guest_vp)
{
struct hlist_head *list;
- struct hlist_node *node, *tmp;
+ struct hlist_node *node;
struct hpte_cache *pte;
u64 vp_mask = 0xffffff000ULL;
list = &vcpu->arch.hpte_hash_vpte_long[
kvmppc_mmu_hash_vpte_long(guest_vp)];
+ rcu_read_lock();
+
/* Check the list for matching entries and invalidate */
- hlist_for_each_entry_safe(pte, node, tmp, list, list_vpte_long)
+ hlist_for_each_entry_rcu(pte, node, list, list_vpte_long)
if ((pte->pte.vpage & vp_mask) == guest_vp)
invalidate_pte(vcpu, pte);
+
+ rcu_read_unlock();
}
void kvmppc_mmu_pte_vflush(struct kvm_vcpu *vcpu, u64 guest_vp, u64 vp_mask)
{
- dprintk_mmu("KVM: Flushing %d Shadow vPTEs: 0x%llx & 0x%llx\n",
- vcpu->arch.hpte_cache_count, guest_vp, vp_mask);
+ trace_kvm_book3s_mmu_flush("v", vcpu, guest_vp, vp_mask);
guest_vp &= vp_mask;
switch(vp_mask) {
@@ -206,21 +261,24 @@ void kvmppc_mmu_pte_vflush(struct kvm_vcpu *vcpu, u64 guest_vp, u64 vp_mask)
void kvmppc_mmu_pte_pflush(struct kvm_vcpu *vcpu, ulong pa_start, ulong pa_end)
{
- struct hlist_node *node, *tmp;
+ struct hlist_node *node;
struct hpte_cache *pte;
int i;
- dprintk_mmu("KVM: Flushing %d Shadow pPTEs: 0x%lx - 0x%lx\n",
- vcpu->arch.hpte_cache_count, pa_start, pa_end);
+ trace_kvm_book3s_mmu_flush("p", vcpu, pa_start, pa_end);
+
+ rcu_read_lock();
for (i = 0; i < HPTEG_HASH_NUM_VPTE_LONG; i++) {
struct hlist_head *list = &vcpu->arch.hpte_hash_vpte_long[i];
- hlist_for_each_entry_safe(pte, node, tmp, list, list_vpte_long)
+ hlist_for_each_entry_rcu(pte, node, list, list_vpte_long)
if ((pte->pte.raddr >= pa_start) &&
(pte->pte.raddr < pa_end))
invalidate_pte(vcpu, pte);
}
+
+ rcu_read_unlock();
}
struct hpte_cache *kvmppc_mmu_hpte_cache_next(struct kvm_vcpu *vcpu)
@@ -254,11 +312,15 @@ int kvmppc_mmu_hpte_init(struct kvm_vcpu *vcpu)
/* init hpte lookup hashes */
kvmppc_mmu_hpte_init_hash(vcpu->arch.hpte_hash_pte,
ARRAY_SIZE(vcpu->arch.hpte_hash_pte));
+ kvmppc_mmu_hpte_init_hash(vcpu->arch.hpte_hash_pte_long,
+ ARRAY_SIZE(vcpu->arch.hpte_hash_pte_long));
kvmppc_mmu_hpte_init_hash(vcpu->arch.hpte_hash_vpte,
ARRAY_SIZE(vcpu->arch.hpte_hash_vpte));
kvmppc_mmu_hpte_init_hash(vcpu->arch.hpte_hash_vpte_long,
ARRAY_SIZE(vcpu->arch.hpte_hash_vpte_long));
+ spin_lock_init(&vcpu->arch.mmu_lock);
+
return 0;
}
diff --git a/arch/powerpc/kvm/book3s_paired_singles.c b/arch/powerpc/kvm/book3s_paired_singles.c
index 474f2e24050a..7b0ee96c1bed 100644
--- a/arch/powerpc/kvm/book3s_paired_singles.c
+++ b/arch/powerpc/kvm/book3s_paired_singles.c
@@ -159,20 +159,21 @@
static inline void kvmppc_sync_qpr(struct kvm_vcpu *vcpu, int rt)
{
- kvm_cvt_df(&vcpu->arch.fpr[rt], &vcpu->arch.qpr[rt], &vcpu->arch.fpscr);
+ kvm_cvt_df(&vcpu->arch.fpr[rt], &vcpu->arch.qpr[rt]);
}
static void kvmppc_inject_pf(struct kvm_vcpu *vcpu, ulong eaddr, bool is_store)
{
u64 dsisr;
+ struct kvm_vcpu_arch_shared *shared = vcpu->arch.shared;
- vcpu->arch.msr = kvmppc_set_field(vcpu->arch.msr, 33, 36, 0);
- vcpu->arch.msr = kvmppc_set_field(vcpu->arch.msr, 42, 47, 0);
- vcpu->arch.dear = eaddr;
+ shared->msr = kvmppc_set_field(shared->msr, 33, 36, 0);
+ shared->msr = kvmppc_set_field(shared->msr, 42, 47, 0);
+ shared->dar = eaddr;
/* Page Fault */
dsisr = kvmppc_set_field(0, 33, 33, 1);
if (is_store)
- to_book3s(vcpu)->dsisr = kvmppc_set_field(dsisr, 38, 38, 1);
+ shared->dsisr = kvmppc_set_field(dsisr, 38, 38, 1);
kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_DATA_STORAGE);
}
@@ -204,7 +205,7 @@ static int kvmppc_emulate_fpr_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
/* put in registers */
switch (ls_type) {
case FPU_LS_SINGLE:
- kvm_cvt_fd((u32*)tmp, &vcpu->arch.fpr[rs], &vcpu->arch.fpscr);
+ kvm_cvt_fd((u32*)tmp, &vcpu->arch.fpr[rs]);
vcpu->arch.qpr[rs] = *((u32*)tmp);
break;
case FPU_LS_DOUBLE:
@@ -230,7 +231,7 @@ static int kvmppc_emulate_fpr_store(struct kvm_run *run, struct kvm_vcpu *vcpu,
switch (ls_type) {
case FPU_LS_SINGLE:
- kvm_cvt_df(&vcpu->arch.fpr[rs], (u32*)tmp, &vcpu->arch.fpscr);
+ kvm_cvt_df(&vcpu->arch.fpr[rs], (u32*)tmp);
val = *((u32*)tmp);
len = sizeof(u32);
break;
@@ -296,7 +297,7 @@ static int kvmppc_emulate_psq_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
emulated = EMULATE_DONE;
/* put in registers */
- kvm_cvt_fd(&tmp[0], &vcpu->arch.fpr[rs], &vcpu->arch.fpscr);
+ kvm_cvt_fd(&tmp[0], &vcpu->arch.fpr[rs]);
vcpu->arch.qpr[rs] = tmp[1];
dprintk(KERN_INFO "KVM: PSQ_LD [0x%x, 0x%x] at 0x%lx (%d)\n", tmp[0],
@@ -314,7 +315,7 @@ static int kvmppc_emulate_psq_store(struct kvm_run *run, struct kvm_vcpu *vcpu,
u32 tmp[2];
int len = w ? sizeof(u32) : sizeof(u64);
- kvm_cvt_df(&vcpu->arch.fpr[rs], &tmp[0], &vcpu->arch.fpscr);
+ kvm_cvt_df(&vcpu->arch.fpr[rs], &tmp[0]);
tmp[1] = vcpu->arch.qpr[rs];
r = kvmppc_st(vcpu, &addr, len, tmp, true);
@@ -516,9 +517,9 @@ static int kvmppc_ps_three_in(struct kvm_vcpu *vcpu, bool rc,
WARN_ON(rc);
/* PS0 */
- kvm_cvt_df(&fpr[reg_in1], &ps0_in1, &vcpu->arch.fpscr);
- kvm_cvt_df(&fpr[reg_in2], &ps0_in2, &vcpu->arch.fpscr);
- kvm_cvt_df(&fpr[reg_in3], &ps0_in3, &vcpu->arch.fpscr);
+ kvm_cvt_df(&fpr[reg_in1], &ps0_in1);
+ kvm_cvt_df(&fpr[reg_in2], &ps0_in2);
+ kvm_cvt_df(&fpr[reg_in3], &ps0_in3);
if (scalar & SCALAR_LOW)
ps0_in2 = qpr[reg_in2];
@@ -529,7 +530,7 @@ static int kvmppc_ps_three_in(struct kvm_vcpu *vcpu, bool rc,
ps0_in1, ps0_in2, ps0_in3, ps0_out);
if (!(scalar & SCALAR_NO_PS0))
- kvm_cvt_fd(&ps0_out, &fpr[reg_out], &vcpu->arch.fpscr);
+ kvm_cvt_fd(&ps0_out, &fpr[reg_out]);
/* PS1 */
ps1_in1 = qpr[reg_in1];
@@ -566,12 +567,12 @@ static int kvmppc_ps_two_in(struct kvm_vcpu *vcpu, bool rc,
WARN_ON(rc);
/* PS0 */
- kvm_cvt_df(&fpr[reg_in1], &ps0_in1, &vcpu->arch.fpscr);
+ kvm_cvt_df(&fpr[reg_in1], &ps0_in1);
if (scalar & SCALAR_LOW)
ps0_in2 = qpr[reg_in2];
else
- kvm_cvt_df(&fpr[reg_in2], &ps0_in2, &vcpu->arch.fpscr);
+ kvm_cvt_df(&fpr[reg_in2], &ps0_in2);
func(&vcpu->arch.fpscr, &ps0_out, &ps0_in1, &ps0_in2);
@@ -579,7 +580,7 @@ static int kvmppc_ps_two_in(struct kvm_vcpu *vcpu, bool rc,
dprintk(KERN_INFO "PS2 ps0 -> f(0x%x, 0x%x) = 0x%x\n",
ps0_in1, ps0_in2, ps0_out);
- kvm_cvt_fd(&ps0_out, &fpr[reg_out], &vcpu->arch.fpscr);
+ kvm_cvt_fd(&ps0_out, &fpr[reg_out]);
}
/* PS1 */
@@ -615,13 +616,13 @@ static int kvmppc_ps_one_in(struct kvm_vcpu *vcpu, bool rc,
WARN_ON(rc);
/* PS0 */
- kvm_cvt_df(&fpr[reg_in], &ps0_in, &vcpu->arch.fpscr);
+ kvm_cvt_df(&fpr[reg_in], &ps0_in);
func(&vcpu->arch.fpscr, &ps0_out, &ps0_in);
dprintk(KERN_INFO "PS1 ps0 -> f(0x%x) = 0x%x\n",
ps0_in, ps0_out);
- kvm_cvt_fd(&ps0_out, &fpr[reg_out], &vcpu->arch.fpscr);
+ kvm_cvt_fd(&ps0_out, &fpr[reg_out]);
/* PS1 */
ps1_in = qpr[reg_in];
@@ -658,7 +659,7 @@ int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu)
if (!kvmppc_inst_is_paired_single(vcpu, inst))
return EMULATE_FAIL;
- if (!(vcpu->arch.msr & MSR_FP)) {
+ if (!(vcpu->arch.shared->msr & MSR_FP)) {
kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_FP_UNAVAIL);
return EMULATE_AGAIN;
}
@@ -671,7 +672,7 @@ int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu)
#ifdef DEBUG
for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++) {
u32 f;
- kvm_cvt_df(&vcpu->arch.fpr[i], &f, &vcpu->arch.fpscr);
+ kvm_cvt_df(&vcpu->arch.fpr[i], &f);
dprintk(KERN_INFO "FPR[%d] = 0x%x / 0x%llx QPR[%d] = 0x%x\n",
i, f, vcpu->arch.fpr[i], i, vcpu->arch.qpr[i]);
}
@@ -796,8 +797,7 @@ int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu)
vcpu->arch.fpr[ax_rd] = vcpu->arch.fpr[ax_ra];
/* vcpu->arch.qpr[ax_rd] = vcpu->arch.fpr[ax_rb]; */
kvm_cvt_df(&vcpu->arch.fpr[ax_rb],
- &vcpu->arch.qpr[ax_rd],
- &vcpu->arch.fpscr);
+ &vcpu->arch.qpr[ax_rd]);
break;
case OP_4X_PS_MERGE01:
WARN_ON(rcomp);
@@ -808,19 +808,16 @@ int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu)
WARN_ON(rcomp);
/* vcpu->arch.fpr[ax_rd] = vcpu->arch.qpr[ax_ra]; */
kvm_cvt_fd(&vcpu->arch.qpr[ax_ra],
- &vcpu->arch.fpr[ax_rd],
- &vcpu->arch.fpscr);
+ &vcpu->arch.fpr[ax_rd]);
/* vcpu->arch.qpr[ax_rd] = vcpu->arch.fpr[ax_rb]; */
kvm_cvt_df(&vcpu->arch.fpr[ax_rb],
- &vcpu->arch.qpr[ax_rd],
- &vcpu->arch.fpscr);
+ &vcpu->arch.qpr[ax_rd]);
break;
case OP_4X_PS_MERGE11:
WARN_ON(rcomp);
/* vcpu->arch.fpr[ax_rd] = vcpu->arch.qpr[ax_ra]; */
kvm_cvt_fd(&vcpu->arch.qpr[ax_ra],
- &vcpu->arch.fpr[ax_rd],
- &vcpu->arch.fpscr);
+ &vcpu->arch.fpr[ax_rd]);
vcpu->arch.qpr[ax_rd] = vcpu->arch.qpr[ax_rb];
break;
}
@@ -1255,7 +1252,7 @@ int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu)
#ifdef DEBUG
for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++) {
u32 f;
- kvm_cvt_df(&vcpu->arch.fpr[i], &f, &vcpu->arch.fpscr);
+ kvm_cvt_df(&vcpu->arch.fpr[i], &f);
dprintk(KERN_INFO "FPR[%d] = 0x%x\n", i, f);
}
#endif
diff --git a/arch/powerpc/kvm/book3s_rmhandlers.S b/arch/powerpc/kvm/book3s_rmhandlers.S
index 506d5c316c96..2b9c9088d00e 100644
--- a/arch/powerpc/kvm/book3s_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_rmhandlers.S
@@ -202,8 +202,25 @@ _GLOBAL(kvmppc_rmcall)
#if defined(CONFIG_PPC_BOOK3S_32)
#define STACK_LR INT_FRAME_SIZE+4
+
+/* load_up_xxx have to run with MSR_DR=0 on Book3S_32 */
+#define MSR_EXT_START \
+ PPC_STL r20, _NIP(r1); \
+ mfmsr r20; \
+ LOAD_REG_IMMEDIATE(r3, MSR_DR|MSR_EE); \
+ andc r3,r20,r3; /* Disable DR,EE */ \
+ mtmsr r3; \
+ sync
+
+#define MSR_EXT_END \
+ mtmsr r20; /* Enable DR,EE */ \
+ sync; \
+ PPC_LL r20, _NIP(r1)
+
#elif defined(CONFIG_PPC_BOOK3S_64)
#define STACK_LR _LINK
+#define MSR_EXT_START
+#define MSR_EXT_END
#endif
/*
@@ -215,19 +232,12 @@ _GLOBAL(kvmppc_load_up_ ## what); \
PPC_STLU r1, -INT_FRAME_SIZE(r1); \
mflr r3; \
PPC_STL r3, STACK_LR(r1); \
- PPC_STL r20, _NIP(r1); \
- mfmsr r20; \
- LOAD_REG_IMMEDIATE(r3, MSR_DR|MSR_EE); \
- andc r3,r20,r3; /* Disable DR,EE */ \
- mtmsr r3; \
- sync; \
+ MSR_EXT_START; \
\
bl FUNC(load_up_ ## what); \
\
- mtmsr r20; /* Enable DR,EE */ \
- sync; \
+ MSR_EXT_END; \
PPC_LL r3, STACK_LR(r1); \
- PPC_LL r20, _NIP(r1); \
mtlr r3; \
addi r1, r1, INT_FRAME_SIZE; \
blr
@@ -242,10 +252,10 @@ define_load_up(vsx)
.global kvmppc_trampoline_lowmem
kvmppc_trampoline_lowmem:
- .long kvmppc_handler_lowmem_trampoline - CONFIG_KERNEL_START
+ PPC_LONG kvmppc_handler_lowmem_trampoline - CONFIG_KERNEL_START
.global kvmppc_trampoline_enter
kvmppc_trampoline_enter:
- .long kvmppc_handler_trampoline_enter - CONFIG_KERNEL_START
+ PPC_LONG kvmppc_handler_trampoline_enter - CONFIG_KERNEL_START
#include "book3s_segment.S"
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 8d4e35f5372c..77575d08c818 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -62,9 +62,10 @@ void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu)
{
int i;
- printk("pc: %08lx msr: %08lx\n", vcpu->arch.pc, vcpu->arch.msr);
+ printk("pc: %08lx msr: %08llx\n", vcpu->arch.pc, vcpu->arch.shared->msr);
printk("lr: %08lx ctr: %08lx\n", vcpu->arch.lr, vcpu->arch.ctr);
- printk("srr0: %08lx srr1: %08lx\n", vcpu->arch.srr0, vcpu->arch.srr1);
+ printk("srr0: %08llx srr1: %08llx\n", vcpu->arch.shared->srr0,
+ vcpu->arch.shared->srr1);
printk("exceptions: %08lx\n", vcpu->arch.pending_exceptions);
@@ -130,13 +131,19 @@ void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu)
void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
struct kvm_interrupt *irq)
{
- kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_EXTERNAL);
+ unsigned int prio = BOOKE_IRQPRIO_EXTERNAL;
+
+ if (irq->irq == KVM_INTERRUPT_SET_LEVEL)
+ prio = BOOKE_IRQPRIO_EXTERNAL_LEVEL;
+
+ kvmppc_booke_queue_irqprio(vcpu, prio);
}
void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu,
struct kvm_interrupt *irq)
{
clear_bit(BOOKE_IRQPRIO_EXTERNAL, &vcpu->arch.pending_exceptions);
+ clear_bit(BOOKE_IRQPRIO_EXTERNAL_LEVEL, &vcpu->arch.pending_exceptions);
}
/* Deliver the interrupt of the corresponding priority, if possible. */
@@ -146,6 +153,26 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
int allowed = 0;
ulong uninitialized_var(msr_mask);
bool update_esr = false, update_dear = false;
+ ulong crit_raw = vcpu->arch.shared->critical;
+ ulong crit_r1 = kvmppc_get_gpr(vcpu, 1);
+ bool crit;
+ bool keep_irq = false;
+
+ /* Truncate crit indicators in 32 bit mode */
+ if (!(vcpu->arch.shared->msr & MSR_SF)) {
+ crit_raw &= 0xffffffff;
+ crit_r1 &= 0xffffffff;
+ }
+
+ /* Critical section when crit == r1 */
+ crit = (crit_raw == crit_r1);
+ /* ... and we're in supervisor mode */
+ crit = crit && !(vcpu->arch.shared->msr & MSR_PR);
+
+ if (priority == BOOKE_IRQPRIO_EXTERNAL_LEVEL) {
+ priority = BOOKE_IRQPRIO_EXTERNAL;
+ keep_irq = true;
+ }
switch (priority) {
case BOOKE_IRQPRIO_DTLB_MISS:
@@ -169,36 +196,38 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
break;
case BOOKE_IRQPRIO_CRITICAL:
case BOOKE_IRQPRIO_WATCHDOG:
- allowed = vcpu->arch.msr & MSR_CE;
+ allowed = vcpu->arch.shared->msr & MSR_CE;
msr_mask = MSR_ME;
break;
case BOOKE_IRQPRIO_MACHINE_CHECK:
- allowed = vcpu->arch.msr & MSR_ME;
+ allowed = vcpu->arch.shared->msr & MSR_ME;
msr_mask = 0;
break;
case BOOKE_IRQPRIO_EXTERNAL:
case BOOKE_IRQPRIO_DECREMENTER:
case BOOKE_IRQPRIO_FIT:
- allowed = vcpu->arch.msr & MSR_EE;
+ allowed = vcpu->arch.shared->msr & MSR_EE;
+ allowed = allowed && !crit;
msr_mask = MSR_CE|MSR_ME|MSR_DE;
break;
case BOOKE_IRQPRIO_DEBUG:
- allowed = vcpu->arch.msr & MSR_DE;
+ allowed = vcpu->arch.shared->msr & MSR_DE;
msr_mask = MSR_ME;
break;
}
if (allowed) {
- vcpu->arch.srr0 = vcpu->arch.pc;
- vcpu->arch.srr1 = vcpu->arch.msr;
+ vcpu->arch.shared->srr0 = vcpu->arch.pc;
+ vcpu->arch.shared->srr1 = vcpu->arch.shared->msr;
vcpu->arch.pc = vcpu->arch.ivpr | vcpu->arch.ivor[priority];
if (update_esr == true)
vcpu->arch.esr = vcpu->arch.queued_esr;
if (update_dear == true)
- vcpu->arch.dear = vcpu->arch.queued_dear;
- kvmppc_set_msr(vcpu, vcpu->arch.msr & msr_mask);
+ vcpu->arch.shared->dar = vcpu->arch.queued_dear;
+ kvmppc_set_msr(vcpu, vcpu->arch.shared->msr & msr_mask);
- clear_bit(priority, &vcpu->arch.pending_exceptions);
+ if (!keep_irq)
+ clear_bit(priority, &vcpu->arch.pending_exceptions);
}
return allowed;
@@ -208,6 +237,7 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu)
{
unsigned long *pending = &vcpu->arch.pending_exceptions;
+ unsigned long old_pending = vcpu->arch.pending_exceptions;
unsigned int priority;
priority = __ffs(*pending);
@@ -219,6 +249,12 @@ void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu)
BITS_PER_BYTE * sizeof(*pending),
priority + 1);
}
+
+ /* Tell the guest about our interrupt status */
+ if (*pending)
+ vcpu->arch.shared->int_pending = 1;
+ else if (old_pending)
+ vcpu->arch.shared->int_pending = 0;
}
/**
@@ -265,7 +301,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
break;
case BOOKE_INTERRUPT_PROGRAM:
- if (vcpu->arch.msr & MSR_PR) {
+ if (vcpu->arch.shared->msr & MSR_PR) {
/* Program traps generated by user-level software must be handled
* by the guest kernel. */
kvmppc_core_queue_program(vcpu, vcpu->arch.fault_esr);
@@ -337,7 +373,15 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
break;
case BOOKE_INTERRUPT_SYSCALL:
- kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_SYSCALL);
+ if (!(vcpu->arch.shared->msr & MSR_PR) &&
+ (((u32)kvmppc_get_gpr(vcpu, 0)) == KVM_SC_MAGIC_R0)) {
+ /* KVM PV hypercalls */
+ kvmppc_set_gpr(vcpu, 3, kvmppc_kvm_pv(vcpu));
+ r = RESUME_GUEST;
+ } else {
+ /* Guest syscalls */
+ kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_SYSCALL);
+ }
kvmppc_account_exit(vcpu, SYSCALL_EXITS);
r = RESUME_GUEST;
break;
@@ -466,15 +510,19 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
/* Initial guest state: 16MB mapping 0 -> 0, PC = 0, MSR = 0, R1 = 16MB */
int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
{
+ int i;
+
vcpu->arch.pc = 0;
- vcpu->arch.msr = 0;
+ vcpu->arch.shared->msr = 0;
kvmppc_set_gpr(vcpu, 1, (16<<20) - 8); /* -8 for the callee-save LR slot */
vcpu->arch.shadow_pid = 1;
- /* Eye-catching number so we know if the guest takes an interrupt
- * before it's programmed its own IVPR. */
+ /* Eye-catching numbers so we know if the guest takes an interrupt
+ * before it's programmed its own IVPR/IVORs. */
vcpu->arch.ivpr = 0x55550000;
+ for (i = 0; i < BOOKE_IRQPRIO_MAX; i++)
+ vcpu->arch.ivor[i] = 0x7700 | i * 4;
kvmppc_init_timing_stats(vcpu);
@@ -490,14 +538,14 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
regs->ctr = vcpu->arch.ctr;
regs->lr = vcpu->arch.lr;
regs->xer = kvmppc_get_xer(vcpu);
- regs->msr = vcpu->arch.msr;
- regs->srr0 = vcpu->arch.srr0;
- regs->srr1 = vcpu->arch.srr1;
+ regs->msr = vcpu->arch.shared->msr;
+ regs->srr0 = vcpu->arch.shared->srr0;
+ regs->srr1 = vcpu->arch.shared->srr1;
regs->pid = vcpu->arch.pid;
- regs->sprg0 = vcpu->arch.sprg0;
- regs->sprg1 = vcpu->arch.sprg1;
- regs->sprg2 = vcpu->arch.sprg2;
- regs->sprg3 = vcpu->arch.sprg3;
+ regs->sprg0 = vcpu->arch.shared->sprg0;
+ regs->sprg1 = vcpu->arch.shared->sprg1;
+ regs->sprg2 = vcpu->arch.shared->sprg2;
+ regs->sprg3 = vcpu->arch.shared->sprg3;
regs->sprg5 = vcpu->arch.sprg4;
regs->sprg6 = vcpu->arch.sprg5;
regs->sprg7 = vcpu->arch.sprg6;
@@ -518,12 +566,12 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
vcpu->arch.lr = regs->lr;
kvmppc_set_xer(vcpu, regs->xer);
kvmppc_set_msr(vcpu, regs->msr);
- vcpu->arch.srr0 = regs->srr0;
- vcpu->arch.srr1 = regs->srr1;
- vcpu->arch.sprg0 = regs->sprg0;
- vcpu->arch.sprg1 = regs->sprg1;
- vcpu->arch.sprg2 = regs->sprg2;
- vcpu->arch.sprg3 = regs->sprg3;
+ vcpu->arch.shared->srr0 = regs->srr0;
+ vcpu->arch.shared->srr1 = regs->srr1;
+ vcpu->arch.shared->sprg0 = regs->sprg0;
+ vcpu->arch.shared->sprg1 = regs->sprg1;
+ vcpu->arch.shared->sprg2 = regs->sprg2;
+ vcpu->arch.shared->sprg3 = regs->sprg3;
vcpu->arch.sprg5 = regs->sprg4;
vcpu->arch.sprg6 = regs->sprg5;
vcpu->arch.sprg7 = regs->sprg6;
diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h
index d59bcca1f9d8..492bb7030358 100644
--- a/arch/powerpc/kvm/booke.h
+++ b/arch/powerpc/kvm/booke.h
@@ -46,7 +46,9 @@
#define BOOKE_IRQPRIO_FIT 17
#define BOOKE_IRQPRIO_DECREMENTER 18
#define BOOKE_IRQPRIO_PERFORMANCE_MONITOR 19
-#define BOOKE_IRQPRIO_MAX 19
+/* Internal pseudo-irqprio for level triggered externals */
+#define BOOKE_IRQPRIO_EXTERNAL_LEVEL 20
+#define BOOKE_IRQPRIO_MAX 20
extern unsigned long kvmppc_booke_handlers;
@@ -54,12 +56,12 @@ extern unsigned long kvmppc_booke_handlers;
* changing. */
static inline void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr)
{
- if ((new_msr & MSR_PR) != (vcpu->arch.msr & MSR_PR))
+ if ((new_msr & MSR_PR) != (vcpu->arch.shared->msr & MSR_PR))
kvmppc_mmu_priv_switch(vcpu, new_msr & MSR_PR);
- vcpu->arch.msr = new_msr;
+ vcpu->arch.shared->msr = new_msr;
- if (vcpu->arch.msr & MSR_WE) {
+ if (vcpu->arch.shared->msr & MSR_WE) {
kvm_vcpu_block(vcpu);
kvmppc_set_exit_type(vcpu, EMULATED_MTMSRWE_EXITS);
};
diff --git a/arch/powerpc/kvm/booke_emulate.c b/arch/powerpc/kvm/booke_emulate.c
index cbc790ee1928..1260f5f24c0c 100644
--- a/arch/powerpc/kvm/booke_emulate.c
+++ b/arch/powerpc/kvm/booke_emulate.c
@@ -31,8 +31,8 @@
static void kvmppc_emul_rfi(struct kvm_vcpu *vcpu)
{
- vcpu->arch.pc = vcpu->arch.srr0;
- kvmppc_set_msr(vcpu, vcpu->arch.srr1);
+ vcpu->arch.pc = vcpu->arch.shared->srr0;
+ kvmppc_set_msr(vcpu, vcpu->arch.shared->srr1);
}
int kvmppc_booke_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
@@ -62,7 +62,7 @@ int kvmppc_booke_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
case OP_31_XOP_MFMSR:
rt = get_rt(inst);
- kvmppc_set_gpr(vcpu, rt, vcpu->arch.msr);
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->msr);
kvmppc_set_exit_type(vcpu, EMULATED_MFMSR_EXITS);
break;
@@ -74,13 +74,13 @@ int kvmppc_booke_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
case OP_31_XOP_WRTEE:
rs = get_rs(inst);
- vcpu->arch.msr = (vcpu->arch.msr & ~MSR_EE)
+ vcpu->arch.shared->msr = (vcpu->arch.shared->msr & ~MSR_EE)
| (kvmppc_get_gpr(vcpu, rs) & MSR_EE);
kvmppc_set_exit_type(vcpu, EMULATED_WRTEE_EXITS);
break;
case OP_31_XOP_WRTEEI:
- vcpu->arch.msr = (vcpu->arch.msr & ~MSR_EE)
+ vcpu->arch.shared->msr = (vcpu->arch.shared->msr & ~MSR_EE)
| (inst & MSR_EE);
kvmppc_set_exit_type(vcpu, EMULATED_WRTEE_EXITS);
break;
@@ -105,7 +105,7 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
switch (sprn) {
case SPRN_DEAR:
- vcpu->arch.dear = spr_val; break;
+ vcpu->arch.shared->dar = spr_val; break;
case SPRN_ESR:
vcpu->arch.esr = spr_val; break;
case SPRN_DBCR0:
@@ -200,7 +200,7 @@ int kvmppc_booke_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
case SPRN_IVPR:
kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivpr); break;
case SPRN_DEAR:
- kvmppc_set_gpr(vcpu, rt, vcpu->arch.dear); break;
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->dar); break;
case SPRN_ESR:
kvmppc_set_gpr(vcpu, rt, vcpu->arch.esr); break;
case SPRN_DBCR0:
diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S
index 380a78cf484d..049846911ce4 100644
--- a/arch/powerpc/kvm/booke_interrupts.S
+++ b/arch/powerpc/kvm/booke_interrupts.S
@@ -415,7 +415,8 @@ lightweight_exit:
lwz r8, VCPU_GPR(r8)(r4)
lwz r3, VCPU_PC(r4)
mtsrr0 r3
- lwz r3, VCPU_MSR(r4)
+ lwz r3, VCPU_SHARED(r4)
+ lwz r3, VCPU_SHARED_MSR(r3)
oris r3, r3, KVMPPC_MSR_MASK@h
ori r3, r3, KVMPPC_MSR_MASK@l
mtsrr1 r3
diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
index e8a00b0c4449..71750f2dd5d3 100644
--- a/arch/powerpc/kvm/e500.c
+++ b/arch/powerpc/kvm/e500.c
@@ -117,8 +117,14 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
if (err)
goto uninit_vcpu;
+ vcpu->arch.shared = (void*)__get_free_page(GFP_KERNEL|__GFP_ZERO);
+ if (!vcpu->arch.shared)
+ goto uninit_tlb;
+
return vcpu;
+uninit_tlb:
+ kvmppc_e500_tlb_uninit(vcpu_e500);
uninit_vcpu:
kvm_vcpu_uninit(vcpu);
free_vcpu:
@@ -131,6 +137,7 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
{
struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+ free_page((unsigned long)vcpu->arch.shared);
kvmppc_e500_tlb_uninit(vcpu_e500);
kvm_vcpu_uninit(vcpu);
kmem_cache_free(kvm_vcpu_cache, vcpu_e500);
diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c
index 21011e12caeb..d6d6d47a75a9 100644
--- a/arch/powerpc/kvm/e500_tlb.c
+++ b/arch/powerpc/kvm/e500_tlb.c
@@ -226,8 +226,7 @@ static void kvmppc_e500_stlbe_invalidate(struct kvmppc_vcpu_e500 *vcpu_e500,
kvmppc_e500_shadow_release(vcpu_e500, tlbsel, esel);
stlbe->mas1 = 0;
- trace_kvm_stlb_inval(index_of(tlbsel, esel), stlbe->mas1, stlbe->mas2,
- stlbe->mas3, stlbe->mas7);
+ trace_kvm_stlb_inval(index_of(tlbsel, esel));
}
static void kvmppc_e500_tlb1_invalidate(struct kvmppc_vcpu_e500 *vcpu_e500,
@@ -298,7 +297,8 @@ static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
/* Get reference to new page. */
new_page = gfn_to_page(vcpu_e500->vcpu.kvm, gfn);
if (is_error_page(new_page)) {
- printk(KERN_ERR "Couldn't get guest page for gfn %lx!\n", gfn);
+ printk(KERN_ERR "Couldn't get guest page for gfn %lx!\n",
+ (long)gfn);
kvm_release_page_clean(new_page);
return;
}
@@ -314,10 +314,10 @@ static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
| MAS1_TID(get_tlb_tid(gtlbe)) | MAS1_TS | MAS1_VALID;
stlbe->mas2 = (gvaddr & MAS2_EPN)
| e500_shadow_mas2_attrib(gtlbe->mas2,
- vcpu_e500->vcpu.arch.msr & MSR_PR);
+ vcpu_e500->vcpu.arch.shared->msr & MSR_PR);
stlbe->mas3 = (hpaddr & MAS3_RPN)
| e500_shadow_mas3_attrib(gtlbe->mas3,
- vcpu_e500->vcpu.arch.msr & MSR_PR);
+ vcpu_e500->vcpu.arch.shared->msr & MSR_PR);
stlbe->mas7 = (hpaddr >> 32) & MAS7_RPN;
trace_kvm_stlb_write(index_of(tlbsel, esel), stlbe->mas1, stlbe->mas2,
@@ -576,28 +576,28 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu)
int kvmppc_mmu_itlb_index(struct kvm_vcpu *vcpu, gva_t eaddr)
{
- unsigned int as = !!(vcpu->arch.msr & MSR_IS);
+ unsigned int as = !!(vcpu->arch.shared->msr & MSR_IS);
return kvmppc_e500_tlb_search(vcpu, eaddr, get_cur_pid(vcpu), as);
}
int kvmppc_mmu_dtlb_index(struct kvm_vcpu *vcpu, gva_t eaddr)
{
- unsigned int as = !!(vcpu->arch.msr & MSR_DS);
+ unsigned int as = !!(vcpu->arch.shared->msr & MSR_DS);
return kvmppc_e500_tlb_search(vcpu, eaddr, get_cur_pid(vcpu), as);
}
void kvmppc_mmu_itlb_miss(struct kvm_vcpu *vcpu)
{
- unsigned int as = !!(vcpu->arch.msr & MSR_IS);
+ unsigned int as = !!(vcpu->arch.shared->msr & MSR_IS);
kvmppc_e500_deliver_tlb_miss(vcpu, vcpu->arch.pc, as);
}
void kvmppc_mmu_dtlb_miss(struct kvm_vcpu *vcpu)
{
- unsigned int as = !!(vcpu->arch.msr & MSR_DS);
+ unsigned int as = !!(vcpu->arch.shared->msr & MSR_DS);
kvmppc_e500_deliver_tlb_miss(vcpu, vcpu->arch.fault_dear, as);
}
diff --git a/arch/powerpc/kvm/e500_tlb.h b/arch/powerpc/kvm/e500_tlb.h
index d28e3010a5e2..458946b4775d 100644
--- a/arch/powerpc/kvm/e500_tlb.h
+++ b/arch/powerpc/kvm/e500_tlb.h
@@ -171,7 +171,7 @@ static inline int tlbe_is_host_safe(const struct kvm_vcpu *vcpu,
/* Does it match current guest AS? */
/* XXX what about IS != DS? */
- if (get_tlb_ts(tlbe) != !!(vcpu->arch.msr & MSR_IS))
+ if (get_tlb_ts(tlbe) != !!(vcpu->arch.shared->msr & MSR_IS))
return 0;
gpa = get_tlb_raddr(tlbe);
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c
index 4568ec386c2a..c64fd2909bb2 100644
--- a/arch/powerpc/kvm/emulate.c
+++ b/arch/powerpc/kvm/emulate.c
@@ -145,7 +145,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
/* this default type might be overwritten by subcategories */
kvmppc_set_exit_type(vcpu, EMULATED_INST_EXITS);
- pr_debug(KERN_INFO "Emulating opcode %d / %d\n", get_op(inst), get_xop(inst));
+ pr_debug("Emulating opcode %d / %d\n", get_op(inst), get_xop(inst));
switch (get_op(inst)) {
case OP_TRAP:
@@ -242,9 +242,11 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
switch (sprn) {
case SPRN_SRR0:
- kvmppc_set_gpr(vcpu, rt, vcpu->arch.srr0); break;
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->srr0);
+ break;
case SPRN_SRR1:
- kvmppc_set_gpr(vcpu, rt, vcpu->arch.srr1); break;
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->srr1);
+ break;
case SPRN_PVR:
kvmppc_set_gpr(vcpu, rt, vcpu->arch.pvr); break;
case SPRN_PIR:
@@ -261,13 +263,17 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
kvmppc_set_gpr(vcpu, rt, get_tb()); break;
case SPRN_SPRG0:
- kvmppc_set_gpr(vcpu, rt, vcpu->arch.sprg0); break;
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->sprg0);
+ break;
case SPRN_SPRG1:
- kvmppc_set_gpr(vcpu, rt, vcpu->arch.sprg1); break;
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->sprg1);
+ break;
case SPRN_SPRG2:
- kvmppc_set_gpr(vcpu, rt, vcpu->arch.sprg2); break;
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->sprg2);
+ break;
case SPRN_SPRG3:
- kvmppc_set_gpr(vcpu, rt, vcpu->arch.sprg3); break;
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->sprg3);
+ break;
/* Note: SPRG4-7 are user-readable, so we don't get
* a trap. */
@@ -275,7 +281,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
{
u64 jd = get_tb() - vcpu->arch.dec_jiffies;
kvmppc_set_gpr(vcpu, rt, vcpu->arch.dec - jd);
- pr_debug(KERN_INFO "mfDEC: %x - %llx = %lx\n",
+ pr_debug("mfDEC: %x - %llx = %lx\n",
vcpu->arch.dec, jd,
kvmppc_get_gpr(vcpu, rt));
break;
@@ -320,9 +326,11 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
rs = get_rs(inst);
switch (sprn) {
case SPRN_SRR0:
- vcpu->arch.srr0 = kvmppc_get_gpr(vcpu, rs); break;
+ vcpu->arch.shared->srr0 = kvmppc_get_gpr(vcpu, rs);
+ break;
case SPRN_SRR1:
- vcpu->arch.srr1 = kvmppc_get_gpr(vcpu, rs); break;
+ vcpu->arch.shared->srr1 = kvmppc_get_gpr(vcpu, rs);
+ break;
/* XXX We need to context-switch the timebase for
* watchdog and FIT. */
@@ -337,13 +345,17 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
break;
case SPRN_SPRG0:
- vcpu->arch.sprg0 = kvmppc_get_gpr(vcpu, rs); break;
+ vcpu->arch.shared->sprg0 = kvmppc_get_gpr(vcpu, rs);
+ break;
case SPRN_SPRG1:
- vcpu->arch.sprg1 = kvmppc_get_gpr(vcpu, rs); break;
+ vcpu->arch.shared->sprg1 = kvmppc_get_gpr(vcpu, rs);
+ break;
case SPRN_SPRG2:
- vcpu->arch.sprg2 = kvmppc_get_gpr(vcpu, rs); break;
+ vcpu->arch.shared->sprg2 = kvmppc_get_gpr(vcpu, rs);
+ break;
case SPRN_SPRG3:
- vcpu->arch.sprg3 = kvmppc_get_gpr(vcpu, rs); break;
+ vcpu->arch.shared->sprg3 = kvmppc_get_gpr(vcpu, rs);
+ break;
default:
emulated = kvmppc_core_emulate_mtspr(vcpu, sprn, rs);
diff --git a/arch/powerpc/kvm/fpu.S b/arch/powerpc/kvm/fpu.S
index cb34bbe16113..bf68d597549e 100644
--- a/arch/powerpc/kvm/fpu.S
+++ b/arch/powerpc/kvm/fpu.S
@@ -273,19 +273,11 @@ FPD_THREE_IN(fnmsub)
FPD_THREE_IN(fnmadd)
_GLOBAL(kvm_cvt_fd)
- lfd 0,0(r5) /* load up fpscr value */
- MTFSF_L(0)
lfs 0,0(r3)
stfd 0,0(r4)
- mffs 0
- stfd 0,0(r5) /* save new fpscr value */
blr
_GLOBAL(kvm_cvt_df)
- lfd 0,0(r5) /* load up fpscr value */
- MTFSF_L(0)
lfd 0,0(r3)
stfs 0,0(r4)
- mffs 0
- stfd 0,0(r5) /* save new fpscr value */
blr
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 72a4ad86ee91..2f87a1627f6c 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -38,9 +38,56 @@
int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)
{
- return !(v->arch.msr & MSR_WE) || !!(v->arch.pending_exceptions);
+ return !(v->arch.shared->msr & MSR_WE) ||
+ !!(v->arch.pending_exceptions);
}
+int kvmppc_kvm_pv(struct kvm_vcpu *vcpu)
+{
+ int nr = kvmppc_get_gpr(vcpu, 11);
+ int r;
+ unsigned long __maybe_unused param1 = kvmppc_get_gpr(vcpu, 3);
+ unsigned long __maybe_unused param2 = kvmppc_get_gpr(vcpu, 4);
+ unsigned long __maybe_unused param3 = kvmppc_get_gpr(vcpu, 5);
+ unsigned long __maybe_unused param4 = kvmppc_get_gpr(vcpu, 6);
+ unsigned long r2 = 0;
+
+ if (!(vcpu->arch.shared->msr & MSR_SF)) {
+ /* 32 bit mode */
+ param1 &= 0xffffffff;
+ param2 &= 0xffffffff;
+ param3 &= 0xffffffff;
+ param4 &= 0xffffffff;
+ }
+
+ switch (nr) {
+ case HC_VENDOR_KVM | KVM_HC_PPC_MAP_MAGIC_PAGE:
+ {
+ vcpu->arch.magic_page_pa = param1;
+ vcpu->arch.magic_page_ea = param2;
+
+ r2 = KVM_MAGIC_FEAT_SR;
+
+ r = HC_EV_SUCCESS;
+ break;
+ }
+ case HC_VENDOR_KVM | KVM_HC_FEATURES:
+ r = HC_EV_SUCCESS;
+#if defined(CONFIG_PPC_BOOK3S) /* XXX Missing magic page on BookE */
+ r2 |= (1 << KVM_FEATURE_MAGIC_PAGE);
+#endif
+
+ /* Second return value is in r4 */
+ break;
+ default:
+ r = HC_EV_UNIMPLEMENTED;
+ break;
+ }
+
+ kvmppc_set_gpr(vcpu, 4, r2);
+
+ return r;
+}
int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu)
{
@@ -145,8 +192,10 @@ int kvm_dev_ioctl_check_extension(long ext)
case KVM_CAP_PPC_SEGSTATE:
case KVM_CAP_PPC_PAIRED_SINGLES:
case KVM_CAP_PPC_UNSET_IRQ:
+ case KVM_CAP_PPC_IRQ_LEVEL:
case KVM_CAP_ENABLE_CAP:
case KVM_CAP_PPC_OSI:
+ case KVM_CAP_PPC_GET_PVINFO:
r = 1;
break;
case KVM_CAP_COALESCED_MMIO:
@@ -534,16 +583,53 @@ out:
return r;
}
+static int kvm_vm_ioctl_get_pvinfo(struct kvm_ppc_pvinfo *pvinfo)
+{
+ u32 inst_lis = 0x3c000000;
+ u32 inst_ori = 0x60000000;
+ u32 inst_nop = 0x60000000;
+ u32 inst_sc = 0x44000002;
+ u32 inst_imm_mask = 0xffff;
+
+ /*
+ * The hypercall to get into KVM from within guest context is as
+ * follows:
+ *
+ * lis r0, r0, KVM_SC_MAGIC_R0@h
+ * ori r0, KVM_SC_MAGIC_R0@l
+ * sc
+ * nop
+ */
+ pvinfo->hcall[0] = inst_lis | ((KVM_SC_MAGIC_R0 >> 16) & inst_imm_mask);
+ pvinfo->hcall[1] = inst_ori | (KVM_SC_MAGIC_R0 & inst_imm_mask);
+ pvinfo->hcall[2] = inst_sc;
+ pvinfo->hcall[3] = inst_nop;
+
+ return 0;
+}
+
long kvm_arch_vm_ioctl(struct file *filp,
unsigned int ioctl, unsigned long arg)
{
+ void __user *argp = (void __user *)arg;
long r;
switch (ioctl) {
+ case KVM_PPC_GET_PVINFO: {
+ struct kvm_ppc_pvinfo pvinfo;
+ r = kvm_vm_ioctl_get_pvinfo(&pvinfo);
+ if (copy_to_user(argp, &pvinfo, sizeof(pvinfo))) {
+ r = -EFAULT;
+ goto out;
+ }
+
+ break;
+ }
default:
r = -ENOTTY;
}
+out:
return r;
}
diff --git a/arch/powerpc/kvm/trace.h b/arch/powerpc/kvm/trace.h
index a8e840018052..3aca1b042b8c 100644
--- a/arch/powerpc/kvm/trace.h
+++ b/arch/powerpc/kvm/trace.h
@@ -98,6 +98,245 @@ TRACE_EVENT(kvm_gtlb_write,
__entry->word1, __entry->word2)
);
+
+/*************************************************************************
+ * Book3S trace points *
+ *************************************************************************/
+
+#ifdef CONFIG_PPC_BOOK3S
+
+TRACE_EVENT(kvm_book3s_exit,
+ TP_PROTO(unsigned int exit_nr, struct kvm_vcpu *vcpu),
+ TP_ARGS(exit_nr, vcpu),
+
+ TP_STRUCT__entry(
+ __field( unsigned int, exit_nr )
+ __field( unsigned long, pc )
+ __field( unsigned long, msr )
+ __field( unsigned long, dar )
+ __field( unsigned long, srr1 )
+ ),
+
+ TP_fast_assign(
+ __entry->exit_nr = exit_nr;
+ __entry->pc = kvmppc_get_pc(vcpu);
+ __entry->dar = kvmppc_get_fault_dar(vcpu);
+ __entry->msr = vcpu->arch.shared->msr;
+ __entry->srr1 = to_svcpu(vcpu)->shadow_srr1;
+ ),
+
+ TP_printk("exit=0x%x | pc=0x%lx | msr=0x%lx | dar=0x%lx | srr1=0x%lx",
+ __entry->exit_nr, __entry->pc, __entry->msr, __entry->dar,
+ __entry->srr1)
+);
+
+TRACE_EVENT(kvm_book3s_reenter,
+ TP_PROTO(int r, struct kvm_vcpu *vcpu),
+ TP_ARGS(r, vcpu),
+
+ TP_STRUCT__entry(
+ __field( unsigned int, r )
+ __field( unsigned long, pc )
+ ),
+
+ TP_fast_assign(
+ __entry->r = r;
+ __entry->pc = kvmppc_get_pc(vcpu);
+ ),
+
+ TP_printk("reentry r=%d | pc=0x%lx", __entry->r, __entry->pc)
+);
+
+#ifdef CONFIG_PPC_BOOK3S_64
+
+TRACE_EVENT(kvm_book3s_64_mmu_map,
+ TP_PROTO(int rflags, ulong hpteg, ulong va, pfn_t hpaddr,
+ struct kvmppc_pte *orig_pte),
+ TP_ARGS(rflags, hpteg, va, hpaddr, orig_pte),
+
+ TP_STRUCT__entry(
+ __field( unsigned char, flag_w )
+ __field( unsigned char, flag_x )
+ __field( unsigned long, eaddr )
+ __field( unsigned long, hpteg )
+ __field( unsigned long, va )
+ __field( unsigned long long, vpage )
+ __field( unsigned long, hpaddr )
+ ),
+
+ TP_fast_assign(
+ __entry->flag_w = ((rflags & HPTE_R_PP) == 3) ? '-' : 'w';
+ __entry->flag_x = (rflags & HPTE_R_N) ? '-' : 'x';
+ __entry->eaddr = orig_pte->eaddr;
+ __entry->hpteg = hpteg;
+ __entry->va = va;
+ __entry->vpage = orig_pte->vpage;
+ __entry->hpaddr = hpaddr;
+ ),
+
+ TP_printk("KVM: %c%c Map 0x%lx: [%lx] 0x%lx (0x%llx) -> %lx",
+ __entry->flag_w, __entry->flag_x, __entry->eaddr,
+ __entry->hpteg, __entry->va, __entry->vpage, __entry->hpaddr)
+);
+
+#endif /* CONFIG_PPC_BOOK3S_64 */
+
+TRACE_EVENT(kvm_book3s_mmu_map,
+ TP_PROTO(struct hpte_cache *pte),
+ TP_ARGS(pte),
+
+ TP_STRUCT__entry(
+ __field( u64, host_va )
+ __field( u64, pfn )
+ __field( ulong, eaddr )
+ __field( u64, vpage )
+ __field( ulong, raddr )
+ __field( int, flags )
+ ),
+
+ TP_fast_assign(
+ __entry->host_va = pte->host_va;
+ __entry->pfn = pte->pfn;
+ __entry->eaddr = pte->pte.eaddr;
+ __entry->vpage = pte->pte.vpage;
+ __entry->raddr = pte->pte.raddr;
+ __entry->flags = (pte->pte.may_read ? 0x4 : 0) |
+ (pte->pte.may_write ? 0x2 : 0) |
+ (pte->pte.may_execute ? 0x1 : 0);
+ ),
+
+ TP_printk("Map: hva=%llx pfn=%llx ea=%lx vp=%llx ra=%lx [%x]",
+ __entry->host_va, __entry->pfn, __entry->eaddr,
+ __entry->vpage, __entry->raddr, __entry->flags)
+);
+
+TRACE_EVENT(kvm_book3s_mmu_invalidate,
+ TP_PROTO(struct hpte_cache *pte),
+ TP_ARGS(pte),
+
+ TP_STRUCT__entry(
+ __field( u64, host_va )
+ __field( u64, pfn )
+ __field( ulong, eaddr )
+ __field( u64, vpage )
+ __field( ulong, raddr )
+ __field( int, flags )
+ ),
+
+ TP_fast_assign(
+ __entry->host_va = pte->host_va;
+ __entry->pfn = pte->pfn;
+ __entry->eaddr = pte->pte.eaddr;
+ __entry->vpage = pte->pte.vpage;
+ __entry->raddr = pte->pte.raddr;
+ __entry->flags = (pte->pte.may_read ? 0x4 : 0) |
+ (pte->pte.may_write ? 0x2 : 0) |
+ (pte->pte.may_execute ? 0x1 : 0);
+ ),
+
+ TP_printk("Flush: hva=%llx pfn=%llx ea=%lx vp=%llx ra=%lx [%x]",
+ __entry->host_va, __entry->pfn, __entry->eaddr,
+ __entry->vpage, __entry->raddr, __entry->flags)
+);
+
+TRACE_EVENT(kvm_book3s_mmu_flush,
+ TP_PROTO(const char *type, struct kvm_vcpu *vcpu, unsigned long long p1,
+ unsigned long long p2),
+ TP_ARGS(type, vcpu, p1, p2),
+
+ TP_STRUCT__entry(
+ __field( int, count )
+ __field( unsigned long long, p1 )
+ __field( unsigned long long, p2 )
+ __field( const char *, type )
+ ),
+
+ TP_fast_assign(
+ __entry->count = vcpu->arch.hpte_cache_count;
+ __entry->p1 = p1;
+ __entry->p2 = p2;
+ __entry->type = type;
+ ),
+
+ TP_printk("Flush %d %sPTEs: %llx - %llx",
+ __entry->count, __entry->type, __entry->p1, __entry->p2)
+);
+
+TRACE_EVENT(kvm_book3s_slb_found,
+ TP_PROTO(unsigned long long gvsid, unsigned long long hvsid),
+ TP_ARGS(gvsid, hvsid),
+
+ TP_STRUCT__entry(
+ __field( unsigned long long, gvsid )
+ __field( unsigned long long, hvsid )
+ ),
+
+ TP_fast_assign(
+ __entry->gvsid = gvsid;
+ __entry->hvsid = hvsid;
+ ),
+
+ TP_printk("%llx -> %llx", __entry->gvsid, __entry->hvsid)
+);
+
+TRACE_EVENT(kvm_book3s_slb_fail,
+ TP_PROTO(u16 sid_map_mask, unsigned long long gvsid),
+ TP_ARGS(sid_map_mask, gvsid),
+
+ TP_STRUCT__entry(
+ __field( unsigned short, sid_map_mask )
+ __field( unsigned long long, gvsid )
+ ),
+
+ TP_fast_assign(
+ __entry->sid_map_mask = sid_map_mask;
+ __entry->gvsid = gvsid;
+ ),
+
+ TP_printk("%x/%x: %llx", __entry->sid_map_mask,
+ SID_MAP_MASK - __entry->sid_map_mask, __entry->gvsid)
+);
+
+TRACE_EVENT(kvm_book3s_slb_map,
+ TP_PROTO(u16 sid_map_mask, unsigned long long gvsid,
+ unsigned long long hvsid),
+ TP_ARGS(sid_map_mask, gvsid, hvsid),
+
+ TP_STRUCT__entry(
+ __field( unsigned short, sid_map_mask )
+ __field( unsigned long long, guest_vsid )
+ __field( unsigned long long, host_vsid )
+ ),
+
+ TP_fast_assign(
+ __entry->sid_map_mask = sid_map_mask;
+ __entry->guest_vsid = gvsid;
+ __entry->host_vsid = hvsid;
+ ),
+
+ TP_printk("%x: %llx -> %llx", __entry->sid_map_mask,
+ __entry->guest_vsid, __entry->host_vsid)
+);
+
+TRACE_EVENT(kvm_book3s_slbmte,
+ TP_PROTO(u64 slb_vsid, u64 slb_esid),
+ TP_ARGS(slb_vsid, slb_esid),
+
+ TP_STRUCT__entry(
+ __field( u64, slb_vsid )
+ __field( u64, slb_esid )
+ ),
+
+ TP_fast_assign(
+ __entry->slb_vsid = slb_vsid;
+ __entry->slb_esid = slb_esid;
+ ),
+
+ TP_printk("%llx, %llx", __entry->slb_vsid, __entry->slb_esid)
+);
+
+#endif /* CONFIG_PPC_BOOK3S */
+
#endif /* _TRACE_KVM_H */
/* This part must be outside protection */
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index 5bb89c828070..889f2bc106dd 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -4,9 +4,7 @@
subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
-ifeq ($(CONFIG_PPC64),y)
-EXTRA_CFLAGS += -mno-minimal-toc
-endif
+ccflags-$(CONFIG_PPC64) := -mno-minimal-toc
CFLAGS_REMOVE_code-patching.o = -pg
CFLAGS_REMOVE_feature-fixups.o = -pg
@@ -17,7 +15,8 @@ obj-$(CONFIG_PPC32) += div64.o copy_32.o
obj-$(CONFIG_HAS_IOMEM) += devres.o
obj-$(CONFIG_PPC64) += copypage_64.o copyuser_64.o \
- memcpy_64.o usercopy_64.o mem_64.o string.o
+ memcpy_64.o usercopy_64.o mem_64.o string.o \
+ checksum_wrappers_64.o
obj-$(CONFIG_XMON) += sstep.o ldstfp.o
obj-$(CONFIG_KPROBES) += sstep.o ldstfp.o
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += sstep.o ldstfp.o
diff --git a/arch/powerpc/lib/checksum_64.S b/arch/powerpc/lib/checksum_64.S
index ef96c6c58efc..18245af38aea 100644
--- a/arch/powerpc/lib/checksum_64.S
+++ b/arch/powerpc/lib/checksum_64.S
@@ -65,165 +65,393 @@ _GLOBAL(csum_tcpudp_magic)
srwi r3,r3,16
blr
+#define STACKFRAMESIZE 256
+#define STK_REG(i) (112 + ((i)-14)*8)
+
/*
* Computes the checksum of a memory block at buff, length len,
* and adds in "sum" (32-bit).
*
- * This code assumes at least halfword alignment, though the length
- * can be any number of bytes. The sum is accumulated in r5.
- *
* csum_partial(r3=buff, r4=len, r5=sum)
*/
_GLOBAL(csum_partial)
- subi r3,r3,8 /* we'll offset by 8 for the loads */
- srdi. r6,r4,3 /* divide by 8 for doubleword count */
- addic r5,r5,0 /* clear carry */
- beq 3f /* if we're doing < 8 bytes */
- andi. r0,r3,2 /* aligned on a word boundary already? */
- beq+ 1f
- lhz r6,8(r3) /* do 2 bytes to get aligned */
- addi r3,r3,2
- subi r4,r4,2
- addc r5,r5,r6
- srdi. r6,r4,3 /* recompute number of doublewords */
- beq 3f /* any left? */
-1: mtctr r6
-2: ldu r6,8(r3) /* main sum loop */
- adde r5,r5,r6
- bdnz 2b
- andi. r4,r4,7 /* compute bytes left to sum after doublewords */
-3: cmpwi 0,r4,4 /* is at least a full word left? */
- blt 4f
- lwz r6,8(r3) /* sum this word */
+ addic r0,r5,0 /* clear carry */
+
+ srdi. r6,r4,3 /* less than 8 bytes? */
+ beq .Lcsum_tail_word
+
+ /*
+ * If only halfword aligned, align to a double word. Since odd
+ * aligned addresses should be rare and they would require more
+ * work to calculate the correct checksum, we ignore that case
+ * and take the potential slowdown of unaligned loads.
+ */
+ rldicl. r6,r3,64-1,64-2 /* r6 = (r3 & 0x3) >> 1 */
+ beq .Lcsum_aligned
+
+ li r7,4
+ sub r6,r7,r6
+ mtctr r6
+
+1:
+ lhz r6,0(r3) /* align to doubleword */
+ subi r4,r4,2
+ addi r3,r3,2
+ adde r0,r0,r6
+ bdnz 1b
+
+.Lcsum_aligned:
+ /*
+ * We unroll the loop such that each iteration is 64 bytes with an
+ * entry and exit limb of 64 bytes, meaning a minimum size of
+ * 128 bytes.
+ */
+ srdi. r6,r4,7
+ beq .Lcsum_tail_doublewords /* len < 128 */
+
+ srdi r6,r4,6
+ subi r6,r6,1
+ mtctr r6
+
+ stdu r1,-STACKFRAMESIZE(r1)
+ std r14,STK_REG(r14)(r1)
+ std r15,STK_REG(r15)(r1)
+ std r16,STK_REG(r16)(r1)
+
+ ld r6,0(r3)
+ ld r9,8(r3)
+
+ ld r10,16(r3)
+ ld r11,24(r3)
+
+ /*
+ * On POWER6 and POWER7 back to back addes take 2 cycles because of
+ * the XER dependency. This means the fastest this loop can go is
+ * 16 cycles per iteration. The scheduling of the loop below has
+ * been shown to hit this on both POWER6 and POWER7.
+ */
+ .align 5
+2:
+ adde r0,r0,r6
+ ld r12,32(r3)
+ ld r14,40(r3)
+
+ adde r0,r0,r9
+ ld r15,48(r3)
+ ld r16,56(r3)
+ addi r3,r3,64
+
+ adde r0,r0,r10
+
+ adde r0,r0,r11
+
+ adde r0,r0,r12
+
+ adde r0,r0,r14
+
+ adde r0,r0,r15
+ ld r6,0(r3)
+ ld r9,8(r3)
+
+ adde r0,r0,r16
+ ld r10,16(r3)
+ ld r11,24(r3)
+ bdnz 2b
+
+
+ adde r0,r0,r6
+ ld r12,32(r3)
+ ld r14,40(r3)
+
+ adde r0,r0,r9
+ ld r15,48(r3)
+ ld r16,56(r3)
+ addi r3,r3,64
+
+ adde r0,r0,r10
+ adde r0,r0,r11
+ adde r0,r0,r12
+ adde r0,r0,r14
+ adde r0,r0,r15
+ adde r0,r0,r16
+
+ ld r14,STK_REG(r14)(r1)
+ ld r15,STK_REG(r15)(r1)
+ ld r16,STK_REG(r16)(r1)
+ addi r1,r1,STACKFRAMESIZE
+
+ andi. r4,r4,63
+
+.Lcsum_tail_doublewords: /* Up to 127 bytes to go */
+ srdi. r6,r4,3
+ beq .Lcsum_tail_word
+
+ mtctr r6
+3:
+ ld r6,0(r3)
+ addi r3,r3,8
+ adde r0,r0,r6
+ bdnz 3b
+
+ andi. r4,r4,7
+
+.Lcsum_tail_word: /* Up to 7 bytes to go */
+ srdi. r6,r4,2
+ beq .Lcsum_tail_halfword
+
+ lwz r6,0(r3)
addi r3,r3,4
+ adde r0,r0,r6
subi r4,r4,4
- adde r5,r5,r6
-4: cmpwi 0,r4,2 /* is at least a halfword left? */
- blt+ 5f
- lhz r6,8(r3) /* sum this halfword */
- addi r3,r3,2
- subi r4,r4,2
- adde r5,r5,r6
-5: cmpwi 0,r4,1 /* is at least a byte left? */
- bne+ 6f
- lbz r6,8(r3) /* sum this byte */
- slwi r6,r6,8 /* this byte is assumed to be the upper byte of a halfword */
- adde r5,r5,r6
-6: addze r5,r5 /* add in final carry */
- rldicl r4,r5,32,0 /* fold two 32-bit halves together */
- add r3,r4,r5
- srdi r3,r3,32
- blr
+
+.Lcsum_tail_halfword: /* Up to 3 bytes to go */
+ srdi. r6,r4,1
+ beq .Lcsum_tail_byte
+
+ lhz r6,0(r3)
+ addi r3,r3,2
+ adde r0,r0,r6
+ subi r4,r4,2
+
+.Lcsum_tail_byte: /* Up to 1 byte to go */
+ andi. r6,r4,1
+ beq .Lcsum_finish
+
+ lbz r6,0(r3)
+ sldi r9,r6,8 /* Pad the byte out to 16 bits */
+ adde r0,r0,r9
+
+.Lcsum_finish:
+ addze r0,r0 /* add in final carry */
+ rldicl r4,r0,32,0 /* fold two 32 bit halves together */
+ add r3,r4,r0
+ srdi r3,r3,32
+ blr
+
+
+ .macro source
+100:
+ .section __ex_table,"a"
+ .align 3
+ .llong 100b,.Lsrc_error
+ .previous
+ .endm
+
+ .macro dest
+200:
+ .section __ex_table,"a"
+ .align 3
+ .llong 200b,.Ldest_error
+ .previous
+ .endm
/*
* Computes the checksum of a memory block at src, length len,
* and adds in "sum" (32-bit), while copying the block to dst.
* If an access exception occurs on src or dst, it stores -EFAULT
- * to *src_err or *dst_err respectively, and (for an error on
- * src) zeroes the rest of dst.
- *
- * This code needs to be reworked to take advantage of 64 bit sum+copy.
- * However, due to tokenring halfword alignment problems this will be very
- * tricky. For now we'll leave it until we instrument it somehow.
+ * to *src_err or *dst_err respectively. The caller must take any action
+ * required in this case (zeroing memory, recalculating partial checksum etc).
*
* csum_partial_copy_generic(r3=src, r4=dst, r5=len, r6=sum, r7=src_err, r8=dst_err)
*/
_GLOBAL(csum_partial_copy_generic)
- addic r0,r6,0
- subi r3,r3,4
- subi r4,r4,4
- srwi. r6,r5,2
- beq 3f /* if we're doing < 4 bytes */
- andi. r9,r4,2 /* Align dst to longword boundary */
- beq+ 1f
-81: lhz r6,4(r3) /* do 2 bytes to get aligned */
- addi r3,r3,2
+ addic r0,r6,0 /* clear carry */
+
+ srdi. r6,r5,3 /* less than 8 bytes? */
+ beq .Lcopy_tail_word
+
+ /*
+ * If only halfword aligned, align to a double word. Since odd
+ * aligned addresses should be rare and they would require more
+ * work to calculate the correct checksum, we ignore that case
+ * and take the potential slowdown of unaligned loads.
+ *
+ * If the source and destination are relatively unaligned we only
+ * align the source. This keeps things simple.
+ */
+ rldicl. r6,r3,64-1,64-2 /* r6 = (r3 & 0x3) >> 1 */
+ beq .Lcopy_aligned
+
+ li r7,4
+ sub r6,r7,r6
+ mtctr r6
+
+1:
+source; lhz r6,0(r3) /* align to doubleword */
subi r5,r5,2
-91: sth r6,4(r4)
- addi r4,r4,2
- addc r0,r0,r6
- srwi. r6,r5,2 /* # words to do */
- beq 3f
-1: mtctr r6
-82: lwzu r6,4(r3) /* the bdnz has zero overhead, so it should */
-92: stwu r6,4(r4) /* be unnecessary to unroll this loop */
- adde r0,r0,r6
- bdnz 82b
- andi. r5,r5,3
-3: cmpwi 0,r5,2
- blt+ 4f
-83: lhz r6,4(r3)
addi r3,r3,2
- subi r5,r5,2
-93: sth r6,4(r4)
+ adde r0,r0,r6
+dest; sth r6,0(r4)
addi r4,r4,2
+ bdnz 1b
+
+.Lcopy_aligned:
+ /*
+ * We unroll the loop such that each iteration is 64 bytes with an
+ * entry and exit limb of 64 bytes, meaning a minimum size of
+ * 128 bytes.
+ */
+ srdi. r6,r5,7
+ beq .Lcopy_tail_doublewords /* len < 128 */
+
+ srdi r6,r5,6
+ subi r6,r6,1
+ mtctr r6
+
+ stdu r1,-STACKFRAMESIZE(r1)
+ std r14,STK_REG(r14)(r1)
+ std r15,STK_REG(r15)(r1)
+ std r16,STK_REG(r16)(r1)
+
+source; ld r6,0(r3)
+source; ld r9,8(r3)
+
+source; ld r10,16(r3)
+source; ld r11,24(r3)
+
+ /*
+ * On POWER6 and POWER7 back to back addes take 2 cycles because of
+ * the XER dependency. This means the fastest this loop can go is
+ * 16 cycles per iteration. The scheduling of the loop below has
+ * been shown to hit this on both POWER6 and POWER7.
+ */
+ .align 5
+2:
adde r0,r0,r6
-4: cmpwi 0,r5,1
- bne+ 5f
-84: lbz r6,4(r3)
-94: stb r6,4(r4)
- slwi r6,r6,8 /* Upper byte of word */
+source; ld r12,32(r3)
+source; ld r14,40(r3)
+
+ adde r0,r0,r9
+source; ld r15,48(r3)
+source; ld r16,56(r3)
+ addi r3,r3,64
+
+ adde r0,r0,r10
+dest; std r6,0(r4)
+dest; std r9,8(r4)
+
+ adde r0,r0,r11
+dest; std r10,16(r4)
+dest; std r11,24(r4)
+
+ adde r0,r0,r12
+dest; std r12,32(r4)
+dest; std r14,40(r4)
+
+ adde r0,r0,r14
+dest; std r15,48(r4)
+dest; std r16,56(r4)
+ addi r4,r4,64
+
+ adde r0,r0,r15
+source; ld r6,0(r3)
+source; ld r9,8(r3)
+
+ adde r0,r0,r16
+source; ld r10,16(r3)
+source; ld r11,24(r3)
+ bdnz 2b
+
+
adde r0,r0,r6
-5: addze r3,r0 /* add in final carry (unlikely with 64-bit regs) */
- rldicl r4,r3,32,0 /* fold 64 bit value */
- add r3,r4,r3
- srdi r3,r3,32
- blr
+source; ld r12,32(r3)
+source; ld r14,40(r3)
-/* These shouldn't go in the fixup section, since that would
- cause the ex_table addresses to get out of order. */
+ adde r0,r0,r9
+source; ld r15,48(r3)
+source; ld r16,56(r3)
+ addi r3,r3,64
+
+ adde r0,r0,r10
+dest; std r6,0(r4)
+dest; std r9,8(r4)
+
+ adde r0,r0,r11
+dest; std r10,16(r4)
+dest; std r11,24(r4)
+
+ adde r0,r0,r12
+dest; std r12,32(r4)
+dest; std r14,40(r4)
+
+ adde r0,r0,r14
+dest; std r15,48(r4)
+dest; std r16,56(r4)
+ addi r4,r4,64
+
+ adde r0,r0,r15
+ adde r0,r0,r16
+
+ ld r14,STK_REG(r14)(r1)
+ ld r15,STK_REG(r15)(r1)
+ ld r16,STK_REG(r16)(r1)
+ addi r1,r1,STACKFRAMESIZE
+
+ andi. r5,r5,63
+
+.Lcopy_tail_doublewords: /* Up to 127 bytes to go */
+ srdi. r6,r5,3
+ beq .Lcopy_tail_word
- .globl src_error_1
-src_error_1:
- li r6,0
- subi r5,r5,2
-95: sth r6,4(r4)
- addi r4,r4,2
- srwi. r6,r5,2
- beq 3f
mtctr r6
- .globl src_error_2
-src_error_2:
- li r6,0
-96: stwu r6,4(r4)
- bdnz 96b
-3: andi. r5,r5,3
- beq src_error
- .globl src_error_3
-src_error_3:
- li r6,0
- mtctr r5
- addi r4,r4,3
-97: stbu r6,1(r4)
- bdnz 97b
- .globl src_error
-src_error:
+3:
+source; ld r6,0(r3)
+ addi r3,r3,8
+ adde r0,r0,r6
+dest; std r6,0(r4)
+ addi r4,r4,8
+ bdnz 3b
+
+ andi. r5,r5,7
+
+.Lcopy_tail_word: /* Up to 7 bytes to go */
+ srdi. r6,r5,2
+ beq .Lcopy_tail_halfword
+
+source; lwz r6,0(r3)
+ addi r3,r3,4
+ adde r0,r0,r6
+dest; stw r6,0(r4)
+ addi r4,r4,4
+ subi r5,r5,4
+
+.Lcopy_tail_halfword: /* Up to 3 bytes to go */
+ srdi. r6,r5,1
+ beq .Lcopy_tail_byte
+
+source; lhz r6,0(r3)
+ addi r3,r3,2
+ adde r0,r0,r6
+dest; sth r6,0(r4)
+ addi r4,r4,2
+ subi r5,r5,2
+
+.Lcopy_tail_byte: /* Up to 1 byte to go */
+ andi. r6,r5,1
+ beq .Lcopy_finish
+
+source; lbz r6,0(r3)
+ sldi r9,r6,8 /* Pad the byte out to 16 bits */
+ adde r0,r0,r9
+dest; stb r6,0(r4)
+
+.Lcopy_finish:
+ addze r0,r0 /* add in final carry */
+ rldicl r4,r0,32,0 /* fold two 32 bit halves together */
+ add r3,r4,r0
+ srdi r3,r3,32
+ blr
+
+.Lsrc_error:
cmpdi 0,r7,0
- beq 1f
+ beqlr
li r6,-EFAULT
stw r6,0(r7)
-1: addze r3,r0
blr
- .globl dst_error
-dst_error:
+.Ldest_error:
cmpdi 0,r8,0
- beq 1f
+ beqlr
li r6,-EFAULT
stw r6,0(r8)
-1: addze r3,r0
blr
-
-.section __ex_table,"a"
- .align 3
- .llong 81b,src_error_1
- .llong 91b,dst_error
- .llong 82b,src_error_2
- .llong 92b,dst_error
- .llong 83b,src_error_3
- .llong 93b,dst_error
- .llong 84b,src_error_3
- .llong 94b,dst_error
- .llong 95b,dst_error
- .llong 96b,dst_error
- .llong 97b,dst_error
diff --git a/arch/powerpc/lib/checksum_wrappers_64.c b/arch/powerpc/lib/checksum_wrappers_64.c
new file mode 100644
index 000000000000..769b817fbb32
--- /dev/null
+++ b/arch/powerpc/lib/checksum_wrappers_64.c
@@ -0,0 +1,102 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2010
+ *
+ * Author: Anton Blanchard <anton@au.ibm.com>
+ */
+#include <linux/module.h>
+#include <linux/compiler.h>
+#include <linux/types.h>
+#include <asm/checksum.h>
+#include <asm/uaccess.h>
+
+__wsum csum_and_copy_from_user(const void __user *src, void *dst,
+ int len, __wsum sum, int *err_ptr)
+{
+ unsigned int csum;
+
+ might_sleep();
+
+ *err_ptr = 0;
+
+ if (!len) {
+ csum = 0;
+ goto out;
+ }
+
+ if (unlikely((len < 0) || !access_ok(VERIFY_READ, src, len))) {
+ *err_ptr = -EFAULT;
+ csum = (__force unsigned int)sum;
+ goto out;
+ }
+
+ csum = csum_partial_copy_generic((void __force *)src, dst,
+ len, sum, err_ptr, NULL);
+
+ if (unlikely(*err_ptr)) {
+ int missing = __copy_from_user(dst, src, len);
+
+ if (missing) {
+ memset(dst + len - missing, 0, missing);
+ *err_ptr = -EFAULT;
+ } else {
+ *err_ptr = 0;
+ }
+
+ csum = csum_partial(dst, len, sum);
+ }
+
+out:
+ return (__force __wsum)csum;
+}
+EXPORT_SYMBOL(csum_and_copy_from_user);
+
+__wsum csum_and_copy_to_user(const void *src, void __user *dst, int len,
+ __wsum sum, int *err_ptr)
+{
+ unsigned int csum;
+
+ might_sleep();
+
+ *err_ptr = 0;
+
+ if (!len) {
+ csum = 0;
+ goto out;
+ }
+
+ if (unlikely((len < 0) || !access_ok(VERIFY_WRITE, dst, len))) {
+ *err_ptr = -EFAULT;
+ csum = -1; /* invalid checksum */
+ goto out;
+ }
+
+ csum = csum_partial_copy_generic(src, (void __force *)dst,
+ len, sum, NULL, err_ptr);
+
+ if (unlikely(*err_ptr)) {
+ csum = csum_partial(src, len, sum);
+
+ if (copy_to_user(dst, src, len)) {
+ *err_ptr = -EFAULT;
+ csum = -1; /* invalid checksum */
+ }
+ }
+
+out:
+ return (__force __wsum)csum;
+}
+EXPORT_SYMBOL(csum_and_copy_to_user);
diff --git a/arch/powerpc/lib/copy_32.S b/arch/powerpc/lib/copy_32.S
index 74a7f4130b4c..55f19f9fd708 100644
--- a/arch/powerpc/lib/copy_32.S
+++ b/arch/powerpc/lib/copy_32.S
@@ -62,7 +62,7 @@
.text
.stabs "arch/powerpc/lib/",N_SO,0,0,0f
- .stabs "copy32.S",N_SO,0,0,0f
+ .stabs "copy_32.S",N_SO,0,0,0f
0:
CACHELINE_BYTES = L1_CACHE_BYTES
diff --git a/arch/powerpc/lib/ldstfp.S b/arch/powerpc/lib/ldstfp.S
index f6448636baf5..6a85380520b6 100644
--- a/arch/powerpc/lib/ldstfp.S
+++ b/arch/powerpc/lib/ldstfp.S
@@ -17,6 +17,8 @@
#include <asm/asm-offsets.h>
#include <linux/errno.h>
+#ifdef CONFIG_PPC_FPU
+
#define STKFRM (PPC_MIN_STKFRM + 16)
.macro extab instr,handler
@@ -81,7 +83,7 @@ _GLOBAL(do_lfs)
mfmsr r6
ori r7,r6,MSR_FP
cmpwi cr7,r3,0
- mtmsrd r7
+ MTMSRD(r7)
isync
beq cr7,1f
stfd fr0,STKFRM-16(r1)
@@ -93,7 +95,7 @@ _GLOBAL(do_lfs)
lfd fr0,STKFRM-16(r1)
4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
mtlr r0
- mtmsrd r6
+ MTMSRD(r6)
isync
mr r3,r9
addi r1,r1,STKFRM
@@ -108,7 +110,7 @@ _GLOBAL(do_lfd)
mfmsr r6
ori r7,r6,MSR_FP
cmpwi cr7,r3,0
- mtmsrd r7
+ MTMSRD(r7)
isync
beq cr7,1f
stfd fr0,STKFRM-16(r1)
@@ -120,7 +122,7 @@ _GLOBAL(do_lfd)
lfd fr0,STKFRM-16(r1)
4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
mtlr r0
- mtmsrd r6
+ MTMSRD(r6)
isync
mr r3,r9
addi r1,r1,STKFRM
@@ -135,7 +137,7 @@ _GLOBAL(do_stfs)
mfmsr r6
ori r7,r6,MSR_FP
cmpwi cr7,r3,0
- mtmsrd r7
+ MTMSRD(r7)
isync
beq cr7,1f
stfd fr0,STKFRM-16(r1)
@@ -147,7 +149,7 @@ _GLOBAL(do_stfs)
lfd fr0,STKFRM-16(r1)
4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
mtlr r0
- mtmsrd r6
+ MTMSRD(r6)
isync
mr r3,r9
addi r1,r1,STKFRM
@@ -162,7 +164,7 @@ _GLOBAL(do_stfd)
mfmsr r6
ori r7,r6,MSR_FP
cmpwi cr7,r3,0
- mtmsrd r7
+ MTMSRD(r7)
isync
beq cr7,1f
stfd fr0,STKFRM-16(r1)
@@ -174,7 +176,7 @@ _GLOBAL(do_stfd)
lfd fr0,STKFRM-16(r1)
4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
mtlr r0
- mtmsrd r6
+ MTMSRD(r6)
isync
mr r3,r9
addi r1,r1,STKFRM
@@ -229,7 +231,7 @@ _GLOBAL(do_lvx)
oris r7,r6,MSR_VEC@h
cmpwi cr7,r3,0
li r8,STKFRM-16
- mtmsrd r7
+ MTMSRD(r7)
isync
beq cr7,1f
stvx vr0,r1,r8
@@ -241,7 +243,7 @@ _GLOBAL(do_lvx)
lvx vr0,r1,r8
4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
mtlr r0
- mtmsrd r6
+ MTMSRD(r6)
isync
mr r3,r9
addi r1,r1,STKFRM
@@ -257,7 +259,7 @@ _GLOBAL(do_stvx)
oris r7,r6,MSR_VEC@h
cmpwi cr7,r3,0
li r8,STKFRM-16
- mtmsrd r7
+ MTMSRD(r7)
isync
beq cr7,1f
stvx vr0,r1,r8
@@ -269,7 +271,7 @@ _GLOBAL(do_stvx)
lvx vr0,r1,r8
4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
mtlr r0
- mtmsrd r6
+ MTMSRD(r6)
isync
mr r3,r9
addi r1,r1,STKFRM
@@ -325,7 +327,7 @@ _GLOBAL(do_lxvd2x)
oris r7,r6,MSR_VSX@h
cmpwi cr7,r3,0
li r8,STKFRM-16
- mtmsrd r7
+ MTMSRD(r7)
isync
beq cr7,1f
STXVD2X(0,r1,r8)
@@ -337,7 +339,7 @@ _GLOBAL(do_lxvd2x)
LXVD2X(0,r1,r8)
4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
mtlr r0
- mtmsrd r6
+ MTMSRD(r6)
isync
mr r3,r9
addi r1,r1,STKFRM
@@ -353,7 +355,7 @@ _GLOBAL(do_stxvd2x)
oris r7,r6,MSR_VSX@h
cmpwi cr7,r3,0
li r8,STKFRM-16
- mtmsrd r7
+ MTMSRD(r7)
isync
beq cr7,1f
STXVD2X(0,r1,r8)
@@ -365,7 +367,7 @@ _GLOBAL(do_stxvd2x)
LXVD2X(0,r1,r8)
4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
mtlr r0
- mtmsrd r6
+ MTMSRD(r6)
isync
mr r3,r9
addi r1,r1,STKFRM
@@ -373,3 +375,5 @@ _GLOBAL(do_stxvd2x)
extab 2b,3b
#endif /* CONFIG_VSX */
+
+#endif /* CONFIG_PPC_FPU */
diff --git a/arch/powerpc/lib/locks.c b/arch/powerpc/lib/locks.c
index 58e14fba11b1..9b8182e82166 100644
--- a/arch/powerpc/lib/locks.c
+++ b/arch/powerpc/lib/locks.c
@@ -34,7 +34,7 @@ void __spin_yield(arch_spinlock_t *lock)
return;
holder_cpu = lock_value & 0xffff;
BUG_ON(holder_cpu >= NR_CPUS);
- yield_count = lppaca[holder_cpu].yield_count;
+ yield_count = lppaca_of(holder_cpu).yield_count;
if ((yield_count & 1) == 0)
return; /* virtual cpu is currently running */
rmb();
@@ -65,7 +65,7 @@ void __rw_yield(arch_rwlock_t *rw)
return; /* no write lock at present */
holder_cpu = lock_value & 0xffff;
BUG_ON(holder_cpu >= NR_CPUS);
- yield_count = lppaca[holder_cpu].yield_count;
+ yield_count = lppaca_of(holder_cpu).yield_count;
if ((yield_count & 1) == 0)
return; /* virtual cpu is currently running */
rmb();
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index e0a9858d537e..ae5189ab0049 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -30,6 +30,7 @@ extern char system_call_common[];
#define XER_OV 0x40000000U
#define XER_CA 0x20000000U
+#ifdef CONFIG_PPC_FPU
/*
* Functions in ldstfp.S
*/
@@ -41,6 +42,7 @@ extern int do_lvx(int rn, unsigned long ea);
extern int do_stvx(int rn, unsigned long ea);
extern int do_lxvd2x(int rn, unsigned long ea);
extern int do_stxvd2x(int rn, unsigned long ea);
+#endif
/*
* Determine whether a conditional branch instruction would branch.
@@ -290,6 +292,7 @@ static int __kprobes write_mem(unsigned long val, unsigned long ea, int nb,
return write_mem_unaligned(val, ea, nb, regs);
}
+#ifdef CONFIG_PPC_FPU
/*
* Check the address and alignment, and call func to do the actual
* load or store.
@@ -351,6 +354,7 @@ static int __kprobes do_fp_store(int rn, int (*func)(int, unsigned long),
}
return err;
}
+#endif
#ifdef CONFIG_ALTIVEC
/* For Altivec/VMX, no need to worry about alignment */
@@ -1393,6 +1397,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
regs->gpr[rd] = byterev_4(val);
goto ldst_done;
+#ifdef CONFIG_PPC_CPU
case 535: /* lfsx */
case 567: /* lfsux */
if (!(regs->msr & MSR_FP))
@@ -1424,6 +1429,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
ea = xform_ea(instr, regs, u);
err = do_fp_store(rd, do_stfd, ea, 8, regs);
goto ldst_done;
+#endif
#ifdef __powerpc64__
case 660: /* stdbrx */
@@ -1534,6 +1540,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
} while (++rd < 32);
goto instr_done;
+#ifdef CONFIG_PPC_FPU
case 48: /* lfs */
case 49: /* lfsu */
if (!(regs->msr & MSR_FP))
@@ -1565,6 +1572,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
ea = dform_ea(instr, regs);
err = do_fp_store(rd, do_stfd, ea, 8, regs);
goto ldst_done;
+#endif
#ifdef __powerpc64__
case 58: /* ld[u], lwa */
diff --git a/arch/powerpc/math-emu/Makefile b/arch/powerpc/math-emu/Makefile
index 0c16ab947f1f..7d1dba0d57f9 100644
--- a/arch/powerpc/math-emu/Makefile
+++ b/arch/powerpc/math-emu/Makefile
@@ -15,4 +15,4 @@ obj-$(CONFIG_SPE) += math_efp.o
CFLAGS_fabs.o = -fno-builtin-fabs
CFLAGS_math.o = -fno-builtin-fabs
-EXTRA_CFLAGS = -I. -Iinclude/math-emu -w
+ccflags-y = -I. -Iinclude/math-emu -w
diff --git a/arch/powerpc/mm/40x_mmu.c b/arch/powerpc/mm/40x_mmu.c
index 1dc2fa5ce1bd..5810967511d4 100644
--- a/arch/powerpc/mm/40x_mmu.c
+++ b/arch/powerpc/mm/40x_mmu.c
@@ -35,6 +35,7 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/highmem.h>
+#include <linux/memblock.h>
#include <asm/pgalloc.h>
#include <asm/prom.h>
@@ -47,6 +48,7 @@
#include <asm/bootx.h>
#include <asm/machdep.h>
#include <asm/setup.h>
+
#include "mmu_decl.h"
extern int __map_without_ltlbs;
@@ -139,8 +141,19 @@ unsigned long __init mmu_mapin_ram(unsigned long top)
* coverage with normal-sized pages (or other reasons) do not
* attempt to allocate outside the allowed range.
*/
-
- __initial_memory_limit_addr = memstart_addr + mapped;
+ memblock_set_current_limit(mapped);
return mapped;
}
+
+void setup_initial_memory_limit(phys_addr_t first_memblock_base,
+ phys_addr_t first_memblock_size)
+{
+ /* We don't currently support the first MEMBLOCK not mapping 0
+ * physical on those processors
+ */
+ BUG_ON(first_memblock_base != 0);
+
+ /* 40x can only access 16MB at the moment (see head_40x.S) */
+ memblock_set_current_limit(min_t(u64, first_memblock_size, 0x00800000));
+}
diff --git a/arch/powerpc/mm/44x_mmu.c b/arch/powerpc/mm/44x_mmu.c
index d8c6efb32bc6..024acab588fd 100644
--- a/arch/powerpc/mm/44x_mmu.c
+++ b/arch/powerpc/mm/44x_mmu.c
@@ -24,6 +24,8 @@
*/
#include <linux/init.h>
+#include <linux/memblock.h>
+
#include <asm/mmu.h>
#include <asm/system.h>
#include <asm/page.h>
@@ -213,6 +215,18 @@ unsigned long __init mmu_mapin_ram(unsigned long top)
return total_lowmem;
}
+void setup_initial_memory_limit(phys_addr_t first_memblock_base,
+ phys_addr_t first_memblock_size)
+{
+ /* We don't currently support the first MEMBLOCK not mapping 0
+ * physical on those processors
+ */
+ BUG_ON(first_memblock_base != 0);
+
+ /* 44x has a 256M TLB entry pinned at boot */
+ memblock_set_current_limit(min_t(u64, first_memblock_size, PPC_PIN_SIZE));
+}
+
#ifdef CONFIG_SMP
void __cpuinit mmu_init_secondary(int cpu)
{
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index ce68708bbad5..bdca46e08382 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -4,9 +4,7 @@
subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
-ifeq ($(CONFIG_PPC64),y)
-EXTRA_CFLAGS += -mno-minimal-toc
-endif
+ccflags-$(CONFIG_PPC64) := -mno-minimal-toc
obj-y := fault.o mem.o pgtable.o gup.o \
init_$(CONFIG_WORD_SIZE).o \
@@ -25,7 +23,7 @@ obj-$(CONFIG_PPC_STD_MMU) += hash_low_$(CONFIG_WORD_SIZE).o \
mmu_context_hash$(CONFIG_WORD_SIZE).o
obj-$(CONFIG_40x) += 40x_mmu.o
obj-$(CONFIG_44x) += 44x_mmu.o
-obj-$(CONFIG_FSL_BOOKE) += fsl_booke_mmu.o
+obj-$(CONFIG_PPC_FSL_BOOK3E) += fsl_booke_mmu.o
obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o
obj-$(CONFIG_PPC_MM_SLICES) += slice.o
ifeq ($(CONFIG_HUGETLB_PAGE),y)
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 1bd712c33ce2..54f4fb994e99 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -30,6 +30,7 @@
#include <linux/kprobes.h>
#include <linux/kdebug.h>
#include <linux/perf_event.h>
+#include <linux/magic.h>
#include <asm/firmware.h>
#include <asm/page.h>
@@ -385,6 +386,7 @@ do_sigbus:
void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
{
const struct exception_table_entry *entry;
+ unsigned long *stackend;
/* Are we prepared to handle this fault? */
if ((entry = search_exception_tables(regs->nip)) != NULL) {
@@ -413,5 +415,9 @@ void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
printk(KERN_ALERT "Faulting instruction address: 0x%08lx\n",
regs->nip);
+ stackend = end_of_stack(current);
+ if (current != &init_task && *stackend != STACK_END_MAGIC)
+ printk(KERN_ALERT "Thread overran stack, or stack corrupted\n");
+
die("Kernel access of bad area", regs, sig);
}
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index 4b66a1ece6d8..f7802c8bba0a 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -40,6 +40,7 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/highmem.h>
+#include <linux/memblock.h>
#include <asm/pgalloc.h>
#include <asm/prom.h>
@@ -56,11 +57,6 @@
unsigned int tlbcam_index;
-
-#if defined(CONFIG_LOWMEM_CAM_NUM_BOOL) && (CONFIG_LOWMEM_CAM_NUM >= NUM_TLBCAMS)
-#error "LOWMEM_CAM_NUM must be less than NUM_TLBCAMS"
-#endif
-
#define NUM_TLBCAMS (64)
struct tlbcam TLBCAM[NUM_TLBCAMS];
@@ -137,7 +133,8 @@ static void settlbcam(int index, unsigned long virt, phys_addr_t phys,
if (mmu_has_feature(MMU_FTR_BIG_PHYS))
TLBCAM[index].MAS7 = (u64)phys >> 32;
- if (flags & _PAGE_USER) {
+ /* Below is unlikely -- only for large user pages or similar */
+ if (pte_user(flags)) {
TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
}
@@ -184,6 +181,12 @@ unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx)
return amount_mapped;
}
+#ifdef CONFIG_PPC32
+
+#if defined(CONFIG_LOWMEM_CAM_NUM_BOOL) && (CONFIG_LOWMEM_CAM_NUM >= NUM_TLBCAMS)
+#error "LOWMEM_CAM_NUM must be less than NUM_TLBCAMS"
+#endif
+
unsigned long __init mmu_mapin_ram(unsigned long top)
{
return tlbcam_addrs[tlbcam_index - 1].limit - PAGE_OFFSET + 1;
@@ -213,5 +216,15 @@ void __init adjust_total_lowmem(void)
pr_cont("%lu Mb, residual: %dMb\n", tlbcam_sz(tlbcam_index - 1) >> 20,
(unsigned int)((total_lowmem - __max_low_memory) >> 20));
- __initial_memory_limit_addr = memstart_addr + __max_low_memory;
+ memblock_set_current_limit(memstart_addr + __max_low_memory);
}
+
+void setup_initial_memory_limit(phys_addr_t first_memblock_base,
+ phys_addr_t first_memblock_size)
+{
+ phys_addr_t limit = first_memblock_base + first_memblock_size;
+
+ /* 64M mapped initially according to head_fsl_booke.S */
+ memblock_set_current_limit(min_t(u64, limit, 0x04000000));
+}
+#endif
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 09dffe6efa46..83f534d862db 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -588,7 +588,7 @@ static void __init htab_initialize(void)
unsigned long pteg_count;
unsigned long prot;
unsigned long base = 0, size = 0, limit;
- int i;
+ struct memblock_region *reg;
DBG(" -> htab_initialize()\n");
@@ -625,7 +625,7 @@ static void __init htab_initialize(void)
if (machine_is(cell))
limit = 0x80000000;
else
- limit = 0;
+ limit = MEMBLOCK_ALLOC_ANYWHERE;
table = memblock_alloc_base(htab_size_bytes, htab_size_bytes, limit);
@@ -649,7 +649,7 @@ static void __init htab_initialize(void)
#ifdef CONFIG_DEBUG_PAGEALLOC
linear_map_hash_count = memblock_end_of_DRAM() >> PAGE_SHIFT;
linear_map_hash_slots = __va(memblock_alloc_base(linear_map_hash_count,
- 1, memblock.rmo_size));
+ 1, ppc64_rma_size));
memset(linear_map_hash_slots, 0, linear_map_hash_count);
#endif /* CONFIG_DEBUG_PAGEALLOC */
@@ -659,9 +659,9 @@ static void __init htab_initialize(void)
*/
/* create bolted the linear mapping in the hash table */
- for (i=0; i < memblock.memory.cnt; i++) {
- base = (unsigned long)__va(memblock.memory.region[i].base);
- size = memblock.memory.region[i].size;
+ for_each_memblock(memory, reg) {
+ base = (unsigned long)__va(reg->base);
+ size = reg->size;
DBG("creating mapping for region: %lx..%lx (prot: %lx)\n",
base, size, prot);
@@ -696,7 +696,8 @@ static void __init htab_initialize(void)
#endif /* CONFIG_U3_DART */
BUG_ON(htab_bolt_mapping(base, base + size, __pa(base),
prot, mmu_linear_psize, mmu_kernel_ssize));
- }
+ }
+ memblock_set_current_limit(MEMBLOCK_ALLOC_ANYWHERE);
/*
* If we have a memory_limit and we've allocated TCEs then we need to
@@ -1247,3 +1248,23 @@ void kernel_map_pages(struct page *page, int numpages, int enable)
local_irq_restore(flags);
}
#endif /* CONFIG_DEBUG_PAGEALLOC */
+
+void setup_initial_memory_limit(phys_addr_t first_memblock_base,
+ phys_addr_t first_memblock_size)
+{
+ /* We don't currently support the first MEMBLOCK not mapping 0
+ * physical on those processors
+ */
+ BUG_ON(first_memblock_base != 0);
+
+ /* On LPAR systems, the first entry is our RMA region,
+ * non-LPAR 64-bit hash MMU systems don't have a limitation
+ * on real mode access, but using the first entry works well
+ * enough. We also clamp it to 1G to avoid some funky things
+ * such as RTAS bugs etc...
+ */
+ ppc64_rma_size = min_t(u64, first_memblock_size, 0x40000000);
+
+ /* Finally limit subsequent allocations */
+ memblock_set_current_limit(ppc64_rma_size);
+}
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
index 6a6975dc2654..742da43b4ab6 100644
--- a/arch/powerpc/mm/init_32.c
+++ b/arch/powerpc/mm/init_32.c
@@ -92,12 +92,6 @@ int __allow_ioremap_reserved;
unsigned long __max_low_memory = MAX_LOW_MEM;
/*
- * address of the limit of what is accessible with initial MMU setup -
- * 256MB usually, but only 16MB on 601.
- */
-phys_addr_t __initial_memory_limit_addr = (phys_addr_t)0x10000000;
-
-/*
* Check for command-line options that affect what MMU_init will do.
*/
void MMU_setup(void)
@@ -126,13 +120,6 @@ void __init MMU_init(void)
if (ppc_md.progress)
ppc_md.progress("MMU:enter", 0x111);
- /* 601 can only access 16MB at the moment */
- if (PVR_VER(mfspr(SPRN_PVR)) == 1)
- __initial_memory_limit_addr = 0x01000000;
- /* 8xx can only access 8MB at the moment */
- if (PVR_VER(mfspr(SPRN_PVR)) == 0x50)
- __initial_memory_limit_addr = 0x00800000;
-
/* parse args from command line */
MMU_setup();
@@ -190,20 +177,18 @@ void __init MMU_init(void)
#ifdef CONFIG_BOOTX_TEXT
btext_unmap();
#endif
+
+ /* Shortly after that, the entire linear mapping will be available */
+ memblock_set_current_limit(lowmem_end_addr);
}
/* This is only called until mem_init is done. */
void __init *early_get_page(void)
{
- void *p;
-
- if (init_bootmem_done) {
- p = alloc_bootmem_pages(PAGE_SIZE);
- } else {
- p = __va(memblock_alloc_base(PAGE_SIZE, PAGE_SIZE,
- __initial_memory_limit_addr));
- }
- return p;
+ if (init_bootmem_done)
+ return alloc_bootmem_pages(PAGE_SIZE);
+ else
+ return __va(memblock_alloc(PAGE_SIZE, PAGE_SIZE));
}
/* Free up now-unused memory */
@@ -252,3 +237,17 @@ void free_initrd_mem(unsigned long start, unsigned long end)
}
#endif
+
+#ifdef CONFIG_8xx /* No 8xx specific .c file to put that in ... */
+void setup_initial_memory_limit(phys_addr_t first_memblock_base,
+ phys_addr_t first_memblock_size)
+{
+ /* We don't currently support the first MEMBLOCK not mapping 0
+ * physical on those processors
+ */
+ BUG_ON(first_memblock_base != 0);
+
+ /* 8xx can only access 8MB at the moment */
+ memblock_set_current_limit(min_t(u64, first_memblock_size, 0x00800000));
+}
+#endif /* CONFIG_8xx */
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index ace85fa74b29..6374b2196a17 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -330,3 +330,4 @@ int __meminit vmemmap_populate(struct page *start_page,
return 0;
}
#endif /* CONFIG_SPARSEMEM_VMEMMAP */
+
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 1a84a8d00005..a66499650909 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -82,18 +82,11 @@ int page_is_ram(unsigned long pfn)
return pfn < max_pfn;
#else
unsigned long paddr = (pfn << PAGE_SHIFT);
- int i;
- for (i=0; i < memblock.memory.cnt; i++) {
- unsigned long base;
+ struct memblock_region *reg;
- base = memblock.memory.region[i].base;
-
- if ((paddr >= base) &&
- (paddr < (base + memblock.memory.region[i].size))) {
+ for_each_memblock(memory, reg)
+ if (paddr >= reg->base && paddr < (reg->base + reg->size))
return 1;
- }
- }
-
return 0;
#endif
}
@@ -149,23 +142,19 @@ int
walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages,
void *arg, int (*func)(unsigned long, unsigned long, void *))
{
- struct memblock_property res;
- unsigned long pfn, len;
- u64 end;
+ struct memblock_region *reg;
+ unsigned long end_pfn = start_pfn + nr_pages;
+ unsigned long tstart, tend;
int ret = -1;
- res.base = (u64) start_pfn << PAGE_SHIFT;
- res.size = (u64) nr_pages << PAGE_SHIFT;
-
- end = res.base + res.size - 1;
- while ((res.base < end) && (memblock_find(&res) >= 0)) {
- pfn = (unsigned long)(res.base >> PAGE_SHIFT);
- len = (unsigned long)(res.size >> PAGE_SHIFT);
- ret = (*func)(pfn, len, arg);
+ for_each_memblock(memory, reg) {
+ tstart = max(start_pfn, memblock_region_memory_base_pfn(reg));
+ tend = min(end_pfn, memblock_region_memory_end_pfn(reg));
+ if (tstart >= tend)
+ continue;
+ ret = (*func)(tstart, tend - tstart, arg);
if (ret)
break;
- res.base += (res.size + 1);
- res.size = (end - res.base + 1);
}
return ret;
}
@@ -179,9 +168,9 @@ EXPORT_SYMBOL_GPL(walk_system_ram_range);
#ifndef CONFIG_NEED_MULTIPLE_NODES
void __init do_init_bootmem(void)
{
- unsigned long i;
unsigned long start, bootmap_pages;
unsigned long total_pages;
+ struct memblock_region *reg;
int boot_mapsize;
max_low_pfn = max_pfn = memblock_end_of_DRAM() >> PAGE_SHIFT;
@@ -204,10 +193,10 @@ void __init do_init_bootmem(void)
boot_mapsize = init_bootmem_node(NODE_DATA(0), start >> PAGE_SHIFT, min_low_pfn, max_low_pfn);
/* Add active regions with valid PFNs */
- for (i = 0; i < memblock.memory.cnt; i++) {
+ for_each_memblock(memory, reg) {
unsigned long start_pfn, end_pfn;
- start_pfn = memblock.memory.region[i].base >> PAGE_SHIFT;
- end_pfn = start_pfn + memblock_size_pages(&memblock.memory, i);
+ start_pfn = memblock_region_memory_base_pfn(reg);
+ end_pfn = memblock_region_memory_end_pfn(reg);
add_active_range(0, start_pfn, end_pfn);
}
@@ -218,29 +207,21 @@ void __init do_init_bootmem(void)
free_bootmem_with_active_regions(0, lowmem_end_addr >> PAGE_SHIFT);
/* reserve the sections we're already using */
- for (i = 0; i < memblock.reserved.cnt; i++) {
- unsigned long addr = memblock.reserved.region[i].base +
- memblock_size_bytes(&memblock.reserved, i) - 1;
- if (addr < lowmem_end_addr)
- reserve_bootmem(memblock.reserved.region[i].base,
- memblock_size_bytes(&memblock.reserved, i),
- BOOTMEM_DEFAULT);
- else if (memblock.reserved.region[i].base < lowmem_end_addr) {
- unsigned long adjusted_size = lowmem_end_addr -
- memblock.reserved.region[i].base;
- reserve_bootmem(memblock.reserved.region[i].base,
- adjusted_size, BOOTMEM_DEFAULT);
+ for_each_memblock(reserved, reg) {
+ unsigned long top = reg->base + reg->size - 1;
+ if (top < lowmem_end_addr)
+ reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT);
+ else if (reg->base < lowmem_end_addr) {
+ unsigned long trunc_size = lowmem_end_addr - reg->base;
+ reserve_bootmem(reg->base, trunc_size, BOOTMEM_DEFAULT);
}
}
#else
free_bootmem_with_active_regions(0, max_pfn);
/* reserve the sections we're already using */
- for (i = 0; i < memblock.reserved.cnt; i++)
- reserve_bootmem(memblock.reserved.region[i].base,
- memblock_size_bytes(&memblock.reserved, i),
- BOOTMEM_DEFAULT);
-
+ for_each_memblock(reserved, reg)
+ reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT);
#endif
/* XXX need to clip this if using highmem? */
sparse_memory_present_with_active_regions(0);
@@ -251,22 +232,15 @@ void __init do_init_bootmem(void)
/* mark pages that don't exist as nosave */
static int __init mark_nonram_nosave(void)
{
- unsigned long memblock_next_region_start_pfn,
- memblock_region_max_pfn;
- int i;
-
- for (i = 0; i < memblock.memory.cnt - 1; i++) {
- memblock_region_max_pfn =
- (memblock.memory.region[i].base >> PAGE_SHIFT) +
- (memblock.memory.region[i].size >> PAGE_SHIFT);
- memblock_next_region_start_pfn =
- memblock.memory.region[i+1].base >> PAGE_SHIFT;
-
- if (memblock_region_max_pfn < memblock_next_region_start_pfn)
- register_nosave_region(memblock_region_max_pfn,
- memblock_next_region_start_pfn);
+ struct memblock_region *reg, *prev = NULL;
+
+ for_each_memblock(memory, reg) {
+ if (prev &&
+ memblock_region_memory_end_pfn(prev) < memblock_region_memory_base_pfn(reg))
+ register_nosave_region(memblock_region_memory_end_pfn(prev),
+ memblock_region_memory_base_pfn(reg));
+ prev = reg;
}
-
return 0;
}
@@ -327,7 +301,7 @@ void __init mem_init(void)
swiotlb_init(1);
#endif
- num_physpages = memblock.memory.size >> PAGE_SHIFT;
+ num_physpages = memblock_phys_mem_size() >> PAGE_SHIFT;
high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
#ifdef CONFIG_NEED_MULTIPLE_NODES
diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c
index ddfd7ad4e1d6..5ce99848d91e 100644
--- a/arch/powerpc/mm/mmu_context_nohash.c
+++ b/arch/powerpc/mm/mmu_context_nohash.c
@@ -334,7 +334,7 @@ static int __cpuinit mmu_context_cpu_notify(struct notifier_block *self,
/* We don't touch CPU 0 map, it's allocated at aboot and kept
* around forever
*/
- if (cpu == 0)
+ if (cpu == boot_cpuid)
return NOTIFY_OK;
switch (action) {
@@ -420,9 +420,11 @@ void __init mmu_context_init(void)
*/
context_map = alloc_bootmem(CTX_MAP_SIZE);
context_mm = alloc_bootmem(sizeof(void *) * (last_context + 1));
+#ifndef CONFIG_SMP
stale_map[0] = alloc_bootmem(CTX_MAP_SIZE);
+#else
+ stale_map[boot_cpuid] = alloc_bootmem(CTX_MAP_SIZE);
-#ifdef CONFIG_SMP
register_cpu_notifier(&mmu_context_cpu_nb);
#endif
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index 63b84a0d3b10..dd0a2589591d 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -140,10 +140,13 @@ extern void wii_memory_fixups(void);
extern void MMU_init_hw(void);
extern unsigned long mmu_mapin_ram(unsigned long top);
-#elif defined(CONFIG_FSL_BOOKE)
+#elif defined(CONFIG_PPC_FSL_BOOK3E)
+extern unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx);
+#ifdef CONFIG_PPC32
extern void MMU_init_hw(void);
extern unsigned long mmu_mapin_ram(unsigned long top);
extern void adjust_total_lowmem(void);
+#endif
extern void loadcam_entry(unsigned int index);
struct tlbcam {
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 002878ccf90b..74505b245374 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -802,16 +802,17 @@ static void __init setup_nonnuma(void)
unsigned long top_of_ram = memblock_end_of_DRAM();
unsigned long total_ram = memblock_phys_mem_size();
unsigned long start_pfn, end_pfn;
- unsigned int i, nid = 0;
+ unsigned int nid = 0;
+ struct memblock_region *reg;
printk(KERN_DEBUG "Top of RAM: 0x%lx, Total RAM: 0x%lx\n",
top_of_ram, total_ram);
printk(KERN_DEBUG "Memory hole size: %ldMB\n",
(top_of_ram - total_ram) >> 20);
- for (i = 0; i < memblock.memory.cnt; ++i) {
- start_pfn = memblock.memory.region[i].base >> PAGE_SHIFT;
- end_pfn = start_pfn + memblock_size_pages(&memblock.memory, i);
+ for_each_memblock(memory, reg) {
+ start_pfn = memblock_region_memory_base_pfn(reg);
+ end_pfn = memblock_region_memory_end_pfn(reg);
fake_numa_create_new_node(end_pfn, &nid);
add_active_range(nid, start_pfn, end_pfn);
@@ -947,11 +948,11 @@ static struct notifier_block __cpuinitdata ppc64_numa_nb = {
static void mark_reserved_regions_for_nid(int nid)
{
struct pglist_data *node = NODE_DATA(nid);
- int i;
+ struct memblock_region *reg;
- for (i = 0; i < memblock.reserved.cnt; i++) {
- unsigned long physbase = memblock.reserved.region[i].base;
- unsigned long size = memblock.reserved.region[i].size;
+ for_each_memblock(reserved, reg) {
+ unsigned long physbase = reg->base;
+ unsigned long size = reg->size;
unsigned long start_pfn = physbase >> PAGE_SHIFT;
unsigned long end_pfn = PFN_UP(physbase + size);
struct node_active_region node_ar;
diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c
index f8a01829d64f..11571e118831 100644
--- a/arch/powerpc/mm/ppc_mmu_32.c
+++ b/arch/powerpc/mm/ppc_mmu_32.c
@@ -223,8 +223,7 @@ void __init MMU_init_hw(void)
* Find some memory for the hash table.
*/
if ( ppc_md.progress ) ppc_md.progress("hash:find piece", 0x322);
- Hash = __va(memblock_alloc_base(Hash_size, Hash_size,
- __initial_memory_limit_addr));
+ Hash = __va(memblock_alloc(Hash_size, Hash_size));
cacheable_memzero(Hash, Hash_size);
_SDR1 = __pa(Hash) | SDR1_LOW_BITS;
@@ -272,3 +271,18 @@ void __init MMU_init_hw(void)
if ( ppc_md.progress ) ppc_md.progress("hash:done", 0x205);
}
+
+void setup_initial_memory_limit(phys_addr_t first_memblock_base,
+ phys_addr_t first_memblock_size)
+{
+ /* We don't currently support the first MEMBLOCK not mapping 0
+ * physical on those processors
+ */
+ BUG_ON(first_memblock_base != 0);
+
+ /* 601 can only access 16MB at the moment */
+ if (PVR_VER(mfspr(SPRN_PVR)) == 1)
+ memblock_set_current_limit(min_t(u64, first_memblock_size, 0x01000000));
+ else /* Anything else has 256M mapped */
+ memblock_set_current_limit(min_t(u64, first_memblock_size, 0x10000000));
+}
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c
index fe391e942521..36c0c449a899 100644
--- a/arch/powerpc/mm/tlb_nohash.c
+++ b/arch/powerpc/mm/tlb_nohash.c
@@ -349,11 +349,47 @@ void tlb_flush_pgtable(struct mmu_gather *tlb, unsigned long address)
static void setup_page_sizes(void)
{
- unsigned int tlb0cfg = mfspr(SPRN_TLB0CFG);
- unsigned int tlb0ps = mfspr(SPRN_TLB0PS);
- unsigned int eptcfg = mfspr(SPRN_EPTCFG);
+ unsigned int tlb0cfg;
+ unsigned int tlb0ps;
+ unsigned int eptcfg;
int i, psize;
+#ifdef CONFIG_PPC_FSL_BOOK3E
+ unsigned int mmucfg = mfspr(SPRN_MMUCFG);
+
+ if (((mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V1) &&
+ (mmu_has_feature(MMU_FTR_TYPE_FSL_E))) {
+ unsigned int tlb1cfg = mfspr(SPRN_TLB1CFG);
+ unsigned int min_pg, max_pg;
+
+ min_pg = (tlb1cfg & TLBnCFG_MINSIZE) >> TLBnCFG_MINSIZE_SHIFT;
+ max_pg = (tlb1cfg & TLBnCFG_MAXSIZE) >> TLBnCFG_MAXSIZE_SHIFT;
+
+ for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
+ struct mmu_psize_def *def;
+ unsigned int shift;
+
+ def = &mmu_psize_defs[psize];
+ shift = def->shift;
+
+ if (shift == 0)
+ continue;
+
+ /* adjust to be in terms of 4^shift Kb */
+ shift = (shift - 10) >> 1;
+
+ if ((shift >= min_pg) && (shift <= max_pg))
+ def->flags |= MMU_PAGE_SIZE_DIRECT;
+ }
+
+ goto no_indirect;
+ }
+#endif
+
+ tlb0cfg = mfspr(SPRN_TLB0CFG);
+ tlb0ps = mfspr(SPRN_TLB0PS);
+ eptcfg = mfspr(SPRN_EPTCFG);
+
/* Look for supported direct sizes */
for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
struct mmu_psize_def *def = &mmu_psize_defs[psize];
@@ -505,10 +541,26 @@ static void __early_init_mmu(int boot_cpu)
*/
linear_map_top = memblock_end_of_DRAM();
+#ifdef CONFIG_PPC_FSL_BOOK3E
+ if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
+ unsigned int num_cams;
+
+ /* use a quarter of the TLBCAM for bolted linear map */
+ num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4;
+ linear_map_top = map_mem_in_cams(linear_map_top, num_cams);
+
+ /* limit memory so we dont have linear faults */
+ memblock_enforce_memory_limit(linear_map_top);
+ memblock_analyze();
+ }
+#endif
+
/* A sync won't hurt us after mucking around with
* the MMU configuration
*/
mb();
+
+ memblock_set_current_limit(linear_map_top);
}
void __init early_init_mmu(void)
@@ -521,4 +573,18 @@ void __cpuinit early_init_mmu_secondary(void)
__early_init_mmu(0);
}
+void setup_initial_memory_limit(phys_addr_t first_memblock_base,
+ phys_addr_t first_memblock_size)
+{
+ /* On Embedded 64-bit, we adjust the RMA size to match
+ * the bolted TLB entry. We know for now that only 1G
+ * entries are supported though that may eventually
+ * change. We crop it to the size of the first MEMBLOCK to
+ * avoid going over total available memory just in case...
+ */
+ ppc64_rma_size = min_t(u64, first_memblock_size, 0x40000000);
+
+ /* Finally limit subsequent allocations */
+ memblock_set_current_limit(ppc64_memblock_base + ppc64_rma_size);
+}
#endif /* CONFIG_PPC64 */
diff --git a/arch/powerpc/mm/tlb_nohash_low.S b/arch/powerpc/mm/tlb_nohash_low.S
index b9d9fed8f36e..af405eefe48d 100644
--- a/arch/powerpc/mm/tlb_nohash_low.S
+++ b/arch/powerpc/mm/tlb_nohash_low.S
@@ -367,7 +367,7 @@ _GLOBAL(set_context)
#error Unsupported processor type !
#endif
-#if defined(CONFIG_FSL_BOOKE)
+#if defined(CONFIG_PPC_FSL_BOOK3E)
/*
* extern void loadcam_entry(unsigned int index)
*
diff --git a/arch/powerpc/oprofile/Makefile b/arch/powerpc/oprofile/Makefile
index e219ca43962d..73456c4cec28 100644
--- a/arch/powerpc/oprofile/Makefile
+++ b/arch/powerpc/oprofile/Makefile
@@ -1,8 +1,6 @@
subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
-ifeq ($(CONFIG_PPC64),y)
-EXTRA_CFLAGS += -mno-minimal-toc
-endif
+ccflags-$(CONFIG_PPC64) := -mno-minimal-toc
obj-$(CONFIG_OPROFILE) += oprofile.o
diff --git a/arch/powerpc/oprofile/backtrace.c b/arch/powerpc/oprofile/backtrace.c
index b4278cfd1f80..f75301f2c85f 100644
--- a/arch/powerpc/oprofile/backtrace.c
+++ b/arch/powerpc/oprofile/backtrace.c
@@ -105,7 +105,7 @@ void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth)
}
} else {
#ifdef CONFIG_PPC64
- if (!test_thread_flag(TIF_32BIT)) {
+ if (!is_32bit_task()) {
while (depth--) {
sp = user_getsp64(sp, first_frame);
if (!sp)
diff --git a/arch/powerpc/oprofile/op_model_fsl_emb.c b/arch/powerpc/oprofile/op_model_fsl_emb.c
index 62312abffa28..d4e6507277b5 100644
--- a/arch/powerpc/oprofile/op_model_fsl_emb.c
+++ b/arch/powerpc/oprofile/op_model_fsl_emb.c
@@ -2,7 +2,7 @@
* Freescale Embedded oprofile support, based on ppc64 oprofile support
* Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
*
- * Copyright (c) 2004 Freescale Semiconductor, Inc
+ * Copyright (c) 2004, 2010 Freescale Semiconductor, Inc
*
* Author: Andy Fleming
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
@@ -321,9 +321,6 @@ static void fsl_emb_handle_interrupt(struct pt_regs *regs,
int val;
int i;
- /* set the PMM bit (see comment below) */
- mtmsr(mfmsr() | MSR_PMM);
-
pc = regs->nip;
is_kernel = is_kernel_addr(pc);
@@ -340,9 +337,13 @@ static void fsl_emb_handle_interrupt(struct pt_regs *regs,
}
/* The freeze bit was set by the interrupt. */
- /* Clear the freeze bit, and reenable the interrupt.
- * The counters won't actually start until the rfi clears
- * the PMM bit */
+ /* Clear the freeze bit, and reenable the interrupt. The
+ * counters won't actually start until the rfi clears the PMM
+ * bit. The PMM bit should not be set until after the interrupt
+ * is cleared to avoid it getting lost in some hypervisor
+ * environments.
+ */
+ mtmsr(mfmsr() | MSR_PMM);
pmc_start_ctrs(1);
}
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig
index 69d668c072ae..0f979c5c756b 100644
--- a/arch/powerpc/platforms/44x/Kconfig
+++ b/arch/powerpc/platforms/44x/Kconfig
@@ -17,6 +17,16 @@ config BAMBOO
help
This option enables support for the IBM PPC440EP evaluation board.
+config BLUESTONE
+ bool "Bluestone"
+ depends on 44x
+ default n
+ select PPC44x_SIMPLE
+ select APM821xx
+ select IBM_NEW_EMAC_RGMII
+ help
+ This option enables support for the APM APM821xx Evaluation board.
+
config EBONY
bool "Ebony"
depends on 44x
@@ -293,6 +303,12 @@ config 460SX
select IBM_NEW_EMAC_ZMII
select IBM_NEW_EMAC_TAH
+config APM821xx
+ bool
+ select PPC_FPU
+ select IBM_NEW_EMAC_EMAC4
+ select IBM_NEW_EMAC_TAH
+
# 44x errata/workaround config symbols, selected by the CPU models above
config IBM440EP_ERR42
bool
diff --git a/arch/powerpc/platforms/44x/ppc44x_simple.c b/arch/powerpc/platforms/44x/ppc44x_simple.c
index 5f7a29d7f590..7ddcba3b9397 100644
--- a/arch/powerpc/platforms/44x/ppc44x_simple.c
+++ b/arch/powerpc/platforms/44x/ppc44x_simple.c
@@ -52,6 +52,7 @@ machine_device_initcall(ppc44x_simple, ppc44x_device_probe);
static char *board[] __initdata = {
"amcc,arches",
"amcc,bamboo",
+ "amcc,bluestone",
"amcc,canyonlands",
"amcc,glacier",
"ibm,ebony",
diff --git a/arch/powerpc/platforms/512x/clock.c b/arch/powerpc/platforms/512x/clock.c
index 5b243bd3eb3b..3dc2a8d262b8 100644
--- a/arch/powerpc/platforms/512x/clock.c
+++ b/arch/powerpc/platforms/512x/clock.c
@@ -57,7 +57,7 @@ static struct clk *mpc5121_clk_get(struct device *dev, const char *id)
int id_match = 0;
if (dev == NULL || id == NULL)
- return NULL;
+ return clk;
mutex_lock(&clocks_mutex);
list_for_each_entry(p, &clocks, node) {
diff --git a/arch/powerpc/platforms/52xx/efika.c b/arch/powerpc/platforms/52xx/efika.c
index 45c0cb9b67e6..18c104820198 100644
--- a/arch/powerpc/platforms/52xx/efika.c
+++ b/arch/powerpc/platforms/52xx/efika.c
@@ -99,7 +99,7 @@ static void __init efika_pcisetup(void)
if (bus_range == NULL || len < 2 * sizeof(int)) {
printk(KERN_WARNING EFIKA_PLATFORM_NAME
": Can't get bus-range for %s\n", pcictrl->full_name);
- return;
+ goto out_put;
}
if (bus_range[1] == bus_range[0])
@@ -111,12 +111,12 @@ static void __init efika_pcisetup(void)
printk(" controlled by %s\n", pcictrl->full_name);
printk("\n");
- hose = pcibios_alloc_controller(of_node_get(pcictrl));
+ hose = pcibios_alloc_controller(pcictrl);
if (!hose) {
printk(KERN_WARNING EFIKA_PLATFORM_NAME
": Can't allocate PCI controller structure for %s\n",
pcictrl->full_name);
- return;
+ goto out_put;
}
hose->first_busno = bus_range[0];
@@ -124,6 +124,9 @@ static void __init efika_pcisetup(void)
hose->ops = &rtas_pci_ops;
pci_process_bridge_OF_ranges(hose, pcictrl, 0);
+ return;
+out_put:
+ of_node_put(pcictrl);
}
#else
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c
index 6e905314ad5d..41f3a7eda1de 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_common.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c
@@ -325,12 +325,16 @@ int mpc5200_psc_ac97_gpio_reset(int psc_number)
clrbits32(&simple_gpio->simple_dvo, sync | out);
clrbits8(&wkup_gpio->wkup_dvo, reset);
- /* wait at lease 1 us */
- udelay(2);
+ /* wait for 1 us */
+ udelay(1);
/* Deassert reset */
setbits8(&wkup_gpio->wkup_dvo, reset);
+ /* wait at least 200ns */
+ /* 7 ~= (200ns * timebase) / ns2sec */
+ __delay(7);
+
/* Restore pin-muxing */
out_be32(&simple_gpio->port_config, mux);
diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig
index 021763a32c2f..73f4135f3a1a 100644
--- a/arch/powerpc/platforms/83xx/Kconfig
+++ b/arch/powerpc/platforms/83xx/Kconfig
@@ -10,12 +10,12 @@ menuconfig PPC_83xx
if PPC_83xx
config MPC830x_RDB
- bool "Freescale MPC830x RDB"
+ bool "Freescale MPC830x RDB and derivatives"
select DEFAULT_UIMAGE
select PPC_MPC831x
select FSL_GTM
help
- This option enables support for the MPC8308 RDB board.
+ This option enables support for the MPC8308 RDB and MPC8308 P1M boards.
config MPC831x_RDB
bool "Freescale MPC831x RDB"
diff --git a/arch/powerpc/platforms/83xx/mpc830x_rdb.c b/arch/powerpc/platforms/83xx/mpc830x_rdb.c
index ac102ee9abe8..846831d495b5 100644
--- a/arch/powerpc/platforms/83xx/mpc830x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc830x_rdb.c
@@ -65,7 +65,8 @@ static int __init mpc830x_rdb_probe(void)
unsigned long root = of_get_flat_dt_root();
return of_flat_dt_is_compatible(root, "MPC8308RDB") ||
- of_flat_dt_is_compatible(root, "fsl,mpc8308rdb");
+ of_flat_dt_is_compatible(root, "fsl,mpc8308rdb") ||
+ of_flat_dt_is_compatible(root, "denx,mpc8308_p1m");
}
static struct of_device_id __initdata of_bus_ids[] = {
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index bea1f5905ad4..b6976e1726e4 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -11,6 +11,8 @@ menuconfig FSL_SOC_BOOKE
if FSL_SOC_BOOKE
+if PPC32
+
config MPC8540_ADS
bool "Freescale MPC8540 ADS"
select DEFAULT_UIMAGE
@@ -153,10 +155,20 @@ config SBC8560
help
This option enables support for the Wind River SBC8560 board
+config P3041_DS
+ bool "Freescale P3041 DS"
+ select DEFAULT_UIMAGE
+ select PPC_E500MC
+ select PHYS_64BIT
+ select SWIOTLB
+ select MPC8xxx_GPIO
+ select HAS_RAPIDIO
+ help
+ This option enables support for the P3041 DS board
+
config P4080_DS
bool "Freescale P4080 DS"
select DEFAULT_UIMAGE
- select PPC_FSL_BOOK3E
select PPC_E500MC
select PHYS_64BIT
select SWIOTLB
@@ -165,6 +177,20 @@ config P4080_DS
help
This option enables support for the P4080 DS board
+endif # PPC32
+
+config P5020_DS
+ bool "Freescale P5020 DS"
+ select DEFAULT_UIMAGE
+ select E500
+ select PPC_E500MC
+ select PHYS_64BIT
+ select SWIOTLB
+ select MPC8xxx_GPIO
+ select HAS_RAPIDIO
+ help
+ This option enables support for the P5020 DS board
+
endif # FSL_SOC_BOOKE
config TQM85xx
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile
index a2ec3f8f4d06..dd70db77d63e 100644
--- a/arch/powerpc/platforms/85xx/Makefile
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -11,7 +11,9 @@ obj-$(CONFIG_MPC85xx_DS) += mpc85xx_ds.o
obj-$(CONFIG_MPC85xx_MDS) += mpc85xx_mds.o
obj-$(CONFIG_MPC85xx_RDB) += mpc85xx_rdb.o
obj-$(CONFIG_P1022_DS) += p1022_ds.o
+obj-$(CONFIG_P3041_DS) += p3041_ds.o corenet_ds.o
obj-$(CONFIG_P4080_DS) += p4080_ds.o corenet_ds.o
+obj-$(CONFIG_P5020_DS) += p5020_ds.o corenet_ds.o
obj-$(CONFIG_STX_GP3) += stx_gp3.o
obj-$(CONFIG_TQM85xx) += tqm85xx.o
obj-$(CONFIG_SBC8560) += sbc8560.o
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c
index 34e00902ce86..2b390d19a1d1 100644
--- a/arch/powerpc/platforms/85xx/p1022_ds.c
+++ b/arch/powerpc/platforms/85xx/p1022_ds.c
@@ -112,6 +112,8 @@ static struct of_device_id __initdata p1022_ds_ids[] = {
{ .compatible = "soc", },
{ .compatible = "simple-bus", },
{ .compatible = "gianfar", },
+ /* So that the DMA channel nodes can be probed individually: */
+ { .compatible = "fsl,eloplus-dma", },
{},
};
diff --git a/arch/powerpc/platforms/85xx/p3041_ds.c b/arch/powerpc/platforms/85xx/p3041_ds.c
new file mode 100644
index 000000000000..0ed52e18298c
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/p3041_ds.c
@@ -0,0 +1,64 @@
+/*
+ * P3041 DS Setup
+ *
+ * Maintained by Kumar Gala (see MAINTAINERS for contact information)
+ *
+ * Copyright 2009-2010 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/phy.h>
+
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <mm/mmu_decl.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <asm/mpic.h>
+
+#include <linux/of_platform.h>
+#include <sysdev/fsl_soc.h>
+#include <sysdev/fsl_pci.h>
+
+#include "corenet_ds.h"
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init p3041_ds_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ return of_flat_dt_is_compatible(root, "fsl,P3041DS");
+}
+
+define_machine(p3041_ds) {
+ .name = "P3041 DS",
+ .probe = p3041_ds_probe,
+ .setup_arch = corenet_ds_setup_arch,
+ .init_IRQ = corenet_ds_pic_init,
+#ifdef CONFIG_PCI
+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
+#endif
+ .get_irq = mpic_get_coreint_irq,
+ .restart = fsl_rstcr_restart,
+ .calibrate_decr = generic_calibrate_decr,
+ .progress = udbg_progress,
+};
+
+machine_device_initcall(p3041_ds, corenet_ds_publish_devices);
+
+#ifdef CONFIG_SWIOTLB
+machine_arch_initcall(p3041_ds, swiotlb_setup_bus_notifier);
+#endif
diff --git a/arch/powerpc/platforms/85xx/p5020_ds.c b/arch/powerpc/platforms/85xx/p5020_ds.c
new file mode 100644
index 000000000000..7467b712ee00
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/p5020_ds.c
@@ -0,0 +1,69 @@
+/*
+ * P5020 DS Setup
+ *
+ * Maintained by Kumar Gala (see MAINTAINERS for contact information)
+ *
+ * Copyright 2009-2010 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/phy.h>
+
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <mm/mmu_decl.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <asm/mpic.h>
+
+#include <linux/of_platform.h>
+#include <sysdev/fsl_soc.h>
+#include <sysdev/fsl_pci.h>
+
+#include "corenet_ds.h"
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init p5020_ds_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ return of_flat_dt_is_compatible(root, "fsl,P5020DS");
+}
+
+define_machine(p5020_ds) {
+ .name = "P5020 DS",
+ .probe = p5020_ds_probe,
+ .setup_arch = corenet_ds_setup_arch,
+ .init_IRQ = corenet_ds_pic_init,
+#ifdef CONFIG_PCI
+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
+#endif
+/* coreint doesn't play nice with lazy EE, use legacy mpic for now */
+#ifdef CONFIG_PPC64
+ .get_irq = mpic_get_irq,
+#else
+ .get_irq = mpic_get_coreint_irq,
+#endif
+ .restart = fsl_rstcr_restart,
+ .calibrate_decr = generic_calibrate_decr,
+ .progress = udbg_progress,
+};
+
+machine_device_initcall(p5020_ds, corenet_ds_publish_devices);
+
+#ifdef CONFIG_SWIOTLB
+machine_arch_initcall(p5020_ds, swiotlb_setup_bus_notifier);
+#endif
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
index a6b106557be4..5c91a992f02b 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -16,6 +16,7 @@
#include <linux/delay.h>
#include <linux/of.h>
#include <linux/kexec.h>
+#include <linux/highmem.h>
#include <asm/machdep.h>
#include <asm/pgtable.h>
@@ -79,6 +80,7 @@ smp_85xx_kick_cpu(int nr)
local_irq_save(flags);
out_be32(bptr_vaddr + BOOT_ENTRY_PIR, nr);
+#ifdef CONFIG_PPC32
out_be32(bptr_vaddr + BOOT_ENTRY_ADDR_LOWER, __pa(__early_start));
if (!ioremappable)
@@ -88,6 +90,12 @@ smp_85xx_kick_cpu(int nr)
/* Wait a bit for the CPU to ack. */
while ((__secondary_hold_acknowledge != nr) && (++n < 1000))
mdelay(1);
+#else
+ out_be64((u64 *)(bptr_vaddr + BOOT_ENTRY_ADDR_UPPER),
+ __pa((u64)*((unsigned long long *) generic_secondary_smp_init)));
+
+ smp_generic_kick_cpu(nr);
+#endif
local_irq_restore(flags);
@@ -114,19 +122,15 @@ struct smp_ops_t smp_85xx_ops = {
};
#ifdef CONFIG_KEXEC
-static int kexec_down_cpus = 0;
+atomic_t kexec_down_cpus = ATOMIC_INIT(0);
void mpc85xx_smp_kexec_cpu_down(int crash_shutdown, int secondary)
{
- mpic_teardown_this_cpu(1);
-
- /* When crashing, this gets called on all CPU's we only
- * take down the non-boot cpus */
- if (smp_processor_id() != boot_cpuid)
- {
- local_irq_disable();
- kexec_down_cpus++;
+ local_irq_disable();
+ if (secondary) {
+ atomic_inc(&kexec_down_cpus);
+ /* loop forever */
while (1);
}
}
@@ -137,16 +141,65 @@ static void mpc85xx_smp_kexec_down(void *arg)
ppc_md.kexec_cpu_down(0,1);
}
-static void mpc85xx_smp_machine_kexec(struct kimage *image)
+static void map_and_flush(unsigned long paddr)
{
- int timeout = 2000;
+ struct page *page = pfn_to_page(paddr >> PAGE_SHIFT);
+ unsigned long kaddr = (unsigned long)kmap(page);
+
+ flush_dcache_range(kaddr, kaddr + PAGE_SIZE);
+ kunmap(page);
+}
+
+/**
+ * Before we reset the other cores, we need to flush relevant cache
+ * out to memory so we don't get anything corrupted, some of these flushes
+ * are performed out of an overabundance of caution as interrupts are not
+ * disabled yet and we can switch cores
+ */
+static void mpc85xx_smp_flush_dcache_kexec(struct kimage *image)
+{
+ kimage_entry_t *ptr, entry;
+ unsigned long paddr;
int i;
- set_cpus_allowed(current, cpumask_of_cpu(boot_cpuid));
+ if (image->type == KEXEC_TYPE_DEFAULT) {
+ /* normal kexec images are stored in temporary pages */
+ for (ptr = &image->head; (entry = *ptr) && !(entry & IND_DONE);
+ ptr = (entry & IND_INDIRECTION) ?
+ phys_to_virt(entry & PAGE_MASK) : ptr + 1) {
+ if (!(entry & IND_DESTINATION)) {
+ map_and_flush(entry);
+ }
+ }
+ /* flush out last IND_DONE page */
+ map_and_flush(entry);
+ } else {
+ /* crash type kexec images are copied to the crash region */
+ for (i = 0; i < image->nr_segments; i++) {
+ struct kexec_segment *seg = &image->segment[i];
+ for (paddr = seg->mem; paddr < seg->mem + seg->memsz;
+ paddr += PAGE_SIZE) {
+ map_and_flush(paddr);
+ }
+ }
+ }
+
+ /* also flush the kimage struct to be passed in as well */
+ flush_dcache_range((unsigned long)image,
+ (unsigned long)image + sizeof(*image));
+}
+
+static void mpc85xx_smp_machine_kexec(struct kimage *image)
+{
+ int timeout = INT_MAX;
+ int i, num_cpus = num_present_cpus();
+
+ mpc85xx_smp_flush_dcache_kexec(image);
- smp_call_function(mpc85xx_smp_kexec_down, NULL, 0);
+ if (image->type == KEXEC_TYPE_DEFAULT)
+ smp_call_function(mpc85xx_smp_kexec_down, NULL, 0);
- while ( (kexec_down_cpus != (num_online_cpus() - 1)) &&
+ while ( (atomic_read(&kexec_down_cpus) != (num_cpus - 1)) &&
( timeout > 0 ) )
{
timeout--;
@@ -155,7 +208,7 @@ static void mpc85xx_smp_machine_kexec(struct kimage *image)
if ( !timeout )
printk(KERN_ERR "Unable to bring down secondary cpu(s)");
- for (i = 0; i < num_present_cpus(); i++)
+ for (i = 0; i < num_cpus; i++)
{
if ( i == smp_processor_id() ) continue;
mpic_reset_core(i);
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index 81c9208025fa..956154f32cfe 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -21,6 +21,16 @@ source "arch/powerpc/platforms/44x/Kconfig"
source "arch/powerpc/platforms/40x/Kconfig"
source "arch/powerpc/platforms/amigaone/Kconfig"
+config KVM_GUEST
+ bool "KVM Guest support"
+ default y
+ ---help---
+ This option enables various optimizations for running under the KVM
+ hypervisor. Overhead for the kernel when not running inside KVM should
+ be minimal.
+
+ In case of doubt, say Y
+
config PPC_NATIVE
bool
depends on 6xx || PPC64
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index d361f8119b1e..111138c55f9c 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -125,6 +125,7 @@ config 8xx
config E500
select FSL_EMB_PERFMON
+ select PPC_FSL_BOOK3E
bool
config PPC_E500MC
@@ -166,9 +167,14 @@ config BOOKE
config FSL_BOOKE
bool
- depends on E200 || E500
+ depends on (E200 || E500) && PPC32
default y
+# this is for common code between PPC32 & PPC64 FSL BOOKE
+config PPC_FSL_BOOK3E
+ bool
+ select FSL_EMB_PERFMON
+ default y if FSL_BOOKE
config PTE_64BIT
bool
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index 97085530aa63..e3e379c6caa7 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -310,9 +310,9 @@ static void axon_msi_teardown_msi_irqs(struct pci_dev *dev)
}
static struct irq_chip msic_irq_chip = {
- .mask = mask_msi_irq,
- .unmask = unmask_msi_irq,
- .shutdown = unmask_msi_irq,
+ .irq_mask = mask_msi_irq,
+ .irq_unmask = unmask_msi_irq,
+ .irq_shutdown = mask_msi_irq,
.name = "AXON-MSI",
};
diff --git a/arch/powerpc/platforms/cell/ras.c b/arch/powerpc/platforms/cell/ras.c
index 1d3c4effea10..5ec1e47a0d77 100644
--- a/arch/powerpc/platforms/cell/ras.c
+++ b/arch/powerpc/platforms/cell/ras.c
@@ -173,8 +173,10 @@ static int __init cbe_ptcal_enable(void)
return -ENODEV;
size = of_get_property(np, "ibm,cbe-ptcal-size", NULL);
- if (!size)
+ if (!size) {
+ of_node_put(np);
return -ENODEV;
+ }
pr_debug("%s: enabling PTCAL, size = 0x%x\n", __func__, *size);
order = get_order(*size);
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index 5876e888e412..3f2e557344a3 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -258,8 +258,10 @@ static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
return NO_IRQ;
imap += intsize + 1;
tmp = of_get_property(iic, "#interrupt-cells", NULL);
- if (tmp == NULL)
+ if (tmp == NULL) {
+ of_node_put(iic);
return NO_IRQ;
+ }
intsize = *tmp;
/* Assume unit is last entry of interrupt specifier */
unit = imap[intsize - 1];
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 1a40da92154c..02f7b113a31b 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -154,6 +154,7 @@ static const struct file_operations __fops = { \
.release = spufs_attr_release, \
.read = spufs_attr_read, \
.write = spufs_attr_write, \
+ .llseek = generic_file_llseek, \
};
@@ -521,6 +522,7 @@ static const struct file_operations spufs_cntl_fops = {
.release = spufs_cntl_release,
.read = simple_attr_read,
.write = simple_attr_write,
+ .llseek = generic_file_llseek,
.mmap = spufs_cntl_mmap,
};
@@ -714,6 +716,7 @@ static ssize_t spufs_mbox_read(struct file *file, char __user *buf,
static const struct file_operations spufs_mbox_fops = {
.open = spufs_pipe_open,
.read = spufs_mbox_read,
+ .llseek = no_llseek,
};
static ssize_t spufs_mbox_stat_read(struct file *file, char __user *buf,
@@ -743,6 +746,7 @@ static ssize_t spufs_mbox_stat_read(struct file *file, char __user *buf,
static const struct file_operations spufs_mbox_stat_fops = {
.open = spufs_pipe_open,
.read = spufs_mbox_stat_read,
+ .llseek = no_llseek,
};
/* low-level ibox access function */
@@ -863,6 +867,7 @@ static const struct file_operations spufs_ibox_fops = {
.read = spufs_ibox_read,
.poll = spufs_ibox_poll,
.fasync = spufs_ibox_fasync,
+ .llseek = no_llseek,
};
static ssize_t spufs_ibox_stat_read(struct file *file, char __user *buf,
@@ -890,6 +895,7 @@ static ssize_t spufs_ibox_stat_read(struct file *file, char __user *buf,
static const struct file_operations spufs_ibox_stat_fops = {
.open = spufs_pipe_open,
.read = spufs_ibox_stat_read,
+ .llseek = no_llseek,
};
/* low-level mailbox write */
@@ -1011,6 +1017,7 @@ static const struct file_operations spufs_wbox_fops = {
.write = spufs_wbox_write,
.poll = spufs_wbox_poll,
.fasync = spufs_wbox_fasync,
+ .llseek = no_llseek,
};
static ssize_t spufs_wbox_stat_read(struct file *file, char __user *buf,
@@ -1038,6 +1045,7 @@ static ssize_t spufs_wbox_stat_read(struct file *file, char __user *buf,
static const struct file_operations spufs_wbox_stat_fops = {
.open = spufs_pipe_open,
.read = spufs_wbox_stat_read,
+ .llseek = no_llseek,
};
static int spufs_signal1_open(struct inode *inode, struct file *file)
@@ -1166,6 +1174,7 @@ static const struct file_operations spufs_signal1_fops = {
.read = spufs_signal1_read,
.write = spufs_signal1_write,
.mmap = spufs_signal1_mmap,
+ .llseek = no_llseek,
};
static const struct file_operations spufs_signal1_nosched_fops = {
@@ -1173,6 +1182,7 @@ static const struct file_operations spufs_signal1_nosched_fops = {
.release = spufs_signal1_release,
.write = spufs_signal1_write,
.mmap = spufs_signal1_mmap,
+ .llseek = no_llseek,
};
static int spufs_signal2_open(struct inode *inode, struct file *file)
@@ -1305,6 +1315,7 @@ static const struct file_operations spufs_signal2_fops = {
.read = spufs_signal2_read,
.write = spufs_signal2_write,
.mmap = spufs_signal2_mmap,
+ .llseek = no_llseek,
};
static const struct file_operations spufs_signal2_nosched_fops = {
@@ -1312,6 +1323,7 @@ static const struct file_operations spufs_signal2_nosched_fops = {
.release = spufs_signal2_release,
.write = spufs_signal2_write,
.mmap = spufs_signal2_mmap,
+ .llseek = no_llseek,
};
/*
@@ -1451,6 +1463,7 @@ static const struct file_operations spufs_mss_fops = {
.open = spufs_mss_open,
.release = spufs_mss_release,
.mmap = spufs_mss_mmap,
+ .llseek = no_llseek,
};
static int
@@ -1508,6 +1521,7 @@ static const struct file_operations spufs_psmap_fops = {
.open = spufs_psmap_open,
.release = spufs_psmap_release,
.mmap = spufs_psmap_mmap,
+ .llseek = no_llseek,
};
@@ -1871,6 +1885,7 @@ static const struct file_operations spufs_mfc_fops = {
.fsync = spufs_mfc_fsync,
.fasync = spufs_mfc_fasync,
.mmap = spufs_mfc_mmap,
+ .llseek = no_llseek,
};
static int spufs_npc_set(void *data, u64 val)
@@ -2246,6 +2261,7 @@ static ssize_t spufs_dma_info_read(struct file *file, char __user *buf,
static const struct file_operations spufs_dma_info_fops = {
.open = spufs_info_open,
.read = spufs_dma_info_read,
+ .llseek = no_llseek,
};
static ssize_t __spufs_proxydma_info_read(struct spu_context *ctx,
@@ -2299,6 +2315,7 @@ static ssize_t spufs_proxydma_info_read(struct file *file, char __user *buf,
static const struct file_operations spufs_proxydma_info_fops = {
.open = spufs_info_open,
.read = spufs_proxydma_info_read,
+ .llseek = no_llseek,
};
static int spufs_show_tid(struct seq_file *s, void *private)
@@ -2585,6 +2602,7 @@ static const struct file_operations spufs_switch_log_fops = {
.read = spufs_switch_log_read,
.poll = spufs_switch_log_poll,
.release = spufs_switch_log_release,
+ .llseek = no_llseek,
};
/**
diff --git a/arch/powerpc/platforms/chrp/nvram.c b/arch/powerpc/platforms/chrp/nvram.c
index ba3588f2d8e0..d3ceff04ffc7 100644
--- a/arch/powerpc/platforms/chrp/nvram.c
+++ b/arch/powerpc/platforms/chrp/nvram.c
@@ -74,8 +74,10 @@ void __init chrp_nvram_init(void)
return;
nbytes_p = of_get_property(nvram, "#bytes", &proplen);
- if (nbytes_p == NULL || proplen != sizeof(unsigned int))
+ if (nbytes_p == NULL || proplen != sizeof(unsigned int)) {
+ of_node_put(nvram);
return;
+ }
nvram_size = *nbytes_p;
diff --git a/arch/powerpc/platforms/embedded6xx/wii.c b/arch/powerpc/platforms/embedded6xx/wii.c
index 5cdcc7c8d973..649473a729b8 100644
--- a/arch/powerpc/platforms/embedded6xx/wii.c
+++ b/arch/powerpc/platforms/embedded6xx/wii.c
@@ -65,7 +65,7 @@ static int __init page_aligned(unsigned long x)
void __init wii_memory_fixups(void)
{
- struct memblock_property *p = memblock.memory.region;
+ struct memblock_region *p = memblock.memory.regions;
/*
* This is part of a workaround to allow the use of two
diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile
index ce014928d460..a7602b11ed9d 100644
--- a/arch/powerpc/platforms/iseries/Makefile
+++ b/arch/powerpc/platforms/iseries/Makefile
@@ -1,4 +1,4 @@
-EXTRA_CFLAGS += -mno-minimal-toc
+ccflags-y := -mno-minimal-toc
obj-y += exception.o
obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o dt.o mf.o lpevents.o \
diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c
index 7f45a51fe793..fdb7384c0c4f 100644
--- a/arch/powerpc/platforms/iseries/dt.c
+++ b/arch/powerpc/platforms/iseries/dt.c
@@ -243,7 +243,7 @@ static void __init dt_cpus(struct iseries_flat_dt *dt)
pft_size[1] = __ilog2(HvCallHpt_getHptPages() * HW_PAGE_SIZE);
for (i = 0; i < NR_CPUS; i++) {
- if (lppaca[i].dyn_proc_status >= 2)
+ if (lppaca_of(i).dyn_proc_status >= 2)
continue;
snprintf(p, 32 - (p - buf), "@%d", i);
@@ -251,7 +251,7 @@ static void __init dt_cpus(struct iseries_flat_dt *dt)
dt_prop_str(dt, "device_type", device_type_cpu);
- index = lppaca[i].dyn_hv_phys_proc_index;
+ index = lppaca_of(i).dyn_hv_phys_proc_index;
d = &xIoHriProcessorVpd[index];
dt_prop_u32(dt, "i-cache-size", d->xInstCacheSize * 1024);
diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c
index 33e5fc7334fc..42d0a886de05 100644
--- a/arch/powerpc/platforms/iseries/mf.c
+++ b/arch/powerpc/platforms/iseries/mf.c
@@ -1249,6 +1249,7 @@ out:
static const struct file_operations proc_vmlinux_operations = {
.write = proc_mf_change_vmlinux,
+ .llseek = default_llseek,
};
static int __init mf_proc_init(void)
diff --git a/arch/powerpc/platforms/iseries/smp.c b/arch/powerpc/platforms/iseries/smp.c
index 6590850045af..6c6029914dbc 100644
--- a/arch/powerpc/platforms/iseries/smp.c
+++ b/arch/powerpc/platforms/iseries/smp.c
@@ -91,7 +91,7 @@ static void smp_iSeries_kick_cpu(int nr)
BUG_ON((nr < 0) || (nr >= NR_CPUS));
/* Verify that our partition has a processor nr */
- if (lppaca[nr].dyn_proc_status >= 2)
+ if (lppaca_of(nr).dyn_proc_status >= 2)
return;
/* The processor is currently spinning, waiting
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c
index 3fff8d979b41..fe34c3d9bb74 100644
--- a/arch/powerpc/platforms/maple/setup.c
+++ b/arch/powerpc/platforms/maple/setup.c
@@ -358,6 +358,7 @@ static int __init maple_cpc925_edac_setup(void)
model = (const unsigned char *)of_get_property(np, "model", NULL);
if (!model) {
printk(KERN_ERR "%s: Unabel to get model info\n", __func__);
+ of_node_put(np);
return -ENODEV;
}
diff --git a/arch/powerpc/platforms/powermac/pfunc_core.c b/arch/powerpc/platforms/powermac/pfunc_core.c
index cec635942657..b0c3777528a1 100644
--- a/arch/powerpc/platforms/powermac/pfunc_core.c
+++ b/arch/powerpc/platforms/powermac/pfunc_core.c
@@ -837,8 +837,10 @@ struct pmf_function *__pmf_find_function(struct device_node *target,
return NULL;
find_it:
dev = pmf_find_device(actor);
- if (dev == NULL)
- return NULL;
+ if (dev == NULL) {
+ result = NULL;
+ goto out;
+ }
list_for_each_entry(func, &dev->functions, link) {
if (name && strcmp(name, func->name))
@@ -850,8 +852,9 @@ struct pmf_function *__pmf_find_function(struct device_node *target,
result = func;
break;
}
- of_node_put(actor);
pmf_put_device(dev);
+out:
+ of_node_put(actor);
return result;
}
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index 046ace9c4381..59eb8bdaa79d 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -1,14 +1,9 @@
-ifeq ($(CONFIG_PPC64),y)
-EXTRA_CFLAGS += -mno-minimal-toc
-endif
-
-ifeq ($(CONFIG_PPC_PSERIES_DEBUG),y)
-EXTRA_CFLAGS += -DDEBUG
-endif
+ccflags-$(CONFIG_PPC64) := -mno-minimal-toc
+ccflags-$(CONFIG_PPC_PSERIES_DEBUG) += -DDEBUG
obj-y := lpar.o hvCall.o nvram.o reconfig.o \
setup.o iommu.o event_sources.o ras.o \
- firmware.o power.o dlpar.o
+ firmware.o power.o dlpar.o mobility.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_XICS) += xics.o
obj-$(CONFIG_SCANLOG) += scanlog.o
@@ -23,7 +18,7 @@ obj-$(CONFIG_MEMORY_HOTPLUG) += hotplug-memory.o
obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o
obj-$(CONFIG_HVCS) += hvcserver.o
obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o
-obj-$(CONFIG_PHYP_DUMP) += phyp_dump.o
+obj-$(CONFIG_PHYP_DUMP) += phyp_dump.o
obj-$(CONFIG_CMM) += cmm.o
obj-$(CONFIG_DTL) += dtl.o
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
index 72d8054fa739..b74a9230edc9 100644
--- a/arch/powerpc/platforms/pseries/dlpar.c
+++ b/arch/powerpc/platforms/pseries/dlpar.c
@@ -33,7 +33,7 @@ struct cc_workarea {
u32 prop_offset;
};
-static void dlpar_free_cc_property(struct property *prop)
+void dlpar_free_cc_property(struct property *prop)
{
kfree(prop->name);
kfree(prop->value);
@@ -55,13 +55,12 @@ static struct property *dlpar_parse_cc_property(struct cc_workarea *ccwa)
prop->length = ccwa->prop_length;
value = (char *)ccwa + ccwa->prop_offset;
- prop->value = kzalloc(prop->length, GFP_KERNEL);
+ prop->value = kmemdup(value, prop->length, GFP_KERNEL);
if (!prop->value) {
dlpar_free_cc_property(prop);
return NULL;
}
- memcpy(prop->value, value, prop->length);
return prop;
}
@@ -102,7 +101,7 @@ static void dlpar_free_one_cc_node(struct device_node *dn)
kfree(dn);
}
-static void dlpar_free_cc_nodes(struct device_node *dn)
+void dlpar_free_cc_nodes(struct device_node *dn)
{
if (dn->child)
dlpar_free_cc_nodes(dn->child);
diff --git a/arch/powerpc/platforms/pseries/dtl.c b/arch/powerpc/platforms/pseries/dtl.c
index a00addb55945..c371bc06434b 100644
--- a/arch/powerpc/platforms/pseries/dtl.c
+++ b/arch/powerpc/platforms/pseries/dtl.c
@@ -23,37 +23,22 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/debugfs.h>
+#include <linux/spinlock.h>
#include <asm/smp.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/firmware.h>
+#include <asm/lppaca.h>
#include "plpar_wrappers.h"
-/*
- * Layout of entries in the hypervisor's DTL buffer. Although we don't
- * actually access the internals of an entry (we only need to know the size),
- * we might as well define it here for reference.
- */
-struct dtl_entry {
- u8 dispatch_reason;
- u8 preempt_reason;
- u16 processor_id;
- u32 enqueue_to_dispatch_time;
- u32 ready_to_enqueue_time;
- u32 waiting_to_ready_time;
- u64 timebase;
- u64 fault_addr;
- u64 srr0;
- u64 srr1;
-};
-
struct dtl {
struct dtl_entry *buf;
struct dentry *file;
int cpu;
int buf_entries;
u64 last_idx;
+ spinlock_t lock;
};
static DEFINE_PER_CPU(struct dtl, cpu_dtl);
@@ -72,25 +57,97 @@ static u8 dtl_event_mask = 0x7;
static int dtl_buf_entries = (16 * 85);
-static int dtl_enable(struct dtl *dtl)
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+struct dtl_ring {
+ u64 write_index;
+ struct dtl_entry *write_ptr;
+ struct dtl_entry *buf;
+ struct dtl_entry *buf_end;
+ u8 saved_dtl_mask;
+};
+
+static DEFINE_PER_CPU(struct dtl_ring, dtl_rings);
+
+static atomic_t dtl_count;
+
+/*
+ * The cpu accounting code controls the DTL ring buffer, and we get
+ * given entries as they are processed.
+ */
+static void consume_dtle(struct dtl_entry *dtle, u64 index)
{
- unsigned long addr;
- int ret, hwcpu;
+ struct dtl_ring *dtlr = &__get_cpu_var(dtl_rings);
+ struct dtl_entry *wp = dtlr->write_ptr;
+ struct lppaca *vpa = local_paca->lppaca_ptr;
- /* only allow one reader */
- if (dtl->buf)
- return -EBUSY;
+ if (!wp)
+ return;
- /* we need to store the original allocation size for use during read */
- dtl->buf_entries = dtl_buf_entries;
+ *wp = *dtle;
+ barrier();
- dtl->buf = kmalloc_node(dtl->buf_entries * sizeof(struct dtl_entry),
- GFP_KERNEL, cpu_to_node(dtl->cpu));
- if (!dtl->buf) {
- printk(KERN_WARNING "%s: buffer alloc failed for cpu %d\n",
- __func__, dtl->cpu);
- return -ENOMEM;
- }
+ /* check for hypervisor ring buffer overflow, ignore this entry if so */
+ if (index + N_DISPATCH_LOG < vpa->dtl_idx)
+ return;
+
+ ++wp;
+ if (wp == dtlr->buf_end)
+ wp = dtlr->buf;
+ dtlr->write_ptr = wp;
+
+ /* incrementing write_index makes the new entry visible */
+ smp_wmb();
+ ++dtlr->write_index;
+}
+
+static int dtl_start(struct dtl *dtl)
+{
+ struct dtl_ring *dtlr = &per_cpu(dtl_rings, dtl->cpu);
+
+ dtlr->buf = dtl->buf;
+ dtlr->buf_end = dtl->buf + dtl->buf_entries;
+ dtlr->write_index = 0;
+
+ /* setting write_ptr enables logging into our buffer */
+ smp_wmb();
+ dtlr->write_ptr = dtl->buf;
+
+ /* enable event logging */
+ dtlr->saved_dtl_mask = lppaca_of(dtl->cpu).dtl_enable_mask;
+ lppaca_of(dtl->cpu).dtl_enable_mask |= dtl_event_mask;
+
+ dtl_consumer = consume_dtle;
+ atomic_inc(&dtl_count);
+ return 0;
+}
+
+static void dtl_stop(struct dtl *dtl)
+{
+ struct dtl_ring *dtlr = &per_cpu(dtl_rings, dtl->cpu);
+
+ dtlr->write_ptr = NULL;
+ smp_wmb();
+
+ dtlr->buf = NULL;
+
+ /* restore dtl_enable_mask */
+ lppaca_of(dtl->cpu).dtl_enable_mask = dtlr->saved_dtl_mask;
+
+ if (atomic_dec_and_test(&dtl_count))
+ dtl_consumer = NULL;
+}
+
+static u64 dtl_current_index(struct dtl *dtl)
+{
+ return per_cpu(dtl_rings, dtl->cpu).write_index;
+}
+
+#else /* CONFIG_VIRT_CPU_ACCOUNTING */
+
+static int dtl_start(struct dtl *dtl)
+{
+ unsigned long addr;
+ int ret, hwcpu;
/* Register our dtl buffer with the hypervisor. The HV expects the
* buffer size to be passed in the second word of the buffer */
@@ -102,34 +159,82 @@ static int dtl_enable(struct dtl *dtl)
if (ret) {
printk(KERN_WARNING "%s: DTL registration for cpu %d (hw %d) "
"failed with %d\n", __func__, dtl->cpu, hwcpu, ret);
- kfree(dtl->buf);
return -EIO;
}
/* set our initial buffer indices */
- dtl->last_idx = lppaca[dtl->cpu].dtl_idx = 0;
+ lppaca_of(dtl->cpu).dtl_idx = 0;
/* ensure that our updates to the lppaca fields have occurred before
* we actually enable the logging */
smp_wmb();
/* enable event logging */
- lppaca[dtl->cpu].dtl_enable_mask = dtl_event_mask;
+ lppaca_of(dtl->cpu).dtl_enable_mask = dtl_event_mask;
return 0;
}
-static void dtl_disable(struct dtl *dtl)
+static void dtl_stop(struct dtl *dtl)
{
int hwcpu = get_hard_smp_processor_id(dtl->cpu);
- lppaca[dtl->cpu].dtl_enable_mask = 0x0;
+ lppaca_of(dtl->cpu).dtl_enable_mask = 0x0;
unregister_dtl(hwcpu, __pa(dtl->buf));
+}
+
+static u64 dtl_current_index(struct dtl *dtl)
+{
+ return lppaca_of(dtl->cpu).dtl_idx;
+}
+#endif /* CONFIG_VIRT_CPU_ACCOUNTING */
+
+static int dtl_enable(struct dtl *dtl)
+{
+ long int n_entries;
+ long int rc;
+ struct dtl_entry *buf = NULL;
+ /* only allow one reader */
+ if (dtl->buf)
+ return -EBUSY;
+
+ n_entries = dtl_buf_entries;
+ buf = kmalloc_node(n_entries * sizeof(struct dtl_entry),
+ GFP_KERNEL, cpu_to_node(dtl->cpu));
+ if (!buf) {
+ printk(KERN_WARNING "%s: buffer alloc failed for cpu %d\n",
+ __func__, dtl->cpu);
+ return -ENOMEM;
+ }
+
+ spin_lock(&dtl->lock);
+ rc = -EBUSY;
+ if (!dtl->buf) {
+ /* store the original allocation size for use during read */
+ dtl->buf_entries = n_entries;
+ dtl->buf = buf;
+ dtl->last_idx = 0;
+ rc = dtl_start(dtl);
+ if (rc)
+ dtl->buf = NULL;
+ }
+ spin_unlock(&dtl->lock);
+
+ if (rc)
+ kfree(buf);
+ return rc;
+}
+
+static void dtl_disable(struct dtl *dtl)
+{
+ spin_lock(&dtl->lock);
+ dtl_stop(dtl);
kfree(dtl->buf);
dtl->buf = NULL;
dtl->buf_entries = 0;
+ spin_unlock(&dtl->lock);
}
/* file interface */
@@ -157,8 +262,9 @@ static int dtl_file_release(struct inode *inode, struct file *filp)
static ssize_t dtl_file_read(struct file *filp, char __user *buf, size_t len,
loff_t *pos)
{
- int rc, cur_idx, last_idx, n_read, n_req, read_size;
+ long int rc, n_read, n_req, read_size;
struct dtl *dtl;
+ u64 cur_idx, last_idx, i;
if ((len % sizeof(struct dtl_entry)) != 0)
return -EINVAL;
@@ -171,41 +277,48 @@ static ssize_t dtl_file_read(struct file *filp, char __user *buf, size_t len,
/* actual number of entries read */
n_read = 0;
- cur_idx = lppaca[dtl->cpu].dtl_idx;
+ spin_lock(&dtl->lock);
+
+ cur_idx = dtl_current_index(dtl);
last_idx = dtl->last_idx;
- if (cur_idx - last_idx > dtl->buf_entries) {
- pr_debug("%s: hv buffer overflow for cpu %d, samples lost\n",
- __func__, dtl->cpu);
- }
+ if (last_idx + dtl->buf_entries <= cur_idx)
+ last_idx = cur_idx - dtl->buf_entries + 1;
+
+ if (last_idx + n_req > cur_idx)
+ n_req = cur_idx - last_idx;
+
+ if (n_req > 0)
+ dtl->last_idx = last_idx + n_req;
+
+ spin_unlock(&dtl->lock);
+
+ if (n_req <= 0)
+ return 0;
- cur_idx %= dtl->buf_entries;
- last_idx %= dtl->buf_entries;
+ i = last_idx % dtl->buf_entries;
/* read the tail of the buffer if we've wrapped */
- if (last_idx > cur_idx) {
- read_size = min(n_req, dtl->buf_entries - last_idx);
+ if (i + n_req > dtl->buf_entries) {
+ read_size = dtl->buf_entries - i;
- rc = copy_to_user(buf, &dtl->buf[last_idx],
+ rc = copy_to_user(buf, &dtl->buf[i],
read_size * sizeof(struct dtl_entry));
if (rc)
return -EFAULT;
- last_idx = 0;
+ i = 0;
n_req -= read_size;
n_read += read_size;
buf += read_size * sizeof(struct dtl_entry);
}
/* .. and now the head */
- read_size = min(n_req, cur_idx - last_idx);
- rc = copy_to_user(buf, &dtl->buf[last_idx],
- read_size * sizeof(struct dtl_entry));
+ rc = copy_to_user(buf, &dtl->buf[i], n_req * sizeof(struct dtl_entry));
if (rc)
return -EFAULT;
- n_read += read_size;
- dtl->last_idx += n_read;
+ n_read += n_req;
return n_read * sizeof(struct dtl_entry);
}
@@ -263,6 +376,7 @@ static int dtl_init(void)
/* set up the per-cpu log structures */
for_each_possible_cpu(i) {
struct dtl *dtl = &per_cpu(cpu_dtl, i);
+ spin_lock_init(&dtl->lock);
dtl->cpu = i;
rc = dtl_setup_file(dtl);
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index cf79b46d8f88..f129040d974c 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -248,11 +248,13 @@ void vpa_init(int cpu)
int hwcpu = get_hard_smp_processor_id(cpu);
unsigned long addr;
long ret;
+ struct paca_struct *pp;
+ struct dtl_entry *dtl;
if (cpu_has_feature(CPU_FTR_ALTIVEC))
- lppaca[cpu].vmxregs_in_use = 1;
+ lppaca_of(cpu).vmxregs_in_use = 1;
- addr = __pa(&lppaca[cpu]);
+ addr = __pa(&lppaca_of(cpu));
ret = register_vpa(hwcpu, addr);
if (ret) {
@@ -274,6 +276,25 @@ void vpa_init(int cpu)
"registration for cpu %d (hw %d) of area %lx "
"returns %ld\n", cpu, hwcpu, addr, ret);
}
+
+ /*
+ * Register dispatch trace log, if one has been allocated.
+ */
+ pp = &paca[cpu];
+ dtl = pp->dispatch_log;
+ if (dtl) {
+ pp->dtl_ridx = 0;
+ pp->dtl_curr = dtl;
+ lppaca_of(cpu).dtl_idx = 0;
+
+ /* hypervisor reads buffer length from this field */
+ dtl->enqueue_to_dispatch_time = DISPATCH_LOG_BYTES;
+ ret = register_dtl(hwcpu, __pa(dtl));
+ if (ret)
+ pr_warn("DTL registration failed for cpu %d (%ld)\n",
+ cpu, ret);
+ lppaca_of(cpu).dtl_enable_mask = 2;
+ }
}
static long pSeries_lpar_hpte_insert(unsigned long hpte_group,
diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
new file mode 100644
index 000000000000..3e7f651e50ac
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/mobility.c
@@ -0,0 +1,362 @@
+/*
+ * Support for Partition Mobility/Migration
+ *
+ * Copyright (C) 2010 Nathan Fontenot
+ * Copyright (C) 2010 IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/kobject.h>
+#include <linux/smp.h>
+#include <linux/completion.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+
+#include <asm/rtas.h>
+#include "pseries.h"
+
+static struct kobject *mobility_kobj;
+
+struct update_props_workarea {
+ u32 phandle;
+ u32 state;
+ u64 reserved;
+ u32 nprops;
+};
+
+#define NODE_ACTION_MASK 0xff000000
+#define NODE_COUNT_MASK 0x00ffffff
+
+#define DELETE_DT_NODE 0x01000000
+#define UPDATE_DT_NODE 0x02000000
+#define ADD_DT_NODE 0x03000000
+
+static int mobility_rtas_call(int token, char *buf)
+{
+ int rc;
+
+ spin_lock(&rtas_data_buf_lock);
+
+ memcpy(rtas_data_buf, buf, RTAS_DATA_BUF_SIZE);
+ rc = rtas_call(token, 2, 1, NULL, rtas_data_buf, 1);
+ memcpy(buf, rtas_data_buf, RTAS_DATA_BUF_SIZE);
+
+ spin_unlock(&rtas_data_buf_lock);
+ return rc;
+}
+
+static int delete_dt_node(u32 phandle)
+{
+ struct device_node *dn;
+
+ dn = of_find_node_by_phandle(phandle);
+ if (!dn)
+ return -ENOENT;
+
+ dlpar_detach_node(dn);
+ return 0;
+}
+
+static int update_dt_property(struct device_node *dn, struct property **prop,
+ const char *name, u32 vd, char *value)
+{
+ struct property *new_prop = *prop;
+ struct property *old_prop;
+ int more = 0;
+
+ /* A negative 'vd' value indicates that only part of the new property
+ * value is contained in the buffer and we need to call
+ * ibm,update-properties again to get the rest of the value.
+ *
+ * A negative value is also the two's compliment of the actual value.
+ */
+ if (vd & 0x80000000) {
+ vd = ~vd + 1;
+ more = 1;
+ }
+
+ if (new_prop) {
+ /* partial property fixup */
+ char *new_data = kzalloc(new_prop->length + vd, GFP_KERNEL);
+ if (!new_data)
+ return -ENOMEM;
+
+ memcpy(new_data, new_prop->value, new_prop->length);
+ memcpy(new_data + new_prop->length, value, vd);
+
+ kfree(new_prop->value);
+ new_prop->value = new_data;
+ new_prop->length += vd;
+ } else {
+ new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL);
+ if (!new_prop)
+ return -ENOMEM;
+
+ new_prop->name = kstrdup(name, GFP_KERNEL);
+ if (!new_prop->name) {
+ kfree(new_prop);
+ return -ENOMEM;
+ }
+
+ new_prop->length = vd;
+ new_prop->value = kzalloc(new_prop->length, GFP_KERNEL);
+ if (!new_prop->value) {
+ kfree(new_prop->name);
+ kfree(new_prop);
+ return -ENOMEM;
+ }
+
+ memcpy(new_prop->value, value, vd);
+ *prop = new_prop;
+ }
+
+ if (!more) {
+ old_prop = of_find_property(dn, new_prop->name, NULL);
+ if (old_prop)
+ prom_update_property(dn, new_prop, old_prop);
+ else
+ prom_add_property(dn, new_prop);
+
+ new_prop = NULL;
+ }
+
+ return 0;
+}
+
+static int update_dt_node(u32 phandle)
+{
+ struct update_props_workarea *upwa;
+ struct device_node *dn;
+ struct property *prop = NULL;
+ int i, rc;
+ char *prop_data;
+ char *rtas_buf;
+ int update_properties_token;
+
+ update_properties_token = rtas_token("ibm,update-properties");
+ if (update_properties_token == RTAS_UNKNOWN_SERVICE)
+ return -EINVAL;
+
+ rtas_buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL);
+ if (!rtas_buf)
+ return -ENOMEM;
+
+ dn = of_find_node_by_phandle(phandle);
+ if (!dn) {
+ kfree(rtas_buf);
+ return -ENOENT;
+ }
+
+ upwa = (struct update_props_workarea *)&rtas_buf[0];
+ upwa->phandle = phandle;
+
+ do {
+ rc = mobility_rtas_call(update_properties_token, rtas_buf);
+ if (rc < 0)
+ break;
+
+ prop_data = rtas_buf + sizeof(*upwa);
+
+ for (i = 0; i < upwa->nprops; i++) {
+ char *prop_name;
+ u32 vd;
+
+ prop_name = prop_data + 1;
+ prop_data += strlen(prop_name) + 1;
+ vd = *prop_data++;
+
+ switch (vd) {
+ case 0x00000000:
+ /* name only property, nothing to do */
+ break;
+
+ case 0x80000000:
+ prop = of_find_property(dn, prop_name, NULL);
+ prom_remove_property(dn, prop);
+ prop = NULL;
+ break;
+
+ default:
+ rc = update_dt_property(dn, &prop, prop_name,
+ vd, prop_data);
+ if (rc) {
+ printk(KERN_ERR "Could not update %s"
+ " property\n", prop_name);
+ }
+
+ prop_data += vd;
+ }
+ }
+ } while (rc == 1);
+
+ of_node_put(dn);
+ kfree(rtas_buf);
+ return 0;
+}
+
+static int add_dt_node(u32 parent_phandle, u32 drc_index)
+{
+ struct device_node *dn;
+ struct device_node *parent_dn;
+ int rc;
+
+ dn = dlpar_configure_connector(drc_index);
+ if (!dn)
+ return -ENOENT;
+
+ parent_dn = of_find_node_by_phandle(parent_phandle);
+ if (!parent_dn) {
+ dlpar_free_cc_nodes(dn);
+ return -ENOENT;
+ }
+
+ dn->parent = parent_dn;
+ rc = dlpar_attach_node(dn);
+ if (rc)
+ dlpar_free_cc_nodes(dn);
+
+ of_node_put(parent_dn);
+ return rc;
+}
+
+static int pseries_devicetree_update(void)
+{
+ char *rtas_buf;
+ u32 *data;
+ int update_nodes_token;
+ int rc;
+
+ update_nodes_token = rtas_token("ibm,update-nodes");
+ if (update_nodes_token == RTAS_UNKNOWN_SERVICE)
+ return -EINVAL;
+
+ rtas_buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL);
+ if (!rtas_buf)
+ return -ENOMEM;
+
+ do {
+ rc = mobility_rtas_call(update_nodes_token, rtas_buf);
+ if (rc && rc != 1)
+ break;
+
+ data = (u32 *)rtas_buf + 4;
+ while (*data & NODE_ACTION_MASK) {
+ int i;
+ u32 action = *data & NODE_ACTION_MASK;
+ int node_count = *data & NODE_COUNT_MASK;
+
+ data++;
+
+ for (i = 0; i < node_count; i++) {
+ u32 phandle = *data++;
+ u32 drc_index;
+
+ switch (action) {
+ case DELETE_DT_NODE:
+ delete_dt_node(phandle);
+ break;
+ case UPDATE_DT_NODE:
+ update_dt_node(phandle);
+ break;
+ case ADD_DT_NODE:
+ drc_index = *data++;
+ add_dt_node(phandle, drc_index);
+ break;
+ }
+ }
+ }
+ } while (rc == 1);
+
+ kfree(rtas_buf);
+ return rc;
+}
+
+void post_mobility_fixup(void)
+{
+ int rc;
+ int activate_fw_token;
+
+ rc = pseries_devicetree_update();
+ if (rc) {
+ printk(KERN_ERR "Initial post-mobility device tree update "
+ "failed: %d\n", rc);
+ return;
+ }
+
+ activate_fw_token = rtas_token("ibm,activate-firmware");
+ if (activate_fw_token == RTAS_UNKNOWN_SERVICE) {
+ printk(KERN_ERR "Could not make post-mobility "
+ "activate-fw call.\n");
+ return;
+ }
+
+ rc = rtas_call(activate_fw_token, 0, 1, NULL);
+ if (!rc) {
+ rc = pseries_devicetree_update();
+ if (rc)
+ printk(KERN_ERR "Secondary post-mobility device tree "
+ "update failed: %d\n", rc);
+ } else {
+ printk(KERN_ERR "Post-mobility activate-fw failed: %d\n", rc);
+ return;
+ }
+
+ return;
+}
+
+static ssize_t migrate_store(struct class *class, struct class_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct rtas_args args;
+ u64 streamid;
+ int rc;
+
+ rc = strict_strtoull(buf, 0, &streamid);
+ if (rc)
+ return rc;
+
+ memset(&args, 0, sizeof(args));
+ args.token = rtas_token("ibm,suspend-me");
+ args.nargs = 2;
+ args.nret = 1;
+
+ args.args[0] = streamid >> 32 ;
+ args.args[1] = streamid & 0xffffffff;
+ args.rets = &args.args[args.nargs];
+
+ do {
+ args.rets[0] = 0;
+ rc = rtas_ibm_suspend_me(&args);
+ if (!rc && args.rets[0] == RTAS_NOT_SUSPENDABLE)
+ ssleep(1);
+ } while (!rc && args.rets[0] == RTAS_NOT_SUSPENDABLE);
+
+ if (rc)
+ return rc;
+ else if (args.rets[0])
+ return args.rets[0];
+
+ post_mobility_fixup();
+ return count;
+}
+
+static CLASS_ATTR(migration, S_IWUSR, NULL, migrate_store);
+
+static int __init mobility_sysfs_init(void)
+{
+ int rc;
+
+ mobility_kobj = kobject_create_and_add("mobility", kernel_kobj);
+ if (!mobility_kobj)
+ return -ENOMEM;
+
+ rc = sysfs_create_file(mobility_kobj, &class_attr_migration.attr);
+
+ return rc;
+}
+device_initcall(mobility_sysfs_init);
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
index 40c93cad91d2..e9f6d2859c3c 100644
--- a/arch/powerpc/platforms/pseries/pseries.h
+++ b/arch/powerpc/platforms/pseries/pseries.h
@@ -17,6 +17,8 @@ struct device_node;
extern void request_event_sources_irqs(struct device_node *np,
irq_handler_t handler, const char *name);
+#include <linux/of.h>
+
extern void __init fw_feature_init(const char *hypertas, unsigned long len);
struct pt_regs;
@@ -47,4 +49,11 @@ extern unsigned long rtas_poweron_auto;
extern void find_udbg_vterm(void);
+/* Dynamic logical Partitioning/Mobility */
+extern void dlpar_free_cc_nodes(struct device_node *);
+extern void dlpar_free_cc_property(struct property *);
+extern struct device_node *dlpar_configure_connector(u32);
+extern int dlpar_attach_node(struct device_node *);
+extern int dlpar_detach_node(struct device_node *);
+
#endif /* _PSERIES_PSERIES_H */
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index 57ddbb43b33a..1de2cbb92303 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -539,7 +539,8 @@ out:
}
static const struct file_operations ofdt_fops = {
- .write = ofdt_write
+ .write = ofdt_write,
+ .llseek = noop_llseek,
};
/* create /proc/powerpc/ofdt write-only by root */
diff --git a/arch/powerpc/platforms/pseries/scanlog.c b/arch/powerpc/platforms/pseries/scanlog.c
index 80e9e7652a4d..554457294a2b 100644
--- a/arch/powerpc/platforms/pseries/scanlog.c
+++ b/arch/powerpc/platforms/pseries/scanlog.c
@@ -170,6 +170,7 @@ const struct file_operations scanlog_fops = {
.write = scanlog_write,
.open = scanlog_open,
.release = scanlog_release,
+ .llseek = noop_llseek,
};
static int __init scanlog_init(void)
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index a6d19e3a505e..d345bfd56bbe 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -273,6 +273,58 @@ static struct notifier_block pci_dn_reconfig_nb = {
.notifier_call = pci_dn_reconfig_notifier,
};
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+/*
+ * Allocate space for the dispatch trace log for all possible cpus
+ * and register the buffers with the hypervisor. This is used for
+ * computing time stolen by the hypervisor.
+ */
+static int alloc_dispatch_logs(void)
+{
+ int cpu, ret;
+ struct paca_struct *pp;
+ struct dtl_entry *dtl;
+
+ if (!firmware_has_feature(FW_FEATURE_SPLPAR))
+ return 0;
+
+ for_each_possible_cpu(cpu) {
+ pp = &paca[cpu];
+ dtl = kmalloc_node(DISPATCH_LOG_BYTES, GFP_KERNEL,
+ cpu_to_node(cpu));
+ if (!dtl) {
+ pr_warn("Failed to allocate dispatch trace log for cpu %d\n",
+ cpu);
+ pr_warn("Stolen time statistics will be unreliable\n");
+ break;
+ }
+
+ pp->dtl_ridx = 0;
+ pp->dispatch_log = dtl;
+ pp->dispatch_log_end = dtl + N_DISPATCH_LOG;
+ pp->dtl_curr = dtl;
+ }
+
+ /* Register the DTL for the current (boot) cpu */
+ dtl = get_paca()->dispatch_log;
+ get_paca()->dtl_ridx = 0;
+ get_paca()->dtl_curr = dtl;
+ get_paca()->lppaca_ptr->dtl_idx = 0;
+
+ /* hypervisor reads buffer length from this field */
+ dtl->enqueue_to_dispatch_time = DISPATCH_LOG_BYTES;
+ ret = register_dtl(hard_smp_processor_id(), __pa(dtl));
+ if (ret)
+ pr_warn("DTL registration failed for boot cpu %d (%d)\n",
+ smp_processor_id(), ret);
+ get_paca()->lppaca_ptr->dtl_enable_mask = 2;
+
+ return 0;
+}
+
+early_initcall(alloc_dispatch_logs);
+#endif /* CONFIG_VIRT_CPU_ACCOUNTING */
+
static void __init pSeries_setup_arch(void)
{
/* Discover PIC type and setup ppc_md accordingly */
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 93834b0d8272..7b96e5a270ce 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -178,7 +178,7 @@ static int get_irq_server(unsigned int virq, const struct cpumask *cpumask,
if (!distribute_irqs)
return default_server;
- if (!cpumask_equal(cpumask, cpu_all_mask)) {
+ if (!cpumask_subset(cpu_possible_mask, cpumask)) {
int server = cpumask_first_and(cpu_online_mask, cpumask);
if (server < nr_cpu_ids)
@@ -243,7 +243,7 @@ static unsigned int xics_startup(unsigned int virq)
* at that level, so we do it here by hand.
*/
if (irq_to_desc(virq)->msi_desc)
- unmask_msi_irq(virq);
+ unmask_msi_irq(irq_get_irq_data(virq));
/* unmask it */
xics_unmask_irq(virq);
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 5642924fb9fb..0bef9dacb64e 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -1,8 +1,6 @@
subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
-ifeq ($(CONFIG_PPC64),y)
-EXTRA_CFLAGS += -mno-minimal-toc
-endif
+ccflags-$(CONFIG_PPC64) := -mno-minimal-toc
mpic-msi-obj-$(CONFIG_PCI_MSI) += mpic_msi.o mpic_u3msi.o mpic_pasemi_msi.o
obj-$(CONFIG_MPIC) += mpic.o $(mpic-msi-obj-y)
@@ -20,6 +18,7 @@ obj-$(CONFIG_FSL_PMC) += fsl_pmc.o
obj-$(CONFIG_FSL_LBC) += fsl_lbc.o
obj-$(CONFIG_FSL_GTM) += fsl_gtm.o
obj-$(CONFIG_MPC8xxx_GPIO) += mpc8xxx_gpio.o
+obj-$(CONFIG_FSL_85XX_CACHE_SRAM) += fsl_85xx_l2ctlr.o fsl_85xx_cache_sram.o
obj-$(CONFIG_SIMPLE_GPIO) += simple_gpio.o
obj-$(CONFIG_RAPIDIO) += fsl_rio.o
obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c
index 559db2b846a9..17cf15ec38be 100644
--- a/arch/powerpc/sysdev/dart_iommu.c
+++ b/arch/powerpc/sysdev/dart_iommu.c
@@ -70,6 +70,8 @@ static int iommu_table_dart_inited;
static int dart_dirty;
static int dart_is_u4;
+#define DART_U4_BYPASS_BASE 0x8000000000ull
+
#define DBG(...)
static inline void dart_tlb_invalidate_all(void)
@@ -292,12 +294,20 @@ static void iommu_table_dart_setup(void)
set_bit(iommu_table_dart.it_size - 1, iommu_table_dart.it_map);
}
-static void pci_dma_dev_setup_dart(struct pci_dev *dev)
+static void dma_dev_setup_dart(struct device *dev)
{
/* We only have one iommu table on the mac for now, which makes
* things simple. Setup all PCI devices to point to this table
*/
- set_iommu_table_base(&dev->dev, &iommu_table_dart);
+ if (get_dma_ops(dev) == &dma_direct_ops)
+ set_dma_offset(dev, DART_U4_BYPASS_BASE);
+ else
+ set_iommu_table_base(dev, &iommu_table_dart);
+}
+
+static void pci_dma_dev_setup_dart(struct pci_dev *dev)
+{
+ dma_dev_setup_dart(&dev->dev);
}
static void pci_dma_bus_setup_dart(struct pci_bus *bus)
@@ -315,6 +325,45 @@ static void pci_dma_bus_setup_dart(struct pci_bus *bus)
PCI_DN(dn)->iommu_table = &iommu_table_dart;
}
+static bool dart_device_on_pcie(struct device *dev)
+{
+ struct device_node *np = of_node_get(dev->of_node);
+
+ while(np) {
+ if (of_device_is_compatible(np, "U4-pcie") ||
+ of_device_is_compatible(np, "u4-pcie")) {
+ of_node_put(np);
+ return true;
+ }
+ np = of_get_next_parent(np);
+ }
+ return false;
+}
+
+static int dart_dma_set_mask(struct device *dev, u64 dma_mask)
+{
+ if (!dev->dma_mask || !dma_supported(dev, dma_mask))
+ return -EIO;
+
+ /* U4 supports a DART bypass, we use it for 64-bit capable
+ * devices to improve performances. However, that only works
+ * for devices connected to U4 own PCIe interface, not bridged
+ * through hypertransport. We need the device to support at
+ * least 40 bits of addresses.
+ */
+ if (dart_device_on_pcie(dev) && dma_mask >= DMA_BIT_MASK(40)) {
+ dev_info(dev, "Using 64-bit DMA iommu bypass\n");
+ set_dma_ops(dev, &dma_direct_ops);
+ } else {
+ dev_info(dev, "Using 32-bit DMA via iommu\n");
+ set_dma_ops(dev, &dma_iommu_ops);
+ }
+ dma_dev_setup_dart(dev);
+
+ *dev->dma_mask = dma_mask;
+ return 0;
+}
+
void __init iommu_init_early_dart(void)
{
struct device_node *dn;
@@ -328,20 +377,25 @@ void __init iommu_init_early_dart(void)
dart_is_u4 = 1;
}
+ /* Initialize the DART HW */
+ if (dart_init(dn) != 0)
+ goto bail;
+
/* Setup low level TCE operations for the core IOMMU code */
ppc_md.tce_build = dart_build;
ppc_md.tce_free = dart_free;
ppc_md.tce_flush = dart_flush;
- /* Initialize the DART HW */
- if (dart_init(dn) == 0) {
- ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_dart;
- ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_dart;
+ /* Setup bypass if supported */
+ if (dart_is_u4)
+ ppc_md.dma_set_mask = dart_dma_set_mask;
- /* Setup pci_dma ops */
- set_pci_dma_ops(&dma_iommu_ops);
- return;
- }
+ ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_dart;
+ ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_dart;
+
+ /* Setup pci_dma ops */
+ set_pci_dma_ops(&dma_iommu_ops);
+ return;
bail:
/* If init failed, use direct iommu and null setup functions */
diff --git a/arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h b/arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h
new file mode 100644
index 000000000000..60c9c0bd5ba2
--- /dev/null
+++ b/arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2009-2010 Freescale Semiconductor, Inc
+ *
+ * QorIQ based Cache Controller Memory Mapped Registers
+ *
+ * Author: Vivek Mahajan <vivek.mahajan@freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __FSL_85XX_CACHE_CTLR_H__
+#define __FSL_85XX_CACHE_CTLR_H__
+
+#define L2CR_L2FI 0x40000000 /* L2 flash invalidate */
+#define L2CR_L2IO 0x00200000 /* L2 instruction only */
+#define L2CR_SRAM_ZERO 0x00000000 /* L2SRAM zero size */
+#define L2CR_SRAM_FULL 0x00010000 /* L2SRAM full size */
+#define L2CR_SRAM_HALF 0x00020000 /* L2SRAM half size */
+#define L2CR_SRAM_TWO_HALFS 0x00030000 /* L2SRAM two half sizes */
+#define L2CR_SRAM_QUART 0x00040000 /* L2SRAM one quarter size */
+#define L2CR_SRAM_TWO_QUARTS 0x00050000 /* L2SRAM two quarter size */
+#define L2CR_SRAM_EIGHTH 0x00060000 /* L2SRAM one eighth size */
+#define L2CR_SRAM_TWO_EIGHTH 0x00070000 /* L2SRAM two eighth size */
+
+#define L2SRAM_OPTIMAL_SZ_SHIFT 0x00000003 /* Optimum size for L2SRAM */
+
+#define L2SRAM_BAR_MSK_LO18 0xFFFFC000 /* Lower 18 bits */
+#define L2SRAM_BARE_MSK_HI4 0x0000000F /* Upper 4 bits */
+
+enum cache_sram_lock_ways {
+ LOCK_WAYS_ZERO,
+ LOCK_WAYS_EIGHTH,
+ LOCK_WAYS_TWO_EIGHTH,
+ LOCK_WAYS_HALF = 4,
+ LOCK_WAYS_FULL = 8,
+};
+
+struct mpc85xx_l2ctlr {
+ u32 ctl; /* 0x000 - L2 control */
+ u8 res1[0xC];
+ u32 ewar0; /* 0x010 - External write address 0 */
+ u32 ewarea0; /* 0x014 - External write address extended 0 */
+ u32 ewcr0; /* 0x018 - External write ctrl */
+ u8 res2[4];
+ u32 ewar1; /* 0x020 - External write address 1 */
+ u32 ewarea1; /* 0x024 - External write address extended 1 */
+ u32 ewcr1; /* 0x028 - External write ctrl 1 */
+ u8 res3[4];
+ u32 ewar2; /* 0x030 - External write address 2 */
+ u32 ewarea2; /* 0x034 - External write address extended 2 */
+ u32 ewcr2; /* 0x038 - External write ctrl 2 */
+ u8 res4[4];
+ u32 ewar3; /* 0x040 - External write address 3 */
+ u32 ewarea3; /* 0x044 - External write address extended 3 */
+ u32 ewcr3; /* 0x048 - External write ctrl 3 */
+ u8 res5[0xB4];
+ u32 srbar0; /* 0x100 - SRAM base address 0 */
+ u32 srbarea0; /* 0x104 - SRAM base addr reg ext address 0 */
+ u32 srbar1; /* 0x108 - SRAM base address 1 */
+ u32 srbarea1; /* 0x10C - SRAM base addr reg ext address 1 */
+ u8 res6[0xCF0];
+ u32 errinjhi; /* 0xE00 - Error injection mask high */
+ u32 errinjlo; /* 0xE04 - Error injection mask low */
+ u32 errinjctl; /* 0xE08 - Error injection tag/ecc control */
+ u8 res7[0x14];
+ u32 captdatahi; /* 0xE20 - Error data high capture */
+ u32 captdatalo; /* 0xE24 - Error data low capture */
+ u32 captecc; /* 0xE28 - Error syndrome */
+ u8 res8[0x14];
+ u32 errdet; /* 0xE40 - Error detect */
+ u32 errdis; /* 0xE44 - Error disable */
+ u32 errinten; /* 0xE48 - Error interrupt enable */
+ u32 errattr; /* 0xE4c - Error attribute capture */
+ u32 erradrrl; /* 0xE50 - Error address capture low */
+ u32 erradrrh; /* 0xE54 - Error address capture high */
+ u32 errctl; /* 0xE58 - Error control */
+ u8 res9[0x1A4];
+};
+
+struct sram_parameters {
+ unsigned int sram_size;
+ uint64_t sram_offset;
+};
+
+extern int instantiate_cache_sram(struct platform_device *dev,
+ struct sram_parameters sram_params);
+extern void remove_cache_sram(struct platform_device *dev);
+
+#endif /* __FSL_85XX_CACHE_CTLR_H__ */
diff --git a/arch/powerpc/sysdev/fsl_85xx_cache_sram.c b/arch/powerpc/sysdev/fsl_85xx_cache_sram.c
new file mode 100644
index 000000000000..54fb1922fe30
--- /dev/null
+++ b/arch/powerpc/sysdev/fsl_85xx_cache_sram.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2009-2010 Freescale Semiconductor, Inc.
+ *
+ * Simple memory allocator abstraction for QorIQ (P1/P2) based Cache-SRAM
+ *
+ * Author: Vivek Mahajan <vivek.mahajan@freescale.com>
+ *
+ * This file is derived from the original work done
+ * by Sylvain Munaut for the Bestcomm SRAM allocator.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/of_platform.h>
+#include <asm/pgtable.h>
+#include <asm/fsl_85xx_cache_sram.h>
+
+#include "fsl_85xx_cache_ctlr.h"
+
+struct mpc85xx_cache_sram *cache_sram;
+
+void *mpc85xx_cache_sram_alloc(unsigned int size,
+ phys_addr_t *phys, unsigned int align)
+{
+ unsigned long offset;
+ unsigned long flags;
+
+ if (unlikely(cache_sram == NULL))
+ return NULL;
+
+ if (!size || (size > cache_sram->size) || (align > cache_sram->size)) {
+ pr_err("%s(): size(=%x) or align(=%x) zero or too big\n",
+ __func__, size, align);
+ return NULL;
+ }
+
+ if ((align & (align - 1)) || align <= 1) {
+ pr_err("%s(): align(=%x) must be power of two and >1\n",
+ __func__, align);
+ return NULL;
+ }
+
+ spin_lock_irqsave(&cache_sram->lock, flags);
+ offset = rh_alloc_align(cache_sram->rh, size, align, NULL);
+ spin_unlock_irqrestore(&cache_sram->lock, flags);
+
+ if (IS_ERR_VALUE(offset))
+ return NULL;
+
+ *phys = cache_sram->base_phys + offset;
+
+ return (unsigned char *)cache_sram->base_virt + offset;
+}
+EXPORT_SYMBOL(mpc85xx_cache_sram_alloc);
+
+void mpc85xx_cache_sram_free(void *ptr)
+{
+ unsigned long flags;
+ BUG_ON(!ptr);
+
+ spin_lock_irqsave(&cache_sram->lock, flags);
+ rh_free(cache_sram->rh, ptr - cache_sram->base_virt);
+ spin_unlock_irqrestore(&cache_sram->lock, flags);
+}
+EXPORT_SYMBOL(mpc85xx_cache_sram_free);
+
+int __init instantiate_cache_sram(struct platform_device *dev,
+ struct sram_parameters sram_params)
+{
+ int ret = 0;
+
+ if (cache_sram) {
+ dev_err(&dev->dev, "Already initialized cache-sram\n");
+ return -EBUSY;
+ }
+
+ cache_sram = kzalloc(sizeof(struct mpc85xx_cache_sram), GFP_KERNEL);
+ if (!cache_sram) {
+ dev_err(&dev->dev, "Out of memory for cache_sram structure\n");
+ return -ENOMEM;
+ }
+
+ cache_sram->base_phys = sram_params.sram_offset;
+ cache_sram->size = sram_params.sram_size;
+
+ if (!request_mem_region(cache_sram->base_phys, cache_sram->size,
+ "fsl_85xx_cache_sram")) {
+ dev_err(&dev->dev, "%s: request memory failed\n",
+ dev->dev.of_node->full_name);
+ ret = -ENXIO;
+ goto out_free;
+ }
+
+ cache_sram->base_virt = ioremap_flags(cache_sram->base_phys,
+ cache_sram->size, _PAGE_COHERENT | PAGE_KERNEL);
+ if (!cache_sram->base_virt) {
+ dev_err(&dev->dev, "%s: ioremap_flags failed\n",
+ dev->dev.of_node->full_name);
+ ret = -ENOMEM;
+ goto out_release;
+ }
+
+ cache_sram->rh = rh_create(sizeof(unsigned int));
+ if (IS_ERR(cache_sram->rh)) {
+ dev_err(&dev->dev, "%s: Unable to create remote heap\n",
+ dev->dev.of_node->full_name);
+ ret = PTR_ERR(cache_sram->rh);
+ goto out_unmap;
+ }
+
+ rh_attach_region(cache_sram->rh, 0, cache_sram->size);
+ spin_lock_init(&cache_sram->lock);
+
+ dev_info(&dev->dev, "[base:0x%llx, size:0x%x] configured and loaded\n",
+ (unsigned long long)cache_sram->base_phys, cache_sram->size);
+
+ return 0;
+
+out_unmap:
+ iounmap(cache_sram->base_virt);
+
+out_release:
+ release_mem_region(cache_sram->base_phys, cache_sram->size);
+
+out_free:
+ kfree(cache_sram);
+ return ret;
+}
+
+void remove_cache_sram(struct platform_device *dev)
+{
+ BUG_ON(!cache_sram);
+
+ rh_detach_region(cache_sram->rh, 0, cache_sram->size);
+ rh_destroy(cache_sram->rh);
+
+ iounmap(cache_sram->base_virt);
+ release_mem_region(cache_sram->base_phys, cache_sram->size);
+
+ kfree(cache_sram);
+ cache_sram = NULL;
+
+ dev_info(&dev->dev, "MPC85xx Cache-SRAM driver unloaded\n");
+}
diff --git a/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c b/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
new file mode 100644
index 000000000000..cc8d6556d799
--- /dev/null
+++ b/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright 2009-2010 Freescale Semiconductor, Inc.
+ *
+ * QorIQ (P1/P2) L2 controller init for Cache-SRAM instantiation
+ *
+ * Author: Vivek Mahajan <vivek.mahajan@freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/of_platform.h>
+#include <asm/io.h>
+
+#include "fsl_85xx_cache_ctlr.h"
+
+static char *sram_size;
+static char *sram_offset;
+struct mpc85xx_l2ctlr __iomem *l2ctlr;
+
+static long get_cache_sram_size(void)
+{
+ unsigned long val;
+
+ if (!sram_size || (strict_strtoul(sram_size, 0, &val) < 0))
+ return -EINVAL;
+
+ return val;
+}
+
+static long get_cache_sram_offset(void)
+{
+ unsigned long val;
+
+ if (!sram_offset || (strict_strtoul(sram_offset, 0, &val) < 0))
+ return -EINVAL;
+
+ return val;
+}
+
+static int __init get_size_from_cmdline(char *str)
+{
+ if (!str)
+ return 0;
+
+ sram_size = str;
+ return 1;
+}
+
+static int __init get_offset_from_cmdline(char *str)
+{
+ if (!str)
+ return 0;
+
+ sram_offset = str;
+ return 1;
+}
+
+__setup("cache-sram-size=", get_size_from_cmdline);
+__setup("cache-sram-offset=", get_offset_from_cmdline);
+
+static int __devinit mpc85xx_l2ctlr_of_probe(struct platform_device *dev,
+ const struct of_device_id *match)
+{
+ long rval;
+ unsigned int rem;
+ unsigned char ways;
+ const unsigned int *prop;
+ unsigned int l2cache_size;
+ struct sram_parameters sram_params;
+
+ if (!dev->dev.of_node) {
+ dev_err(&dev->dev, "Device's OF-node is NULL\n");
+ return -EINVAL;
+ }
+
+ prop = of_get_property(dev->dev.of_node, "cache-size", NULL);
+ if (!prop) {
+ dev_err(&dev->dev, "Missing L2 cache-size\n");
+ return -EINVAL;
+ }
+ l2cache_size = *prop;
+
+ sram_params.sram_size = get_cache_sram_size();
+ if (sram_params.sram_size <= 0) {
+ dev_err(&dev->dev,
+ "Entire L2 as cache, Aborting Cache-SRAM stuff\n");
+ return -EINVAL;
+ }
+
+ sram_params.sram_offset = get_cache_sram_offset();
+ if (sram_params.sram_offset <= 0) {
+ dev_err(&dev->dev,
+ "Entire L2 as cache, provide a valid sram offset\n");
+ return -EINVAL;
+ }
+
+
+ rem = l2cache_size % sram_params.sram_size;
+ ways = LOCK_WAYS_FULL * sram_params.sram_size / l2cache_size;
+ if (rem || (ways & (ways - 1))) {
+ dev_err(&dev->dev, "Illegal cache-sram-size in command line\n");
+ return -EINVAL;
+ }
+
+ l2ctlr = of_iomap(dev->dev.of_node, 0);
+ if (!l2ctlr) {
+ dev_err(&dev->dev, "Can't map L2 controller\n");
+ return -EINVAL;
+ }
+
+ /*
+ * Write bits[0-17] to srbar0
+ */
+ out_be32(&l2ctlr->srbar0,
+ sram_params.sram_offset & L2SRAM_BAR_MSK_LO18);
+
+ /*
+ * Write bits[18-21] to srbare0
+ */
+#ifdef CONFIG_PHYS_64BIT
+ out_be32(&l2ctlr->srbarea0,
+ (sram_params.sram_offset >> 32) & L2SRAM_BARE_MSK_HI4);
+#endif
+
+ clrsetbits_be32(&l2ctlr->ctl, L2CR_L2E, L2CR_L2FI);
+
+ switch (ways) {
+ case LOCK_WAYS_EIGHTH:
+ setbits32(&l2ctlr->ctl,
+ L2CR_L2E | L2CR_L2FI | L2CR_SRAM_EIGHTH);
+ break;
+
+ case LOCK_WAYS_TWO_EIGHTH:
+ setbits32(&l2ctlr->ctl,
+ L2CR_L2E | L2CR_L2FI | L2CR_SRAM_QUART);
+ break;
+
+ case LOCK_WAYS_HALF:
+ setbits32(&l2ctlr->ctl,
+ L2CR_L2E | L2CR_L2FI | L2CR_SRAM_HALF);
+ break;
+
+ case LOCK_WAYS_FULL:
+ default:
+ setbits32(&l2ctlr->ctl,
+ L2CR_L2E | L2CR_L2FI | L2CR_SRAM_FULL);
+ break;
+ }
+ eieio();
+
+ rval = instantiate_cache_sram(dev, sram_params);
+ if (rval < 0) {
+ dev_err(&dev->dev, "Can't instantiate Cache-SRAM\n");
+ iounmap(l2ctlr);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int __devexit mpc85xx_l2ctlr_of_remove(struct platform_device *dev)
+{
+ BUG_ON(!l2ctlr);
+
+ iounmap(l2ctlr);
+ remove_cache_sram(dev);
+ dev_info(&dev->dev, "MPC85xx L2 controller unloaded\n");
+
+ return 0;
+}
+
+static struct of_device_id mpc85xx_l2ctlr_of_match[] = {
+ {
+ .compatible = "fsl,p2020-l2-cache-controller",
+ },
+ {
+ .compatible = "fsl,p2010-l2-cache-controller",
+ },
+ {
+ .compatible = "fsl,p1020-l2-cache-controller",
+ },
+ {
+ .compatible = "fsl,p1011-l2-cache-controller",
+ },
+ {
+ .compatible = "fsl,p1013-l2-cache-controller",
+ },
+ {
+ .compatible = "fsl,p1022-l2-cache-controller",
+ },
+ {},
+};
+
+static struct of_platform_driver mpc85xx_l2ctlr_of_platform_driver = {
+ .driver = {
+ .name = "fsl-l2ctlr",
+ .owner = THIS_MODULE,
+ .of_match_table = mpc85xx_l2ctlr_of_match,
+ },
+ .probe = mpc85xx_l2ctlr_of_probe,
+ .remove = __devexit_p(mpc85xx_l2ctlr_of_remove),
+};
+
+static __init int mpc85xx_l2ctlr_of_init(void)
+{
+ return of_register_platform_driver(&mpc85xx_l2ctlr_of_platform_driver);
+}
+
+static void __exit mpc85xx_l2ctlr_of_exit(void)
+{
+ of_unregister_platform_driver(&mpc85xx_l2ctlr_of_platform_driver);
+}
+
+subsys_initcall(mpc85xx_l2ctlr_of_init);
+module_exit(mpc85xx_l2ctlr_of_exit);
+
+MODULE_DESCRIPTION("Freescale MPC85xx L2 controller init");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index 87991d3abbab..108d76fa8f1c 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -24,6 +24,7 @@
#include <asm/ppc-pci.h>
#include <asm/mpic.h>
#include "fsl_msi.h"
+#include "fsl_pci.h"
LIST_HEAD(msi_head);
@@ -51,8 +52,8 @@ static void fsl_msi_end_irq(unsigned int virq)
}
static struct irq_chip fsl_msi_chip = {
- .mask = mask_msi_irq,
- .unmask = unmask_msi_irq,
+ .irq_mask = mask_msi_irq,
+ .irq_unmask = unmask_msi_irq,
.ack = fsl_msi_end_irq,
.name = "FSL-MSI",
};
@@ -125,13 +126,11 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq,
{
struct fsl_msi *msi_data = fsl_msi_data;
struct pci_controller *hose = pci_bus_to_host(pdev->bus);
- u32 base = 0;
+ u64 base = fsl_pci_immrbar_base(hose);
- pci_bus_read_config_dword(hose->bus,
- PCI_DEVFN(0, 0), PCI_BASE_ADDRESS_0, &base);
+ msg->address_lo = msi_data->msi_addr_lo + lower_32_bits(base);
+ msg->address_hi = msi_data->msi_addr_hi + upper_32_bits(base);
- msg->address_lo = msi_data->msi_addr_lo + base;
- msg->address_hi = msi_data->msi_addr_hi;
msg->data = hwirq;
pr_debug("%s: allocated srs: %d, ibs: %d\n",
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 4ae933225251..818f7c6c8fa1 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -1,7 +1,7 @@
/*
* MPC83xx/85xx/86xx PCI/PCIE support routing.
*
- * Copyright 2007-2009 Freescale Semiconductor, Inc.
+ * Copyright 2007-2010 Freescale Semiconductor, Inc.
* Copyright 2008-2009 MontaVista Software, Inc.
*
* Initial author: Xianghua Xiao <x.xiao@freescale.com>
@@ -34,7 +34,7 @@
#include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h>
-static int fsl_pcie_bus_fixup;
+static int fsl_pcie_bus_fixup, is_mpc83xx_pci;
static void __init quirk_fsl_pcie_header(struct pci_dev *dev)
{
@@ -407,10 +407,18 @@ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2010E, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2010, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2020E, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2020, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2040E, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2040, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P3041E, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P3041, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P4040E, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P4040, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P4080E, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P4080, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P5010E, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P5010, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P5020E, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P5020, quirk_fsl_pcie_header);
#endif /* CONFIG_FSL_SOC_BOOKE || CONFIG_PPC_86xx */
#if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x)
@@ -430,6 +438,13 @@ struct mpc83xx_pcie_priv {
u32 dev_base;
};
+struct pex_inbound_window {
+ u32 ar;
+ u32 tar;
+ u32 barl;
+ u32 barh;
+};
+
/*
* With the convention of u-boot, the PCIE outbound window 0 serves
* as configuration transactions outbound.
@@ -437,6 +452,8 @@ struct mpc83xx_pcie_priv {
#define PEX_OUTWIN0_BAR 0xCA4
#define PEX_OUTWIN0_TAL 0xCA8
#define PEX_OUTWIN0_TAH 0xCAC
+#define PEX_RC_INWIN_BASE 0xE60
+#define PEX_RCIWARn_EN 0x1
static int mpc83xx_pcie_exclude_device(struct pci_bus *bus, unsigned int devfn)
{
@@ -604,6 +621,8 @@ int __init mpc83xx_add_bridge(struct device_node *dev)
const int *bus_range;
int primary;
+ is_mpc83xx_pci = 1;
+
if (!of_device_is_available(dev)) {
pr_warning("%s: disabled by the firmware.\n",
dev->full_name);
@@ -683,3 +702,40 @@ err0:
return ret;
}
#endif /* CONFIG_PPC_83xx */
+
+u64 fsl_pci_immrbar_base(struct pci_controller *hose)
+{
+#ifdef CONFIG_PPC_83xx
+ if (is_mpc83xx_pci) {
+ struct mpc83xx_pcie_priv *pcie = hose->dn->data;
+ struct pex_inbound_window *in;
+ int i;
+
+ /* Walk the Root Complex Inbound windows to match IMMR base */
+ in = pcie->cfg_type0 + PEX_RC_INWIN_BASE;
+ for (i = 0; i < 4; i++) {
+ /* not enabled, skip */
+ if (!in_le32(&in[i].ar) & PEX_RCIWARn_EN)
+ continue;
+
+ if (get_immrbase() == in_le32(&in[i].tar))
+ return (u64)in_le32(&in[i].barh) << 32 |
+ in_le32(&in[i].barl);
+ }
+
+ printk(KERN_WARNING "could not find PCI BAR matching IMMR\n");
+ }
+#endif
+
+#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
+ if (!is_mpc83xx_pci) {
+ u32 base;
+
+ pci_bus_read_config_dword(hose->bus,
+ PCI_DEVFN(0, 0), PCI_BASE_ADDRESS_0, &base);
+ return base;
+ }
+#endif
+
+ return 0;
+}
diff --git a/arch/powerpc/sysdev/fsl_pci.h b/arch/powerpc/sysdev/fsl_pci.h
index a9d8bbebed80..8ad72a11f77b 100644
--- a/arch/powerpc/sysdev/fsl_pci.h
+++ b/arch/powerpc/sysdev/fsl_pci.h
@@ -88,6 +88,7 @@ struct ccsr_pci {
extern int fsl_add_bridge(struct device_node *dev, int is_primary);
extern void fsl_pcibios_fixup_bus(struct pci_bus *bus);
extern int mpc83xx_add_bridge(struct device_node *dev);
+u64 fsl_pci_immrbar_base(struct pci_controller *hose);
#endif /* __POWERPC_FSL_PCI_H */
#endif /* __KERNEL__ */
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 3017532319c8..412763672d23 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -117,44 +117,59 @@ struct rio_atmu_regs {
};
struct rio_msg_regs {
- u32 omr;
- u32 osr;
+ u32 omr; /* 0xD_3000 - Outbound message 0 mode register */
+ u32 osr; /* 0xD_3004 - Outbound message 0 status register */
u32 pad1;
- u32 odqdpar;
+ u32 odqdpar; /* 0xD_300C - Outbound message 0 descriptor queue
+ dequeue pointer address register */
u32 pad2;
- u32 osar;
- u32 odpr;
- u32 odatr;
- u32 odcr;
+ u32 osar; /* 0xD_3014 - Outbound message 0 source address
+ register */
+ u32 odpr; /* 0xD_3018 - Outbound message 0 destination port
+ register */
+ u32 odatr; /* 0xD_301C - Outbound message 0 destination attributes
+ Register*/
+ u32 odcr; /* 0xD_3020 - Outbound message 0 double-word count
+ register */
u32 pad3;
- u32 odqepar;
+ u32 odqepar; /* 0xD_3028 - Outbound message 0 descriptor queue
+ enqueue pointer address register */
u32 pad4[13];
- u32 imr;
- u32 isr;
+ u32 imr; /* 0xD_3060 - Inbound message 0 mode register */
+ u32 isr; /* 0xD_3064 - Inbound message 0 status register */
u32 pad5;
- u32 ifqdpar;
+ u32 ifqdpar; /* 0xD_306C - Inbound message 0 frame queue dequeue
+ pointer address register*/
u32 pad6;
- u32 ifqepar;
+ u32 ifqepar; /* 0xD_3074 - Inbound message 0 frame queue enqueue
+ pointer address register */
u32 pad7[226];
- u32 odmr;
- u32 odsr;
+ u32 odmr; /* 0xD_3400 - Outbound doorbell mode register */
+ u32 odsr; /* 0xD_3404 - Outbound doorbell status register */
u32 res0[4];
- u32 oddpr;
- u32 oddatr;
+ u32 oddpr; /* 0xD_3418 - Outbound doorbell destination port
+ register */
+ u32 oddatr; /* 0xD_341c - Outbound doorbell destination attributes
+ register */
u32 res1[3];
- u32 odretcr;
+ u32 odretcr; /* 0xD_342C - Outbound doorbell retry error threshold
+ configuration register */
u32 res2[12];
- u32 dmr;
- u32 dsr;
+ u32 dmr; /* 0xD_3460 - Inbound doorbell mode register */
+ u32 dsr; /* 0xD_3464 - Inbound doorbell status register */
u32 pad8;
- u32 dqdpar;
+ u32 dqdpar; /* 0xD_346C - Inbound doorbell queue dequeue Pointer
+ address register */
u32 pad9;
- u32 dqepar;
+ u32 dqepar; /* 0xD_3474 - Inbound doorbell Queue enqueue pointer
+ address register */
u32 pad10[26];
- u32 pwmr;
- u32 pwsr;
- u32 epwqbar;
- u32 pwqbar;
+ u32 pwmr; /* 0xD_34E0 - Inbound port-write mode register */
+ u32 pwsr; /* 0xD_34E4 - Inbound port-write status register */
+ u32 epwqbar; /* 0xD_34E8 - Extended Port-Write Queue Base Address
+ register */
+ u32 pwqbar; /* 0xD_34EC - Inbound port-write queue base address
+ register */
};
struct rio_tx_desc {
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index b91f7acdda6f..19e5015e039b 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -209,186 +209,29 @@ static int __init of_add_fixed_phys(void)
arch_initcall(of_add_fixed_phys);
#endif /* CONFIG_FIXED_PHY */
-static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type)
-{
- if (!phy_type)
- return FSL_USB2_PHY_NONE;
- if (!strcasecmp(phy_type, "ulpi"))
- return FSL_USB2_PHY_ULPI;
- if (!strcasecmp(phy_type, "utmi"))
- return FSL_USB2_PHY_UTMI;
- if (!strcasecmp(phy_type, "utmi_wide"))
- return FSL_USB2_PHY_UTMI_WIDE;
- if (!strcasecmp(phy_type, "serial"))
- return FSL_USB2_PHY_SERIAL;
-
- return FSL_USB2_PHY_NONE;
-}
+#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
+static __be32 __iomem *rstcr;
-static int __init fsl_usb_of_init(void)
+static int __init setup_rstcr(void)
{
struct device_node *np;
- unsigned int i = 0;
- struct platform_device *usb_dev_mph = NULL, *usb_dev_dr_host = NULL,
- *usb_dev_dr_client = NULL;
- int ret;
-
- for_each_compatible_node(np, NULL, "fsl-usb2-mph") {
- struct resource r[2];
- struct fsl_usb2_platform_data usb_data;
- const unsigned char *prop = NULL;
-
- memset(&r, 0, sizeof(r));
- memset(&usb_data, 0, sizeof(usb_data));
-
- ret = of_address_to_resource(np, 0, &r[0]);
- if (ret)
- goto err;
-
- of_irq_to_resource(np, 0, &r[1]);
-
- usb_dev_mph =
- platform_device_register_simple("fsl-ehci", i, r, 2);
- if (IS_ERR(usb_dev_mph)) {
- ret = PTR_ERR(usb_dev_mph);
- goto err;
- }
-
- usb_dev_mph->dev.coherent_dma_mask = 0xffffffffUL;
- usb_dev_mph->dev.dma_mask = &usb_dev_mph->dev.coherent_dma_mask;
-
- usb_data.operating_mode = FSL_USB2_MPH_HOST;
-
- prop = of_get_property(np, "port0", NULL);
- if (prop)
- usb_data.port_enables |= FSL_USB2_PORT0_ENABLED;
-
- prop = of_get_property(np, "port1", NULL);
- if (prop)
- usb_data.port_enables |= FSL_USB2_PORT1_ENABLED;
-
- prop = of_get_property(np, "phy_type", NULL);
- usb_data.phy_mode = determine_usb_phy(prop);
-
- ret =
- platform_device_add_data(usb_dev_mph, &usb_data,
- sizeof(struct
- fsl_usb2_platform_data));
- if (ret)
- goto unreg_mph;
- i++;
- }
-
- for_each_compatible_node(np, NULL, "fsl-usb2-dr") {
- struct resource r[2];
- struct fsl_usb2_platform_data usb_data;
- const unsigned char *prop = NULL;
- if (!of_device_is_available(np))
- continue;
-
- memset(&r, 0, sizeof(r));
- memset(&usb_data, 0, sizeof(usb_data));
-
- ret = of_address_to_resource(np, 0, &r[0]);
- if (ret)
- goto unreg_mph;
-
- of_irq_to_resource(np, 0, &r[1]);
-
- prop = of_get_property(np, "dr_mode", NULL);
-
- if (!prop || !strcmp(prop, "host")) {
- usb_data.operating_mode = FSL_USB2_DR_HOST;
- usb_dev_dr_host = platform_device_register_simple(
- "fsl-ehci", i, r, 2);
- if (IS_ERR(usb_dev_dr_host)) {
- ret = PTR_ERR(usb_dev_dr_host);
- goto err;
- }
- } else if (prop && !strcmp(prop, "peripheral")) {
- usb_data.operating_mode = FSL_USB2_DR_DEVICE;
- usb_dev_dr_client = platform_device_register_simple(
- "fsl-usb2-udc", i, r, 2);
- if (IS_ERR(usb_dev_dr_client)) {
- ret = PTR_ERR(usb_dev_dr_client);
- goto err;
- }
- } else if (prop && !strcmp(prop, "otg")) {
- usb_data.operating_mode = FSL_USB2_DR_OTG;
- usb_dev_dr_host = platform_device_register_simple(
- "fsl-ehci", i, r, 2);
- if (IS_ERR(usb_dev_dr_host)) {
- ret = PTR_ERR(usb_dev_dr_host);
- goto err;
- }
- usb_dev_dr_client = platform_device_register_simple(
- "fsl-usb2-udc", i, r, 2);
- if (IS_ERR(usb_dev_dr_client)) {
- ret = PTR_ERR(usb_dev_dr_client);
- goto err;
- }
- } else {
- ret = -EINVAL;
- goto err;
+ for_each_node_by_name(np, "global-utilities") {
+ if ((of_get_property(np, "fsl,has-rstcr", NULL))) {
+ rstcr = of_iomap(np, 0) + 0xb0;
+ if (!rstcr)
+ printk (KERN_ERR "Error: reset control "
+ "register not mapped!\n");
+ break;
}
-
- prop = of_get_property(np, "phy_type", NULL);
- usb_data.phy_mode = determine_usb_phy(prop);
-
- if (usb_dev_dr_host) {
- usb_dev_dr_host->dev.coherent_dma_mask = 0xffffffffUL;
- usb_dev_dr_host->dev.dma_mask = &usb_dev_dr_host->
- dev.coherent_dma_mask;
- if ((ret = platform_device_add_data(usb_dev_dr_host,
- &usb_data, sizeof(struct
- fsl_usb2_platform_data))))
- goto unreg_dr;
- }
- if (usb_dev_dr_client) {
- usb_dev_dr_client->dev.coherent_dma_mask = 0xffffffffUL;
- usb_dev_dr_client->dev.dma_mask = &usb_dev_dr_client->
- dev.coherent_dma_mask;
- if ((ret = platform_device_add_data(usb_dev_dr_client,
- &usb_data, sizeof(struct
- fsl_usb2_platform_data))))
- goto unreg_dr;
- }
- i++;
}
- return 0;
-
-unreg_dr:
- if (usb_dev_dr_host)
- platform_device_unregister(usb_dev_dr_host);
- if (usb_dev_dr_client)
- platform_device_unregister(usb_dev_dr_client);
-unreg_mph:
- if (usb_dev_mph)
- platform_device_unregister(usb_dev_mph);
-err:
- return ret;
-}
-
-arch_initcall(fsl_usb_of_init);
-
-#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
-static __be32 __iomem *rstcr;
-static int __init setup_rstcr(void)
-{
- struct device_node *np;
- np = of_find_node_by_name(NULL, "global-utilities");
- if ((np && of_get_property(np, "fsl,has-rstcr", NULL))) {
- rstcr = of_iomap(np, 0) + 0xb0;
- if (!rstcr)
- printk (KERN_EMERG "Error: reset control register "
- "not mapped!\n");
- } else if (ppc_md.restart == fsl_rstcr_restart)
+ if (!rstcr && ppc_md.restart == fsl_rstcr_restart)
printk(KERN_ERR "No RSTCR register, warm reboot won't work\n");
if (np)
of_node_put(np);
+
return 0;
}
diff --git a/arch/powerpc/sysdev/mpc8xxx_gpio.c b/arch/powerpc/sysdev/mpc8xxx_gpio.c
index 2b69084d0f0c..c0ea05e87f1d 100644
--- a/arch/powerpc/sysdev/mpc8xxx_gpio.c
+++ b/arch/powerpc/sysdev/mpc8xxx_gpio.c
@@ -330,6 +330,9 @@ static int __init mpc8xxx_add_gpiochips(void)
for_each_compatible_node(np, NULL, "fsl,mpc8610-gpio")
mpc8xxx_add_controller(np);
+ for_each_compatible_node(np, NULL, "fsl,qoriq-gpio")
+ mpc8xxx_add_controller(np);
+
return 0;
}
arch_initcall(mpc8xxx_add_gpiochips);
diff --git a/arch/powerpc/sysdev/mpic_pasemi_msi.c b/arch/powerpc/sysdev/mpic_pasemi_msi.c
index 3b6a9a43718f..320ad5a9a25d 100644
--- a/arch/powerpc/sysdev/mpic_pasemi_msi.c
+++ b/arch/powerpc/sysdev/mpic_pasemi_msi.c
@@ -39,24 +39,24 @@
static struct mpic *msi_mpic;
-static void mpic_pasemi_msi_mask_irq(unsigned int irq)
+static void mpic_pasemi_msi_mask_irq(struct irq_data *data)
{
- pr_debug("mpic_pasemi_msi_mask_irq %d\n", irq);
- mask_msi_irq(irq);
- mpic_mask_irq(irq);
+ pr_debug("mpic_pasemi_msi_mask_irq %d\n", data->irq);
+ mask_msi_irq(data);
+ mpic_mask_irq(data->irq);
}
-static void mpic_pasemi_msi_unmask_irq(unsigned int irq)
+static void mpic_pasemi_msi_unmask_irq(struct irq_data *data)
{
- pr_debug("mpic_pasemi_msi_unmask_irq %d\n", irq);
- mpic_unmask_irq(irq);
- unmask_msi_irq(irq);
+ pr_debug("mpic_pasemi_msi_unmask_irq %d\n", data->irq);
+ mpic_unmask_irq(data->irq);
+ unmask_msi_irq(data);
}
static struct irq_chip mpic_pasemi_msi_chip = {
- .shutdown = mpic_pasemi_msi_mask_irq,
- .mask = mpic_pasemi_msi_mask_irq,
- .unmask = mpic_pasemi_msi_unmask_irq,
+ .irq_shutdown = mpic_pasemi_msi_mask_irq,
+ .irq_mask = mpic_pasemi_msi_mask_irq,
+ .irq_unmask = mpic_pasemi_msi_unmask_irq,
.eoi = mpic_end_irq,
.set_type = mpic_set_irq_type,
.set_affinity = mpic_set_affinity,
diff --git a/arch/powerpc/sysdev/mpic_u3msi.c b/arch/powerpc/sysdev/mpic_u3msi.c
index bcbfe79c704b..a2b028b4a202 100644
--- a/arch/powerpc/sysdev/mpic_u3msi.c
+++ b/arch/powerpc/sysdev/mpic_u3msi.c
@@ -23,22 +23,22 @@
/* A bit ugly, can we get this from the pci_dev somehow? */
static struct mpic *msi_mpic;
-static void mpic_u3msi_mask_irq(unsigned int irq)
+static void mpic_u3msi_mask_irq(struct irq_data *data)
{
- mask_msi_irq(irq);
- mpic_mask_irq(irq);
+ mask_msi_irq(data);
+ mpic_mask_irq(data->irq);
}
-static void mpic_u3msi_unmask_irq(unsigned int irq)
+static void mpic_u3msi_unmask_irq(struct irq_data *data)
{
- mpic_unmask_irq(irq);
- unmask_msi_irq(irq);
+ mpic_unmask_irq(data->irq);
+ unmask_msi_irq(data);
}
static struct irq_chip mpic_u3msi_chip = {
- .shutdown = mpic_u3msi_mask_irq,
- .mask = mpic_u3msi_mask_irq,
- .unmask = mpic_u3msi_unmask_irq,
+ .irq_shutdown = mpic_u3msi_mask_irq,
+ .irq_mask = mpic_u3msi_mask_irq,
+ .irq_unmask = mpic_u3msi_unmask_irq,
.eoi = mpic_end_irq,
.set_type = mpic_set_irq_type,
.set_affinity = mpic_set_affinity,
diff --git a/arch/powerpc/sysdev/pmi.c b/arch/powerpc/sysdev/pmi.c
index 24a0bb955b18..4260f368db52 100644
--- a/arch/powerpc/sysdev/pmi.c
+++ b/arch/powerpc/sysdev/pmi.c
@@ -114,7 +114,7 @@ static void pmi_notify_handlers(struct work_struct *work)
spin_lock(&data->handler_spinlock);
list_for_each_entry(handler, &data->handler, node) {
- pr_debug(KERN_INFO "pmi: notifying handler %p\n", handler);
+ pr_debug("pmi: notifying handler %p\n", handler);
if (handler->type == data->msg.type)
handler->handle_pmi_message(data->msg);
}
diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile
index faa81b6a6612..c168c54e3c40 100644
--- a/arch/powerpc/xmon/Makefile
+++ b/arch/powerpc/xmon/Makefile
@@ -4,9 +4,7 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
GCOV_PROFILE := n
-ifdef CONFIG_PPC64
-EXTRA_CFLAGS += -mno-minimal-toc
-endif
+ccflags-$(CONFIG_PPC64) := -mno-minimal-toc
obj-y += xmon.o start.o nonstdio.o
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index f0777a47e3a5..75976a141947 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -95,6 +95,7 @@ config S390
select HAVE_KVM if 64BIT
select HAVE_ARCH_TRACEHOOK
select INIT_ALL_POSSIBLE
+ select HAVE_IRQ_WORK
select HAVE_PERF_EVENTS
select HAVE_KERNEL_GZIP
select HAVE_KERNEL_BZIP2
@@ -198,6 +199,13 @@ config HOTPLUG_CPU
can be controlled through /sys/devices/system/cpu/cpu#.
Say N if you want to disable CPU hotplug.
+config SCHED_BOOK
+ bool "Book scheduler support"
+ depends on SMP
+ help
+ Book scheduler support improves the CPU scheduler's decision making
+ when dealing with machines that have several books.
+
config MATHEMU
bool "IEEE FPU emulation"
depends on MARCH_G5
diff --git a/arch/s390/crypto/prng.c b/arch/s390/crypto/prng.c
index aa819dac2360..975e3ab13cb5 100644
--- a/arch/s390/crypto/prng.c
+++ b/arch/s390/crypto/prng.c
@@ -152,6 +152,7 @@ static const struct file_operations prng_fops = {
.open = &prng_open,
.release = NULL,
.read = &prng_read,
+ .llseek = noop_llseek,
};
static struct miscdevice prng_dev = {
diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c
index 1211bb1d2f24..020e51c063d2 100644
--- a/arch/s390/hypfs/hypfs_diag.c
+++ b/arch/s390/hypfs/hypfs_diag.c
@@ -618,6 +618,7 @@ static const struct file_operations dbfs_d204_ops = {
.open = dbfs_d204_open,
.read = dbfs_d204_read,
.release = dbfs_d204_release,
+ .llseek = no_llseek,
};
static int hypfs_dbfs_init(void)
diff --git a/arch/s390/hypfs/hypfs_vm.c b/arch/s390/hypfs/hypfs_vm.c
index ee5ab1a578e7..26cf177f6a3a 100644
--- a/arch/s390/hypfs/hypfs_vm.c
+++ b/arch/s390/hypfs/hypfs_vm.c
@@ -275,6 +275,7 @@ static const struct file_operations dbfs_d2fc_ops = {
.open = dbfs_d2fc_open,
.read = dbfs_d2fc_read,
.release = dbfs_d2fc_release,
+ .llseek = no_llseek,
};
int hypfs_vm_init(void)
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c
index 98a4a4c267a7..74d98670be27 100644
--- a/arch/s390/hypfs/inode.c
+++ b/arch/s390/hypfs/inode.c
@@ -449,6 +449,7 @@ static const struct file_operations hypfs_file_ops = {
.write = do_sync_write,
.aio_read = hypfs_aio_read,
.aio_write = hypfs_aio_write,
+ .llseek = no_llseek,
};
static struct file_system_type hypfs_type = {
diff --git a/arch/s390/include/asm/Kbuild b/arch/s390/include/asm/Kbuild
index 42e512ba8b43..287d7bbb6d36 100644
--- a/arch/s390/include/asm/Kbuild
+++ b/arch/s390/include/asm/Kbuild
@@ -5,6 +5,7 @@ header-y += chsc.h
header-y += cmb.h
header-y += dasd.h
header-y += debug.h
+header-y += kvm_virtio.h
header-y += monwriter.h
header-y += qeth.h
header-y += schid.h
diff --git a/arch/s390/include/asm/hardirq.h b/arch/s390/include/asm/hardirq.h
index 498bc3892385..881d94590aeb 100644
--- a/arch/s390/include/asm/hardirq.h
+++ b/arch/s390/include/asm/hardirq.h
@@ -12,10 +12,6 @@
#ifndef __ASM_HARDIRQ_H
#define __ASM_HARDIRQ_H
-#include <linux/threads.h>
-#include <linux/sched.h>
-#include <linux/cache.h>
-#include <linux/interrupt.h>
#include <asm/lowcore.h>
#define local_softirq_pending() (S390_lowcore.softirq_pending)
diff --git a/arch/s390/include/asm/ioctls.h b/arch/s390/include/asm/ioctls.h
index 2f3d8736361f..960a4c1ebdf1 100644
--- a/arch/s390/include/asm/ioctls.h
+++ b/arch/s390/include/asm/ioctls.h
@@ -1,94 +1,8 @@
-/*
- * include/asm-s390/ioctls.h
- *
- * S390 version
- *
- * Derived from "include/asm-i386/ioctls.h"
- */
-
#ifndef __ARCH_S390_IOCTLS_H__
#define __ARCH_S390_IOCTLS_H__
-#include <asm/ioctl.h>
-
-/* 0x54 is just a magic number to make these relatively unique ('T') */
-
-#define TCGETS 0x5401
-#define TCSETS 0x5402
-#define TCSETSW 0x5403
-#define TCSETSF 0x5404
-#define TCGETA 0x5405
-#define TCSETA 0x5406
-#define TCSETAW 0x5407
-#define TCSETAF 0x5408
-#define TCSBRK 0x5409
-#define TCXONC 0x540A
-#define TCFLSH 0x540B
-#define TIOCEXCL 0x540C
-#define TIOCNXCL 0x540D
-#define TIOCSCTTY 0x540E
-#define TIOCGPGRP 0x540F
-#define TIOCSPGRP 0x5410
-#define TIOCOUTQ 0x5411
-#define TIOCSTI 0x5412
-#define TIOCGWINSZ 0x5413
-#define TIOCSWINSZ 0x5414
-#define TIOCMGET 0x5415
-#define TIOCMBIS 0x5416
-#define TIOCMBIC 0x5417
-#define TIOCMSET 0x5418
-#define TIOCGSOFTCAR 0x5419
-#define TIOCSSOFTCAR 0x541A
-#define FIONREAD 0x541B
-#define TIOCINQ FIONREAD
-#define TIOCLINUX 0x541C
-#define TIOCCONS 0x541D
-#define TIOCGSERIAL 0x541E
-#define TIOCSSERIAL 0x541F
-#define TIOCPKT 0x5420
-#define FIONBIO 0x5421
-#define TIOCNOTTY 0x5422
-#define TIOCSETD 0x5423
-#define TIOCGETD 0x5424
-#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
-#define TIOCSBRK 0x5427 /* BSD compatibility */
-#define TIOCCBRK 0x5428 /* BSD compatibility */
-#define TIOCGSID 0x5429 /* Return the session ID of FD */
-#define TCGETS2 _IOR('T',0x2A, struct termios2)
-#define TCSETS2 _IOW('T',0x2B, struct termios2)
-#define TCSETSW2 _IOW('T',0x2C, struct termios2)
-#define TCSETSF2 _IOW('T',0x2D, struct termios2)
-#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
-#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
-#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */
-
-#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */
-#define FIOCLEX 0x5451
-#define FIOASYNC 0x5452
-#define TIOCSERCONFIG 0x5453
-#define TIOCSERGWILD 0x5454
-#define TIOCSERSWILD 0x5455
-#define TIOCGLCKTRMIOS 0x5456
-#define TIOCSLCKTRMIOS 0x5457
-#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
-#define TIOCSERGETLSR 0x5459 /* Get line status register */
-#define TIOCSERGETMULTI 0x545A /* Get multiport config */
-#define TIOCSERSETMULTI 0x545B /* Set multiport config */
-
-#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
-#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
#define FIOQSIZE 0x545E
-/* Used for packet mode */
-#define TIOCPKT_DATA 0
-#define TIOCPKT_FLUSHREAD 1
-#define TIOCPKT_FLUSHWRITE 2
-#define TIOCPKT_STOP 4
-#define TIOCPKT_START 8
-#define TIOCPKT_NOSTOP 16
-#define TIOCPKT_DOSTOP 32
-#define TIOCPKT_IOCTL 64
-
-#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
+#include <asm-generic/ioctls.h>
#endif
diff --git a/arch/s390/include/asm/irqflags.h b/arch/s390/include/asm/irqflags.h
index 15b3ac253898..865d6d891ace 100644
--- a/arch/s390/include/asm/irqflags.h
+++ b/arch/s390/include/asm/irqflags.h
@@ -8,8 +8,8 @@
#include <linux/types.h>
-/* store then or system mask. */
-#define __raw_local_irq_stosm(__or) \
+/* store then OR system mask. */
+#define __arch_local_irq_stosm(__or) \
({ \
unsigned long __mask; \
asm volatile( \
@@ -18,8 +18,8 @@
__mask; \
})
-/* store then and system mask. */
-#define __raw_local_irq_stnsm(__and) \
+/* store then AND system mask. */
+#define __arch_local_irq_stnsm(__and) \
({ \
unsigned long __mask; \
asm volatile( \
@@ -29,39 +29,44 @@
})
/* set system mask. */
-#define __raw_local_irq_ssm(__mask) \
-({ \
- asm volatile("ssm %0" : : "Q" (__mask) : "memory"); \
-})
+static inline void __arch_local_irq_ssm(unsigned long flags)
+{
+ asm volatile("ssm %0" : : "Q" (flags) : "memory");
+}
-/* interrupt control.. */
-static inline unsigned long raw_local_irq_enable(void)
+static inline unsigned long arch_local_save_flags(void)
{
- return __raw_local_irq_stosm(0x03);
+ return __arch_local_irq_stosm(0x00);
}
-static inline unsigned long raw_local_irq_disable(void)
+static inline unsigned long arch_local_irq_save(void)
{
- return __raw_local_irq_stnsm(0xfc);
+ return __arch_local_irq_stnsm(0xfc);
}
-#define raw_local_save_flags(x) \
-do { \
- typecheck(unsigned long, x); \
- (x) = __raw_local_irq_stosm(0x00); \
-} while (0)
+static inline void arch_local_irq_disable(void)
+{
+ arch_local_irq_save();
+}
-static inline void raw_local_irq_restore(unsigned long flags)
+static inline void arch_local_irq_enable(void)
{
- __raw_local_irq_ssm(flags);
+ __arch_local_irq_stosm(0x03);
}
-static inline int raw_irqs_disabled_flags(unsigned long flags)
+static inline void arch_local_irq_restore(unsigned long flags)
+{
+ __arch_local_irq_ssm(flags);
+}
+
+static inline bool arch_irqs_disabled_flags(unsigned long flags)
{
return !(flags & (3UL << (BITS_PER_LONG - 8)));
}
-/* For spinlocks etc */
-#define raw_local_irq_save(x) ((x) = raw_local_irq_disable())
+static inline bool arch_irqs_disabled(void)
+{
+ return arch_irqs_disabled_flags(arch_local_save_flags());
+}
#endif /* __ASM_IRQFLAGS_H */
diff --git a/arch/s390/include/asm/kvm_virtio.h b/arch/s390/include/asm/kvm_virtio.h
index acdfdff26611..72f614181eff 100644
--- a/arch/s390/include/asm/kvm_virtio.h
+++ b/arch/s390/include/asm/kvm_virtio.h
@@ -54,4 +54,11 @@ struct kvm_vqconfig {
* This is pagesize for historical reasons. */
#define KVM_S390_VIRTIO_RING_ALIGN 4096
+
+/* These values are supposed to be in ext_params on an interrupt */
+#define VIRTIO_PARAM_MASK 0xff
+#define VIRTIO_PARAM_VRING_INTERRUPT 0x0
+#define VIRTIO_PARAM_CONFIG_CHANGED 0x1
+#define VIRTIO_PARAM_DEV_ADD 0x2
+
#endif
diff --git a/arch/s390/include/asm/perf_event.h b/arch/s390/include/asm/perf_event.h
index 3840cbe77637..a75f168d2718 100644
--- a/arch/s390/include/asm/perf_event.h
+++ b/arch/s390/include/asm/perf_event.h
@@ -4,7 +4,6 @@
* Copyright 2009 Martin Schwidefsky, IBM Corporation.
*/
-static inline void set_perf_event_pending(void) {}
-static inline void clear_perf_event_pending(void) {}
+/* Empty, just to avoid compiling error */
#define PERF_EVENT_INDEX_OFFSET 0
diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h
index 2ba630276295..46e96bc1f5a1 100644
--- a/arch/s390/include/asm/qdio.h
+++ b/arch/s390/include/asm/qdio.h
@@ -360,6 +360,7 @@ struct qdio_initialize {
unsigned int no_output_qs;
qdio_handler_t *input_handler;
qdio_handler_t *output_handler;
+ void (*queue_start_poll) (struct ccw_device *, int, unsigned long);
unsigned long int_parm;
void **input_sbal_addr_array;
void **output_sbal_addr_array;
@@ -377,11 +378,13 @@ struct qdio_initialize {
extern int qdio_allocate(struct qdio_initialize *);
extern int qdio_establish(struct qdio_initialize *);
extern int qdio_activate(struct ccw_device *);
-
-extern int do_QDIO(struct ccw_device *cdev, unsigned int callflags,
- int q_nr, unsigned int bufnr, unsigned int count);
-extern int qdio_shutdown(struct ccw_device*, int);
+extern int do_QDIO(struct ccw_device *, unsigned int, int, unsigned int,
+ unsigned int);
+extern int qdio_start_irq(struct ccw_device *, int);
+extern int qdio_stop_irq(struct ccw_device *, int);
+extern int qdio_get_next_buffers(struct ccw_device *, int, int *, int *);
+extern int qdio_shutdown(struct ccw_device *, int);
extern int qdio_free(struct ccw_device *);
-extern int qdio_get_ssqd_desc(struct ccw_device *dev, struct qdio_ssqd_desc*);
+extern int qdio_get_ssqd_desc(struct ccw_device *, struct qdio_ssqd_desc *);
#endif /* __QDIO_H__ */
diff --git a/arch/s390/include/asm/system.h b/arch/s390/include/asm/system.h
index cef66210c846..1f2ebc4afd82 100644
--- a/arch/s390/include/asm/system.h
+++ b/arch/s390/include/asm/system.h
@@ -97,7 +97,6 @@ static inline void restore_access_regs(unsigned int *acrs)
extern void account_vtime(struct task_struct *, struct task_struct *);
extern void account_tick_vtime(struct task_struct *);
-extern void account_system_vtime(struct task_struct *);
#ifdef CONFIG_PFAULT
extern void pfault_irq_init(void);
@@ -399,7 +398,7 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr,
static inline void
__set_psw_mask(unsigned long mask)
{
- __load_psw_mask(mask | (__raw_local_irq_stosm(0x00) & ~(-1UL >> 8)));
+ __load_psw_mask(mask | (arch_local_save_flags() & ~(-1UL >> 8)));
}
#define local_mcck_enable() __set_psw_mask(psw_kernel_bits)
diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h
index 831bd033ea77..051107a2c5e2 100644
--- a/arch/s390/include/asm/topology.h
+++ b/arch/s390/include/asm/topology.h
@@ -3,15 +3,32 @@
#include <linux/cpumask.h>
-#define mc_capable() (1)
-
-const struct cpumask *cpu_coregroup_mask(unsigned int cpu);
-
extern unsigned char cpu_core_id[NR_CPUS];
extern cpumask_t cpu_core_map[NR_CPUS];
+static inline const struct cpumask *cpu_coregroup_mask(unsigned int cpu)
+{
+ return &cpu_core_map[cpu];
+}
+
#define topology_core_id(cpu) (cpu_core_id[cpu])
#define topology_core_cpumask(cpu) (&cpu_core_map[cpu])
+#define mc_capable() (1)
+
+#ifdef CONFIG_SCHED_BOOK
+
+extern unsigned char cpu_book_id[NR_CPUS];
+extern cpumask_t cpu_book_map[NR_CPUS];
+
+static inline const struct cpumask *cpu_book_mask(unsigned int cpu)
+{
+ return &cpu_book_map[cpu];
+}
+
+#define topology_book_id(cpu) (cpu_book_id[cpu])
+#define topology_book_cpumask(cpu) (&cpu_book_map[cpu])
+
+#endif /* CONFIG_SCHED_BOOK */
int topology_set_cpu_management(int fc);
void topology_schedule_update(void);
@@ -30,6 +47,8 @@ static inline void s390_init_cpu_topology(void)
};
#endif
+#define SD_BOOK_INIT SD_CPU_INIT
+
#include <asm-generic/topology.h>
#endif /* _ASM_S390_TOPOLOGY_H */
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
index 98192261491d..5ad6bc078bfd 100644
--- a/arch/s390/kernel/debug.c
+++ b/arch/s390/kernel/debug.c
@@ -174,6 +174,7 @@ static const struct file_operations debug_file_ops = {
.write = debug_input,
.open = debug_open,
.release = debug_close,
+ .llseek = no_llseek,
};
static struct dentry *debug_debugfs_root_entry;
diff --git a/arch/s390/kernel/mem_detect.c b/arch/s390/kernel/mem_detect.c
index 559af0d07878..0fbe4e32f7ba 100644
--- a/arch/s390/kernel/mem_detect.c
+++ b/arch/s390/kernel/mem_detect.c
@@ -54,11 +54,11 @@ void detect_memory_layout(struct mem_chunk chunk[])
* right thing and we don't get scheduled away with low address
* protection disabled.
*/
- flags = __raw_local_irq_stnsm(0xf8);
+ flags = __arch_local_irq_stnsm(0xf8);
__ctl_store(cr0, 0, 0);
__ctl_clear_bit(0, 28);
find_memory_chunks(chunk);
__ctl_load(cr0, 0, 0);
- __raw_local_irq_ssm(flags);
+ arch_local_irq_restore(flags);
}
EXPORT_SYMBOL(detect_memory_layout);
diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c
index 22cfd634c355..f7167ee4604c 100644
--- a/arch/s390/kernel/module.c
+++ b/arch/s390/kernel/module.c
@@ -407,10 +407,9 @@ int module_finalize(const Elf_Ehdr *hdr,
{
vfree(me->arch.syminfo);
me->arch.syminfo = NULL;
- return module_bug_finalize(hdr, sechdrs, me);
+ return 0;
}
void module_arch_cleanup(struct module *mod)
{
- module_bug_cleanup(mod);
}
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c
index bcef00766a64..13559c993847 100644
--- a/arch/s390/kernel/topology.c
+++ b/arch/s390/kernel/topology.c
@@ -57,8 +57,8 @@ struct tl_info {
union tl_entry tle[0];
};
-struct core_info {
- struct core_info *next;
+struct mask_info {
+ struct mask_info *next;
unsigned char id;
cpumask_t mask;
};
@@ -66,7 +66,6 @@ struct core_info {
static int topology_enabled;
static void topology_work_fn(struct work_struct *work);
static struct tl_info *tl_info;
-static struct core_info core_info;
static int machine_has_topology;
static struct timer_list topology_timer;
static void set_topology_timer(void);
@@ -74,38 +73,37 @@ static DECLARE_WORK(topology_work, topology_work_fn);
/* topology_lock protects the core linked list */
static DEFINE_SPINLOCK(topology_lock);
+static struct mask_info core_info;
cpumask_t cpu_core_map[NR_CPUS];
unsigned char cpu_core_id[NR_CPUS];
-static cpumask_t cpu_coregroup_map(unsigned int cpu)
+#ifdef CONFIG_SCHED_BOOK
+static struct mask_info book_info;
+cpumask_t cpu_book_map[NR_CPUS];
+unsigned char cpu_book_id[NR_CPUS];
+#endif
+
+static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu)
{
- struct core_info *core = &core_info;
- unsigned long flags;
cpumask_t mask;
cpus_clear(mask);
if (!topology_enabled || !machine_has_topology)
return cpu_possible_map;
- spin_lock_irqsave(&topology_lock, flags);
- while (core) {
- if (cpu_isset(cpu, core->mask)) {
- mask = core->mask;
+ while (info) {
+ if (cpu_isset(cpu, info->mask)) {
+ mask = info->mask;
break;
}
- core = core->next;
+ info = info->next;
}
- spin_unlock_irqrestore(&topology_lock, flags);
if (cpus_empty(mask))
mask = cpumask_of_cpu(cpu);
return mask;
}
-const struct cpumask *cpu_coregroup_mask(unsigned int cpu)
-{
- return &cpu_core_map[cpu];
-}
-
-static void add_cpus_to_core(struct tl_cpu *tl_cpu, struct core_info *core)
+static void add_cpus_to_mask(struct tl_cpu *tl_cpu, struct mask_info *book,
+ struct mask_info *core)
{
unsigned int cpu;
@@ -117,23 +115,35 @@ static void add_cpus_to_core(struct tl_cpu *tl_cpu, struct core_info *core)
rcpu = CPU_BITS - 1 - cpu + tl_cpu->origin;
for_each_present_cpu(lcpu) {
- if (cpu_logical_map(lcpu) == rcpu) {
- cpu_set(lcpu, core->mask);
- cpu_core_id[lcpu] = core->id;
- smp_cpu_polarization[lcpu] = tl_cpu->pp;
- }
+ if (cpu_logical_map(lcpu) != rcpu)
+ continue;
+#ifdef CONFIG_SCHED_BOOK
+ cpu_set(lcpu, book->mask);
+ cpu_book_id[lcpu] = book->id;
+#endif
+ cpu_set(lcpu, core->mask);
+ cpu_core_id[lcpu] = core->id;
+ smp_cpu_polarization[lcpu] = tl_cpu->pp;
}
}
}
-static void clear_cores(void)
+static void clear_masks(void)
{
- struct core_info *core = &core_info;
+ struct mask_info *info;
- while (core) {
- cpus_clear(core->mask);
- core = core->next;
+ info = &core_info;
+ while (info) {
+ cpus_clear(info->mask);
+ info = info->next;
+ }
+#ifdef CONFIG_SCHED_BOOK
+ info = &book_info;
+ while (info) {
+ cpus_clear(info->mask);
+ info = info->next;
}
+#endif
}
static union tl_entry *next_tle(union tl_entry *tle)
@@ -146,29 +156,36 @@ static union tl_entry *next_tle(union tl_entry *tle)
static void tl_to_cores(struct tl_info *info)
{
+#ifdef CONFIG_SCHED_BOOK
+ struct mask_info *book = &book_info;
+#else
+ struct mask_info *book = NULL;
+#endif
+ struct mask_info *core = &core_info;
union tl_entry *tle, *end;
- struct core_info *core = &core_info;
+
spin_lock_irq(&topology_lock);
- clear_cores();
+ clear_masks();
tle = info->tle;
end = (union tl_entry *)((unsigned long)info + info->length);
while (tle < end) {
switch (tle->nl) {
- case 5:
- case 4:
- case 3:
+#ifdef CONFIG_SCHED_BOOK
case 2:
+ book = book->next;
+ book->id = tle->container.id;
break;
+#endif
case 1:
core = core->next;
core->id = tle->container.id;
break;
case 0:
- add_cpus_to_core(&tle->cpu, core);
+ add_cpus_to_mask(&tle->cpu, book, core);
break;
default:
- clear_cores();
+ clear_masks();
machine_has_topology = 0;
goto out;
}
@@ -221,10 +238,29 @@ int topology_set_cpu_management(int fc)
static void update_cpu_core_map(void)
{
+ unsigned long flags;
int cpu;
- for_each_possible_cpu(cpu)
- cpu_core_map[cpu] = cpu_coregroup_map(cpu);
+ spin_lock_irqsave(&topology_lock, flags);
+ for_each_possible_cpu(cpu) {
+ cpu_core_map[cpu] = cpu_group_map(&core_info, cpu);
+#ifdef CONFIG_SCHED_BOOK
+ cpu_book_map[cpu] = cpu_group_map(&book_info, cpu);
+#endif
+ }
+ spin_unlock_irqrestore(&topology_lock, flags);
+}
+
+static void store_topology(struct tl_info *info)
+{
+#ifdef CONFIG_SCHED_BOOK
+ int rc;
+
+ rc = stsi(info, 15, 1, 3);
+ if (rc != -ENOSYS)
+ return;
+#endif
+ stsi(info, 15, 1, 2);
}
int arch_update_cpu_topology(void)
@@ -238,7 +274,7 @@ int arch_update_cpu_topology(void)
topology_update_polarization_simple();
return 0;
}
- stsi(info, 15, 1, 2);
+ store_topology(info);
tl_to_cores(info);
update_cpu_core_map();
for_each_online_cpu(cpu) {
@@ -299,12 +335,24 @@ out:
}
__initcall(init_topology_update);
+static void alloc_masks(struct tl_info *info, struct mask_info *mask, int offset)
+{
+ int i, nr_masks;
+
+ nr_masks = info->mag[NR_MAG - offset];
+ for (i = 0; i < info->mnest - offset; i++)
+ nr_masks *= info->mag[NR_MAG - offset - 1 - i];
+ nr_masks = max(nr_masks, 1);
+ for (i = 0; i < nr_masks; i++) {
+ mask->next = alloc_bootmem(sizeof(struct mask_info));
+ mask = mask->next;
+ }
+}
+
void __init s390_init_cpu_topology(void)
{
unsigned long long facility_bits;
struct tl_info *info;
- struct core_info *core;
- int nr_cores;
int i;
if (stfle(&facility_bits, 1) <= 0)
@@ -315,25 +363,13 @@ void __init s390_init_cpu_topology(void)
tl_info = alloc_bootmem_pages(PAGE_SIZE);
info = tl_info;
- stsi(info, 15, 1, 2);
-
- nr_cores = info->mag[NR_MAG - 2];
- for (i = 0; i < info->mnest - 2; i++)
- nr_cores *= info->mag[NR_MAG - 3 - i];
-
+ store_topology(info);
pr_info("The CPU configuration topology of the machine is:");
for (i = 0; i < NR_MAG; i++)
printk(" %d", info->mag[i]);
printk(" / %d\n", info->mnest);
-
- core = &core_info;
- for (i = 0; i < nr_cores; i++) {
- core->next = alloc_bootmem(sizeof(struct core_info));
- core = core->next;
- if (!core)
- goto error;
- }
- return;
-error:
- machine_has_topology = 0;
+ alloc_masks(info, &core_info, 2);
+#ifdef CONFIG_SCHED_BOOK
+ alloc_masks(info, &book_info, 3);
+#endif
}
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index 30eb6d02ddb8..94b8ba2ec857 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -50,7 +50,6 @@ EXPORT_SYMBOL(empty_zero_page);
*/
void __init paging_init(void)
{
- static const int ssm_mask = 0x04000000L;
unsigned long max_zone_pfns[MAX_NR_ZONES];
unsigned long pgd_type;
@@ -72,7 +71,7 @@ void __init paging_init(void)
__ctl_load(S390_lowcore.kernel_asce, 1, 1);
__ctl_load(S390_lowcore.kernel_asce, 7, 7);
__ctl_load(S390_lowcore.kernel_asce, 13, 13);
- __raw_local_irq_ssm(ssm_mask);
+ arch_local_irq_restore(4UL << (BITS_PER_LONG - 8));
atomic_set(&init_mm.context.attach_count, 1);
diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c
index a8c2af8c650f..71a4b0d34be0 100644
--- a/arch/s390/mm/maccess.c
+++ b/arch/s390/mm/maccess.c
@@ -71,7 +71,7 @@ int memcpy_real(void *dest, void *src, size_t count)
if (!count)
return 0;
- flags = __raw_local_irq_stnsm(0xf8UL);
+ flags = __arch_local_irq_stnsm(0xf8UL);
asm volatile (
"0: mvcle %1,%2,0x0\n"
"1: jo 0b\n"
@@ -82,6 +82,6 @@ int memcpy_real(void *dest, void *src, size_t count)
"+d" (_len2), "=m" (*((long *) dest))
: "m" (*((long *) src))
: "cc", "memory");
- __raw_local_irq_ssm(flags);
+ arch_local_irq_restore(flags);
return rc;
}
diff --git a/arch/score/include/asm/irqflags.h b/arch/score/include/asm/irqflags.h
index 690a6cae7294..5c7563891e28 100644
--- a/arch/score/include/asm/irqflags.h
+++ b/arch/score/include/asm/irqflags.h
@@ -3,107 +3,118 @@
#ifndef __ASSEMBLY__
-#define raw_local_irq_save(x) \
-{ \
- __asm__ __volatile__( \
- "mfcr r8, cr0;" \
- "li r9, 0xfffffffe;" \
- "nop;" \
- "mv %0, r8;" \
- "and r8, r8, r9;" \
- "mtcr r8, cr0;" \
- "nop;" \
- "nop;" \
- "nop;" \
- "nop;" \
- "nop;" \
- : "=r" (x) \
- : \
- : "r8", "r9" \
- ); \
+#include <linux/types.h>
+
+static inline unsigned long arch_local_save_flags(void)
+{
+ unsigned long flags;
+
+ asm volatile(
+ " mfcr r8, cr0 \n"
+ " nop \n"
+ " nop \n"
+ " mv %0, r8 \n"
+ " nop \n"
+ " nop \n"
+ " nop \n"
+ " nop \n"
+ " nop \n"
+ " ldi r9, 0x1 \n"
+ " and %0, %0, r9 \n"
+ : "=r" (flags)
+ :
+ : "r8", "r9");
+ return flags;
}
-#define raw_local_irq_restore(x) \
-{ \
- __asm__ __volatile__( \
- "mfcr r8, cr0;" \
- "ldi r9, 0x1;" \
- "and %0, %0, r9;" \
- "or r8, r8, %0;" \
- "mtcr r8, cr0;" \
- "nop;" \
- "nop;" \
- "nop;" \
- "nop;" \
- "nop;" \
- : \
- : "r"(x) \
- : "r8", "r9" \
- ); \
+static inline unsigned long arch_local_irq_save(void)
+{
+ unsigned long flags
+
+ asm volatile(
+ " mfcr r8, cr0 \n"
+ " li r9, 0xfffffffe \n"
+ " nop \n"
+ " mv %0, r8 \n"
+ " and r8, r8, r9 \n"
+ " mtcr r8, cr0 \n"
+ " nop \n"
+ " nop \n"
+ " nop \n"
+ " nop \n"
+ " nop \n"
+ : "=r" (flags)
+ :
+ : "r8", "r9", "memory");
+
+ return flags;
}
-#define raw_local_irq_enable(void) \
-{ \
- __asm__ __volatile__( \
- "mfcr\tr8,cr0;" \
- "nop;" \
- "nop;" \
- "ori\tr8,0x1;" \
- "mtcr\tr8,cr0;" \
- "nop;" \
- "nop;" \
- "nop;" \
- "nop;" \
- "nop;" \
- : \
- : \
- : "r8"); \
+static inline void arch_local_irq_restore(unsigned long flags)
+{
+ asm volatile(
+ " mfcr r8, cr0 \n"
+ " ldi r9, 0x1 \n"
+ " and %0, %0, r9 \n"
+ " or r8, r8, %0 \n"
+ " mtcr r8, cr0 \n"
+ " nop \n"
+ " nop \n"
+ " nop \n"
+ " nop \n"
+ " nop \n"
+ :
+ : "r"(flags)
+ : "r8", "r9", "memory");
}
-#define raw_local_irq_disable(void) \
-{ \
- __asm__ __volatile__( \
- "mfcr\tr8,cr0;" \
- "nop;" \
- "nop;" \
- "srli\tr8,r8,1;" \
- "slli\tr8,r8,1;" \
- "mtcr\tr8,cr0;" \
- "nop;" \
- "nop;" \
- "nop;" \
- "nop;" \
- "nop;" \
- : \
- : \
- : "r8"); \
+static inline void arch_local_irq_enable(void)
+{
+ asm volatile(
+ " mfcr r8,cr0 \n"
+ " nop \n"
+ " nop \n"
+ " ori r8,0x1 \n"
+ " mtcr r8,cr0 \n"
+ " nop \n"
+ " nop \n"
+ " nop \n"
+ " nop \n"
+ " nop \n"
+ :
+ :
+ : "r8", "memory");
}
-#define raw_local_save_flags(x) \
-{ \
- __asm__ __volatile__( \
- "mfcr r8, cr0;" \
- "nop;" \
- "nop;" \
- "mv %0, r8;" \
- "nop;" \
- "nop;" \
- "nop;" \
- "nop;" \
- "nop;" \
- "ldi r9, 0x1;" \
- "and %0, %0, r9;" \
- : "=r" (x) \
- : \
- : "r8", "r9" \
- ); \
+static inline void arch_local_irq_disable(void)
+{
+ asm volatile(
+ " mfcr r8,cr0 \n"
+ " nop \n"
+ " nop \n"
+ " srli r8,r8,1 \n"
+ " slli r8,r8,1 \n"
+ " mtcr r8,cr0 \n"
+ " nop \n"
+ " nop \n"
+ " nop \n"
+ " nop \n"
+ " nop \n"
+ :
+ :
+ : "r8", "memory");
}
-static inline int raw_irqs_disabled_flags(unsigned long flags)
+static inline bool arch_irqs_disabled_flags(unsigned long flags)
{
return !(flags & 1);
}
-#endif
+static inline bool arch_irqs_disabled(void)
+{
+ return arch_irqs_disabled_flags(arch_local_save_flags());
+}
+
+#endif /* __ASSEMBLY__ */
#endif /* _ASM_SCORE_IRQFLAGS_H */
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 33990fa95af0..0f40fc35d0a2 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -16,6 +16,7 @@ config SUPERH
select HAVE_ARCH_TRACEHOOK
select HAVE_DMA_API_DEBUG
select HAVE_DMA_ATTRS
+ select HAVE_IRQ_WORK
select HAVE_PERF_EVENTS
select PERF_USE_VMALLOC
select HAVE_KERNEL_GZIP
@@ -23,6 +24,7 @@ config SUPERH
select HAVE_KERNEL_LZMA
select HAVE_KERNEL_LZO
select HAVE_SYSCALL_TRACEPOINTS
+ select HAVE_REGS_AND_STACK_ACCESS_API
select RTC_LIB
select GENERIC_ATOMIC64
help
@@ -45,7 +47,7 @@ config SUPERH32
select HAVE_ARCH_KGDB
select HAVE_HW_BREAKPOINT
select HAVE_MIXED_BREAKPOINTS_REGS
- select PERF_EVENTS if HAVE_HW_BREAKPOINT
+ select PERF_EVENTS
select ARCH_HIBERNATION_POSSIBLE if MMU
config SUPERH64
@@ -249,6 +251,11 @@ config ARCH_SHMOBILE
select PM
select PM_RUNTIME
+config CPU_HAS_PMU
+ depends on CPU_SH4 || CPU_SH4A
+ default y
+ bool
+
if SUPERH32
choice
@@ -465,6 +472,7 @@ config CPU_SUBTYPE_SHX3
select CPU_SH4A
select CPU_SHX3
select GENERIC_CLOCKEVENTS_BROADCAST if SMP
+ select ARCH_REQUIRE_GPIOLIB
# SH4AL-DSP Processor Support
@@ -569,7 +577,7 @@ config SH_CLK_CPG
config SH_CLK_CPG_LEGACY
depends on SH_CLK_CPG
def_bool y if !CPU_SUBTYPE_SH7785 && !ARCH_SHMOBILE && \
- !CPU_SUBTYPE_SH7786
+ !CPU_SHX3 && !CPU_SUBTYPE_SH7757
config SH_CLK_MD
int "CPU Mode Pin Setting"
@@ -738,6 +746,14 @@ config GUSA_RB
LLSC, this should be more efficient than the other alternative of
disabling interrupts around the atomic sequence.
+config HW_PERF_EVENTS
+ bool "Enable hardware performance counter support for perf events"
+ depends on PERF_EVENTS && CPU_HAS_PMU
+ default y
+ help
+ Enable hardware performance counter support for perf events. If
+ disabled, perf events will use software events only.
+
source "drivers/sh/Kconfig"
endmenu
diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
index 07b35ca2f644..9c94711aa6ca 100644
--- a/arch/sh/boards/Kconfig
+++ b/arch/sh/boards/Kconfig
@@ -155,6 +155,8 @@ config SH_SDK7786
depends on CPU_SUBTYPE_SH7786
select SYS_SUPPORTS_PCI
select NO_IOPORT if !PCI
+ select ARCH_WANT_OPTIONAL_GPIOLIB
+ select HAVE_SRAM_POOL
help
Select SDK7786 if configuring for a Renesas Technology Europe
SH7786-65nm board.
@@ -165,6 +167,11 @@ config SH_HIGHLANDER
select SYS_SUPPORTS_PCI
select IO_TRAPPED if MMU
+config SH_SH7757LCR
+ bool "SH7757LCR"
+ depends on CPU_SUBTYPE_SH7757
+ select ARCH_REQUIRE_GPIOLIB
+
config SH_SH7785LCR
bool "SH7785LCR"
depends on CPU_SUBTYPE_SH7785
@@ -309,6 +316,17 @@ config SH_POLARIS
help
Select if configuring for an SMSC Polaris development board
+config SH_SH2007
+ bool "SH-2007 board"
+ select NO_IOPORT
+ depends on CPU_SUBTYPE_SH7780
+ help
+ SH-2007 is a single-board computer based around SH7780 chip
+ intended for embedded applications.
+ It has an Ethernet interface (SMC9118), direct connected
+ Compact Flash socket, two serial ports and PC-104 bus.
+ More information at <http://sh2000.sh-linux.org>.
+
endmenu
source "arch/sh/boards/mach-r2d/Kconfig"
diff --git a/arch/sh/boards/Makefile b/arch/sh/boards/Makefile
index 4f90f9b7a922..38ef655cc0f0 100644
--- a/arch/sh/boards/Makefile
+++ b/arch/sh/boards/Makefile
@@ -2,6 +2,7 @@
# Specific board support, not covered by a mach group.
#
obj-$(CONFIG_SH_MAGIC_PANEL_R2) += board-magicpanelr2.o
+obj-$(CONFIG_SH_SH2007) += board-sh2007.o
obj-$(CONFIG_SH_SH7785LCR) += board-sh7785lcr.o
obj-$(CONFIG_SH_URQUELL) += board-urquell.o
obj-$(CONFIG_SH_SHMIN) += board-shmin.o
@@ -9,3 +10,4 @@ obj-$(CONFIG_SH_EDOSK7760) += board-edosk7760.o
obj-$(CONFIG_SH_ESPT) += board-espt.o
obj-$(CONFIG_SH_POLARIS) += board-polaris.o
obj-$(CONFIG_SH_TITAN) += board-titan.o
+obj-$(CONFIG_SH_SH7757LCR) += board-sh7757lcr.o
diff --git a/arch/sh/boards/board-sh2007.c b/arch/sh/boards/board-sh2007.c
new file mode 100644
index 000000000000..b90b78f6a829
--- /dev/null
+++ b/arch/sh/boards/board-sh2007.c
@@ -0,0 +1,133 @@
+/*
+ * SH-2007 board support.
+ *
+ * Copyright (C) 2003, 2004 SUGIOKA Toshinobu
+ * Copyright (C) 2010 Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/smsc911x.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/io.h>
+#include <asm/machvec.h>
+#include <mach/sh2007.h>
+
+struct smsc911x_platform_config smc911x_info = {
+ .flags = SMSC911X_USE_32BIT,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+};
+
+static struct resource smsc9118_0_resources[] = {
+ [0] = {
+ .start = SMC0_BASE,
+ .end = SMC0_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x240),
+ .end = evt2irq(0x240),
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct resource smsc9118_1_resources[] = {
+ [0] = {
+ .start = SMC1_BASE,
+ .end = SMC1_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x280),
+ .end = evt2irq(0x280),
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device smsc9118_0_device = {
+ .name = "smsc911x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smsc9118_0_resources),
+ .resource = smsc9118_0_resources,
+ .dev = {
+ .platform_data = &smc911x_info,
+ },
+};
+
+static struct platform_device smsc9118_1_device = {
+ .name = "smsc911x",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(smsc9118_1_resources),
+ .resource = smsc9118_1_resources,
+ .dev = {
+ .platform_data = &smc911x_info,
+ },
+};
+
+static struct resource cf_resources[] = {
+ [0] = {
+ .start = CF_BASE + CF_OFFSET,
+ .end = CF_BASE + CF_OFFSET + 0x0f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = CF_BASE + CF_OFFSET + 0x206,
+ .end = CF_BASE + CF_OFFSET + 0x20f,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = evt2irq(0x2c0),
+ .end = evt2irq(0x2c0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cf_device = {
+ .name = "pata_platform",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(cf_resources),
+ .resource = cf_resources,
+};
+
+static struct platform_device *sh2007_devices[] __initdata = {
+ &smsc9118_0_device,
+ &smsc9118_1_device,
+ &cf_device,
+};
+
+static int __init sh2007_io_init(void)
+{
+ platform_add_devices(sh2007_devices, ARRAY_SIZE(sh2007_devices));
+ return 0;
+}
+subsys_initcall(sh2007_io_init);
+
+static void __init sh2007_init_irq(void)
+{
+ plat_irq_setup_pins(IRQ_MODE_IRQ);
+}
+
+/*
+ * Initialize the board
+ */
+static void __init sh2007_setup(char **cmdline_p)
+{
+ printk(KERN_INFO "SH-2007 Setup...");
+
+ /* setup wait control registers for area 5 */
+ __raw_writel(CS5BCR_D, CS5BCR);
+ __raw_writel(CS5WCR_D, CS5WCR);
+ __raw_writel(CS5PCR_D, CS5PCR);
+
+ printk(KERN_INFO " done.\n");
+}
+
+/*
+ * The Machine Vector
+ */
+struct sh_machine_vector mv_sh2007 __initmv = {
+ .mv_setup = sh2007_setup,
+ .mv_name = "sh2007",
+ .mv_init_irq = sh2007_init_irq,
+};
diff --git a/arch/sh/boards/board-sh7757lcr.c b/arch/sh/boards/board-sh7757lcr.c
new file mode 100644
index 000000000000..c475f1056ab4
--- /dev/null
+++ b/arch/sh/boards/board-sh7757lcr.c
@@ -0,0 +1,374 @@
+/*
+ * Renesas R0P7757LC0012RL Support.
+ *
+ * Copyright (C) 2009 - 2010 Renesas Solutions Corp.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/io.h>
+#include <cpu/sh7757.h>
+#include <asm/sh_eth.h>
+#include <asm/heartbeat.h>
+
+static struct resource heartbeat_resource = {
+ .start = 0xffec005c, /* PUDR */
+ .end = 0xffec005c,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_8BIT,
+};
+
+static unsigned char heartbeat_bit_pos[] = { 0, 1, 2, 3 };
+
+static struct heartbeat_data heartbeat_data = {
+ .bit_pos = heartbeat_bit_pos,
+ .nr_bits = ARRAY_SIZE(heartbeat_bit_pos),
+ .flags = HEARTBEAT_INVERTED,
+};
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+ .dev = {
+ .platform_data = &heartbeat_data,
+ },
+ .num_resources = 1,
+ .resource = &heartbeat_resource,
+};
+
+/* Fast Ethernet */
+static struct resource sh_eth0_resources[] = {
+ {
+ .start = 0xfef00000,
+ .end = 0xfef001ff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = 84,
+ .end = 84,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct sh_eth_plat_data sh7757_eth0_pdata = {
+ .phy = 1,
+ .edmac_endian = EDMAC_LITTLE_ENDIAN,
+};
+
+static struct platform_device sh7757_eth0_device = {
+ .name = "sh-eth",
+ .resource = sh_eth0_resources,
+ .id = 0,
+ .num_resources = ARRAY_SIZE(sh_eth0_resources),
+ .dev = {
+ .platform_data = &sh7757_eth0_pdata,
+ },
+};
+
+static struct resource sh_eth1_resources[] = {
+ {
+ .start = 0xfef00800,
+ .end = 0xfef009ff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = 84,
+ .end = 84,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct sh_eth_plat_data sh7757_eth1_pdata = {
+ .phy = 1,
+ .edmac_endian = EDMAC_LITTLE_ENDIAN,
+};
+
+static struct platform_device sh7757_eth1_device = {
+ .name = "sh-eth",
+ .resource = sh_eth1_resources,
+ .id = 1,
+ .num_resources = ARRAY_SIZE(sh_eth1_resources),
+ .dev = {
+ .platform_data = &sh7757_eth1_pdata,
+ },
+};
+
+static struct platform_device *sh7757lcr_devices[] __initdata = {
+ &heartbeat_device,
+ &sh7757_eth0_device,
+ &sh7757_eth1_device,
+};
+
+static int __init sh7757lcr_devices_setup(void)
+{
+ /* RGMII (PTA) */
+ gpio_request(GPIO_FN_ET0_MDC, NULL);
+ gpio_request(GPIO_FN_ET0_MDIO, NULL);
+ gpio_request(GPIO_FN_ET1_MDC, NULL);
+ gpio_request(GPIO_FN_ET1_MDIO, NULL);
+
+ /* ONFI (PTB, PTZ) */
+ gpio_request(GPIO_FN_ON_NRE, NULL);
+ gpio_request(GPIO_FN_ON_NWE, NULL);
+ gpio_request(GPIO_FN_ON_NWP, NULL);
+ gpio_request(GPIO_FN_ON_NCE0, NULL);
+ gpio_request(GPIO_FN_ON_R_B0, NULL);
+ gpio_request(GPIO_FN_ON_ALE, NULL);
+ gpio_request(GPIO_FN_ON_CLE, NULL);
+
+ gpio_request(GPIO_FN_ON_DQ7, NULL);
+ gpio_request(GPIO_FN_ON_DQ6, NULL);
+ gpio_request(GPIO_FN_ON_DQ5, NULL);
+ gpio_request(GPIO_FN_ON_DQ4, NULL);
+ gpio_request(GPIO_FN_ON_DQ3, NULL);
+ gpio_request(GPIO_FN_ON_DQ2, NULL);
+ gpio_request(GPIO_FN_ON_DQ1, NULL);
+ gpio_request(GPIO_FN_ON_DQ0, NULL);
+
+ /* IRQ8 to 0 (PTB, PTC) */
+ gpio_request(GPIO_FN_IRQ8, NULL);
+ gpio_request(GPIO_FN_IRQ7, NULL);
+ gpio_request(GPIO_FN_IRQ6, NULL);
+ gpio_request(GPIO_FN_IRQ5, NULL);
+ gpio_request(GPIO_FN_IRQ4, NULL);
+ gpio_request(GPIO_FN_IRQ3, NULL);
+ gpio_request(GPIO_FN_IRQ2, NULL);
+ gpio_request(GPIO_FN_IRQ1, NULL);
+ gpio_request(GPIO_FN_IRQ0, NULL);
+
+ /* SPI0 (PTD) */
+ gpio_request(GPIO_FN_SP0_MOSI, NULL);
+ gpio_request(GPIO_FN_SP0_MISO, NULL);
+ gpio_request(GPIO_FN_SP0_SCK, NULL);
+ gpio_request(GPIO_FN_SP0_SCK_FB, NULL);
+ gpio_request(GPIO_FN_SP0_SS0, NULL);
+ gpio_request(GPIO_FN_SP0_SS1, NULL);
+ gpio_request(GPIO_FN_SP0_SS2, NULL);
+ gpio_request(GPIO_FN_SP0_SS3, NULL);
+
+ /* RMII 0/1 (PTE, PTF) */
+ gpio_request(GPIO_FN_RMII0_CRS_DV, NULL);
+ gpio_request(GPIO_FN_RMII0_TXD1, NULL);
+ gpio_request(GPIO_FN_RMII0_TXD0, NULL);
+ gpio_request(GPIO_FN_RMII0_TXEN, NULL);
+ gpio_request(GPIO_FN_RMII0_REFCLK, NULL);
+ gpio_request(GPIO_FN_RMII0_RXD1, NULL);
+ gpio_request(GPIO_FN_RMII0_RXD0, NULL);
+ gpio_request(GPIO_FN_RMII0_RX_ER, NULL);
+ gpio_request(GPIO_FN_RMII1_CRS_DV, NULL);
+ gpio_request(GPIO_FN_RMII1_TXD1, NULL);
+ gpio_request(GPIO_FN_RMII1_TXD0, NULL);
+ gpio_request(GPIO_FN_RMII1_TXEN, NULL);
+ gpio_request(GPIO_FN_RMII1_REFCLK, NULL);
+ gpio_request(GPIO_FN_RMII1_RXD1, NULL);
+ gpio_request(GPIO_FN_RMII1_RXD0, NULL);
+ gpio_request(GPIO_FN_RMII1_RX_ER, NULL);
+
+ /* eMMC (PTG) */
+ gpio_request(GPIO_FN_MMCCLK, NULL);
+ gpio_request(GPIO_FN_MMCCMD, NULL);
+ gpio_request(GPIO_FN_MMCDAT7, NULL);
+ gpio_request(GPIO_FN_MMCDAT6, NULL);
+ gpio_request(GPIO_FN_MMCDAT5, NULL);
+ gpio_request(GPIO_FN_MMCDAT4, NULL);
+ gpio_request(GPIO_FN_MMCDAT3, NULL);
+ gpio_request(GPIO_FN_MMCDAT2, NULL);
+ gpio_request(GPIO_FN_MMCDAT1, NULL);
+ gpio_request(GPIO_FN_MMCDAT0, NULL);
+
+ /* LPC (PTG, PTH, PTQ, PTU) */
+ gpio_request(GPIO_FN_SERIRQ, NULL);
+ gpio_request(GPIO_FN_LPCPD, NULL);
+ gpio_request(GPIO_FN_LDRQ, NULL);
+ gpio_request(GPIO_FN_WP, NULL);
+ gpio_request(GPIO_FN_FMS0, NULL);
+ gpio_request(GPIO_FN_LAD3, NULL);
+ gpio_request(GPIO_FN_LAD2, NULL);
+ gpio_request(GPIO_FN_LAD1, NULL);
+ gpio_request(GPIO_FN_LAD0, NULL);
+ gpio_request(GPIO_FN_LFRAME, NULL);
+ gpio_request(GPIO_FN_LRESET, NULL);
+ gpio_request(GPIO_FN_LCLK, NULL);
+ gpio_request(GPIO_FN_LGPIO7, NULL);
+ gpio_request(GPIO_FN_LGPIO6, NULL);
+ gpio_request(GPIO_FN_LGPIO5, NULL);
+ gpio_request(GPIO_FN_LGPIO4, NULL);
+
+ /* SPI1 (PTH) */
+ gpio_request(GPIO_FN_SP1_MOSI, NULL);
+ gpio_request(GPIO_FN_SP1_MISO, NULL);
+ gpio_request(GPIO_FN_SP1_SCK, NULL);
+ gpio_request(GPIO_FN_SP1_SCK_FB, NULL);
+ gpio_request(GPIO_FN_SP1_SS0, NULL);
+ gpio_request(GPIO_FN_SP1_SS1, NULL);
+
+ /* SDHI (PTI) */
+ gpio_request(GPIO_FN_SD_WP, NULL);
+ gpio_request(GPIO_FN_SD_CD, NULL);
+ gpio_request(GPIO_FN_SD_CLK, NULL);
+ gpio_request(GPIO_FN_SD_CMD, NULL);
+ gpio_request(GPIO_FN_SD_D3, NULL);
+ gpio_request(GPIO_FN_SD_D2, NULL);
+ gpio_request(GPIO_FN_SD_D1, NULL);
+ gpio_request(GPIO_FN_SD_D0, NULL);
+
+ /* SCIF3/4 (PTJ, PTW) */
+ gpio_request(GPIO_FN_RTS3, NULL);
+ gpio_request(GPIO_FN_CTS3, NULL);
+ gpio_request(GPIO_FN_TXD3, NULL);
+ gpio_request(GPIO_FN_RXD3, NULL);
+ gpio_request(GPIO_FN_RTS4, NULL);
+ gpio_request(GPIO_FN_RXD4, NULL);
+ gpio_request(GPIO_FN_TXD4, NULL);
+ gpio_request(GPIO_FN_CTS4, NULL);
+
+ /* SERMUX (PTK, PTL, PTO, PTV) */
+ gpio_request(GPIO_FN_COM2_TXD, NULL);
+ gpio_request(GPIO_FN_COM2_RXD, NULL);
+ gpio_request(GPIO_FN_COM2_RTS, NULL);
+ gpio_request(GPIO_FN_COM2_CTS, NULL);
+ gpio_request(GPIO_FN_COM2_DTR, NULL);
+ gpio_request(GPIO_FN_COM2_DSR, NULL);
+ gpio_request(GPIO_FN_COM2_DCD, NULL);
+ gpio_request(GPIO_FN_COM2_RI, NULL);
+ gpio_request(GPIO_FN_RAC_RXD, NULL);
+ gpio_request(GPIO_FN_RAC_RTS, NULL);
+ gpio_request(GPIO_FN_RAC_CTS, NULL);
+ gpio_request(GPIO_FN_RAC_DTR, NULL);
+ gpio_request(GPIO_FN_RAC_DSR, NULL);
+ gpio_request(GPIO_FN_RAC_DCD, NULL);
+ gpio_request(GPIO_FN_RAC_TXD, NULL);
+ gpio_request(GPIO_FN_COM1_TXD, NULL);
+ gpio_request(GPIO_FN_COM1_RXD, NULL);
+ gpio_request(GPIO_FN_COM1_RTS, NULL);
+ gpio_request(GPIO_FN_COM1_CTS, NULL);
+
+ writeb(0x10, 0xfe470000); /* SMR0: SerMux mode 0 */
+
+ /* IIC (PTM, PTR, PTS) */
+ gpio_request(GPIO_FN_SDA7, NULL);
+ gpio_request(GPIO_FN_SCL7, NULL);
+ gpio_request(GPIO_FN_SDA6, NULL);
+ gpio_request(GPIO_FN_SCL6, NULL);
+ gpio_request(GPIO_FN_SDA5, NULL);
+ gpio_request(GPIO_FN_SCL5, NULL);
+ gpio_request(GPIO_FN_SDA4, NULL);
+ gpio_request(GPIO_FN_SCL4, NULL);
+ gpio_request(GPIO_FN_SDA3, NULL);
+ gpio_request(GPIO_FN_SCL3, NULL);
+ gpio_request(GPIO_FN_SDA2, NULL);
+ gpio_request(GPIO_FN_SCL2, NULL);
+ gpio_request(GPIO_FN_SDA1, NULL);
+ gpio_request(GPIO_FN_SCL1, NULL);
+ gpio_request(GPIO_FN_SDA0, NULL);
+ gpio_request(GPIO_FN_SCL0, NULL);
+
+ /* USB (PTN) */
+ gpio_request(GPIO_FN_VBUS_EN, NULL);
+ gpio_request(GPIO_FN_VBUS_OC, NULL);
+
+ /* SGPIO1/0 (PTN, PTO) */
+ gpio_request(GPIO_FN_SGPIO1_CLK, NULL);
+ gpio_request(GPIO_FN_SGPIO1_LOAD, NULL);
+ gpio_request(GPIO_FN_SGPIO1_DI, NULL);
+ gpio_request(GPIO_FN_SGPIO1_DO, NULL);
+ gpio_request(GPIO_FN_SGPIO0_CLK, NULL);
+ gpio_request(GPIO_FN_SGPIO0_LOAD, NULL);
+ gpio_request(GPIO_FN_SGPIO0_DI, NULL);
+ gpio_request(GPIO_FN_SGPIO0_DO, NULL);
+
+ /* WDT (PTN) */
+ gpio_request(GPIO_FN_SUB_CLKIN, NULL);
+
+ /* System (PTT) */
+ gpio_request(GPIO_FN_STATUS1, NULL);
+ gpio_request(GPIO_FN_STATUS0, NULL);
+
+ /* PWMX (PTT) */
+ gpio_request(GPIO_FN_PWMX1, NULL);
+ gpio_request(GPIO_FN_PWMX0, NULL);
+
+ /* R-SPI (PTV) */
+ gpio_request(GPIO_FN_R_SPI_MOSI, NULL);
+ gpio_request(GPIO_FN_R_SPI_MISO, NULL);
+ gpio_request(GPIO_FN_R_SPI_RSPCK, NULL);
+ gpio_request(GPIO_FN_R_SPI_SSL0, NULL);
+ gpio_request(GPIO_FN_R_SPI_SSL1, NULL);
+
+ /* EVC (PTV, PTW) */
+ gpio_request(GPIO_FN_EVENT7, NULL);
+ gpio_request(GPIO_FN_EVENT6, NULL);
+ gpio_request(GPIO_FN_EVENT5, NULL);
+ gpio_request(GPIO_FN_EVENT4, NULL);
+ gpio_request(GPIO_FN_EVENT3, NULL);
+ gpio_request(GPIO_FN_EVENT2, NULL);
+ gpio_request(GPIO_FN_EVENT1, NULL);
+ gpio_request(GPIO_FN_EVENT0, NULL);
+
+ /* LED for heartbeat */
+ gpio_request(GPIO_PTU3, NULL);
+ gpio_direction_output(GPIO_PTU3, 1);
+ gpio_request(GPIO_PTU2, NULL);
+ gpio_direction_output(GPIO_PTU2, 1);
+ gpio_request(GPIO_PTU1, NULL);
+ gpio_direction_output(GPIO_PTU1, 1);
+ gpio_request(GPIO_PTU0, NULL);
+ gpio_direction_output(GPIO_PTU0, 1);
+
+ /* control for MDIO of Gigabit Ethernet */
+ gpio_request(GPIO_PTT4, NULL);
+ gpio_direction_output(GPIO_PTT4, 1);
+
+ /* control for eMMC */
+ gpio_request(GPIO_PTT7, NULL); /* eMMC_RST# */
+ gpio_direction_output(GPIO_PTT7, 0);
+ gpio_request(GPIO_PTT6, NULL); /* eMMC_INDEX# */
+ gpio_direction_output(GPIO_PTT6, 0);
+ gpio_request(GPIO_PTT5, NULL); /* eMMC_PRST# */
+ gpio_direction_output(GPIO_PTT5, 1);
+
+ /* General platform */
+ return platform_add_devices(sh7757lcr_devices,
+ ARRAY_SIZE(sh7757lcr_devices));
+}
+arch_initcall(sh7757lcr_devices_setup);
+
+/* Initialize IRQ setting */
+void __init init_sh7757lcr_IRQ(void)
+{
+ plat_irq_setup_pins(IRQ_MODE_IRQ7654);
+ plat_irq_setup_pins(IRQ_MODE_IRQ3210);
+}
+
+/* Initialize the board */
+static void __init sh7757lcr_setup(char **cmdline_p)
+{
+ printk(KERN_INFO "Renesas R0P7757LC0012RL support.\n");
+}
+
+static int sh7757lcr_mode_pins(void)
+{
+ int value = 0;
+
+ /* These are the factory default settings of S3 (Low active).
+ * If you change these dip switches then you will need to
+ * adjust the values below as well.
+ */
+ value |= MODE_PIN0; /* Clock Mode: 1 */
+
+ return value;
+}
+
+/* The Machine Vector */
+static struct sh_machine_vector mv_sh7757lcr __initmv = {
+ .mv_name = "SH7757LCR",
+ .mv_setup = sh7757lcr_setup,
+ .mv_init_irq = init_sh7757lcr_IRQ,
+ .mv_mode_pins = sh7757lcr_mode_pins,
+};
+
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 1d7b495a7db4..71a3368ab1fc 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -1248,14 +1248,14 @@ static int __init arch_setup(void)
/* set SPU2 clock to 83.4 MHz */
clk = clk_get(NULL, "spu_clk");
- if (clk) {
+ if (!IS_ERR(clk)) {
clk_set_rate(clk, clk_round_rate(clk, 83333333));
clk_put(clk);
}
/* change parent of FSI B */
clk = clk_get(NULL, "fsib_clk");
- if (clk) {
+ if (!IS_ERR(clk)) {
clk_register(&fsimckb_clk);
clk_set_parent(clk, &fsimckb_clk);
clk_set_rate(clk, 11000);
@@ -1273,7 +1273,7 @@ static int __init arch_setup(void)
/* set VPU clock to 166 MHz */
clk = clk_get(NULL, "vpu_clk");
- if (clk) {
+ if (!IS_ERR(clk)) {
clk_set_rate(clk, clk_round_rate(clk, 166000000));
clk_put(clk);
}
diff --git a/arch/sh/boards/mach-landisk/gio.c b/arch/sh/boards/mach-landisk/gio.c
index 01e6abb769b9..8132dff078fb 100644
--- a/arch/sh/boards/mach-landisk/gio.c
+++ b/arch/sh/boards/mach-landisk/gio.c
@@ -128,6 +128,7 @@ static const struct file_operations gio_fops = {
.open = gio_open, /* open */
.release = gio_close, /* release */
.unlocked_ioctl = gio_ioctl,
+ .llseek = noop_llseek,
};
static int __init gio_init(void)
diff --git a/arch/sh/boards/mach-sdk7786/Makefile b/arch/sh/boards/mach-sdk7786/Makefile
index a29f19e85b63..23ff7d4ac491 100644
--- a/arch/sh/boards/mach-sdk7786/Makefile
+++ b/arch/sh/boards/mach-sdk7786/Makefile
@@ -1 +1,4 @@
-obj-y := setup.o fpga.o irq.o
+obj-y := fpga.o irq.o setup.o
+
+obj-$(CONFIG_GENERIC_GPIO) += gpio.o
+obj-$(CONFIG_HAVE_SRAM_POOL) += sram.o
diff --git a/arch/sh/boards/mach-sdk7786/gpio.c b/arch/sh/boards/mach-sdk7786/gpio.c
new file mode 100644
index 000000000000..f71ce09d4e15
--- /dev/null
+++ b/arch/sh/boards/mach-sdk7786/gpio.c
@@ -0,0 +1,49 @@
+/*
+ * SDK7786 FPGA USRGPIR Support.
+ *
+ * Copyright (C) 2010 Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <mach/fpga.h>
+
+#define NR_FPGA_GPIOS 8
+
+static const char *usrgpir_gpio_names[NR_FPGA_GPIOS] = {
+ "in0", "in1", "in2", "in3", "in4", "in5", "in6", "in7",
+};
+
+static int usrgpir_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
+{
+ /* always in */
+ return 0;
+}
+
+static int usrgpir_gpio_get(struct gpio_chip *chip, unsigned gpio)
+{
+ return !!(fpga_read_reg(USRGPIR) & (1 << gpio));
+}
+
+static struct gpio_chip usrgpir_gpio_chip = {
+ .label = "sdk7786-fpga",
+ .names = usrgpir_gpio_names,
+ .direction_input = usrgpir_gpio_direction_input,
+ .get = usrgpir_gpio_get,
+ .base = -1, /* don't care */
+ .ngpio = NR_FPGA_GPIOS,
+};
+
+static int __init usrgpir_gpio_setup(void)
+{
+ return gpiochip_add(&usrgpir_gpio_chip);
+}
+device_initcall(usrgpir_gpio_setup);
diff --git a/arch/sh/boards/mach-sdk7786/setup.c b/arch/sh/boards/mach-sdk7786/setup.c
index 2ec1ea5cf8ef..7e0c4e3878e0 100644
--- a/arch/sh/boards/mach-sdk7786/setup.c
+++ b/arch/sh/boards/mach-sdk7786/setup.c
@@ -20,6 +20,8 @@
#include <asm/machvec.h>
#include <asm/heartbeat.h>
#include <asm/sizes.h>
+#include <asm/clock.h>
+#include <asm/clkdev.h>
#include <asm/reboot.h>
#include <asm/smp-ops.h>
@@ -140,6 +142,45 @@ static int sdk7786_mode_pins(void)
return fpga_read_reg(MODSWR);
}
+/*
+ * FPGA-driven PCIe clocks
+ *
+ * Historically these include the oscillator, clock B (slots 2/3/4) and
+ * clock A (slot 1 and the CPU clock). Newer revs of the PCB shove
+ * everything under a single PCIe clocks enable bit that happens to map
+ * to the same bit position as the oscillator bit for earlier FPGA
+ * versions.
+ *
+ * Given that the legacy clocks have the side-effect of shutting the CPU
+ * off through the FPGA along with the PCI slots, we simply leave them in
+ * their initial state and don't bother registering them with the clock
+ * framework.
+ */
+static int sdk7786_pcie_clk_enable(struct clk *clk)
+{
+ fpga_write_reg(fpga_read_reg(PCIECR) | PCIECR_CLKEN, PCIECR);
+ return 0;
+}
+
+static void sdk7786_pcie_clk_disable(struct clk *clk)
+{
+ fpga_write_reg(fpga_read_reg(PCIECR) & ~PCIECR_CLKEN, PCIECR);
+}
+
+static struct clk_ops sdk7786_pcie_clk_ops = {
+ .enable = sdk7786_pcie_clk_enable,
+ .disable = sdk7786_pcie_clk_disable,
+};
+
+static struct clk sdk7786_pcie_clk = {
+ .ops = &sdk7786_pcie_clk_ops,
+};
+
+static struct clk_lookup sdk7786_pcie_cl = {
+ .con_id = "pcie_plat_clk",
+ .clk = &sdk7786_pcie_clk,
+};
+
static int sdk7786_clk_init(void)
{
struct clk *clk;
@@ -158,7 +199,18 @@ static int sdk7786_clk_init(void)
ret = clk_set_rate(clk, 33333333);
clk_put(clk);
- return ret;
+ /*
+ * Setup the FPGA clocks.
+ */
+ ret = clk_register(&sdk7786_pcie_clk);
+ if (unlikely(ret)) {
+ pr_err("FPGA clock registration failed\n");
+ return ret;
+ }
+
+ clkdev_add(&sdk7786_pcie_cl);
+
+ return 0;
}
static void sdk7786_restart(char *cmd)
diff --git a/arch/sh/boards/mach-sdk7786/sram.c b/arch/sh/boards/mach-sdk7786/sram.c
new file mode 100644
index 000000000000..c81c3abbe01c
--- /dev/null
+++ b/arch/sh/boards/mach-sdk7786/sram.c
@@ -0,0 +1,72 @@
+/*
+ * SDK7786 FPGA SRAM Support.
+ *
+ * Copyright (C) 2010 Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/io.h>
+#include <linux/string.h>
+#include <mach/fpga.h>
+#include <asm/sram.h>
+#include <asm/sizes.h>
+
+static int __init fpga_sram_init(void)
+{
+ unsigned long phys;
+ unsigned int area;
+ void __iomem *vaddr;
+ int ret;
+ u16 data;
+
+ /* Enable FPGA SRAM */
+ data = fpga_read_reg(LCLASR);
+ data |= LCLASR_FRAMEN;
+ fpga_write_reg(data, LCLASR);
+
+ /*
+ * FPGA_SEL determines the area mapping
+ */
+ area = (data & LCLASR_FPGA_SEL_MASK) >> LCLASR_FPGA_SEL_SHIFT;
+ if (unlikely(area == LCLASR_AREA_MASK)) {
+ pr_err("FPGA memory unmapped.\n");
+ return -ENXIO;
+ }
+
+ /*
+ * The memory itself occupies a 2KiB range at the top of the area
+ * immediately below the system registers.
+ */
+ phys = (area << 26) + SZ_64M - SZ_4K;
+
+ /*
+ * The FPGA SRAM resides in translatable physical space, so set
+ * up a mapping prior to inserting it in to the pool.
+ */
+ vaddr = ioremap(phys, SZ_2K);
+ if (unlikely(!vaddr)) {
+ pr_err("Failed remapping FPGA memory.\n");
+ return -ENXIO;
+ }
+
+ pr_info("Adding %dKiB of FPGA memory at 0x%08lx-0x%08lx "
+ "(area %d) to pool.\n",
+ SZ_2K >> 10, phys, phys + SZ_2K - 1, area);
+
+ ret = gen_pool_add(sram_pool, (unsigned long)vaddr, SZ_2K, -1);
+ if (unlikely(ret < 0)) {
+ pr_err("Failed adding memory\n");
+ iounmap(vaddr);
+ return ret;
+ }
+
+ return 0;
+}
+postcore_initcall(fpga_sram_init);
diff --git a/arch/sh/boards/mach-x3proto/Makefile b/arch/sh/boards/mach-x3proto/Makefile
index 983e4551fecf..708c21c919ff 100644
--- a/arch/sh/boards/mach-x3proto/Makefile
+++ b/arch/sh/boards/mach-x3proto/Makefile
@@ -1 +1,3 @@
obj-y += setup.o ilsel.o
+
+obj-$(CONFIG_GENERIC_GPIO) += gpio.o
diff --git a/arch/sh/boards/mach-x3proto/gpio.c b/arch/sh/boards/mach-x3proto/gpio.c
new file mode 100644
index 000000000000..594adf76e46a
--- /dev/null
+++ b/arch/sh/boards/mach-x3proto/gpio.c
@@ -0,0 +1,135 @@
+/*
+ * arch/sh/boards/mach-x3proto/gpio.c
+ *
+ * Renesas SH-X3 Prototype Baseboard GPIO Support.
+ *
+ * Copyright (C) 2010 Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <mach/ilsel.h>
+#include <mach/hardware.h>
+
+#define KEYCTLR 0xb81c0000
+#define KEYOUTR 0xb81c0002
+#define KEYDETR 0xb81c0004
+
+static DEFINE_SPINLOCK(x3proto_gpio_lock);
+static unsigned int x3proto_gpio_irq_map[NR_BASEBOARD_GPIOS] = { 0, };
+
+static int x3proto_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
+{
+ unsigned long flags;
+ unsigned int data;
+
+ spin_lock_irqsave(&x3proto_gpio_lock, flags);
+ data = __raw_readw(KEYCTLR);
+ data |= (1 << gpio);
+ __raw_writew(data, KEYCTLR);
+ spin_unlock_irqrestore(&x3proto_gpio_lock, flags);
+
+ return 0;
+}
+
+static int x3proto_gpio_get(struct gpio_chip *chip, unsigned gpio)
+{
+ return !!(__raw_readw(KEYDETR) & (1 << gpio));
+}
+
+static int x3proto_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
+{
+ return x3proto_gpio_irq_map[gpio];
+}
+
+static void x3proto_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ struct irq_chip *chip = get_irq_desc_chip(desc);
+ unsigned long mask;
+ int pin;
+
+ chip->mask_ack(irq);
+
+ mask = __raw_readw(KEYDETR);
+
+ for_each_set_bit(pin, &mask, NR_BASEBOARD_GPIOS)
+ generic_handle_irq(x3proto_gpio_to_irq(NULL, pin));
+
+ chip->unmask(irq);
+}
+
+struct gpio_chip x3proto_gpio_chip = {
+ .label = "x3proto-gpio",
+ .direction_input = x3proto_gpio_direction_input,
+ .get = x3proto_gpio_get,
+ .to_irq = x3proto_gpio_to_irq,
+ .base = -1,
+ .ngpio = NR_BASEBOARD_GPIOS,
+};
+
+int __init x3proto_gpio_setup(void)
+{
+ int ilsel;
+ int ret, i;
+
+ ilsel = ilsel_enable(ILSEL_KEY);
+ if (unlikely(ilsel < 0))
+ return ilsel;
+
+ ret = gpiochip_add(&x3proto_gpio_chip);
+ if (unlikely(ret))
+ goto err_gpio;
+
+ for (i = 0; i < NR_BASEBOARD_GPIOS; i++) {
+ unsigned long flags;
+ int irq = create_irq();
+
+ if (unlikely(irq < 0)) {
+ ret = -EINVAL;
+ goto err_irq;
+ }
+
+ spin_lock_irqsave(&x3proto_gpio_lock, flags);
+ x3proto_gpio_irq_map[i] = irq;
+ set_irq_chip_and_handler_name(irq, &dummy_irq_chip,
+ handle_simple_irq, "gpio");
+ spin_unlock_irqrestore(&x3proto_gpio_lock, flags);
+ }
+
+ pr_info("registering '%s' support, handling GPIOs %u -> %u, "
+ "bound to IRQ %u\n",
+ x3proto_gpio_chip.label, x3proto_gpio_chip.base,
+ x3proto_gpio_chip.base + x3proto_gpio_chip.ngpio,
+ ilsel);
+
+ set_irq_chained_handler(ilsel, x3proto_gpio_irq_handler);
+ set_irq_wake(ilsel, 1);
+
+ return 0;
+
+err_irq:
+ for (; i >= 0; --i)
+ if (x3proto_gpio_irq_map[i])
+ destroy_irq(x3proto_gpio_irq_map[i]);
+
+ ret = gpiochip_remove(&x3proto_gpio_chip);
+ if (unlikely(ret))
+ pr_err("Failed deregistering GPIO\n");
+
+err_gpio:
+ synchronize_irq(ilsel);
+
+ ilsel_disable(ILSEL_KEY);
+
+ return ret;
+}
diff --git a/arch/sh/boards/mach-x3proto/ilsel.c b/arch/sh/boards/mach-x3proto/ilsel.c
index 5c9842704c60..95e346139515 100644
--- a/arch/sh/boards/mach-x3proto/ilsel.c
+++ b/arch/sh/boards/mach-x3proto/ilsel.c
@@ -1,20 +1,22 @@
/*
- * arch/sh/boards/renesas/x3proto/ilsel.c
+ * arch/sh/boards/mach-x3proto/ilsel.c
*
* Helper routines for SH-X3 proto board ILSEL.
*
- * Copyright (C) 2007 Paul Mundt
+ * Copyright (C) 2007 - 2010 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/bitmap.h>
#include <linux/io.h>
-#include <asm/ilsel.h>
+#include <mach/ilsel.h>
/*
* ILSEL is split across:
@@ -64,6 +66,8 @@ static void __ilsel_enable(ilsel_source_t set, unsigned int bit)
unsigned int tmp, shift;
unsigned long addr;
+ pr_notice("enabling ILSEL set %d\n", set);
+
addr = mk_ilsel_addr(bit);
shift = mk_ilsel_shift(bit);
@@ -92,8 +96,10 @@ int ilsel_enable(ilsel_source_t set)
{
unsigned int bit;
- /* Aliased sources must use ilsel_enable_fixed() */
- BUG_ON(set > ILSEL_KEY);
+ if (unlikely(set > ILSEL_KEY)) {
+ pr_err("Aliased sources must use ilsel_enable_fixed()\n");
+ return -EINVAL;
+ }
do {
bit = find_first_zero_bit(&ilsel_level_map, ILSEL_LEVELS);
@@ -140,6 +146,8 @@ void ilsel_disable(unsigned int irq)
unsigned long addr;
unsigned int tmp;
+ pr_notice("disabling ILSEL set %d\n", irq);
+
addr = mk_ilsel_addr(irq);
tmp = __raw_readw(addr);
diff --git a/arch/sh/boards/mach-x3proto/setup.c b/arch/sh/boards/mach-x3proto/setup.c
index 102bf56befb4..d682e2b6a856 100644
--- a/arch/sh/boards/mach-x3proto/setup.c
+++ b/arch/sh/boards/mach-x3proto/setup.c
@@ -1,9 +1,9 @@
/*
- * arch/sh/boards/renesas/x3proto/setup.c
+ * arch/sh/boards/mach-x3proto/setup.c
*
* Renesas SH-X3 Prototype Board Support.
*
- * Copyright (C) 2007 - 2008 Paul Mundt
+ * Copyright (C) 2007 - 2010 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -16,9 +16,13 @@
#include <linux/smc91x.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
+#include <linux/input.h>
#include <linux/usb/r8a66597.h>
#include <linux/usb/m66592.h>
-#include <asm/ilsel.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <mach/ilsel.h>
+#include <mach/hardware.h>
#include <asm/smp-ops.h>
static struct resource heartbeat_resources[] = {
@@ -122,15 +126,128 @@ static struct platform_device m66592_usb_peripheral_device = {
.resource = m66592_usb_peripheral_resources,
};
+static struct gpio_keys_button baseboard_buttons[NR_BASEBOARD_GPIOS] = {
+ {
+ .desc = "key44",
+ .code = KEY_POWER,
+ .active_low = 1,
+ .wakeup = 1,
+ }, {
+ .desc = "key43",
+ .code = KEY_SUSPEND,
+ .active_low = 1,
+ .wakeup = 1,
+ }, {
+ .desc = "key42",
+ .code = KEY_KATAKANAHIRAGANA,
+ .active_low = 1,
+ }, {
+ .desc = "key41",
+ .code = KEY_SWITCHVIDEOMODE,
+ .active_low = 1,
+ }, {
+ .desc = "key34",
+ .code = KEY_F12,
+ .active_low = 1,
+ }, {
+ .desc = "key33",
+ .code = KEY_F11,
+ .active_low = 1,
+ }, {
+ .desc = "key32",
+ .code = KEY_F10,
+ .active_low = 1,
+ }, {
+ .desc = "key31",
+ .code = KEY_F9,
+ .active_low = 1,
+ }, {
+ .desc = "key24",
+ .code = KEY_F8,
+ .active_low = 1,
+ }, {
+ .desc = "key23",
+ .code = KEY_F7,
+ .active_low = 1,
+ }, {
+ .desc = "key22",
+ .code = KEY_F6,
+ .active_low = 1,
+ }, {
+ .desc = "key21",
+ .code = KEY_F5,
+ .active_low = 1,
+ }, {
+ .desc = "key14",
+ .code = KEY_F4,
+ .active_low = 1,
+ }, {
+ .desc = "key13",
+ .code = KEY_F3,
+ .active_low = 1,
+ }, {
+ .desc = "key12",
+ .code = KEY_F2,
+ .active_low = 1,
+ }, {
+ .desc = "key11",
+ .code = KEY_F1,
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data baseboard_buttons_data = {
+ .buttons = baseboard_buttons,
+ .nbuttons = ARRAY_SIZE(baseboard_buttons),
+};
+
+static struct platform_device baseboard_buttons_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &baseboard_buttons_data,
+ },
+};
+
static struct platform_device *x3proto_devices[] __initdata = {
&heartbeat_device,
&smc91x_device,
&r8a66597_usb_host_device,
&m66592_usb_peripheral_device,
+ &baseboard_buttons_device,
};
+static void __init x3proto_init_irq(void)
+{
+ plat_irq_setup_pins(IRQ_MODE_IRL3210);
+
+ /* Set ICR0.LVLMODE */
+ __raw_writel(__raw_readl(0xfe410000) | (1 << 21), 0xfe410000);
+}
+
static int __init x3proto_devices_setup(void)
{
+ int ret, i;
+
+ /*
+ * IRLs are only needed for ILSEL mappings, so flip over the INTC
+ * pins at a later point to enable the GPIOs to settle.
+ */
+ x3proto_init_irq();
+
+ /*
+ * Now that ILSELs are available, set up the baseboard GPIOs.
+ */
+ ret = x3proto_gpio_setup();
+ if (unlikely(ret))
+ return ret;
+
+ /*
+ * Propagate dynamic GPIOs for the baseboard button device.
+ */
+ for (i = 0; i < ARRAY_SIZE(baseboard_buttons); i++)
+ baseboard_buttons[i].gpio = x3proto_gpio_chip.base + i;
+
r8a66597_usb_host_resources[1].start =
r8a66597_usb_host_resources[1].end = ilsel_enable(ILSEL_USBH_I);
@@ -145,14 +262,6 @@ static int __init x3proto_devices_setup(void)
}
device_initcall(x3proto_devices_setup);
-static void __init x3proto_init_irq(void)
-{
- plat_irq_setup_pins(IRQ_MODE_IRL3210);
-
- /* Set ICR0.LVLMODE */
- __raw_writel(__raw_readl(0xfe410000) | (1 << 21), 0xfe410000);
-}
-
static void __init x3proto_setup(char **cmdline_p)
{
register_smp_ops(&shx3_smp_ops);
@@ -161,5 +270,4 @@ static void __init x3proto_setup(char **cmdline_p)
static struct sh_machine_vector mv_x3proto __initmv = {
.mv_name = "x3proto",
.mv_setup = x3proto_setup,
- .mv_init_irq = x3proto_init_irq,
};
diff --git a/arch/sh/boot/compressed/head_32.S b/arch/sh/boot/compressed/head_32.S
index 200c1d4f1efe..3e150326f1fd 100644
--- a/arch/sh/boot/compressed/head_32.S
+++ b/arch/sh/boot/compressed/head_32.S
@@ -91,7 +91,9 @@ bss_start_addr:
end_addr:
.long _end
init_sr:
- .long 0x400000F0 /* Privileged mode, Bank=0, Block=0, IMASK=0xF */
+ .long 0x500000F0 /* Privileged mode, Bank=0, Block=1, IMASK=0xF */
+kexec_magic:
+ .long 0x400000F0 /* magic used by kexec to parse zImage format */
init_stack_addr:
.long stack_start
decompress_kernel_addr:
diff --git a/arch/sh/cchips/hd6446x/Makefile b/arch/sh/cchips/hd6446x/Makefile
index 9682e3ab668f..59c348337bb8 100644
--- a/arch/sh/cchips/hd6446x/Makefile
+++ b/arch/sh/cchips/hd6446x/Makefile
@@ -1,3 +1,3 @@
obj-$(CONFIG_HD64461) += hd64461.o
-EXTRA_CFLAGS += -Werror
+ccflags-y := -Werror
diff --git a/arch/sh/configs/ap325rxa_defconfig b/arch/sh/configs/ap325rxa_defconfig
index 238d6833ac70..e5335123b5e9 100644
--- a/arch/sh/configs/ap325rxa_defconfig
+++ b/arch/sh/configs/ap325rxa_defconfig
@@ -3,7 +3,6 @@ CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_KALLSYMS is not set
CONFIG_SLAB=y
CONFIG_MODULES=y
diff --git a/arch/sh/configs/cayman_defconfig b/arch/sh/configs/cayman_defconfig
index b3bf11bcf025..67e150631ea5 100644
--- a/arch/sh/configs/cayman_defconfig
+++ b/arch/sh/configs/cayman_defconfig
@@ -1,7 +1,6 @@
CONFIG_EXPERIMENTAL=y
CONFIG_POSIX_MQUEUE=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SLAB=y
CONFIG_MODULES=y
diff --git a/arch/sh/configs/dreamcast_defconfig b/arch/sh/configs/dreamcast_defconfig
index 3cdee4f0c184..ec243ca29529 100644
--- a/arch/sh/configs/dreamcast_defconfig
+++ b/arch/sh/configs/dreamcast_defconfig
@@ -2,7 +2,6 @@ CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_SLAB=y
CONFIG_PROFILING=y
diff --git a/arch/sh/configs/ecovec24-romimage_defconfig b/arch/sh/configs/ecovec24-romimage_defconfig
index 021633b02835..5fcb17bff24a 100644
--- a/arch/sh/configs/ecovec24-romimage_defconfig
+++ b/arch/sh/configs/ecovec24-romimage_defconfig
@@ -5,7 +5,6 @@ CONFIG_BSD_PROCESS_ACCT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_KALLSYMS is not set
CONFIG_SLAB=y
diff --git a/arch/sh/configs/edosk7760_defconfig b/arch/sh/configs/edosk7760_defconfig
index 365f2318e9b5..e1077a041ac3 100644
--- a/arch/sh/configs/edosk7760_defconfig
+++ b/arch/sh/configs/edosk7760_defconfig
@@ -5,7 +5,6 @@ CONFIG_POSIX_MQUEUE=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
-CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_KALLSYMS_ALL=y
CONFIG_MODULES=y
diff --git a/arch/sh/configs/espt_defconfig b/arch/sh/configs/espt_defconfig
index ca7fc1b3d567..67cb1094a033 100644
--- a/arch/sh/configs/espt_defconfig
+++ b/arch/sh/configs/espt_defconfig
@@ -3,7 +3,6 @@ CONFIG_SYSVIPC=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_NAMESPACES=y
CONFIG_UTS_NS=y
CONFIG_IPC_NS=y
diff --git a/arch/sh/configs/hp6xx_defconfig b/arch/sh/configs/hp6xx_defconfig
index 45c18a3830d2..496edcdf95a3 100644
--- a/arch/sh/configs/hp6xx_defconfig
+++ b/arch/sh/configs/hp6xx_defconfig
@@ -3,7 +3,6 @@ CONFIG_BSD_PROCESS_ACCT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_SLAB=y
diff --git a/arch/sh/configs/kfr2r09-romimage_defconfig b/arch/sh/configs/kfr2r09-romimage_defconfig
index d4268b1953bc..029a506ca325 100644
--- a/arch/sh/configs/kfr2r09-romimage_defconfig
+++ b/arch/sh/configs/kfr2r09-romimage_defconfig
@@ -5,7 +5,6 @@ CONFIG_BSD_PROCESS_ACCT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_KALLSYMS is not set
CONFIG_SLAB=y
diff --git a/arch/sh/configs/kfr2r09_defconfig b/arch/sh/configs/kfr2r09_defconfig
index ad5d296b375f..fac13ded07b2 100644
--- a/arch/sh/configs/kfr2r09_defconfig
+++ b/arch/sh/configs/kfr2r09_defconfig
@@ -5,7 +5,6 @@ CONFIG_BSD_PROCESS_ACCT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_KALLSYMS is not set
CONFIG_SLAB=y
diff --git a/arch/sh/configs/landisk_defconfig b/arch/sh/configs/landisk_defconfig
index 14e658e9318f..3670e937f2b7 100644
--- a/arch/sh/configs/landisk_defconfig
+++ b/arch/sh/configs/landisk_defconfig
@@ -1,7 +1,6 @@
CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS_EXTRA_PASS=y
CONFIG_SLAB=y
diff --git a/arch/sh/configs/lboxre2_defconfig b/arch/sh/configs/lboxre2_defconfig
index 6be7eaaa8bb6..e3c0894b1bb4 100644
--- a/arch/sh/configs/lboxre2_defconfig
+++ b/arch/sh/configs/lboxre2_defconfig
@@ -1,7 +1,6 @@
CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS_EXTRA_PASS=y
CONFIG_SLAB=y
diff --git a/arch/sh/configs/magicpanelr2_defconfig b/arch/sh/configs/magicpanelr2_defconfig
index 4d61b7711b40..9479872b1ae6 100644
--- a/arch/sh/configs/magicpanelr2_defconfig
+++ b/arch/sh/configs/magicpanelr2_defconfig
@@ -5,7 +5,6 @@ CONFIG_POSIX_MQUEUE=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
CONFIG_AUDIT=y
-CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_RELAY=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
diff --git a/arch/sh/configs/microdev_defconfig b/arch/sh/configs/microdev_defconfig
index 0e32a24fed53..f1d2e1b5ee41 100644
--- a/arch/sh/configs/microdev_defconfig
+++ b/arch/sh/configs/microdev_defconfig
@@ -1,7 +1,6 @@
CONFIG_EXPERIMENTAL=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
# CONFIG_SYSCTL_SYSCALL is not set
diff --git a/arch/sh/configs/migor_defconfig b/arch/sh/configs/migor_defconfig
index c19fcdfdee37..9ad904a110de 100644
--- a/arch/sh/configs/migor_defconfig
+++ b/arch/sh/configs/migor_defconfig
@@ -3,7 +3,6 @@ CONFIG_SYSVIPC=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
# CONFIG_SYSCTL_SYSCALL is not set
diff --git a/arch/sh/configs/polaris_defconfig b/arch/sh/configs/polaris_defconfig
index 984e3fe1ce5d..f3d5d9f76310 100644
--- a/arch/sh/configs/polaris_defconfig
+++ b/arch/sh/configs/polaris_defconfig
@@ -7,7 +7,6 @@ CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
CONFIG_AUDIT=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SLAB=y
CONFIG_MODULES=y
diff --git a/arch/sh/configs/r7780mp_defconfig b/arch/sh/configs/r7780mp_defconfig
index e8b5472e6d84..920b8471ceb7 100644
--- a/arch/sh/configs/r7780mp_defconfig
+++ b/arch/sh/configs/r7780mp_defconfig
@@ -4,7 +4,6 @@ CONFIG_BSD_PROCESS_ACCT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_SYSCTL_SYSCALL is not set
# CONFIG_FUTEX is not set
# CONFIG_EPOLL is not set
diff --git a/arch/sh/configs/r7785rp_defconfig b/arch/sh/configs/r7785rp_defconfig
index fd8848060982..c77da6be06b8 100644
--- a/arch/sh/configs/r7785rp_defconfig
+++ b/arch/sh/configs/r7785rp_defconfig
@@ -8,7 +8,6 @@ CONFIG_RCU_TRACE=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_SLAB=y
CONFIG_PROFILING=y
diff --git a/arch/sh/configs/rts7751r2d1_defconfig b/arch/sh/configs/rts7751r2d1_defconfig
index a42f7c22ca1a..a3d081095ce2 100644
--- a/arch/sh/configs/rts7751r2d1_defconfig
+++ b/arch/sh/configs/rts7751r2d1_defconfig
@@ -1,7 +1,6 @@
CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_SLAB=y
diff --git a/arch/sh/configs/rts7751r2dplus_defconfig b/arch/sh/configs/rts7751r2dplus_defconfig
index 742aa61f2427..b1a04f3c598b 100644
--- a/arch/sh/configs/rts7751r2dplus_defconfig
+++ b/arch/sh/configs/rts7751r2dplus_defconfig
@@ -1,7 +1,6 @@
CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_SLAB=y
diff --git a/arch/sh/configs/sdk7780_defconfig b/arch/sh/configs/sdk7780_defconfig
index aed394d89346..ae1115849dda 100644
--- a/arch/sh/configs/sdk7780_defconfig
+++ b/arch/sh/configs/sdk7780_defconfig
@@ -6,7 +6,6 @@ CONFIG_BSD_PROCESS_ACCT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=18
-CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_RELAY=y
CONFIG_KALLSYMS_ALL=y
CONFIG_MODULES=y
diff --git a/arch/sh/configs/se7343_defconfig b/arch/sh/configs/se7343_defconfig
index 7a7e13853cfd..be9c474197b3 100644
--- a/arch/sh/configs/se7343_defconfig
+++ b/arch/sh/configs/se7343_defconfig
@@ -3,7 +3,6 @@ CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_SYSCTL_SYSCALL is not set
# CONFIG_FUTEX is not set
# CONFIG_EPOLL is not set
diff --git a/arch/sh/configs/se7712_defconfig b/arch/sh/configs/se7712_defconfig
index 3620a7f4c821..1248635e4f88 100644
--- a/arch/sh/configs/se7712_defconfig
+++ b/arch/sh/configs/se7712_defconfig
@@ -5,7 +5,6 @@ CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_KALLSYMS_ALL=y
# CONFIG_BUG is not set
diff --git a/arch/sh/configs/se7721_defconfig b/arch/sh/configs/se7721_defconfig
index fe22f599c0cb..c3ba6e8a9818 100644
--- a/arch/sh/configs/se7721_defconfig
+++ b/arch/sh/configs/se7721_defconfig
@@ -5,7 +5,6 @@ CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_KALLSYMS_ALL=y
# CONFIG_BUG is not set
diff --git a/arch/sh/configs/se7722_defconfig b/arch/sh/configs/se7722_defconfig
index b9b64c38810e..ae998c7e2ee0 100644
--- a/arch/sh/configs/se7722_defconfig
+++ b/arch/sh/configs/se7722_defconfig
@@ -4,7 +4,6 @@ CONFIG_BSD_PROCESS_ACCT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_PROFILING=y
CONFIG_MODULES=y
diff --git a/arch/sh/configs/se7724_defconfig b/arch/sh/configs/se7724_defconfig
index 03e736781c2e..ed35093e3758 100644
--- a/arch/sh/configs/se7724_defconfig
+++ b/arch/sh/configs/se7724_defconfig
@@ -3,7 +3,6 @@ CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_KALLSYMS is not set
CONFIG_SLAB=y
CONFIG_MODULES=y
diff --git a/arch/sh/configs/se7750_defconfig b/arch/sh/configs/se7750_defconfig
index 1a686b6d5cd4..912c98590e22 100644
--- a/arch/sh/configs/se7750_defconfig
+++ b/arch/sh/configs/se7750_defconfig
@@ -5,7 +5,6 @@ CONFIG_BSD_PROCESS_ACCT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
# CONFIG_SYSCTL_SYSCALL is not set
# CONFIG_HOTPLUG is not set
diff --git a/arch/sh/configs/se7751_defconfig b/arch/sh/configs/se7751_defconfig
index 7e03451a9fad..75c92fc1876b 100644
--- a/arch/sh/configs/se7751_defconfig
+++ b/arch/sh/configs/se7751_defconfig
@@ -2,7 +2,6 @@ CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
# CONFIG_SYSCTL_SYSCALL is not set
diff --git a/arch/sh/configs/se7780_defconfig b/arch/sh/configs/se7780_defconfig
index 4cfc4deff135..c8c5e7f7a68d 100644
--- a/arch/sh/configs/se7780_defconfig
+++ b/arch/sh/configs/se7780_defconfig
@@ -3,7 +3,6 @@ CONFIG_SYSVIPC=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_KALLSYMS is not set
# CONFIG_HOTPLUG is not set
# CONFIG_EPOLL is not set
diff --git a/arch/sh/configs/sh03_defconfig b/arch/sh/configs/sh03_defconfig
index b95dc76b04c1..2051821724c6 100644
--- a/arch/sh/configs/sh03_defconfig
+++ b/arch/sh/configs/sh03_defconfig
@@ -3,7 +3,6 @@ CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_SLAB=y
diff --git a/arch/sh/configs/sh2007_defconfig b/arch/sh/configs/sh2007_defconfig
new file mode 100644
index 000000000000..0d2f41472a19
--- /dev/null
+++ b/arch/sh/configs/sh2007_defconfig
@@ -0,0 +1,212 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+CONFIG_IKCONFIG=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_KALLSYMS_ALL=y
+CONFIG_SLAB=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_CPU_SUBTYPE_SH7780=y
+CONFIG_MEMORY_SIZE=0x08000000
+# CONFIG_VSYSCALL is not set
+CONFIG_FLATMEM_MANUAL=y
+CONFIG_SH_SH2007=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_SH_DMA=y
+CONFIG_SH_DMA_API=y
+CONFIG_NR_DMA_CHANNELS_BOOL=y
+CONFIG_HZ_100=y
+CONFIG_CMDLINE_OVERWRITE=y
+CONFIG_CMDLINE="console=ttySC1,115200 ip=dhcp root=/dev/nfs rw nfsroot=/nfs/rootfs,rsize=1024,wsize=1024 earlyprintk=sh-sci.1"
+CONFIG_PCCARD=y
+CONFIG_BINFMT_MISC=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_NET_IPIP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NET_PKTGEN=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_CDROM_PKTCDVD=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_RAID_ATTRS=y
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_SPI_ATTRS=y
+CONFIG_SCSI_FC_ATTRS=y
+CONFIG_SCSI_ISCSI_ATTRS=y
+CONFIG_SCSI_SRP_ATTRS=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+CONFIG_EQUALIZER=y
+CONFIG_TUN=y
+CONFIG_VETH=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMSC911X=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+CONFIG_INPUT_FF_MEMLESS=y
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_SH_WDT=y
+CONFIG_SSB=y
+CONFIG_FB=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_LOGO=y
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_MON=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+CONFIG_DMADEVICES=y
+CONFIG_TIMB_DMA=y
+CONFIG_EXT3_FS=y
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=932
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CONFIGFS_FS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=y
+CONFIG_NLS_CODEPAGE_775=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
+CONFIG_NLS_CODEPAGE_855=y
+CONFIG_NLS_CODEPAGE_857=y
+CONFIG_NLS_CODEPAGE_860=y
+CONFIG_NLS_CODEPAGE_861=y
+CONFIG_NLS_CODEPAGE_862=y
+CONFIG_NLS_CODEPAGE_863=y
+CONFIG_NLS_CODEPAGE_864=y
+CONFIG_NLS_CODEPAGE_865=y
+CONFIG_NLS_CODEPAGE_866=y
+CONFIG_NLS_CODEPAGE_869=y
+CONFIG_NLS_CODEPAGE_936=y
+CONFIG_NLS_CODEPAGE_950=y
+CONFIG_NLS_CODEPAGE_932=y
+CONFIG_NLS_CODEPAGE_949=y
+CONFIG_NLS_CODEPAGE_874=y
+CONFIG_NLS_ISO8859_8=y
+CONFIG_NLS_CODEPAGE_1250=y
+CONFIG_NLS_CODEPAGE_1251=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_NLS_ISO8859_3=y
+CONFIG_NLS_ISO8859_4=y
+CONFIG_NLS_ISO8859_5=y
+CONFIG_NLS_ISO8859_6=y
+CONFIG_NLS_ISO8859_7=y
+CONFIG_NLS_ISO8859_9=y
+CONFIG_NLS_ISO8859_13=y
+CONFIG_NLS_ISO8859_14=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_KOI8_R=y
+CONFIG_NLS_KOI8_U=y
+CONFIG_NLS_UTF8=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SH_STANDARD_BIOS=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_AUTHENC=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_LRW=y
+CONFIG_CRYPTO_PCBC=y
+CONFIG_CRYPTO_XTS=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_CAMELLIA=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_FCRYPT=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_SEED=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_LZO=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+CONFIG_LIBCRC32C=y
diff --git a/arch/sh/configs/sh7710voipgw_defconfig b/arch/sh/configs/sh7710voipgw_defconfig
index b804641c8dd2..f92ad17cd629 100644
--- a/arch/sh/configs/sh7710voipgw_defconfig
+++ b/arch/sh/configs/sh7710voipgw_defconfig
@@ -3,7 +3,6 @@ CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_SYSCTL_SYSCALL is not set
# CONFIG_FUTEX is not set
# CONFIG_EPOLL is not set
diff --git a/arch/sh/configs/sh7757lcr_defconfig b/arch/sh/configs/sh7757lcr_defconfig
new file mode 100644
index 000000000000..273f3fa198f7
--- /dev/null
+++ b/arch/sh/configs/sh7757lcr_defconfig
@@ -0,0 +1,85 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS_ALL=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_CPU_SUBTYPE_SH7757=y
+CONFIG_MEMORY_START=0x40000000
+CONFIG_MEMORY_SIZE=0x0f000000
+CONFIG_PMB=y
+CONFIG_FLATMEM_MANUAL=y
+CONFIG_SH_SH7757LCR=y
+CONFIG_HEARTBEAT=y
+CONFIG_SECCOMP=y
+CONFIG_CMDLINE_OVERWRITE=y
+CONFIG_CMDLINE="console=ttySC2,115200 root=/dev/nfs ip=dhcp"
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_INET_LRO is not set
+CONFIG_IPV6=y
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FW_LOADER is not set
+CONFIG_BLK_DEV_RAM=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_NETDEVICES=y
+CONFIG_PHYLIB=y
+CONFIG_VITESSE_PHY=y
+CONFIG_MDIO_BITBANG=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=3
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_INOTIFY=y
+CONFIG_ISO9660_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_SQUASHFS=y
+CONFIG_MINIX_FS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_932=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_FTRACE is not set
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/sh/configs/sh7763rdp_defconfig b/arch/sh/configs/sh7763rdp_defconfig
index 361876786932..479536440264 100644
--- a/arch/sh/configs/sh7763rdp_defconfig
+++ b/arch/sh/configs/sh7763rdp_defconfig
@@ -3,7 +3,6 @@ CONFIG_SYSVIPC=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_NAMESPACES=y
CONFIG_UTS_NS=y
CONFIG_IPC_NS=y
diff --git a/arch/sh/configs/sh7785lcr_defconfig b/arch/sh/configs/sh7785lcr_defconfig
index ee6b81f7539e..51561f5677d8 100644
--- a/arch/sh/configs/sh7785lcr_defconfig
+++ b/arch/sh/configs/sh7785lcr_defconfig
@@ -4,7 +4,6 @@ CONFIG_BSD_PROCESS_ACCT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_SLAB=y
CONFIG_PROFILING=y
CONFIG_MODULES=y
diff --git a/arch/sh/configs/shx3_defconfig b/arch/sh/configs/shx3_defconfig
index bb4f60c0f866..3f92d37c6374 100644
--- a/arch/sh/configs/shx3_defconfig
+++ b/arch/sh/configs/shx3_defconfig
@@ -15,7 +15,6 @@ CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
CONFIG_CGROUP_MEM_RES_CTLR=y
-CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_RELAY=y
CONFIG_NAMESPACES=y
CONFIG_UTS_NS=y
diff --git a/arch/sh/configs/snapgear_defconfig b/arch/sh/configs/snapgear_defconfig
index f38c98341f15..7eae4e59d7f0 100644
--- a/arch/sh/configs/snapgear_defconfig
+++ b/arch/sh/configs/snapgear_defconfig
@@ -1,7 +1,6 @@
CONFIG_EXPERIMENTAL=y
# CONFIG_SWAP is not set
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_SYSCTL_SYSCALL is not set
# CONFIG_HOTPLUG is not set
diff --git a/arch/sh/configs/systemh_defconfig b/arch/sh/configs/systemh_defconfig
index 7007d00c67e0..b58dfc505efe 100644
--- a/arch/sh/configs/systemh_defconfig
+++ b/arch/sh/configs/systemh_defconfig
@@ -1,6 +1,5 @@
CONFIG_EXPERIMENTAL=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
# CONFIG_SYSCTL_SYSCALL is not set
diff --git a/arch/sh/configs/titan_defconfig b/arch/sh/configs/titan_defconfig
index 45c309ff447e..0f558914e760 100644
--- a/arch/sh/configs/titan_defconfig
+++ b/arch/sh/configs/titan_defconfig
@@ -5,7 +5,6 @@ CONFIG_POSIX_MQUEUE=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=16
-CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
# CONFIG_SYSCTL_SYSCALL is not set
diff --git a/arch/sh/configs/ul2_defconfig b/arch/sh/configs/ul2_defconfig
index e107d424acf0..2d288b887fbd 100644
--- a/arch/sh/configs/ul2_defconfig
+++ b/arch/sh/configs/ul2_defconfig
@@ -4,7 +4,6 @@ CONFIG_BSD_PROCESS_ACCT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_PROFILING=y
CONFIG_MODULES=y
diff --git a/arch/sh/drivers/dma/dma-api.c b/arch/sh/drivers/dma/dma-api.c
index 4a277224a871..f46848f088e4 100644
--- a/arch/sh/drivers/dma/dma-api.c
+++ b/arch/sh/drivers/dma/dma-api.c
@@ -412,8 +412,8 @@ EXPORT_SYMBOL(unregister_dmac);
static int __init dma_api_init(void)
{
printk(KERN_NOTICE "DMA: Registering DMA API.\n");
- create_proc_read_entry("dma", 0, 0, dma_read_proc, 0);
- return 0;
+ return create_proc_read_entry("dma", 0, 0, dma_read_proc, 0)
+ ? 0 : -ENOMEM;
}
subsys_initcall(dma_api_init);
diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile
index 4a59e6890876..82f0a335fd19 100644
--- a/arch/sh/drivers/pci/Makefile
+++ b/arch/sh/drivers/pci/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_SH_RTS7751R2D) += fixups-rts7751r2d.o
obj-$(CONFIG_SH_SH03) += fixups-sh03.o
obj-$(CONFIG_SH_HIGHLANDER) += fixups-r7780rp.o
obj-$(CONFIG_SH_SH7785LCR) += fixups-r7780rp.o
+obj-$(CONFIG_SH_SDK7786) += fixups-sdk7786.o
obj-$(CONFIG_SH_SDK7780) += fixups-sdk7780.o
obj-$(CONFIG_SH_7780_SOLUTION_ENGINE) += fixups-sdk7780.o
obj-$(CONFIG_SH_TITAN) += fixups-titan.o
diff --git a/arch/sh/drivers/pci/fixups-sdk7786.c b/arch/sh/drivers/pci/fixups-sdk7786.c
new file mode 100644
index 000000000000..0e18ee332553
--- /dev/null
+++ b/arch/sh/drivers/pci/fixups-sdk7786.c
@@ -0,0 +1,67 @@
+/*
+ * SDK7786 FPGA PCIe mux handling
+ *
+ * Copyright (C) 2010 Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#define pr_fmt(fmt) "PCI: " fmt
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <mach/fpga.h>
+
+/*
+ * The SDK7786 FPGA supports mangling of most of the slots in some way or
+ * another. Slots 3/4 are special in that only one can be supported at a
+ * time, and both appear on port 3 to the PCI bus scan. Enabling slot 4
+ * (the horizontal edge connector) will disable slot 3 entirely.
+ *
+ * Misconfigurations can be detected through the FPGA via the slot
+ * resistors to determine card presence. Hotplug remains unsupported.
+ */
+static unsigned int slot4en __devinitdata;
+
+char *__devinit pcibios_setup(char *str)
+{
+ if (strcmp(str, "slot4en") == 0) {
+ slot4en = 1;
+ return NULL;
+ }
+
+ return str;
+}
+
+static int __init sdk7786_pci_init(void)
+{
+ u16 data = fpga_read_reg(PCIECR);
+
+ /*
+ * Enable slot #4 if it's been specified on the command line.
+ *
+ * Optionally reroute if slot #4 has a card present while slot #3
+ * does not, regardless of command line value.
+ *
+ * Card presence is logically inverted.
+ */
+ slot4en ?: (!(data & PCIECR_PRST4) && (data & PCIECR_PRST3));
+ if (slot4en) {
+ pr_info("Activating PCIe slot#4 (disabling slot#3)\n");
+
+ data &= ~PCIECR_PCIEMUX1;
+ fpga_write_reg(data, PCIECR);
+
+ /* Warn about forced rerouting if slot#3 is occupied */
+ if ((data & PCIECR_PRST3) == 0) {
+ pr_warning("Unreachable card detected in slot#3\n");
+ return -EBUSY;
+ }
+ } else
+ pr_info("PCIe slot#4 disabled\n");
+
+ return 0;
+}
+postcore_initcall(sdk7786_pci_init);
diff --git a/arch/sh/drivers/pci/ops-sh4.c b/arch/sh/drivers/pci/ops-sh4.c
index 0b81999fb88b..b6234203e0ac 100644
--- a/arch/sh/drivers/pci/ops-sh4.c
+++ b/arch/sh/drivers/pci/ops-sh4.c
@@ -9,6 +9,7 @@
*/
#include <linux/pci.h>
#include <linux/io.h>
+#include <linux/spinlock.h>
#include <asm/addrspace.h>
#include "pci-sh4.h"
@@ -18,8 +19,6 @@
#define CONFIG_CMD(bus, devfn, where) \
(0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
-static DEFINE_SPINLOCK(sh4_pci_lock);
-
/*
* Functions for accessing PCI configuration space with type 1 accesses
*/
@@ -34,10 +33,10 @@ static int sh4_pci_read(struct pci_bus *bus, unsigned int devfn,
* PCIPDR may only be accessed as 32 bit words,
* so we must do byte alignment by hand
*/
- spin_lock_irqsave(&sh4_pci_lock, flags);
+ raw_spin_lock_irqsave(&pci_config_lock, flags);
pci_write_reg(chan, CONFIG_CMD(bus, devfn, where), SH4_PCIPAR);
data = pci_read_reg(chan, SH4_PCIPDR);
- spin_unlock_irqrestore(&sh4_pci_lock, flags);
+ raw_spin_unlock_irqrestore(&pci_config_lock, flags);
switch (size) {
case 1:
@@ -69,10 +68,10 @@ static int sh4_pci_write(struct pci_bus *bus, unsigned int devfn,
int shift;
u32 data;
- spin_lock_irqsave(&sh4_pci_lock, flags);
+ raw_spin_lock_irqsave(&pci_config_lock, flags);
pci_write_reg(chan, CONFIG_CMD(bus, devfn, where), SH4_PCIPAR);
data = pci_read_reg(chan, SH4_PCIPDR);
- spin_unlock_irqrestore(&sh4_pci_lock, flags);
+ raw_spin_unlock_irqrestore(&pci_config_lock, flags);
switch (size) {
case 1:
diff --git a/arch/sh/drivers/pci/ops-sh7786.c b/arch/sh/drivers/pci/ops-sh7786.c
index 48f594b9582b..128421009e3f 100644
--- a/arch/sh/drivers/pci/ops-sh7786.c
+++ b/arch/sh/drivers/pci/ops-sh7786.c
@@ -1,7 +1,7 @@
/*
* Generic SH7786 PCI-Express operations.
*
- * Copyright (C) 2009 Paul Mundt
+ * Copyright (C) 2009 - 2010 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License v2. See the file "COPYING" in the main directory of this archive
@@ -19,37 +19,72 @@ enum {
PCI_ACCESS_WRITE,
};
-static DEFINE_SPINLOCK(sh7786_pcie_lock);
-
static int sh7786_pcie_config_access(unsigned char access_type,
struct pci_bus *bus, unsigned int devfn, int where, u32 *data)
{
struct pci_channel *chan = bus->sysdata;
- int dev, func;
+ int dev, func, type, reg;
dev = PCI_SLOT(devfn);
func = PCI_FUNC(devfn);
+ type = !!bus->parent;
+ reg = where & ~3;
if (bus->number > 255 || dev > 31 || func > 7)
return PCIBIOS_FUNC_NOT_SUPPORTED;
- if (devfn)
- return PCIBIOS_DEVICE_NOT_FOUND;
+
+ /*
+ * While each channel has its own memory-mapped extended config
+ * space, it's generally only accessible when in endpoint mode.
+ * When in root complex mode, the controller is unable to target
+ * itself with either type 0 or type 1 accesses, and indeed, any
+ * controller initiated target transfer to its own config space
+ * result in a completer abort.
+ *
+ * Each channel effectively only supports a single device, but as
+ * the same channel <-> device access works for any PCI_SLOT()
+ * value, we cheat a bit here and bind the controller's config
+ * space to devfn 0 in order to enable self-enumeration. In this
+ * case the regular PAR/PDR path is sidelined and the mangled
+ * config access itself is initiated as a SuperHyway transaction.
+ */
+ if (pci_is_root_bus(bus)) {
+ if (dev == 0) {
+ if (access_type == PCI_ACCESS_READ)
+ *data = pci_read_reg(chan, PCI_REG(reg));
+ else
+ pci_write_reg(chan, *data, PCI_REG(reg));
+
+ return PCIBIOS_SUCCESSFUL;
+ } else if (dev > 1)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ /* Clear errors */
+ pci_write_reg(chan, pci_read_reg(chan, SH4A_PCIEERRFR), SH4A_PCIEERRFR);
/* Set the PIO address */
pci_write_reg(chan, (bus->number << 24) | (dev << 19) |
- (func << 16) | (where & ~3), SH4A_PCIEPAR);
+ (func << 16) | reg, SH4A_PCIEPAR);
/* Enable the configuration access */
- pci_write_reg(chan, (1 << 31), SH4A_PCIEPCTLR);
+ pci_write_reg(chan, (1 << 31) | (type << 8), SH4A_PCIEPCTLR);
+
+ /* Check for errors */
+ if (pci_read_reg(chan, SH4A_PCIEERRFR) & 0x10)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ /* Check for master and target aborts */
+ if (pci_read_reg(chan, SH4A_PCIEPCICONF1) & ((1 << 29) | (1 << 28)))
+ return PCIBIOS_DEVICE_NOT_FOUND;
if (access_type == PCI_ACCESS_READ)
*data = pci_read_reg(chan, SH4A_PCIEPDR);
else
pci_write_reg(chan, *data, SH4A_PCIEPDR);
- /* Check for master and target aborts */
- if (pci_read_reg(chan, SH4A_PCIEPCICONF1) & ((1 << 29) | (1 << 28)))
- return PCIBIOS_DEVICE_NOT_FOUND;
+ /* Disable the configuration access */
+ pci_write_reg(chan, 0, SH4A_PCIEPCTLR);
return PCIBIOS_SUCCESSFUL;
}
@@ -66,11 +101,13 @@ static int sh7786_pcie_read(struct pci_bus *bus, unsigned int devfn,
else if ((size == 4) && (where & 3))
return PCIBIOS_BAD_REGISTER_NUMBER;
- spin_lock_irqsave(&sh7786_pcie_lock, flags);
+ raw_spin_lock_irqsave(&pci_config_lock, flags);
ret = sh7786_pcie_config_access(PCI_ACCESS_READ, bus,
devfn, where, &data);
- if (ret != PCIBIOS_SUCCESSFUL)
+ if (ret != PCIBIOS_SUCCESSFUL) {
+ *val = 0xffffffff;
goto out;
+ }
if (size == 1)
*val = (data >> ((where & 3) << 3)) & 0xff;
@@ -84,7 +121,7 @@ static int sh7786_pcie_read(struct pci_bus *bus, unsigned int devfn,
devfn, where, size, (unsigned long)*val);
out:
- spin_unlock_irqrestore(&sh7786_pcie_lock, flags);
+ raw_spin_unlock_irqrestore(&pci_config_lock, flags);
return ret;
}
@@ -100,7 +137,7 @@ static int sh7786_pcie_write(struct pci_bus *bus, unsigned int devfn,
else if ((size == 4) && (where & 3))
return PCIBIOS_BAD_REGISTER_NUMBER;
- spin_lock_irqsave(&sh7786_pcie_lock, flags);
+ raw_spin_lock_irqsave(&pci_config_lock, flags);
ret = sh7786_pcie_config_access(PCI_ACCESS_READ, bus,
devfn, where, &data);
if (ret != PCIBIOS_SUCCESSFUL)
@@ -124,7 +161,7 @@ static int sh7786_pcie_write(struct pci_bus *bus, unsigned int devfn,
ret = sh7786_pcie_config_access(PCI_ACCESS_WRITE, bus,
devfn, where, &data);
out:
- spin_unlock_irqrestore(&sh7786_pcie_lock, flags);
+ raw_spin_unlock_irqrestore(&pci_config_lock, flags);
return ret;
}
diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c
index f98141b3b7d7..86adb1e235cd 100644
--- a/arch/sh/drivers/pci/pci-sh7751.c
+++ b/arch/sh/drivers/pci/pci-sh7751.c
@@ -81,7 +81,7 @@ static int __init sh7751_pci_init(void)
unsigned int id;
u32 word, reg;
- printk(KERN_NOTICE "PCI: Starting intialization.\n");
+ printk(KERN_NOTICE "PCI: Starting initialization.\n");
chan->reg_base = 0xfe200000;
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c
index ffdcbf10b95e..edb7cca14882 100644
--- a/arch/sh/drivers/pci/pci-sh7780.c
+++ b/arch/sh/drivers/pci/pci-sh7780.c
@@ -246,7 +246,7 @@ static int __init sh7780_pci_init(void)
const char *type;
int ret, i;
- printk(KERN_NOTICE "PCI: Starting intialization.\n");
+ printk(KERN_NOTICE "PCI: Starting initialization.\n");
chan->reg_base = 0xfe040000;
diff --git a/arch/sh/drivers/pci/pci-sh7780.h b/arch/sh/drivers/pci/pci-sh7780.h
index 205dcbefe275..1742e2c9db7a 100644
--- a/arch/sh/drivers/pci/pci-sh7780.h
+++ b/arch/sh/drivers/pci/pci-sh7780.h
@@ -12,12 +12,6 @@
#ifndef _PCI_SH7780_H_
#define _PCI_SH7780_H_
-#define PCI_VENDOR_ID_RENESAS 0x1912
-#define PCI_DEVICE_ID_RENESAS_SH7781 0x0001
-#define PCI_DEVICE_ID_RENESAS_SH7780 0x0002
-#define PCI_DEVICE_ID_RENESAS_SH7763 0x0004
-#define PCI_DEVICE_ID_RENESAS_SH7785 0x0007
-
/* SH7780 Control Registers */
#define PCIECR 0xFE000008
#define PCIECR_ENBL 0x01
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index 1e9598d2bbf4..60ee09a4e121 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -19,6 +19,7 @@
#include <linux/dma-debug.h>
#include <linux/io.h>
#include <linux/mutex.h>
+#include <linux/spinlock.h>
unsigned long PCIBIOS_MIN_IO = 0x0000;
unsigned long PCIBIOS_MIN_MEM = 0;
@@ -56,6 +57,11 @@ static void __devinit pcibios_scanbus(struct pci_channel *hose)
}
}
+/*
+ * This interrupt-safe spinlock protects all accesses to PCI
+ * configuration space.
+ */
+DEFINE_RAW_SPINLOCK(pci_config_lock);
static DEFINE_MUTEX(pci_scan_mutex);
int __devinit register_pci_controller(struct pci_channel *hose)
@@ -233,40 +239,7 @@ void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
int pcibios_enable_device(struct pci_dev *dev, int mask)
{
- u16 cmd, old_cmd;
- int idx;
- struct resource *r;
-
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- old_cmd = cmd;
- for (idx=0; idx < PCI_NUM_RESOURCES; idx++) {
- /* Only set up the requested stuff */
- if (!(mask & (1<<idx)))
- continue;
-
- r = &dev->resource[idx];
- if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
- continue;
- if ((idx == PCI_ROM_RESOURCE) &&
- (!(r->flags & IORESOURCE_ROM_ENABLE)))
- continue;
- if (!r->start && r->end) {
- printk(KERN_ERR "PCI: Device %s not available "
- "because of resource collisions\n",
- pci_name(dev));
- return -EINVAL;
- }
- if (r->flags & IORESOURCE_IO)
- cmd |= PCI_COMMAND_IO;
- if (r->flags & IORESOURCE_MEM)
- cmd |= PCI_COMMAND_MEMORY;
- }
- if (cmd != old_cmd) {
- printk("PCI: Enabling device %s (%04x -> %04x)\n",
- pci_name(dev), old_cmd, cmd);
- pci_write_config_word(dev, PCI_COMMAND, cmd);
- }
- return 0;
+ return pci_enable_resources(dev, mask);
}
/*
@@ -295,7 +268,7 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq)
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
}
-char * __devinit pcibios_setup(char *str)
+char * __devinit __weak pcibios_setup(char *str)
{
return str;
}
diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c
index 68cb9b0ac9d2..96e9b058aa1d 100644
--- a/arch/sh/drivers/pci/pcie-sh7786.c
+++ b/arch/sh/drivers/pci/pcie-sh7786.c
@@ -13,11 +13,14 @@
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/slab.h>
+#include <linux/clk.h>
+#include <linux/sh_clk.h>
#include "pcie-sh7786.h"
#include <asm/sizes.h>
struct sh7786_pcie_port {
struct pci_channel *hose;
+ struct clk *fclk, phy_clk;
unsigned int index;
int endpoint;
int link;
@@ -51,6 +54,7 @@ static struct resource sh7786_pci0_resources[] = {
.name = "PCIe0 MEM 2",
.start = 0xfe100000,
.end = 0xfe100000 + SZ_1M - 1,
+ .flags = IORESOURCE_MEM,
},
};
@@ -74,6 +78,7 @@ static struct resource sh7786_pci1_resources[] = {
.name = "PCIe1 MEM 2",
.start = 0xfe300000,
.end = 0xfe300000 + SZ_1M - 1,
+ .flags = IORESOURCE_MEM,
},
};
@@ -82,6 +87,7 @@ static struct resource sh7786_pci2_resources[] = {
.name = "PCIe2 IO",
.start = 0xfc800000,
.end = 0xfc800000 + SZ_4M - 1,
+ .flags = IORESOURCE_IO,
}, {
.name = "PCIe2 MEM 0",
.start = 0x80000000,
@@ -96,6 +102,7 @@ static struct resource sh7786_pci2_resources[] = {
.name = "PCIe2 MEM 2",
.start = 0xfcd00000,
.end = 0xfcd00000 + SZ_1M - 1,
+ .flags = IORESOURCE_MEM,
},
};
@@ -117,7 +124,29 @@ static struct pci_channel sh7786_pci_channels[] = {
DEFINE_CONTROLLER(0xfcc00000, 2),
};
-static int phy_wait_for_ack(struct pci_channel *chan)
+static struct clk fixed_pciexclkp = {
+ .rate = 100000000, /* 100 MHz reference clock */
+};
+
+static void __devinit sh7786_pci_fixup(struct pci_dev *dev)
+{
+ /*
+ * Prevent enumeration of root complex resources.
+ */
+ if (pci_is_root_bus(dev->bus) && dev->devfn == 0) {
+ int i;
+
+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+ dev->resource[i].start = 0;
+ dev->resource[i].end = 0;
+ dev->resource[i].flags = 0;
+ }
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_SH7786,
+ sh7786_pci_fixup);
+
+static int __init phy_wait_for_ack(struct pci_channel *chan)
{
unsigned int timeout = 100;
@@ -131,7 +160,7 @@ static int phy_wait_for_ack(struct pci_channel *chan)
return -ETIMEDOUT;
}
-static int pci_wait_for_irq(struct pci_channel *chan, unsigned int mask)
+static int __init pci_wait_for_irq(struct pci_channel *chan, unsigned int mask)
{
unsigned int timeout = 100;
@@ -145,19 +174,14 @@ static int pci_wait_for_irq(struct pci_channel *chan, unsigned int mask)
return -ETIMEDOUT;
}
-static void phy_write_reg(struct pci_channel *chan, unsigned int addr,
- unsigned int lane, unsigned int data)
+static void __init phy_write_reg(struct pci_channel *chan, unsigned int addr,
+ unsigned int lane, unsigned int data)
{
- unsigned long phyaddr, ctrl;
+ unsigned long phyaddr;
phyaddr = (1 << BITS_CMD) + ((lane & 0xf) << BITS_LANE) +
((addr & 0xff) << BITS_ADR);
- /* Enable clock */
- ctrl = pci_read_reg(chan, SH4A_PCIEPHYCTLR);
- ctrl |= (1 << BITS_CKE);
- pci_write_reg(chan, ctrl, SH4A_PCIEPHYCTLR);
-
/* Set write data */
pci_write_reg(chan, data, SH4A_PCIEPHYDOUTR);
pci_write_reg(chan, phyaddr, SH4A_PCIEPHYADRR);
@@ -165,20 +189,74 @@ static void phy_write_reg(struct pci_channel *chan, unsigned int addr,
phy_wait_for_ack(chan);
/* Clear command */
+ pci_write_reg(chan, 0, SH4A_PCIEPHYDOUTR);
pci_write_reg(chan, 0, SH4A_PCIEPHYADRR);
phy_wait_for_ack(chan);
+}
- /* Disable clock */
- ctrl = pci_read_reg(chan, SH4A_PCIEPHYCTLR);
- ctrl &= ~(1 << BITS_CKE);
- pci_write_reg(chan, ctrl, SH4A_PCIEPHYCTLR);
+static int __init pcie_clk_init(struct sh7786_pcie_port *port)
+{
+ struct pci_channel *chan = port->hose;
+ struct clk *clk;
+ char fclk_name[16];
+ int ret;
+
+ /*
+ * First register the fixed clock
+ */
+ ret = clk_register(&fixed_pciexclkp);
+ if (unlikely(ret != 0))
+ return ret;
+
+ /*
+ * Grab the port's function clock, which the PHY clock depends
+ * on. clock lookups don't help us much at this point, since no
+ * dev_id is available this early. Lame.
+ */
+ snprintf(fclk_name, sizeof(fclk_name), "pcie%d_fck", port->index);
+
+ port->fclk = clk_get(NULL, fclk_name);
+ if (IS_ERR(port->fclk)) {
+ ret = PTR_ERR(port->fclk);
+ goto err_fclk;
+ }
+
+ clk_enable(port->fclk);
+
+ /*
+ * And now, set up the PHY clock
+ */
+ clk = &port->phy_clk;
+
+ memset(clk, 0, sizeof(struct clk));
+
+ clk->parent = &fixed_pciexclkp;
+ clk->enable_reg = (void __iomem *)(chan->reg_base + SH4A_PCIEPHYCTLR);
+ clk->enable_bit = BITS_CKE;
+
+ ret = sh_clk_mstp32_register(clk, 1);
+ if (unlikely(ret < 0))
+ goto err_phy;
+
+ return 0;
+
+err_phy:
+ clk_disable(port->fclk);
+ clk_put(port->fclk);
+err_fclk:
+ clk_unregister(&fixed_pciexclkp);
+
+ return ret;
}
-static int phy_init(struct pci_channel *chan)
+static int __init phy_init(struct sh7786_pcie_port *port)
{
+ struct pci_channel *chan = port->hose;
unsigned int timeout = 100;
+ clk_enable(&port->phy_clk);
+
/* Initialize the phy */
phy_write_reg(chan, 0x60, 0xf, 0x004b008b);
phy_write_reg(chan, 0x61, 0xf, 0x00007b41);
@@ -187,9 +265,13 @@ static int phy_init(struct pci_channel *chan)
phy_write_reg(chan, 0x66, 0xf, 0x00000010);
phy_write_reg(chan, 0x74, 0xf, 0x0007001c);
phy_write_reg(chan, 0x79, 0xf, 0x01fc000d);
+ phy_write_reg(chan, 0xb0, 0xf, 0x00000610);
/* Deassert Standby */
- phy_write_reg(chan, 0x67, 0xf, 0x00000400);
+ phy_write_reg(chan, 0x67, 0x1, 0x00000400);
+
+ /* Disable clock */
+ clk_disable(&port->phy_clk);
while (timeout--) {
if (pci_read_reg(chan, SH4A_PCIEPHYSR))
@@ -201,22 +283,33 @@ static int phy_init(struct pci_channel *chan)
return -ETIMEDOUT;
}
-static int pcie_init(struct sh7786_pcie_port *port)
+static void __init pcie_reset(struct sh7786_pcie_port *port)
+{
+ struct pci_channel *chan = port->hose;
+
+ pci_write_reg(chan, 1, SH4A_PCIESRSTR);
+ pci_write_reg(chan, 0, SH4A_PCIETCTLR);
+ pci_write_reg(chan, 0, SH4A_PCIESRSTR);
+ pci_write_reg(chan, 0, SH4A_PCIETXVC0SR);
+}
+
+static int __init pcie_init(struct sh7786_pcie_port *port)
{
struct pci_channel *chan = port->hose;
unsigned int data;
phys_addr_t memphys;
size_t memsize;
- int ret, i;
+ int ret, i, win;
/* Begin initialization */
- pci_write_reg(chan, 0, SH4A_PCIETCTLR);
+ pcie_reset(port);
- /* Initialize as type1. */
- data = pci_read_reg(chan, SH4A_PCIEPCICONF3);
- data &= ~(0x7f << 16);
- data |= PCI_HEADER_TYPE_BRIDGE << 16;
- pci_write_reg(chan, data, SH4A_PCIEPCICONF3);
+ /*
+ * Initial header for port config space is type 1, set the device
+ * class to match. Hardware takes care of propagating the IDSETR
+ * settings, so there is no need to bother with a quirk.
+ */
+ pci_write_reg(chan, PCI_CLASS_BRIDGE_PCI << 16, SH4A_PCIEIDSETR1);
/* Initialize default capabilities. */
data = pci_read_reg(chan, SH4A_PCIEEXPCAP0);
@@ -268,30 +361,33 @@ static int pcie_init(struct sh7786_pcie_port *port)
* LAR1/LAMR1.
*/
if (memsize > SZ_512M) {
- __raw_writel(memphys + SZ_512M, chan->reg_base + SH4A_PCIELAR1);
- __raw_writel(((memsize - SZ_512M) - SZ_256) | 1,
- chan->reg_base + SH4A_PCIELAMR1);
+ pci_write_reg(chan, memphys + SZ_512M, SH4A_PCIELAR1);
+ pci_write_reg(chan, ((memsize - SZ_512M) - SZ_256) | 1,
+ SH4A_PCIELAMR1);
memsize = SZ_512M;
} else {
/*
* Otherwise just zero it out and disable it.
*/
- __raw_writel(0, chan->reg_base + SH4A_PCIELAR1);
- __raw_writel(0, chan->reg_base + SH4A_PCIELAMR1);
+ pci_write_reg(chan, 0, SH4A_PCIELAR1);
+ pci_write_reg(chan, 0, SH4A_PCIELAMR1);
}
/*
* LAR0/LAMR0 covers up to the first 512MB, which is enough to
* cover all of lowmem on most platforms.
*/
- __raw_writel(memphys, chan->reg_base + SH4A_PCIELAR0);
- __raw_writel((memsize - SZ_256) | 1, chan->reg_base + SH4A_PCIELAMR0);
+ pci_write_reg(chan, memphys, SH4A_PCIELAR0);
+ pci_write_reg(chan, (memsize - SZ_256) | 1, SH4A_PCIELAMR0);
/* Finish initialization */
data = pci_read_reg(chan, SH4A_PCIETCTLR);
data |= 0x1;
pci_write_reg(chan, data, SH4A_PCIETCTLR);
+ /* Let things settle down a bit.. */
+ mdelay(100);
+
/* Enable DL_Active Interrupt generation */
data = pci_read_reg(chan, SH4A_PCIEDLINTENR);
data |= PCIEDLINTENR_DLL_ACT_ENABLE;
@@ -302,9 +398,12 @@ static int pcie_init(struct sh7786_pcie_port *port)
data |= PCIEMACCTLR_SCR_DIS | (0xff << 16);
pci_write_reg(chan, data, SH4A_PCIEMACCTLR);
+ /*
+ * This will timeout if we don't have a link, but we permit the
+ * port to register anyways in order to support hotplug on future
+ * hardware.
+ */
ret = pci_wait_for_irq(chan, MASK_INT_TX_CTRL);
- if (unlikely(ret != 0))
- return -ENODEV;
data = pci_read_reg(chan, SH4A_PCIEPCICONF1);
data &= ~(PCI_STATUS_DEVSEL_MASK << 16);
@@ -317,35 +416,48 @@ static int pcie_init(struct sh7786_pcie_port *port)
wmb();
- data = pci_read_reg(chan, SH4A_PCIEMACSR);
- printk(KERN_NOTICE "PCI: PCIe#%d link width %d\n",
- port->index, (data >> 20) & 0x3f);
-
+ if (ret == 0) {
+ data = pci_read_reg(chan, SH4A_PCIEMACSR);
+ printk(KERN_NOTICE "PCI: PCIe#%d x%d link detected\n",
+ port->index, (data >> 20) & 0x3f);
+ } else
+ printk(KERN_NOTICE "PCI: PCIe#%d link down\n",
+ port->index);
- for (i = 0; i < chan->nr_resources; i++) {
+ for (i = win = 0; i < chan->nr_resources; i++) {
struct resource *res = chan->resources + i;
resource_size_t size;
- u32 enable_mask;
+ u32 mask;
- pci_write_reg(chan, 0x00000000, SH4A_PCIEPTCTLR(i));
+ /*
+ * We can't use the 32-bit mode windows in legacy 29-bit
+ * mode, so just skip them entirely.
+ */
+ if ((res->flags & IORESOURCE_MEM_32BIT) && __in_29bit_mode())
+ continue;
- size = resource_size(res);
+ pci_write_reg(chan, 0x00000000, SH4A_PCIEPTCTLR(win));
/*
* The PAMR mask is calculated in units of 256kB, which
* keeps things pretty simple.
*/
- __raw_writel(((roundup_pow_of_two(size) / SZ_256K) - 1) << 18,
- chan->reg_base + SH4A_PCIEPAMR(i));
+ size = resource_size(res);
+ mask = (roundup_pow_of_two(size) / SZ_256K) - 1;
+ pci_write_reg(chan, mask << 18, SH4A_PCIEPAMR(win));
- pci_write_reg(chan, 0x00000000, SH4A_PCIEPARH(i));
- pci_write_reg(chan, 0x00000000, SH4A_PCIEPARL(i));
+ pci_write_reg(chan, upper_32_bits(res->start),
+ SH4A_PCIEPARH(win));
+ pci_write_reg(chan, lower_32_bits(res->start),
+ SH4A_PCIEPARL(win));
- enable_mask = MASK_PARE;
+ mask = MASK_PARE;
if (res->flags & IORESOURCE_IO)
- enable_mask |= MASK_SPC;
+ mask |= MASK_SPC;
+
+ pci_write_reg(chan, mask, SH4A_PCIEPTCTLR(win));
- pci_write_reg(chan, enable_mask, SH4A_PCIEPTCTLR(i));
+ win++;
}
return 0;
@@ -356,26 +468,33 @@ int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
return 71;
}
-static int sh7786_pcie_core_init(void)
+static int __init sh7786_pcie_core_init(void)
{
/* Return the number of ports */
return test_mode_pin(MODE_PIN12) ? 3 : 2;
}
-static int __devinit sh7786_pcie_init_hw(struct sh7786_pcie_port *port)
+static int __init sh7786_pcie_init_hw(struct sh7786_pcie_port *port)
{
int ret;
- ret = phy_init(port->hose);
- if (unlikely(ret < 0))
- return ret;
-
/*
* Check if we are configured in endpoint or root complex mode,
* this is a fixed pin setting that applies to all PCIe ports.
*/
port->endpoint = test_mode_pin(MODE_PIN11);
+ /*
+ * Setup clocks, needed both for PHY and PCIe registers.
+ */
+ ret = pcie_clk_init(port);
+ if (unlikely(ret < 0))
+ return ret;
+
+ ret = phy_init(port);
+ if (unlikely(ret < 0))
+ return ret;
+
ret = pcie_init(port);
if (unlikely(ret < 0))
return ret;
@@ -390,9 +509,10 @@ static struct sh7786_pcie_hwops sh7786_65nm_pcie_hwops __initdata = {
static int __init sh7786_pcie_init(void)
{
+ struct clk *platclk;
int ret = 0, i;
- printk(KERN_NOTICE "PCI: Starting intialization.\n");
+ printk(KERN_NOTICE "PCI: Starting initialization.\n");
sh7786_pcie_hwops = &sh7786_65nm_pcie_hwops;
@@ -407,6 +527,22 @@ static int __init sh7786_pcie_init(void)
if (unlikely(!sh7786_pcie_ports))
return -ENOMEM;
+ /*
+ * Fetch any optional platform clock associated with this block.
+ *
+ * This is a rather nasty hack for boards with spec-mocking FPGAs
+ * that have a secondary set of clocks outside of the on-chip
+ * ones that need to be accounted for before there is any chance
+ * of touching the existing MSTP bits or CPG clocks.
+ */
+ platclk = clk_get(NULL, "pcie_plat_clk");
+ if (IS_ERR(platclk)) {
+ /* Sane hardware should probably get a WARN_ON.. */
+ platclk = NULL;
+ }
+
+ clk_enable(platclk);
+
printk(KERN_NOTICE "PCI: probing %d ports.\n", nr_ports);
for (i = 0; i < nr_ports; i++) {
@@ -419,8 +555,11 @@ static int __init sh7786_pcie_init(void)
ret |= sh7786_pcie_hwops->port_init_hw(port);
}
- if (unlikely(ret))
+ if (unlikely(ret)) {
+ clk_disable(platclk);
+ clk_put(platclk);
return ret;
+ }
return 0;
}
diff --git a/arch/sh/drivers/pci/pcie-sh7786.h b/arch/sh/drivers/pci/pcie-sh7786.h
index 90a6992576b0..1ee054e47eae 100644
--- a/arch/sh/drivers/pci/pcie-sh7786.h
+++ b/arch/sh/drivers/pci/pcie-sh7786.h
@@ -55,8 +55,11 @@
#define BITS_ERRRCV (0) /* 0 ERRRCV 0 */
#define MASK_ERRRCV (1<<BITS_ERRRCV)
+/* PCIEENBLR */
+#define SH4A_PCIEENBLR (0x000008) /* R/W - 0x0000 0001 32 */
+
/* PCIEECR */
-#define SH4A_PCIEECR (0x000008) /* R/W - 0x0000 0000 32 */
+#define SH4A_PCIEECR (0x00000C) /* R/W - 0x0000 0000 32 */
#define BITS_ENBL (0) /* 0 ENBL 0 R/W */
#define MASK_ENBL (1<<BITS_ENBL)
@@ -113,6 +116,27 @@
#define BITS_MDATA (0)
#define MASK_MDATA (0xffffffff<<BITS_MDATA)
+/* PCIEUNLOCKCR */
+#define SH4A_PCIEUNLOCKCR (0x000048) /* R/W - 0x0000 0000 32 */
+
+/* PCIEIDR */
+#define SH4A_PCIEIDR (0x000060) /* R/W - 0x0101 1101 32 */
+
+/* PCIEDBGCTLR */
+#define SH4A_PCIEDBGCTLR (0x000100) /* R/W - 0x0000 0000 32 */
+
+/* PCIEINTXR */
+#define SH4A_PCIEINTXR (0x004000) /* R/W - 0x0000 0000 32 */
+
+/* PCIERMSGR */
+#define SH4A_PCIERMSGR (0x004010) /* R/W - 0x0000 0000 32 */
+
+/* PCIERSTR */
+#define SH4A_PCIERSTR(x) (0x008000 + ((x) * 0x4)) /* R/W - 0x0000 0000 32 */
+
+/* PCIESRSTR */
+#define SH4A_PCIESRSTR (0x008040) /* R/W - 0x0000 0000 32 */
+
/* PCIEPHYCTLR */
#define SH4A_PCIEPHYCTLR (0x010000) /* R/W - 0x0000 0000 32 */
#define BITS_CKE (0)
@@ -121,6 +145,9 @@
/* PCIERMSGIER */
#define SH4A_PCIERMSGIER (0x004040) /* R/W - 0x0000 0000 32 */
+/* PCIEPHYCTLR */
+#define SH4A_PCIEPHYCTLR (0x010000) /* R/W - 0x0000 0000 32 */
+
/* PCIEPHYADRR */
#define SH4A_PCIEPHYADRR (0x010004) /* R/W - 0x0000 0000 32 */
#define BITS_ACK (24) // Rev1.171
@@ -152,7 +179,7 @@
#define MASK_CFINT (1<<BITS_CFINT)
/* PCIETSTR */
-#define SH4A_PCIETSTR (0x020004) /* R/W R/W 0x0000 0000 32 */
+#define SH4A_PCIETSTR (0x020004) /* R 0x0000 0000 32 */
/* PCIEINTR */
#define SH4A_PCIEINTR (0x020008) /* R/W R/W 0x0000 0000 32 */
@@ -236,6 +263,9 @@
#define BITS_INTPM (8)
#define MASK_INTPM (1<<BITS_INTPM)
+/* PCIEEH0R */
+#define SH4A_PCIEEHR(x) (0x020010 + ((x) * 0x4)) /* R - 0x0000 0000 32 */
+
/* PCIEAIR */
#define SH4A_PCIEAIR (SH4A_PCIE_BASE + 0x020010) /* R/W R/W 0xxxxx xxxx 32 */
@@ -244,6 +274,25 @@
/* PCIEERRFR */ // Rev1.18
#define SH4A_PCIEERRFR (0x020020) /* R/W R/W 0xxxxx xxxx 32 */ // Rev1.18
+
+/* PCIEERRFER */
+#define SH4A_PCIEERRFER (0x020024) /* R/W R/W 0x0000 0000 32 */
+
+/* PCIEERRFR2 */
+#define SH4A_PCIEERRFR2 (0x020028) /* R/W R/W 0x0000 0000 32 */
+
+/* PCIEMSIR */
+#define SH4A_PCIEMSIR (0x020040) /* R/W - 0x0000 0000 32 */
+
+/* PCIEMSIFR */
+#define SH4A_PCIEMSIFR (0x020044) /* R/W R/W 0x0000 0000 32 */
+
+/* PCIEPWRCTLR */
+#define SH4A_PCIEPWRCTLR (0x020100) /* R/W - 0x0000 0000 32 */
+
+/* PCIEPCCTLR */
+#define SH4A_PCIEPCCTLR (0x020180) /* R/W - 0x0000 0000 32 */
+
// Rev1.18
/* PCIELAR0 */
#define SH4A_PCIELAR0 (0x020200) /* R/W R/W 0x0000 0000 32 */
@@ -352,6 +401,7 @@
#define SH4A_PCIEDMCCR0 (0x021120) /* R/W R/W 0x0000 0000 32 */
#define SH4A_PCIEDMCC2R0 (0x021124) /* R/W R/W 0x0000 0000 - */
#define SH4A_PCIEDMCCCR0 (0x021128) /* R/W R/W 0x0000 0000 32 */
+#define SH4A_PCIEDMCHSR0 (0x02112C) /* R/W - 0x0000 0000 32 */
#define SH4A_PCIEDMSAR1 (0x021140) /* R/W R/W 0x0000 0000 32 */
#define SH4A_PCIEDMSAHR1 (0x021144) /* R/W R/W 0x0000 0000 32 */
#define SH4A_PCIEDMDAR1 (0x021148) /* R/W R/W 0x0000 0000 32 */
@@ -363,6 +413,7 @@
#define SH4A_PCIEDMCCR1 (0x021160) /* R/W R/W 0x0000 0000 32 */
#define SH4A_PCIEDMCC2R1 (0x021164) /* R/W R/W 0x0000 0000 - */
#define SH4A_PCIEDMCCCR1 (0x021168) /* R/W R/W 0x0000 0000 32 */
+#define SH4A_PCIEDMCHSR1 (0x02116C) /* R/W - 0x0000 0000 32 */
#define SH4A_PCIEDMSAR2 (0x021180) /* R/W R/W 0x0000 0000 32 */
#define SH4A_PCIEDMSAHR2 (0x021184) /* R/W R/W 0x0000 0000 32 */
#define SH4A_PCIEDMDAR2 (0x021188) /* R/W R/W 0x0000 0000 32 */
@@ -385,6 +436,7 @@
#define SH4A_PCIEDMCCR3 (0x0211E0) /* R/W R/W 0x0000 0000 32 */
#define SH4A_PCIEDMCC2R3 (0x0211E4) /* R/W R/W 0x0000 0000 - */
#define SH4A_PCIEDMCCCR3 (0x0211E8) /* R/W R/W 0x0000 0000 32 */
+#define SH4A_PCIEDMCHSR3 (0x0211EC) /* R/W R/W 0x0000 0000 32 */
#define SH4A_PCIEPCICONF0 (0x040000) /* R R - 8/16/32 */
#define SH4A_PCIEPCICONF1 (0x040004) /* R/W R/W 0x0008 0000 8/16/32 */
#define SH4A_PCIEPCICONF2 (0x040008) /* R/W R/W 0xFF00 0000 8/16/32 */
diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild
index 0eed47b236ab..7beb42322f60 100644
--- a/arch/sh/include/asm/Kbuild
+++ b/arch/sh/include/asm/Kbuild
@@ -5,5 +5,7 @@ header-y += cpu-features.h
header-y += hw_breakpoint.h
header-y += posix_types_32.h
header-y += posix_types_64.h
+header-y += ptrace_32.h
+header-y += ptrace_64.h
header-y += unistd_32.h
header-y += unistd_64.h
diff --git a/arch/sh/include/asm/elf.h b/arch/sh/include/asm/elf.h
index ce830faeebbf..f38112be67d2 100644
--- a/arch/sh/include/asm/elf.h
+++ b/arch/sh/include/asm/elf.h
@@ -50,25 +50,14 @@
#define R_SH_GOTPC 167
/* FDPIC relocs */
-#define R_SH_GOT20 70
-#define R_SH_GOTOFF20 71
-#define R_SH_GOTFUNCDESC 72
-#define R_SH_GOTFUNCDESC20 73
-#define R_SH_GOTOFFFUNCDESC 74
-#define R_SH_GOTOFFFUNCDESC20 75
-#define R_SH_FUNCDESC 76
-#define R_SH_FUNCDESC_VALUE 77
-
-#if 0 /* XXX - later .. */
-#define R_SH_GOT20 198
-#define R_SH_GOTOFF20 199
-#define R_SH_GOTFUNCDESC 200
-#define R_SH_GOTFUNCDESC20 201
-#define R_SH_GOTOFFFUNCDESC 202
-#define R_SH_GOTOFFFUNCDESC20 203
-#define R_SH_FUNCDESC 204
-#define R_SH_FUNCDESC_VALUE 205
-#endif
+#define R_SH_GOT20 201
+#define R_SH_GOTOFF20 202
+#define R_SH_GOTFUNCDESC 203
+#define R_SH_GOTFUNCDESC20 204
+#define R_SH_GOTOFFFUNCDESC 205
+#define R_SH_GOTOFFFUNCDESC20 206
+#define R_SH_FUNCDESC 207
+#define R_SH_FUNCDESC_VALUE 208
/* SHmedia relocs */
#define R_SH_IMM_LOW16 246
diff --git a/arch/sh/include/asm/fixmap.h b/arch/sh/include/asm/fixmap.h
index 6e7cea453895..bd7e79a12653 100644
--- a/arch/sh/include/asm/fixmap.h
+++ b/arch/sh/include/asm/fixmap.h
@@ -58,7 +58,7 @@ enum fixed_addresses {
#ifdef CONFIG_HIGHMEM
FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
- FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
+ FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1,
#endif
#ifdef CONFIG_IOREMAP_FIXED
@@ -69,7 +69,7 @@ enum fixed_addresses {
*/
#define FIX_N_IOREMAPS 32
FIX_IOREMAP_BEGIN,
- FIX_IOREMAP_END = FIX_IOREMAP_BEGIN + FIX_N_IOREMAPS,
+ FIX_IOREMAP_END = FIX_IOREMAP_BEGIN + FIX_N_IOREMAPS - 1,
#endif
__end_of_fixed_addresses
diff --git a/arch/sh/include/asm/gpio.h b/arch/sh/include/asm/gpio.h
index f8d9a731e903..04f53d31489f 100644
--- a/arch/sh/include/asm/gpio.h
+++ b/arch/sh/include/asm/gpio.h
@@ -41,14 +41,12 @@ static inline int gpio_cansleep(unsigned gpio)
static inline int gpio_to_irq(unsigned gpio)
{
- WARN_ON(1);
- return -ENOSYS;
+ return __gpio_to_irq(gpio);
}
static inline int irq_to_gpio(unsigned int irq)
{
- WARN_ON(1);
- return -EINVAL;
+ return -ENOSYS;
}
#endif /* CONFIG_GPIOLIB */
diff --git a/arch/sh/include/asm/irq.h b/arch/sh/include/asm/irq.h
index 02c2f0102cfa..45d08b6a5ef7 100644
--- a/arch/sh/include/asm/irq.h
+++ b/arch/sh/include/asm/irq.h
@@ -9,7 +9,7 @@
* advised to cap this at the hard limit that they're interested in
* through the machvec.
*/
-#define NR_IRQS 256
+#define NR_IRQS 512
#define NR_IRQS_LEGACY 8 /* Legacy external IRQ0-7 */
/*
diff --git a/arch/sh/include/asm/irqflags.h b/arch/sh/include/asm/irqflags.h
index a741153b41c2..43b7608606c3 100644
--- a/arch/sh/include/asm/irqflags.h
+++ b/arch/sh/include/asm/irqflags.h
@@ -1,8 +1,8 @@
#ifndef __ASM_SH_IRQFLAGS_H
#define __ASM_SH_IRQFLAGS_H
-#define RAW_IRQ_DISABLED 0xf0
-#define RAW_IRQ_ENABLED 0x00
+#define ARCH_IRQ_DISABLED 0xf0
+#define ARCH_IRQ_ENABLED 0x00
#include <asm-generic/irqflags.h>
diff --git a/arch/sh/include/asm/kprobes.h b/arch/sh/include/asm/kprobes.h
index 036c3311233c..134f3980e44a 100644
--- a/arch/sh/include/asm/kprobes.h
+++ b/arch/sh/include/asm/kprobes.h
@@ -16,7 +16,6 @@ typedef insn_size_t kprobe_opcode_t;
? (MAX_STACK_SIZE) \
: (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR)))
-#define regs_return_value(_regs) ((_regs)->regs[0])
#define flush_insn_slot(p) do { } while (0)
#define kretprobe_blacklist_size 0
diff --git a/arch/sh/include/asm/memblock.h b/arch/sh/include/asm/memblock.h
index dfe683b88075..e87063fad2ea 100644
--- a/arch/sh/include/asm/memblock.h
+++ b/arch/sh/include/asm/memblock.h
@@ -1,6 +1,4 @@
#ifndef __ASM_SH_MEMBLOCK_H
#define __ASM_SH_MEMBLOCK_H
-#define MEMBLOCK_REAL_LIMIT 0
-
#endif /* __ASM_SH_MEMBLOCK_H */
diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h
index 8bd952fcf3ba..f0efe97f1750 100644
--- a/arch/sh/include/asm/pci.h
+++ b/arch/sh/include/asm/pci.h
@@ -37,6 +37,8 @@ struct pci_channel {
};
/* arch/sh/drivers/pci/pci.c */
+extern raw_spinlock_t pci_config_lock;
+
extern int register_pci_controller(struct pci_channel *hose);
extern void pcibios_report_status(unsigned int status_mask, int warn);
diff --git a/arch/sh/include/asm/perf_event.h b/arch/sh/include/asm/perf_event.h
index 3d0c9f36d150..14308bed7ea5 100644
--- a/arch/sh/include/asm/perf_event.h
+++ b/arch/sh/include/asm/perf_event.h
@@ -26,11 +26,4 @@ extern int register_sh_pmu(struct sh_pmu *);
extern int reserve_pmc_hardware(void);
extern void release_pmc_hardware(void);
-static inline void set_perf_event_pending(void)
-{
- /* Nothing to see here, move along. */
-}
-
-#define PERF_EVENT_INDEX_OFFSET 0
-
#endif /* __ASM_SH_PERF_EVENT_H */
diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h
index 61a445d2d02a..46d5179c9f49 100644
--- a/arch/sh/include/asm/processor_32.h
+++ b/arch/sh/include/asm/processor_32.h
@@ -13,7 +13,6 @@
#include <linux/linkage.h>
#include <asm/page.h>
#include <asm/types.h>
-#include <asm/ptrace.h>
#include <asm/hw_breakpoint.h>
/*
@@ -194,8 +193,6 @@ extern unsigned long get_wchan(struct task_struct *p);
#define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc)
#define KSTK_ESP(tsk) (task_pt_regs(tsk)->regs[15])
-#define user_stack_pointer(_regs) ((_regs)->regs[15])
-
#if defined(CONFIG_CPU_SH2A) || defined(CONFIG_CPU_SH4)
#define PREFETCH_STRIDE L1_CACHE_BYTES
#define ARCH_HAS_PREFETCH
diff --git a/arch/sh/include/asm/processor_64.h b/arch/sh/include/asm/processor_64.h
index 621bc4618c6b..2a541ddb5a1b 100644
--- a/arch/sh/include/asm/processor_64.h
+++ b/arch/sh/include/asm/processor_64.h
@@ -17,7 +17,6 @@
#include <linux/compiler.h>
#include <asm/page.h>
#include <asm/types.h>
-#include <asm/ptrace.h>
#include <cpu/registers.h>
/*
@@ -231,7 +230,5 @@ extern unsigned long get_wchan(struct task_struct *p);
#define KSTK_EIP(tsk) ((tsk)->thread.pc)
#define KSTK_ESP(tsk) ((tsk)->thread.sp)
-#define user_stack_pointer(_regs) ((_regs)->regs[15])
-
#endif /* __ASSEMBLY__ */
#endif /* __ASM_SH_PROCESSOR_64_H */
diff --git a/arch/sh/include/asm/ptrace.h b/arch/sh/include/asm/ptrace.h
index 2168fde25611..f6edc10aa0d3 100644
--- a/arch/sh/include/asm/ptrace.h
+++ b/arch/sh/include/asm/ptrace.h
@@ -3,90 +3,7 @@
/*
* Copyright (C) 1999, 2000 Niibe Yutaka
- *
- */
-#if defined(__SH5__)
-struct pt_regs {
- unsigned long long pc;
- unsigned long long sr;
- long long syscall_nr;
- unsigned long long regs[63];
- unsigned long long tregs[8];
- unsigned long long pad[2];
-};
-#else
-/*
- * GCC defines register number like this:
- * -----------------------------
- * 0 - 15 are integer registers
- * 17 - 22 are control/special registers
- * 24 - 39 fp registers
- * 40 - 47 xd registers
- * 48 - fpscr register
- * -----------------------------
- *
- * We follows above, except:
- * 16 --- program counter (PC)
- * 22 --- syscall #
- * 23 --- floating point communication register
*/
-#define REG_REG0 0
-#define REG_REG15 15
-
-#define REG_PC 16
-
-#define REG_PR 17
-#define REG_SR 18
-#define REG_GBR 19
-#define REG_MACH 20
-#define REG_MACL 21
-
-#define REG_SYSCALL 22
-
-#define REG_FPREG0 23
-#define REG_FPREG15 38
-#define REG_XFREG0 39
-#define REG_XFREG15 54
-
-#define REG_FPSCR 55
-#define REG_FPUL 56
-
-/*
- * This struct defines the way the registers are stored on the
- * kernel stack during a system call or other kernel entry.
- */
-struct pt_regs {
- unsigned long regs[16];
- unsigned long pc;
- unsigned long pr;
- unsigned long sr;
- unsigned long gbr;
- unsigned long mach;
- unsigned long macl;
- long tra;
-};
-
-/*
- * This struct defines the way the DSP registers are stored on the
- * kernel stack during a system call or other kernel entry.
- */
-struct pt_dspregs {
- unsigned long a1;
- unsigned long a0g;
- unsigned long a1g;
- unsigned long m0;
- unsigned long m1;
- unsigned long a0;
- unsigned long x0;
- unsigned long x1;
- unsigned long y0;
- unsigned long y1;
- unsigned long dsr;
- unsigned long rs;
- unsigned long re;
- unsigned long mod;
-};
-#endif
#define PTRACE_GETREGS 12 /* General registers */
#define PTRACE_SETREGS 13
@@ -107,22 +24,102 @@ struct pt_dspregs {
#define PT_DATA_ADDR 248 /* &(struct user)->start_data */
#define PT_TEXT_LEN 252
+#if defined(__SH5__) || defined(CONFIG_CPU_SH5)
+#include "ptrace_64.h"
+#else
+#include "ptrace_32.h"
+#endif
+
#ifdef __KERNEL__
+
+#include <linux/stringify.h>
+#include <linux/stddef.h>
+#include <linux/thread_info.h>
#include <asm/addrspace.h>
#include <asm/page.h>
#include <asm/system.h>
#define user_mode(regs) (((regs)->sr & 0x40000000)==0)
+#define user_stack_pointer(regs) ((unsigned long)(regs)->regs[15])
+#define kernel_stack_pointer(regs) ((unsigned long)(regs)->regs[15])
#define instruction_pointer(regs) ((unsigned long)(regs)->pc)
extern void show_regs(struct pt_regs *);
+#define arch_has_single_step() (1)
+
/*
- * These are defined as per linux/ptrace.h.
+ * kprobe-based event tracer support
*/
-struct task_struct;
+struct pt_regs_offset {
+ const char *name;
+ int offset;
+};
-#define arch_has_single_step() (1)
+#define REG_OFFSET_NAME(r) {.name = #r, .offset = offsetof(struct pt_regs, r)}
+#define REGS_OFFSET_NAME(num) \
+ {.name = __stringify(r##num), .offset = offsetof(struct pt_regs, regs[num])}
+#define TREGS_OFFSET_NAME(num) \
+ {.name = __stringify(tr##num), .offset = offsetof(struct pt_regs, tregs[num])}
+#define REG_OFFSET_END {.name = NULL, .offset = 0}
+
+/* Query offset/name of register from its name/offset */
+extern int regs_query_register_offset(const char *name);
+extern const char *regs_query_register_name(unsigned int offset);
+
+extern const struct pt_regs_offset regoffset_table[];
+
+/**
+ * regs_get_register() - get register value from its offset
+ * @regs: pt_regs from which register value is gotten.
+ * @offset: offset number of the register.
+ *
+ * regs_get_register returns the value of a register. The @offset is the
+ * offset of the register in struct pt_regs address which specified by @regs.
+ * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
+ */
+static inline unsigned long regs_get_register(struct pt_regs *regs,
+ unsigned int offset)
+{
+ if (unlikely(offset > MAX_REG_OFFSET))
+ return 0;
+ return *(unsigned long *)((unsigned long)regs + offset);
+}
+
+/**
+ * regs_within_kernel_stack() - check the address in the stack
+ * @regs: pt_regs which contains kernel stack pointer.
+ * @addr: address which is checked.
+ *
+ * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
+ * If @addr is within the kernel stack, it returns true. If not, returns false.
+ */
+static inline int regs_within_kernel_stack(struct pt_regs *regs,
+ unsigned long addr)
+{
+ return ((addr & ~(THREAD_SIZE - 1)) ==
+ (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1)));
+}
+
+/**
+ * regs_get_kernel_stack_nth() - get Nth entry of the stack
+ * @regs: pt_regs which contains kernel stack pointer.
+ * @n: stack entry number.
+ *
+ * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
+ * is specified by @regs. If the @n th entry is NOT in the kernel stack,
+ * this returns 0.
+ */
+static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
+ unsigned int n)
+{
+ unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
+ addr += n;
+ if (regs_within_kernel_stack(regs, (unsigned long)addr))
+ return *addr;
+ else
+ return 0;
+}
struct perf_event;
struct perf_sample_data;
diff --git a/arch/sh/include/asm/ptrace_32.h b/arch/sh/include/asm/ptrace_32.h
new file mode 100644
index 000000000000..35d9e257558c
--- /dev/null
+++ b/arch/sh/include/asm/ptrace_32.h
@@ -0,0 +1,83 @@
+#ifndef __ASM_SH_PTRACE_32_H
+#define __ASM_SH_PTRACE_32_H
+
+/*
+ * GCC defines register number like this:
+ * -----------------------------
+ * 0 - 15 are integer registers
+ * 17 - 22 are control/special registers
+ * 24 - 39 fp registers
+ * 40 - 47 xd registers
+ * 48 - fpscr register
+ * -----------------------------
+ *
+ * We follows above, except:
+ * 16 --- program counter (PC)
+ * 22 --- syscall #
+ * 23 --- floating point communication register
+ */
+#define REG_REG0 0
+#define REG_REG15 15
+
+#define REG_PC 16
+
+#define REG_PR 17
+#define REG_SR 18
+#define REG_GBR 19
+#define REG_MACH 20
+#define REG_MACL 21
+
+#define REG_SYSCALL 22
+
+#define REG_FPREG0 23
+#define REG_FPREG15 38
+#define REG_XFREG0 39
+#define REG_XFREG15 54
+
+#define REG_FPSCR 55
+#define REG_FPUL 56
+
+/*
+ * This struct defines the way the registers are stored on the
+ * kernel stack during a system call or other kernel entry.
+ */
+struct pt_regs {
+ unsigned long regs[16];
+ unsigned long pc;
+ unsigned long pr;
+ unsigned long sr;
+ unsigned long gbr;
+ unsigned long mach;
+ unsigned long macl;
+ long tra;
+};
+
+/*
+ * This struct defines the way the DSP registers are stored on the
+ * kernel stack during a system call or other kernel entry.
+ */
+struct pt_dspregs {
+ unsigned long a1;
+ unsigned long a0g;
+ unsigned long a1g;
+ unsigned long m0;
+ unsigned long m1;
+ unsigned long a0;
+ unsigned long x0;
+ unsigned long x1;
+ unsigned long y0;
+ unsigned long y1;
+ unsigned long dsr;
+ unsigned long rs;
+ unsigned long re;
+ unsigned long mod;
+};
+
+#ifdef __KERNEL__
+
+#define MAX_REG_OFFSET offsetof(struct pt_regs, tra)
+#define regs_return_value(regs) ((regs)->regs[0])
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_SH_PTRACE_32_H */
diff --git a/arch/sh/include/asm/ptrace_64.h b/arch/sh/include/asm/ptrace_64.h
new file mode 100644
index 000000000000..d43c1cb0bbe7
--- /dev/null
+++ b/arch/sh/include/asm/ptrace_64.h
@@ -0,0 +1,20 @@
+#ifndef __ASM_SH_PTRACE_64_H
+#define __ASM_SH_PTRACE_64_H
+
+struct pt_regs {
+ unsigned long long pc;
+ unsigned long long sr;
+ long long syscall_nr;
+ unsigned long long regs[63];
+ unsigned long long tregs[8];
+ unsigned long long pad[2];
+};
+
+#ifdef __KERNEL__
+
+#define MAX_REG_OFFSET offsetof(struct pt_regs, tregs[7])
+#define regs_return_value(regs) ((regs)->regs[3])
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_SH_PTRACE_64_H */
diff --git a/arch/sh/include/asm/sizes.h b/arch/sh/include/asm/sizes.h
index 3a1fb97770f1..0b9fe2d5c36d 100644
--- a/arch/sh/include/asm/sizes.h
+++ b/arch/sh/include/asm/sizes.h
@@ -32,6 +32,7 @@
#define SZ_512 0x00000200
#define SZ_1K 0x00000400
+#define SZ_2K 0x00000800
#define SZ_4K 0x00001000
#define SZ_8K 0x00002000
#define SZ_16K 0x00004000
diff --git a/arch/sh/include/asm/sram.h b/arch/sh/include/asm/sram.h
new file mode 100644
index 000000000000..a2808ce4c0aa
--- /dev/null
+++ b/arch/sh/include/asm/sram.h
@@ -0,0 +1,38 @@
+#ifndef __ASM_SRAM_H
+#define __ASM_SRAM_H
+
+#ifdef CONFIG_HAVE_SRAM_POOL
+
+#include <linux/spinlock.h>
+#include <linux/genalloc.h>
+
+/* arch/sh/mm/sram.c */
+extern struct gen_pool *sram_pool;
+
+static inline unsigned long sram_alloc(size_t len)
+{
+ if (!sram_pool)
+ return 0UL;
+
+ return gen_pool_alloc(sram_pool, len);
+}
+
+static inline void sram_free(unsigned long addr, size_t len)
+{
+ return gen_pool_free(sram_pool, addr, len);
+}
+
+#else
+
+static inline unsigned long sram_alloc(size_t len)
+{
+ return 0;
+}
+
+static inline void sram_free(unsigned long addr, size_t len)
+{
+}
+
+#endif /* CONFIG_HAVE_SRAM_POOL */
+
+#endif /* __ASM_SRAM_H */
diff --git a/arch/sh/include/asm/syscalls_32.h b/arch/sh/include/asm/syscalls_32.h
index be201fdc97aa..ae717e3c26d6 100644
--- a/arch/sh/include/asm/syscalls_32.h
+++ b/arch/sh/include/asm/syscalls_32.h
@@ -19,9 +19,10 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
asmlinkage int sys_vfork(unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7,
struct pt_regs __regs);
-asmlinkage int sys_execve(const char __user *ufilename, char __user * __user *uargv,
- char __user * __user *uenvp, unsigned long r7,
- struct pt_regs __regs);
+asmlinkage int sys_execve(const char __user *ufilename,
+ const char __user *const __user *uargv,
+ const char __user *const __user *uenvp,
+ unsigned long r7, struct pt_regs __regs);
asmlinkage int sys_sigsuspend(old_sigset_t mask, unsigned long r5,
unsigned long r6, unsigned long r7,
struct pt_regs __regs);
diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h
index 0bd7a17d5e1a..1f1af5afff03 100644
--- a/arch/sh/include/asm/system.h
+++ b/arch/sh/include/asm/system.h
@@ -140,8 +140,6 @@ extern unsigned int instruction_size(unsigned int insn);
extern unsigned long cached_to_uncached;
extern unsigned long uncached_size;
-extern struct dentry *sh_debugfs_root;
-
void per_cpu_trap_init(void);
void default_idle(void);
void cpu_idle_wait(void);
diff --git a/arch/sh/include/asm/system_32.h b/arch/sh/include/asm/system_32.h
index 51296b36770e..c941b2739405 100644
--- a/arch/sh/include/asm/system_32.h
+++ b/arch/sh/include/asm/system_32.h
@@ -212,17 +212,16 @@ static inline reg_size_t register_align(void *val)
}
int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
- struct mem_access *ma, int);
+ struct mem_access *ma, int, unsigned long address);
static inline void trigger_address_error(void)
{
- if (__in_29bit_mode())
- __asm__ __volatile__ (
- "ldc %0, sr\n\t"
- "mov.l @%1, %0"
- :
- : "r" (0x10000000), "r" (0x80000001)
- );
+ __asm__ __volatile__ (
+ "ldc %0, sr\n\t"
+ "mov.l @%1, %0"
+ :
+ : "r" (0x10000000), "r" (0x80000001)
+ );
}
asmlinkage void do_address_error(struct pt_regs *regs,
diff --git a/arch/sh/include/asm/tlbflush.h b/arch/sh/include/asm/tlbflush.h
index e0ac97221ae6..0df66f0c7284 100644
--- a/arch/sh/include/asm/tlbflush.h
+++ b/arch/sh/include/asm/tlbflush.h
@@ -21,6 +21,8 @@ extern void local_flush_tlb_kernel_range(unsigned long start,
unsigned long end);
extern void local_flush_tlb_one(unsigned long asid, unsigned long page);
+extern void __flush_tlb_global(void);
+
#ifdef CONFIG_SMP
extern void flush_tlb_all(void);
diff --git a/arch/sh/include/asm/unistd_32.h b/arch/sh/include/asm/unistd_32.h
index 0e7f0fc8f086..903cd618eb74 100644
--- a/arch/sh/include/asm/unistd_32.h
+++ b/arch/sh/include/asm/unistd_32.h
@@ -345,12 +345,33 @@
#define __NR_pwritev 334
#define __NR_rt_tgsigqueueinfo 335
#define __NR_perf_event_open 336
+#define __NR_fanotify_init 337
+#define __NR_fanotify_mark 338
+#define __NR_prlimit64 339
-#define NR_syscalls 337
+/* Non-multiplexed socket family */
+#define __NR_socket 340
+#define __NR_bind 341
+#define __NR_connect 342
+#define __NR_listen 343
+#define __NR_accept 344
+#define __NR_getsockname 345
+#define __NR_getpeername 346
+#define __NR_socketpair 347
+#define __NR_send 348
+#define __NR_sendto 349
+#define __NR_recv 350
+#define __NR_recvfrom 351
+#define __NR_shutdown 352
+#define __NR_setsockopt 353
+#define __NR_getsockopt 354
+#define __NR_sendmsg 355
+#define __NR_recvmsg 356
+#define __NR_recvmmsg 357
-#ifdef __KERNEL__
+#define NR_syscalls 358
-#define __IGNORE_recvmmsg
+#ifdef __KERNEL__
#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
diff --git a/arch/sh/include/asm/unistd_64.h b/arch/sh/include/asm/unistd_64.h
index 0580c33a1e04..09aa93f9eb70 100644
--- a/arch/sh/include/asm/unistd_64.h
+++ b/arch/sh/include/asm/unistd_64.h
@@ -387,10 +387,13 @@
#define __NR_perf_event_open 364
#define __NR_recvmmsg 365
#define __NR_accept4 366
+#define __NR_fanotify_init 367
+#define __NR_fanotify_mark 368
+#define __NR_prlimit64 369
#ifdef __KERNEL__
-#define NR_syscalls 367
+#define NR_syscalls 370
#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
diff --git a/arch/sh/include/cpu-sh3/cpu/mmu_context.h b/arch/sh/include/cpu-sh3/cpu/mmu_context.h
index ab09da73ce77..0c7c735ea82a 100644
--- a/arch/sh/include/cpu-sh3/cpu/mmu_context.h
+++ b/arch/sh/include/cpu-sh3/cpu/mmu_context.h
@@ -16,6 +16,7 @@
#define MMU_TEA 0xFFFFFFFC /* TLB Exception Address */
#define MMUCR 0xFFFFFFE0 /* MMU Control Register */
+#define MMUCR_TI (1 << 2) /* TLB flush bit */
#define MMU_TLB_ADDRESS_ARRAY 0xF2000000
#define MMU_PAGE_ASSOC_BIT 0x80
diff --git a/arch/sh/include/cpu-sh4/cpu/freq.h b/arch/sh/include/cpu-sh4/cpu/freq.h
index e1e90960ee9a..cffd25ed0240 100644
--- a/arch/sh/include/cpu-sh4/cpu/freq.h
+++ b/arch/sh/include/cpu-sh4/cpu/freq.h
@@ -56,7 +56,9 @@
#define FRQCR1 0xffc40004
#define FRQMR1 0xffc40014
#elif defined(CONFIG_CPU_SUBTYPE_SHX3)
-#define FRQCR 0xffc00014
+#define FRQCR0 0xffc00000
+#define FRQCR1 0xffc00004
+#define FRQMR1 0xffc00014
#else
#define FRQCR 0xffc00000
#define FRQCR_PSTBY 0x0200
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7757.h b/arch/sh/include/cpu-sh4/cpu/sh7757.h
index f4d267efad71..15f3de11c55a 100644
--- a/arch/sh/include/cpu-sh4/cpu/sh7757.h
+++ b/arch/sh/include/cpu-sh4/cpu/sh7757.h
@@ -3,241 +3,252 @@
enum {
/* PTA */
- GPIO_PTA7, GPIO_PTA6, GPIO_PTA5, GPIO_PTA4,
- GPIO_PTA3, GPIO_PTA2, GPIO_PTA1, GPIO_PTA0,
+ GPIO_PTA0, GPIO_PTA1, GPIO_PTA2, GPIO_PTA3,
+ GPIO_PTA4, GPIO_PTA5, GPIO_PTA6, GPIO_PTA7,
/* PTB */
- GPIO_PTB7, GPIO_PTB6, GPIO_PTB5, GPIO_PTB4,
- GPIO_PTB3, GPIO_PTB2, GPIO_PTB1, GPIO_PTB0,
+ GPIO_PTB0, GPIO_PTB1, GPIO_PTB2, GPIO_PTB3,
+ GPIO_PTB4, GPIO_PTB5, GPIO_PTB6, GPIO_PTB7,
/* PTC */
- GPIO_PTC7, GPIO_PTC6, GPIO_PTC5, GPIO_PTC4,
- GPIO_PTC3, GPIO_PTC2, GPIO_PTC1, GPIO_PTC0,
+ GPIO_PTC0, GPIO_PTC1, GPIO_PTC2, GPIO_PTC3,
+ GPIO_PTC4, GPIO_PTC5, GPIO_PTC6, GPIO_PTC7,
/* PTD */
- GPIO_PTD7, GPIO_PTD6, GPIO_PTD5, GPIO_PTD4,
- GPIO_PTD3, GPIO_PTD2, GPIO_PTD1, GPIO_PTD0,
+ GPIO_PTD0, GPIO_PTD1, GPIO_PTD2, GPIO_PTD3,
+ GPIO_PTD4, GPIO_PTD5, GPIO_PTD6, GPIO_PTD7,
/* PTE */
- GPIO_PTE7, GPIO_PTE6, GPIO_PTE5, GPIO_PTE4,
- GPIO_PTE3, GPIO_PTE2, GPIO_PTE1, GPIO_PTE0,
+ GPIO_PTE0, GPIO_PTE1, GPIO_PTE2, GPIO_PTE3,
+ GPIO_PTE4, GPIO_PTE5, GPIO_PTE6, GPIO_PTE7,
/* PTF */
- GPIO_PTF7, GPIO_PTF6, GPIO_PTF5, GPIO_PTF4,
- GPIO_PTF3, GPIO_PTF2, GPIO_PTF1, GPIO_PTF0,
+ GPIO_PTF0, GPIO_PTF1, GPIO_PTF2, GPIO_PTF3,
+ GPIO_PTF4, GPIO_PTF5, GPIO_PTF6, GPIO_PTF7,
/* PTG */
- GPIO_PTG7, GPIO_PTG6, GPIO_PTG5, GPIO_PTG4,
- GPIO_PTG3, GPIO_PTG2, GPIO_PTG1, GPIO_PTG0,
+ GPIO_PTG0, GPIO_PTG1, GPIO_PTG2, GPIO_PTG3,
+ GPIO_PTG4, GPIO_PTG5, GPIO_PTG6, GPIO_PTG7,
/* PTH */
- GPIO_PTH7, GPIO_PTH6, GPIO_PTH5, GPIO_PTH4,
- GPIO_PTH3, GPIO_PTH2, GPIO_PTH1, GPIO_PTH0,
+ GPIO_PTH0, GPIO_PTH1, GPIO_PTH2, GPIO_PTH3,
+ GPIO_PTH4, GPIO_PTH5, GPIO_PTH6, GPIO_PTH7,
/* PTI */
- GPIO_PTI7, GPIO_PTI6, GPIO_PTI5, GPIO_PTI4,
- GPIO_PTI3, GPIO_PTI2, GPIO_PTI1, GPIO_PTI0,
+ GPIO_PTI0, GPIO_PTI1, GPIO_PTI2, GPIO_PTI3,
+ GPIO_PTI4, GPIO_PTI5, GPIO_PTI6, GPIO_PTI7,
/* PTJ */
- GPIO_PTJ7, GPIO_PTJ6, GPIO_PTJ5, GPIO_PTJ4,
- GPIO_PTJ3, GPIO_PTJ2, GPIO_PTJ1, GPIO_PTJ0,
+ GPIO_PTJ0, GPIO_PTJ1, GPIO_PTJ2, GPIO_PTJ3,
+ GPIO_PTJ4, GPIO_PTJ5, GPIO_PTJ6, GPIO_PTJ7_RESV,
/* PTK */
- GPIO_PTK7, GPIO_PTK6, GPIO_PTK5, GPIO_PTK4,
- GPIO_PTK3, GPIO_PTK2, GPIO_PTK1, GPIO_PTK0,
+ GPIO_PTK0, GPIO_PTK1, GPIO_PTK2, GPIO_PTK3,
+ GPIO_PTK4, GPIO_PTK5, GPIO_PTK6, GPIO_PTK7,
/* PTL */
- GPIO_PTL7, GPIO_PTL6, GPIO_PTL5, GPIO_PTL4,
- GPIO_PTL3, GPIO_PTL2, GPIO_PTL1, GPIO_PTL0,
+ GPIO_PTL0, GPIO_PTL1, GPIO_PTL2, GPIO_PTL3,
+ GPIO_PTL4, GPIO_PTL5, GPIO_PTL6, GPIO_PTL7_RESV,
/* PTM */
- GPIO_PTM6, GPIO_PTM5, GPIO_PTM4,
- GPIO_PTM3, GPIO_PTM2, GPIO_PTM1, GPIO_PTM0,
+ GPIO_PTM0, GPIO_PTM1, GPIO_PTM2, GPIO_PTM3,
+ GPIO_PTM4, GPIO_PTM5, GPIO_PTM6, GPIO_PTM7,
/* PTN */
- GPIO_PTN7, GPIO_PTN6, GPIO_PTN5, GPIO_PTN4,
- GPIO_PTN3, GPIO_PTN2, GPIO_PTN1, GPIO_PTN0,
+ GPIO_PTN0, GPIO_PTN1, GPIO_PTN2, GPIO_PTN3,
+ GPIO_PTN4, GPIO_PTN5, GPIO_PTN6, GPIO_PTN7_RESV,
/* PTO */
- GPIO_PTO7, GPIO_PTO6, GPIO_PTO5, GPIO_PTO4,
- GPIO_PTO3, GPIO_PTO2, GPIO_PTO1, GPIO_PTO0,
+ GPIO_PTO0, GPIO_PTO1, GPIO_PTO2, GPIO_PTO3,
+ GPIO_PTO4, GPIO_PTO5, GPIO_PTO6, GPIO_PTO7,
/* PTP */
- GPIO_PTP6, GPIO_PTP5, GPIO_PTP4,
- GPIO_PTP3, GPIO_PTP2, GPIO_PTP1, GPIO_PTP0,
+ GPIO_PTP0, GPIO_PTP1, GPIO_PTP2, GPIO_PTP3,
+ GPIO_PTP4, GPIO_PTP5, GPIO_PTP6, GPIO_PTP7,
/* PTQ */
- GPIO_PTQ6, GPIO_PTQ5, GPIO_PTQ4,
- GPIO_PTQ3, GPIO_PTQ2, GPIO_PTQ1, GPIO_PTQ0,
+ GPIO_PTQ0, GPIO_PTQ1, GPIO_PTQ2, GPIO_PTQ3,
+ GPIO_PTQ4, GPIO_PTQ5, GPIO_PTQ6, GPIO_PTQ7_RESV,
/* PTR */
- GPIO_PTR7, GPIO_PTR6, GPIO_PTR5, GPIO_PTR4,
- GPIO_PTR3, GPIO_PTR2, GPIO_PTR1, GPIO_PTR0,
+ GPIO_PTR0, GPIO_PTR1, GPIO_PTR2, GPIO_PTR3,
+ GPIO_PTR4, GPIO_PTR5, GPIO_PTR6, GPIO_PTR7,
/* PTS */
- GPIO_PTS7, GPIO_PTS6, GPIO_PTS5, GPIO_PTS4,
- GPIO_PTS3, GPIO_PTS2, GPIO_PTS1, GPIO_PTS0,
+ GPIO_PTS0, GPIO_PTS1, GPIO_PTS2, GPIO_PTS3,
+ GPIO_PTS4, GPIO_PTS5, GPIO_PTS6, GPIO_PTS7,
/* PTT */
- GPIO_PTT5, GPIO_PTT4,
- GPIO_PTT3, GPIO_PTT2, GPIO_PTT1, GPIO_PTT0,
+ GPIO_PTT0, GPIO_PTT1, GPIO_PTT2, GPIO_PTT3,
+ GPIO_PTT4, GPIO_PTT5, GPIO_PTT6, GPIO_PTT7,
/* PTU */
- GPIO_PTU7, GPIO_PTU6, GPIO_PTU5, GPIO_PTU4,
- GPIO_PTU3, GPIO_PTU2, GPIO_PTU1, GPIO_PTU0,
+ GPIO_PTU0, GPIO_PTU1, GPIO_PTU2, GPIO_PTU3,
+ GPIO_PTU4, GPIO_PTU5, GPIO_PTU6, GPIO_PTU7,
/* PTV */
- GPIO_PTV7, GPIO_PTV6, GPIO_PTV5, GPIO_PTV4,
- GPIO_PTV3, GPIO_PTV2, GPIO_PTV1, GPIO_PTV0,
+ GPIO_PTV0, GPIO_PTV1, GPIO_PTV2, GPIO_PTV3,
+ GPIO_PTV4, GPIO_PTV5, GPIO_PTV6, GPIO_PTV7,
/* PTW */
- GPIO_PTW7, GPIO_PTW6, GPIO_PTW5, GPIO_PTW4,
- GPIO_PTW3, GPIO_PTW2, GPIO_PTW1, GPIO_PTW0,
+ GPIO_PTW0, GPIO_PTW1, GPIO_PTW2, GPIO_PTW3,
+ GPIO_PTW4, GPIO_PTW5, GPIO_PTW6, GPIO_PTW7,
/* PTX */
- GPIO_PTX7, GPIO_PTX6, GPIO_PTX5, GPIO_PTX4,
- GPIO_PTX3, GPIO_PTX2, GPIO_PTX1, GPIO_PTX0,
+ GPIO_PTX0, GPIO_PTX1, GPIO_PTX2, GPIO_PTX3,
+ GPIO_PTX4, GPIO_PTX5, GPIO_PTX6, GPIO_PTX7,
/* PTY */
- GPIO_PTY7, GPIO_PTY6, GPIO_PTY5, GPIO_PTY4,
- GPIO_PTY3, GPIO_PTY2, GPIO_PTY1, GPIO_PTY0,
+ GPIO_PTY0, GPIO_PTY1, GPIO_PTY2, GPIO_PTY3,
+ GPIO_PTY4, GPIO_PTY5, GPIO_PTY6, GPIO_PTY7,
/* PTZ */
- GPIO_PTZ7, GPIO_PTZ6, GPIO_PTZ5, GPIO_PTZ4,
- GPIO_PTZ3, GPIO_PTZ2, GPIO_PTZ1, GPIO_PTZ0,
+ GPIO_PTZ0, GPIO_PTZ1, GPIO_PTZ2, GPIO_PTZ3,
+ GPIO_PTZ4, GPIO_PTZ5, GPIO_PTZ6, GPIO_PTZ7,
- /* PTA (mobule: LBSC, CPG, LPC) */
+ /* PTA (mobule: LBSC, RGMII) */
GPIO_FN_BS, GPIO_FN_RDWR, GPIO_FN_WE1, GPIO_FN_RDY,
- GPIO_FN_MD10, GPIO_FN_MD9, GPIO_FN_MD8,
- GPIO_FN_LGPIO7, GPIO_FN_LGPIO6, GPIO_FN_LGPIO5, GPIO_FN_LGPIO4,
- GPIO_FN_LGPIO3, GPIO_FN_LGPIO2, GPIO_FN_LGPIO1, GPIO_FN_LGPIO0,
-
- /* PTB (mobule: LBSC, EtherC, SIM, LPC) */
- GPIO_FN_D15, GPIO_FN_D14, GPIO_FN_D13, GPIO_FN_D12,
- GPIO_FN_D11, GPIO_FN_D10, GPIO_FN_D9, GPIO_FN_D8,
- GPIO_FN_ET0_MDC, GPIO_FN_ET0_MDIO,
- GPIO_FN_ET1_MDC, GPIO_FN_ET1_MDIO,
- GPIO_FN_SIM_D, GPIO_FN_SIM_CLK, GPIO_FN_SIM_RST,
- GPIO_FN_WPSZ1, GPIO_FN_WPSZ0, GPIO_FN_FWID, GPIO_FN_FLSHSZ,
- GPIO_FN_LPC_SPIEN, GPIO_FN_BASEL,
+ GPIO_FN_ET0_MDC, GPIO_FN_ET0_MDIO,
+ GPIO_FN_ET1_MDC, GPIO_FN_ET1_MDIO,
- /* PTC (mobule: SD) */
- GPIO_FN_SD_WP, GPIO_FN_SD_CD, GPIO_FN_SD_CLK, GPIO_FN_SD_CMD,
- GPIO_FN_SD_D3, GPIO_FN_SD_D2, GPIO_FN_SD_D1, GPIO_FN_SD_D0,
+ /* PTB (mobule: INTC, ONFI, TMU) */
+ GPIO_FN_IRQ15, GPIO_FN_IRQ14, GPIO_FN_IRQ13, GPIO_FN_IRQ12,
+ GPIO_FN_IRQ11, GPIO_FN_IRQ10, GPIO_FN_IRQ9, GPIO_FN_IRQ8,
+ GPIO_FN_ON_NRE, GPIO_FN_ON_NWE, GPIO_FN_ON_NWP, GPIO_FN_ON_NCE0,
+ GPIO_FN_ON_R_B0, GPIO_FN_ON_ALE, GPIO_FN_ON_CLE,
+ GPIO_FN_TCLK,
- /* PTD (mobule: INTC, SPI0, LBSC, CPG, ADC) */
+ /* PTC (mobule: IRQ, PWMU) */
GPIO_FN_IRQ7, GPIO_FN_IRQ6, GPIO_FN_IRQ5, GPIO_FN_IRQ4,
GPIO_FN_IRQ3, GPIO_FN_IRQ2, GPIO_FN_IRQ1, GPIO_FN_IRQ0,
- GPIO_FN_MD6, GPIO_FN_MD5, GPIO_FN_MD3, GPIO_FN_MD2,
- GPIO_FN_MD1, GPIO_FN_MD0, GPIO_FN_ADTRG1, GPIO_FN_ADTRG0,
-
- /* PTE (mobule: EtherC) */
- GPIO_FN_ET0_CRS_DV, GPIO_FN_ET0_TXD1,
- GPIO_FN_ET0_TXD0, GPIO_FN_ET0_TX_EN,
- GPIO_FN_ET0_REF_CLK, GPIO_FN_ET0_RXD1,
- GPIO_FN_ET0_RXD0, GPIO_FN_ET0_RX_ER,
-
- /* PTF (mobule: EtherC) */
- GPIO_FN_ET1_CRS_DV, GPIO_FN_ET1_TXD1,
- GPIO_FN_ET1_TXD0, GPIO_FN_ET1_TX_EN,
- GPIO_FN_ET1_REF_CLK, GPIO_FN_ET1_RXD1,
- GPIO_FN_ET1_RXD0, GPIO_FN_ET1_RX_ER,
-
- /* PTG (mobule: SYSTEM, PWMX, LPC) */
- GPIO_FN_STATUS0, GPIO_FN_STATUS1,
- GPIO_FN_PWX0, GPIO_FN_PWX1, GPIO_FN_PWX2, GPIO_FN_PWX3,
- GPIO_FN_SERIRQ, GPIO_FN_CLKRUN, GPIO_FN_LPCPD, GPIO_FN_LDRQ,
-
- /* PTH (mobule: TMU, SCIF234, SPI1, SPI0) */
- GPIO_FN_TCLK, GPIO_FN_RXD4, GPIO_FN_TXD4,
+ GPIO_FN_PWMU0, GPIO_FN_PWMU1, GPIO_FN_PWMU2, GPIO_FN_PWMU3,
+ GPIO_FN_PWMU4, GPIO_FN_PWMU5,
+
+ /* PTD (mobule: SPI0, DMAC) */
+ GPIO_FN_SP0_MOSI, GPIO_FN_SP0_MISO, GPIO_FN_SP0_SCK,
+ GPIO_FN_SP0_SCK_FB, GPIO_FN_SP0_SS0, GPIO_FN_SP0_SS1,
+ GPIO_FN_SP0_SS2, GPIO_FN_SP0_SS3, GPIO_FN_DREQ0,
+ GPIO_FN_DACK0, GPIO_FN_TEND0,
+
+ /* PTE (mobule: RMII) */
+ GPIO_FN_RMII0_CRS_DV, GPIO_FN_RMII0_TXD1, GPIO_FN_RMII0_TXD0,
+ GPIO_FN_RMII0_TXEN, GPIO_FN_RMII0_REFCLK, GPIO_FN_RMII0_RXD1,
+ GPIO_FN_RMII0_RXD0, GPIO_FN_RMII0_RX_ER,
+
+ /* PTF (mobule: RMII, SerMux) */
+ GPIO_FN_RMII1_CRS_DV, GPIO_FN_RMII1_TXD1, GPIO_FN_RMII1_TXD0,
+ GPIO_FN_RMII1_TXEN, GPIO_FN_RMII1_REFCLK, GPIO_FN_RMII1_RXD1,
+ GPIO_FN_RMII1_RXD0, GPIO_FN_RMII1_RX_ER, GPIO_FN_RAC_RI,
+
+ /* PTG (mobule: system, LBSC, LPC, WDT, LPC, eMMC) */
+ GPIO_FN_BOOTFMS, GPIO_FN_BOOTWP,
+ GPIO_FN_A25, GPIO_FN_A24, GPIO_FN_SERIRQ, GPIO_FN_WDTOVF,
+ GPIO_FN_LPCPD, GPIO_FN_LDRQ, GPIO_FN_MMCCLK, GPIO_FN_MMCCMD,
+
+ /* PTH (mobule: SPI1, LPC, DMAC, ADC) */
GPIO_FN_SP1_MOSI, GPIO_FN_SP1_MISO,
GPIO_FN_SP1_SCK, GPIO_FN_SP1_SCK_FB,
GPIO_FN_SP1_SS0, GPIO_FN_SP1_SS1,
- GPIO_FN_SP0_SS1,
-
- /* PTI (mobule: INTC) */
- GPIO_FN_IRQ15, GPIO_FN_IRQ14, GPIO_FN_IRQ13, GPIO_FN_IRQ12,
- GPIO_FN_IRQ11, GPIO_FN_IRQ10, GPIO_FN_IRQ9, GPIO_FN_IRQ8,
-
- /* PTJ (mobule: SCIF234, SERMUX) */
- GPIO_FN_RXD3, GPIO_FN_TXD3, GPIO_FN_RXD2, GPIO_FN_TXD2,
- GPIO_FN_COM1_TXD, GPIO_FN_COM1_RXD,
- GPIO_FN_COM1_RTS, GPIO_FN_COM1_CTS,
-
- /* PTK (mobule: SERMUX) */
- GPIO_FN_COM2_TXD, GPIO_FN_COM2_RXD,
- GPIO_FN_COM2_RTS, GPIO_FN_COM2_CTS,
- GPIO_FN_COM2_DTR, GPIO_FN_COM2_DSR,
- GPIO_FN_COM2_DCD, GPIO_FN_COM2_RI,
+ GPIO_FN_WP, GPIO_FN_FMS0, GPIO_FN_TEND1, GPIO_FN_DREQ1,
+ GPIO_FN_DACK1, GPIO_FN_ADTRG1, GPIO_FN_ADTRG0,
- /* PTL (mobule: SERMUX) */
- GPIO_FN_RAC_TXD, GPIO_FN_RAC_RXD,
- GPIO_FN_RAC_RTS, GPIO_FN_RAC_CTS,
- GPIO_FN_RAC_DTR, GPIO_FN_RAC_DSR,
- GPIO_FN_RAC_DCD, GPIO_FN_RAC_RI,
+ /* PTI (mobule: LBSC, SDHI) */
+ GPIO_FN_D15, GPIO_FN_D14, GPIO_FN_D13, GPIO_FN_D12,
+ GPIO_FN_D11, GPIO_FN_D10, GPIO_FN_D9, GPIO_FN_D8,
+ GPIO_FN_SD_WP, GPIO_FN_SD_CD, GPIO_FN_SD_CLK, GPIO_FN_SD_CMD,
+ GPIO_FN_SD_D3, GPIO_FN_SD_D2, GPIO_FN_SD_D1, GPIO_FN_SD_D0,
- /* PTM (mobule: IIC, LPC) */
+ /* PTJ (mobule: SCIF234) */
+ GPIO_FN_RTS3, GPIO_FN_CTS3, GPIO_FN_TXD3, GPIO_FN_RXD3,
+ GPIO_FN_RTS4, GPIO_FN_RXD4, GPIO_FN_TXD4,
+
+ /* PTK (mobule: SERMUX, LBSC, SCIF) */
+ GPIO_FN_COM2_TXD, GPIO_FN_COM2_RXD, GPIO_FN_COM2_RTS,
+ GPIO_FN_COM2_CTS, GPIO_FN_COM2_DTR, GPIO_FN_COM2_DSR,
+ GPIO_FN_COM2_DCD, GPIO_FN_CLKOUT,
+ GPIO_FN_SCK2, GPIO_FN_SCK4, GPIO_FN_SCK3,
+
+ /* PTL (mobule: SERMUX, SCIF, LBSC, AUD) */
+ GPIO_FN_RAC_RXD, GPIO_FN_RAC_RTS, GPIO_FN_RAC_CTS,
+ GPIO_FN_RAC_DTR, GPIO_FN_RAC_DSR, GPIO_FN_RAC_DCD,
+ GPIO_FN_RAC_TXD, GPIO_FN_RXD2, GPIO_FN_CS5,
+ GPIO_FN_CS6, GPIO_FN_AUDSYNC, GPIO_FN_AUDCK,
+ GPIO_FN_TXD2,
+
+ /* PTM (mobule: LBSC, IIC) */
+ GPIO_FN_CS4, GPIO_FN_RD, GPIO_FN_WE0, GPIO_FN_CS0,
GPIO_FN_SDA6, GPIO_FN_SCL6, GPIO_FN_SDA7, GPIO_FN_SCL7,
- GPIO_FN_WP, GPIO_FN_FMS0, GPIO_FN_FMS1,
-
- /* PTN (mobule: SCIF234, EVC) */
- GPIO_FN_SCK2, GPIO_FN_RTS4, GPIO_FN_RTS3, GPIO_FN_RTS2,
- GPIO_FN_CTS4, GPIO_FN_CTS3, GPIO_FN_CTS2,
- GPIO_FN_EVENT7, GPIO_FN_EVENT6, GPIO_FN_EVENT5, GPIO_FN_EVENT4,
- GPIO_FN_EVENT3, GPIO_FN_EVENT2, GPIO_FN_EVENT1, GPIO_FN_EVENT0,
- /* PTO (mobule: SGPIO) */
- GPIO_FN_SGPIO0_CLK, GPIO_FN_SGPIO0_LOAD,
- GPIO_FN_SGPIO0_DI, GPIO_FN_SGPIO0_DO,
- GPIO_FN_SGPIO1_CLK, GPIO_FN_SGPIO1_LOAD,
- GPIO_FN_SGPIO1_DI, GPIO_FN_SGPIO1_DO,
+ /* PTN (mobule: USB, JMC, SGPIO, WDT) */
+ GPIO_FN_VBUS_EN, GPIO_FN_VBUS_OC, GPIO_FN_JMCTCK,
+ GPIO_FN_JMCTMS, GPIO_FN_JMCTDO, GPIO_FN_JMCTDI,
+ GPIO_FN_JMCTRST,
+ GPIO_FN_SGPIO1_CLK, GPIO_FN_SGPIO1_LOAD, GPIO_FN_SGPIO1_DI,
+ GPIO_FN_SGPIO1_DO, GPIO_FN_SUB_CLKIN,
- /* PTP (mobule: JMC, SCIF234) */
- GPIO_FN_JMCTCK, GPIO_FN_JMCTMS, GPIO_FN_JMCTDO, GPIO_FN_JMCTDI,
- GPIO_FN_JMCRST, GPIO_FN_SCK4, GPIO_FN_SCK3,
+ /* PTO (mobule: SGPIO, SerMux) */
+ GPIO_FN_SGPIO0_CLK, GPIO_FN_SGPIO0_LOAD, GPIO_FN_SGPIO0_DI,
+ GPIO_FN_SGPIO0_DO, GPIO_FN_SGPIO2_CLK, GPIO_FN_SGPIO2_LOAD,
+ GPIO_FN_SGPIO2_DI, GPIO_FN_SGPIO2_DO, GPIO_FN_COM1_TXD,
+ GPIO_FN_COM1_RXD, GPIO_FN_COM1_RTS, GPIO_FN_COM1_CTS,
/* PTQ (mobule: LPC) */
GPIO_FN_LAD3, GPIO_FN_LAD2, GPIO_FN_LAD1, GPIO_FN_LAD0,
GPIO_FN_LFRAME, GPIO_FN_LRESET, GPIO_FN_LCLK,
/* PTR (mobule: GRA, IIC) */
- GPIO_FN_DDC3, GPIO_FN_DDC2,
- GPIO_FN_SDA8, GPIO_FN_SCL8, GPIO_FN_SDA2, GPIO_FN_SCL2,
+ GPIO_FN_DDC3, GPIO_FN_DDC2, GPIO_FN_SDA2, GPIO_FN_SCL2,
GPIO_FN_SDA1, GPIO_FN_SCL1, GPIO_FN_SDA0, GPIO_FN_SCL0,
+ GPIO_FN_SDA8, GPIO_FN_SCL8,
/* PTS (mobule: GRA, IIC) */
- GPIO_FN_DDC1, GPIO_FN_DDC0,
- GPIO_FN_SDA9, GPIO_FN_SCL9, GPIO_FN_SDA5, GPIO_FN_SCL5,
+ GPIO_FN_DDC1, GPIO_FN_DDC0, GPIO_FN_SDA5, GPIO_FN_SCL5,
GPIO_FN_SDA4, GPIO_FN_SCL4, GPIO_FN_SDA3, GPIO_FN_SCL3,
+ GPIO_FN_SDA9, GPIO_FN_SCL9,
- /* PTT (mobule: SYSTEM, PWMX) */
- GPIO_FN_AUDSYNC, GPIO_FN_AUDCK,
- GPIO_FN_AUDATA3, GPIO_FN_AUDATA2,
- GPIO_FN_AUDATA1, GPIO_FN_AUDATA0,
- GPIO_FN_PWX7, GPIO_FN_PWX6, GPIO_FN_PWX5, GPIO_FN_PWX4,
+ /* PTT (mobule: PWMX, AUD) */
+ GPIO_FN_PWMX7, GPIO_FN_PWMX6, GPIO_FN_PWMX5, GPIO_FN_PWMX4,
+ GPIO_FN_PWMX3, GPIO_FN_PWMX2, GPIO_FN_PWMX1, GPIO_FN_PWMX0,
+ GPIO_FN_AUDATA3, GPIO_FN_AUDATA2, GPIO_FN_AUDATA1,
+ GPIO_FN_AUDATA0, GPIO_FN_STATUS1, GPIO_FN_STATUS0,
- /* PTU (mobule: LBSC, DMAC) */
- GPIO_FN_CS6, GPIO_FN_CS5, GPIO_FN_CS4, GPIO_FN_CS0,
- GPIO_FN_RD, GPIO_FN_WE0, GPIO_FN_A25, GPIO_FN_A24,
- GPIO_FN_DREQ0, GPIO_FN_DACK0,
+ /* PTU (mobule: LPC, APM) */
+ GPIO_FN_LGPIO7, GPIO_FN_LGPIO6, GPIO_FN_LGPIO5, GPIO_FN_LGPIO4,
+ GPIO_FN_LGPIO3, GPIO_FN_LGPIO2, GPIO_FN_LGPIO1, GPIO_FN_LGPIO0,
+ GPIO_FN_APMONCTL_O, GPIO_FN_APMPWBTOUT_O, GPIO_FN_APMSCI_O,
+ GPIO_FN_APMVDDON, GPIO_FN_APMSLPBTN, GPIO_FN_APMPWRBTN,
+ GPIO_FN_APMS5N, GPIO_FN_APMS3N,
- /* PTV (mobule: LBSC, DMAC) */
+ /* PTV (mobule: LBSC, SerMux, R-SPI, EVC, GRA) */
GPIO_FN_A23, GPIO_FN_A22, GPIO_FN_A21, GPIO_FN_A20,
GPIO_FN_A19, GPIO_FN_A18, GPIO_FN_A17, GPIO_FN_A16,
- GPIO_FN_TEND0, GPIO_FN_DREQ1, GPIO_FN_DACK1, GPIO_FN_TEND1,
+ GPIO_FN_COM2_RI, GPIO_FN_R_SPI_MOSI, GPIO_FN_R_SPI_MISO,
+ GPIO_FN_R_SPI_RSPCK, GPIO_FN_R_SPI_SSL0, GPIO_FN_R_SPI_SSL1,
+ GPIO_FN_EVENT7, GPIO_FN_EVENT6, GPIO_FN_VBIOS_DI,
+ GPIO_FN_VBIOS_DO, GPIO_FN_VBIOS_CLK, GPIO_FN_VBIOS_CS,
- /* PTW (mobule: LBSC) */
+ /* PTW (mobule: LBSC, EVC, SCIF) */
GPIO_FN_A15, GPIO_FN_A14, GPIO_FN_A13, GPIO_FN_A12,
GPIO_FN_A11, GPIO_FN_A10, GPIO_FN_A9, GPIO_FN_A8,
+ GPIO_FN_EVENT5, GPIO_FN_EVENT4, GPIO_FN_EVENT3, GPIO_FN_EVENT2,
+ GPIO_FN_EVENT1, GPIO_FN_EVENT0, GPIO_FN_CTS4, GPIO_FN_CTS2,
- /* PTX (mobule: LBSC) */
+ /* PTX (mobule: LBSC, SCIF, SIM) */
GPIO_FN_A7, GPIO_FN_A6, GPIO_FN_A5, GPIO_FN_A4,
GPIO_FN_A3, GPIO_FN_A2, GPIO_FN_A1, GPIO_FN_A0,
+ GPIO_FN_RTS2, GPIO_FN_SIM_D, GPIO_FN_SIM_CLK, GPIO_FN_SIM_RST,
/* PTY (mobule: LBSC) */
GPIO_FN_D7, GPIO_FN_D6, GPIO_FN_D5, GPIO_FN_D4,
GPIO_FN_D3, GPIO_FN_D2, GPIO_FN_D1, GPIO_FN_D0,
+
+ /* PTZ (mobule: eMMC, ONFI) */
+ GPIO_FN_MMCDAT7, GPIO_FN_MMCDAT6, GPIO_FN_MMCDAT5,
+ GPIO_FN_MMCDAT4, GPIO_FN_MMCDAT3, GPIO_FN_MMCDAT2,
+ GPIO_FN_MMCDAT1, GPIO_FN_MMCDAT0,
+ GPIO_FN_ON_DQ7, GPIO_FN_ON_DQ6, GPIO_FN_ON_DQ5, GPIO_FN_ON_DQ4,
+ GPIO_FN_ON_DQ3, GPIO_FN_ON_DQ2, GPIO_FN_ON_DQ1, GPIO_FN_ON_DQ0,
};
#endif /* __ASM_SH7757_H__ */
diff --git a/arch/sh/include/cpu-sh4/cpu/shx3.h b/arch/sh/include/cpu-sh4/cpu/shx3.h
new file mode 100644
index 000000000000..68d9080a8da9
--- /dev/null
+++ b/arch/sh/include/cpu-sh4/cpu/shx3.h
@@ -0,0 +1,64 @@
+#ifndef __CPU_SHX3_H
+#define __CPU_SHX3_H
+
+enum {
+ /* PA */
+ GPIO_PA7, GPIO_PA6, GPIO_PA5, GPIO_PA4,
+ GPIO_PA3, GPIO_PA2, GPIO_PA1, GPIO_PA0,
+
+ /* PB */
+ GPIO_PB7, GPIO_PB6, GPIO_PB5, GPIO_PB4,
+ GPIO_PB3, GPIO_PB2, GPIO_PB1, GPIO_PB0,
+
+ /* PC */
+ GPIO_PC7, GPIO_PC6, GPIO_PC5, GPIO_PC4,
+ GPIO_PC3, GPIO_PC2, GPIO_PC1, GPIO_PC0,
+
+ /* PD */
+ GPIO_PD7, GPIO_PD6, GPIO_PD5, GPIO_PD4,
+ GPIO_PD3, GPIO_PD2, GPIO_PD1, GPIO_PD0,
+
+ /* PE */
+ GPIO_PE7, GPIO_PE6, GPIO_PE5, GPIO_PE4,
+ GPIO_PE3, GPIO_PE2, GPIO_PE1, GPIO_PE0,
+
+ /* PF */
+ GPIO_PF7, GPIO_PF6, GPIO_PF5, GPIO_PF4,
+ GPIO_PF3, GPIO_PF2, GPIO_PF1, GPIO_PF0,
+
+ /* PG */
+ GPIO_PG7, GPIO_PG6, GPIO_PG5, GPIO_PG4,
+ GPIO_PG3, GPIO_PG2, GPIO_PG1, GPIO_PG0,
+
+ /* PH */
+ GPIO_PH5, GPIO_PH4,
+ GPIO_PH3, GPIO_PH2, GPIO_PH1, GPIO_PH0,
+
+ /* SCIF */
+ GPIO_FN_SCK3, GPIO_FN_TXD3, GPIO_FN_RXD3,
+ GPIO_FN_SCK2, GPIO_FN_TXD2, GPIO_FN_RXD2,
+ GPIO_FN_SCK1, GPIO_FN_TXD1, GPIO_FN_RXD1,
+ GPIO_FN_SCK0, GPIO_FN_TXD0, GPIO_FN_RXD0,
+
+ /* LBSC */
+ GPIO_FN_D31, GPIO_FN_D30, GPIO_FN_D29, GPIO_FN_D28,
+ GPIO_FN_D27, GPIO_FN_D26, GPIO_FN_D25, GPIO_FN_D24,
+ GPIO_FN_D23, GPIO_FN_D22, GPIO_FN_D21, GPIO_FN_D20,
+ GPIO_FN_D19, GPIO_FN_D18, GPIO_FN_D17, GPIO_FN_D16,
+ GPIO_FN_WE3, GPIO_FN_WE2, GPIO_FN_CS6, GPIO_FN_CS5,
+ GPIO_FN_CS4, GPIO_FN_CLKOUTENB, GPIO_FN_BREQ,
+ GPIO_FN_IOIS16, GPIO_FN_CE2B, GPIO_FN_CE2A, GPIO_FN_BACK,
+
+ /* DMAC */
+ GPIO_FN_DACK0, GPIO_FN_DREQ0, GPIO_FN_DRAK0,
+ GPIO_FN_DACK1, GPIO_FN_DREQ1, GPIO_FN_DRAK1,
+ GPIO_FN_DACK2, GPIO_FN_DREQ2, GPIO_FN_DRAK2,
+ GPIO_FN_DACK3, GPIO_FN_DREQ3, GPIO_FN_DRAK3,
+
+ /* INTC */
+ GPIO_FN_IRQ3, GPIO_FN_IRQ2, GPIO_FN_IRQ1, GPIO_FN_IRQ0,
+ GPIO_FN_IRL3, GPIO_FN_IRL2, GPIO_FN_IRL1, GPIO_FN_IRL0,
+ GPIO_FN_IRQOUT, GPIO_FN_STATUS1, GPIO_FN_STATUS0,
+};
+
+#endif /* __CPU_SHX3_H */
diff --git a/arch/sh/include/mach-common/mach/sh2007.h b/arch/sh/include/mach-common/mach/sh2007.h
new file mode 100644
index 000000000000..48180b9aa03d
--- /dev/null
+++ b/arch/sh/include/mach-common/mach/sh2007.h
@@ -0,0 +1,117 @@
+#ifndef __MACH_SH2007_H
+#define __MACH_SH2007_H
+
+#define CS5BCR 0xff802050
+#define CS5WCR 0xff802058
+#define CS5PCR 0xff802070
+
+#define BUS_SZ8 1
+#define BUS_SZ16 2
+#define BUS_SZ32 3
+
+#define PCMCIA_IODYN 1
+#define PCMCIA_ATA 0
+#define PCMCIA_IO8 2
+#define PCMCIA_IO16 3
+#define PCMCIA_COMM8 4
+#define PCMCIA_COMM16 5
+#define PCMCIA_ATTR8 6
+#define PCMCIA_ATTR16 7
+
+#define TYPE_SRAM 0
+#define TYPE_PCMCIA 4
+
+/* write-read/write-write delay (0-7:0,1,2,3,4,5,6,7) */
+#define IWW5 0
+#define IWW6 3
+/* different area, read-write delay (0-7:0,1,2,3,4,5,6,7) */
+#define IWRWD5 2
+#define IWRWD6 2
+/* same area, read-write delay (0-7:0,1,2,3,4,5,6,7) */
+#define IWRWS5 2
+#define IWRWS6 2
+/* different area, read-read delay (0-7:0,1,2,3,4,5,6,7) */
+#define IWRRD5 2
+#define IWRRD6 2
+/* same area, read-read delay (0-7:0,1,2,3,4,5,6,7) */
+#define IWRRS5 0
+#define IWRRS6 2
+/* burst count (0-3:4,8,16,32) */
+#define BST5 0
+#define BST6 0
+/* bus size */
+#define SZ5 BUS_SZ16
+#define SZ6 BUS_SZ16
+/* RD hold for SRAM (0-1:0,1) */
+#define RDSPL5 0
+#define RDSPL6 0
+/* Burst pitch (0-7:0,1,2,3,4,5,6,7) */
+#define BW5 0
+#define BW6 0
+/* Multiplex (0-1:0,1) */
+#define MPX5 0
+#define MPX6 0
+/* device type */
+#define TYPE5 TYPE_PCMCIA
+#define TYPE6 TYPE_PCMCIA
+/* address setup before assert CSn for SRAM (0-7:0,1,2,3,4,5,6,7) */
+#define ADS5 0
+#define ADS6 0
+/* address hold after negate CSn for SRAM (0-7:0,1,2,3,4,5,6,7) */
+#define ADH5 0
+#define ADH6 0
+/* CSn assert to RD assert delay for SRAM (0-7:0,1,2,3,4,5,6,7) */
+#define RDS5 0
+#define RDS6 0
+/* RD negate to CSn negate delay for SRAM (0-7:0,1,2,3,4,5,6,7) */
+#define RDH5 0
+#define RDH6 0
+/* CSn assert to WE assert delay for SRAM (0-7:0,1,2,3,4,5,6,7) */
+#define WTS5 0
+#define WTS6 0
+/* WE negate to CSn negate delay for SRAM (0-7:0,1,2,3,4,5,6,7) */
+#define WTH5 0
+#define WTH6 0
+/* BS hold (0-1:1,2) */
+#define BSH5 0
+#define BSH6 0
+/* wait cycle (0-15:0,1,2,3,4,5,6,7,8,9,11,13,15,17,21,25) */
+#define IW5 6 /* 60ns PIO mode 4 */
+#define IW6 15 /* 250ns */
+
+#define SAA5 PCMCIA_IODYN /* IDE area b4000000-b5ffffff */
+#define SAB5 PCMCIA_IODYN /* CF area b6000000-b7ffffff */
+#define PCWA5 0 /* additional wait A (0-3:0,15,30,50) */
+#define PCWB5 0 /* additional wait B (0-3:0,15,30,50) */
+/* wait B (0-15:0,1,2,3,4,5,6,7,8,9,11,13,15,17,21,25) */
+#define PCIW5 12
+/* Address->OE/WE assert delay A (0-7:0,1,2,3,6,9,12,15) */
+#define TEDA5 2
+/* Address->OE/WE assert delay B (0-7:0,1,2,3,6,9,12,15) */
+#define TEDB5 4
+/* OE/WE negate->Address delay A (0-7:0,1,2,3,6,9,12,15) */
+#define TEHA5 2
+/* OE/WE negate->Address delay B (0-7:0,1,2,3,6,9,12,15) */
+#define TEHB5 3
+
+#define CS5BCR_D ((IWW5<<28)|(IWRWD5<<24)|(IWRWS5<<20)| \
+ (IWRRD5<<16)|(IWRRS5<<12)|(BST5<<10)| \
+ (SZ5<<8)|(RDSPL5<<7)|(BW5<<4)|(MPX5<<3)|TYPE5)
+#define CS5WCR_D ((ADS5<<28)|(ADH5<<24)|(RDS5<<20)| \
+ (RDH5<<16)|(WTS5<<12)|(WTH5<<8)|(BSH5<<4)|IW5)
+#define CS5PCR_D ((SAA5<<28)|(SAB5<<24)|(PCWA5<<22)| \
+ (PCWB5<<20)|(PCIW5<<16)|(TEDA5<<12)| \
+ (TEDB5<<8)|(TEHA5<<4)|TEHB5)
+
+#define SMC0_BASE 0xb0800000 /* eth0 */
+#define SMC1_BASE 0xb0900000 /* eth1 */
+#define CF_BASE 0xb6100000 /* Compact Flash (I/O area) */
+#define IDE_BASE 0xb4000000 /* IDE */
+#define PC104_IO_BASE 0xb8000000
+#define PC104_MEM_BASE 0xba000000
+#define SMC_IO_SIZE 0x100
+
+#define CF_OFFSET 0x1f0
+#define IDE_OFFSET 0x170
+
+#endif /* __MACH_SH2007_H */
diff --git a/arch/sh/include/mach-sdk7786/mach/fpga.h b/arch/sh/include/mach-sdk7786/mach/fpga.h
index 416b621d94d1..40f0c2d3690c 100644
--- a/arch/sh/include/mach-sdk7786/mach/fpga.h
+++ b/arch/sh/include/mach-sdk7786/mach/fpga.h
@@ -31,11 +31,35 @@
#define EXTASR 0x110
#define SPCAR 0x120
#define INTMSR 0x130
+
#define PCIECR 0x140
+#define PCIECR_PCIEMUX1 BIT(15)
+#define PCIECR_PCIEMUX0 BIT(14)
+#define PCIECR_PRST4 BIT(12) /* slot 4 card present */
+#define PCIECR_PRST3 BIT(11) /* slot 3 card present */
+#define PCIECR_PRST2 BIT(10) /* slot 2 card present */
+#define PCIECR_PRST1 BIT(9) /* slot 1 card present */
+#define PCIECR_CLKEN BIT(4) /* oscillator enable */
+
#define FAER 0x150
#define USRGPIR 0x160
+
/* 0x170 reserved */
-#define LCLASR 0x180
+
+#define LCLASR 0x180
+#define LCLASR_FRAMEN BIT(15)
+
+#define LCLASR_FPGA_SEL_SHIFT 12
+#define LCLASR_NAND_SEL_SHIFT 8
+#define LCLASR_NORB_SEL_SHIFT 4
+#define LCLASR_NORA_SEL_SHIFT 0
+
+#define LCLASR_AREA_MASK 0x7
+
+#define LCLASR_FPGA_SEL_MASK (LCLASR_AREA_MASK << LCLASR_FPGA_SEL_SHIFT)
+#define LCLASR_NAND_SEL_MASK (LCLASR_AREA_MASK << LCLASR_NAND_SEL_SHIFT)
+#define LCLASR_NORB_SEL_MASK (LCLASR_AREA_MASK << LCLASR_NORB_SEL_SHIFT)
+#define LCLASR_NORA_SEL_MASK (LCLASR_AREA_MASK << LCLASR_NORA_SEL_SHIFT)
#define SBCR 0x190
#define SCBR_I2CMEN BIT(0) /* FPGA I2C master enable */
diff --git a/arch/sh/include/mach-x3proto/mach/hardware.h b/arch/sh/include/mach-x3proto/mach/hardware.h
new file mode 100644
index 000000000000..52bca57bfeb6
--- /dev/null
+++ b/arch/sh/include/mach-x3proto/mach/hardware.h
@@ -0,0 +1,12 @@
+#ifndef __MACH_X3PROTO_HARDWARE_H
+#define __MACH_X3PROTO_HARDWARE_H
+
+struct gpio_chip;
+
+/* arch/sh/boards/mach-x3proto/gpio.c */
+int x3proto_gpio_setup(void);
+extern struct gpio_chip x3proto_gpio_chip;
+
+#define NR_BASEBOARD_GPIOS 16
+
+#endif /* __MACH_X3PROTO_HARDWARE_H */
diff --git a/arch/sh/include/asm/ilsel.h b/arch/sh/include/mach-x3proto/mach/ilsel.h
index e3d304b280f6..e3d304b280f6 100644
--- a/arch/sh/include/asm/ilsel.h
+++ b/arch/sh/include/mach-x3proto/mach/ilsel.h
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index e25f3c69525d..8eed6a485446 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -12,9 +12,9 @@ endif
CFLAGS_REMOVE_return_address.o = -pg
obj-y := clkdev.o debugtraps.o dma-nommu.o dumpstack.o \
- idle.o io.o irq.o \
- irq_$(BITS).o machvec.o nmi_debug.o process.o \
- process_$(BITS).o ptrace_$(BITS).o \
+ idle.o io.o irq.o irq_$(BITS).o kdebugfs.o \
+ machvec.o nmi_debug.o process.o \
+ process_$(BITS).o ptrace.o ptrace_$(BITS).o \
reboot.o return_address.o \
setup.o signal_$(BITS).o sys_sh.o sys_sh$(BITS).o \
syscalls_$(BITS).o time.o topology.o traps.o \
@@ -44,4 +44,4 @@ obj-$(CONFIG_HAS_IOPORT) += io_generic.o
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o
-EXTRA_CFLAGS += -Werror
+ccflags-y := -Werror
diff --git a/arch/sh/kernel/clkdev.c b/arch/sh/kernel/clkdev.c
index befc255830a4..1f800ef4a735 100644
--- a/arch/sh/kernel/clkdev.c
+++ b/arch/sh/kernel/clkdev.c
@@ -161,9 +161,11 @@ EXPORT_SYMBOL(clk_add_alias);
*/
void clkdev_drop(struct clk_lookup *cl)
{
+ struct clk_lookup_alloc *cla = container_of(cl, struct clk_lookup_alloc, cl);
+
mutex_lock(&clocks_mutex);
list_del(&cl->node);
mutex_unlock(&clocks_mutex);
- kfree(cl);
+ kfree(cla);
}
EXPORT_SYMBOL(clkdev_drop);
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c
index d180f16281ed..b93458f33b74 100644
--- a/arch/sh/kernel/cpu/sh4/probe.c
+++ b/arch/sh/kernel/cpu/sh4/probe.c
@@ -150,7 +150,7 @@ void __cpuinit cpu_probe(void)
boot_cpu_data.type = CPU_SH7724;
boot_cpu_data.flags |= CPU_HAS_L2_CACHE;
break;
- case 0x50:
+ case 0x10:
boot_cpu_data.type = CPU_SH7757;
break;
}
diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile
index b144e8af89dc..cc122b1d3035 100644
--- a/arch/sh/kernel/cpu/sh4a/Makefile
+++ b/arch/sh/kernel/cpu/sh4a/Makefile
@@ -8,13 +8,13 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7763) += setup-sh7763.o
obj-$(CONFIG_CPU_SUBTYPE_SH7770) += setup-sh7770.o
obj-$(CONFIG_CPU_SUBTYPE_SH7780) += setup-sh7780.o
obj-$(CONFIG_CPU_SUBTYPE_SH7785) += setup-sh7785.o
-obj-$(CONFIG_CPU_SUBTYPE_SH7786) += setup-sh7786.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7786) += setup-sh7786.o intc-shx3.o
obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o
obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o
obj-$(CONFIG_CPU_SUBTYPE_SH7723) += setup-sh7723.o
obj-$(CONFIG_CPU_SUBTYPE_SH7724) += setup-sh7724.o
obj-$(CONFIG_CPU_SUBTYPE_SH7366) += setup-sh7366.o
-obj-$(CONFIG_CPU_SUBTYPE_SHX3) += setup-shx3.o
+obj-$(CONFIG_CPU_SUBTYPE_SHX3) += setup-shx3.o intc-shx3.o
# SMP setup
smp-$(CONFIG_CPU_SHX3) := smp-shx3.o
@@ -40,6 +40,7 @@ pinmux-$(CONFIG_CPU_SUBTYPE_SH7724) := pinmux-sh7724.o
pinmux-$(CONFIG_CPU_SUBTYPE_SH7757) := pinmux-sh7757.o
pinmux-$(CONFIG_CPU_SUBTYPE_SH7785) := pinmux-sh7785.o
pinmux-$(CONFIG_CPU_SUBTYPE_SH7786) := pinmux-sh7786.o
+pinmux-$(CONFIG_CPU_SUBTYPE_SHX3) := pinmux-shx3.o
obj-y += $(clock-y)
obj-$(CONFIG_SMP) += $(smp-y)
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
index 0a752bd324ac..ce39a2ae8c6c 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
@@ -3,7 +3,7 @@
*
* SH7757 support for the clock framework
*
- * Copyright (C) 2009 Renesas Solutions Corp.
+ * Copyright (C) 2009-2010 Renesas Solutions Corp.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -16,124 +16,147 @@
#include <asm/clock.h>
#include <asm/freq.h>
-static int ifc_divisors[] = { 2, 1, 4, 1, 1, 8, 1, 1,
- 16, 1, 1, 32, 1, 1, 1, 1 };
-static int sfc_divisors[] = { 2, 1, 4, 1, 1, 8, 1, 1,
- 16, 1, 1, 32, 1, 1, 1, 1 };
-static int bfc_divisors[] = { 2, 1, 4, 1, 1, 8, 1, 1,
- 16, 1, 1, 32, 1, 1, 1, 1 };
-static int p1fc_divisors[] = { 2, 1, 4, 1, 1, 8, 1, 1,
- 16, 1, 1, 32, 1, 1, 1, 1 };
+/*
+ * Default rate for the root input clock, reset this with clk_set_rate()
+ * from the platform code.
+ */
+static struct clk extal_clk = {
+ .rate = 48000000,
+};
-static void master_clk_init(struct clk *clk)
+static unsigned long pll_recalc(struct clk *clk)
{
- clk->rate = CONFIG_SH_PCLK_FREQ * 16;
-}
+ int multiplier;
-static struct clk_ops sh7757_master_clk_ops = {
- .init = master_clk_init,
-};
+ multiplier = test_mode_pin(MODE_PIN0) ? 24 : 16;
-static void module_clk_recalc(struct clk *clk)
-{
- int idx = __raw_readl(FRQCR) & 0x0000000f;
- clk->rate = clk->parent->rate / p1fc_divisors[idx];
+ return clk->parent->rate * multiplier;
}
-static struct clk_ops sh7757_module_clk_ops = {
- .recalc = module_clk_recalc,
+static struct clk_ops pll_clk_ops = {
+ .recalc = pll_recalc,
};
-static void bus_clk_recalc(struct clk *clk)
-{
- int idx = (__raw_readl(FRQCR) >> 8) & 0x0000000f;
- clk->rate = clk->parent->rate / bfc_divisors[idx];
-}
+static struct clk pll_clk = {
+ .ops = &pll_clk_ops,
+ .parent = &extal_clk,
+ .flags = CLK_ENABLE_ON_INIT,
+};
-static struct clk_ops sh7757_bus_clk_ops = {
- .recalc = bus_clk_recalc,
+static struct clk *clks[] = {
+ &extal_clk,
+ &pll_clk,
};
-static void cpu_clk_recalc(struct clk *clk)
-{
- int idx = (__raw_readl(FRQCR) >> 20) & 0x0000000f;
- clk->rate = clk->parent->rate / ifc_divisors[idx];
-}
+static unsigned int div2[] = { 1, 1, 2, 1, 1, 4, 1, 6,
+ 1, 1, 1, 16, 1, 24, 1, 1 };
-static struct clk_ops sh7757_cpu_clk_ops = {
- .recalc = cpu_clk_recalc,
+static struct clk_div_mult_table div4_div_mult_table = {
+ .divisors = div2,
+ .nr_divisors = ARRAY_SIZE(div2),
};
-static struct clk_ops *sh7757_clk_ops[] = {
- &sh7757_master_clk_ops,
- &sh7757_module_clk_ops,
- &sh7757_bus_clk_ops,
- &sh7757_cpu_clk_ops,
+static struct clk_div4_table div4_table = {
+ .div_mult_table = &div4_div_mult_table,
};
-void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
-{
- if (idx < ARRAY_SIZE(sh7757_clk_ops))
- *ops = sh7757_clk_ops[idx];
-}
+enum { DIV4_I, DIV4_SH, DIV4_P, DIV4_NR };
-static void shyway_clk_recalc(struct clk *clk)
-{
- int idx = (__raw_readl(FRQCR) >> 12) & 0x0000000f;
- clk->rate = clk->parent->rate / sfc_divisors[idx];
-}
-
-static struct clk_ops sh7757_shyway_clk_ops = {
- .recalc = shyway_clk_recalc,
-};
+#define DIV4(_bit, _mask, _flags) \
+ SH_CLK_DIV4(&pll_clk, FRQCR, _bit, _mask, _flags)
-static struct clk sh7757_shyway_clk = {
- .flags = CLK_ENABLE_ON_INIT,
- .ops = &sh7757_shyway_clk_ops,
+struct clk div4_clks[DIV4_NR] = {
+ /*
+ * P clock is always enable, because some P clock modules is used
+ * by Host PC.
+ */
+ [DIV4_P] = DIV4(0, 0x2800, CLK_ENABLE_ON_INIT),
+ [DIV4_SH] = DIV4(12, 0x00a0, CLK_ENABLE_ON_INIT),
+ [DIV4_I] = DIV4(20, 0x0004, CLK_ENABLE_ON_INIT),
};
-/*
- * Additional sh7757-specific on-chip clocks that aren't already part of the
- * clock framework
- */
-static struct clk *sh7757_onchip_clocks[] = {
- &sh7757_shyway_clk,
+#define MSTPCR0 0xffc80030
+#define MSTPCR1 0xffc80034
+
+enum { MSTP004, MSTP000, MSTP114, MSTP113, MSTP112,
+ MSTP111, MSTP110, MSTP103, MSTP102,
+ MSTP_NR };
+
+static struct clk mstp_clks[MSTP_NR] = {
+ /* MSTPCR0 */
+ [MSTP004] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 4, 0),
+ [MSTP000] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 0, 0),
+
+ /* MSTPCR1 */
+ [MSTP114] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 14, 0),
+ [MSTP113] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 13, 0),
+ [MSTP112] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 12, 0),
+ [MSTP111] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 11, 0),
+ [MSTP110] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 10, 0),
+ [MSTP103] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 3, 0),
+ [MSTP102] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 2, 0),
};
#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
static struct clk_lookup lookups[] = {
/* main clocks */
- CLKDEV_CON_ID("shyway_clk", &sh7757_shyway_clk),
+ CLKDEV_CON_ID("extal", &extal_clk),
+ CLKDEV_CON_ID("pll_clk", &pll_clk),
+
+ /* DIV4 clocks */
+ CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
+ CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]),
+ CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
+
+ /* MSTP32 clocks */
+ CLKDEV_CON_ID("sdhi0", &mstp_clks[MSTP004]),
+ CLKDEV_CON_ID("riic", &mstp_clks[MSTP000]),
+ {
+ /* TMU0 */
+ .dev_id = "sh_tmu.0",
+ .con_id = "tmu_fck",
+ .clk = &mstp_clks[MSTP113],
+ }, {
+ /* TMU1 */
+ .dev_id = "sh_tmu.1",
+ .con_id = "tmu_fck",
+ .clk = &mstp_clks[MSTP114],
+ },
+ {
+ /* SCIF4 (But, ID is 2) */
+ .dev_id = "sh-sci.2",
+ .con_id = "sci_fck",
+ .clk = &mstp_clks[MSTP112],
+ }, {
+ /* SCIF3 */
+ .dev_id = "sh-sci.1",
+ .con_id = "sci_fck",
+ .clk = &mstp_clks[MSTP111],
+ }, {
+ /* SCIF2 */
+ .dev_id = "sh-sci.0",
+ .con_id = "sci_fck",
+ .clk = &mstp_clks[MSTP110],
+ },
+ CLKDEV_CON_ID("usb0", &mstp_clks[MSTP102]),
};
-static int __init sh7757_clk_init(void)
+int __init arch_clk_init(void)
{
- struct clk *clk = clk_get(NULL, "master_clk");
- int i;
-
- for (i = 0; i < ARRAY_SIZE(sh7757_onchip_clocks); i++) {
- struct clk *clkp = sh7757_onchip_clocks[i];
+ int i, ret = 0;
- clkp->parent = clk;
- clk_register(clkp);
- clk_enable(clkp);
- }
+ for (i = 0; i < ARRAY_SIZE(clks); i++)
+ ret |= clk_register(clks[i]);
+ for (i = 0; i < ARRAY_SIZE(lookups); i++)
+ clkdev_add(&lookups[i]);
- /*
- * Now that we have the rest of the clocks registered, we need to
- * force the parent clock to propagate so that these clocks will
- * automatically figure out their rate. We cheat by handing the
- * parent clock its current rate and forcing child propagation.
- */
- clk_set_rate(clk, clk_get_rate(clk));
+ if (!ret)
+ ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks),
+ &div4_table);
+ if (!ret)
+ ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
- clk_put(clk);
-
- clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-
- return 0;
+ return ret;
}
-arch_initcall(sh7757_clk_init);
-
diff --git a/arch/sh/kernel/cpu/sh4a/clock-shx3.c b/arch/sh/kernel/cpu/sh4a/clock-shx3.c
index 236a6282d778..4f70df6b6169 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-shx3.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-shx3.c
@@ -5,7 +5,7 @@
*
* Copyright (C) 2006-2007 Renesas Technology Corp.
* Copyright (C) 2006-2007 Renesas Solutions Corp.
- * Copyright (C) 2006-2007 Paul Mundt
+ * Copyright (C) 2006-2010 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -18,120 +18,179 @@
#include <asm/clock.h>
#include <asm/freq.h>
-static int ifc_divisors[] = { 1, 2, 4 ,6 };
-static int bfc_divisors[] = { 1, 1, 1, 1, 1, 12, 16, 18, 24, 32, 36, 48 };
-static int pfc_divisors[] = { 1, 1, 1, 1, 1, 1, 1, 18, 24, 32, 36, 48 };
-static int cfc_divisors[] = { 1, 1, 4, 6 };
-
-#define IFC_POS 28
-#define IFC_MSK 0x0003
-#define BFC_MSK 0x000f
-#define PFC_MSK 0x000f
-#define CFC_MSK 0x0003
-#define BFC_POS 16
-#define PFC_POS 0
-#define CFC_POS 20
-
-static void master_clk_init(struct clk *clk)
-{
- clk->rate *= pfc_divisors[(__raw_readl(FRQCR) >> PFC_POS) & PFC_MSK];
-}
-
-static struct clk_ops shx3_master_clk_ops = {
- .init = master_clk_init,
+/*
+ * Default rate for the root input clock, reset this with clk_set_rate()
+ * from the platform code.
+ */
+static struct clk extal_clk = {
+ .rate = 16666666,
};
-static unsigned long module_clk_recalc(struct clk *clk)
+static unsigned long pll_recalc(struct clk *clk)
{
- int idx = ((__raw_readl(FRQCR) >> PFC_POS) & PFC_MSK);
- return clk->parent->rate / pfc_divisors[idx];
+ /* PLL1 has a fixed x72 multiplier. */
+ return clk->parent->rate * 72;
}
-static struct clk_ops shx3_module_clk_ops = {
- .recalc = module_clk_recalc,
+static struct clk_ops pll_clk_ops = {
+ .recalc = pll_recalc,
};
-static unsigned long bus_clk_recalc(struct clk *clk)
-{
- int idx = ((__raw_readl(FRQCR) >> BFC_POS) & BFC_MSK);
- return clk->parent->rate / bfc_divisors[idx];
-}
+static struct clk pll_clk = {
+ .ops = &pll_clk_ops,
+ .parent = &extal_clk,
+ .flags = CLK_ENABLE_ON_INIT,
+};
-static struct clk_ops shx3_bus_clk_ops = {
- .recalc = bus_clk_recalc,
+static struct clk *clks[] = {
+ &extal_clk,
+ &pll_clk,
};
-static unsigned long cpu_clk_recalc(struct clk *clk)
-{
- int idx = ((__raw_readl(FRQCR) >> IFC_POS) & IFC_MSK);
- return clk->parent->rate / ifc_divisors[idx];
-}
+static unsigned int div2[] = { 1, 2, 4, 6, 8, 12, 16, 18,
+ 24, 32, 36, 48 };
-static struct clk_ops shx3_cpu_clk_ops = {
- .recalc = cpu_clk_recalc,
+static struct clk_div_mult_table div4_div_mult_table = {
+ .divisors = div2,
+ .nr_divisors = ARRAY_SIZE(div2),
};
-static struct clk_ops *shx3_clk_ops[] = {
- &shx3_master_clk_ops,
- &shx3_module_clk_ops,
- &shx3_bus_clk_ops,
- &shx3_cpu_clk_ops,
+static struct clk_div4_table div4_table = {
+ .div_mult_table = &div4_div_mult_table,
};
-void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
-{
- if (idx < ARRAY_SIZE(shx3_clk_ops))
- *ops = shx3_clk_ops[idx];
-}
+enum { DIV4_I, DIV4_SH, DIV4_B, DIV4_DDR, DIV4_SHA, DIV4_P, DIV4_NR };
-static unsigned long shyway_clk_recalc(struct clk *clk)
-{
- int idx = ((__raw_readl(FRQCR) >> CFC_POS) & CFC_MSK);
- return clk->parent->rate / cfc_divisors[idx];
-}
+#define DIV4(_bit, _mask, _flags) \
+ SH_CLK_DIV4(&pll_clk, FRQMR1, _bit, _mask, _flags)
-static struct clk_ops shx3_shyway_clk_ops = {
- .recalc = shyway_clk_recalc,
+struct clk div4_clks[DIV4_NR] = {
+ [DIV4_P] = DIV4(0, 0x0f80, 0),
+ [DIV4_SHA] = DIV4(4, 0x0ff0, 0),
+ [DIV4_DDR] = DIV4(12, 0x000c, CLK_ENABLE_ON_INIT),
+ [DIV4_B] = DIV4(16, 0x0fe0, CLK_ENABLE_ON_INIT),
+ [DIV4_SH] = DIV4(20, 0x000c, CLK_ENABLE_ON_INIT),
+ [DIV4_I] = DIV4(28, 0x000e, CLK_ENABLE_ON_INIT),
};
-static struct clk shx3_shyway_clk = {
- .flags = CLK_ENABLE_ON_INIT,
- .ops = &shx3_shyway_clk_ops,
-};
-
-/*
- * Additional SHx3-specific on-chip clocks that aren't already part of the
- * clock framework
- */
-static struct clk *shx3_onchip_clocks[] = {
- &shx3_shyway_clk,
+#define MSTPCR0 0xffc00030
+#define MSTPCR1 0xffc00034
+
+enum { MSTP027, MSTP026, MSTP025, MSTP024,
+ MSTP009, MSTP008, MSTP003, MSTP002,
+ MSTP001, MSTP000, MSTP119, MSTP105,
+ MSTP104, MSTP_NR };
+
+static struct clk mstp_clks[MSTP_NR] = {
+ /* MSTPCR0 */
+ [MSTP027] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 27, 0),
+ [MSTP026] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 26, 0),
+ [MSTP025] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 25, 0),
+ [MSTP024] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 24, 0),
+ [MSTP009] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 9, 0),
+ [MSTP008] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 8, 0),
+ [MSTP003] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 3, 0),
+ [MSTP002] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 2, 0),
+ [MSTP001] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 1, 0),
+ [MSTP000] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 0, 0),
+
+ /* MSTPCR1 */
+ [MSTP119] = SH_CLK_MSTP32(NULL, MSTPCR1, 19, 0),
+ [MSTP105] = SH_CLK_MSTP32(NULL, MSTPCR1, 5, 0),
+ [MSTP104] = SH_CLK_MSTP32(NULL, MSTPCR1, 4, 0),
};
#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
static struct clk_lookup lookups[] = {
/* main clocks */
- CLKDEV_CON_ID("shyway_clk", &shx3_shyway_clk),
+ CLKDEV_CON_ID("extal", &extal_clk),
+ CLKDEV_CON_ID("pll_clk", &pll_clk),
+
+ /* DIV4 clocks */
+ CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
+ CLKDEV_CON_ID("shywaya_clk", &div4_clks[DIV4_SHA]),
+ CLKDEV_CON_ID("ddr_clk", &div4_clks[DIV4_DDR]),
+ CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]),
+ CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]),
+ CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
+
+ /* MSTP32 clocks */
+ {
+ /* SCIF3 */
+ .dev_id = "sh-sci.3",
+ .con_id = "sci_fck",
+ .clk = &mstp_clks[MSTP027],
+ }, {
+ /* SCIF2 */
+ .dev_id = "sh-sci.2",
+ .con_id = "sci_fck",
+ .clk = &mstp_clks[MSTP026],
+ }, {
+ /* SCIF1 */
+ .dev_id = "sh-sci.1",
+ .con_id = "sci_fck",
+ .clk = &mstp_clks[MSTP025],
+ }, {
+ /* SCIF0 */
+ .dev_id = "sh-sci.0",
+ .con_id = "sci_fck",
+ .clk = &mstp_clks[MSTP024],
+ },
+ CLKDEV_CON_ID("h8ex_fck", &mstp_clks[MSTP003]),
+ CLKDEV_CON_ID("csm_fck", &mstp_clks[MSTP002]),
+ CLKDEV_CON_ID("fe1_fck", &mstp_clks[MSTP001]),
+ CLKDEV_CON_ID("fe0_fck", &mstp_clks[MSTP000]),
+ {
+ /* TMU0 */
+ .dev_id = "sh_tmu.0",
+ .con_id = "tmu_fck",
+ .clk = &mstp_clks[MSTP008],
+ }, {
+ /* TMU1 */
+ .dev_id = "sh_tmu.1",
+ .con_id = "tmu_fck",
+ .clk = &mstp_clks[MSTP008],
+ }, {
+ /* TMU2 */
+ .dev_id = "sh_tmu.2",
+ .con_id = "tmu_fck",
+ .clk = &mstp_clks[MSTP008],
+ }, {
+ /* TMU3 */
+ .dev_id = "sh_tmu.3",
+ .con_id = "tmu_fck",
+ .clk = &mstp_clks[MSTP009],
+ }, {
+ /* TMU4 */
+ .dev_id = "sh_tmu.4",
+ .con_id = "tmu_fck",
+ .clk = &mstp_clks[MSTP009],
+ }, {
+ /* TMU5 */
+ .dev_id = "sh_tmu.5",
+ .con_id = "tmu_fck",
+ .clk = &mstp_clks[MSTP009],
+ },
+ CLKDEV_CON_ID("hudi_fck", &mstp_clks[MSTP119]),
+ CLKDEV_CON_ID("dmac_11_6_fck", &mstp_clks[MSTP105]),
+ CLKDEV_CON_ID("dmac_5_0_fck", &mstp_clks[MSTP104]),
};
int __init arch_clk_init(void)
{
- struct clk *clk;
int i, ret = 0;
- cpg_clk_init();
-
- clk = clk_get(NULL, "master_clk");
- for (i = 0; i < ARRAY_SIZE(shx3_onchip_clocks); i++) {
- struct clk *clkp = shx3_onchip_clocks[i];
-
- clkp->parent = clk;
- ret |= clk_register(clkp);
- }
-
- clk_put(clk);
+ for (i = 0; i < ARRAY_SIZE(clks); i++)
+ ret |= clk_register(clks[i]);
+ for (i = 0; i < ARRAY_SIZE(lookups); i++)
+ clkdev_add(&lookups[i]);
- clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+ if (!ret)
+ ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks),
+ &div4_table);
+ if (!ret)
+ ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
return ret;
}
diff --git a/arch/sh/kernel/cpu/sh4a/intc-shx3.c b/arch/sh/kernel/cpu/sh4a/intc-shx3.c
new file mode 100644
index 000000000000..78c971486b4e
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/intc-shx3.c
@@ -0,0 +1,34 @@
+/*
+ * Shared support for SH-X3 interrupt controllers.
+ *
+ * Copyright (C) 2009 - 2010 Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/init.h>
+
+#define INTACK 0xfe4100b8
+#define INTACKCLR 0xfe4100bc
+#define INTC_USERIMASK 0xfe411000
+
+#ifdef CONFIG_INTC_BALANCING
+unsigned int irq_lookup(unsigned int irq)
+{
+ return __raw_readl(INTACK) & 1 ? irq : NO_IRQ_IGNORE;
+}
+
+void irq_finish(unsigned int irq)
+{
+ __raw_writel(irq2evt(irq), INTACKCLR);
+}
+#endif
+
+static int __init shx3_irq_setup(void)
+{
+ return register_intc_userimask(INTC_USERIMASK);
+}
+arch_initcall(shx3_irq_setup);
diff --git a/arch/sh/kernel/cpu/sh4a/perf_event.c b/arch/sh/kernel/cpu/sh4a/perf_event.c
index eddc21973fa1..b8b873d8d6b5 100644
--- a/arch/sh/kernel/cpu/sh4a/perf_event.c
+++ b/arch/sh/kernel/cpu/sh4a/perf_event.c
@@ -1,7 +1,7 @@
/*
* Performance events support for SH-4A performance counters
*
- * Copyright (C) 2009 Paul Mundt
+ * Copyright (C) 2009, 2010 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -22,7 +22,25 @@
#define CCBR_CMDS (1 << 1)
#define CCBR_PPCE (1 << 0)
+#ifdef CONFIG_CPU_SHX3
+/*
+ * The PMCAT location for SH-X3 CPUs was quietly moved, while the CCBR
+ * and PMCTR locations remains tentatively constant. This change remains
+ * wholly undocumented, and was simply found through trial and error.
+ *
+ * Early cuts of SH-X3 still appear to use the SH-X/SH-X2 locations, and
+ * it's unclear when this ceased to be the case. For now we always use
+ * the new location (if future parts keep up with this trend then
+ * scanning for them at runtime also remains a viable option.)
+ *
+ * The gap in the register space also suggests that there are other
+ * undocumented counters, so this will need to be revisited at a later
+ * point in time.
+ */
+#define PPC_PMCAT 0xfc100240
+#else
#define PPC_PMCAT 0xfc100080
+#endif
#define PMCAT_OVF3 (1 << 27)
#define PMCAT_CNN3 (1 << 26)
diff --git a/arch/sh/kernel/cpu/sh4a/pinmux-sh7757.c b/arch/sh/kernel/cpu/sh4a/pinmux-sh7757.c
index ed23b155c097..4c74bd04bba4 100644
--- a/arch/sh/kernel/cpu/sh4a/pinmux-sh7757.c
+++ b/arch/sh/kernel/cpu/sh4a/pinmux-sh7757.c
@@ -1,11 +1,11 @@
/*
- * SH7757 (A0 step) Pinmux
+ * SH7757 (B0 step) Pinmux
*
- * Copyright (C) 2009 Renesas Solutions Corp.
+ * Copyright (C) 2009-2010 Renesas Solutions Corp.
*
* Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
*
- * Based on SH7757 Pinmux
+ * Based on SH7723 Pinmux
* Copyright (C) 2008 Magnus Damm
*
* This file is subject to the terms and conditions of the GNU General Public
@@ -40,27 +40,27 @@ enum {
PTH3_DATA, PTH2_DATA, PTH1_DATA, PTH0_DATA,
PTI7_DATA, PTI6_DATA, PTI5_DATA, PTI4_DATA,
PTI3_DATA, PTI2_DATA, PTI1_DATA, PTI0_DATA,
- PTJ7_DATA, PTJ6_DATA, PTJ5_DATA, PTJ4_DATA,
+ PTJ6_DATA, PTJ5_DATA, PTJ4_DATA,
PTJ3_DATA, PTJ2_DATA, PTJ1_DATA, PTJ0_DATA,
PTK7_DATA, PTK6_DATA, PTK5_DATA, PTK4_DATA,
PTK3_DATA, PTK2_DATA, PTK1_DATA, PTK0_DATA,
- PTL7_DATA, PTL6_DATA, PTL5_DATA, PTL4_DATA,
+ PTL6_DATA, PTL5_DATA, PTL4_DATA,
PTL3_DATA, PTL2_DATA, PTL1_DATA, PTL0_DATA,
- PTM6_DATA, PTM5_DATA, PTM4_DATA,
+ PTM7_DATA, PTM6_DATA, PTM5_DATA, PTM4_DATA,
PTM3_DATA, PTM2_DATA, PTM1_DATA, PTM0_DATA,
- PTN7_DATA, PTN6_DATA, PTN5_DATA, PTN4_DATA,
+ PTN6_DATA, PTN5_DATA, PTN4_DATA,
PTN3_DATA, PTN2_DATA, PTN1_DATA, PTN0_DATA,
PTO7_DATA, PTO6_DATA, PTO5_DATA, PTO4_DATA,
PTO3_DATA, PTO2_DATA, PTO1_DATA, PTO0_DATA,
- PTP6_DATA, PTP5_DATA, PTP4_DATA,
+ PTP7_DATA, PTP6_DATA, PTP5_DATA, PTP4_DATA,
PTP3_DATA, PTP2_DATA, PTP1_DATA, PTP0_DATA,
- PTQ6_DATA, PTQ5_DATA, PTQ4_DATA,
+ PTQ6_DATA, PTQ5_DATA, PTQ4_DATA,
PTQ3_DATA, PTQ2_DATA, PTQ1_DATA, PTQ0_DATA,
PTR7_DATA, PTR6_DATA, PTR5_DATA, PTR4_DATA,
PTR3_DATA, PTR2_DATA, PTR1_DATA, PTR0_DATA,
PTS7_DATA, PTS6_DATA, PTS5_DATA, PTS4_DATA,
PTS3_DATA, PTS2_DATA, PTS1_DATA, PTS0_DATA,
- PTT5_DATA, PTT4_DATA,
+ PTT7_DATA, PTT6_DATA, PTT5_DATA, PTT4_DATA,
PTT3_DATA, PTT2_DATA, PTT1_DATA, PTT0_DATA,
PTU7_DATA, PTU6_DATA, PTU5_DATA, PTU4_DATA,
PTU3_DATA, PTU2_DATA, PTU1_DATA, PTU0_DATA,
@@ -95,27 +95,27 @@ enum {
PTH3_IN, PTH2_IN, PTH1_IN, PTH0_IN,
PTI7_IN, PTI6_IN, PTI5_IN, PTI4_IN,
PTI3_IN, PTI2_IN, PTI1_IN, PTI0_IN,
- PTJ7_IN, PTJ6_IN, PTJ5_IN, PTJ4_IN,
+ PTJ6_IN, PTJ5_IN, PTJ4_IN,
PTJ3_IN, PTJ2_IN, PTJ1_IN, PTJ0_IN,
PTK7_IN, PTK6_IN, PTK5_IN, PTK4_IN,
PTK3_IN, PTK2_IN, PTK1_IN, PTK0_IN,
- PTL7_IN, PTL6_IN, PTL5_IN, PTL4_IN,
+ PTL6_IN, PTL5_IN, PTL4_IN,
PTL3_IN, PTL2_IN, PTL1_IN, PTL0_IN,
- PTM6_IN, PTM5_IN, PTM4_IN,
+ PTM7_IN, PTM6_IN, PTM5_IN, PTM4_IN,
PTM3_IN, PTM2_IN, PTM1_IN, PTM0_IN,
- PTN7_IN, PTN6_IN, PTN5_IN, PTN4_IN,
+ PTN6_IN, PTN5_IN, PTN4_IN,
PTN3_IN, PTN2_IN, PTN1_IN, PTN0_IN,
PTO7_IN, PTO6_IN, PTO5_IN, PTO4_IN,
PTO3_IN, PTO2_IN, PTO1_IN, PTO0_IN,
- PTP6_IN, PTP5_IN, PTP4_IN,
+ PTP7_IN, PTP6_IN, PTP5_IN, PTP4_IN,
PTP3_IN, PTP2_IN, PTP1_IN, PTP0_IN,
- PTQ6_IN, PTQ5_IN, PTQ4_IN,
+ PTQ6_IN, PTQ5_IN, PTQ4_IN,
PTQ3_IN, PTQ2_IN, PTQ1_IN, PTQ0_IN,
PTR7_IN, PTR6_IN, PTR5_IN, PTR4_IN,
PTR3_IN, PTR2_IN, PTR1_IN, PTR0_IN,
PTS7_IN, PTS6_IN, PTS5_IN, PTS4_IN,
PTS3_IN, PTS2_IN, PTS1_IN, PTS0_IN,
- PTT5_IN, PTT4_IN,
+ PTT7_IN, PTT6_IN, PTT5_IN, PTT4_IN,
PTT3_IN, PTT2_IN, PTT1_IN, PTT0_IN,
PTU7_IN, PTU6_IN, PTU5_IN, PTU4_IN,
PTU3_IN, PTU2_IN, PTU1_IN, PTU0_IN,
@@ -132,16 +132,43 @@ enum {
PINMUX_INPUT_END,
PINMUX_INPUT_PULLUP_BEGIN,
+ PTA7_IN_PU, PTA6_IN_PU, PTA5_IN_PU, PTA4_IN_PU,
+ PTA3_IN_PU, PTA2_IN_PU, PTA1_IN_PU, PTA0_IN_PU,
+ PTD7_IN_PU, PTD6_IN_PU, PTD5_IN_PU, PTD4_IN_PU,
+ PTD3_IN_PU, PTD2_IN_PU, PTD1_IN_PU, PTD0_IN_PU,
+ PTE7_IN_PU, PTE6_IN_PU, PTE5_IN_PU, PTE4_IN_PU,
+ PTE3_IN_PU, PTE2_IN_PU, PTE1_IN_PU, PTE0_IN_PU,
+ PTF7_IN_PU, PTF6_IN_PU, PTF5_IN_PU, PTF4_IN_PU,
+ PTF3_IN_PU, PTF2_IN_PU, PTF1_IN_PU, PTF0_IN_PU,
+ PTG7_IN_PU, PTG6_IN_PU, PTG4_IN_PU,
+ PTH7_IN_PU, PTH6_IN_PU, PTH5_IN_PU, PTH4_IN_PU,
+ PTH3_IN_PU, PTH2_IN_PU, PTH1_IN_PU, PTH0_IN_PU,
+ PTI7_IN_PU, PTI6_IN_PU, PTI4_IN_PU,
+ PTI3_IN_PU, PTI2_IN_PU, PTI1_IN_PU, PTI0_IN_PU,
+ PTJ6_IN_PU, PTJ5_IN_PU, PTJ4_IN_PU,
+ PTJ3_IN_PU, PTJ2_IN_PU, PTJ1_IN_PU, PTJ0_IN_PU,
+ PTK7_IN_PU, PTK6_IN_PU, PTK5_IN_PU, PTK4_IN_PU,
+ PTK3_IN_PU, PTK2_IN_PU, PTK1_IN_PU, PTK0_IN_PU,
+ PTL6_IN_PU, PTL5_IN_PU, PTL4_IN_PU,
+ PTL3_IN_PU, PTL2_IN_PU, PTL1_IN_PU, PTL0_IN_PU,
+ PTM7_IN_PU, PTM6_IN_PU, PTM5_IN_PU, PTM4_IN_PU,
+ PTN4_IN_PU,
+ PTN3_IN_PU, PTN2_IN_PU, PTN1_IN_PU, PTN0_IN_PU,
+ PTO7_IN_PU, PTO6_IN_PU, PTO5_IN_PU, PTO4_IN_PU,
+ PTO3_IN_PU, PTO2_IN_PU, PTO1_IN_PU, PTO0_IN_PU,
+ PTT7_IN_PU, PTT6_IN_PU, PTT5_IN_PU, PTT4_IN_PU,
+ PTT3_IN_PU, PTT2_IN_PU, PTT1_IN_PU, PTT0_IN_PU,
PTU7_IN_PU, PTU6_IN_PU, PTU5_IN_PU, PTU4_IN_PU,
PTU3_IN_PU, PTU2_IN_PU, PTU1_IN_PU, PTU0_IN_PU,
PTV7_IN_PU, PTV6_IN_PU, PTV5_IN_PU, PTV4_IN_PU,
- PTV3_IN_PU, PTV2_IN_PU, PTV1_IN_PU, PTV0_IN_PU,
- PTW7_IN_PU, PTW6_IN_PU, PTW5_IN_PU, PTW4_IN_PU,
- PTW3_IN_PU, PTW2_IN_PU, PTW1_IN_PU, PTW0_IN_PU,
+ PTV3_IN_PU, PTV2_IN_PU,
+ PTW1_IN_PU, PTW0_IN_PU,
PTX7_IN_PU, PTX6_IN_PU, PTX5_IN_PU, PTX4_IN_PU,
PTX3_IN_PU, PTX2_IN_PU, PTX1_IN_PU, PTX0_IN_PU,
PTY7_IN_PU, PTY6_IN_PU, PTY5_IN_PU, PTY4_IN_PU,
PTY3_IN_PU, PTY2_IN_PU, PTY1_IN_PU, PTY0_IN_PU,
+ PTZ7_IN_PU, PTZ6_IN_PU, PTZ5_IN_PU, PTZ4_IN_PU,
+ PTZ3_IN_PU, PTZ2_IN_PU, PTZ1_IN_PU, PTZ0_IN_PU,
PINMUX_INPUT_PULLUP_END,
PINMUX_OUTPUT_BEGIN,
@@ -163,27 +190,27 @@ enum {
PTH3_OUT, PTH2_OUT, PTH1_OUT, PTH0_OUT,
PTI7_OUT, PTI6_OUT, PTI5_OUT, PTI4_OUT,
PTI3_OUT, PTI2_OUT, PTI1_OUT, PTI0_OUT,
- PTJ7_OUT, PTJ6_OUT, PTJ5_OUT, PTJ4_OUT,
+ PTJ6_OUT, PTJ5_OUT, PTJ4_OUT,
PTJ3_OUT, PTJ2_OUT, PTJ1_OUT, PTJ0_OUT,
PTK7_OUT, PTK6_OUT, PTK5_OUT, PTK4_OUT,
PTK3_OUT, PTK2_OUT, PTK1_OUT, PTK0_OUT,
- PTL7_OUT, PTL6_OUT, PTL5_OUT, PTL4_OUT,
+ PTL6_OUT, PTL5_OUT, PTL4_OUT,
PTL3_OUT, PTL2_OUT, PTL1_OUT, PTL0_OUT,
- PTM6_OUT, PTM5_OUT, PTM4_OUT,
+ PTM7_OUT, PTM6_OUT, PTM5_OUT, PTM4_OUT,
PTM3_OUT, PTM2_OUT, PTM1_OUT, PTM0_OUT,
- PTN7_OUT, PTN6_OUT, PTN5_OUT, PTN4_OUT,
+ PTN6_OUT, PTN5_OUT, PTN4_OUT,
PTN3_OUT, PTN2_OUT, PTN1_OUT, PTN0_OUT,
PTO7_OUT, PTO6_OUT, PTO5_OUT, PTO4_OUT,
PTO3_OUT, PTO2_OUT, PTO1_OUT, PTO0_OUT,
- PTP6_OUT, PTP5_OUT, PTP4_OUT,
+ PTP7_OUT, PTP6_OUT, PTP5_OUT, PTP4_OUT,
PTP3_OUT, PTP2_OUT, PTP1_OUT, PTP0_OUT,
- PTQ6_OUT, PTQ5_OUT, PTQ4_OUT,
+ PTQ6_OUT, PTQ5_OUT, PTQ4_OUT,
PTQ3_OUT, PTQ2_OUT, PTQ1_OUT, PTQ0_OUT,
PTR7_OUT, PTR6_OUT, PTR5_OUT, PTR4_OUT,
PTR3_OUT, PTR2_OUT, PTR1_OUT, PTR0_OUT,
PTS7_OUT, PTS6_OUT, PTS5_OUT, PTS4_OUT,
PTS3_OUT, PTS2_OUT, PTS1_OUT, PTS0_OUT,
- PTT5_OUT, PTT4_OUT,
+ PTT7_OUT, PTT6_OUT, PTT5_OUT, PTT4_OUT,
PTT3_OUT, PTT2_OUT, PTT1_OUT, PTT0_OUT,
PTU7_OUT, PTU6_OUT, PTU5_OUT, PTU4_OUT,
PTU3_OUT, PTU2_OUT, PTU1_OUT, PTU0_OUT,
@@ -218,27 +245,27 @@ enum {
PTH3_FN, PTH2_FN, PTH1_FN, PTH0_FN,
PTI7_FN, PTI6_FN, PTI5_FN, PTI4_FN,
PTI3_FN, PTI2_FN, PTI1_FN, PTI0_FN,
- PTJ7_FN, PTJ6_FN, PTJ5_FN, PTJ4_FN,
+ PTJ6_FN, PTJ5_FN, PTJ4_FN,
PTJ3_FN, PTJ2_FN, PTJ1_FN, PTJ0_FN,
PTK7_FN, PTK6_FN, PTK5_FN, PTK4_FN,
PTK3_FN, PTK2_FN, PTK1_FN, PTK0_FN,
- PTL7_FN, PTL6_FN, PTL5_FN, PTL4_FN,
+ PTL6_FN, PTL5_FN, PTL4_FN,
PTL3_FN, PTL2_FN, PTL1_FN, PTL0_FN,
- PTM6_FN, PTM5_FN, PTM4_FN,
+ PTM7_FN, PTM6_FN, PTM5_FN, PTM4_FN,
PTM3_FN, PTM2_FN, PTM1_FN, PTM0_FN,
- PTN7_FN, PTN6_FN, PTN5_FN, PTN4_FN,
+ PTN6_FN, PTN5_FN, PTN4_FN,
PTN3_FN, PTN2_FN, PTN1_FN, PTN0_FN,
PTO7_FN, PTO6_FN, PTO5_FN, PTO4_FN,
PTO3_FN, PTO2_FN, PTO1_FN, PTO0_FN,
- PTP6_FN, PTP5_FN, PTP4_FN,
+ PTP7_FN, PTP6_FN, PTP5_FN, PTP4_FN,
PTP3_FN, PTP2_FN, PTP1_FN, PTP0_FN,
- PTQ6_FN, PTQ5_FN, PTQ4_FN,
+ PTQ6_FN, PTQ5_FN, PTQ4_FN,
PTQ3_FN, PTQ2_FN, PTQ1_FN, PTQ0_FN,
PTR7_FN, PTR6_FN, PTR5_FN, PTR4_FN,
PTR3_FN, PTR2_FN, PTR1_FN, PTR0_FN,
PTS7_FN, PTS6_FN, PTS5_FN, PTS4_FN,
PTS3_FN, PTS2_FN, PTS1_FN, PTS0_FN,
- PTT5_FN, PTT4_FN,
+ PTT7_FN, PTT6_FN, PTT5_FN, PTT4_FN,
PTT3_FN, PTT2_FN, PTT1_FN, PTT0_FN,
PTU7_FN, PTU6_FN, PTU5_FN, PTU4_FN,
PTU3_FN, PTU2_FN, PTU1_FN, PTU0_FN,
@@ -253,181 +280,248 @@ enum {
PTZ7_FN, PTZ6_FN, PTZ5_FN, PTZ4_FN,
PTZ3_FN, PTZ2_FN, PTZ1_FN, PTZ0_FN,
- PS0_15_FN1, PS0_15_FN3,
- PS0_14_FN1, PS0_14_FN3,
- PS0_13_FN1, PS0_13_FN3,
- PS0_12_FN1, PS0_12_FN3,
+ PS0_15_FN1, PS0_15_FN2,
+ PS0_14_FN1, PS0_14_FN2,
+ PS0_13_FN1, PS0_13_FN2,
+ PS0_12_FN1, PS0_12_FN2,
+ PS0_11_FN1, PS0_11_FN2,
+ PS0_10_FN1, PS0_10_FN2,
+ PS0_9_FN1, PS0_9_FN2,
+ PS0_8_FN1, PS0_8_FN2,
PS0_7_FN1, PS0_7_FN2,
PS0_6_FN1, PS0_6_FN2,
PS0_5_FN1, PS0_5_FN2,
PS0_4_FN1, PS0_4_FN2,
PS0_3_FN1, PS0_3_FN2,
PS0_2_FN1, PS0_2_FN2,
- PS0_1_FN1, PS0_1_FN2,
- PS1_7_FN1, PS1_7_FN3,
- PS1_6_FN1, PS1_6_FN3,
+ PS1_10_FN1, PS1_10_FN2,
+ PS1_9_FN1, PS1_9_FN2,
+ PS1_8_FN1, PS1_8_FN2,
+ PS1_2_FN1, PS1_2_FN2,
+
+ PS2_13_FN1, PS2_13_FN2,
+ PS2_12_FN1, PS2_12_FN2,
+ PS2_7_FN1, PS2_7_FN2,
+ PS2_6_FN1, PS2_6_FN2,
+ PS2_5_FN1, PS2_5_FN2,
+ PS2_4_FN1, PS2_4_FN2,
+ PS2_2_FN1, PS2_2_FN2,
+
+ PS3_15_FN1, PS3_15_FN2,
+ PS3_14_FN1, PS3_14_FN2,
+ PS3_13_FN1, PS3_13_FN2,
+ PS3_12_FN1, PS3_12_FN2,
+ PS3_11_FN1, PS3_11_FN2,
+ PS3_10_FN1, PS3_10_FN2,
+ PS3_9_FN1, PS3_9_FN2,
+ PS3_8_FN1, PS3_8_FN2,
+ PS3_7_FN1, PS3_7_FN2,
+ PS3_2_FN1, PS3_2_FN2,
+ PS3_1_FN1, PS3_1_FN2,
- PS2_13_FN1, PS2_13_FN3,
- PS2_12_FN1, PS2_12_FN3,
- PS2_1_FN1, PS2_1_FN2,
- PS2_0_FN1, PS2_0_FN2,
-
- PS4_15_FN1, PS4_15_FN2,
PS4_14_FN1, PS4_14_FN2,
PS4_13_FN1, PS4_13_FN2,
PS4_12_FN1, PS4_12_FN2,
- PS4_11_FN1, PS4_11_FN2,
PS4_10_FN1, PS4_10_FN2,
PS4_9_FN1, PS4_9_FN2,
+ PS4_8_FN1, PS4_8_FN2,
+ PS4_4_FN1, PS4_4_FN2,
PS4_3_FN1, PS4_3_FN2,
PS4_2_FN1, PS4_2_FN2,
PS4_1_FN1, PS4_1_FN2,
PS4_0_FN1, PS4_0_FN2,
+ PS5_11_FN1, PS5_11_FN2,
+ PS5_10_FN1, PS5_10_FN2,
PS5_9_FN1, PS5_9_FN2,
PS5_8_FN1, PS5_8_FN2,
PS5_7_FN1, PS5_7_FN2,
PS5_6_FN1, PS5_6_FN2,
PS5_5_FN1, PS5_5_FN2,
PS5_4_FN1, PS5_4_FN2,
-
- /* AN15 to 8 : EVENT15 to 8 */
- PS6_7_FN_AN, PS6_7_FN_EV,
- PS6_6_FN_AN, PS6_6_FN_EV,
- PS6_5_FN_AN, PS6_5_FN_EV,
- PS6_4_FN_AN, PS6_4_FN_EV,
- PS6_3_FN_AN, PS6_3_FN_EV,
- PS6_2_FN_AN, PS6_2_FN_EV,
- PS6_1_FN_AN, PS6_1_FN_EV,
- PS6_0_FN_AN, PS6_0_FN_EV,
-
+ PS5_3_FN1, PS5_3_FN2,
+ PS5_2_FN1, PS5_2_FN2,
+
+ PS6_15_FN1, PS6_15_FN2,
+ PS6_14_FN1, PS6_14_FN2,
+ PS6_13_FN1, PS6_13_FN2,
+ PS6_12_FN1, PS6_12_FN2,
+ PS6_11_FN1, PS6_11_FN2,
+ PS6_10_FN1, PS6_10_FN2,
+ PS6_9_FN1, PS6_9_FN2,
+ PS6_8_FN1, PS6_8_FN2,
+ PS6_7_FN1, PS6_7_FN2,
+ PS6_6_FN1, PS6_6_FN2,
+ PS6_5_FN1, PS6_5_FN2,
+ PS6_4_FN1, PS6_4_FN2,
+ PS6_3_FN1, PS6_3_FN2,
+ PS6_2_FN1, PS6_2_FN2,
+ PS6_1_FN1, PS6_1_FN2,
+ PS6_0_FN1, PS6_0_FN2,
+
+ PS7_15_FN1, PS7_15_FN2,
+ PS7_14_FN1, PS7_14_FN2,
+ PS7_13_FN1, PS7_13_FN2,
+ PS7_12_FN1, PS7_12_FN2,
+ PS7_11_FN1, PS7_11_FN2,
+ PS7_10_FN1, PS7_10_FN2,
+ PS7_9_FN1, PS7_9_FN2,
+ PS7_8_FN1, PS7_8_FN2,
+ PS7_7_FN1, PS7_7_FN2,
+ PS7_6_FN1, PS7_6_FN2,
+ PS7_5_FN1, PS7_5_FN2,
+ PS7_4_FN1, PS7_4_FN2,
+
+ PS8_15_FN1, PS8_15_FN2,
+ PS8_14_FN1, PS8_14_FN2,
+ PS8_13_FN1, PS8_13_FN2,
+ PS8_12_FN1, PS8_12_FN2,
+ PS8_11_FN1, PS8_11_FN2,
+ PS8_10_FN1, PS8_10_FN2,
+ PS8_9_FN1, PS8_9_FN2,
+ PS8_8_FN1, PS8_8_FN2,
PINMUX_FUNCTION_END,
PINMUX_MARK_BEGIN,
- /* PTA (mobule: LBSC, CPG, LPC) */
+ /* PTA (mobule: LBSC, RGMII) */
BS_MARK, RDWR_MARK, WE1_MARK, RDY_MARK,
- MD10_MARK, MD9_MARK, MD8_MARK,
- LGPIO7_MARK, LGPIO6_MARK, LGPIO5_MARK, LGPIO4_MARK,
- LGPIO3_MARK, LGPIO2_MARK, LGPIO1_MARK, LGPIO0_MARK,
-
- /* PTB (mobule: LBSC, EtherC, SIM, LPC) */
- D15_MARK, D14_MARK, D13_MARK, D12_MARK,
- D11_MARK, D10_MARK, D9_MARK, D8_MARK,
ET0_MDC_MARK, ET0_MDIO_MARK, ET1_MDC_MARK, ET1_MDIO_MARK,
- SIM_D_MARK, SIM_CLK_MARK, SIM_RST_MARK,
- WPSZ1_MARK, WPSZ0_MARK, FWID_MARK, FLSHSZ_MARK,
- LPC_SPIEN_MARK, BASEL_MARK,
- /* PTC (mobule: SD) */
- SD_WP_MARK, SD_CD_MARK, SD_CLK_MARK, SD_CMD_MARK,
- SD_D3_MARK, SD_D2_MARK, SD_D1_MARK, SD_D0_MARK,
+ /* PTB (mobule: INTC, ONFI, TMU) */
+ IRQ15_MARK, IRQ14_MARK, IRQ13_MARK, IRQ12_MARK,
+ IRQ11_MARK, IRQ10_MARK, IRQ9_MARK, IRQ8_MARK,
+ ON_NRE_MARK, ON_NWE_MARK, ON_NWP_MARK, ON_NCE0_MARK,
+ ON_R_B0_MARK, ON_ALE_MARK, ON_CLE_MARK, TCLK_MARK,
- /* PTD (mobule: INTC, SPI0, LBSC, CPG, ADC) */
+ /* PTC (mobule: IRQ, PWMU) */
IRQ7_MARK, IRQ6_MARK, IRQ5_MARK, IRQ4_MARK,
IRQ3_MARK, IRQ2_MARK, IRQ1_MARK, IRQ0_MARK,
- MD6_MARK, MD5_MARK, MD3_MARK, MD2_MARK,
- MD1_MARK, MD0_MARK, ADTRG1_MARK, ADTRG0_MARK,
-
- /* PTE (mobule: EtherC) */
- ET0_CRS_DV_MARK, ET0_TXD1_MARK,
- ET0_TXD0_MARK, ET0_TX_EN_MARK,
- ET0_REF_CLK_MARK, ET0_RXD1_MARK,
- ET0_RXD0_MARK, ET0_RX_ER_MARK,
-
- /* PTF (mobule: EtherC) */
- ET1_CRS_DV_MARK, ET1_TXD1_MARK,
- ET1_TXD0_MARK, ET1_TX_EN_MARK,
- ET1_REF_CLK_MARK, ET1_RXD1_MARK,
- ET1_RXD0_MARK, ET1_RX_ER_MARK,
-
- /* PTG (mobule: SYSTEM, PWMX, LPC) */
- STATUS0_MARK, STATUS1_MARK,
- PWX0_MARK, PWX1_MARK, PWX2_MARK, PWX3_MARK,
- SERIRQ_MARK, CLKRUN_MARK, LPCPD_MARK, LDRQ_MARK,
-
- /* PTH (mobule: TMU, SCIF234, SPI1, SPI0) */
- TCLK_MARK, RXD4_MARK, TXD4_MARK,
+ PWMU0_MARK, PWMU1_MARK, PWMU2_MARK, PWMU3_MARK,
+ PWMU4_MARK, PWMU5_MARK,
+
+ /* PTD (mobule: SPI0, DMAC) */
+ SP0_MOSI_MARK, SP0_MISO_MARK, SP0_SCK_MARK, SP0_SCK_FB_MARK,
+ SP0_SS0_MARK, SP0_SS1_MARK, SP0_SS2_MARK, SP0_SS3_MARK,
+ DREQ0_MARK, DACK0_MARK, TEND0_MARK,
+
+ /* PTE (mobule: RMII) */
+ RMII0_CRS_DV_MARK, RMII0_TXD1_MARK,
+ RMII0_TXD0_MARK, RMII0_TXEN_MARK,
+ RMII0_REFCLK_MARK, RMII0_RXD1_MARK,
+ RMII0_RXD0_MARK, RMII0_RX_ER_MARK,
+
+ /* PTF (mobule: RMII, SerMux) */
+ RMII1_CRS_DV_MARK, RMII1_TXD1_MARK,
+ RMII1_TXD0_MARK, RMII1_TXEN_MARK,
+ RMII1_REFCLK_MARK, RMII1_RXD1_MARK,
+ RMII1_RXD0_MARK, RMII1_RX_ER_MARK,
+ RAC_RI_MARK,
+
+ /* PTG (mobule: system, LBSC, LPC, WDT, LPC, eMMC) */
+ BOOTFMS_MARK, BOOTWP_MARK, A25_MARK, A24_MARK,
+ SERIRQ_MARK, WDTOVF_MARK, LPCPD_MARK, LDRQ_MARK,
+ MMCCLK_MARK, MMCCMD_MARK,
+
+ /* PTH (mobule: SPI1, LPC, DMAC, ADC) */
SP1_MOSI_MARK, SP1_MISO_MARK, SP1_SCK_MARK, SP1_SCK_FB_MARK,
- SP1_SS0_MARK, SP1_SS1_MARK, SP0_SS1_MARK,
+ SP1_SS0_MARK, SP1_SS1_MARK, WP_MARK, FMS0_MARK,
+ TEND1_MARK, DREQ1_MARK, DACK1_MARK, ADTRG1_MARK,
+ ADTRG0_MARK,
- /* PTI (mobule: INTC) */
- IRQ15_MARK, IRQ14_MARK, IRQ13_MARK, IRQ12_MARK,
- IRQ11_MARK, IRQ10_MARK, IRQ9_MARK, IRQ8_MARK,
+ /* PTI (mobule: LBSC, SDHI) */
+ D15_MARK, D14_MARK, D13_MARK, D12_MARK,
+ D11_MARK, D10_MARK, D9_MARK, D8_MARK,
+ SD_WP_MARK, SD_CD_MARK, SD_CLK_MARK, SD_CMD_MARK,
+ SD_D3_MARK, SD_D2_MARK, SD_D1_MARK, SD_D0_MARK,
- /* PTJ (mobule: SCIF234, SERMUX) */
- RXD3_MARK, TXD3_MARK, RXD2_MARK, TXD2_MARK,
- COM1_TXD_MARK, COM1_RXD_MARK, COM1_RTS_MARK, COM1_CTS_MARK,
+ /* PTJ (mobule: SCIF234) */
+ RTS3_MARK, CTS3_MARK, TXD3_MARK, RXD3_MARK,
+ RTS4_MARK, RXD4_MARK, TXD4_MARK,
- /* PTK (mobule: SERMUX) */
+ /* PTK (mobule: SERMUX, LBSC, SCIF) */
COM2_TXD_MARK, COM2_RXD_MARK, COM2_RTS_MARK, COM2_CTS_MARK,
- COM2_DTR_MARK, COM2_DSR_MARK, COM2_DCD_MARK, COM2_RI_MARK,
+ COM2_DTR_MARK, COM2_DSR_MARK, COM2_DCD_MARK, CLKOUT_MARK,
+ SCK2_MARK, SCK4_MARK, SCK3_MARK,
- /* PTL (mobule: SERMUX) */
- RAC_TXD_MARK, RAC_RXD_MARK, RAC_RTS_MARK, RAC_CTS_MARK,
- RAC_DTR_MARK, RAC_DSR_MARK, RAC_DCD_MARK, RAC_RI_MARK,
+ /* PTL (mobule: SERMUX, SCIF, LBSC, AUD) */
+ RAC_RXD_MARK, RAC_RTS_MARK, RAC_CTS_MARK, RAC_DTR_MARK,
+ RAC_DSR_MARK, RAC_DCD_MARK, RAC_TXD_MARK, RXD2_MARK,
+ CS5_MARK, CS6_MARK, AUDSYNC_MARK, AUDCK_MARK,
+ TXD2_MARK,
- /* PTM (mobule: IIC, LPC) */
+ /* PTM (mobule: LBSC, IIC) */
+ CS4_MARK, RD_MARK, WE0_MARK, CS0_MARK,
SDA6_MARK, SCL6_MARK, SDA7_MARK, SCL7_MARK,
- WP_MARK, FMS0_MARK, FMS1_MARK,
- /* PTN (mobule: SCIF234, EVC) */
- SCK2_MARK, RTS4_MARK, RTS3_MARK, RTS2_MARK,
- CTS4_MARK, CTS3_MARK, CTS2_MARK,
- EVENT7_MARK, EVENT6_MARK, EVENT5_MARK, EVENT4_MARK,
- EVENT3_MARK, EVENT2_MARK, EVENT1_MARK, EVENT0_MARK,
+ /* PTN (mobule: USB, JMC, SGPIO, WDT) */
+ VBUS_EN_MARK, VBUS_OC_MARK, JMCTCK_MARK, JMCTMS_MARK,
+ JMCTDO_MARK, JMCTDI_MARK, JMCTRST_MARK,
+ SGPIO1_CLK_MARK, SGPIO1_LOAD_MARK, SGPIO1_DI_MARK,
+ SGPIO1_DO_MARK, SUB_CLKIN_MARK,
- /* PTO (mobule: SGPIO) */
- SGPIO0_CLK_MARK, SGPIO0_LOAD_MARK,
- SGPIO0_DI_MARK, SGPIO0_DO_MARK,
- SGPIO1_CLK_MARK, SGPIO1_LOAD_MARK,
- SGPIO1_DI_MARK, SGPIO1_DO_MARK,
-
- /* PTP (mobule: JMC, SCIF234) */
- JMCTCK_MARK, JMCTMS_MARK, JMCTDO_MARK, JMCTDI_MARK,
- JMCRST_MARK, SCK4_MARK, SCK3_MARK,
+ /* PTO (mobule: SGPIO, SerMux) */
+ SGPIO0_CLK_MARK, SGPIO0_LOAD_MARK, SGPIO0_DI_MARK,
+ SGPIO0_DO_MARK, SGPIO2_CLK_MARK, SGPIO2_LOAD_MARK,
+ SGPIO2_DI_MARK, SGPIO2_DO_MARK,
+ COM1_TXD_MARK, COM1_RXD_MARK, COM1_RTS_MARK, COM1_CTS_MARK,
/* PTQ (mobule: LPC) */
LAD3_MARK, LAD2_MARK, LAD1_MARK, LAD0_MARK,
LFRAME_MARK, LRESET_MARK, LCLK_MARK,
/* PTR (mobule: GRA, IIC) */
- DDC3_MARK, DDC2_MARK,
- SDA8_MARK, SCL8_MARK, SDA2_MARK, SCL2_MARK,
+ DDC3_MARK, DDC2_MARK, SDA2_MARK, SCL2_MARK,
SDA1_MARK, SCL1_MARK, SDA0_MARK, SCL0_MARK,
+ SDA8_MARK, SCL8_MARK,
/* PTS (mobule: GRA, IIC) */
- DDC1_MARK, DDC0_MARK,
- SDA9_MARK, SCL9_MARK, SDA5_MARK, SCL5_MARK,
+ DDC1_MARK, DDC0_MARK, SDA5_MARK, SCL5_MARK,
SDA4_MARK, SCL4_MARK, SDA3_MARK, SCL3_MARK,
+ SDA9_MARK, SCL9_MARK,
- /* PTT (mobule: SYSTEM, PWMX) */
- AUDSYNC_MARK, AUDCK_MARK,
- AUDATA3_MARK, AUDATA2_MARK,
- AUDATA1_MARK, AUDATA0_MARK,
- PWX7_MARK, PWX6_MARK, PWX5_MARK, PWX4_MARK,
+ /* PTT (mobule: PWMX, AUD) */
+ PWMX7_MARK, PWMX6_MARK, PWMX5_MARK, PWMX4_MARK,
+ PWMX3_MARK, PWMX2_MARK, PWMX1_MARK, PWMX0_MARK,
+ AUDATA3_MARK, AUDATA2_MARK, AUDATA1_MARK, AUDATA0_MARK,
+ STATUS1_MARK, STATUS0_MARK,
- /* PTU (mobule: LBSC, DMAC) */
- CS6_MARK, CS5_MARK, CS4_MARK, CS0_MARK,
- RD_MARK, WE0_MARK, A25_MARK, A24_MARK,
- DREQ0_MARK, DACK0_MARK,
+ /* PTU (mobule: LPC, APM) */
+ LGPIO7_MARK, LGPIO6_MARK, LGPIO5_MARK, LGPIO4_MARK,
+ LGPIO3_MARK, LGPIO2_MARK, LGPIO1_MARK, LGPIO0_MARK,
+ APMONCTL_O_MARK, APMPWBTOUT_O_MARK, APMSCI_O_MARK,
+ APMVDDON_MARK, APMSLPBTN_MARK, APMPWRBTN_MARK, APMS5N_MARK,
+ APMS3N_MARK,
- /* PTV (mobule: LBSC, DMAC) */
+ /* PTV (mobule: LBSC, SerMux, R-SPI, EVC, GRA) */
A23_MARK, A22_MARK, A21_MARK, A20_MARK,
A19_MARK, A18_MARK, A17_MARK, A16_MARK,
- TEND0_MARK, DREQ1_MARK, DACK1_MARK, TEND1_MARK,
+ COM2_RI_MARK, R_SPI_MOSI_MARK, R_SPI_MISO_MARK,
+ R_SPI_RSPCK_MARK, R_SPI_SSL0_MARK, R_SPI_SSL1_MARK,
+ EVENT7_MARK, EVENT6_MARK, VBIOS_DI_MARK, VBIOS_DO_MARK,
+ VBIOS_CLK_MARK, VBIOS_CS_MARK,
- /* PTW (mobule: LBSC) */
+ /* PTW (mobule: LBSC, EVC, SCIF) */
A15_MARK, A14_MARK, A13_MARK, A12_MARK,
A11_MARK, A10_MARK, A9_MARK, A8_MARK,
+ EVENT5_MARK, EVENT4_MARK, EVENT3_MARK, EVENT2_MARK,
+ EVENT1_MARK, EVENT0_MARK, CTS4_MARK, CTS2_MARK,
- /* PTX (mobule: LBSC) */
+ /* PTX (mobule: LBSC, SCIF, SIM) */
A7_MARK, A6_MARK, A5_MARK, A4_MARK,
A3_MARK, A2_MARK, A1_MARK, A0_MARK,
+ RTS2_MARK, SIM_D_MARK, SIM_CLK_MARK, SIM_RST_MARK,
/* PTY (mobule: LBSC) */
D7_MARK, D6_MARK, D5_MARK, D4_MARK,
D3_MARK, D2_MARK, D1_MARK, D0_MARK,
+
+ /* PTZ (mobule: eMMC, ONFI) */
+ MMCDAT7_MARK, MMCDAT6_MARK, MMCDAT5_MARK, MMCDAT4_MARK,
+ MMCDAT3_MARK, MMCDAT2_MARK, MMCDAT1_MARK, MMCDAT0_MARK,
+ ON_DQ7_MARK, ON_DQ6_MARK, ON_DQ5_MARK, ON_DQ4_MARK,
+ ON_DQ3_MARK, ON_DQ2_MARK, ON_DQ1_MARK, ON_DQ0_MARK,
+
PINMUX_MARK_END,
};
@@ -473,6 +567,8 @@ static pinmux_enum_t pinmux_data[] = {
PINMUX_DATA(PTD0_DATA, PTD0_IN, PTD0_OUT),
/* PTE GPIO */
+ PINMUX_DATA(PTE7_DATA, PTE7_IN, PTE7_OUT),
+ PINMUX_DATA(PTE6_DATA, PTE6_IN, PTE6_OUT),
PINMUX_DATA(PTE5_DATA, PTE5_IN, PTE5_OUT),
PINMUX_DATA(PTE4_DATA, PTE4_IN, PTE4_OUT),
PINMUX_DATA(PTE3_DATA, PTE3_IN, PTE3_OUT),
@@ -521,7 +617,6 @@ static pinmux_enum_t pinmux_data[] = {
PINMUX_DATA(PTI0_DATA, PTI0_IN, PTI0_OUT),
/* PTJ GPIO */
- PINMUX_DATA(PTJ7_DATA, PTJ7_IN, PTJ7_OUT),
PINMUX_DATA(PTJ6_DATA, PTJ6_IN, PTJ6_OUT),
PINMUX_DATA(PTJ5_DATA, PTJ5_IN, PTJ5_OUT),
PINMUX_DATA(PTJ4_DATA, PTJ4_IN, PTJ4_OUT),
@@ -541,7 +636,6 @@ static pinmux_enum_t pinmux_data[] = {
PINMUX_DATA(PTK0_DATA, PTK0_IN, PTK0_OUT),
/* PTL GPIO */
- PINMUX_DATA(PTL7_DATA, PTL7_IN, PTL7_OUT),
PINMUX_DATA(PTL6_DATA, PTL6_IN, PTL6_OUT),
PINMUX_DATA(PTL5_DATA, PTL5_IN, PTL5_OUT),
PINMUX_DATA(PTL4_DATA, PTL4_IN, PTL4_OUT),
@@ -560,7 +654,6 @@ static pinmux_enum_t pinmux_data[] = {
PINMUX_DATA(PTM0_DATA, PTM0_IN, PTM0_OUT),
/* PTN GPIO */
- PINMUX_DATA(PTN7_DATA, PTN7_IN, PTN7_OUT),
PINMUX_DATA(PTN6_DATA, PTN6_IN, PTN6_OUT),
PINMUX_DATA(PTN5_DATA, PTN5_IN, PTN5_OUT),
PINMUX_DATA(PTN4_DATA, PTN4_IN, PTN4_OUT),
@@ -609,6 +702,8 @@ static pinmux_enum_t pinmux_data[] = {
PINMUX_DATA(PTS0_DATA, PTS0_IN, PTS0_OUT),
/* PTT GPIO */
+ PINMUX_DATA(PTT7_DATA, PTT7_IN, PTT7_OUT),
+ PINMUX_DATA(PTT6_DATA, PTT6_IN, PTT6_OUT),
PINMUX_DATA(PTT5_DATA, PTT5_IN, PTT5_OUT),
PINMUX_DATA(PTT4_DATA, PTT4_IN, PTT4_OUT),
PINMUX_DATA(PTT3_DATA, PTT3_IN, PTT3_OUT),
@@ -677,186 +772,204 @@ static pinmux_enum_t pinmux_data[] = {
PINMUX_DATA(PTZ0_DATA, PTZ0_IN, PTZ0_OUT),
/* PTA FN */
- PINMUX_DATA(BS_MARK, PS0_15_FN1, PTA7_FN),
- PINMUX_DATA(LGPIO7_MARK, PS0_15_FN3, PTA7_FN),
- PINMUX_DATA(RDWR_MARK, PS0_14_FN1, PTA6_FN),
- PINMUX_DATA(LGPIO6_MARK, PS0_14_FN3, PTA6_FN),
- PINMUX_DATA(WE1_MARK, PS0_13_FN1, PTA5_FN),
- PINMUX_DATA(LGPIO5_MARK, PS0_13_FN3, PTA5_FN),
- PINMUX_DATA(RDY_MARK, PS0_12_FN1, PTA4_FN),
- PINMUX_DATA(LGPIO4_MARK, PS0_12_FN3, PTA4_FN),
- PINMUX_DATA(LGPIO3_MARK, PTA3_FN),
- PINMUX_DATA(LGPIO2_MARK, PTA2_FN),
- PINMUX_DATA(LGPIO1_MARK, PTA1_FN),
- PINMUX_DATA(LGPIO0_MARK, PTA0_FN),
+ PINMUX_DATA(BS_MARK, PTA7_FN),
+ PINMUX_DATA(RDWR_MARK, PTA6_FN),
+ PINMUX_DATA(WE1_MARK, PTA5_FN),
+ PINMUX_DATA(RDY_MARK, PTA4_FN),
+ PINMUX_DATA(ET0_MDC_MARK, PTA3_FN),
+ PINMUX_DATA(ET0_MDIO_MARK, PTA2_FN),
+ PINMUX_DATA(ET1_MDC_MARK, PTA1_FN),
+ PINMUX_DATA(ET1_MDIO_MARK, PTA0_FN),
/* PTB FN */
- PINMUX_DATA(D15_MARK, PS0_7_FN1, PTB7_FN),
- PINMUX_DATA(ET0_MDC_MARK, PS0_7_FN2, PTB7_FN),
- PINMUX_DATA(D14_MARK, PS0_6_FN1, PTB6_FN),
- PINMUX_DATA(ET0_MDIO_MARK, PS0_6_FN2, PTB6_FN),
- PINMUX_DATA(D13_MARK, PS0_5_FN1, PTB5_FN),
- PINMUX_DATA(ET1_MDC_MARK, PS0_5_FN2, PTB5_FN),
- PINMUX_DATA(D12_MARK, PS0_4_FN1, PTB4_FN),
- PINMUX_DATA(ET1_MDIO_MARK, PS0_4_FN2, PTB4_FN),
- PINMUX_DATA(D11_MARK, PS0_3_FN1, PTB3_FN),
- PINMUX_DATA(SIM_D_MARK, PS0_3_FN2, PTB3_FN),
- PINMUX_DATA(D10_MARK, PS0_2_FN1, PTB2_FN),
- PINMUX_DATA(SIM_CLK_MARK, PS0_2_FN2, PTB2_FN),
- PINMUX_DATA(D9_MARK, PS0_1_FN1, PTB1_FN),
- PINMUX_DATA(SIM_RST_MARK, PS0_1_FN2, PTB1_FN),
- PINMUX_DATA(D8_MARK, PTB0_FN),
+ PINMUX_DATA(IRQ15_MARK, PS0_15_FN1, PTB7_FN),
+ PINMUX_DATA(ON_NRE_MARK, PS0_15_FN2, PTB7_FN),
+ PINMUX_DATA(IRQ14_MARK, PS0_14_FN1, PTB6_FN),
+ PINMUX_DATA(ON_NWE_MARK, PS0_14_FN2, PTB6_FN),
+ PINMUX_DATA(IRQ13_MARK, PS0_13_FN1, PTB5_FN),
+ PINMUX_DATA(ON_NWP_MARK, PS0_13_FN2, PTB5_FN),
+ PINMUX_DATA(IRQ12_MARK, PS0_12_FN1, PTB4_FN),
+ PINMUX_DATA(ON_NCE0_MARK, PS0_12_FN2, PTB4_FN),
+ PINMUX_DATA(IRQ11_MARK, PS0_11_FN1, PTB3_FN),
+ PINMUX_DATA(ON_R_B0_MARK, PS0_11_FN2, PTB3_FN),
+ PINMUX_DATA(IRQ10_MARK, PS0_10_FN1, PTB2_FN),
+ PINMUX_DATA(ON_ALE_MARK, PS0_10_FN2, PTB2_FN),
+ PINMUX_DATA(IRQ9_MARK, PS0_9_FN1, PTB1_FN),
+ PINMUX_DATA(ON_CLE_MARK, PS0_9_FN2, PTB1_FN),
+ PINMUX_DATA(IRQ8_MARK, PS0_8_FN1, PTB0_FN),
+ PINMUX_DATA(TCLK_MARK, PS0_8_FN2, PTB0_FN),
/* PTC FN */
- PINMUX_DATA(SD_WP_MARK, PTC7_FN),
- PINMUX_DATA(SD_CD_MARK, PTC6_FN),
- PINMUX_DATA(SD_CLK_MARK, PTC5_FN),
- PINMUX_DATA(SD_CMD_MARK, PTC4_FN),
- PINMUX_DATA(SD_D3_MARK, PTC3_FN),
- PINMUX_DATA(SD_D2_MARK, PTC2_FN),
- PINMUX_DATA(SD_D1_MARK, PTC1_FN),
- PINMUX_DATA(SD_D0_MARK, PTC0_FN),
+ PINMUX_DATA(IRQ7_MARK, PS0_7_FN1, PTC7_FN),
+ PINMUX_DATA(PWMU0_MARK, PS0_7_FN2, PTC7_FN),
+ PINMUX_DATA(IRQ6_MARK, PS0_6_FN1, PTC6_FN),
+ PINMUX_DATA(PWMU1_MARK, PS0_6_FN2, PTC6_FN),
+ PINMUX_DATA(IRQ5_MARK, PS0_5_FN1, PTC5_FN),
+ PINMUX_DATA(PWMU2_MARK, PS0_5_FN2, PTC5_FN),
+ PINMUX_DATA(IRQ4_MARK, PS0_4_FN1, PTC5_FN),
+ PINMUX_DATA(PWMU3_MARK, PS0_4_FN2, PTC4_FN),
+ PINMUX_DATA(IRQ3_MARK, PS0_3_FN1, PTC3_FN),
+ PINMUX_DATA(PWMU4_MARK, PS0_3_FN2, PTC3_FN),
+ PINMUX_DATA(IRQ2_MARK, PS0_2_FN1, PTC2_FN),
+ PINMUX_DATA(PWMU5_MARK, PS0_2_FN2, PTC2_FN),
+ PINMUX_DATA(IRQ1_MARK, PTC1_FN),
+ PINMUX_DATA(IRQ0_MARK, PTC0_FN),
/* PTD FN */
- PINMUX_DATA(IRQ7_MARK, PS1_7_FN1, PTD7_FN),
- PINMUX_DATA(ADTRG1_MARK, PS1_7_FN3, PTD7_FN),
- PINMUX_DATA(IRQ6_MARK, PS1_6_FN1, PTD6_FN),
- PINMUX_DATA(ADTRG0_MARK, PS1_6_FN3, PTD6_FN),
- PINMUX_DATA(IRQ5_MARK, PTD5_FN),
- PINMUX_DATA(IRQ4_MARK, PTD4_FN),
- PINMUX_DATA(IRQ3_MARK, PTD3_FN),
- PINMUX_DATA(IRQ2_MARK, PTD2_FN),
- PINMUX_DATA(IRQ1_MARK, PTD1_FN),
- PINMUX_DATA(IRQ0_MARK, PTD0_FN),
+ PINMUX_DATA(SP0_MOSI_MARK, PTD7_FN),
+ PINMUX_DATA(SP0_MISO_MARK, PTD6_FN),
+ PINMUX_DATA(SP0_SCK_MARK, PTD5_FN),
+ PINMUX_DATA(SP0_SCK_FB_MARK, PTD4_FN),
+ PINMUX_DATA(SP0_SS0_MARK, PTD3_FN),
+ PINMUX_DATA(SP0_SS1_MARK, PS1_10_FN1, PTD2_FN),
+ PINMUX_DATA(DREQ0_MARK, PS1_10_FN2, PTD2_FN),
+ PINMUX_DATA(SP0_SS2_MARK, PS1_9_FN1, PTD1_FN),
+ PINMUX_DATA(DACK0_MARK, PS1_9_FN2, PTD1_FN),
+ PINMUX_DATA(SP0_SS3_MARK, PS1_8_FN1, PTD0_FN),
+ PINMUX_DATA(TEND0_MARK, PS1_8_FN2, PTD0_FN),
/* PTE FN */
- PINMUX_DATA(ET0_CRS_DV_MARK, PTE7_FN),
- PINMUX_DATA(ET0_TXD1_MARK, PTE6_FN),
- PINMUX_DATA(ET0_TXD0_MARK, PTE5_FN),
- PINMUX_DATA(ET0_TX_EN_MARK, PTE4_FN),
- PINMUX_DATA(ET0_REF_CLK_MARK, PTE3_FN),
- PINMUX_DATA(ET0_RXD1_MARK, PTE2_FN),
- PINMUX_DATA(ET0_RXD0_MARK, PTE1_FN),
- PINMUX_DATA(ET0_RX_ER_MARK, PTE0_FN),
+ PINMUX_DATA(RMII0_CRS_DV_MARK, PTE7_FN),
+ PINMUX_DATA(RMII0_TXD1_MARK, PTE6_FN),
+ PINMUX_DATA(RMII0_TXD0_MARK, PTE5_FN),
+ PINMUX_DATA(RMII0_TXEN_MARK, PTE4_FN),
+ PINMUX_DATA(RMII0_REFCLK_MARK, PTE3_FN),
+ PINMUX_DATA(RMII0_RXD1_MARK, PTE2_FN),
+ PINMUX_DATA(RMII0_RXD0_MARK, PTE1_FN),
+ PINMUX_DATA(RMII0_RX_ER_MARK, PTE0_FN),
/* PTF FN */
- PINMUX_DATA(ET1_CRS_DV_MARK, PTF7_FN),
- PINMUX_DATA(ET1_TXD1_MARK, PTF6_FN),
- PINMUX_DATA(ET1_TXD0_MARK, PTF5_FN),
- PINMUX_DATA(ET1_TX_EN_MARK, PTF4_FN),
- PINMUX_DATA(ET1_REF_CLK_MARK, PTF3_FN),
- PINMUX_DATA(ET1_RXD1_MARK, PTF2_FN),
- PINMUX_DATA(ET1_RXD0_MARK, PTF1_FN),
- PINMUX_DATA(ET1_RX_ER_MARK, PTF0_FN),
+ PINMUX_DATA(RMII1_CRS_DV_MARK, PTF7_FN),
+ PINMUX_DATA(RMII1_TXD1_MARK, PTF6_FN),
+ PINMUX_DATA(RMII1_TXD0_MARK, PTF5_FN),
+ PINMUX_DATA(RMII1_TXEN_MARK, PTF4_FN),
+ PINMUX_DATA(RMII1_REFCLK_MARK, PTF3_FN),
+ PINMUX_DATA(RMII1_RXD1_MARK, PS1_2_FN1, PTF2_FN),
+ PINMUX_DATA(RAC_RI_MARK, PS1_2_FN2, PTF2_FN),
+ PINMUX_DATA(RMII1_RXD0_MARK, PTF1_FN),
+ PINMUX_DATA(RMII1_RX_ER_MARK, PTF0_FN),
/* PTG FN */
- PINMUX_DATA(PWX0_MARK, PTG7_FN),
- PINMUX_DATA(PWX1_MARK, PTG6_FN),
- PINMUX_DATA(STATUS0_MARK, PS2_13_FN1, PTG5_FN),
- PINMUX_DATA(PWX2_MARK, PS2_13_FN3, PTG5_FN),
- PINMUX_DATA(STATUS1_MARK, PS2_12_FN1, PTG4_FN),
- PINMUX_DATA(PWX3_MARK, PS2_12_FN3, PTG4_FN),
+ PINMUX_DATA(BOOTFMS_MARK, PTG7_FN),
+ PINMUX_DATA(BOOTWP_MARK, PTG6_FN),
+ PINMUX_DATA(A25_MARK, PS2_13_FN1, PTG5_FN),
+ PINMUX_DATA(MMCCLK_MARK, PS2_13_FN2, PTG5_FN),
+ PINMUX_DATA(A24_MARK, PS2_12_FN1, PTG4_FN),
+ PINMUX_DATA(MMCCMD_MARK, PS2_12_FN2, PTG4_FN),
PINMUX_DATA(SERIRQ_MARK, PTG3_FN),
- PINMUX_DATA(CLKRUN_MARK, PTG2_FN),
+ PINMUX_DATA(WDTOVF_MARK, PTG2_FN),
PINMUX_DATA(LPCPD_MARK, PTG1_FN),
PINMUX_DATA(LDRQ_MARK, PTG0_FN),
/* PTH FN */
- PINMUX_DATA(SP1_MOSI_MARK, PTH7_FN),
- PINMUX_DATA(SP1_MISO_MARK, PTH6_FN),
- PINMUX_DATA(SP1_SCK_MARK, PTH5_FN),
- PINMUX_DATA(SP1_SCK_FB_MARK, PTH4_FN),
+ PINMUX_DATA(SP1_MOSI_MARK, PS2_7_FN1, PTH7_FN),
+ PINMUX_DATA(TEND1_MARK, PS2_7_FN2, PTH7_FN),
+ PINMUX_DATA(SP1_MISO_MARK, PS2_6_FN1, PTH6_FN),
+ PINMUX_DATA(DREQ1_MARK, PS2_6_FN2, PTH6_FN),
+ PINMUX_DATA(SP1_SCK_MARK, PS2_5_FN1, PTH5_FN),
+ PINMUX_DATA(DACK1_MARK, PS2_5_FN2, PTH5_FN),
+ PINMUX_DATA(SP1_SCK_FB_MARK, PS2_4_FN1, PTH4_FN),
+ PINMUX_DATA(ADTRG1_MARK, PS2_4_FN2, PTH4_FN),
PINMUX_DATA(SP1_SS0_MARK, PTH3_FN),
- PINMUX_DATA(TCLK_MARK, PTH2_FN),
- PINMUX_DATA(RXD4_MARK, PS2_1_FN1, PTH1_FN),
- PINMUX_DATA(SP1_SS1_MARK, PS2_1_FN2, PTH1_FN),
- PINMUX_DATA(TXD4_MARK, PS2_0_FN1, PTH0_FN),
- PINMUX_DATA(SP0_SS1_MARK, PS2_0_FN2, PTH0_FN),
+ PINMUX_DATA(SP1_SS1_MARK, PS2_2_FN1, PTH2_FN),
+ PINMUX_DATA(ADTRG0_MARK, PS2_2_FN2, PTH2_FN),
+ PINMUX_DATA(WP_MARK, PTH1_FN),
+ PINMUX_DATA(FMS0_MARK, PTH0_FN),
/* PTI FN */
- PINMUX_DATA(IRQ15_MARK, PTI7_FN),
- PINMUX_DATA(IRQ14_MARK, PTI6_FN),
- PINMUX_DATA(IRQ13_MARK, PTI5_FN),
- PINMUX_DATA(IRQ12_MARK, PTI4_FN),
- PINMUX_DATA(IRQ11_MARK, PTI3_FN),
- PINMUX_DATA(IRQ10_MARK, PTI2_FN),
- PINMUX_DATA(IRQ9_MARK, PTI1_FN),
- PINMUX_DATA(IRQ8_MARK, PTI0_FN),
+ PINMUX_DATA(D15_MARK, PS3_15_FN1, PTI7_FN),
+ PINMUX_DATA(SD_WP_MARK, PS3_15_FN2, PTI7_FN),
+ PINMUX_DATA(D14_MARK, PS3_14_FN1, PTI6_FN),
+ PINMUX_DATA(SD_CD_MARK, PS3_14_FN2, PTI6_FN),
+ PINMUX_DATA(D13_MARK, PS3_13_FN1, PTI5_FN),
+ PINMUX_DATA(SD_CLK_MARK, PS3_13_FN2, PTI5_FN),
+ PINMUX_DATA(D12_MARK, PS3_12_FN1, PTI4_FN),
+ PINMUX_DATA(SD_CMD_MARK, PS3_12_FN2, PTI4_FN),
+ PINMUX_DATA(D11_MARK, PS3_11_FN1, PTI3_FN),
+ PINMUX_DATA(SD_D3_MARK, PS3_11_FN2, PTI3_FN),
+ PINMUX_DATA(D10_MARK, PS3_10_FN1, PTI2_FN),
+ PINMUX_DATA(SD_D2_MARK, PS3_10_FN2, PTI2_FN),
+ PINMUX_DATA(D9_MARK, PS3_9_FN1, PTI1_FN),
+ PINMUX_DATA(SD_D1_MARK, PS3_9_FN2, PTI1_FN),
+ PINMUX_DATA(D8_MARK, PS3_8_FN1, PTI0_FN),
+ PINMUX_DATA(SD_D0_MARK, PS3_8_FN2, PTI0_FN),
/* PTJ FN */
- PINMUX_DATA(RXD3_MARK, PTJ7_FN),
- PINMUX_DATA(TXD3_MARK, PTJ6_FN),
- PINMUX_DATA(RXD2_MARK, PTJ5_FN),
- PINMUX_DATA(TXD2_MARK, PTJ4_FN),
- PINMUX_DATA(COM1_TXD_MARK, PTJ3_FN),
- PINMUX_DATA(COM1_RXD_MARK, PTJ2_FN),
- PINMUX_DATA(COM1_RTS_MARK, PTJ1_FN),
- PINMUX_DATA(COM1_CTS_MARK, PTJ0_FN),
+ PINMUX_DATA(RTS3_MARK, PTJ6_FN),
+ PINMUX_DATA(CTS3_MARK, PTJ5_FN),
+ PINMUX_DATA(TXD3_MARK, PTJ4_FN),
+ PINMUX_DATA(RXD3_MARK, PTJ3_FN),
+ PINMUX_DATA(RTS4_MARK, PTJ2_FN),
+ PINMUX_DATA(RXD4_MARK, PTJ1_FN),
+ PINMUX_DATA(TXD4_MARK, PTJ0_FN),
/* PTK FN */
- PINMUX_DATA(COM2_TXD_MARK, PTK7_FN),
+ PINMUX_DATA(COM2_TXD_MARK, PS3_7_FN1, PTK7_FN),
+ PINMUX_DATA(SCK2_MARK, PS3_7_FN2, PTK7_FN),
PINMUX_DATA(COM2_RXD_MARK, PTK6_FN),
PINMUX_DATA(COM2_RTS_MARK, PTK5_FN),
PINMUX_DATA(COM2_CTS_MARK, PTK4_FN),
PINMUX_DATA(COM2_DTR_MARK, PTK3_FN),
- PINMUX_DATA(COM2_DSR_MARK, PTK2_FN),
- PINMUX_DATA(COM2_DCD_MARK, PTK1_FN),
- PINMUX_DATA(COM2_RI_MARK, PTK0_FN),
+ PINMUX_DATA(COM2_DSR_MARK, PS3_2_FN1, PTK2_FN),
+ PINMUX_DATA(SCK4_MARK, PS3_2_FN2, PTK2_FN),
+ PINMUX_DATA(COM2_DCD_MARK, PS3_1_FN1, PTK1_FN),
+ PINMUX_DATA(SCK3_MARK, PS3_1_FN2, PTK1_FN),
+ PINMUX_DATA(CLKOUT_MARK, PTK0_FN),
/* PTL FN */
- PINMUX_DATA(RAC_TXD_MARK, PTL7_FN),
- PINMUX_DATA(RAC_RXD_MARK, PTL6_FN),
- PINMUX_DATA(RAC_RTS_MARK, PTL5_FN),
- PINMUX_DATA(RAC_CTS_MARK, PTL4_FN),
+ PINMUX_DATA(RAC_RXD_MARK, PS4_14_FN1, PTL6_FN),
+ PINMUX_DATA(RXD2_MARK, PS4_14_FN2, PTL6_FN),
+ PINMUX_DATA(RAC_RTS_MARK, PS4_13_FN1, PTL5_FN),
+ PINMUX_DATA(CS5_MARK, PS4_13_FN2, PTL5_FN),
+ PINMUX_DATA(RAC_CTS_MARK, PS4_12_FN1, PTL4_FN),
+ PINMUX_DATA(CS6_MARK, PS4_12_FN2, PTL4_FN),
PINMUX_DATA(RAC_DTR_MARK, PTL3_FN),
- PINMUX_DATA(RAC_DSR_MARK, PTL2_FN),
- PINMUX_DATA(RAC_DCD_MARK, PTL1_FN),
- PINMUX_DATA(RAC_RI_MARK, PTL0_FN),
+ PINMUX_DATA(RAC_DSR_MARK, PS4_10_FN1, PTL2_FN),
+ PINMUX_DATA(AUDSYNC_MARK, PS4_10_FN2, PTL2_FN),
+ PINMUX_DATA(RAC_DCD_MARK, PS4_9_FN1, PTL1_FN),
+ PINMUX_DATA(AUDCK_MARK, PS4_9_FN2, PTL1_FN),
+ PINMUX_DATA(RAC_TXD_MARK, PS4_8_FN1, PTL0_FN),
+ PINMUX_DATA(TXD2_MARK, PS4_8_FN1, PTL0_FN),
/* PTM FN */
- PINMUX_DATA(WP_MARK, PTM6_FN),
- PINMUX_DATA(FMS0_MARK, PTM5_FN),
- PINMUX_DATA(FMS1_MARK, PTM4_FN),
+ PINMUX_DATA(CS4_MARK, PTM7_FN),
+ PINMUX_DATA(RD_MARK, PTM6_FN),
+ PINMUX_DATA(WE0_MARK, PTM7_FN),
+ PINMUX_DATA(CS0_MARK, PTM4_FN),
PINMUX_DATA(SDA6_MARK, PTM3_FN),
PINMUX_DATA(SCL6_MARK, PTM2_FN),
PINMUX_DATA(SDA7_MARK, PTM1_FN),
PINMUX_DATA(SCL7_MARK, PTM0_FN),
/* PTN FN */
- PINMUX_DATA(SCK2_MARK, PS4_15_FN1, PTN7_FN),
- PINMUX_DATA(EVENT7_MARK, PS4_15_FN2, PTN7_FN),
- PINMUX_DATA(RTS4_MARK, PS4_14_FN1, PTN6_FN),
- PINMUX_DATA(EVENT6_MARK, PS4_14_FN2, PTN6_FN),
- PINMUX_DATA(RTS3_MARK, PS4_13_FN1, PTN5_FN),
- PINMUX_DATA(EVENT5_MARK, PS4_13_FN2, PTN5_FN),
- PINMUX_DATA(RTS2_MARK, PS4_12_FN1, PTN4_FN),
- PINMUX_DATA(EVENT4_MARK, PS4_12_FN2, PTN4_FN),
- PINMUX_DATA(CTS4_MARK, PS4_11_FN1, PTN3_FN),
- PINMUX_DATA(EVENT3_MARK, PS4_11_FN2, PTN3_FN),
- PINMUX_DATA(CTS3_MARK, PS4_10_FN1, PTN2_FN),
- PINMUX_DATA(EVENT2_MARK, PS4_10_FN2, PTN2_FN),
- PINMUX_DATA(CTS2_MARK, PS4_9_FN1, PTN1_FN),
- PINMUX_DATA(EVENT1_MARK, PS4_9_FN2, PTN1_FN),
- PINMUX_DATA(EVENT0_MARK, PTN0_FN),
+ PINMUX_DATA(VBUS_EN_MARK, PTN6_FN),
+ PINMUX_DATA(VBUS_OC_MARK, PTN5_FN),
+ PINMUX_DATA(JMCTCK_MARK, PS4_4_FN1, PTN4_FN),
+ PINMUX_DATA(SGPIO1_CLK_MARK, PS4_4_FN2, PTN4_FN),
+ PINMUX_DATA(JMCTMS_MARK, PS4_3_FN1, PTN5_FN),
+ PINMUX_DATA(SGPIO1_LOAD_MARK, PS4_3_FN2, PTN5_FN),
+ PINMUX_DATA(JMCTDO_MARK, PS4_2_FN1, PTN2_FN),
+ PINMUX_DATA(SGPIO1_DO_MARK, PS4_2_FN2, PTN2_FN),
+ PINMUX_DATA(JMCTDI_MARK, PS4_1_FN1, PTN1_FN),
+ PINMUX_DATA(SGPIO1_DI_MARK, PS4_1_FN2, PTN1_FN),
+ PINMUX_DATA(JMCTRST_MARK, PS4_0_FN1, PTN0_FN),
+ PINMUX_DATA(SUB_CLKIN_MARK, PS4_0_FN2, PTN0_FN),
/* PTO FN */
PINMUX_DATA(SGPIO0_CLK_MARK, PTO7_FN),
PINMUX_DATA(SGPIO0_LOAD_MARK, PTO6_FN),
PINMUX_DATA(SGPIO0_DI_MARK, PTO5_FN),
PINMUX_DATA(SGPIO0_DO_MARK, PTO4_FN),
- PINMUX_DATA(SGPIO1_CLK_MARK, PTO3_FN),
- PINMUX_DATA(SGPIO1_LOAD_MARK, PTO2_FN),
- PINMUX_DATA(SGPIO1_DI_MARK, PTO1_FN),
- PINMUX_DATA(SGPIO1_DO_MARK, PTO0_FN),
+ PINMUX_DATA(SGPIO2_CLK_MARK, PS5_11_FN1, PTO3_FN),
+ PINMUX_DATA(COM1_TXD_MARK, PS5_11_FN2, PTO3_FN),
+ PINMUX_DATA(SGPIO2_LOAD_MARK, PS5_10_FN1, PTO2_FN),
+ PINMUX_DATA(COM1_RXD_MARK, PS5_10_FN2, PTO2_FN),
+ PINMUX_DATA(SGPIO2_DI_MARK, PS5_9_FN1, PTO1_FN),
+ PINMUX_DATA(COM1_RTS_MARK, PS5_9_FN2, PTO1_FN),
+ PINMUX_DATA(SGPIO2_DO_MARK, PS5_8_FN1, PTO0_FN),
+ PINMUX_DATA(COM1_CTS_MARK, PS5_8_FN2, PTO0_FN),
/* PTP FN */
- PINMUX_DATA(JMCTCK_MARK, PTP6_FN),
- PINMUX_DATA(JMCTMS_MARK, PTP5_FN),
- PINMUX_DATA(JMCTDO_MARK, PTP4_FN),
- PINMUX_DATA(JMCTDI_MARK, PTP3_FN),
- PINMUX_DATA(JMCRST_MARK, PTP2_FN),
- PINMUX_DATA(SCK4_MARK, PTP1_FN),
- PINMUX_DATA(SCK3_MARK, PTP0_FN),
/* PTQ FN */
PINMUX_DATA(LAD3_MARK, PTQ6_FN),
@@ -864,8 +977,8 @@ static pinmux_enum_t pinmux_data[] = {
PINMUX_DATA(LAD1_MARK, PTQ4_FN),
PINMUX_DATA(LAD0_MARK, PTQ3_FN),
PINMUX_DATA(LFRAME_MARK, PTQ2_FN),
- PINMUX_DATA(SCK4_MARK, PTQ1_FN),
- PINMUX_DATA(SCK3_MARK, PTQ0_FN),
+ PINMUX_DATA(LRESET_MARK, PTQ1_FN),
+ PINMUX_DATA(LCLK_MARK, PTQ0_FN),
/* PTR FN */
PINMUX_DATA(SDA8_MARK, PTR7_FN), /* DDC3? */
@@ -888,58 +1001,84 @@ static pinmux_enum_t pinmux_data[] = {
PINMUX_DATA(SCL3_MARK, PTS0_FN),
/* PTT FN */
- PINMUX_DATA(AUDSYNC_MARK, PTS5_FN),
- PINMUX_DATA(AUDCK_MARK, PTS4_FN),
- PINMUX_DATA(AUDATA3_MARK, PS4_3_FN1, PTS3_FN),
- PINMUX_DATA(PWX7_MARK, PS4_3_FN2, PTS3_FN),
- PINMUX_DATA(AUDATA2_MARK, PS4_2_FN1, PTS2_FN),
- PINMUX_DATA(PWX6_MARK, PS4_2_FN2, PTS2_FN),
- PINMUX_DATA(AUDATA1_MARK, PS4_1_FN1, PTS1_FN),
- PINMUX_DATA(PWX5_MARK, PS4_1_FN2, PTS1_FN),
- PINMUX_DATA(AUDATA0_MARK, PS4_0_FN1, PTS0_FN),
- PINMUX_DATA(PWX4_MARK, PS4_0_FN2, PTS0_FN),
+ PINMUX_DATA(PWMX7_MARK, PS5_7_FN1, PTT7_FN),
+ PINMUX_DATA(AUDATA3_MARK, PS5_7_FN2, PTT7_FN),
+ PINMUX_DATA(PWMX6_MARK, PS5_6_FN1, PTT6_FN),
+ PINMUX_DATA(AUDATA2_MARK, PS5_6_FN2, PTT6_FN),
+ PINMUX_DATA(PWMX5_MARK, PS5_5_FN1, PTT5_FN),
+ PINMUX_DATA(AUDATA1_MARK, PS5_5_FN2, PTT5_FN),
+ PINMUX_DATA(PWMX4_MARK, PS5_4_FN1, PTT4_FN),
+ PINMUX_DATA(AUDATA0_MARK, PS5_4_FN2, PTT4_FN),
+ PINMUX_DATA(PWMX3_MARK, PS5_3_FN1, PTT3_FN),
+ PINMUX_DATA(STATUS1_MARK, PS5_3_FN2, PTT3_FN),
+ PINMUX_DATA(PWMX2_MARK, PS5_2_FN1, PTT2_FN),
+ PINMUX_DATA(STATUS0_MARK, PS5_2_FN2, PTT2_FN),
+ PINMUX_DATA(PWMX1_MARK, PTT1_FN),
+ PINMUX_DATA(PWMX0_MARK, PTT0_FN),
/* PTU FN */
- PINMUX_DATA(CS6_MARK, PTU7_FN),
- PINMUX_DATA(CS5_MARK, PTU6_FN),
- PINMUX_DATA(CS4_MARK, PTU5_FN),
- PINMUX_DATA(CS0_MARK, PTU4_FN),
- PINMUX_DATA(RD_MARK, PTU3_FN),
- PINMUX_DATA(WE0_MARK, PTU2_FN),
- PINMUX_DATA(A25_MARK, PS5_9_FN1, PTU1_FN),
- PINMUX_DATA(DREQ0_MARK, PS5_9_FN2, PTU1_FN),
- PINMUX_DATA(A24_MARK, PS5_8_FN1, PTU0_FN),
- PINMUX_DATA(DACK0_MARK, PS5_8_FN2, PTU0_FN),
+ PINMUX_DATA(LGPIO7_MARK, PS6_15_FN1, PTU7_FN),
+ PINMUX_DATA(APMONCTL_O_MARK, PS6_15_FN2, PTU7_FN),
+ PINMUX_DATA(LGPIO6_MARK, PS6_14_FN1, PTU6_FN),
+ PINMUX_DATA(APMPWBTOUT_O_MARK, PS6_14_FN2, PTU6_FN),
+ PINMUX_DATA(LGPIO5_MARK, PS6_13_FN1, PTU5_FN),
+ PINMUX_DATA(APMSCI_O_MARK, PS6_13_FN2, PTU5_FN),
+ PINMUX_DATA(LGPIO4_MARK, PS6_12_FN1, PTU4_FN),
+ PINMUX_DATA(APMVDDON_MARK, PS6_12_FN2, PTU4_FN),
+ PINMUX_DATA(LGPIO3_MARK, PS6_11_FN1, PTU3_FN),
+ PINMUX_DATA(APMSLPBTN_MARK, PS6_11_FN2, PTU3_FN),
+ PINMUX_DATA(LGPIO2_MARK, PS6_10_FN1, PTU2_FN),
+ PINMUX_DATA(APMPWRBTN_MARK, PS6_10_FN2, PTU2_FN),
+ PINMUX_DATA(LGPIO1_MARK, PS6_9_FN1, PTU1_FN),
+ PINMUX_DATA(APMS5N_MARK, PS6_9_FN2, PTU1_FN),
+ PINMUX_DATA(LGPIO0_MARK, PS6_8_FN1, PTU0_FN),
+ PINMUX_DATA(APMS3N_MARK, PS6_8_FN2, PTU0_FN),
/* PTV FN */
- PINMUX_DATA(A23_MARK, PS5_7_FN1, PTV7_FN),
- PINMUX_DATA(TEND0_MARK, PS5_7_FN2, PTV7_FN),
- PINMUX_DATA(A22_MARK, PS5_6_FN1, PTV6_FN),
- PINMUX_DATA(DREQ1_MARK, PS5_6_FN2, PTV6_FN),
- PINMUX_DATA(A21_MARK, PS5_5_FN1, PTV5_FN),
- PINMUX_DATA(DACK1_MARK, PS5_5_FN2, PTV5_FN),
- PINMUX_DATA(A20_MARK, PS5_4_FN1, PTV4_FN),
- PINMUX_DATA(TEND1_MARK, PS5_4_FN2, PTV4_FN),
- PINMUX_DATA(A19_MARK, PTV3_FN),
- PINMUX_DATA(A18_MARK, PTV2_FN),
- PINMUX_DATA(A17_MARK, PTV1_FN),
- PINMUX_DATA(A16_MARK, PTV0_FN),
+ PINMUX_DATA(A23_MARK, PS6_7_FN1, PTV7_FN),
+ PINMUX_DATA(COM2_RI_MARK, PS6_7_FN2, PTV7_FN),
+ PINMUX_DATA(A22_MARK, PS6_6_FN1, PTV6_FN),
+ PINMUX_DATA(R_SPI_MOSI_MARK, PS6_6_FN2, PTV6_FN),
+ PINMUX_DATA(A21_MARK, PS6_5_FN1, PTV5_FN),
+ PINMUX_DATA(R_SPI_MISO_MARK, PS6_5_FN2, PTV5_FN),
+ PINMUX_DATA(A20_MARK, PS6_4_FN1, PTV4_FN),
+ PINMUX_DATA(R_SPI_RSPCK_MARK, PS6_4_FN2, PTV4_FN),
+ PINMUX_DATA(A19_MARK, PS6_3_FN1, PTV3_FN),
+ PINMUX_DATA(R_SPI_SSL0_MARK, PS6_3_FN2, PTV3_FN),
+ PINMUX_DATA(A18_MARK, PS6_2_FN1, PTV2_FN),
+ PINMUX_DATA(R_SPI_SSL1_MARK, PS6_2_FN2, PTV2_FN),
+ PINMUX_DATA(A17_MARK, PS6_1_FN1, PTV1_FN),
+ PINMUX_DATA(EVENT7_MARK, PS6_1_FN2, PTV1_FN),
+ PINMUX_DATA(A16_MARK, PS6_0_FN1, PTV0_FN),
+ PINMUX_DATA(EVENT6_MARK, PS6_0_FN1, PTV0_FN),
/* PTW FN */
- PINMUX_DATA(A15_MARK, PTW7_FN),
- PINMUX_DATA(A14_MARK, PTW6_FN),
- PINMUX_DATA(A13_MARK, PTW5_FN),
- PINMUX_DATA(A12_MARK, PTW4_FN),
- PINMUX_DATA(A11_MARK, PTW3_FN),
- PINMUX_DATA(A10_MARK, PTW2_FN),
- PINMUX_DATA(A9_MARK, PTW1_FN),
- PINMUX_DATA(A8_MARK, PTW0_FN),
+ PINMUX_DATA(A15_MARK, PS7_15_FN1, PTW7_FN),
+ PINMUX_DATA(EVENT5_MARK, PS7_15_FN2, PTW7_FN),
+ PINMUX_DATA(A14_MARK, PS7_14_FN1, PTW6_FN),
+ PINMUX_DATA(EVENT4_MARK, PS7_14_FN2, PTW6_FN),
+ PINMUX_DATA(A13_MARK, PS7_13_FN1, PTW5_FN),
+ PINMUX_DATA(EVENT3_MARK, PS7_13_FN2, PTW5_FN),
+ PINMUX_DATA(A12_MARK, PS7_12_FN1, PTW4_FN),
+ PINMUX_DATA(EVENT2_MARK, PS7_12_FN2, PTW4_FN),
+ PINMUX_DATA(A11_MARK, PS7_11_FN1, PTW3_FN),
+ PINMUX_DATA(EVENT1_MARK, PS7_11_FN2, PTW3_FN),
+ PINMUX_DATA(A10_MARK, PS7_10_FN1, PTW2_FN),
+ PINMUX_DATA(EVENT0_MARK, PS7_10_FN2, PTW2_FN),
+ PINMUX_DATA(A9_MARK, PS7_9_FN1, PTW1_FN),
+ PINMUX_DATA(CTS4_MARK, PS7_9_FN2, PTW1_FN),
+ PINMUX_DATA(A8_MARK, PS7_8_FN1, PTW0_FN),
+ PINMUX_DATA(CTS2_MARK, PS7_8_FN2, PTW0_FN),
/* PTX FN */
- PINMUX_DATA(A7_MARK, PTX7_FN),
- PINMUX_DATA(A6_MARK, PTX6_FN),
- PINMUX_DATA(A5_MARK, PTX5_FN),
- PINMUX_DATA(A4_MARK, PTX4_FN),
+ PINMUX_DATA(A7_MARK, PS7_7_FN1, PTX7_FN),
+ PINMUX_DATA(RTS2_MARK, PS7_7_FN2, PTX7_FN),
+ PINMUX_DATA(A6_MARK, PS7_6_FN1, PTX6_FN),
+ PINMUX_DATA(SIM_D_MARK, PS7_6_FN2, PTX6_FN),
+ PINMUX_DATA(A5_MARK, PS7_5_FN1, PTX5_FN),
+ PINMUX_DATA(SIM_CLK_MARK, PS7_5_FN2, PTX5_FN),
+ PINMUX_DATA(A4_MARK, PS7_4_FN1, PTX4_FN),
+ PINMUX_DATA(SIM_RST_MARK, PS7_4_FN2, PTX4_FN),
PINMUX_DATA(A3_MARK, PTX3_FN),
PINMUX_DATA(A2_MARK, PTX2_FN),
PINMUX_DATA(A1_MARK, PTX1_FN),
@@ -954,6 +1093,24 @@ static pinmux_enum_t pinmux_data[] = {
PINMUX_DATA(D2_MARK, PTY2_FN),
PINMUX_DATA(D1_MARK, PTY1_FN),
PINMUX_DATA(D0_MARK, PTY0_FN),
+
+ /* PTZ FN */
+ PINMUX_DATA(MMCDAT7_MARK, PS8_15_FN1, PTZ7_FN),
+ PINMUX_DATA(ON_DQ7_MARK, PS8_15_FN2, PTZ7_FN),
+ PINMUX_DATA(MMCDAT6_MARK, PS8_14_FN1, PTZ6_FN),
+ PINMUX_DATA(ON_DQ6_MARK, PS8_14_FN2, PTZ6_FN),
+ PINMUX_DATA(MMCDAT5_MARK, PS8_13_FN1, PTZ5_FN),
+ PINMUX_DATA(ON_DQ5_MARK, PS8_13_FN2, PTZ5_FN),
+ PINMUX_DATA(MMCDAT4_MARK, PS8_12_FN1, PTZ4_FN),
+ PINMUX_DATA(ON_DQ4_MARK, PS8_12_FN2, PTZ4_FN),
+ PINMUX_DATA(MMCDAT3_MARK, PS8_11_FN1, PTZ3_FN),
+ PINMUX_DATA(ON_DQ3_MARK, PS8_11_FN2, PTZ3_FN),
+ PINMUX_DATA(MMCDAT2_MARK, PS8_10_FN1, PTZ2_FN),
+ PINMUX_DATA(ON_DQ2_MARK, PS8_10_FN2, PTZ2_FN),
+ PINMUX_DATA(MMCDAT1_MARK, PS8_9_FN1, PTZ1_FN),
+ PINMUX_DATA(ON_DQ1_MARK, PS8_9_FN2, PTZ1_FN),
+ PINMUX_DATA(MMCDAT0_MARK, PS8_8_FN1, PTZ0_FN),
+ PINMUX_DATA(ON_DQ0_MARK, PS8_8_FN2, PTZ0_FN),
};
static struct pinmux_gpio pinmux_gpios[] = {
@@ -1048,7 +1205,6 @@ static struct pinmux_gpio pinmux_gpios[] = {
PINMUX_GPIO(GPIO_PTI0, PTI0_DATA),
/* PTJ */
- PINMUX_GPIO(GPIO_PTJ7, PTJ7_DATA),
PINMUX_GPIO(GPIO_PTJ6, PTJ6_DATA),
PINMUX_GPIO(GPIO_PTJ5, PTJ5_DATA),
PINMUX_GPIO(GPIO_PTJ4, PTJ4_DATA),
@@ -1068,7 +1224,6 @@ static struct pinmux_gpio pinmux_gpios[] = {
PINMUX_GPIO(GPIO_PTK0, PTK0_DATA),
/* PTL */
- PINMUX_GPIO(GPIO_PTL7, PTL7_DATA),
PINMUX_GPIO(GPIO_PTL6, PTL6_DATA),
PINMUX_GPIO(GPIO_PTL5, PTL5_DATA),
PINMUX_GPIO(GPIO_PTL4, PTL4_DATA),
@@ -1078,6 +1233,7 @@ static struct pinmux_gpio pinmux_gpios[] = {
PINMUX_GPIO(GPIO_PTL0, PTL0_DATA),
/* PTM */
+ PINMUX_GPIO(GPIO_PTM7, PTM7_DATA),
PINMUX_GPIO(GPIO_PTM6, PTM6_DATA),
PINMUX_GPIO(GPIO_PTM5, PTM5_DATA),
PINMUX_GPIO(GPIO_PTM4, PTM4_DATA),
@@ -1087,7 +1243,6 @@ static struct pinmux_gpio pinmux_gpios[] = {
PINMUX_GPIO(GPIO_PTM0, PTM0_DATA),
/* PTN */
- PINMUX_GPIO(GPIO_PTN7, PTN7_DATA),
PINMUX_GPIO(GPIO_PTN6, PTN6_DATA),
PINMUX_GPIO(GPIO_PTN5, PTN5_DATA),
PINMUX_GPIO(GPIO_PTN4, PTN4_DATA),
@@ -1107,6 +1262,7 @@ static struct pinmux_gpio pinmux_gpios[] = {
PINMUX_GPIO(GPIO_PTO0, PTO0_DATA),
/* PTP */
+ PINMUX_GPIO(GPIO_PTP7, PTP7_DATA),
PINMUX_GPIO(GPIO_PTP6, PTP6_DATA),
PINMUX_GPIO(GPIO_PTP5, PTP5_DATA),
PINMUX_GPIO(GPIO_PTP4, PTP4_DATA),
@@ -1145,6 +1301,8 @@ static struct pinmux_gpio pinmux_gpios[] = {
PINMUX_GPIO(GPIO_PTS0, PTS0_DATA),
/* PTT */
+ PINMUX_GPIO(GPIO_PTT7, PTT7_DATA),
+ PINMUX_GPIO(GPIO_PTT6, PTT6_DATA),
PINMUX_GPIO(GPIO_PTT5, PTT5_DATA),
PINMUX_GPIO(GPIO_PTT4, PTT4_DATA),
PINMUX_GPIO(GPIO_PTT3, PTT3_DATA),
@@ -1212,54 +1370,35 @@ static struct pinmux_gpio pinmux_gpios[] = {
PINMUX_GPIO(GPIO_PTZ1, PTZ1_DATA),
PINMUX_GPIO(GPIO_PTZ0, PTZ0_DATA),
- /* PTA (mobule: LBSC, CPG, LPC) */
+ /* PTA (mobule: LBSC, RGMII) */
PINMUX_GPIO(GPIO_FN_BS, BS_MARK),
PINMUX_GPIO(GPIO_FN_RDWR, RDWR_MARK),
PINMUX_GPIO(GPIO_FN_WE1, WE1_MARK),
PINMUX_GPIO(GPIO_FN_RDY, RDY_MARK),
- PINMUX_GPIO(GPIO_FN_MD10, MD10_MARK),
- PINMUX_GPIO(GPIO_FN_MD9, MD9_MARK),
- PINMUX_GPIO(GPIO_FN_MD8, MD8_MARK),
- PINMUX_GPIO(GPIO_FN_LGPIO7, LGPIO7_MARK),
- PINMUX_GPIO(GPIO_FN_LGPIO6, LGPIO6_MARK),
- PINMUX_GPIO(GPIO_FN_LGPIO5, LGPIO5_MARK),
- PINMUX_GPIO(GPIO_FN_LGPIO4, LGPIO4_MARK),
- PINMUX_GPIO(GPIO_FN_LGPIO3, LGPIO3_MARK),
- PINMUX_GPIO(GPIO_FN_LGPIO2, LGPIO2_MARK),
- PINMUX_GPIO(GPIO_FN_LGPIO1, LGPIO1_MARK),
- PINMUX_GPIO(GPIO_FN_LGPIO0, LGPIO0_MARK),
-
- /* PTB (mobule: LBSC, EtherC, SIM, LPC) */
- PINMUX_GPIO(GPIO_FN_D15, D15_MARK),
- PINMUX_GPIO(GPIO_FN_D14, D14_MARK),
- PINMUX_GPIO(GPIO_FN_D13, D13_MARK),
- PINMUX_GPIO(GPIO_FN_D12, D12_MARK),
- PINMUX_GPIO(GPIO_FN_D11, D11_MARK),
- PINMUX_GPIO(GPIO_FN_D10, D10_MARK),
- PINMUX_GPIO(GPIO_FN_D9, D9_MARK),
- PINMUX_GPIO(GPIO_FN_D8, D8_MARK),
PINMUX_GPIO(GPIO_FN_ET0_MDC, ET0_MDC_MARK),
- PINMUX_GPIO(GPIO_FN_ET0_MDIO, ET0_MDIO_MARK),
+ PINMUX_GPIO(GPIO_FN_ET0_MDIO, ET0_MDC_MARK),
PINMUX_GPIO(GPIO_FN_ET1_MDC, ET1_MDC_MARK),
- PINMUX_GPIO(GPIO_FN_ET1_MDIO, ET1_MDIO_MARK),
- PINMUX_GPIO(GPIO_FN_WPSZ1, WPSZ1_MARK),
- PINMUX_GPIO(GPIO_FN_WPSZ0, WPSZ0_MARK),
- PINMUX_GPIO(GPIO_FN_FWID, FWID_MARK),
- PINMUX_GPIO(GPIO_FN_FLSHSZ, FLSHSZ_MARK),
- PINMUX_GPIO(GPIO_FN_LPC_SPIEN, LPC_SPIEN_MARK),
- PINMUX_GPIO(GPIO_FN_BASEL, BASEL_MARK),
-
- /* PTC (mobule: SD) */
- PINMUX_GPIO(GPIO_FN_SD_WP, SD_WP_MARK),
- PINMUX_GPIO(GPIO_FN_SD_CD, SD_CD_MARK),
- PINMUX_GPIO(GPIO_FN_SD_CLK, SD_CLK_MARK),
- PINMUX_GPIO(GPIO_FN_SD_CMD, SD_CMD_MARK),
- PINMUX_GPIO(GPIO_FN_SD_D3, SD_D3_MARK),
- PINMUX_GPIO(GPIO_FN_SD_D2, SD_D2_MARK),
- PINMUX_GPIO(GPIO_FN_SD_D1, SD_D1_MARK),
- PINMUX_GPIO(GPIO_FN_SD_D0, SD_D0_MARK),
+ PINMUX_GPIO(GPIO_FN_ET1_MDIO, ET1_MDC_MARK),
- /* PTD (mobule: INTC, SPI0, LBSC, CPG, ADC) */
+ /* PTB (mobule: INTC, ONFI, TMU) */
+ PINMUX_GPIO(GPIO_FN_IRQ15, IRQ15_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ14, IRQ14_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ13, IRQ13_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ12, IRQ12_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ11, IRQ11_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ10, IRQ10_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ9, IRQ9_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ8, IRQ8_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_NRE, ON_NRE_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_NWE, ON_NWE_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_NWP, ON_NWP_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_NCE0, ON_NCE0_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_R_B0, ON_R_B0_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_ALE, ON_ALE_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_CLE, ON_CLE_MARK),
+ PINMUX_GPIO(GPIO_FN_TCLK, TCLK_MARK),
+
+ /* PTC (mobule: IRQ, PWMU) */
PINMUX_GPIO(GPIO_FN_IRQ7, IRQ7_MARK),
PINMUX_GPIO(GPIO_FN_IRQ6, IRQ6_MARK),
PINMUX_GPIO(GPIO_FN_IRQ5, IRQ5_MARK),
@@ -1268,80 +1407,102 @@ static struct pinmux_gpio pinmux_gpios[] = {
PINMUX_GPIO(GPIO_FN_IRQ2, IRQ2_MARK),
PINMUX_GPIO(GPIO_FN_IRQ1, IRQ1_MARK),
PINMUX_GPIO(GPIO_FN_IRQ0, IRQ0_MARK),
- PINMUX_GPIO(GPIO_FN_MD6, MD6_MARK),
- PINMUX_GPIO(GPIO_FN_MD5, MD5_MARK),
- PINMUX_GPIO(GPIO_FN_MD3, MD3_MARK),
- PINMUX_GPIO(GPIO_FN_MD2, MD2_MARK),
- PINMUX_GPIO(GPIO_FN_MD1, MD1_MARK),
- PINMUX_GPIO(GPIO_FN_MD0, MD0_MARK),
- PINMUX_GPIO(GPIO_FN_ADTRG1, ADTRG1_MARK),
- PINMUX_GPIO(GPIO_FN_ADTRG0, ADTRG0_MARK),
+ PINMUX_GPIO(GPIO_FN_PWMU0, PWMU0_MARK),
+ PINMUX_GPIO(GPIO_FN_PWMU1, PWMU1_MARK),
+ PINMUX_GPIO(GPIO_FN_PWMU2, PWMU2_MARK),
+ PINMUX_GPIO(GPIO_FN_PWMU3, PWMU3_MARK),
+ PINMUX_GPIO(GPIO_FN_PWMU4, PWMU4_MARK),
+ PINMUX_GPIO(GPIO_FN_PWMU5, PWMU5_MARK),
+
+ /* PTD (mobule: SPI0, DMAC) */
+ PINMUX_GPIO(GPIO_FN_SP0_MOSI, SP0_MOSI_MARK),
+ PINMUX_GPIO(GPIO_FN_SP0_MISO, SP0_MISO_MARK),
+ PINMUX_GPIO(GPIO_FN_SP0_SCK, SP0_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_SP0_SCK_FB, SP0_SCK_FB_MARK),
+ PINMUX_GPIO(GPIO_FN_SP0_SS0, SP0_SS0_MARK),
+ PINMUX_GPIO(GPIO_FN_SP0_SS1, SP0_SS1_MARK),
+ PINMUX_GPIO(GPIO_FN_SP0_SS2, SP0_SS2_MARK),
+ PINMUX_GPIO(GPIO_FN_SP0_SS3, SP0_SS3_MARK),
+ PINMUX_GPIO(GPIO_FN_DREQ0, DREQ0_MARK),
+ PINMUX_GPIO(GPIO_FN_DACK0, DACK0_MARK),
+ PINMUX_GPIO(GPIO_FN_TEND0, TEND0_MARK),
- /* PTE (mobule: EtherC) */
- PINMUX_GPIO(GPIO_FN_ET0_CRS_DV, ET0_CRS_DV_MARK),
- PINMUX_GPIO(GPIO_FN_ET0_TXD1, ET0_TXD1_MARK),
- PINMUX_GPIO(GPIO_FN_ET0_TXD0, ET0_TXD0_MARK),
- PINMUX_GPIO(GPIO_FN_ET0_TX_EN, ET0_TX_EN_MARK),
- PINMUX_GPIO(GPIO_FN_ET0_REF_CLK, ET0_REF_CLK_MARK),
- PINMUX_GPIO(GPIO_FN_ET0_RXD1, ET0_RXD1_MARK),
- PINMUX_GPIO(GPIO_FN_ET0_RXD0, ET0_RXD0_MARK),
- PINMUX_GPIO(GPIO_FN_ET0_RX_ER, ET0_RX_ER_MARK),
-
- /* PTF (mobule: EtherC) */
- PINMUX_GPIO(GPIO_FN_ET1_CRS_DV, ET1_CRS_DV_MARK),
- PINMUX_GPIO(GPIO_FN_ET1_TXD1, ET1_TXD1_MARK),
- PINMUX_GPIO(GPIO_FN_ET1_TXD0, ET1_TXD0_MARK),
- PINMUX_GPIO(GPIO_FN_ET1_TX_EN, ET1_TX_EN_MARK),
- PINMUX_GPIO(GPIO_FN_ET1_REF_CLK, ET1_REF_CLK_MARK),
- PINMUX_GPIO(GPIO_FN_ET1_RXD1, ET1_RXD1_MARK),
- PINMUX_GPIO(GPIO_FN_ET1_RXD0, ET1_RXD0_MARK),
- PINMUX_GPIO(GPIO_FN_ET1_RX_ER, ET1_RX_ER_MARK),
-
- /* PTG (mobule: SYSTEM, PWMX, LPC) */
- PINMUX_GPIO(GPIO_FN_STATUS0, STATUS0_MARK),
- PINMUX_GPIO(GPIO_FN_STATUS1, STATUS1_MARK),
- PINMUX_GPIO(GPIO_FN_PWX0, PWX0_MARK),
- PINMUX_GPIO(GPIO_FN_PWX1, PWX1_MARK),
- PINMUX_GPIO(GPIO_FN_PWX2, PWX2_MARK),
- PINMUX_GPIO(GPIO_FN_PWX3, PWX3_MARK),
+ /* PTE (mobule: RMII) */
+ PINMUX_GPIO(GPIO_FN_RMII0_CRS_DV, RMII0_CRS_DV_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII0_TXD1, RMII0_TXD1_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII0_TXD0, RMII0_TXD0_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII0_TXEN, RMII0_TXEN_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII0_REFCLK, RMII0_REFCLK_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII0_RXD1, RMII0_RXD1_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII0_RXD0, RMII0_RXD0_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII0_RX_ER, RMII0_RX_ER_MARK),
+
+ /* PTF (mobule: RMII, SerMux) */
+ PINMUX_GPIO(GPIO_FN_RMII1_CRS_DV, RMII1_CRS_DV_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII1_TXD1, RMII1_TXD1_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII1_TXD0, RMII1_TXD0_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII1_TXEN, RMII1_TXEN_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII1_REFCLK, RMII1_REFCLK_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII1_RXD1, RMII1_RXD1_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII1_RXD0, RMII1_RXD0_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII1_RX_ER, RMII1_RX_ER_MARK),
+ PINMUX_GPIO(GPIO_FN_RAC_RI, RAC_RI_MARK),
+
+ /* PTG (mobule: system, LBSC, LPC, WDT, LPC, eMMC) */
+ PINMUX_GPIO(GPIO_FN_BOOTFMS, BOOTFMS_MARK),
+ PINMUX_GPIO(GPIO_FN_BOOTWP, BOOTWP_MARK),
+ PINMUX_GPIO(GPIO_FN_A25, A25_MARK),
+ PINMUX_GPIO(GPIO_FN_A24, A24_MARK),
PINMUX_GPIO(GPIO_FN_SERIRQ, SERIRQ_MARK),
- PINMUX_GPIO(GPIO_FN_CLKRUN, CLKRUN_MARK),
+ PINMUX_GPIO(GPIO_FN_WDTOVF, WDTOVF_MARK),
PINMUX_GPIO(GPIO_FN_LPCPD, LPCPD_MARK),
PINMUX_GPIO(GPIO_FN_LDRQ, LDRQ_MARK),
+ PINMUX_GPIO(GPIO_FN_MMCCLK, MMCCLK_MARK),
+ PINMUX_GPIO(GPIO_FN_MMCCMD, MMCCMD_MARK),
- /* PTH (mobule: TMU, SCIF234, SPI1, SPI0) */
- PINMUX_GPIO(GPIO_FN_TCLK, TCLK_MARK),
- PINMUX_GPIO(GPIO_FN_RXD4, RXD4_MARK),
- PINMUX_GPIO(GPIO_FN_TXD4, TXD4_MARK),
+ /* PTH (mobule: SPI1, LPC, DMAC, ADC) */
PINMUX_GPIO(GPIO_FN_SP1_MOSI, SP1_MOSI_MARK),
PINMUX_GPIO(GPIO_FN_SP1_MISO, SP1_MISO_MARK),
PINMUX_GPIO(GPIO_FN_SP1_SCK, SP1_SCK_MARK),
PINMUX_GPIO(GPIO_FN_SP1_SCK_FB, SP1_SCK_FB_MARK),
PINMUX_GPIO(GPIO_FN_SP1_SS0, SP1_SS0_MARK),
PINMUX_GPIO(GPIO_FN_SP1_SS1, SP1_SS1_MARK),
- PINMUX_GPIO(GPIO_FN_SP0_SS1, SP0_SS1_MARK),
+ PINMUX_GPIO(GPIO_FN_WP, WP_MARK),
+ PINMUX_GPIO(GPIO_FN_FMS0, FMS0_MARK),
+ PINMUX_GPIO(GPIO_FN_TEND1, TEND1_MARK),
+ PINMUX_GPIO(GPIO_FN_DREQ1, DREQ1_MARK),
+ PINMUX_GPIO(GPIO_FN_DACK1, DACK1_MARK),
+ PINMUX_GPIO(GPIO_FN_ADTRG1, ADTRG1_MARK),
+ PINMUX_GPIO(GPIO_FN_ADTRG0, ADTRG0_MARK),
- /* PTI (mobule: INTC) */
- PINMUX_GPIO(GPIO_FN_IRQ15, IRQ15_MARK),
- PINMUX_GPIO(GPIO_FN_IRQ14, IRQ14_MARK),
- PINMUX_GPIO(GPIO_FN_IRQ13, IRQ13_MARK),
- PINMUX_GPIO(GPIO_FN_IRQ12, IRQ12_MARK),
- PINMUX_GPIO(GPIO_FN_IRQ11, IRQ11_MARK),
- PINMUX_GPIO(GPIO_FN_IRQ10, IRQ10_MARK),
- PINMUX_GPIO(GPIO_FN_IRQ9, IRQ9_MARK),
- PINMUX_GPIO(GPIO_FN_IRQ8, IRQ8_MARK),
+ /* PTI (mobule: LBSC, SDHI) */
+ PINMUX_GPIO(GPIO_FN_D15, D15_MARK),
+ PINMUX_GPIO(GPIO_FN_D14, D14_MARK),
+ PINMUX_GPIO(GPIO_FN_D13, D13_MARK),
+ PINMUX_GPIO(GPIO_FN_D12, D12_MARK),
+ PINMUX_GPIO(GPIO_FN_D11, D11_MARK),
+ PINMUX_GPIO(GPIO_FN_D10, D10_MARK),
+ PINMUX_GPIO(GPIO_FN_D9, D9_MARK),
+ PINMUX_GPIO(GPIO_FN_D8, D8_MARK),
+ PINMUX_GPIO(GPIO_FN_SD_WP, SD_WP_MARK),
+ PINMUX_GPIO(GPIO_FN_SD_CD, SD_CD_MARK),
+ PINMUX_GPIO(GPIO_FN_SD_CLK, SD_CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_SD_CMD, SD_CMD_MARK),
+ PINMUX_GPIO(GPIO_FN_SD_D3, SD_D3_MARK),
+ PINMUX_GPIO(GPIO_FN_SD_D2, SD_D2_MARK),
+ PINMUX_GPIO(GPIO_FN_SD_D1, SD_D1_MARK),
+ PINMUX_GPIO(GPIO_FN_SD_D0, SD_D0_MARK),
/* PTJ (mobule: SCIF234, SERMUX) */
- PINMUX_GPIO(GPIO_FN_RXD3, RXD3_MARK),
+ PINMUX_GPIO(GPIO_FN_RTS3, RTS3_MARK),
+ PINMUX_GPIO(GPIO_FN_CTS3, CTS3_MARK),
PINMUX_GPIO(GPIO_FN_TXD3, TXD3_MARK),
- PINMUX_GPIO(GPIO_FN_RXD2, RXD2_MARK),
- PINMUX_GPIO(GPIO_FN_TXD2, TXD2_MARK),
- PINMUX_GPIO(GPIO_FN_COM1_TXD, COM1_TXD_MARK),
- PINMUX_GPIO(GPIO_FN_COM1_RXD, COM1_RXD_MARK),
- PINMUX_GPIO(GPIO_FN_COM1_RTS, COM1_RTS_MARK),
- PINMUX_GPIO(GPIO_FN_COM1_CTS, COM1_CTS_MARK),
+ PINMUX_GPIO(GPIO_FN_RXD3, RXD3_MARK),
+ PINMUX_GPIO(GPIO_FN_RTS4, RTS4_MARK),
+ PINMUX_GPIO(GPIO_FN_RXD4, RXD4_MARK),
+ PINMUX_GPIO(GPIO_FN_TXD4, TXD4_MARK),
- /* PTK (mobule: SERMUX) */
+ /* PTK (mobule: SERMUX, LBSC, SCIF) */
PINMUX_GPIO(GPIO_FN_COM2_TXD, COM2_TXD_MARK),
PINMUX_GPIO(GPIO_FN_COM2_RXD, COM2_RXD_MARK),
PINMUX_GPIO(GPIO_FN_COM2_RTS, COM2_RTS_MARK),
@@ -1349,62 +1510,65 @@ static struct pinmux_gpio pinmux_gpios[] = {
PINMUX_GPIO(GPIO_FN_COM2_DTR, COM2_DTR_MARK),
PINMUX_GPIO(GPIO_FN_COM2_DSR, COM2_DSR_MARK),
PINMUX_GPIO(GPIO_FN_COM2_DCD, COM2_DCD_MARK),
- PINMUX_GPIO(GPIO_FN_COM2_RI, COM2_RI_MARK),
+ PINMUX_GPIO(GPIO_FN_CLKOUT, CLKOUT_MARK),
+ PINMUX_GPIO(GPIO_FN_SCK2, SCK2_MARK),
+ PINMUX_GPIO(GPIO_FN_SCK4, SCK4_MARK),
+ PINMUX_GPIO(GPIO_FN_SCK3, SCK3_MARK),
- /* PTL (mobule: SERMUX) */
- PINMUX_GPIO(GPIO_FN_RAC_TXD, RAC_TXD_MARK),
+ /* PTL (mobule: SERMUX, SCIF, LBSC, AUD) */
PINMUX_GPIO(GPIO_FN_RAC_RXD, RAC_RXD_MARK),
PINMUX_GPIO(GPIO_FN_RAC_RTS, RAC_RTS_MARK),
PINMUX_GPIO(GPIO_FN_RAC_CTS, RAC_CTS_MARK),
PINMUX_GPIO(GPIO_FN_RAC_DTR, RAC_DTR_MARK),
PINMUX_GPIO(GPIO_FN_RAC_DSR, RAC_DSR_MARK),
PINMUX_GPIO(GPIO_FN_RAC_DCD, RAC_DCD_MARK),
- PINMUX_GPIO(GPIO_FN_RAC_RI, RAC_RI_MARK),
+ PINMUX_GPIO(GPIO_FN_RAC_TXD, RAC_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_RXD2, RXD2_MARK),
+ PINMUX_GPIO(GPIO_FN_CS5, CS5_MARK),
+ PINMUX_GPIO(GPIO_FN_CS6, CS6_MARK),
+ PINMUX_GPIO(GPIO_FN_AUDSYNC, AUDSYNC_MARK),
+ PINMUX_GPIO(GPIO_FN_AUDCK, AUDCK_MARK),
+ PINMUX_GPIO(GPIO_FN_TXD2, TXD2_MARK),
- /* PTM (mobule: IIC, LPC) */
+ /* PTM (mobule: LBSC, IIC) */
+ PINMUX_GPIO(GPIO_FN_CS4, CS4_MARK),
+ PINMUX_GPIO(GPIO_FN_RD, RD_MARK),
+ PINMUX_GPIO(GPIO_FN_WE0, WE0_MARK),
+ PINMUX_GPIO(GPIO_FN_CS0, CS0_MARK),
PINMUX_GPIO(GPIO_FN_SDA6, SDA6_MARK),
PINMUX_GPIO(GPIO_FN_SCL6, SCL6_MARK),
PINMUX_GPIO(GPIO_FN_SDA7, SDA7_MARK),
PINMUX_GPIO(GPIO_FN_SCL7, SCL7_MARK),
- PINMUX_GPIO(GPIO_FN_WP, WP_MARK),
- PINMUX_GPIO(GPIO_FN_FMS0, FMS0_MARK),
- PINMUX_GPIO(GPIO_FN_FMS1, FMS1_MARK),
- /* PTN (mobule: SCIF234, EVC) */
- PINMUX_GPIO(GPIO_FN_SCK2, SCK2_MARK),
- PINMUX_GPIO(GPIO_FN_RTS4, RTS4_MARK),
- PINMUX_GPIO(GPIO_FN_RTS3, RTS3_MARK),
- PINMUX_GPIO(GPIO_FN_RTS2, RTS2_MARK),
- PINMUX_GPIO(GPIO_FN_CTS4, CTS4_MARK),
- PINMUX_GPIO(GPIO_FN_CTS3, CTS3_MARK),
- PINMUX_GPIO(GPIO_FN_CTS2, CTS2_MARK),
- PINMUX_GPIO(GPIO_FN_EVENT7, EVENT7_MARK),
- PINMUX_GPIO(GPIO_FN_EVENT6, EVENT6_MARK),
- PINMUX_GPIO(GPIO_FN_EVENT5, EVENT5_MARK),
- PINMUX_GPIO(GPIO_FN_EVENT4, EVENT4_MARK),
- PINMUX_GPIO(GPIO_FN_EVENT3, EVENT3_MARK),
- PINMUX_GPIO(GPIO_FN_EVENT2, EVENT2_MARK),
- PINMUX_GPIO(GPIO_FN_EVENT1, EVENT1_MARK),
- PINMUX_GPIO(GPIO_FN_EVENT0, EVENT0_MARK),
+ /* PTN (mobule: USB, JMC, SGPIO, WDT) */
+ PINMUX_GPIO(GPIO_FN_VBUS_EN, VBUS_EN_MARK),
+ PINMUX_GPIO(GPIO_FN_VBUS_OC, VBUS_OC_MARK),
+ PINMUX_GPIO(GPIO_FN_JMCTCK, JMCTCK_MARK),
+ PINMUX_GPIO(GPIO_FN_JMCTMS, JMCTMS_MARK),
+ PINMUX_GPIO(GPIO_FN_JMCTDO, JMCTDO_MARK),
+ PINMUX_GPIO(GPIO_FN_JMCTDI, JMCTDI_MARK),
+ PINMUX_GPIO(GPIO_FN_JMCTRST, JMCTRST_MARK),
+ PINMUX_GPIO(GPIO_FN_SGPIO1_CLK, SGPIO1_CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_SGPIO1_LOAD, SGPIO1_LOAD_MARK),
+ PINMUX_GPIO(GPIO_FN_SGPIO1_DI, SGPIO1_DI_MARK),
+ PINMUX_GPIO(GPIO_FN_SGPIO1_DO, SGPIO1_DO_MARK),
+ PINMUX_GPIO(GPIO_FN_SUB_CLKIN, SUB_CLKIN_MARK),
- /* PTO (mobule: SGPIO) */
+ /* PTO (mobule: SGPIO, SerMux) */
PINMUX_GPIO(GPIO_FN_SGPIO0_CLK, SGPIO0_CLK_MARK),
PINMUX_GPIO(GPIO_FN_SGPIO0_LOAD, SGPIO0_LOAD_MARK),
PINMUX_GPIO(GPIO_FN_SGPIO0_DI, SGPIO0_DI_MARK),
PINMUX_GPIO(GPIO_FN_SGPIO0_DO, SGPIO0_DO_MARK),
- PINMUX_GPIO(GPIO_FN_SGPIO1_CLK, SGPIO1_CLK_MARK),
- PINMUX_GPIO(GPIO_FN_SGPIO1_LOAD, SGPIO1_LOAD_MARK),
- PINMUX_GPIO(GPIO_FN_SGPIO1_DI, SGPIO1_DI_MARK),
- PINMUX_GPIO(GPIO_FN_SGPIO1_DO, SGPIO1_DO_MARK),
+ PINMUX_GPIO(GPIO_FN_SGPIO2_CLK, SGPIO2_CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_SGPIO2_LOAD, SGPIO2_LOAD_MARK),
+ PINMUX_GPIO(GPIO_FN_SGPIO2_DI, SGPIO2_DI_MARK),
+ PINMUX_GPIO(GPIO_FN_SGPIO2_DO, SGPIO2_DO_MARK),
+ PINMUX_GPIO(GPIO_FN_COM1_TXD, COM1_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_COM1_RXD, COM1_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_COM1_RTS, COM1_RTS_MARK),
+ PINMUX_GPIO(GPIO_FN_COM1_CTS, COM1_CTS_MARK),
- /* PTP (mobule: JMC, SCIF234) */
- PINMUX_GPIO(GPIO_FN_JMCTCK, JMCTCK_MARK),
- PINMUX_GPIO(GPIO_FN_JMCTMS, JMCTMS_MARK),
- PINMUX_GPIO(GPIO_FN_JMCTDO, JMCTDO_MARK),
- PINMUX_GPIO(GPIO_FN_JMCTDI, JMCTDI_MARK),
- PINMUX_GPIO(GPIO_FN_JMCRST, JMCRST_MARK),
- PINMUX_GPIO(GPIO_FN_SCK4, SCK4_MARK),
- PINMUX_GPIO(GPIO_FN_SCK3, SCK3_MARK),
+ /* PTP (mobule: EVC, ADC) */
/* PTQ (mobule: LPC) */
PINMUX_GPIO(GPIO_FN_LAD3, LAD3_MARK),
@@ -1439,31 +1603,41 @@ static struct pinmux_gpio pinmux_gpios[] = {
PINMUX_GPIO(GPIO_FN_SDA3, SDA3_MARK),
PINMUX_GPIO(GPIO_FN_SCL3, SCL3_MARK),
- /* PTT (mobule: SYSTEM, PWMX) */
- PINMUX_GPIO(GPIO_FN_AUDSYNC, AUDSYNC_MARK),
- PINMUX_GPIO(GPIO_FN_AUDCK, AUDCK_MARK),
+ /* PTT (mobule: PWMX, AUD) */
+ PINMUX_GPIO(GPIO_FN_PWMX7, PWMX7_MARK),
+ PINMUX_GPIO(GPIO_FN_PWMX6, PWMX6_MARK),
+ PINMUX_GPIO(GPIO_FN_PWMX5, PWMX5_MARK),
+ PINMUX_GPIO(GPIO_FN_PWMX4, PWMX4_MARK),
+ PINMUX_GPIO(GPIO_FN_PWMX3, PWMX3_MARK),
+ PINMUX_GPIO(GPIO_FN_PWMX2, PWMX2_MARK),
+ PINMUX_GPIO(GPIO_FN_PWMX1, PWMX1_MARK),
+ PINMUX_GPIO(GPIO_FN_PWMX0, PWMX0_MARK),
PINMUX_GPIO(GPIO_FN_AUDATA3, AUDATA3_MARK),
PINMUX_GPIO(GPIO_FN_AUDATA2, AUDATA2_MARK),
PINMUX_GPIO(GPIO_FN_AUDATA1, AUDATA1_MARK),
PINMUX_GPIO(GPIO_FN_AUDATA0, AUDATA0_MARK),
- PINMUX_GPIO(GPIO_FN_PWX7, PWX7_MARK),
- PINMUX_GPIO(GPIO_FN_PWX6, PWX6_MARK),
- PINMUX_GPIO(GPIO_FN_PWX5, PWX5_MARK),
- PINMUX_GPIO(GPIO_FN_PWX4, PWX4_MARK),
-
- /* PTU (mobule: LBSC, DMAC) */
- PINMUX_GPIO(GPIO_FN_CS6, CS6_MARK),
- PINMUX_GPIO(GPIO_FN_CS5, CS5_MARK),
- PINMUX_GPIO(GPIO_FN_CS4, CS4_MARK),
- PINMUX_GPIO(GPIO_FN_CS0, CS0_MARK),
- PINMUX_GPIO(GPIO_FN_RD, RD_MARK),
- PINMUX_GPIO(GPIO_FN_WE0, WE0_MARK),
- PINMUX_GPIO(GPIO_FN_A25, A25_MARK),
- PINMUX_GPIO(GPIO_FN_A24, A24_MARK),
- PINMUX_GPIO(GPIO_FN_DREQ0, DREQ0_MARK),
- PINMUX_GPIO(GPIO_FN_DACK0, DACK0_MARK),
+ PINMUX_GPIO(GPIO_FN_STATUS1, STATUS1_MARK),
+ PINMUX_GPIO(GPIO_FN_STATUS0, STATUS0_MARK),
- /* PTV (mobule: LBSC, DMAC) */
+ /* PTU (mobule: LPC, APM) */
+ PINMUX_GPIO(GPIO_FN_LGPIO7, LGPIO7_MARK),
+ PINMUX_GPIO(GPIO_FN_LGPIO6, LGPIO6_MARK),
+ PINMUX_GPIO(GPIO_FN_LGPIO5, LGPIO5_MARK),
+ PINMUX_GPIO(GPIO_FN_LGPIO4, LGPIO4_MARK),
+ PINMUX_GPIO(GPIO_FN_LGPIO3, LGPIO3_MARK),
+ PINMUX_GPIO(GPIO_FN_LGPIO2, LGPIO2_MARK),
+ PINMUX_GPIO(GPIO_FN_LGPIO1, LGPIO1_MARK),
+ PINMUX_GPIO(GPIO_FN_LGPIO0, LGPIO0_MARK),
+ PINMUX_GPIO(GPIO_FN_APMONCTL_O, APMONCTL_O_MARK),
+ PINMUX_GPIO(GPIO_FN_APMPWBTOUT_O, APMPWBTOUT_O_MARK),
+ PINMUX_GPIO(GPIO_FN_APMSCI_O, APMSCI_O_MARK),
+ PINMUX_GPIO(GPIO_FN_APMVDDON, APMVDDON_MARK),
+ PINMUX_GPIO(GPIO_FN_APMSLPBTN, APMSLPBTN_MARK),
+ PINMUX_GPIO(GPIO_FN_APMPWRBTN, APMPWRBTN_MARK),
+ PINMUX_GPIO(GPIO_FN_APMS5N, APMS5N_MARK),
+ PINMUX_GPIO(GPIO_FN_APMS3N, APMS3N_MARK),
+
+ /* PTV (mobule: LBSC, SerMux, R-SPI, EVC, GRA) */
PINMUX_GPIO(GPIO_FN_A23, A23_MARK),
PINMUX_GPIO(GPIO_FN_A22, A22_MARK),
PINMUX_GPIO(GPIO_FN_A21, A21_MARK),
@@ -1472,12 +1646,20 @@ static struct pinmux_gpio pinmux_gpios[] = {
PINMUX_GPIO(GPIO_FN_A18, A18_MARK),
PINMUX_GPIO(GPIO_FN_A17, A17_MARK),
PINMUX_GPIO(GPIO_FN_A16, A16_MARK),
- PINMUX_GPIO(GPIO_FN_TEND0, TEND0_MARK),
- PINMUX_GPIO(GPIO_FN_DREQ1, DREQ1_MARK),
- PINMUX_GPIO(GPIO_FN_DACK1, DACK1_MARK),
- PINMUX_GPIO(GPIO_FN_TEND1, TEND1_MARK),
+ PINMUX_GPIO(GPIO_FN_COM2_RI, COM2_RI_MARK),
+ PINMUX_GPIO(GPIO_FN_R_SPI_MOSI, R_SPI_MOSI_MARK),
+ PINMUX_GPIO(GPIO_FN_R_SPI_MISO, R_SPI_MISO_MARK),
+ PINMUX_GPIO(GPIO_FN_R_SPI_RSPCK, R_SPI_RSPCK_MARK),
+ PINMUX_GPIO(GPIO_FN_R_SPI_SSL0, R_SPI_SSL0_MARK),
+ PINMUX_GPIO(GPIO_FN_R_SPI_SSL1, R_SPI_SSL1_MARK),
+ PINMUX_GPIO(GPIO_FN_EVENT7, EVENT7_MARK),
+ PINMUX_GPIO(GPIO_FN_EVENT6, EVENT6_MARK),
+ PINMUX_GPIO(GPIO_FN_VBIOS_DI, VBIOS_DI_MARK),
+ PINMUX_GPIO(GPIO_FN_VBIOS_DO, VBIOS_DO_MARK),
+ PINMUX_GPIO(GPIO_FN_VBIOS_CLK, VBIOS_CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_VBIOS_CS, VBIOS_CS_MARK),
- /* PTW (mobule: LBSC) */
+ /* PTW (mobule: LBSC, EVC, SCIF) */
PINMUX_GPIO(GPIO_FN_A16, A16_MARK),
PINMUX_GPIO(GPIO_FN_A15, A15_MARK),
PINMUX_GPIO(GPIO_FN_A14, A14_MARK),
@@ -1487,6 +1669,14 @@ static struct pinmux_gpio pinmux_gpios[] = {
PINMUX_GPIO(GPIO_FN_A10, A10_MARK),
PINMUX_GPIO(GPIO_FN_A9, A9_MARK),
PINMUX_GPIO(GPIO_FN_A8, A8_MARK),
+ PINMUX_GPIO(GPIO_FN_EVENT5, EVENT5_MARK),
+ PINMUX_GPIO(GPIO_FN_EVENT4, EVENT4_MARK),
+ PINMUX_GPIO(GPIO_FN_EVENT3, EVENT3_MARK),
+ PINMUX_GPIO(GPIO_FN_EVENT2, EVENT2_MARK),
+ PINMUX_GPIO(GPIO_FN_EVENT1, EVENT1_MARK),
+ PINMUX_GPIO(GPIO_FN_EVENT0, EVENT0_MARK),
+ PINMUX_GPIO(GPIO_FN_CTS4, CTS4_MARK),
+ PINMUX_GPIO(GPIO_FN_CTS2, CTS2_MARK),
/* PTX (mobule: LBSC) */
PINMUX_GPIO(GPIO_FN_A7, A7_MARK),
@@ -1497,6 +1687,10 @@ static struct pinmux_gpio pinmux_gpios[] = {
PINMUX_GPIO(GPIO_FN_A2, A2_MARK),
PINMUX_GPIO(GPIO_FN_A1, A1_MARK),
PINMUX_GPIO(GPIO_FN_A0, A0_MARK),
+ PINMUX_GPIO(GPIO_FN_RTS2, RTS2_MARK),
+ PINMUX_GPIO(GPIO_FN_SIM_D, SIM_D_MARK),
+ PINMUX_GPIO(GPIO_FN_SIM_CLK, SIM_CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_SIM_RST, SIM_RST_MARK),
/* PTY (mobule: LBSC) */
PINMUX_GPIO(GPIO_FN_D7, D7_MARK),
@@ -1507,18 +1701,36 @@ static struct pinmux_gpio pinmux_gpios[] = {
PINMUX_GPIO(GPIO_FN_D2, D2_MARK),
PINMUX_GPIO(GPIO_FN_D1, D1_MARK),
PINMUX_GPIO(GPIO_FN_D0, D0_MARK),
+
+ /* PTZ (mobule: eMMC, ONFI) */
+ PINMUX_GPIO(GPIO_FN_MMCDAT7, MMCDAT7_MARK),
+ PINMUX_GPIO(GPIO_FN_MMCDAT6, MMCDAT6_MARK),
+ PINMUX_GPIO(GPIO_FN_MMCDAT5, MMCDAT5_MARK),
+ PINMUX_GPIO(GPIO_FN_MMCDAT4, MMCDAT4_MARK),
+ PINMUX_GPIO(GPIO_FN_MMCDAT3, MMCDAT3_MARK),
+ PINMUX_GPIO(GPIO_FN_MMCDAT2, MMCDAT2_MARK),
+ PINMUX_GPIO(GPIO_FN_MMCDAT1, MMCDAT1_MARK),
+ PINMUX_GPIO(GPIO_FN_MMCDAT0, MMCDAT0_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_DQ7, ON_DQ7_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_DQ6, ON_DQ6_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_DQ5, ON_DQ5_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_DQ4, ON_DQ4_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_DQ3, ON_DQ3_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_DQ2, ON_DQ2_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_DQ1, ON_DQ1_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_DQ0, ON_DQ0_MARK),
};
static struct pinmux_cfg_reg pinmux_config_regs[] = {
{ PINMUX_CFG_REG("PACR", 0xffec0000, 16, 2) {
- PTA7_FN, PTA7_OUT, PTA7_IN, 0,
- PTA6_FN, PTA6_OUT, PTA6_IN, 0,
- PTA5_FN, PTA5_OUT, PTA5_IN, 0,
- PTA4_FN, PTA4_OUT, PTA4_IN, 0,
- PTA3_FN, PTA3_OUT, PTA3_IN, 0,
- PTA2_FN, PTA2_OUT, PTA2_IN, 0,
- PTA1_FN, PTA1_OUT, PTA1_IN, 0,
- PTA0_FN, PTA0_OUT, PTA0_IN, 0 }
+ PTA7_FN, PTA7_OUT, PTA7_IN, PTA7_IN_PU,
+ PTA6_FN, PTA6_OUT, PTA6_IN, PTA6_IN_PU,
+ PTA5_FN, PTA5_OUT, PTA5_IN, PTA5_IN_PU,
+ PTA4_FN, PTA4_OUT, PTA4_IN, PTA4_IN_PU,
+ PTA3_FN, PTA3_OUT, PTA3_IN, PTA3_IN_PU,
+ PTA2_FN, PTA2_OUT, PTA2_IN, PTA2_IN_PU,
+ PTA1_FN, PTA1_OUT, PTA1_IN, PTA1_IN_PU,
+ PTA0_FN, PTA0_OUT, PTA0_IN, PTA0_IN_PU }
},
{ PINMUX_CFG_REG("PBCR", 0xffec0002, 16, 2) {
PTB7_FN, PTB7_OUT, PTB7_IN, 0,
@@ -1541,125 +1753,126 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = {
PTC0_FN, PTC0_OUT, PTC0_IN, 0 }
},
{ PINMUX_CFG_REG("PDCR", 0xffec0006, 16, 2) {
- PTD7_FN, PTD7_OUT, PTD7_IN, 0,
- PTD6_FN, PTD6_OUT, PTD6_IN, 0,
- PTD5_FN, PTD5_OUT, PTD5_IN, 0,
- PTD4_FN, PTD4_OUT, PTD4_IN, 0,
- PTD3_FN, PTD3_OUT, PTD3_IN, 0,
- PTD2_FN, PTD2_OUT, PTD2_IN, 0,
- PTD1_FN, PTD1_OUT, PTD1_IN, 0,
- PTD0_FN, PTD0_OUT, PTD0_IN, 0 }
+ PTD7_FN, PTD7_OUT, PTD7_IN, PTD7_IN_PU,
+ PTD6_FN, PTD6_OUT, PTD6_IN, PTD6_IN_PU,
+ PTD5_FN, PTD5_OUT, PTD5_IN, PTD5_IN_PU,
+ PTD4_FN, PTD4_OUT, PTD4_IN, PTD4_IN_PU,
+ PTD3_FN, PTD3_OUT, PTD3_IN, PTD3_IN_PU,
+ PTD2_FN, PTD2_OUT, PTD2_IN, PTD2_IN_PU,
+ PTD1_FN, PTD1_OUT, PTD1_IN, PTD1_IN_PU,
+ PTD0_FN, PTD0_OUT, PTD0_IN, PTD0_IN_PU }
},
{ PINMUX_CFG_REG("PECR", 0xffec0008, 16, 2) {
- PTE7_FN, PTE7_OUT, PTE7_IN, 0,
- PTE6_FN, PTE6_OUT, PTE6_IN, 0,
- PTE5_FN, PTE5_OUT, PTE5_IN, 0,
- PTE4_FN, PTE4_OUT, PTE4_IN, 0,
- PTE3_FN, PTE3_OUT, PTE3_IN, 0,
- PTE2_FN, PTE2_OUT, PTE2_IN, 0,
- PTE1_FN, PTE1_OUT, PTE1_IN, 0,
- PTE0_FN, PTE0_OUT, PTE0_IN, 0 }
+ PTE7_FN, PTE7_OUT, PTE7_IN, PTE7_IN_PU,
+ PTE6_FN, PTE6_OUT, PTE6_IN, PTE6_IN_PU,
+ PTE5_FN, PTE5_OUT, PTE5_IN, PTE5_IN_PU,
+ PTE4_FN, PTE4_OUT, PTE4_IN, PTE4_IN_PU,
+ PTE3_FN, PTE3_OUT, PTE3_IN, PTE3_IN_PU,
+ PTE2_FN, PTE2_OUT, PTE2_IN, PTE2_IN_PU,
+ PTE1_FN, PTE1_OUT, PTE1_IN, PTE1_IN_PU,
+ PTE0_FN, PTE0_OUT, PTE0_IN, PTE0_IN_PU }
},
{ PINMUX_CFG_REG("PFCR", 0xffec000a, 16, 2) {
- PTF7_FN, PTF7_OUT, PTF7_IN, 0,
- PTF6_FN, PTF6_OUT, PTF6_IN, 0,
- PTF5_FN, PTF5_OUT, PTF5_IN, 0,
- PTF4_FN, PTF4_OUT, PTF4_IN, 0,
- PTF3_FN, PTF3_OUT, PTF3_IN, 0,
- PTF2_FN, PTF2_OUT, PTF2_IN, 0,
- PTF1_FN, PTF1_OUT, PTF1_IN, 0,
- PTF0_FN, PTF0_OUT, PTF0_IN, 0 }
+ PTF7_FN, PTF7_OUT, PTF7_IN, PTF7_IN_PU,
+ PTF6_FN, PTF6_OUT, PTF6_IN, PTF6_IN_PU,
+ PTF5_FN, PTF5_OUT, PTF5_IN, PTF5_IN_PU,
+ PTF4_FN, PTF4_OUT, PTF4_IN, PTF4_IN_PU,
+ PTF3_FN, PTF3_OUT, PTF3_IN, PTF3_IN_PU,
+ PTF2_FN, PTF2_OUT, PTF2_IN, PTF2_IN_PU,
+ PTF1_FN, PTF1_OUT, PTF1_IN, PTF1_IN_PU,
+ PTF0_FN, PTF0_OUT, PTF0_IN, PTF0_IN_PU }
},
{ PINMUX_CFG_REG("PGCR", 0xffec000c, 16, 2) {
- PTG7_FN, PTG7_OUT, PTG7_IN, 0,
- PTG6_FN, PTG6_OUT, PTG6_IN, 0,
+ PTG7_FN, PTG7_OUT, PTG7_IN, PTG7_IN_PU ,
+ PTG6_FN, PTG6_OUT, PTG6_IN, PTG6_IN_PU ,
PTG5_FN, PTG5_OUT, PTG5_IN, 0,
- PTG4_FN, PTG4_OUT, PTG4_IN, 0,
+ PTG4_FN, PTG4_OUT, PTG4_IN, PTG4_IN_PU ,
PTG3_FN, PTG3_OUT, PTG3_IN, 0,
PTG2_FN, PTG2_OUT, PTG2_IN, 0,
PTG1_FN, PTG1_OUT, PTG1_IN, 0,
PTG0_FN, PTG0_OUT, PTG0_IN, 0 }
},
{ PINMUX_CFG_REG("PHCR", 0xffec000e, 16, 2) {
- PTH7_FN, PTH7_OUT, PTH7_IN, 0,
- PTH6_FN, PTH6_OUT, PTH6_IN, 0,
- PTH5_FN, PTH5_OUT, PTH5_IN, 0,
- PTH4_FN, PTH4_OUT, PTH4_IN, 0,
- PTH3_FN, PTH3_OUT, PTH3_IN, 0,
- PTH2_FN, PTH2_OUT, PTH2_IN, 0,
- PTH1_FN, PTH1_OUT, PTH1_IN, 0,
- PTH0_FN, PTH0_OUT, PTH0_IN, 0 }
+ PTH7_FN, PTH7_OUT, PTH7_IN, PTH7_IN_PU,
+ PTH6_FN, PTH6_OUT, PTH6_IN, PTH6_IN_PU,
+ PTH5_FN, PTH5_OUT, PTH5_IN, PTH5_IN_PU,
+ PTH4_FN, PTH4_OUT, PTH4_IN, PTH4_IN_PU,
+ PTH3_FN, PTH3_OUT, PTH3_IN, PTH3_IN_PU,
+ PTH2_FN, PTH2_OUT, PTH2_IN, PTH2_IN_PU,
+ PTH1_FN, PTH1_OUT, PTH1_IN, PTH1_IN_PU,
+ PTH0_FN, PTH0_OUT, PTH0_IN, PTH0_IN_PU }
},
{ PINMUX_CFG_REG("PICR", 0xffec0010, 16, 2) {
- PTI7_FN, PTI7_OUT, PTI7_IN, 0,
- PTI6_FN, PTI6_OUT, PTI6_IN, 0,
+ PTI7_FN, PTI7_OUT, PTI7_IN, PTI7_IN_PU,
+ PTI6_FN, PTI6_OUT, PTI6_IN, PTI6_IN_PU,
PTI5_FN, PTI5_OUT, PTI5_IN, 0,
- PTI4_FN, PTI4_OUT, PTI4_IN, 0,
- PTI3_FN, PTI3_OUT, PTI3_IN, 0,
- PTI2_FN, PTI2_OUT, PTI2_IN, 0,
- PTI1_FN, PTI1_OUT, PTI1_IN, 0,
- PTI0_FN, PTI0_OUT, PTI0_IN, 0 }
+ PTI4_FN, PTI4_OUT, PTI4_IN, PTI4_IN_PU,
+ PTI3_FN, PTI3_OUT, PTI3_IN, PTI3_IN_PU,
+ PTI2_FN, PTI2_OUT, PTI2_IN, PTI2_IN_PU,
+ PTI1_FN, PTI1_OUT, PTI1_IN, PTI1_IN_PU,
+ PTI0_FN, PTI0_OUT, PTI0_IN, PTI0_IN_PU }
},
{ PINMUX_CFG_REG("PJCR", 0xffec0012, 16, 2) {
- PTJ7_FN, PTJ7_OUT, PTJ7_IN, 0,
- PTJ6_FN, PTJ6_OUT, PTJ6_IN, 0,
- PTJ5_FN, PTJ5_OUT, PTJ5_IN, 0,
- PTJ4_FN, PTJ4_OUT, PTJ4_IN, 0,
- PTJ3_FN, PTJ3_OUT, PTJ3_IN, 0,
- PTJ2_FN, PTJ2_OUT, PTJ2_IN, 0,
- PTJ1_FN, PTJ1_OUT, PTJ1_IN, 0,
- PTJ0_FN, PTJ0_OUT, PTJ0_IN, 0 }
+ 0, 0, 0, 0, /* reserved: always set 1 */
+ PTJ6_FN, PTJ6_OUT, PTJ6_IN, PTJ6_IN_PU,
+ PTJ5_FN, PTJ5_OUT, PTJ5_IN, PTJ5_IN_PU,
+ PTJ4_FN, PTJ4_OUT, PTJ4_IN, PTJ4_IN_PU,
+ PTJ3_FN, PTJ3_OUT, PTJ3_IN, PTJ3_IN_PU,
+ PTJ2_FN, PTJ2_OUT, PTJ2_IN, PTJ2_IN_PU,
+ PTJ1_FN, PTJ1_OUT, PTJ1_IN, PTJ1_IN_PU,
+ PTJ0_FN, PTJ0_OUT, PTJ0_IN, PTJ0_IN_PU }
},
{ PINMUX_CFG_REG("PKCR", 0xffec0014, 16, 2) {
- PTK7_FN, PTK7_OUT, PTK7_IN, 0,
- PTK6_FN, PTK6_OUT, PTK6_IN, 0,
- PTK5_FN, PTK5_OUT, PTK5_IN, 0,
- PTK4_FN, PTK4_OUT, PTK4_IN, 0,
- PTK3_FN, PTK3_OUT, PTK3_IN, 0,
- PTK2_FN, PTK2_OUT, PTK2_IN, 0,
- PTK1_FN, PTK1_OUT, PTK1_IN, 0,
- PTK0_FN, PTK0_OUT, PTK0_IN, 0 }
+ PTK7_FN, PTK7_OUT, PTK7_IN, PTK7_IN_PU,
+ PTK6_FN, PTK6_OUT, PTK6_IN, PTK6_IN_PU,
+ PTK5_FN, PTK5_OUT, PTK5_IN, PTK5_IN_PU,
+ PTK4_FN, PTK4_OUT, PTK4_IN, PTK4_IN_PU,
+ PTK3_FN, PTK3_OUT, PTK3_IN, PTK3_IN_PU,
+ PTK2_FN, PTK2_OUT, PTK2_IN, PTK2_IN_PU,
+ PTK1_FN, PTK1_OUT, PTK1_IN, PTK1_IN_PU,
+ PTK0_FN, PTK0_OUT, PTK0_IN, PTK0_IN_PU }
},
{ PINMUX_CFG_REG("PLCR", 0xffec0016, 16, 2) {
- PTL7_FN, PTL7_OUT, PTL7_IN, 0,
- PTL6_FN, PTL6_OUT, PTL6_IN, 0,
- PTL5_FN, PTL5_OUT, PTL5_IN, 0,
- PTL4_FN, PTL4_OUT, PTL4_IN, 0,
- PTL3_FN, PTL3_OUT, PTL3_IN, 0,
- PTL2_FN, PTL2_OUT, PTL2_IN, 0,
- PTL1_FN, PTL1_OUT, PTL1_IN, 0,
- PTL0_FN, PTL0_OUT, PTL0_IN, 0 }
+ 0, 0, 0, 0, /* reserved: always set 1 */
+ PTL6_FN, PTL6_OUT, PTL6_IN, PTL6_IN_PU,
+ PTL5_FN, PTL5_OUT, PTL5_IN, PTL5_IN_PU,
+ PTL4_FN, PTL4_OUT, PTL4_IN, PTL4_IN_PU,
+ PTL3_FN, PTL3_OUT, PTL3_IN, PTL3_IN_PU,
+ PTL2_FN, PTL2_OUT, PTL2_IN, PTL2_IN_PU,
+ PTL1_FN, PTL1_OUT, PTL1_IN, PTL1_IN_PU,
+ PTL0_FN, PTL0_OUT, PTL0_IN, PTL0_IN_PU }
},
{ PINMUX_CFG_REG("PMCR", 0xffec0018, 16, 2) {
- 0, 0, 0, 0, /* reserved: always set 1 */
- PTM6_FN, PTM6_OUT, PTM6_IN, 0,
- PTM5_FN, PTM5_OUT, PTM5_IN, 0,
- PTM4_FN, PTM4_OUT, PTM4_IN, 0,
+ PTM7_FN, PTM7_OUT, PTM7_IN, PTM7_IN_PU,
+ PTM6_FN, PTM6_OUT, PTM6_IN, PTM6_IN_PU,
+ PTM5_FN, PTM5_OUT, PTM5_IN, PTM5_IN_PU,
+ PTM4_FN, PTM4_OUT, PTM4_IN, PTM4_IN_PU,
PTM3_FN, PTM3_OUT, PTM3_IN, 0,
PTM2_FN, PTM2_OUT, PTM2_IN, 0,
PTM1_FN, PTM1_OUT, PTM1_IN, 0,
PTM0_FN, PTM0_OUT, PTM0_IN, 0 }
},
{ PINMUX_CFG_REG("PNCR", 0xffec001a, 16, 2) {
- PTN7_FN, PTN7_OUT, PTN7_IN, 0,
+ 0, 0, 0, 0, /* reserved: always set 1 */
PTN6_FN, PTN6_OUT, PTN6_IN, 0,
PTN5_FN, PTN5_OUT, PTN5_IN, 0,
- PTN4_FN, PTN4_OUT, PTN4_IN, 0,
- PTN3_FN, PTN3_OUT, PTN3_IN, 0,
- PTN2_FN, PTN2_OUT, PTN2_IN, 0,
- PTN1_FN, PTN1_OUT, PTN1_IN, 0,
- PTN0_FN, PTN0_OUT, PTN0_IN, 0 }
+ PTN4_FN, PTN4_OUT, PTN4_IN, PTN4_IN_PU,
+ PTN3_FN, PTN3_OUT, PTN3_IN, PTN3_IN_PU,
+ PTN2_FN, PTN2_OUT, PTN2_IN, PTN2_IN_PU,
+ PTN1_FN, PTN1_OUT, PTN1_IN, PTN1_IN_PU,
+ PTN0_FN, PTN0_OUT, PTN0_IN, PTN0_IN_PU }
},
{ PINMUX_CFG_REG("POCR", 0xffec001c, 16, 2) {
- PTO7_FN, PTO7_OUT, PTO7_IN, 0,
- PTO6_FN, PTO6_OUT, PTO6_IN, 0,
- PTO5_FN, PTO5_OUT, PTO5_IN, 0,
- PTO4_FN, PTO4_OUT, PTO4_IN, 0,
- PTO3_FN, PTO3_OUT, PTO3_IN, 0,
- PTO2_FN, PTO2_OUT, PTO2_IN, 0,
- PTO1_FN, PTO1_OUT, PTO1_IN, 0,
- PTO0_FN, PTO0_OUT, PTO0_IN, 0 }
+ PTO7_FN, PTO7_OUT, PTO7_IN, PTO7_IN_PU,
+ PTO6_FN, PTO6_OUT, PTO6_IN, PTO6_IN_PU,
+ PTO5_FN, PTO5_OUT, PTO5_IN, PTO5_IN_PU,
+ PTO4_FN, PTO4_OUT, PTO4_IN, PTO4_IN_PU,
+ PTO3_FN, PTO3_OUT, PTO3_IN, PTO3_IN_PU,
+ PTO2_FN, PTO2_OUT, PTO2_IN, PTO2_IN_PU,
+ PTO1_FN, PTO1_OUT, PTO1_IN, PTO1_IN_PU,
+ PTO0_FN, PTO0_OUT, PTO0_IN, PTO0_IN_PU }
},
+#if 0 /* FIXME: Remove it? */
{ PINMUX_CFG_REG("PPCR", 0xffec001e, 16, 2) {
0, 0, 0, 0, /* reserved: always set 1 */
PTP6_FN, PTP6_OUT, PTP6_IN, 0,
@@ -1670,6 +1883,7 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = {
PTP1_FN, PTP1_OUT, PTP1_IN, 0,
PTP0_FN, PTP0_OUT, PTP0_IN, 0 }
},
+#endif
{ PINMUX_CFG_REG("PQCR", 0xffec0020, 16, 2) {
0, 0, 0, 0, /* reserved: always set 1 */
PTQ6_FN, PTQ6_OUT, PTQ6_IN, 0,
@@ -1701,14 +1915,14 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = {
PTS0_FN, PTS0_OUT, PTS0_IN, 0 }
},
{ PINMUX_CFG_REG("PTCR", 0xffec0026, 16, 2) {
- 0, 0, 0, 0, /* reserved: always set 1 */
- 0, 0, 0, 0, /* reserved: always set 1 */
- PTT5_FN, PTT5_OUT, PTT5_IN, 0,
- PTT4_FN, PTT4_OUT, PTT4_IN, 0,
- PTT3_FN, PTT3_OUT, PTT3_IN, 0,
- PTT2_FN, PTT2_OUT, PTT2_IN, 0,
- PTT1_FN, PTT1_OUT, PTT1_IN, 0,
- PTT0_FN, PTT0_OUT, PTT0_IN, 0 }
+ PTT7_FN, PTT7_OUT, PTT7_IN, PTO7_IN_PU,
+ PTT6_FN, PTT6_OUT, PTT6_IN, PTO6_IN_PU,
+ PTT5_FN, PTT5_OUT, PTT5_IN, PTO5_IN_PU,
+ PTT4_FN, PTT4_OUT, PTT4_IN, PTO4_IN_PU,
+ PTT3_FN, PTT3_OUT, PTT3_IN, PTO3_IN_PU,
+ PTT2_FN, PTT2_OUT, PTT2_IN, PTO2_IN_PU,
+ PTT1_FN, PTT1_OUT, PTT1_IN, PTO1_IN_PU,
+ PTT0_FN, PTT0_OUT, PTT0_IN, PTO0_IN_PU }
},
{ PINMUX_CFG_REG("PUCR", 0xffec0028, 16, 2) {
PTU7_FN, PTU7_OUT, PTU7_IN, PTU7_IN_PU,
@@ -1727,16 +1941,16 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = {
PTV4_FN, PTV4_OUT, PTV4_IN, PTV4_IN_PU,
PTV3_FN, PTV3_OUT, PTV3_IN, PTV3_IN_PU,
PTV2_FN, PTV2_OUT, PTV2_IN, PTV2_IN_PU,
- PTV1_FN, PTV1_OUT, PTV1_IN, PTV1_IN_PU,
- PTV0_FN, PTV0_OUT, PTV0_IN, PTV0_IN_PU }
+ PTV1_FN, PTV1_OUT, PTV1_IN, 0,
+ PTV0_FN, PTV0_OUT, PTV0_IN, 0 }
},
{ PINMUX_CFG_REG("PWCR", 0xffec002c, 16, 2) {
- PTW7_FN, PTW7_OUT, PTW7_IN, PTW7_IN_PU,
- PTW6_FN, PTW6_OUT, PTW6_IN, PTW6_IN_PU,
- PTW5_FN, PTW5_OUT, PTW5_IN, PTW5_IN_PU,
- PTW4_FN, PTW4_OUT, PTW4_IN, PTW4_IN_PU,
- PTW3_FN, PTW3_OUT, PTW3_IN, PTW3_IN_PU,
- PTW2_FN, PTW2_OUT, PTW2_IN, PTW2_IN_PU,
+ PTW7_FN, PTW7_OUT, PTW7_IN, 0,
+ PTW6_FN, PTW6_OUT, PTW6_IN, 0,
+ PTW5_FN, PTW5_OUT, PTW5_IN, 0,
+ PTW4_FN, PTW4_OUT, PTW4_IN, 0,
+ PTW3_FN, PTW3_OUT, PTW3_IN, 0,
+ PTW2_FN, PTW2_OUT, PTW2_IN, 0,
PTW1_FN, PTW1_OUT, PTW1_IN, PTW1_IN_PU,
PTW0_FN, PTW0_OUT, PTW0_IN, PTW0_IN_PU }
},
@@ -1761,32 +1975,32 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = {
PTY0_FN, PTY0_OUT, PTY0_IN, PTY0_IN_PU }
},
{ PINMUX_CFG_REG("PZCR", 0xffec0032, 16, 2) {
- 0, PTZ7_OUT, PTZ7_IN, 0,
- 0, PTZ6_OUT, PTZ6_IN, 0,
- 0, PTZ5_OUT, PTZ5_IN, 0,
- 0, PTZ4_OUT, PTZ4_IN, 0,
- 0, PTZ3_OUT, PTZ3_IN, 0,
- 0, PTZ2_OUT, PTZ2_IN, 0,
- 0, PTZ1_OUT, PTZ1_IN, 0,
- 0, PTZ0_OUT, PTZ0_IN, 0 }
+ PTZ7_FN, PTZ7_OUT, PTZ7_IN, 0,
+ PTZ6_FN, PTZ6_OUT, PTZ6_IN, 0,
+ PTZ5_FN, PTZ5_OUT, PTZ5_IN, 0,
+ PTZ4_FN, PTZ4_OUT, PTZ4_IN, 0,
+ PTZ3_FN, PTZ3_OUT, PTZ3_IN, 0,
+ PTZ2_FN, PTZ2_OUT, PTZ2_IN, 0,
+ PTZ1_FN, PTZ1_OUT, PTZ1_IN, 0,
+ PTZ0_FN, PTZ0_OUT, PTZ0_IN, 0 }
},
{ PINMUX_CFG_REG("PSEL0", 0xffec0070, 16, 1) {
- PS0_15_FN3, PS0_15_FN1,
- PS0_14_FN3, PS0_14_FN1,
- PS0_13_FN3, PS0_13_FN1,
- PS0_12_FN3, PS0_12_FN1,
- 0, 0,
- 0, 0,
+ PS0_15_FN1, PS0_15_FN2,
+ PS0_14_FN1, PS0_14_FN2,
+ PS0_13_FN1, PS0_13_FN2,
+ PS0_12_FN1, PS0_12_FN2,
+ PS0_11_FN1, PS0_11_FN2,
+ PS0_10_FN1, PS0_10_FN2,
+ PS0_9_FN1, PS0_9_FN2,
+ PS0_8_FN1, PS0_8_FN2,
+ PS0_7_FN1, PS0_7_FN2,
+ PS0_6_FN1, PS0_6_FN2,
+ PS0_5_FN1, PS0_5_FN2,
+ PS0_4_FN1, PS0_4_FN2,
+ PS0_3_FN1, PS0_3_FN2,
+ PS0_2_FN1, PS0_2_FN2,
0, 0,
- 0, 0,
- PS0_7_FN2, PS0_7_FN1,
- PS0_6_FN2, PS0_6_FN1,
- PS0_5_FN2, PS0_5_FN1,
- PS0_4_FN2, PS0_4_FN1,
- PS0_3_FN2, PS0_3_FN1,
- PS0_2_FN2, PS0_2_FN1,
- PS0_1_FN2, PS0_1_FN1,
0, 0, }
},
{ PINMUX_CFG_REG("PSEL1", 0xffec0072, 16, 1) {
@@ -1795,73 +2009,136 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = {
0, 0,
0, 0,
0, 0,
+ PS1_10_FN1, PS1_10_FN2,
+ PS1_9_FN1, PS1_9_FN2,
+ PS1_8_FN1, PS1_8_FN2,
0, 0,
0, 0,
0, 0,
- PS1_7_FN1, PS1_7_FN3,
- PS1_6_FN1, PS1_6_FN3,
- 0, 0,
- 0, 0,
0, 0,
0, 0,
+ PS1_2_FN1, PS1_2_FN2,
0, 0,
0, 0, }
},
{ PINMUX_CFG_REG("PSEL2", 0xffec0074, 16, 1) {
0, 0,
0, 0,
- PS2_13_FN3, PS2_13_FN1,
- PS2_12_FN3, PS2_12_FN1,
+ PS2_13_FN1, PS2_13_FN2,
+ PS2_12_FN1, PS2_12_FN2,
0, 0,
0, 0,
0, 0,
0, 0,
+ PS2_7_FN1, PS2_7_FN2,
+ PS2_6_FN1, PS2_6_FN2,
+ PS2_5_FN1, PS2_5_FN2,
+ PS2_4_FN1, PS2_4_FN2,
0, 0,
+ PS2_2_FN1, PS2_2_FN2,
0, 0,
+ 0, 0, }
+ },
+ { PINMUX_CFG_REG("PSEL3", 0xffec0076, 16, 1) {
+ PS3_15_FN1, PS3_15_FN2,
+ PS3_14_FN1, PS3_14_FN2,
+ PS3_13_FN1, PS3_13_FN2,
+ PS3_12_FN1, PS3_12_FN2,
+ PS3_11_FN1, PS3_11_FN2,
+ PS3_10_FN1, PS3_10_FN2,
+ PS3_9_FN1, PS3_9_FN2,
+ PS3_8_FN1, PS3_8_FN2,
+ PS3_7_FN1, PS3_7_FN2,
0, 0,
0, 0,
0, 0,
0, 0,
- PS2_1_FN1, PS2_1_FN2,
- PS2_0_FN1, PS2_0_FN2, }
+ PS3_2_FN1, PS3_2_FN2,
+ PS3_1_FN1, PS3_1_FN2,
+ 0, 0, }
},
+
{ PINMUX_CFG_REG("PSEL4", 0xffec0078, 16, 1) {
- PS4_15_FN2, PS4_15_FN1,
- PS4_14_FN2, PS4_14_FN1,
- PS4_13_FN2, PS4_13_FN1,
- PS4_12_FN2, PS4_12_FN1,
- PS4_11_FN2, PS4_11_FN1,
- PS4_10_FN2, PS4_10_FN1,
- PS4_9_FN2, PS4_9_FN1,
0, 0,
+ PS4_14_FN1, PS4_14_FN2,
+ PS4_13_FN1, PS4_13_FN2,
+ PS4_12_FN1, PS4_12_FN2,
0, 0,
+ PS4_10_FN1, PS4_10_FN2,
+ PS4_9_FN1, PS4_9_FN2,
+ PS4_8_FN1, PS4_8_FN2,
0, 0,
0, 0,
0, 0,
- PS4_3_FN2, PS4_3_FN1,
- PS4_2_FN2, PS4_2_FN1,
- PS4_1_FN2, PS4_1_FN1,
- PS4_0_FN2, PS4_0_FN1, }
+ PS4_4_FN1, PS4_4_FN2,
+ PS4_3_FN1, PS4_3_FN2,
+ PS4_2_FN1, PS4_2_FN2,
+ PS4_1_FN1, PS4_1_FN2,
+ PS4_0_FN1, PS4_0_FN2, }
},
{ PINMUX_CFG_REG("PSEL5", 0xffec007a, 16, 1) {
0, 0,
0, 0,
0, 0,
0, 0,
- 0, 0,
- 0, 0,
+ PS5_11_FN1, PS5_11_FN2,
+ PS5_10_FN1, PS5_10_FN2,
PS5_9_FN1, PS5_9_FN2,
PS5_8_FN1, PS5_8_FN2,
PS5_7_FN1, PS5_7_FN2,
PS5_6_FN1, PS5_6_FN2,
PS5_5_FN1, PS5_5_FN2,
+ PS5_4_FN1, PS5_4_FN2,
+ PS5_3_FN1, PS5_3_FN2,
+ PS5_2_FN1, PS5_2_FN2,
+ 0, 0,
+ 0, 0, }
+ },
+ { PINMUX_CFG_REG("PSEL6", 0xffec007c, 16, 1) {
+ PS6_15_FN1, PS6_15_FN2,
+ PS6_14_FN1, PS6_14_FN2,
+ PS6_13_FN1, PS6_13_FN2,
+ PS6_12_FN1, PS6_12_FN2,
+ PS6_11_FN1, PS6_11_FN2,
+ PS6_10_FN1, PS6_10_FN2,
+ PS6_9_FN1, PS6_9_FN2,
+ PS6_8_FN1, PS6_8_FN2,
+ PS6_7_FN1, PS6_7_FN2,
+ PS6_6_FN1, PS6_6_FN2,
+ PS6_5_FN1, PS6_5_FN2,
+ PS6_4_FN1, PS6_4_FN2,
+ PS6_3_FN1, PS6_3_FN2,
+ PS6_2_FN1, PS6_2_FN2,
+ PS6_1_FN1, PS6_1_FN2,
+ PS6_0_FN1, PS6_0_FN2, }
+ },
+ { PINMUX_CFG_REG("PSEL7", 0xffec0082, 16, 1) {
+ PS7_15_FN1, PS7_15_FN2,
+ PS7_14_FN1, PS7_14_FN2,
+ PS7_13_FN1, PS7_13_FN2,
+ PS7_12_FN1, PS7_12_FN2,
+ PS7_11_FN1, PS7_11_FN2,
+ PS7_10_FN1, PS7_10_FN2,
+ PS7_9_FN1, PS7_9_FN2,
+ PS7_8_FN1, PS7_8_FN2,
+ PS7_7_FN1, PS7_7_FN2,
+ PS7_6_FN1, PS7_6_FN2,
+ PS7_5_FN1, PS7_5_FN2,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0, }
},
- { PINMUX_CFG_REG("PSEL6", 0xffec007c, 16, 1) {
+ { PINMUX_CFG_REG("PSEL8", 0xffec0084, 16, 1) {
+ PS8_15_FN1, PS8_15_FN2,
+ PS8_14_FN1, PS8_14_FN2,
+ PS8_13_FN1, PS8_13_FN2,
+ PS8_12_FN1, PS8_12_FN2,
+ PS8_11_FN1, PS8_11_FN2,
+ PS8_10_FN1, PS8_10_FN2,
+ PS8_9_FN1, PS8_9_FN2,
+ PS8_8_FN1, PS8_8_FN2,
0, 0,
0, 0,
0, 0,
@@ -1869,15 +2146,7 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = {
0, 0,
0, 0,
0, 0,
- 0, 0,
- PS6_7_FN_AN, PS6_7_FN_EV,
- PS6_6_FN_AN, PS6_6_FN_EV,
- PS6_5_FN_AN, PS6_5_FN_EV,
- PS6_4_FN_AN, PS6_4_FN_EV,
- PS6_3_FN_AN, PS6_3_FN_EV,
- PS6_2_FN_AN, PS6_2_FN_EV,
- PS6_1_FN_AN, PS6_1_FN_EV,
- PS6_0_FN_AN, PS6_0_FN_EV, }
+ 0, 0, }
},
{}
};
@@ -1920,7 +2189,7 @@ static struct pinmux_data_reg pinmux_data_regs[] = {
PTI3_DATA, PTI2_DATA, PTI1_DATA, PTI0_DATA }
},
{ PINMUX_DATA_REG("PJDR", 0xffec0046, 8) {
- PTJ7_DATA, PTJ6_DATA, PTJ5_DATA, PTJ4_DATA,
+ 0, PTJ6_DATA, PTJ5_DATA, PTJ4_DATA,
PTJ3_DATA, PTJ2_DATA, PTJ1_DATA, PTJ0_DATA }
},
{ PINMUX_DATA_REG("PKDR", 0xffec0048, 8) {
@@ -1928,15 +2197,15 @@ static struct pinmux_data_reg pinmux_data_regs[] = {
PTK3_DATA, PTK2_DATA, PTK1_DATA, PTK0_DATA }
},
{ PINMUX_DATA_REG("PLDR", 0xffec004a, 8) {
- PTL7_DATA, PTL6_DATA, PTL5_DATA, PTL4_DATA,
+ 0, PTL6_DATA, PTL5_DATA, PTL4_DATA,
PTL3_DATA, PTL2_DATA, PTL1_DATA, PTL0_DATA }
},
{ PINMUX_DATA_REG("PMDR", 0xffec004c, 8) {
- 0, PTM6_DATA, PTM5_DATA, PTM4_DATA,
+ PTM7_DATA, PTM6_DATA, PTM5_DATA, PTM4_DATA,
PTM3_DATA, PTM2_DATA, PTM1_DATA, PTM0_DATA }
},
{ PINMUX_DATA_REG("PNDR", 0xffec004e, 8) {
- PTN7_DATA, PTN6_DATA, PTN5_DATA, PTN4_DATA,
+ 0, PTN6_DATA, PTN5_DATA, PTN4_DATA,
PTN3_DATA, PTN2_DATA, PTN1_DATA, PTN0_DATA }
},
{ PINMUX_DATA_REG("PODR", 0xffec0050, 8) {
@@ -1944,7 +2213,7 @@ static struct pinmux_data_reg pinmux_data_regs[] = {
PTO3_DATA, PTO2_DATA, PTO1_DATA, PTO0_DATA }
},
{ PINMUX_DATA_REG("PPDR", 0xffec0052, 8) {
- 0, PTP6_DATA, PTP5_DATA, PTP4_DATA,
+ PTP7_DATA, PTP6_DATA, PTP5_DATA, PTP4_DATA,
PTP3_DATA, PTP2_DATA, PTP1_DATA, PTP0_DATA }
},
{ PINMUX_DATA_REG("PQDR", 0xffec0054, 8) {
@@ -1960,7 +2229,7 @@ static struct pinmux_data_reg pinmux_data_regs[] = {
PTS3_DATA, PTS2_DATA, PTS1_DATA, PTS0_DATA }
},
{ PINMUX_DATA_REG("PTDR", 0xffec005a, 8) {
- 0, 0, PTT5_DATA, PTT4_DATA,
+ PTT7_DATA, PTT6_DATA, PTT5_DATA, PTT4_DATA,
PTT3_DATA, PTT2_DATA, PTT1_DATA, PTT0_DATA }
},
{ PINMUX_DATA_REG("PUDR", 0xffec005c, 8) {
@@ -2000,8 +2269,8 @@ static struct pinmux_info sh7757_pinmux_info = {
.mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END },
.function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
- .first_gpio = GPIO_PTA7,
- .last_gpio = GPIO_FN_D0,
+ .first_gpio = GPIO_PTA0,
+ .last_gpio = GPIO_FN_ON_DQ0,
.gpios = pinmux_gpios,
.cfg_regs = pinmux_config_regs,
@@ -2015,5 +2284,4 @@ static int __init plat_pinmux_setup(void)
{
return register_pinmux(&sh7757_pinmux_info);
}
-
arch_initcall(plat_pinmux_setup);
diff --git a/arch/sh/kernel/cpu/sh4a/pinmux-shx3.c b/arch/sh/kernel/cpu/sh4a/pinmux-shx3.c
new file mode 100644
index 000000000000..aaa5338abbff
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/pinmux-shx3.c
@@ -0,0 +1,587 @@
+/*
+ * SH-X3 prototype CPU pinmux
+ *
+ * Copyright (C) 2010 Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <cpu/shx3.h>
+
+enum {
+ PINMUX_RESERVED = 0,
+
+ PINMUX_DATA_BEGIN,
+ PA7_DATA, PA6_DATA, PA5_DATA, PA4_DATA,
+ PA3_DATA, PA2_DATA, PA1_DATA, PA0_DATA,
+ PB7_DATA, PB6_DATA, PB5_DATA, PB4_DATA,
+ PB3_DATA, PB2_DATA, PB1_DATA, PB0_DATA,
+ PC7_DATA, PC6_DATA, PC5_DATA, PC4_DATA,
+ PC3_DATA, PC2_DATA, PC1_DATA, PC0_DATA,
+ PD7_DATA, PD6_DATA, PD5_DATA, PD4_DATA,
+ PD3_DATA, PD2_DATA, PD1_DATA, PD0_DATA,
+ PE7_DATA, PE6_DATA, PE5_DATA, PE4_DATA,
+ PE3_DATA, PE2_DATA, PE1_DATA, PE0_DATA,
+ PF7_DATA, PF6_DATA, PF5_DATA, PF4_DATA,
+ PF3_DATA, PF2_DATA, PF1_DATA, PF0_DATA,
+ PG7_DATA, PG6_DATA, PG5_DATA, PG4_DATA,
+ PG3_DATA, PG2_DATA, PG1_DATA, PG0_DATA,
+
+ PH5_DATA, PH4_DATA,
+ PH3_DATA, PH2_DATA, PH1_DATA, PH0_DATA,
+ PINMUX_DATA_END,
+
+ PINMUX_INPUT_BEGIN,
+ PA7_IN, PA6_IN, PA5_IN, PA4_IN,
+ PA3_IN, PA2_IN, PA1_IN, PA0_IN,
+ PB7_IN, PB6_IN, PB5_IN, PB4_IN,
+ PB3_IN, PB2_IN, PB1_IN, PB0_IN,
+ PC7_IN, PC6_IN, PC5_IN, PC4_IN,
+ PC3_IN, PC2_IN, PC1_IN, PC0_IN,
+ PD7_IN, PD6_IN, PD5_IN, PD4_IN,
+ PD3_IN, PD2_IN, PD1_IN, PD0_IN,
+ PE7_IN, PE6_IN, PE5_IN, PE4_IN,
+ PE3_IN, PE2_IN, PE1_IN, PE0_IN,
+ PF7_IN, PF6_IN, PF5_IN, PF4_IN,
+ PF3_IN, PF2_IN, PF1_IN, PF0_IN,
+ PG7_IN, PG6_IN, PG5_IN, PG4_IN,
+ PG3_IN, PG2_IN, PG1_IN, PG0_IN,
+
+ PH5_IN, PH4_IN,
+ PH3_IN, PH2_IN, PH1_IN, PH0_IN,
+ PINMUX_INPUT_END,
+
+ PINMUX_INPUT_PULLUP_BEGIN,
+ PA7_IN_PU, PA6_IN_PU, PA5_IN_PU, PA4_IN_PU,
+ PA3_IN_PU, PA2_IN_PU, PA1_IN_PU, PA0_IN_PU,
+ PB7_IN_PU, PB6_IN_PU, PB5_IN_PU, PB4_IN_PU,
+ PB3_IN_PU, PB2_IN_PU, PB1_IN_PU, PB0_IN_PU,
+ PC7_IN_PU, PC6_IN_PU, PC5_IN_PU, PC4_IN_PU,
+ PC3_IN_PU, PC2_IN_PU, PC1_IN_PU, PC0_IN_PU,
+ PD7_IN_PU, PD6_IN_PU, PD5_IN_PU, PD4_IN_PU,
+ PD3_IN_PU, PD2_IN_PU, PD1_IN_PU, PD0_IN_PU,
+ PE7_IN_PU, PE6_IN_PU, PE5_IN_PU, PE4_IN_PU,
+ PE3_IN_PU, PE2_IN_PU, PE1_IN_PU, PE0_IN_PU,
+ PF7_IN_PU, PF6_IN_PU, PF5_IN_PU, PF4_IN_PU,
+ PF3_IN_PU, PF2_IN_PU, PF1_IN_PU, PF0_IN_PU,
+ PG7_IN_PU, PG6_IN_PU, PG5_IN_PU, PG4_IN_PU,
+ PG3_IN_PU, PG2_IN_PU, PG1_IN_PU, PG0_IN_PU,
+
+ PH5_IN_PU, PH4_IN_PU,
+ PH3_IN_PU, PH2_IN_PU, PH1_IN_PU, PH0_IN_PU,
+ PINMUX_INPUT_PULLUP_END,
+
+ PINMUX_OUTPUT_BEGIN,
+ PA7_OUT, PA6_OUT, PA5_OUT, PA4_OUT,
+ PA3_OUT, PA2_OUT, PA1_OUT, PA0_OUT,
+ PB7_OUT, PB6_OUT, PB5_OUT, PB4_OUT,
+ PB3_OUT, PB2_OUT, PB1_OUT, PB0_OUT,
+ PC7_OUT, PC6_OUT, PC5_OUT, PC4_OUT,
+ PC3_OUT, PC2_OUT, PC1_OUT, PC0_OUT,
+ PD7_OUT, PD6_OUT, PD5_OUT, PD4_OUT,
+ PD3_OUT, PD2_OUT, PD1_OUT, PD0_OUT,
+ PE7_OUT, PE6_OUT, PE5_OUT, PE4_OUT,
+ PE3_OUT, PE2_OUT, PE1_OUT, PE0_OUT,
+ PF7_OUT, PF6_OUT, PF5_OUT, PF4_OUT,
+ PF3_OUT, PF2_OUT, PF1_OUT, PF0_OUT,
+ PG7_OUT, PG6_OUT, PG5_OUT, PG4_OUT,
+ PG3_OUT, PG2_OUT, PG1_OUT, PG0_OUT,
+
+ PH5_OUT, PH4_OUT,
+ PH3_OUT, PH2_OUT, PH1_OUT, PH0_OUT,
+ PINMUX_OUTPUT_END,
+
+ PINMUX_FUNCTION_BEGIN,
+ PA7_FN, PA6_FN, PA5_FN, PA4_FN,
+ PA3_FN, PA2_FN, PA1_FN, PA0_FN,
+ PB7_FN, PB6_FN, PB5_FN, PB4_FN,
+ PB3_FN, PB2_FN, PB1_FN, PB0_FN,
+ PC7_FN, PC6_FN, PC5_FN, PC4_FN,
+ PC3_FN, PC2_FN, PC1_FN, PC0_FN,
+ PD7_FN, PD6_FN, PD5_FN, PD4_FN,
+ PD3_FN, PD2_FN, PD1_FN, PD0_FN,
+ PE7_FN, PE6_FN, PE5_FN, PE4_FN,
+ PE3_FN, PE2_FN, PE1_FN, PE0_FN,
+ PF7_FN, PF6_FN, PF5_FN, PF4_FN,
+ PF3_FN, PF2_FN, PF1_FN, PF0_FN,
+ PG7_FN, PG6_FN, PG5_FN, PG4_FN,
+ PG3_FN, PG2_FN, PG1_FN, PG0_FN,
+
+ PH5_FN, PH4_FN,
+ PH3_FN, PH2_FN, PH1_FN, PH0_FN,
+ PINMUX_FUNCTION_END,
+
+ PINMUX_MARK_BEGIN,
+
+ D31_MARK, D30_MARK, D29_MARK, D28_MARK, D27_MARK, D26_MARK,
+ D25_MARK, D24_MARK, D23_MARK, D22_MARK, D21_MARK, D20_MARK,
+ D19_MARK, D18_MARK, D17_MARK, D16_MARK,
+
+ BACK_MARK, BREQ_MARK,
+ WE3_MARK, WE2_MARK,
+ CS6_MARK, CS5_MARK, CS4_MARK,
+ CLKOUTENB_MARK,
+
+ DACK3_MARK, DACK2_MARK, DACK1_MARK, DACK0_MARK,
+ DREQ3_MARK, DREQ2_MARK, DREQ1_MARK, DREQ0_MARK,
+
+ IRQ3_MARK, IRQ2_MARK, IRQ1_MARK, IRQ0_MARK,
+
+ DRAK3_MARK, DRAK2_MARK, DRAK1_MARK, DRAK0_MARK,
+
+ SCK3_MARK, SCK2_MARK, SCK1_MARK, SCK0_MARK,
+ IRL3_MARK, IRL2_MARK, IRL1_MARK, IRL0_MARK,
+ TXD3_MARK, TXD2_MARK, TXD1_MARK, TXD0_MARK,
+ RXD3_MARK, RXD2_MARK, RXD1_MARK, RXD0_MARK,
+
+ CE2B_MARK, CE2A_MARK, IOIS16_MARK,
+ STATUS1_MARK, STATUS0_MARK,
+
+ IRQOUT_MARK,
+
+ PINMUX_MARK_END,
+};
+
+static pinmux_enum_t shx3_pinmux_data[] = {
+
+ /* PA GPIO */
+ PINMUX_DATA(PA7_DATA, PA7_IN, PA7_OUT, PA7_IN_PU),
+ PINMUX_DATA(PA6_DATA, PA6_IN, PA6_OUT, PA6_IN_PU),
+ PINMUX_DATA(PA5_DATA, PA5_IN, PA5_OUT, PA5_IN_PU),
+ PINMUX_DATA(PA4_DATA, PA4_IN, PA4_OUT, PA4_IN_PU),
+ PINMUX_DATA(PA3_DATA, PA3_IN, PA3_OUT, PA3_IN_PU),
+ PINMUX_DATA(PA2_DATA, PA2_IN, PA2_OUT, PA2_IN_PU),
+ PINMUX_DATA(PA1_DATA, PA1_IN, PA1_OUT, PA1_IN_PU),
+ PINMUX_DATA(PA0_DATA, PA0_IN, PA0_OUT, PA0_IN_PU),
+
+ /* PB GPIO */
+ PINMUX_DATA(PB7_DATA, PB7_IN, PB7_OUT, PB7_IN_PU),
+ PINMUX_DATA(PB6_DATA, PB6_IN, PB6_OUT, PB6_IN_PU),
+ PINMUX_DATA(PB5_DATA, PB5_IN, PB5_OUT, PB5_IN_PU),
+ PINMUX_DATA(PB4_DATA, PB4_IN, PB4_OUT, PB4_IN_PU),
+ PINMUX_DATA(PB3_DATA, PB3_IN, PB3_OUT, PB3_IN_PU),
+ PINMUX_DATA(PB2_DATA, PB2_IN, PB2_OUT, PB2_IN_PU),
+ PINMUX_DATA(PB1_DATA, PB1_IN, PB1_OUT, PB1_IN_PU),
+ PINMUX_DATA(PB0_DATA, PB0_IN, PB0_OUT, PB0_IN_PU),
+
+ /* PC GPIO */
+ PINMUX_DATA(PC7_DATA, PC7_IN, PC7_OUT, PC7_IN_PU),
+ PINMUX_DATA(PC6_DATA, PC6_IN, PC6_OUT, PC6_IN_PU),
+ PINMUX_DATA(PC5_DATA, PC5_IN, PC5_OUT, PC5_IN_PU),
+ PINMUX_DATA(PC4_DATA, PC4_IN, PC4_OUT, PC4_IN_PU),
+ PINMUX_DATA(PC3_DATA, PC3_IN, PC3_OUT, PC3_IN_PU),
+ PINMUX_DATA(PC2_DATA, PC2_IN, PC2_OUT, PC2_IN_PU),
+ PINMUX_DATA(PC1_DATA, PC1_IN, PC1_OUT, PC1_IN_PU),
+ PINMUX_DATA(PC0_DATA, PC0_IN, PC0_OUT, PC0_IN_PU),
+
+ /* PD GPIO */
+ PINMUX_DATA(PD7_DATA, PD7_IN, PD7_OUT, PD7_IN_PU),
+ PINMUX_DATA(PD6_DATA, PD6_IN, PD6_OUT, PD6_IN_PU),
+ PINMUX_DATA(PD5_DATA, PD5_IN, PD5_OUT, PD5_IN_PU),
+ PINMUX_DATA(PD4_DATA, PD4_IN, PD4_OUT, PD4_IN_PU),
+ PINMUX_DATA(PD3_DATA, PD3_IN, PD3_OUT, PD3_IN_PU),
+ PINMUX_DATA(PD2_DATA, PD2_IN, PD2_OUT, PD2_IN_PU),
+ PINMUX_DATA(PD1_DATA, PD1_IN, PD1_OUT, PD1_IN_PU),
+ PINMUX_DATA(PD0_DATA, PD0_IN, PD0_OUT, PD0_IN_PU),
+
+ /* PE GPIO */
+ PINMUX_DATA(PE7_DATA, PE7_IN, PE7_OUT, PE7_IN_PU),
+ PINMUX_DATA(PE6_DATA, PE6_IN, PE6_OUT, PE6_IN_PU),
+ PINMUX_DATA(PE5_DATA, PE5_IN, PE5_OUT, PE5_IN_PU),
+ PINMUX_DATA(PE4_DATA, PE4_IN, PE4_OUT, PE4_IN_PU),
+ PINMUX_DATA(PE3_DATA, PE3_IN, PE3_OUT, PE3_IN_PU),
+ PINMUX_DATA(PE2_DATA, PE2_IN, PE2_OUT, PE2_IN_PU),
+ PINMUX_DATA(PE1_DATA, PE1_IN, PE1_OUT, PE1_IN_PU),
+ PINMUX_DATA(PE0_DATA, PE0_IN, PE0_OUT, PE0_IN_PU),
+
+ /* PF GPIO */
+ PINMUX_DATA(PF7_DATA, PF7_IN, PF7_OUT, PF7_IN_PU),
+ PINMUX_DATA(PF6_DATA, PF6_IN, PF6_OUT, PF6_IN_PU),
+ PINMUX_DATA(PF5_DATA, PF5_IN, PF5_OUT, PF5_IN_PU),
+ PINMUX_DATA(PF4_DATA, PF4_IN, PF4_OUT, PF4_IN_PU),
+ PINMUX_DATA(PF3_DATA, PF3_IN, PF3_OUT, PF3_IN_PU),
+ PINMUX_DATA(PF2_DATA, PF2_IN, PF2_OUT, PF2_IN_PU),
+ PINMUX_DATA(PF1_DATA, PF1_IN, PF1_OUT, PF1_IN_PU),
+ PINMUX_DATA(PF0_DATA, PF0_IN, PF0_OUT, PF0_IN_PU),
+
+ /* PG GPIO */
+ PINMUX_DATA(PG7_DATA, PG7_IN, PG7_OUT, PG7_IN_PU),
+ PINMUX_DATA(PG6_DATA, PG6_IN, PG6_OUT, PG6_IN_PU),
+ PINMUX_DATA(PG5_DATA, PG5_IN, PG5_OUT, PG5_IN_PU),
+ PINMUX_DATA(PG4_DATA, PG4_IN, PG4_OUT, PG4_IN_PU),
+ PINMUX_DATA(PG3_DATA, PG3_IN, PG3_OUT, PG3_IN_PU),
+ PINMUX_DATA(PG2_DATA, PG2_IN, PG2_OUT, PG2_IN_PU),
+ PINMUX_DATA(PG1_DATA, PG1_IN, PG1_OUT, PG1_IN_PU),
+ PINMUX_DATA(PG0_DATA, PG0_IN, PG0_OUT, PG0_IN_PU),
+
+ /* PH GPIO */
+ PINMUX_DATA(PH5_DATA, PH5_IN, PH5_OUT, PH5_IN_PU),
+ PINMUX_DATA(PH4_DATA, PH4_IN, PH4_OUT, PH4_IN_PU),
+ PINMUX_DATA(PH3_DATA, PH3_IN, PH3_OUT, PH3_IN_PU),
+ PINMUX_DATA(PH2_DATA, PH2_IN, PH2_OUT, PH2_IN_PU),
+ PINMUX_DATA(PH1_DATA, PH1_IN, PH1_OUT, PH1_IN_PU),
+ PINMUX_DATA(PH0_DATA, PH0_IN, PH0_OUT, PH0_IN_PU),
+
+ /* PA FN */
+ PINMUX_DATA(D31_MARK, PA7_FN),
+ PINMUX_DATA(D30_MARK, PA6_FN),
+ PINMUX_DATA(D29_MARK, PA5_FN),
+ PINMUX_DATA(D28_MARK, PA4_FN),
+ PINMUX_DATA(D27_MARK, PA3_FN),
+ PINMUX_DATA(D26_MARK, PA2_FN),
+ PINMUX_DATA(D25_MARK, PA1_FN),
+ PINMUX_DATA(D24_MARK, PA0_FN),
+
+ /* PB FN */
+ PINMUX_DATA(D23_MARK, PB7_FN),
+ PINMUX_DATA(D22_MARK, PB6_FN),
+ PINMUX_DATA(D21_MARK, PB5_FN),
+ PINMUX_DATA(D20_MARK, PB4_FN),
+ PINMUX_DATA(D19_MARK, PB3_FN),
+ PINMUX_DATA(D18_MARK, PB2_FN),
+ PINMUX_DATA(D17_MARK, PB1_FN),
+ PINMUX_DATA(D16_MARK, PB0_FN),
+
+ /* PC FN */
+ PINMUX_DATA(BACK_MARK, PC7_FN),
+ PINMUX_DATA(BREQ_MARK, PC6_FN),
+ PINMUX_DATA(WE3_MARK, PC5_FN),
+ PINMUX_DATA(WE2_MARK, PC4_FN),
+ PINMUX_DATA(CS6_MARK, PC3_FN),
+ PINMUX_DATA(CS5_MARK, PC2_FN),
+ PINMUX_DATA(CS4_MARK, PC1_FN),
+ PINMUX_DATA(CLKOUTENB_MARK, PC0_FN),
+
+ /* PD FN */
+ PINMUX_DATA(DACK3_MARK, PD7_FN),
+ PINMUX_DATA(DACK2_MARK, PD6_FN),
+ PINMUX_DATA(DACK1_MARK, PD5_FN),
+ PINMUX_DATA(DACK0_MARK, PD4_FN),
+ PINMUX_DATA(DREQ3_MARK, PD3_FN),
+ PINMUX_DATA(DREQ2_MARK, PD2_FN),
+ PINMUX_DATA(DREQ1_MARK, PD1_FN),
+ PINMUX_DATA(DREQ0_MARK, PD0_FN),
+
+ /* PE FN */
+ PINMUX_DATA(IRQ3_MARK, PE7_FN),
+ PINMUX_DATA(IRQ2_MARK, PE6_FN),
+ PINMUX_DATA(IRQ1_MARK, PE5_FN),
+ PINMUX_DATA(IRQ0_MARK, PE4_FN),
+ PINMUX_DATA(DRAK3_MARK, PE3_FN),
+ PINMUX_DATA(DRAK2_MARK, PE2_FN),
+ PINMUX_DATA(DRAK1_MARK, PE1_FN),
+ PINMUX_DATA(DRAK0_MARK, PE0_FN),
+
+ /* PF FN */
+ PINMUX_DATA(SCK3_MARK, PF7_FN),
+ PINMUX_DATA(SCK2_MARK, PF6_FN),
+ PINMUX_DATA(SCK1_MARK, PF5_FN),
+ PINMUX_DATA(SCK0_MARK, PF4_FN),
+ PINMUX_DATA(IRL3_MARK, PF3_FN),
+ PINMUX_DATA(IRL2_MARK, PF2_FN),
+ PINMUX_DATA(IRL1_MARK, PF1_FN),
+ PINMUX_DATA(IRL0_MARK, PF0_FN),
+
+ /* PG FN */
+ PINMUX_DATA(TXD3_MARK, PG7_FN),
+ PINMUX_DATA(TXD2_MARK, PG6_FN),
+ PINMUX_DATA(TXD1_MARK, PG5_FN),
+ PINMUX_DATA(TXD0_MARK, PG4_FN),
+ PINMUX_DATA(RXD3_MARK, PG3_FN),
+ PINMUX_DATA(RXD2_MARK, PG2_FN),
+ PINMUX_DATA(RXD1_MARK, PG1_FN),
+ PINMUX_DATA(RXD0_MARK, PG0_FN),
+
+ /* PH FN */
+ PINMUX_DATA(CE2B_MARK, PH5_FN),
+ PINMUX_DATA(CE2A_MARK, PH4_FN),
+ PINMUX_DATA(IOIS16_MARK, PH3_FN),
+ PINMUX_DATA(STATUS1_MARK, PH2_FN),
+ PINMUX_DATA(STATUS0_MARK, PH1_FN),
+ PINMUX_DATA(IRQOUT_MARK, PH0_FN),
+};
+
+static struct pinmux_gpio shx3_pinmux_gpios[] = {
+ /* PA */
+ PINMUX_GPIO(GPIO_PA7, PA7_DATA),
+ PINMUX_GPIO(GPIO_PA6, PA6_DATA),
+ PINMUX_GPIO(GPIO_PA5, PA5_DATA),
+ PINMUX_GPIO(GPIO_PA4, PA4_DATA),
+ PINMUX_GPIO(GPIO_PA3, PA3_DATA),
+ PINMUX_GPIO(GPIO_PA2, PA2_DATA),
+ PINMUX_GPIO(GPIO_PA1, PA1_DATA),
+ PINMUX_GPIO(GPIO_PA0, PA0_DATA),
+
+ /* PB */
+ PINMUX_GPIO(GPIO_PB7, PB7_DATA),
+ PINMUX_GPIO(GPIO_PB6, PB6_DATA),
+ PINMUX_GPIO(GPIO_PB5, PB5_DATA),
+ PINMUX_GPIO(GPIO_PB4, PB4_DATA),
+ PINMUX_GPIO(GPIO_PB3, PB3_DATA),
+ PINMUX_GPIO(GPIO_PB2, PB2_DATA),
+ PINMUX_GPIO(GPIO_PB1, PB1_DATA),
+ PINMUX_GPIO(GPIO_PB0, PB0_DATA),
+
+ /* PC */
+ PINMUX_GPIO(GPIO_PC7, PC7_DATA),
+ PINMUX_GPIO(GPIO_PC6, PC6_DATA),
+ PINMUX_GPIO(GPIO_PC5, PC5_DATA),
+ PINMUX_GPIO(GPIO_PC4, PC4_DATA),
+ PINMUX_GPIO(GPIO_PC3, PC3_DATA),
+ PINMUX_GPIO(GPIO_PC2, PC2_DATA),
+ PINMUX_GPIO(GPIO_PC1, PC1_DATA),
+ PINMUX_GPIO(GPIO_PC0, PC0_DATA),
+
+ /* PD */
+ PINMUX_GPIO(GPIO_PD7, PD7_DATA),
+ PINMUX_GPIO(GPIO_PD6, PD6_DATA),
+ PINMUX_GPIO(GPIO_PD5, PD5_DATA),
+ PINMUX_GPIO(GPIO_PD4, PD4_DATA),
+ PINMUX_GPIO(GPIO_PD3, PD3_DATA),
+ PINMUX_GPIO(GPIO_PD2, PD2_DATA),
+ PINMUX_GPIO(GPIO_PD1, PD1_DATA),
+ PINMUX_GPIO(GPIO_PD0, PD0_DATA),
+
+ /* PE */
+ PINMUX_GPIO(GPIO_PE7, PE7_DATA),
+ PINMUX_GPIO(GPIO_PE6, PE6_DATA),
+ PINMUX_GPIO(GPIO_PE5, PE5_DATA),
+ PINMUX_GPIO(GPIO_PE4, PE4_DATA),
+ PINMUX_GPIO(GPIO_PE3, PE3_DATA),
+ PINMUX_GPIO(GPIO_PE2, PE2_DATA),
+ PINMUX_GPIO(GPIO_PE1, PE1_DATA),
+ PINMUX_GPIO(GPIO_PE0, PE0_DATA),
+
+ /* PF */
+ PINMUX_GPIO(GPIO_PF7, PF7_DATA),
+ PINMUX_GPIO(GPIO_PF6, PF6_DATA),
+ PINMUX_GPIO(GPIO_PF5, PF5_DATA),
+ PINMUX_GPIO(GPIO_PF4, PF4_DATA),
+ PINMUX_GPIO(GPIO_PF3, PF3_DATA),
+ PINMUX_GPIO(GPIO_PF2, PF2_DATA),
+ PINMUX_GPIO(GPIO_PF1, PF1_DATA),
+ PINMUX_GPIO(GPIO_PF0, PF0_DATA),
+
+ /* PG */
+ PINMUX_GPIO(GPIO_PG7, PG7_DATA),
+ PINMUX_GPIO(GPIO_PG6, PG6_DATA),
+ PINMUX_GPIO(GPIO_PG5, PG5_DATA),
+ PINMUX_GPIO(GPIO_PG4, PG4_DATA),
+ PINMUX_GPIO(GPIO_PG3, PG3_DATA),
+ PINMUX_GPIO(GPIO_PG2, PG2_DATA),
+ PINMUX_GPIO(GPIO_PG1, PG1_DATA),
+ PINMUX_GPIO(GPIO_PG0, PG0_DATA),
+
+ /* PH */
+ PINMUX_GPIO(GPIO_PH5, PH5_DATA),
+ PINMUX_GPIO(GPIO_PH4, PH4_DATA),
+ PINMUX_GPIO(GPIO_PH3, PH3_DATA),
+ PINMUX_GPIO(GPIO_PH2, PH2_DATA),
+ PINMUX_GPIO(GPIO_PH1, PH1_DATA),
+ PINMUX_GPIO(GPIO_PH0, PH0_DATA),
+
+ /* FN */
+ PINMUX_GPIO(GPIO_FN_D31, D31_MARK),
+ PINMUX_GPIO(GPIO_FN_D30, D30_MARK),
+ PINMUX_GPIO(GPIO_FN_D29, D29_MARK),
+ PINMUX_GPIO(GPIO_FN_D28, D28_MARK),
+ PINMUX_GPIO(GPIO_FN_D27, D27_MARK),
+ PINMUX_GPIO(GPIO_FN_D26, D26_MARK),
+ PINMUX_GPIO(GPIO_FN_D25, D25_MARK),
+ PINMUX_GPIO(GPIO_FN_D24, D24_MARK),
+ PINMUX_GPIO(GPIO_FN_D23, D23_MARK),
+ PINMUX_GPIO(GPIO_FN_D22, D22_MARK),
+ PINMUX_GPIO(GPIO_FN_D21, D21_MARK),
+ PINMUX_GPIO(GPIO_FN_D20, D20_MARK),
+ PINMUX_GPIO(GPIO_FN_D19, D19_MARK),
+ PINMUX_GPIO(GPIO_FN_D18, D18_MARK),
+ PINMUX_GPIO(GPIO_FN_D17, D17_MARK),
+ PINMUX_GPIO(GPIO_FN_D16, D16_MARK),
+ PINMUX_GPIO(GPIO_FN_BACK, BACK_MARK),
+ PINMUX_GPIO(GPIO_FN_BREQ, BREQ_MARK),
+ PINMUX_GPIO(GPIO_FN_WE3, WE3_MARK),
+ PINMUX_GPIO(GPIO_FN_WE2, WE2_MARK),
+ PINMUX_GPIO(GPIO_FN_CS6, CS6_MARK),
+ PINMUX_GPIO(GPIO_FN_CS5, CS5_MARK),
+ PINMUX_GPIO(GPIO_FN_CS4, CS4_MARK),
+ PINMUX_GPIO(GPIO_FN_CLKOUTENB, CLKOUTENB_MARK),
+ PINMUX_GPIO(GPIO_FN_DACK3, DACK3_MARK),
+ PINMUX_GPIO(GPIO_FN_DACK2, DACK2_MARK),
+ PINMUX_GPIO(GPIO_FN_DACK1, DACK1_MARK),
+ PINMUX_GPIO(GPIO_FN_DACK0, DACK0_MARK),
+ PINMUX_GPIO(GPIO_FN_DREQ3, DREQ3_MARK),
+ PINMUX_GPIO(GPIO_FN_DREQ2, DREQ2_MARK),
+ PINMUX_GPIO(GPIO_FN_DREQ1, DREQ1_MARK),
+ PINMUX_GPIO(GPIO_FN_DREQ0, DREQ0_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ3, IRQ3_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ2, IRQ2_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ1, IRQ1_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ0, IRQ0_MARK),
+ PINMUX_GPIO(GPIO_FN_DRAK3, DRAK3_MARK),
+ PINMUX_GPIO(GPIO_FN_DRAK2, DRAK2_MARK),
+ PINMUX_GPIO(GPIO_FN_DRAK1, DRAK1_MARK),
+ PINMUX_GPIO(GPIO_FN_DRAK0, DRAK0_MARK),
+ PINMUX_GPIO(GPIO_FN_SCK3, SCK3_MARK),
+ PINMUX_GPIO(GPIO_FN_SCK2, SCK2_MARK),
+ PINMUX_GPIO(GPIO_FN_SCK1, SCK1_MARK),
+ PINMUX_GPIO(GPIO_FN_SCK0, SCK0_MARK),
+ PINMUX_GPIO(GPIO_FN_IRL3, IRL3_MARK),
+ PINMUX_GPIO(GPIO_FN_IRL2, IRL2_MARK),
+ PINMUX_GPIO(GPIO_FN_IRL1, IRL1_MARK),
+ PINMUX_GPIO(GPIO_FN_IRL0, IRL0_MARK),
+ PINMUX_GPIO(GPIO_FN_TXD3, TXD3_MARK),
+ PINMUX_GPIO(GPIO_FN_TXD2, TXD2_MARK),
+ PINMUX_GPIO(GPIO_FN_TXD1, TXD1_MARK),
+ PINMUX_GPIO(GPIO_FN_TXD0, TXD0_MARK),
+ PINMUX_GPIO(GPIO_FN_RXD3, RXD3_MARK),
+ PINMUX_GPIO(GPIO_FN_RXD2, RXD2_MARK),
+ PINMUX_GPIO(GPIO_FN_RXD1, RXD1_MARK),
+ PINMUX_GPIO(GPIO_FN_RXD0, RXD0_MARK),
+ PINMUX_GPIO(GPIO_FN_CE2B, CE2B_MARK),
+ PINMUX_GPIO(GPIO_FN_CE2A, CE2A_MARK),
+ PINMUX_GPIO(GPIO_FN_IOIS16, IOIS16_MARK),
+ PINMUX_GPIO(GPIO_FN_STATUS1, STATUS1_MARK),
+ PINMUX_GPIO(GPIO_FN_STATUS0, STATUS0_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQOUT, IRQOUT_MARK),
+};
+
+static struct pinmux_cfg_reg shx3_pinmux_config_regs[] = {
+ { PINMUX_CFG_REG("PABCR", 0xffc70000, 32, 2) {
+ PA7_FN, PA7_OUT, PA7_IN, PA7_IN_PU,
+ PA6_FN, PA6_OUT, PA6_IN, PA6_IN_PU,
+ PA5_FN, PA5_OUT, PA5_IN, PA5_IN_PU,
+ PA4_FN, PA4_OUT, PA4_IN, PA4_IN_PU,
+ PA3_FN, PA3_OUT, PA3_IN, PA3_IN_PU,
+ PA2_FN, PA2_OUT, PA2_IN, PA2_IN_PU,
+ PA1_FN, PA1_OUT, PA1_IN, PA1_IN_PU,
+ PA0_FN, PA0_OUT, PA0_IN, PA0_IN_PU,
+ PB7_FN, PB7_OUT, PB7_IN, PB7_IN_PU,
+ PB6_FN, PB6_OUT, PB6_IN, PB6_IN_PU,
+ PB5_FN, PB5_OUT, PB5_IN, PB5_IN_PU,
+ PB4_FN, PB4_OUT, PB4_IN, PB4_IN_PU,
+ PB3_FN, PB3_OUT, PB3_IN, PB3_IN_PU,
+ PB2_FN, PB2_OUT, PB2_IN, PB2_IN_PU,
+ PB1_FN, PB1_OUT, PB1_IN, PB1_IN_PU,
+ PB0_FN, PB0_OUT, PB0_IN, PB0_IN_PU, },
+ },
+ { PINMUX_CFG_REG("PCDCR", 0xffc70004, 32, 2) {
+ PC7_FN, PC7_OUT, PC7_IN, PC7_IN_PU,
+ PC6_FN, PC6_OUT, PC6_IN, PC6_IN_PU,
+ PC5_FN, PC5_OUT, PC5_IN, PC5_IN_PU,
+ PC4_FN, PC4_OUT, PC4_IN, PC4_IN_PU,
+ PC3_FN, PC3_OUT, PC3_IN, PC3_IN_PU,
+ PC2_FN, PC2_OUT, PC2_IN, PC2_IN_PU,
+ PC1_FN, PC1_OUT, PC1_IN, PC1_IN_PU,
+ PC0_FN, PC0_OUT, PC0_IN, PC0_IN_PU,
+ PD7_FN, PD7_OUT, PD7_IN, PD7_IN_PU,
+ PD6_FN, PD6_OUT, PD6_IN, PD6_IN_PU,
+ PD5_FN, PD5_OUT, PD5_IN, PD5_IN_PU,
+ PD4_FN, PD4_OUT, PD4_IN, PD4_IN_PU,
+ PD3_FN, PD3_OUT, PD3_IN, PD3_IN_PU,
+ PD2_FN, PD2_OUT, PD2_IN, PD2_IN_PU,
+ PD1_FN, PD1_OUT, PD1_IN, PD1_IN_PU,
+ PD0_FN, PD0_OUT, PD0_IN, PD0_IN_PU, },
+ },
+ { PINMUX_CFG_REG("PEFCR", 0xffc70008, 32, 2) {
+ PE7_FN, PE7_OUT, PE7_IN, PE7_IN_PU,
+ PE6_FN, PE6_OUT, PE6_IN, PE6_IN_PU,
+ PE5_FN, PE5_OUT, PE5_IN, PE5_IN_PU,
+ PE4_FN, PE4_OUT, PE4_IN, PE4_IN_PU,
+ PE3_FN, PE3_OUT, PE3_IN, PE3_IN_PU,
+ PE2_FN, PE2_OUT, PE2_IN, PE2_IN_PU,
+ PE1_FN, PE1_OUT, PE1_IN, PE1_IN_PU,
+ PE0_FN, PE0_OUT, PE0_IN, PE0_IN_PU,
+ PF7_FN, PF7_OUT, PF7_IN, PF7_IN_PU,
+ PF6_FN, PF6_OUT, PF6_IN, PF6_IN_PU,
+ PF5_FN, PF5_OUT, PF5_IN, PF5_IN_PU,
+ PF4_FN, PF4_OUT, PF4_IN, PF4_IN_PU,
+ PF3_FN, PF3_OUT, PF3_IN, PF3_IN_PU,
+ PF2_FN, PF2_OUT, PF2_IN, PF2_IN_PU,
+ PF1_FN, PF1_OUT, PF1_IN, PF1_IN_PU,
+ PF0_FN, PF0_OUT, PF0_IN, PF0_IN_PU, },
+ },
+ { PINMUX_CFG_REG("PGHCR", 0xffc7000c, 32, 2) {
+ PG7_FN, PG7_OUT, PG7_IN, PG7_IN_PU,
+ PG6_FN, PG6_OUT, PG6_IN, PG6_IN_PU,
+ PG5_FN, PG5_OUT, PG5_IN, PG5_IN_PU,
+ PG4_FN, PG4_OUT, PG4_IN, PG4_IN_PU,
+ PG3_FN, PG3_OUT, PG3_IN, PG3_IN_PU,
+ PG2_FN, PG2_OUT, PG2_IN, PG2_IN_PU,
+ PG1_FN, PG1_OUT, PG1_IN, PG1_IN_PU,
+ PG0_FN, PG0_OUT, PG0_IN, PG0_IN_PU,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ PH5_FN, PH5_OUT, PH5_IN, PH5_IN_PU,
+ PH4_FN, PH4_OUT, PH4_IN, PH4_IN_PU,
+ PH3_FN, PH3_OUT, PH3_IN, PH3_IN_PU,
+ PH2_FN, PH2_OUT, PH2_IN, PH2_IN_PU,
+ PH1_FN, PH1_OUT, PH1_IN, PH1_IN_PU,
+ PH0_FN, PH0_OUT, PH0_IN, PH0_IN_PU, },
+ },
+ { },
+};
+
+static struct pinmux_data_reg shx3_pinmux_data_regs[] = {
+ { PINMUX_DATA_REG("PABDR", 0xffc70010, 32) {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ PA7_DATA, PA6_DATA, PA5_DATA, PA4_DATA,
+ PA3_DATA, PA2_DATA, PA1_DATA, PA0_DATA,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ PB7_DATA, PB6_DATA, PB5_DATA, PB4_DATA,
+ PB3_DATA, PB2_DATA, PB1_DATA, PB0_DATA, },
+ },
+ { PINMUX_DATA_REG("PCDDR", 0xffc70014, 32) {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ PC7_DATA, PC6_DATA, PC5_DATA, PC4_DATA,
+ PC3_DATA, PC2_DATA, PC1_DATA, PC0_DATA,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ PD7_DATA, PD6_DATA, PD5_DATA, PD4_DATA,
+ PD3_DATA, PD2_DATA, PD1_DATA, PD0_DATA, },
+ },
+ { PINMUX_DATA_REG("PEFDR", 0xffc70018, 32) {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ PE7_DATA, PE6_DATA, PE5_DATA, PE4_DATA,
+ PE3_DATA, PE2_DATA, PE1_DATA, PE0_DATA,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ PF7_DATA, PF6_DATA, PF5_DATA, PF4_DATA,
+ PF3_DATA, PF2_DATA, PF1_DATA, PF0_DATA, },
+ },
+ { PINMUX_DATA_REG("PGHDR", 0xffc7001c, 32) {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ PG7_DATA, PG6_DATA, PG5_DATA, PG4_DATA,
+ PG3_DATA, PG2_DATA, PG1_DATA, PG0_DATA,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, PH5_DATA, PH4_DATA,
+ PH3_DATA, PH2_DATA, PH1_DATA, PH0_DATA, },
+ },
+ { },
+};
+
+static struct pinmux_info shx3_pinmux_info = {
+ .name = "shx3_pfc",
+ .reserved_id = PINMUX_RESERVED,
+ .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END },
+ .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
+ .input_pu = { PINMUX_INPUT_PULLUP_BEGIN,
+ PINMUX_INPUT_PULLUP_END },
+ .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
+ .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END },
+ .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
+ .first_gpio = GPIO_PA7,
+ .last_gpio = GPIO_FN_IRQOUT,
+ .gpios = shx3_pinmux_gpios,
+ .gpio_data = shx3_pinmux_data,
+ .gpio_data_size = ARRAY_SIZE(shx3_pinmux_data),
+ .cfg_regs = shx3_pinmux_config_regs,
+ .data_regs = shx3_pinmux_data_regs,
+};
+
+static int __init shx3_pinmux_setup(void)
+{
+ return register_pinmux(&shx3_pinmux_info);
+}
+arch_initcall(shx3_pinmux_setup);
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
index 79c556e56262..828c9657eb52 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
@@ -524,6 +524,70 @@ static struct platform_device veu1_device = {
},
};
+/* BEU0 */
+static struct uio_info beu0_platform_data = {
+ .name = "BEU0",
+ .version = "0",
+ .irq = evt2irq(0x8A0),
+};
+
+static struct resource beu0_resources[] = {
+ [0] = {
+ .name = "BEU0",
+ .start = 0xfe930000,
+ .end = 0xfe933400,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ /* place holder for contiguous memory */
+ },
+};
+
+static struct platform_device beu0_device = {
+ .name = "uio_pdrv_genirq",
+ .id = 6,
+ .dev = {
+ .platform_data = &beu0_platform_data,
+ },
+ .resource = beu0_resources,
+ .num_resources = ARRAY_SIZE(beu0_resources),
+ .archdata = {
+ .hwblk_id = HWBLK_BEU0,
+ },
+};
+
+/* BEU1 */
+static struct uio_info beu1_platform_data = {
+ .name = "BEU1",
+ .version = "0",
+ .irq = evt2irq(0xA00),
+};
+
+static struct resource beu1_resources[] = {
+ [0] = {
+ .name = "BEU1",
+ .start = 0xfe940000,
+ .end = 0xfe943400,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ /* place holder for contiguous memory */
+ },
+};
+
+static struct platform_device beu1_device = {
+ .name = "uio_pdrv_genirq",
+ .id = 7,
+ .dev = {
+ .platform_data = &beu1_platform_data,
+ },
+ .resource = beu1_resources,
+ .num_resources = ARRAY_SIZE(beu1_resources),
+ .archdata = {
+ .hwblk_id = HWBLK_BEU1,
+ },
+};
+
static struct sh_timer_config cmt_platform_data = {
.channel_offset = 0x60,
.timer_bit = 5,
@@ -857,6 +921,8 @@ static struct platform_device *sh7724_devices[] __initdata = {
&vpu_device,
&veu0_device,
&veu1_device,
+ &beu0_device,
+ &beu1_device,
&jpu_device,
&spu0_device,
&spu1_device,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
index 444aca95b20d..749c6388d5a5 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
@@ -26,7 +26,7 @@ static struct plat_sci_port scif2_platform_data = {
static struct platform_device scif2_device = {
.name = "sh-sci",
- .id = 2,
+ .id = 0,
.dev = {
.platform_data = &scif2_platform_data,
},
@@ -41,7 +41,7 @@ static struct plat_sci_port scif3_platform_data = {
static struct platform_device scif3_device = {
.name = "sh-sci",
- .id = 3,
+ .id = 1,
.dev = {
.platform_data = &scif3_platform_data,
},
@@ -56,7 +56,7 @@ static struct plat_sci_port scif4_platform_data = {
static struct platform_device scif4_device = {
.name = "sh-sci",
- .id = 4,
+ .id = 2,
.dev = {
.platform_data = &scif4_platform_data,
},
@@ -163,39 +163,23 @@ enum {
IRL4_HHLL, IRL4_HHLH, IRL4_HHHL,
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
- SDHI,
- DVC,
- IRQ8, IRQ9, IRQ10,
- WDT0,
- TMU0, TMU1, TMU2, TMU2_TICPI,
+ SDHI, DVC,
+ IRQ8, IRQ9, IRQ11, IRQ10, IRQ12, IRQ13, IRQ14, IRQ15,
+ TMU0, TMU1, TMU2, TMU2_TICPI, TMU3, TMU4, TMU5,
HUDI,
-
ARC4,
- DMAC0,
- IRQ11,
- SCIF2,
- DMAC1_6,
- USB0,
- IRQ12,
+ DMAC0_5, DMAC6_7, DMAC8_11,
+ SCIF0, SCIF1, SCIF2, SCIF3, SCIF4,
+ USB0, USB1,
JMC,
- SPI1,
- IRQ13, IRQ14,
- USB1,
+ SPI0, SPI1,
TMR01, TMR23, TMR45,
- WDT1,
FRT,
- LPC,
- SCIF0, SCIF1, SCIF3,
- PECI0I, PECI1I, PECI2I,
- IRQ15,
+ LPC, LPC5, LPC6, LPC7, LPC8,
+ PECI0, PECI1, PECI2, PECI3, PECI4, PECI5,
ETHERC,
- SPI0,
- ADC1,
- DMAC1_8,
+ ADC0, ADC1,
SIM,
- TMU3, TMU4, TMU5,
- ADC0,
- SCIF4,
IIC0_0, IIC0_1, IIC0_2, IIC0_3,
IIC1_0, IIC1_1, IIC1_2, IIC1_3,
IIC2_0, IIC2_1, IIC2_2, IIC2_3,
@@ -206,9 +190,23 @@ enum {
IIC7_0, IIC7_1, IIC7_2, IIC7_3,
IIC8_0, IIC8_1, IIC8_2, IIC8_3,
IIC9_0, IIC9_1, IIC9_2, IIC9_3,
- PCIINTA,
- PCIE,
+ ONFICTL,
+ MMC1, MMC2,
+ ECCU,
+ PCIC,
+ G200,
+ RSPI,
SGPIO,
+ DMINT12, DMINT13, DMINT14, DMINT15, DMINT16, DMINT17, DMINT18, DMINT19,
+ DMINT20, DMINT21, DMINT22, DMINT23,
+ DDRECC,
+ TSIP,
+ PCIE_BRIDGE,
+ WDT0B, WDT1B, WDT2B, WDT3B, WDT4B, WDT5B, WDT6B, WDT7B, WDT8B,
+ GETHER0, GETHER1, GETHER2,
+ PBIA, PBIB, PBIC,
+ DMAE2, DMAE3,
+ SERMUX2, SERMUX3,
/* interrupt groups */
@@ -221,19 +219,18 @@ static struct intc_vect vectors[] __initdata = {
INTC_VECT(DVC, 0x4e0),
INTC_VECT(IRQ8, 0x500), INTC_VECT(IRQ9, 0x520),
INTC_VECT(IRQ10, 0x540),
- INTC_VECT(WDT0, 0x560),
INTC_VECT(TMU0, 0x580), INTC_VECT(TMU1, 0x5a0),
INTC_VECT(TMU2, 0x5c0), INTC_VECT(TMU2_TICPI, 0x5e0),
INTC_VECT(HUDI, 0x600),
INTC_VECT(ARC4, 0x620),
- INTC_VECT(DMAC0, 0x640), INTC_VECT(DMAC0, 0x660),
- INTC_VECT(DMAC0, 0x680), INTC_VECT(DMAC0, 0x6a0),
- INTC_VECT(DMAC0, 0x6c0),
+ INTC_VECT(DMAC0_5, 0x640), INTC_VECT(DMAC0_5, 0x660),
+ INTC_VECT(DMAC0_5, 0x680), INTC_VECT(DMAC0_5, 0x6a0),
+ INTC_VECT(DMAC0_5, 0x6c0),
INTC_VECT(IRQ11, 0x6e0),
INTC_VECT(SCIF2, 0x700), INTC_VECT(SCIF2, 0x720),
INTC_VECT(SCIF2, 0x740), INTC_VECT(SCIF2, 0x760),
- INTC_VECT(DMAC0, 0x780), INTC_VECT(DMAC0, 0x7a0),
- INTC_VECT(DMAC1_6, 0x7c0), INTC_VECT(DMAC1_6, 0x7e0),
+ INTC_VECT(DMAC0_5, 0x780), INTC_VECT(DMAC0_5, 0x7a0),
+ INTC_VECT(DMAC6_7, 0x7c0), INTC_VECT(DMAC6_7, 0x7e0),
INTC_VECT(USB0, 0x840),
INTC_VECT(IRQ12, 0x880),
INTC_VECT(JMC, 0x8a0),
@@ -242,7 +239,6 @@ static struct intc_vect vectors[] __initdata = {
INTC_VECT(USB1, 0x920),
INTC_VECT(TMR01, 0xa00), INTC_VECT(TMR23, 0xa20),
INTC_VECT(TMR45, 0xa40),
- INTC_VECT(WDT1, 0xa60),
INTC_VECT(FRT, 0xa80),
INTC_VECT(LPC, 0xaa0), INTC_VECT(LPC, 0xac0),
INTC_VECT(LPC, 0xae0), INTC_VECT(LPC, 0xb00),
@@ -250,14 +246,14 @@ static struct intc_vect vectors[] __initdata = {
INTC_VECT(SCIF0, 0xb40), INTC_VECT(SCIF1, 0xb60),
INTC_VECT(SCIF3, 0xb80), INTC_VECT(SCIF3, 0xba0),
INTC_VECT(SCIF3, 0xbc0), INTC_VECT(SCIF3, 0xbe0),
- INTC_VECT(PECI0I, 0xc00), INTC_VECT(PECI1I, 0xc20),
- INTC_VECT(PECI2I, 0xc40),
+ INTC_VECT(PECI0, 0xc00), INTC_VECT(PECI1, 0xc20),
+ INTC_VECT(PECI2, 0xc40),
INTC_VECT(IRQ15, 0xc60),
INTC_VECT(ETHERC, 0xc80), INTC_VECT(ETHERC, 0xca0),
INTC_VECT(SPI0, 0xcc0),
INTC_VECT(ADC1, 0xce0),
- INTC_VECT(DMAC1_8, 0xd00), INTC_VECT(DMAC1_8, 0xd20),
- INTC_VECT(DMAC1_8, 0xd40), INTC_VECT(DMAC1_8, 0xd60),
+ INTC_VECT(DMAC8_11, 0xd00), INTC_VECT(DMAC8_11, 0xd20),
+ INTC_VECT(DMAC8_11, 0xd40), INTC_VECT(DMAC8_11, 0xd60),
INTC_VECT(SIM, 0xd80), INTC_VECT(SIM, 0xda0),
INTC_VECT(SIM, 0xdc0), INTC_VECT(SIM, 0xde0),
INTC_VECT(TMU3, 0xe00), INTC_VECT(TMU4, 0xe20),
@@ -278,17 +274,47 @@ static struct intc_vect vectors[] __initdata = {
INTC_VECT(IIC5_0, 0x1860), INTC_VECT(IIC5_1, 0x1880),
INTC_VECT(IIC5_2, 0x18a0), INTC_VECT(IIC5_3, 0x18c0),
INTC_VECT(IIC6_0, 0x18e0), INTC_VECT(IIC6_1, 0x1900),
- INTC_VECT(IIC6_2, 0x1920), INTC_VECT(IIC6_3, 0x1980),
+ INTC_VECT(IIC6_2, 0x1920),
+ INTC_VECT(ONFICTL, 0x1960),
+ INTC_VECT(IIC6_3, 0x1980),
INTC_VECT(IIC7_0, 0x19a0), INTC_VECT(IIC7_1, 0x1a00),
INTC_VECT(IIC7_2, 0x1a20), INTC_VECT(IIC7_3, 0x1a40),
INTC_VECT(IIC8_0, 0x1a60), INTC_VECT(IIC8_1, 0x1a80),
INTC_VECT(IIC8_2, 0x1aa0), INTC_VECT(IIC8_3, 0x1b40),
INTC_VECT(IIC9_0, 0x1b60), INTC_VECT(IIC9_1, 0x1b80),
INTC_VECT(IIC9_2, 0x1c00), INTC_VECT(IIC9_3, 0x1c20),
- INTC_VECT(PCIINTA, 0x1ce0),
- INTC_VECT(PCIE, 0x1e00),
- INTC_VECT(SGPIO, 0x1f80),
- INTC_VECT(SGPIO, 0x1fa0),
+ INTC_VECT(MMC1, 0x1c60), INTC_VECT(MMC2, 0x1c80),
+ INTC_VECT(ECCU, 0x1cc0),
+ INTC_VECT(PCIC, 0x1ce0),
+ INTC_VECT(G200, 0x1d00),
+ INTC_VECT(RSPI, 0x1d80), INTC_VECT(RSPI, 0x1da0),
+ INTC_VECT(RSPI, 0x1dc0), INTC_VECT(RSPI, 0x1de0),
+ INTC_VECT(PECI3, 0x1ec0), INTC_VECT(PECI4, 0x1ee0),
+ INTC_VECT(PECI5, 0x1f00),
+ INTC_VECT(SGPIO, 0x1f80), INTC_VECT(SGPIO, 0x1fa0),
+ INTC_VECT(SGPIO, 0x1fc0),
+ INTC_VECT(DMINT12, 0x2400), INTC_VECT(DMINT13, 0x2420),
+ INTC_VECT(DMINT14, 0x2440), INTC_VECT(DMINT15, 0x2460),
+ INTC_VECT(DMINT16, 0x2480), INTC_VECT(DMINT17, 0x24e0),
+ INTC_VECT(DMINT18, 0x2500), INTC_VECT(DMINT19, 0x2520),
+ INTC_VECT(DMINT20, 0x2540), INTC_VECT(DMINT21, 0x2560),
+ INTC_VECT(DMINT22, 0x2580), INTC_VECT(DMINT23, 0x2600),
+ INTC_VECT(DDRECC, 0x2620),
+ INTC_VECT(TSIP, 0x2640),
+ INTC_VECT(PCIE_BRIDGE, 0x27c0),
+ INTC_VECT(WDT0B, 0x2800), INTC_VECT(WDT1B, 0x2820),
+ INTC_VECT(WDT2B, 0x2840), INTC_VECT(WDT3B, 0x2860),
+ INTC_VECT(WDT4B, 0x2880), INTC_VECT(WDT5B, 0x28a0),
+ INTC_VECT(WDT6B, 0x28c0), INTC_VECT(WDT7B, 0x28e0),
+ INTC_VECT(WDT8B, 0x2900),
+ INTC_VECT(GETHER0, 0x2960), INTC_VECT(GETHER1, 0x2980),
+ INTC_VECT(GETHER2, 0x29a0),
+ INTC_VECT(PBIA, 0x2a00), INTC_VECT(PBIB, 0x2a20),
+ INTC_VECT(PBIC, 0x2a40),
+ INTC_VECT(DMAE2, 0x2a60), INTC_VECT(DMAE3, 0x2a80),
+ INTC_VECT(SERMUX2, 0x2aa0), INTC_VECT(SERMUX3, 0x2b40),
+ INTC_VECT(LPC5, 0x2b60), INTC_VECT(LPC6, 0x2b80),
+ INTC_VECT(LPC7, 0x2c00), INTC_VECT(LPC8, 0x2c20),
};
static struct intc_group groups[] __initdata = {
@@ -312,31 +338,45 @@ static struct intc_mask_reg mask_registers[] __initdata = {
{ 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */
{ 0, 0, 0, 0, 0, 0, 0, 0,
- 0, DMAC1_8, 0, PECI0I, LPC, FRT, WDT1, TMR45,
- TMR23, TMR01, 0, 0, 0, 0, 0, DMAC0,
- HUDI, 0, WDT0, SCIF3, SCIF2, SDHI, TMU345, TMU012
+ 0, DMAC8_11, 0, PECI0, LPC, FRT, 0, TMR45,
+ TMR23, TMR01, 0, 0, 0, 0, 0, DMAC0_5,
+ HUDI, 0, 0, SCIF3, SCIF2, SDHI, TMU345, TMU012
} },
{ 0xffd400d0, 0xffd400d4, 32, /* INT2MSKR1 / INT2MSKCR1 */
{ IRQ15, IRQ14, IRQ13, IRQ12, IRQ11, IRQ10, SCIF4, ETHERC,
IRQ9, IRQ8, SCIF1, SCIF0, USB0, 0, 0, USB1,
- ADC1, 0, DMAC1_6, ADC0, SPI0, SIM, PECI2I, PECI1I,
+ ADC1, 0, DMAC6_7, ADC0, SPI0, SIM, PECI2, PECI1,
ARC4, 0, SPI1, JMC, 0, 0, 0, DVC
} },
{ 0xffd10038, 0xffd1003c, 32, /* INT2MSKR2 / INT2MSKCR2 */
- { IIC4_1, IIC4_2, IIC5_0, 0, 0, 0, SGPIO, 0,
- 0, 0, 0, IIC9_2, IIC8_2, IIC8_1, IIC8_0, IIC7_3,
+ { IIC4_1, IIC4_2, IIC5_0, ONFICTL, 0, 0, SGPIO, 0,
+ 0, G200, 0, IIC9_2, IIC8_2, IIC8_1, IIC8_0, IIC7_3,
IIC7_2, IIC7_1, IIC6_3, IIC0_0, IIC0_1, IIC0_2, IIC0_3, IIC3_1,
- IIC2_3, 0, IIC2_1, IIC9_1, IIC3_3, IIC1_0, PCIE, IIC2_2
+ IIC2_3, 0, IIC2_1, IIC9_1, IIC3_3, IIC1_0, 0, IIC2_2
} },
- { 0xffd100d0, 0xff1400d4, 32, /* INT2MSKR3 / INT2MSKCR4 */
- { 0, IIC6_1, IIC6_0, IIC5_1, IIC3_2, IIC2_0, 0, 0,
+ { 0xffd100d0, 0xffd100d4, 32, /* INT2MSKR3 / INT2MSKCR3 */
+ { MMC1, IIC6_1, IIC6_0, IIC5_1, IIC3_2, IIC2_0, PECI5, MMC2,
IIC1_3, IIC1_2, IIC9_0, IIC8_3, IIC4_3, IIC7_0, 0, IIC6_2,
- PCIINTA, 0, IIC4_0, 0, 0, 0, 0, IIC9_3,
+ PCIC, 0, IIC4_0, 0, ECCU, RSPI, 0, IIC9_3,
IIC3_0, 0, IIC5_3, IIC5_2, 0, 0, 0, IIC1_1
} },
+
+ { 0xffd20038, 0xffd2003c, 32, /* INT2MSKR4 / INT2MSKCR4 */
+ { WDT0B, WDT1B, WDT3B, GETHER0, 0, 0, 0, 0,
+ 0, 0, 0, LPC7, SERMUX2, DMAE3, DMAE2, PBIC,
+ PBIB, PBIA, GETHER1, DMINT12, DMINT13, DMINT14, DMINT15, TSIP,
+ DMINT23, 0, DMINT21, LPC6, 0, DMINT16, 0, DMINT22
+ } },
+
+ { 0xffd200d0, 0xffd200d4, 32, /* INT2MSKR5 / INT2MSKCR5 */
+ { 0, WDT8B, WDT7B, WDT4B, 0, DMINT20, 0, 0,
+ DMINT19, DMINT18, LPC5, SERMUX3, WDT2B, GETHER2, 0, 0,
+ 0, 0, PCIE_BRIDGE, 0, 0, 0, 0, LPC8,
+ DDRECC, 0, WDT6B, WDT5B, 0, 0, 0, DMINT17
+ } },
};
#define INTPRI 0xffd00010
@@ -372,6 +412,22 @@ static struct intc_mask_reg mask_registers[] __initdata = {
#define INT2PRI29 0xffd100b4
#define INT2PRI30 0xffd100b8
#define INT2PRI31 0xffd100bc
+#define INT2PRI32 0xffd20000
+#define INT2PRI33 0xffd20004
+#define INT2PRI34 0xffd20008
+#define INT2PRI35 0xffd2000c
+#define INT2PRI36 0xffd20010
+#define INT2PRI37 0xffd20014
+#define INT2PRI38 0xffd20018
+#define INT2PRI39 0xffd2001c
+#define INT2PRI40 0xffd200a0
+#define INT2PRI41 0xffd200a4
+#define INT2PRI42 0xffd200a8
+#define INT2PRI43 0xffd200ac
+#define INT2PRI44 0xffd200b0
+#define INT2PRI45 0xffd200b4
+#define INT2PRI46 0xffd200b8
+#define INT2PRI47 0xffd200bc
static struct intc_prio_reg prio_registers[] __initdata = {
{ INTPRI, 0, 32, 4, { IRQ0, IRQ1, IRQ2, IRQ3,
@@ -379,39 +435,61 @@ static struct intc_prio_reg prio_registers[] __initdata = {
{ INT2PRI0, 0, 32, 8, { TMU0, TMU1, TMU2, TMU2_TICPI } },
{ INT2PRI1, 0, 32, 8, { TMU3, TMU4, TMU5, SDHI } },
- { INT2PRI2, 0, 32, 8, { SCIF2, SCIF3, WDT0, IRQ8 } },
- { INT2PRI3, 0, 32, 8, { HUDI, DMAC0, ADC0, IRQ9 } },
+ { INT2PRI2, 0, 32, 8, { SCIF2, SCIF3, 0, IRQ8 } },
+ { INT2PRI3, 0, 32, 8, { HUDI, DMAC0_5, ADC0, IRQ9 } },
{ INT2PRI4, 0, 32, 8, { IRQ10, 0, TMR01, TMR23 } },
- { INT2PRI5, 0, 32, 8, { TMR45, WDT1, FRT, LPC } },
- { INT2PRI6, 0, 32, 8, { PECI0I, ETHERC, DMAC1_8, 0 } },
+ { INT2PRI5, 0, 32, 8, { TMR45, 0, FRT, LPC } },
+ { INT2PRI6, 0, 32, 8, { PECI0, ETHERC, DMAC8_11, 0 } },
{ INT2PRI7, 0, 32, 8, { SCIF4, 0, IRQ11, IRQ12 } },
{ INT2PRI8, 0, 32, 8, { 0, 0, 0, DVC } },
{ INT2PRI9, 0, 32, 8, { ARC4, 0, SPI1, JMC } },
- { INT2PRI10, 0, 32, 8, { SPI0, SIM, PECI2I, PECI1I } },
- { INT2PRI11, 0, 32, 8, { ADC1, IRQ13, DMAC1_6, IRQ14 } },
+ { INT2PRI10, 0, 32, 8, { SPI0, SIM, PECI2, PECI1 } },
+ { INT2PRI11, 0, 32, 8, { ADC1, IRQ13, DMAC6_7, IRQ14 } },
{ INT2PRI12, 0, 32, 8, { USB0, 0, IRQ15, USB1 } },
{ INT2PRI13, 0, 32, 8, { 0, 0, SCIF1, SCIF0 } },
{ INT2PRI16, 0, 32, 8, { IIC2_2, 0, 0, 0 } },
- { INT2PRI17, 0, 32, 8, { PCIE, 0, 0, IIC1_0 } },
+ { INT2PRI17, 0, 32, 8, { 0, 0, 0, IIC1_0 } },
{ INT2PRI18, 0, 32, 8, { IIC3_3, IIC9_1, IIC2_1, IIC1_2 } },
{ INT2PRI19, 0, 32, 8, { IIC2_3, IIC3_1, 0, IIC1_3 } },
{ INT2PRI20, 0, 32, 8, { IIC2_0, IIC6_3, IIC7_1, IIC7_2 } },
{ INT2PRI21, 0, 32, 8, { IIC7_3, IIC8_0, IIC8_1, IIC8_2 } },
- { INT2PRI22, 0, 32, 8, { IIC9_2, 0, 0, 0 } },
- { INT2PRI23, 0, 32, 8, { 0, SGPIO, IIC3_2, IIC5_1 } },
- { INT2PRI24, 0, 32, 8, { 0, 0, 0, IIC1_1 } },
+ { INT2PRI22, 0, 32, 8, { IIC9_2, MMC2, G200, 0 } },
+ { INT2PRI23, 0, 32, 8, { PECI5, SGPIO, IIC3_2, IIC5_1 } },
+ { INT2PRI24, 0, 32, 8, { PECI4, PECI3, 0, IIC1_1 } },
{ INT2PRI25, 0, 32, 8, { IIC3_0, 0, IIC5_3, IIC5_2 } },
- { INT2PRI26, 0, 32, 8, { 0, 0, 0, IIC9_3 } },
- { INT2PRI27, 0, 32, 8, { PCIINTA, IIC6_0, IIC4_0, IIC6_1 } },
- { INT2PRI28, 0, 32, 8, { IIC4_3, IIC7_0, 0, IIC6_2 } },
+ { INT2PRI26, 0, 32, 8, { ECCU, RSPI, 0, IIC9_3 } },
+ { INT2PRI27, 0, 32, 8, { PCIC, IIC6_0, IIC4_0, IIC6_1 } },
+ { INT2PRI28, 0, 32, 8, { IIC4_3, IIC7_0, MMC1, IIC6_2 } },
{ INT2PRI29, 0, 32, 8, { 0, 0, IIC9_0, IIC8_3 } },
- { INT2PRI30, 0, 32, 8, { IIC4_1, IIC4_2, IIC5_0, 0 } },
+ { INT2PRI30, 0, 32, 8, { IIC4_1, IIC4_2, IIC5_0, ONFICTL } },
{ INT2PRI31, 0, 32, 8, { IIC0_0, IIC0_1, IIC0_2, IIC0_3 } },
+ { INT2PRI32, 0, 32, 8, { DMINT22, 0, 0, 0 } },
+ { INT2PRI33, 0, 32, 8, { 0, 0, 0, DMINT16 } },
+ { INT2PRI34, 0, 32, 8, { 0, LPC6, DMINT21, DMINT18 } },
+ { INT2PRI35, 0, 32, 8, { DMINT23, TSIP, 0, DMINT19 } },
+ { INT2PRI36, 0, 32, 8, { DMINT20, GETHER1, PBIA, PBIB } },
+ { INT2PRI37, 0, 32, 8, { PBIC, DMAE2, DMAE3, SERMUX2 } },
+ { INT2PRI38, 0, 32, 8, { LPC7, 0, 0, 0 } },
+ { INT2PRI39, 0, 32, 8, { 0, 0, 0, WDT4B } },
+ { INT2PRI40, 0, 32, 8, { 0, 0, 0, DMINT17 } },
+ { INT2PRI41, 0, 32, 8, { DDRECC, 0, WDT6B, WDT5B } },
+ { INT2PRI42, 0, 32, 8, { 0, 0, 0, LPC8 } },
+ { INT2PRI43, 0, 32, 8, { 0, WDT7B, PCIE_BRIDGE, WDT8B } },
+ { INT2PRI44, 0, 32, 8, { WDT2B, GETHER2, 0, 0 } },
+ { INT2PRI45, 0, 32, 8, { 0, 0, LPC5, SERMUX3 } },
+ { INT2PRI46, 0, 32, 8, { WDT0B, WDT1B, WDT3B, GETHER0 } },
+ { INT2PRI47, 0, 32, 8, { DMINT12, DMINT13, DMINT14, DMINT15 } },
+};
+
+static struct intc_sense_reg sense_registers_irq8to15[] __initdata = {
+ { 0xffd100f8, 32, 2, /* ICR2 */ { IRQ15, IRQ14, IRQ13, IRQ12,
+ IRQ11, IRQ10, IRQ9, IRQ8 } },
};
static DECLARE_INTC_DESC(intc_desc, "sh7757", vectors, groups,
- mask_registers, prio_registers, NULL);
+ mask_registers, prio_registers,
+ sense_registers_irq8to15);
/* Support for external interrupt pins in IRQ mode */
static struct intc_vect vectors_irq0123[] __initdata = {
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
index 8797723231ea..c016c0004714 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
@@ -629,33 +629,10 @@ static void __init sh7786_usb_setup(void)
}
}
-static int __init sh7786_devices_setup(void)
-{
- int ret;
-
- sh7786_usb_setup();
-
- ret = platform_add_devices(sh7786_early_devices,
- ARRAY_SIZE(sh7786_early_devices));
- if (unlikely(ret != 0))
- return ret;
-
- return platform_add_devices(sh7786_devices,
- ARRAY_SIZE(sh7786_devices));
-}
-arch_initcall(sh7786_devices_setup);
-
-void __init plat_early_device_setup(void)
-{
- early_platform_add_devices(sh7786_early_devices,
- ARRAY_SIZE(sh7786_early_devices));
-}
-
enum {
UNUSED = 0,
/* interrupt sources */
-
IRL0_LLLL, IRL0_LLLH, IRL0_LLHL, IRL0_LLHH,
IRL0_LHLL, IRL0_LHLH, IRL0_LHHL, IRL0_LHHH,
IRL0_HLLL, IRL0_HLLH, IRL0_HLHL, IRL0_HLHH,
@@ -693,9 +670,12 @@ enum {
Thermal,
INTICI0, INTICI1, INTICI2, INTICI3,
INTICI4, INTICI5, INTICI6, INTICI7,
+
+ /* Muxed sub-events */
+ TXI1, BRI1, RXI1, ERI1,
};
-static struct intc_vect vectors[] __initdata = {
+static struct intc_vect sh7786_vectors[] __initdata = {
INTC_VECT(WDT, 0x3e0),
INTC_VECT(TMU0_0, 0x400), INTC_VECT(TMU0_1, 0x420),
INTC_VECT(TMU0_2, 0x440), INTC_VECT(TMU0_3, 0x460),
@@ -756,14 +736,12 @@ static struct intc_vect vectors[] __initdata = {
#define INTDISTCR0 0xfe4100b0
#define INTDISTCR1 0xfe4100b4
-#define INTACK 0xfe4100b8
-#define INTACKCLR 0xfe4100bc
#define INT2DISTCR0 0xfe410900
#define INT2DISTCR1 0xfe410904
#define INT2DISTCR2 0xfe410908
#define INT2DISTCR3 0xfe41090c
-static struct intc_mask_reg mask_registers[] __initdata = {
+static struct intc_mask_reg sh7786_mask_registers[] __initdata = {
{ CnINTMSK0, CnINTMSKCLR0, 32,
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 },
INTC_SMP_BALANCING(INTDISTCR0) },
@@ -807,7 +785,7 @@ static struct intc_mask_reg mask_registers[] __initdata = {
0, 0, 0, 0, 0, 0, 0, 0 }, INTC_SMP_BALANCING(INT2DISTCR3) },
};
-static struct intc_prio_reg prio_registers[] __initdata = {
+static struct intc_prio_reg sh7786_prio_registers[] __initdata = {
{ 0xfe410010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3,
IRQ4, IRQ5, IRQ6, IRQ7 } },
{ 0xfe410800, 0, 32, 8, /* INT2PRI0 */ { 0, 0, 0, WDT } },
@@ -851,11 +829,27 @@ static struct intc_prio_reg prio_registers[] __initdata = {
INTICI3, INTICI2, INTICI1, INTICI0 }, INTC_SMP(4, 2) },
};
-static DECLARE_INTC_DESC(intc_desc, "sh7786", vectors, NULL,
- mask_registers, prio_registers, NULL);
+static struct intc_subgroup sh7786_subgroups[] __initdata = {
+ { 0xfe410c20, 32, SCIF1,
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, TXI1, BRI1, RXI1, ERI1 } },
+};
-/* Support for external interrupt pins in IRQ mode */
+static struct intc_desc sh7786_intc_desc __initdata = {
+ .name = "sh7786",
+ .hw = {
+ .vectors = sh7786_vectors,
+ .nr_vectors = ARRAY_SIZE(sh7786_vectors),
+ .mask_regs = sh7786_mask_registers,
+ .nr_mask_regs = ARRAY_SIZE(sh7786_mask_registers),
+ .subgroups = sh7786_subgroups,
+ .nr_subgroups = ARRAY_SIZE(sh7786_subgroups),
+ .prio_regs = sh7786_prio_registers,
+ .nr_prio_regs = ARRAY_SIZE(sh7786_prio_registers),
+ },
+};
+/* Support for external interrupt pins in IRQ mode */
static struct intc_vect vectors_irq0123[] __initdata = {
INTC_VECT(IRQ0, 0x200), INTC_VECT(IRQ1, 0x240),
INTC_VECT(IRQ2, 0x280), INTC_VECT(IRQ3, 0x2c0),
@@ -866,23 +860,25 @@ static struct intc_vect vectors_irq4567[] __initdata = {
INTC_VECT(IRQ6, 0x380), INTC_VECT(IRQ7, 0x3c0),
};
-static struct intc_sense_reg sense_registers[] __initdata = {
+static struct intc_sense_reg sh7786_sense_registers[] __initdata = {
{ 0xfe41001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3,
IRQ4, IRQ5, IRQ6, IRQ7 } },
};
-static struct intc_mask_reg ack_registers[] __initdata = {
+static struct intc_mask_reg sh7786_ack_registers[] __initdata = {
{ 0xfe410024, 0, 32, /* INTREQ */
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static DECLARE_INTC_DESC_ACK(intc_desc_irq0123, "sh7786-irq0123",
- vectors_irq0123, NULL, mask_registers,
- prio_registers, sense_registers, ack_registers);
+ vectors_irq0123, NULL, sh7786_mask_registers,
+ sh7786_prio_registers, sh7786_sense_registers,
+ sh7786_ack_registers);
static DECLARE_INTC_DESC_ACK(intc_desc_irq4567, "sh7786-irq4567",
- vectors_irq4567, NULL, mask_registers,
- prio_registers, sense_registers, ack_registers);
+ vectors_irq4567, NULL, sh7786_mask_registers,
+ sh7786_prio_registers, sh7786_sense_registers,
+ sh7786_ack_registers);
/* External interrupt pins in IRL mode */
@@ -909,10 +905,10 @@ static struct intc_vect vectors_irl4567[] __initdata = {
};
static DECLARE_INTC_DESC(intc_desc_irl0123, "sh7786-irl0123", vectors_irl0123,
- NULL, mask_registers, NULL, NULL);
+ NULL, sh7786_mask_registers, NULL, NULL);
static DECLARE_INTC_DESC(intc_desc_irl4567, "sh7786-irl4567", vectors_irl4567,
- NULL, mask_registers, NULL, NULL);
+ NULL, sh7786_mask_registers, NULL, NULL);
#define INTC_ICR0 0xfe410000
#define INTC_INTMSK0 CnINTMSK0
@@ -920,19 +916,6 @@ static DECLARE_INTC_DESC(intc_desc_irl4567, "sh7786-irl4567", vectors_irl4567,
#define INTC_INTMSK2 INTMSK2
#define INTC_INTMSKCLR1 CnINTMSKCLR1
#define INTC_INTMSKCLR2 INTMSKCLR2
-#define INTC_USERIMASK 0xfe411000
-
-#ifdef CONFIG_INTC_BALANCING
-unsigned int irq_lookup(unsigned int irq)
-{
- return __raw_readl(INTACK) & 1 ? irq : NO_IRQ_IGNORE;
-}
-
-void irq_finish(unsigned int irq)
-{
- __raw_writel(irq2evt(irq), INTACKCLR);
-}
-#endif
void __init plat_irq_setup(void)
{
@@ -946,8 +929,7 @@ void __init plat_irq_setup(void)
/* select IRL mode for IRL3-0 + IRL7-4 */
__raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
- register_intc_controller(&intc_desc);
- register_intc_userimask(INTC_USERIMASK);
+ register_intc_controller(&sh7786_intc_desc);
}
void __init plat_irq_setup_pins(int mode)
@@ -991,3 +973,39 @@ void __init plat_irq_setup_pins(int mode)
void __init plat_mem_setup(void)
{
}
+
+static int __init sh7786_devices_setup(void)
+{
+ int ret, irq;
+
+ sh7786_usb_setup();
+
+ /*
+ * De-mux SCIF1 IRQs if possible
+ */
+ irq = intc_irq_lookup(sh7786_intc_desc.name, TXI1);
+ if (irq > 0) {
+ scif1_platform_data.irqs[SCIx_TXI_IRQ] = irq;
+ scif1_platform_data.irqs[SCIx_ERI_IRQ] =
+ intc_irq_lookup(sh7786_intc_desc.name, ERI1);
+ scif1_platform_data.irqs[SCIx_BRI_IRQ] =
+ intc_irq_lookup(sh7786_intc_desc.name, BRI1);
+ scif1_platform_data.irqs[SCIx_RXI_IRQ] =
+ intc_irq_lookup(sh7786_intc_desc.name, RXI1);
+ }
+
+ ret = platform_add_devices(sh7786_early_devices,
+ ARRAY_SIZE(sh7786_early_devices));
+ if (unlikely(ret != 0))
+ return ret;
+
+ return platform_add_devices(sh7786_devices,
+ ARRAY_SIZE(sh7786_devices));
+}
+arch_initcall(sh7786_devices_setup);
+
+void __init plat_early_device_setup(void)
+{
+ early_platform_add_devices(sh7786_early_devices,
+ ARRAY_SIZE(sh7786_early_devices));
+}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
index 9158bc5ea38b..013f0b144489 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
@@ -1,7 +1,7 @@
/*
* SH-X3 Prototype Setup
*
- * Copyright (C) 2007 - 2009 Paul Mundt
+ * Copyright (C) 2007 - 2010 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -12,7 +12,9 @@
#include <linux/serial.h>
#include <linux/serial_sci.h>
#include <linux/io.h>
+#include <linux/gpio.h>
#include <linux/sh_timer.h>
+#include <cpu/shx3.h>
#include <asm/mmzone.h>
/*
@@ -354,6 +356,10 @@ static struct intc_group groups[] __initdata = {
DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11),
};
+#define INT2DISTCR0 0xfe4108a0
+#define INT2DISTCR1 0xfe4108a4
+#define INT2DISTCR2 0xfe4108a8
+
static struct intc_mask_reg mask_registers[] __initdata = {
{ 0xfe410030, 0xfe410050, 32, /* CnINTMSK0 / CnINTMSKCLR0 */
{ IRQ0, IRQ1, IRQ2, IRQ3 } },
@@ -363,20 +369,23 @@ static struct intc_mask_reg mask_registers[] __initdata = {
{ FE1, FE0, 0, ATAPI, VCORE0, VIN1, VIN0, IIC,
DU, GPIO3, GPIO2, GPIO1, GPIO0, PAM, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, /* HUDI bits ignored */
- 0, TMU5, TMU4, TMU3, TMU2, TMU1, TMU0, 0, } },
+ 0, TMU5, TMU4, TMU3, TMU2, TMU1, TMU0, 0, },
+ INTC_SMP_BALANCING(INT2DISTCR0) },
{ 0xfe410830, 0xfe410860, 32, /* CnINT2MSK1 / CnINT2MSKCLR1 */
{ 0, 0, 0, 0, DTU3, DTU2, DTU1, DTU0, /* IRM bits ignored */
PCII9, PCII8, PCII7, PCII6, PCII5, PCII4, PCII3, PCII2,
PCII1, PCII0, DMAC1_DMAE, DMAC1_DMINT11,
DMAC1_DMINT10, DMAC1_DMINT9, DMAC1_DMINT8, DMAC1_DMINT7,
DMAC1_DMINT6, DMAC0_DMAE, DMAC0_DMINT5, DMAC0_DMINT4,
- DMAC0_DMINT3, DMAC0_DMINT2, DMAC0_DMINT1, DMAC0_DMINT0 } },
+ DMAC0_DMINT3, DMAC0_DMINT2, DMAC0_DMINT1, DMAC0_DMINT0 },
+ INTC_SMP_BALANCING(INT2DISTCR1) },
{ 0xfe410840, 0xfe410870, 32, /* CnINT2MSK2 / CnINT2MSKCLR2 */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
SCIF3_TXI, SCIF3_BRI, SCIF3_RXI, SCIF3_ERI,
SCIF2_TXI, SCIF2_BRI, SCIF2_RXI, SCIF2_ERI,
SCIF1_TXI, SCIF1_BRI, SCIF1_RXI, SCIF1_ERI,
- SCIF0_TXI, SCIF0_BRI, SCIF0_RXI, SCIF0_ERI } },
+ SCIF0_TXI, SCIF0_BRI, SCIF0_RXI, SCIF0_ERI },
+ INTC_SMP_BALANCING(INT2DISTCR2) },
};
static struct intc_prio_reg prio_registers[] __initdata = {
@@ -433,11 +442,33 @@ static DECLARE_INTC_DESC(intc_desc_irl, "shx3-irl", vectors_irl, groups,
void __init plat_irq_setup_pins(int mode)
{
+ int ret = 0;
+
switch (mode) {
case IRQ_MODE_IRQ:
+ ret |= gpio_request(GPIO_FN_IRQ3, intc_desc_irq.name);
+ ret |= gpio_request(GPIO_FN_IRQ2, intc_desc_irq.name);
+ ret |= gpio_request(GPIO_FN_IRQ1, intc_desc_irq.name);
+ ret |= gpio_request(GPIO_FN_IRQ0, intc_desc_irq.name);
+
+ if (unlikely(ret)) {
+ pr_err("Failed to set IRQ mode\n");
+ return;
+ }
+
register_intc_controller(&intc_desc_irq);
break;
case IRQ_MODE_IRL3210:
+ ret |= gpio_request(GPIO_FN_IRL3, intc_desc_irl.name);
+ ret |= gpio_request(GPIO_FN_IRL2, intc_desc_irl.name);
+ ret |= gpio_request(GPIO_FN_IRL1, intc_desc_irl.name);
+ ret |= gpio_request(GPIO_FN_IRL0, intc_desc_irl.name);
+
+ if (unlikely(ret)) {
+ pr_err("Failed to set IRL mode\n");
+ return;
+ }
+
register_intc_controller(&intc_desc_irl);
break;
default:
@@ -447,6 +478,9 @@ void __init plat_irq_setup_pins(int mode)
void __init plat_irq_setup(void)
{
+ reserve_intc_vectors(vectors_irq, ARRAY_SIZE(vectors_irq));
+ reserve_intc_vectors(vectors_irl, ARRAY_SIZE(vectors_irl));
+
register_intc_controller(&intc_desc);
}
diff --git a/arch/sh/kernel/head_32.S b/arch/sh/kernel/head_32.S
index 6e35f012cc03..7db248936b60 100644
--- a/arch/sh/kernel/head_32.S
+++ b/arch/sh/kernel/head_32.S
@@ -330,7 +330,7 @@ ENTRY(_stext)
#if defined(CONFIG_CPU_SH2)
1: .long 0x000000F0 ! IMASK=0xF
#else
-1: .long 0x400080F0 ! MD=1, RB=0, BL=0, FD=1, IMASK=0xF
+1: .long 0x500080F0 ! MD=1, RB=0, BL=1, FD=1, IMASK=0xF
#endif
ENTRY(stack_start)
2: .long init_thread_union+THREAD_SIZE
diff --git a/arch/sh/kernel/io_trapped.c b/arch/sh/kernel/io_trapped.c
index 2947d2bd1291..32c385ef1011 100644
--- a/arch/sh/kernel/io_trapped.c
+++ b/arch/sh/kernel/io_trapped.c
@@ -291,7 +291,7 @@ int handle_trapped_io(struct pt_regs *regs, unsigned long address)
}
tmp = handle_unaligned_access(instruction, regs,
- &trapped_io_access, 1);
+ &trapped_io_access, 1, address);
set_fs(oldfs);
return tmp == 0;
}
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index 257de1f0692b..9dc447db8a44 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -283,6 +283,8 @@ void __init init_IRQ(void)
if (sh_mv.mv_init_irq)
sh_mv.mv_init_irq();
+ intc_finalize();
+
irq_ctx_init(smp_processor_id());
}
@@ -290,7 +292,7 @@ void __init init_IRQ(void)
int __init arch_probe_nr_irqs(void)
{
nr_irqs = sh_mv.mv_nr_irqs;
- return 0;
+ return NR_IRQS_LEGACY;
}
#endif
diff --git a/arch/sh/kernel/irq_32.c b/arch/sh/kernel/irq_32.c
index e33ab15831f9..e5a755be9129 100644
--- a/arch/sh/kernel/irq_32.c
+++ b/arch/sh/kernel/irq_32.c
@@ -10,11 +10,11 @@
#include <linux/irqflags.h>
#include <linux/module.h>
-void notrace raw_local_irq_restore(unsigned long flags)
+void notrace arch_local_irq_restore(unsigned long flags)
{
unsigned long __dummy0, __dummy1;
- if (flags == RAW_IRQ_DISABLED) {
+ if (flags == ARCH_IRQ_DISABLED) {
__asm__ __volatile__ (
"stc sr, %0\n\t"
"or #0xf0, %0\n\t"
@@ -33,14 +33,14 @@ void notrace raw_local_irq_restore(unsigned long flags)
#endif
"ldc %0, sr\n\t"
: "=&r" (__dummy0), "=r" (__dummy1)
- : "1" (~RAW_IRQ_DISABLED)
+ : "1" (~ARCH_IRQ_DISABLED)
: "memory"
);
}
}
-EXPORT_SYMBOL(raw_local_irq_restore);
+EXPORT_SYMBOL(arch_local_irq_restore);
-unsigned long notrace __raw_local_save_flags(void)
+unsigned long notrace arch_local_save_flags(void)
{
unsigned long flags;
@@ -54,4 +54,4 @@ unsigned long notrace __raw_local_save_flags(void)
return flags;
}
-EXPORT_SYMBOL(__raw_local_save_flags);
+EXPORT_SYMBOL(arch_local_save_flags);
diff --git a/arch/sh/kernel/kdebugfs.c b/arch/sh/kernel/kdebugfs.c
new file mode 100644
index 000000000000..e11c30bb100c
--- /dev/null
+++ b/arch/sh/kernel/kdebugfs.c
@@ -0,0 +1,16 @@
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/debugfs.h>
+
+struct dentry *arch_debugfs_dir;
+EXPORT_SYMBOL(arch_debugfs_dir);
+
+static int __init arch_kdebugfs_init(void)
+{
+ arch_debugfs_dir = debugfs_create_dir("sh", NULL);
+ if (!arch_debugfs_dir)
+ return -ENOMEM;
+
+ return 0;
+}
+arch_initcall(arch_kdebugfs_init);
diff --git a/arch/sh/kernel/kprobes.c b/arch/sh/kernel/kprobes.c
index 4049d99f76e1..1208b09e95c3 100644
--- a/arch/sh/kernel/kprobes.c
+++ b/arch/sh/kernel/kprobes.c
@@ -20,9 +20,9 @@
DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
-static struct kprobe saved_current_opcode;
-static struct kprobe saved_next_opcode;
-static struct kprobe saved_next_opcode2;
+static DEFINE_PER_CPU(struct kprobe, saved_current_opcode);
+static DEFINE_PER_CPU(struct kprobe, saved_next_opcode);
+static DEFINE_PER_CPU(struct kprobe, saved_next_opcode2);
#define OPCODE_JMP(x) (((x) & 0xF0FF) == 0x402b)
#define OPCODE_JSR(x) (((x) & 0xF0FF) == 0x400b)
@@ -102,16 +102,21 @@ int __kprobes kprobe_handle_illslot(unsigned long pc)
void __kprobes arch_remove_kprobe(struct kprobe *p)
{
- if (saved_next_opcode.addr != 0x0) {
+ struct kprobe *saved = &__get_cpu_var(saved_next_opcode);
+
+ if (saved->addr) {
arch_disarm_kprobe(p);
- arch_disarm_kprobe(&saved_next_opcode);
- saved_next_opcode.addr = 0x0;
- saved_next_opcode.opcode = 0x0;
-
- if (saved_next_opcode2.addr != 0x0) {
- arch_disarm_kprobe(&saved_next_opcode2);
- saved_next_opcode2.addr = 0x0;
- saved_next_opcode2.opcode = 0x0;
+ arch_disarm_kprobe(saved);
+
+ saved->addr = NULL;
+ saved->opcode = 0;
+
+ saved = &__get_cpu_var(saved_next_opcode2);
+ if (saved->addr) {
+ arch_disarm_kprobe(saved);
+
+ saved->addr = NULL;
+ saved->opcode = 0;
}
}
}
@@ -141,57 +146,59 @@ static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
*/
static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
{
- kprobe_opcode_t *addr = NULL;
- saved_current_opcode.addr = (kprobe_opcode_t *) (regs->pc);
- addr = saved_current_opcode.addr;
+ __get_cpu_var(saved_current_opcode).addr = (kprobe_opcode_t *)regs->pc;
if (p != NULL) {
+ struct kprobe *op1, *op2;
+
arch_disarm_kprobe(p);
+ op1 = &__get_cpu_var(saved_next_opcode);
+ op2 = &__get_cpu_var(saved_next_opcode2);
+
if (OPCODE_JSR(p->opcode) || OPCODE_JMP(p->opcode)) {
unsigned int reg_nr = ((p->opcode >> 8) & 0x000F);
- saved_next_opcode.addr =
- (kprobe_opcode_t *) regs->regs[reg_nr];
+ op1->addr = (kprobe_opcode_t *) regs->regs[reg_nr];
} else if (OPCODE_BRA(p->opcode) || OPCODE_BSR(p->opcode)) {
unsigned long disp = (p->opcode & 0x0FFF);
- saved_next_opcode.addr =
+ op1->addr =
(kprobe_opcode_t *) (regs->pc + 4 + disp * 2);
} else if (OPCODE_BRAF(p->opcode) || OPCODE_BSRF(p->opcode)) {
unsigned int reg_nr = ((p->opcode >> 8) & 0x000F);
- saved_next_opcode.addr =
+ op1->addr =
(kprobe_opcode_t *) (regs->pc + 4 +
regs->regs[reg_nr]);
} else if (OPCODE_RTS(p->opcode)) {
- saved_next_opcode.addr = (kprobe_opcode_t *) regs->pr;
+ op1->addr = (kprobe_opcode_t *) regs->pr;
} else if (OPCODE_BF(p->opcode) || OPCODE_BT(p->opcode)) {
unsigned long disp = (p->opcode & 0x00FF);
/* case 1 */
- saved_next_opcode.addr = p->addr + 1;
+ op1->addr = p->addr + 1;
/* case 2 */
- saved_next_opcode2.addr =
+ op2->addr =
(kprobe_opcode_t *) (regs->pc + 4 + disp * 2);
- saved_next_opcode2.opcode = *(saved_next_opcode2.addr);
- arch_arm_kprobe(&saved_next_opcode2);
+ op2->opcode = *(op2->addr);
+ arch_arm_kprobe(op2);
} else if (OPCODE_BF_S(p->opcode) || OPCODE_BT_S(p->opcode)) {
unsigned long disp = (p->opcode & 0x00FF);
/* case 1 */
- saved_next_opcode.addr = p->addr + 2;
+ op1->addr = p->addr + 2;
/* case 2 */
- saved_next_opcode2.addr =
+ op2->addr =
(kprobe_opcode_t *) (regs->pc + 4 + disp * 2);
- saved_next_opcode2.opcode = *(saved_next_opcode2.addr);
- arch_arm_kprobe(&saved_next_opcode2);
+ op2->opcode = *(op2->addr);
+ arch_arm_kprobe(op2);
} else {
- saved_next_opcode.addr = p->addr + 1;
+ op1->addr = p->addr + 1;
}
- saved_next_opcode.opcode = *(saved_next_opcode.addr);
- arch_arm_kprobe(&saved_next_opcode);
+ op1->opcode = *(op1->addr);
+ arch_arm_kprobe(op1);
}
}
@@ -376,21 +383,23 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs)
cur->post_handler(cur, regs, 0);
}
- if (saved_next_opcode.addr != 0x0) {
- arch_disarm_kprobe(&saved_next_opcode);
- saved_next_opcode.addr = 0x0;
- saved_next_opcode.opcode = 0x0;
+ p = &__get_cpu_var(saved_next_opcode);
+ if (p->addr) {
+ arch_disarm_kprobe(p);
+ p->addr = NULL;
+ p->opcode = 0;
- addr = saved_current_opcode.addr;
- saved_current_opcode.addr = 0x0;
+ addr = __get_cpu_var(saved_current_opcode).addr;
+ __get_cpu_var(saved_current_opcode).addr = NULL;
p = get_kprobe(addr);
arch_arm_kprobe(p);
- if (saved_next_opcode2.addr != 0x0) {
- arch_disarm_kprobe(&saved_next_opcode2);
- saved_next_opcode2.addr = 0x0;
- saved_next_opcode2.opcode = 0x0;
+ p = &__get_cpu_var(saved_next_opcode2);
+ if (p->addr) {
+ arch_disarm_kprobe(p);
+ p->addr = NULL;
+ p->opcode = 0;
}
}
@@ -572,14 +581,5 @@ static struct kprobe trampoline_p = {
int __init arch_init_kprobes(void)
{
- saved_next_opcode.addr = 0x0;
- saved_next_opcode.opcode = 0x0;
-
- saved_current_opcode.addr = 0x0;
- saved_current_opcode.opcode = 0x0;
-
- saved_next_opcode2.addr = 0x0;
- saved_next_opcode2.opcode = 0x0;
-
return register_kprobe(&trampoline_p);
}
diff --git a/arch/sh/kernel/module.c b/arch/sh/kernel/module.c
index 43adddfe4c04..ae0be697a89e 100644
--- a/arch/sh/kernel/module.c
+++ b/arch/sh/kernel/module.c
@@ -149,13 +149,11 @@ int module_finalize(const Elf_Ehdr *hdr,
int ret = 0;
ret |= module_dwarf_finalize(hdr, sechdrs, me);
- ret |= module_bug_finalize(hdr, sechdrs, me);
return ret;
}
void module_arch_cleanup(struct module *mod)
{
- module_bug_cleanup(mod);
module_dwarf_cleanup(mod);
}
diff --git a/arch/sh/kernel/perf_callchain.c b/arch/sh/kernel/perf_callchain.c
index a9dd3abde28e..d5ca1ef50fa9 100644
--- a/arch/sh/kernel/perf_callchain.c
+++ b/arch/sh/kernel/perf_callchain.c
@@ -14,11 +14,6 @@
#include <asm/unwinder.h>
#include <asm/ptrace.h>
-static inline void callchain_store(struct perf_callchain_entry *entry, u64 ip)
-{
- if (entry->nr < PERF_MAX_STACK_DEPTH)
- entry->ip[entry->nr++] = ip;
-}
static void callchain_warning(void *data, char *msg)
{
@@ -39,7 +34,7 @@ static void callchain_address(void *data, unsigned long addr, int reliable)
struct perf_callchain_entry *entry = data;
if (reliable)
- callchain_store(entry, addr);
+ perf_callchain_store(entry, addr);
}
static const struct stacktrace_ops callchain_ops = {
@@ -49,47 +44,10 @@ static const struct stacktrace_ops callchain_ops = {
.address = callchain_address,
};
-static void
-perf_callchain_kernel(struct pt_regs *regs, struct perf_callchain_entry *entry)
+void
+perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs)
{
- callchain_store(entry, PERF_CONTEXT_KERNEL);
- callchain_store(entry, regs->pc);
+ perf_callchain_store(entry, regs->pc);
unwind_stack(NULL, regs, NULL, &callchain_ops, entry);
}
-
-static void
-perf_do_callchain(struct pt_regs *regs, struct perf_callchain_entry *entry)
-{
- int is_user;
-
- if (!regs)
- return;
-
- is_user = user_mode(regs);
-
- if (is_user && current->state != TASK_RUNNING)
- return;
-
- /*
- * Only the kernel side is implemented for now.
- */
- if (!is_user)
- perf_callchain_kernel(regs, entry);
-}
-
-/*
- * No need for separate IRQ and NMI entries.
- */
-static DEFINE_PER_CPU(struct perf_callchain_entry, callchain);
-
-struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
-{
- struct perf_callchain_entry *entry = &__get_cpu_var(callchain);
-
- entry->nr = 0;
-
- perf_do_callchain(regs, entry);
-
- return entry;
-}
diff --git a/arch/sh/kernel/perf_event.c b/arch/sh/kernel/perf_event.c
index 7a3dc3567258..5a4b33435650 100644
--- a/arch/sh/kernel/perf_event.c
+++ b/arch/sh/kernel/perf_event.c
@@ -59,6 +59,24 @@ static inline int sh_pmu_initialized(void)
return !!sh_pmu;
}
+const char *perf_pmu_name(void)
+{
+ if (!sh_pmu)
+ return NULL;
+
+ return sh_pmu->name;
+}
+EXPORT_SYMBOL_GPL(perf_pmu_name);
+
+int perf_num_counters(void)
+{
+ if (!sh_pmu)
+ return 0;
+
+ return sh_pmu->num_events;
+}
+EXPORT_SYMBOL_GPL(perf_num_counters);
+
/*
* Release the PMU if this is the last perf_event.
*/
@@ -206,50 +224,80 @@ again:
local64_add(delta, &event->count);
}
-static void sh_pmu_disable(struct perf_event *event)
+static void sh_pmu_stop(struct perf_event *event, int flags)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
struct hw_perf_event *hwc = &event->hw;
int idx = hwc->idx;
- clear_bit(idx, cpuc->active_mask);
- sh_pmu->disable(hwc, idx);
+ if (!(event->hw.state & PERF_HES_STOPPED)) {
+ sh_pmu->disable(hwc, idx);
+ cpuc->events[idx] = NULL;
+ event->hw.state |= PERF_HES_STOPPED;
+ }
+
+ if ((flags & PERF_EF_UPDATE) && !(event->hw.state & PERF_HES_UPTODATE)) {
+ sh_perf_event_update(event, &event->hw, idx);
+ event->hw.state |= PERF_HES_UPTODATE;
+ }
+}
+
+static void sh_pmu_start(struct perf_event *event, int flags)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ struct hw_perf_event *hwc = &event->hw;
+ int idx = hwc->idx;
+
+ if (WARN_ON_ONCE(idx == -1))
+ return;
+
+ if (flags & PERF_EF_RELOAD)
+ WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE));
- barrier();
+ cpuc->events[idx] = event;
+ event->hw.state = 0;
+ sh_pmu->enable(hwc, idx);
+}
- sh_perf_event_update(event, &event->hw, idx);
+static void sh_pmu_del(struct perf_event *event, int flags)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
- cpuc->events[idx] = NULL;
- clear_bit(idx, cpuc->used_mask);
+ sh_pmu_stop(event, PERF_EF_UPDATE);
+ __clear_bit(event->hw.idx, cpuc->used_mask);
perf_event_update_userpage(event);
}
-static int sh_pmu_enable(struct perf_event *event)
+static int sh_pmu_add(struct perf_event *event, int flags)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
struct hw_perf_event *hwc = &event->hw;
int idx = hwc->idx;
+ int ret = -EAGAIN;
+
+ perf_pmu_disable(event->pmu);
- if (test_and_set_bit(idx, cpuc->used_mask)) {
+ if (__test_and_set_bit(idx, cpuc->used_mask)) {
idx = find_first_zero_bit(cpuc->used_mask, sh_pmu->num_events);
if (idx == sh_pmu->num_events)
- return -EAGAIN;
+ goto out;
- set_bit(idx, cpuc->used_mask);
+ __set_bit(idx, cpuc->used_mask);
hwc->idx = idx;
}
sh_pmu->disable(hwc, idx);
- cpuc->events[idx] = event;
- set_bit(idx, cpuc->active_mask);
-
- sh_pmu->enable(hwc, idx);
+ event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
+ if (flags & PERF_EF_START)
+ sh_pmu_start(event, PERF_EF_RELOAD);
perf_event_update_userpage(event);
-
- return 0;
+ ret = 0;
+out:
+ perf_pmu_enable(event->pmu);
+ return ret;
}
static void sh_pmu_read(struct perf_event *event)
@@ -257,24 +305,56 @@ static void sh_pmu_read(struct perf_event *event)
sh_perf_event_update(event, &event->hw, event->hw.idx);
}
-static const struct pmu pmu = {
- .enable = sh_pmu_enable,
- .disable = sh_pmu_disable,
- .read = sh_pmu_read,
-};
-
-const struct pmu *hw_perf_event_init(struct perf_event *event)
+static int sh_pmu_event_init(struct perf_event *event)
{
- int err = __hw_perf_event_init(event);
+ int err;
+
+ switch (event->attr.type) {
+ case PERF_TYPE_RAW:
+ case PERF_TYPE_HW_CACHE:
+ case PERF_TYPE_HARDWARE:
+ err = __hw_perf_event_init(event);
+ break;
+
+ default:
+ return -ENOENT;
+ }
+
if (unlikely(err)) {
if (event->destroy)
event->destroy(event);
- return ERR_PTR(err);
}
- return &pmu;
+ return err;
+}
+
+static void sh_pmu_enable(struct pmu *pmu)
+{
+ if (!sh_pmu_initialized())
+ return;
+
+ sh_pmu->enable_all();
+}
+
+static void sh_pmu_disable(struct pmu *pmu)
+{
+ if (!sh_pmu_initialized())
+ return;
+
+ sh_pmu->disable_all();
}
+static struct pmu pmu = {
+ .pmu_enable = sh_pmu_enable,
+ .pmu_disable = sh_pmu_disable,
+ .event_init = sh_pmu_event_init,
+ .add = sh_pmu_add,
+ .del = sh_pmu_del,
+ .start = sh_pmu_start,
+ .stop = sh_pmu_stop,
+ .read = sh_pmu_read,
+};
+
static void sh_pmu_setup(int cpu)
{
struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu);
@@ -299,32 +379,17 @@ sh_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
return NOTIFY_OK;
}
-void hw_perf_enable(void)
-{
- if (!sh_pmu_initialized())
- return;
-
- sh_pmu->enable_all();
-}
-
-void hw_perf_disable(void)
-{
- if (!sh_pmu_initialized())
- return;
-
- sh_pmu->disable_all();
-}
-
-int __cpuinit register_sh_pmu(struct sh_pmu *pmu)
+int __cpuinit register_sh_pmu(struct sh_pmu *_pmu)
{
if (sh_pmu)
return -EBUSY;
- sh_pmu = pmu;
+ sh_pmu = _pmu;
- pr_info("Performance Events: %s support registered\n", pmu->name);
+ pr_info("Performance Events: %s support registered\n", _pmu->name);
- WARN_ON(pmu->num_events > MAX_HWEVENTS);
+ WARN_ON(_pmu->num_events > MAX_HWEVENTS);
+ perf_pmu_register(&pmu);
perf_cpu_notifier(sh_pmu_notifier);
return 0;
}
diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c
new file mode 100644
index 000000000000..0a05983633ca
--- /dev/null
+++ b/arch/sh/kernel/ptrace.c
@@ -0,0 +1,33 @@
+#include <linux/ptrace.h>
+
+/**
+ * regs_query_register_offset() - query register offset from its name
+ * @name: the name of a register
+ *
+ * regs_query_register_offset() returns the offset of a register in struct
+ * pt_regs from its name. If the name is invalid, this returns -EINVAL;
+ */
+int regs_query_register_offset(const char *name)
+{
+ const struct pt_regs_offset *roff;
+ for (roff = regoffset_table; roff->name != NULL; roff++)
+ if (!strcmp(roff->name, name))
+ return roff->offset;
+ return -EINVAL;
+}
+
+/**
+ * regs_query_register_name() - query register name from its offset
+ * @offset: the offset of a register in struct pt_regs.
+ *
+ * regs_query_register_name() returns the name of a register from its
+ * offset in struct pt_regs. If the @offset is invalid, this returns NULL;
+ */
+const char *regs_query_register_name(unsigned int offset)
+{
+ const struct pt_regs_offset *roff;
+ for (roff = regoffset_table; roff->name != NULL; roff++)
+ if (roff->offset == offset)
+ return roff->name;
+ return NULL;
+}
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c
index 6c4bbba2a675..2cd42b58cb20 100644
--- a/arch/sh/kernel/ptrace_32.c
+++ b/arch/sh/kernel/ptrace_32.c
@@ -274,6 +274,33 @@ static int dspregs_active(struct task_struct *target,
}
#endif
+const struct pt_regs_offset regoffset_table[] = {
+ REGS_OFFSET_NAME(0),
+ REGS_OFFSET_NAME(1),
+ REGS_OFFSET_NAME(2),
+ REGS_OFFSET_NAME(3),
+ REGS_OFFSET_NAME(4),
+ REGS_OFFSET_NAME(5),
+ REGS_OFFSET_NAME(6),
+ REGS_OFFSET_NAME(7),
+ REGS_OFFSET_NAME(8),
+ REGS_OFFSET_NAME(9),
+ REGS_OFFSET_NAME(10),
+ REGS_OFFSET_NAME(11),
+ REGS_OFFSET_NAME(12),
+ REGS_OFFSET_NAME(13),
+ REGS_OFFSET_NAME(14),
+ REGS_OFFSET_NAME(15),
+ REG_OFFSET_NAME(pc),
+ REG_OFFSET_NAME(pr),
+ REG_OFFSET_NAME(sr),
+ REG_OFFSET_NAME(gbr),
+ REG_OFFSET_NAME(mach),
+ REG_OFFSET_NAME(macl),
+ REG_OFFSET_NAME(tra),
+ REG_OFFSET_END,
+};
+
/*
* These are our native regset flavours.
*/
diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c
index 5fd644da7f02..e0fb065914aa 100644
--- a/arch/sh/kernel/ptrace_64.c
+++ b/arch/sh/kernel/ptrace_64.c
@@ -20,7 +20,7 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
+#include <linux/bitops.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
@@ -252,6 +252,85 @@ static int fpregs_active(struct task_struct *target,
}
#endif
+const struct pt_regs_offset regoffset_table[] = {
+ REG_OFFSET_NAME(pc),
+ REG_OFFSET_NAME(sr),
+ REG_OFFSET_NAME(syscall_nr),
+ REGS_OFFSET_NAME(0),
+ REGS_OFFSET_NAME(1),
+ REGS_OFFSET_NAME(2),
+ REGS_OFFSET_NAME(3),
+ REGS_OFFSET_NAME(4),
+ REGS_OFFSET_NAME(5),
+ REGS_OFFSET_NAME(6),
+ REGS_OFFSET_NAME(7),
+ REGS_OFFSET_NAME(8),
+ REGS_OFFSET_NAME(9),
+ REGS_OFFSET_NAME(10),
+ REGS_OFFSET_NAME(11),
+ REGS_OFFSET_NAME(12),
+ REGS_OFFSET_NAME(13),
+ REGS_OFFSET_NAME(14),
+ REGS_OFFSET_NAME(15),
+ REGS_OFFSET_NAME(16),
+ REGS_OFFSET_NAME(17),
+ REGS_OFFSET_NAME(18),
+ REGS_OFFSET_NAME(19),
+ REGS_OFFSET_NAME(20),
+ REGS_OFFSET_NAME(21),
+ REGS_OFFSET_NAME(22),
+ REGS_OFFSET_NAME(23),
+ REGS_OFFSET_NAME(24),
+ REGS_OFFSET_NAME(25),
+ REGS_OFFSET_NAME(26),
+ REGS_OFFSET_NAME(27),
+ REGS_OFFSET_NAME(28),
+ REGS_OFFSET_NAME(29),
+ REGS_OFFSET_NAME(30),
+ REGS_OFFSET_NAME(31),
+ REGS_OFFSET_NAME(32),
+ REGS_OFFSET_NAME(33),
+ REGS_OFFSET_NAME(34),
+ REGS_OFFSET_NAME(35),
+ REGS_OFFSET_NAME(36),
+ REGS_OFFSET_NAME(37),
+ REGS_OFFSET_NAME(38),
+ REGS_OFFSET_NAME(39),
+ REGS_OFFSET_NAME(40),
+ REGS_OFFSET_NAME(41),
+ REGS_OFFSET_NAME(42),
+ REGS_OFFSET_NAME(43),
+ REGS_OFFSET_NAME(44),
+ REGS_OFFSET_NAME(45),
+ REGS_OFFSET_NAME(46),
+ REGS_OFFSET_NAME(47),
+ REGS_OFFSET_NAME(48),
+ REGS_OFFSET_NAME(49),
+ REGS_OFFSET_NAME(50),
+ REGS_OFFSET_NAME(51),
+ REGS_OFFSET_NAME(52),
+ REGS_OFFSET_NAME(53),
+ REGS_OFFSET_NAME(54),
+ REGS_OFFSET_NAME(55),
+ REGS_OFFSET_NAME(56),
+ REGS_OFFSET_NAME(57),
+ REGS_OFFSET_NAME(58),
+ REGS_OFFSET_NAME(59),
+ REGS_OFFSET_NAME(60),
+ REGS_OFFSET_NAME(61),
+ REGS_OFFSET_NAME(62),
+ REGS_OFFSET_NAME(63),
+ TREGS_OFFSET_NAME(0),
+ TREGS_OFFSET_NAME(1),
+ TREGS_OFFSET_NAME(2),
+ TREGS_OFFSET_NAME(3),
+ TREGS_OFFSET_NAME(4),
+ TREGS_OFFSET_NAME(5),
+ TREGS_OFFSET_NAME(6),
+ TREGS_OFFSET_NAME(7),
+ REG_OFFSET_END,
+};
+
/*
* These are our native regset flavours.
*/
@@ -395,10 +474,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
asmlinkage int sh64_ptrace(long request, long pid, long addr, long data)
{
#define WPC_DBRMODE 0x0d104008
- static int first_call = 1;
+ static unsigned long first_call;
- lock_kernel();
- if (first_call) {
+ if (!test_and_set_bit(0, &first_call)) {
/* Set WPC.DBRMODE to 0. This makes all debug events get
* delivered through RESVEC, i.e. into the handlers in entry.S.
* (If the kernel was downloaded using a remote gdb, WPC.DBRMODE
@@ -408,9 +486,7 @@ asmlinkage int sh64_ptrace(long request, long pid, long addr, long data)
* the remote gdb.) */
printk("DBRMODE set to 0 to permit native debugging\n");
poke_real_address_q(WPC_DBRMODE, 0);
- first_call = 0;
}
- unlock_kernel();
return sys_ptrace(request, pid, addr, data);
}
diff --git a/arch/sh/kernel/reboot.c b/arch/sh/kernel/reboot.c
index b1fca66bb92e..ca6a5ca64015 100644
--- a/arch/sh/kernel/reboot.c
+++ b/arch/sh/kernel/reboot.c
@@ -9,6 +9,7 @@
#include <asm/addrspace.h>
#include <asm/reboot.h>
#include <asm/system.h>
+#include <asm/tlbflush.h>
void (*pm_power_off)(void);
EXPORT_SYMBOL(pm_power_off);
@@ -25,6 +26,9 @@ static void native_machine_restart(char * __unused)
{
local_irq_disable();
+ /* Destroy all of the TLBs in preparation for reset by MMU */
+ __flush_tlb_global();
+
/* Address error with SR.BL=1 first. */
trigger_address_error();
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index e769401a78ba..4e278467f76c 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -24,7 +24,6 @@
#include <linux/module.h>
#include <linux/smp.h>
#include <linux/err.h>
-#include <linux/debugfs.h>
#include <linux/crash_dump.h>
#include <linux/mmzone.h>
#include <linux/clk.h>
@@ -136,8 +135,9 @@ void __init check_for_initrd(void)
goto disable;
}
- if (unlikely(start < PAGE_OFFSET)) {
- pr_err("initrd start < PAGE_OFFSET\n");
+ if (unlikely(start < __MEMORY_START)) {
+ pr_err("initrd start (%08lx) < __MEMORY_START(%x)\n",
+ start, __MEMORY_START);
goto disable;
}
@@ -158,7 +158,7 @@ void __init check_for_initrd(void)
/*
* Address sanitization
*/
- initrd_start = (unsigned long)__va(__pa(start));
+ initrd_start = (unsigned long)__va(start);
initrd_end = initrd_start + INITRD_SIZE;
memblock_reserve(__pa(initrd_start), INITRD_SIZE);
@@ -458,17 +458,3 @@ const struct seq_operations cpuinfo_op = {
.show = show_cpuinfo,
};
#endif /* CONFIG_PROC_FS */
-
-struct dentry *sh_debugfs_root;
-
-static int __init sh_debugfs_init(void)
-{
- sh_debugfs_root = debugfs_create_dir("sh", NULL);
- if (!sh_debugfs_root)
- return -ENOMEM;
- if (IS_ERR(sh_debugfs_root))
- return PTR_ERR(sh_debugfs_root);
-
- return 0;
-}
-arch_initcall(sh_debugfs_init);
diff --git a/arch/sh/kernel/syscalls_32.S b/arch/sh/kernel/syscalls_32.S
index 19fd11dd9871..e872e81add8a 100644
--- a/arch/sh/kernel/syscalls_32.S
+++ b/arch/sh/kernel/syscalls_32.S
@@ -353,3 +353,25 @@ ENTRY(sys_call_table)
.long sys_pwritev
.long sys_rt_tgsigqueueinfo /* 335 */
.long sys_perf_event_open
+ .long sys_fanotify_init
+ .long sys_fanotify_mark
+ .long sys_prlimit64
+ /* Broken-out socket family */
+ .long sys_socket /* 340 */
+ .long sys_bind
+ .long sys_connect
+ .long sys_listen
+ .long sys_accept
+ .long sys_getsockname /* 345 */
+ .long sys_getpeername
+ .long sys_socketpair
+ .long sys_send
+ .long sys_sendto
+ .long sys_recv /* 350 */
+ .long sys_recvfrom
+ .long sys_shutdown
+ .long sys_setsockopt
+ .long sys_getsockopt
+ .long sys_sendmsg /* 355 */
+ .long sys_recvmsg
+ .long sys_recvmmsg
diff --git a/arch/sh/kernel/syscalls_64.S b/arch/sh/kernel/syscalls_64.S
index 2048a20d7c80..66585708ce90 100644
--- a/arch/sh/kernel/syscalls_64.S
+++ b/arch/sh/kernel/syscalls_64.S
@@ -393,3 +393,6 @@ sys_call_table:
.long sys_perf_event_open
.long sys_recvmmsg /* 365 */
.long sys_accept4
+ .long sys_fanotify_init
+ .long sys_fanotify_mark
+ .long sys_prlimit64
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index c3d86fa71ddf..3484c2f65aba 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -5,7 +5,7 @@
* SuperH version: Copyright (C) 1999 Niibe Yutaka
* Copyright (C) 2000 Philipp Rumpf
* Copyright (C) 2000 David Howells
- * Copyright (C) 2002 - 2007 Paul Mundt
+ * Copyright (C) 2002 - 2010 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -26,6 +26,7 @@
#include <linux/limits.h>
#include <linux/sysfs.h>
#include <linux/uaccess.h>
+#include <linux/perf_event.h>
#include <asm/system.h>
#include <asm/alignment.h>
#include <asm/fpu.h>
@@ -369,7 +370,8 @@ static inline int handle_delayslot(struct pt_regs *regs,
#define SH_PC_12BIT_OFFSET(instr) ((((signed short)(instr<<4))>>3) + 4)
int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
- struct mem_access *ma, int expected)
+ struct mem_access *ma, int expected,
+ unsigned long address)
{
u_int rm;
int ret, index;
@@ -383,9 +385,18 @@ int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
index = (instruction>>8)&15; /* 0x0F00 */
rm = regs->regs[index];
- /* shout about fixups */
- if (!expected)
+ /*
+ * Log the unexpected fixups, and then pass them on to perf.
+ *
+ * We intentionally don't report the expected cases to perf as
+ * otherwise the trapped I/O case will skew the results too much
+ * to be useful.
+ */
+ if (!expected) {
unaligned_fixups_notify(current, instruction, regs);
+ perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0,
+ regs, address);
+ }
ret = -EFAULT;
switch (instruction&0xF000) {
@@ -574,7 +585,8 @@ fixup:
set_fs(USER_DS);
tmp = handle_unaligned_access(instruction, regs,
- &user_mem_access, 0);
+ &user_mem_access, 0,
+ address);
set_fs(oldfs);
if (tmp == 0)
@@ -607,8 +619,8 @@ uspace_segv:
unaligned_fixups_notify(current, instruction, regs);
- handle_unaligned_access(instruction, regs,
- &user_mem_access, 0);
+ handle_unaligned_access(instruction, regs, &user_mem_access,
+ 0, address);
set_fs(oldfs);
}
}
@@ -802,6 +814,9 @@ void __cpuinit per_cpu_trap_init(void)
: /* no output */
: "r" (&vbr_base)
: "memory");
+
+ /* disable exception blocking now when the vbr has been setup */
+ clear_bl_bit();
}
void *set_exception_table_vec(unsigned int vec, void *handler)
diff --git a/arch/sh/kernel/traps_64.c b/arch/sh/kernel/traps_64.c
index e67e140bf1f6..6713ca97e553 100644
--- a/arch/sh/kernel/traps_64.c
+++ b/arch/sh/kernel/traps_64.c
@@ -24,6 +24,7 @@
#include <linux/interrupt.h>
#include <linux/sysctl.h>
#include <linux/module.h>
+#include <linux/perf_event.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -50,7 +51,7 @@ asmlinkage void do_##name(unsigned long error_code, struct pt_regs *regs) \
do_unhandled_exception(trapnr, signr, str, __stringify(name), error_code, regs, current); \
}
-spinlock_t die_lock;
+static DEFINE_SPINLOCK(die_lock);
void die(const char * str, struct pt_regs * regs, long err)
{
@@ -433,6 +434,8 @@ static int misaligned_load(struct pt_regs *regs,
return error;
}
+ perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, address);
+
destreg = (opcode >> 4) & 0x3f;
if (user_mode(regs)) {
__u64 buffer;
@@ -509,6 +512,8 @@ static int misaligned_store(struct pt_regs *regs,
return error;
}
+ perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, address);
+
srcreg = (opcode >> 4) & 0x3f;
if (user_mode(regs)) {
__u64 buffer;
@@ -583,6 +588,8 @@ static int misaligned_fpu_load(struct pt_regs *regs,
return error;
}
+ perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, address);
+
destreg = (opcode >> 4) & 0x3f;
if (user_mode(regs)) {
__u64 buffer;
@@ -658,6 +665,8 @@ static int misaligned_fpu_store(struct pt_regs *regs,
return error;
}
+ perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, address);
+
srcreg = (opcode >> 4) & 0x3f;
if (user_mode(regs)) {
__u64 buffer;
diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile
index dab4d2129812..7b95f29e3174 100644
--- a/arch/sh/lib/Makefile
+++ b/arch/sh/lib/Makefile
@@ -30,4 +30,4 @@ lib-$(CONFIG_MMU) += copy_page.o __clear_user.o
lib-$(CONFIG_MCOUNT) += mcount.o
lib-y += $(memcpy-y) $(memset-y) $(udivsi3-y)
-EXTRA_CFLAGS += -Werror
+ccflags-y := -Werror
diff --git a/arch/sh/math-emu/math.c b/arch/sh/math-emu/math.c
index 1fcdb1220975..f76a5090d5d1 100644
--- a/arch/sh/math-emu/math.c
+++ b/arch/sh/math-emu/math.c
@@ -12,6 +12,7 @@
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/signal.h>
+#include <linux/perf_event.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -619,6 +620,8 @@ int do_fpu_inst(unsigned short inst, struct pt_regs *regs)
struct task_struct *tsk = current;
struct sh_fpu_soft_struct *fpu = &(tsk->thread.xstate->softfpu);
+ perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0);
+
if (!(task_thread_info(tsk)->status & TS_USEDFPU)) {
/* initialize once. */
fpu_init(fpu);
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig
index 1445ca6257df..09370392aff1 100644
--- a/arch/sh/mm/Kconfig
+++ b/arch/sh/mm/Kconfig
@@ -168,6 +168,10 @@ config IOREMAP_FIXED
config UNCACHED_MAPPING
bool
+config HAVE_SRAM_POOL
+ bool
+ select GENERIC_ALLOCATOR
+
choice
prompt "Kernel page size"
default PAGE_SIZE_4KB
diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile
index 53f7c684afb2..ab89ea4f9414 100644
--- a/arch/sh/mm/Makefile
+++ b/arch/sh/mm/Makefile
@@ -40,6 +40,7 @@ obj-$(CONFIG_PMB) += pmb.o
obj-$(CONFIG_NUMA) += numa.o
obj-$(CONFIG_IOREMAP_FIXED) += ioremap_fixed.o
obj-$(CONFIG_UNCACHED_MAPPING) += uncached.o
+obj-$(CONFIG_HAVE_SRAM_POOL) += sram.o
# Special flags for fault_64.o. This puts restrictions on the number of
# caller-save registers that the compiler can target when building this file.
@@ -66,4 +67,4 @@ CFLAGS_fault_64.o += -ffixed-r7 \
-ffixed-r60 -ffixed-r61 -ffixed-r62 \
-fomit-frame-pointer
-EXTRA_CFLAGS += -Werror
+ccflags-y := -Werror
diff --git a/arch/sh/mm/asids-debugfs.c b/arch/sh/mm/asids-debugfs.c
index cd8c3bf39b5a..74c03ecc4871 100644
--- a/arch/sh/mm/asids-debugfs.c
+++ b/arch/sh/mm/asids-debugfs.c
@@ -63,7 +63,7 @@ static int __init asids_debugfs_init(void)
{
struct dentry *asids_dentry;
- asids_dentry = debugfs_create_file("asids", S_IRUSR, sh_debugfs_root,
+ asids_dentry = debugfs_create_file("asids", S_IRUSR, arch_debugfs_dir,
NULL, &asids_debugfs_fops);
if (!asids_dentry)
return -ENOMEM;
diff --git a/arch/sh/mm/cache-debugfs.c b/arch/sh/mm/cache-debugfs.c
index 690ed010d002..52411462c409 100644
--- a/arch/sh/mm/cache-debugfs.c
+++ b/arch/sh/mm/cache-debugfs.c
@@ -126,25 +126,19 @@ static int __init cache_debugfs_init(void)
{
struct dentry *dcache_dentry, *icache_dentry;
- dcache_dentry = debugfs_create_file("dcache", S_IRUSR, sh_debugfs_root,
+ dcache_dentry = debugfs_create_file("dcache", S_IRUSR, arch_debugfs_dir,
(unsigned int *)CACHE_TYPE_DCACHE,
&cache_debugfs_fops);
if (!dcache_dentry)
return -ENOMEM;
- if (IS_ERR(dcache_dentry))
- return PTR_ERR(dcache_dentry);
- icache_dentry = debugfs_create_file("icache", S_IRUSR, sh_debugfs_root,
+ icache_dentry = debugfs_create_file("icache", S_IRUSR, arch_debugfs_dir,
(unsigned int *)CACHE_TYPE_ICACHE,
&cache_debugfs_fops);
if (!icache_dentry) {
debugfs_remove(dcache_dentry);
return -ENOMEM;
}
- if (IS_ERR(icache_dentry)) {
- debugfs_remove(dcache_dentry);
- return PTR_ERR(icache_dentry);
- }
return 0;
}
diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c
index c86a08540258..038793286990 100644
--- a/arch/sh/mm/consistent.c
+++ b/arch/sh/mm/consistent.c
@@ -38,11 +38,12 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size,
void *ret, *ret_nocache;
int order = get_order(size);
+ gfp |= __GFP_ZERO;
+
ret = (void *)__get_free_pages(gfp, order);
if (!ret)
return NULL;
- memset(ret, 0, size);
/*
* Pages from the page allocator may have data present in
* cache. So flush the cache before using uncached memory.
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index d0e249100e98..3385b28acaac 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -47,7 +47,6 @@ static pte_t *__get_pte_phys(unsigned long addr)
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
- pte_t *pte;
pgd = pgd_offset_k(addr);
if (pgd_none(*pgd)) {
@@ -67,8 +66,7 @@ static pte_t *__get_pte_phys(unsigned long addr)
return NULL;
}
- pte = pte_offset_kernel(pmd, addr);
- return pte;
+ return pte_offset_kernel(pmd, addr);
}
static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot)
@@ -125,13 +123,45 @@ void __clear_fixmap(enum fixed_addresses idx, pgprot_t prot)
clear_pte_phys(address, prot);
}
+static pmd_t * __init one_md_table_init(pud_t *pud)
+{
+ if (pud_none(*pud)) {
+ pmd_t *pmd;
+
+ pmd = alloc_bootmem_pages(PAGE_SIZE);
+ pud_populate(&init_mm, pud, pmd);
+ BUG_ON(pmd != pmd_offset(pud, 0));
+ }
+
+ return pmd_offset(pud, 0);
+}
+
+static pte_t * __init one_page_table_init(pmd_t *pmd)
+{
+ if (pmd_none(*pmd)) {
+ pte_t *pte;
+
+ pte = alloc_bootmem_pages(PAGE_SIZE);
+ pmd_populate_kernel(&init_mm, pmd, pte);
+ BUG_ON(pte != pte_offset_kernel(pmd, 0));
+ }
+
+ return pte_offset_kernel(pmd, 0);
+}
+
+static pte_t * __init page_table_kmap_check(pte_t *pte, pmd_t *pmd,
+ unsigned long vaddr, pte_t *lastpte)
+{
+ return pte;
+}
+
void __init page_table_range_init(unsigned long start, unsigned long end,
pgd_t *pgd_base)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
- pte_t *pte;
+ pte_t *pte = NULL;
int i, j, k;
unsigned long vaddr;
@@ -144,19 +174,13 @@ void __init page_table_range_init(unsigned long start, unsigned long end,
for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
pud = (pud_t *)pgd;
for ( ; (j < PTRS_PER_PUD) && (vaddr != end); pud++, j++) {
-#ifdef __PAGETABLE_PMD_FOLDED
- pmd = (pmd_t *)pud;
-#else
- pmd = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);
- pud_populate(&init_mm, pud, pmd);
+ pmd = one_md_table_init(pud);
+#ifndef __PAGETABLE_PMD_FOLDED
pmd += k;
#endif
for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) {
- if (pmd_none(*pmd)) {
- pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
- pmd_populate_kernel(&init_mm, pmd, pte);
- BUG_ON(pte != pte_offset_kernel(pmd, 0));
- }
+ pte = page_table_kmap_check(one_page_table_init(pmd),
+ pmd, vaddr, pte);
vaddr += PMD_SIZE;
}
k = 0;
@@ -200,7 +224,6 @@ static void __init bootmem_init_one_node(unsigned int nid)
unsigned long total_pages, paddr;
unsigned long end_pfn;
struct pglist_data *p;
- int i;
p = NODE_DATA(nid);
@@ -226,11 +249,12 @@ static void __init bootmem_init_one_node(unsigned int nid)
* reservations in other nodes.
*/
if (nid == 0) {
+ struct memblock_region *reg;
+
/* Reserve the sections we're already using. */
- for (i = 0; i < memblock.reserved.cnt; i++)
- reserve_bootmem(memblock.reserved.region[i].base,
- memblock_size_bytes(&memblock.reserved, i),
- BOOTMEM_DEFAULT);
+ for_each_memblock(reserved, reg) {
+ reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT);
+ }
}
sparse_memory_present_with_active_regions(nid);
@@ -238,13 +262,14 @@ static void __init bootmem_init_one_node(unsigned int nid)
static void __init do_init_bootmem(void)
{
+ struct memblock_region *reg;
int i;
/* Add active regions with valid PFNs. */
- for (i = 0; i < memblock.memory.cnt; i++) {
+ for_each_memblock(memory, reg) {
unsigned long start_pfn, end_pfn;
- start_pfn = memblock.memory.region[i].base >> PAGE_SHIFT;
- end_pfn = start_pfn + memblock_size_pages(&memblock.memory, i);
+ start_pfn = memblock_region_memory_base_pfn(reg);
+ end_pfn = memblock_region_memory_end_pfn(reg);
__add_active_range(0, start_pfn, end_pfn);
}
diff --git a/arch/sh/mm/nommu.c b/arch/sh/mm/nommu.c
index 7694f50c9034..36312d254faf 100644
--- a/arch/sh/mm/nommu.c
+++ b/arch/sh/mm/nommu.c
@@ -67,6 +67,10 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
BUG();
}
+void __flush_tlb_global(void)
+{
+}
+
void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
{
}
diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c
index 6379091a1647..b20b1b3eee4b 100644
--- a/arch/sh/mm/pmb.c
+++ b/arch/sh/mm/pmb.c
@@ -40,7 +40,7 @@ struct pmb_entry {
unsigned long flags;
unsigned long size;
- spinlock_t lock;
+ raw_spinlock_t lock;
/*
* 0 .. NR_PMB_ENTRIES for specific entry selection, or
@@ -265,7 +265,7 @@ static struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn,
memset(pmbe, 0, sizeof(struct pmb_entry));
- spin_lock_init(&pmbe->lock);
+ raw_spin_lock_init(&pmbe->lock);
pmbe->vpn = vpn;
pmbe->ppn = ppn;
@@ -327,9 +327,9 @@ static void set_pmb_entry(struct pmb_entry *pmbe)
{
unsigned long flags;
- spin_lock_irqsave(&pmbe->lock, flags);
+ raw_spin_lock_irqsave(&pmbe->lock, flags);
__set_pmb_entry(pmbe);
- spin_unlock_irqrestore(&pmbe->lock, flags);
+ raw_spin_unlock_irqrestore(&pmbe->lock, flags);
}
#endif /* CONFIG_PM */
@@ -368,7 +368,7 @@ int pmb_bolt_mapping(unsigned long vaddr, phys_addr_t phys,
return PTR_ERR(pmbe);
}
- spin_lock_irqsave(&pmbe->lock, flags);
+ raw_spin_lock_irqsave(&pmbe->lock, flags);
pmbe->size = pmb_sizes[i].size;
@@ -383,9 +383,10 @@ int pmb_bolt_mapping(unsigned long vaddr, phys_addr_t phys,
* entries for easier tear-down.
*/
if (likely(pmbp)) {
- spin_lock(&pmbp->lock);
+ raw_spin_lock_nested(&pmbp->lock,
+ SINGLE_DEPTH_NESTING);
pmbp->link = pmbe;
- spin_unlock(&pmbp->lock);
+ raw_spin_unlock(&pmbp->lock);
}
pmbp = pmbe;
@@ -398,7 +399,7 @@ int pmb_bolt_mapping(unsigned long vaddr, phys_addr_t phys,
i--;
mapped++;
- spin_unlock_irqrestore(&pmbe->lock, flags);
+ raw_spin_unlock_irqrestore(&pmbe->lock, flags);
}
} while (size >= SZ_16M);
@@ -627,15 +628,14 @@ static void __init pmb_synchronize(void)
continue;
}
- spin_lock_irqsave(&pmbe->lock, irqflags);
+ raw_spin_lock_irqsave(&pmbe->lock, irqflags);
for (j = 0; j < ARRAY_SIZE(pmb_sizes); j++)
if (pmb_sizes[j].flag == size)
pmbe->size = pmb_sizes[j].size;
if (pmbp) {
- spin_lock(&pmbp->lock);
-
+ raw_spin_lock_nested(&pmbp->lock, SINGLE_DEPTH_NESTING);
/*
* Compare the previous entry against the current one to
* see if the entries span a contiguous mapping. If so,
@@ -644,13 +644,12 @@ static void __init pmb_synchronize(void)
*/
if (pmb_can_merge(pmbp, pmbe))
pmbp->link = pmbe;
-
- spin_unlock(&pmbp->lock);
+ raw_spin_unlock(&pmbp->lock);
}
pmbp = pmbe;
- spin_unlock_irqrestore(&pmbe->lock, irqflags);
+ raw_spin_unlock_irqrestore(&pmbe->lock, irqflags);
}
}
@@ -757,7 +756,7 @@ static void __init pmb_resize(void)
/*
* Found it, now resize it.
*/
- spin_lock_irqsave(&pmbe->lock, flags);
+ raw_spin_lock_irqsave(&pmbe->lock, flags);
pmbe->size = SZ_16M;
pmbe->flags &= ~PMB_SZ_MASK;
@@ -767,7 +766,7 @@ static void __init pmb_resize(void)
__set_pmb_entry(pmbe);
- spin_unlock_irqrestore(&pmbe->lock, flags);
+ raw_spin_unlock_irqrestore(&pmbe->lock, flags);
}
read_unlock(&pmb_rwlock);
@@ -866,11 +865,9 @@ static int __init pmb_debugfs_init(void)
struct dentry *dentry;
dentry = debugfs_create_file("pmb", S_IFREG | S_IRUGO,
- sh_debugfs_root, NULL, &pmb_debugfs_fops);
+ arch_debugfs_dir, NULL, &pmb_debugfs_fops);
if (!dentry)
return -ENOMEM;
- if (IS_ERR(dentry))
- return PTR_ERR(dentry);
return 0;
}
diff --git a/arch/sh/mm/sram.c b/arch/sh/mm/sram.c
new file mode 100644
index 000000000000..bc156ec4545e
--- /dev/null
+++ b/arch/sh/mm/sram.c
@@ -0,0 +1,34 @@
+/*
+ * SRAM pool for tiny memories not otherwise managed.
+ *
+ * Copyright (C) 2010 Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/sram.h>
+
+/*
+ * This provides a standard SRAM pool for tiny memories that can be
+ * added either by the CPU or the platform code. Typical SRAM sizes
+ * to be inserted in to the pool will generally be less than the page
+ * size, with anything more reasonably sized handled as a NUMA memory
+ * node.
+ */
+struct gen_pool *sram_pool;
+
+static int __init sram_pool_init(void)
+{
+ /*
+ * This is a global pool, we don't care about node locality.
+ */
+ sram_pool = gen_pool_create(1, -1);
+ if (unlikely(!sram_pool))
+ return -ENOMEM;
+
+ return 0;
+}
+core_initcall(sram_pool_init);
diff --git a/arch/sh/mm/tlb-debugfs.c b/arch/sh/mm/tlb-debugfs.c
index 229bf75f28df..dea637a09246 100644
--- a/arch/sh/mm/tlb-debugfs.c
+++ b/arch/sh/mm/tlb-debugfs.c
@@ -151,15 +151,13 @@ static int __init tlb_debugfs_init(void)
{
struct dentry *itlb, *utlb;
- itlb = debugfs_create_file("itlb", S_IRUSR, sh_debugfs_root,
+ itlb = debugfs_create_file("itlb", S_IRUSR, arch_debugfs_dir,
(unsigned int *)TLB_TYPE_ITLB,
&tlb_debugfs_fops);
if (unlikely(!itlb))
return -ENOMEM;
- if (IS_ERR(itlb))
- return PTR_ERR(itlb);
- utlb = debugfs_create_file("utlb", S_IRUSR, sh_debugfs_root,
+ utlb = debugfs_create_file("utlb", S_IRUSR, arch_debugfs_dir,
(unsigned int *)TLB_TYPE_UTLB,
&tlb_debugfs_fops);
if (unlikely(!utlb)) {
@@ -167,11 +165,6 @@ static int __init tlb_debugfs_init(void)
return -ENOMEM;
}
- if (IS_ERR(utlb)) {
- debugfs_remove(itlb);
- return PTR_ERR(utlb);
- }
-
return 0;
}
module_init(tlb_debugfs_init);
diff --git a/arch/sh/mm/tlbflush_32.c b/arch/sh/mm/tlbflush_32.c
index 3fbe03ce8fe3..a6a20d6de4c0 100644
--- a/arch/sh/mm/tlbflush_32.c
+++ b/arch/sh/mm/tlbflush_32.c
@@ -119,3 +119,19 @@ void local_flush_tlb_mm(struct mm_struct *mm)
local_irq_restore(flags);
}
}
+
+void __flush_tlb_global(void)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ /*
+ * This is the most destructive of the TLB flushing options,
+ * and will tear down all of the UTLB/ITLB mappings, including
+ * wired entries.
+ */
+ __raw_writel(__raw_readl(MMUCR) | MMUCR_TI, MMUCR);
+
+ local_irq_restore(flags);
+}
diff --git a/arch/sh/mm/tlbflush_64.c b/arch/sh/mm/tlbflush_64.c
index 03db41cc1268..7f5810f5dfdc 100644
--- a/arch/sh/mm/tlbflush_64.c
+++ b/arch/sh/mm/tlbflush_64.c
@@ -455,6 +455,11 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
flush_tlb_all();
}
+void __flush_tlb_global(void)
+{
+ flush_tlb_all();
+}
+
void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
{
}
diff --git a/arch/sh/oprofile/Makefile b/arch/sh/oprofile/Makefile
index 4886c5c1786c..e85aae73e3dc 100644
--- a/arch/sh/oprofile/Makefile
+++ b/arch/sh/oprofile/Makefile
@@ -6,4 +6,8 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
oprofilefs.o oprofile_stats.o \
timer_int.o )
+ifeq ($(CONFIG_HW_PERF_EVENTS),y)
+DRIVER_OBJS += $(addprefix ../../../drivers/oprofile/, oprofile_perf.o)
+endif
+
oprofile-y := $(DRIVER_OBJS) common.o backtrace.o
diff --git a/arch/sh/oprofile/common.c b/arch/sh/oprofile/common.c
index ac604937f3ee..e10d89376f9b 100644
--- a/arch/sh/oprofile/common.c
+++ b/arch/sh/oprofile/common.c
@@ -17,114 +17,45 @@
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/smp.h>
+#include <linux/perf_event.h>
#include <asm/processor.h>
-#include "op_impl.h"
-
-static struct op_sh_model *model;
-
-static struct op_counter_config ctr[20];
+#ifdef CONFIG_HW_PERF_EVENTS
extern void sh_backtrace(struct pt_regs * const regs, unsigned int depth);
-static int op_sh_setup(void)
-{
- /* Pre-compute the values to stuff in the hardware registers. */
- model->reg_setup(ctr);
-
- /* Configure the registers on all cpus. */
- on_each_cpu(model->cpu_setup, NULL, 1);
-
- return 0;
-}
-
-static int op_sh_create_files(struct super_block *sb, struct dentry *root)
+char *op_name_from_perf_id(void)
{
- int i, ret = 0;
+ const char *pmu;
+ char buf[20];
+ int size;
- for (i = 0; i < model->num_counters; i++) {
- struct dentry *dir;
- char buf[4];
+ pmu = perf_pmu_name();
+ if (!pmu)
+ return NULL;
- snprintf(buf, sizeof(buf), "%d", i);
- dir = oprofilefs_mkdir(sb, root, buf);
+ size = snprintf(buf, sizeof(buf), "sh/%s", pmu);
+ if (size > -1 && size < sizeof(buf))
+ return buf;
- ret |= oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
- ret |= oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
- ret |= oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
- ret |= oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
-
- if (model->create_files)
- ret |= model->create_files(sb, dir);
- else
- ret |= oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
-
- /* Dummy entries */
- ret |= oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
- }
-
- return ret;
+ return NULL;
}
-static int op_sh_start(void)
+int __init oprofile_arch_init(struct oprofile_operations *ops)
{
- /* Enable performance monitoring for all counters. */
- on_each_cpu(model->cpu_start, NULL, 1);
+ ops->backtrace = sh_backtrace;
- return 0;
+ return oprofile_perf_init(ops);
}
-static void op_sh_stop(void)
+void __exit oprofile_arch_exit(void)
{
- /* Disable performance monitoring for all counters. */
- on_each_cpu(model->cpu_stop, NULL, 1);
+ oprofile_perf_exit();
}
-
+#else
int __init oprofile_arch_init(struct oprofile_operations *ops)
{
- struct op_sh_model *lmodel = NULL;
- int ret;
-
- /*
- * Always assign the backtrace op. If the counter initialization
- * fails, we fall back to the timer which will still make use of
- * this.
- */
- ops->backtrace = sh_backtrace;
-
- /*
- * XXX
- *
- * All of the SH7750/SH-4A counters have been converted to perf,
- * this infrastructure hook is left for other users until they've
- * had a chance to convert over, at which point all of this
- * will be deleted.
- */
-
- if (!lmodel)
- return -ENODEV;
- if (!(current_cpu_data.flags & CPU_HAS_PERF_COUNTER))
- return -ENODEV;
-
- ret = lmodel->init();
- if (unlikely(ret != 0))
- return ret;
-
- model = lmodel;
-
- ops->setup = op_sh_setup;
- ops->create_files = op_sh_create_files;
- ops->start = op_sh_start;
- ops->stop = op_sh_stop;
- ops->cpu_type = lmodel->cpu_type;
-
- printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
- lmodel->cpu_type);
-
- return 0;
-}
-
-void oprofile_arch_exit(void)
-{
- if (model && model->exit)
- model->exit();
+ pr_info("oprofile: hardware counters not available\n");
+ return -ENODEV;
}
+void __exit oprofile_arch_exit(void) {}
+#endif /* CONFIG_HW_PERF_EVENTS */
diff --git a/arch/sh/oprofile/op_impl.h b/arch/sh/oprofile/op_impl.h
deleted file mode 100644
index 1244479ceb29..000000000000
--- a/arch/sh/oprofile/op_impl.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef __OP_IMPL_H
-#define __OP_IMPL_H
-
-/* Per-counter configuration as set via oprofilefs. */
-struct op_counter_config {
- unsigned long enabled;
- unsigned long event;
-
- unsigned long count;
-
- /* Dummy values for userspace tool compliance */
- unsigned long kernel;
- unsigned long user;
- unsigned long unit_mask;
-};
-
-/* Per-architecture configury and hooks. */
-struct op_sh_model {
- void (*reg_setup)(struct op_counter_config *);
- int (*create_files)(struct super_block *sb, struct dentry *dir);
- void (*cpu_setup)(void *dummy);
- int (*init)(void);
- void (*exit)(void);
- void (*cpu_start)(void *args);
- void (*cpu_stop)(void *args);
- char *cpu_type;
- unsigned char num_counters;
-};
-
-/* arch/sh/oprofile/common.c */
-extern void sh_backtrace(struct pt_regs * const regs, unsigned int depth);
-
-#endif /* __OP_IMPL_H */
diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types
index b25aa554ee5e..9f56eb978024 100644
--- a/arch/sh/tools/mach-types
+++ b/arch/sh/tools/mach-types
@@ -52,6 +52,8 @@ MIGOR SH_MIGOR
RSK7201 SH_RSK7201
RSK7203 SH_RSK7203
AP325RXA SH_AP325RXA
+SH2007 SH_SH2007
+SH7757LCR SH_SH7757LCR
SH7763RDP SH_SH7763RDP
SH7785LCR SH_SH7785LCR
SH7785LCR_PT SH_SH7785LCR_PT
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 491e9d6de191..8e7bafc5dd0e 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -19,6 +19,7 @@ config SPARC
bool
default y
select OF
+ select OF_PROMTREE
select HAVE_IDE
select HAVE_OPROFILE
select HAVE_ARCH_KGDB if !SMP || SPARC64
@@ -26,10 +27,12 @@ config SPARC
select ARCH_WANT_OPTIONAL_GPIOLIB
select RTC_CLASS
select RTC_DRV_M48T59
+ select HAVE_IRQ_WORK
select HAVE_PERF_EVENTS
select PERF_USE_VMALLOC
select HAVE_DMA_ATTRS
select HAVE_DMA_API_DEBUG
+ select HAVE_ARCH_JUMP_LABEL
config SPARC32
def_bool !64BIT
@@ -53,6 +56,7 @@ config SPARC64
select RTC_DRV_BQ4802
select RTC_DRV_SUN4V
select RTC_DRV_STARFIRE
+ select HAVE_IRQ_WORK
select HAVE_PERF_EVENTS
select PERF_USE_VMALLOC
diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild
index deeb0fba8029..3c93f08ce187 100644
--- a/arch/sparc/include/asm/Kbuild
+++ b/arch/sparc/include/asm/Kbuild
@@ -7,7 +7,6 @@ header-y += display7seg.h
header-y += envctrl.h
header-y += fbio.h
header-y += jsflash.h
-header-y += openprom.h
header-y += openpromio.h
header-y += perfctr.h
header-y += psrcompat.h
diff --git a/arch/sparc/include/asm/floppy_32.h b/arch/sparc/include/asm/floppy_32.h
index c792830636de..86666f70322e 100644
--- a/arch/sparc/include/asm/floppy_32.h
+++ b/arch/sparc/include/asm/floppy_32.h
@@ -304,7 +304,8 @@ static struct linux_prom_registers fd_regs[2];
static int sun_floppy_init(void)
{
char state[128];
- int tnode, fd_node, num_regs;
+ phandle tnode, fd_node;
+ int num_regs;
struct resource r;
use_virtual_dma = 1;
diff --git a/arch/sparc/include/asm/irqflags_32.h b/arch/sparc/include/asm/irqflags_32.h
index 0fca9d97d44f..d4d0711de0f9 100644
--- a/arch/sparc/include/asm/irqflags_32.h
+++ b/arch/sparc/include/asm/irqflags_32.h
@@ -5,33 +5,40 @@
*
* This file gets included from lowlevel asm headers too, to provide
* wrapped versions of the local_irq_*() APIs, based on the
- * raw_local_irq_*() functions from the lowlevel headers.
+ * arch_local_irq_*() functions from the lowlevel headers.
*/
#ifndef _ASM_IRQFLAGS_H
#define _ASM_IRQFLAGS_H
#ifndef __ASSEMBLY__
-extern void raw_local_irq_restore(unsigned long);
-extern unsigned long __raw_local_irq_save(void);
-extern void raw_local_irq_enable(void);
+#include <linux/types.h>
-static inline unsigned long getipl(void)
+extern void arch_local_irq_restore(unsigned long);
+extern unsigned long arch_local_irq_save(void);
+extern void arch_local_irq_enable(void);
+
+static inline unsigned long arch_local_save_flags(void)
{
- unsigned long retval;
+ unsigned long flags;
+
+ asm volatile("rd %%psr, %0" : "=r" (flags));
+ return flags;
+}
- __asm__ __volatile__("rd %%psr, %0" : "=r" (retval));
- return retval;
+static inline void arch_local_irq_disable(void)
+{
+ arch_local_irq_save();
}
-#define raw_local_save_flags(flags) ((flags) = getipl())
-#define raw_local_irq_save(flags) ((flags) = __raw_local_irq_save())
-#define raw_local_irq_disable() ((void) __raw_local_irq_save())
-#define raw_irqs_disabled() ((getipl() & PSR_PIL) != 0)
+static inline bool arch_irqs_disabled_flags(unsigned long flags)
+{
+ return (flags & PSR_PIL) != 0;
+}
-static inline int raw_irqs_disabled_flags(unsigned long flags)
+static inline bool arch_irqs_disabled(void)
{
- return ((flags & PSR_PIL) != 0);
+ return arch_irqs_disabled_flags(arch_local_save_flags());
}
#endif /* (__ASSEMBLY__) */
diff --git a/arch/sparc/include/asm/irqflags_64.h b/arch/sparc/include/asm/irqflags_64.h
index bfa1ea45b4cd..aab969c82c2b 100644
--- a/arch/sparc/include/asm/irqflags_64.h
+++ b/arch/sparc/include/asm/irqflags_64.h
@@ -5,7 +5,7 @@
*
* This file gets included from lowlevel asm headers too, to provide
* wrapped versions of the local_irq_*() APIs, based on the
- * raw_local_irq_*() functions from the lowlevel headers.
+ * arch_local_irq_*() functions from the lowlevel headers.
*/
#ifndef _ASM_IRQFLAGS_H
#define _ASM_IRQFLAGS_H
@@ -14,7 +14,7 @@
#ifndef __ASSEMBLY__
-static inline unsigned long __raw_local_save_flags(void)
+static inline unsigned long arch_local_save_flags(void)
{
unsigned long flags;
@@ -26,10 +26,7 @@ static inline unsigned long __raw_local_save_flags(void)
return flags;
}
-#define raw_local_save_flags(flags) \
- do { (flags) = __raw_local_save_flags(); } while (0)
-
-static inline void raw_local_irq_restore(unsigned long flags)
+static inline void arch_local_irq_restore(unsigned long flags)
{
__asm__ __volatile__(
"wrpr %0, %%pil"
@@ -39,7 +36,7 @@ static inline void raw_local_irq_restore(unsigned long flags)
);
}
-static inline void raw_local_irq_disable(void)
+static inline void arch_local_irq_disable(void)
{
__asm__ __volatile__(
"wrpr %0, %%pil"
@@ -49,7 +46,7 @@ static inline void raw_local_irq_disable(void)
);
}
-static inline void raw_local_irq_enable(void)
+static inline void arch_local_irq_enable(void)
{
__asm__ __volatile__(
"wrpr 0, %%pil"
@@ -59,22 +56,17 @@ static inline void raw_local_irq_enable(void)
);
}
-static inline int raw_irqs_disabled_flags(unsigned long flags)
+static inline int arch_irqs_disabled_flags(unsigned long flags)
{
return (flags > 0);
}
-static inline int raw_irqs_disabled(void)
+static inline int arch_irqs_disabled(void)
{
- unsigned long flags = __raw_local_save_flags();
-
- return raw_irqs_disabled_flags(flags);
+ return arch_irqs_disabled_flags(arch_local_save_flags());
}
-/*
- * For spinlocks, etc:
- */
-static inline unsigned long __raw_local_irq_save(void)
+static inline unsigned long arch_local_irq_save(void)
{
unsigned long flags, tmp;
@@ -100,9 +92,6 @@ static inline unsigned long __raw_local_irq_save(void)
return flags;
}
-#define raw_local_irq_save(flags) \
- do { (flags) = __raw_local_irq_save(); } while (0)
-
#endif /* (__ASSEMBLY__) */
#endif /* !(_ASM_IRQFLAGS_H) */
diff --git a/arch/sparc/include/asm/jump_label.h b/arch/sparc/include/asm/jump_label.h
new file mode 100644
index 000000000000..62e66d7b2fb6
--- /dev/null
+++ b/arch/sparc/include/asm/jump_label.h
@@ -0,0 +1,32 @@
+#ifndef _ASM_SPARC_JUMP_LABEL_H
+#define _ASM_SPARC_JUMP_LABEL_H
+
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <asm/system.h>
+
+#define JUMP_LABEL_NOP_SIZE 4
+
+#define JUMP_LABEL(key, label) \
+ do { \
+ asm goto("1:\n\t" \
+ "nop\n\t" \
+ "nop\n\t" \
+ ".pushsection __jump_table, \"a\"\n\t"\
+ ".word 1b, %l[" #label "], %c0\n\t" \
+ ".popsection \n\t" \
+ : : "i" (key) : : label);\
+ } while (0)
+
+#endif /* __KERNEL__ */
+
+typedef u32 jump_label_t;
+
+struct jump_entry {
+ jump_label_t code;
+ jump_label_t target;
+ jump_label_t key;
+};
+
+#endif
diff --git a/arch/sparc/include/asm/memblock.h b/arch/sparc/include/asm/memblock.h
index f12af880649b..c67b047ef85e 100644
--- a/arch/sparc/include/asm/memblock.h
+++ b/arch/sparc/include/asm/memblock.h
@@ -5,6 +5,4 @@
#define MEMBLOCK_DBG(fmt...) prom_printf(fmt)
-#define MEMBLOCK_REAL_LIMIT 0
-
#endif /* !(_SPARC64_MEMBLOCK_H) */
diff --git a/arch/sparc/include/asm/openprom.h b/arch/sparc/include/asm/openprom.h
index 963e1a45c35f..81cd43432dc0 100644
--- a/arch/sparc/include/asm/openprom.h
+++ b/arch/sparc/include/asm/openprom.h
@@ -11,6 +11,8 @@
#define LINUX_OPPROM_MAGIC 0x10010407
#ifndef __ASSEMBLY__
+#include <linux/of.h>
+
/* V0 prom device operations. */
struct linux_dev_v0_funcs {
int (*v0_devopen)(char *device_str);
@@ -26,7 +28,7 @@ struct linux_dev_v0_funcs {
/* V2 and later prom device operations. */
struct linux_dev_v2_funcs {
- int (*v2_inst2pkg)(int d); /* Convert ihandle to phandle */
+ phandle (*v2_inst2pkg)(int d); /* Convert ihandle to phandle */
char * (*v2_dumb_mem_alloc)(char *va, unsigned sz);
void (*v2_dumb_mem_free)(char *va, unsigned sz);
@@ -168,12 +170,12 @@ struct linux_romvec {
/* Routines for traversing the prom device tree. */
struct linux_nodeops {
- int (*no_nextnode)(int node);
- int (*no_child)(int node);
- int (*no_proplen)(int node, const char *name);
- int (*no_getprop)(int node, const char *name, char *val);
- int (*no_setprop)(int node, const char *name, char *val, int len);
- char * (*no_nextprop)(int node, char *name);
+ phandle (*no_nextnode)(phandle node);
+ phandle (*no_child)(phandle node);
+ int (*no_proplen)(phandle node, const char *name);
+ int (*no_getprop)(phandle node, const char *name, char *val);
+ int (*no_setprop)(phandle node, const char *name, char *val, int len);
+ char * (*no_nextprop)(phandle node, char *name);
};
/* More fun PROM structures for device probing. */
diff --git a/arch/sparc/include/asm/oplib_32.h b/arch/sparc/include/asm/oplib_32.h
index 33e31ce6b31f..51296a6f5005 100644
--- a/arch/sparc/include/asm/oplib_32.h
+++ b/arch/sparc/include/asm/oplib_32.h
@@ -30,7 +30,7 @@ extern unsigned int prom_rev, prom_prev;
/* Root node of the prom device tree, this stays constant after
* initialization is complete.
*/
-extern int prom_root_node;
+extern phandle prom_root_node;
/* Pointer to prom structure containing the device tree traversal
* and usage utility functions. Only prom-lib should use these,
@@ -178,68 +178,68 @@ extern void prom_putsegment(int context, unsigned long virt_addr,
/* PROM device tree traversal functions... */
/* Get the child node of the given node, or zero if no child exists. */
-extern int prom_getchild(int parent_node);
+extern phandle prom_getchild(phandle parent_node);
/* Get the next sibling node of the given node, or zero if no further
* siblings exist.
*/
-extern int prom_getsibling(int node);
+extern phandle prom_getsibling(phandle node);
/* Get the length, at the passed node, of the given property type.
* Returns -1 on error (ie. no such property at this node).
*/
-extern int prom_getproplen(int thisnode, const char *property);
+extern int prom_getproplen(phandle thisnode, const char *property);
/* Fetch the requested property using the given buffer. Returns
* the number of bytes the prom put into your buffer or -1 on error.
*/
-extern int __must_check prom_getproperty(int thisnode, const char *property,
+extern int __must_check prom_getproperty(phandle thisnode, const char *property,
char *prop_buffer, int propbuf_size);
/* Acquire an integer property. */
-extern int prom_getint(int node, char *property);
+extern int prom_getint(phandle node, char *property);
/* Acquire an integer property, with a default value. */
-extern int prom_getintdefault(int node, char *property, int defval);
+extern int prom_getintdefault(phandle node, char *property, int defval);
/* Acquire a boolean property, 0=FALSE 1=TRUE. */
-extern int prom_getbool(int node, char *prop);
+extern int prom_getbool(phandle node, char *prop);
/* Acquire a string property, null string on error. */
-extern void prom_getstring(int node, char *prop, char *buf, int bufsize);
+extern void prom_getstring(phandle node, char *prop, char *buf, int bufsize);
/* Does the passed node have the given "name"? YES=1 NO=0 */
-extern int prom_nodematch(int thisnode, char *name);
+extern int prom_nodematch(phandle thisnode, char *name);
/* Search all siblings starting at the passed node for "name" matching
* the given string. Returns the node on success, zero on failure.
*/
-extern int prom_searchsiblings(int node_start, char *name);
+extern phandle prom_searchsiblings(phandle node_start, char *name);
/* Return the first property type, as a string, for the given node.
* Returns a null string on error.
*/
-extern char *prom_firstprop(int node, char *buffer);
+extern char *prom_firstprop(phandle node, char *buffer);
/* Returns the next property after the passed property for the given
* node. Returns null string on failure.
*/
-extern char *prom_nextprop(int node, char *prev_property, char *buffer);
+extern char *prom_nextprop(phandle node, char *prev_property, char *buffer);
/* Returns phandle of the path specified */
-extern int prom_finddevice(char *name);
+extern phandle prom_finddevice(char *name);
/* Returns 1 if the specified node has given property. */
-extern int prom_node_has_property(int node, char *property);
+extern int prom_node_has_property(phandle node, char *property);
/* Set the indicated property at the given node with the passed value.
* Returns the number of bytes of your value that the prom took.
*/
-extern int prom_setprop(int node, const char *prop_name, char *prop_value,
+extern int prom_setprop(phandle node, const char *prop_name, char *prop_value,
int value_size);
-extern int prom_pathtoinode(char *path);
-extern int prom_inst2pkg(int);
+extern phandle prom_pathtoinode(char *path);
+extern phandle prom_inst2pkg(int);
/* Dorking with Bus ranges... */
@@ -247,13 +247,13 @@ extern int prom_inst2pkg(int);
extern void prom_apply_obio_ranges(struct linux_prom_registers *obioregs, int nregs);
/* Apply ranges of any prom node (and optionally parent node as well) to registers. */
-extern void prom_apply_generic_ranges(int node, int parent,
+extern void prom_apply_generic_ranges(phandle node, phandle parent,
struct linux_prom_registers *sbusregs, int nregs);
/* CPU probing helpers. */
-int cpu_find_by_instance(int instance, int *prom_node, int *mid);
-int cpu_find_by_mid(int mid, int *prom_node);
-int cpu_get_hwmid(int prom_node);
+int cpu_find_by_instance(int instance, phandle *prom_node, int *mid);
+int cpu_find_by_mid(int mid, phandle *prom_node);
+int cpu_get_hwmid(phandle prom_node);
extern spinlock_t prom_lock;
diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h
index 3e0b2d62303d..c9cc078e3e31 100644
--- a/arch/sparc/include/asm/oplib_64.h
+++ b/arch/sparc/include/asm/oplib_64.h
@@ -16,7 +16,7 @@ extern char prom_version[];
/* Root node of the prom device tree, this stays constant after
* initialization is complete.
*/
-extern int prom_root_node;
+extern phandle prom_root_node;
/* PROM stdin and stdout */
extern int prom_stdin, prom_stdout;
@@ -24,7 +24,7 @@ extern int prom_stdin, prom_stdout;
/* /chosen node of the prom device tree, this stays constant after
* initialization is complete.
*/
-extern int prom_chosen_node;
+extern phandle prom_chosen_node;
/* Helper values and strings in arch/sparc64/kernel/head.S */
extern const char prom_peer_name[];
@@ -218,68 +218,69 @@ extern void prom_unmap(unsigned long size, unsigned long vaddr);
/* PROM device tree traversal functions... */
/* Get the child node of the given node, or zero if no child exists. */
-extern int prom_getchild(int parent_node);
+extern phandle prom_getchild(phandle parent_node);
/* Get the next sibling node of the given node, or zero if no further
* siblings exist.
*/
-extern int prom_getsibling(int node);
+extern phandle prom_getsibling(phandle node);
/* Get the length, at the passed node, of the given property type.
* Returns -1 on error (ie. no such property at this node).
*/
-extern int prom_getproplen(int thisnode, const char *property);
+extern int prom_getproplen(phandle thisnode, const char *property);
/* Fetch the requested property using the given buffer. Returns
* the number of bytes the prom put into your buffer or -1 on error.
*/
-extern int prom_getproperty(int thisnode, const char *property,
+extern int prom_getproperty(phandle thisnode, const char *property,
char *prop_buffer, int propbuf_size);
/* Acquire an integer property. */
-extern int prom_getint(int node, const char *property);
+extern int prom_getint(phandle node, const char *property);
/* Acquire an integer property, with a default value. */
-extern int prom_getintdefault(int node, const char *property, int defval);
+extern int prom_getintdefault(phandle node, const char *property, int defval);
/* Acquire a boolean property, 0=FALSE 1=TRUE. */
-extern int prom_getbool(int node, const char *prop);
+extern int prom_getbool(phandle node, const char *prop);
/* Acquire a string property, null string on error. */
-extern void prom_getstring(int node, const char *prop, char *buf, int bufsize);
+extern void prom_getstring(phandle node, const char *prop, char *buf,
+ int bufsize);
/* Does the passed node have the given "name"? YES=1 NO=0 */
-extern int prom_nodematch(int thisnode, const char *name);
+extern int prom_nodematch(phandle thisnode, const char *name);
/* Search all siblings starting at the passed node for "name" matching
* the given string. Returns the node on success, zero on failure.
*/
-extern int prom_searchsiblings(int node_start, const char *name);
+extern phandle prom_searchsiblings(phandle node_start, const char *name);
/* Return the first property type, as a string, for the given node.
* Returns a null string on error. Buffer should be at least 32B long.
*/
-extern char *prom_firstprop(int node, char *buffer);
+extern char *prom_firstprop(phandle node, char *buffer);
/* Returns the next property after the passed property for the given
* node. Returns null string on failure. Buffer should be at least 32B long.
*/
-extern char *prom_nextprop(int node, const char *prev_property, char *buffer);
+extern char *prom_nextprop(phandle node, const char *prev_property, char *buf);
/* Returns 1 if the specified node has given property. */
-extern int prom_node_has_property(int node, const char *property);
+extern int prom_node_has_property(phandle node, const char *property);
/* Returns phandle of the path specified */
-extern int prom_finddevice(const char *name);
+extern phandle prom_finddevice(const char *name);
/* Set the indicated property at the given node with the passed value.
* Returns the number of bytes of your value that the prom took.
*/
-extern int prom_setprop(int node, const char *prop_name, char *prop_value,
+extern int prom_setprop(phandle node, const char *prop_name, char *prop_value,
int value_size);
-extern int prom_pathtoinode(const char *path);
-extern int prom_inst2pkg(int);
+extern phandle prom_pathtoinode(const char *path);
+extern phandle prom_inst2pkg(int);
extern int prom_service_exists(const char *service_name);
extern void prom_sun4v_guest_soft_state(void);
diff --git a/arch/sparc/include/asm/perf_event.h b/arch/sparc/include/asm/perf_event.h
index 727af70646cb..6e8bfa1786da 100644
--- a/arch/sparc/include/asm/perf_event.h
+++ b/arch/sparc/include/asm/perf_event.h
@@ -1,10 +1,6 @@
#ifndef __ASM_SPARC_PERF_EVENT_H
#define __ASM_SPARC_PERF_EVENT_H
-extern void set_perf_event_pending(void);
-
-#define PERF_EVENT_INDEX_OFFSET 0
-
#ifdef CONFIG_PERF_EVENTS
#include <asm/ptrace.h>
diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h
index 291f12575edd..56bbaadef646 100644
--- a/arch/sparc/include/asm/prom.h
+++ b/arch/sparc/include/asm/prom.h
@@ -18,6 +18,7 @@
* 2 of the License, or (at your option) any later version.
*/
#include <linux/types.h>
+#include <linux/of_pdt.h>
#include <linux/proc_fs.h>
#include <linux/mutex.h>
#include <asm/atomic.h>
@@ -67,8 +68,8 @@ extern struct device_node *of_console_device;
extern char *of_console_path;
extern char *of_console_options;
-extern void (*prom_build_more)(struct device_node *dp, struct device_node ***nextp);
-extern char *build_full_name(struct device_node *dp);
+extern void irq_trans_init(struct device_node *dp);
+extern char *build_path_component(struct device_node *dp);
#endif /* __KERNEL__ */
#endif /* _SPARC_PROM_H */
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index 0c2dc1f24a9a..599398fbbc7c 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -119,3 +119,5 @@ obj-$(CONFIG_COMPAT) += $(audit--y)
pc--$(CONFIG_PERF_EVENTS) := perf_event.o
obj-$(CONFIG_SPARC64) += $(pc--y)
+
+obj-$(CONFIG_SPARC64) += jump_label.o
diff --git a/arch/sparc/kernel/apc.c b/arch/sparc/kernel/apc.c
index 2c0046ecc715..52de4a9424e8 100644
--- a/arch/sparc/kernel/apc.c
+++ b/arch/sparc/kernel/apc.c
@@ -132,6 +132,7 @@ static const struct file_operations apc_fops = {
.unlocked_ioctl = apc_ioctl,
.open = apc_open,
.release = apc_release,
+ .llseek = noop_llseek,
};
static struct miscdevice apc_miscdev = { APC_MINOR, APC_DEVNAME, &apc_fops };
diff --git a/arch/sparc/kernel/auxio_32.c b/arch/sparc/kernel/auxio_32.c
index ee8d214cae1e..35f48837871a 100644
--- a/arch/sparc/kernel/auxio_32.c
+++ b/arch/sparc/kernel/auxio_32.c
@@ -23,7 +23,7 @@ static DEFINE_SPINLOCK(auxio_lock);
void __init auxio_probe(void)
{
- int node, auxio_nd;
+ phandle node, auxio_nd;
struct linux_prom_registers auxregs[1];
struct resource r;
@@ -113,7 +113,7 @@ volatile unsigned char * auxio_power_register = NULL;
void __init auxio_power_probe(void)
{
struct linux_prom_registers regs;
- int node;
+ phandle node;
struct resource r;
/* Attempt to find the sun4m power control node. */
diff --git a/arch/sparc/kernel/btext.c b/arch/sparc/kernel/btext.c
index 8cc2d56ffe9a..89aa4eb20cf5 100644
--- a/arch/sparc/kernel/btext.c
+++ b/arch/sparc/kernel/btext.c
@@ -40,7 +40,7 @@ static unsigned char *dispDeviceBase __force_data;
static unsigned char vga_font[cmapsz];
-static int __init btext_initialize(unsigned int node)
+static int __init btext_initialize(phandle node)
{
unsigned int width, height, depth, pitch;
unsigned long address = 0;
@@ -309,7 +309,7 @@ static struct console btext_console = {
int __init btext_find_display(void)
{
- unsigned int node;
+ phandle node;
char type[32];
int ret;
diff --git a/arch/sparc/kernel/devices.c b/arch/sparc/kernel/devices.c
index 62dc7a021413..d2eddd6647cd 100644
--- a/arch/sparc/kernel/devices.c
+++ b/arch/sparc/kernel/devices.c
@@ -31,9 +31,9 @@ static char *cpu_mid_prop(void)
return "mid";
}
-static int check_cpu_node(int nd, int *cur_inst,
- int (*compare)(int, int, void *), void *compare_arg,
- int *prom_node, int *mid)
+static int check_cpu_node(phandle nd, int *cur_inst,
+ int (*compare)(phandle, int, void *), void *compare_arg,
+ phandle *prom_node, int *mid)
{
if (!compare(nd, *cur_inst, compare_arg)) {
if (prom_node)
@@ -51,8 +51,8 @@ static int check_cpu_node(int nd, int *cur_inst,
return -ENODEV;
}
-static int __cpu_find_by(int (*compare)(int, int, void *), void *compare_arg,
- int *prom_node, int *mid)
+static int __cpu_find_by(int (*compare)(phandle, int, void *),
+ void *compare_arg, phandle *prom_node, int *mid)
{
struct device_node *dp;
int cur_inst;
@@ -71,7 +71,7 @@ static int __cpu_find_by(int (*compare)(int, int, void *), void *compare_arg,
return -ENODEV;
}
-static int cpu_instance_compare(int nd, int instance, void *_arg)
+static int cpu_instance_compare(phandle nd, int instance, void *_arg)
{
int desired_instance = (int) _arg;
@@ -80,13 +80,13 @@ static int cpu_instance_compare(int nd, int instance, void *_arg)
return -ENODEV;
}
-int cpu_find_by_instance(int instance, int *prom_node, int *mid)
+int cpu_find_by_instance(int instance, phandle *prom_node, int *mid)
{
return __cpu_find_by(cpu_instance_compare, (void *)instance,
prom_node, mid);
}
-static int cpu_mid_compare(int nd, int instance, void *_arg)
+static int cpu_mid_compare(phandle nd, int instance, void *_arg)
{
int desired_mid = (int) _arg;
int this_mid;
@@ -98,7 +98,7 @@ static int cpu_mid_compare(int nd, int instance, void *_arg)
return -ENODEV;
}
-int cpu_find_by_mid(int mid, int *prom_node)
+int cpu_find_by_mid(int mid, phandle *prom_node)
{
return __cpu_find_by(cpu_mid_compare, (void *)mid,
prom_node, NULL);
@@ -108,7 +108,7 @@ int cpu_find_by_mid(int mid, int *prom_node)
* address (0-3). This gives us the true hardware mid, which might have
* some other bits set. On 4d hardware and software mids are the same.
*/
-int cpu_get_hwmid(int prom_node)
+int cpu_get_hwmid(phandle prom_node)
{
return prom_getintdefault(prom_node, cpu_mid_prop(), -ENODEV);
}
@@ -119,7 +119,8 @@ void __init device_scan(void)
#ifndef CONFIG_SMP
{
- int err, cpu_node;
+ phandle cpu_node;
+ int err;
err = cpu_find_by_instance(0, &cpu_node, NULL);
if (err) {
/* Probably a sun4e, Sun is trying to trick us ;-) */
diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c
index e1af43728329..0116d8d10def 100644
--- a/arch/sparc/kernel/irq_32.c
+++ b/arch/sparc/kernel/irq_32.c
@@ -57,7 +57,7 @@
#define SMP_NOP2
#define SMP_NOP3
#endif /* SMP */
-unsigned long __raw_local_irq_save(void)
+unsigned long arch_local_irq_save(void)
{
unsigned long retval;
unsigned long tmp;
@@ -74,8 +74,9 @@ unsigned long __raw_local_irq_save(void)
return retval;
}
+EXPORT_SYMBOL(arch_local_irq_save);
-void raw_local_irq_enable(void)
+void arch_local_irq_enable(void)
{
unsigned long tmp;
@@ -89,8 +90,9 @@ void raw_local_irq_enable(void)
: "i" (PSR_PIL)
: "memory");
}
+EXPORT_SYMBOL(arch_local_irq_enable);
-void raw_local_irq_restore(unsigned long old_psr)
+void arch_local_irq_restore(unsigned long old_psr)
{
unsigned long tmp;
@@ -105,10 +107,7 @@ void raw_local_irq_restore(unsigned long old_psr)
: "i" (PSR_PIL), "r" (old_psr)
: "memory");
}
-
-EXPORT_SYMBOL(__raw_local_irq_save);
-EXPORT_SYMBOL(raw_local_irq_enable);
-EXPORT_SYMBOL(raw_local_irq_restore);
+EXPORT_SYMBOL(arch_local_irq_restore);
/*
* Dave Redman (djhr@tadpole.co.uk)
diff --git a/arch/sparc/kernel/jump_label.c b/arch/sparc/kernel/jump_label.c
new file mode 100644
index 000000000000..ea2dafc93d78
--- /dev/null
+++ b/arch/sparc/kernel/jump_label.c
@@ -0,0 +1,47 @@
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mutex.h>
+#include <linux/cpu.h>
+
+#include <linux/jump_label.h>
+#include <linux/memory.h>
+
+#ifdef HAVE_JUMP_LABEL
+
+void arch_jump_label_transform(struct jump_entry *entry,
+ enum jump_label_type type)
+{
+ u32 val;
+ u32 *insn = (u32 *) (unsigned long) entry->code;
+
+ if (type == JUMP_LABEL_ENABLE) {
+ s32 off = (s32)entry->target - (s32)entry->code;
+
+#ifdef CONFIG_SPARC64
+ /* ba,pt %xcc, . + (off << 2) */
+ val = 0x10680000 | ((u32) off >> 2);
+#else
+ /* ba . + (off << 2) */
+ val = 0x10800000 | ((u32) off >> 2);
+#endif
+ } else {
+ val = 0x01000000;
+ }
+
+ get_online_cpus();
+ mutex_lock(&text_mutex);
+ *insn = val;
+ flushi(insn);
+ mutex_unlock(&text_mutex);
+ put_online_cpus();
+}
+
+void arch_jump_label_text_poke_early(jump_label_t addr)
+{
+ u32 *insn_p = (u32 *) (unsigned long) addr;
+
+ *insn_p = 0x01000000;
+ flushi(insn_p);
+}
+
+#endif
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
index 6a7b4dbc8e09..2d51527d810f 100644
--- a/arch/sparc/kernel/leon_kernel.c
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -282,5 +282,5 @@ void __init leon_init_IRQ(void)
void __init leon_init(void)
{
- prom_build_more = &leon_node_init;
+ of_pdt_build_more = &leon_node_init;
}
diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c
index 83e85c2e802a..6addb914fcc8 100644
--- a/arch/sparc/kernel/mdesc.c
+++ b/arch/sparc/kernel/mdesc.c
@@ -890,6 +890,7 @@ static ssize_t mdesc_read(struct file *file, char __user *buf,
static const struct file_operations mdesc_fops = {
.read = mdesc_read,
.owner = THIS_MODULE,
+ .llseek = noop_llseek,
};
static struct miscdevice mdesc_misc = {
diff --git a/arch/sparc/kernel/module.c b/arch/sparc/kernel/module.c
index f848aadf54dc..ee3c7dde8d9f 100644
--- a/arch/sparc/kernel/module.c
+++ b/arch/sparc/kernel/module.c
@@ -18,6 +18,9 @@
#include <asm/spitfire.h>
#ifdef CONFIG_SPARC64
+
+#include <linux/jump_label.h>
+
static void *module_map(unsigned long size)
{
struct vm_struct *area;
@@ -227,6 +230,9 @@ int module_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs,
struct module *me)
{
+ /* make jump label nops */
+ jump_label_apply_nops(me);
+
/* Cheetah's I-cache is fully coherent. */
if (tlb_type == spitfire) {
unsigned long va;
diff --git a/arch/sparc/kernel/pci_msi.c b/arch/sparc/kernel/pci_msi.c
index 548b8ca9c210..b210416ace7b 100644
--- a/arch/sparc/kernel/pci_msi.c
+++ b/arch/sparc/kernel/pci_msi.c
@@ -114,10 +114,10 @@ static void free_msi(struct pci_pbm_info *pbm, int msi_num)
static struct irq_chip msi_irq = {
.name = "PCI-MSI",
- .mask = mask_msi_irq,
- .unmask = unmask_msi_irq,
- .enable = unmask_msi_irq,
- .disable = mask_msi_irq,
+ .irq_mask = mask_msi_irq,
+ .irq_unmask = unmask_msi_irq,
+ .irq_enable = unmask_msi_irq,
+ .irq_disable = mask_msi_irq,
/* XXX affinity XXX */
};
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
index d36a8d391ca0..aeaa09a3c655 100644
--- a/arch/sparc/kernel/pcic.c
+++ b/arch/sparc/kernel/pcic.c
@@ -284,7 +284,7 @@ int __init pcic_probe(void)
struct linux_prom_registers regs[PROMREG_MAX];
struct linux_pbm_info* pbm;
char namebuf[64];
- int node;
+ phandle node;
int err;
if (pcic0_up) {
@@ -440,7 +440,7 @@ static int __devinit pdev_to_pnode(struct linux_pbm_info *pbm,
{
struct linux_prom_pci_registers regs[PROMREG_MAX];
int err;
- int node = prom_getchild(pbm->prom_node);
+ phandle node = prom_getchild(pbm->prom_node);
while(node) {
err = prom_getproperty(node, "reg",
diff --git a/arch/sparc/kernel/pcr.c b/arch/sparc/kernel/pcr.c
index c4a6a50b4849..b87873c0e8ea 100644
--- a/arch/sparc/kernel/pcr.c
+++ b/arch/sparc/kernel/pcr.c
@@ -7,7 +7,7 @@
#include <linux/init.h>
#include <linux/irq.h>
-#include <linux/perf_event.h>
+#include <linux/irq_work.h>
#include <linux/ftrace.h>
#include <asm/pil.h>
@@ -43,14 +43,14 @@ void __irq_entry deferred_pcr_work_irq(int irq, struct pt_regs *regs)
old_regs = set_irq_regs(regs);
irq_enter();
-#ifdef CONFIG_PERF_EVENTS
- perf_event_do_pending();
+#ifdef CONFIG_IRQ_WORK
+ irq_work_run();
#endif
irq_exit();
set_irq_regs(old_regs);
}
-void set_perf_event_pending(void)
+void arch_irq_work_raise(void)
{
set_softint(1 << PIL_DEFERRED_PCR_WORK);
}
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c
index 6318e622cfb0..0d6deb55a2ae 100644
--- a/arch/sparc/kernel/perf_event.c
+++ b/arch/sparc/kernel/perf_event.c
@@ -658,13 +658,16 @@ static u64 maybe_change_configuration(struct cpu_hw_events *cpuc, u64 pcr)
enc = perf_event_get_enc(cpuc->events[i]);
pcr &= ~mask_for_index(idx);
- pcr |= event_encoding(enc, idx);
+ if (hwc->state & PERF_HES_STOPPED)
+ pcr |= nop_for_index(idx);
+ else
+ pcr |= event_encoding(enc, idx);
}
out:
return pcr;
}
-void hw_perf_enable(void)
+static void sparc_pmu_enable(struct pmu *pmu)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
u64 pcr;
@@ -691,7 +694,7 @@ void hw_perf_enable(void)
pcr_ops->write(cpuc->pcr);
}
-void hw_perf_disable(void)
+static void sparc_pmu_disable(struct pmu *pmu)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
u64 val;
@@ -710,19 +713,65 @@ void hw_perf_disable(void)
pcr_ops->write(cpuc->pcr);
}
-static void sparc_pmu_disable(struct perf_event *event)
+static int active_event_index(struct cpu_hw_events *cpuc,
+ struct perf_event *event)
+{
+ int i;
+
+ for (i = 0; i < cpuc->n_events; i++) {
+ if (cpuc->event[i] == event)
+ break;
+ }
+ BUG_ON(i == cpuc->n_events);
+ return cpuc->current_idx[i];
+}
+
+static void sparc_pmu_start(struct perf_event *event, int flags)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ int idx = active_event_index(cpuc, event);
+
+ if (flags & PERF_EF_RELOAD) {
+ WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE));
+ sparc_perf_event_set_period(event, &event->hw, idx);
+ }
+
+ event->hw.state = 0;
+
+ sparc_pmu_enable_event(cpuc, &event->hw, idx);
+}
+
+static void sparc_pmu_stop(struct perf_event *event, int flags)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ int idx = active_event_index(cpuc, event);
+
+ if (!(event->hw.state & PERF_HES_STOPPED)) {
+ sparc_pmu_disable_event(cpuc, &event->hw, idx);
+ event->hw.state |= PERF_HES_STOPPED;
+ }
+
+ if (!(event->hw.state & PERF_HES_UPTODATE) && (flags & PERF_EF_UPDATE)) {
+ sparc_perf_event_update(event, &event->hw, idx);
+ event->hw.state |= PERF_HES_UPTODATE;
+ }
+}
+
+static void sparc_pmu_del(struct perf_event *event, int _flags)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
- struct hw_perf_event *hwc = &event->hw;
unsigned long flags;
int i;
local_irq_save(flags);
- perf_disable();
+ perf_pmu_disable(event->pmu);
for (i = 0; i < cpuc->n_events; i++) {
if (event == cpuc->event[i]) {
- int idx = cpuc->current_idx[i];
+ /* Absorb the final count and turn off the
+ * event.
+ */
+ sparc_pmu_stop(event, PERF_EF_UPDATE);
/* Shift remaining entries down into
* the existing slot.
@@ -734,13 +783,6 @@ static void sparc_pmu_disable(struct perf_event *event)
cpuc->current_idx[i];
}
- /* Absorb the final count and turn off the
- * event.
- */
- sparc_pmu_disable_event(cpuc, hwc, idx);
- barrier();
- sparc_perf_event_update(event, hwc, idx);
-
perf_event_update_userpage(event);
cpuc->n_events--;
@@ -748,23 +790,10 @@ static void sparc_pmu_disable(struct perf_event *event)
}
}
- perf_enable();
+ perf_pmu_enable(event->pmu);
local_irq_restore(flags);
}
-static int active_event_index(struct cpu_hw_events *cpuc,
- struct perf_event *event)
-{
- int i;
-
- for (i = 0; i < cpuc->n_events; i++) {
- if (cpuc->event[i] == event)
- break;
- }
- BUG_ON(i == cpuc->n_events);
- return cpuc->current_idx[i];
-}
-
static void sparc_pmu_read(struct perf_event *event)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
@@ -774,15 +803,6 @@ static void sparc_pmu_read(struct perf_event *event)
sparc_perf_event_update(event, hwc, idx);
}
-static void sparc_pmu_unthrottle(struct perf_event *event)
-{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
- int idx = active_event_index(cpuc, event);
- struct hw_perf_event *hwc = &event->hw;
-
- sparc_pmu_enable_event(cpuc, hwc, idx);
-}
-
static atomic_t active_events = ATOMIC_INIT(0);
static DEFINE_MUTEX(pmc_grab_mutex);
@@ -877,7 +897,7 @@ static int sparc_check_constraints(struct perf_event **evts,
if (!n_ev)
return 0;
- if (n_ev > perf_max_events)
+ if (n_ev > MAX_HWEVENTS)
return -1;
msk0 = perf_event_get_msk(events[0]);
@@ -984,23 +1004,27 @@ static int collect_events(struct perf_event *group, int max_count,
return n;
}
-static int sparc_pmu_enable(struct perf_event *event)
+static int sparc_pmu_add(struct perf_event *event, int ef_flags)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
int n0, ret = -EAGAIN;
unsigned long flags;
local_irq_save(flags);
- perf_disable();
+ perf_pmu_disable(event->pmu);
n0 = cpuc->n_events;
- if (n0 >= perf_max_events)
+ if (n0 >= MAX_HWEVENTS)
goto out;
cpuc->event[n0] = event;
cpuc->events[n0] = event->hw.event_base;
cpuc->current_idx[n0] = PIC_NO_INDEX;
+ event->hw.state = PERF_HES_UPTODATE;
+ if (!(ef_flags & PERF_EF_START))
+ event->hw.state |= PERF_HES_STOPPED;
+
/*
* If group events scheduling transaction was started,
* skip the schedulability test here, it will be peformed
@@ -1020,12 +1044,12 @@ nocheck:
ret = 0;
out:
- perf_enable();
+ perf_pmu_enable(event->pmu);
local_irq_restore(flags);
return ret;
}
-static int __hw_perf_event_init(struct perf_event *event)
+static int sparc_pmu_event_init(struct perf_event *event)
{
struct perf_event_attr *attr = &event->attr;
struct perf_event *evts[MAX_HWEVENTS];
@@ -1038,22 +1062,33 @@ static int __hw_perf_event_init(struct perf_event *event)
if (atomic_read(&nmi_active) < 0)
return -ENODEV;
- pmap = NULL;
- if (attr->type == PERF_TYPE_HARDWARE) {
+ switch (attr->type) {
+ case PERF_TYPE_HARDWARE:
if (attr->config >= sparc_pmu->max_events)
return -EINVAL;
pmap = sparc_pmu->event_map(attr->config);
- } else if (attr->type == PERF_TYPE_HW_CACHE) {
+ break;
+
+ case PERF_TYPE_HW_CACHE:
pmap = sparc_map_cache_event(attr->config);
if (IS_ERR(pmap))
return PTR_ERR(pmap);
- } else if (attr->type != PERF_TYPE_RAW)
- return -EOPNOTSUPP;
+ break;
+
+ case PERF_TYPE_RAW:
+ pmap = NULL;
+ break;
+
+ default:
+ return -ENOENT;
+
+ }
if (pmap) {
hwc->event_base = perf_event_encode(pmap);
} else {
- /* User gives us "(encoding << 16) | pic_mask" for
+ /*
+ * User gives us "(encoding << 16) | pic_mask" for
* PERF_TYPE_RAW events.
*/
hwc->event_base = attr->config;
@@ -1071,7 +1106,7 @@ static int __hw_perf_event_init(struct perf_event *event)
n = 0;
if (event->group_leader != event) {
n = collect_events(event->group_leader,
- perf_max_events - 1,
+ MAX_HWEVENTS - 1,
evts, events, current_idx_dmy);
if (n < 0)
return -EINVAL;
@@ -1107,10 +1142,11 @@ static int __hw_perf_event_init(struct perf_event *event)
* Set the flag to make pmu::enable() not perform the
* schedulability test, it will be performed at commit time
*/
-static void sparc_pmu_start_txn(const struct pmu *pmu)
+static void sparc_pmu_start_txn(struct pmu *pmu)
{
struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
+ perf_pmu_disable(pmu);
cpuhw->group_flag |= PERF_EVENT_TXN;
}
@@ -1119,11 +1155,12 @@ static void sparc_pmu_start_txn(const struct pmu *pmu)
* Clear the flag and pmu::enable() will perform the
* schedulability test.
*/
-static void sparc_pmu_cancel_txn(const struct pmu *pmu)
+static void sparc_pmu_cancel_txn(struct pmu *pmu)
{
struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
cpuhw->group_flag &= ~PERF_EVENT_TXN;
+ perf_pmu_enable(pmu);
}
/*
@@ -1131,7 +1168,7 @@ static void sparc_pmu_cancel_txn(const struct pmu *pmu)
* Perform the group schedulability test as a whole
* Return 0 if success
*/
-static int sparc_pmu_commit_txn(const struct pmu *pmu)
+static int sparc_pmu_commit_txn(struct pmu *pmu)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
int n;
@@ -1147,28 +1184,24 @@ static int sparc_pmu_commit_txn(const struct pmu *pmu)
return -EAGAIN;
cpuc->group_flag &= ~PERF_EVENT_TXN;
+ perf_pmu_enable(pmu);
return 0;
}
-static const struct pmu pmu = {
- .enable = sparc_pmu_enable,
- .disable = sparc_pmu_disable,
+static struct pmu pmu = {
+ .pmu_enable = sparc_pmu_enable,
+ .pmu_disable = sparc_pmu_disable,
+ .event_init = sparc_pmu_event_init,
+ .add = sparc_pmu_add,
+ .del = sparc_pmu_del,
+ .start = sparc_pmu_start,
+ .stop = sparc_pmu_stop,
.read = sparc_pmu_read,
- .unthrottle = sparc_pmu_unthrottle,
.start_txn = sparc_pmu_start_txn,
.cancel_txn = sparc_pmu_cancel_txn,
.commit_txn = sparc_pmu_commit_txn,
};
-const struct pmu *hw_perf_event_init(struct perf_event *event)
-{
- int err = __hw_perf_event_init(event);
-
- if (err)
- return ERR_PTR(err);
- return &pmu;
-}
-
void perf_event_print_debug(void)
{
unsigned long flags;
@@ -1244,7 +1277,7 @@ static int __kprobes perf_event_nmi_handler(struct notifier_block *self,
continue;
if (perf_event_overflow(event, 1, &data, regs))
- sparc_pmu_disable_event(cpuc, hwc, idx);
+ sparc_pmu_stop(event, 0);
}
return NOTIFY_STOP;
@@ -1285,28 +1318,21 @@ void __init init_hw_perf_events(void)
pr_cont("Supported PMU type is '%s'\n", sparc_pmu_type);
- /* All sparc64 PMUs currently have 2 events. */
- perf_max_events = 2;
-
+ perf_pmu_register(&pmu);
register_die_notifier(&perf_event_nmi_notifier);
}
-static inline void callchain_store(struct perf_callchain_entry *entry, u64 ip)
-{
- if (entry->nr < PERF_MAX_STACK_DEPTH)
- entry->ip[entry->nr++] = ip;
-}
-
-static void perf_callchain_kernel(struct pt_regs *regs,
- struct perf_callchain_entry *entry)
+void perf_callchain_kernel(struct perf_callchain_entry *entry,
+ struct pt_regs *regs)
{
unsigned long ksp, fp;
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
int graph = 0;
#endif
- callchain_store(entry, PERF_CONTEXT_KERNEL);
- callchain_store(entry, regs->tpc);
+ stack_trace_flush();
+
+ perf_callchain_store(entry, regs->tpc);
ksp = regs->u_regs[UREG_I6];
fp = ksp + STACK_BIAS;
@@ -1330,13 +1356,13 @@ static void perf_callchain_kernel(struct pt_regs *regs,
pc = sf->callers_pc;
fp = (unsigned long)sf->fp + STACK_BIAS;
}
- callchain_store(entry, pc);
+ perf_callchain_store(entry, pc);
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
if ((pc + 8UL) == (unsigned long) &return_to_handler) {
int index = current->curr_ret_stack;
if (current->ret_stack && index >= graph) {
pc = current->ret_stack[index - graph].ret;
- callchain_store(entry, pc);
+ perf_callchain_store(entry, pc);
graph++;
}
}
@@ -1344,13 +1370,12 @@ static void perf_callchain_kernel(struct pt_regs *regs,
} while (entry->nr < PERF_MAX_STACK_DEPTH);
}
-static void perf_callchain_user_64(struct pt_regs *regs,
- struct perf_callchain_entry *entry)
+static void perf_callchain_user_64(struct perf_callchain_entry *entry,
+ struct pt_regs *regs)
{
unsigned long ufp;
- callchain_store(entry, PERF_CONTEXT_USER);
- callchain_store(entry, regs->tpc);
+ perf_callchain_store(entry, regs->tpc);
ufp = regs->u_regs[UREG_I6] + STACK_BIAS;
do {
@@ -1363,17 +1388,16 @@ static void perf_callchain_user_64(struct pt_regs *regs,
pc = sf.callers_pc;
ufp = (unsigned long)sf.fp + STACK_BIAS;
- callchain_store(entry, pc);
+ perf_callchain_store(entry, pc);
} while (entry->nr < PERF_MAX_STACK_DEPTH);
}
-static void perf_callchain_user_32(struct pt_regs *regs,
- struct perf_callchain_entry *entry)
+static void perf_callchain_user_32(struct perf_callchain_entry *entry,
+ struct pt_regs *regs)
{
unsigned long ufp;
- callchain_store(entry, PERF_CONTEXT_USER);
- callchain_store(entry, regs->tpc);
+ perf_callchain_store(entry, regs->tpc);
ufp = regs->u_regs[UREG_I6] & 0xffffffffUL;
do {
@@ -1386,34 +1410,16 @@ static void perf_callchain_user_32(struct pt_regs *regs,
pc = sf.callers_pc;
ufp = (unsigned long)sf.fp;
- callchain_store(entry, pc);
+ perf_callchain_store(entry, pc);
} while (entry->nr < PERF_MAX_STACK_DEPTH);
}
-/* Like powerpc we can't get PMU interrupts within the PMU handler,
- * so no need for separate NMI and IRQ chains as on x86.
- */
-static DEFINE_PER_CPU(struct perf_callchain_entry, callchain);
-
-struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
+void
+perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
{
- struct perf_callchain_entry *entry = &__get_cpu_var(callchain);
-
- entry->nr = 0;
- if (!user_mode(regs)) {
- stack_trace_flush();
- perf_callchain_kernel(regs, entry);
- if (current->mm)
- regs = task_pt_regs(current);
- else
- regs = NULL;
- }
- if (regs) {
- flushw_user();
- if (test_thread_flag(TIF_32BIT))
- perf_callchain_user_32(regs, entry);
- else
- perf_callchain_user_64(regs, entry);
- }
- return entry;
+ flushw_user();
+ if (test_thread_flag(TIF_32BIT))
+ perf_callchain_user_32(entry, regs);
+ else
+ perf_callchain_user_64(entry, regs);
}
diff --git a/arch/sparc/kernel/prom.h b/arch/sparc/kernel/prom.h
index eeb04a782ec8..cf5fe1c0b024 100644
--- a/arch/sparc/kernel/prom.h
+++ b/arch/sparc/kernel/prom.h
@@ -4,12 +4,6 @@
#include <linux/spinlock.h>
#include <asm/prom.h>
-extern void * prom_early_alloc(unsigned long size);
-extern void irq_trans_init(struct device_node *dp);
-
-extern unsigned int prom_unique_id;
-
-extern char *build_path_component(struct device_node *dp);
extern void of_console_init(void);
extern unsigned int prom_early_allocated;
diff --git a/arch/sparc/kernel/prom_common.c b/arch/sparc/kernel/prom_common.c
index 1f830da2ddf2..ed25834328f4 100644
--- a/arch/sparc/kernel/prom_common.c
+++ b/arch/sparc/kernel/prom_common.c
@@ -20,14 +20,13 @@
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/of.h>
+#include <linux/of_pdt.h>
#include <asm/prom.h>
#include <asm/oplib.h>
#include <asm/leon.h>
#include "prom.h"
-void (*prom_build_more)(struct device_node *dp, struct device_node ***nextp);
-
struct device_node *of_console_device;
EXPORT_SYMBOL(of_console_device);
@@ -119,192 +118,47 @@ int of_find_in_proplist(const char *list, const char *match, int len)
}
EXPORT_SYMBOL(of_find_in_proplist);
-unsigned int prom_unique_id;
-
-static struct property * __init build_one_prop(phandle node, char *prev,
- char *special_name,
- void *special_val,
- int special_len)
+/*
+ * SPARC32 and SPARC64's prom_nextprop() do things differently
+ * here, despite sharing the same interface. SPARC32 doesn't fill in 'buf',
+ * returning NULL on an error. SPARC64 fills in 'buf', but sets it to an
+ * empty string upon error.
+ */
+static int __init handle_nextprop_quirks(char *buf, const char *name)
{
- static struct property *tmp = NULL;
- struct property *p;
- const char *name;
-
- if (tmp) {
- p = tmp;
- memset(p, 0, sizeof(*p) + 32);
- tmp = NULL;
- } else {
- p = prom_early_alloc(sizeof(struct property) + 32);
- p->unique_id = prom_unique_id++;
- }
-
- p->name = (char *) (p + 1);
- if (special_name) {
- strcpy(p->name, special_name);
- p->length = special_len;
- p->value = prom_early_alloc(special_len);
- memcpy(p->value, special_val, special_len);
- } else {
- if (prev == NULL) {
- name = prom_firstprop(node, p->name);
- } else {
- name = prom_nextprop(node, prev, p->name);
- }
+ if (!name || strlen(name) == 0)
+ return -1;
- if (!name || strlen(name) == 0) {
- tmp = p;
- return NULL;
- }
#ifdef CONFIG_SPARC32
- strcpy(p->name, name);
+ strcpy(buf, name);
#endif
- p->length = prom_getproplen(node, p->name);
- if (p->length <= 0) {
- p->length = 0;
- } else {
- int len;
-
- p->value = prom_early_alloc(p->length + 1);
- len = prom_getproperty(node, p->name, p->value,
- p->length);
- if (len <= 0)
- p->length = 0;
- ((unsigned char *)p->value)[p->length] = '\0';
- }
- }
- return p;
-}
-
-static struct property * __init build_prop_list(phandle node)
-{
- struct property *head, *tail;
-
- head = tail = build_one_prop(node, NULL,
- ".node", &node, sizeof(node));
-
- tail->next = build_one_prop(node, NULL, NULL, NULL, 0);
- tail = tail->next;
- while(tail) {
- tail->next = build_one_prop(node, tail->name,
- NULL, NULL, 0);
- tail = tail->next;
- }
-
- return head;
-}
-
-static char * __init get_one_property(phandle node, const char *name)
-{
- char *buf = "<NULL>";
- int len;
-
- len = prom_getproplen(node, name);
- if (len > 0) {
- buf = prom_early_alloc(len);
- len = prom_getproperty(node, name, buf, len);
- }
-
- return buf;
-}
-
-static struct device_node * __init prom_create_node(phandle node,
- struct device_node *parent)
-{
- struct device_node *dp;
-
- if (!node)
- return NULL;
-
- dp = prom_early_alloc(sizeof(*dp));
- dp->unique_id = prom_unique_id++;
- dp->parent = parent;
-
- kref_init(&dp->kref);
-
- dp->name = get_one_property(node, "name");
- dp->type = get_one_property(node, "device_type");
- dp->phandle = node;
-
- dp->properties = build_prop_list(node);
-
- irq_trans_init(dp);
-
- return dp;
-}
-
-char * __init build_full_name(struct device_node *dp)
-{
- int len, ourlen, plen;
- char *n;
-
- plen = strlen(dp->parent->full_name);
- ourlen = strlen(dp->path_component_name);
- len = ourlen + plen + 2;
-
- n = prom_early_alloc(len);
- strcpy(n, dp->parent->full_name);
- if (!of_node_is_root(dp->parent)) {
- strcpy(n + plen, "/");
- plen++;
- }
- strcpy(n + plen, dp->path_component_name);
-
- return n;
+ return 0;
}
-static struct device_node * __init prom_build_tree(struct device_node *parent,
- phandle node,
- struct device_node ***nextp)
+static int __init prom_common_nextprop(phandle node, char *prev, char *buf)
{
- struct device_node *ret = NULL, *prev_sibling = NULL;
- struct device_node *dp;
-
- while (1) {
- dp = prom_create_node(node, parent);
- if (!dp)
- break;
-
- if (prev_sibling)
- prev_sibling->sibling = dp;
-
- if (!ret)
- ret = dp;
- prev_sibling = dp;
-
- *(*nextp) = dp;
- *nextp = &dp->allnext;
-
- dp->path_component_name = build_path_component(dp);
- dp->full_name = build_full_name(dp);
-
- dp->child = prom_build_tree(dp, prom_getchild(node), nextp);
-
- if (prom_build_more)
- prom_build_more(dp, nextp);
-
- node = prom_getsibling(node);
- }
+ const char *name;
- return ret;
+ buf[0] = '\0';
+ name = prom_nextprop(node, prev, buf);
+ return handle_nextprop_quirks(buf, name);
}
unsigned int prom_early_allocated __initdata;
+static struct of_pdt_ops prom_sparc_ops __initdata = {
+ .nextprop = prom_common_nextprop,
+ .getproplen = prom_getproplen,
+ .getproperty = prom_getproperty,
+ .getchild = prom_getchild,
+ .getsibling = prom_getsibling,
+};
+
void __init prom_build_devicetree(void)
{
- struct device_node **nextp;
-
- allnodes = prom_create_node(prom_root_node, NULL);
- allnodes->path_component_name = "";
- allnodes->full_name = "/";
-
- nextp = &allnodes->allnext;
- allnodes->child = prom_build_tree(allnodes,
- prom_getchild(allnodes->phandle),
- &nextp);
+ of_pdt_build_devicetree(prom_root_node, &prom_sparc_ops);
of_console_init();
- printk("PROM: Built device tree with %u bytes of memory.\n",
- prom_early_allocated);
+ pr_info("PROM: Built device tree with %u bytes of memory.\n",
+ prom_early_allocated);
}
diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c
index 5f72de67588b..29bafe051bb1 100644
--- a/arch/sparc/kernel/setup_64.c
+++ b/arch/sparc/kernel/setup_64.c
@@ -315,7 +315,7 @@ void __init setup_arch(char **cmdline_p)
#ifdef CONFIG_IP_PNP
if (!ic_set_manually) {
- int chosen = prom_finddevice ("/chosen");
+ phandle chosen = prom_finddevice("/chosen");
u32 cl, sv, gw;
cl = prom_getintdefault (chosen, "client-ip", 0);
diff --git a/arch/sparc/kernel/starfire.c b/arch/sparc/kernel/starfire.c
index 060d0f3a6151..a4446c0fb7a1 100644
--- a/arch/sparc/kernel/starfire.c
+++ b/arch/sparc/kernel/starfire.c
@@ -23,7 +23,7 @@ int this_is_starfire = 0;
void check_if_starfire(void)
{
- int ssnode = prom_finddevice("/ssp-serial");
+ phandle ssnode = prom_finddevice("/ssp-serial");
if (ssnode != 0 && ssnode != -1)
this_is_starfire = 1;
}
diff --git a/arch/sparc/kernel/tadpole.c b/arch/sparc/kernel/tadpole.c
index f476a5f4af6a..9aba8bd5a78b 100644
--- a/arch/sparc/kernel/tadpole.c
+++ b/arch/sparc/kernel/tadpole.c
@@ -100,7 +100,7 @@ static void swift_clockstop(void)
void __init clock_stop_probe(void)
{
- unsigned int node, clk_nd;
+ phandle node, clk_nd;
char name[20];
prom_getstring(prom_root_node, "name", name, sizeof(name));
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index f0434513df15..2f6ae1d1fb6b 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -88,7 +88,7 @@ static void __init read_obp_memory(const char *property,
struct linux_prom64_registers *regs,
int *num_ents)
{
- int node = prom_finddevice("/memory");
+ phandle node = prom_finddevice("/memory");
int prop_size = prom_getproplen(node, property);
int ents, ret, i;
@@ -785,8 +785,7 @@ static int find_node(unsigned long addr)
return -1;
}
-static unsigned long long nid_range(unsigned long long start,
- unsigned long long end, int *nid)
+u64 memblock_nid_range(u64 start, u64 end, int *nid)
{
*nid = find_node(start);
start += PAGE_SIZE;
@@ -804,8 +803,7 @@ static unsigned long long nid_range(unsigned long long start,
return start;
}
#else
-static unsigned long long nid_range(unsigned long long start,
- unsigned long long end, int *nid)
+u64 memblock_nid_range(u64 start, u64 end, int *nid)
{
*nid = 0;
return end;
@@ -822,8 +820,7 @@ static void __init allocate_node_data(int nid)
struct pglist_data *p;
#ifdef CONFIG_NEED_MULTIPLE_NODES
- paddr = memblock_alloc_nid(sizeof(struct pglist_data),
- SMP_CACHE_BYTES, nid, nid_range);
+ paddr = memblock_alloc_try_nid(sizeof(struct pglist_data), SMP_CACHE_BYTES, nid);
if (!paddr) {
prom_printf("Cannot allocate pglist_data for nid[%d]\n", nid);
prom_halt();
@@ -843,8 +840,7 @@ static void __init allocate_node_data(int nid)
if (p->node_spanned_pages) {
num_pages = bootmem_bootmap_pages(p->node_spanned_pages);
- paddr = memblock_alloc_nid(num_pages << PAGE_SHIFT, PAGE_SIZE, nid,
- nid_range);
+ paddr = memblock_alloc_try_nid(num_pages << PAGE_SHIFT, PAGE_SIZE, nid);
if (!paddr) {
prom_printf("Cannot allocate bootmap for nid[%d]\n",
nid);
@@ -972,19 +968,19 @@ int of_node_to_nid(struct device_node *dp)
static void __init add_node_ranges(void)
{
- int i;
+ struct memblock_region *reg;
- for (i = 0; i < memblock.memory.cnt; i++) {
- unsigned long size = memblock_size_bytes(&memblock.memory, i);
+ for_each_memblock(memory, reg) {
+ unsigned long size = reg->size;
unsigned long start, end;
- start = memblock.memory.region[i].base;
+ start = reg->base;
end = start + size;
while (start < end) {
unsigned long this_end;
int nid;
- this_end = nid_range(start, end, &nid);
+ this_end = memblock_nid_range(start, end, &nid);
numadbg("Adding active range nid[%d] "
"start[%lx] end[%lx]\n",
@@ -1281,7 +1277,7 @@ static void __init bootmem_init_nonnuma(void)
{
unsigned long top_of_ram = memblock_end_of_DRAM();
unsigned long total_ram = memblock_phys_mem_size();
- unsigned int i;
+ struct memblock_region *reg;
numadbg("bootmem_init_nonnuma()\n");
@@ -1292,15 +1288,14 @@ static void __init bootmem_init_nonnuma(void)
init_node_masks_nonnuma();
- for (i = 0; i < memblock.memory.cnt; i++) {
- unsigned long size = memblock_size_bytes(&memblock.memory, i);
+ for_each_memblock(memory, reg) {
unsigned long start_pfn, end_pfn;
- if (!size)
+ if (!reg->size)
continue;
- start_pfn = memblock.memory.region[i].base >> PAGE_SHIFT;
- end_pfn = start_pfn + memblock_size_pages(&memblock.memory, i);
+ start_pfn = memblock_region_memory_base_pfn(reg);
+ end_pfn = memblock_region_memory_end_pfn(reg);
add_active_range(0, start_pfn, end_pfn);
}
@@ -1318,7 +1313,7 @@ static void __init reserve_range_in_node(int nid, unsigned long start,
unsigned long this_end;
int n;
- this_end = nid_range(start, end, &n);
+ this_end = memblock_nid_range(start, end, &n);
if (n == nid) {
numadbg(" MATCH reserving range [%lx:%lx]\n",
start, this_end);
@@ -1334,17 +1329,12 @@ static void __init reserve_range_in_node(int nid, unsigned long start,
static void __init trim_reserved_in_node(int nid)
{
- int i;
+ struct memblock_region *reg;
numadbg(" trim_reserved_in_node(%d)\n", nid);
- for (i = 0; i < memblock.reserved.cnt; i++) {
- unsigned long start = memblock.reserved.region[i].base;
- unsigned long size = memblock_size_bytes(&memblock.reserved, i);
- unsigned long end = start + size;
-
- reserve_range_in_node(nid, start, end);
- }
+ for_each_memblock(reserved, reg)
+ reserve_range_in_node(nid, reg->base, reg->base + reg->size);
}
static void __init bootmem_init_one_node(int nid)
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index b0b43aa5e45a..92319aa8b662 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -1262,7 +1262,8 @@ extern unsigned long bootmem_init(unsigned long *pages_avail);
void __init srmmu_paging_init(void)
{
- int i, cpunode;
+ int i;
+ phandle cpunode;
char node_str[128];
pgd_t *pgd;
pmd_t *pmd;
@@ -1398,7 +1399,8 @@ static void __init srmmu_is_bad(void)
static void __init init_vac_layout(void)
{
- int nd, cache_lines;
+ phandle nd;
+ int cache_lines;
char node_str[128];
#ifdef CONFIG_SMP
int cpu = 0;
@@ -2082,7 +2084,7 @@ static void __init get_srmmu_type(void)
/* Next check for Fujitsu Swift. */
if(psr_typ == 0 && psr_vers == 4) {
- int cpunode;
+ phandle cpunode;
char node_str[128];
/* Look if it is not a TurboSparc emulating Swift... */
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
index 4289f90f8697..ddd0d86e508e 100644
--- a/arch/sparc/mm/sun4c.c
+++ b/arch/sparc/mm/sun4c.c
@@ -420,7 +420,7 @@ volatile unsigned long __iomem *sun4c_memerr_reg = NULL;
void __init sun4c_probe_memerr_reg(void)
{
- int node;
+ phandle node;
struct linux_prom_registers regs[1];
node = prom_getchild(prom_root_node);
diff --git a/arch/sparc/prom/init_32.c b/arch/sparc/prom/init_32.c
index ccb36c7f9b8c..d342dba4dd54 100644
--- a/arch/sparc/prom/init_32.c
+++ b/arch/sparc/prom/init_32.c
@@ -20,7 +20,7 @@ enum prom_major_version prom_vers;
unsigned int prom_rev, prom_prev;
/* The root node of the prom device tree. */
-int prom_root_node;
+phandle prom_root_node;
EXPORT_SYMBOL(prom_root_node);
/* Pointer to the device tree operations structure. */
diff --git a/arch/sparc/prom/init_64.c b/arch/sparc/prom/init_64.c
index 7b00f89490a4..3ff911e7d25b 100644
--- a/arch/sparc/prom/init_64.c
+++ b/arch/sparc/prom/init_64.c
@@ -19,7 +19,7 @@ char prom_version[80];
/* The root node of the prom device tree. */
int prom_stdin, prom_stdout;
-int prom_chosen_node;
+phandle prom_chosen_node;
/* You must call prom_init() before you attempt to use any of the
* routines in the prom library. It returns 0 on success, 1 on
@@ -30,7 +30,7 @@ extern void prom_cif_init(void *, void *);
void __init prom_init(void *cif_handler, void *cif_stack)
{
- int node;
+ phandle node;
prom_cif_init(cif_handler, cif_stack);
diff --git a/arch/sparc/prom/memory.c b/arch/sparc/prom/memory.c
index fac7899a29c3..3f263a64857d 100644
--- a/arch/sparc/prom/memory.c
+++ b/arch/sparc/prom/memory.c
@@ -31,7 +31,8 @@ static int __init prom_meminit_v0(void)
static int __init prom_meminit_v2(void)
{
struct linux_prom_registers reg[64];
- int node, size, num_ents, i;
+ phandle node;
+ int size, num_ents, i;
node = prom_searchsiblings(prom_getchild(prom_root_node), "memory");
size = prom_getproperty(node, "available", (char *) reg, sizeof(reg));
diff --git a/arch/sparc/prom/misc_64.c b/arch/sparc/prom/misc_64.c
index 6cb1581d6aef..d24bc44e361e 100644
--- a/arch/sparc/prom/misc_64.c
+++ b/arch/sparc/prom/misc_64.c
@@ -183,7 +183,8 @@ unsigned char prom_get_idprom(char *idbuf, int num_bytes)
int prom_get_mmu_ihandle(void)
{
- int node, ret;
+ phandle node;
+ int ret;
if (prom_mmu_ihandle_cache != 0)
return prom_mmu_ihandle_cache;
@@ -201,7 +202,8 @@ int prom_get_mmu_ihandle(void)
static int prom_get_memory_ihandle(void)
{
static int memory_ihandle_cache;
- int node, ret;
+ phandle node;
+ int ret;
if (memory_ihandle_cache != 0)
return memory_ihandle_cache;
diff --git a/arch/sparc/prom/p1275.c b/arch/sparc/prom/p1275.c
index fa6e4e219b9c..d9850c2b9bf2 100644
--- a/arch/sparc/prom/p1275.c
+++ b/arch/sparc/prom/p1275.c
@@ -39,7 +39,7 @@ void p1275_cmd_direct(unsigned long *args)
unsigned long flags;
raw_local_save_flags(flags);
- raw_local_irq_restore(PIL_NMI);
+ raw_local_irq_restore((unsigned long)PIL_NMI);
raw_spin_lock(&prom_entry_lock);
prom_world(1);
diff --git a/arch/sparc/prom/ranges.c b/arch/sparc/prom/ranges.c
index aeff43e44e45..541fc829c207 100644
--- a/arch/sparc/prom/ranges.c
+++ b/arch/sparc/prom/ranges.c
@@ -68,7 +68,7 @@ EXPORT_SYMBOL(prom_apply_obio_ranges);
void __init prom_ranges_init(void)
{
- int node, obio_node;
+ phandle node, obio_node;
int success;
num_obio_ranges = 0;
@@ -89,8 +89,8 @@ void __init prom_ranges_init(void)
prom_printf("PROMLIB: obio_ranges %d\n", num_obio_ranges);
}
-void
-prom_apply_generic_ranges (int node, int parent, struct linux_prom_registers *regs, int nregs)
+void prom_apply_generic_ranges(phandle node, phandle parent,
+ struct linux_prom_registers *regs, int nregs)
{
int success;
int num_ranges;
diff --git a/arch/sparc/prom/tree_32.c b/arch/sparc/prom/tree_32.c
index b21592f8e3fe..63e08e149774 100644
--- a/arch/sparc/prom/tree_32.c
+++ b/arch/sparc/prom/tree_32.c
@@ -20,10 +20,10 @@ extern void restore_current(void);
static char promlib_buf[128];
/* Internal version of prom_getchild that does not alter return values. */
-int __prom_getchild(int node)
+phandle __prom_getchild(phandle node)
{
unsigned long flags;
- int cnode;
+ phandle cnode;
spin_lock_irqsave(&prom_lock, flags);
cnode = prom_nodeops->no_child(node);
@@ -36,9 +36,9 @@ int __prom_getchild(int node)
/* Return the child of node 'node' or zero if no this node has no
* direct descendent.
*/
-int prom_getchild(int node)
+phandle prom_getchild(phandle node)
{
- int cnode;
+ phandle cnode;
if (node == -1)
return 0;
@@ -52,10 +52,10 @@ int prom_getchild(int node)
EXPORT_SYMBOL(prom_getchild);
/* Internal version of prom_getsibling that does not alter return values. */
-int __prom_getsibling(int node)
+phandle __prom_getsibling(phandle node)
{
unsigned long flags;
- int cnode;
+ phandle cnode;
spin_lock_irqsave(&prom_lock, flags);
cnode = prom_nodeops->no_nextnode(node);
@@ -68,9 +68,9 @@ int __prom_getsibling(int node)
/* Return the next sibling of node 'node' or zero if no more siblings
* at this level of depth in the tree.
*/
-int prom_getsibling(int node)
+phandle prom_getsibling(phandle node)
{
- int sibnode;
+ phandle sibnode;
if (node == -1)
return 0;
@@ -86,7 +86,7 @@ EXPORT_SYMBOL(prom_getsibling);
/* Return the length in bytes of property 'prop' at node 'node'.
* Return -1 on error.
*/
-int prom_getproplen(int node, const char *prop)
+int prom_getproplen(phandle node, const char *prop)
{
int ret;
unsigned long flags;
@@ -106,7 +106,7 @@ EXPORT_SYMBOL(prom_getproplen);
* 'buffer' which has a size of 'bufsize'. If the acquisition
* was successful the length will be returned, else -1 is returned.
*/
-int prom_getproperty(int node, const char *prop, char *buffer, int bufsize)
+int prom_getproperty(phandle node, const char *prop, char *buffer, int bufsize)
{
int plen, ret;
unsigned long flags;
@@ -126,7 +126,7 @@ EXPORT_SYMBOL(prom_getproperty);
/* Acquire an integer property and return its value. Returns -1
* on failure.
*/
-int prom_getint(int node, char *prop)
+int prom_getint(phandle node, char *prop)
{
static int intprop;
@@ -140,7 +140,7 @@ EXPORT_SYMBOL(prom_getint);
/* Acquire an integer property, upon error return the passed default
* integer.
*/
-int prom_getintdefault(int node, char *property, int deflt)
+int prom_getintdefault(phandle node, char *property, int deflt)
{
int retval;
@@ -152,7 +152,7 @@ int prom_getintdefault(int node, char *property, int deflt)
EXPORT_SYMBOL(prom_getintdefault);
/* Acquire a boolean property, 1=TRUE 0=FALSE. */
-int prom_getbool(int node, char *prop)
+int prom_getbool(phandle node, char *prop)
{
int retval;
@@ -166,7 +166,7 @@ EXPORT_SYMBOL(prom_getbool);
* string on error. The char pointer is the user supplied string
* buffer.
*/
-void prom_getstring(int node, char *prop, char *user_buf, int ubuf_size)
+void prom_getstring(phandle node, char *prop, char *user_buf, int ubuf_size)
{
int len;
@@ -180,7 +180,7 @@ EXPORT_SYMBOL(prom_getstring);
/* Does the device at node 'node' have name 'name'?
* YES = 1 NO = 0
*/
-int prom_nodematch(int node, char *name)
+int prom_nodematch(phandle node, char *name)
{
int error;
@@ -194,10 +194,11 @@ int prom_nodematch(int node, char *name)
/* Search siblings at 'node_start' for a node with name
* 'nodename'. Return node if successful, zero if not.
*/
-int prom_searchsiblings(int node_start, char *nodename)
+phandle prom_searchsiblings(phandle node_start, char *nodename)
{
- int thisnode, error;
+ phandle thisnode;
+ int error;
for(thisnode = node_start; thisnode;
thisnode=prom_getsibling(thisnode)) {
@@ -213,7 +214,7 @@ int prom_searchsiblings(int node_start, char *nodename)
EXPORT_SYMBOL(prom_searchsiblings);
/* Interal version of nextprop that does not alter return values. */
-char * __prom_nextprop(int node, char * oprop)
+char *__prom_nextprop(phandle node, char * oprop)
{
unsigned long flags;
char *prop;
@@ -228,7 +229,7 @@ char * __prom_nextprop(int node, char * oprop)
/* Return the first property name for node 'node'. */
/* buffer is unused argument, but as v9 uses it, we need to have the same interface */
-char * prom_firstprop(int node, char *bufer)
+char *prom_firstprop(phandle node, char *bufer)
{
if (node == 0 || node == -1)
return "";
@@ -241,7 +242,7 @@ EXPORT_SYMBOL(prom_firstprop);
* at node 'node' . Returns empty string if no more
* property types for this node.
*/
-char * prom_nextprop(int node, char *oprop, char *buffer)
+char *prom_nextprop(phandle node, char *oprop, char *buffer)
{
if (node == 0 || node == -1)
return "";
@@ -250,11 +251,11 @@ char * prom_nextprop(int node, char *oprop, char *buffer)
}
EXPORT_SYMBOL(prom_nextprop);
-int prom_finddevice(char *name)
+phandle prom_finddevice(char *name)
{
char nbuf[128];
char *s = name, *d;
- int node = prom_root_node, node2;
+ phandle node = prom_root_node, node2;
unsigned int which_io, phys_addr;
struct linux_prom_registers reg[PROMREG_MAX];
@@ -298,7 +299,7 @@ int prom_finddevice(char *name)
}
EXPORT_SYMBOL(prom_finddevice);
-int prom_node_has_property(int node, char *prop)
+int prom_node_has_property(phandle node, char *prop)
{
char *current_property = "";
@@ -314,7 +315,7 @@ EXPORT_SYMBOL(prom_node_has_property);
/* Set property 'pname' at node 'node' to value 'value' which has a length
* of 'size' bytes. Return the number of bytes the prom accepted.
*/
-int prom_setprop(int node, const char *pname, char *value, int size)
+int prom_setprop(phandle node, const char *pname, char *value, int size)
{
unsigned long flags;
int ret;
@@ -329,9 +330,9 @@ int prom_setprop(int node, const char *pname, char *value, int size)
}
EXPORT_SYMBOL(prom_setprop);
-int prom_inst2pkg(int inst)
+phandle prom_inst2pkg(int inst)
{
- int node;
+ phandle node;
unsigned long flags;
spin_lock_irqsave(&prom_lock, flags);
@@ -345,9 +346,10 @@ int prom_inst2pkg(int inst)
/* Return 'node' assigned to a particular prom 'path'
* FIXME: Should work for v0 as well
*/
-int prom_pathtoinode(char *path)
+phandle prom_pathtoinode(char *path)
{
- int node, inst;
+ phandle node;
+ int inst;
inst = prom_devopen (path);
if (inst == -1) return 0;
diff --git a/arch/sparc/prom/tree_64.c b/arch/sparc/prom/tree_64.c
index 9d3f9137a43a..691be68932f8 100644
--- a/arch/sparc/prom/tree_64.c
+++ b/arch/sparc/prom/tree_64.c
@@ -16,7 +16,7 @@
#include <asm/oplib.h>
#include <asm/ldc.h>
-static int prom_node_to_node(const char *type, int node)
+static phandle prom_node_to_node(const char *type, phandle node)
{
unsigned long args[5];
@@ -28,20 +28,20 @@ static int prom_node_to_node(const char *type, int node)
p1275_cmd_direct(args);
- return (int) args[4];
+ return (phandle) args[4];
}
/* Return the child of node 'node' or zero if no this node has no
* direct descendent.
*/
-inline int __prom_getchild(int node)
+inline phandle __prom_getchild(phandle node)
{
return prom_node_to_node("child", node);
}
-inline int prom_getchild(int node)
+inline phandle prom_getchild(phandle node)
{
- int cnode;
+ phandle cnode;
if (node == -1)
return 0;
@@ -52,9 +52,9 @@ inline int prom_getchild(int node)
}
EXPORT_SYMBOL(prom_getchild);
-inline int prom_getparent(int node)
+inline phandle prom_getparent(phandle node)
{
- int cnode;
+ phandle cnode;
if (node == -1)
return 0;
@@ -67,14 +67,14 @@ inline int prom_getparent(int node)
/* Return the next sibling of node 'node' or zero if no more siblings
* at this level of depth in the tree.
*/
-inline int __prom_getsibling(int node)
+inline phandle __prom_getsibling(phandle node)
{
return prom_node_to_node(prom_peer_name, node);
}
-inline int prom_getsibling(int node)
+inline phandle prom_getsibling(phandle node)
{
- int sibnode;
+ phandle sibnode;
if (node == -1)
return 0;
@@ -89,7 +89,7 @@ EXPORT_SYMBOL(prom_getsibling);
/* Return the length in bytes of property 'prop' at node 'node'.
* Return -1 on error.
*/
-inline int prom_getproplen(int node, const char *prop)
+inline int prom_getproplen(phandle node, const char *prop)
{
unsigned long args[6];
@@ -113,7 +113,7 @@ EXPORT_SYMBOL(prom_getproplen);
* 'buffer' which has a size of 'bufsize'. If the acquisition
* was successful the length will be returned, else -1 is returned.
*/
-inline int prom_getproperty(int node, const char *prop,
+inline int prom_getproperty(phandle node, const char *prop,
char *buffer, int bufsize)
{
unsigned long args[8];
@@ -141,7 +141,7 @@ EXPORT_SYMBOL(prom_getproperty);
/* Acquire an integer property and return its value. Returns -1
* on failure.
*/
-inline int prom_getint(int node, const char *prop)
+inline int prom_getint(phandle node, const char *prop)
{
int intprop;
@@ -156,7 +156,7 @@ EXPORT_SYMBOL(prom_getint);
* integer.
*/
-int prom_getintdefault(int node, const char *property, int deflt)
+int prom_getintdefault(phandle node, const char *property, int deflt)
{
int retval;
@@ -169,7 +169,7 @@ int prom_getintdefault(int node, const char *property, int deflt)
EXPORT_SYMBOL(prom_getintdefault);
/* Acquire a boolean property, 1=TRUE 0=FALSE. */
-int prom_getbool(int node, const char *prop)
+int prom_getbool(phandle node, const char *prop)
{
int retval;
@@ -184,7 +184,8 @@ EXPORT_SYMBOL(prom_getbool);
* string on error. The char pointer is the user supplied string
* buffer.
*/
-void prom_getstring(int node, const char *prop, char *user_buf, int ubuf_size)
+void prom_getstring(phandle node, const char *prop, char *user_buf,
+ int ubuf_size)
{
int len;
@@ -198,7 +199,7 @@ EXPORT_SYMBOL(prom_getstring);
/* Does the device at node 'node' have name 'name'?
* YES = 1 NO = 0
*/
-int prom_nodematch(int node, const char *name)
+int prom_nodematch(phandle node, const char *name)
{
char namebuf[128];
prom_getproperty(node, "name", namebuf, sizeof(namebuf));
@@ -210,10 +211,10 @@ int prom_nodematch(int node, const char *name)
/* Search siblings at 'node_start' for a node with name
* 'nodename'. Return node if successful, zero if not.
*/
-int prom_searchsiblings(int node_start, const char *nodename)
+phandle prom_searchsiblings(phandle node_start, const char *nodename)
{
-
- int thisnode, error;
+ phandle thisnode;
+ int error;
char promlib_buf[128];
for(thisnode = node_start; thisnode;
@@ -234,7 +235,7 @@ static const char *prom_nextprop_name = "nextprop";
/* Return the first property type for node 'node'.
* buffer should be at least 32B in length
*/
-inline char *prom_firstprop(int node, char *buffer)
+inline char *prom_firstprop(phandle node, char *buffer)
{
unsigned long args[7];
@@ -260,7 +261,7 @@ EXPORT_SYMBOL(prom_firstprop);
* at node 'node' . Returns NULL string if no more
* property types for this node.
*/
-inline char *prom_nextprop(int node, const char *oprop, char *buffer)
+inline char *prom_nextprop(phandle node, const char *oprop, char *buffer)
{
unsigned long args[7];
char buf[32];
@@ -288,8 +289,7 @@ inline char *prom_nextprop(int node, const char *oprop, char *buffer)
}
EXPORT_SYMBOL(prom_nextprop);
-int
-prom_finddevice(const char *name)
+phandle prom_finddevice(const char *name)
{
unsigned long args[5];
@@ -307,7 +307,7 @@ prom_finddevice(const char *name)
}
EXPORT_SYMBOL(prom_finddevice);
-int prom_node_has_property(int node, const char *prop)
+int prom_node_has_property(phandle node, const char *prop)
{
char buf [32];
@@ -325,7 +325,7 @@ EXPORT_SYMBOL(prom_node_has_property);
* of 'size' bytes. Return the number of bytes the prom accepted.
*/
int
-prom_setprop(int node, const char *pname, char *value, int size)
+prom_setprop(phandle node, const char *pname, char *value, int size)
{
unsigned long args[8];
@@ -355,10 +355,10 @@ prom_setprop(int node, const char *pname, char *value, int size)
}
EXPORT_SYMBOL(prom_setprop);
-inline int prom_inst2pkg(int inst)
+inline phandle prom_inst2pkg(int inst)
{
unsigned long args[5];
- int node;
+ phandle node;
args[0] = (unsigned long) "instance-to-package";
args[1] = 1;
@@ -377,10 +377,10 @@ inline int prom_inst2pkg(int inst)
/* Return 'node' assigned to a particular prom 'path'
* FIXME: Should work for v0 as well
*/
-int
-prom_pathtoinode(const char *path)
+phandle prom_pathtoinode(const char *path)
{
- int node, inst;
+ phandle node;
+ int inst;
inst = prom_devopen (path);
if (inst == 0)
diff --git a/arch/tile/include/asm/bitops.h b/arch/tile/include/asm/bitops.h
index 6832b4be8990..6d4f0ff2c68c 100644
--- a/arch/tile/include/asm/bitops.h
+++ b/arch/tile/include/asm/bitops.h
@@ -120,6 +120,7 @@ static inline unsigned long __arch_hweight64(__u64 w)
#include <asm-generic/bitops/const_hweight.h>
#include <asm-generic/bitops/lock.h>
+#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/ext2-non-atomic.h>
#include <asm-generic/bitops/minix.h>
diff --git a/arch/tile/include/asm/irqflags.h b/arch/tile/include/asm/irqflags.h
index 45cf67c2f286..a11d4837ee4d 100644
--- a/arch/tile/include/asm/irqflags.h
+++ b/arch/tile/include/asm/irqflags.h
@@ -103,55 +103,57 @@ DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask);
#define INITIAL_INTERRUPTS_ENABLED INT_MASK(INT_MEM_ERROR)
/* Disable interrupts. */
-#define raw_local_irq_disable() \
+#define arch_local_irq_disable() \
interrupt_mask_set_mask(LINUX_MASKABLE_INTERRUPTS)
/* Disable all interrupts, including NMIs. */
-#define raw_local_irq_disable_all() \
+#define arch_local_irq_disable_all() \
interrupt_mask_set_mask(-1UL)
/* Re-enable all maskable interrupts. */
-#define raw_local_irq_enable() \
+#define arch_local_irq_enable() \
interrupt_mask_reset_mask(__get_cpu_var(interrupts_enabled_mask))
/* Disable or enable interrupts based on flag argument. */
-#define raw_local_irq_restore(disabled) do { \
+#define arch_local_irq_restore(disabled) do { \
if (disabled) \
- raw_local_irq_disable(); \
+ arch_local_irq_disable(); \
else \
- raw_local_irq_enable(); \
+ arch_local_irq_enable(); \
} while (0)
/* Return true if "flags" argument means interrupts are disabled. */
-#define raw_irqs_disabled_flags(flags) ((flags) != 0)
+#define arch_irqs_disabled_flags(flags) ((flags) != 0)
/* Return true if interrupts are currently disabled. */
-#define raw_irqs_disabled() interrupt_mask_check(INT_MEM_ERROR)
+#define arch_irqs_disabled() interrupt_mask_check(INT_MEM_ERROR)
/* Save whether interrupts are currently disabled. */
-#define raw_local_save_flags(flags) ((flags) = raw_irqs_disabled())
+#define arch_local_save_flags() arch_irqs_disabled()
/* Save whether interrupts are currently disabled, then disable them. */
-#define raw_local_irq_save(flags) \
- do { raw_local_save_flags(flags); raw_local_irq_disable(); } while (0)
+#define arch_local_irq_save() ({ \
+ unsigned long __flags = arch_local_save_flags(); \
+ arch_local_irq_disable(); \
+ __flags; })
/* Prevent the given interrupt from being enabled next time we enable irqs. */
-#define raw_local_irq_mask(interrupt) \
+#define arch_local_irq_mask(interrupt) \
(__get_cpu_var(interrupts_enabled_mask) &= ~INT_MASK(interrupt))
/* Prevent the given interrupt from being enabled immediately. */
-#define raw_local_irq_mask_now(interrupt) do { \
- raw_local_irq_mask(interrupt); \
+#define arch_local_irq_mask_now(interrupt) do { \
+ arch_local_irq_mask(interrupt); \
interrupt_mask_set(interrupt); \
} while (0)
/* Allow the given interrupt to be enabled next time we enable irqs. */
-#define raw_local_irq_unmask(interrupt) \
+#define arch_local_irq_unmask(interrupt) \
(__get_cpu_var(interrupts_enabled_mask) |= INT_MASK(interrupt))
/* Allow the given interrupt to be enabled immediately, if !irqs_disabled. */
-#define raw_local_irq_unmask_now(interrupt) do { \
- raw_local_irq_unmask(interrupt); \
+#define arch_local_irq_unmask_now(interrupt) do { \
+ arch_local_irq_unmask(interrupt); \
if (!irqs_disabled()) \
interrupt_mask_reset(interrupt); \
} while (0)
diff --git a/arch/tile/kernel/hardwall.c b/arch/tile/kernel/hardwall.c
index 584b965dc824..1e54a7843410 100644
--- a/arch/tile/kernel/hardwall.c
+++ b/arch/tile/kernel/hardwall.c
@@ -774,6 +774,7 @@ static const struct file_operations dev_hardwall_fops = {
#endif
.flush = hardwall_flush,
.release = hardwall_release,
+ .llseek = noop_llseek,
};
static struct cdev hardwall_dev;
diff --git a/arch/tile/kernel/irq.c b/arch/tile/kernel/irq.c
index 596c60086930..9a27d563fc30 100644
--- a/arch/tile/kernel/irq.c
+++ b/arch/tile/kernel/irq.c
@@ -208,7 +208,7 @@ static void tile_irq_chip_eoi(unsigned int irq)
}
static struct irq_chip tile_irq_chip = {
- .typename = "tile_irq_chip",
+ .name = "tile_irq_chip",
.ack = tile_irq_chip_ack,
.eoi = tile_irq_chip_eoi,
.mask = tile_irq_chip_mask,
@@ -288,7 +288,7 @@ int show_interrupts(struct seq_file *p, void *v)
for_each_online_cpu(j)
seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
#endif
- seq_printf(p, " %14s", irq_desc[i].chip->typename);
+ seq_printf(p, " %14s", irq_desc[i].chip->name);
seq_printf(p, " %s", action->name);
for (action = action->next; action; action = action->next)
diff --git a/arch/um/drivers/harddog_kern.c b/arch/um/drivers/harddog_kern.c
index cfcac1ff4cf2..2d0266d0254d 100644
--- a/arch/um/drivers/harddog_kern.c
+++ b/arch/um/drivers/harddog_kern.c
@@ -42,7 +42,7 @@
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/reboot.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <asm/uaccess.h>
@@ -50,6 +50,7 @@
MODULE_LICENSE("GPL");
+static DEFINE_MUTEX(harddog_mutex);
static DEFINE_SPINLOCK(lock);
static int timer_alive;
static int harddog_in_fd = -1;
@@ -66,7 +67,7 @@ static int harddog_open(struct inode *inode, struct file *file)
int err = -EBUSY;
char *sock = NULL;
- lock_kernel();
+ mutex_lock(&harddog_mutex);
spin_lock(&lock);
if(timer_alive)
goto err;
@@ -83,11 +84,11 @@ static int harddog_open(struct inode *inode, struct file *file)
timer_alive = 1;
spin_unlock(&lock);
- unlock_kernel();
+ mutex_unlock(&harddog_mutex);
return nonseekable_open(inode, file);
err:
spin_unlock(&lock);
- unlock_kernel();
+ mutex_unlock(&harddog_mutex);
return err;
}
@@ -153,9 +154,9 @@ static long harddog_ioctl(struct file *file,
{
long ret;
- lock_kernel();
+ mutex_lock(&harddog_mutex);
ret = harddog_ioctl_unlocked(file, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&harddog_mutex);
return ret;
}
@@ -166,6 +167,7 @@ static const struct file_operations harddog_fops = {
.unlocked_ioctl = harddog_ioctl,
.open = harddog_open,
.release = harddog_release,
+ .llseek = no_llseek,
};
static struct miscdevice harddog_miscdev = {
diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c
index 0c46e398cd8f..f9f6a4e20590 100644
--- a/arch/um/drivers/hostaudio_kern.c
+++ b/arch/um/drivers/hostaudio_kern.c
@@ -8,7 +8,7 @@
#include "linux/slab.h"
#include "linux/sound.h"
#include "linux/soundcard.h"
-#include "linux/smp_lock.h"
+#include "linux/mutex.h"
#include "asm/uaccess.h"
#include "init.h"
#include "os.h"
@@ -40,6 +40,11 @@ static char *mixer = HOSTAUDIO_DEV_MIXER;
" This is used to specify the host mixer device to the hostaudio driver.\n"\
" The default is \"" HOSTAUDIO_DEV_MIXER "\".\n\n"
+module_param(dsp, charp, 0644);
+MODULE_PARM_DESC(dsp, DSP_HELP);
+module_param(mixer, charp, 0644);
+MODULE_PARM_DESC(mixer, MIXER_HELP);
+
#ifndef MODULE
static int set_dsp(char *name, int *add)
{
@@ -56,17 +61,10 @@ static int set_mixer(char *name, int *add)
}
__uml_setup("mixer=", set_mixer, "mixer=<mixer device>\n" MIXER_HELP);
-
-#else /*MODULE*/
-
-module_param(dsp, charp, 0644);
-MODULE_PARM_DESC(dsp, DSP_HELP);
-
-module_param(mixer, charp, 0644);
-MODULE_PARM_DESC(mixer, MIXER_HELP);
-
#endif
+static DEFINE_MUTEX(hostaudio_mutex);
+
/* /dev/dsp file operations */
static ssize_t hostaudio_read(struct file *file, char __user *buffer,
@@ -202,9 +200,9 @@ static int hostaudio_open(struct inode *inode, struct file *file)
w = 1;
kparam_block_sysfs_write(dsp);
- lock_kernel();
+ mutex_lock(&hostaudio_mutex);
ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
- unlock_kernel();
+ mutex_unlock(&hostaudio_mutex);
kparam_unblock_sysfs_write(dsp);
if (ret < 0) {
@@ -263,9 +261,9 @@ static int hostmixer_open_mixdev(struct inode *inode, struct file *file)
w = 1;
kparam_block_sysfs_write(mixer);
- lock_kernel();
+ mutex_lock(&hostaudio_mutex);
ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0);
- unlock_kernel();
+ mutex_unlock(&hostaudio_mutex);
kparam_unblock_sysfs_write(mixer);
if (ret < 0) {
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index ebc680717e59..975613b23dcf 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -843,6 +843,7 @@ static ssize_t mconsole_proc_write(struct file *file,
static const struct file_operations mconsole_proc_fops = {
.owner = THIS_MODULE,
.write = mconsole_proc_write,
+ .llseek = noop_llseek,
};
static int create_proc_mconsole(void)
diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
index 7158393b6793..8501e7d0015c 100644
--- a/arch/um/drivers/mmapper_kern.c
+++ b/arch/um/drivers/mmapper_kern.c
@@ -93,6 +93,7 @@ static const struct file_operations mmapper_fops = {
.mmap = mmapper_mmap,
.open = mmapper_open,
.release = mmapper_release,
+ .llseek = default_llseek,
};
/*
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 2ab233ba32c1..47d0c37897d5 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -255,18 +255,6 @@ static void uml_net_tx_timeout(struct net_device *dev)
netif_wake_queue(dev);
}
-static int uml_net_set_mac(struct net_device *dev, void *addr)
-{
- struct uml_net_private *lp = netdev_priv(dev);
- struct sockaddr *hwaddr = addr;
-
- spin_lock_irq(&lp->lock);
- eth_mac_addr(dev, hwaddr->sa_data);
- spin_unlock_irq(&lp->lock);
-
- return 0;
-}
-
static int uml_net_change_mtu(struct net_device *dev, int new_mtu)
{
dev->mtu = new_mtu;
@@ -373,7 +361,7 @@ static const struct net_device_ops uml_netdev_ops = {
.ndo_start_xmit = uml_net_start_xmit,
.ndo_set_multicast_list = uml_net_set_multicast_list,
.ndo_tx_timeout = uml_net_tx_timeout,
- .ndo_set_mac_address = uml_net_set_mac,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_change_mtu = uml_net_change_mtu,
.ndo_validate_addr = eth_validate_addr,
};
@@ -472,7 +460,8 @@ static void eth_configure(int n, void *init, char *mac,
((*transport->user->init)(&lp->user, dev) != 0))
goto out_unregister;
- eth_mac_addr(dev, device->mac);
+ /* don't use eth_mac_addr, it will not work here */
+ memcpy(dev->dev_addr, device->mac, ETH_ALEN);
dev->mtu = transport->user->mtu;
dev->netdev_ops = &uml_netdev_ops;
dev->ethtool_ops = &uml_net_ethtool_ops;
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c
index 4949044773ba..981085a93f30 100644
--- a/arch/um/drivers/random.c
+++ b/arch/um/drivers/random.c
@@ -100,6 +100,7 @@ static const struct file_operations rng_chrdev_ops = {
.owner = THIS_MODULE,
.open = rng_dev_open,
.read = rng_dev_read,
+ .llseek = noop_llseek,
};
/* rng_init shouldn't be called more than once at boot time */
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 1bcd208c459f..ba4a98ba39c0 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -33,7 +33,7 @@
#include "linux/mm.h"
#include "linux/slab.h"
#include "linux/vmalloc.h"
-#include "linux/smp_lock.h"
+#include "linux/mutex.h"
#include "linux/blkpg.h"
#include "linux/genhd.h"
#include "linux/spinlock.h"
@@ -100,6 +100,7 @@ static inline void ubd_set_bit(__u64 bit, unsigned char *data)
#define DRIVER_NAME "uml-blkdev"
static DEFINE_MUTEX(ubd_lock);
+static DEFINE_MUTEX(ubd_mutex); /* replaces BKL, might not be needed */
static int ubd_open(struct block_device *bdev, fmode_t mode);
static int ubd_release(struct gendisk *disk, fmode_t mode);
@@ -163,6 +164,7 @@ struct ubd {
struct scatterlist sg[MAX_SG];
struct request *request;
int start_sg, end_sg;
+ sector_t rq_pos;
};
#define DEFAULT_COW { \
@@ -187,6 +189,7 @@ struct ubd {
.request = NULL, \
.start_sg = 0, \
.end_sg = 0, \
+ .rq_pos = 0, \
}
/* Protected by ubd_lock */
@@ -1099,7 +1102,7 @@ static int ubd_open(struct block_device *bdev, fmode_t mode)
struct ubd *ubd_dev = disk->private_data;
int err = 0;
- lock_kernel();
+ mutex_lock(&ubd_mutex);
if(ubd_dev->count == 0){
err = ubd_open_dev(ubd_dev);
if(err){
@@ -1118,7 +1121,7 @@ static int ubd_open(struct block_device *bdev, fmode_t mode)
err = -EROFS;
}*/
out:
- unlock_kernel();
+ mutex_unlock(&ubd_mutex);
return err;
}
@@ -1126,10 +1129,10 @@ static int ubd_release(struct gendisk *disk, fmode_t mode)
{
struct ubd *ubd_dev = disk->private_data;
- lock_kernel();
+ mutex_lock(&ubd_mutex);
if(--ubd_dev->count == 0)
ubd_close_dev(ubd_dev);
- unlock_kernel();
+ mutex_unlock(&ubd_mutex);
return 0;
}
@@ -1228,7 +1231,6 @@ static void do_ubd_request(struct request_queue *q)
{
struct io_thread_req *io_req;
struct request *req;
- sector_t sector;
int n;
while(1){
@@ -1239,12 +1241,12 @@ static void do_ubd_request(struct request_queue *q)
return;
dev->request = req;
+ dev->rq_pos = blk_rq_pos(req);
dev->start_sg = 0;
dev->end_sg = blk_rq_map_sg(q, req, dev->sg);
}
req = dev->request;
- sector = blk_rq_pos(req);
while(dev->start_sg < dev->end_sg){
struct scatterlist *sg = &dev->sg[dev->start_sg];
@@ -1256,10 +1258,9 @@ static void do_ubd_request(struct request_queue *q)
return;
}
prepare_request(req, io_req,
- (unsigned long long)sector << 9,
+ (unsigned long long)dev->rq_pos << 9,
sg->offset, sg->length, sg_page(sg));
- sector += sg->length >> 9;
n = os_write_file(thread_fd, &io_req,
sizeof(struct io_thread_req *));
if(n != sizeof(struct io_thread_req *)){
@@ -1272,6 +1273,7 @@ static void do_ubd_request(struct request_queue *q)
return;
}
+ dev->rq_pos += sg->length >> 9;
dev->start_sg++;
}
dev->end_sg = 0;
diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c
index 49b5e1eb3262..340268be00b5 100644
--- a/arch/um/kernel/exec.c
+++ b/arch/um/kernel/exec.c
@@ -78,13 +78,11 @@ long sys_execve(const char __user *file, const char __user *const __user *argv,
long error;
char *filename;
- lock_kernel();
filename = getname(file);
error = PTR_ERR(filename);
if (IS_ERR(filename)) goto out;
error = execve1(filename, argv, env);
putname(filename);
out:
- unlock_kernel();
return error;
}
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index a3f0b04d7101..a746e3037a5b 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -46,7 +46,7 @@ int show_interrupts(struct seq_file *p, void *v)
for_each_online_cpu(j)
seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
#endif
- seq_printf(p, " %14s", irq_desc[i].chip->typename);
+ seq_printf(p, " %14s", irq_desc[i].chip->name);
seq_printf(p, " %s", action->name);
for (action=action->next; action; action = action->next)
@@ -369,7 +369,7 @@ static void dummy(unsigned int irq)
/* This is used for everything else than the timer. */
static struct irq_chip normal_irq_type = {
- .typename = "SIGIO",
+ .name = "SIGIO",
.release = free_irq_by_irq_and_dev,
.disable = dummy,
.enable = dummy,
@@ -378,7 +378,7 @@ static struct irq_chip normal_irq_type = {
};
static struct irq_chip SIGVTALRM_irq_type = {
- .typename = "SIGVTALRM",
+ .name = "SIGVTALRM",
.release = free_irq_by_irq_and_dev,
.shutdown = dummy, /* never called */
.disable = dummy,
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index cea0cd9a316f..dfabfefc21c4 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -25,14 +25,17 @@ config X86
select HAVE_IDE
select HAVE_OPROFILE
select HAVE_PERF_EVENTS if (!M386 && !M486)
+ select HAVE_IRQ_WORK
select HAVE_IOREMAP_PROT
select HAVE_KPROBES
+ select HAVE_MEMBLOCK
select ARCH_WANT_OPTIONAL_GPIOLIB
select ARCH_WANT_FRAME_POINTERS
select HAVE_DMA_ATTRS
select HAVE_KRETPROBES
select HAVE_OPTPROBES
select HAVE_FTRACE_MCOUNT_RECORD
+ select HAVE_C_RECORDMCOUNT
select HAVE_DYNAMIC_FTRACE
select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_GRAPH_TRACER
@@ -59,6 +62,12 @@ config X86
select ANON_INODES
select HAVE_ARCH_KMEMCHECK
select HAVE_USER_RETURN_NOTIFIER
+ select HAVE_ARCH_JUMP_LABEL
+ select HAVE_TEXT_POKE_SMP
+ select HAVE_GENERIC_HARDIRQS
+ select HAVE_SPARSE_IRQ
+ select GENERIC_IRQ_PROBE
+ select GENERIC_PENDING_IRQ if SMP
config INSTRUCTION_DECODER
def_bool (KPROBES || PERF_EVENTS)
@@ -193,27 +202,10 @@ config ARCH_SUPPORTS_OPTIMIZED_INLINING
config ARCH_SUPPORTS_DEBUG_PAGEALLOC
def_bool y
-config HAVE_EARLY_RES
- def_bool y
-
config HAVE_INTEL_TXT
def_bool y
depends on EXPERIMENTAL && DMAR && ACPI
-# Use the generic interrupt handling code in kernel/irq/:
-config GENERIC_HARDIRQS
- def_bool y
-
-config GENERIC_HARDIRQS_NO__DO_IRQ
- def_bool y
-
-config GENERIC_IRQ_PROBE
- def_bool y
-
-config GENERIC_PENDING_IRQ
- def_bool y
- depends on GENERIC_HARDIRQS && SMP
-
config USE_GENERIC_SMP_HELPERS
def_bool y
depends on SMP
@@ -296,23 +288,6 @@ config X86_X2APIC
If you don't know what to do here, say N.
-config SPARSE_IRQ
- bool "Support sparse irq numbering"
- depends on PCI_MSI || HT_IRQ
- ---help---
- This enables support for sparse irqs. This is useful for distro
- kernels that want to define a high CONFIG_NR_CPUS value but still
- want to have low kernel memory footprint on smaller machines.
-
- ( Sparse IRQs can also be beneficial on NUMA boxes, as they spread
- out the irq_desc[] array in a more NUMA-friendly way. )
-
- If you don't know what to do here, say N.
-
-config NUMA_IRQ_DESC
- def_bool y
- depends on SPARSE_IRQ && NUMA
-
config X86_MPPARSE
bool "Enable MPS table" if ACPI
default y
@@ -517,25 +492,6 @@ if PARAVIRT_GUEST
source "arch/x86/xen/Kconfig"
-config VMI
- bool "VMI Guest support (DEPRECATED)"
- select PARAVIRT
- depends on X86_32
- ---help---
- VMI provides a paravirtualized interface to the VMware ESX server
- (it could be used by other hypervisors in theory too, but is not
- at the moment), by linking the kernel to a GPL-ed ROM module
- provided by the hypervisor.
-
- As of September 2009, VMware has started a phased retirement
- of this feature from VMware's products. Please see
- feature-removal-schedule.txt for details. If you are
- planning to enable this option, please note that you cannot
- live migrate a VMI enabled VM to a future VMware product,
- which doesn't support VMI. So if you expect your kernel to
- seamlessly migrate to newer VMware products, keep this
- disabled.
-
config KVM_CLOCK
bool "KVM paravirtualized clock"
select PARAVIRT
@@ -590,16 +546,7 @@ config PARAVIRT_DEBUG
a paravirt_op is missing when it is called.
config NO_BOOTMEM
- default y
- bool "Disable Bootmem code"
- ---help---
- Use early_res directly instead of bootmem before slab is ready.
- - allocator (buddy) [generic]
- - early allocator (bootmem) [generic]
- - very early allocator (reserve_early*()) [x86]
- - very very early allocator (early brk model) [x86]
- So reduce one layer between early allocator to final allocator
-
+ def_bool y
config MEMTEST
bool "Memtest"
@@ -670,7 +617,7 @@ config GART_IOMMU
bool "GART IOMMU support" if EMBEDDED
default y
select SWIOTLB
- depends on X86_64 && PCI && K8_NB
+ depends on X86_64 && PCI && AMD_NB
---help---
Support for full DMA access of devices with 32bit memory access only
on systems with more than 3GB. This is usually needed for USB,
@@ -795,6 +742,17 @@ config SCHED_MC
making when dealing with multi-core CPU chips at a cost of slightly
increased overhead in some places. If unsure say N here.
+config IRQ_TIME_ACCOUNTING
+ bool "Fine granularity task level IRQ time accounting"
+ default n
+ ---help---
+ Select this option to enable fine granularity task irq time
+ accounting. This is done by reading a timestamp on each
+ transitions between softirq and hardirq state, so there can be a
+ small performance impact.
+
+ If in doubt, say N here.
+
source "kernel/Kconfig.preempt"
config X86_UP_APIC
@@ -1148,6 +1106,9 @@ config X86_PAE
config ARCH_PHYS_ADDR_T_64BIT
def_bool X86_64 || X86_PAE
+config ARCH_DMA_ADDR_T_64BIT
+ def_bool X86_64 || HIGHMEM64G
+
config DIRECT_GBPAGES
bool "Enable 1GB pages for kernel pagetables" if EMBEDDED
default y
@@ -1326,25 +1287,34 @@ config X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK
Set whether the default state of memory_corruption_check is
on or off.
-config X86_RESERVE_LOW_64K
- bool "Reserve low 64K of RAM on AMI/Phoenix BIOSen"
- default y
+config X86_RESERVE_LOW
+ int "Amount of low memory, in kilobytes, to reserve for the BIOS"
+ default 64
+ range 4 640
---help---
- Reserve the first 64K of physical RAM on BIOSes that are known
- to potentially corrupt that memory range. A numbers of BIOSes are
- known to utilize this area during suspend/resume, so it must not
- be used by the kernel.
+ Specify the amount of low memory to reserve for the BIOS.
+
+ The first page contains BIOS data structures that the kernel
+ must not use, so that page must always be reserved.
+
+ By default we reserve the first 64K of physical RAM, as a
+ number of BIOSes are known to corrupt that memory range
+ during events such as suspend/resume or monitor cable
+ insertion, so it must not be used by the kernel.
- Set this to N if you are absolutely sure that you trust the BIOS
- to get all its memory reservations and usages right.
+ You can set this to 4 if you are absolutely sure that you
+ trust the BIOS to get all its memory reservations and usages
+ right. If you know your BIOS have problems beyond the
+ default 64K area, you can set this to 640 to avoid using the
+ entire low memory range.
- If you have doubts about the BIOS (e.g. suspend/resume does not
- work or there's kernel crashes after certain hardware hotplug
- events) and it's not AMI or Phoenix, then you might want to enable
- X86_CHECK_BIOS_CORRUPTION=y to allow the kernel to check typical
- corruption patterns.
+ If you have doubts about the BIOS (e.g. suspend/resume does
+ not work or there's kernel crashes after certain hardware
+ hotplug events) then you might want to enable
+ X86_CHECK_BIOS_CORRUPTION=y to allow the kernel to check
+ typical corruption patterns.
- Say Y if unsure.
+ Leave this to the default value of 64 if you are unsure.
config MATH_EMULATION
bool
@@ -1900,7 +1870,7 @@ config PCI_GODIRECT
bool "Direct"
config PCI_GOOLPC
- bool "OLPC"
+ bool "OLPC XO-1"
depends on OLPC
config PCI_GOANY
@@ -2061,14 +2031,21 @@ config SCx200HR_TIMER
config OLPC
bool "One Laptop Per Child support"
select GPIOLIB
+ select OLPC_OPENFIRMWARE
---help---
Add support for detecting the unique features of the OLPC
XO hardware.
+config OLPC_XO1
+ tristate "OLPC XO-1 support"
+ depends on OLPC && PCI
+ ---help---
+ Add support for non-essential features of the OLPC XO-1 laptop.
+
config OLPC_OPENFIRMWARE
bool "Support for OLPC's Open Firmware"
depends on !X86_64 && !X86_PAE
- default y if OLPC
+ default n
help
This option adds support for the implementation of Open Firmware
that is used on the OLPC XO-1 Children's Machine.
@@ -2076,7 +2053,7 @@ config OLPC_OPENFIRMWARE
endif # X86_32
-config K8_NB
+config AMD_NB
def_bool y
depends on CPU_SUP_AMD && PCI
@@ -2125,6 +2102,10 @@ config HAVE_ATOMIC_IOMAP
def_bool y
depends on X86_32
+config HAVE_TEXT_POKE_SMP
+ bool
+ select STOP_MACHINE if SMP
+
source "net/Kconfig"
source "drivers/Kconfig"
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index 75085080b63e..b59ee765414e 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -43,6 +43,10 @@ config EARLY_PRINTK
with klogd/syslogd or the X server. You should normally N here,
unless you want to debug such a crash.
+config EARLY_PRINTK_MRST
+ bool "Early printk for MRST platform support"
+ depends on EARLY_PRINTK && X86_MRST
+
config EARLY_PRINTK_DBGP
bool "Early printk via EHCI debug port"
depends on EARLY_PRINTK && PCI
@@ -121,16 +125,6 @@ config DEBUG_NX_TEST
and the software setup of this feature.
If in doubt, say "N"
-config 4KSTACKS
- bool "Use 4Kb for kernel stacks instead of 8Kb"
- depends on X86_32
- ---help---
- If you say Y here the kernel will use a 4Kb stacksize for the
- kernel stack attached to each process/thread. This facilitates
- running more threads on a system and also reduces the pressure
- on the VM subsystem for higher order allocations. This option
- will also use IRQ stacks to compensate for the reduced stackspace.
-
config DOUBLEFAULT
default y
bool "Enable doublefault exception handler" if EMBEDDED
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index e8c8881351b3..b02e509072a7 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -96,8 +96,12 @@ cfi := $(call as-instr,.cfi_startproc\n.cfi_rel_offset $(sp-y)$(comma)0\n.cfi_en
# is .cfi_signal_frame supported too?
cfi-sigframe := $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1)
cfi-sections := $(call as-instr,.cfi_sections .debug_frame,-DCONFIG_AS_CFI_SECTIONS=1)
-KBUILD_AFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections)
-KBUILD_CFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections)
+
+# does binutils support specific instructions?
+asinstr := $(call as-instr,fxsaveq (%rax),-DCONFIG_AS_FXSAVEQ=1)
+
+KBUILD_AFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections) $(asinstr)
+KBUILD_CFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections) $(asinstr)
LDFLAGS := -m elf_$(UTS_MACHINE)
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
index 8f7bef8e9fff..23f315c9f215 100644
--- a/arch/x86/boot/compressed/misc.c
+++ b/arch/x86/boot/compressed/misc.c
@@ -229,18 +229,35 @@ void *memset(void *s, int c, size_t n)
ss[i] = c;
return s;
}
-
+#ifdef CONFIG_X86_32
void *memcpy(void *dest, const void *src, size_t n)
{
- int i;
- const char *s = src;
- char *d = dest;
+ int d0, d1, d2;
+ asm volatile(
+ "rep ; movsl\n\t"
+ "movl %4,%%ecx\n\t"
+ "rep ; movsb\n\t"
+ : "=&c" (d0), "=&D" (d1), "=&S" (d2)
+ : "0" (n >> 2), "g" (n & 3), "1" (dest), "2" (src)
+ : "memory");
- for (i = 0; i < n; i++)
- d[i] = s[i];
return dest;
}
+#else
+void *memcpy(void *dest, const void *src, size_t n)
+{
+ long d0, d1, d2;
+ asm volatile(
+ "rep ; movsq\n\t"
+ "movq %4,%%rcx\n\t"
+ "rep ; movsb\n\t"
+ : "=&c" (d0), "=&D" (d1), "=&S" (d2)
+ : "0" (n >> 3), "g" (n & 7), "1" (dest), "2" (src)
+ : "memory");
+ return dest;
+}
+#endif
static void error(char *x)
{
diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c
index 0350311906ae..2d93bdbc9ac0 100644
--- a/arch/x86/ia32/ia32_aout.c
+++ b/arch/x86/ia32/ia32_aout.c
@@ -34,7 +34,7 @@
#include <asm/ia32.h>
#undef WARN_OLD
-#undef CORE_DUMP /* probably broken */
+#undef CORE_DUMP /* definitely broken */
static int load_aout_binary(struct linux_binprm *, struct pt_regs *regs);
static int load_aout_library(struct file *);
@@ -131,21 +131,15 @@ static void set_brk(unsigned long start, unsigned long end)
* macros to write out all the necessary info.
*/
-static int dump_write(struct file *file, const void *addr, int nr)
-{
- return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
-}
+#include <linux/coredump.h>
#define DUMP_WRITE(addr, nr) \
if (!dump_write(file, (void *)(addr), (nr))) \
goto end_coredump;
-#define DUMP_SEEK(offset) \
- if (file->f_op->llseek) { \
- if (file->f_op->llseek(file, (offset), 0) != (offset)) \
- goto end_coredump; \
- } else \
- file->f_pos = (offset)
+#define DUMP_SEEK(offset) \
+ if (!dump_seek(file, offset)) \
+ goto end_coredump;
#define START_DATA() (u.u_tsize << PAGE_SHIFT)
#define START_STACK(u) (u.start_stack)
@@ -217,12 +211,6 @@ static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file,
dump_size = dump.u_ssize << PAGE_SHIFT;
DUMP_WRITE(dump_start, dump_size);
}
- /*
- * Finally dump the task struct. Not be used by gdb, but
- * could be useful
- */
- set_fs(KERNEL_DS);
- DUMP_WRITE(current, sizeof(*current));
end_coredump:
set_fs(fs);
return has_dumped;
diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h
index bc6abb7bc7ee..76561d20ea2f 100644
--- a/arch/x86/include/asm/alternative.h
+++ b/arch/x86/include/asm/alternative.h
@@ -4,6 +4,7 @@
#include <linux/types.h>
#include <linux/stddef.h>
#include <linux/stringify.h>
+#include <linux/jump_label.h>
#include <asm/asm.h>
/*
@@ -160,6 +161,8 @@ static inline void apply_paravirt(struct paravirt_patch_site *start,
#define __parainstructions_end NULL
#endif
+extern void *text_poke_early(void *addr, const void *opcode, size_t len);
+
/*
* Clear and restore the kernel write-protection flag on the local CPU.
* Allows the kernel to edit read-only pages.
@@ -180,4 +183,12 @@ static inline void apply_paravirt(struct paravirt_patch_site *start,
extern void *text_poke(void *addr, const void *opcode, size_t len);
extern void *text_poke_smp(void *addr, const void *opcode, size_t len);
+#if defined(CONFIG_DYNAMIC_FTRACE) || defined(HAVE_JUMP_LABEL)
+#define IDEAL_NOP_SIZE_5 5
+extern unsigned char ideal_nop5[IDEAL_NOP_SIZE_5];
+extern void arch_init_ideal_nop5(void);
+#else
+static inline void arch_init_ideal_nop5(void) {}
+#endif
+
#endif /* _ASM_X86_ALTERNATIVE_H */
diff --git a/arch/x86/include/asm/amd_iommu.h b/arch/x86/include/asm/amd_iommu.h
index 5af2982133b5..a6863a2dec1f 100644
--- a/arch/x86/include/asm/amd_iommu.h
+++ b/arch/x86/include/asm/amd_iommu.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007-2009 Advanced Micro Devices, Inc.
+ * Copyright (C) 2007-2010 Advanced Micro Devices, Inc.
* Author: Joerg Roedel <joerg.roedel@amd.com>
* Leo Duran <leo.duran@amd.com>
*
@@ -24,11 +24,11 @@
#ifdef CONFIG_AMD_IOMMU
-extern void amd_iommu_detect(void);
+extern int amd_iommu_detect(void);
#else
-static inline void amd_iommu_detect(void) { }
+static inline int amd_iommu_detect(void) { return -ENODEV; }
#endif
diff --git a/arch/x86/include/asm/amd_iommu_proto.h b/arch/x86/include/asm/amd_iommu_proto.h
index cb030374b90a..916bc8111a01 100644
--- a/arch/x86/include/asm/amd_iommu_proto.h
+++ b/arch/x86/include/asm/amd_iommu_proto.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Advanced Micro Devices, Inc.
+ * Copyright (C) 2009-2010 Advanced Micro Devices, Inc.
* Author: Joerg Roedel <joerg.roedel@amd.com>
*
* This program is free software; you can redistribute it and/or modify it
diff --git a/arch/x86/include/asm/amd_iommu_types.h b/arch/x86/include/asm/amd_iommu_types.h
index 08616180deaf..e3509fc303bf 100644
--- a/arch/x86/include/asm/amd_iommu_types.h
+++ b/arch/x86/include/asm/amd_iommu_types.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007-2009 Advanced Micro Devices, Inc.
+ * Copyright (C) 2007-2010 Advanced Micro Devices, Inc.
* Author: Joerg Roedel <joerg.roedel@amd.com>
* Leo Duran <leo.duran@amd.com>
*
@@ -416,13 +416,22 @@ struct amd_iommu {
struct dma_ops_domain *default_dom;
/*
- * This array is required to work around a potential BIOS bug.
- * The BIOS may miss to restore parts of the PCI configuration
- * space when the system resumes from S3. The result is that the
- * IOMMU does not execute commands anymore which leads to system
- * failure.
+ * We can't rely on the BIOS to restore all values on reinit, so we
+ * need to stash them
*/
- u32 cache_cfg[4];
+
+ /* The iommu BAR */
+ u32 stored_addr_lo;
+ u32 stored_addr_hi;
+
+ /*
+ * Each iommu has 6 l1s, each of which is documented as having 0x12
+ * registers
+ */
+ u32 stored_l1[6][0x12];
+
+ /* The l2 indirect registers */
+ u32 stored_l2[0x83];
};
/*
diff --git a/arch/x86/include/asm/k8.h b/arch/x86/include/asm/amd_nb.h
index af00bd1d2089..c8517f81b21e 100644
--- a/arch/x86/include/asm/k8.h
+++ b/arch/x86/include/asm/amd_nb.h
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_K8_H
-#define _ASM_X86_K8_H
+#ifndef _ASM_X86_AMD_NB_H
+#define _ASM_X86_AMD_NB_H
#include <linux/pci.h>
@@ -7,24 +7,27 @@ extern struct pci_device_id k8_nb_ids[];
struct bootnode;
extern int early_is_k8_nb(u32 value);
-extern struct pci_dev **k8_northbridges;
-extern int num_k8_northbridges;
extern int cache_k8_northbridges(void);
extern void k8_flush_garts(void);
extern int k8_get_nodes(struct bootnode *nodes);
extern int k8_numa_init(unsigned long start_pfn, unsigned long end_pfn);
extern int k8_scan_nodes(void);
-#ifdef CONFIG_K8_NB
-extern int num_k8_northbridges;
+struct k8_northbridge_info {
+ u16 num;
+ u8 gart_supported;
+ struct pci_dev **nb_misc;
+};
+extern struct k8_northbridge_info k8_northbridges;
+
+#ifdef CONFIG_AMD_NB
static inline struct pci_dev *node_to_k8_nb_misc(int node)
{
- return (node < num_k8_northbridges) ? k8_northbridges[node] : NULL;
+ return (node < k8_northbridges.num) ? k8_northbridges.nb_misc[node] : NULL;
}
#else
-#define num_k8_northbridges 0
static inline struct pci_dev *node_to_k8_nb_misc(int node)
{
@@ -33,4 +36,4 @@ static inline struct pci_dev *node_to_k8_nb_misc(int node)
#endif
-#endif /* _ASM_X86_K8_H */
+#endif /* _ASM_X86_AMD_NB_H */
diff --git a/arch/x86/include/asm/apb_timer.h b/arch/x86/include/asm/apb_timer.h
index a69b1ac9eaf8..2fefa501d3ba 100644
--- a/arch/x86/include/asm/apb_timer.h
+++ b/arch/x86/include/asm/apb_timer.h
@@ -54,7 +54,6 @@ extern struct clock_event_device *global_clock_event;
extern unsigned long apbt_quick_calibrate(void);
extern int arch_setup_apbt_irqs(int irq, int trigger, int mask, int cpu);
extern void apbt_setup_secondary_clock(void);
-extern unsigned int boot_cpu_id;
extern struct sfi_timer_table_entry *sfi_get_mtmr(int hint);
extern void sfi_free_mtmr(struct sfi_timer_table_entry *mtmr);
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index 1fa03e04ae44..286de34b0ed6 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -252,9 +252,7 @@ static inline int apic_is_clustered_box(void)
}
#endif
-extern u8 setup_APIC_eilvt_mce(u8 vector, u8 msg_type, u8 mask);
-extern u8 setup_APIC_eilvt_ibs(u8 vector, u8 msg_type, u8 mask);
-
+extern int setup_APIC_eilvt(u8 lvt_off, u8 vector, u8 msg_type, u8 mask);
#else /* !CONFIG_X86_LOCAL_APIC */
static inline void lapic_shutdown(void) { }
diff --git a/arch/x86/include/asm/apicdef.h b/arch/x86/include/asm/apicdef.h
index 7fe3b3060f08..a859ca461fb0 100644
--- a/arch/x86/include/asm/apicdef.h
+++ b/arch/x86/include/asm/apicdef.h
@@ -131,6 +131,7 @@
#define APIC_EILVTn(n) (0x500 + 0x10 * n)
#define APIC_EILVT_NR_AMD_K8 1 /* # of extended interrupts */
#define APIC_EILVT_NR_AMD_10H 4
+#define APIC_EILVT_NR_MAX APIC_EILVT_NR_AMD_10H
#define APIC_EILVT_LVTOFF(x) (((x) >> 4) & 0xF)
#define APIC_EILVT_MSG_FIX 0x0
#define APIC_EILVT_MSG_SMI 0x2
diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h
index bafd80defa43..903683b07e42 100644
--- a/arch/x86/include/asm/bitops.h
+++ b/arch/x86/include/asm/bitops.h
@@ -440,6 +440,8 @@ static inline int fls(int x)
#ifdef __KERNEL__
+#include <asm-generic/bitops/find.h>
+
#include <asm-generic/bitops/sched.h>
#define ARCH_HAS_FAST_MULTIPLIER 1
diff --git a/arch/x86/include/asm/calgary.h b/arch/x86/include/asm/calgary.h
index 0918654305af..0d467b338835 100644
--- a/arch/x86/include/asm/calgary.h
+++ b/arch/x86/include/asm/calgary.h
@@ -62,9 +62,9 @@ struct cal_chipset_ops {
extern int use_calgary;
#ifdef CONFIG_CALGARY_IOMMU
-extern void detect_calgary(void);
+extern int detect_calgary(void);
#else
-static inline void detect_calgary(void) { return; }
+static inline int detect_calgary(void) { return -ENODEV; }
#endif
#endif /* _ASM_X86_CALGARY_H */
diff --git a/arch/x86/include/asm/calling.h b/arch/x86/include/asm/calling.h
index 0e63c9a2a8d0..30af5a832163 100644
--- a/arch/x86/include/asm/calling.h
+++ b/arch/x86/include/asm/calling.h
@@ -48,36 +48,38 @@ For 32-bit we have the following conventions - kernel is built with
/*
- * 64-bit system call stack frame layout defines and helpers,
- * for assembly code:
+ * 64-bit system call stack frame layout defines and helpers, for
+ * assembly code (note that the seemingly unnecessary parentheses
+ * are to prevent cpp from inserting spaces in expressions that get
+ * passed to macros):
*/
-#define R15 0
-#define R14 8
-#define R13 16
-#define R12 24
-#define RBP 32
-#define RBX 40
+#define R15 (0)
+#define R14 (8)
+#define R13 (16)
+#define R12 (24)
+#define RBP (32)
+#define RBX (40)
/* arguments: interrupts/non tracing syscalls only save up to here: */
-#define R11 48
-#define R10 56
-#define R9 64
-#define R8 72
-#define RAX 80
-#define RCX 88
-#define RDX 96
-#define RSI 104
-#define RDI 112
-#define ORIG_RAX 120 /* + error_code */
+#define R11 (48)
+#define R10 (56)
+#define R9 (64)
+#define R8 (72)
+#define RAX (80)
+#define RCX (88)
+#define RDX (96)
+#define RSI (104)
+#define RDI (112)
+#define ORIG_RAX (120) /* + error_code */
/* end of arguments */
/* cpu exception frame or undefined in case of fast syscall: */
-#define RIP 128
-#define CS 136
-#define EFLAGS 144
-#define RSP 152
-#define SS 160
+#define RIP (128)
+#define CS (136)
+#define EFLAGS (144)
+#define RSP (152)
+#define SS (160)
#define ARGOFFSET R11
#define SWFRAME ORIG_RAX
@@ -111,7 +113,7 @@ For 32-bit we have the following conventions - kernel is built with
.endif
.endm
-#define ARG_SKIP 9*8
+#define ARG_SKIP (9*8)
.macro RESTORE_ARGS skiprax=0, addskip=0, skiprcx=0, skipr11=0, \
skipr8910=0, skiprdx=0
@@ -169,7 +171,7 @@ For 32-bit we have the following conventions - kernel is built with
.endif
.endm
-#define REST_SKIP 6*8
+#define REST_SKIP (6*8)
.macro SAVE_REST
subq $REST_SKIP, %rsp
diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
index b185091bf19c..4fab24de26b1 100644
--- a/arch/x86/include/asm/cpu.h
+++ b/arch/x86/include/asm/cpu.h
@@ -32,6 +32,5 @@ extern void arch_unregister_cpu(int);
DECLARE_PER_CPU(int, cpu_state);
-extern unsigned int boot_cpu_id;
#endif /* _ASM_X86_CPU_H */
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 3f76523589af..220e2ea08e80 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -152,10 +152,14 @@
#define X86_FEATURE_3DNOWPREFETCH (6*32+ 8) /* 3DNow prefetch instructions */
#define X86_FEATURE_OSVW (6*32+ 9) /* OS Visible Workaround */
#define X86_FEATURE_IBS (6*32+10) /* Instruction Based Sampling */
-#define X86_FEATURE_SSE5 (6*32+11) /* SSE-5 */
+#define X86_FEATURE_XOP (6*32+11) /* extended AVX instructions */
#define X86_FEATURE_SKINIT (6*32+12) /* SKINIT/STGI instructions */
#define X86_FEATURE_WDT (6*32+13) /* Watchdog timer */
+#define X86_FEATURE_LWP (6*32+15) /* Light Weight Profiling */
+#define X86_FEATURE_FMA4 (6*32+16) /* 4 operands MAC instructions */
#define X86_FEATURE_NODEID_MSR (6*32+19) /* NodeId MSR */
+#define X86_FEATURE_TBM (6*32+21) /* trailing bit manipulations */
+#define X86_FEATURE_TOPOEXT (6*32+22) /* topology extensions CPUID leafs */
/*
* Auxiliary flags: Linux defined - For features scattered in various
@@ -180,6 +184,13 @@
#define X86_FEATURE_LBRV (8*32+ 6) /* AMD LBR Virtualization support */
#define X86_FEATURE_SVML (8*32+ 7) /* "svm_lock" AMD SVM locking MSR */
#define X86_FEATURE_NRIPS (8*32+ 8) /* "nrip_save" AMD SVM next_rip save */
+#define X86_FEATURE_TSCRATEMSR (8*32+ 9) /* "tsc_scale" AMD TSC scaling support */
+#define X86_FEATURE_VMCBCLEAN (8*32+10) /* "vmcb_clean" AMD VMCB clean bits support */
+#define X86_FEATURE_FLUSHBYASID (8*32+11) /* AMD flush-by-ASID support */
+#define X86_FEATURE_DECODEASSISTS (8*32+12) /* AMD Decode Assists support */
+#define X86_FEATURE_PAUSEFILTER (8*32+13) /* AMD filtered pause intercept */
+#define X86_FEATURE_PFTHRESHOLD (8*32+14) /* AMD pause filter threshold */
+
/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */
#define X86_FEATURE_FSGSBASE (9*32+ 0) /* {RD/WR}{FS/GS}BASE instructions*/
diff --git a/arch/x86/include/asm/dwarf2.h b/arch/x86/include/asm/dwarf2.h
index 733f7e91e7a9..326099199318 100644
--- a/arch/x86/include/asm/dwarf2.h
+++ b/arch/x86/include/asm/dwarf2.h
@@ -89,6 +89,16 @@
CFI_ADJUST_CFA_OFFSET -8
.endm
+ .macro pushfq_cfi
+ pushfq
+ CFI_ADJUST_CFA_OFFSET 8
+ .endm
+
+ .macro popfq_cfi
+ popfq
+ CFI_ADJUST_CFA_OFFSET -8
+ .endm
+
.macro movq_cfi reg offset=0
movq %\reg, \offset(%rsp)
CFI_REL_OFFSET \reg, \offset
@@ -109,6 +119,16 @@
CFI_ADJUST_CFA_OFFSET -4
.endm
+ .macro pushfl_cfi
+ pushfl
+ CFI_ADJUST_CFA_OFFSET 4
+ .endm
+
+ .macro popfl_cfi
+ popfl
+ CFI_ADJUST_CFA_OFFSET -4
+ .endm
+
.macro movl_cfi reg offset=0
movl %\reg, \offset(%esp)
CFI_REL_OFFSET \reg, \offset
diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
index ec8a52d14ab1..5be1542fbfaf 100644
--- a/arch/x86/include/asm/e820.h
+++ b/arch/x86/include/asm/e820.h
@@ -112,23 +112,13 @@ static inline void early_memtest(unsigned long start, unsigned long end)
}
#endif
-extern unsigned long end_user_pfn;
-
-extern u64 find_e820_area(u64 start, u64 end, u64 size, u64 align);
-extern u64 find_e820_area_size(u64 start, u64 *sizep, u64 align);
-extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align);
-#include <linux/early_res.h>
-
extern unsigned long e820_end_of_ram_pfn(void);
extern unsigned long e820_end_of_low_ram_pfn(void);
-extern int e820_find_active_region(const struct e820entry *ei,
- unsigned long start_pfn,
- unsigned long last_pfn,
- unsigned long *ei_startpfn,
- unsigned long *ei_endpfn);
-extern void e820_register_active_regions(int nid, unsigned long start_pfn,
- unsigned long end_pfn);
-extern u64 e820_hole_size(u64 start, u64 end);
+extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align);
+
+void memblock_x86_fill(void);
+void memblock_find_dma_reserve(void);
+
extern void finish_e820_parsing(void);
extern void e820_reserve_resources(void);
extern void e820_reserve_resources_late(void);
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index 8406ed7f9926..8e4a16508d4e 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -90,7 +90,7 @@ extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size,
#endif /* CONFIG_X86_32 */
extern int add_efi_memmap;
-extern void efi_reserve_early(void);
+extern void efi_memblock_x86_reserve_range(void);
extern void efi_call_phys_prelog(void);
extern void efi_call_phys_epilog(void);
diff --git a/arch/x86/include/asm/entry_arch.h b/arch/x86/include/asm/entry_arch.h
index 8e8ec663a98f..57650ab4a5f5 100644
--- a/arch/x86/include/asm/entry_arch.h
+++ b/arch/x86/include/asm/entry_arch.h
@@ -16,22 +16,11 @@ BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR)
BUILD_INTERRUPT(irq_move_cleanup_interrupt,IRQ_MOVE_CLEANUP_VECTOR)
BUILD_INTERRUPT(reboot_interrupt,REBOOT_VECTOR)
-BUILD_INTERRUPT3(invalidate_interrupt0,INVALIDATE_TLB_VECTOR_START+0,
- smp_invalidate_interrupt)
-BUILD_INTERRUPT3(invalidate_interrupt1,INVALIDATE_TLB_VECTOR_START+1,
- smp_invalidate_interrupt)
-BUILD_INTERRUPT3(invalidate_interrupt2,INVALIDATE_TLB_VECTOR_START+2,
- smp_invalidate_interrupt)
-BUILD_INTERRUPT3(invalidate_interrupt3,INVALIDATE_TLB_VECTOR_START+3,
- smp_invalidate_interrupt)
-BUILD_INTERRUPT3(invalidate_interrupt4,INVALIDATE_TLB_VECTOR_START+4,
- smp_invalidate_interrupt)
-BUILD_INTERRUPT3(invalidate_interrupt5,INVALIDATE_TLB_VECTOR_START+5,
- smp_invalidate_interrupt)
-BUILD_INTERRUPT3(invalidate_interrupt6,INVALIDATE_TLB_VECTOR_START+6,
- smp_invalidate_interrupt)
-BUILD_INTERRUPT3(invalidate_interrupt7,INVALIDATE_TLB_VECTOR_START+7,
+.irpc idx, "01234567"
+BUILD_INTERRUPT3(invalidate_interrupt\idx,
+ (INVALIDATE_TLB_VECTOR_START)+\idx,
smp_invalidate_interrupt)
+.endr
#endif
BUILD_INTERRUPT(x86_platform_ipi, X86_PLATFORM_IPI_VECTOR)
@@ -49,8 +38,8 @@ BUILD_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR)
BUILD_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR)
BUILD_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR)
-#ifdef CONFIG_PERF_EVENTS
-BUILD_INTERRUPT(perf_pending_interrupt, LOCAL_PENDING_VECTOR)
+#ifdef CONFIG_IRQ_WORK
+BUILD_INTERRUPT(irq_work_interrupt, IRQ_WORK_VECTOR)
#endif
#ifdef CONFIG_X86_THERMAL_VECTOR
diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h
index d07b44f7d1dc..4d293dced62f 100644
--- a/arch/x86/include/asm/fixmap.h
+++ b/arch/x86/include/asm/fixmap.h
@@ -214,5 +214,20 @@ static inline unsigned long virt_to_fix(const unsigned long vaddr)
BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
return __virt_to_fix(vaddr);
}
+
+/* Return an pointer with offset calculated */
+static inline unsigned long __set_fixmap_offset(enum fixed_addresses idx,
+ phys_addr_t phys, pgprot_t flags)
+{
+ __set_fixmap(idx, phys, flags);
+ return fix_to_virt(idx) + (phys & (PAGE_SIZE - 1));
+}
+
+#define set_fixmap_offset(idx, phys) \
+ __set_fixmap_offset(idx, phys, PAGE_KERNEL)
+
+#define set_fixmap_offset_nocache(idx, phys) \
+ __set_fixmap_offset(idx, phys, PAGE_KERNEL_NOCACHE)
+
#endif /* !__ASSEMBLY__ */
#endif /* _ASM_X86_FIXMAP_H */
diff --git a/arch/x86/include/asm/gart.h b/arch/x86/include/asm/gart.h
index 4ac5b0f33fc1..43085bfc99c3 100644
--- a/arch/x86/include/asm/gart.h
+++ b/arch/x86/include/asm/gart.h
@@ -17,6 +17,7 @@ extern int fix_aperture;
#define GARTEN (1<<0)
#define DISGARTCPU (1<<4)
#define DISGARTIO (1<<5)
+#define DISTLBWALKPRB (1<<6)
/* GART cache control register bits. */
#define INVGART (1<<0)
@@ -27,7 +28,6 @@ extern int fix_aperture;
#define AMD64_GARTAPERTUREBASE 0x94
#define AMD64_GARTTABLEBASE 0x98
#define AMD64_GARTCACHECTL 0x9c
-#define AMD64_GARTEN (1<<0)
#ifdef CONFIG_GART_IOMMU
extern int gart_iommu_aperture;
@@ -37,7 +37,7 @@ extern int gart_iommu_aperture_disabled;
extern void early_gart_iommu_check(void);
extern int gart_iommu_init(void);
extern void __init gart_parse_options(char *);
-extern void gart_iommu_hole_init(void);
+extern int gart_iommu_hole_init(void);
#else
#define gart_iommu_aperture 0
@@ -50,13 +50,27 @@ static inline void early_gart_iommu_check(void)
static inline void gart_parse_options(char *options)
{
}
-static inline void gart_iommu_hole_init(void)
+static inline int gart_iommu_hole_init(void)
{
+ return -ENODEV;
}
#endif
extern int agp_amd64_init(void);
+static inline void gart_set_size_and_enable(struct pci_dev *dev, u32 order)
+{
+ u32 ctl;
+
+ /*
+ * Don't enable translation but enable GART IO and CPU accesses.
+ * Also, set DISTLBWALKPRB since GART tables memory is UC.
+ */
+ ctl = DISTLBWALKPRB | order << 1;
+
+ pci_write_config_dword(dev, AMD64_GARTAPERTURECTL, ctl);
+}
+
static inline void enable_gart_translation(struct pci_dev *dev, u64 addr)
{
u32 tmp, ctl;
diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h
index aeab29aee617..55e4de613f0e 100644
--- a/arch/x86/include/asm/hardirq.h
+++ b/arch/x86/include/asm/hardirq.h
@@ -14,7 +14,7 @@ typedef struct {
#endif
unsigned int x86_platform_ipis; /* arch dependent */
unsigned int apic_perf_irqs;
- unsigned int apic_pending_irqs;
+ unsigned int apic_irq_work_irqs;
#ifdef CONFIG_SMP
unsigned int irq_resched_count;
unsigned int irq_call_count;
diff --git a/arch/x86/include/asm/hpet.h b/arch/x86/include/asm/hpet.h
index 1d5c08a1bdfd..2c392d663dce 100644
--- a/arch/x86/include/asm/hpet.h
+++ b/arch/x86/include/asm/hpet.h
@@ -74,10 +74,12 @@ extern void hpet_disable(void);
extern unsigned int hpet_readl(unsigned int a);
extern void force_hpet_resume(void);
-extern void hpet_msi_unmask(unsigned int irq);
-extern void hpet_msi_mask(unsigned int irq);
-extern void hpet_msi_write(unsigned int irq, struct msi_msg *msg);
-extern void hpet_msi_read(unsigned int irq, struct msi_msg *msg);
+struct irq_data;
+extern void hpet_msi_unmask(struct irq_data *data);
+extern void hpet_msi_mask(struct irq_data *data);
+struct hpet_dev;
+extern void hpet_msi_write(struct hpet_dev *hdev, struct msi_msg *msg);
+extern void hpet_msi_read(struct hpet_dev *hdev, struct msi_msg *msg);
#ifdef CONFIG_PCI_MSI
extern int arch_setup_hpet_msi(unsigned int irq, unsigned int id);
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index 46c0fe05f230..0274ec5a7e62 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -29,7 +29,7 @@
extern void apic_timer_interrupt(void);
extern void x86_platform_ipi(void);
extern void error_interrupt(void);
-extern void perf_pending_interrupt(void);
+extern void irq_work_interrupt(void);
extern void spurious_interrupt(void);
extern void thermal_interrupt(void);
@@ -78,6 +78,13 @@ static inline void set_io_apic_irq_attr(struct io_apic_irq_attr *irq_attr,
irq_attr->polarity = polarity;
}
+struct irq_2_iommu {
+ struct intel_iommu *iommu;
+ u16 irte_index;
+ u16 sub_handle;
+ u8 irte_mask;
+};
+
/*
* This is performance-critical, we want to do it O(1)
*
@@ -89,15 +96,17 @@ struct irq_cfg {
cpumask_var_t old_domain;
u8 vector;
u8 move_in_progress : 1;
+#ifdef CONFIG_INTR_REMAP
+ struct irq_2_iommu irq_2_iommu;
+#endif
};
-extern struct irq_cfg *irq_cfg(unsigned int);
extern int assign_irq_vector(int, struct irq_cfg *, const struct cpumask *);
extern void send_cleanup_vector(struct irq_cfg *);
-struct irq_desc;
-extern unsigned int set_desc_affinity(struct irq_desc *, const struct cpumask *,
- unsigned int *dest_id);
+struct irq_data;
+int __ioapic_set_affinity(struct irq_data *, const struct cpumask *,
+ unsigned int *dest_id);
extern int IO_APIC_get_PCI_irq_vector(int bus, int devfn, int pin, struct io_apic_irq_attr *irq_attr);
extern void setup_ioapic_dest(void);
diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h
index a73a8d5a5e69..4aa2bb3b242a 100644
--- a/arch/x86/include/asm/i387.h
+++ b/arch/x86/include/asm/i387.h
@@ -55,6 +55,12 @@ extern int save_i387_xstate_ia32(void __user *buf);
extern int restore_i387_xstate_ia32(void __user *buf);
#endif
+#ifdef CONFIG_MATH_EMULATION
+extern void finit_soft_fpu(struct i387_soft_struct *soft);
+#else
+static inline void finit_soft_fpu(struct i387_soft_struct *soft) {}
+#endif
+
#define X87_FSW_ES (1 << 7) /* Exception Summary */
static __always_inline __pure bool use_xsaveopt(void)
@@ -67,6 +73,11 @@ static __always_inline __pure bool use_xsave(void)
return static_cpu_has(X86_FEATURE_XSAVE);
}
+static __always_inline __pure bool use_fxsr(void)
+{
+ return static_cpu_has(X86_FEATURE_FXSR);
+}
+
extern void __sanitize_i387_state(struct task_struct *);
static inline void sanitize_i387_state(struct task_struct *tsk)
@@ -77,19 +88,11 @@ static inline void sanitize_i387_state(struct task_struct *tsk)
}
#ifdef CONFIG_X86_64
-
-/* Ignore delayed exceptions from user space */
-static inline void tolerant_fwait(void)
-{
- asm volatile("1: fwait\n"
- "2:\n"
- _ASM_EXTABLE(1b, 2b));
-}
-
static inline int fxrstor_checking(struct i387_fxsave_struct *fx)
{
int err;
+ /* See comment in fxsave() below. */
asm volatile("1: rex64/fxrstor (%[fx])\n\t"
"2:\n"
".section .fixup,\"ax\"\n"
@@ -98,44 +101,10 @@ static inline int fxrstor_checking(struct i387_fxsave_struct *fx)
".previous\n"
_ASM_EXTABLE(1b, 3b)
: [err] "=r" (err)
-#if 0 /* See comment in fxsave() below. */
- : [fx] "r" (fx), "m" (*fx), "0" (0));
-#else
- : [fx] "cdaSDb" (fx), "m" (*fx), "0" (0));
-#endif
+ : [fx] "R" (fx), "m" (*fx), "0" (0));
return err;
}
-/* AMD CPUs don't save/restore FDP/FIP/FOP unless an exception
- is pending. Clear the x87 state here by setting it to fixed
- values. The kernel data segment can be sometimes 0 and sometimes
- new user value. Both should be ok.
- Use the PDA as safe address because it should be already in L1. */
-static inline void fpu_clear(struct fpu *fpu)
-{
- struct xsave_struct *xstate = &fpu->state->xsave;
- struct i387_fxsave_struct *fx = &fpu->state->fxsave;
-
- /*
- * xsave header may indicate the init state of the FP.
- */
- if (use_xsave() &&
- !(xstate->xsave_hdr.xstate_bv & XSTATE_FP))
- return;
-
- if (unlikely(fx->swd & X87_FSW_ES))
- asm volatile("fnclex");
- alternative_input(ASM_NOP8 ASM_NOP2,
- " emms\n" /* clear stack tags */
- " fildl %%gs:0", /* load to clear state */
- X86_FEATURE_FXSAVE_LEAK);
-}
-
-static inline void clear_fpu_state(struct task_struct *tsk)
-{
- fpu_clear(&tsk->thread.fpu);
-}
-
static inline int fxsave_user(struct i387_fxsave_struct __user *fx)
{
int err;
@@ -149,6 +118,7 @@ static inline int fxsave_user(struct i387_fxsave_struct __user *fx)
if (unlikely(err))
return -EFAULT;
+ /* See comment in fxsave() below. */
asm volatile("1: rex64/fxsave (%[fx])\n\t"
"2:\n"
".section .fixup,\"ax\"\n"
@@ -157,11 +127,7 @@ static inline int fxsave_user(struct i387_fxsave_struct __user *fx)
".previous\n"
_ASM_EXTABLE(1b, 3b)
: [err] "=r" (err), "=m" (*fx)
-#if 0 /* See comment in fxsave() below. */
- : [fx] "r" (fx), "0" (0));
-#else
- : [fx] "cdaSDb" (fx), "0" (0));
-#endif
+ : [fx] "R" (fx), "0" (0));
if (unlikely(err) &&
__clear_user(fx, sizeof(struct i387_fxsave_struct)))
err = -EFAULT;
@@ -175,56 +141,29 @@ static inline void fpu_fxsave(struct fpu *fpu)
uses any extended registers for addressing, a second REX prefix
will be generated (to the assembler, rex64 followed by semicolon
is a separate instruction), and hence the 64-bitness is lost. */
-#if 0
+
+#ifdef CONFIG_AS_FXSAVEQ
/* Using "fxsaveq %0" would be the ideal choice, but is only supported
starting with gas 2.16. */
__asm__ __volatile__("fxsaveq %0"
: "=m" (fpu->state->fxsave));
-#elif 0
+#else
/* Using, as a workaround, the properly prefixed form below isn't
accepted by any binutils version so far released, complaining that
the same type of prefix is used twice if an extended register is
- needed for addressing (fix submitted to mainline 2005-11-21). */
- __asm__ __volatile__("rex64/fxsave %0"
- : "=m" (fpu->state->fxsave));
-#else
- /* This, however, we can work around by forcing the compiler to select
+ needed for addressing (fix submitted to mainline 2005-11-21).
+ asm volatile("rex64/fxsave %0"
+ : "=m" (fpu->state->fxsave));
+ This, however, we can work around by forcing the compiler to select
an addressing mode that doesn't require extended registers. */
- __asm__ __volatile__("rex64/fxsave (%1)"
- : "=m" (fpu->state->fxsave)
- : "cdaSDb" (&fpu->state->fxsave));
+ asm volatile("rex64/fxsave (%[fx])"
+ : "=m" (fpu->state->fxsave)
+ : [fx] "R" (&fpu->state->fxsave));
#endif
}
-static inline void fpu_save_init(struct fpu *fpu)
-{
- if (use_xsave())
- fpu_xsave(fpu);
- else
- fpu_fxsave(fpu);
-
- fpu_clear(fpu);
-}
-
-static inline void __save_init_fpu(struct task_struct *tsk)
-{
- fpu_save_init(&tsk->thread.fpu);
- task_thread_info(tsk)->status &= ~TS_USEDFPU;
-}
-
#else /* CONFIG_X86_32 */
-#ifdef CONFIG_MATH_EMULATION
-extern void finit_soft_fpu(struct i387_soft_struct *soft);
-#else
-static inline void finit_soft_fpu(struct i387_soft_struct *soft) {}
-#endif
-
-static inline void tolerant_fwait(void)
-{
- asm volatile("fnclex ; fwait");
-}
-
/* perform fxrstor iff the processor has extended states, otherwise frstor */
static inline int fxrstor_checking(struct i387_fxsave_struct *fx)
{
@@ -241,6 +180,14 @@ static inline int fxrstor_checking(struct i387_fxsave_struct *fx)
return 0;
}
+static inline void fpu_fxsave(struct fpu *fpu)
+{
+ asm volatile("fxsave %[fx]"
+ : [fx] "=m" (fpu->state->fxsave));
+}
+
+#endif /* CONFIG_X86_64 */
+
/* We need a safe address that is cheap to find and that is already
in L1 during context switch. The best choices are unfortunately
different for UP and SMP */
@@ -256,47 +203,33 @@ static inline int fxrstor_checking(struct i387_fxsave_struct *fx)
static inline void fpu_save_init(struct fpu *fpu)
{
if (use_xsave()) {
- struct xsave_struct *xstate = &fpu->state->xsave;
- struct i387_fxsave_struct *fx = &fpu->state->fxsave;
-
fpu_xsave(fpu);
/*
* xsave header may indicate the init state of the FP.
*/
- if (!(xstate->xsave_hdr.xstate_bv & XSTATE_FP))
- goto end;
-
- if (unlikely(fx->swd & X87_FSW_ES))
- asm volatile("fnclex");
-
- /*
- * we can do a simple return here or be paranoid :)
- */
- goto clear_state;
+ if (!(fpu->state->xsave.xsave_hdr.xstate_bv & XSTATE_FP))
+ return;
+ } else if (use_fxsr()) {
+ fpu_fxsave(fpu);
+ } else {
+ asm volatile("fsave %[fx]; fwait"
+ : [fx] "=m" (fpu->state->fsave));
+ return;
}
- /* Use more nops than strictly needed in case the compiler
- varies code */
- alternative_input(
- "fnsave %[fx] ;fwait;" GENERIC_NOP8 GENERIC_NOP4,
- "fxsave %[fx]\n"
- "bt $7,%[fsw] ; jnc 1f ; fnclex\n1:",
- X86_FEATURE_FXSR,
- [fx] "m" (fpu->state->fxsave),
- [fsw] "m" (fpu->state->fxsave.swd) : "memory");
-clear_state:
+ if (unlikely(fpu->state->fxsave.swd & X87_FSW_ES))
+ asm volatile("fnclex");
+
/* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception
is pending. Clear the x87 state here by setting it to fixed
values. safe_address is a random variable that should be in L1 */
alternative_input(
- GENERIC_NOP8 GENERIC_NOP2,
+ ASM_NOP8 ASM_NOP2,
"emms\n\t" /* clear stack tags */
- "fildl %[addr]", /* set F?P to defined value */
+ "fildl %P[addr]", /* set F?P to defined value */
X86_FEATURE_FXSAVE_LEAK,
[addr] "m" (safe_address));
-end:
- ;
}
static inline void __save_init_fpu(struct task_struct *tsk)
@@ -305,9 +238,6 @@ static inline void __save_init_fpu(struct task_struct *tsk)
task_thread_info(tsk)->status &= ~TS_USEDFPU;
}
-
-#endif /* CONFIG_X86_64 */
-
static inline int fpu_fxrstor_checking(struct fpu *fpu)
{
return fxrstor_checking(&fpu->state->fxsave);
@@ -344,7 +274,10 @@ static inline void __unlazy_fpu(struct task_struct *tsk)
static inline void __clear_fpu(struct task_struct *tsk)
{
if (task_thread_info(tsk)->status & TS_USEDFPU) {
- tolerant_fwait();
+ /* Ignore delayed exceptions from user space */
+ asm volatile("1: fwait\n"
+ "2:\n"
+ _ASM_EXTABLE(1b, 2b));
task_thread_info(tsk)->status &= ~TS_USEDFPU;
stts();
}
@@ -405,19 +338,6 @@ static inline void irq_ts_restore(int TS_state)
stts();
}
-#ifdef CONFIG_X86_64
-
-static inline void save_init_fpu(struct task_struct *tsk)
-{
- __save_init_fpu(tsk);
- stts();
-}
-
-#define unlazy_fpu __unlazy_fpu
-#define clear_fpu __clear_fpu
-
-#else /* CONFIG_X86_32 */
-
/*
* These disable preemption on their own and are safe
*/
@@ -443,8 +363,6 @@ static inline void clear_fpu(struct task_struct *tsk)
preempt_enable();
}
-#endif /* CONFIG_X86_64 */
-
/*
* i387 state interaction
*/
@@ -508,7 +426,4 @@ extern void fpu_finit(struct fpu *fpu);
#endif /* __ASSEMBLY__ */
-#define PSHUFB_XMM5_XMM0 .byte 0x66, 0x0f, 0x38, 0x00, 0xc5
-#define PSHUFB_XMM5_XMM6 .byte 0x66, 0x0f, 0x38, 0x00, 0xf5
-
#endif /* _ASM_X86_I387_H */
diff --git a/arch/x86/include/asm/i8259.h b/arch/x86/include/asm/i8259.h
index 1655147646aa..a20365953bf8 100644
--- a/arch/x86/include/asm/i8259.h
+++ b/arch/x86/include/asm/i8259.h
@@ -55,6 +55,8 @@ extern struct irq_chip i8259A_chip;
struct legacy_pic {
int nr_legacy_irqs;
struct irq_chip *chip;
+ void (*mask)(unsigned int irq);
+ void (*unmask)(unsigned int irq);
void (*mask_all)(void);
void (*restore_mask)(void);
void (*init)(int auto_eoi);
diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index 30a3e9776123..f0203f4791a8 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -206,6 +206,7 @@ static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
extern void iounmap(volatile void __iomem *addr);
+extern void set_iounmap_nonlazy(void);
#ifdef __KERNEL__
@@ -348,6 +349,7 @@ extern void __iomem *early_memremap(resource_size_t phys_addr,
unsigned long size);
extern void early_iounmap(void __iomem *addr, unsigned long size);
extern void fixup_early_ioremap(void);
+extern bool is_early_ioremap_ptep(pte_t *ptep);
#define IO_SPACE_LIMIT 0xffff
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 9cb2edb87c2f..c8be4566c3d2 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -170,12 +170,6 @@ extern int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
extern void probe_nr_irqs_gsi(void);
-extern int setup_ioapic_entry(int apic, int irq,
- struct IO_APIC_route_entry *entry,
- unsigned int destination, int trigger,
- int polarity, int vector, int pin);
-extern void ioapic_write_entry(int apic, int pin,
- struct IO_APIC_route_entry e);
extern void setup_ioapic_ids_from_mpc(void);
struct mp_ioapic_gsi{
diff --git a/arch/x86/include/asm/iommu_table.h b/arch/x86/include/asm/iommu_table.h
new file mode 100644
index 000000000000..f229b13a5f30
--- /dev/null
+++ b/arch/x86/include/asm/iommu_table.h
@@ -0,0 +1,100 @@
+#ifndef _ASM_X86_IOMMU_TABLE_H
+#define _ASM_X86_IOMMU_TABLE_H
+
+#include <asm/swiotlb.h>
+
+/*
+ * History lesson:
+ * The execution chain of IOMMUs in 2.6.36 looks as so:
+ *
+ * [xen-swiotlb]
+ * |
+ * +----[swiotlb *]--+
+ * / | \
+ * / | \
+ * [GART] [Calgary] [Intel VT-d]
+ * /
+ * /
+ * [AMD-Vi]
+ *
+ * *: if SWIOTLB detected 'iommu=soft'/'swiotlb=force' it would skip
+ * over the rest of IOMMUs and unconditionally initialize the SWIOTLB.
+ * Also it would surreptitiously initialize set the swiotlb=1 if there were
+ * more than 4GB and if the user did not pass in 'iommu=off'. The swiotlb
+ * flag would be turned off by all IOMMUs except the Calgary one.
+ *
+ * The IOMMU_INIT* macros allow a similar tree (or more complex if desired)
+ * to be built by defining who we depend on.
+ *
+ * And all that needs to be done is to use one of the macros in the IOMMU
+ * and the pci-dma.c will take care of the rest.
+ */
+
+struct iommu_table_entry {
+ initcall_t detect;
+ initcall_t depend;
+ void (*early_init)(void); /* No memory allocate available. */
+ void (*late_init)(void); /* Yes, can allocate memory. */
+#define IOMMU_FINISH_IF_DETECTED (1<<0)
+#define IOMMU_DETECTED (1<<1)
+ int flags;
+};
+/*
+ * Macro fills out an entry in the .iommu_table that is equivalent
+ * to the fields that 'struct iommu_table_entry' has. The entries
+ * that are put in the .iommu_table section are not put in any order
+ * hence during boot-time we will have to resort them based on
+ * dependency. */
+
+
+#define __IOMMU_INIT(_detect, _depend, _early_init, _late_init, _finish)\
+ static const struct iommu_table_entry const \
+ __iommu_entry_##_detect __used \
+ __attribute__ ((unused, __section__(".iommu_table"), \
+ aligned((sizeof(void *))))) \
+ = {_detect, _depend, _early_init, _late_init, \
+ _finish ? IOMMU_FINISH_IF_DETECTED : 0}
+/*
+ * The simplest IOMMU definition. Provide the detection routine
+ * and it will be run after the SWIOTLB and the other IOMMUs
+ * that utilize this macro. If the IOMMU is detected (ie, the
+ * detect routine returns a positive value), the other IOMMUs
+ * are also checked. You can use IOMMU_INIT_POST_FINISH if you prefer
+ * to stop detecting the other IOMMUs after yours has been detected.
+ */
+#define IOMMU_INIT_POST(_detect) \
+ __IOMMU_INIT(_detect, pci_swiotlb_detect_4gb, 0, 0, 0)
+
+#define IOMMU_INIT_POST_FINISH(detect) \
+ __IOMMU_INIT(_detect, pci_swiotlb_detect_4gb, 0, 0, 1)
+
+/*
+ * A more sophisticated version of IOMMU_INIT. This variant requires:
+ * a). A detection routine function.
+ * b). The name of the detection routine we depend on to get called
+ * before us.
+ * c). The init routine which gets called if the detection routine
+ * returns a positive value from the pci_iommu_alloc. This means
+ * no presence of a memory allocator.
+ * d). Similar to the 'init', except that this gets called from pci_iommu_init
+ * where we do have a memory allocator.
+ *
+ * The standard vs the _FINISH differs in that the _FINISH variant will
+ * continue detecting other IOMMUs in the call list after the
+ * the detection routine returns a positive number. The _FINISH will
+ * stop the execution chain. Both will still call the 'init' and
+ * 'late_init' functions if they are set.
+ */
+#define IOMMU_INIT_FINISH(_detect, _depend, _init, _late_init) \
+ __IOMMU_INIT(_detect, _depend, _init, _late_init, 1)
+
+#define IOMMU_INIT(_detect, _depend, _init, _late_init) \
+ __IOMMU_INIT(_detect, _depend, _init, _late_init, 0)
+
+void sort_iommu_table(struct iommu_table_entry *start,
+ struct iommu_table_entry *finish);
+
+void check_iommu_entries(struct iommu_table_entry *start,
+ struct iommu_table_entry *finish);
+
+#endif /* _ASM_X86_IOMMU_TABLE_H */
diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h
index 5458380b6ef8..0bf5b0083650 100644
--- a/arch/x86/include/asm/irq.h
+++ b/arch/x86/include/asm/irq.h
@@ -19,18 +19,16 @@ static inline int irq_canonicalize(int irq)
# define ARCH_HAS_NMI_WATCHDOG
#endif
-#ifdef CONFIG_4KSTACKS
- extern void irq_ctx_init(int cpu);
- extern void irq_ctx_exit(int cpu);
-# define __ARCH_HAS_DO_SOFTIRQ
+#ifdef CONFIG_X86_32
+extern void irq_ctx_init(int cpu);
+extern void irq_ctx_exit(int cpu);
#else
# define irq_ctx_init(cpu) do { } while (0)
# define irq_ctx_exit(cpu) do { } while (0)
-# ifdef CONFIG_X86_64
-# define __ARCH_HAS_DO_SOFTIRQ
-# endif
#endif
+#define __ARCH_HAS_DO_SOFTIRQ
+
#ifdef CONFIG_HOTPLUG_CPU
#include <linux/cpumask.h>
extern void fixup_irqs(void);
diff --git a/arch/x86/include/asm/irq_remapping.h b/arch/x86/include/asm/irq_remapping.h
index f275e2244505..1c23360fb2d8 100644
--- a/arch/x86/include/asm/irq_remapping.h
+++ b/arch/x86/include/asm/irq_remapping.h
@@ -3,4 +3,39 @@
#define IRTE_DEST(dest) ((x2apic_mode) ? dest : dest << 8)
+#ifdef CONFIG_INTR_REMAP
+static inline void prepare_irte(struct irte *irte, int vector,
+ unsigned int dest)
+{
+ memset(irte, 0, sizeof(*irte));
+
+ irte->present = 1;
+ irte->dst_mode = apic->irq_dest_mode;
+ /*
+ * Trigger mode in the IRTE will always be edge, and for IO-APIC, the
+ * actual level or edge trigger will be setup in the IO-APIC
+ * RTE. This will help simplify level triggered irq migration.
+ * For more details, see the comments (in io_apic.c) explainig IO-APIC
+ * irq migration in the presence of interrupt-remapping.
+ */
+ irte->trigger_mode = 0;
+ irte->dlvry_mode = apic->irq_delivery_mode;
+ irte->vector = vector;
+ irte->dest_id = IRTE_DEST(dest);
+ irte->redir_hint = 1;
+}
+static inline bool irq_remapped(struct irq_cfg *cfg)
+{
+ return cfg->irq_2_iommu.iommu != NULL;
+}
+#else
+static void prepare_irte(struct irte *irte, int vector, unsigned int dest)
+{
+}
+static inline bool irq_remapped(struct irq_cfg *cfg)
+{
+ return false;
+}
+#endif
+
#endif /* _ASM_X86_IRQ_REMAPPING_H */
diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h
index e2ca30092557..6af0894dafb4 100644
--- a/arch/x86/include/asm/irq_vectors.h
+++ b/arch/x86/include/asm/irq_vectors.h
@@ -114,9 +114,9 @@
#define X86_PLATFORM_IPI_VECTOR 0xed
/*
- * Performance monitoring pending work vector:
+ * IRQ work vector:
*/
-#define LOCAL_PENDING_VECTOR 0xec
+#define IRQ_WORK_VECTOR 0xec
#define UV_BAU_MESSAGE 0xea
diff --git a/arch/x86/include/asm/irqflags.h b/arch/x86/include/asm/irqflags.h
index 9e2b952f810a..5745ce8bf108 100644
--- a/arch/x86/include/asm/irqflags.h
+++ b/arch/x86/include/asm/irqflags.h
@@ -61,22 +61,22 @@ static inline void native_halt(void)
#else
#ifndef __ASSEMBLY__
-static inline unsigned long __raw_local_save_flags(void)
+static inline unsigned long arch_local_save_flags(void)
{
return native_save_fl();
}
-static inline void raw_local_irq_restore(unsigned long flags)
+static inline void arch_local_irq_restore(unsigned long flags)
{
native_restore_fl(flags);
}
-static inline void raw_local_irq_disable(void)
+static inline void arch_local_irq_disable(void)
{
native_irq_disable();
}
-static inline void raw_local_irq_enable(void)
+static inline void arch_local_irq_enable(void)
{
native_irq_enable();
}
@@ -85,7 +85,7 @@ static inline void raw_local_irq_enable(void)
* Used in the idle loop; sti takes one instruction cycle
* to complete:
*/
-static inline void raw_safe_halt(void)
+static inline void arch_safe_halt(void)
{
native_safe_halt();
}
@@ -102,12 +102,10 @@ static inline void halt(void)
/*
* For spinlocks, etc:
*/
-static inline unsigned long __raw_local_irq_save(void)
+static inline unsigned long arch_local_irq_save(void)
{
- unsigned long flags = __raw_local_save_flags();
-
- raw_local_irq_disable();
-
+ unsigned long flags = arch_local_save_flags();
+ arch_local_irq_disable();
return flags;
}
#else
@@ -153,22 +151,16 @@ static inline unsigned long __raw_local_irq_save(void)
#endif /* CONFIG_PARAVIRT */
#ifndef __ASSEMBLY__
-#define raw_local_save_flags(flags) \
- do { (flags) = __raw_local_save_flags(); } while (0)
-
-#define raw_local_irq_save(flags) \
- do { (flags) = __raw_local_irq_save(); } while (0)
-
-static inline int raw_irqs_disabled_flags(unsigned long flags)
+static inline int arch_irqs_disabled_flags(unsigned long flags)
{
return !(flags & X86_EFLAGS_IF);
}
-static inline int raw_irqs_disabled(void)
+static inline int arch_irqs_disabled(void)
{
- unsigned long flags = __raw_local_save_flags();
+ unsigned long flags = arch_local_save_flags();
- return raw_irqs_disabled_flags(flags);
+ return arch_irqs_disabled_flags(flags);
}
#else
diff --git a/arch/x86/include/asm/jump_label.h b/arch/x86/include/asm/jump_label.h
new file mode 100644
index 000000000000..f52d42e80585
--- /dev/null
+++ b/arch/x86/include/asm/jump_label.h
@@ -0,0 +1,37 @@
+#ifndef _ASM_X86_JUMP_LABEL_H
+#define _ASM_X86_JUMP_LABEL_H
+
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <asm/nops.h>
+
+#define JUMP_LABEL_NOP_SIZE 5
+
+# define JUMP_LABEL_INITIAL_NOP ".byte 0xe9 \n\t .long 0\n\t"
+
+# define JUMP_LABEL(key, label) \
+ do { \
+ asm goto("1:" \
+ JUMP_LABEL_INITIAL_NOP \
+ ".pushsection __jump_table, \"a\" \n\t"\
+ _ASM_PTR "1b, %l[" #label "], %c0 \n\t" \
+ ".popsection \n\t" \
+ : : "i" (key) : : label); \
+ } while (0)
+
+#endif /* __KERNEL__ */
+
+#ifdef CONFIG_X86_64
+typedef u64 jump_label_t;
+#else
+typedef u32 jump_label_t;
+#endif
+
+struct jump_entry {
+ jump_label_t code;
+ jump_label_t target;
+ jump_label_t key;
+};
+
+#endif
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index 1f99ecfc48e1..b36c6b3fe144 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -139,6 +139,7 @@ struct x86_emulate_ops {
void (*set_segment_selector)(u16 sel, int seg, struct kvm_vcpu *vcpu);
unsigned long (*get_cached_segment_base)(int seg, struct kvm_vcpu *vcpu);
void (*get_gdt)(struct desc_ptr *dt, struct kvm_vcpu *vcpu);
+ void (*get_idt)(struct desc_ptr *dt, struct kvm_vcpu *vcpu);
ulong (*get_cr)(int cr, struct kvm_vcpu *vcpu);
int (*set_cr)(int cr, ulong val, struct kvm_vcpu *vcpu);
int (*cpl)(struct kvm_vcpu *vcpu);
@@ -156,7 +157,10 @@ struct operand {
unsigned long orig_val;
u64 orig_val64;
};
- unsigned long *ptr;
+ union {
+ unsigned long *reg;
+ unsigned long mem;
+ } addr;
union {
unsigned long val;
u64 val64;
@@ -190,6 +194,7 @@ struct decode_cache {
bool has_seg_override;
u8 seg_override;
unsigned int d;
+ int (*execute)(struct x86_emulate_ctxt *ctxt);
unsigned long regs[NR_VCPU_REGS];
unsigned long eip;
/* modrm */
@@ -197,17 +202,16 @@ struct decode_cache {
u8 modrm_mod;
u8 modrm_reg;
u8 modrm_rm;
- u8 use_modrm_ea;
+ u8 modrm_seg;
bool rip_relative;
- unsigned long modrm_ea;
- void *modrm_ptr;
- unsigned long modrm_val;
struct fetch_cache fetch;
struct read_cache io_read;
struct read_cache mem_read;
};
struct x86_emulate_ctxt {
+ struct x86_emulate_ops *ops;
+
/* Register state before/after emulation. */
struct kvm_vcpu *vcpu;
@@ -220,12 +224,11 @@ struct x86_emulate_ctxt {
/* interruptibility state, as a result of execution of STI or MOV SS */
int interruptibility;
- bool restart; /* restart string instruction after writeback */
+ bool perm_ok; /* do not check permissions if true */
int exception; /* exception that happens during emulation or -1 */
u32 error_code; /* error code for exception */
bool error_code_valid;
- unsigned long cr2; /* faulted address in case of #PF */
/* decode cache */
struct decode_cache decode;
@@ -249,13 +252,14 @@ struct x86_emulate_ctxt {
#define X86EMUL_MODE_HOST X86EMUL_MODE_PROT64
#endif
-int x86_decode_insn(struct x86_emulate_ctxt *ctxt,
- struct x86_emulate_ops *ops);
-int x86_emulate_insn(struct x86_emulate_ctxt *ctxt,
- struct x86_emulate_ops *ops);
+int x86_decode_insn(struct x86_emulate_ctxt *ctxt);
+#define EMULATION_FAILED -1
+#define EMULATION_OK 0
+#define EMULATION_RESTART 1
+int x86_emulate_insn(struct x86_emulate_ctxt *ctxt);
int emulator_task_switch(struct x86_emulate_ctxt *ctxt,
- struct x86_emulate_ops *ops,
u16 tss_selector, int reason,
bool has_error_code, u32 error_code);
-
+int emulate_int_real(struct x86_emulate_ctxt *ctxt,
+ struct x86_emulate_ops *ops, int irq);
#endif /* _ASM_X86_KVM_X86_EMULATE_H */
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 502e53f999cf..9e6fe391094e 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -236,10 +236,14 @@ struct kvm_pio_request {
*/
struct kvm_mmu {
void (*new_cr3)(struct kvm_vcpu *vcpu);
+ void (*set_cr3)(struct kvm_vcpu *vcpu, unsigned long root);
+ unsigned long (*get_cr3)(struct kvm_vcpu *vcpu);
int (*page_fault)(struct kvm_vcpu *vcpu, gva_t gva, u32 err);
+ void (*inject_page_fault)(struct kvm_vcpu *vcpu);
void (*free)(struct kvm_vcpu *vcpu);
gpa_t (*gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t gva, u32 access,
u32 *error);
+ gpa_t (*translate_gpa)(struct kvm_vcpu *vcpu, gpa_t gpa, u32 access);
void (*prefetch_page)(struct kvm_vcpu *vcpu,
struct kvm_mmu_page *page);
int (*sync_page)(struct kvm_vcpu *vcpu,
@@ -249,13 +253,18 @@ struct kvm_mmu {
int root_level;
int shadow_root_level;
union kvm_mmu_page_role base_role;
+ bool direct_map;
u64 *pae_root;
+ u64 *lm_root;
u64 rsvd_bits_mask[2][4];
+
+ bool nx;
+
+ u64 pdptrs[4]; /* pae */
};
struct kvm_vcpu_arch {
- u64 host_tsc;
/*
* rip and regs accesses must go through
* kvm_{register,rip}_{read,write} functions.
@@ -272,7 +281,6 @@ struct kvm_vcpu_arch {
unsigned long cr4_guest_owned_bits;
unsigned long cr8;
u32 hflags;
- u64 pdptrs[4]; /* pae */
u64 efer;
u64 apic_base;
struct kvm_lapic *apic; /* kernel irqchip context */
@@ -282,7 +290,41 @@ struct kvm_vcpu_arch {
u64 ia32_misc_enable_msr;
bool tpr_access_reporting;
+ /*
+ * Paging state of the vcpu
+ *
+ * If the vcpu runs in guest mode with two level paging this still saves
+ * the paging mode of the l1 guest. This context is always used to
+ * handle faults.
+ */
struct kvm_mmu mmu;
+
+ /*
+ * Paging state of an L2 guest (used for nested npt)
+ *
+ * This context will save all necessary information to walk page tables
+ * of the an L2 guest. This context is only initialized for page table
+ * walking and not for faulting since we never handle l2 page faults on
+ * the host.
+ */
+ struct kvm_mmu nested_mmu;
+
+ /*
+ * Pointer to the mmu context currently used for
+ * gva_to_gpa translations.
+ */
+ struct kvm_mmu *walk_mmu;
+
+ /*
+ * This struct is filled with the necessary information to propagate a
+ * page fault into the guest
+ */
+ struct {
+ u64 address;
+ unsigned error_code;
+ bool nested;
+ } fault;
+
/* only needed in kvm_pv_mmu_op() path, but it's hot so
* put it here to avoid allocation */
struct kvm_pv_mmu_op_buffer mmu_op_buffer;
@@ -336,9 +378,15 @@ struct kvm_vcpu_arch {
gpa_t time;
struct pvclock_vcpu_time_info hv_clock;
- unsigned int hv_clock_tsc_khz;
+ unsigned int hw_tsc_khz;
unsigned int time_offset;
struct page *time_page;
+ u64 last_host_tsc;
+ u64 last_guest_tsc;
+ u64 last_kernel_ns;
+ u64 last_tsc_nsec;
+ u64 last_tsc_write;
+ bool tsc_catchup;
bool nmi_pending;
bool nmi_injected;
@@ -367,9 +415,9 @@ struct kvm_vcpu_arch {
};
struct kvm_arch {
- unsigned int n_free_mmu_pages;
+ unsigned int n_used_mmu_pages;
unsigned int n_requested_mmu_pages;
- unsigned int n_alloc_mmu_pages;
+ unsigned int n_max_mmu_pages;
atomic_t invlpg_counter;
struct hlist_head mmu_page_hash[KVM_NUM_MMU_PAGES];
/*
@@ -394,8 +442,14 @@ struct kvm_arch {
gpa_t ept_identity_map_addr;
unsigned long irq_sources_bitmap;
- u64 vm_init_tsc;
s64 kvmclock_offset;
+ spinlock_t tsc_write_lock;
+ u64 last_tsc_nsec;
+ u64 last_tsc_offset;
+ u64 last_tsc_write;
+ u32 virtual_tsc_khz;
+ u32 virtual_tsc_mult;
+ s8 virtual_tsc_shift;
struct kvm_xen_hvm_config xen_hvm_config;
@@ -505,6 +559,7 @@ struct kvm_x86_ops {
void (*queue_exception)(struct kvm_vcpu *vcpu, unsigned nr,
bool has_error_code, u32 error_code,
bool reinject);
+ void (*cancel_injection)(struct kvm_vcpu *vcpu);
int (*interrupt_allowed)(struct kvm_vcpu *vcpu);
int (*nmi_allowed)(struct kvm_vcpu *vcpu);
bool (*get_nmi_mask)(struct kvm_vcpu *vcpu);
@@ -517,11 +572,16 @@ struct kvm_x86_ops {
u64 (*get_mt_mask)(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio);
int (*get_lpage_level)(void);
bool (*rdtscp_supported)(void);
+ void (*adjust_tsc_offset)(struct kvm_vcpu *vcpu, s64 adjustment);
+
+ void (*set_tdp_cr3)(struct kvm_vcpu *vcpu, unsigned long cr3);
void (*set_supported_cpuid)(u32 func, struct kvm_cpuid_entry2 *entry);
bool (*has_wbinvd_exit)(void);
+ void (*write_tsc_offset)(struct kvm_vcpu *vcpu, u64 offset);
+
const struct trace_print_flags *exit_reasons_str;
};
@@ -544,7 +604,7 @@ void kvm_mmu_zap_all(struct kvm *kvm);
unsigned int kvm_mmu_calculate_mmu_pages(struct kvm *kvm);
void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int kvm_nr_mmu_pages);
-int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3);
+int load_pdptrs(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, unsigned long cr3);
int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
const void *val, int bytes);
@@ -608,8 +668,11 @@ void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr);
void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code);
void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned nr);
void kvm_requeue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code);
-void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long cr2,
- u32 error_code);
+void kvm_inject_page_fault(struct kvm_vcpu *vcpu);
+int kvm_read_guest_page_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
+ gfn_t gfn, void *data, int offset, int len,
+ u32 access);
+void kvm_propagate_fault(struct kvm_vcpu *vcpu);
bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl);
int kvm_pic_set_irq(void *opaque, int irq, int level);
@@ -652,20 +715,6 @@ static inline struct kvm_mmu_page *page_header(hpa_t shadow_page)
return (struct kvm_mmu_page *)page_private(page);
}
-static inline u16 kvm_read_fs(void)
-{
- u16 seg;
- asm("mov %%fs, %0" : "=g"(seg));
- return seg;
-}
-
-static inline u16 kvm_read_gs(void)
-{
- u16 seg;
- asm("mov %%gs, %0" : "=g"(seg));
- return seg;
-}
-
static inline u16 kvm_read_ldt(void)
{
u16 ldt;
@@ -673,16 +722,6 @@ static inline u16 kvm_read_ldt(void)
return ldt;
}
-static inline void kvm_load_fs(u16 sel)
-{
- asm("mov %0, %%fs" : : "rm"(sel));
-}
-
-static inline void kvm_load_gs(u16 sel)
-{
- asm("mov %0, %%gs" : : "rm"(sel));
-}
-
static inline void kvm_load_ldt(u16 sel)
{
asm("lldt %0" : : "rm"(sel));
diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h
index 05eba5e9a8e8..7b562b6184bc 100644
--- a/arch/x86/include/asm/kvm_para.h
+++ b/arch/x86/include/asm/kvm_para.h
@@ -158,6 +158,12 @@ static inline unsigned int kvm_arch_para_features(void)
return cpuid_eax(KVM_CPUID_FEATURES);
}
+#ifdef CONFIG_KVM_GUEST
+void __init kvm_guest_init(void);
+#else
+#define kvm_guest_init() do { } while (0)
#endif
+#endif /* __KERNEL__ */
+
#endif /* _ASM_X86_KVM_PARA_H */
diff --git a/arch/x86/include/asm/memblock.h b/arch/x86/include/asm/memblock.h
new file mode 100644
index 000000000000..19ae14ba6978
--- /dev/null
+++ b/arch/x86/include/asm/memblock.h
@@ -0,0 +1,23 @@
+#ifndef _X86_MEMBLOCK_H
+#define _X86_MEMBLOCK_H
+
+#define ARCH_DISCARD_MEMBLOCK
+
+u64 memblock_x86_find_in_range_size(u64 start, u64 *sizep, u64 align);
+void memblock_x86_to_bootmem(u64 start, u64 end);
+
+void memblock_x86_reserve_range(u64 start, u64 end, char *name);
+void memblock_x86_free_range(u64 start, u64 end);
+struct range;
+int __get_free_all_memory_range(struct range **range, int nodeid,
+ unsigned long start_pfn, unsigned long end_pfn);
+int get_free_all_memory_range(struct range **rangep, int nodeid);
+
+void memblock_x86_register_active_regions(int nid, unsigned long start_pfn,
+ unsigned long last_pfn);
+u64 memblock_x86_hole_size(u64 start, u64 end);
+u64 memblock_x86_find_in_range_node(int nid, u64 start, u64 end, u64 size, u64 align);
+u64 memblock_x86_free_memory_in_range(u64 addr, u64 limit);
+u64 memblock_x86_memory_in_range(u64 addr, u64 limit);
+
+#endif
diff --git a/arch/x86/include/asm/module.h b/arch/x86/include/asm/module.h
index 3e2ce58a31a3..67763c5d8b4e 100644
--- a/arch/x86/include/asm/module.h
+++ b/arch/x86/include/asm/module.h
@@ -60,12 +60,7 @@
#endif
#ifdef CONFIG_X86_32
-# ifdef CONFIG_4KSTACKS
-# define MODULE_STACKSIZE "4KSTACKS "
-# else
-# define MODULE_STACKSIZE ""
-# endif
-# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE
+# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY
#endif
#endif /* _ASM_X86_MODULE_H */
diff --git a/arch/x86/include/asm/mrst.h b/arch/x86/include/asm/mrst.h
index 16350740edf6..4a711a684b17 100644
--- a/arch/x86/include/asm/mrst.h
+++ b/arch/x86/include/asm/mrst.h
@@ -10,6 +10,9 @@
*/
#ifndef _ASM_X86_MRST_H
#define _ASM_X86_MRST_H
+
+#include <linux/sfi.h>
+
extern int pci_mrst_init(void);
int __init sfi_parse_mrtc(struct sfi_table_header *table);
@@ -26,7 +29,7 @@ enum mrst_cpu_type {
};
extern enum mrst_cpu_type __mrst_cpu_chip;
-static enum mrst_cpu_type mrst_identify_cpu(void)
+static inline enum mrst_cpu_type mrst_identify_cpu(void)
{
return __mrst_cpu_chip;
}
@@ -42,4 +45,9 @@ extern enum mrst_timer_options mrst_timer_options;
#define SFI_MTMR_MAX_NUM 8
#define SFI_MRTC_MAX 8
+extern struct console early_mrst_console;
+extern void mrst_early_console_init(void);
+
+extern struct console early_hsu_console;
+extern void hsu_early_console_init(void);
#endif /* _ASM_X86_MRST_H */
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 986f7790fdb2..83c4bb1d917d 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -198,6 +198,7 @@
#define MSR_IA32_TSC 0x00000010
#define MSR_IA32_PLATFORM_ID 0x00000017
#define MSR_IA32_EBL_CR_POWERON 0x0000002a
+#define MSR_EBC_FREQUENCY_ID 0x0000002c
#define MSR_IA32_FEATURE_CONTROL 0x0000003a
#define FEATURE_CONTROL_LOCKED (1<<0)
diff --git a/arch/x86/include/asm/mwait.h b/arch/x86/include/asm/mwait.h
new file mode 100644
index 000000000000..bcdff997668c
--- /dev/null
+++ b/arch/x86/include/asm/mwait.h
@@ -0,0 +1,15 @@
+#ifndef _ASM_X86_MWAIT_H
+#define _ASM_X86_MWAIT_H
+
+#define MWAIT_SUBSTATE_MASK 0xf
+#define MWAIT_CSTATE_MASK 0xf
+#define MWAIT_SUBSTATE_SIZE 4
+#define MWAIT_MAX_NUM_CSTATES 8
+
+#define CPUID_MWAIT_LEAF 5
+#define CPUID5_ECX_EXTENSIONS_SUPPORTED 0x1
+#define CPUID5_ECX_INTERRUPT_BREAK 0x2
+
+#define MWAIT_ECX_INTERRUPT_BREAK 0x1
+
+#endif /* _ASM_X86_MWAIT_H */
diff --git a/arch/x86/include/asm/olpc_ofw.h b/arch/x86/include/asm/olpc_ofw.h
index 08fde475cb3b..2a8478140bb3 100644
--- a/arch/x86/include/asm/olpc_ofw.h
+++ b/arch/x86/include/asm/olpc_ofw.h
@@ -21,10 +21,14 @@ extern void olpc_ofw_detect(void);
/* install OFW's pde permanently into the kernel's pgtable */
extern void setup_olpc_ofw_pgd(void);
+/* check if OFW was detected during boot */
+extern bool olpc_ofw_present(void);
+
#else /* !CONFIG_OLPC_OPENFIRMWARE */
static inline void olpc_ofw_detect(void) { }
static inline void setup_olpc_ofw_pgd(void) { }
+static inline bool olpc_ofw_present(void) { return false; }
#endif /* !CONFIG_OLPC_OPENFIRMWARE */
diff --git a/arch/x86/include/asm/page_32_types.h b/arch/x86/include/asm/page_32_types.h
index 6f1b7331313f..ade619ff9e2a 100644
--- a/arch/x86/include/asm/page_32_types.h
+++ b/arch/x86/include/asm/page_32_types.h
@@ -15,11 +15,7 @@
*/
#define __PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL)
-#ifdef CONFIG_4KSTACKS
-#define THREAD_ORDER 0
-#else
#define THREAD_ORDER 1
-#endif
#define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER)
#define STACKFAULT_STACK 0
diff --git a/arch/x86/include/asm/page_types.h b/arch/x86/include/asm/page_types.h
index a667f24c7254..1df66211fd1b 100644
--- a/arch/x86/include/asm/page_types.h
+++ b/arch/x86/include/asm/page_types.h
@@ -8,7 +8,7 @@
#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
-#define __PHYSICAL_MASK ((phys_addr_t)(1ULL << __PHYSICAL_MASK_SHIFT) - 1)
+#define __PHYSICAL_MASK ((phys_addr_t)((1ULL << __PHYSICAL_MASK_SHIFT) - 1))
#define __VIRTUAL_MASK ((1UL << __VIRTUAL_MASK_SHIFT) - 1)
/* Cast PAGE_MASK to a signed type so that it is sign-extended if
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index 5653f43d90e5..18e3b8a8709f 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -105,7 +105,7 @@ static inline void write_cr8(unsigned long x)
}
#endif
-static inline void raw_safe_halt(void)
+static inline void arch_safe_halt(void)
{
PVOP_VCALL0(pv_irq_ops.safe_halt);
}
@@ -416,11 +416,6 @@ static inline void paravirt_alloc_pmd(struct mm_struct *mm, unsigned long pfn)
PVOP_VCALL2(pv_mmu_ops.alloc_pmd, mm, pfn);
}
-static inline void paravirt_alloc_pmd_clone(unsigned long pfn, unsigned long clonepfn,
- unsigned long start, unsigned long count)
-{
- PVOP_VCALL4(pv_mmu_ops.alloc_pmd_clone, pfn, clonepfn, start, count);
-}
static inline void paravirt_release_pmd(unsigned long pfn)
{
PVOP_VCALL1(pv_mmu_ops.release_pmd, pfn);
@@ -829,32 +824,32 @@ static __always_inline void arch_spin_unlock(struct arch_spinlock *lock)
#define __PV_IS_CALLEE_SAVE(func) \
((struct paravirt_callee_save) { func })
-static inline unsigned long __raw_local_save_flags(void)
+static inline unsigned long arch_local_save_flags(void)
{
return PVOP_CALLEE0(unsigned long, pv_irq_ops.save_fl);
}
-static inline void raw_local_irq_restore(unsigned long f)
+static inline void arch_local_irq_restore(unsigned long f)
{
PVOP_VCALLEE1(pv_irq_ops.restore_fl, f);
}
-static inline void raw_local_irq_disable(void)
+static inline void arch_local_irq_disable(void)
{
PVOP_VCALLEE0(pv_irq_ops.irq_disable);
}
-static inline void raw_local_irq_enable(void)
+static inline void arch_local_irq_enable(void)
{
PVOP_VCALLEE0(pv_irq_ops.irq_enable);
}
-static inline unsigned long __raw_local_irq_save(void)
+static inline unsigned long arch_local_irq_save(void)
{
unsigned long f;
- f = __raw_local_save_flags();
- raw_local_irq_disable();
+ f = arch_local_save_flags();
+ arch_local_irq_disable();
return f;
}
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h
index db9ef5532341..b82bac975250 100644
--- a/arch/x86/include/asm/paravirt_types.h
+++ b/arch/x86/include/asm/paravirt_types.h
@@ -255,7 +255,6 @@ struct pv_mmu_ops {
*/
void (*alloc_pte)(struct mm_struct *mm, unsigned long pfn);
void (*alloc_pmd)(struct mm_struct *mm, unsigned long pfn);
- void (*alloc_pmd_clone)(unsigned long pfn, unsigned long clonepfn, unsigned long start, unsigned long count);
void (*alloc_pud)(struct mm_struct *mm, unsigned long pfn);
void (*release_pte)(unsigned long pfn);
void (*release_pmd)(unsigned long pfn);
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h
index cd28f9ad910d..f899e01a8ac9 100644
--- a/arch/x86/include/asm/percpu.h
+++ b/arch/x86/include/asm/percpu.h
@@ -47,6 +47,20 @@
#ifdef CONFIG_SMP
#define __percpu_arg(x) "%%"__stringify(__percpu_seg)":%P" #x
#define __my_cpu_offset percpu_read(this_cpu_off)
+
+/*
+ * Compared to the generic __my_cpu_offset version, the following
+ * saves one instruction and avoids clobbering a temp register.
+ */
+#define __this_cpu_ptr(ptr) \
+({ \
+ unsigned long tcp_ptr__; \
+ __verify_pcpu_ptr(ptr); \
+ asm volatile("add " __percpu_arg(1) ", %0" \
+ : "=r" (tcp_ptr__) \
+ : "m" (this_cpu_off), "0" (ptr)); \
+ (typeof(*(ptr)) __kernel __force *)tcp_ptr__; \
+})
#else
#define __percpu_arg(x) "%P" #x
#endif
diff --git a/arch/x86/include/asm/perf_event_p4.h b/arch/x86/include/asm/perf_event_p4.h
index def500776b16..a70cd216be5d 100644
--- a/arch/x86/include/asm/perf_event_p4.h
+++ b/arch/x86/include/asm/perf_event_p4.h
@@ -36,19 +36,6 @@
#define P4_ESCR_EMASK(v) ((v) << P4_ESCR_EVENTMASK_SHIFT)
#define P4_ESCR_TAG(v) ((v) << P4_ESCR_TAG_SHIFT)
-/* Non HT mask */
-#define P4_ESCR_MASK \
- (P4_ESCR_EVENT_MASK | \
- P4_ESCR_EVENTMASK_MASK | \
- P4_ESCR_TAG_MASK | \
- P4_ESCR_TAG_ENABLE | \
- P4_ESCR_T0_OS | \
- P4_ESCR_T0_USR)
-
-/* HT mask */
-#define P4_ESCR_MASK_HT \
- (P4_ESCR_MASK | P4_ESCR_T1_OS | P4_ESCR_T1_USR)
-
#define P4_CCCR_OVF 0x80000000U
#define P4_CCCR_CASCADE 0x40000000U
#define P4_CCCR_OVF_PMI_T0 0x04000000U
@@ -70,23 +57,6 @@
#define P4_CCCR_THRESHOLD(v) ((v) << P4_CCCR_THRESHOLD_SHIFT)
#define P4_CCCR_ESEL(v) ((v) << P4_CCCR_ESCR_SELECT_SHIFT)
-/* Non HT mask */
-#define P4_CCCR_MASK \
- (P4_CCCR_OVF | \
- P4_CCCR_CASCADE | \
- P4_CCCR_OVF_PMI_T0 | \
- P4_CCCR_FORCE_OVF | \
- P4_CCCR_EDGE | \
- P4_CCCR_THRESHOLD_MASK | \
- P4_CCCR_COMPLEMENT | \
- P4_CCCR_COMPARE | \
- P4_CCCR_ESCR_SELECT_MASK | \
- P4_CCCR_ENABLE)
-
-/* HT mask */
-#define P4_CCCR_MASK_HT \
- (P4_CCCR_MASK | P4_CCCR_OVF_PMI_T1 | P4_CCCR_THREAD_ANY)
-
#define P4_GEN_ESCR_EMASK(class, name, bit) \
class##__##name = ((1 << bit) << P4_ESCR_EVENTMASK_SHIFT)
#define P4_ESCR_EMASK_BIT(class, name) class##__##name
@@ -127,6 +97,28 @@
#define P4_CONFIG_HT_SHIFT 63
#define P4_CONFIG_HT (1ULL << P4_CONFIG_HT_SHIFT)
+/*
+ * The bits we allow to pass for RAW events
+ */
+#define P4_CONFIG_MASK_ESCR \
+ P4_ESCR_EVENT_MASK | \
+ P4_ESCR_EVENTMASK_MASK | \
+ P4_ESCR_TAG_MASK | \
+ P4_ESCR_TAG_ENABLE
+
+#define P4_CONFIG_MASK_CCCR \
+ P4_CCCR_EDGE | \
+ P4_CCCR_THRESHOLD_MASK | \
+ P4_CCCR_COMPLEMENT | \
+ P4_CCCR_COMPARE | \
+ P4_CCCR_THREAD_ANY | \
+ P4_CCCR_RESERVED
+
+/* some dangerous bits are reserved for kernel internals */
+#define P4_CONFIG_MASK \
+ (p4_config_pack_escr(P4_CONFIG_MASK_ESCR)) | \
+ (p4_config_pack_cccr(P4_CONFIG_MASK_CCCR))
+
static inline bool p4_is_event_cascaded(u64 config)
{
u32 cccr = p4_config_unpack_cccr(config);
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index a34c785c5a63..ada823a13c7c 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -28,6 +28,8 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
extern spinlock_t pgd_lock;
extern struct list_head pgd_list;
+extern struct mm_struct *pgd_page_get_mm(struct page *page);
+
#ifdef CONFIG_PARAVIRT
#include <asm/paravirt.h>
#else /* !CONFIG_PARAVIRT */
@@ -603,6 +605,8 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm,
pte_update(mm, addr, ptep);
}
+#define flush_tlb_fix_spurious_fault(vma, address)
+
/*
* clone_pgd_range(pgd_t *dst, pgd_t *src, int count);
*
diff --git a/arch/x86/include/asm/pgtable_32.h b/arch/x86/include/asm/pgtable_32.h
index f686f49e8b7b..8abde9ec90bf 100644
--- a/arch/x86/include/asm/pgtable_32.h
+++ b/arch/x86/include/asm/pgtable_32.h
@@ -26,7 +26,7 @@ struct mm_struct;
struct vm_area_struct;
extern pgd_t swapper_pg_dir[1024];
-extern pgd_t trampoline_pg_dir[1024];
+extern pgd_t initial_page_table[1024];
static inline void pgtable_cache_init(void) { }
static inline void check_pgt_cache(void) { }
diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h
index 076052cd62be..f96ac9bedf75 100644
--- a/arch/x86/include/asm/pgtable_64.h
+++ b/arch/x86/include/asm/pgtable_64.h
@@ -102,6 +102,8 @@ static inline void native_pgd_clear(pgd_t *pgd)
native_set_pgd(pgd, native_make_pgd(0));
}
+extern void sync_global_pgds(unsigned long start, unsigned long end);
+
/*
* Conversion functions: convert a page and protection to a page entry,
* and a page entry and page directory to the page they refer to.
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 325b7bdbebaa..cae9c3cb95cf 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -110,6 +110,8 @@ struct cpuinfo_x86 {
u16 phys_proc_id;
/* Core id: */
u16 cpu_core_id;
+ /* Compute unit id */
+ u8 compute_unit_id;
/* Index into per_cpu list: */
u16 cpu_index;
#endif
@@ -602,7 +604,7 @@ extern unsigned long mmu_cr4_features;
static inline void set_in_cr4(unsigned long mask)
{
- unsigned cr4;
+ unsigned long cr4;
mmu_cr4_features |= mask;
cr4 = read_cr4();
@@ -612,7 +614,7 @@ static inline void set_in_cr4(unsigned long mask)
static inline void clear_in_cr4(unsigned long mask)
{
- unsigned cr4;
+ unsigned long cr4;
mmu_cr4_features &= ~mask;
cr4 = read_cr4();
@@ -764,29 +766,6 @@ extern unsigned long idle_halt;
extern unsigned long idle_nomwait;
extern bool c1e_detected;
-/*
- * on systems with caches, caches must be flashed as the absolute
- * last instruction before going into a suspended halt. Otherwise,
- * dirty data can linger in the cache and become stale on resume,
- * leading to strange errors.
- *
- * perform a variety of operations to guarantee that the compiler
- * will not reorder instructions. wbinvd itself is serializing
- * so the processor will not reorder.
- *
- * Systems without cache can just go into halt.
- */
-static inline void wbinvd_halt(void)
-{
- mb();
- /* check for clflush to determine if wbinvd is legal */
- if (cpu_has_clflush)
- asm volatile("cli; wbinvd; 1: hlt; jmp 1b" : : : "memory");
- else
- while (1)
- halt();
-}
-
extern void enable_sep_cpu(void);
extern int sysenter_setup(void);
diff --git a/arch/x86/include/asm/pvclock.h b/arch/x86/include/asm/pvclock.h
index cd02f324aa6b..7f7e577a0e39 100644
--- a/arch/x86/include/asm/pvclock.h
+++ b/arch/x86/include/asm/pvclock.h
@@ -12,4 +12,42 @@ void pvclock_read_wallclock(struct pvclock_wall_clock *wall,
struct pvclock_vcpu_time_info *vcpu,
struct timespec *ts);
+/*
+ * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction,
+ * yielding a 64-bit result.
+ */
+static inline u64 pvclock_scale_delta(u64 delta, u32 mul_frac, int shift)
+{
+ u64 product;
+#ifdef __i386__
+ u32 tmp1, tmp2;
+#endif
+
+ if (shift < 0)
+ delta >>= -shift;
+ else
+ delta <<= shift;
+
+#ifdef __i386__
+ __asm__ (
+ "mul %5 ; "
+ "mov %4,%%eax ; "
+ "mov %%edx,%4 ; "
+ "mul %5 ; "
+ "xor %5,%5 ; "
+ "add %4,%%eax ; "
+ "adc %5,%%edx ; "
+ : "=A" (product), "=r" (tmp1), "=r" (tmp2)
+ : "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) );
+#elif defined(__x86_64__)
+ __asm__ (
+ "mul %%rdx ; shrd $32,%%rdx,%%rax"
+ : "=a" (product) : "0" (delta), "d" ((u64)mul_frac) );
+#else
+#error implement me!
+#endif
+
+ return product;
+}
+
#endif /* _ASM_X86_PVCLOCK_H */
diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h
index 14e0ed86a6f9..231f1c1d6607 100644
--- a/arch/x86/include/asm/segment.h
+++ b/arch/x86/include/asm/segment.h
@@ -73,31 +73,31 @@
#define GDT_ENTRY_DEFAULT_USER_DS 15
-#define GDT_ENTRY_KERNEL_BASE 12
+#define GDT_ENTRY_KERNEL_BASE (12)
-#define GDT_ENTRY_KERNEL_CS (GDT_ENTRY_KERNEL_BASE + 0)
+#define GDT_ENTRY_KERNEL_CS (GDT_ENTRY_KERNEL_BASE+0)
-#define GDT_ENTRY_KERNEL_DS (GDT_ENTRY_KERNEL_BASE + 1)
+#define GDT_ENTRY_KERNEL_DS (GDT_ENTRY_KERNEL_BASE+1)
-#define GDT_ENTRY_TSS (GDT_ENTRY_KERNEL_BASE + 4)
-#define GDT_ENTRY_LDT (GDT_ENTRY_KERNEL_BASE + 5)
+#define GDT_ENTRY_TSS (GDT_ENTRY_KERNEL_BASE+4)
+#define GDT_ENTRY_LDT (GDT_ENTRY_KERNEL_BASE+5)
-#define GDT_ENTRY_PNPBIOS_BASE (GDT_ENTRY_KERNEL_BASE + 6)
-#define GDT_ENTRY_APMBIOS_BASE (GDT_ENTRY_KERNEL_BASE + 11)
+#define GDT_ENTRY_PNPBIOS_BASE (GDT_ENTRY_KERNEL_BASE+6)
+#define GDT_ENTRY_APMBIOS_BASE (GDT_ENTRY_KERNEL_BASE+11)
-#define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE + 14)
-#define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)
+#define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE+14)
+#define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS*8)
-#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
+#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE+15)
#ifdef CONFIG_SMP
#define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8)
#else
#define __KERNEL_PERCPU 0
#endif
-#define GDT_ENTRY_STACK_CANARY (GDT_ENTRY_KERNEL_BASE + 16)
+#define GDT_ENTRY_STACK_CANARY (GDT_ENTRY_KERNEL_BASE+16)
#ifdef CONFIG_CC_STACKPROTECTOR
-#define __KERNEL_STACK_CANARY (GDT_ENTRY_STACK_CANARY * 8)
+#define __KERNEL_STACK_CANARY (GDT_ENTRY_STACK_CANARY*8)
#else
#define __KERNEL_STACK_CANARY 0
#endif
@@ -182,10 +182,10 @@
#endif
-#define __KERNEL_CS (GDT_ENTRY_KERNEL_CS * 8)
-#define __KERNEL_DS (GDT_ENTRY_KERNEL_DS * 8)
-#define __USER_DS (GDT_ENTRY_DEFAULT_USER_DS* 8 + 3)
-#define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS* 8 + 3)
+#define __KERNEL_CS (GDT_ENTRY_KERNEL_CS*8)
+#define __KERNEL_DS (GDT_ENTRY_KERNEL_DS*8)
+#define __USER_DS (GDT_ENTRY_DEFAULT_USER_DS*8+3)
+#define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS*8+3)
#ifndef CONFIG_PARAVIRT
#define get_kernel_rpl() 0
#endif
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
index ef292c792d74..d6763b139a84 100644
--- a/arch/x86/include/asm/setup.h
+++ b/arch/x86/include/asm/setup.h
@@ -93,6 +93,11 @@ void *extend_brk(size_t size, size_t align);
: : "i" (sz)); \
}
+/* Helper for reserving space for arrays of things */
+#define RESERVE_BRK_ARRAY(type, name, entries) \
+ type *name; \
+ RESERVE_BRK(name, sizeof(type) * entries)
+
#ifdef __i386__
void __init i386_start_kernel(void);
diff --git a/arch/x86/include/asm/swiotlb.h b/arch/x86/include/asm/swiotlb.h
index 8085277e1b8b..977f1761a25d 100644
--- a/arch/x86/include/asm/swiotlb.h
+++ b/arch/x86/include/asm/swiotlb.h
@@ -5,17 +5,26 @@
#ifdef CONFIG_SWIOTLB
extern int swiotlb;
-extern int __init pci_swiotlb_detect(void);
+extern int __init pci_swiotlb_detect_override(void);
+extern int __init pci_swiotlb_detect_4gb(void);
extern void __init pci_swiotlb_init(void);
+extern void __init pci_swiotlb_late_init(void);
#else
#define swiotlb 0
-static inline int pci_swiotlb_detect(void)
+static inline int pci_swiotlb_detect_override(void)
+{
+ return 0;
+}
+static inline int pci_swiotlb_detect_4gb(void)
{
return 0;
}
static inline void pci_swiotlb_init(void)
{
}
+static inline void pci_swiotlb_late_init(void)
+{
+}
#endif
static inline void dma_mark_clean(void *addr, size_t size) {}
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
index 7f3eba08e7de..169be8938b96 100644
--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -172,6 +172,4 @@ static inline void flush_tlb_kernel_range(unsigned long start,
flush_tlb_all();
}
-extern void zap_low_mappings(bool early);
-
#endif /* _ASM_X86_TLBFLUSH_H */
diff --git a/arch/x86/include/asm/trampoline.h b/arch/x86/include/asm/trampoline.h
index 4dde797c0578..f4500fb3b485 100644
--- a/arch/x86/include/asm/trampoline.h
+++ b/arch/x86/include/asm/trampoline.h
@@ -13,16 +13,13 @@ extern unsigned char *trampoline_base;
extern unsigned long init_rsp;
extern unsigned long initial_code;
-extern unsigned long initial_page_table;
extern unsigned long initial_gs;
#define TRAMPOLINE_SIZE roundup(trampoline_end - trampoline_data, PAGE_SIZE)
extern unsigned long setup_trampoline(void);
-extern void __init setup_trampoline_page_table(void);
extern void __init reserve_trampoline_memory(void);
#else
-static inline void setup_trampoline_page_table(void) {}
static inline void reserve_trampoline_memory(void) {}
#endif /* CONFIG_X86_TRAMPOLINE */
diff --git a/arch/x86/include/asm/vmi.h b/arch/x86/include/asm/vmi.h
deleted file mode 100644
index 61e08c0a2907..000000000000
--- a/arch/x86/include/asm/vmi.h
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * VMI interface definition
- *
- * Copyright (C) 2005, VMware, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Maintained by: Zachary Amsden zach@vmware.com
- *
- */
-#include <linux/types.h>
-
-/*
- *---------------------------------------------------------------------
- *
- * VMI Option ROM API
- *
- *---------------------------------------------------------------------
- */
-#define VMI_SIGNATURE 0x696d5663 /* "cVmi" */
-
-#define PCI_VENDOR_ID_VMWARE 0x15AD
-#define PCI_DEVICE_ID_VMWARE_VMI 0x0801
-
-/*
- * We use two version numbers for compatibility, with the major
- * number signifying interface breakages, and the minor number
- * interface extensions.
- */
-#define VMI_API_REV_MAJOR 3
-#define VMI_API_REV_MINOR 0
-
-#define VMI_CALL_CPUID 0
-#define VMI_CALL_WRMSR 1
-#define VMI_CALL_RDMSR 2
-#define VMI_CALL_SetGDT 3
-#define VMI_CALL_SetLDT 4
-#define VMI_CALL_SetIDT 5
-#define VMI_CALL_SetTR 6
-#define VMI_CALL_GetGDT 7
-#define VMI_CALL_GetLDT 8
-#define VMI_CALL_GetIDT 9
-#define VMI_CALL_GetTR 10
-#define VMI_CALL_WriteGDTEntry 11
-#define VMI_CALL_WriteLDTEntry 12
-#define VMI_CALL_WriteIDTEntry 13
-#define VMI_CALL_UpdateKernelStack 14
-#define VMI_CALL_SetCR0 15
-#define VMI_CALL_SetCR2 16
-#define VMI_CALL_SetCR3 17
-#define VMI_CALL_SetCR4 18
-#define VMI_CALL_GetCR0 19
-#define VMI_CALL_GetCR2 20
-#define VMI_CALL_GetCR3 21
-#define VMI_CALL_GetCR4 22
-#define VMI_CALL_WBINVD 23
-#define VMI_CALL_SetDR 24
-#define VMI_CALL_GetDR 25
-#define VMI_CALL_RDPMC 26
-#define VMI_CALL_RDTSC 27
-#define VMI_CALL_CLTS 28
-#define VMI_CALL_EnableInterrupts 29
-#define VMI_CALL_DisableInterrupts 30
-#define VMI_CALL_GetInterruptMask 31
-#define VMI_CALL_SetInterruptMask 32
-#define VMI_CALL_IRET 33
-#define VMI_CALL_SYSEXIT 34
-#define VMI_CALL_Halt 35
-#define VMI_CALL_Reboot 36
-#define VMI_CALL_Shutdown 37
-#define VMI_CALL_SetPxE 38
-#define VMI_CALL_SetPxELong 39
-#define VMI_CALL_UpdatePxE 40
-#define VMI_CALL_UpdatePxELong 41
-#define VMI_CALL_MachineToPhysical 42
-#define VMI_CALL_PhysicalToMachine 43
-#define VMI_CALL_AllocatePage 44
-#define VMI_CALL_ReleasePage 45
-#define VMI_CALL_InvalPage 46
-#define VMI_CALL_FlushTLB 47
-#define VMI_CALL_SetLinearMapping 48
-
-#define VMI_CALL_SetIOPLMask 61
-#define VMI_CALL_SetInitialAPState 62
-#define VMI_CALL_APICWrite 63
-#define VMI_CALL_APICRead 64
-#define VMI_CALL_IODelay 65
-#define VMI_CALL_SetLazyMode 73
-
-/*
- *---------------------------------------------------------------------
- *
- * MMU operation flags
- *
- *---------------------------------------------------------------------
- */
-
-/* Flags used by VMI_{Allocate|Release}Page call */
-#define VMI_PAGE_PAE 0x10 /* Allocate PAE shadow */
-#define VMI_PAGE_CLONE 0x20 /* Clone from another shadow */
-#define VMI_PAGE_ZEROED 0x40 /* Page is pre-zeroed */
-
-
-/* Flags shared by Allocate|Release Page and PTE updates */
-#define VMI_PAGE_PT 0x01
-#define VMI_PAGE_PD 0x02
-#define VMI_PAGE_PDP 0x04
-#define VMI_PAGE_PML4 0x08
-
-#define VMI_PAGE_NORMAL 0x00 /* for debugging */
-
-/* Flags used by PTE updates */
-#define VMI_PAGE_CURRENT_AS 0x10 /* implies VMI_PAGE_VA_MASK is valid */
-#define VMI_PAGE_DEFER 0x20 /* may queue update until TLB inval */
-#define VMI_PAGE_VA_MASK 0xfffff000
-
-#ifdef CONFIG_X86_PAE
-#define VMI_PAGE_L1 (VMI_PAGE_PT | VMI_PAGE_PAE | VMI_PAGE_ZEROED)
-#define VMI_PAGE_L2 (VMI_PAGE_PD | VMI_PAGE_PAE | VMI_PAGE_ZEROED)
-#else
-#define VMI_PAGE_L1 (VMI_PAGE_PT | VMI_PAGE_ZEROED)
-#define VMI_PAGE_L2 (VMI_PAGE_PD | VMI_PAGE_ZEROED)
-#endif
-
-/* Flags used by VMI_FlushTLB call */
-#define VMI_FLUSH_TLB 0x01
-#define VMI_FLUSH_GLOBAL 0x02
-
-/*
- *---------------------------------------------------------------------
- *
- * VMI relocation definitions for ROM call get_reloc
- *
- *---------------------------------------------------------------------
- */
-
-/* VMI Relocation types */
-#define VMI_RELOCATION_NONE 0
-#define VMI_RELOCATION_CALL_REL 1
-#define VMI_RELOCATION_JUMP_REL 2
-#define VMI_RELOCATION_NOP 3
-
-#ifndef __ASSEMBLY__
-struct vmi_relocation_info {
- unsigned char *eip;
- unsigned char type;
- unsigned char reserved[3];
-};
-#endif
-
-
-/*
- *---------------------------------------------------------------------
- *
- * Generic ROM structures and definitions
- *
- *---------------------------------------------------------------------
- */
-
-#ifndef __ASSEMBLY__
-
-struct vrom_header {
- u16 rom_signature; /* option ROM signature */
- u8 rom_length; /* ROM length in 512 byte chunks */
- u8 rom_entry[4]; /* 16-bit code entry point */
- u8 rom_pad0; /* 4-byte align pad */
- u32 vrom_signature; /* VROM identification signature */
- u8 api_version_min;/* Minor version of API */
- u8 api_version_maj;/* Major version of API */
- u8 jump_slots; /* Number of jump slots */
- u8 reserved1; /* Reserved for expansion */
- u32 virtual_top; /* Hypervisor virtual address start */
- u16 reserved2; /* Reserved for expansion */
- u16 license_offs; /* Offset to License string */
- u16 pci_header_offs;/* Offset to PCI OPROM header */
- u16 pnp_header_offs;/* Offset to PnP OPROM header */
- u32 rom_pad3; /* PnP reserverd / VMI reserved */
- u8 reserved[96]; /* Reserved for headers */
- char vmi_init[8]; /* VMI_Init jump point */
- char get_reloc[8]; /* VMI_GetRelocationInfo jump point */
-} __attribute__((packed));
-
-struct pnp_header {
- char sig[4];
- char rev;
- char size;
- short next;
- short res;
- long devID;
- unsigned short manufacturer_offset;
- unsigned short product_offset;
-} __attribute__((packed));
-
-struct pci_header {
- char sig[4];
- short vendorID;
- short deviceID;
- short vpdData;
- short size;
- char rev;
- char class;
- char subclass;
- char interface;
- short chunks;
- char rom_version_min;
- char rom_version_maj;
- char codetype;
- char lastRom;
- short reserved;
-} __attribute__((packed));
-
-/* Function prototypes for bootstrapping */
-#ifdef CONFIG_VMI
-extern void vmi_init(void);
-extern void vmi_activate(void);
-extern void vmi_bringup(void);
-#else
-static inline void vmi_init(void) {}
-static inline void vmi_activate(void) {}
-static inline void vmi_bringup(void) {}
-#endif
-
-/* State needed to start an application processor in an SMP system. */
-struct vmi_ap_state {
- u32 cr0;
- u32 cr2;
- u32 cr3;
- u32 cr4;
-
- u64 efer;
-
- u32 eip;
- u32 eflags;
- u32 eax;
- u32 ebx;
- u32 ecx;
- u32 edx;
- u32 esp;
- u32 ebp;
- u32 esi;
- u32 edi;
- u16 cs;
- u16 ss;
- u16 ds;
- u16 es;
- u16 fs;
- u16 gs;
- u16 ldtr;
-
- u16 gdtr_limit;
- u32 gdtr_base;
- u32 idtr_base;
- u16 idtr_limit;
-};
-
-#endif
diff --git a/arch/x86/include/asm/vmi_time.h b/arch/x86/include/asm/vmi_time.h
deleted file mode 100644
index c6e0bee93e3c..000000000000
--- a/arch/x86/include/asm/vmi_time.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * VMI Time wrappers
- *
- * Copyright (C) 2006, VMware, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to dhecht@vmware.com
- *
- */
-
-#ifndef _ASM_X86_VMI_TIME_H
-#define _ASM_X86_VMI_TIME_H
-
-/*
- * Raw VMI call indices for timer functions
- */
-#define VMI_CALL_GetCycleFrequency 66
-#define VMI_CALL_GetCycleCounter 67
-#define VMI_CALL_SetAlarm 68
-#define VMI_CALL_CancelAlarm 69
-#define VMI_CALL_GetWallclockTime 70
-#define VMI_CALL_WallclockUpdated 71
-
-/* Cached VMI timer operations */
-extern struct vmi_timer_ops {
- u64 (*get_cycle_frequency)(void);
- u64 (*get_cycle_counter)(int);
- u64 (*get_wallclock)(void);
- int (*wallclock_updated)(void);
- void (*set_alarm)(u32 flags, u64 expiry, u64 period);
- void (*cancel_alarm)(u32 flags);
-} vmi_timer_ops;
-
-/* Prototypes */
-extern void __init vmi_time_init(void);
-extern unsigned long vmi_get_wallclock(void);
-extern int vmi_set_wallclock(unsigned long now);
-extern unsigned long long vmi_sched_clock(void);
-extern unsigned long vmi_tsc_khz(void);
-
-#ifdef CONFIG_X86_LOCAL_APIC
-extern void __devinit vmi_time_bsp_init(void);
-extern void __devinit vmi_time_ap_init(void);
-#endif
-
-/*
- * When run under a hypervisor, a vcpu is always in one of three states:
- * running, halted, or ready. The vcpu is in the 'running' state if it
- * is executing. When the vcpu executes the halt interface, the vcpu
- * enters the 'halted' state and remains halted until there is some work
- * pending for the vcpu (e.g. an alarm expires, host I/O completes on
- * behalf of virtual I/O). At this point, the vcpu enters the 'ready'
- * state (waiting for the hypervisor to reschedule it). Finally, at any
- * time when the vcpu is not in the 'running' state nor the 'halted'
- * state, it is in the 'ready' state.
- *
- * Real time is advances while the vcpu is 'running', 'ready', or
- * 'halted'. Stolen time is the time in which the vcpu is in the
- * 'ready' state. Available time is the remaining time -- the vcpu is
- * either 'running' or 'halted'.
- *
- * All three views of time are accessible through the VMI cycle
- * counters.
- */
-
-/* The cycle counters. */
-#define VMI_CYCLES_REAL 0
-#define VMI_CYCLES_AVAILABLE 1
-#define VMI_CYCLES_STOLEN 2
-
-/* The alarm interface 'flags' bits */
-#define VMI_ALARM_COUNTERS 2
-
-#define VMI_ALARM_COUNTER_MASK 0x000000ff
-
-#define VMI_ALARM_WIRED_IRQ0 0x00000000
-#define VMI_ALARM_WIRED_LVTT 0x00010000
-
-#define VMI_ALARM_IS_ONESHOT 0x00000000
-#define VMI_ALARM_IS_PERIODIC 0x00000100
-
-#define CONFIG_VMI_ALARM_HZ 100
-
-#endif /* _ASM_X86_VMI_TIME_H */
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index fedf32a8c3ec..2c833d8c4141 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -34,7 +34,8 @@ GCOV_PROFILE_paravirt.o := n
obj-y := process_$(BITS).o signal.o entry_$(BITS).o
obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o
obj-y += time.o ioport.o ldt.o dumpstack.o
-obj-y += setup.o x86_init.o i8259.o irqinit.o
+obj-y += setup.o x86_init.o i8259.o irqinit.o jump_label.o
+obj-$(CONFIG_IRQ_WORK) += irq_work.o
obj-$(CONFIG_X86_VISWS) += visws_quirks.o
obj-$(CONFIG_X86_32) += probe_roms_32.o
obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o
@@ -44,6 +45,7 @@ obj-y += bootflag.o e820.o
obj-y += pci-dma.o quirks.o i8237.o topology.o kdebugfs.o
obj-y += alternative.o i8253.o pci-nommu.o hw_breakpoint.o
obj-y += tsc.o io_delay.o rtc.o
+obj-y += pci-iommu_table.o
obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o
obj-y += process.o
@@ -85,15 +87,15 @@ obj-$(CONFIG_DOUBLEFAULT) += doublefault_32.o
obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_VM86) += vm86_32.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+obj-$(CONFIG_EARLY_PRINTK_MRST) += early_printk_mrst.o
obj-$(CONFIG_HPET_TIMER) += hpet.o
obj-$(CONFIG_APB_TIMER) += apb_timer.o
-obj-$(CONFIG_K8_NB) += k8.o
+obj-$(CONFIG_AMD_NB) += amd_nb.o
obj-$(CONFIG_DEBUG_RODATA_TEST) += test_rodata.o
obj-$(CONFIG_DEBUG_NX_TEST) += test_nx.o
-obj-$(CONFIG_VMI) += vmi_32.o vmiclock_32.o
obj-$(CONFIG_KVM_GUEST) += kvm.o
obj-$(CONFIG_KVM_CLOCK) += kvmclock.o
obj-$(CONFIG_PARAVIRT) += paravirt.o paravirt_patch_$(BITS).o
@@ -106,6 +108,7 @@ obj-$(CONFIG_SCx200) += scx200.o
scx200-y += scx200_32.o
obj-$(CONFIG_OLPC) += olpc.o
+obj-$(CONFIG_OLPC_XO1) += olpc-xo1.o
obj-$(CONFIG_OLPC_OPENFIRMWARE) += olpc_ofw.o
obj-$(CONFIG_X86_MRST) += mrst.o
@@ -122,7 +125,6 @@ obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o
# 64 bit specific files
ifeq ($(CONFIG_X86_64),y)
obj-$(CONFIG_X86_UV) += tlb_uv.o bios_uv.o uv_irq.o uv_sysfs.o uv_time.o
- obj-$(CONFIG_X86_PM_TIMER) += pmtimer_64.o
obj-$(CONFIG_AUDIT) += audit_64.o
obj-$(CONFIG_GART_IOMMU) += pci-gart_64.o aperture_64.o
diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c
index fb7a5f052e2b..5812404a0d4c 100644
--- a/arch/x86/kernel/acpi/cstate.c
+++ b/arch/x86/kernel/acpi/cstate.c
@@ -13,6 +13,7 @@
#include <acpi/processor.h>
#include <asm/acpi.h>
+#include <asm/mwait.h>
/*
* Initialize bm_flags based on the CPU cache properties
@@ -61,20 +62,10 @@ struct cstate_entry {
unsigned int ecx;
} states[ACPI_PROCESSOR_MAX_POWER];
};
-static struct cstate_entry *cpu_cstate_entry; /* per CPU ptr */
+static struct cstate_entry __percpu *cpu_cstate_entry; /* per CPU ptr */
static short mwait_supported[ACPI_PROCESSOR_MAX_POWER];
-#define MWAIT_SUBSTATE_MASK (0xf)
-#define MWAIT_CSTATE_MASK (0xf)
-#define MWAIT_SUBSTATE_SIZE (4)
-
-#define CPUID_MWAIT_LEAF (5)
-#define CPUID5_ECX_EXTENSIONS_SUPPORTED (0x1)
-#define CPUID5_ECX_INTERRUPT_BREAK (0x2)
-
-#define MWAIT_ECX_INTERRUPT_BREAK (0x1)
-
#define NATIVE_CSTATE_BEYOND_HALT (2)
static long acpi_processor_ffh_cstate_probe_cpu(void *_cx)
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
index 33cec152070d..74a847835bab 100644
--- a/arch/x86/kernel/acpi/sleep.c
+++ b/arch/x86/kernel/acpi/sleep.c
@@ -7,11 +7,17 @@
#include <linux/acpi.h>
#include <linux/bootmem.h>
+#include <linux/memblock.h>
#include <linux/dmi.h>
#include <linux/cpumask.h>
#include <asm/segment.h>
#include <asm/desc.h>
+#ifdef CONFIG_X86_32
+#include <asm/pgtable.h>
+#include <asm/pgtable_32.h>
+#endif
+
#include "realmode/wakeup.h"
#include "sleep.h"
@@ -90,7 +96,7 @@ int acpi_save_state_mem(void)
#ifndef CONFIG_64BIT
header->pmode_entry = (u32)&wakeup_pmode_return;
- header->pmode_cr3 = (u32)(swsusp_pg_dir - __PAGE_OFFSET);
+ header->pmode_cr3 = (u32)__pa(&initial_page_table);
saved_magic = 0x12345678;
#else /* CONFIG_64BIT */
header->trampoline_segment = setup_trampoline() >> 4;
@@ -125,7 +131,7 @@ void acpi_restore_state_mem(void)
*/
void __init acpi_reserve_wakeup_memory(void)
{
- unsigned long mem;
+ phys_addr_t mem;
if ((&wakeup_code_end - &wakeup_code_start) > WAKEUP_SIZE) {
printk(KERN_ERR
@@ -133,15 +139,15 @@ void __init acpi_reserve_wakeup_memory(void)
return;
}
- mem = find_e820_area(0, 1<<20, WAKEUP_SIZE, PAGE_SIZE);
+ mem = memblock_find_in_range(0, 1<<20, WAKEUP_SIZE, PAGE_SIZE);
- if (mem == -1L) {
+ if (mem == MEMBLOCK_ERROR) {
printk(KERN_ERR "ACPI: Cannot allocate lowmem, S3 disabled.\n");
return;
}
acpi_realmode = (unsigned long) phys_to_virt(mem);
acpi_wakeup_address = mem;
- reserve_early(mem, mem + WAKEUP_SIZE, "ACPI WAKEUP");
+ memblock_x86_reserve_range(mem, mem + WAKEUP_SIZE, "ACPI WAKEUP");
}
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index f65ab8b014c4..a36bb90aef53 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -195,7 +195,7 @@ static void __init_or_module add_nops(void *insns, unsigned int len)
extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
extern s32 __smp_locks[], __smp_locks_end[];
-static void *text_poke_early(void *addr, const void *opcode, size_t len);
+void *text_poke_early(void *addr, const void *opcode, size_t len);
/* Replace instructions with better alternatives for this CPU type.
This runs before SMP is initialized to avoid SMP problems with
@@ -522,7 +522,7 @@ void __init alternative_instructions(void)
* instructions. And on the local CPU you need to be protected again NMI or MCE
* handlers seeing an inconsistent instruction while you patch.
*/
-static void *__init_or_module text_poke_early(void *addr, const void *opcode,
+void *__init_or_module text_poke_early(void *addr, const void *opcode,
size_t len)
{
unsigned long flags;
@@ -637,7 +637,72 @@ void *__kprobes text_poke_smp(void *addr, const void *opcode, size_t len)
tpp.len = len;
atomic_set(&stop_machine_first, 1);
wrote_text = 0;
- stop_machine(stop_machine_text_poke, (void *)&tpp, NULL);
+ /* Use __stop_machine() because the caller already got online_cpus. */
+ __stop_machine(stop_machine_text_poke, (void *)&tpp, NULL);
return addr;
}
+#if defined(CONFIG_DYNAMIC_FTRACE) || defined(HAVE_JUMP_LABEL)
+
+unsigned char ideal_nop5[IDEAL_NOP_SIZE_5];
+
+void __init arch_init_ideal_nop5(void)
+{
+ extern const unsigned char ftrace_test_p6nop[];
+ extern const unsigned char ftrace_test_nop5[];
+ extern const unsigned char ftrace_test_jmp[];
+ int faulted = 0;
+
+ /*
+ * There is no good nop for all x86 archs.
+ * We will default to using the P6_NOP5, but first we
+ * will test to make sure that the nop will actually
+ * work on this CPU. If it faults, we will then
+ * go to a lesser efficient 5 byte nop. If that fails
+ * we then just use a jmp as our nop. This isn't the most
+ * efficient nop, but we can not use a multi part nop
+ * since we would then risk being preempted in the middle
+ * of that nop, and if we enabled tracing then, it might
+ * cause a system crash.
+ *
+ * TODO: check the cpuid to determine the best nop.
+ */
+ asm volatile (
+ "ftrace_test_jmp:"
+ "jmp ftrace_test_p6nop\n"
+ "nop\n"
+ "nop\n"
+ "nop\n" /* 2 byte jmp + 3 bytes */
+ "ftrace_test_p6nop:"
+ P6_NOP5
+ "jmp 1f\n"
+ "ftrace_test_nop5:"
+ ".byte 0x66,0x66,0x66,0x66,0x90\n"
+ "1:"
+ ".section .fixup, \"ax\"\n"
+ "2: movl $1, %0\n"
+ " jmp ftrace_test_nop5\n"
+ "3: movl $2, %0\n"
+ " jmp 1b\n"
+ ".previous\n"
+ _ASM_EXTABLE(ftrace_test_p6nop, 2b)
+ _ASM_EXTABLE(ftrace_test_nop5, 3b)
+ : "=r"(faulted) : "0" (faulted));
+
+ switch (faulted) {
+ case 0:
+ pr_info("converting mcount calls to 0f 1f 44 00 00\n");
+ memcpy(ideal_nop5, ftrace_test_p6nop, IDEAL_NOP_SIZE_5);
+ break;
+ case 1:
+ pr_info("converting mcount calls to 66 66 66 66 90\n");
+ memcpy(ideal_nop5, ftrace_test_nop5, IDEAL_NOP_SIZE_5);
+ break;
+ case 2:
+ pr_info("converting mcount calls to jmp . + 5\n");
+ memcpy(ideal_nop5, ftrace_test_jmp, IDEAL_NOP_SIZE_5);
+ break;
+ }
+
+}
+#endif
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
index 679b6450382b..d2fdb0826df2 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007-2009 Advanced Micro Devices, Inc.
+ * Copyright (C) 2007-2010 Advanced Micro Devices, Inc.
* Author: Joerg Roedel <joerg.roedel@amd.com>
* Leo Duran <leo.duran@amd.com>
*
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c
index 5a170cbbbed8..6e11c8134158 100644
--- a/arch/x86/kernel/amd_iommu_init.c
+++ b/arch/x86/kernel/amd_iommu_init.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007-2009 Advanced Micro Devices, Inc.
+ * Copyright (C) 2007-2010 Advanced Micro Devices, Inc.
* Author: Joerg Roedel <joerg.roedel@amd.com>
* Leo Duran <leo.duran@amd.com>
*
@@ -31,7 +31,7 @@
#include <asm/iommu.h>
#include <asm/gart.h>
#include <asm/x86_init.h>
-
+#include <asm/iommu_table.h>
/*
* definitions for the ACPI scanning code
*/
@@ -194,6 +194,39 @@ static inline unsigned long tbl_size(int entry_size)
return 1UL << shift;
}
+/* Access to l1 and l2 indexed register spaces */
+
+static u32 iommu_read_l1(struct amd_iommu *iommu, u16 l1, u8 address)
+{
+ u32 val;
+
+ pci_write_config_dword(iommu->dev, 0xf8, (address | l1 << 16));
+ pci_read_config_dword(iommu->dev, 0xfc, &val);
+ return val;
+}
+
+static void iommu_write_l1(struct amd_iommu *iommu, u16 l1, u8 address, u32 val)
+{
+ pci_write_config_dword(iommu->dev, 0xf8, (address | l1 << 16 | 1 << 31));
+ pci_write_config_dword(iommu->dev, 0xfc, val);
+ pci_write_config_dword(iommu->dev, 0xf8, (address | l1 << 16));
+}
+
+static u32 iommu_read_l2(struct amd_iommu *iommu, u8 address)
+{
+ u32 val;
+
+ pci_write_config_dword(iommu->dev, 0xf0, address);
+ pci_read_config_dword(iommu->dev, 0xf4, &val);
+ return val;
+}
+
+static void iommu_write_l2(struct amd_iommu *iommu, u8 address, u32 val)
+{
+ pci_write_config_dword(iommu->dev, 0xf0, (address | 1 << 8));
+ pci_write_config_dword(iommu->dev, 0xf4, val);
+}
+
/****************************************************************************
*
* AMD IOMMU MMIO register space handling functions
@@ -619,6 +652,7 @@ static void __init init_iommu_from_pci(struct amd_iommu *iommu)
{
int cap_ptr = iommu->cap_ptr;
u32 range, misc;
+ int i, j;
pci_read_config_dword(iommu->dev, cap_ptr + MMIO_CAP_HDR_OFFSET,
&iommu->cap);
@@ -633,12 +667,29 @@ static void __init init_iommu_from_pci(struct amd_iommu *iommu)
MMIO_GET_LD(range));
iommu->evt_msi_num = MMIO_MSI_NUM(misc);
- if (is_rd890_iommu(iommu->dev)) {
- pci_read_config_dword(iommu->dev, 0xf0, &iommu->cache_cfg[0]);
- pci_read_config_dword(iommu->dev, 0xf4, &iommu->cache_cfg[1]);
- pci_read_config_dword(iommu->dev, 0xf8, &iommu->cache_cfg[2]);
- pci_read_config_dword(iommu->dev, 0xfc, &iommu->cache_cfg[3]);
- }
+ if (!is_rd890_iommu(iommu->dev))
+ return;
+
+ /*
+ * Some rd890 systems may not be fully reconfigured by the BIOS, so
+ * it's necessary for us to store this information so it can be
+ * reprogrammed on resume
+ */
+
+ pci_read_config_dword(iommu->dev, iommu->cap_ptr + 4,
+ &iommu->stored_addr_lo);
+ pci_read_config_dword(iommu->dev, iommu->cap_ptr + 8,
+ &iommu->stored_addr_hi);
+
+ /* Low bit locks writes to configuration space */
+ iommu->stored_addr_lo &= ~1;
+
+ for (i = 0; i < 6; i++)
+ for (j = 0; j < 0x12; j++)
+ iommu->stored_l1[i][j] = iommu_read_l1(iommu, i, j);
+
+ for (i = 0; i < 0x83; i++)
+ iommu->stored_l2[i] = iommu_read_l2(iommu, i);
}
/*
@@ -1127,14 +1178,53 @@ static void iommu_init_flags(struct amd_iommu *iommu)
iommu_feature_enable(iommu, CONTROL_COHERENT_EN);
}
-static void iommu_apply_quirks(struct amd_iommu *iommu)
+static void iommu_apply_resume_quirks(struct amd_iommu *iommu)
{
- if (is_rd890_iommu(iommu->dev)) {
- pci_write_config_dword(iommu->dev, 0xf0, iommu->cache_cfg[0]);
- pci_write_config_dword(iommu->dev, 0xf4, iommu->cache_cfg[1]);
- pci_write_config_dword(iommu->dev, 0xf8, iommu->cache_cfg[2]);
- pci_write_config_dword(iommu->dev, 0xfc, iommu->cache_cfg[3]);
- }
+ int i, j;
+ u32 ioc_feature_control;
+ struct pci_dev *pdev = NULL;
+
+ /* RD890 BIOSes may not have completely reconfigured the iommu */
+ if (!is_rd890_iommu(iommu->dev))
+ return;
+
+ /*
+ * First, we need to ensure that the iommu is enabled. This is
+ * controlled by a register in the northbridge
+ */
+ pdev = pci_get_bus_and_slot(iommu->dev->bus->number, PCI_DEVFN(0, 0));
+
+ if (!pdev)
+ return;
+
+ /* Select Northbridge indirect register 0x75 and enable writing */
+ pci_write_config_dword(pdev, 0x60, 0x75 | (1 << 7));
+ pci_read_config_dword(pdev, 0x64, &ioc_feature_control);
+
+ /* Enable the iommu */
+ if (!(ioc_feature_control & 0x1))
+ pci_write_config_dword(pdev, 0x64, ioc_feature_control | 1);
+
+ pci_dev_put(pdev);
+
+ /* Restore the iommu BAR */
+ pci_write_config_dword(iommu->dev, iommu->cap_ptr + 4,
+ iommu->stored_addr_lo);
+ pci_write_config_dword(iommu->dev, iommu->cap_ptr + 8,
+ iommu->stored_addr_hi);
+
+ /* Restore the l1 indirect regs for each of the 6 l1s */
+ for (i = 0; i < 6; i++)
+ for (j = 0; j < 0x12; j++)
+ iommu_write_l1(iommu, i, j, iommu->stored_l1[i][j]);
+
+ /* Restore the l2 indirect regs */
+ for (i = 0; i < 0x83; i++)
+ iommu_write_l2(iommu, i, iommu->stored_l2[i]);
+
+ /* Lock PCI setup registers */
+ pci_write_config_dword(iommu->dev, iommu->cap_ptr + 4,
+ iommu->stored_addr_lo | 1);
}
/*
@@ -1147,7 +1237,6 @@ static void enable_iommus(void)
for_each_iommu(iommu) {
iommu_disable(iommu);
- iommu_apply_quirks(iommu);
iommu_init_flags(iommu);
iommu_set_device_table(iommu);
iommu_enable_command_buffer(iommu);
@@ -1173,6 +1262,11 @@ static void disable_iommus(void)
static int amd_iommu_resume(struct sys_device *dev)
{
+ struct amd_iommu *iommu;
+
+ for_each_iommu(iommu)
+ iommu_apply_resume_quirks(iommu);
+
/* re-load the hardware */
enable_iommus();
@@ -1405,13 +1499,13 @@ static int __init early_amd_iommu_detect(struct acpi_table_header *table)
return 0;
}
-void __init amd_iommu_detect(void)
+int __init amd_iommu_detect(void)
{
if (no_iommu || (iommu_detected && !gart_iommu_aperture))
- return;
+ return -ENODEV;
if (amd_iommu_disabled)
- return;
+ return -ENODEV;
if (acpi_table_parse("IVRS", early_amd_iommu_detect) == 0) {
iommu_detected = 1;
@@ -1420,7 +1514,9 @@ void __init amd_iommu_detect(void)
/* Make sure ACS will be enabled */
pci_request_acs();
+ return 1;
}
+ return -ENODEV;
}
/****************************************************************************
@@ -1451,3 +1547,8 @@ static int __init parse_amd_iommu_options(char *str)
__setup("amd_iommu_dump", parse_amd_iommu_dump);
__setup("amd_iommu=", parse_amd_iommu_options);
+
+IOMMU_INIT_FINISH(amd_iommu_detect,
+ gart_iommu_hole_init,
+ 0,
+ 0);
diff --git a/arch/x86/kernel/k8.c b/arch/x86/kernel/amd_nb.c
index 0f7bc20cfcde..8f6463d8ed0d 100644
--- a/arch/x86/kernel/k8.c
+++ b/arch/x86/kernel/amd_nb.c
@@ -8,21 +8,19 @@
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/spinlock.h>
-#include <asm/k8.h>
-
-int num_k8_northbridges;
-EXPORT_SYMBOL(num_k8_northbridges);
+#include <asm/amd_nb.h>
static u32 *flush_words;
struct pci_device_id k8_nb_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) },
+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_MISC) },
{}
};
EXPORT_SYMBOL(k8_nb_ids);
-struct pci_dev **k8_northbridges;
+struct k8_northbridge_info k8_northbridges;
EXPORT_SYMBOL(k8_northbridges);
static struct pci_dev *next_k8_northbridge(struct pci_dev *dev)
@@ -40,36 +38,45 @@ int cache_k8_northbridges(void)
int i;
struct pci_dev *dev;
- if (num_k8_northbridges)
+ if (k8_northbridges.num)
return 0;
dev = NULL;
while ((dev = next_k8_northbridge(dev)) != NULL)
- num_k8_northbridges++;
+ k8_northbridges.num++;
+
+ /* some CPU families (e.g. family 0x11) do not support GART */
+ if (boot_cpu_data.x86 == 0xf || boot_cpu_data.x86 == 0x10 ||
+ boot_cpu_data.x86 == 0x15)
+ k8_northbridges.gart_supported = 1;
- k8_northbridges = kmalloc((num_k8_northbridges + 1) * sizeof(void *),
- GFP_KERNEL);
- if (!k8_northbridges)
+ k8_northbridges.nb_misc = kmalloc((k8_northbridges.num + 1) *
+ sizeof(void *), GFP_KERNEL);
+ if (!k8_northbridges.nb_misc)
return -ENOMEM;
- if (!num_k8_northbridges) {
- k8_northbridges[0] = NULL;
+ if (!k8_northbridges.num) {
+ k8_northbridges.nb_misc[0] = NULL;
return 0;
}
- flush_words = kmalloc(num_k8_northbridges * sizeof(u32), GFP_KERNEL);
- if (!flush_words) {
- kfree(k8_northbridges);
- return -ENOMEM;
+ if (k8_northbridges.gart_supported) {
+ flush_words = kmalloc(k8_northbridges.num * sizeof(u32),
+ GFP_KERNEL);
+ if (!flush_words) {
+ kfree(k8_northbridges.nb_misc);
+ return -ENOMEM;
+ }
}
dev = NULL;
i = 0;
while ((dev = next_k8_northbridge(dev)) != NULL) {
- k8_northbridges[i] = dev;
- pci_read_config_dword(dev, 0x9c, &flush_words[i++]);
+ k8_northbridges.nb_misc[i] = dev;
+ if (k8_northbridges.gart_supported)
+ pci_read_config_dword(dev, 0x9c, &flush_words[i++]);
}
- k8_northbridges[i] = NULL;
+ k8_northbridges.nb_misc[i] = NULL;
return 0;
}
EXPORT_SYMBOL_GPL(cache_k8_northbridges);
@@ -93,22 +100,25 @@ void k8_flush_garts(void)
unsigned long flags;
static DEFINE_SPINLOCK(gart_lock);
+ if (!k8_northbridges.gart_supported)
+ return;
+
/* Avoid races between AGP and IOMMU. In theory it's not needed
but I'm not sure if the hardware won't lose flush requests
when another is pending. This whole thing is so expensive anyways
that it doesn't matter to serialize more. -AK */
spin_lock_irqsave(&gart_lock, flags);
flushed = 0;
- for (i = 0; i < num_k8_northbridges; i++) {
- pci_write_config_dword(k8_northbridges[i], 0x9c,
+ for (i = 0; i < k8_northbridges.num; i++) {
+ pci_write_config_dword(k8_northbridges.nb_misc[i], 0x9c,
flush_words[i]|1);
flushed++;
}
- for (i = 0; i < num_k8_northbridges; i++) {
+ for (i = 0; i < k8_northbridges.num; i++) {
u32 w;
/* Make sure the hardware actually executed the flush*/
for (;;) {
- pci_read_config_dword(k8_northbridges[i],
+ pci_read_config_dword(k8_northbridges.nb_misc[i],
0x9c, &w);
if (!(w & 1))
break;
diff --git a/arch/x86/kernel/apb_timer.c b/arch/x86/kernel/apb_timer.c
index 8dd77800ff5d..92543c73cf8e 100644
--- a/arch/x86/kernel/apb_timer.c
+++ b/arch/x86/kernel/apb_timer.c
@@ -231,34 +231,6 @@ static void apbt_restart_clocksource(struct clocksource *cs)
apbt_start_counter(phy_cs_timer_id);
}
-/* Setup IRQ routing via IOAPIC */
-#ifdef CONFIG_SMP
-static void apbt_setup_irq(struct apbt_dev *adev)
-{
- struct irq_chip *chip;
- struct irq_desc *desc;
-
- /* timer0 irq has been setup early */
- if (adev->irq == 0)
- return;
- desc = irq_to_desc(adev->irq);
- chip = get_irq_chip(adev->irq);
- disable_irq(adev->irq);
- desc->status |= IRQ_MOVE_PCNTXT;
- irq_set_affinity(adev->irq, cpumask_of(adev->cpu));
- /* APB timer irqs are set up as mp_irqs, timer is edge triggerred */
- set_irq_chip_and_handler_name(adev->irq, chip, handle_edge_irq, "edge");
- enable_irq(adev->irq);
- if (system_state == SYSTEM_BOOTING)
- if (request_irq(adev->irq, apbt_interrupt_handler,
- IRQF_TIMER | IRQF_DISABLED | IRQF_NOBALANCING,
- adev->name, adev)) {
- printk(KERN_ERR "Failed request IRQ for APBT%d\n",
- adev->num);
- }
-}
-#endif
-
static void apbt_enable_int(int n)
{
unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL);
@@ -334,6 +306,27 @@ static int __init apbt_clockevent_register(void)
}
#ifdef CONFIG_SMP
+
+static void apbt_setup_irq(struct apbt_dev *adev)
+{
+ /* timer0 irq has been setup early */
+ if (adev->irq == 0)
+ return;
+
+ if (system_state == SYSTEM_BOOTING) {
+ irq_modify_status(adev->irq, 0, IRQ_MOVE_PCNTXT);
+ /* APB timer irqs are set up as mp_irqs, timer is edge type */
+ __set_irq_handler(adev->irq, handle_edge_irq, 0, "edge");
+ if (request_irq(adev->irq, apbt_interrupt_handler,
+ IRQF_TIMER | IRQF_DISABLED | IRQF_NOBALANCING,
+ adev->name, adev)) {
+ printk(KERN_ERR "Failed request IRQ for APBT%d\n",
+ adev->num);
+ }
+ } else
+ enable_irq(adev->irq);
+}
+
/* Should be called with per cpu */
void apbt_setup_secondary_clock(void)
{
@@ -343,7 +336,7 @@ void apbt_setup_secondary_clock(void)
/* Don't register boot CPU clockevent */
cpu = smp_processor_id();
- if (cpu == boot_cpu_id)
+ if (!cpu)
return;
/*
* We need to calculate the scaled math multiplication factor for
@@ -389,16 +382,17 @@ static int apbt_cpuhp_notify(struct notifier_block *n,
switch (action & 0xf) {
case CPU_DEAD:
+ disable_irq(adev->irq);
apbt_disable_int(cpu);
- if (system_state == SYSTEM_RUNNING)
+ if (system_state == SYSTEM_RUNNING) {
pr_debug("skipping APBT CPU %lu offline\n", cpu);
- else if (adev) {
+ } else if (adev) {
pr_debug("APBT clockevent for cpu %lu offline\n", cpu);
free_irq(adev->irq, adev);
}
break;
default:
- pr_debug(KERN_INFO "APBT notified %lu, no action\n", action);
+ pr_debug("APBT notified %lu, no action\n", action);
}
return NOTIFY_OK;
}
@@ -552,7 +546,7 @@ bad_count:
pr_debug("APB CS going back %lx:%lx:%lx ",
t2, last_read, t2 - last_read);
bad_count_x3:
- pr_debug(KERN_INFO "tripple check enforced\n");
+ pr_debug("triple check enforced\n");
t0 = apbt_readl(phy_cs_timer_id,
APBTMR_N_CURRENT_VALUE);
udelay(1);
diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c
index a2e0caf26e17..b3a16e8f0703 100644
--- a/arch/x86/kernel/aperture_64.c
+++ b/arch/x86/kernel/aperture_64.c
@@ -27,7 +27,7 @@
#include <asm/gart.h>
#include <asm/pci-direct.h>
#include <asm/dma.h>
-#include <asm/k8.h>
+#include <asm/amd_nb.h>
#include <asm/x86_init.h>
int gart_iommu_aperture;
@@ -307,7 +307,7 @@ void __init early_gart_iommu_check(void)
continue;
ctl = read_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL);
- aper_enabled = ctl & AMD64_GARTEN;
+ aper_enabled = ctl & GARTEN;
aper_order = (ctl >> 1) & 7;
aper_size = (32 * 1024 * 1024) << aper_order;
aper_base = read_pci_config(bus, slot, 3, AMD64_GARTAPERTUREBASE) & 0x7fff;
@@ -362,7 +362,7 @@ void __init early_gart_iommu_check(void)
continue;
ctl = read_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL);
- ctl &= ~AMD64_GARTEN;
+ ctl &= ~GARTEN;
write_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL, ctl);
}
}
@@ -371,7 +371,7 @@ void __init early_gart_iommu_check(void)
static int __initdata printed_gart_size_msg;
-void __init gart_iommu_hole_init(void)
+int __init gart_iommu_hole_init(void)
{
u32 agp_aper_base = 0, agp_aper_order = 0;
u32 aper_size, aper_alloc = 0, aper_order = 0, last_aper_order = 0;
@@ -381,7 +381,7 @@ void __init gart_iommu_hole_init(void)
if (gart_iommu_aperture_disabled || !fix_aperture ||
!early_pci_allowed())
- return;
+ return -ENODEV;
printk(KERN_INFO "Checking aperture...\n");
@@ -463,8 +463,9 @@ out:
unsigned long n = (32 * 1024 * 1024) << last_aper_order;
insert_aperture_resource((u32)last_aper_base, n);
+ return 1;
}
- return;
+ return 0;
}
if (!fallback_aper_force) {
@@ -500,13 +501,18 @@ out:
panic("Not enough memory for aperture");
}
} else {
- return;
+ return 0;
}
/* Fix up the north bridges */
for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
- int bus;
- int dev_base, dev_limit;
+ int bus, dev_base, dev_limit;
+
+ /*
+ * Don't enable translation yet but enable GART IO and CPU
+ * accesses and set DISTLBWALKPRB since GART table memory is UC.
+ */
+ u32 ctl = DISTLBWALKPRB | aper_order << 1;
bus = bus_dev_ranges[i].bus;
dev_base = bus_dev_ranges[i].dev_base;
@@ -515,13 +521,12 @@ out:
if (!early_is_k8_nb(read_pci_config(bus, slot, 3, 0x00)))
continue;
- /* Don't enable translation yet. That is done later.
- Assume this BIOS didn't initialise the GART so
- just overwrite all previous bits */
- write_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL, aper_order << 1);
+ write_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL, ctl);
write_pci_config(bus, slot, 3, AMD64_GARTAPERTUREBASE, aper_alloc >> 25);
}
}
set_up_gart_resume(aper_order, aper_alloc);
+
+ return 1;
}
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index e3b534cda49a..850657d1b0ed 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -52,6 +52,7 @@
#include <asm/mce.h>
#include <asm/kvm_para.h>
#include <asm/tsc.h>
+#include <asm/atomic.h>
unsigned int num_processors;
@@ -370,38 +371,87 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
}
/*
- * Setup extended LVT, AMD specific (K8, family 10h)
+ * Setup extended LVT, AMD specific
*
- * Vector mappings are hard coded. On K8 only offset 0 (APIC500) and
- * MCE interrupts are supported. Thus MCE offset must be set to 0.
+ * Software should use the LVT offsets the BIOS provides. The offsets
+ * are determined by the subsystems using it like those for MCE
+ * threshold or IBS. On K8 only offset 0 (APIC500) and MCE interrupts
+ * are supported. Beginning with family 10h at least 4 offsets are
+ * available.
*
- * If mask=1, the LVT entry does not generate interrupts while mask=0
- * enables the vector. See also the BKDGs.
+ * Since the offsets must be consistent for all cores, we keep track
+ * of the LVT offsets in software and reserve the offset for the same
+ * vector also to be used on other cores. An offset is freed by
+ * setting the entry to APIC_EILVT_MASKED.
+ *
+ * If the BIOS is right, there should be no conflicts. Otherwise a
+ * "[Firmware Bug]: ..." error message is generated. However, if
+ * software does not properly determines the offsets, it is not
+ * necessarily a BIOS bug.
*/
-#define APIC_EILVT_LVTOFF_MCE 0
-#define APIC_EILVT_LVTOFF_IBS 1
+static atomic_t eilvt_offsets[APIC_EILVT_NR_MAX];
-static void setup_APIC_eilvt(u8 lvt_off, u8 vector, u8 msg_type, u8 mask)
+static inline int eilvt_entry_is_changeable(unsigned int old, unsigned int new)
{
- unsigned long reg = (lvt_off << 4) + APIC_EILVTn(0);
- unsigned int v = (mask << 16) | (msg_type << 8) | vector;
-
- apic_write(reg, v);
+ return (old & APIC_EILVT_MASKED)
+ || (new == APIC_EILVT_MASKED)
+ || ((new & ~APIC_EILVT_MASKED) == old);
}
-u8 setup_APIC_eilvt_mce(u8 vector, u8 msg_type, u8 mask)
+static unsigned int reserve_eilvt_offset(int offset, unsigned int new)
{
- setup_APIC_eilvt(APIC_EILVT_LVTOFF_MCE, vector, msg_type, mask);
- return APIC_EILVT_LVTOFF_MCE;
+ unsigned int rsvd; /* 0: uninitialized */
+
+ if (offset >= APIC_EILVT_NR_MAX)
+ return ~0;
+
+ rsvd = atomic_read(&eilvt_offsets[offset]) & ~APIC_EILVT_MASKED;
+ do {
+ if (rsvd &&
+ !eilvt_entry_is_changeable(rsvd, new))
+ /* may not change if vectors are different */
+ return rsvd;
+ rsvd = atomic_cmpxchg(&eilvt_offsets[offset], rsvd, new);
+ } while (rsvd != new);
+
+ return new;
}
-u8 setup_APIC_eilvt_ibs(u8 vector, u8 msg_type, u8 mask)
+/*
+ * If mask=1, the LVT entry does not generate interrupts while mask=0
+ * enables the vector. See also the BKDGs.
+ */
+
+int setup_APIC_eilvt(u8 offset, u8 vector, u8 msg_type, u8 mask)
{
- setup_APIC_eilvt(APIC_EILVT_LVTOFF_IBS, vector, msg_type, mask);
- return APIC_EILVT_LVTOFF_IBS;
+ unsigned long reg = APIC_EILVTn(offset);
+ unsigned int new, old, reserved;
+
+ new = (mask << 16) | (msg_type << 8) | vector;
+ old = apic_read(reg);
+ reserved = reserve_eilvt_offset(offset, new);
+
+ if (reserved != new) {
+ pr_err(FW_BUG "cpu %d, try to setup vector 0x%x, but "
+ "vector 0x%x was already reserved by another core, "
+ "APIC%lX=0x%x\n",
+ smp_processor_id(), new, reserved, reg, old);
+ return -EINVAL;
+ }
+
+ if (!eilvt_entry_is_changeable(old, new)) {
+ pr_err(FW_BUG "cpu %d, try to setup vector 0x%x but "
+ "register already in use, APIC%lX=0x%x\n",
+ smp_processor_id(), new, reg, old);
+ return -EBUSY;
+ }
+
+ apic_write(reg, new);
+
+ return 0;
}
-EXPORT_SYMBOL_GPL(setup_APIC_eilvt_ibs);
+EXPORT_SYMBOL_GPL(setup_APIC_eilvt);
/*
* Program the next event, relative to now
@@ -1665,10 +1715,7 @@ int __init APIC_init_uniprocessor(void)
}
#endif
-#ifndef CONFIG_SMP
- enable_IR_x2apic();
default_setup_apic_routing();
-#endif
verify_local_APIC();
connect_bsp_APIC();
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index f1efebaf5510..8ae808d110f4 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -131,13 +131,9 @@ struct irq_pin_list {
struct irq_pin_list *next;
};
-static struct irq_pin_list *get_one_free_irq_2_pin(int node)
+static struct irq_pin_list *alloc_irq_pin_list(int node)
{
- struct irq_pin_list *pin;
-
- pin = kzalloc_node(sizeof(*pin), GFP_ATOMIC, node);
-
- return pin;
+ return kzalloc_node(sizeof(struct irq_pin_list), GFP_KERNEL, node);
}
/* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */
@@ -150,10 +146,7 @@ static struct irq_cfg irq_cfgx[NR_IRQS];
int __init arch_early_irq_init(void)
{
struct irq_cfg *cfg;
- struct irq_desc *desc;
- int count;
- int node;
- int i;
+ int count, node, i;
if (!legacy_pic->nr_legacy_irqs) {
nr_irqs_gsi = 0;
@@ -162,13 +155,15 @@ int __init arch_early_irq_init(void)
cfg = irq_cfgx;
count = ARRAY_SIZE(irq_cfgx);
- node= cpu_to_node(boot_cpu_id);
+ node = cpu_to_node(0);
+
+ /* Make sure the legacy interrupts are marked in the bitmap */
+ irq_reserve_irqs(0, legacy_pic->nr_legacy_irqs);
for (i = 0; i < count; i++) {
- desc = irq_to_desc(i);
- desc->chip_data = &cfg[i];
- zalloc_cpumask_var_node(&cfg[i].domain, GFP_NOWAIT, node);
- zalloc_cpumask_var_node(&cfg[i].old_domain, GFP_NOWAIT, node);
+ set_irq_chip_data(i, &cfg[i]);
+ zalloc_cpumask_var_node(&cfg[i].domain, GFP_KERNEL, node);
+ zalloc_cpumask_var_node(&cfg[i].old_domain, GFP_KERNEL, node);
/*
* For legacy IRQ's, start with assigning irq0 to irq15 to
* IRQ0_VECTOR to IRQ15_VECTOR on cpu 0.
@@ -183,165 +178,88 @@ int __init arch_early_irq_init(void)
}
#ifdef CONFIG_SPARSE_IRQ
-struct irq_cfg *irq_cfg(unsigned int irq)
+static struct irq_cfg *irq_cfg(unsigned int irq)
{
- struct irq_cfg *cfg = NULL;
- struct irq_desc *desc;
-
- desc = irq_to_desc(irq);
- if (desc)
- cfg = desc->chip_data;
-
- return cfg;
+ return get_irq_chip_data(irq);
}
-static struct irq_cfg *get_one_free_irq_cfg(int node)
+static struct irq_cfg *alloc_irq_cfg(unsigned int irq, int node)
{
struct irq_cfg *cfg;
- cfg = kzalloc_node(sizeof(*cfg), GFP_ATOMIC, node);
- if (cfg) {
- if (!zalloc_cpumask_var_node(&cfg->domain, GFP_ATOMIC, node)) {
- kfree(cfg);
- cfg = NULL;
- } else if (!zalloc_cpumask_var_node(&cfg->old_domain,
- GFP_ATOMIC, node)) {
- free_cpumask_var(cfg->domain);
- kfree(cfg);
- cfg = NULL;
- }
- }
-
+ cfg = kzalloc_node(sizeof(*cfg), GFP_KERNEL, node);
+ if (!cfg)
+ return NULL;
+ if (!zalloc_cpumask_var_node(&cfg->domain, GFP_KERNEL, node))
+ goto out_cfg;
+ if (!zalloc_cpumask_var_node(&cfg->old_domain, GFP_KERNEL, node))
+ goto out_domain;
return cfg;
+out_domain:
+ free_cpumask_var(cfg->domain);
+out_cfg:
+ kfree(cfg);
+ return NULL;
}
-int arch_init_chip_data(struct irq_desc *desc, int node)
-{
- struct irq_cfg *cfg;
-
- cfg = desc->chip_data;
- if (!cfg) {
- desc->chip_data = get_one_free_irq_cfg(node);
- if (!desc->chip_data) {
- printk(KERN_ERR "can not alloc irq_cfg\n");
- BUG_ON(1);
- }
- }
-
- return 0;
-}
-
-/* for move_irq_desc */
-static void
-init_copy_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg, int node)
+static void free_irq_cfg(unsigned int at, struct irq_cfg *cfg)
{
- struct irq_pin_list *old_entry, *head, *tail, *entry;
-
- cfg->irq_2_pin = NULL;
- old_entry = old_cfg->irq_2_pin;
- if (!old_entry)
- return;
-
- entry = get_one_free_irq_2_pin(node);
- if (!entry)
+ if (!cfg)
return;
+ set_irq_chip_data(at, NULL);
+ free_cpumask_var(cfg->domain);
+ free_cpumask_var(cfg->old_domain);
+ kfree(cfg);
+}
- entry->apic = old_entry->apic;
- entry->pin = old_entry->pin;
- head = entry;
- tail = entry;
- old_entry = old_entry->next;
- while (old_entry) {
- entry = get_one_free_irq_2_pin(node);
- if (!entry) {
- entry = head;
- while (entry) {
- head = entry->next;
- kfree(entry);
- entry = head;
- }
- /* still use the old one */
- return;
- }
- entry->apic = old_entry->apic;
- entry->pin = old_entry->pin;
- tail->next = entry;
- tail = entry;
- old_entry = old_entry->next;
- }
+#else
- tail->next = NULL;
- cfg->irq_2_pin = head;
+struct irq_cfg *irq_cfg(unsigned int irq)
+{
+ return irq < nr_irqs ? irq_cfgx + irq : NULL;
}
-static void free_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg)
+static struct irq_cfg *alloc_irq_cfg(unsigned int irq, int node)
{
- struct irq_pin_list *entry, *next;
-
- if (old_cfg->irq_2_pin == cfg->irq_2_pin)
- return;
+ return irq_cfgx + irq;
+}
- entry = old_cfg->irq_2_pin;
+static inline void free_irq_cfg(unsigned int at, struct irq_cfg *cfg) { }
- while (entry) {
- next = entry->next;
- kfree(entry);
- entry = next;
- }
- old_cfg->irq_2_pin = NULL;
-}
+#endif
-void arch_init_copy_chip_data(struct irq_desc *old_desc,
- struct irq_desc *desc, int node)
+static struct irq_cfg *alloc_irq_and_cfg_at(unsigned int at, int node)
{
+ int res = irq_alloc_desc_at(at, node);
struct irq_cfg *cfg;
- struct irq_cfg *old_cfg;
-
- cfg = get_one_free_irq_cfg(node);
-
- if (!cfg)
- return;
- desc->chip_data = cfg;
-
- old_cfg = old_desc->chip_data;
-
- memcpy(cfg, old_cfg, sizeof(struct irq_cfg));
-
- init_copy_irq_2_pin(old_cfg, cfg, node);
-}
+ if (res < 0) {
+ if (res != -EEXIST)
+ return NULL;
+ cfg = get_irq_chip_data(at);
+ if (cfg)
+ return cfg;
+ }
-static void free_irq_cfg(struct irq_cfg *old_cfg)
-{
- kfree(old_cfg);
+ cfg = alloc_irq_cfg(at, node);
+ if (cfg)
+ set_irq_chip_data(at, cfg);
+ else
+ irq_free_desc(at);
+ return cfg;
}
-void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc)
+static int alloc_irq_from(unsigned int from, int node)
{
- struct irq_cfg *old_cfg, *cfg;
-
- old_cfg = old_desc->chip_data;
- cfg = desc->chip_data;
-
- if (old_cfg == cfg)
- return;
-
- if (old_cfg) {
- free_irq_2_pin(old_cfg, cfg);
- free_irq_cfg(old_cfg);
- old_desc->chip_data = NULL;
- }
+ return irq_alloc_desc_from(from, node);
}
-/* end for move_irq_desc */
-#else
-struct irq_cfg *irq_cfg(unsigned int irq)
+static void free_irq_at(unsigned int at, struct irq_cfg *cfg)
{
- return irq < nr_irqs ? irq_cfgx + irq : NULL;
+ free_irq_cfg(at, cfg);
+ irq_free_desc(at);
}
-#endif
-
struct io_apic {
unsigned int index;
unsigned int unused[3];
@@ -446,7 +364,7 @@ __ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e)
io_apic_write(apic, 0x10 + 2*pin, eu.w1);
}
-void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e)
+static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e)
{
unsigned long flags;
raw_spin_lock_irqsave(&ioapic_lock, flags);
@@ -476,7 +394,7 @@ static void ioapic_mask_entry(int apic, int pin)
* fast in the common case, and fast for shared ISA-space IRQs.
*/
static int
-add_pin_to_irq_node_nopanic(struct irq_cfg *cfg, int node, int apic, int pin)
+__add_pin_to_irq_node(struct irq_cfg *cfg, int node, int apic, int pin)
{
struct irq_pin_list **last, *entry;
@@ -488,7 +406,7 @@ add_pin_to_irq_node_nopanic(struct irq_cfg *cfg, int node, int apic, int pin)
last = &entry->next;
}
- entry = get_one_free_irq_2_pin(node);
+ entry = alloc_irq_pin_list(node);
if (!entry) {
printk(KERN_ERR "can not alloc irq_pin_list (%d,%d,%d)\n",
node, apic, pin);
@@ -503,7 +421,7 @@ add_pin_to_irq_node_nopanic(struct irq_cfg *cfg, int node, int apic, int pin)
static void add_pin_to_irq_node(struct irq_cfg *cfg, int node, int apic, int pin)
{
- if (add_pin_to_irq_node_nopanic(cfg, node, apic, pin))
+ if (__add_pin_to_irq_node(cfg, node, apic, pin))
panic("IO-APIC: failed to add irq-pin. Can not proceed\n");
}
@@ -566,11 +484,6 @@ static void __unmask_and_level_IO_APIC_irq(struct irq_pin_list *entry)
IO_APIC_REDIR_LEVEL_TRIGGER, NULL);
}
-static void __unmask_IO_APIC_irq(struct irq_cfg *cfg)
-{
- io_apic_modify_irq(cfg, ~IO_APIC_REDIR_MASKED, 0, NULL);
-}
-
static void io_apic_sync(struct irq_pin_list *entry)
{
/*
@@ -582,44 +495,37 @@ static void io_apic_sync(struct irq_pin_list *entry)
readl(&io_apic->data);
}
-static void __mask_IO_APIC_irq(struct irq_cfg *cfg)
+static void mask_ioapic(struct irq_cfg *cfg)
{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&ioapic_lock, flags);
io_apic_modify_irq(cfg, ~0, IO_APIC_REDIR_MASKED, &io_apic_sync);
+ raw_spin_unlock_irqrestore(&ioapic_lock, flags);
}
-static void mask_IO_APIC_irq_desc(struct irq_desc *desc)
+static void mask_ioapic_irq(struct irq_data *data)
{
- struct irq_cfg *cfg = desc->chip_data;
- unsigned long flags;
-
- BUG_ON(!cfg);
+ mask_ioapic(data->chip_data);
+}
- raw_spin_lock_irqsave(&ioapic_lock, flags);
- __mask_IO_APIC_irq(cfg);
- raw_spin_unlock_irqrestore(&ioapic_lock, flags);
+static void __unmask_ioapic(struct irq_cfg *cfg)
+{
+ io_apic_modify_irq(cfg, ~IO_APIC_REDIR_MASKED, 0, NULL);
}
-static void unmask_IO_APIC_irq_desc(struct irq_desc *desc)
+static void unmask_ioapic(struct irq_cfg *cfg)
{
- struct irq_cfg *cfg = desc->chip_data;
unsigned long flags;
raw_spin_lock_irqsave(&ioapic_lock, flags);
- __unmask_IO_APIC_irq(cfg);
+ __unmask_ioapic(cfg);
raw_spin_unlock_irqrestore(&ioapic_lock, flags);
}
-static void mask_IO_APIC_irq(unsigned int irq)
-{
- struct irq_desc *desc = irq_to_desc(irq);
-
- mask_IO_APIC_irq_desc(desc);
-}
-static void unmask_IO_APIC_irq(unsigned int irq)
+static void unmask_ioapic_irq(struct irq_data *data)
{
- struct irq_desc *desc = irq_to_desc(irq);
-
- unmask_IO_APIC_irq_desc(desc);
+ unmask_ioapic(data->chip_data);
}
static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin)
@@ -689,14 +595,14 @@ struct IO_APIC_route_entry **alloc_ioapic_entries(void)
struct IO_APIC_route_entry **ioapic_entries;
ioapic_entries = kzalloc(sizeof(*ioapic_entries) * nr_ioapics,
- GFP_ATOMIC);
+ GFP_KERNEL);
if (!ioapic_entries)
return 0;
for (apic = 0; apic < nr_ioapics; apic++) {
ioapic_entries[apic] =
kzalloc(sizeof(struct IO_APIC_route_entry) *
- nr_ioapic_registers[apic], GFP_ATOMIC);
+ nr_ioapic_registers[apic], GFP_KERNEL);
if (!ioapic_entries[apic])
goto nomem;
}
@@ -1254,7 +1160,6 @@ void __setup_vector_irq(int cpu)
/* Initialize vector_irq on a new cpu */
int irq, vector;
struct irq_cfg *cfg;
- struct irq_desc *desc;
/*
* vector_lock will make sure that we don't run into irq vector
@@ -1263,9 +1168,10 @@ void __setup_vector_irq(int cpu)
*/
raw_spin_lock(&vector_lock);
/* Mark the inuse vectors */
- for_each_irq_desc(irq, desc) {
- cfg = desc->chip_data;
-
+ for_each_active_irq(irq) {
+ cfg = get_irq_chip_data(irq);
+ if (!cfg)
+ continue;
/*
* If it is a legacy IRQ handled by the legacy PIC, this cpu
* will be part of the irq_cfg's domain.
@@ -1322,17 +1228,17 @@ static inline int IO_APIC_irq_trigger(int irq)
}
#endif
-static void ioapic_register_intr(int irq, struct irq_desc *desc, unsigned long trigger)
+static void ioapic_register_intr(unsigned int irq, unsigned long trigger)
{
if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
trigger == IOAPIC_LEVEL)
- desc->status |= IRQ_LEVEL;
+ irq_set_status_flags(irq, IRQ_LEVEL);
else
- desc->status &= ~IRQ_LEVEL;
+ irq_clear_status_flags(irq, IRQ_LEVEL);
- if (irq_remapped(irq)) {
- desc->status |= IRQ_MOVE_PCNTXT;
+ if (irq_remapped(get_irq_chip_data(irq))) {
+ irq_set_status_flags(irq, IRQ_MOVE_PCNTXT);
if (trigger)
set_irq_chip_and_handler_name(irq, &ir_ioapic_chip,
handle_fasteoi_irq,
@@ -1353,10 +1259,10 @@ static void ioapic_register_intr(int irq, struct irq_desc *desc, unsigned long t
handle_edge_irq, "edge");
}
-int setup_ioapic_entry(int apic_id, int irq,
- struct IO_APIC_route_entry *entry,
- unsigned int destination, int trigger,
- int polarity, int vector, int pin)
+static int setup_ioapic_entry(int apic_id, int irq,
+ struct IO_APIC_route_entry *entry,
+ unsigned int destination, int trigger,
+ int polarity, int vector, int pin)
{
/*
* add it to the IO-APIC irq-routing table:
@@ -1377,21 +1283,7 @@ int setup_ioapic_entry(int apic_id, int irq,
if (index < 0)
panic("Failed to allocate IRTE for ioapic %d\n", apic_id);
- memset(&irte, 0, sizeof(irte));
-
- irte.present = 1;
- irte.dst_mode = apic->irq_dest_mode;
- /*
- * Trigger mode in the IRTE will always be edge, and the
- * actual level or edge trigger will be setup in the IO-APIC
- * RTE. This will help simplify level triggered irq migration.
- * For more details, see the comments above explainig IO-APIC
- * irq migration in the presence of interrupt-remapping.
- */
- irte.trigger_mode = 0;
- irte.dlvry_mode = apic->irq_delivery_mode;
- irte.vector = vector;
- irte.dest_id = IRTE_DEST(destination);
+ prepare_irte(&irte, vector, destination);
/* Set source-id of interrupt request */
set_ioapic_sid(&irte, apic_id);
@@ -1426,18 +1318,14 @@ int setup_ioapic_entry(int apic_id, int irq,
return 0;
}
-static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq_desc *desc,
- int trigger, int polarity)
+static void setup_ioapic_irq(int apic_id, int pin, unsigned int irq,
+ struct irq_cfg *cfg, int trigger, int polarity)
{
- struct irq_cfg *cfg;
struct IO_APIC_route_entry entry;
unsigned int dest;
if (!IO_APIC_IRQ(irq))
return;
-
- cfg = desc->chip_data;
-
/*
* For legacy irqs, cfg->domain starts with cpu 0 for legacy
* controllers like 8259. Now that IO-APIC can handle this irq, update
@@ -1466,9 +1354,9 @@ static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq
return;
}
- ioapic_register_intr(irq, desc, trigger);
+ ioapic_register_intr(irq, trigger);
if (irq < legacy_pic->nr_legacy_irqs)
- legacy_pic->chip->mask(irq);
+ legacy_pic->mask(irq);
ioapic_write_entry(apic_id, pin, entry);
}
@@ -1479,11 +1367,9 @@ static struct {
static void __init setup_IO_APIC_irqs(void)
{
- int apic_id, pin, idx, irq;
- int notcon = 0;
- struct irq_desc *desc;
+ int apic_id, pin, idx, irq, notcon = 0;
+ int node = cpu_to_node(0);
struct irq_cfg *cfg;
- int node = cpu_to_node(boot_cpu_id);
apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
@@ -1520,19 +1406,17 @@ static void __init setup_IO_APIC_irqs(void)
apic->multi_timer_check(apic_id, irq))
continue;
- desc = irq_to_desc_alloc_node(irq, node);
- if (!desc) {
- printk(KERN_INFO "can not get irq_desc for %d\n", irq);
+ cfg = alloc_irq_and_cfg_at(irq, node);
+ if (!cfg)
continue;
- }
- cfg = desc->chip_data;
+
add_pin_to_irq_node(cfg, node, apic_id, pin);
/*
* don't mark it in pin_programmed, so later acpi could
* set it correctly when irq < 16
*/
- setup_IO_APIC_irq(apic_id, pin, irq, desc,
- irq_trigger(idx), irq_polarity(idx));
+ setup_ioapic_irq(apic_id, pin, irq, cfg, irq_trigger(idx),
+ irq_polarity(idx));
}
if (notcon)
@@ -1547,9 +1431,7 @@ static void __init setup_IO_APIC_irqs(void)
*/
void setup_IO_APIC_irq_extra(u32 gsi)
{
- int apic_id = 0, pin, idx, irq;
- int node = cpu_to_node(boot_cpu_id);
- struct irq_desc *desc;
+ int apic_id = 0, pin, idx, irq, node = cpu_to_node(0);
struct irq_cfg *cfg;
/*
@@ -1565,18 +1447,15 @@ void setup_IO_APIC_irq_extra(u32 gsi)
return;
irq = pin_2_irq(idx, apic_id, pin);
-#ifdef CONFIG_SPARSE_IRQ
- desc = irq_to_desc(irq);
- if (desc)
+
+ /* Only handle the non legacy irqs on secondary ioapics */
+ if (apic_id == 0 || irq < NR_IRQS_LEGACY)
return;
-#endif
- desc = irq_to_desc_alloc_node(irq, node);
- if (!desc) {
- printk(KERN_INFO "can not get irq_desc for %d\n", irq);
+
+ cfg = alloc_irq_and_cfg_at(irq, node);
+ if (!cfg)
return;
- }
- cfg = desc->chip_data;
add_pin_to_irq_node(cfg, node, apic_id, pin);
if (test_bit(pin, mp_ioapic_routing[apic_id].pin_programmed)) {
@@ -1586,7 +1465,7 @@ void setup_IO_APIC_irq_extra(u32 gsi)
}
set_bit(pin, mp_ioapic_routing[apic_id].pin_programmed);
- setup_IO_APIC_irq(apic_id, pin, irq, desc,
+ setup_ioapic_irq(apic_id, pin, irq, cfg,
irq_trigger(idx), irq_polarity(idx));
}
@@ -1637,7 +1516,6 @@ __apicdebuginit(void) print_IO_APIC(void)
union IO_APIC_reg_03 reg_03;
unsigned long flags;
struct irq_cfg *cfg;
- struct irq_desc *desc;
unsigned int irq;
printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries);
@@ -1724,10 +1602,10 @@ __apicdebuginit(void) print_IO_APIC(void)
}
}
printk(KERN_DEBUG "IRQ to pin mappings:\n");
- for_each_irq_desc(irq, desc) {
+ for_each_active_irq(irq) {
struct irq_pin_list *entry;
- cfg = desc->chip_data;
+ cfg = get_irq_chip_data(irq);
if (!cfg)
continue;
entry = cfg->irq_2_pin;
@@ -2234,29 +2112,26 @@ static int __init timer_irq_works(void)
* an edge even if it isn't on the 8259A...
*/
-static unsigned int startup_ioapic_irq(unsigned int irq)
+static unsigned int startup_ioapic_irq(struct irq_data *data)
{
- int was_pending = 0;
+ int was_pending = 0, irq = data->irq;
unsigned long flags;
- struct irq_cfg *cfg;
raw_spin_lock_irqsave(&ioapic_lock, flags);
if (irq < legacy_pic->nr_legacy_irqs) {
- legacy_pic->chip->mask(irq);
+ legacy_pic->mask(irq);
if (legacy_pic->irq_pending(irq))
was_pending = 1;
}
- cfg = irq_cfg(irq);
- __unmask_IO_APIC_irq(cfg);
+ __unmask_ioapic(data->chip_data);
raw_spin_unlock_irqrestore(&ioapic_lock, flags);
return was_pending;
}
-static int ioapic_retrigger_irq(unsigned int irq)
+static int ioapic_retrigger_irq(struct irq_data *data)
{
-
- struct irq_cfg *cfg = irq_cfg(irq);
+ struct irq_cfg *cfg = data->chip_data;
unsigned long flags;
raw_spin_lock_irqsave(&vector_lock, flags);
@@ -2307,7 +2182,7 @@ static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq
* With interrupt-remapping, destination information comes
* from interrupt-remapping table entry.
*/
- if (!irq_remapped(irq))
+ if (!irq_remapped(cfg))
io_apic_write(apic, 0x11 + pin*2, dest);
reg = io_apic_read(apic, 0x10 + pin*2);
reg &= ~IO_APIC_REDIR_VECTOR_MASK;
@@ -2317,65 +2192,46 @@ static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq
}
/*
- * Either sets desc->affinity to a valid value, and returns
+ * Either sets data->affinity to a valid value, and returns
* ->cpu_mask_to_apicid of that in dest_id, or returns -1 and
- * leaves desc->affinity untouched.
+ * leaves data->affinity untouched.
*/
-unsigned int
-set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask,
- unsigned int *dest_id)
+int __ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
+ unsigned int *dest_id)
{
- struct irq_cfg *cfg;
- unsigned int irq;
+ struct irq_cfg *cfg = data->chip_data;
if (!cpumask_intersects(mask, cpu_online_mask))
return -1;
- irq = desc->irq;
- cfg = desc->chip_data;
- if (assign_irq_vector(irq, cfg, mask))
+ if (assign_irq_vector(data->irq, data->chip_data, mask))
return -1;
- cpumask_copy(desc->affinity, mask);
+ cpumask_copy(data->affinity, mask);
- *dest_id = apic->cpu_mask_to_apicid_and(desc->affinity, cfg->domain);
+ *dest_id = apic->cpu_mask_to_apicid_and(mask, cfg->domain);
return 0;
}
static int
-set_ioapic_affinity_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
+ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
+ bool force)
{
- struct irq_cfg *cfg;
+ unsigned int dest, irq = data->irq;
unsigned long flags;
- unsigned int dest;
- unsigned int irq;
- int ret = -1;
-
- irq = desc->irq;
- cfg = desc->chip_data;
+ int ret;
raw_spin_lock_irqsave(&ioapic_lock, flags);
- ret = set_desc_affinity(desc, mask, &dest);
+ ret = __ioapic_set_affinity(data, mask, &dest);
if (!ret) {
/* Only the high 8 bits are valid. */
dest = SET_APIC_LOGICAL_ID(dest);
- __target_IO_APIC_irq(irq, dest, cfg);
+ __target_IO_APIC_irq(irq, dest, data->chip_data);
}
raw_spin_unlock_irqrestore(&ioapic_lock, flags);
-
return ret;
}
-static int
-set_ioapic_affinity_irq(unsigned int irq, const struct cpumask *mask)
-{
- struct irq_desc *desc;
-
- desc = irq_to_desc(irq);
-
- return set_ioapic_affinity_irq_desc(desc, mask);
-}
-
#ifdef CONFIG_INTR_REMAP
/*
@@ -2390,24 +2246,21 @@ set_ioapic_affinity_irq(unsigned int irq, const struct cpumask *mask)
* the interrupt-remapping table entry.
*/
static int
-migrate_ioapic_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
+ir_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
+ bool force)
{
- struct irq_cfg *cfg;
+ struct irq_cfg *cfg = data->chip_data;
+ unsigned int dest, irq = data->irq;
struct irte irte;
- unsigned int dest;
- unsigned int irq;
- int ret = -1;
if (!cpumask_intersects(mask, cpu_online_mask))
- return ret;
+ return -EINVAL;
- irq = desc->irq;
if (get_irte(irq, &irte))
- return ret;
+ return -EBUSY;
- cfg = desc->chip_data;
if (assign_irq_vector(irq, cfg, mask))
- return ret;
+ return -EBUSY;
dest = apic->cpu_mask_to_apicid_and(cfg->domain, mask);
@@ -2422,29 +2275,14 @@ migrate_ioapic_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
if (cfg->move_in_progress)
send_cleanup_vector(cfg);
- cpumask_copy(desc->affinity, mask);
-
+ cpumask_copy(data->affinity, mask);
return 0;
}
-/*
- * Migrates the IRQ destination in the process context.
- */
-static int set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc,
- const struct cpumask *mask)
-{
- return migrate_ioapic_irq_desc(desc, mask);
-}
-static int set_ir_ioapic_affinity_irq(unsigned int irq,
- const struct cpumask *mask)
-{
- struct irq_desc *desc = irq_to_desc(irq);
-
- return set_ir_ioapic_affinity_irq_desc(desc, mask);
-}
#else
-static inline int set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc,
- const struct cpumask *mask)
+static inline int
+ir_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
+ bool force)
{
return 0;
}
@@ -2506,10 +2344,8 @@ unlock:
irq_exit();
}
-static void __irq_complete_move(struct irq_desc **descp, unsigned vector)
+static void __irq_complete_move(struct irq_cfg *cfg, unsigned vector)
{
- struct irq_desc *desc = *descp;
- struct irq_cfg *cfg = desc->chip_data;
unsigned me;
if (likely(!cfg->move_in_progress))
@@ -2521,31 +2357,28 @@ static void __irq_complete_move(struct irq_desc **descp, unsigned vector)
send_cleanup_vector(cfg);
}
-static void irq_complete_move(struct irq_desc **descp)
+static void irq_complete_move(struct irq_cfg *cfg)
{
- __irq_complete_move(descp, ~get_irq_regs()->orig_ax);
+ __irq_complete_move(cfg, ~get_irq_regs()->orig_ax);
}
void irq_force_complete_move(int irq)
{
- struct irq_desc *desc = irq_to_desc(irq);
- struct irq_cfg *cfg = desc->chip_data;
+ struct irq_cfg *cfg = get_irq_chip_data(irq);
if (!cfg)
return;
- __irq_complete_move(&desc, cfg->vector);
+ __irq_complete_move(cfg, cfg->vector);
}
#else
-static inline void irq_complete_move(struct irq_desc **descp) {}
+static inline void irq_complete_move(struct irq_cfg *cfg) { }
#endif
-static void ack_apic_edge(unsigned int irq)
+static void ack_apic_edge(struct irq_data *data)
{
- struct irq_desc *desc = irq_to_desc(irq);
-
- irq_complete_move(&desc);
- move_native_irq(irq);
+ irq_complete_move(data->chip_data);
+ move_native_irq(data->irq);
ack_APIC_irq();
}
@@ -2567,10 +2400,12 @@ atomic_t irq_mis_count;
* Otherwise, we simulate the EOI message manually by changing the trigger
* mode to edge and then back to level, with RTE being masked during this.
*/
-static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg)
+static void eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg)
{
struct irq_pin_list *entry;
+ unsigned long flags;
+ raw_spin_lock_irqsave(&ioapic_lock, flags);
for_each_irq_pin(entry, cfg->irq_2_pin) {
if (mp_ioapics[entry->apic].apicver >= 0x20) {
/*
@@ -2579,7 +2414,7 @@ static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg)
* intr-remapping table entry. Hence for the io-apic
* EOI we use the pin number.
*/
- if (irq_remapped(irq))
+ if (irq_remapped(cfg))
io_apic_eoi(entry->apic, entry->pin);
else
io_apic_eoi(entry->apic, cfg->vector);
@@ -2588,36 +2423,22 @@ static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg)
__unmask_and_level_IO_APIC_irq(entry);
}
}
-}
-
-static void eoi_ioapic_irq(struct irq_desc *desc)
-{
- struct irq_cfg *cfg;
- unsigned long flags;
- unsigned int irq;
-
- irq = desc->irq;
- cfg = desc->chip_data;
-
- raw_spin_lock_irqsave(&ioapic_lock, flags);
- __eoi_ioapic_irq(irq, cfg);
raw_spin_unlock_irqrestore(&ioapic_lock, flags);
}
-static void ack_apic_level(unsigned int irq)
+static void ack_apic_level(struct irq_data *data)
{
+ struct irq_cfg *cfg = data->chip_data;
+ int i, do_unmask_irq = 0, irq = data->irq;
struct irq_desc *desc = irq_to_desc(irq);
unsigned long v;
- int i;
- struct irq_cfg *cfg;
- int do_unmask_irq = 0;
- irq_complete_move(&desc);
+ irq_complete_move(cfg);
#ifdef CONFIG_GENERIC_PENDING_IRQ
/* If we are moving the irq we need to mask it */
if (unlikely(desc->status & IRQ_MOVE_PENDING)) {
do_unmask_irq = 1;
- mask_IO_APIC_irq_desc(desc);
+ mask_ioapic(cfg);
}
#endif
@@ -2653,7 +2474,6 @@ static void ack_apic_level(unsigned int irq)
* we use the above logic (mask+edge followed by unmask+level) from
* Manfred Spraul to clear the remote IRR.
*/
- cfg = desc->chip_data;
i = cfg->vector;
v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1));
@@ -2673,7 +2493,7 @@ static void ack_apic_level(unsigned int irq)
if (!(v & (1 << (i & 0x1f)))) {
atomic_inc(&irq_mis_count);
- eoi_ioapic_irq(desc);
+ eoi_ioapic_irq(irq, cfg);
}
/* Now we can move and renable the irq */
@@ -2704,61 +2524,57 @@ static void ack_apic_level(unsigned int irq)
* accurate and is causing problems then it is a hardware bug
* and you can go talk to the chipset vendor about it.
*/
- cfg = desc->chip_data;
if (!io_apic_level_ack_pending(cfg))
move_masked_irq(irq);
- unmask_IO_APIC_irq_desc(desc);
+ unmask_ioapic(cfg);
}
}
#ifdef CONFIG_INTR_REMAP
-static void ir_ack_apic_edge(unsigned int irq)
+static void ir_ack_apic_edge(struct irq_data *data)
{
ack_APIC_irq();
}
-static void ir_ack_apic_level(unsigned int irq)
+static void ir_ack_apic_level(struct irq_data *data)
{
- struct irq_desc *desc = irq_to_desc(irq);
-
ack_APIC_irq();
- eoi_ioapic_irq(desc);
+ eoi_ioapic_irq(data->irq, data->chip_data);
}
#endif /* CONFIG_INTR_REMAP */
static struct irq_chip ioapic_chip __read_mostly = {
- .name = "IO-APIC",
- .startup = startup_ioapic_irq,
- .mask = mask_IO_APIC_irq,
- .unmask = unmask_IO_APIC_irq,
- .ack = ack_apic_edge,
- .eoi = ack_apic_level,
+ .name = "IO-APIC",
+ .irq_startup = startup_ioapic_irq,
+ .irq_mask = mask_ioapic_irq,
+ .irq_unmask = unmask_ioapic_irq,
+ .irq_ack = ack_apic_edge,
+ .irq_eoi = ack_apic_level,
#ifdef CONFIG_SMP
- .set_affinity = set_ioapic_affinity_irq,
+ .irq_set_affinity = ioapic_set_affinity,
#endif
- .retrigger = ioapic_retrigger_irq,
+ .irq_retrigger = ioapic_retrigger_irq,
};
static struct irq_chip ir_ioapic_chip __read_mostly = {
- .name = "IR-IO-APIC",
- .startup = startup_ioapic_irq,
- .mask = mask_IO_APIC_irq,
- .unmask = unmask_IO_APIC_irq,
+ .name = "IR-IO-APIC",
+ .irq_startup = startup_ioapic_irq,
+ .irq_mask = mask_ioapic_irq,
+ .irq_unmask = unmask_ioapic_irq,
#ifdef CONFIG_INTR_REMAP
- .ack = ir_ack_apic_edge,
- .eoi = ir_ack_apic_level,
+ .irq_ack = ir_ack_apic_edge,
+ .irq_eoi = ir_ack_apic_level,
#ifdef CONFIG_SMP
- .set_affinity = set_ir_ioapic_affinity_irq,
+ .irq_set_affinity = ir_ioapic_set_affinity,
#endif
#endif
- .retrigger = ioapic_retrigger_irq,
+ .irq_retrigger = ioapic_retrigger_irq,
};
static inline void init_IO_APIC_traps(void)
{
- int irq;
- struct irq_desc *desc;
struct irq_cfg *cfg;
+ unsigned int irq;
/*
* NOTE! The local APIC isn't very good at handling
@@ -2771,8 +2587,8 @@ static inline void init_IO_APIC_traps(void)
* Also, we've got to be careful not to trash gate
* 0x80, because int 0x80 is hm, kind of importantish. ;)
*/
- for_each_irq_desc(irq, desc) {
- cfg = desc->chip_data;
+ for_each_active_irq(irq) {
+ cfg = get_irq_chip_data(irq);
if (IO_APIC_IRQ(irq) && cfg && !cfg->vector) {
/*
* Hmm.. We don't have an entry for this,
@@ -2783,7 +2599,7 @@ static inline void init_IO_APIC_traps(void)
legacy_pic->make_irq(irq);
else
/* Strange. Oh, well.. */
- desc->chip = &no_irq_chip;
+ set_irq_chip(irq, &no_irq_chip);
}
}
}
@@ -2792,7 +2608,7 @@ static inline void init_IO_APIC_traps(void)
* The local APIC irq-chip implementation:
*/
-static void mask_lapic_irq(unsigned int irq)
+static void mask_lapic_irq(struct irq_data *data)
{
unsigned long v;
@@ -2800,7 +2616,7 @@ static void mask_lapic_irq(unsigned int irq)
apic_write(APIC_LVT0, v | APIC_LVT_MASKED);
}
-static void unmask_lapic_irq(unsigned int irq)
+static void unmask_lapic_irq(struct irq_data *data)
{
unsigned long v;
@@ -2808,21 +2624,21 @@ static void unmask_lapic_irq(unsigned int irq)
apic_write(APIC_LVT0, v & ~APIC_LVT_MASKED);
}
-static void ack_lapic_irq(unsigned int irq)
+static void ack_lapic_irq(struct irq_data *data)
{
ack_APIC_irq();
}
static struct irq_chip lapic_chip __read_mostly = {
.name = "local-APIC",
- .mask = mask_lapic_irq,
- .unmask = unmask_lapic_irq,
- .ack = ack_lapic_irq,
+ .irq_mask = mask_lapic_irq,
+ .irq_unmask = unmask_lapic_irq,
+ .irq_ack = ack_lapic_irq,
};
-static void lapic_register_intr(int irq, struct irq_desc *desc)
+static void lapic_register_intr(int irq)
{
- desc->status &= ~IRQ_LEVEL;
+ irq_clear_status_flags(irq, IRQ_LEVEL);
set_irq_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq,
"edge");
}
@@ -2925,9 +2741,8 @@ int timer_through_8259 __initdata;
*/
static inline void __init check_timer(void)
{
- struct irq_desc *desc = irq_to_desc(0);
- struct irq_cfg *cfg = desc->chip_data;
- int node = cpu_to_node(boot_cpu_id);
+ struct irq_cfg *cfg = get_irq_chip_data(0);
+ int node = cpu_to_node(0);
int apic1, pin1, apic2, pin2;
unsigned long flags;
int no_pin1 = 0;
@@ -2937,7 +2752,7 @@ static inline void __init check_timer(void)
/*
* get/set the timer IRQ vector:
*/
- legacy_pic->chip->mask(0);
+ legacy_pic->mask(0);
assign_irq_vector(0, cfg, apic->target_cpus());
/*
@@ -2996,7 +2811,7 @@ static inline void __init check_timer(void)
add_pin_to_irq_node(cfg, node, apic1, pin1);
setup_timer_IRQ0_pin(apic1, pin1, cfg->vector);
} else {
- /* for edge trigger, setup_IO_APIC_irq already
+ /* for edge trigger, setup_ioapic_irq already
* leave it unmasked.
* so only need to unmask if it is level-trigger
* do we really have level trigger timer?
@@ -3004,12 +2819,12 @@ static inline void __init check_timer(void)
int idx;
idx = find_irq_entry(apic1, pin1, mp_INT);
if (idx != -1 && irq_trigger(idx))
- unmask_IO_APIC_irq_desc(desc);
+ unmask_ioapic(cfg);
}
if (timer_irq_works()) {
if (nmi_watchdog == NMI_IO_APIC) {
setup_nmi();
- legacy_pic->chip->unmask(0);
+ legacy_pic->unmask(0);
}
if (disable_timer_pin_1 > 0)
clear_IO_APIC_pin(0, pin1);
@@ -3032,14 +2847,14 @@ static inline void __init check_timer(void)
*/
replace_pin_at_irq_node(cfg, node, apic1, pin1, apic2, pin2);
setup_timer_IRQ0_pin(apic2, pin2, cfg->vector);
- legacy_pic->chip->unmask(0);
+ legacy_pic->unmask(0);
if (timer_irq_works()) {
apic_printk(APIC_QUIET, KERN_INFO "....... works.\n");
timer_through_8259 = 1;
if (nmi_watchdog == NMI_IO_APIC) {
- legacy_pic->chip->mask(0);
+ legacy_pic->mask(0);
setup_nmi();
- legacy_pic->chip->unmask(0);
+ legacy_pic->unmask(0);
}
goto out;
}
@@ -3047,7 +2862,7 @@ static inline void __init check_timer(void)
* Cleanup, just in case ...
*/
local_irq_disable();
- legacy_pic->chip->mask(0);
+ legacy_pic->mask(0);
clear_IO_APIC_pin(apic2, pin2);
apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n");
}
@@ -3064,16 +2879,16 @@ static inline void __init check_timer(void)
apic_printk(APIC_QUIET, KERN_INFO
"...trying to set up timer as Virtual Wire IRQ...\n");
- lapic_register_intr(0, desc);
+ lapic_register_intr(0);
apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector); /* Fixed mode */
- legacy_pic->chip->unmask(0);
+ legacy_pic->unmask(0);
if (timer_irq_works()) {
apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
goto out;
}
local_irq_disable();
- legacy_pic->chip->mask(0);
+ legacy_pic->mask(0);
apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector);
apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n");
@@ -3239,49 +3054,42 @@ device_initcall(ioapic_init_sysfs);
/*
* Dynamic irq allocate and deallocation
*/
-unsigned int create_irq_nr(unsigned int irq_want, int node)
+unsigned int create_irq_nr(unsigned int from, int node)
{
- /* Allocate an unused irq */
- unsigned int irq;
- unsigned int new;
+ struct irq_cfg *cfg;
unsigned long flags;
- struct irq_cfg *cfg_new = NULL;
- struct irq_desc *desc_new = NULL;
-
- irq = 0;
- if (irq_want < nr_irqs_gsi)
- irq_want = nr_irqs_gsi;
-
- raw_spin_lock_irqsave(&vector_lock, flags);
- for (new = irq_want; new < nr_irqs; new++) {
- desc_new = irq_to_desc_alloc_node(new, node);
- if (!desc_new) {
- printk(KERN_INFO "can not get irq_desc for %d\n", new);
- continue;
- }
- cfg_new = desc_new->chip_data;
-
- if (cfg_new->vector != 0)
- continue;
+ unsigned int ret = 0;
+ int irq;
- desc_new = move_irq_desc(desc_new, node);
- cfg_new = desc_new->chip_data;
+ if (from < nr_irqs_gsi)
+ from = nr_irqs_gsi;
- if (__assign_irq_vector(new, cfg_new, apic->target_cpus()) == 0)
- irq = new;
- break;
+ irq = alloc_irq_from(from, node);
+ if (irq < 0)
+ return 0;
+ cfg = alloc_irq_cfg(irq, node);
+ if (!cfg) {
+ free_irq_at(irq, NULL);
+ return 0;
}
- raw_spin_unlock_irqrestore(&vector_lock, flags);
- if (irq > 0)
- dynamic_irq_init_keep_chip_data(irq);
+ raw_spin_lock_irqsave(&vector_lock, flags);
+ if (!__assign_irq_vector(irq, cfg, apic->target_cpus()))
+ ret = irq;
+ raw_spin_unlock_irqrestore(&vector_lock, flags);
- return irq;
+ if (ret) {
+ set_irq_chip_data(irq, cfg);
+ irq_clear_status_flags(irq, IRQ_NOREQUEST);
+ } else {
+ free_irq_at(irq, cfg);
+ }
+ return ret;
}
int create_irq(void)
{
- int node = cpu_to_node(boot_cpu_id);
+ int node = cpu_to_node(0);
unsigned int irq_want;
int irq;
@@ -3296,14 +3104,17 @@ int create_irq(void)
void destroy_irq(unsigned int irq)
{
+ struct irq_cfg *cfg = get_irq_chip_data(irq);
unsigned long flags;
- dynamic_irq_cleanup_keep_chip_data(irq);
+ irq_set_status_flags(irq, IRQ_NOREQUEST|IRQ_NOPROBE);
- free_irte(irq);
+ if (intr_remapping_enabled)
+ free_irte(irq);
raw_spin_lock_irqsave(&vector_lock, flags);
- __clear_irq_vector(irq, get_irq_chip_data(irq));
+ __clear_irq_vector(irq, cfg);
raw_spin_unlock_irqrestore(&vector_lock, flags);
+ free_irq_at(irq, cfg);
}
/*
@@ -3327,7 +3138,7 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq,
dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus());
- if (irq_remapped(irq)) {
+ if (irq_remapped(get_irq_chip_data(irq))) {
struct irte irte;
int ir_index;
u16 sub_handle;
@@ -3335,14 +3146,7 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq,
ir_index = map_irq_to_irte_handle(irq, &sub_handle);
BUG_ON(ir_index == -1);
- memset (&irte, 0, sizeof(irte));
-
- irte.present = 1;
- irte.dst_mode = apic->irq_dest_mode;
- irte.trigger_mode = 0; /* edge */
- irte.dlvry_mode = apic->irq_delivery_mode;
- irte.vector = cfg->vector;
- irte.dest_id = IRTE_DEST(dest);
+ prepare_irte(&irte, cfg->vector, dest);
/* Set source-id of interrupt request */
if (pdev)
@@ -3387,26 +3191,24 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq,
}
#ifdef CONFIG_SMP
-static int set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
+static int
+msi_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force)
{
- struct irq_desc *desc = irq_to_desc(irq);
- struct irq_cfg *cfg;
+ struct irq_cfg *cfg = data->chip_data;
struct msi_msg msg;
unsigned int dest;
- if (set_desc_affinity(desc, mask, &dest))
+ if (__ioapic_set_affinity(data, mask, &dest))
return -1;
- cfg = desc->chip_data;
-
- get_cached_msi_msg_desc(desc, &msg);
+ __get_cached_msi_msg(data->msi_desc, &msg);
msg.data &= ~MSI_DATA_VECTOR_MASK;
msg.data |= MSI_DATA_VECTOR(cfg->vector);
msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
msg.address_lo |= MSI_ADDR_DEST_ID(dest);
- write_msi_msg_desc(desc, &msg);
+ __write_msi_msg(data->msi_desc, &msg);
return 0;
}
@@ -3416,17 +3218,17 @@ static int set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
* done in the process context using interrupt-remapping hardware.
*/
static int
-ir_set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
+ir_msi_set_affinity(struct irq_data *data, const struct cpumask *mask,
+ bool force)
{
- struct irq_desc *desc = irq_to_desc(irq);
- struct irq_cfg *cfg = desc->chip_data;
- unsigned int dest;
+ struct irq_cfg *cfg = data->chip_data;
+ unsigned int dest, irq = data->irq;
struct irte irte;
if (get_irte(irq, &irte))
return -1;
- if (set_desc_affinity(desc, mask, &dest))
+ if (__ioapic_set_affinity(data, mask, &dest))
return -1;
irte.vector = cfg->vector;
@@ -3456,27 +3258,27 @@ ir_set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
* which implement the MSI or MSI-X Capability Structure.
*/
static struct irq_chip msi_chip = {
- .name = "PCI-MSI",
- .unmask = unmask_msi_irq,
- .mask = mask_msi_irq,
- .ack = ack_apic_edge,
+ .name = "PCI-MSI",
+ .irq_unmask = unmask_msi_irq,
+ .irq_mask = mask_msi_irq,
+ .irq_ack = ack_apic_edge,
#ifdef CONFIG_SMP
- .set_affinity = set_msi_irq_affinity,
+ .irq_set_affinity = msi_set_affinity,
#endif
- .retrigger = ioapic_retrigger_irq,
+ .irq_retrigger = ioapic_retrigger_irq,
};
static struct irq_chip msi_ir_chip = {
- .name = "IR-PCI-MSI",
- .unmask = unmask_msi_irq,
- .mask = mask_msi_irq,
+ .name = "IR-PCI-MSI",
+ .irq_unmask = unmask_msi_irq,
+ .irq_mask = mask_msi_irq,
#ifdef CONFIG_INTR_REMAP
- .ack = ir_ack_apic_edge,
+ .irq_ack = ir_ack_apic_edge,
#ifdef CONFIG_SMP
- .set_affinity = ir_set_msi_irq_affinity,
+ .irq_set_affinity = ir_msi_set_affinity,
#endif
#endif
- .retrigger = ioapic_retrigger_irq,
+ .irq_retrigger = ioapic_retrigger_irq,
};
/*
@@ -3508,8 +3310,8 @@ static int msi_alloc_irte(struct pci_dev *dev, int irq, int nvec)
static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq)
{
- int ret;
struct msi_msg msg;
+ int ret;
ret = msi_compose_msg(dev, irq, &msg, -1);
if (ret < 0)
@@ -3518,12 +3320,8 @@ static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq)
set_irq_msi(irq, msidesc);
write_msi_msg(irq, &msg);
- if (irq_remapped(irq)) {
- struct irq_desc *desc = irq_to_desc(irq);
- /*
- * irq migration in process context
- */
- desc->status |= IRQ_MOVE_PCNTXT;
+ if (irq_remapped(get_irq_chip_data(irq))) {
+ irq_set_status_flags(irq, IRQ_MOVE_PCNTXT);
set_irq_chip_and_handler_name(irq, &msi_ir_chip, handle_edge_irq, "edge");
} else
set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge");
@@ -3535,13 +3333,10 @@ static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq)
int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
{
- unsigned int irq;
- int ret, sub_handle;
+ int node, ret, sub_handle, index = 0;
+ unsigned int irq, irq_want;
struct msi_desc *msidesc;
- unsigned int irq_want;
struct intel_iommu *iommu = NULL;
- int index = 0;
- int node;
/* x86 doesn't support multiple MSI yet */
if (type == PCI_CAP_ID_MSI && nvec > 1)
@@ -3601,18 +3396,17 @@ void arch_teardown_msi_irq(unsigned int irq)
#if defined (CONFIG_DMAR) || defined (CONFIG_INTR_REMAP)
#ifdef CONFIG_SMP
-static int dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
+static int
+dmar_msi_set_affinity(struct irq_data *data, const struct cpumask *mask,
+ bool force)
{
- struct irq_desc *desc = irq_to_desc(irq);
- struct irq_cfg *cfg;
+ struct irq_cfg *cfg = data->chip_data;
+ unsigned int dest, irq = data->irq;
struct msi_msg msg;
- unsigned int dest;
- if (set_desc_affinity(desc, mask, &dest))
+ if (__ioapic_set_affinity(data, mask, &dest))
return -1;
- cfg = desc->chip_data;
-
dmar_msi_read(irq, &msg);
msg.data &= ~MSI_DATA_VECTOR_MASK;
@@ -3628,14 +3422,14 @@ static int dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
#endif /* CONFIG_SMP */
static struct irq_chip dmar_msi_type = {
- .name = "DMAR_MSI",
- .unmask = dmar_msi_unmask,
- .mask = dmar_msi_mask,
- .ack = ack_apic_edge,
+ .name = "DMAR_MSI",
+ .irq_unmask = dmar_msi_unmask,
+ .irq_mask = dmar_msi_mask,
+ .irq_ack = ack_apic_edge,
#ifdef CONFIG_SMP
- .set_affinity = dmar_msi_set_affinity,
+ .irq_set_affinity = dmar_msi_set_affinity,
#endif
- .retrigger = ioapic_retrigger_irq,
+ .irq_retrigger = ioapic_retrigger_irq,
};
int arch_setup_dmar_msi(unsigned int irq)
@@ -3656,26 +3450,24 @@ int arch_setup_dmar_msi(unsigned int irq)
#ifdef CONFIG_HPET_TIMER
#ifdef CONFIG_SMP
-static int hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
+static int hpet_msi_set_affinity(struct irq_data *data,
+ const struct cpumask *mask, bool force)
{
- struct irq_desc *desc = irq_to_desc(irq);
- struct irq_cfg *cfg;
+ struct irq_cfg *cfg = data->chip_data;
struct msi_msg msg;
unsigned int dest;
- if (set_desc_affinity(desc, mask, &dest))
+ if (__ioapic_set_affinity(data, mask, &dest))
return -1;
- cfg = desc->chip_data;
-
- hpet_msi_read(irq, &msg);
+ hpet_msi_read(data->handler_data, &msg);
msg.data &= ~MSI_DATA_VECTOR_MASK;
msg.data |= MSI_DATA_VECTOR(cfg->vector);
msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
msg.address_lo |= MSI_ADDR_DEST_ID(dest);
- hpet_msi_write(irq, &msg);
+ hpet_msi_write(data->handler_data, &msg);
return 0;
}
@@ -3683,34 +3475,33 @@ static int hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
#endif /* CONFIG_SMP */
static struct irq_chip ir_hpet_msi_type = {
- .name = "IR-HPET_MSI",
- .unmask = hpet_msi_unmask,
- .mask = hpet_msi_mask,
+ .name = "IR-HPET_MSI",
+ .irq_unmask = hpet_msi_unmask,
+ .irq_mask = hpet_msi_mask,
#ifdef CONFIG_INTR_REMAP
- .ack = ir_ack_apic_edge,
+ .irq_ack = ir_ack_apic_edge,
#ifdef CONFIG_SMP
- .set_affinity = ir_set_msi_irq_affinity,
+ .irq_set_affinity = ir_msi_set_affinity,
#endif
#endif
- .retrigger = ioapic_retrigger_irq,
+ .irq_retrigger = ioapic_retrigger_irq,
};
static struct irq_chip hpet_msi_type = {
.name = "HPET_MSI",
- .unmask = hpet_msi_unmask,
- .mask = hpet_msi_mask,
- .ack = ack_apic_edge,
+ .irq_unmask = hpet_msi_unmask,
+ .irq_mask = hpet_msi_mask,
+ .irq_ack = ack_apic_edge,
#ifdef CONFIG_SMP
- .set_affinity = hpet_msi_set_affinity,
+ .irq_set_affinity = hpet_msi_set_affinity,
#endif
- .retrigger = ioapic_retrigger_irq,
+ .irq_retrigger = ioapic_retrigger_irq,
};
int arch_setup_hpet_msi(unsigned int irq, unsigned int id)
{
- int ret;
struct msi_msg msg;
- struct irq_desc *desc = irq_to_desc(irq);
+ int ret;
if (intr_remapping_enabled) {
struct intel_iommu *iommu = map_hpet_to_ir(id);
@@ -3728,9 +3519,9 @@ int arch_setup_hpet_msi(unsigned int irq, unsigned int id)
if (ret < 0)
return ret;
- hpet_msi_write(irq, &msg);
- desc->status |= IRQ_MOVE_PCNTXT;
- if (irq_remapped(irq))
+ hpet_msi_write(get_irq_data(irq), &msg);
+ irq_set_status_flags(irq, IRQ_MOVE_PCNTXT);
+ if (irq_remapped(get_irq_chip_data(irq)))
set_irq_chip_and_handler_name(irq, &ir_hpet_msi_type,
handle_edge_irq, "edge");
else
@@ -3763,33 +3554,30 @@ static void target_ht_irq(unsigned int irq, unsigned int dest, u8 vector)
write_ht_irq_msg(irq, &msg);
}
-static int set_ht_irq_affinity(unsigned int irq, const struct cpumask *mask)
+static int
+ht_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force)
{
- struct irq_desc *desc = irq_to_desc(irq);
- struct irq_cfg *cfg;
+ struct irq_cfg *cfg = data->chip_data;
unsigned int dest;
- if (set_desc_affinity(desc, mask, &dest))
+ if (__ioapic_set_affinity(data, mask, &dest))
return -1;
- cfg = desc->chip_data;
-
- target_ht_irq(irq, dest, cfg->vector);
-
+ target_ht_irq(data->irq, dest, cfg->vector);
return 0;
}
#endif
static struct irq_chip ht_irq_chip = {
- .name = "PCI-HT",
- .mask = mask_ht_irq,
- .unmask = unmask_ht_irq,
- .ack = ack_apic_edge,
+ .name = "PCI-HT",
+ .irq_mask = mask_ht_irq,
+ .irq_unmask = unmask_ht_irq,
+ .irq_ack = ack_apic_edge,
#ifdef CONFIG_SMP
- .set_affinity = set_ht_irq_affinity,
+ .irq_set_affinity = ht_set_affinity,
#endif
- .retrigger = ioapic_retrigger_irq,
+ .irq_retrigger = ioapic_retrigger_irq,
};
int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
@@ -3880,14 +3668,13 @@ int __init arch_probe_nr_irqs(void)
if (nr < nr_irqs)
nr_irqs = nr;
- return 0;
+ return NR_IRQS_LEGACY;
}
#endif
static int __io_apic_set_pci_routing(struct device *dev, int irq,
struct io_apic_irq_attr *irq_attr)
{
- struct irq_desc *desc;
struct irq_cfg *cfg;
int node;
int ioapic, pin;
@@ -3903,13 +3690,11 @@ static int __io_apic_set_pci_routing(struct device *dev, int irq,
if (dev)
node = dev_to_node(dev);
else
- node = cpu_to_node(boot_cpu_id);
+ node = cpu_to_node(0);
- desc = irq_to_desc_alloc_node(irq, node);
- if (!desc) {
- printk(KERN_INFO "can not get irq_desc %d\n", irq);
+ cfg = alloc_irq_and_cfg_at(irq, node);
+ if (!cfg)
return 0;
- }
pin = irq_attr->ioapic_pin;
trigger = irq_attr->trigger;
@@ -3919,15 +3704,14 @@ static int __io_apic_set_pci_routing(struct device *dev, int irq,
* IRQs < 16 are already in the irq_2_pin[] map
*/
if (irq >= legacy_pic->nr_legacy_irqs) {
- cfg = desc->chip_data;
- if (add_pin_to_irq_node_nopanic(cfg, node, ioapic, pin)) {
+ if (__add_pin_to_irq_node(cfg, node, ioapic, pin)) {
printk(KERN_INFO "can not add pin %d for irq %d\n",
pin, irq);
return 0;
}
}
- setup_IO_APIC_irq(ioapic, pin, irq, desc, trigger, polarity);
+ setup_ioapic_irq(ioapic, pin, irq, cfg, trigger, polarity);
return 0;
}
@@ -4120,14 +3904,14 @@ void __init setup_ioapic_dest(void)
*/
if (desc->status &
(IRQ_NO_BALANCING | IRQ_AFFINITY_SET))
- mask = desc->affinity;
+ mask = desc->irq_data.affinity;
else
mask = apic->target_cpus();
if (intr_remapping_enabled)
- set_ir_ioapic_affinity_irq_desc(desc, mask);
+ ir_ioapic_set_affinity(&desc->irq_data, mask, false);
else
- set_ioapic_affinity_irq_desc(desc, mask);
+ ioapic_set_affinity(&desc->irq_data, mask, false);
}
}
@@ -4311,19 +4095,18 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
void __init pre_init_apic_IRQ0(void)
{
struct irq_cfg *cfg;
- struct irq_desc *desc;
printk(KERN_INFO "Early APIC setup for system timer0\n");
#ifndef CONFIG_SMP
phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid);
#endif
- desc = irq_to_desc_alloc_node(0, 0);
+ /* Make sure the irq descriptor is set up */
+ cfg = alloc_irq_and_cfg_at(0, 0);
setup_local_APIC();
- cfg = irq_cfg(0);
add_pin_to_irq_node(cfg, 0, 0, 0);
set_irq_chip_and_handler_name(0, &ioapic_chip, handle_edge_irq, "edge");
- setup_IO_APIC_irq(0, 0, 0, desc, 0, 0);
+ setup_ioapic_irq(0, 0, 0, cfg, 0, 0);
}
diff --git a/arch/x86/kernel/apic/nmi.c b/arch/x86/kernel/apic/nmi.c
index a43f71cb30f8..c90041ccb742 100644
--- a/arch/x86/kernel/apic/nmi.c
+++ b/arch/x86/kernel/apic/nmi.c
@@ -178,7 +178,7 @@ int __init check_nmi_watchdog(void)
error:
if (nmi_watchdog == NMI_IO_APIC) {
if (!timer_through_8259)
- legacy_pic->chip->mask(0);
+ legacy_pic->mask(0);
on_each_cpu(__acpi_nmi_disable, NULL, 1);
}
diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c
index 3e28401f161c..960f26ab5c9f 100644
--- a/arch/x86/kernel/apic/numaq_32.c
+++ b/arch/x86/kernel/apic/numaq_32.c
@@ -26,6 +26,7 @@
#include <linux/nodemask.h>
#include <linux/topology.h>
#include <linux/bootmem.h>
+#include <linux/memblock.h>
#include <linux/threads.h>
#include <linux/cpumask.h>
#include <linux/kernel.h>
@@ -88,7 +89,7 @@ static inline void numaq_register_node(int node, struct sys_cfg_data *scd)
node_end_pfn[node] =
MB_TO_PAGES(eq->hi_shrd_mem_start + eq->hi_shrd_mem_size);
- e820_register_active_regions(node, node_start_pfn[node],
+ memblock_x86_register_active_regions(node, node_start_pfn[node],
node_end_pfn[node]);
memory_present(node, node_start_pfn[node], node_end_pfn[node]);
diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c
index 83e9be4778e2..f9e4e6a54073 100644
--- a/arch/x86/kernel/apic/probe_64.c
+++ b/arch/x86/kernel/apic/probe_64.c
@@ -54,6 +54,9 @@ static int apicid_phys_pkg_id(int initial_apic_id, int index_msb)
*/
void __init default_setup_apic_routing(void)
{
+
+ enable_IR_x2apic();
+
#ifdef CONFIG_X86_X2APIC
if (x2apic_mode
#ifdef CONFIG_X86_UV
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index 4c9c67bf09b7..0e4f24c2a746 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -189,8 +189,8 @@
* Intel Order Number 241704-001. Microsoft Part Number 781-110-X01.
*
* [This document is available free from Intel by calling 800.628.8686 (fax
- * 916.356.6100) or 800.548.4725; or via anonymous ftp from
- * ftp://ftp.intel.com/pub/IAL/software_specs/apmv11.doc. It is also
+ * 916.356.6100) or 800.548.4725; or from
+ * http://www.microsoft.com/whdc/archive/amp_12.mspx It is also
* available from Microsoft by calling 206.882.8080.]
*
* APM 1.2 Reference:
@@ -1926,6 +1926,7 @@ static const struct file_operations apm_bios_fops = {
.unlocked_ioctl = do_ioctl,
.open = do_open,
.release = do_release,
+ .llseek = noop_llseek,
};
static struct miscdevice apm_device = {
diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c
index dfdbf6403895..1a4088dda37a 100644
--- a/arch/x86/kernel/asm-offsets_32.c
+++ b/arch/x86/kernel/asm-offsets_32.c
@@ -99,9 +99,7 @@ void foo(void)
DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
DEFINE(PAGE_SHIFT_asm, PAGE_SHIFT);
- DEFINE(PTRS_PER_PTE, PTRS_PER_PTE);
- DEFINE(PTRS_PER_PMD, PTRS_PER_PMD);
- DEFINE(PTRS_PER_PGD, PTRS_PER_PGD);
+ DEFINE(THREAD_SIZE_asm, THREAD_SIZE);
OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx);
diff --git a/arch/x86/kernel/check.c b/arch/x86/kernel/check.c
index fc999e6fc46a..13a389179514 100644
--- a/arch/x86/kernel/check.c
+++ b/arch/x86/kernel/check.c
@@ -2,7 +2,8 @@
#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/workqueue.h>
-#include <asm/e820.h>
+#include <linux/memblock.h>
+
#include <asm/proto.h>
/*
@@ -18,10 +19,12 @@ static int __read_mostly memory_corruption_check = -1;
static unsigned __read_mostly corruption_check_size = 64*1024;
static unsigned __read_mostly corruption_check_period = 60; /* seconds */
-static struct e820entry scan_areas[MAX_SCAN_AREAS];
+static struct scan_area {
+ u64 addr;
+ u64 size;
+} scan_areas[MAX_SCAN_AREAS];
static int num_scan_areas;
-
static __init int set_corruption_check(char *arg)
{
char *end;
@@ -81,9 +84,9 @@ void __init setup_bios_corruption_check(void)
while (addr < corruption_check_size && num_scan_areas < MAX_SCAN_AREAS) {
u64 size;
- addr = find_e820_area_size(addr, &size, PAGE_SIZE);
+ addr = memblock_x86_find_in_range_size(addr, &size, PAGE_SIZE);
- if (!(addr + 1))
+ if (addr == MEMBLOCK_ERROR)
break;
if (addr >= corruption_check_size)
@@ -92,7 +95,7 @@ void __init setup_bios_corruption_check(void)
if ((addr + size) > corruption_check_size)
size = corruption_check_size - addr;
- e820_update_range(addr, size, E820_RAM, E820_RESERVED);
+ memblock_x86_reserve_range(addr, addr + size, "SCAN RAM");
scan_areas[num_scan_areas].addr = addr;
scan_areas[num_scan_areas].size = size;
num_scan_areas++;
@@ -105,7 +108,6 @@ void __init setup_bios_corruption_check(void)
printk(KERN_INFO "Scanning %d areas for low memory corruption\n",
num_scan_areas);
- update_e820();
}
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index ba5f62f45f01..9e093f8fe78c 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -148,7 +148,7 @@ static void __cpuinit amd_k7_smp_check(struct cpuinfo_x86 *c)
{
#ifdef CONFIG_SMP
/* calling is from identify_secondary_cpu() ? */
- if (c->cpu_index == boot_cpu_id)
+ if (!c->cpu_index)
return;
/*
@@ -253,37 +253,51 @@ static int __cpuinit nearby_node(int apicid)
#endif
/*
- * Fixup core topology information for AMD multi-node processors.
- * Assumption: Number of cores in each internal node is the same.
+ * Fixup core topology information for
+ * (1) AMD multi-node processors
+ * Assumption: Number of cores in each internal node is the same.
+ * (2) AMD processors supporting compute units
*/
#ifdef CONFIG_X86_HT
-static void __cpuinit amd_fixup_dcm(struct cpuinfo_x86 *c)
+static void __cpuinit amd_get_topology(struct cpuinfo_x86 *c)
{
- unsigned long long value;
- u32 nodes, cores_per_node;
+ u32 nodes;
+ u8 node_id;
int cpu = smp_processor_id();
- if (!cpu_has(c, X86_FEATURE_NODEID_MSR))
- return;
+ /* get information required for multi-node processors */
+ if (cpu_has(c, X86_FEATURE_TOPOEXT)) {
+ u32 eax, ebx, ecx, edx;
- /* fixup topology information only once for a core */
- if (cpu_has(c, X86_FEATURE_AMD_DCM))
- return;
+ cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
+ nodes = ((ecx >> 8) & 7) + 1;
+ node_id = ecx & 7;
- rdmsrl(MSR_FAM10H_NODE_ID, value);
+ /* get compute unit information */
+ smp_num_siblings = ((ebx >> 8) & 3) + 1;
+ c->compute_unit_id = ebx & 0xff;
+ } else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) {
+ u64 value;
- nodes = ((value >> 3) & 7) + 1;
- if (nodes == 1)
+ rdmsrl(MSR_FAM10H_NODE_ID, value);
+ nodes = ((value >> 3) & 7) + 1;
+ node_id = value & 7;
+ } else
return;
- set_cpu_cap(c, X86_FEATURE_AMD_DCM);
- cores_per_node = c->x86_max_cores / nodes;
+ /* fixup multi-node processor information */
+ if (nodes > 1) {
+ u32 cores_per_node;
+
+ set_cpu_cap(c, X86_FEATURE_AMD_DCM);
+ cores_per_node = c->x86_max_cores / nodes;
- /* store NodeID, use llc_shared_map to store sibling info */
- per_cpu(cpu_llc_id, cpu) = value & 7;
+ /* store NodeID, use llc_shared_map to store sibling info */
+ per_cpu(cpu_llc_id, cpu) = node_id;
- /* fixup core id to be in range from 0 to (cores_per_node - 1) */
- c->cpu_core_id = c->cpu_core_id % cores_per_node;
+ /* core id to be in range from 0 to (cores_per_node - 1) */
+ c->cpu_core_id = c->cpu_core_id % cores_per_node;
+ }
}
#endif
@@ -304,9 +318,7 @@ static void __cpuinit amd_detect_cmp(struct cpuinfo_x86 *c)
c->phys_proc_id = c->initial_apicid >> bits;
/* use socket ID also for last level cache */
per_cpu(cpu_llc_id, cpu) = c->phys_proc_id;
- /* fixup topology information on multi-node processors */
- if ((c->x86 == 0x10) && (c->x86_model == 9))
- amd_fixup_dcm(c);
+ amd_get_topology(c);
#endif
}
@@ -412,6 +424,23 @@ static void __cpuinit early_init_amd(struct cpuinfo_x86 *c)
set_cpu_cap(c, X86_FEATURE_EXTD_APICID);
}
#endif
+
+ /* We need to do the following only once */
+ if (c != &boot_cpu_data)
+ return;
+
+ if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) {
+
+ if (c->x86 > 0x10 ||
+ (c->x86 == 0x10 && c->x86_model >= 0x2)) {
+ u64 val;
+
+ rdmsrl(MSR_K7_HWCR, val);
+ if (!(val & BIT(24)))
+ printk(KERN_WARNING FW_BUG "TSC doesn't count "
+ "with P0 frequency!\n");
+ }
+ }
}
static void __cpuinit init_amd(struct cpuinfo_x86 *c)
@@ -523,7 +552,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
#endif
if (c->extended_cpuid_level >= 0x80000006) {
- if ((c->x86 >= 0x0f) && (cpuid_edx(0x80000006) & 0xf000))
+ if (cpuid_edx(0x80000006) & 0xf000)
num_cache_leaves = 4;
else
num_cache_leaves = 3;
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 490dac63c2d2..4b68bda30938 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -545,7 +545,7 @@ void __cpuinit cpu_detect(struct cpuinfo_x86 *c)
}
}
-static void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c)
+void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c)
{
u32 tfms, xlvl;
u32 ebx;
@@ -665,7 +665,7 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c)
this_cpu->c_early_init(c);
#ifdef CONFIG_SMP
- c->cpu_index = boot_cpu_id;
+ c->cpu_index = 0;
#endif
filter_cpuid_features(c, false);
}
@@ -704,16 +704,21 @@ void __init early_cpu_init(void)
}
/*
- * The NOPL instruction is supposed to exist on all CPUs with
- * family >= 6; unfortunately, that's not true in practice because
- * of early VIA chips and (more importantly) broken virtualizers that
- * are not easy to detect. In the latter case it doesn't even *fail*
- * reliably, so probing for it doesn't even work. Disable it completely
+ * The NOPL instruction is supposed to exist on all CPUs of family >= 6;
+ * unfortunately, that's not true in practice because of early VIA
+ * chips and (more importantly) broken virtualizers that are not easy
+ * to detect. In the latter case it doesn't even *fail* reliably, so
+ * probing for it doesn't even work. Disable it completely on 32-bit
* unless we can find a reliable way to detect all the broken cases.
+ * Enable it explicitly on 64-bit for non-constant inputs of cpu_has().
*/
static void __cpuinit detect_nopl(struct cpuinfo_x86 *c)
{
+#ifdef CONFIG_X86_32
clear_cpu_cap(c, X86_FEATURE_NOPL);
+#else
+ set_cpu_cap(c, X86_FEATURE_NOPL);
+#endif
}
static void __cpuinit generic_identify(struct cpuinfo_x86 *c)
@@ -1264,13 +1269,6 @@ void __cpuinit cpu_init(void)
clear_all_debug_regs();
dbg_restore_debug_regs();
- /*
- * Force FPU initialization:
- */
- current_thread_info()->status = 0;
- clear_used_math();
- mxcsr_feature_mask_init();
-
fpu_init();
xsave_init();
}
diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h
index 3624e8a0f71b..e765633f210e 100644
--- a/arch/x86/kernel/cpu/cpu.h
+++ b/arch/x86/kernel/cpu/cpu.h
@@ -32,6 +32,8 @@ struct cpu_dev {
extern const struct cpu_dev *const __x86_cpu_dev_start[],
*const __x86_cpu_dev_end[];
+extern void get_cpu_cap(struct cpuinfo_x86 *c);
extern void cpu_detect_cache_sizes(struct cpuinfo_x86 *c);
+extern void get_cpu_cap(struct cpuinfo_x86 *c);
#endif
diff --git a/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c
index 994230d4dc4e..4f6f679f2799 100644
--- a/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c
+++ b/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c
@@ -368,16 +368,22 @@ static int __init pcc_cpufreq_do_osc(acpi_handle *handle)
return -ENODEV;
out_obj = output.pointer;
- if (out_obj->type != ACPI_TYPE_BUFFER)
- return -ENODEV;
+ if (out_obj->type != ACPI_TYPE_BUFFER) {
+ ret = -ENODEV;
+ goto out_free;
+ }
errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
- if (errors)
- return -ENODEV;
+ if (errors) {
+ ret = -ENODEV;
+ goto out_free;
+ }
supported = *((u32 *)(out_obj->buffer.pointer + 4));
- if (!(supported & 0x1))
- return -ENODEV;
+ if (!(supported & 0x1)) {
+ ret = -ENODEV;
+ goto out_free;
+ }
out_free:
kfree(output.pointer);
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 85f69cdeae10..d16c2c53d6bf 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -39,6 +39,7 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
misc_enable &= ~MSR_IA32_MISC_ENABLE_LIMIT_CPUID;
wrmsrl(MSR_IA32_MISC_ENABLE, misc_enable);
c->cpuid_level = cpuid_eax(0);
+ get_cpu_cap(c);
}
}
@@ -169,7 +170,7 @@ static void __cpuinit intel_smp_check(struct cpuinfo_x86 *c)
{
#ifdef CONFIG_SMP
/* calling is from identify_secondary_cpu() ? */
- if (c->cpu_index == boot_cpu_id)
+ if (!c->cpu_index)
return;
/*
@@ -283,9 +284,7 @@ static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c)
/* Don't do the funky fallback heuristics the AMD version employs
for now. */
node = apicid_to_node[apicid];
- if (node == NUMA_NO_NODE)
- node = first_node(node_online_map);
- else if (!node_online(node)) {
+ if (node == NUMA_NO_NODE || !node_online(node)) {
/* reuse the value from init_cpu_to_node() */
node = cpu_to_node(cpu);
}
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index 898c2f4eab88..12cd823c8d03 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -17,7 +17,7 @@
#include <asm/processor.h>
#include <linux/smp.h>
-#include <asm/k8.h>
+#include <asm/amd_nb.h>
#include <asm/smp.h>
#define LVL_1_INST 1
@@ -306,7 +306,7 @@ struct _cache_attr {
ssize_t (*store)(struct _cpuid4_info *, const char *, size_t count);
};
-#ifdef CONFIG_CPU_SUP_AMD
+#ifdef CONFIG_AMD_NB
/*
* L3 cache descriptors
@@ -369,7 +369,7 @@ static void __cpuinit amd_check_l3_disable(struct _cpuid4_info_regs *this_leaf,
return;
/* not in virtualized environments */
- if (num_k8_northbridges == 0)
+ if (k8_northbridges.num == 0)
return;
/*
@@ -377,7 +377,7 @@ static void __cpuinit amd_check_l3_disable(struct _cpuid4_info_regs *this_leaf,
* never freed but this is done only on shutdown so it doesn't matter.
*/
if (!l3_caches) {
- int size = num_k8_northbridges * sizeof(struct amd_l3_cache *);
+ int size = k8_northbridges.num * sizeof(struct amd_l3_cache *);
l3_caches = kzalloc(size, GFP_ATOMIC);
if (!l3_caches)
@@ -556,12 +556,12 @@ static struct _cache_attr cache_disable_0 = __ATTR(cache_disable_0, 0644,
static struct _cache_attr cache_disable_1 = __ATTR(cache_disable_1, 0644,
show_cache_disable_1, store_cache_disable_1);
-#else /* CONFIG_CPU_SUP_AMD */
+#else /* CONFIG_AMD_NB */
static void __cpuinit
amd_check_l3_disable(struct _cpuid4_info_regs *this_leaf, int index)
{
};
-#endif /* CONFIG_CPU_SUP_AMD */
+#endif /* CONFIG_AMD_NB */
static int
__cpuinit cpuid4_cache_lookup_regs(int index,
@@ -1000,7 +1000,7 @@ static struct attribute *default_attrs[] = {
static struct attribute *default_l3_attrs[] = {
DEFAULT_SYSFS_CACHE_ATTRS,
-#ifdef CONFIG_CPU_SUP_AMD
+#ifdef CONFIG_AMD_NB
&cache_disable_0.attr,
&cache_disable_1.attr,
#endif
diff --git a/arch/x86/kernel/cpu/mcheck/mce-severity.c b/arch/x86/kernel/cpu/mcheck/mce-severity.c
index 8a85dd1b1aa1..1e8d66c1336a 100644
--- a/arch/x86/kernel/cpu/mcheck/mce-severity.c
+++ b/arch/x86/kernel/cpu/mcheck/mce-severity.c
@@ -192,6 +192,7 @@ static const struct file_operations severities_coverage_fops = {
.release = seq_release,
.read = seq_read,
.write = severities_coverage_write,
+ .llseek = seq_lseek,
};
static int __init severities_debugfs_init(void)
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index ed41562909fe..7a35b72d7c03 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -1665,6 +1665,7 @@ struct file_operations mce_chrdev_ops = {
.read = mce_read,
.poll = mce_poll,
.unlocked_ioctl = mce_ioctl,
+ .llseek = no_llseek,
};
EXPORT_SYMBOL_GPL(mce_chrdev_ops);
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c
index 5e975298fa81..80c482382d5c 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
@@ -131,7 +131,8 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c)
u32 low = 0, high = 0, address = 0;
unsigned int bank, block;
struct thresh_restart tr;
- u8 lvt_off;
+ int lvt_off = -1;
+ u8 offset;
for (bank = 0; bank < NR_BANKS; ++bank) {
for (block = 0; block < NR_BLOCKS; ++block) {
@@ -141,6 +142,7 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c)
address = (low & MASK_BLKPTR_LO) >> 21;
if (!address)
break;
+
address += MCG_XBLK_ADDR;
} else
++address;
@@ -148,12 +150,8 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c)
if (rdmsr_safe(address, &low, &high))
break;
- if (!(high & MASK_VALID_HI)) {
- if (block)
- continue;
- else
- break;
- }
+ if (!(high & MASK_VALID_HI))
+ continue;
if (!(high & MASK_CNTP_HI) ||
(high & MASK_LOCKED_HI))
@@ -165,8 +163,28 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c)
if (shared_bank[bank] && c->cpu_core_id)
break;
#endif
- lvt_off = setup_APIC_eilvt_mce(THRESHOLD_APIC_VECTOR,
- APIC_EILVT_MSG_FIX, 0);
+ offset = (high & MASK_LVTOFF_HI) >> 20;
+ if (lvt_off < 0) {
+ if (setup_APIC_eilvt(offset,
+ THRESHOLD_APIC_VECTOR,
+ APIC_EILVT_MSG_FIX, 0)) {
+ pr_err(FW_BUG "cpu %d, failed to "
+ "setup threshold interrupt "
+ "for bank %d, block %d "
+ "(MSR%08X=0x%x%08x)",
+ smp_processor_id(), bank, block,
+ address, high, low);
+ continue;
+ }
+ lvt_off = offset;
+ } else if (lvt_off != offset) {
+ pr_err(FW_BUG "cpu %d, invalid threshold "
+ "interrupt offset %d for bank %d,"
+ "block %d (MSR%08X=0x%x%08x)",
+ smp_processor_id(), lvt_off, bank,
+ block, address, high, low);
+ continue;
+ }
high &= ~MASK_LVTOFF_HI;
high |= lvt_off << 20;
diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c
index d9368eeda309..4b683267eca5 100644
--- a/arch/x86/kernel/cpu/mcheck/therm_throt.c
+++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c
@@ -216,7 +216,7 @@ static __cpuinit int thermal_throttle_add_dev(struct sys_device *sys_dev,
err = sysfs_add_file_to_group(&sys_dev->kobj,
&attr_core_power_limit_count.attr,
thermal_attr_group.name);
- if (cpu_has(c, X86_FEATURE_PTS))
+ if (cpu_has(c, X86_FEATURE_PTS)) {
err = sysfs_add_file_to_group(&sys_dev->kobj,
&attr_package_throttle_count.attr,
thermal_attr_group.name);
@@ -224,6 +224,7 @@ static __cpuinit int thermal_throttle_add_dev(struct sys_device *sys_dev,
err = sysfs_add_file_to_group(&sys_dev->kobj,
&attr_package_power_limit_count.attr,
thermal_attr_group.name);
+ }
return err;
}
@@ -349,7 +350,7 @@ static void intel_thermal_interrupt(void)
static void unexpected_thermal_interrupt(void)
{
- printk(KERN_ERR "CPU%d: Unexpected LVT TMR interrupt!\n",
+ printk(KERN_ERR "CPU%d: Unexpected LVT thermal interrupt!\n",
smp_processor_id());
add_taint(TAINT_MACHINE_CHECK);
}
diff --git a/arch/x86/kernel/cpu/mtrr/cleanup.c b/arch/x86/kernel/cpu/mtrr/cleanup.c
index c5f59d071425..ac140c7be396 100644
--- a/arch/x86/kernel/cpu/mtrr/cleanup.c
+++ b/arch/x86/kernel/cpu/mtrr/cleanup.c
@@ -827,7 +827,7 @@ int __init amd_special_default_mtrr(void)
if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
return 0;
- if (boot_cpu_data.x86 < 0xf || boot_cpu_data.x86 > 0x11)
+ if (boot_cpu_data.x86 < 0xf)
return 0;
/* In case some hypervisor doesn't pass SYSCFG through: */
if (rdmsr_safe(MSR_K8_SYSCFG, &l, &h) < 0)
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
index 7d28d7d03885..9f27228ceffd 100644
--- a/arch/x86/kernel/cpu/mtrr/generic.c
+++ b/arch/x86/kernel/cpu/mtrr/generic.c
@@ -64,18 +64,59 @@ static inline void k8_check_syscfg_dram_mod_en(void)
}
}
+/* Get the size of contiguous MTRR range */
+static u64 get_mtrr_size(u64 mask)
+{
+ u64 size;
+
+ mask >>= PAGE_SHIFT;
+ mask |= size_or_mask;
+ size = -mask;
+ size <<= PAGE_SHIFT;
+ return size;
+}
+
/*
- * Returns the effective MTRR type for the region
- * Error returns:
- * - 0xFE - when the range is "not entirely covered" by _any_ var range MTRR
- * - 0xFF - when MTRR is not enabled
+ * Check and return the effective type for MTRR-MTRR type overlap.
+ * Returns 1 if the effective type is UNCACHEABLE, else returns 0
*/
-u8 mtrr_type_lookup(u64 start, u64 end)
+static int check_type_overlap(u8 *prev, u8 *curr)
+{
+ if (*prev == MTRR_TYPE_UNCACHABLE || *curr == MTRR_TYPE_UNCACHABLE) {
+ *prev = MTRR_TYPE_UNCACHABLE;
+ *curr = MTRR_TYPE_UNCACHABLE;
+ return 1;
+ }
+
+ if ((*prev == MTRR_TYPE_WRBACK && *curr == MTRR_TYPE_WRTHROUGH) ||
+ (*prev == MTRR_TYPE_WRTHROUGH && *curr == MTRR_TYPE_WRBACK)) {
+ *prev = MTRR_TYPE_WRTHROUGH;
+ *curr = MTRR_TYPE_WRTHROUGH;
+ }
+
+ if (*prev != *curr) {
+ *prev = MTRR_TYPE_UNCACHABLE;
+ *curr = MTRR_TYPE_UNCACHABLE;
+ return 1;
+ }
+
+ return 0;
+}
+
+/*
+ * Error/Semi-error returns:
+ * 0xFF - when MTRR is not enabled
+ * *repeat == 1 implies [start:end] spanned across MTRR range and type returned
+ * corresponds only to [start:*partial_end].
+ * Caller has to lookup again for [*partial_end:end].
+ */
+static u8 __mtrr_type_lookup(u64 start, u64 end, u64 *partial_end, int *repeat)
{
int i;
u64 base, mask;
u8 prev_match, curr_match;
+ *repeat = 0;
if (!mtrr_state_set)
return 0xFF;
@@ -126,8 +167,34 @@ u8 mtrr_type_lookup(u64 start, u64 end)
start_state = ((start & mask) == (base & mask));
end_state = ((end & mask) == (base & mask));
- if (start_state != end_state)
- return 0xFE;
+
+ if (start_state != end_state) {
+ /*
+ * We have start:end spanning across an MTRR.
+ * We split the region into
+ * either
+ * (start:mtrr_end) (mtrr_end:end)
+ * or
+ * (start:mtrr_start) (mtrr_start:end)
+ * depending on kind of overlap.
+ * Return the type for first region and a pointer to
+ * the start of second region so that caller will
+ * lookup again on the second region.
+ * Note: This way we handle multiple overlaps as well.
+ */
+ if (start_state)
+ *partial_end = base + get_mtrr_size(mask);
+ else
+ *partial_end = base;
+
+ if (unlikely(*partial_end <= start)) {
+ WARN_ON(1);
+ *partial_end = start + PAGE_SIZE;
+ }
+
+ end = *partial_end - 1; /* end is inclusive */
+ *repeat = 1;
+ }
if ((start & mask) != (base & mask))
continue;
@@ -138,21 +205,8 @@ u8 mtrr_type_lookup(u64 start, u64 end)
continue;
}
- if (prev_match == MTRR_TYPE_UNCACHABLE ||
- curr_match == MTRR_TYPE_UNCACHABLE) {
- return MTRR_TYPE_UNCACHABLE;
- }
-
- if ((prev_match == MTRR_TYPE_WRBACK &&
- curr_match == MTRR_TYPE_WRTHROUGH) ||
- (prev_match == MTRR_TYPE_WRTHROUGH &&
- curr_match == MTRR_TYPE_WRBACK)) {
- prev_match = MTRR_TYPE_WRTHROUGH;
- curr_match = MTRR_TYPE_WRTHROUGH;
- }
-
- if (prev_match != curr_match)
- return MTRR_TYPE_UNCACHABLE;
+ if (check_type_overlap(&prev_match, &curr_match))
+ return curr_match;
}
if (mtrr_tom2) {
@@ -166,6 +220,36 @@ u8 mtrr_type_lookup(u64 start, u64 end)
return mtrr_state.def_type;
}
+/*
+ * Returns the effective MTRR type for the region
+ * Error return:
+ * 0xFF - when MTRR is not enabled
+ */
+u8 mtrr_type_lookup(u64 start, u64 end)
+{
+ u8 type, prev_type;
+ int repeat;
+ u64 partial_end;
+
+ type = __mtrr_type_lookup(start, end, &partial_end, &repeat);
+
+ /*
+ * Common path is with repeat = 0.
+ * However, we can have cases where [start:end] spans across some
+ * MTRR range. Do repeated lookups for that case here.
+ */
+ while (repeat) {
+ prev_type = type;
+ start = partial_end;
+ type = __mtrr_type_lookup(start, end, &partial_end, &repeat);
+
+ if (check_type_overlap(&prev_type, &type))
+ return type;
+ }
+
+ return type;
+}
+
/* Get the MSR pair relating to a var range */
static void
get_mtrr_var_range(unsigned int index, struct mtrr_var_range *vr)
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 03a5b0385ad6..fe73c1844a9a 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -531,7 +531,7 @@ static int x86_pmu_hw_config(struct perf_event *event)
/*
* Setup the hardware configuration for a given attr_type
*/
-static int __hw_perf_event_init(struct perf_event *event)
+static int __x86_pmu_event_init(struct perf_event *event)
{
int err;
@@ -584,7 +584,7 @@ static void x86_pmu_disable_all(void)
}
}
-void hw_perf_disable(void)
+static void x86_pmu_disable(struct pmu *pmu)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
@@ -619,7 +619,7 @@ static void x86_pmu_enable_all(int added)
}
}
-static const struct pmu pmu;
+static struct pmu pmu;
static inline int is_x86_event(struct perf_event *event)
{
@@ -801,10 +801,10 @@ static inline int match_prev_assignment(struct hw_perf_event *hwc,
hwc->last_tag == cpuc->tags[i];
}
-static int x86_pmu_start(struct perf_event *event);
-static void x86_pmu_stop(struct perf_event *event);
+static void x86_pmu_start(struct perf_event *event, int flags);
+static void x86_pmu_stop(struct perf_event *event, int flags);
-void hw_perf_enable(void)
+static void x86_pmu_enable(struct pmu *pmu)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
struct perf_event *event;
@@ -840,7 +840,14 @@ void hw_perf_enable(void)
match_prev_assignment(hwc, cpuc, i))
continue;
- x86_pmu_stop(event);
+ /*
+ * Ensure we don't accidentally enable a stopped
+ * counter simply because we rescheduled.
+ */
+ if (hwc->state & PERF_HES_STOPPED)
+ hwc->state |= PERF_HES_ARCH;
+
+ x86_pmu_stop(event, PERF_EF_UPDATE);
}
for (i = 0; i < cpuc->n_events; i++) {
@@ -852,7 +859,10 @@ void hw_perf_enable(void)
else if (i < n_running)
continue;
- x86_pmu_start(event);
+ if (hwc->state & PERF_HES_ARCH)
+ continue;
+
+ x86_pmu_start(event, PERF_EF_RELOAD);
}
cpuc->n_added = 0;
perf_events_lapic_init();
@@ -953,15 +963,12 @@ static void x86_pmu_enable_event(struct perf_event *event)
}
/*
- * activate a single event
+ * Add a single event to the PMU.
*
* The event is added to the group of enabled events
* but only if it can be scehduled with existing events.
- *
- * Called with PMU disabled. If successful and return value 1,
- * then guaranteed to call perf_enable() and hw_perf_enable()
*/
-static int x86_pmu_enable(struct perf_event *event)
+static int x86_pmu_add(struct perf_event *event, int flags)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
struct hw_perf_event *hwc;
@@ -970,58 +977,67 @@ static int x86_pmu_enable(struct perf_event *event)
hwc = &event->hw;
+ perf_pmu_disable(event->pmu);
n0 = cpuc->n_events;
- n = collect_events(cpuc, event, false);
- if (n < 0)
- return n;
+ ret = n = collect_events(cpuc, event, false);
+ if (ret < 0)
+ goto out;
+
+ hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
+ if (!(flags & PERF_EF_START))
+ hwc->state |= PERF_HES_ARCH;
/*
* If group events scheduling transaction was started,
* skip the schedulability test here, it will be peformed
- * at commit time(->commit_txn) as a whole
+ * at commit time (->commit_txn) as a whole
*/
if (cpuc->group_flag & PERF_EVENT_TXN)
- goto out;
+ goto done_collect;
ret = x86_pmu.schedule_events(cpuc, n, assign);
if (ret)
- return ret;
+ goto out;
/*
* copy new assignment, now we know it is possible
* will be used by hw_perf_enable()
*/
memcpy(cpuc->assign, assign, n*sizeof(int));
-out:
+done_collect:
cpuc->n_events = n;
cpuc->n_added += n - n0;
cpuc->n_txn += n - n0;
- return 0;
+ ret = 0;
+out:
+ perf_pmu_enable(event->pmu);
+ return ret;
}
-static int x86_pmu_start(struct perf_event *event)
+static void x86_pmu_start(struct perf_event *event, int flags)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
int idx = event->hw.idx;
- if (idx == -1)
- return -EAGAIN;
+ if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
+ return;
+
+ if (WARN_ON_ONCE(idx == -1))
+ return;
+
+ if (flags & PERF_EF_RELOAD) {
+ WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE));
+ x86_perf_event_set_period(event);
+ }
+
+ event->hw.state = 0;
- x86_perf_event_set_period(event);
cpuc->events[idx] = event;
__set_bit(idx, cpuc->active_mask);
__set_bit(idx, cpuc->running);
x86_pmu.enable(event);
perf_event_update_userpage(event);
-
- return 0;
-}
-
-static void x86_pmu_unthrottle(struct perf_event *event)
-{
- int ret = x86_pmu_start(event);
- WARN_ON_ONCE(ret);
}
void perf_event_print_debug(void)
@@ -1078,27 +1094,29 @@ void perf_event_print_debug(void)
local_irq_restore(flags);
}
-static void x86_pmu_stop(struct perf_event *event)
+static void x86_pmu_stop(struct perf_event *event, int flags)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
struct hw_perf_event *hwc = &event->hw;
- int idx = hwc->idx;
- if (!__test_and_clear_bit(idx, cpuc->active_mask))
- return;
-
- x86_pmu.disable(event);
-
- /*
- * Drain the remaining delta count out of a event
- * that we are disabling:
- */
- x86_perf_event_update(event);
+ if (__test_and_clear_bit(hwc->idx, cpuc->active_mask)) {
+ x86_pmu.disable(event);
+ cpuc->events[hwc->idx] = NULL;
+ WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
+ hwc->state |= PERF_HES_STOPPED;
+ }
- cpuc->events[idx] = NULL;
+ if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
+ /*
+ * Drain the remaining delta count out of a event
+ * that we are disabling:
+ */
+ x86_perf_event_update(event);
+ hwc->state |= PERF_HES_UPTODATE;
+ }
}
-static void x86_pmu_disable(struct perf_event *event)
+static void x86_pmu_del(struct perf_event *event, int flags)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
int i;
@@ -1111,7 +1129,7 @@ static void x86_pmu_disable(struct perf_event *event)
if (cpuc->group_flag & PERF_EVENT_TXN)
return;
- x86_pmu_stop(event);
+ x86_pmu_stop(event, PERF_EF_UPDATE);
for (i = 0; i < cpuc->n_events; i++) {
if (event == cpuc->event_list[i]) {
@@ -1134,7 +1152,6 @@ static int x86_pmu_handle_irq(struct pt_regs *regs)
struct perf_sample_data data;
struct cpu_hw_events *cpuc;
struct perf_event *event;
- struct hw_perf_event *hwc;
int idx, handled = 0;
u64 val;
@@ -1155,7 +1172,6 @@ static int x86_pmu_handle_irq(struct pt_regs *regs)
}
event = cpuc->events[idx];
- hwc = &event->hw;
val = x86_perf_event_update(event);
if (val & (1ULL << (x86_pmu.cntval_bits - 1)))
@@ -1171,7 +1187,7 @@ static int x86_pmu_handle_irq(struct pt_regs *regs)
continue;
if (perf_event_overflow(event, 1, &data, regs))
- x86_pmu_stop(event);
+ x86_pmu_stop(event, 0);
}
if (handled)
@@ -1180,25 +1196,6 @@ static int x86_pmu_handle_irq(struct pt_regs *regs)
return handled;
}
-void smp_perf_pending_interrupt(struct pt_regs *regs)
-{
- irq_enter();
- ack_APIC_irq();
- inc_irq_stat(apic_pending_irqs);
- perf_event_do_pending();
- irq_exit();
-}
-
-void set_perf_event_pending(void)
-{
-#ifdef CONFIG_X86_LOCAL_APIC
- if (!x86_pmu.apic || !x86_pmu_initialized())
- return;
-
- apic->send_IPI_self(LOCAL_PENDING_VECTOR);
-#endif
-}
-
void perf_events_lapic_init(void)
{
if (!x86_pmu.apic || !x86_pmu_initialized())
@@ -1388,7 +1385,6 @@ void __init init_hw_perf_events(void)
x86_pmu.num_counters = X86_PMC_MAX_GENERIC;
}
x86_pmu.intel_ctrl = (1 << x86_pmu.num_counters) - 1;
- perf_max_events = x86_pmu.num_counters;
if (x86_pmu.num_counters_fixed > X86_PMC_MAX_FIXED) {
WARN(1, KERN_ERR "hw perf events fixed %d > max(%d), clipping!",
@@ -1424,6 +1420,7 @@ void __init init_hw_perf_events(void)
pr_info("... fixed-purpose events: %d\n", x86_pmu.num_counters_fixed);
pr_info("... event mask: %016Lx\n", x86_pmu.intel_ctrl);
+ perf_pmu_register(&pmu);
perf_cpu_notifier(x86_pmu_notifier);
}
@@ -1437,10 +1434,11 @@ static inline void x86_pmu_read(struct perf_event *event)
* Set the flag to make pmu::enable() not perform the
* schedulability test, it will be performed at commit time
*/
-static void x86_pmu_start_txn(const struct pmu *pmu)
+static void x86_pmu_start_txn(struct pmu *pmu)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ perf_pmu_disable(pmu);
cpuc->group_flag |= PERF_EVENT_TXN;
cpuc->n_txn = 0;
}
@@ -1450,7 +1448,7 @@ static void x86_pmu_start_txn(const struct pmu *pmu)
* Clear the flag and pmu::enable() will perform the
* schedulability test.
*/
-static void x86_pmu_cancel_txn(const struct pmu *pmu)
+static void x86_pmu_cancel_txn(struct pmu *pmu)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
@@ -1460,6 +1458,7 @@ static void x86_pmu_cancel_txn(const struct pmu *pmu)
*/
cpuc->n_added -= cpuc->n_txn;
cpuc->n_events -= cpuc->n_txn;
+ perf_pmu_enable(pmu);
}
/*
@@ -1467,7 +1466,7 @@ static void x86_pmu_cancel_txn(const struct pmu *pmu)
* Perform the group schedulability test as a whole
* Return 0 if success
*/
-static int x86_pmu_commit_txn(const struct pmu *pmu)
+static int x86_pmu_commit_txn(struct pmu *pmu)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
int assign[X86_PMC_IDX_MAX];
@@ -1489,22 +1488,10 @@ static int x86_pmu_commit_txn(const struct pmu *pmu)
memcpy(cpuc->assign, assign, n*sizeof(int));
cpuc->group_flag &= ~PERF_EVENT_TXN;
-
+ perf_pmu_enable(pmu);
return 0;
}
-static const struct pmu pmu = {
- .enable = x86_pmu_enable,
- .disable = x86_pmu_disable,
- .start = x86_pmu_start,
- .stop = x86_pmu_stop,
- .read = x86_pmu_read,
- .unthrottle = x86_pmu_unthrottle,
- .start_txn = x86_pmu_start_txn,
- .cancel_txn = x86_pmu_cancel_txn,
- .commit_txn = x86_pmu_commit_txn,
-};
-
/*
* validate that we can schedule this event
*/
@@ -1579,12 +1566,22 @@ out:
return ret;
}
-const struct pmu *hw_perf_event_init(struct perf_event *event)
+int x86_pmu_event_init(struct perf_event *event)
{
- const struct pmu *tmp;
+ struct pmu *tmp;
int err;
- err = __hw_perf_event_init(event);
+ switch (event->attr.type) {
+ case PERF_TYPE_RAW:
+ case PERF_TYPE_HARDWARE:
+ case PERF_TYPE_HW_CACHE:
+ break;
+
+ default:
+ return -ENOENT;
+ }
+
+ err = __x86_pmu_event_init(event);
if (!err) {
/*
* we temporarily connect event to its pmu
@@ -1604,26 +1601,31 @@ const struct pmu *hw_perf_event_init(struct perf_event *event)
if (err) {
if (event->destroy)
event->destroy(event);
- return ERR_PTR(err);
}
- return &pmu;
+ return err;
}
-/*
- * callchain support
- */
+static struct pmu pmu = {
+ .pmu_enable = x86_pmu_enable,
+ .pmu_disable = x86_pmu_disable,
-static inline
-void callchain_store(struct perf_callchain_entry *entry, u64 ip)
-{
- if (entry->nr < PERF_MAX_STACK_DEPTH)
- entry->ip[entry->nr++] = ip;
-}
+ .event_init = x86_pmu_event_init,
-static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_irq_entry);
-static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_nmi_entry);
+ .add = x86_pmu_add,
+ .del = x86_pmu_del,
+ .start = x86_pmu_start,
+ .stop = x86_pmu_stop,
+ .read = x86_pmu_read,
+ .start_txn = x86_pmu_start_txn,
+ .cancel_txn = x86_pmu_cancel_txn,
+ .commit_txn = x86_pmu_commit_txn,
+};
+
+/*
+ * callchain support
+ */
static void
backtrace_warning_symbol(void *data, char *msg, unsigned long symbol)
@@ -1645,7 +1647,7 @@ static void backtrace_address(void *data, unsigned long addr, int reliable)
{
struct perf_callchain_entry *entry = data;
- callchain_store(entry, addr);
+ perf_callchain_store(entry, addr);
}
static const struct stacktrace_ops backtrace_ops = {
@@ -1656,11 +1658,15 @@ static const struct stacktrace_ops backtrace_ops = {
.walk_stack = print_context_stack_bp,
};
-static void
-perf_callchain_kernel(struct pt_regs *regs, struct perf_callchain_entry *entry)
+void
+perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs)
{
- callchain_store(entry, PERF_CONTEXT_KERNEL);
- callchain_store(entry, regs->ip);
+ if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+ /* TODO: We don't support guest os callchain now */
+ return;
+ }
+
+ perf_callchain_store(entry, regs->ip);
dump_trace(NULL, regs, NULL, regs->bp, &backtrace_ops, entry);
}
@@ -1689,7 +1695,7 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry)
if (fp < compat_ptr(regs->sp))
break;
- callchain_store(entry, frame.return_address);
+ perf_callchain_store(entry, frame.return_address);
fp = compat_ptr(frame.next_frame);
}
return 1;
@@ -1702,19 +1708,20 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry)
}
#endif
-static void
-perf_callchain_user(struct pt_regs *regs, struct perf_callchain_entry *entry)
+void
+perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
{
struct stack_frame frame;
const void __user *fp;
- if (!user_mode(regs))
- regs = task_pt_regs(current);
+ if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+ /* TODO: We don't support guest os callchain now */
+ return;
+ }
fp = (void __user *)regs->bp;
- callchain_store(entry, PERF_CONTEXT_USER);
- callchain_store(entry, regs->ip);
+ perf_callchain_store(entry, regs->ip);
if (perf_callchain_user32(regs, entry))
return;
@@ -1731,52 +1738,11 @@ perf_callchain_user(struct pt_regs *regs, struct perf_callchain_entry *entry)
if ((unsigned long)fp < regs->sp)
break;
- callchain_store(entry, frame.return_address);
+ perf_callchain_store(entry, frame.return_address);
fp = frame.next_frame;
}
}
-static void
-perf_do_callchain(struct pt_regs *regs, struct perf_callchain_entry *entry)
-{
- int is_user;
-
- if (!regs)
- return;
-
- is_user = user_mode(regs);
-
- if (is_user && current->state != TASK_RUNNING)
- return;
-
- if (!is_user)
- perf_callchain_kernel(regs, entry);
-
- if (current->mm)
- perf_callchain_user(regs, entry);
-}
-
-struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
-{
- struct perf_callchain_entry *entry;
-
- if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
- /* TODO: We don't support guest os callchain now */
- return NULL;
- }
-
- if (in_nmi())
- entry = &__get_cpu_var(pmc_nmi_entry);
- else
- entry = &__get_cpu_var(pmc_irq_entry);
-
- entry->nr = 0;
-
- perf_do_callchain(regs, entry);
-
- return entry;
-}
-
unsigned long perf_instruction_pointer(struct pt_regs *regs)
{
unsigned long ip;
diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c
index c2897b7b4a3b..46d58448c3af 100644
--- a/arch/x86/kernel/cpu/perf_event_amd.c
+++ b/arch/x86/kernel/cpu/perf_event_amd.c
@@ -52,7 +52,7 @@ static __initconst const u64 amd_hw_cache_event_ids
[ C(DTLB) ] = {
[ C(OP_READ) ] = {
[ C(RESULT_ACCESS) ] = 0x0040, /* Data Cache Accesses */
- [ C(RESULT_MISS) ] = 0x0046, /* L1 DTLB and L2 DLTB Miss */
+ [ C(RESULT_MISS) ] = 0x0746, /* L1_DTLB_AND_L2_DLTB_MISS.ALL */
},
[ C(OP_WRITE) ] = {
[ C(RESULT_ACCESS) ] = 0,
@@ -66,7 +66,7 @@ static __initconst const u64 amd_hw_cache_event_ids
[ C(ITLB) ] = {
[ C(OP_READ) ] = {
[ C(RESULT_ACCESS) ] = 0x0080, /* Instruction fecthes */
- [ C(RESULT_MISS) ] = 0x0085, /* Instr. fetch ITLB misses */
+ [ C(RESULT_MISS) ] = 0x0385, /* L1_ITLB_AND_L2_ITLB_MISS.ALL */
},
[ C(OP_WRITE) ] = {
[ C(RESULT_ACCESS) ] = -1,
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index ee05c90012d2..c8f5c088cad1 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -713,18 +713,18 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
struct cpu_hw_events *cpuc;
int bit, loops;
u64 status;
- int handled = 0;
+ int handled;
perf_sample_data_init(&data, 0);
cpuc = &__get_cpu_var(cpu_hw_events);
intel_pmu_disable_all();
- intel_pmu_drain_bts_buffer();
+ handled = intel_pmu_drain_bts_buffer();
status = intel_pmu_get_status();
if (!status) {
intel_pmu_enable_all(0);
- return 0;
+ return handled;
}
loops = 0;
@@ -763,7 +763,7 @@ again:
data.period = event->hw.last_period;
if (perf_event_overflow(event, 1, &data, regs))
- x86_pmu_stop(event);
+ x86_pmu_stop(event, 0);
}
/*
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c
index 18018d1311cd..4977f9c400e5 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c
@@ -214,7 +214,7 @@ static void intel_pmu_disable_bts(void)
update_debugctlmsr(debugctlmsr);
}
-static void intel_pmu_drain_bts_buffer(void)
+static int intel_pmu_drain_bts_buffer(void)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
struct debug_store *ds = cpuc->ds;
@@ -231,16 +231,16 @@ static void intel_pmu_drain_bts_buffer(void)
struct pt_regs regs;
if (!event)
- return;
+ return 0;
if (!ds)
- return;
+ return 0;
at = (struct bts_record *)(unsigned long)ds->bts_buffer_base;
top = (struct bts_record *)(unsigned long)ds->bts_index;
if (top <= at)
- return;
+ return 0;
ds->bts_index = ds->bts_buffer_base;
@@ -256,7 +256,7 @@ static void intel_pmu_drain_bts_buffer(void)
perf_prepare_sample(&header, &data, event, &regs);
if (perf_output_begin(&handle, event, header.size * (top - at), 1, 1))
- return;
+ return 1;
for (; at < top; at++) {
data.ip = at->from;
@@ -270,6 +270,7 @@ static void intel_pmu_drain_bts_buffer(void)
/* There's new data available. */
event->hw.interrupts++;
event->pending_kill = POLL_IN;
+ return 1;
}
/*
@@ -491,7 +492,7 @@ static void __intel_pmu_pebs_event(struct perf_event *event,
regs.flags &= ~PERF_EFLAGS_EXACT;
if (perf_event_overflow(event, 1, &data, &regs))
- x86_pmu_stop(event);
+ x86_pmu_stop(event, 0);
}
static void intel_pmu_drain_pebs_core(struct pt_regs *iregs)
diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c
index b560db3305be..81400b93e694 100644
--- a/arch/x86/kernel/cpu/perf_event_p4.c
+++ b/arch/x86/kernel/cpu/perf_event_p4.c
@@ -18,6 +18,8 @@
struct p4_event_bind {
unsigned int opcode; /* Event code and ESCR selector */
unsigned int escr_msr[2]; /* ESCR MSR for this event */
+ unsigned int escr_emask; /* valid ESCR EventMask bits */
+ unsigned int shared; /* event is shared across threads */
char cntr[2][P4_CNTR_LIMIT]; /* counter index (offset), -1 on abscence */
};
@@ -66,231 +68,435 @@ static struct p4_event_bind p4_event_bind_map[] = {
[P4_EVENT_TC_DELIVER_MODE] = {
.opcode = P4_OPCODE(P4_EVENT_TC_DELIVER_MODE),
.escr_msr = { MSR_P4_TC_ESCR0, MSR_P4_TC_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, DD) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, DB) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, DI) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, BD) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, BB) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, BI) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, ID),
+ .shared = 1,
.cntr = { {4, 5, -1}, {6, 7, -1} },
},
[P4_EVENT_BPU_FETCH_REQUEST] = {
.opcode = P4_OPCODE(P4_EVENT_BPU_FETCH_REQUEST),
.escr_msr = { MSR_P4_BPU_ESCR0, MSR_P4_BPU_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_BPU_FETCH_REQUEST, TCMISS),
.cntr = { {0, -1, -1}, {2, -1, -1} },
},
[P4_EVENT_ITLB_REFERENCE] = {
.opcode = P4_OPCODE(P4_EVENT_ITLB_REFERENCE),
.escr_msr = { MSR_P4_ITLB_ESCR0, MSR_P4_ITLB_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_ITLB_REFERENCE, HIT) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_ITLB_REFERENCE, MISS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_ITLB_REFERENCE, HIT_UK),
.cntr = { {0, -1, -1}, {2, -1, -1} },
},
[P4_EVENT_MEMORY_CANCEL] = {
.opcode = P4_OPCODE(P4_EVENT_MEMORY_CANCEL),
.escr_msr = { MSR_P4_DAC_ESCR0, MSR_P4_DAC_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_MEMORY_CANCEL, ST_RB_FULL) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_MEMORY_CANCEL, 64K_CONF),
.cntr = { {8, 9, -1}, {10, 11, -1} },
},
[P4_EVENT_MEMORY_COMPLETE] = {
.opcode = P4_OPCODE(P4_EVENT_MEMORY_COMPLETE),
.escr_msr = { MSR_P4_SAAT_ESCR0 , MSR_P4_SAAT_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_MEMORY_COMPLETE, LSC) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_MEMORY_COMPLETE, SSC),
.cntr = { {8, 9, -1}, {10, 11, -1} },
},
[P4_EVENT_LOAD_PORT_REPLAY] = {
.opcode = P4_OPCODE(P4_EVENT_LOAD_PORT_REPLAY),
.escr_msr = { MSR_P4_SAAT_ESCR0, MSR_P4_SAAT_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_LOAD_PORT_REPLAY, SPLIT_LD),
.cntr = { {8, 9, -1}, {10, 11, -1} },
},
[P4_EVENT_STORE_PORT_REPLAY] = {
.opcode = P4_OPCODE(P4_EVENT_STORE_PORT_REPLAY),
.escr_msr = { MSR_P4_SAAT_ESCR0 , MSR_P4_SAAT_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_STORE_PORT_REPLAY, SPLIT_ST),
.cntr = { {8, 9, -1}, {10, 11, -1} },
},
[P4_EVENT_MOB_LOAD_REPLAY] = {
.opcode = P4_OPCODE(P4_EVENT_MOB_LOAD_REPLAY),
.escr_msr = { MSR_P4_MOB_ESCR0, MSR_P4_MOB_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_MOB_LOAD_REPLAY, NO_STA) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_MOB_LOAD_REPLAY, NO_STD) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_MOB_LOAD_REPLAY, PARTIAL_DATA) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_MOB_LOAD_REPLAY, UNALGN_ADDR),
.cntr = { {0, -1, -1}, {2, -1, -1} },
},
[P4_EVENT_PAGE_WALK_TYPE] = {
.opcode = P4_OPCODE(P4_EVENT_PAGE_WALK_TYPE),
.escr_msr = { MSR_P4_PMH_ESCR0, MSR_P4_PMH_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_PAGE_WALK_TYPE, DTMISS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_PAGE_WALK_TYPE, ITMISS),
+ .shared = 1,
.cntr = { {0, -1, -1}, {2, -1, -1} },
},
[P4_EVENT_BSQ_CACHE_REFERENCE] = {
.opcode = P4_OPCODE(P4_EVENT_BSQ_CACHE_REFERENCE),
.escr_msr = { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITM) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITM) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_MISS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_MISS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, WR_2ndL_MISS),
.cntr = { {0, -1, -1}, {2, -1, -1} },
},
[P4_EVENT_IOQ_ALLOCATION] = {
.opcode = P4_OPCODE(P4_EVENT_IOQ_ALLOCATION),
.escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, DEFAULT) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, ALL_READ) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, ALL_WRITE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_UC) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_WC) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_WT) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_WP) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_WB) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, OWN) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, OTHER) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, PREFETCH),
.cntr = { {0, -1, -1}, {2, -1, -1} },
},
[P4_EVENT_IOQ_ACTIVE_ENTRIES] = { /* shared ESCR */
.opcode = P4_OPCODE(P4_EVENT_IOQ_ACTIVE_ENTRIES),
.escr_msr = { MSR_P4_FSB_ESCR1, MSR_P4_FSB_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, DEFAULT) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, ALL_READ) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, ALL_WRITE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_UC) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WC) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WT) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WP) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WB) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, OWN) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, OTHER) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, PREFETCH),
.cntr = { {2, -1, -1}, {3, -1, -1} },
},
[P4_EVENT_FSB_DATA_ACTIVITY] = {
.opcode = P4_OPCODE(P4_EVENT_FSB_DATA_ACTIVITY),
.escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_DRV) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_OWN) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_OTHER) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_DRV) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_OWN) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_OTHER),
+ .shared = 1,
.cntr = { {0, -1, -1}, {2, -1, -1} },
},
[P4_EVENT_BSQ_ALLOCATION] = { /* shared ESCR, broken CCCR1 */
.opcode = P4_OPCODE(P4_EVENT_BSQ_ALLOCATION),
.escr_msr = { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR0 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_TYPE0) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_TYPE1) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_LEN0) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_LEN1) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_IO_TYPE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_LOCK_TYPE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_CACHE_TYPE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_SPLIT_TYPE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_DEM_TYPE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_ORD_TYPE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE0) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE1) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE2),
.cntr = { {0, -1, -1}, {1, -1, -1} },
},
[P4_EVENT_BSQ_ACTIVE_ENTRIES] = { /* shared ESCR */
.opcode = P4_OPCODE(P4_EVENT_BSQ_ACTIVE_ENTRIES),
.escr_msr = { MSR_P4_BSU_ESCR1 , MSR_P4_BSU_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_TYPE0) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_TYPE1) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LEN0) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LEN1) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_IO_TYPE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LOCK_TYPE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_CACHE_TYPE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_SPLIT_TYPE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_DEM_TYPE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_ORD_TYPE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE0) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE1) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE2),
.cntr = { {2, -1, -1}, {3, -1, -1} },
},
[P4_EVENT_SSE_INPUT_ASSIST] = {
.opcode = P4_OPCODE(P4_EVENT_SSE_INPUT_ASSIST),
.escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_SSE_INPUT_ASSIST, ALL),
+ .shared = 1,
.cntr = { {8, 9, -1}, {10, 11, -1} },
},
[P4_EVENT_PACKED_SP_UOP] = {
.opcode = P4_OPCODE(P4_EVENT_PACKED_SP_UOP),
.escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_PACKED_SP_UOP, ALL),
+ .shared = 1,
.cntr = { {8, 9, -1}, {10, 11, -1} },
},
[P4_EVENT_PACKED_DP_UOP] = {
.opcode = P4_OPCODE(P4_EVENT_PACKED_DP_UOP),
.escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_PACKED_DP_UOP, ALL),
+ .shared = 1,
.cntr = { {8, 9, -1}, {10, 11, -1} },
},
[P4_EVENT_SCALAR_SP_UOP] = {
.opcode = P4_OPCODE(P4_EVENT_SCALAR_SP_UOP),
.escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_SCALAR_SP_UOP, ALL),
+ .shared = 1,
.cntr = { {8, 9, -1}, {10, 11, -1} },
},
[P4_EVENT_SCALAR_DP_UOP] = {
.opcode = P4_OPCODE(P4_EVENT_SCALAR_DP_UOP),
.escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_SCALAR_DP_UOP, ALL),
+ .shared = 1,
.cntr = { {8, 9, -1}, {10, 11, -1} },
},
[P4_EVENT_64BIT_MMX_UOP] = {
.opcode = P4_OPCODE(P4_EVENT_64BIT_MMX_UOP),
.escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_64BIT_MMX_UOP, ALL),
+ .shared = 1,
.cntr = { {8, 9, -1}, {10, 11, -1} },
},
[P4_EVENT_128BIT_MMX_UOP] = {
.opcode = P4_OPCODE(P4_EVENT_128BIT_MMX_UOP),
.escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_128BIT_MMX_UOP, ALL),
+ .shared = 1,
.cntr = { {8, 9, -1}, {10, 11, -1} },
},
[P4_EVENT_X87_FP_UOP] = {
.opcode = P4_OPCODE(P4_EVENT_X87_FP_UOP),
.escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_X87_FP_UOP, ALL),
+ .shared = 1,
.cntr = { {8, 9, -1}, {10, 11, -1} },
},
[P4_EVENT_TC_MISC] = {
.opcode = P4_OPCODE(P4_EVENT_TC_MISC),
.escr_msr = { MSR_P4_TC_ESCR0, MSR_P4_TC_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_TC_MISC, FLUSH),
.cntr = { {4, 5, -1}, {6, 7, -1} },
},
[P4_EVENT_GLOBAL_POWER_EVENTS] = {
.opcode = P4_OPCODE(P4_EVENT_GLOBAL_POWER_EVENTS),
.escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_GLOBAL_POWER_EVENTS, RUNNING),
.cntr = { {0, -1, -1}, {2, -1, -1} },
},
[P4_EVENT_TC_MS_XFER] = {
.opcode = P4_OPCODE(P4_EVENT_TC_MS_XFER),
.escr_msr = { MSR_P4_MS_ESCR0, MSR_P4_MS_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_TC_MS_XFER, CISC),
.cntr = { {4, 5, -1}, {6, 7, -1} },
},
[P4_EVENT_UOP_QUEUE_WRITES] = {
.opcode = P4_OPCODE(P4_EVENT_UOP_QUEUE_WRITES),
.escr_msr = { MSR_P4_MS_ESCR0, MSR_P4_MS_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_UOP_QUEUE_WRITES, FROM_TC_BUILD) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_UOP_QUEUE_WRITES, FROM_TC_DELIVER) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_UOP_QUEUE_WRITES, FROM_ROM),
.cntr = { {4, 5, -1}, {6, 7, -1} },
},
[P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE] = {
.opcode = P4_OPCODE(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE),
.escr_msr = { MSR_P4_TBPU_ESCR0 , MSR_P4_TBPU_ESCR0 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, CONDITIONAL) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, CALL) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, RETURN) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, INDIRECT),
.cntr = { {4, 5, -1}, {6, 7, -1} },
},
[P4_EVENT_RETIRED_BRANCH_TYPE] = {
.opcode = P4_OPCODE(P4_EVENT_RETIRED_BRANCH_TYPE),
.escr_msr = { MSR_P4_TBPU_ESCR0 , MSR_P4_TBPU_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, CONDITIONAL) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, CALL) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, RETURN) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, INDIRECT),
.cntr = { {4, 5, -1}, {6, 7, -1} },
},
[P4_EVENT_RESOURCE_STALL] = {
.opcode = P4_OPCODE(P4_EVENT_RESOURCE_STALL),
.escr_msr = { MSR_P4_ALF_ESCR0, MSR_P4_ALF_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_RESOURCE_STALL, SBFULL),
.cntr = { {12, 13, 16}, {14, 15, 17} },
},
[P4_EVENT_WC_BUFFER] = {
.opcode = P4_OPCODE(P4_EVENT_WC_BUFFER),
.escr_msr = { MSR_P4_DAC_ESCR0, MSR_P4_DAC_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_WC_BUFFER, WCB_EVICTS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_WC_BUFFER, WCB_FULL_EVICTS),
+ .shared = 1,
.cntr = { {8, 9, -1}, {10, 11, -1} },
},
[P4_EVENT_B2B_CYCLES] = {
.opcode = P4_OPCODE(P4_EVENT_B2B_CYCLES),
.escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+ .escr_emask = 0,
.cntr = { {0, -1, -1}, {2, -1, -1} },
},
[P4_EVENT_BNR] = {
.opcode = P4_OPCODE(P4_EVENT_BNR),
.escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+ .escr_emask = 0,
.cntr = { {0, -1, -1}, {2, -1, -1} },
},
[P4_EVENT_SNOOP] = {
.opcode = P4_OPCODE(P4_EVENT_SNOOP),
.escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+ .escr_emask = 0,
.cntr = { {0, -1, -1}, {2, -1, -1} },
},
[P4_EVENT_RESPONSE] = {
.opcode = P4_OPCODE(P4_EVENT_RESPONSE),
.escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+ .escr_emask = 0,
.cntr = { {0, -1, -1}, {2, -1, -1} },
},
[P4_EVENT_FRONT_END_EVENT] = {
.opcode = P4_OPCODE(P4_EVENT_FRONT_END_EVENT),
.escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_FRONT_END_EVENT, NBOGUS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_FRONT_END_EVENT, BOGUS),
.cntr = { {12, 13, 16}, {14, 15, 17} },
},
[P4_EVENT_EXECUTION_EVENT] = {
.opcode = P4_OPCODE(P4_EVENT_EXECUTION_EVENT),
.escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS0) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS1) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS2) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS3) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS0) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS1) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS2) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS3),
.cntr = { {12, 13, 16}, {14, 15, 17} },
},
[P4_EVENT_REPLAY_EVENT] = {
.opcode = P4_OPCODE(P4_EVENT_REPLAY_EVENT),
.escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_REPLAY_EVENT, NBOGUS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_REPLAY_EVENT, BOGUS),
.cntr = { {12, 13, 16}, {14, 15, 17} },
},
[P4_EVENT_INSTR_RETIRED] = {
.opcode = P4_OPCODE(P4_EVENT_INSTR_RETIRED),
.escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, NBOGUSNTAG) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, NBOGUSTAG) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, BOGUSNTAG) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, BOGUSTAG),
.cntr = { {12, 13, 16}, {14, 15, 17} },
},
[P4_EVENT_UOPS_RETIRED] = {
.opcode = P4_OPCODE(P4_EVENT_UOPS_RETIRED),
.escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_UOPS_RETIRED, NBOGUS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_UOPS_RETIRED, BOGUS),
.cntr = { {12, 13, 16}, {14, 15, 17} },
},
[P4_EVENT_UOP_TYPE] = {
.opcode = P4_OPCODE(P4_EVENT_UOP_TYPE),
.escr_msr = { MSR_P4_RAT_ESCR0, MSR_P4_RAT_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_UOP_TYPE, TAGLOADS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_UOP_TYPE, TAGSTORES),
.cntr = { {12, 13, 16}, {14, 15, 17} },
},
[P4_EVENT_BRANCH_RETIRED] = {
.opcode = P4_OPCODE(P4_EVENT_BRANCH_RETIRED),
.escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_BRANCH_RETIRED, MMNP) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BRANCH_RETIRED, MMNM) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BRANCH_RETIRED, MMTP) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BRANCH_RETIRED, MMTM),
.cntr = { {12, 13, 16}, {14, 15, 17} },
},
[P4_EVENT_MISPRED_BRANCH_RETIRED] = {
.opcode = P4_OPCODE(P4_EVENT_MISPRED_BRANCH_RETIRED),
.escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_MISPRED_BRANCH_RETIRED, NBOGUS),
.cntr = { {12, 13, 16}, {14, 15, 17} },
},
[P4_EVENT_X87_ASSIST] = {
.opcode = P4_OPCODE(P4_EVENT_X87_ASSIST),
.escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, FPSU) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, FPSO) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, POAO) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, POAU) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, PREA),
.cntr = { {12, 13, 16}, {14, 15, 17} },
},
[P4_EVENT_MACHINE_CLEAR] = {
.opcode = P4_OPCODE(P4_EVENT_MACHINE_CLEAR),
.escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_MACHINE_CLEAR, CLEAR) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_MACHINE_CLEAR, MOCLEAR) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_MACHINE_CLEAR, SMCLEAR),
.cntr = { {12, 13, 16}, {14, 15, 17} },
},
[P4_EVENT_INSTR_COMPLETED] = {
.opcode = P4_OPCODE(P4_EVENT_INSTR_COMPLETED),
.escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_COMPLETED, NBOGUS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_COMPLETED, BOGUS),
.cntr = { {12, 13, 16}, {14, 15, 17} },
},
};
@@ -428,29 +634,73 @@ static u64 p4_pmu_event_map(int hw_event)
return config;
}
+/* check cpu model specifics */
+static bool p4_event_match_cpu_model(unsigned int event_idx)
+{
+ /* INSTR_COMPLETED event only exist for model 3, 4, 6 (Prescott) */
+ if (event_idx == P4_EVENT_INSTR_COMPLETED) {
+ if (boot_cpu_data.x86_model != 3 &&
+ boot_cpu_data.x86_model != 4 &&
+ boot_cpu_data.x86_model != 6)
+ return false;
+ }
+
+ /*
+ * For info
+ * - IQ_ESCR0, IQ_ESCR1 only for models 1 and 2
+ */
+
+ return true;
+}
+
static int p4_validate_raw_event(struct perf_event *event)
{
- unsigned int v;
+ unsigned int v, emask;
- /* user data may have out-of-bound event index */
+ /* User data may have out-of-bound event index */
v = p4_config_unpack_event(event->attr.config);
- if (v >= ARRAY_SIZE(p4_event_bind_map)) {
- pr_warning("P4 PMU: Unknown event code: %d\n", v);
+ if (v >= ARRAY_SIZE(p4_event_bind_map))
+ return -EINVAL;
+
+ /* It may be unsupported: */
+ if (!p4_event_match_cpu_model(v))
return -EINVAL;
+
+ /*
+ * NOTE: P4_CCCR_THREAD_ANY has not the same meaning as
+ * in Architectural Performance Monitoring, it means not
+ * on _which_ logical cpu to count but rather _when_, ie it
+ * depends on logical cpu state -- count event if one cpu active,
+ * none, both or any, so we just allow user to pass any value
+ * desired.
+ *
+ * In turn we always set Tx_OS/Tx_USR bits bound to logical
+ * cpu without their propagation to another cpu
+ */
+
+ /*
+ * if an event is shared accross the logical threads
+ * the user needs special permissions to be able to use it
+ */
+ if (p4_event_bind_map[v].shared) {
+ if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN))
+ return -EACCES;
}
+ /* ESCR EventMask bits may be invalid */
+ emask = p4_config_unpack_escr(event->attr.config) & P4_ESCR_EVENTMASK_MASK;
+ if (emask & ~p4_event_bind_map[v].escr_emask)
+ return -EINVAL;
+
/*
- * it may have some screwed PEBS bits
+ * it may have some invalid PEBS bits
*/
- if (p4_config_pebs_has(event->attr.config, P4_PEBS_CONFIG_ENABLE)) {
- pr_warning("P4 PMU: PEBS are not supported yet\n");
+ if (p4_config_pebs_has(event->attr.config, P4_PEBS_CONFIG_ENABLE))
return -EINVAL;
- }
+
v = p4_config_unpack_metric(event->attr.config);
- if (v >= ARRAY_SIZE(p4_pebs_bind_map)) {
- pr_warning("P4 PMU: Unknown metric code: %d\n", v);
+ if (v >= ARRAY_SIZE(p4_pebs_bind_map))
return -EINVAL;
- }
return 0;
}
@@ -478,27 +728,21 @@ static int p4_hw_config(struct perf_event *event)
if (event->attr.type == PERF_TYPE_RAW) {
+ /*
+ * Clear bits we reserve to be managed by kernel itself
+ * and never allowed from a user space
+ */
+ event->attr.config &= P4_CONFIG_MASK;
+
rc = p4_validate_raw_event(event);
if (rc)
goto out;
/*
- * We don't control raw events so it's up to the caller
- * to pass sane values (and we don't count the thread number
- * on HT machine but allow HT-compatible specifics to be
- * passed on)
- *
* Note that for RAW events we allow user to use P4_CCCR_RESERVED
* bits since we keep additional info here (for cache events and etc)
- *
- * XXX: HT wide things should check perf_paranoid_cpu() &&
- * CAP_SYS_ADMIN
*/
- event->hw.config |= event->attr.config &
- (p4_config_pack_escr(P4_ESCR_MASK_HT) |
- p4_config_pack_cccr(P4_CCCR_MASK_HT | P4_CCCR_RESERVED));
-
- event->hw.config &= ~P4_CCCR_FORCE_OVF;
+ event->hw.config |= event->attr.config;
}
rc = x86_setup_perfctr(event);
@@ -660,8 +904,12 @@ static int p4_pmu_handle_irq(struct pt_regs *regs)
for (idx = 0; idx < x86_pmu.num_counters; idx++) {
int overflow;
- if (!test_bit(idx, cpuc->active_mask))
+ if (!test_bit(idx, cpuc->active_mask)) {
+ /* catch in-flight IRQs */
+ if (__test_and_clear_bit(idx, cpuc->running))
+ handled++;
continue;
+ }
event = cpuc->events[idx];
hwc = &event->hw;
diff --git a/arch/x86/kernel/cpu/perfctr-watchdog.c b/arch/x86/kernel/cpu/perfctr-watchdog.c
index fb329e9f8494..d9f4ff8fcd69 100644
--- a/arch/x86/kernel/cpu/perfctr-watchdog.c
+++ b/arch/x86/kernel/cpu/perfctr-watchdog.c
@@ -700,11 +700,10 @@ static void probe_nmi_watchdog(void)
{
switch (boot_cpu_data.x86_vendor) {
case X86_VENDOR_AMD:
- if (boot_cpu_data.x86 != 6 && boot_cpu_data.x86 != 15 &&
- boot_cpu_data.x86 != 16 && boot_cpu_data.x86 != 17)
- return;
- wd_ops = &k7_wd_ops;
- break;
+ if (boot_cpu_data.x86 == 6 ||
+ (boot_cpu_data.x86 >= 0xf && boot_cpu_data.x86 <= 0x15))
+ wd_ops = &k7_wd_ops;
+ return;
case X86_VENDOR_INTEL:
/* Work around where perfctr1 doesn't have a working enable
* bit as described in the following errata:
diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c
index d49079515122..c7f64e6f537a 100644
--- a/arch/x86/kernel/cpu/scattered.c
+++ b/arch/x86/kernel/cpu/scattered.c
@@ -44,6 +44,12 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
{ X86_FEATURE_LBRV, CR_EDX, 1, 0x8000000a, 0 },
{ X86_FEATURE_SVML, CR_EDX, 2, 0x8000000a, 0 },
{ X86_FEATURE_NRIPS, CR_EDX, 3, 0x8000000a, 0 },
+ { X86_FEATURE_TSCRATEMSR, CR_EDX, 4, 0x8000000a, 0 },
+ { X86_FEATURE_VMCBCLEAN, CR_EDX, 5, 0x8000000a, 0 },
+ { X86_FEATURE_FLUSHBYASID, CR_EDX, 6, 0x8000000a, 0 },
+ { X86_FEATURE_DECODEASSISTS, CR_EDX, 7, 0x8000000a, 0 },
+ { X86_FEATURE_PAUSEFILTER, CR_EDX,10, 0x8000000a, 0 },
+ { X86_FEATURE_PFTHRESHOLD, CR_EDX,12, 0x8000000a, 0 },
{ 0, 0, 0, 0, 0 }
};
diff --git a/arch/x86/kernel/crash_dump_64.c b/arch/x86/kernel/crash_dump_64.c
index 045b36cada65..994828899e09 100644
--- a/arch/x86/kernel/crash_dump_64.c
+++ b/arch/x86/kernel/crash_dump_64.c
@@ -34,7 +34,7 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
if (!csize)
return 0;
- vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
+ vaddr = ioremap_cache(pfn << PAGE_SHIFT, PAGE_SIZE);
if (!vaddr)
return -ENOMEM;
@@ -46,6 +46,7 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
} else
memcpy(buf, vaddr + offset, csize);
+ set_iounmap_nonlazy();
iounmap(vaddr);
return csize;
}
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 0d6fc71bedb1..0c2b7ef7a34d 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -15,6 +15,7 @@
#include <linux/pfn.h>
#include <linux/suspend.h>
#include <linux/firmware-map.h>
+#include <linux/memblock.h>
#include <asm/e820.h>
#include <asm/proto.h>
@@ -738,73 +739,7 @@ core_initcall(e820_mark_nvs_memory);
#endif
/*
- * Find a free area with specified alignment in a specific range.
- */
-u64 __init find_e820_area(u64 start, u64 end, u64 size, u64 align)
-{
- int i;
-
- for (i = 0; i < e820.nr_map; i++) {
- struct e820entry *ei = &e820.map[i];
- u64 addr;
- u64 ei_start, ei_last;
-
- if (ei->type != E820_RAM)
- continue;
-
- ei_last = ei->addr + ei->size;
- ei_start = ei->addr;
- addr = find_early_area(ei_start, ei_last, start, end,
- size, align);
-
- if (addr != -1ULL)
- return addr;
- }
- return -1ULL;
-}
-
-u64 __init find_fw_memmap_area(u64 start, u64 end, u64 size, u64 align)
-{
- return find_e820_area(start, end, size, align);
-}
-
-u64 __init get_max_mapped(void)
-{
- u64 end = max_pfn_mapped;
-
- end <<= PAGE_SHIFT;
-
- return end;
-}
-/*
- * Find next free range after *start
- */
-u64 __init find_e820_area_size(u64 start, u64 *sizep, u64 align)
-{
- int i;
-
- for (i = 0; i < e820.nr_map; i++) {
- struct e820entry *ei = &e820.map[i];
- u64 addr;
- u64 ei_start, ei_last;
-
- if (ei->type != E820_RAM)
- continue;
-
- ei_last = ei->addr + ei->size;
- ei_start = ei->addr;
- addr = find_early_area_size(ei_start, ei_last, start,
- sizep, align);
-
- if (addr != -1ULL)
- return addr;
- }
-
- return -1ULL;
-}
-
-/*
- * pre allocated 4k and reserved it in e820
+ * pre allocated 4k and reserved it in memblock and e820_saved
*/
u64 __init early_reserve_e820(u64 startt, u64 sizet, u64 align)
{
@@ -813,8 +748,8 @@ u64 __init early_reserve_e820(u64 startt, u64 sizet, u64 align)
u64 start;
for (start = startt; ; start += size) {
- start = find_e820_area_size(start, &size, align);
- if (!(start + 1))
+ start = memblock_x86_find_in_range_size(start, &size, align);
+ if (start == MEMBLOCK_ERROR)
return 0;
if (size >= sizet)
break;
@@ -830,10 +765,9 @@ u64 __init early_reserve_e820(u64 startt, u64 sizet, u64 align)
addr = round_down(start + size - sizet, align);
if (addr < start)
return 0;
- e820_update_range(addr, sizet, E820_RAM, E820_RESERVED);
+ memblock_x86_reserve_range(addr, addr + sizet, "new next");
e820_update_range_saved(addr, sizet, E820_RAM, E820_RESERVED);
- printk(KERN_INFO "update e820 for early_reserve_e820\n");
- update_e820();
+ printk(KERN_INFO "update e820_saved for early_reserve_e820\n");
update_e820_saved();
return addr;
@@ -895,74 +829,6 @@ unsigned long __init e820_end_of_low_ram_pfn(void)
{
return e820_end_pfn(1UL<<(32 - PAGE_SHIFT), E820_RAM);
}
-/*
- * Finds an active region in the address range from start_pfn to last_pfn and
- * returns its range in ei_startpfn and ei_endpfn for the e820 entry.
- */
-int __init e820_find_active_region(const struct e820entry *ei,
- unsigned long start_pfn,
- unsigned long last_pfn,
- unsigned long *ei_startpfn,
- unsigned long *ei_endpfn)
-{
- u64 align = PAGE_SIZE;
-
- *ei_startpfn = round_up(ei->addr, align) >> PAGE_SHIFT;
- *ei_endpfn = round_down(ei->addr + ei->size, align) >> PAGE_SHIFT;
-
- /* Skip map entries smaller than a page */
- if (*ei_startpfn >= *ei_endpfn)
- return 0;
-
- /* Skip if map is outside the node */
- if (ei->type != E820_RAM || *ei_endpfn <= start_pfn ||
- *ei_startpfn >= last_pfn)
- return 0;
-
- /* Check for overlaps */
- if (*ei_startpfn < start_pfn)
- *ei_startpfn = start_pfn;
- if (*ei_endpfn > last_pfn)
- *ei_endpfn = last_pfn;
-
- return 1;
-}
-
-/* Walk the e820 map and register active regions within a node */
-void __init e820_register_active_regions(int nid, unsigned long start_pfn,
- unsigned long last_pfn)
-{
- unsigned long ei_startpfn;
- unsigned long ei_endpfn;
- int i;
-
- for (i = 0; i < e820.nr_map; i++)
- if (e820_find_active_region(&e820.map[i],
- start_pfn, last_pfn,
- &ei_startpfn, &ei_endpfn))
- add_active_range(nid, ei_startpfn, ei_endpfn);
-}
-
-/*
- * Find the hole size (in bytes) in the memory range.
- * @start: starting address of the memory range to scan
- * @end: ending address of the memory range to scan
- */
-u64 __init e820_hole_size(u64 start, u64 end)
-{
- unsigned long start_pfn = start >> PAGE_SHIFT;
- unsigned long last_pfn = end >> PAGE_SHIFT;
- unsigned long ei_startpfn, ei_endpfn, ram = 0;
- int i;
-
- for (i = 0; i < e820.nr_map; i++) {
- if (e820_find_active_region(&e820.map[i],
- start_pfn, last_pfn,
- &ei_startpfn, &ei_endpfn))
- ram += ei_endpfn - ei_startpfn;
- }
- return end - start - ((u64)ram << PAGE_SHIFT);
-}
static void early_panic(char *msg)
{
@@ -1210,3 +1076,48 @@ void __init setup_memory_map(void)
printk(KERN_INFO "BIOS-provided physical RAM map:\n");
e820_print_map(who);
}
+
+void __init memblock_x86_fill(void)
+{
+ int i;
+ u64 end;
+
+ /*
+ * EFI may have more than 128 entries
+ * We are safe to enable resizing, beause memblock_x86_fill()
+ * is rather later for x86
+ */
+ memblock_can_resize = 1;
+
+ for (i = 0; i < e820.nr_map; i++) {
+ struct e820entry *ei = &e820.map[i];
+
+ end = ei->addr + ei->size;
+ if (end != (resource_size_t)end)
+ continue;
+
+ if (ei->type != E820_RAM && ei->type != E820_RESERVED_KERN)
+ continue;
+
+ memblock_add(ei->addr, ei->size);
+ }
+
+ memblock_analyze();
+ memblock_dump_all();
+}
+
+void __init memblock_find_dma_reserve(void)
+{
+#ifdef CONFIG_X86_64
+ u64 free_size_pfn;
+ u64 mem_size_pfn;
+ /*
+ * need to find out used area below MAX_DMA_PFN
+ * need to use memblock to get free size in [0, MAX_DMA_PFN]
+ * at first, and assume boot_mem will not take below MAX_DMA_PFN
+ */
+ mem_size_pfn = memblock_x86_memory_in_range(0, MAX_DMA_PFN << PAGE_SHIFT) >> PAGE_SHIFT;
+ free_size_pfn = memblock_x86_free_memory_in_range(0, MAX_DMA_PFN << PAGE_SHIFT) >> PAGE_SHIFT;
+ set_dma_reserve(mem_size_pfn - free_size_pfn);
+#endif
+}
diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
index ebdb85cf2686..76b8cd953dee 100644
--- a/arch/x86/kernel/early-quirks.c
+++ b/arch/x86/kernel/early-quirks.c
@@ -97,7 +97,6 @@ static void __init nvidia_bugs(int num, int slot, int func)
}
#if defined(CONFIG_ACPI) && defined(CONFIG_X86_IO_APIC)
-#if defined(CONFIG_ACPI) && defined(CONFIG_X86_IO_APIC)
static u32 __init ati_ixp4x0_rev(int num, int slot, int func)
{
u32 d;
@@ -115,7 +114,6 @@ static u32 __init ati_ixp4x0_rev(int num, int slot, int func)
d &= 0xff;
return d;
}
-#endif
static void __init ati_bugs(int num, int slot, int func)
{
diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c
index fa99bae75ace..4572f25f9325 100644
--- a/arch/x86/kernel/early_printk.c
+++ b/arch/x86/kernel/early_printk.c
@@ -14,6 +14,7 @@
#include <xen/hvc-console.h>
#include <asm/pci-direct.h>
#include <asm/fixmap.h>
+#include <asm/mrst.h>
#include <asm/pgtable.h>
#include <linux/usb/ehci_def.h>
@@ -239,6 +240,18 @@ static int __init setup_early_printk(char *buf)
if (!strncmp(buf, "xen", 3))
early_console_register(&xenboot_console, keep);
#endif
+#ifdef CONFIG_X86_MRST_EARLY_PRINTK
+ if (!strncmp(buf, "mrst", 4)) {
+ mrst_early_console_init();
+ early_console_register(&early_mrst_console, keep);
+ }
+
+ if (!strncmp(buf, "hsu", 3)) {
+ hsu_early_console_init();
+ early_console_register(&early_hsu_console, keep);
+ }
+
+#endif
buf++;
}
return 0;
diff --git a/arch/x86/kernel/early_printk_mrst.c b/arch/x86/kernel/early_printk_mrst.c
new file mode 100644
index 000000000000..65df603622b2
--- /dev/null
+++ b/arch/x86/kernel/early_printk_mrst.c
@@ -0,0 +1,319 @@
+/*
+ * early_printk_mrst.c - early consoles for Intel MID platforms
+ *
+ * Copyright (c) 2008-2010, Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+
+/*
+ * This file implements two early consoles named mrst and hsu.
+ * mrst is based on Maxim3110 spi-uart device, it exists in both
+ * Moorestown and Medfield platforms, while hsu is based on a High
+ * Speed UART device which only exists in the Medfield platform
+ */
+
+#include <linux/serial_reg.h>
+#include <linux/serial_mfd.h>
+#include <linux/kmsg_dump.h>
+#include <linux/console.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <asm/fixmap.h>
+#include <asm/pgtable.h>
+#include <asm/mrst.h>
+
+#define MRST_SPI_TIMEOUT 0x200000
+#define MRST_REGBASE_SPI0 0xff128000
+#define MRST_REGBASE_SPI1 0xff128400
+#define MRST_CLK_SPI0_REG 0xff11d86c
+
+/* Bit fields in CTRLR0 */
+#define SPI_DFS_OFFSET 0
+
+#define SPI_FRF_OFFSET 4
+#define SPI_FRF_SPI 0x0
+#define SPI_FRF_SSP 0x1
+#define SPI_FRF_MICROWIRE 0x2
+#define SPI_FRF_RESV 0x3
+
+#define SPI_MODE_OFFSET 6
+#define SPI_SCPH_OFFSET 6
+#define SPI_SCOL_OFFSET 7
+#define SPI_TMOD_OFFSET 8
+#define SPI_TMOD_TR 0x0 /* xmit & recv */
+#define SPI_TMOD_TO 0x1 /* xmit only */
+#define SPI_TMOD_RO 0x2 /* recv only */
+#define SPI_TMOD_EPROMREAD 0x3 /* eeprom read mode */
+
+#define SPI_SLVOE_OFFSET 10
+#define SPI_SRL_OFFSET 11
+#define SPI_CFS_OFFSET 12
+
+/* Bit fields in SR, 7 bits */
+#define SR_MASK 0x7f /* cover 7 bits */
+#define SR_BUSY (1 << 0)
+#define SR_TF_NOT_FULL (1 << 1)
+#define SR_TF_EMPT (1 << 2)
+#define SR_RF_NOT_EMPT (1 << 3)
+#define SR_RF_FULL (1 << 4)
+#define SR_TX_ERR (1 << 5)
+#define SR_DCOL (1 << 6)
+
+struct dw_spi_reg {
+ u32 ctrl0;
+ u32 ctrl1;
+ u32 ssienr;
+ u32 mwcr;
+ u32 ser;
+ u32 baudr;
+ u32 txfltr;
+ u32 rxfltr;
+ u32 txflr;
+ u32 rxflr;
+ u32 sr;
+ u32 imr;
+ u32 isr;
+ u32 risr;
+ u32 txoicr;
+ u32 rxoicr;
+ u32 rxuicr;
+ u32 msticr;
+ u32 icr;
+ u32 dmacr;
+ u32 dmatdlr;
+ u32 dmardlr;
+ u32 idr;
+ u32 version;
+
+ /* Currently operates as 32 bits, though only the low 16 bits matter */
+ u32 dr;
+} __packed;
+
+#define dw_readl(dw, name) __raw_readl(&(dw)->name)
+#define dw_writel(dw, name, val) __raw_writel((val), &(dw)->name)
+
+/* Default use SPI0 register for mrst, we will detect Penwell and use SPI1 */
+static unsigned long mrst_spi_paddr = MRST_REGBASE_SPI0;
+
+static u32 *pclk_spi0;
+/* Always contains an accessable address, start with 0 */
+static struct dw_spi_reg *pspi;
+
+static struct kmsg_dumper dw_dumper;
+static int dumper_registered;
+
+static void dw_kmsg_dump(struct kmsg_dumper *dumper,
+ enum kmsg_dump_reason reason,
+ const char *s1, unsigned long l1,
+ const char *s2, unsigned long l2)
+{
+ int i;
+
+ /* When run to this, we'd better re-init the HW */
+ mrst_early_console_init();
+
+ for (i = 0; i < l1; i++)
+ early_mrst_console.write(&early_mrst_console, s1 + i, 1);
+ for (i = 0; i < l2; i++)
+ early_mrst_console.write(&early_mrst_console, s2 + i, 1);
+}
+
+/* Set the ratio rate to 115200, 8n1, IRQ disabled */
+static void max3110_write_config(void)
+{
+ u16 config;
+
+ config = 0xc001;
+ dw_writel(pspi, dr, config);
+}
+
+/* Translate char to a eligible word and send to max3110 */
+static void max3110_write_data(char c)
+{
+ u16 data;
+
+ data = 0x8000 | c;
+ dw_writel(pspi, dr, data);
+}
+
+void mrst_early_console_init(void)
+{
+ u32 ctrlr0 = 0;
+ u32 spi0_cdiv;
+ u32 freq; /* Freqency info only need be searched once */
+
+ /* Base clk is 100 MHz, the actual clk = 100M / (clk_divider + 1) */
+ pclk_spi0 = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE,
+ MRST_CLK_SPI0_REG);
+ spi0_cdiv = ((*pclk_spi0) & 0xe00) >> 9;
+ freq = 100000000 / (spi0_cdiv + 1);
+
+ if (mrst_identify_cpu() == MRST_CPU_CHIP_PENWELL)
+ mrst_spi_paddr = MRST_REGBASE_SPI1;
+
+ pspi = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE,
+ mrst_spi_paddr);
+
+ /* Disable SPI controller */
+ dw_writel(pspi, ssienr, 0);
+
+ /* Set control param, 8 bits, transmit only mode */
+ ctrlr0 = dw_readl(pspi, ctrl0);
+
+ ctrlr0 &= 0xfcc0;
+ ctrlr0 |= 0xf | (SPI_FRF_SPI << SPI_FRF_OFFSET)
+ | (SPI_TMOD_TO << SPI_TMOD_OFFSET);
+ dw_writel(pspi, ctrl0, ctrlr0);
+
+ /*
+ * Change the spi0 clk to comply with 115200 bps, use 100000 to
+ * calculate the clk dividor to make the clock a little slower
+ * than real baud rate.
+ */
+ dw_writel(pspi, baudr, freq/100000);
+
+ /* Disable all INT for early phase */
+ dw_writel(pspi, imr, 0x0);
+
+ /* Set the cs to spi-uart */
+ dw_writel(pspi, ser, 0x2);
+
+ /* Enable the HW, the last step for HW init */
+ dw_writel(pspi, ssienr, 0x1);
+
+ /* Set the default configuration */
+ max3110_write_config();
+
+ /* Register the kmsg dumper */
+ if (!dumper_registered) {
+ dw_dumper.dump = dw_kmsg_dump;
+ kmsg_dump_register(&dw_dumper);
+ dumper_registered = 1;
+ }
+}
+
+/* Slave select should be called in the read/write function */
+static void early_mrst_spi_putc(char c)
+{
+ unsigned int timeout;
+ u32 sr;
+
+ timeout = MRST_SPI_TIMEOUT;
+ /* Early putc needs to make sure the TX FIFO is not full */
+ while (--timeout) {
+ sr = dw_readl(pspi, sr);
+ if (!(sr & SR_TF_NOT_FULL))
+ cpu_relax();
+ else
+ break;
+ }
+
+ if (!timeout)
+ pr_warning("MRST earlycon: timed out\n");
+ else
+ max3110_write_data(c);
+}
+
+/* Early SPI only uses polling mode */
+static void early_mrst_spi_write(struct console *con, const char *str, unsigned n)
+{
+ int i;
+
+ for (i = 0; i < n && *str; i++) {
+ if (*str == '\n')
+ early_mrst_spi_putc('\r');
+ early_mrst_spi_putc(*str);
+ str++;
+ }
+}
+
+struct console early_mrst_console = {
+ .name = "earlymrst",
+ .write = early_mrst_spi_write,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+};
+
+/*
+ * Following is the early console based on Medfield HSU (High
+ * Speed UART) device.
+ */
+#define HSU_PORT2_PADDR 0xffa28180
+
+static void __iomem *phsu;
+
+void hsu_early_console_init(void)
+{
+ u8 lcr;
+
+ phsu = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE,
+ HSU_PORT2_PADDR);
+
+ /* Disable FIFO */
+ writeb(0x0, phsu + UART_FCR);
+
+ /* Set to default 115200 bps, 8n1 */
+ lcr = readb(phsu + UART_LCR);
+ writeb((0x80 | lcr), phsu + UART_LCR);
+ writeb(0x18, phsu + UART_DLL);
+ writeb(lcr, phsu + UART_LCR);
+ writel(0x3600, phsu + UART_MUL*4);
+
+ writeb(0x8, phsu + UART_MCR);
+ writeb(0x7, phsu + UART_FCR);
+ writeb(0x3, phsu + UART_LCR);
+
+ /* Clear IRQ status */
+ readb(phsu + UART_LSR);
+ readb(phsu + UART_RX);
+ readb(phsu + UART_IIR);
+ readb(phsu + UART_MSR);
+
+ /* Enable FIFO */
+ writeb(0x7, phsu + UART_FCR);
+}
+
+#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
+
+static void early_hsu_putc(char ch)
+{
+ unsigned int timeout = 10000; /* 10ms */
+ u8 status;
+
+ while (--timeout) {
+ status = readb(phsu + UART_LSR);
+ if (status & BOTH_EMPTY)
+ break;
+ udelay(1);
+ }
+
+ /* Only write the char when there was no timeout */
+ if (timeout)
+ writeb(ch, phsu + UART_TX);
+}
+
+static void early_hsu_write(struct console *con, const char *str, unsigned n)
+{
+ int i;
+
+ for (i = 0; i < n && *str; i++) {
+ if (*str == '\n')
+ early_hsu_putc('\r');
+ early_hsu_putc(*str);
+ str++;
+ }
+}
+
+struct console early_hsu_console = {
+ .name = "earlyhsu",
+ .write = early_hsu_write,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+};
diff --git a/arch/x86/kernel/efi.c b/arch/x86/kernel/efi.c
index c2fa9b8b497e..0fe27d7c6258 100644
--- a/arch/x86/kernel/efi.c
+++ b/arch/x86/kernel/efi.c
@@ -30,6 +30,7 @@
#include <linux/init.h>
#include <linux/efi.h>
#include <linux/bootmem.h>
+#include <linux/memblock.h>
#include <linux/spinlock.h>
#include <linux/uaccess.h>
#include <linux/time.h>
@@ -275,7 +276,7 @@ static void __init do_add_efi_memmap(void)
sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
}
-void __init efi_reserve_early(void)
+void __init efi_memblock_x86_reserve_range(void)
{
unsigned long pmap;
@@ -290,7 +291,7 @@ void __init efi_reserve_early(void)
boot_params.efi_info.efi_memdesc_size;
memmap.desc_version = boot_params.efi_info.efi_memdesc_version;
memmap.desc_size = boot_params.efi_info.efi_memdesc_size;
- reserve_early(pmap, pmap + memmap.nr_map * memmap.desc_size,
+ memblock_x86_reserve_range(pmap, pmap + memmap.nr_map * memmap.desc_size,
"EFI memmap");
}
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 227d00920d2f..59e175e89599 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -115,8 +115,7 @@
/* unfortunately push/pop can't be no-op */
.macro PUSH_GS
- pushl $0
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi $0
.endm
.macro POP_GS pop=0
addl $(4 + \pop), %esp
@@ -140,14 +139,12 @@
#else /* CONFIG_X86_32_LAZY_GS */
.macro PUSH_GS
- pushl %gs
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %gs
/*CFI_REL_OFFSET gs, 0*/
.endm
.macro POP_GS pop=0
-98: popl %gs
- CFI_ADJUST_CFA_OFFSET -4
+98: popl_cfi %gs
/*CFI_RESTORE gs*/
.if \pop <> 0
add $\pop, %esp
@@ -195,35 +192,25 @@
.macro SAVE_ALL
cld
PUSH_GS
- pushl %fs
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %fs
/*CFI_REL_OFFSET fs, 0;*/
- pushl %es
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %es
/*CFI_REL_OFFSET es, 0;*/
- pushl %ds
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %ds
/*CFI_REL_OFFSET ds, 0;*/
- pushl %eax
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %eax
CFI_REL_OFFSET eax, 0
- pushl %ebp
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %ebp
CFI_REL_OFFSET ebp, 0
- pushl %edi
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %edi
CFI_REL_OFFSET edi, 0
- pushl %esi
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %esi
CFI_REL_OFFSET esi, 0
- pushl %edx
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %edx
CFI_REL_OFFSET edx, 0
- pushl %ecx
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %ecx
CFI_REL_OFFSET ecx, 0
- pushl %ebx
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %ebx
CFI_REL_OFFSET ebx, 0
movl $(__USER_DS), %edx
movl %edx, %ds
@@ -234,39 +221,29 @@
.endm
.macro RESTORE_INT_REGS
- popl %ebx
- CFI_ADJUST_CFA_OFFSET -4
+ popl_cfi %ebx
CFI_RESTORE ebx
- popl %ecx
- CFI_ADJUST_CFA_OFFSET -4
+ popl_cfi %ecx
CFI_RESTORE ecx
- popl %edx
- CFI_ADJUST_CFA_OFFSET -4
+ popl_cfi %edx
CFI_RESTORE edx
- popl %esi
- CFI_ADJUST_CFA_OFFSET -4
+ popl_cfi %esi
CFI_RESTORE esi
- popl %edi
- CFI_ADJUST_CFA_OFFSET -4
+ popl_cfi %edi
CFI_RESTORE edi
- popl %ebp
- CFI_ADJUST_CFA_OFFSET -4
+ popl_cfi %ebp
CFI_RESTORE ebp
- popl %eax
- CFI_ADJUST_CFA_OFFSET -4
+ popl_cfi %eax
CFI_RESTORE eax
.endm
.macro RESTORE_REGS pop=0
RESTORE_INT_REGS
-1: popl %ds
- CFI_ADJUST_CFA_OFFSET -4
+1: popl_cfi %ds
/*CFI_RESTORE ds;*/
-2: popl %es
- CFI_ADJUST_CFA_OFFSET -4
+2: popl_cfi %es
/*CFI_RESTORE es;*/
-3: popl %fs
- CFI_ADJUST_CFA_OFFSET -4
+3: popl_cfi %fs
/*CFI_RESTORE fs;*/
POP_GS \pop
.pushsection .fixup, "ax"
@@ -320,16 +297,12 @@
ENTRY(ret_from_fork)
CFI_STARTPROC
- pushl %eax
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %eax
call schedule_tail
GET_THREAD_INFO(%ebp)
- popl %eax
- CFI_ADJUST_CFA_OFFSET -4
- pushl $0x0202 # Reset kernel eflags
- CFI_ADJUST_CFA_OFFSET 4
- popfl
- CFI_ADJUST_CFA_OFFSET -4
+ popl_cfi %eax
+ pushl_cfi $0x0202 # Reset kernel eflags
+ popfl_cfi
jmp syscall_exit
CFI_ENDPROC
END(ret_from_fork)
@@ -409,29 +382,23 @@ sysenter_past_esp:
* enough kernel state to call TRACE_IRQS_OFF can be called - but
* we immediately enable interrupts at that point anyway.
*/
- pushl $(__USER_DS)
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi $__USER_DS
/*CFI_REL_OFFSET ss, 0*/
- pushl %ebp
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %ebp
CFI_REL_OFFSET esp, 0
- pushfl
+ pushfl_cfi
orl $X86_EFLAGS_IF, (%esp)
- CFI_ADJUST_CFA_OFFSET 4
- pushl $(__USER_CS)
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi $__USER_CS
/*CFI_REL_OFFSET cs, 0*/
/*
* Push current_thread_info()->sysenter_return to the stack.
* A tiny bit of offset fixup is necessary - 4*4 means the 4 words
* pushed above; +8 corresponds to copy_thread's esp0 setting.
*/
- pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi (TI_sysenter_return-THREAD_SIZE_asm+8+4*4)(%esp)
CFI_REL_OFFSET eip, 0
- pushl %eax
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %eax
SAVE_ALL
ENABLE_INTERRUPTS(CLBR_NONE)
@@ -486,8 +453,7 @@ sysenter_audit:
movl %eax,%edx /* 2nd arg: syscall number */
movl $AUDIT_ARCH_I386,%eax /* 1st arg: audit arch */
call audit_syscall_entry
- pushl %ebx
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %ebx
movl PT_EAX(%esp),%eax /* reload syscall number */
jmp sysenter_do_call
@@ -529,8 +495,7 @@ ENDPROC(ia32_sysenter_target)
# system call handler stub
ENTRY(system_call)
RING0_INT_FRAME # can't unwind into user space anyway
- pushl %eax # save orig_eax
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %eax # save orig_eax
SAVE_ALL
GET_THREAD_INFO(%ebp)
# system call tracing in operation / emulation
@@ -566,7 +531,6 @@ restore_all_notrace:
je ldt_ss # returning to user-space with LDT SS
restore_nocheck:
RESTORE_REGS 4 # skip orig_eax/error_code
- CFI_ADJUST_CFA_OFFSET -4
irq_return:
INTERRUPT_RETURN
.section .fixup,"ax"
@@ -619,10 +583,8 @@ ldt_ss:
shr $16, %edx
mov %dl, GDT_ESPFIX_SS + 4 /* bits 16..23 */
mov %dh, GDT_ESPFIX_SS + 7 /* bits 24..31 */
- pushl $__ESPFIX_SS
- CFI_ADJUST_CFA_OFFSET 4
- push %eax /* new kernel esp */
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi $__ESPFIX_SS
+ pushl_cfi %eax /* new kernel esp */
/* Disable interrupts, but do not irqtrace this section: we
* will soon execute iret and the tracer was already set to
* the irqstate after the iret */
@@ -666,11 +628,9 @@ work_notifysig: # deal with pending signals and
ALIGN
work_notifysig_v86:
- pushl %ecx # save ti_flags for do_notify_resume
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %ecx # save ti_flags for do_notify_resume
call save_v86_state # %eax contains pt_regs pointer
- popl %ecx
- CFI_ADJUST_CFA_OFFSET -4
+ popl_cfi %ecx
movl %eax, %esp
#else
movl %esp, %eax
@@ -750,14 +710,18 @@ ptregs_##name: \
#define PTREGSCALL3(name) \
ALIGN; \
ptregs_##name: \
+ CFI_STARTPROC; \
leal 4(%esp),%eax; \
- pushl %eax; \
+ pushl_cfi %eax; \
movl PT_EDX(%eax),%ecx; \
movl PT_ECX(%eax),%edx; \
movl PT_EBX(%eax),%eax; \
call sys_##name; \
addl $4,%esp; \
- ret
+ CFI_ADJUST_CFA_OFFSET -4; \
+ ret; \
+ CFI_ENDPROC; \
+ENDPROC(ptregs_##name)
PTREGSCALL1(iopl)
PTREGSCALL0(fork)
@@ -772,15 +736,19 @@ PTREGSCALL1(vm86old)
/* Clone is an oddball. The 4th arg is in %edi */
ALIGN;
ptregs_clone:
+ CFI_STARTPROC
leal 4(%esp),%eax
- pushl %eax
- pushl PT_EDI(%eax)
+ pushl_cfi %eax
+ pushl_cfi PT_EDI(%eax)
movl PT_EDX(%eax),%ecx
movl PT_ECX(%eax),%edx
movl PT_EBX(%eax),%eax
call sys_clone
addl $8,%esp
+ CFI_ADJUST_CFA_OFFSET -8
ret
+ CFI_ENDPROC
+ENDPROC(ptregs_clone)
.macro FIXUP_ESPFIX_STACK
/*
@@ -795,10 +763,8 @@ ptregs_clone:
mov GDT_ESPFIX_SS + 7, %ah /* bits 24..31 */
shl $16, %eax
addl %esp, %eax /* the adjusted stack pointer */
- pushl $__KERNEL_DS
- CFI_ADJUST_CFA_OFFSET 4
- pushl %eax
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi $__KERNEL_DS
+ pushl_cfi %eax
lss (%esp), %esp /* switch to the normal stack segment */
CFI_ADJUST_CFA_OFFSET -8
.endm
@@ -835,8 +801,7 @@ vector=FIRST_EXTERNAL_VECTOR
.if vector <> FIRST_EXTERNAL_VECTOR
CFI_ADJUST_CFA_OFFSET -4
.endif
-1: pushl $(~vector+0x80) /* Note: always in signed byte range */
- CFI_ADJUST_CFA_OFFSET 4
+1: pushl_cfi $(~vector+0x80) /* Note: always in signed byte range */
.if ((vector-FIRST_EXTERNAL_VECTOR)%7) <> 6
jmp 2f
.endif
@@ -876,8 +841,7 @@ ENDPROC(common_interrupt)
#define BUILD_INTERRUPT3(name, nr, fn) \
ENTRY(name) \
RING0_INT_FRAME; \
- pushl $~(nr); \
- CFI_ADJUST_CFA_OFFSET 4; \
+ pushl_cfi $~(nr); \
SAVE_ALL; \
TRACE_IRQS_OFF \
movl %esp,%eax; \
@@ -893,21 +857,18 @@ ENDPROC(name)
ENTRY(coprocessor_error)
RING0_INT_FRAME
- pushl $0
- CFI_ADJUST_CFA_OFFSET 4
- pushl $do_coprocessor_error
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi $0
+ pushl_cfi $do_coprocessor_error
jmp error_code
CFI_ENDPROC
END(coprocessor_error)
ENTRY(simd_coprocessor_error)
RING0_INT_FRAME
- pushl $0
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi $0
#ifdef CONFIG_X86_INVD_BUG
/* AMD 486 bug: invd from userspace calls exception 19 instead of #GP */
-661: pushl $do_general_protection
+661: pushl_cfi $do_general_protection
662:
.section .altinstructions,"a"
.balign 4
@@ -922,19 +883,16 @@ ENTRY(simd_coprocessor_error)
664:
.previous
#else
- pushl $do_simd_coprocessor_error
+ pushl_cfi $do_simd_coprocessor_error
#endif
- CFI_ADJUST_CFA_OFFSET 4
jmp error_code
CFI_ENDPROC
END(simd_coprocessor_error)
ENTRY(device_not_available)
RING0_INT_FRAME
- pushl $-1 # mark this as an int
- CFI_ADJUST_CFA_OFFSET 4
- pushl $do_device_not_available
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi $-1 # mark this as an int
+ pushl_cfi $do_device_not_available
jmp error_code
CFI_ENDPROC
END(device_not_available)
@@ -956,82 +914,68 @@ END(native_irq_enable_sysexit)
ENTRY(overflow)
RING0_INT_FRAME
- pushl $0
- CFI_ADJUST_CFA_OFFSET 4
- pushl $do_overflow
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi $0
+ pushl_cfi $do_overflow
jmp error_code
CFI_ENDPROC
END(overflow)
ENTRY(bounds)
RING0_INT_FRAME
- pushl $0
- CFI_ADJUST_CFA_OFFSET 4
- pushl $do_bounds
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi $0
+ pushl_cfi $do_bounds
jmp error_code
CFI_ENDPROC
END(bounds)
ENTRY(invalid_op)
RING0_INT_FRAME
- pushl $0
- CFI_ADJUST_CFA_OFFSET 4
- pushl $do_invalid_op
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi $0
+ pushl_cfi $do_invalid_op
jmp error_code
CFI_ENDPROC
END(invalid_op)
ENTRY(coprocessor_segment_overrun)
RING0_INT_FRAME
- pushl $0
- CFI_ADJUST_CFA_OFFSET 4
- pushl $do_coprocessor_segment_overrun
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi $0
+ pushl_cfi $do_coprocessor_segment_overrun
jmp error_code
CFI_ENDPROC
END(coprocessor_segment_overrun)
ENTRY(invalid_TSS)
RING0_EC_FRAME
- pushl $do_invalid_TSS
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi $do_invalid_TSS
jmp error_code
CFI_ENDPROC
END(invalid_TSS)
ENTRY(segment_not_present)
RING0_EC_FRAME
- pushl $do_segment_not_present
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi $do_segment_not_present
jmp error_code
CFI_ENDPROC
END(segment_not_present)
ENTRY(stack_segment)
RING0_EC_FRAME
- pushl $do_stack_segment
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi $do_stack_segment
jmp error_code
CFI_ENDPROC
END(stack_segment)
ENTRY(alignment_check)
RING0_EC_FRAME
- pushl $do_alignment_check
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi $do_alignment_check
jmp error_code
CFI_ENDPROC
END(alignment_check)
ENTRY(divide_error)
RING0_INT_FRAME
- pushl $0 # no error code
- CFI_ADJUST_CFA_OFFSET 4
- pushl $do_divide_error
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi $0 # no error code
+ pushl_cfi $do_divide_error
jmp error_code
CFI_ENDPROC
END(divide_error)
@@ -1039,10 +983,8 @@ END(divide_error)
#ifdef CONFIG_X86_MCE
ENTRY(machine_check)
RING0_INT_FRAME
- pushl $0
- CFI_ADJUST_CFA_OFFSET 4
- pushl machine_check_vector
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi $0
+ pushl_cfi machine_check_vector
jmp error_code
CFI_ENDPROC
END(machine_check)
@@ -1050,10 +992,8 @@ END(machine_check)
ENTRY(spurious_interrupt_bug)
RING0_INT_FRAME
- pushl $0
- CFI_ADJUST_CFA_OFFSET 4
- pushl $do_spurious_interrupt_bug
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi $0
+ pushl_cfi $do_spurious_interrupt_bug
jmp error_code
CFI_ENDPROC
END(spurious_interrupt_bug)
@@ -1084,8 +1024,7 @@ ENTRY(xen_sysenter_target)
ENTRY(xen_hypervisor_callback)
CFI_STARTPROC
- pushl $0
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi $0
SAVE_ALL
TRACE_IRQS_OFF
@@ -1121,23 +1060,20 @@ ENDPROC(xen_hypervisor_callback)
# We distinguish between categories by maintaining a status value in EAX.
ENTRY(xen_failsafe_callback)
CFI_STARTPROC
- pushl %eax
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %eax
movl $1,%eax
1: mov 4(%esp),%ds
2: mov 8(%esp),%es
3: mov 12(%esp),%fs
4: mov 16(%esp),%gs
testl %eax,%eax
- popl %eax
- CFI_ADJUST_CFA_OFFSET -4
+ popl_cfi %eax
lea 16(%esp),%esp
CFI_ADJUST_CFA_OFFSET -16
jz 5f
addl $16,%esp
jmp iret_exc # EAX != 0 => Category 2 (Bad IRET)
-5: pushl $0 # EAX == 0 => Category 1 (Bad segment)
- CFI_ADJUST_CFA_OFFSET 4
+5: pushl_cfi $0 # EAX == 0 => Category 1 (Bad segment)
SAVE_ALL
jmp ret_from_exception
CFI_ENDPROC
@@ -1287,40 +1223,29 @@ syscall_table_size=(.-sys_call_table)
ENTRY(page_fault)
RING0_EC_FRAME
- pushl $do_page_fault
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi $do_page_fault
ALIGN
error_code:
/* the function address is in %gs's slot on the stack */
- pushl %fs
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %fs
/*CFI_REL_OFFSET fs, 0*/
- pushl %es
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %es
/*CFI_REL_OFFSET es, 0*/
- pushl %ds
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %ds
/*CFI_REL_OFFSET ds, 0*/
- pushl %eax
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %eax
CFI_REL_OFFSET eax, 0
- pushl %ebp
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %ebp
CFI_REL_OFFSET ebp, 0
- pushl %edi
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %edi
CFI_REL_OFFSET edi, 0
- pushl %esi
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %esi
CFI_REL_OFFSET esi, 0
- pushl %edx
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %edx
CFI_REL_OFFSET edx, 0
- pushl %ecx
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %ecx
CFI_REL_OFFSET ecx, 0
- pushl %ebx
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %ebx
CFI_REL_OFFSET ebx, 0
cld
movl $(__KERNEL_PERCPU), %ecx
@@ -1362,12 +1287,9 @@ END(page_fault)
movl TSS_sysenter_sp0 + \offset(%esp), %esp
CFI_DEF_CFA esp, 0
CFI_UNDEFINED eip
- pushfl
- CFI_ADJUST_CFA_OFFSET 4
- pushl $__KERNEL_CS
- CFI_ADJUST_CFA_OFFSET 4
- pushl $sysenter_past_esp
- CFI_ADJUST_CFA_OFFSET 4
+ pushfl_cfi
+ pushl_cfi $__KERNEL_CS
+ pushl_cfi $sysenter_past_esp
CFI_REL_OFFSET eip, 0
.endm
@@ -1377,8 +1299,7 @@ ENTRY(debug)
jne debug_stack_correct
FIX_STACK 12, debug_stack_correct, debug_esp_fix_insn
debug_stack_correct:
- pushl $-1 # mark this as an int
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi $-1 # mark this as an int
SAVE_ALL
TRACE_IRQS_OFF
xorl %edx,%edx # error code 0
@@ -1398,32 +1319,27 @@ END(debug)
*/
ENTRY(nmi)
RING0_INT_FRAME
- pushl %eax
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %eax
movl %ss, %eax
cmpw $__ESPFIX_SS, %ax
- popl %eax
- CFI_ADJUST_CFA_OFFSET -4
+ popl_cfi %eax
je nmi_espfix_stack
cmpl $ia32_sysenter_target,(%esp)
je nmi_stack_fixup
- pushl %eax
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %eax
movl %esp,%eax
/* Do not access memory above the end of our stack page,
* it might not exist.
*/
andl $(THREAD_SIZE-1),%eax
cmpl $(THREAD_SIZE-20),%eax
- popl %eax
- CFI_ADJUST_CFA_OFFSET -4
+ popl_cfi %eax
jae nmi_stack_correct
cmpl $ia32_sysenter_target,12(%esp)
je nmi_debug_stack_check
nmi_stack_correct:
/* We have a RING0_INT_FRAME here */
- pushl %eax
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %eax
SAVE_ALL
xorl %edx,%edx # zero error code
movl %esp,%eax # pt_regs pointer
@@ -1452,18 +1368,14 @@ nmi_espfix_stack:
*
* create the pointer to lss back
*/
- pushl %ss
- CFI_ADJUST_CFA_OFFSET 4
- pushl %esp
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %ss
+ pushl_cfi %esp
addl $4, (%esp)
/* copy the iret frame of 12 bytes */
.rept 3
- pushl 16(%esp)
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi 16(%esp)
.endr
- pushl %eax
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi %eax
SAVE_ALL
FIXUP_ESPFIX_STACK # %eax == %esp
xorl %edx,%edx # zero error code
@@ -1477,8 +1389,7 @@ END(nmi)
ENTRY(int3)
RING0_INT_FRAME
- pushl $-1 # mark this as an int
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi $-1 # mark this as an int
SAVE_ALL
TRACE_IRQS_OFF
xorl %edx,%edx # zero error code
@@ -1490,8 +1401,7 @@ END(int3)
ENTRY(general_protection)
RING0_EC_FRAME
- pushl $do_general_protection
- CFI_ADJUST_CFA_OFFSET 4
+ pushl_cfi $do_general_protection
jmp error_code
CFI_ENDPROC
END(general_protection)
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 17be5ec7cbba..fe2690d71c0c 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -213,23 +213,17 @@ ENDPROC(native_usergs_sysret64)
.macro FAKE_STACK_FRAME child_rip
/* push in order ss, rsp, eflags, cs, rip */
xorl %eax, %eax
- pushq $__KERNEL_DS /* ss */
- CFI_ADJUST_CFA_OFFSET 8
+ pushq_cfi $__KERNEL_DS /* ss */
/*CFI_REL_OFFSET ss,0*/
- pushq %rax /* rsp */
- CFI_ADJUST_CFA_OFFSET 8
+ pushq_cfi %rax /* rsp */
CFI_REL_OFFSET rsp,0
- pushq $X86_EFLAGS_IF /* eflags - interrupts on */
- CFI_ADJUST_CFA_OFFSET 8
+ pushq_cfi $X86_EFLAGS_IF /* eflags - interrupts on */
/*CFI_REL_OFFSET rflags,0*/
- pushq $__KERNEL_CS /* cs */
- CFI_ADJUST_CFA_OFFSET 8
+ pushq_cfi $__KERNEL_CS /* cs */
/*CFI_REL_OFFSET cs,0*/
- pushq \child_rip /* rip */
- CFI_ADJUST_CFA_OFFSET 8
+ pushq_cfi \child_rip /* rip */
CFI_REL_OFFSET rip,0
- pushq %rax /* orig rax */
- CFI_ADJUST_CFA_OFFSET 8
+ pushq_cfi %rax /* orig rax */
.endm
.macro UNFAKE_STACK_FRAME
@@ -398,10 +392,8 @@ ENTRY(ret_from_fork)
LOCK ; btr $TIF_FORK,TI_flags(%r8)
- push kernel_eflags(%rip)
- CFI_ADJUST_CFA_OFFSET 8
- popf # reset kernel eflags
- CFI_ADJUST_CFA_OFFSET -8
+ pushq_cfi kernel_eflags(%rip)
+ popfq_cfi # reset kernel eflags
call schedule_tail # rdi: 'prev' task parameter
@@ -521,11 +513,9 @@ sysret_careful:
jnc sysret_signal
TRACE_IRQS_ON
ENABLE_INTERRUPTS(CLBR_NONE)
- pushq %rdi
- CFI_ADJUST_CFA_OFFSET 8
+ pushq_cfi %rdi
call schedule
- popq %rdi
- CFI_ADJUST_CFA_OFFSET -8
+ popq_cfi %rdi
jmp sysret_check
/* Handle a signal */
@@ -634,11 +624,9 @@ int_careful:
jnc int_very_careful
TRACE_IRQS_ON
ENABLE_INTERRUPTS(CLBR_NONE)
- pushq %rdi
- CFI_ADJUST_CFA_OFFSET 8
+ pushq_cfi %rdi
call schedule
- popq %rdi
- CFI_ADJUST_CFA_OFFSET -8
+ popq_cfi %rdi
DISABLE_INTERRUPTS(CLBR_NONE)
TRACE_IRQS_OFF
jmp int_with_check
@@ -652,12 +640,10 @@ int_check_syscall_exit_work:
/* Check for syscall exit trace */
testl $_TIF_WORK_SYSCALL_EXIT,%edx
jz int_signal
- pushq %rdi
- CFI_ADJUST_CFA_OFFSET 8
+ pushq_cfi %rdi
leaq 8(%rsp),%rdi # &ptregs -> arg1
call syscall_trace_leave
- popq %rdi
- CFI_ADJUST_CFA_OFFSET -8
+ popq_cfi %rdi
andl $~(_TIF_WORK_SYSCALL_EXIT|_TIF_SYSCALL_EMU),%edi
jmp int_restore_rest
@@ -714,9 +700,8 @@ END(ptregscall_common)
ENTRY(stub_execve)
CFI_STARTPROC
- popq %r11
- CFI_ADJUST_CFA_OFFSET -8
- CFI_REGISTER rip, r11
+ addq $8, %rsp
+ PARTIAL_FRAME 0
SAVE_REST
FIXUP_TOP_OF_STACK %r11
movq %rsp, %rcx
@@ -735,7 +720,7 @@ END(stub_execve)
ENTRY(stub_rt_sigreturn)
CFI_STARTPROC
addq $8, %rsp
- CFI_ADJUST_CFA_OFFSET -8
+ PARTIAL_FRAME 0
SAVE_REST
movq %rsp,%rdi
FIXUP_TOP_OF_STACK %r11
@@ -766,8 +751,7 @@ vector=FIRST_EXTERNAL_VECTOR
.if vector <> FIRST_EXTERNAL_VECTOR
CFI_ADJUST_CFA_OFFSET -8
.endif
-1: pushq $(~vector+0x80) /* Note: always in signed byte range */
- CFI_ADJUST_CFA_OFFSET 8
+1: pushq_cfi $(~vector+0x80) /* Note: always in signed byte range */
.if ((vector-FIRST_EXTERNAL_VECTOR)%7) <> 6
jmp 2f
.endif
@@ -796,8 +780,8 @@ END(interrupt)
/* 0(%rsp): ~(interrupt number) */
.macro interrupt func
- subq $10*8, %rsp
- CFI_ADJUST_CFA_OFFSET 10*8
+ subq $ORIG_RAX-ARGOFFSET+8, %rsp
+ CFI_ADJUST_CFA_OFFSET ORIG_RAX-ARGOFFSET+8
call save_args
PARTIAL_FRAME 0
call \func
@@ -822,6 +806,7 @@ ret_from_intr:
TRACE_IRQS_OFF
decl PER_CPU_VAR(irq_count)
leaveq
+ CFI_RESTORE rbp
CFI_DEF_CFA_REGISTER rsp
CFI_ADJUST_CFA_OFFSET -8
exit_intr:
@@ -903,11 +888,9 @@ retint_careful:
jnc retint_signal
TRACE_IRQS_ON
ENABLE_INTERRUPTS(CLBR_NONE)
- pushq %rdi
- CFI_ADJUST_CFA_OFFSET 8
+ pushq_cfi %rdi
call schedule
- popq %rdi
- CFI_ADJUST_CFA_OFFSET -8
+ popq_cfi %rdi
GET_THREAD_INFO(%rcx)
DISABLE_INTERRUPTS(CLBR_NONE)
TRACE_IRQS_OFF
@@ -956,8 +939,7 @@ END(common_interrupt)
.macro apicinterrupt num sym do_sym
ENTRY(\sym)
INTR_FRAME
- pushq $~(\num)
- CFI_ADJUST_CFA_OFFSET 8
+ pushq_cfi $~(\num)
interrupt \do_sym
jmp ret_from_intr
CFI_ENDPROC
@@ -981,22 +963,10 @@ apicinterrupt X86_PLATFORM_IPI_VECTOR \
x86_platform_ipi smp_x86_platform_ipi
#ifdef CONFIG_SMP
-apicinterrupt INVALIDATE_TLB_VECTOR_START+0 \
- invalidate_interrupt0 smp_invalidate_interrupt
-apicinterrupt INVALIDATE_TLB_VECTOR_START+1 \
- invalidate_interrupt1 smp_invalidate_interrupt
-apicinterrupt INVALIDATE_TLB_VECTOR_START+2 \
- invalidate_interrupt2 smp_invalidate_interrupt
-apicinterrupt INVALIDATE_TLB_VECTOR_START+3 \
- invalidate_interrupt3 smp_invalidate_interrupt
-apicinterrupt INVALIDATE_TLB_VECTOR_START+4 \
- invalidate_interrupt4 smp_invalidate_interrupt
-apicinterrupt INVALIDATE_TLB_VECTOR_START+5 \
- invalidate_interrupt5 smp_invalidate_interrupt
-apicinterrupt INVALIDATE_TLB_VECTOR_START+6 \
- invalidate_interrupt6 smp_invalidate_interrupt
-apicinterrupt INVALIDATE_TLB_VECTOR_START+7 \
- invalidate_interrupt7 smp_invalidate_interrupt
+.irpc idx, "01234567"
+apicinterrupt (INVALIDATE_TLB_VECTOR_START)+\idx \
+ invalidate_interrupt\idx smp_invalidate_interrupt
+.endr
#endif
apicinterrupt THRESHOLD_APIC_VECTOR \
@@ -1023,9 +993,9 @@ apicinterrupt ERROR_APIC_VECTOR \
apicinterrupt SPURIOUS_APIC_VECTOR \
spurious_interrupt smp_spurious_interrupt
-#ifdef CONFIG_PERF_EVENTS
-apicinterrupt LOCAL_PENDING_VECTOR \
- perf_pending_interrupt smp_perf_pending_interrupt
+#ifdef CONFIG_IRQ_WORK
+apicinterrupt IRQ_WORK_VECTOR \
+ irq_work_interrupt smp_irq_work_interrupt
#endif
/*
@@ -1036,8 +1006,8 @@ ENTRY(\sym)
INTR_FRAME
PARAVIRT_ADJUST_EXCEPTION_FRAME
pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */
- subq $15*8,%rsp
- CFI_ADJUST_CFA_OFFSET 15*8
+ subq $ORIG_RAX-R15, %rsp
+ CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
call error_entry
DEFAULT_FRAME 0
movq %rsp,%rdi /* pt_regs pointer */
@@ -1052,9 +1022,9 @@ END(\sym)
ENTRY(\sym)
INTR_FRAME
PARAVIRT_ADJUST_EXCEPTION_FRAME
- pushq $-1 /* ORIG_RAX: no syscall to restart */
- CFI_ADJUST_CFA_OFFSET 8
- subq $15*8, %rsp
+ pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */
+ subq $ORIG_RAX-R15, %rsp
+ CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
call save_paranoid
TRACE_IRQS_OFF
movq %rsp,%rdi /* pt_regs pointer */
@@ -1070,9 +1040,9 @@ END(\sym)
ENTRY(\sym)
INTR_FRAME
PARAVIRT_ADJUST_EXCEPTION_FRAME
- pushq $-1 /* ORIG_RAX: no syscall to restart */
- CFI_ADJUST_CFA_OFFSET 8
- subq $15*8, %rsp
+ pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */
+ subq $ORIG_RAX-R15, %rsp
+ CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
call save_paranoid
TRACE_IRQS_OFF
movq %rsp,%rdi /* pt_regs pointer */
@@ -1089,8 +1059,8 @@ END(\sym)
ENTRY(\sym)
XCPT_FRAME
PARAVIRT_ADJUST_EXCEPTION_FRAME
- subq $15*8,%rsp
- CFI_ADJUST_CFA_OFFSET 15*8
+ subq $ORIG_RAX-R15, %rsp
+ CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
call error_entry
DEFAULT_FRAME 0
movq %rsp,%rdi /* pt_regs pointer */
@@ -1107,8 +1077,8 @@ END(\sym)
ENTRY(\sym)
XCPT_FRAME
PARAVIRT_ADJUST_EXCEPTION_FRAME
- subq $15*8,%rsp
- CFI_ADJUST_CFA_OFFSET 15*8
+ subq $ORIG_RAX-R15, %rsp
+ CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
call save_paranoid
DEFAULT_FRAME 0
TRACE_IRQS_OFF
@@ -1139,16 +1109,14 @@ zeroentry simd_coprocessor_error do_simd_coprocessor_error
/* edi: new selector */
ENTRY(native_load_gs_index)
CFI_STARTPROC
- pushf
- CFI_ADJUST_CFA_OFFSET 8
+ pushfq_cfi
DISABLE_INTERRUPTS(CLBR_ANY & ~CLBR_RDI)
SWAPGS
gs_change:
movl %edi,%gs
2: mfence /* workaround */
SWAPGS
- popf
- CFI_ADJUST_CFA_OFFSET -8
+ popfq_cfi
ret
CFI_ENDPROC
END(native_load_gs_index)
@@ -1215,8 +1183,7 @@ END(kernel_execve)
/* Call softirq on interrupt stack. Interrupts are off. */
ENTRY(call_softirq)
CFI_STARTPROC
- push %rbp
- CFI_ADJUST_CFA_OFFSET 8
+ pushq_cfi %rbp
CFI_REL_OFFSET rbp,0
mov %rsp,%rbp
CFI_DEF_CFA_REGISTER rbp
@@ -1225,6 +1192,7 @@ ENTRY(call_softirq)
push %rbp # backlink for old unwinder
call __do_softirq
leaveq
+ CFI_RESTORE rbp
CFI_DEF_CFA_REGISTER rsp
CFI_ADJUST_CFA_OFFSET -8
decl PER_CPU_VAR(irq_count)
@@ -1368,7 +1336,7 @@ paranoidzeroentry machine_check *machine_check_vector(%rip)
/* ebx: no swapgs flag */
ENTRY(paranoid_exit)
- INTR_FRAME
+ DEFAULT_FRAME
DISABLE_INTERRUPTS(CLBR_NONE)
TRACE_IRQS_OFF
testl %ebx,%ebx /* swapgs needed? */
@@ -1445,7 +1413,6 @@ error_swapgs:
error_sti:
TRACE_IRQS_OFF
ret
- CFI_ENDPROC
/*
* There are two places in the kernel that can potentially fault with
@@ -1470,6 +1437,7 @@ bstep_iret:
/* Fix truncated RIP */
movq %rcx,RIP+8(%rsp)
jmp error_swapgs
+ CFI_ENDPROC
END(error_entry)
@@ -1498,8 +1466,8 @@ ENTRY(nmi)
INTR_FRAME
PARAVIRT_ADJUST_EXCEPTION_FRAME
pushq_cfi $-1
- subq $15*8, %rsp
- CFI_ADJUST_CFA_OFFSET 15*8
+ subq $ORIG_RAX-R15, %rsp
+ CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
call save_paranoid
DEFAULT_FRAME 0
/* paranoidentry do_nmi, 0; without TRACE_IRQS_OFF */
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
index cd37469b54ee..3afb33f14d2d 100644
--- a/arch/x86/kernel/ftrace.c
+++ b/arch/x86/kernel/ftrace.c
@@ -257,14 +257,9 @@ do_ftrace_mod_code(unsigned long ip, void *new_code)
return mod_code_status;
}
-
-
-
-static unsigned char ftrace_nop[MCOUNT_INSN_SIZE];
-
static unsigned char *ftrace_nop_replace(void)
{
- return ftrace_nop;
+ return ideal_nop5;
}
static int
@@ -338,62 +333,6 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
int __init ftrace_dyn_arch_init(void *data)
{
- extern const unsigned char ftrace_test_p6nop[];
- extern const unsigned char ftrace_test_nop5[];
- extern const unsigned char ftrace_test_jmp[];
- int faulted = 0;
-
- /*
- * There is no good nop for all x86 archs.
- * We will default to using the P6_NOP5, but first we
- * will test to make sure that the nop will actually
- * work on this CPU. If it faults, we will then
- * go to a lesser efficient 5 byte nop. If that fails
- * we then just use a jmp as our nop. This isn't the most
- * efficient nop, but we can not use a multi part nop
- * since we would then risk being preempted in the middle
- * of that nop, and if we enabled tracing then, it might
- * cause a system crash.
- *
- * TODO: check the cpuid to determine the best nop.
- */
- asm volatile (
- "ftrace_test_jmp:"
- "jmp ftrace_test_p6nop\n"
- "nop\n"
- "nop\n"
- "nop\n" /* 2 byte jmp + 3 bytes */
- "ftrace_test_p6nop:"
- P6_NOP5
- "jmp 1f\n"
- "ftrace_test_nop5:"
- ".byte 0x66,0x66,0x66,0x66,0x90\n"
- "1:"
- ".section .fixup, \"ax\"\n"
- "2: movl $1, %0\n"
- " jmp ftrace_test_nop5\n"
- "3: movl $2, %0\n"
- " jmp 1b\n"
- ".previous\n"
- _ASM_EXTABLE(ftrace_test_p6nop, 2b)
- _ASM_EXTABLE(ftrace_test_nop5, 3b)
- : "=r"(faulted) : "0" (faulted));
-
- switch (faulted) {
- case 0:
- pr_info("converting mcount calls to 0f 1f 44 00 00\n");
- memcpy(ftrace_nop, ftrace_test_p6nop, MCOUNT_INSN_SIZE);
- break;
- case 1:
- pr_info("converting mcount calls to 66 66 66 66 90\n");
- memcpy(ftrace_nop, ftrace_test_nop5, MCOUNT_INSN_SIZE);
- break;
- case 2:
- pr_info("converting mcount calls to jmp . + 5\n");
- memcpy(ftrace_nop, ftrace_test_jmp, MCOUNT_INSN_SIZE);
- break;
- }
-
/* The return code is retured via data */
*(unsigned long *)data = 0;
diff --git a/arch/x86/kernel/head.c b/arch/x86/kernel/head.c
index 3e66bd364a9d..af0699ba48cf 100644
--- a/arch/x86/kernel/head.c
+++ b/arch/x86/kernel/head.c
@@ -1,5 +1,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/memblock.h>
#include <asm/setup.h>
#include <asm/bios_ebda.h>
@@ -51,5 +52,5 @@ void __init reserve_ebda_region(void)
lowmem = 0x9f000;
/* reserve all memory between lowmem and the 1MB mark */
- reserve_early_overlap_ok(lowmem, 0x100000, "BIOS reserved");
+ memblock_x86_reserve_range(lowmem, 0x100000, "* BIOS reserved");
}
diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c
index 784360c0625c..763310165fa0 100644
--- a/arch/x86/kernel/head32.c
+++ b/arch/x86/kernel/head32.c
@@ -8,6 +8,7 @@
#include <linux/init.h>
#include <linux/start_kernel.h>
#include <linux/mm.h>
+#include <linux/memblock.h>
#include <asm/setup.h>
#include <asm/sections.h>
@@ -17,6 +18,7 @@
#include <asm/apic.h>
#include <asm/io_apic.h>
#include <asm/bios_ebda.h>
+#include <asm/tlbflush.h>
static void __init i386_default_early_setup(void)
{
@@ -30,17 +32,18 @@ static void __init i386_default_early_setup(void)
void __init i386_start_kernel(void)
{
+ memblock_init();
+
#ifdef CONFIG_X86_TRAMPOLINE
/*
* But first pinch a few for the stack/trampoline stuff
* FIXME: Don't need the extra page at 4K, but need to fix
* trampoline before removing it. (see the GDT stuff)
*/
- reserve_early_overlap_ok(PAGE_SIZE, PAGE_SIZE + PAGE_SIZE,
- "EX TRAMPOLINE");
+ memblock_x86_reserve_range(PAGE_SIZE, PAGE_SIZE + PAGE_SIZE, "EX TRAMPOLINE");
#endif
- reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");
+ memblock_x86_reserve_range(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");
#ifdef CONFIG_BLK_DEV_INITRD
/* Reserve INITRD */
@@ -49,7 +52,7 @@ void __init i386_start_kernel(void)
u64 ramdisk_image = boot_params.hdr.ramdisk_image;
u64 ramdisk_size = boot_params.hdr.ramdisk_size;
u64 ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size);
- reserve_early(ramdisk_image, ramdisk_end, "RAMDISK");
+ memblock_x86_reserve_range(ramdisk_image, ramdisk_end, "RAMDISK");
}
#endif
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index 7147143fd614..2d2673c28aff 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -12,6 +12,7 @@
#include <linux/percpu.h>
#include <linux/start_kernel.h>
#include <linux/io.h>
+#include <linux/memblock.h>
#include <asm/processor.h>
#include <asm/proto.h>
@@ -79,6 +80,8 @@ void __init x86_64_start_kernel(char * real_mode_data)
/* Cleanup the over mapped high alias */
cleanup_highmap();
+ max_pfn_mapped = KERNEL_IMAGE_SIZE >> PAGE_SHIFT;
+
for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) {
#ifdef CONFIG_EARLY_PRINTK
set_intr_gate(i, &early_idt_handlers[i]);
@@ -98,7 +101,9 @@ void __init x86_64_start_reservations(char *real_mode_data)
{
copy_bootdata(__va(real_mode_data));
- reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");
+ memblock_init();
+
+ memblock_x86_reserve_range(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");
#ifdef CONFIG_BLK_DEV_INITRD
/* Reserve INITRD */
@@ -107,7 +112,7 @@ void __init x86_64_start_reservations(char *real_mode_data)
unsigned long ramdisk_image = boot_params.hdr.ramdisk_image;
unsigned long ramdisk_size = boot_params.hdr.ramdisk_size;
unsigned long ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size);
- reserve_early(ramdisk_image, ramdisk_end, "RAMDISK");
+ memblock_x86_reserve_range(ramdisk_image, ramdisk_end, "RAMDISK");
}
#endif
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index fa8c1b8e09fb..bcece91dd311 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -183,13 +183,12 @@ default_entry:
#ifdef CONFIG_X86_PAE
/*
- * In PAE mode swapper_pg_dir is statically defined to contain enough
- * entries to cover the VMSPLIT option (that is the top 1, 2 or 3
- * entries). The identity mapping is handled by pointing two PGD
- * entries to the first kernel PMD.
+ * In PAE mode initial_page_table is statically defined to contain
+ * enough entries to cover the VMSPLIT option (that is the top 1, 2 or 3
+ * entries). The identity mapping is handled by pointing two PGD entries
+ * to the first kernel PMD.
*
- * Note the upper half of each PMD or PTE are always zero at
- * this stage.
+ * Note the upper half of each PMD or PTE are always zero at this stage.
*/
#define KPMDS (((-__PAGE_OFFSET) >> 30) & 3) /* Number of kernel PMDs */
@@ -197,7 +196,7 @@ default_entry:
xorl %ebx,%ebx /* %ebx is kept at zero */
movl $pa(__brk_base), %edi
- movl $pa(swapper_pg_pmd), %edx
+ movl $pa(initial_pg_pmd), %edx
movl $PTE_IDENT_ATTR, %eax
10:
leal PDE_IDENT_ATTR(%edi),%ecx /* Create PMD entry */
@@ -226,14 +225,14 @@ default_entry:
movl %eax, pa(max_pfn_mapped)
/* Do early initialization of the fixmap area */
- movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,%eax
- movl %eax,pa(swapper_pg_pmd+0x1000*KPMDS-8)
+ movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax
+ movl %eax,pa(initial_pg_pmd+0x1000*KPMDS-8)
#else /* Not PAE */
page_pde_offset = (__PAGE_OFFSET >> 20);
movl $pa(__brk_base), %edi
- movl $pa(swapper_pg_dir), %edx
+ movl $pa(initial_page_table), %edx
movl $PTE_IDENT_ATTR, %eax
10:
leal PDE_IDENT_ATTR(%edi),%ecx /* Create PDE entry */
@@ -257,8 +256,8 @@ page_pde_offset = (__PAGE_OFFSET >> 20);
movl %eax, pa(max_pfn_mapped)
/* Do early initialization of the fixmap area */
- movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,%eax
- movl %eax,pa(swapper_pg_dir+0xffc)
+ movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax
+ movl %eax,pa(initial_page_table+0xffc)
#endif
jmp 3f
/*
@@ -334,7 +333,7 @@ ENTRY(startup_32_smp)
/*
* Enable paging
*/
- movl pa(initial_page_table), %eax
+ movl $pa(initial_page_table), %eax
movl %eax,%cr3 /* set the page table pointer.. */
movl %cr0,%eax
orl $X86_CR0_PG,%eax
@@ -614,8 +613,6 @@ ignore_int:
.align 4
ENTRY(initial_code)
.long i386_start_kernel
-ENTRY(initial_page_table)
- .long pa(swapper_pg_dir)
/*
* BSS section
@@ -623,20 +620,18 @@ ENTRY(initial_page_table)
__PAGE_ALIGNED_BSS
.align PAGE_SIZE_asm
#ifdef CONFIG_X86_PAE
-swapper_pg_pmd:
+initial_pg_pmd:
.fill 1024*KPMDS,4,0
#else
-ENTRY(swapper_pg_dir)
+ENTRY(initial_page_table)
.fill 1024,4,0
#endif
-swapper_pg_fixmap:
+initial_pg_fixmap:
.fill 1024,4,0
-#ifdef CONFIG_X86_TRAMPOLINE
-ENTRY(trampoline_pg_dir)
- .fill 1024,4,0
-#endif
ENTRY(empty_zero_page)
.fill 4096,1,0
+ENTRY(swapper_pg_dir)
+ .fill 1024,4,0
/*
* This starts the data section.
@@ -645,20 +640,20 @@ ENTRY(empty_zero_page)
__PAGE_ALIGNED_DATA
/* Page-aligned for the benefit of paravirt? */
.align PAGE_SIZE_asm
-ENTRY(swapper_pg_dir)
- .long pa(swapper_pg_pmd+PGD_IDENT_ATTR),0 /* low identity map */
+ENTRY(initial_page_table)
+ .long pa(initial_pg_pmd+PGD_IDENT_ATTR),0 /* low identity map */
# if KPMDS == 3
- .long pa(swapper_pg_pmd+PGD_IDENT_ATTR),0
- .long pa(swapper_pg_pmd+PGD_IDENT_ATTR+0x1000),0
- .long pa(swapper_pg_pmd+PGD_IDENT_ATTR+0x2000),0
+ .long pa(initial_pg_pmd+PGD_IDENT_ATTR),0
+ .long pa(initial_pg_pmd+PGD_IDENT_ATTR+0x1000),0
+ .long pa(initial_pg_pmd+PGD_IDENT_ATTR+0x2000),0
# elif KPMDS == 2
.long 0,0
- .long pa(swapper_pg_pmd+PGD_IDENT_ATTR),0
- .long pa(swapper_pg_pmd+PGD_IDENT_ATTR+0x1000),0
+ .long pa(initial_pg_pmd+PGD_IDENT_ATTR),0
+ .long pa(initial_pg_pmd+PGD_IDENT_ATTR+0x1000),0
# elif KPMDS == 1
.long 0,0
.long 0,0
- .long pa(swapper_pg_pmd+PGD_IDENT_ATTR),0
+ .long pa(initial_pg_pmd+PGD_IDENT_ATTR),0
# else
# error "Kernel PMDs should be 1, 2 or 3"
# endif
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index 410fdb3f1939..aff0b3c27509 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -380,44 +380,35 @@ static int hpet_next_event(unsigned long delta,
struct clock_event_device *evt, int timer)
{
u32 cnt;
+ s32 res;
cnt = hpet_readl(HPET_COUNTER);
cnt += (u32) delta;
hpet_writel(cnt, HPET_Tn_CMP(timer));
/*
- * We need to read back the CMP register on certain HPET
- * implementations (ATI chipsets) which seem to delay the
- * transfer of the compare register into the internal compare
- * logic. With small deltas this might actually be too late as
- * the counter could already be higher than the compare value
- * at that point and we would wait for the next hpet interrupt
- * forever. We found out that reading the CMP register back
- * forces the transfer so we can rely on the comparison with
- * the counter register below. If the read back from the
- * compare register does not match the value we programmed
- * then we might have a real hardware problem. We can not do
- * much about it here, but at least alert the user/admin with
- * a prominent warning.
- *
- * An erratum on some chipsets (ICH9,..), results in
- * comparator read immediately following a write returning old
- * value. Workaround for this is to read this value second
- * time, when first read returns old value.
- *
- * In fact the write to the comparator register is delayed up
- * to two HPET cycles so the workaround we tried to restrict
- * the readback to those known to be borked ATI chipsets
- * failed miserably. So we give up on optimizations forever
- * and penalize all HPET incarnations unconditionally.
+ * HPETs are a complete disaster. The compare register is
+ * based on a equal comparison and neither provides a less
+ * than or equal functionality (which would require to take
+ * the wraparound into account) nor a simple count down event
+ * mode. Further the write to the comparator register is
+ * delayed internally up to two HPET clock cycles in certain
+ * chipsets (ATI, ICH9,10). We worked around that by reading
+ * back the compare register, but that required another
+ * workaround for ICH9,10 chips where the first readout after
+ * write can return the old stale value. We already have a
+ * minimum delta of 5us enforced, but a NMI or SMI hitting
+ * between the counter readout and the comparator write can
+ * move us behind that point easily. Now instead of reading
+ * the compare register back several times, we make the ETIME
+ * decision based on the following: Return ETIME if the
+ * counter value after the write is less than 8 HPET cycles
+ * away from the event or if the counter is already ahead of
+ * the event.
*/
- if (unlikely((u32)hpet_readl(HPET_Tn_CMP(timer)) != cnt)) {
- if (hpet_readl(HPET_Tn_CMP(timer)) != cnt)
- printk_once(KERN_WARNING
- "hpet: compare register read back failed.\n");
- }
+ res = (s32)(cnt - hpet_readl(HPET_COUNTER));
- return (s32)(hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0;
+ return res < 8 ? -ETIME : 0;
}
static void hpet_legacy_set_mode(enum clock_event_mode mode,
@@ -440,9 +431,9 @@ static int hpet_legacy_next_event(unsigned long delta,
static DEFINE_PER_CPU(struct hpet_dev *, cpu_hpet_dev);
static struct hpet_dev *hpet_devs;
-void hpet_msi_unmask(unsigned int irq)
+void hpet_msi_unmask(struct irq_data *data)
{
- struct hpet_dev *hdev = get_irq_data(irq);
+ struct hpet_dev *hdev = data->handler_data;
unsigned int cfg;
/* unmask it */
@@ -451,10 +442,10 @@ void hpet_msi_unmask(unsigned int irq)
hpet_writel(cfg, HPET_Tn_CFG(hdev->num));
}
-void hpet_msi_mask(unsigned int irq)
+void hpet_msi_mask(struct irq_data *data)
{
+ struct hpet_dev *hdev = data->handler_data;
unsigned int cfg;
- struct hpet_dev *hdev = get_irq_data(irq);
/* mask it */
cfg = hpet_readl(HPET_Tn_CFG(hdev->num));
@@ -462,18 +453,14 @@ void hpet_msi_mask(unsigned int irq)
hpet_writel(cfg, HPET_Tn_CFG(hdev->num));
}
-void hpet_msi_write(unsigned int irq, struct msi_msg *msg)
+void hpet_msi_write(struct hpet_dev *hdev, struct msi_msg *msg)
{
- struct hpet_dev *hdev = get_irq_data(irq);
-
hpet_writel(msg->data, HPET_Tn_ROUTE(hdev->num));
hpet_writel(msg->address_lo, HPET_Tn_ROUTE(hdev->num) + 4);
}
-void hpet_msi_read(unsigned int irq, struct msi_msg *msg)
+void hpet_msi_read(struct hpet_dev *hdev, struct msi_msg *msg)
{
- struct hpet_dev *hdev = get_irq_data(irq);
-
msg->data = hpet_readl(HPET_Tn_ROUTE(hdev->num));
msg->address_lo = hpet_readl(HPET_Tn_ROUTE(hdev->num) + 4);
msg->address_hi = 0;
@@ -506,7 +493,7 @@ static int hpet_assign_irq(struct hpet_dev *dev)
{
unsigned int irq;
- irq = create_irq();
+ irq = create_irq_nr(0, -1);
if (!irq)
return -EINVAL;
diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c
index a46cb3522c0c..58bb239a2fd7 100644
--- a/arch/x86/kernel/i387.c
+++ b/arch/x86/kernel/i387.c
@@ -68,19 +68,22 @@ static void __cpuinit init_thread_xstate(void)
*/
if (!HAVE_HWFP) {
+ /*
+ * Disable xsave as we do not support it if i387
+ * emulation is enabled.
+ */
+ setup_clear_cpu_cap(X86_FEATURE_XSAVE);
+ setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT);
xstate_size = sizeof(struct i387_soft_struct);
return;
}
if (cpu_has_fxsr)
xstate_size = sizeof(struct i387_fxsave_struct);
-#ifdef CONFIG_X86_32
else
xstate_size = sizeof(struct i387_fsave_struct);
-#endif
}
-#ifdef CONFIG_X86_64
/*
* Called at bootup to set up the initial FPU state that is later cloned
* into all processes.
@@ -88,12 +91,21 @@ static void __cpuinit init_thread_xstate(void)
void __cpuinit fpu_init(void)
{
- unsigned long oldcr0 = read_cr0();
-
- set_in_cr4(X86_CR4_OSFXSR);
- set_in_cr4(X86_CR4_OSXMMEXCPT);
+ unsigned long cr0;
+ unsigned long cr4_mask = 0;
- write_cr0(oldcr0 & ~(X86_CR0_TS|X86_CR0_EM)); /* clear TS and EM */
+ if (cpu_has_fxsr)
+ cr4_mask |= X86_CR4_OSFXSR;
+ if (cpu_has_xmm)
+ cr4_mask |= X86_CR4_OSXMMEXCPT;
+ if (cr4_mask)
+ set_in_cr4(cr4_mask);
+
+ cr0 = read_cr0();
+ cr0 &= ~(X86_CR0_TS|X86_CR0_EM); /* clear TS and EM */
+ if (!HAVE_HWFP)
+ cr0 |= X86_CR0_EM;
+ write_cr0(cr0);
if (!smp_processor_id())
init_thread_xstate();
@@ -104,24 +116,12 @@ void __cpuinit fpu_init(void)
clear_used_math();
}
-#else /* CONFIG_X86_64 */
-
-void __cpuinit fpu_init(void)
-{
- if (!smp_processor_id())
- init_thread_xstate();
-}
-
-#endif /* CONFIG_X86_32 */
-
void fpu_finit(struct fpu *fpu)
{
-#ifdef CONFIG_X86_32
if (!HAVE_HWFP) {
finit_soft_fpu(&fpu->state->soft);
return;
}
-#endif
if (cpu_has_fxsr) {
struct i387_fxsave_struct *fx = &fpu->state->fxsave;
@@ -386,19 +386,17 @@ convert_from_fxsr(struct user_i387_ia32_struct *env, struct task_struct *tsk)
#ifdef CONFIG_X86_64
env->fip = fxsave->rip;
env->foo = fxsave->rdp;
+ /*
+ * should be actually ds/cs at fpu exception time, but
+ * that information is not available in 64bit mode.
+ */
+ env->fcs = task_pt_regs(tsk)->cs;
if (tsk == current) {
- /*
- * should be actually ds/cs at fpu exception time, but
- * that information is not available in 64bit mode.
- */
- asm("mov %%ds, %[fos]" : [fos] "=r" (env->fos));
- asm("mov %%cs, %[fcs]" : [fcs] "=r" (env->fcs));
+ savesegment(ds, env->fos);
} else {
- struct pt_regs *regs = task_pt_regs(tsk);
-
- env->fos = 0xffff0000 | tsk->thread.ds;
- env->fcs = regs->cs;
+ env->fos = tsk->thread.ds;
}
+ env->fos |= 0xffff0000;
#else
env->fip = fxsave->fip;
env->fcs = (u16) fxsave->fcs | ((u32) fxsave->fop << 16);
diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c
index cafa7c80ac95..20757cb2efa3 100644
--- a/arch/x86/kernel/i8259.c
+++ b/arch/x86/kernel/i8259.c
@@ -29,24 +29,10 @@
* plus some generic x86 specific things if generic specifics makes
* any sense at all.
*/
+static void init_8259A(int auto_eoi);
static int i8259A_auto_eoi;
DEFINE_RAW_SPINLOCK(i8259A_lock);
-static void mask_and_ack_8259A(unsigned int);
-static void mask_8259A(void);
-static void unmask_8259A(void);
-static void disable_8259A_irq(unsigned int irq);
-static void enable_8259A_irq(unsigned int irq);
-static void init_8259A(int auto_eoi);
-static int i8259A_irq_pending(unsigned int irq);
-
-struct irq_chip i8259A_chip = {
- .name = "XT-PIC",
- .mask = disable_8259A_irq,
- .disable = disable_8259A_irq,
- .unmask = enable_8259A_irq,
- .mask_ack = mask_and_ack_8259A,
-};
/*
* 8259A PIC functions to handle ISA devices:
@@ -68,7 +54,7 @@ unsigned int cached_irq_mask = 0xffff;
*/
unsigned long io_apic_irqs;
-static void disable_8259A_irq(unsigned int irq)
+static void mask_8259A_irq(unsigned int irq)
{
unsigned int mask = 1 << irq;
unsigned long flags;
@@ -82,7 +68,12 @@ static void disable_8259A_irq(unsigned int irq)
raw_spin_unlock_irqrestore(&i8259A_lock, flags);
}
-static void enable_8259A_irq(unsigned int irq)
+static void disable_8259A_irq(struct irq_data *data)
+{
+ mask_8259A_irq(data->irq);
+}
+
+static void unmask_8259A_irq(unsigned int irq)
{
unsigned int mask = ~(1 << irq);
unsigned long flags;
@@ -96,6 +87,11 @@ static void enable_8259A_irq(unsigned int irq)
raw_spin_unlock_irqrestore(&i8259A_lock, flags);
}
+static void enable_8259A_irq(struct irq_data *data)
+{
+ unmask_8259A_irq(data->irq);
+}
+
static int i8259A_irq_pending(unsigned int irq)
{
unsigned int mask = 1<<irq;
@@ -117,7 +113,7 @@ static void make_8259A_irq(unsigned int irq)
disable_irq_nosync(irq);
io_apic_irqs &= ~(1<<irq);
set_irq_chip_and_handler_name(irq, &i8259A_chip, handle_level_irq,
- "XT");
+ i8259A_chip.name);
enable_irq(irq);
}
@@ -150,8 +146,9 @@ static inline int i8259A_irq_real(unsigned int irq)
* first, _then_ send the EOI, and the order of EOI
* to the two 8259s is important!
*/
-static void mask_and_ack_8259A(unsigned int irq)
+static void mask_and_ack_8259A(struct irq_data *data)
{
+ unsigned int irq = data->irq;
unsigned int irqmask = 1 << irq;
unsigned long flags;
@@ -223,6 +220,14 @@ spurious_8259A_irq:
}
}
+struct irq_chip i8259A_chip = {
+ .name = "XT-PIC",
+ .irq_mask = disable_8259A_irq,
+ .irq_disable = disable_8259A_irq,
+ .irq_unmask = enable_8259A_irq,
+ .irq_mask_ack = mask_and_ack_8259A,
+};
+
static char irq_trigger[2];
/**
* ELCR registers (0x4d0, 0x4d1) control edge/level of IRQ
@@ -342,9 +347,9 @@ static void init_8259A(int auto_eoi)
* In AEOI mode we just have to mask the interrupt
* when acking.
*/
- i8259A_chip.mask_ack = disable_8259A_irq;
+ i8259A_chip.irq_mask_ack = disable_8259A_irq;
else
- i8259A_chip.mask_ack = mask_and_ack_8259A;
+ i8259A_chip.irq_mask_ack = mask_and_ack_8259A;
udelay(100); /* wait for 8259A to initialize */
@@ -363,14 +368,6 @@ static void init_8259A(int auto_eoi)
static void legacy_pic_noop(void) { };
static void legacy_pic_uint_noop(unsigned int unused) { };
static void legacy_pic_int_noop(int unused) { };
-
-static struct irq_chip dummy_pic_chip = {
- .name = "dummy pic",
- .mask = legacy_pic_uint_noop,
- .unmask = legacy_pic_uint_noop,
- .disable = legacy_pic_uint_noop,
- .mask_ack = legacy_pic_uint_noop,
-};
static int legacy_pic_irq_pending_noop(unsigned int irq)
{
return 0;
@@ -378,7 +375,9 @@ static int legacy_pic_irq_pending_noop(unsigned int irq)
struct legacy_pic null_legacy_pic = {
.nr_legacy_irqs = 0,
- .chip = &dummy_pic_chip,
+ .chip = &dummy_irq_chip,
+ .mask = legacy_pic_uint_noop,
+ .unmask = legacy_pic_uint_noop,
.mask_all = legacy_pic_noop,
.restore_mask = legacy_pic_noop,
.init = legacy_pic_int_noop,
@@ -389,7 +388,9 @@ struct legacy_pic null_legacy_pic = {
struct legacy_pic default_legacy_pic = {
.nr_legacy_irqs = NR_IRQS_LEGACY,
.chip = &i8259A_chip,
- .mask_all = mask_8259A,
+ .mask = mask_8259A_irq,
+ .unmask = unmask_8259A_irq,
+ .mask_all = mask_8259A,
.restore_mask = unmask_8259A,
.init = init_8259A,
.irq_pending = i8259A_irq_pending,
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 91fd0c70a18a..83ec0175f986 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -67,10 +67,10 @@ static int show_other_interrupts(struct seq_file *p, int prec)
for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->apic_perf_irqs);
seq_printf(p, " Performance monitoring interrupts\n");
- seq_printf(p, "%*s: ", prec, "PND");
+ seq_printf(p, "%*s: ", prec, "IWI");
for_each_online_cpu(j)
- seq_printf(p, "%10u ", irq_stats(j)->apic_pending_irqs);
- seq_printf(p, " Performance pending work\n");
+ seq_printf(p, "%10u ", irq_stats(j)->apic_irq_work_irqs);
+ seq_printf(p, " IRQ work interrupts\n");
#endif
if (x86_platform_ipi_callback) {
seq_printf(p, "%*s: ", prec, "PLT");
@@ -159,7 +159,7 @@ int show_interrupts(struct seq_file *p, void *v)
seq_printf(p, "%*d: ", prec, i);
for_each_online_cpu(j)
seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
- seq_printf(p, " %8s", desc->chip->name);
+ seq_printf(p, " %8s", desc->irq_data.chip->name);
seq_printf(p, "-%-8s", desc->name);
if (action) {
@@ -185,7 +185,7 @@ u64 arch_irq_stat_cpu(unsigned int cpu)
sum += irq_stats(cpu)->apic_timer_irqs;
sum += irq_stats(cpu)->irq_spurious_count;
sum += irq_stats(cpu)->apic_perf_irqs;
- sum += irq_stats(cpu)->apic_pending_irqs;
+ sum += irq_stats(cpu)->apic_irq_work_irqs;
#endif
if (x86_platform_ipi_callback)
sum += irq_stats(cpu)->x86_platform_ipis;
@@ -282,6 +282,7 @@ void fixup_irqs(void)
unsigned int irq, vector;
static int warned;
struct irq_desc *desc;
+ struct irq_data *data;
for_each_irq_desc(irq, desc) {
int break_affinity = 0;
@@ -296,7 +297,8 @@ void fixup_irqs(void)
/* interrupt's are disabled at this point */
raw_spin_lock(&desc->lock);
- affinity = desc->affinity;
+ data = &desc->irq_data;
+ affinity = data->affinity;
if (!irq_has_action(irq) ||
cpumask_equal(affinity, cpu_online_mask)) {
raw_spin_unlock(&desc->lock);
@@ -315,16 +317,16 @@ void fixup_irqs(void)
affinity = cpu_all_mask;
}
- if (!(desc->status & IRQ_MOVE_PCNTXT) && desc->chip->mask)
- desc->chip->mask(irq);
+ if (!(desc->status & IRQ_MOVE_PCNTXT) && data->chip->irq_mask)
+ data->chip->irq_mask(data);
- if (desc->chip->set_affinity)
- desc->chip->set_affinity(irq, affinity);
+ if (data->chip->irq_set_affinity)
+ data->chip->irq_set_affinity(data, affinity, true);
else if (!(warned++))
set_affinity = 0;
- if (!(desc->status & IRQ_MOVE_PCNTXT) && desc->chip->unmask)
- desc->chip->unmask(irq);
+ if (!(desc->status & IRQ_MOVE_PCNTXT) && data->chip->irq_unmask)
+ data->chip->irq_unmask(data);
raw_spin_unlock(&desc->lock);
@@ -355,10 +357,10 @@ void fixup_irqs(void)
if (irr & (1 << (vector % 32))) {
irq = __get_cpu_var(vector_irq)[vector];
- desc = irq_to_desc(irq);
+ data = irq_get_irq_data(irq);
raw_spin_lock(&desc->lock);
- if (desc->chip->retrigger)
- desc->chip->retrigger(irq);
+ if (data->chip->irq_retrigger)
+ data->chip->irq_retrigger(data);
raw_spin_unlock(&desc->lock);
}
}
diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c
index 10709f29d166..50fbbe60e507 100644
--- a/arch/x86/kernel/irq_32.c
+++ b/arch/x86/kernel/irq_32.c
@@ -49,20 +49,19 @@ static inline int check_stack_overflow(void) { return 0; }
static inline void print_stack_overflow(void) { }
#endif
-#ifdef CONFIG_4KSTACKS
/*
* per-CPU IRQ handling contexts (thread information and stack)
*/
union irq_ctx {
struct thread_info tinfo;
u32 stack[THREAD_SIZE/sizeof(u32)];
-} __attribute__((aligned(PAGE_SIZE)));
+} __attribute__((aligned(THREAD_SIZE)));
static DEFINE_PER_CPU(union irq_ctx *, hardirq_ctx);
static DEFINE_PER_CPU(union irq_ctx *, softirq_ctx);
-static DEFINE_PER_CPU_PAGE_ALIGNED(union irq_ctx, hardirq_stack);
-static DEFINE_PER_CPU_PAGE_ALIGNED(union irq_ctx, softirq_stack);
+static DEFINE_PER_CPU_MULTIPAGE_ALIGNED(union irq_ctx, hardirq_stack, THREAD_SIZE);
+static DEFINE_PER_CPU_MULTIPAGE_ALIGNED(union irq_ctx, softirq_stack, THREAD_SIZE);
static void call_on_stack(void *func, void *stack)
{
@@ -187,11 +186,6 @@ asmlinkage void do_softirq(void)
local_irq_restore(flags);
}
-#else
-static inline int
-execute_on_irq_stack(int overflow, struct irq_desc *desc, int irq) { return 0; }
-#endif
-
bool handle_irq(unsigned irq, struct pt_regs *regs)
{
struct irq_desc *desc;
diff --git a/arch/x86/kernel/irq_work.c b/arch/x86/kernel/irq_work.c
new file mode 100644
index 000000000000..ca8f703a1e70
--- /dev/null
+++ b/arch/x86/kernel/irq_work.c
@@ -0,0 +1,30 @@
+/*
+ * x86 specific code for irq_work
+ *
+ * Copyright (C) 2010 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/irq_work.h>
+#include <linux/hardirq.h>
+#include <asm/apic.h>
+
+void smp_irq_work_interrupt(struct pt_regs *regs)
+{
+ irq_enter();
+ ack_APIC_irq();
+ inc_irq_stat(apic_irq_work_irqs);
+ irq_work_run();
+ irq_exit();
+}
+
+void arch_irq_work_raise(void)
+{
+#ifdef CONFIG_X86_LOCAL_APIC
+ if (!cpu_has_apic)
+ return;
+
+ apic->send_IPI_self(IRQ_WORK_VECTOR);
+ apic_wait_icr_idle();
+#endif
+}
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
index 990ae7cfc578..c752e973958d 100644
--- a/arch/x86/kernel/irqinit.c
+++ b/arch/x86/kernel/irqinit.c
@@ -100,6 +100,8 @@ int vector_used_by_percpu_irq(unsigned int vector)
void __init init_ISA_irqs(void)
{
+ struct irq_chip *chip = legacy_pic->chip;
+ const char *name = chip->name;
int i;
#if defined(CONFIG_X86_64) || defined(CONFIG_X86_LOCAL_APIC)
@@ -107,19 +109,8 @@ void __init init_ISA_irqs(void)
#endif
legacy_pic->init(0);
- /*
- * 16 old-style INTA-cycle interrupts:
- */
- for (i = 0; i < legacy_pic->nr_legacy_irqs; i++) {
- struct irq_desc *desc = irq_to_desc(i);
-
- desc->status = IRQ_DISABLED;
- desc->action = NULL;
- desc->depth = 1;
-
- set_irq_chip_and_handler_name(i, &i8259A_chip,
- handle_level_irq, "XT");
- }
+ for (i = 0; i < legacy_pic->nr_legacy_irqs; i++)
+ set_irq_chip_and_handler_name(i, chip, handle_level_irq, name);
}
void __init init_IRQ(void)
@@ -224,9 +215,9 @@ static void __init apic_intr_init(void)
alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
- /* Performance monitoring interrupts: */
-# ifdef CONFIG_PERF_EVENTS
- alloc_intr_gate(LOCAL_PENDING_VECTOR, perf_pending_interrupt);
+ /* IRQ work interrupts: */
+# ifdef CONFIG_IRQ_WORK
+ alloc_intr_gate(IRQ_WORK_VECTOR, irq_work_interrupt);
# endif
#endif
diff --git a/arch/x86/kernel/jump_label.c b/arch/x86/kernel/jump_label.c
new file mode 100644
index 000000000000..961b6b30ba90
--- /dev/null
+++ b/arch/x86/kernel/jump_label.c
@@ -0,0 +1,50 @@
+/*
+ * jump label x86 support
+ *
+ * Copyright (C) 2009 Jason Baron <jbaron@redhat.com>
+ *
+ */
+#include <linux/jump_label.h>
+#include <linux/memory.h>
+#include <linux/uaccess.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/jhash.h>
+#include <linux/cpu.h>
+#include <asm/kprobes.h>
+#include <asm/alternative.h>
+
+#ifdef HAVE_JUMP_LABEL
+
+union jump_code_union {
+ char code[JUMP_LABEL_NOP_SIZE];
+ struct {
+ char jump;
+ int offset;
+ } __attribute__((packed));
+};
+
+void arch_jump_label_transform(struct jump_entry *entry,
+ enum jump_label_type type)
+{
+ union jump_code_union code;
+
+ if (type == JUMP_LABEL_ENABLE) {
+ code.jump = 0xe9;
+ code.offset = entry->target -
+ (entry->code + JUMP_LABEL_NOP_SIZE);
+ } else
+ memcpy(&code, ideal_nop5, JUMP_LABEL_NOP_SIZE);
+ get_online_cpus();
+ mutex_lock(&text_mutex);
+ text_poke_smp((void *)entry->code, &code, JUMP_LABEL_NOP_SIZE);
+ mutex_unlock(&text_mutex);
+ put_online_cpus();
+}
+
+void arch_jump_label_text_poke_early(jump_label_t addr)
+{
+ text_poke_early((void *)addr, ideal_nop5, JUMP_LABEL_NOP_SIZE);
+}
+
+#endif
diff --git a/arch/x86/kernel/kdebugfs.c b/arch/x86/kernel/kdebugfs.c
index 8afd9f321f10..90fcf62854bb 100644
--- a/arch/x86/kernel/kdebugfs.c
+++ b/arch/x86/kernel/kdebugfs.c
@@ -78,6 +78,7 @@ static int setup_data_open(struct inode *inode, struct file *file)
static const struct file_operations fops_setup_data = {
.read = setup_data_read,
.open = setup_data_open,
+ .llseek = default_llseek,
};
static int __init
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c
index 852b81967a37..d81cfebb848f 100644
--- a/arch/x86/kernel/kgdb.c
+++ b/arch/x86/kernel/kgdb.c
@@ -477,8 +477,6 @@ int kgdb_arch_handle_exception(int e_vector, int signo, int err_code,
raw_smp_processor_id());
}
- kgdb_correct_hw_break();
-
return 0;
}
@@ -621,7 +619,12 @@ int kgdb_arch_init(void)
static void kgdb_hw_overflow_handler(struct perf_event *event, int nmi,
struct perf_sample_data *data, struct pt_regs *regs)
{
- kgdb_ll_trap(DIE_DEBUG, "debug", regs, 0, 0, SIGTRAP);
+ struct task_struct *tsk = current;
+ int i;
+
+ for (i = 0; i < 4; i++)
+ if (breakinfo[i].enabled)
+ tsk->thread.debugreg6 |= (DR_TRAP0 << i);
}
void kgdb_arch_late(void)
@@ -644,7 +647,7 @@ void kgdb_arch_late(void)
if (breakinfo[i].pev)
continue;
breakinfo[i].pev = register_wide_hw_breakpoint(&attr, NULL);
- if (IS_ERR(breakinfo[i].pev)) {
+ if (IS_ERR((void * __force)breakinfo[i].pev)) {
printk(KERN_ERR "kgdb: Could not allocate hw"
"breakpoints\nDisabling the kernel debugger\n");
breakinfo[i].pev = NULL;
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
index 770ebfb349e9..1cbd54c0df99 100644
--- a/arch/x86/kernel/kprobes.c
+++ b/arch/x86/kernel/kprobes.c
@@ -230,9 +230,6 @@ static int recover_probed_instruction(kprobe_opcode_t *buf, unsigned long addr)
return 0;
}
-/* Dummy buffers for kallsyms_lookup */
-static char __dummy_buf[KSYM_NAME_LEN];
-
/* Check if paddr is at an instruction boundary */
static int __kprobes can_probe(unsigned long paddr)
{
@@ -241,7 +238,7 @@ static int __kprobes can_probe(unsigned long paddr)
struct insn insn;
kprobe_opcode_t buf[MAX_INSN_SIZE];
- if (!kallsyms_lookup(paddr, NULL, &offset, NULL, __dummy_buf))
+ if (!kallsyms_lookup_size_offset(paddr, NULL, &offset))
return 0;
/* Decode instructions */
@@ -1129,7 +1126,7 @@ static void __kprobes synthesize_set_arg1(kprobe_opcode_t *addr,
*(unsigned long *)addr = val;
}
-void __kprobes kprobes_optinsn_template_holder(void)
+static void __used __kprobes kprobes_optinsn_template_holder(void)
{
asm volatile (
".global optprobe_template_entry\n"
@@ -1221,7 +1218,8 @@ static int __kprobes copy_optimized_instructions(u8 *dest, u8 *src)
}
/* Check whether the address range is reserved */
if (ftrace_text_reserved(src, src + len - 1) ||
- alternatives_text_reserved(src, src + len - 1))
+ alternatives_text_reserved(src, src + len - 1) ||
+ jump_label_text_reserved(src, src + len - 1))
return -EBUSY;
return len;
@@ -1269,11 +1267,9 @@ static int __kprobes can_optimize(unsigned long paddr)
unsigned long addr, size = 0, offset = 0;
struct insn insn;
kprobe_opcode_t buf[MAX_INSN_SIZE];
- /* Dummy buffers for lookup_symbol_attrs */
- static char __dummy_buf[KSYM_NAME_LEN];
/* Lookup symbol including addr */
- if (!kallsyms_lookup(paddr, &size, &offset, NULL, __dummy_buf))
+ if (!kallsyms_lookup_size_offset(paddr, &size, &offset))
return 0;
/* Check there is enough space for a relative jump. */
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c
index eb9b76c716c2..ca43ce31a19c 100644
--- a/arch/x86/kernel/kvmclock.c
+++ b/arch/x86/kernel/kvmclock.c
@@ -128,13 +128,15 @@ static struct clocksource kvm_clock = {
static int kvm_register_clock(char *txt)
{
int cpu = smp_processor_id();
- int low, high;
+ int low, high, ret;
+
low = (int)__pa(&per_cpu(hv_clock, cpu)) | 1;
high = ((u64)__pa(&per_cpu(hv_clock, cpu)) >> 32);
+ ret = native_write_msr_safe(msr_kvm_system_time, low, high);
printk(KERN_INFO "kvm-clock: cpu %d, msr %x:%x, %s\n",
cpu, high, low, txt);
- return native_write_msr_safe(msr_kvm_system_time, low, high);
+ return ret;
}
#ifdef CONFIG_X86_LOCAL_APIC
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
index 035c8c529181..b3ea9db39db6 100644
--- a/arch/x86/kernel/machine_kexec_64.c
+++ b/arch/x86/kernel/machine_kexec_64.c
@@ -36,7 +36,7 @@ static int init_one_level2_page(struct kimage *image, pgd_t *pgd,
if (!page)
goto out;
pud = (pud_t *)page_address(page);
- memset(pud, 0, PAGE_SIZE);
+ clear_page(pud);
set_pgd(pgd, __pgd(__pa(pud) | _KERNPG_TABLE));
}
pud = pud_offset(pgd, addr);
@@ -45,7 +45,7 @@ static int init_one_level2_page(struct kimage *image, pgd_t *pgd,
if (!page)
goto out;
pmd = (pmd_t *)page_address(page);
- memset(pmd, 0, PAGE_SIZE);
+ clear_page(pmd);
set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE));
}
pmd = pmd_offset(pud, addr);
diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c
index fa6551d36c10..1cca374a2bac 100644
--- a/arch/x86/kernel/microcode_core.c
+++ b/arch/x86/kernel/microcode_core.c
@@ -12,7 +12,7 @@
* Software Developer's Manual
* Order Number 253668 or free download from:
*
- * http://developer.intel.com/design/pentium4/manuals/253668.htm
+ * http://developer.intel.com/Assets/PDF/manual/253668.pdf
*
* For more information, go to http://www.urbanmyth.org/microcode
*
@@ -232,6 +232,7 @@ static const struct file_operations microcode_fops = {
.owner = THIS_MODULE,
.write = microcode_write,
.open = microcode_open,
+ .llseek = no_llseek,
};
static struct miscdevice microcode_dev = {
diff --git a/arch/x86/kernel/microcode_intel.c b/arch/x86/kernel/microcode_intel.c
index 356170262a93..dcb65cc0a053 100644
--- a/arch/x86/kernel/microcode_intel.c
+++ b/arch/x86/kernel/microcode_intel.c
@@ -12,7 +12,7 @@
* Software Developer's Manual
* Order Number 253668 or free download from:
*
- * http://developer.intel.com/design/pentium4/manuals/253668.htm
+ * http://developer.intel.com/Assets/PDF/manual/253668.pdf
*
* For more information, go to http://www.urbanmyth.org/microcode
*
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c
index e0bc186d7501..8f2956091735 100644
--- a/arch/x86/kernel/module.c
+++ b/arch/x86/kernel/module.c
@@ -239,11 +239,13 @@ int module_finalize(const Elf_Ehdr *hdr,
apply_paravirt(pseg, pseg + para->sh_size);
}
- return module_bug_finalize(hdr, sechdrs, me);
+ /* make jump label nops */
+ jump_label_apply_nops(me);
+
+ return 0;
}
void module_arch_cleanup(struct module *mod)
{
alternatives_smp_module_del(mod);
- module_bug_cleanup(mod);
}
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c
index d7b6f7fb4fec..9af64d9c4b67 100644
--- a/arch/x86/kernel/mpparse.c
+++ b/arch/x86/kernel/mpparse.c
@@ -11,6 +11,7 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/bootmem.h>
+#include <linux/memblock.h>
#include <linux/kernel_stat.h>
#include <linux/mc146818rtc.h>
#include <linux/bitops.h>
@@ -657,7 +658,7 @@ static void __init smp_reserve_memory(struct mpf_intel *mpf)
{
unsigned long size = get_mpc_size(mpf->physptr);
- reserve_early_overlap_ok(mpf->physptr, mpf->physptr+size, "MP-table mpc");
+ memblock_x86_reserve_range(mpf->physptr, mpf->physptr+size, "* MP-table mpc");
}
static int __init smp_scan_config(unsigned long base, unsigned long length)
@@ -686,7 +687,7 @@ static int __init smp_scan_config(unsigned long base, unsigned long length)
mpf, (u64)virt_to_phys(mpf));
mem = virt_to_phys(mpf);
- reserve_early_overlap_ok(mem, mem + sizeof(*mpf), "MP-table mpf");
+ memblock_x86_reserve_range(mem, mem + sizeof(*mpf), "* MP-table mpf");
if (mpf->physptr)
smp_reserve_memory(mpf);
diff --git a/arch/x86/kernel/olpc-xo1.c b/arch/x86/kernel/olpc-xo1.c
new file mode 100644
index 000000000000..f5442c03abc3
--- /dev/null
+++ b/arch/x86/kernel/olpc-xo1.c
@@ -0,0 +1,140 @@
+/*
+ * Support for features of the OLPC XO-1 laptop
+ *
+ * Copyright (C) 2010 One Laptop per Child
+ * Copyright (C) 2006 Red Hat, Inc.
+ * Copyright (C) 2006 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+
+#include <asm/io.h>
+#include <asm/olpc.h>
+
+#define DRV_NAME "olpc-xo1"
+
+#define PMS_BAR 4
+#define ACPI_BAR 5
+
+/* PMC registers (PMS block) */
+#define PM_SCLK 0x10
+#define PM_IN_SLPCTL 0x20
+#define PM_WKXD 0x34
+#define PM_WKD 0x30
+#define PM_SSC 0x54
+
+/* PM registers (ACPI block) */
+#define PM1_CNT 0x08
+#define PM_GPE0_STS 0x18
+
+static unsigned long acpi_base;
+static unsigned long pms_base;
+
+static void xo1_power_off(void)
+{
+ printk(KERN_INFO "OLPC XO-1 power off sequence...\n");
+
+ /* Enable all of these controls with 0 delay */
+ outl(0x40000000, pms_base + PM_SCLK);
+ outl(0x40000000, pms_base + PM_IN_SLPCTL);
+ outl(0x40000000, pms_base + PM_WKXD);
+ outl(0x40000000, pms_base + PM_WKD);
+
+ /* Clear status bits (possibly unnecessary) */
+ outl(0x0002ffff, pms_base + PM_SSC);
+ outl(0xffffffff, acpi_base + PM_GPE0_STS);
+
+ /* Write SLP_EN bit to start the machinery */
+ outl(0x00002000, acpi_base + PM1_CNT);
+}
+
+/* Read the base addresses from the PCI BAR info */
+static int __devinit setup_bases(struct pci_dev *pdev)
+{
+ int r;
+
+ r = pci_enable_device_io(pdev);
+ if (r) {
+ dev_err(&pdev->dev, "can't enable device IO\n");
+ return r;
+ }
+
+ r = pci_request_region(pdev, ACPI_BAR, DRV_NAME);
+ if (r) {
+ dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", ACPI_BAR);
+ return r;
+ }
+
+ r = pci_request_region(pdev, PMS_BAR, DRV_NAME);
+ if (r) {
+ dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", PMS_BAR);
+ pci_release_region(pdev, ACPI_BAR);
+ return r;
+ }
+
+ acpi_base = pci_resource_start(pdev, ACPI_BAR);
+ pms_base = pci_resource_start(pdev, PMS_BAR);
+
+ return 0;
+}
+
+static int __devinit olpc_xo1_probe(struct platform_device *pdev)
+{
+ struct pci_dev *pcidev;
+ int r;
+
+ pcidev = pci_get_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA,
+ NULL);
+ if (!pdev)
+ return -ENODEV;
+
+ r = setup_bases(pcidev);
+ if (r)
+ return r;
+
+ pm_power_off = xo1_power_off;
+
+ printk(KERN_INFO "OLPC XO-1 support registered\n");
+ return 0;
+}
+
+static int __devexit olpc_xo1_remove(struct platform_device *pdev)
+{
+ pm_power_off = NULL;
+ return 0;
+}
+
+static struct platform_driver olpc_xo1_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = olpc_xo1_probe,
+ .remove = __devexit_p(olpc_xo1_remove),
+};
+
+static int __init olpc_xo1_init(void)
+{
+ return platform_driver_register(&olpc_xo1_driver);
+}
+
+static void __exit olpc_xo1_exit(void)
+{
+ platform_driver_unregister(&olpc_xo1_driver);
+}
+
+MODULE_AUTHOR("Daniel Drake <dsd@laptop.org>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:olpc-xo1");
+
+module_init(olpc_xo1_init);
+module_exit(olpc_xo1_exit);
diff --git a/arch/x86/kernel/olpc.c b/arch/x86/kernel/olpc.c
index 0e0cdde519be..edaf3fe8dc5e 100644
--- a/arch/x86/kernel/olpc.c
+++ b/arch/x86/kernel/olpc.c
@@ -17,6 +17,7 @@
#include <linux/spinlock.h>
#include <linux/io.h>
#include <linux/string.h>
+#include <linux/platform_device.h>
#include <asm/geode.h>
#include <asm/setup.h>
@@ -114,6 +115,7 @@ int olpc_ec_cmd(unsigned char cmd, unsigned char *inbuf, size_t inlen,
unsigned long flags;
int ret = -EIO;
int i;
+ int restarts = 0;
spin_lock_irqsave(&ec_lock, flags);
@@ -169,7 +171,9 @@ restart:
if (wait_on_obf(0x6c, 1)) {
printk(KERN_ERR "olpc-ec: timeout waiting for"
" EC to provide data!\n");
- goto restart;
+ if (restarts++ < 10)
+ goto restart;
+ goto err;
}
outbuf[i] = inb(0x68);
pr_devel("olpc-ec: received 0x%x\n", outbuf[i]);
@@ -183,8 +187,21 @@ err:
}
EXPORT_SYMBOL_GPL(olpc_ec_cmd);
-#ifdef CONFIG_OLPC_OPENFIRMWARE
-static void __init platform_detect(void)
+static bool __init check_ofw_architecture(void)
+{
+ size_t propsize;
+ char olpc_arch[5];
+ const void *args[] = { NULL, "architecture", olpc_arch, (void *)5 };
+ void *res[] = { &propsize };
+
+ if (olpc_ofw("getprop", args, res)) {
+ printk(KERN_ERR "ofw: getprop call failed!\n");
+ return false;
+ }
+ return propsize == 5 && strncmp("OLPC", olpc_arch, 5) == 0;
+}
+
+static u32 __init get_board_revision(void)
{
size_t propsize;
__be32 rev;
@@ -193,45 +210,43 @@ static void __init platform_detect(void)
if (olpc_ofw("getprop", args, res) || propsize != 4) {
printk(KERN_ERR "ofw: getprop call failed!\n");
- rev = cpu_to_be32(0);
+ return cpu_to_be32(0);
}
- olpc_platform_info.boardrev = be32_to_cpu(rev);
+ return be32_to_cpu(rev);
}
-#else
-static void __init platform_detect(void)
+
+static bool __init platform_detect(void)
{
- /* stopgap until OFW support is added to the kernel */
- olpc_platform_info.boardrev = olpc_board(0xc2);
+ if (!check_ofw_architecture())
+ return false;
+ olpc_platform_info.flags |= OLPC_F_PRESENT;
+ olpc_platform_info.boardrev = get_board_revision();
+ return true;
}
-#endif
-static int __init olpc_init(void)
+static int __init add_xo1_platform_devices(void)
{
- unsigned char *romsig;
+ struct platform_device *pdev;
- /* The ioremap check is dangerous; limit what we run it on */
- if (!is_geode() || cs5535_has_vsa2())
- return 0;
+ pdev = platform_device_register_simple("xo1-rfkill", -1, NULL, 0);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
- spin_lock_init(&ec_lock);
+ pdev = platform_device_register_simple("olpc-xo1", -1, NULL, 0);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
- romsig = ioremap(0xffffffc0, 16);
- if (!romsig)
- return 0;
+ return 0;
+}
- if (strncmp(romsig, "CL1 Q", 7))
- goto unmap;
- if (strncmp(romsig+6, romsig+13, 3)) {
- printk(KERN_INFO "OLPC BIOS signature looks invalid. "
- "Assuming not OLPC\n");
- goto unmap;
- }
+static int __init olpc_init(void)
+{
+ int r = 0;
- printk(KERN_INFO "OLPC board with OpenFirmware %.16s\n", romsig);
- olpc_platform_info.flags |= OLPC_F_PRESENT;
+ if (!olpc_ofw_present() || !platform_detect())
+ return 0;
- /* get the platform revision */
- platform_detect();
+ spin_lock_init(&ec_lock);
/* assume B1 and above models always have a DCON */
if (olpc_board_at_least(olpc_board(0xb1)))
@@ -242,8 +257,10 @@ static int __init olpc_init(void)
(unsigned char *) &olpc_platform_info.ecver, 1);
#ifdef CONFIG_PCI_OLPC
- /* If the VSA exists let it emulate PCI, if not emulate in kernel */
- if (!cs5535_has_vsa2())
+ /* If the VSA exists let it emulate PCI, if not emulate in kernel.
+ * XO-1 only. */
+ if (olpc_platform_info.boardrev < olpc_board_pre(0xd0) &&
+ !cs5535_has_vsa2())
x86_init.pci.arch_init = pci_olpc_init;
#endif
@@ -252,8 +269,12 @@ static int __init olpc_init(void)
olpc_platform_info.boardrev >> 4,
olpc_platform_info.ecver);
-unmap:
- iounmap(romsig);
+ if (olpc_platform_info.boardrev < olpc_board_pre(0xd0)) { /* XO-1 */
+ r = add_xo1_platform_devices();
+ if (r)
+ return r;
+ }
+
return 0;
}
diff --git a/arch/x86/kernel/olpc_ofw.c b/arch/x86/kernel/olpc_ofw.c
index 3218aa71ab5e..787320464379 100644
--- a/arch/x86/kernel/olpc_ofw.c
+++ b/arch/x86/kernel/olpc_ofw.c
@@ -74,6 +74,12 @@ int __olpc_ofw(const char *name, int nr_args, const void **args, int nr_res,
}
EXPORT_SYMBOL_GPL(__olpc_ofw);
+bool olpc_ofw_present(void)
+{
+ return olpc_ofw_cif != NULL;
+}
+EXPORT_SYMBOL_GPL(olpc_ofw_present);
+
/* OFW cif _should_ be above this address */
#define OFW_MIN 0xff000000
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index 1db183ed7c01..c5b250011fd4 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -413,7 +413,6 @@ struct pv_mmu_ops pv_mmu_ops = {
.alloc_pte = paravirt_nop,
.alloc_pmd = paravirt_nop,
- .alloc_pmd_clone = paravirt_nop,
.alloc_pud = paravirt_nop,
.release_pte = paravirt_nop,
.release_pmd = paravirt_nop,
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 078d4ec1a9d9..f56a117cef68 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -47,6 +47,7 @@
#include <asm/rio.h>
#include <asm/bios_ebda.h>
#include <asm/x86_init.h>
+#include <asm/iommu_table.h>
#ifdef CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT
int use_calgary __read_mostly = 1;
@@ -1364,7 +1365,7 @@ static int __init calgary_iommu_init(void)
return 0;
}
-void __init detect_calgary(void)
+int __init detect_calgary(void)
{
int bus;
void *tbl;
@@ -1378,13 +1379,13 @@ void __init detect_calgary(void)
* another HW IOMMU already, bail out.
*/
if (no_iommu || iommu_detected)
- return;
+ return -ENODEV;
if (!use_calgary)
- return;
+ return -ENODEV;
if (!early_pci_allowed())
- return;
+ return -ENODEV;
printk(KERN_DEBUG "Calgary: detecting Calgary via BIOS EBDA area\n");
@@ -1410,13 +1411,13 @@ void __init detect_calgary(void)
if (!rio_table_hdr) {
printk(KERN_DEBUG "Calgary: Unable to locate Rio Grande table "
"in EBDA - bailing!\n");
- return;
+ return -ENODEV;
}
ret = build_detail_arrays();
if (ret) {
printk(KERN_DEBUG "Calgary: build_detail_arrays ret %d\n", ret);
- return;
+ return -ENOMEM;
}
specified_table_size = determine_tce_table_size((is_kdump_kernel() ?
@@ -1464,7 +1465,7 @@ void __init detect_calgary(void)
x86_init.iommu.iommu_init = calgary_iommu_init;
}
- return;
+ return calgary_found;
cleanup:
for (--bus; bus >= 0; --bus) {
@@ -1473,6 +1474,7 @@ cleanup:
if (info->tce_space)
free_tce_table(info->tce_space);
}
+ return -ENOMEM;
}
static int __init calgary_parse_options(char *p)
@@ -1594,3 +1596,5 @@ static int __init calgary_fixup_tce_spaces(void)
* and before device_initcall.
*/
rootfs_initcall(calgary_fixup_tce_spaces);
+
+IOMMU_INIT_POST(detect_calgary);
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index 9f07cfcbd3a5..9ea999a4dcc1 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -11,9 +11,8 @@
#include <asm/iommu.h>
#include <asm/gart.h>
#include <asm/calgary.h>
-#include <asm/amd_iommu.h>
#include <asm/x86_init.h>
-#include <asm/xen/swiotlb-xen.h>
+#include <asm/iommu_table.h>
static int forbid_dac __read_mostly;
@@ -45,6 +44,8 @@ int iommu_detected __read_mostly = 0;
*/
int iommu_pass_through __read_mostly;
+extern struct iommu_table_entry __iommu_table[], __iommu_table_end[];
+
/* Dummy device used for NULL arguments (normally ISA). */
struct device x86_dma_fallback_dev = {
.init_name = "fallback device",
@@ -130,26 +131,24 @@ static void __init dma32_free_bootmem(void)
void __init pci_iommu_alloc(void)
{
+ struct iommu_table_entry *p;
+
/* free the range so iommu could get some range less than 4G */
dma32_free_bootmem();
- if (pci_xen_swiotlb_detect() || pci_swiotlb_detect())
- goto out;
-
- gart_iommu_hole_init();
-
- detect_calgary();
-
- detect_intel_iommu();
+ sort_iommu_table(__iommu_table, __iommu_table_end);
+ check_iommu_entries(__iommu_table, __iommu_table_end);
- /* needs to be called after gart_iommu_hole_init */
- amd_iommu_detect();
-out:
- pci_xen_swiotlb_init();
-
- pci_swiotlb_init();
+ for (p = __iommu_table; p < __iommu_table_end; p++) {
+ if (p && p->detect && p->detect() > 0) {
+ p->flags |= IOMMU_DETECTED;
+ if (p->early_init)
+ p->early_init();
+ if (p->flags & IOMMU_FINISH_IF_DETECTED)
+ break;
+ }
+ }
}
-
void *dma_generic_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_addr, gfp_t flag)
{
@@ -292,6 +291,7 @@ EXPORT_SYMBOL(dma_supported);
static int __init pci_iommu_init(void)
{
+ struct iommu_table_entry *p;
dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
#ifdef CONFIG_PCI
@@ -299,12 +299,10 @@ static int __init pci_iommu_init(void)
#endif
x86_init.iommu.iommu_init();
- if (swiotlb || xen_swiotlb) {
- printk(KERN_INFO "PCI-DMA: "
- "Using software bounce buffering for IO (SWIOTLB)\n");
- swiotlb_print_info();
- } else
- swiotlb_free();
+ for (p = __iommu_table; p < __iommu_table_end; p++) {
+ if (p && (p->flags & IOMMU_DETECTED) && p->late_init)
+ p->late_init();
+ }
return 0;
}
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index 0f7f130caa67..ba0f0ca9f280 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -39,8 +39,9 @@
#include <asm/cacheflush.h>
#include <asm/swiotlb.h>
#include <asm/dma.h>
-#include <asm/k8.h>
+#include <asm/amd_nb.h>
#include <asm/x86_init.h>
+#include <asm/iommu_table.h>
static unsigned long iommu_bus_base; /* GART remapping area (physical) */
static unsigned long iommu_size; /* size of remapping area bytes */
@@ -560,8 +561,11 @@ static void enable_gart_translations(void)
{
int i;
- for (i = 0; i < num_k8_northbridges; i++) {
- struct pci_dev *dev = k8_northbridges[i];
+ if (!k8_northbridges.gart_supported)
+ return;
+
+ for (i = 0; i < k8_northbridges.num; i++) {
+ struct pci_dev *dev = k8_northbridges.nb_misc[i];
enable_gart_translation(dev, __pa(agp_gatt_table));
}
@@ -592,16 +596,19 @@ static void gart_fixup_northbridges(struct sys_device *dev)
if (!fix_up_north_bridges)
return;
+ if (!k8_northbridges.gart_supported)
+ return;
+
pr_info("PCI-DMA: Restoring GART aperture settings\n");
- for (i = 0; i < num_k8_northbridges; i++) {
- struct pci_dev *dev = k8_northbridges[i];
+ for (i = 0; i < k8_northbridges.num; i++) {
+ struct pci_dev *dev = k8_northbridges.nb_misc[i];
/*
* Don't enable translations just yet. That is the next
* step. Restore the pre-suspend aperture settings.
*/
- pci_write_config_dword(dev, AMD64_GARTAPERTURECTL, aperture_order << 1);
+ gart_set_size_and_enable(dev, aperture_order);
pci_write_config_dword(dev, AMD64_GARTAPERTUREBASE, aperture_alloc >> 25);
}
}
@@ -649,8 +656,8 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
aper_size = aper_base = info->aper_size = 0;
dev = NULL;
- for (i = 0; i < num_k8_northbridges; i++) {
- dev = k8_northbridges[i];
+ for (i = 0; i < k8_northbridges.num; i++) {
+ dev = k8_northbridges.nb_misc[i];
new_aper_base = read_aperture(dev, &new_aper_size);
if (!new_aper_base)
goto nommu;
@@ -718,10 +725,13 @@ static void gart_iommu_shutdown(void)
if (!no_agp)
return;
- for (i = 0; i < num_k8_northbridges; i++) {
+ if (!k8_northbridges.gart_supported)
+ return;
+
+ for (i = 0; i < k8_northbridges.num; i++) {
u32 ctl;
- dev = k8_northbridges[i];
+ dev = k8_northbridges.nb_misc[i];
pci_read_config_dword(dev, AMD64_GARTAPERTURECTL, &ctl);
ctl &= ~GARTEN;
@@ -739,7 +749,7 @@ int __init gart_iommu_init(void)
unsigned long scratch;
long i;
- if (num_k8_northbridges == 0)
+ if (!k8_northbridges.gart_supported)
return 0;
#ifndef CONFIG_AGP_AMD64
@@ -896,3 +906,4 @@ void __init gart_parse_options(char *p)
}
}
}
+IOMMU_INIT_POST(gart_iommu_hole_init);
diff --git a/arch/x86/kernel/pci-iommu_table.c b/arch/x86/kernel/pci-iommu_table.c
new file mode 100644
index 000000000000..55d745ec1181
--- /dev/null
+++ b/arch/x86/kernel/pci-iommu_table.c
@@ -0,0 +1,89 @@
+#include <linux/dma-mapping.h>
+#include <asm/iommu_table.h>
+#include <linux/string.h>
+#include <linux/kallsyms.h>
+
+
+#define DEBUG 1
+
+static struct iommu_table_entry * __init
+find_dependents_of(struct iommu_table_entry *start,
+ struct iommu_table_entry *finish,
+ struct iommu_table_entry *q)
+{
+ struct iommu_table_entry *p;
+
+ if (!q)
+ return NULL;
+
+ for (p = start; p < finish; p++)
+ if (p->detect == q->depend)
+ return p;
+
+ return NULL;
+}
+
+
+void __init sort_iommu_table(struct iommu_table_entry *start,
+ struct iommu_table_entry *finish) {
+
+ struct iommu_table_entry *p, *q, tmp;
+
+ for (p = start; p < finish; p++) {
+again:
+ q = find_dependents_of(start, finish, p);
+ /* We are bit sneaky here. We use the memory address to figure
+ * out if the node we depend on is past our point, if so, swap.
+ */
+ if (q > p) {
+ tmp = *p;
+ memmove(p, q, sizeof(*p));
+ *q = tmp;
+ goto again;
+ }
+ }
+
+}
+
+#ifdef DEBUG
+void __init check_iommu_entries(struct iommu_table_entry *start,
+ struct iommu_table_entry *finish)
+{
+ struct iommu_table_entry *p, *q, *x;
+ char sym_p[KSYM_SYMBOL_LEN];
+ char sym_q[KSYM_SYMBOL_LEN];
+
+ /* Simple cyclic dependency checker. */
+ for (p = start; p < finish; p++) {
+ q = find_dependents_of(start, finish, p);
+ x = find_dependents_of(start, finish, q);
+ if (p == x) {
+ sprint_symbol(sym_p, (unsigned long)p->detect);
+ sprint_symbol(sym_q, (unsigned long)q->detect);
+
+ printk(KERN_ERR "CYCLIC DEPENDENCY FOUND! %s depends" \
+ " on %s and vice-versa. BREAKING IT.\n",
+ sym_p, sym_q);
+ /* Heavy handed way..*/
+ x->depend = 0;
+ }
+ }
+
+ for (p = start; p < finish; p++) {
+ q = find_dependents_of(p, finish, p);
+ if (q && q > p) {
+ sprint_symbol(sym_p, (unsigned long)p->detect);
+ sprint_symbol(sym_q, (unsigned long)q->detect);
+
+ printk(KERN_ERR "EXECUTION ORDER INVALID! %s "\
+ "should be called before %s!\n",
+ sym_p, sym_q);
+ }
+ }
+}
+#else
+inline void check_iommu_entries(struct iommu_table_entry *start,
+ struct iommu_table_entry *finish)
+{
+}
+#endif
diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c
index a5bc528d4328..8f972cbddef0 100644
--- a/arch/x86/kernel/pci-swiotlb.c
+++ b/arch/x86/kernel/pci-swiotlb.c
@@ -10,7 +10,8 @@
#include <asm/iommu.h>
#include <asm/swiotlb.h>
#include <asm/dma.h>
-
+#include <asm/xen/swiotlb-xen.h>
+#include <asm/iommu_table.h>
int swiotlb __read_mostly;
static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
@@ -41,25 +42,42 @@ static struct dma_map_ops swiotlb_dma_ops = {
};
/*
- * pci_swiotlb_detect - set swiotlb to 1 if necessary
+ * pci_swiotlb_detect_override - set swiotlb to 1 if necessary
*
* This returns non-zero if we are forced to use swiotlb (by the boot
* option).
*/
-int __init pci_swiotlb_detect(void)
+int __init pci_swiotlb_detect_override(void)
{
int use_swiotlb = swiotlb | swiotlb_force;
+ if (swiotlb_force)
+ swiotlb = 1;
+
+ return use_swiotlb;
+}
+IOMMU_INIT_FINISH(pci_swiotlb_detect_override,
+ pci_xen_swiotlb_detect,
+ pci_swiotlb_init,
+ pci_swiotlb_late_init);
+
+/*
+ * if 4GB or more detected (and iommu=off not set) return 1
+ * and set swiotlb to 1.
+ */
+int __init pci_swiotlb_detect_4gb(void)
+{
/* don't initialize swiotlb if iommu=off (no_iommu=1) */
#ifdef CONFIG_X86_64
if (!no_iommu && max_pfn > MAX_DMA32_PFN)
swiotlb = 1;
#endif
- if (swiotlb_force)
- swiotlb = 1;
-
- return use_swiotlb;
+ return swiotlb;
}
+IOMMU_INIT(pci_swiotlb_detect_4gb,
+ pci_swiotlb_detect_override,
+ pci_swiotlb_init,
+ pci_swiotlb_late_init);
void __init pci_swiotlb_init(void)
{
@@ -68,3 +86,15 @@ void __init pci_swiotlb_init(void)
dma_ops = &swiotlb_dma_ops;
}
}
+
+void __init pci_swiotlb_late_init(void)
+{
+ /* An IOMMU turned us off. */
+ if (!swiotlb)
+ swiotlb_free();
+ else {
+ printk(KERN_INFO "PCI-DMA: "
+ "Using software bounce buffering for IO (SWIOTLB)\n");
+ swiotlb_print_info();
+ }
+}
diff --git a/arch/x86/kernel/pmtimer_64.c b/arch/x86/kernel/pmtimer_64.c
deleted file mode 100644
index b112406f1996..000000000000
--- a/arch/x86/kernel/pmtimer_64.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/* Ported over from i386 by AK, original copyright was:
- *
- * (C) Dominik Brodowski <linux@brodo.de> 2003
- *
- * Driver to use the Power Management Timer (PMTMR) available in some
- * southbridges as primary timing source for the Linux kernel.
- *
- * Based on parts of linux/drivers/acpi/hardware/hwtimer.c, timer_pit.c,
- * timer_hpet.c, and on Arjan van de Ven's implementation for 2.4.
- *
- * This file is licensed under the GPL v2.
- *
- * Dropped all the hardware bug workarounds for now. Hopefully they
- * are not needed on 64bit chipsets.
- */
-
-#include <linux/jiffies.h>
-#include <linux/kernel.h>
-#include <linux/time.h>
-#include <linux/init.h>
-#include <linux/cpumask.h>
-#include <linux/acpi_pmtmr.h>
-
-#include <asm/io.h>
-#include <asm/proto.h>
-#include <asm/msr.h>
-#include <asm/vsyscall.h>
-
-static inline u32 cyc2us(u32 cycles)
-{
- /* The Power Management Timer ticks at 3.579545 ticks per microsecond.
- * 1 / PM_TIMER_FREQUENCY == 0.27936511 =~ 286/1024 [error: 0.024%]
- *
- * Even with HZ = 100, delta is at maximum 35796 ticks, so it can
- * easily be multiplied with 286 (=0x11E) without having to fear
- * u32 overflows.
- */
- cycles *= 286;
- return (cycles >> 10);
-}
-
-static unsigned pmtimer_wait_tick(void)
-{
- u32 a, b;
- for (a = b = inl(pmtmr_ioport) & ACPI_PM_MASK;
- a == b;
- b = inl(pmtmr_ioport) & ACPI_PM_MASK)
- cpu_relax();
- return b;
-}
-
-/* note: wait time is rounded up to one tick */
-void pmtimer_wait(unsigned us)
-{
- u32 a, b;
- a = pmtimer_wait_tick();
- do {
- b = inl(pmtmr_ioport);
- cpu_relax();
- } while (cyc2us(b - a) < us);
-}
-
-static int __init nopmtimer_setup(char *s)
-{
- pmtmr_ioport = 0;
- return 1;
-}
-
-__setup("nopmtimer", nopmtimer_setup);
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 3d9ea531ddd1..b3d7a3a04f38 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -424,7 +424,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
load_TLS(next, cpu);
/* Must be after DS reload */
- unlazy_fpu(prev_p);
+ __unlazy_fpu(prev_p);
/* Make sure cpu is ready for new context */
if (preload_fpu)
diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c
index 239427ca02af..bab3b9e6f66d 100644
--- a/arch/x86/kernel/pvclock.c
+++ b/arch/x86/kernel/pvclock.c
@@ -82,7 +82,8 @@ static inline u64 scale_delta(u64 delta, u32 mul_frac, int shift)
static u64 pvclock_get_nsec_offset(struct pvclock_shadow_time *shadow)
{
u64 delta = native_read_tsc() - shadow->tsc_timestamp;
- return scale_delta(delta, shadow->tsc_to_nsec_mul, shadow->tsc_shift);
+ return pvclock_scale_delta(delta, shadow->tsc_to_nsec_mul,
+ shadow->tsc_shift);
}
/*
diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c
index 939b9e98245f..8bbe8c56916d 100644
--- a/arch/x86/kernel/quirks.c
+++ b/arch/x86/kernel/quirks.c
@@ -344,6 +344,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235,
vt8237_force_enable_hpet);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237,
vt8237_force_enable_hpet);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_CX700,
+ vt8237_force_enable_hpet);
static void ati_force_hpet_resume(void)
{
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index e3af342fe83a..f7f53dcd3e0a 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -84,7 +84,7 @@ static int __init reboot_setup(char *str)
}
/* we will leave sorting out the final value
when we are ready to reboot, since we might not
- have set up boot_cpu_id or smp_num_cpu */
+ have detected BSP APIC ID or smp_num_cpu */
break;
#endif /* CONFIG_SMP */
@@ -371,16 +371,10 @@ void machine_real_restart(const unsigned char *code, int length)
CMOS_WRITE(0x00, 0x8f);
spin_unlock(&rtc_lock);
- /* Remap the kernel at virtual address zero, as well as offset zero
- from the kernel segment. This assumes the kernel segment starts at
- virtual address PAGE_OFFSET. */
- memcpy(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
- sizeof(swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
-
/*
- * Use `swapper_pg_dir' as our page directory.
+ * Switch back to the initial page table.
*/
- load_cr3(swapper_pg_dir);
+ load_cr3(initial_page_table);
/* Write 0x1234 to absolute memory location 0x472. The BIOS reads
this on booting to tell it to "Bypass memory test (also warm
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index c3a4fbb2b996..95a32746fbf9 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -31,6 +31,7 @@
#include <linux/apm_bios.h>
#include <linux/initrd.h>
#include <linux/bootmem.h>
+#include <linux/memblock.h>
#include <linux/seq_file.h>
#include <linux/console.h>
#include <linux/mca.h>
@@ -83,7 +84,6 @@
#include <asm/dmi.h>
#include <asm/io_apic.h>
#include <asm/ist.h>
-#include <asm/vmi.h>
#include <asm/setup_arch.h>
#include <asm/bios_ebda.h>
#include <asm/cacheflush.h>
@@ -107,11 +107,12 @@
#include <asm/percpu.h>
#include <asm/topology.h>
#include <asm/apicdef.h>
-#include <asm/k8.h>
+#include <asm/amd_nb.h>
#ifdef CONFIG_X86_64
#include <asm/numa_64.h>
#endif
#include <asm/mce.h>
+#include <asm/alternative.h>
/*
* end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries.
@@ -125,7 +126,6 @@ unsigned long max_pfn_mapped;
RESERVE_BRK(dmi_alloc, 65536);
#endif
-unsigned int boot_cpu_id __read_mostly;
static __initdata unsigned long _brk_start = (unsigned long)__brk_base;
unsigned long _brk_end = (unsigned long)__brk_base;
@@ -302,7 +302,7 @@ static inline void init_gbpages(void)
static void __init reserve_brk(void)
{
if (_brk_end > _brk_start)
- reserve_early(__pa(_brk_start), __pa(_brk_end), "BRK");
+ memblock_x86_reserve_range(__pa(_brk_start), __pa(_brk_end), "BRK");
/* Mark brk area as locked down and no longer taking any
new allocations */
@@ -324,17 +324,16 @@ static void __init relocate_initrd(void)
char *p, *q;
/* We need to move the initrd down into lowmem */
- ramdisk_here = find_e820_area(0, end_of_lowmem, area_size,
+ ramdisk_here = memblock_find_in_range(0, end_of_lowmem, area_size,
PAGE_SIZE);
- if (ramdisk_here == -1ULL)
+ if (ramdisk_here == MEMBLOCK_ERROR)
panic("Cannot find place for new RAMDISK of size %lld\n",
ramdisk_size);
/* Note: this includes all the lowmem currently occupied by
the initrd, we rely on that fact to keep the data intact. */
- reserve_early(ramdisk_here, ramdisk_here + area_size,
- "NEW RAMDISK");
+ memblock_x86_reserve_range(ramdisk_here, ramdisk_here + area_size, "NEW RAMDISK");
initrd_start = ramdisk_here + PAGE_OFFSET;
initrd_end = initrd_start + ramdisk_size;
printk(KERN_INFO "Allocated new RAMDISK: %08llx - %08llx\n",
@@ -390,7 +389,7 @@ static void __init reserve_initrd(void)
initrd_start = 0;
if (ramdisk_size >= (end_of_lowmem>>1)) {
- free_early(ramdisk_image, ramdisk_end);
+ memblock_x86_free_range(ramdisk_image, ramdisk_end);
printk(KERN_ERR "initrd too large to handle, "
"disabling initrd\n");
return;
@@ -413,7 +412,7 @@ static void __init reserve_initrd(void)
relocate_initrd();
- free_early(ramdisk_image, ramdisk_end);
+ memblock_x86_free_range(ramdisk_image, ramdisk_end);
}
#else
static void __init reserve_initrd(void)
@@ -469,7 +468,7 @@ static void __init e820_reserve_setup_data(void)
e820_print_map("reserve setup_data");
}
-static void __init reserve_early_setup_data(void)
+static void __init memblock_x86_reserve_range_setup_data(void)
{
struct setup_data *data;
u64 pa_data;
@@ -481,7 +480,7 @@ static void __init reserve_early_setup_data(void)
while (pa_data) {
data = early_memremap(pa_data, sizeof(*data));
sprintf(buf, "setup data %x", data->type);
- reserve_early(pa_data, pa_data+sizeof(*data)+data->len, buf);
+ memblock_x86_reserve_range(pa_data, pa_data+sizeof(*data)+data->len, buf);
pa_data = data->next;
early_iounmap(data, sizeof(*data));
}
@@ -502,6 +501,7 @@ static inline unsigned long long get_total_mem(void)
return total << PAGE_SHIFT;
}
+#define DEFAULT_BZIMAGE_ADDR_MAX 0x37FFFFFF
static void __init reserve_crashkernel(void)
{
unsigned long long total_mem;
@@ -519,23 +519,27 @@ static void __init reserve_crashkernel(void)
if (crash_base <= 0) {
const unsigned long long alignment = 16<<20; /* 16M */
- crash_base = find_e820_area(alignment, ULONG_MAX, crash_size,
- alignment);
- if (crash_base == -1ULL) {
+ /*
+ * kexec want bzImage is below DEFAULT_BZIMAGE_ADDR_MAX
+ */
+ crash_base = memblock_find_in_range(alignment,
+ DEFAULT_BZIMAGE_ADDR_MAX, crash_size, alignment);
+
+ if (crash_base == MEMBLOCK_ERROR) {
pr_info("crashkernel reservation failed - No suitable area found.\n");
return;
}
} else {
unsigned long long start;
- start = find_e820_area(crash_base, ULONG_MAX, crash_size,
- 1<<20);
+ start = memblock_find_in_range(crash_base,
+ crash_base + crash_size, crash_size, 1<<20);
if (start != crash_base) {
pr_info("crashkernel reservation failed - memory is in use.\n");
return;
}
}
- reserve_early(crash_base, crash_base + crash_size, "CRASH KERNEL");
+ memblock_x86_reserve_range(crash_base, crash_base + crash_size, "CRASH KERNEL");
printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
"for crashkernel (System RAM: %ldMB)\n",
@@ -615,82 +619,10 @@ static __init void reserve_ibft_region(void)
addr = find_ibft_region(&size);
if (size)
- reserve_early_overlap_ok(addr, addr + size, "ibft");
+ memblock_x86_reserve_range(addr, addr + size, "* ibft");
}
-#ifdef CONFIG_X86_RESERVE_LOW_64K
-static int __init dmi_low_memory_corruption(const struct dmi_system_id *d)
-{
- printk(KERN_NOTICE
- "%s detected: BIOS may corrupt low RAM, working around it.\n",
- d->ident);
-
- e820_update_range(0, 0x10000, E820_RAM, E820_RESERVED);
- sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
-
- return 0;
-}
-#endif
-
-/* List of systems that have known low memory corruption BIOS problems */
-static struct dmi_system_id __initdata bad_bios_dmi_table[] = {
-#ifdef CONFIG_X86_RESERVE_LOW_64K
- {
- .callback = dmi_low_memory_corruption,
- .ident = "AMI BIOS",
- .matches = {
- DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
- },
- },
- {
- .callback = dmi_low_memory_corruption,
- .ident = "Phoenix BIOS",
- .matches = {
- DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies"),
- },
- },
- {
- .callback = dmi_low_memory_corruption,
- .ident = "Phoenix/MSC BIOS",
- .matches = {
- DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix/MSC"),
- },
- },
- /*
- * AMI BIOS with low memory corruption was found on Intel DG45ID and
- * DG45FC boards.
- * It has a different DMI_BIOS_VENDOR = "Intel Corp.", for now we will
- * match only DMI_BOARD_NAME and see if there is more bad products
- * with this vendor.
- */
- {
- .callback = dmi_low_memory_corruption,
- .ident = "AMI BIOS",
- .matches = {
- DMI_MATCH(DMI_BOARD_NAME, "DG45ID"),
- },
- },
- {
- .callback = dmi_low_memory_corruption,
- .ident = "AMI BIOS",
- .matches = {
- DMI_MATCH(DMI_BOARD_NAME, "DG45FC"),
- },
- },
- /*
- * The Dell Inspiron Mini 1012 has DMI_BIOS_VENDOR = "Dell Inc.", so
- * match on the product name.
- */
- {
- .callback = dmi_low_memory_corruption,
- .ident = "Phoenix BIOS",
- .matches = {
- DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1012"),
- },
- },
-#endif
- {}
-};
+static unsigned reserve_low = CONFIG_X86_RESERVE_LOW << 10;
static void __init trim_bios_range(void)
{
@@ -698,8 +630,14 @@ static void __init trim_bios_range(void)
* A special case is the first 4Kb of memory;
* This is a BIOS owned area, not kernel ram, but generally
* not listed as such in the E820 table.
+ *
+ * This typically reserves additional memory (64KiB by default)
+ * since some BIOSes are known to corrupt low memory. See the
+ * Kconfig help text for X86_RESERVE_LOW.
*/
- e820_update_range(0, PAGE_SIZE, E820_RAM, E820_RESERVED);
+ e820_update_range(0, ALIGN(reserve_low, PAGE_SIZE),
+ E820_RAM, E820_RESERVED);
+
/*
* special case: Some BIOSen report the PC BIOS
* area (640->1Mb) as ram even though it is not.
@@ -709,6 +647,37 @@ static void __init trim_bios_range(void)
sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
}
+static int __init parse_reservelow(char *p)
+{
+ unsigned long long size;
+
+ if (!p)
+ return -EINVAL;
+
+ size = memparse(p, &p);
+
+ if (size < 4096)
+ size = 4096;
+
+ if (size > 640*1024)
+ size = 640*1024;
+
+ reserve_low = size;
+
+ return 0;
+}
+
+early_param("reservelow", parse_reservelow);
+
+static u64 __init get_max_mapped(void)
+{
+ u64 end = max_pfn_mapped;
+
+ end <<= PAGE_SHIFT;
+
+ return end;
+}
+
/*
* Determine if we were loaded by an EFI loader. If so, then we have also been
* passed the efi memmap, systab, etc., so we should use these data structures
@@ -726,18 +695,30 @@ void __init setup_arch(char **cmdline_p)
{
int acpi = 0;
int k8 = 0;
+ unsigned long flags;
#ifdef CONFIG_X86_32
memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
visws_early_detect();
+
+ /*
+ * copy kernel address range established so far and switch
+ * to the proper swapper page table
+ */
+ clone_pgd_range(swapper_pg_dir + KERNEL_PGD_BOUNDARY,
+ initial_page_table + KERNEL_PGD_BOUNDARY,
+ KERNEL_PGD_PTRS);
+
+ load_cr3(swapper_pg_dir);
+ __flush_tlb_all();
#else
printk(KERN_INFO "Command line: %s\n", boot_command_line);
#endif
- /* VMI may relocate the fixmap; do this before touching ioremap area */
- vmi_init();
-
- /* OFW also may relocate the fixmap */
+ /*
+ * If we have OLPC OFW, we might end up relocating the fixmap due to
+ * reserve_top(), so do this before touching the ioremap area.
+ */
olpc_ofw_detect();
early_trap_init();
@@ -782,7 +763,7 @@ void __init setup_arch(char **cmdline_p)
#endif
4)) {
efi_enabled = 1;
- efi_reserve_early();
+ efi_memblock_x86_reserve_range();
}
#endif
@@ -838,11 +819,8 @@ void __init setup_arch(char **cmdline_p)
x86_report_nx();
- /* Must be before kernel pagetables are setup */
- vmi_activate();
-
/* after early param, so could get panic from serial */
- reserve_early_setup_data();
+ memblock_x86_reserve_range_setup_data();
if (acpi_mps_check()) {
#ifdef CONFIG_X86_LOCAL_APIC
@@ -863,8 +841,6 @@ void __init setup_arch(char **cmdline_p)
dmi_scan_machine();
- dmi_check_system(bad_bios_dmi_table);
-
/*
* VMware detection requires dmi to be available, so this
* needs to be done after dmi_scan_machine, for the BP.
@@ -897,8 +873,6 @@ void __init setup_arch(char **cmdline_p)
*/
max_pfn = e820_end_of_ram_pfn();
- /* preallocate 4k for mptable mpc */
- early_reserve_e820_mpc_new();
/* update e820 for memory not covered by WB MTRRs */
mtrr_bp_init();
if (mtrr_trim_uncached_memory(max_pfn))
@@ -920,18 +894,8 @@ void __init setup_arch(char **cmdline_p)
max_low_pfn = max_pfn;
high_memory = (void *)__va(max_pfn * PAGE_SIZE - 1) + 1;
- max_pfn_mapped = KERNEL_IMAGE_SIZE >> PAGE_SHIFT;
#endif
-#ifdef CONFIG_X86_CHECK_BIOS_CORRUPTION
- setup_bios_corruption_check();
-#endif
-
- printk(KERN_DEBUG "initial memory mapped : 0 - %08lx\n",
- max_pfn_mapped<<PAGE_SHIFT);
-
- reserve_brk();
-
/*
* Find and reserve possible boot-time SMP configuration:
*/
@@ -939,6 +903,26 @@ void __init setup_arch(char **cmdline_p)
reserve_ibft_region();
+ /*
+ * Need to conclude brk, before memblock_x86_fill()
+ * it could use memblock_find_in_range, could overlap with
+ * brk area.
+ */
+ reserve_brk();
+
+ memblock.current_limit = get_max_mapped();
+ memblock_x86_fill();
+
+ /* preallocate 4k for mptable mpc */
+ early_reserve_e820_mpc_new();
+
+#ifdef CONFIG_X86_CHECK_BIOS_CORRUPTION
+ setup_bios_corruption_check();
+#endif
+
+ printk(KERN_DEBUG "initial memory mapped : 0 - %08lx\n",
+ max_pfn_mapped<<PAGE_SHIFT);
+
reserve_trampoline_memory();
#ifdef CONFIG_ACPI_SLEEP
@@ -962,6 +946,7 @@ void __init setup_arch(char **cmdline_p)
max_low_pfn = max_pfn;
}
#endif
+ memblock.current_limit = get_max_mapped();
/*
* NOTE: On x86-32, only from this point on, fixmaps are ready for use.
@@ -1000,10 +985,7 @@ void __init setup_arch(char **cmdline_p)
#endif
initmem_init(0, max_pfn, acpi, k8);
-#ifndef CONFIG_NO_BOOTMEM
- early_res_to_bootmem(0, max_low_pfn<<PAGE_SHIFT);
-#endif
-
+ memblock_find_dma_reserve();
dma32_reserve_bootmem();
#ifdef CONFIG_KVM_CLOCK
@@ -1014,7 +996,12 @@ void __init setup_arch(char **cmdline_p)
paging_init();
x86_init.paging.pagetable_setup_done(swapper_pg_dir);
- setup_trampoline_page_table();
+#ifdef CONFIG_X86_32
+ /* sync back kernel address range */
+ clone_pgd_range(initial_page_table + KERNEL_PGD_BOUNDARY,
+ swapper_pg_dir + KERNEL_PGD_BOUNDARY,
+ KERNEL_PGD_PTRS);
+#endif
tboot_probe();
@@ -1071,6 +1058,10 @@ void __init setup_arch(char **cmdline_p)
x86_init.oem.banner();
mcheck_init();
+
+ local_irq_save(flags);
+ arch_init_ideal_nop5();
+ local_irq_restore(flags);
}
#ifdef CONFIG_X86_32
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
index a60df9ae6454..002b79685f73 100644
--- a/arch/x86/kernel/setup_percpu.c
+++ b/arch/x86/kernel/setup_percpu.c
@@ -131,13 +131,7 @@ static void * __init pcpu_fc_alloc(unsigned int cpu, size_t size, size_t align)
static void __init pcpu_fc_free(void *ptr, size_t size)
{
-#ifdef CONFIG_NO_BOOTMEM
- u64 start = __pa(ptr);
- u64 end = start + size;
- free_early_partial(start, end);
-#else
free_bootmem(__pa(ptr), size);
-#endif
}
static int __init pcpu_cpu_distance(unsigned int from, unsigned int to)
@@ -253,7 +247,7 @@ void __init setup_per_cpu_areas(void)
* Up to this point, the boot CPU has been using .init.data
* area. Reload any changed state for the boot CPU.
*/
- if (cpu == boot_cpu_id)
+ if (!cpu)
switch_to_new_gdt(cpu);
}
diff --git a/arch/x86/kernel/sfi.c b/arch/x86/kernel/sfi.c
index cb22acf3ed09..dd4c281ffe57 100644
--- a/arch/x86/kernel/sfi.c
+++ b/arch/x86/kernel/sfi.c
@@ -34,7 +34,7 @@
#ifdef CONFIG_X86_LOCAL_APIC
static unsigned long sfi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
-void __init mp_sfi_register_lapic_address(unsigned long address)
+static void __init mp_sfi_register_lapic_address(unsigned long address)
{
mp_lapic_addr = address;
@@ -46,7 +46,7 @@ void __init mp_sfi_register_lapic_address(unsigned long address)
}
/* All CPUs enumerated by SFI must be present and enabled */
-void __cpuinit mp_sfi_register_lapic(u8 id)
+static void __cpuinit mp_sfi_register_lapic(u8 id)
{
if (MAX_APICS - id <= 0) {
pr_warning("Processor #%d invalid (max %d)\n",
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 8b3bfc4dd708..6af118511b4a 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -62,7 +62,7 @@
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
#include <asm/mtrr.h>
-#include <asm/vmi.h>
+#include <asm/mwait.h>
#include <asm/apic.h>
#include <asm/setup.h>
#include <asm/uv/uv.h>
@@ -299,23 +299,16 @@ notrace static void __cpuinit start_secondary(void *unused)
* fragile that we want to limit the things done here to the
* most necessary things.
*/
+ cpu_init();
+ preempt_disable();
+ smp_callin();
#ifdef CONFIG_X86_32
- /*
- * Switch away from the trampoline page-table
- *
- * Do this before cpu_init() because it needs to access per-cpu
- * data which may not be mapped in the trampoline page-table.
- */
+ /* switch away from the initial page table */
load_cr3(swapper_pg_dir);
__flush_tlb_all();
#endif
- vmi_bringup();
- cpu_init();
- preempt_disable();
- smp_callin();
-
/* otherwise gcc will move up smp_processor_id before the cpu_init */
barrier();
/*
@@ -324,9 +317,9 @@ notrace static void __cpuinit start_secondary(void *unused)
check_tsc_sync_target();
if (nmi_watchdog == NMI_IO_APIC) {
- legacy_pic->chip->mask(0);
+ legacy_pic->mask(0);
enable_NMI_through_LVT0();
- legacy_pic->chip->unmask(0);
+ legacy_pic->unmask(0);
}
/* This must be done before setting cpu_online_mask */
@@ -397,6 +390,19 @@ void __cpuinit smp_store_cpu_info(int id)
identify_secondary_cpu(c);
}
+static void __cpuinit link_thread_siblings(int cpu1, int cpu2)
+{
+ struct cpuinfo_x86 *c1 = &cpu_data(cpu1);
+ struct cpuinfo_x86 *c2 = &cpu_data(cpu2);
+
+ cpumask_set_cpu(cpu1, cpu_sibling_mask(cpu2));
+ cpumask_set_cpu(cpu2, cpu_sibling_mask(cpu1));
+ cpumask_set_cpu(cpu1, cpu_core_mask(cpu2));
+ cpumask_set_cpu(cpu2, cpu_core_mask(cpu1));
+ cpumask_set_cpu(cpu1, c2->llc_shared_map);
+ cpumask_set_cpu(cpu2, c1->llc_shared_map);
+}
+
void __cpuinit set_cpu_sibling_map(int cpu)
{
@@ -409,14 +415,13 @@ void __cpuinit set_cpu_sibling_map(int cpu)
for_each_cpu(i, cpu_sibling_setup_mask) {
struct cpuinfo_x86 *o = &cpu_data(i);
- if (c->phys_proc_id == o->phys_proc_id &&
- c->cpu_core_id == o->cpu_core_id) {
- cpumask_set_cpu(i, cpu_sibling_mask(cpu));
- cpumask_set_cpu(cpu, cpu_sibling_mask(i));
- cpumask_set_cpu(i, cpu_core_mask(cpu));
- cpumask_set_cpu(cpu, cpu_core_mask(i));
- cpumask_set_cpu(i, c->llc_shared_map);
- cpumask_set_cpu(cpu, o->llc_shared_map);
+ if (cpu_has(c, X86_FEATURE_TOPOEXT)) {
+ if (c->phys_proc_id == o->phys_proc_id &&
+ c->compute_unit_id == o->compute_unit_id)
+ link_thread_siblings(cpu, i);
+ } else if (c->phys_proc_id == o->phys_proc_id &&
+ c->cpu_core_id == o->cpu_core_id) {
+ link_thread_siblings(cpu, i);
}
}
} else {
@@ -774,7 +779,6 @@ do_rest:
#ifdef CONFIG_X86_32
/* Stack for startup_32 can be just as for start_secondary onwards */
irq_ctx_init(cpu);
- initial_page_table = __pa(&trampoline_pg_dir);
#else
clear_tsk_thread_flag(c_idle.idle, TIF_FORK);
initial_gs = per_cpu_offset(cpu);
@@ -923,7 +927,6 @@ int __cpuinit native_cpu_up(unsigned int cpu)
per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
err = do_boot_cpu(apicid, cpu);
-
if (err) {
pr_debug("do_boot_cpu failed %d\n", err);
return -EIO;
@@ -1109,8 +1112,6 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
}
set_cpu_sibling_map(0);
- enable_IR_x2apic();
- default_setup_apic_routing();
if (smp_sanity_check(max_cpus) < 0) {
printk(KERN_INFO "SMP disabled\n");
@@ -1118,6 +1119,8 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
goto out;
}
+ default_setup_apic_routing();
+
preempt_disable();
if (read_apic_id() != boot_cpu_physical_apicid) {
panic("Boot APIC ID in local APIC unexpected (%d vs %d)",
@@ -1383,11 +1386,88 @@ void play_dead_common(void)
local_irq_disable();
}
+/*
+ * We need to flush the caches before going to sleep, lest we have
+ * dirty data in our caches when we come back up.
+ */
+static inline void mwait_play_dead(void)
+{
+ unsigned int eax, ebx, ecx, edx;
+ unsigned int highest_cstate = 0;
+ unsigned int highest_subcstate = 0;
+ int i;
+ void *mwait_ptr;
+
+ if (!cpu_has(&current_cpu_data, X86_FEATURE_MWAIT))
+ return;
+ if (!cpu_has(&current_cpu_data, X86_FEATURE_CLFLSH))
+ return;
+ if (current_cpu_data.cpuid_level < CPUID_MWAIT_LEAF)
+ return;
+
+ eax = CPUID_MWAIT_LEAF;
+ ecx = 0;
+ native_cpuid(&eax, &ebx, &ecx, &edx);
+
+ /*
+ * eax will be 0 if EDX enumeration is not valid.
+ * Initialized below to cstate, sub_cstate value when EDX is valid.
+ */
+ if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED)) {
+ eax = 0;
+ } else {
+ edx >>= MWAIT_SUBSTATE_SIZE;
+ for (i = 0; i < 7 && edx; i++, edx >>= MWAIT_SUBSTATE_SIZE) {
+ if (edx & MWAIT_SUBSTATE_MASK) {
+ highest_cstate = i;
+ highest_subcstate = edx & MWAIT_SUBSTATE_MASK;
+ }
+ }
+ eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) |
+ (highest_subcstate - 1);
+ }
+
+ /*
+ * This should be a memory location in a cache line which is
+ * unlikely to be touched by other processors. The actual
+ * content is immaterial as it is not actually modified in any way.
+ */
+ mwait_ptr = &current_thread_info()->flags;
+
+ wbinvd();
+
+ while (1) {
+ /*
+ * The CLFLUSH is a workaround for erratum AAI65 for
+ * the Xeon 7400 series. It's not clear it is actually
+ * needed, but it should be harmless in either case.
+ * The WBINVD is insufficient due to the spurious-wakeup
+ * case where we return around the loop.
+ */
+ clflush(mwait_ptr);
+ __monitor(mwait_ptr, 0, 0);
+ mb();
+ __mwait(eax, 0);
+ }
+}
+
+static inline void hlt_play_dead(void)
+{
+ if (current_cpu_data.x86 >= 4)
+ wbinvd();
+
+ while (1) {
+ native_halt();
+ }
+}
+
void native_play_dead(void)
{
play_dead_common();
tboot_shutdown(TB_SHUTDOWN_WFS);
- wbinvd_halt();
+
+ mwait_play_dead(); /* Only returns on failure */
+ hlt_play_dead();
}
#else /* ... !CONFIG_HOTPLUG_CPU */
diff --git a/arch/x86/kernel/sys_i386_32.c b/arch/x86/kernel/sys_i386_32.c
index d5e06624e34a..0b0cb5fede19 100644
--- a/arch/x86/kernel/sys_i386_32.c
+++ b/arch/x86/kernel/sys_i386_32.c
@@ -33,8 +33,8 @@ int kernel_execve(const char *filename,
const char *const envp[])
{
long __res;
- asm volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx"
+ asm volatile ("int $0x80"
: "=a" (__res)
- : "0" (__NR_execve), "ri" (filename), "c" (argv), "d" (envp) : "memory");
+ : "0" (__NR_execve), "b" (filename), "c" (argv), "d" (envp) : "memory");
return __res;
}
diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c
index 312ef0292815..20ea20a39e2a 100644
--- a/arch/x86/kernel/tlb_uv.c
+++ b/arch/x86/kernel/tlb_uv.c
@@ -1001,10 +1001,10 @@ static int uv_ptc_seq_show(struct seq_file *file, void *data)
static ssize_t tunables_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
- char buf[300];
+ char *buf;
int ret;
- ret = snprintf(buf, 300, "%s %s %s\n%d %d %d %d %d %d %d %d %d\n",
+ buf = kasprintf(GFP_KERNEL, "%s %s %s\n%d %d %d %d %d %d %d %d %d\n",
"max_bau_concurrent plugged_delay plugsb4reset",
"timeoutsb4reset ipi_reset_limit complete_threshold",
"congested_response_us congested_reps congested_period",
@@ -1012,7 +1012,12 @@ static ssize_t tunables_read(struct file *file, char __user *userbuf,
timeoutsb4reset, ipi_reset_limit, complete_threshold,
congested_response_us, congested_reps, congested_period);
- return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
+ if (!buf)
+ return -ENOMEM;
+
+ ret = simple_read_from_buffer(userbuf, count, ppos, buf, strlen(buf));
+ kfree(buf);
+ return ret;
}
/*
@@ -1285,6 +1290,7 @@ static const struct file_operations tunables_fops = {
.open = tunables_open,
.read = tunables_read,
.write = tunables_write,
+ .llseek = default_llseek,
};
static int __init uv_ptc_init(void)
diff --git a/arch/x86/kernel/trampoline.c b/arch/x86/kernel/trampoline.c
index e2a595257390..a375616d77f7 100644
--- a/arch/x86/kernel/trampoline.c
+++ b/arch/x86/kernel/trampoline.c
@@ -1,8 +1,8 @@
#include <linux/io.h>
+#include <linux/memblock.h>
#include <asm/trampoline.h>
#include <asm/pgtable.h>
-#include <asm/e820.h>
#if defined(CONFIG_X86_64) && defined(CONFIG_ACPI_SLEEP)
#define __trampinit
@@ -17,15 +17,15 @@ unsigned char *__trampinitdata trampoline_base;
void __init reserve_trampoline_memory(void)
{
- unsigned long mem;
+ phys_addr_t mem;
/* Has to be in very low memory so we can execute real-mode AP code. */
- mem = find_e820_area(0, 1<<20, TRAMPOLINE_SIZE, PAGE_SIZE);
- if (mem == -1L)
+ mem = memblock_find_in_range(0, 1<<20, TRAMPOLINE_SIZE, PAGE_SIZE);
+ if (mem == MEMBLOCK_ERROR)
panic("Cannot allocate trampoline\n");
trampoline_base = __va(mem);
- reserve_early(mem, mem + TRAMPOLINE_SIZE, "TRAMPOLINE");
+ memblock_x86_reserve_range(mem, mem + TRAMPOLINE_SIZE, "TRAMPOLINE");
}
/*
@@ -38,19 +38,3 @@ unsigned long __trampinit setup_trampoline(void)
memcpy(trampoline_base, trampoline_data, TRAMPOLINE_SIZE);
return virt_to_phys(trampoline_base);
}
-
-void __init setup_trampoline_page_table(void)
-{
-#ifdef CONFIG_X86_32
- /* Copy kernel address range */
- clone_pgd_range(trampoline_pg_dir + KERNEL_PGD_BOUNDARY,
- swapper_pg_dir + KERNEL_PGD_BOUNDARY,
- KERNEL_PGD_PTRS);
-
- /* Initialize low mappings */
- clone_pgd_range(trampoline_pg_dir,
- swapper_pg_dir + KERNEL_PGD_BOUNDARY,
- min_t(unsigned long, KERNEL_PGD_PTRS,
- KERNEL_PGD_BOUNDARY));
-#endif
-}
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 60788dee0f8a..cb838ca42c96 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -575,6 +575,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
if (regs->flags & X86_VM_MASK) {
handle_vm86_trap((struct kernel_vm86_regs *) regs,
error_code, 1);
+ preempt_conditional_cli(regs);
return;
}
@@ -776,21 +777,10 @@ asmlinkage void math_state_restore(void)
}
EXPORT_SYMBOL_GPL(math_state_restore);
-#ifndef CONFIG_MATH_EMULATION
-void math_emulate(struct math_emu_info *info)
-{
- printk(KERN_EMERG
- "math-emulation not enabled and no coprocessor found.\n");
- printk(KERN_EMERG "killing %s.\n", current->comm);
- force_sig(SIGFPE, current);
- schedule();
-}
-#endif /* CONFIG_MATH_EMULATION */
-
dotraplinkage void __kprobes
do_device_not_available(struct pt_regs *regs, long error_code)
{
-#ifdef CONFIG_X86_32
+#ifdef CONFIG_MATH_EMULATION
if (read_cr0() & X86_CR0_EM) {
struct math_emu_info info = { };
@@ -798,12 +788,12 @@ do_device_not_available(struct pt_regs *regs, long error_code)
info.regs = regs;
math_emulate(&info);
- } else {
- math_state_restore(); /* interrupts still off */
- conditional_sti(regs);
+ return;
}
-#else
- math_state_restore();
+#endif
+ math_state_restore(); /* interrupts still off */
+#ifdef CONFIG_X86_32
+ conditional_sti(regs);
#endif
}
@@ -881,18 +871,6 @@ void __init trap_init(void)
#endif
#ifdef CONFIG_X86_32
- if (cpu_has_fxsr) {
- printk(KERN_INFO "Enabling fast FPU save and restore... ");
- set_in_cr4(X86_CR4_OSFXSR);
- printk("done.\n");
- }
- if (cpu_has_xmm) {
- printk(KERN_INFO
- "Enabling unmasked SIMD FPU exception support... ");
- set_in_cr4(X86_CR4_OSXMMEXCPT);
- printk("done.\n");
- }
-
set_system_trap_gate(SYSCALL_VECTOR, &system_call);
set_bit(SYSCALL_VECTOR, used_vectors);
#endif
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 26a863a9c2a8..0c40d8b72416 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -104,10 +104,14 @@ int __init notsc_setup(char *str)
__setup("notsc", notsc_setup);
+static int no_sched_irq_time;
+
static int __init tsc_setup(char *str)
{
if (!strcmp(str, "reliable"))
tsc_clocksource_reliable = 1;
+ if (!strncmp(str, "noirqtime", 9))
+ no_sched_irq_time = 1;
return 1;
}
@@ -801,6 +805,7 @@ void mark_tsc_unstable(char *reason)
if (!tsc_unstable) {
tsc_unstable = 1;
sched_clock_stable = 0;
+ disable_sched_clock_irqtime();
printk(KERN_INFO "Marking TSC unstable due to %s\n", reason);
/* Change only the rating, when not registered */
if (clocksource_tsc.mult)
@@ -892,60 +897,6 @@ static void __init init_tsc_clocksource(void)
clocksource_register_khz(&clocksource_tsc, tsc_khz);
}
-#ifdef CONFIG_X86_64
-/*
- * calibrate_cpu is used on systems with fixed rate TSCs to determine
- * processor frequency
- */
-#define TICK_COUNT 100000000
-static unsigned long __init calibrate_cpu(void)
-{
- int tsc_start, tsc_now;
- int i, no_ctr_free;
- unsigned long evntsel3 = 0, pmc3 = 0, pmc_now = 0;
- unsigned long flags;
-
- for (i = 0; i < 4; i++)
- if (avail_to_resrv_perfctr_nmi_bit(i))
- break;
- no_ctr_free = (i == 4);
- if (no_ctr_free) {
- WARN(1, KERN_WARNING "Warning: AMD perfctrs busy ... "
- "cpu_khz value may be incorrect.\n");
- i = 3;
- rdmsrl(MSR_K7_EVNTSEL3, evntsel3);
- wrmsrl(MSR_K7_EVNTSEL3, 0);
- rdmsrl(MSR_K7_PERFCTR3, pmc3);
- } else {
- reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i);
- reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i);
- }
- local_irq_save(flags);
- /* start measuring cycles, incrementing from 0 */
- wrmsrl(MSR_K7_PERFCTR0 + i, 0);
- wrmsrl(MSR_K7_EVNTSEL0 + i, 1 << 22 | 3 << 16 | 0x76);
- rdtscl(tsc_start);
- do {
- rdmsrl(MSR_K7_PERFCTR0 + i, pmc_now);
- tsc_now = get_cycles();
- } while ((tsc_now - tsc_start) < TICK_COUNT);
-
- local_irq_restore(flags);
- if (no_ctr_free) {
- wrmsrl(MSR_K7_EVNTSEL3, 0);
- wrmsrl(MSR_K7_PERFCTR3, pmc3);
- wrmsrl(MSR_K7_EVNTSEL3, evntsel3);
- } else {
- release_perfctr_nmi(MSR_K7_PERFCTR0 + i);
- release_evntsel_nmi(MSR_K7_EVNTSEL0 + i);
- }
-
- return pmc_now * tsc_khz / (tsc_now - tsc_start);
-}
-#else
-static inline unsigned long calibrate_cpu(void) { return cpu_khz; }
-#endif
-
void __init tsc_init(void)
{
u64 lpj;
@@ -964,10 +915,6 @@ void __init tsc_init(void)
return;
}
- if (cpu_has(&boot_cpu_data, X86_FEATURE_CONSTANT_TSC) &&
- (boot_cpu_data.x86_vendor == X86_VENDOR_AMD))
- cpu_khz = calibrate_cpu();
-
printk("Detected %lu.%03lu MHz processor.\n",
(unsigned long)cpu_khz / 1000,
(unsigned long)cpu_khz % 1000);
@@ -987,6 +934,9 @@ void __init tsc_init(void)
/* now allow native_sched_clock() to use rdtsc */
tsc_disabled = 0;
+ if (!no_sched_irq_time)
+ enable_sched_clock_irqtime();
+
lpj = ((u64)tsc_khz * 1000);
do_div(lpj, HZ);
lpj_fine = lpj;
diff --git a/arch/x86/kernel/uv_irq.c b/arch/x86/kernel/uv_irq.c
index 1132129db792..7b24460917d5 100644
--- a/arch/x86/kernel/uv_irq.c
+++ b/arch/x86/kernel/uv_irq.c
@@ -28,34 +28,21 @@ struct uv_irq_2_mmr_pnode{
static spinlock_t uv_irq_lock;
static struct rb_root uv_irq_root;
-static int uv_set_irq_affinity(unsigned int, const struct cpumask *);
+static int uv_set_irq_affinity(struct irq_data *, const struct cpumask *, bool);
-static void uv_noop(unsigned int irq)
-{
-}
-
-static unsigned int uv_noop_ret(unsigned int irq)
-{
- return 0;
-}
+static void uv_noop(struct irq_data *data) { }
-static void uv_ack_apic(unsigned int irq)
+static void uv_ack_apic(struct irq_data *data)
{
ack_APIC_irq();
}
static struct irq_chip uv_irq_chip = {
- .name = "UV-CORE",
- .startup = uv_noop_ret,
- .shutdown = uv_noop,
- .enable = uv_noop,
- .disable = uv_noop,
- .ack = uv_noop,
- .mask = uv_noop,
- .unmask = uv_noop,
- .eoi = uv_ack_apic,
- .end = uv_noop,
- .set_affinity = uv_set_irq_affinity,
+ .name = "UV-CORE",
+ .irq_mask = uv_noop,
+ .irq_unmask = uv_noop,
+ .irq_eoi = uv_ack_apic,
+ .irq_set_affinity = uv_set_irq_affinity,
};
/*
@@ -144,26 +131,22 @@ arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade,
unsigned long mmr_offset, int limit)
{
const struct cpumask *eligible_cpu = cpumask_of(cpu);
- struct irq_desc *desc = irq_to_desc(irq);
- struct irq_cfg *cfg;
- int mmr_pnode;
+ struct irq_cfg *cfg = get_irq_chip_data(irq);
unsigned long mmr_value;
struct uv_IO_APIC_route_entry *entry;
- int err;
+ int mmr_pnode, err;
BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) !=
sizeof(unsigned long));
- cfg = irq_cfg(irq);
-
err = assign_irq_vector(irq, cfg, eligible_cpu);
if (err != 0)
return err;
if (limit == UV_AFFINITY_CPU)
- desc->status |= IRQ_NO_BALANCING;
+ irq_set_status_flags(irq, IRQ_NO_BALANCING);
else
- desc->status |= IRQ_MOVE_PCNTXT;
+ irq_set_status_flags(irq, IRQ_MOVE_PCNTXT);
set_irq_chip_and_handler_name(irq, &uv_irq_chip, handle_percpu_irq,
irq_name);
@@ -206,17 +189,17 @@ static void arch_disable_uv_irq(int mmr_pnode, unsigned long mmr_offset)
uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value);
}
-static int uv_set_irq_affinity(unsigned int irq, const struct cpumask *mask)
+static int
+uv_set_irq_affinity(struct irq_data *data, const struct cpumask *mask,
+ bool force)
{
- struct irq_desc *desc = irq_to_desc(irq);
- struct irq_cfg *cfg = desc->chip_data;
+ struct irq_cfg *cfg = data->chip_data;
unsigned int dest;
- unsigned long mmr_value;
+ unsigned long mmr_value, mmr_offset;
struct uv_IO_APIC_route_entry *entry;
- unsigned long mmr_offset;
int mmr_pnode;
- if (set_desc_affinity(desc, mask, &dest))
+ if (__ioapic_set_affinity(data, mask, &dest))
return -1;
mmr_value = 0;
@@ -231,7 +214,7 @@ static int uv_set_irq_affinity(unsigned int irq, const struct cpumask *mask)
entry->dest = dest;
/* Get previously stored MMR and pnode of hub sourcing interrupts */
- if (uv_irq_2_mmr_info(irq, &mmr_offset, &mmr_pnode))
+ if (uv_irq_2_mmr_info(data->irq, &mmr_offset, &mmr_pnode))
return -1;
uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value);
diff --git a/arch/x86/kernel/visws_quirks.c b/arch/x86/kernel/visws_quirks.c
index e680ea52db9b..3371bd053b89 100644
--- a/arch/x86/kernel/visws_quirks.c
+++ b/arch/x86/kernel/visws_quirks.c
@@ -66,10 +66,7 @@ static void __init visws_time_init(void)
}
/* Replaces the default init_ISA_irqs in the generic setup */
-static void __init visws_pre_intr_init(void)
-{
- init_VISWS_APIC_irqs();
-}
+static void __init visws_pre_intr_init(void);
/* Quirk for machine specific memory setup. */
@@ -429,67 +426,34 @@ static int is_co_apic(unsigned int irq)
/*
* This is the SGI Cobalt (IO-)APIC:
*/
-
-static void enable_cobalt_irq(unsigned int irq)
+static void enable_cobalt_irq(struct irq_data *data)
{
- co_apic_set(is_co_apic(irq), irq);
+ co_apic_set(is_co_apic(data->irq), data->irq);
}
-static void disable_cobalt_irq(unsigned int irq)
+static void disable_cobalt_irq(struct irq_data *data)
{
- int entry = is_co_apic(irq);
+ int entry = is_co_apic(data->irq);
co_apic_write(CO_APIC_LO(entry), CO_APIC_MASK);
co_apic_read(CO_APIC_LO(entry));
}
-/*
- * "irq" really just serves to identify the device. Here is where we
- * map this to the Cobalt APIC entry where it's physically wired.
- * This is called via request_irq -> setup_irq -> irq_desc->startup()
- */
-static unsigned int startup_cobalt_irq(unsigned int irq)
+static void ack_cobalt_irq(struct irq_data *data)
{
unsigned long flags;
- struct irq_desc *desc = irq_to_desc(irq);
spin_lock_irqsave(&cobalt_lock, flags);
- if ((desc->status & (IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING)))
- desc->status &= ~(IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING);
- enable_cobalt_irq(irq);
- spin_unlock_irqrestore(&cobalt_lock, flags);
- return 0;
-}
-
-static void ack_cobalt_irq(unsigned int irq)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&cobalt_lock, flags);
- disable_cobalt_irq(irq);
+ disable_cobalt_irq(data);
apic_write(APIC_EOI, APIC_EIO_ACK);
spin_unlock_irqrestore(&cobalt_lock, flags);
}
-static void end_cobalt_irq(unsigned int irq)
-{
- unsigned long flags;
- struct irq_desc *desc = irq_to_desc(irq);
-
- spin_lock_irqsave(&cobalt_lock, flags);
- if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS)))
- enable_cobalt_irq(irq);
- spin_unlock_irqrestore(&cobalt_lock, flags);
-}
-
static struct irq_chip cobalt_irq_type = {
- .name = "Cobalt-APIC",
- .startup = startup_cobalt_irq,
- .shutdown = disable_cobalt_irq,
- .enable = enable_cobalt_irq,
- .disable = disable_cobalt_irq,
- .ack = ack_cobalt_irq,
- .end = end_cobalt_irq,
+ .name = "Cobalt-APIC",
+ .irq_enable = enable_cobalt_irq,
+ .irq_disable = disable_cobalt_irq,
+ .irq_ack = ack_cobalt_irq,
};
@@ -503,35 +467,34 @@ static struct irq_chip cobalt_irq_type = {
* interrupt controller type, and through a special virtual interrupt-
* controller. Device drivers only see the virtual interrupt sources.
*/
-static unsigned int startup_piix4_master_irq(unsigned int irq)
+static unsigned int startup_piix4_master_irq(struct irq_data *data)
{
legacy_pic->init(0);
-
- return startup_cobalt_irq(irq);
+ enable_cobalt_irq(data);
}
-static void end_piix4_master_irq(unsigned int irq)
+static void end_piix4_master_irq(struct irq_data *data)
{
unsigned long flags;
spin_lock_irqsave(&cobalt_lock, flags);
- enable_cobalt_irq(irq);
+ enable_cobalt_irq(data);
spin_unlock_irqrestore(&cobalt_lock, flags);
}
static struct irq_chip piix4_master_irq_type = {
- .name = "PIIX4-master",
- .startup = startup_piix4_master_irq,
- .ack = ack_cobalt_irq,
- .end = end_piix4_master_irq,
+ .name = "PIIX4-master",
+ .irq_startup = startup_piix4_master_irq,
+ .irq_ack = ack_cobalt_irq,
};
+static void pii4_mask(struct irq_data *data) { }
static struct irq_chip piix4_virtual_irq_type = {
- .name = "PIIX4-virtual",
+ .name = "PIIX4-virtual",
+ .mask = pii4_mask,
};
-
/*
* PIIX4-8259 master/virtual functions to handle interrupt requests
* from legacy devices: floppy, parallel, serial, rtc.
@@ -549,9 +512,8 @@ static struct irq_chip piix4_virtual_irq_type = {
*/
static irqreturn_t piix4_master_intr(int irq, void *dev_id)
{
- int realirq;
- struct irq_desc *desc;
unsigned long flags;
+ int realirq;
raw_spin_lock_irqsave(&i8259A_lock, flags);
@@ -592,18 +554,10 @@ static irqreturn_t piix4_master_intr(int irq, void *dev_id)
raw_spin_unlock_irqrestore(&i8259A_lock, flags);
- desc = irq_to_desc(realirq);
-
/*
* handle this 'virtual interrupt' as a Cobalt one now.
*/
- kstat_incr_irqs_this_cpu(realirq, desc);
-
- if (likely(desc->action != NULL))
- handle_IRQ_event(realirq, desc->action);
-
- if (!(desc->status & IRQ_DISABLED))
- legacy_pic->chip->unmask(realirq);
+ generic_handle_irq(realirq);
return IRQ_HANDLED;
@@ -624,41 +578,35 @@ static struct irqaction cascade_action = {
static inline void set_piix4_virtual_irq_type(void)
{
- piix4_virtual_irq_type.shutdown = i8259A_chip.mask;
piix4_virtual_irq_type.enable = i8259A_chip.unmask;
piix4_virtual_irq_type.disable = i8259A_chip.mask;
+ piix4_virtual_irq_type.unmask = i8259A_chip.unmask;
}
-void init_VISWS_APIC_irqs(void)
+static void __init visws_pre_intr_init(void)
{
int i;
- for (i = 0; i < CO_IRQ_APIC0 + CO_APIC_LAST + 1; i++) {
- struct irq_desc *desc = irq_to_desc(i);
-
- desc->status = IRQ_DISABLED;
- desc->action = 0;
- desc->depth = 1;
+ set_piix4_virtual_irq_type();
- if (i == 0) {
- desc->chip = &cobalt_irq_type;
- }
- else if (i == CO_IRQ_IDE0) {
- desc->chip = &cobalt_irq_type;
- }
- else if (i == CO_IRQ_IDE1) {
- desc->chip = &cobalt_irq_type;
- }
- else if (i == CO_IRQ_8259) {
- desc->chip = &piix4_master_irq_type;
- }
- else if (i < CO_IRQ_APIC0) {
- set_piix4_virtual_irq_type();
- desc->chip = &piix4_virtual_irq_type;
- }
- else if (IS_CO_APIC(i)) {
- desc->chip = &cobalt_irq_type;
- }
+ for (i = 0; i < CO_IRQ_APIC0 + CO_APIC_LAST + 1; i++) {
+ struct irq_chip *chip = NULL;
+
+ if (i == 0)
+ chip = &cobalt_irq_type;
+ else if (i == CO_IRQ_IDE0)
+ chip = &cobalt_irq_type;
+ else if (i == CO_IRQ_IDE1)
+ >chip = &cobalt_irq_type;
+ else if (i == CO_IRQ_8259)
+ chip = &piix4_master_irq_type;
+ else if (i < CO_IRQ_APIC0)
+ chip = &piix4_virtual_irq_type;
+ else if (IS_CO_APIC(i))
+ chip = &cobalt_irq_type;
+
+ if (chip)
+ set_irq_chip(i, chip);
}
setup_irq(CO_IRQ_8259, &master_action);
diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c
index 5ffb5622f793..61fb98519622 100644
--- a/arch/x86/kernel/vm86_32.c
+++ b/arch/x86/kernel/vm86_32.c
@@ -551,8 +551,14 @@ cannot_handle:
int handle_vm86_trap(struct kernel_vm86_regs *regs, long error_code, int trapno)
{
if (VMPI.is_vm86pus) {
- if ((trapno == 3) || (trapno == 1))
- return_to_32bit(regs, VM86_TRAP + (trapno << 8));
+ if ((trapno == 3) || (trapno == 1)) {
+ KVM86->regs32->ax = VM86_TRAP + (trapno << 8);
+ /* setting this flag forces the code in entry_32.S to
+ call save_v86_state() and change the stack pointer
+ to KVM86->regs32 */
+ set_thread_flag(TIF_IRET);
+ return 0;
+ }
do_int(regs, trapno, (unsigned char __user *) (regs->pt.ss << 4), SP(regs));
return 0;
}
diff --git a/arch/x86/kernel/vmi_32.c b/arch/x86/kernel/vmi_32.c
deleted file mode 100644
index ce9fbacb7526..000000000000
--- a/arch/x86/kernel/vmi_32.c
+++ /dev/null
@@ -1,893 +0,0 @@
-/*
- * VMI specific paravirt-ops implementation
- *
- * Copyright (C) 2005, VMware, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to zach@vmware.com
- *
- */
-
-#include <linux/module.h>
-#include <linux/cpu.h>
-#include <linux/bootmem.h>
-#include <linux/mm.h>
-#include <linux/highmem.h>
-#include <linux/sched.h>
-#include <linux/gfp.h>
-#include <asm/vmi.h>
-#include <asm/io.h>
-#include <asm/fixmap.h>
-#include <asm/apicdef.h>
-#include <asm/apic.h>
-#include <asm/pgalloc.h>
-#include <asm/processor.h>
-#include <asm/timer.h>
-#include <asm/vmi_time.h>
-#include <asm/kmap_types.h>
-#include <asm/setup.h>
-
-/* Convenient for calling VMI functions indirectly in the ROM */
-typedef u32 __attribute__((regparm(1))) (VROMFUNC)(void);
-typedef u64 __attribute__((regparm(2))) (VROMLONGFUNC)(int);
-
-#define call_vrom_func(rom,func) \
- (((VROMFUNC *)(rom->func))())
-
-#define call_vrom_long_func(rom,func,arg) \
- (((VROMLONGFUNC *)(rom->func)) (arg))
-
-static struct vrom_header *vmi_rom;
-static int disable_pge;
-static int disable_pse;
-static int disable_sep;
-static int disable_tsc;
-static int disable_mtrr;
-static int disable_noidle;
-static int disable_vmi_timer;
-
-/* Cached VMI operations */
-static struct {
- void (*cpuid)(void /* non-c */);
- void (*_set_ldt)(u32 selector);
- void (*set_tr)(u32 selector);
- void (*write_idt_entry)(struct desc_struct *, int, u32, u32);
- void (*write_gdt_entry)(struct desc_struct *, int, u32, u32);
- void (*write_ldt_entry)(struct desc_struct *, int, u32, u32);
- void (*set_kernel_stack)(u32 selector, u32 sp0);
- void (*allocate_page)(u32, u32, u32, u32, u32);
- void (*release_page)(u32, u32);
- void (*set_pte)(pte_t, pte_t *, unsigned);
- void (*update_pte)(pte_t *, unsigned);
- void (*set_linear_mapping)(int, void *, u32, u32);
- void (*_flush_tlb)(int);
- void (*set_initial_ap_state)(int, int);
- void (*halt)(void);
- void (*set_lazy_mode)(int mode);
-} vmi_ops;
-
-/* Cached VMI operations */
-struct vmi_timer_ops vmi_timer_ops;
-
-/*
- * VMI patching routines.
- */
-#define MNEM_CALL 0xe8
-#define MNEM_JMP 0xe9
-#define MNEM_RET 0xc3
-
-#define IRQ_PATCH_INT_MASK 0
-#define IRQ_PATCH_DISABLE 5
-
-static inline void patch_offset(void *insnbuf,
- unsigned long ip, unsigned long dest)
-{
- *(unsigned long *)(insnbuf+1) = dest-ip-5;
-}
-
-static unsigned patch_internal(int call, unsigned len, void *insnbuf,
- unsigned long ip)
-{
- u64 reloc;
- struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc;
- reloc = call_vrom_long_func(vmi_rom, get_reloc, call);
- switch(rel->type) {
- case VMI_RELOCATION_CALL_REL:
- BUG_ON(len < 5);
- *(char *)insnbuf = MNEM_CALL;
- patch_offset(insnbuf, ip, (unsigned long)rel->eip);
- return 5;
-
- case VMI_RELOCATION_JUMP_REL:
- BUG_ON(len < 5);
- *(char *)insnbuf = MNEM_JMP;
- patch_offset(insnbuf, ip, (unsigned long)rel->eip);
- return 5;
-
- case VMI_RELOCATION_NOP:
- /* obliterate the whole thing */
- return 0;
-
- case VMI_RELOCATION_NONE:
- /* leave native code in place */
- break;
-
- default:
- BUG();
- }
- return len;
-}
-
-/*
- * Apply patch if appropriate, return length of new instruction
- * sequence. The callee does nop padding for us.
- */
-static unsigned vmi_patch(u8 type, u16 clobbers, void *insns,
- unsigned long ip, unsigned len)
-{
- switch (type) {
- case PARAVIRT_PATCH(pv_irq_ops.irq_disable):
- return patch_internal(VMI_CALL_DisableInterrupts, len,
- insns, ip);
- case PARAVIRT_PATCH(pv_irq_ops.irq_enable):
- return patch_internal(VMI_CALL_EnableInterrupts, len,
- insns, ip);
- case PARAVIRT_PATCH(pv_irq_ops.restore_fl):
- return patch_internal(VMI_CALL_SetInterruptMask, len,
- insns, ip);
- case PARAVIRT_PATCH(pv_irq_ops.save_fl):
- return patch_internal(VMI_CALL_GetInterruptMask, len,
- insns, ip);
- case PARAVIRT_PATCH(pv_cpu_ops.iret):
- return patch_internal(VMI_CALL_IRET, len, insns, ip);
- case PARAVIRT_PATCH(pv_cpu_ops.irq_enable_sysexit):
- return patch_internal(VMI_CALL_SYSEXIT, len, insns, ip);
- default:
- break;
- }
- return len;
-}
-
-/* CPUID has non-C semantics, and paravirt-ops API doesn't match hardware ISA */
-static void vmi_cpuid(unsigned int *ax, unsigned int *bx,
- unsigned int *cx, unsigned int *dx)
-{
- int override = 0;
- if (*ax == 1)
- override = 1;
- asm volatile ("call *%6"
- : "=a" (*ax),
- "=b" (*bx),
- "=c" (*cx),
- "=d" (*dx)
- : "0" (*ax), "2" (*cx), "r" (vmi_ops.cpuid));
- if (override) {
- if (disable_pse)
- *dx &= ~X86_FEATURE_PSE;
- if (disable_pge)
- *dx &= ~X86_FEATURE_PGE;
- if (disable_sep)
- *dx &= ~X86_FEATURE_SEP;
- if (disable_tsc)
- *dx &= ~X86_FEATURE_TSC;
- if (disable_mtrr)
- *dx &= ~X86_FEATURE_MTRR;
- }
-}
-
-static inline void vmi_maybe_load_tls(struct desc_struct *gdt, int nr, struct desc_struct *new)
-{
- if (gdt[nr].a != new->a || gdt[nr].b != new->b)
- write_gdt_entry(gdt, nr, new, 0);
-}
-
-static void vmi_load_tls(struct thread_struct *t, unsigned int cpu)
-{
- struct desc_struct *gdt = get_cpu_gdt_table(cpu);
- vmi_maybe_load_tls(gdt, GDT_ENTRY_TLS_MIN + 0, &t->tls_array[0]);
- vmi_maybe_load_tls(gdt, GDT_ENTRY_TLS_MIN + 1, &t->tls_array[1]);
- vmi_maybe_load_tls(gdt, GDT_ENTRY_TLS_MIN + 2, &t->tls_array[2]);
-}
-
-static void vmi_set_ldt(const void *addr, unsigned entries)
-{
- unsigned cpu = smp_processor_id();
- struct desc_struct desc;
-
- pack_descriptor(&desc, (unsigned long)addr,
- entries * sizeof(struct desc_struct) - 1,
- DESC_LDT, 0);
- write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT, &desc, DESC_LDT);
- vmi_ops._set_ldt(entries ? GDT_ENTRY_LDT*sizeof(struct desc_struct) : 0);
-}
-
-static void vmi_set_tr(void)
-{
- vmi_ops.set_tr(GDT_ENTRY_TSS*sizeof(struct desc_struct));
-}
-
-static void vmi_write_idt_entry(gate_desc *dt, int entry, const gate_desc *g)
-{
- u32 *idt_entry = (u32 *)g;
- vmi_ops.write_idt_entry(dt, entry, idt_entry[0], idt_entry[1]);
-}
-
-static void vmi_write_gdt_entry(struct desc_struct *dt, int entry,
- const void *desc, int type)
-{
- u32 *gdt_entry = (u32 *)desc;
- vmi_ops.write_gdt_entry(dt, entry, gdt_entry[0], gdt_entry[1]);
-}
-
-static void vmi_write_ldt_entry(struct desc_struct *dt, int entry,
- const void *desc)
-{
- u32 *ldt_entry = (u32 *)desc;
- vmi_ops.write_ldt_entry(dt, entry, ldt_entry[0], ldt_entry[1]);
-}
-
-static void vmi_load_sp0(struct tss_struct *tss,
- struct thread_struct *thread)
-{
- tss->x86_tss.sp0 = thread->sp0;
-
- /* This can only happen when SEP is enabled, no need to test "SEP"arately */
- if (unlikely(tss->x86_tss.ss1 != thread->sysenter_cs)) {
- tss->x86_tss.ss1 = thread->sysenter_cs;
- wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0);
- }
- vmi_ops.set_kernel_stack(__KERNEL_DS, tss->x86_tss.sp0);
-}
-
-static void vmi_flush_tlb_user(void)
-{
- vmi_ops._flush_tlb(VMI_FLUSH_TLB);
-}
-
-static void vmi_flush_tlb_kernel(void)
-{
- vmi_ops._flush_tlb(VMI_FLUSH_TLB | VMI_FLUSH_GLOBAL);
-}
-
-/* Stub to do nothing at all; used for delays and unimplemented calls */
-static void vmi_nop(void)
-{
-}
-
-static void vmi_allocate_pte(struct mm_struct *mm, unsigned long pfn)
-{
- vmi_ops.allocate_page(pfn, VMI_PAGE_L1, 0, 0, 0);
-}
-
-static void vmi_allocate_pmd(struct mm_struct *mm, unsigned long pfn)
-{
- /*
- * This call comes in very early, before mem_map is setup.
- * It is called only for swapper_pg_dir, which already has
- * data on it.
- */
- vmi_ops.allocate_page(pfn, VMI_PAGE_L2, 0, 0, 0);
-}
-
-static void vmi_allocate_pmd_clone(unsigned long pfn, unsigned long clonepfn, unsigned long start, unsigned long count)
-{
- vmi_ops.allocate_page(pfn, VMI_PAGE_L2 | VMI_PAGE_CLONE, clonepfn, start, count);
-}
-
-static void vmi_release_pte(unsigned long pfn)
-{
- vmi_ops.release_page(pfn, VMI_PAGE_L1);
-}
-
-static void vmi_release_pmd(unsigned long pfn)
-{
- vmi_ops.release_page(pfn, VMI_PAGE_L2);
-}
-
-/*
- * We use the pgd_free hook for releasing the pgd page:
- */
-static void vmi_pgd_free(struct mm_struct *mm, pgd_t *pgd)
-{
- unsigned long pfn = __pa(pgd) >> PAGE_SHIFT;
-
- vmi_ops.release_page(pfn, VMI_PAGE_L2);
-}
-
-/*
- * Helper macros for MMU update flags. We can defer updates until a flush
- * or page invalidation only if the update is to the current address space
- * (otherwise, there is no flush). We must check against init_mm, since
- * this could be a kernel update, which usually passes init_mm, although
- * sometimes this check can be skipped if we know the particular function
- * is only called on user mode PTEs. We could change the kernel to pass
- * current->active_mm here, but in particular, I was unsure if changing
- * mm/highmem.c to do this would still be correct on other architectures.
- */
-#define is_current_as(mm, mustbeuser) ((mm) == current->active_mm || \
- (!mustbeuser && (mm) == &init_mm))
-#define vmi_flags_addr(mm, addr, level, user) \
- ((level) | (is_current_as(mm, user) ? \
- (VMI_PAGE_CURRENT_AS | ((addr) & VMI_PAGE_VA_MASK)) : 0))
-#define vmi_flags_addr_defer(mm, addr, level, user) \
- ((level) | (is_current_as(mm, user) ? \
- (VMI_PAGE_DEFER | VMI_PAGE_CURRENT_AS | ((addr) & VMI_PAGE_VA_MASK)) : 0))
-
-static void vmi_update_pte(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
-{
- vmi_ops.update_pte(ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0));
-}
-
-static void vmi_update_pte_defer(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
-{
- vmi_ops.update_pte(ptep, vmi_flags_addr_defer(mm, addr, VMI_PAGE_PT, 0));
-}
-
-static void vmi_set_pte(pte_t *ptep, pte_t pte)
-{
- /* XXX because of set_pmd_pte, this can be called on PT or PD layers */
- vmi_ops.set_pte(pte, ptep, VMI_PAGE_PT);
-}
-
-static void vmi_set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte)
-{
- vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0));
-}
-
-static void vmi_set_pmd(pmd_t *pmdp, pmd_t pmdval)
-{
-#ifdef CONFIG_X86_PAE
- const pte_t pte = { .pte = pmdval.pmd };
-#else
- const pte_t pte = { pmdval.pud.pgd.pgd };
-#endif
- vmi_ops.set_pte(pte, (pte_t *)pmdp, VMI_PAGE_PD);
-}
-
-#ifdef CONFIG_X86_PAE
-
-static void vmi_set_pte_atomic(pte_t *ptep, pte_t pteval)
-{
- /*
- * XXX This is called from set_pmd_pte, but at both PT
- * and PD layers so the VMI_PAGE_PT flag is wrong. But
- * it is only called for large page mapping changes,
- * the Xen backend, doesn't support large pages, and the
- * ESX backend doesn't depend on the flag.
- */
- set_64bit((unsigned long long *)ptep,pte_val(pteval));
- vmi_ops.update_pte(ptep, VMI_PAGE_PT);
-}
-
-static void vmi_set_pud(pud_t *pudp, pud_t pudval)
-{
- /* Um, eww */
- const pte_t pte = { .pte = pudval.pgd.pgd };
- vmi_ops.set_pte(pte, (pte_t *)pudp, VMI_PAGE_PDP);
-}
-
-static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
-{
- const pte_t pte = { .pte = 0 };
- vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0));
-}
-
-static void vmi_pmd_clear(pmd_t *pmd)
-{
- const pte_t pte = { .pte = 0 };
- vmi_ops.set_pte(pte, (pte_t *)pmd, VMI_PAGE_PD);
-}
-#endif
-
-#ifdef CONFIG_SMP
-static void __devinit
-vmi_startup_ipi_hook(int phys_apicid, unsigned long start_eip,
- unsigned long start_esp)
-{
- struct vmi_ap_state ap;
-
- /* Default everything to zero. This is fine for most GPRs. */
- memset(&ap, 0, sizeof(struct vmi_ap_state));
-
- ap.gdtr_limit = GDT_SIZE - 1;
- ap.gdtr_base = (unsigned long) get_cpu_gdt_table(phys_apicid);
-
- ap.idtr_limit = IDT_ENTRIES * 8 - 1;
- ap.idtr_base = (unsigned long) idt_table;
-
- ap.ldtr = 0;
-
- ap.cs = __KERNEL_CS;
- ap.eip = (unsigned long) start_eip;
- ap.ss = __KERNEL_DS;
- ap.esp = (unsigned long) start_esp;
-
- ap.ds = __USER_DS;
- ap.es = __USER_DS;
- ap.fs = __KERNEL_PERCPU;
- ap.gs = __KERNEL_STACK_CANARY;
-
- ap.eflags = 0;
-
-#ifdef CONFIG_X86_PAE
- /* efer should match BSP efer. */
- if (cpu_has_nx) {
- unsigned l, h;
- rdmsr(MSR_EFER, l, h);
- ap.efer = (unsigned long long) h << 32 | l;
- }
-#endif
-
- ap.cr3 = __pa(swapper_pg_dir);
- /* Protected mode, paging, AM, WP, NE, MP. */
- ap.cr0 = 0x80050023;
- ap.cr4 = mmu_cr4_features;
- vmi_ops.set_initial_ap_state((u32)&ap, phys_apicid);
-}
-#endif
-
-static void vmi_start_context_switch(struct task_struct *prev)
-{
- paravirt_start_context_switch(prev);
- vmi_ops.set_lazy_mode(2);
-}
-
-static void vmi_end_context_switch(struct task_struct *next)
-{
- vmi_ops.set_lazy_mode(0);
- paravirt_end_context_switch(next);
-}
-
-static void vmi_enter_lazy_mmu(void)
-{
- paravirt_enter_lazy_mmu();
- vmi_ops.set_lazy_mode(1);
-}
-
-static void vmi_leave_lazy_mmu(void)
-{
- vmi_ops.set_lazy_mode(0);
- paravirt_leave_lazy_mmu();
-}
-
-static inline int __init check_vmi_rom(struct vrom_header *rom)
-{
- struct pci_header *pci;
- struct pnp_header *pnp;
- const char *manufacturer = "UNKNOWN";
- const char *product = "UNKNOWN";
- const char *license = "unspecified";
-
- if (rom->rom_signature != 0xaa55)
- return 0;
- if (rom->vrom_signature != VMI_SIGNATURE)
- return 0;
- if (rom->api_version_maj != VMI_API_REV_MAJOR ||
- rom->api_version_min+1 < VMI_API_REV_MINOR+1) {
- printk(KERN_WARNING "VMI: Found mismatched rom version %d.%d\n",
- rom->api_version_maj,
- rom->api_version_min);
- return 0;
- }
-
- /*
- * Relying on the VMI_SIGNATURE field is not 100% safe, so check
- * the PCI header and device type to make sure this is really a
- * VMI device.
- */
- if (!rom->pci_header_offs) {
- printk(KERN_WARNING "VMI: ROM does not contain PCI header.\n");
- return 0;
- }
-
- pci = (struct pci_header *)((char *)rom+rom->pci_header_offs);
- if (pci->vendorID != PCI_VENDOR_ID_VMWARE ||
- pci->deviceID != PCI_DEVICE_ID_VMWARE_VMI) {
- /* Allow it to run... anyways, but warn */
- printk(KERN_WARNING "VMI: ROM from unknown manufacturer\n");
- }
-
- if (rom->pnp_header_offs) {
- pnp = (struct pnp_header *)((char *)rom+rom->pnp_header_offs);
- if (pnp->manufacturer_offset)
- manufacturer = (const char *)rom+pnp->manufacturer_offset;
- if (pnp->product_offset)
- product = (const char *)rom+pnp->product_offset;
- }
-
- if (rom->license_offs)
- license = (char *)rom+rom->license_offs;
-
- printk(KERN_INFO "VMI: Found %s %s, API version %d.%d, ROM version %d.%d\n",
- manufacturer, product,
- rom->api_version_maj, rom->api_version_min,
- pci->rom_version_maj, pci->rom_version_min);
-
- /* Don't allow BSD/MIT here for now because we don't want to end up
- with any binary only shim layers */
- if (strcmp(license, "GPL") && strcmp(license, "GPL v2")) {
- printk(KERN_WARNING "VMI: Non GPL license `%s' found for ROM. Not used.\n",
- license);
- return 0;
- }
-
- return 1;
-}
-
-/*
- * Probe for the VMI option ROM
- */
-static inline int __init probe_vmi_rom(void)
-{
- unsigned long base;
-
- /* VMI ROM is in option ROM area, check signature */
- for (base = 0xC0000; base < 0xE0000; base += 2048) {
- struct vrom_header *romstart;
- romstart = (struct vrom_header *)isa_bus_to_virt(base);
- if (check_vmi_rom(romstart)) {
- vmi_rom = romstart;
- return 1;
- }
- }
- return 0;
-}
-
-/*
- * VMI setup common to all processors
- */
-void vmi_bringup(void)
-{
- /* We must establish the lowmem mapping for MMU ops to work */
- if (vmi_ops.set_linear_mapping)
- vmi_ops.set_linear_mapping(0, (void *)__PAGE_OFFSET, MAXMEM_PFN, 0);
-}
-
-/*
- * Return a pointer to a VMI function or NULL if unimplemented
- */
-static void *vmi_get_function(int vmicall)
-{
- u64 reloc;
- const struct vmi_relocation_info *rel = (struct vmi_relocation_info *)&reloc;
- reloc = call_vrom_long_func(vmi_rom, get_reloc, vmicall);
- BUG_ON(rel->type == VMI_RELOCATION_JUMP_REL);
- if (rel->type == VMI_RELOCATION_CALL_REL)
- return (void *)rel->eip;
- else
- return NULL;
-}
-
-/*
- * Helper macro for making the VMI paravirt-ops fill code readable.
- * For unimplemented operations, fall back to default, unless nop
- * is returned by the ROM.
- */
-#define para_fill(opname, vmicall) \
-do { \
- reloc = call_vrom_long_func(vmi_rom, get_reloc, \
- VMI_CALL_##vmicall); \
- if (rel->type == VMI_RELOCATION_CALL_REL) \
- opname = (void *)rel->eip; \
- else if (rel->type == VMI_RELOCATION_NOP) \
- opname = (void *)vmi_nop; \
- else if (rel->type != VMI_RELOCATION_NONE) \
- printk(KERN_WARNING "VMI: Unknown relocation " \
- "type %d for " #vmicall"\n",\
- rel->type); \
-} while (0)
-
-/*
- * Helper macro for making the VMI paravirt-ops fill code readable.
- * For cached operations which do not match the VMI ROM ABI and must
- * go through a tranlation stub. Ignore NOPs, since it is not clear
- * a NOP * VMI function corresponds to a NOP paravirt-op when the
- * functions are not in 1-1 correspondence.
- */
-#define para_wrap(opname, wrapper, cache, vmicall) \
-do { \
- reloc = call_vrom_long_func(vmi_rom, get_reloc, \
- VMI_CALL_##vmicall); \
- BUG_ON(rel->type == VMI_RELOCATION_JUMP_REL); \
- if (rel->type == VMI_RELOCATION_CALL_REL) { \
- opname = wrapper; \
- vmi_ops.cache = (void *)rel->eip; \
- } \
-} while (0)
-
-/*
- * Activate the VMI interface and switch into paravirtualized mode
- */
-static inline int __init activate_vmi(void)
-{
- short kernel_cs;
- u64 reloc;
- const struct vmi_relocation_info *rel = (struct vmi_relocation_info *)&reloc;
-
- /*
- * Prevent page tables from being allocated in highmem, even if
- * CONFIG_HIGHPTE is enabled.
- */
- __userpte_alloc_gfp &= ~__GFP_HIGHMEM;
-
- if (call_vrom_func(vmi_rom, vmi_init) != 0) {
- printk(KERN_ERR "VMI ROM failed to initialize!");
- return 0;
- }
- savesegment(cs, kernel_cs);
-
- pv_info.paravirt_enabled = 1;
- pv_info.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK;
- pv_info.name = "vmi [deprecated]";
-
- pv_init_ops.patch = vmi_patch;
-
- /*
- * Many of these operations are ABI compatible with VMI.
- * This means we can fill in the paravirt-ops with direct
- * pointers into the VMI ROM. If the calling convention for
- * these operations changes, this code needs to be updated.
- *
- * Exceptions
- * CPUID paravirt-op uses pointers, not the native ISA
- * halt has no VMI equivalent; all VMI halts are "safe"
- * no MSR support yet - just trap and emulate. VMI uses the
- * same ABI as the native ISA, but Linux wants exceptions
- * from bogus MSR read / write handled
- * rdpmc is not yet used in Linux
- */
-
- /* CPUID is special, so very special it gets wrapped like a present */
- para_wrap(pv_cpu_ops.cpuid, vmi_cpuid, cpuid, CPUID);
-
- para_fill(pv_cpu_ops.clts, CLTS);
- para_fill(pv_cpu_ops.get_debugreg, GetDR);
- para_fill(pv_cpu_ops.set_debugreg, SetDR);
- para_fill(pv_cpu_ops.read_cr0, GetCR0);
- para_fill(pv_mmu_ops.read_cr2, GetCR2);
- para_fill(pv_mmu_ops.read_cr3, GetCR3);
- para_fill(pv_cpu_ops.read_cr4, GetCR4);
- para_fill(pv_cpu_ops.write_cr0, SetCR0);
- para_fill(pv_mmu_ops.write_cr2, SetCR2);
- para_fill(pv_mmu_ops.write_cr3, SetCR3);
- para_fill(pv_cpu_ops.write_cr4, SetCR4);
-
- para_fill(pv_irq_ops.save_fl.func, GetInterruptMask);
- para_fill(pv_irq_ops.restore_fl.func, SetInterruptMask);
- para_fill(pv_irq_ops.irq_disable.func, DisableInterrupts);
- para_fill(pv_irq_ops.irq_enable.func, EnableInterrupts);
-
- para_fill(pv_cpu_ops.wbinvd, WBINVD);
- para_fill(pv_cpu_ops.read_tsc, RDTSC);
-
- /* The following we emulate with trap and emulate for now */
- /* paravirt_ops.read_msr = vmi_rdmsr */
- /* paravirt_ops.write_msr = vmi_wrmsr */
- /* paravirt_ops.rdpmc = vmi_rdpmc */
-
- /* TR interface doesn't pass TR value, wrap */
- para_wrap(pv_cpu_ops.load_tr_desc, vmi_set_tr, set_tr, SetTR);
-
- /* LDT is special, too */
- para_wrap(pv_cpu_ops.set_ldt, vmi_set_ldt, _set_ldt, SetLDT);
-
- para_fill(pv_cpu_ops.load_gdt, SetGDT);
- para_fill(pv_cpu_ops.load_idt, SetIDT);
- para_fill(pv_cpu_ops.store_gdt, GetGDT);
- para_fill(pv_cpu_ops.store_idt, GetIDT);
- para_fill(pv_cpu_ops.store_tr, GetTR);
- pv_cpu_ops.load_tls = vmi_load_tls;
- para_wrap(pv_cpu_ops.write_ldt_entry, vmi_write_ldt_entry,
- write_ldt_entry, WriteLDTEntry);
- para_wrap(pv_cpu_ops.write_gdt_entry, vmi_write_gdt_entry,
- write_gdt_entry, WriteGDTEntry);
- para_wrap(pv_cpu_ops.write_idt_entry, vmi_write_idt_entry,
- write_idt_entry, WriteIDTEntry);
- para_wrap(pv_cpu_ops.load_sp0, vmi_load_sp0, set_kernel_stack, UpdateKernelStack);
- para_fill(pv_cpu_ops.set_iopl_mask, SetIOPLMask);
- para_fill(pv_cpu_ops.io_delay, IODelay);
-
- para_wrap(pv_cpu_ops.start_context_switch, vmi_start_context_switch,
- set_lazy_mode, SetLazyMode);
- para_wrap(pv_cpu_ops.end_context_switch, vmi_end_context_switch,
- set_lazy_mode, SetLazyMode);
-
- para_wrap(pv_mmu_ops.lazy_mode.enter, vmi_enter_lazy_mmu,
- set_lazy_mode, SetLazyMode);
- para_wrap(pv_mmu_ops.lazy_mode.leave, vmi_leave_lazy_mmu,
- set_lazy_mode, SetLazyMode);
-
- /* user and kernel flush are just handled with different flags to FlushTLB */
- para_wrap(pv_mmu_ops.flush_tlb_user, vmi_flush_tlb_user, _flush_tlb, FlushTLB);
- para_wrap(pv_mmu_ops.flush_tlb_kernel, vmi_flush_tlb_kernel, _flush_tlb, FlushTLB);
- para_fill(pv_mmu_ops.flush_tlb_single, InvalPage);
-
- /*
- * Until a standard flag format can be agreed on, we need to
- * implement these as wrappers in Linux. Get the VMI ROM
- * function pointers for the two backend calls.
- */
-#ifdef CONFIG_X86_PAE
- vmi_ops.set_pte = vmi_get_function(VMI_CALL_SetPxELong);
- vmi_ops.update_pte = vmi_get_function(VMI_CALL_UpdatePxELong);
-#else
- vmi_ops.set_pte = vmi_get_function(VMI_CALL_SetPxE);
- vmi_ops.update_pte = vmi_get_function(VMI_CALL_UpdatePxE);
-#endif
-
- if (vmi_ops.set_pte) {
- pv_mmu_ops.set_pte = vmi_set_pte;
- pv_mmu_ops.set_pte_at = vmi_set_pte_at;
- pv_mmu_ops.set_pmd = vmi_set_pmd;
-#ifdef CONFIG_X86_PAE
- pv_mmu_ops.set_pte_atomic = vmi_set_pte_atomic;
- pv_mmu_ops.set_pud = vmi_set_pud;
- pv_mmu_ops.pte_clear = vmi_pte_clear;
- pv_mmu_ops.pmd_clear = vmi_pmd_clear;
-#endif
- }
-
- if (vmi_ops.update_pte) {
- pv_mmu_ops.pte_update = vmi_update_pte;
- pv_mmu_ops.pte_update_defer = vmi_update_pte_defer;
- }
-
- vmi_ops.allocate_page = vmi_get_function(VMI_CALL_AllocatePage);
- if (vmi_ops.allocate_page) {
- pv_mmu_ops.alloc_pte = vmi_allocate_pte;
- pv_mmu_ops.alloc_pmd = vmi_allocate_pmd;
- pv_mmu_ops.alloc_pmd_clone = vmi_allocate_pmd_clone;
- }
-
- vmi_ops.release_page = vmi_get_function(VMI_CALL_ReleasePage);
- if (vmi_ops.release_page) {
- pv_mmu_ops.release_pte = vmi_release_pte;
- pv_mmu_ops.release_pmd = vmi_release_pmd;
- pv_mmu_ops.pgd_free = vmi_pgd_free;
- }
-
- /* Set linear is needed in all cases */
- vmi_ops.set_linear_mapping = vmi_get_function(VMI_CALL_SetLinearMapping);
-
- /*
- * These MUST always be patched. Don't support indirect jumps
- * through these operations, as the VMI interface may use either
- * a jump or a call to get to these operations, depending on
- * the backend. They are performance critical anyway, so requiring
- * a patch is not a big problem.
- */
- pv_cpu_ops.irq_enable_sysexit = (void *)0xfeedbab0;
- pv_cpu_ops.iret = (void *)0xbadbab0;
-
-#ifdef CONFIG_SMP
- para_wrap(pv_apic_ops.startup_ipi_hook, vmi_startup_ipi_hook, set_initial_ap_state, SetInitialAPState);
-#endif
-
-#ifdef CONFIG_X86_LOCAL_APIC
- para_fill(apic->read, APICRead);
- para_fill(apic->write, APICWrite);
-#endif
-
- /*
- * Check for VMI timer functionality by probing for a cycle frequency method
- */
- reloc = call_vrom_long_func(vmi_rom, get_reloc, VMI_CALL_GetCycleFrequency);
- if (!disable_vmi_timer && rel->type != VMI_RELOCATION_NONE) {
- vmi_timer_ops.get_cycle_frequency = (void *)rel->eip;
- vmi_timer_ops.get_cycle_counter =
- vmi_get_function(VMI_CALL_GetCycleCounter);
- vmi_timer_ops.get_wallclock =
- vmi_get_function(VMI_CALL_GetWallclockTime);
- vmi_timer_ops.wallclock_updated =
- vmi_get_function(VMI_CALL_WallclockUpdated);
- vmi_timer_ops.set_alarm = vmi_get_function(VMI_CALL_SetAlarm);
- vmi_timer_ops.cancel_alarm =
- vmi_get_function(VMI_CALL_CancelAlarm);
- x86_init.timers.timer_init = vmi_time_init;
-#ifdef CONFIG_X86_LOCAL_APIC
- x86_init.timers.setup_percpu_clockev = vmi_time_bsp_init;
- x86_cpuinit.setup_percpu_clockev = vmi_time_ap_init;
-#endif
- pv_time_ops.sched_clock = vmi_sched_clock;
- x86_platform.calibrate_tsc = vmi_tsc_khz;
- x86_platform.get_wallclock = vmi_get_wallclock;
- x86_platform.set_wallclock = vmi_set_wallclock;
-
- /* We have true wallclock functions; disable CMOS clock sync */
- no_sync_cmos_clock = 1;
- } else {
- disable_noidle = 1;
- disable_vmi_timer = 1;
- }
-
- para_fill(pv_irq_ops.safe_halt, Halt);
-
- /*
- * Alternative instruction rewriting doesn't happen soon enough
- * to convert VMI_IRET to a call instead of a jump; so we have
- * to do this before IRQs get reenabled. Fortunately, it is
- * idempotent.
- */
- apply_paravirt(__parainstructions, __parainstructions_end);
-
- vmi_bringup();
-
- return 1;
-}
-
-#undef para_fill
-
-void __init vmi_init(void)
-{
- if (!vmi_rom)
- probe_vmi_rom();
- else
- check_vmi_rom(vmi_rom);
-
- /* In case probing for or validating the ROM failed, basil */
- if (!vmi_rom)
- return;
-
- reserve_top_address(-vmi_rom->virtual_top);
-
-#ifdef CONFIG_X86_IO_APIC
- /* This is virtual hardware; timer routing is wired correctly */
- no_timer_check = 1;
-#endif
-}
-
-void __init vmi_activate(void)
-{
- unsigned long flags;
-
- if (!vmi_rom)
- return;
-
- local_irq_save(flags);
- activate_vmi();
- local_irq_restore(flags & X86_EFLAGS_IF);
-}
-
-static int __init parse_vmi(char *arg)
-{
- if (!arg)
- return -EINVAL;
-
- if (!strcmp(arg, "disable_pge")) {
- clear_cpu_cap(&boot_cpu_data, X86_FEATURE_PGE);
- disable_pge = 1;
- } else if (!strcmp(arg, "disable_pse")) {
- clear_cpu_cap(&boot_cpu_data, X86_FEATURE_PSE);
- disable_pse = 1;
- } else if (!strcmp(arg, "disable_sep")) {
- clear_cpu_cap(&boot_cpu_data, X86_FEATURE_SEP);
- disable_sep = 1;
- } else if (!strcmp(arg, "disable_tsc")) {
- clear_cpu_cap(&boot_cpu_data, X86_FEATURE_TSC);
- disable_tsc = 1;
- } else if (!strcmp(arg, "disable_mtrr")) {
- clear_cpu_cap(&boot_cpu_data, X86_FEATURE_MTRR);
- disable_mtrr = 1;
- } else if (!strcmp(arg, "disable_timer")) {
- disable_vmi_timer = 1;
- disable_noidle = 1;
- } else if (!strcmp(arg, "disable_noidle"))
- disable_noidle = 1;
- return 0;
-}
-
-early_param("vmi", parse_vmi);
diff --git a/arch/x86/kernel/vmiclock_32.c b/arch/x86/kernel/vmiclock_32.c
deleted file mode 100644
index 5e1ff66ecd73..000000000000
--- a/arch/x86/kernel/vmiclock_32.c
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * VMI paravirtual timer support routines.
- *
- * Copyright (C) 2007, VMware, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <linux/smp.h>
-#include <linux/interrupt.h>
-#include <linux/cpumask.h>
-#include <linux/clocksource.h>
-#include <linux/clockchips.h>
-
-#include <asm/vmi.h>
-#include <asm/vmi_time.h>
-#include <asm/apicdef.h>
-#include <asm/apic.h>
-#include <asm/timer.h>
-#include <asm/i8253.h>
-#include <asm/irq_vectors.h>
-
-#define VMI_ONESHOT (VMI_ALARM_IS_ONESHOT | VMI_CYCLES_REAL | vmi_get_alarm_wiring())
-#define VMI_PERIODIC (VMI_ALARM_IS_PERIODIC | VMI_CYCLES_REAL | vmi_get_alarm_wiring())
-
-static DEFINE_PER_CPU(struct clock_event_device, local_events);
-
-static inline u32 vmi_counter(u32 flags)
-{
- /* Given VMI_ONESHOT or VMI_PERIODIC, return the corresponding
- * cycle counter. */
- return flags & VMI_ALARM_COUNTER_MASK;
-}
-
-/* paravirt_ops.get_wallclock = vmi_get_wallclock */
-unsigned long vmi_get_wallclock(void)
-{
- unsigned long long wallclock;
- wallclock = vmi_timer_ops.get_wallclock(); // nsec
- (void)do_div(wallclock, 1000000000); // sec
-
- return wallclock;
-}
-
-/* paravirt_ops.set_wallclock = vmi_set_wallclock */
-int vmi_set_wallclock(unsigned long now)
-{
- return 0;
-}
-
-/* paravirt_ops.sched_clock = vmi_sched_clock */
-unsigned long long vmi_sched_clock(void)
-{
- return cycles_2_ns(vmi_timer_ops.get_cycle_counter(VMI_CYCLES_AVAILABLE));
-}
-
-/* x86_platform.calibrate_tsc = vmi_tsc_khz */
-unsigned long vmi_tsc_khz(void)
-{
- unsigned long long khz;
- khz = vmi_timer_ops.get_cycle_frequency();
- (void)do_div(khz, 1000);
- return khz;
-}
-
-static inline unsigned int vmi_get_timer_vector(void)
-{
- return IRQ0_VECTOR;
-}
-
-/** vmi clockchip */
-#ifdef CONFIG_X86_LOCAL_APIC
-static unsigned int startup_timer_irq(unsigned int irq)
-{
- unsigned long val = apic_read(APIC_LVTT);
- apic_write(APIC_LVTT, vmi_get_timer_vector());
-
- return (val & APIC_SEND_PENDING);
-}
-
-static void mask_timer_irq(unsigned int irq)
-{
- unsigned long val = apic_read(APIC_LVTT);
- apic_write(APIC_LVTT, val | APIC_LVT_MASKED);
-}
-
-static void unmask_timer_irq(unsigned int irq)
-{
- unsigned long val = apic_read(APIC_LVTT);
- apic_write(APIC_LVTT, val & ~APIC_LVT_MASKED);
-}
-
-static void ack_timer_irq(unsigned int irq)
-{
- ack_APIC_irq();
-}
-
-static struct irq_chip vmi_chip __read_mostly = {
- .name = "VMI-LOCAL",
- .startup = startup_timer_irq,
- .mask = mask_timer_irq,
- .unmask = unmask_timer_irq,
- .ack = ack_timer_irq
-};
-#endif
-
-/** vmi clockevent */
-#define VMI_ALARM_WIRED_IRQ0 0x00000000
-#define VMI_ALARM_WIRED_LVTT 0x00010000
-static int vmi_wiring = VMI_ALARM_WIRED_IRQ0;
-
-static inline int vmi_get_alarm_wiring(void)
-{
- return vmi_wiring;
-}
-
-static void vmi_timer_set_mode(enum clock_event_mode mode,
- struct clock_event_device *evt)
-{
- cycle_t now, cycles_per_hz;
- BUG_ON(!irqs_disabled());
-
- switch (mode) {
- case CLOCK_EVT_MODE_ONESHOT:
- case CLOCK_EVT_MODE_RESUME:
- break;
- case CLOCK_EVT_MODE_PERIODIC:
- cycles_per_hz = vmi_timer_ops.get_cycle_frequency();
- (void)do_div(cycles_per_hz, HZ);
- now = vmi_timer_ops.get_cycle_counter(vmi_counter(VMI_PERIODIC));
- vmi_timer_ops.set_alarm(VMI_PERIODIC, now, cycles_per_hz);
- break;
- case CLOCK_EVT_MODE_UNUSED:
- case CLOCK_EVT_MODE_SHUTDOWN:
- switch (evt->mode) {
- case CLOCK_EVT_MODE_ONESHOT:
- vmi_timer_ops.cancel_alarm(VMI_ONESHOT);
- break;
- case CLOCK_EVT_MODE_PERIODIC:
- vmi_timer_ops.cancel_alarm(VMI_PERIODIC);
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
-}
-
-static int vmi_timer_next_event(unsigned long delta,
- struct clock_event_device *evt)
-{
- /* Unfortunately, set_next_event interface only passes relative
- * expiry, but we want absolute expiry. It'd be better if were
- * were passed an absolute expiry, since a bunch of time may
- * have been stolen between the time the delta is computed and
- * when we set the alarm below. */
- cycle_t now = vmi_timer_ops.get_cycle_counter(vmi_counter(VMI_ONESHOT));
-
- BUG_ON(evt->mode != CLOCK_EVT_MODE_ONESHOT);
- vmi_timer_ops.set_alarm(VMI_ONESHOT, now + delta, 0);
- return 0;
-}
-
-static struct clock_event_device vmi_clockevent = {
- .name = "vmi-timer",
- .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
- .shift = 22,
- .set_mode = vmi_timer_set_mode,
- .set_next_event = vmi_timer_next_event,
- .rating = 1000,
- .irq = 0,
-};
-
-static irqreturn_t vmi_timer_interrupt(int irq, void *dev_id)
-{
- struct clock_event_device *evt = &__get_cpu_var(local_events);
- evt->event_handler(evt);
- return IRQ_HANDLED;
-}
-
-static struct irqaction vmi_clock_action = {
- .name = "vmi-timer",
- .handler = vmi_timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER,
-};
-
-static void __devinit vmi_time_init_clockevent(void)
-{
- cycle_t cycles_per_msec;
- struct clock_event_device *evt;
-
- int cpu = smp_processor_id();
- evt = &__get_cpu_var(local_events);
-
- /* Use cycles_per_msec since div_sc params are 32-bits. */
- cycles_per_msec = vmi_timer_ops.get_cycle_frequency();
- (void)do_div(cycles_per_msec, 1000);
-
- memcpy(evt, &vmi_clockevent, sizeof(*evt));
- /* Must pick .shift such that .mult fits in 32-bits. Choosing
- * .shift to be 22 allows 2^(32-22) cycles per nano-seconds
- * before overflow. */
- evt->mult = div_sc(cycles_per_msec, NSEC_PER_MSEC, evt->shift);
- /* Upper bound is clockevent's use of ulong for cycle deltas. */
- evt->max_delta_ns = clockevent_delta2ns(ULONG_MAX, evt);
- evt->min_delta_ns = clockevent_delta2ns(1, evt);
- evt->cpumask = cpumask_of(cpu);
-
- printk(KERN_WARNING "vmi: registering clock event %s. mult=%u shift=%u\n",
- evt->name, evt->mult, evt->shift);
- clockevents_register_device(evt);
-}
-
-void __init vmi_time_init(void)
-{
- unsigned int cpu;
- /* Disable PIT: BIOSes start PIT CH0 with 18.2hz peridic. */
- outb_pit(0x3a, PIT_MODE); /* binary, mode 5, LSB/MSB, ch 0 */
-
- vmi_time_init_clockevent();
- setup_irq(0, &vmi_clock_action);
- for_each_possible_cpu(cpu)
- per_cpu(vector_irq, cpu)[vmi_get_timer_vector()] = 0;
-}
-
-#ifdef CONFIG_X86_LOCAL_APIC
-void __devinit vmi_time_bsp_init(void)
-{
- /*
- * On APIC systems, we want local timers to fire on each cpu. We do
- * this by programming LVTT to deliver timer events to the IRQ handler
- * for IRQ-0, since we can't re-use the APIC local timer handler
- * without interfering with that code.
- */
- clockevents_notify(CLOCK_EVT_NOTIFY_SUSPEND, NULL);
- local_irq_disable();
-#ifdef CONFIG_SMP
- /*
- * XXX handle_percpu_irq only defined for SMP; we need to switch over
- * to using it, since this is a local interrupt, which each CPU must
- * handle individually without locking out or dropping simultaneous
- * local timers on other CPUs. We also don't want to trigger the
- * quirk workaround code for interrupts which gets invoked from
- * handle_percpu_irq via eoi, so we use our own IRQ chip.
- */
- set_irq_chip_and_handler_name(0, &vmi_chip, handle_percpu_irq, "lvtt");
-#else
- set_irq_chip_and_handler_name(0, &vmi_chip, handle_edge_irq, "lvtt");
-#endif
- vmi_wiring = VMI_ALARM_WIRED_LVTT;
- apic_write(APIC_LVTT, vmi_get_timer_vector());
- local_irq_enable();
- clockevents_notify(CLOCK_EVT_NOTIFY_RESUME, NULL);
-}
-
-void __devinit vmi_time_ap_init(void)
-{
- vmi_time_init_clockevent();
- apic_write(APIC_LVTT, vmi_get_timer_vector());
-}
-#endif
-
-/** vmi clocksource */
-static struct clocksource clocksource_vmi;
-
-static cycle_t read_real_cycles(struct clocksource *cs)
-{
- cycle_t ret = (cycle_t)vmi_timer_ops.get_cycle_counter(VMI_CYCLES_REAL);
- return max(ret, clocksource_vmi.cycle_last);
-}
-
-static struct clocksource clocksource_vmi = {
- .name = "vmi-timer",
- .rating = 450,
- .read = read_real_cycles,
- .mask = CLOCKSOURCE_MASK(64),
- .mult = 0, /* to be set */
- .shift = 22,
- .flags = CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-static int __init init_vmi_clocksource(void)
-{
- cycle_t cycles_per_msec;
-
- if (!vmi_timer_ops.get_cycle_frequency)
- return 0;
- /* Use khz2mult rather than hz2mult since hz arg is only 32-bits. */
- cycles_per_msec = vmi_timer_ops.get_cycle_frequency();
- (void)do_div(cycles_per_msec, 1000);
-
- /* Note that clocksource.{mult, shift} converts in the opposite direction
- * as clockevents. */
- clocksource_vmi.mult = clocksource_khz2mult(cycles_per_msec,
- clocksource_vmi.shift);
-
- printk(KERN_WARNING "vmi: registering clock source khz=%lld\n", cycles_per_msec);
- return clocksource_register(&clocksource_vmi);
-
-}
-module_init(init_vmi_clocksource);
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index d0bb52296fa3..e03530aebfd0 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -242,6 +242,12 @@ SECTIONS
__x86_cpu_dev_end = .;
}
+ /*
+ * start address and size of operations which during runtime
+ * can be patched with virtualization friendly instructions or
+ * baremetal native ones. Think page table operations.
+ * Details in paravirt_types.h
+ */
. = ALIGN(8);
.parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
__parainstructions = .;
@@ -249,6 +255,11 @@ SECTIONS
__parainstructions_end = .;
}
+ /*
+ * struct alt_inst entries. From the header (alternative.h):
+ * "Alternative instructions for different CPU types or capabilities"
+ * Think locking instructions on spinlocks.
+ */
. = ALIGN(8);
.altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
__alt_instructions = .;
@@ -256,11 +267,28 @@ SECTIONS
__alt_instructions_end = .;
}
+ /*
+ * And here are the replacement instructions. The linker sticks
+ * them as binary blobs. The .altinstructions has enough data to
+ * get the address and the length of them to patch the kernel safely.
+ */
.altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
*(.altinstr_replacement)
}
/*
+ * struct iommu_table_entry entries are injected in this section.
+ * It is an array of IOMMUs which during run time gets sorted depending
+ * on its dependency order. After rootfs_initcall is complete
+ * this section can be safely removed.
+ */
+ .iommu_table : AT(ADDR(.iommu_table) - LOAD_OFFSET) {
+ __iommu_table = .;
+ *(.iommu_table)
+ __iommu_table_end = .;
+ }
+ . = ALIGN(8);
+ /*
* .exit.text is discard at runtime, not link time, to deal with
* references from .altinstructions and .eh_frame
*/
@@ -273,7 +301,7 @@ SECTIONS
}
#if !defined(CONFIG_X86_64) || !defined(CONFIG_SMP)
- PERCPU(PAGE_SIZE)
+ PERCPU(THREAD_SIZE)
#endif
. = ALIGN(PAGE_SIZE);
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
index 970bbd479516..ddc131ff438f 100644
--- a/arch/x86/kvm/Kconfig
+++ b/arch/x86/kvm/Kconfig
@@ -64,6 +64,13 @@ config KVM_AMD
To compile this as a module, choose M here: the module
will be called kvm-amd.
+config KVM_MMU_AUDIT
+ bool "Audit KVM MMU"
+ depends on KVM && TRACEPOINTS
+ ---help---
+ This option adds a R/W kVM module parameter 'mmu_audit', which allows
+ audit KVM MMU at runtime.
+
# OK, it's a little counter-intuitive to do this, but it puts it neatly under
# the virtualization menu.
source drivers/vhost/Kconfig
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 66ca98aafdd6..38b6e8dafaff 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -9,7 +9,7 @@
* privileged instructions:
*
* Copyright (C) 2006 Qumranet
- * Copyright 2010 Red Hat, Inc. and/or its affilates.
+ * Copyright 2010 Red Hat, Inc. and/or its affiliates.
*
* Avi Kivity <avi@qumranet.com>
* Yaniv Kamay <yaniv@qumranet.com>
@@ -51,13 +51,13 @@
#define ImplicitOps (1<<1) /* Implicit in opcode. No generic decode. */
#define DstReg (2<<1) /* Register operand. */
#define DstMem (3<<1) /* Memory operand. */
-#define DstAcc (4<<1) /* Destination Accumulator */
+#define DstAcc (4<<1) /* Destination Accumulator */
#define DstDI (5<<1) /* Destination is in ES:(E)DI */
#define DstMem64 (6<<1) /* 64bit memory operand */
+#define DstImmUByte (7<<1) /* 8-bit unsigned immediate operand */
#define DstMask (7<<1)
/* Source operand type. */
#define SrcNone (0<<4) /* No source operand. */
-#define SrcImplicit (0<<4) /* Source operand is implicit in the opcode. */
#define SrcReg (1<<4) /* Register operand. */
#define SrcMem (2<<4) /* Memory operand. */
#define SrcMem16 (3<<4) /* Memory operand (16-bit). */
@@ -71,6 +71,7 @@
#define SrcImmFAddr (0xb<<4) /* Source is immediate far address */
#define SrcMemFAddr (0xc<<4) /* Source is far address in memory */
#define SrcAcc (0xd<<4) /* Source Accumulator */
+#define SrcImmU16 (0xe<<4) /* Immediate operand, unsigned, 16 bits */
#define SrcMask (0xf<<4)
/* Generic ModRM decode. */
#define ModRM (1<<8)
@@ -82,8 +83,10 @@
#define Stack (1<<13) /* Stack instruction (push/pop) */
#define Group (1<<14) /* Bits 3:5 of modrm byte extend opcode */
#define GroupDual (1<<15) /* Alternate decoding of mod == 3 */
-#define GroupMask 0xff /* Group number stored in bits 0:7 */
/* Misc flags */
+#define NoAccess (1<<23) /* Don't access memory (lea/invlpg/verr etc) */
+#define Op3264 (1<<24) /* Operand is 64b in long mode, 32b otherwise */
+#define Undefined (1<<25) /* No Such Instruction */
#define Lock (1<<26) /* lock prefix is allowed for the instruction */
#define Priv (1<<27) /* instruction generates #GP if current CPL != 0 */
#define No64 (1<<28)
@@ -92,285 +95,30 @@
#define Src2CL (1<<29)
#define Src2ImmByte (2<<29)
#define Src2One (3<<29)
+#define Src2Imm (4<<29)
#define Src2Mask (7<<29)
-enum {
- Group1_80, Group1_81, Group1_82, Group1_83,
- Group1A, Group3_Byte, Group3, Group4, Group5, Group7,
- Group8, Group9,
+#define X2(x...) x, x
+#define X3(x...) X2(x), x
+#define X4(x...) X2(x), X2(x)
+#define X5(x...) X4(x), x
+#define X6(x...) X4(x), X2(x)
+#define X7(x...) X4(x), X3(x)
+#define X8(x...) X4(x), X4(x)
+#define X16(x...) X8(x), X8(x)
+
+struct opcode {
+ u32 flags;
+ union {
+ int (*execute)(struct x86_emulate_ctxt *ctxt);
+ struct opcode *group;
+ struct group_dual *gdual;
+ } u;
};
-static u32 opcode_table[256] = {
- /* 0x00 - 0x07 */
- ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
- ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
- ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
- ImplicitOps | Stack | No64, ImplicitOps | Stack | No64,
- /* 0x08 - 0x0F */
- ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
- ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
- ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
- ImplicitOps | Stack | No64, 0,
- /* 0x10 - 0x17 */
- ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
- ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
- ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
- ImplicitOps | Stack | No64, ImplicitOps | Stack | No64,
- /* 0x18 - 0x1F */
- ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
- ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
- ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
- ImplicitOps | Stack | No64, ImplicitOps | Stack | No64,
- /* 0x20 - 0x27 */
- ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
- ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
- ByteOp | DstAcc | SrcImmByte, DstAcc | SrcImm, 0, 0,
- /* 0x28 - 0x2F */
- ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
- ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
- ByteOp | DstAcc | SrcImmByte, DstAcc | SrcImm, 0, 0,
- /* 0x30 - 0x37 */
- ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
- ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
- ByteOp | DstAcc | SrcImmByte, DstAcc | SrcImm, 0, 0,
- /* 0x38 - 0x3F */
- ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
- ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
- ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
- 0, 0,
- /* 0x40 - 0x47 */
- DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg,
- /* 0x48 - 0x4F */
- DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg,
- /* 0x50 - 0x57 */
- SrcReg | Stack, SrcReg | Stack, SrcReg | Stack, SrcReg | Stack,
- SrcReg | Stack, SrcReg | Stack, SrcReg | Stack, SrcReg | Stack,
- /* 0x58 - 0x5F */
- DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack,
- DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack,
- /* 0x60 - 0x67 */
- ImplicitOps | Stack | No64, ImplicitOps | Stack | No64,
- 0, DstReg | SrcMem32 | ModRM | Mov /* movsxd (x86/64) */ ,
- 0, 0, 0, 0,
- /* 0x68 - 0x6F */
- SrcImm | Mov | Stack, 0, SrcImmByte | Mov | Stack, 0,
- DstDI | ByteOp | Mov | String, DstDI | Mov | String, /* insb, insw/insd */
- SrcSI | ByteOp | ImplicitOps | String, SrcSI | ImplicitOps | String, /* outsb, outsw/outsd */
- /* 0x70 - 0x77 */
- SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte,
- SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte,
- /* 0x78 - 0x7F */
- SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte,
- SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte,
- /* 0x80 - 0x87 */
- Group | Group1_80, Group | Group1_81,
- Group | Group1_82, Group | Group1_83,
- ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
- ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
- /* 0x88 - 0x8F */
- ByteOp | DstMem | SrcReg | ModRM | Mov, DstMem | SrcReg | ModRM | Mov,
- ByteOp | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
- DstMem | SrcNone | ModRM | Mov, ModRM | DstReg,
- ImplicitOps | SrcMem16 | ModRM, Group | Group1A,
- /* 0x90 - 0x97 */
- DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg,
- /* 0x98 - 0x9F */
- 0, 0, SrcImmFAddr | No64, 0,
- ImplicitOps | Stack, ImplicitOps | Stack, 0, 0,
- /* 0xA0 - 0xA7 */
- ByteOp | DstAcc | SrcMem | Mov | MemAbs, DstAcc | SrcMem | Mov | MemAbs,
- ByteOp | DstMem | SrcAcc | Mov | MemAbs, DstMem | SrcAcc | Mov | MemAbs,
- ByteOp | SrcSI | DstDI | Mov | String, SrcSI | DstDI | Mov | String,
- ByteOp | SrcSI | DstDI | String, SrcSI | DstDI | String,
- /* 0xA8 - 0xAF */
- DstAcc | SrcImmByte | ByteOp, DstAcc | SrcImm, ByteOp | DstDI | Mov | String, DstDI | Mov | String,
- ByteOp | SrcSI | DstAcc | Mov | String, SrcSI | DstAcc | Mov | String,
- ByteOp | DstDI | String, DstDI | String,
- /* 0xB0 - 0xB7 */
- ByteOp | DstReg | SrcImm | Mov, ByteOp | DstReg | SrcImm | Mov,
- ByteOp | DstReg | SrcImm | Mov, ByteOp | DstReg | SrcImm | Mov,
- ByteOp | DstReg | SrcImm | Mov, ByteOp | DstReg | SrcImm | Mov,
- ByteOp | DstReg | SrcImm | Mov, ByteOp | DstReg | SrcImm | Mov,
- /* 0xB8 - 0xBF */
- DstReg | SrcImm | Mov, DstReg | SrcImm | Mov,
- DstReg | SrcImm | Mov, DstReg | SrcImm | Mov,
- DstReg | SrcImm | Mov, DstReg | SrcImm | Mov,
- DstReg | SrcImm | Mov, DstReg | SrcImm | Mov,
- /* 0xC0 - 0xC7 */
- ByteOp | DstMem | SrcImm | ModRM, DstMem | SrcImmByte | ModRM,
- 0, ImplicitOps | Stack, 0, 0,
- ByteOp | DstMem | SrcImm | ModRM | Mov, DstMem | SrcImm | ModRM | Mov,
- /* 0xC8 - 0xCF */
- 0, 0, 0, ImplicitOps | Stack,
- ImplicitOps, SrcImmByte, ImplicitOps | No64, ImplicitOps,
- /* 0xD0 - 0xD7 */
- ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM,
- ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM,
- 0, 0, 0, 0,
- /* 0xD8 - 0xDF */
- 0, 0, 0, 0, 0, 0, 0, 0,
- /* 0xE0 - 0xE7 */
- 0, 0, 0, 0,
- ByteOp | SrcImmUByte | DstAcc, SrcImmUByte | DstAcc,
- ByteOp | SrcImmUByte | DstAcc, SrcImmUByte | DstAcc,
- /* 0xE8 - 0xEF */
- SrcImm | Stack, SrcImm | ImplicitOps,
- SrcImmFAddr | No64, SrcImmByte | ImplicitOps,
- SrcNone | ByteOp | DstAcc, SrcNone | DstAcc,
- SrcNone | ByteOp | DstAcc, SrcNone | DstAcc,
- /* 0xF0 - 0xF7 */
- 0, 0, 0, 0,
- ImplicitOps | Priv, ImplicitOps, Group | Group3_Byte, Group | Group3,
- /* 0xF8 - 0xFF */
- ImplicitOps, 0, ImplicitOps, ImplicitOps,
- ImplicitOps, ImplicitOps, Group | Group4, Group | Group5,
-};
-
-static u32 twobyte_table[256] = {
- /* 0x00 - 0x0F */
- 0, Group | GroupDual | Group7, 0, 0,
- 0, ImplicitOps, ImplicitOps | Priv, 0,
- ImplicitOps | Priv, ImplicitOps | Priv, 0, 0,
- 0, ImplicitOps | ModRM, 0, 0,
- /* 0x10 - 0x1F */
- 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0,
- /* 0x20 - 0x2F */
- ModRM | ImplicitOps | Priv, ModRM | Priv,
- ModRM | ImplicitOps | Priv, ModRM | Priv,
- 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- /* 0x30 - 0x3F */
- ImplicitOps | Priv, 0, ImplicitOps | Priv, 0,
- ImplicitOps, ImplicitOps | Priv, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- /* 0x40 - 0x47 */
- DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
- DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
- DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
- DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
- /* 0x48 - 0x4F */
- DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
- DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
- DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
- DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
- /* 0x50 - 0x5F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- /* 0x60 - 0x6F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- /* 0x70 - 0x7F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- /* 0x80 - 0x8F */
- SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm,
- SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm,
- /* 0x90 - 0x9F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- /* 0xA0 - 0xA7 */
- ImplicitOps | Stack, ImplicitOps | Stack,
- 0, DstMem | SrcReg | ModRM | BitOp,
- DstMem | SrcReg | Src2ImmByte | ModRM,
- DstMem | SrcReg | Src2CL | ModRM, 0, 0,
- /* 0xA8 - 0xAF */
- ImplicitOps | Stack, ImplicitOps | Stack,
- 0, DstMem | SrcReg | ModRM | BitOp | Lock,
- DstMem | SrcReg | Src2ImmByte | ModRM,
- DstMem | SrcReg | Src2CL | ModRM,
- ModRM, 0,
- /* 0xB0 - 0xB7 */
- ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
- 0, DstMem | SrcReg | ModRM | BitOp | Lock,
- 0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov,
- DstReg | SrcMem16 | ModRM | Mov,
- /* 0xB8 - 0xBF */
- 0, 0,
- Group | Group8, DstMem | SrcReg | ModRM | BitOp | Lock,
- 0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov,
- DstReg | SrcMem16 | ModRM | Mov,
- /* 0xC0 - 0xCF */
- 0, 0, 0, DstMem | SrcReg | ModRM | Mov,
- 0, 0, 0, Group | GroupDual | Group9,
- 0, 0, 0, 0, 0, 0, 0, 0,
- /* 0xD0 - 0xDF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- /* 0xE0 - 0xEF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- /* 0xF0 - 0xFF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-static u32 group_table[] = {
- [Group1_80*8] =
- ByteOp | DstMem | SrcImm | ModRM | Lock,
- ByteOp | DstMem | SrcImm | ModRM | Lock,
- ByteOp | DstMem | SrcImm | ModRM | Lock,
- ByteOp | DstMem | SrcImm | ModRM | Lock,
- ByteOp | DstMem | SrcImm | ModRM | Lock,
- ByteOp | DstMem | SrcImm | ModRM | Lock,
- ByteOp | DstMem | SrcImm | ModRM | Lock,
- ByteOp | DstMem | SrcImm | ModRM,
- [Group1_81*8] =
- DstMem | SrcImm | ModRM | Lock,
- DstMem | SrcImm | ModRM | Lock,
- DstMem | SrcImm | ModRM | Lock,
- DstMem | SrcImm | ModRM | Lock,
- DstMem | SrcImm | ModRM | Lock,
- DstMem | SrcImm | ModRM | Lock,
- DstMem | SrcImm | ModRM | Lock,
- DstMem | SrcImm | ModRM,
- [Group1_82*8] =
- ByteOp | DstMem | SrcImm | ModRM | No64 | Lock,
- ByteOp | DstMem | SrcImm | ModRM | No64 | Lock,
- ByteOp | DstMem | SrcImm | ModRM | No64 | Lock,
- ByteOp | DstMem | SrcImm | ModRM | No64 | Lock,
- ByteOp | DstMem | SrcImm | ModRM | No64 | Lock,
- ByteOp | DstMem | SrcImm | ModRM | No64 | Lock,
- ByteOp | DstMem | SrcImm | ModRM | No64 | Lock,
- ByteOp | DstMem | SrcImm | ModRM | No64,
- [Group1_83*8] =
- DstMem | SrcImmByte | ModRM | Lock,
- DstMem | SrcImmByte | ModRM | Lock,
- DstMem | SrcImmByte | ModRM | Lock,
- DstMem | SrcImmByte | ModRM | Lock,
- DstMem | SrcImmByte | ModRM | Lock,
- DstMem | SrcImmByte | ModRM | Lock,
- DstMem | SrcImmByte | ModRM | Lock,
- DstMem | SrcImmByte | ModRM,
- [Group1A*8] =
- DstMem | SrcNone | ModRM | Mov | Stack, 0, 0, 0, 0, 0, 0, 0,
- [Group3_Byte*8] =
- ByteOp | SrcImm | DstMem | ModRM, ByteOp | SrcImm | DstMem | ModRM,
- ByteOp | DstMem | SrcNone | ModRM, ByteOp | DstMem | SrcNone | ModRM,
- 0, 0, 0, 0,
- [Group3*8] =
- DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM,
- DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM,
- 0, 0, 0, 0,
- [Group4*8] =
- ByteOp | DstMem | SrcNone | ModRM | Lock, ByteOp | DstMem | SrcNone | ModRM | Lock,
- 0, 0, 0, 0, 0, 0,
- [Group5*8] =
- DstMem | SrcNone | ModRM | Lock, DstMem | SrcNone | ModRM | Lock,
- SrcMem | ModRM | Stack, 0,
- SrcMem | ModRM | Stack, SrcMemFAddr | ModRM | ImplicitOps,
- SrcMem | ModRM | Stack, 0,
- [Group7*8] =
- 0, 0, ModRM | SrcMem | Priv, ModRM | SrcMem | Priv,
- SrcNone | ModRM | DstMem | Mov, 0,
- SrcMem16 | ModRM | Mov | Priv, SrcMem | ModRM | ByteOp | Priv,
- [Group8*8] =
- 0, 0, 0, 0,
- DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM | Lock,
- DstMem | SrcImmByte | ModRM | Lock, DstMem | SrcImmByte | ModRM | Lock,
- [Group9*8] =
- 0, DstMem64 | ModRM | Lock, 0, 0, 0, 0, 0, 0,
-};
-
-static u32 group2_table[] = {
- [Group7*8] =
- SrcNone | ModRM | Priv, 0, 0, SrcNone | ModRM | Priv,
- SrcNone | ModRM | DstMem | Mov, 0,
- SrcMem16 | ModRM | Mov | Priv, 0,
- [Group9*8] =
- 0, 0, 0, 0, 0, 0, 0, 0,
+struct group_dual {
+ struct opcode mod012[8];
+ struct opcode mod3[8];
};
/* EFLAGS bit definitions. */
@@ -392,6 +140,9 @@ static u32 group2_table[] = {
#define EFLG_PF (1<<2)
#define EFLG_CF (1<<0)
+#define EFLG_RESERVED_ZEROS_MASK 0xffc0802a
+#define EFLG_RESERVED_ONE_MASK 2
+
/*
* Instruction emulation:
* Most instructions are emulated directly via a fragment of inline assembly
@@ -444,13 +195,13 @@ static u32 group2_table[] = {
#define ON64(x)
#endif
-#define ____emulate_2op(_op, _src, _dst, _eflags, _x, _y, _suffix) \
+#define ____emulate_2op(_op, _src, _dst, _eflags, _x, _y, _suffix, _dsttype) \
do { \
__asm__ __volatile__ ( \
_PRE_EFLAGS("0", "4", "2") \
_op _suffix " %"_x"3,%1; " \
_POST_EFLAGS("0", "4", "2") \
- : "=m" (_eflags), "=m" ((_dst).val), \
+ : "=m" (_eflags), "+q" (*(_dsttype*)&(_dst).val),\
"=&r" (_tmp) \
: _y ((_src).val), "i" (EFLAGS_MASK)); \
} while (0)
@@ -463,13 +214,13 @@ static u32 group2_table[] = {
\
switch ((_dst).bytes) { \
case 2: \
- ____emulate_2op(_op,_src,_dst,_eflags,_wx,_wy,"w"); \
+ ____emulate_2op(_op,_src,_dst,_eflags,_wx,_wy,"w",u16);\
break; \
case 4: \
- ____emulate_2op(_op,_src,_dst,_eflags,_lx,_ly,"l"); \
+ ____emulate_2op(_op,_src,_dst,_eflags,_lx,_ly,"l",u32);\
break; \
case 8: \
- ON64(____emulate_2op(_op,_src,_dst,_eflags,_qx,_qy,"q")); \
+ ON64(____emulate_2op(_op,_src,_dst,_eflags,_qx,_qy,"q",u64)); \
break; \
} \
} while (0)
@@ -479,7 +230,7 @@ static u32 group2_table[] = {
unsigned long _tmp; \
switch ((_dst).bytes) { \
case 1: \
- ____emulate_2op(_op,_src,_dst,_eflags,_bx,_by,"b"); \
+ ____emulate_2op(_op,_src,_dst,_eflags,_bx,_by,"b",u8); \
break; \
default: \
__emulate_2op_nobyte(_op, _src, _dst, _eflags, \
@@ -566,6 +317,74 @@ static u32 group2_table[] = {
} \
} while (0)
+#define __emulate_1op_rax_rdx(_op, _src, _rax, _rdx, _eflags, _suffix) \
+ do { \
+ unsigned long _tmp; \
+ \
+ __asm__ __volatile__ ( \
+ _PRE_EFLAGS("0", "4", "1") \
+ _op _suffix " %5; " \
+ _POST_EFLAGS("0", "4", "1") \
+ : "=m" (_eflags), "=&r" (_tmp), \
+ "+a" (_rax), "+d" (_rdx) \
+ : "i" (EFLAGS_MASK), "m" ((_src).val), \
+ "a" (_rax), "d" (_rdx)); \
+ } while (0)
+
+#define __emulate_1op_rax_rdx_ex(_op, _src, _rax, _rdx, _eflags, _suffix, _ex) \
+ do { \
+ unsigned long _tmp; \
+ \
+ __asm__ __volatile__ ( \
+ _PRE_EFLAGS("0", "5", "1") \
+ "1: \n\t" \
+ _op _suffix " %6; " \
+ "2: \n\t" \
+ _POST_EFLAGS("0", "5", "1") \
+ ".pushsection .fixup,\"ax\" \n\t" \
+ "3: movb $1, %4 \n\t" \
+ "jmp 2b \n\t" \
+ ".popsection \n\t" \
+ _ASM_EXTABLE(1b, 3b) \
+ : "=m" (_eflags), "=&r" (_tmp), \
+ "+a" (_rax), "+d" (_rdx), "+qm"(_ex) \
+ : "i" (EFLAGS_MASK), "m" ((_src).val), \
+ "a" (_rax), "d" (_rdx)); \
+ } while (0)
+
+/* instruction has only one source operand, destination is implicit (e.g. mul, div, imul, idiv) */
+#define emulate_1op_rax_rdx(_op, _src, _rax, _rdx, _eflags) \
+ do { \
+ switch((_src).bytes) { \
+ case 1: __emulate_1op_rax_rdx(_op, _src, _rax, _rdx, _eflags, "b"); break; \
+ case 2: __emulate_1op_rax_rdx(_op, _src, _rax, _rdx, _eflags, "w"); break; \
+ case 4: __emulate_1op_rax_rdx(_op, _src, _rax, _rdx, _eflags, "l"); break; \
+ case 8: ON64(__emulate_1op_rax_rdx(_op, _src, _rax, _rdx, _eflags, "q")); break; \
+ } \
+ } while (0)
+
+#define emulate_1op_rax_rdx_ex(_op, _src, _rax, _rdx, _eflags, _ex) \
+ do { \
+ switch((_src).bytes) { \
+ case 1: \
+ __emulate_1op_rax_rdx_ex(_op, _src, _rax, _rdx, \
+ _eflags, "b", _ex); \
+ break; \
+ case 2: \
+ __emulate_1op_rax_rdx_ex(_op, _src, _rax, _rdx, \
+ _eflags, "w", _ex); \
+ break; \
+ case 4: \
+ __emulate_1op_rax_rdx_ex(_op, _src, _rax, _rdx, \
+ _eflags, "l", _ex); \
+ break; \
+ case 8: ON64( \
+ __emulate_1op_rax_rdx_ex(_op, _src, _rax, _rdx, \
+ _eflags, "q", _ex)); \
+ break; \
+ } \
+ } while (0)
+
/* Fetch next part of the instruction being emulated. */
#define insn_fetch(_type, _size, _eip) \
({ unsigned long _x; \
@@ -661,7 +480,6 @@ static void emulate_exception(struct x86_emulate_ctxt *ctxt, int vec,
ctxt->exception = vec;
ctxt->error_code = error;
ctxt->error_code_valid = valid;
- ctxt->restart = false;
}
static void emulate_gp(struct x86_emulate_ctxt *ctxt, int err)
@@ -669,11 +487,9 @@ static void emulate_gp(struct x86_emulate_ctxt *ctxt, int err)
emulate_exception(ctxt, GP_VECTOR, err, true);
}
-static void emulate_pf(struct x86_emulate_ctxt *ctxt, unsigned long addr,
- int err)
+static void emulate_pf(struct x86_emulate_ctxt *ctxt)
{
- ctxt->cr2 = addr;
- emulate_exception(ctxt, PF_VECTOR, err, true);
+ emulate_exception(ctxt, PF_VECTOR, 0, true);
}
static void emulate_ud(struct x86_emulate_ctxt *ctxt)
@@ -686,6 +502,12 @@ static void emulate_ts(struct x86_emulate_ctxt *ctxt, int err)
emulate_exception(ctxt, TS_VECTOR, err, true);
}
+static int emulate_de(struct x86_emulate_ctxt *ctxt)
+{
+ emulate_exception(ctxt, DE_VECTOR, 0, false);
+ return X86EMUL_PROPAGATE_FAULT;
+}
+
static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt,
struct x86_emulate_ops *ops,
unsigned long eip, u8 *dest)
@@ -742,7 +564,7 @@ static void *decode_register(u8 modrm_reg, unsigned long *regs,
static int read_descriptor(struct x86_emulate_ctxt *ctxt,
struct x86_emulate_ops *ops,
- void *ptr,
+ ulong addr,
u16 *size, unsigned long *address, int op_bytes)
{
int rc;
@@ -750,12 +572,10 @@ static int read_descriptor(struct x86_emulate_ctxt *ctxt,
if (op_bytes == 2)
op_bytes = 3;
*address = 0;
- rc = ops->read_std((unsigned long)ptr, (unsigned long *)size, 2,
- ctxt->vcpu, NULL);
+ rc = ops->read_std(addr, (unsigned long *)size, 2, ctxt->vcpu, NULL);
if (rc != X86EMUL_CONTINUE)
return rc;
- rc = ops->read_std((unsigned long)ptr + 2, address, op_bytes,
- ctxt->vcpu, NULL);
+ rc = ops->read_std(addr + 2, address, op_bytes, ctxt->vcpu, NULL);
return rc;
}
@@ -794,6 +614,24 @@ static int test_cc(unsigned int condition, unsigned int flags)
return (!!rc ^ (condition & 1));
}
+static void fetch_register_operand(struct operand *op)
+{
+ switch (op->bytes) {
+ case 1:
+ op->val = *(u8 *)op->addr.reg;
+ break;
+ case 2:
+ op->val = *(u16 *)op->addr.reg;
+ break;
+ case 4:
+ op->val = *(u32 *)op->addr.reg;
+ break;
+ case 8:
+ op->val = *(u64 *)op->addr.reg;
+ break;
+ }
+}
+
static void decode_register_operand(struct operand *op,
struct decode_cache *c,
int inhibit_bytereg)
@@ -805,34 +643,25 @@ static void decode_register_operand(struct operand *op,
reg = (c->b & 7) | ((c->rex_prefix & 1) << 3);
op->type = OP_REG;
if ((c->d & ByteOp) && !inhibit_bytereg) {
- op->ptr = decode_register(reg, c->regs, highbyte_regs);
- op->val = *(u8 *)op->ptr;
+ op->addr.reg = decode_register(reg, c->regs, highbyte_regs);
op->bytes = 1;
} else {
- op->ptr = decode_register(reg, c->regs, 0);
+ op->addr.reg = decode_register(reg, c->regs, 0);
op->bytes = c->op_bytes;
- switch (op->bytes) {
- case 2:
- op->val = *(u16 *)op->ptr;
- break;
- case 4:
- op->val = *(u32 *)op->ptr;
- break;
- case 8:
- op->val = *(u64 *) op->ptr;
- break;
- }
}
+ fetch_register_operand(op);
op->orig_val = op->val;
}
static int decode_modrm(struct x86_emulate_ctxt *ctxt,
- struct x86_emulate_ops *ops)
+ struct x86_emulate_ops *ops,
+ struct operand *op)
{
struct decode_cache *c = &ctxt->decode;
u8 sib;
int index_reg = 0, base_reg = 0, scale;
int rc = X86EMUL_CONTINUE;
+ ulong modrm_ea = 0;
if (c->rex_prefix) {
c->modrm_reg = (c->rex_prefix & 4) << 1; /* REX.R */
@@ -844,16 +673,19 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
c->modrm_mod |= (c->modrm & 0xc0) >> 6;
c->modrm_reg |= (c->modrm & 0x38) >> 3;
c->modrm_rm |= (c->modrm & 0x07);
- c->modrm_ea = 0;
- c->use_modrm_ea = 1;
+ c->modrm_seg = VCPU_SREG_DS;
if (c->modrm_mod == 3) {
- c->modrm_ptr = decode_register(c->modrm_rm,
+ op->type = OP_REG;
+ op->bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
+ op->addr.reg = decode_register(c->modrm_rm,
c->regs, c->d & ByteOp);
- c->modrm_val = *(unsigned long *)c->modrm_ptr;
+ fetch_register_operand(op);
return rc;
}
+ op->type = OP_MEM;
+
if (c->ad_bytes == 2) {
unsigned bx = c->regs[VCPU_REGS_RBX];
unsigned bp = c->regs[VCPU_REGS_RBP];
@@ -864,47 +696,46 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
switch (c->modrm_mod) {
case 0:
if (c->modrm_rm == 6)
- c->modrm_ea += insn_fetch(u16, 2, c->eip);
+ modrm_ea += insn_fetch(u16, 2, c->eip);
break;
case 1:
- c->modrm_ea += insn_fetch(s8, 1, c->eip);
+ modrm_ea += insn_fetch(s8, 1, c->eip);
break;
case 2:
- c->modrm_ea += insn_fetch(u16, 2, c->eip);
+ modrm_ea += insn_fetch(u16, 2, c->eip);
break;
}
switch (c->modrm_rm) {
case 0:
- c->modrm_ea += bx + si;
+ modrm_ea += bx + si;
break;
case 1:
- c->modrm_ea += bx + di;
+ modrm_ea += bx + di;
break;
case 2:
- c->modrm_ea += bp + si;
+ modrm_ea += bp + si;
break;
case 3:
- c->modrm_ea += bp + di;
+ modrm_ea += bp + di;
break;
case 4:
- c->modrm_ea += si;
+ modrm_ea += si;
break;
case 5:
- c->modrm_ea += di;
+ modrm_ea += di;
break;
case 6:
if (c->modrm_mod != 0)
- c->modrm_ea += bp;
+ modrm_ea += bp;
break;
case 7:
- c->modrm_ea += bx;
+ modrm_ea += bx;
break;
}
if (c->modrm_rm == 2 || c->modrm_rm == 3 ||
(c->modrm_rm == 6 && c->modrm_mod != 0))
- if (!c->has_seg_override)
- set_seg_override(c, VCPU_SREG_SS);
- c->modrm_ea = (u16)c->modrm_ea;
+ c->modrm_seg = VCPU_SREG_SS;
+ modrm_ea = (u16)modrm_ea;
} else {
/* 32/64-bit ModR/M decode. */
if ((c->modrm_rm & 7) == 4) {
@@ -914,410 +745,74 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
scale = sib >> 6;
if ((base_reg & 7) == 5 && c->modrm_mod == 0)
- c->modrm_ea += insn_fetch(s32, 4, c->eip);
+ modrm_ea += insn_fetch(s32, 4, c->eip);
else
- c->modrm_ea += c->regs[base_reg];
+ modrm_ea += c->regs[base_reg];
if (index_reg != 4)
- c->modrm_ea += c->regs[index_reg] << scale;
+ modrm_ea += c->regs[index_reg] << scale;
} else if ((c->modrm_rm & 7) == 5 && c->modrm_mod == 0) {
if (ctxt->mode == X86EMUL_MODE_PROT64)
c->rip_relative = 1;
} else
- c->modrm_ea += c->regs[c->modrm_rm];
+ modrm_ea += c->regs[c->modrm_rm];
switch (c->modrm_mod) {
case 0:
if (c->modrm_rm == 5)
- c->modrm_ea += insn_fetch(s32, 4, c->eip);
+ modrm_ea += insn_fetch(s32, 4, c->eip);
break;
case 1:
- c->modrm_ea += insn_fetch(s8, 1, c->eip);
+ modrm_ea += insn_fetch(s8, 1, c->eip);
break;
case 2:
- c->modrm_ea += insn_fetch(s32, 4, c->eip);
+ modrm_ea += insn_fetch(s32, 4, c->eip);
break;
}
}
+ op->addr.mem = modrm_ea;
done:
return rc;
}
static int decode_abs(struct x86_emulate_ctxt *ctxt,
- struct x86_emulate_ops *ops)
+ struct x86_emulate_ops *ops,
+ struct operand *op)
{
struct decode_cache *c = &ctxt->decode;
int rc = X86EMUL_CONTINUE;
+ op->type = OP_MEM;
switch (c->ad_bytes) {
case 2:
- c->modrm_ea = insn_fetch(u16, 2, c->eip);
+ op->addr.mem = insn_fetch(u16, 2, c->eip);
break;
case 4:
- c->modrm_ea = insn_fetch(u32, 4, c->eip);
+ op->addr.mem = insn_fetch(u32, 4, c->eip);
break;
case 8:
- c->modrm_ea = insn_fetch(u64, 8, c->eip);
+ op->addr.mem = insn_fetch(u64, 8, c->eip);
break;
}
done:
return rc;
}
-int
-x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
+static void fetch_bit_operand(struct decode_cache *c)
{
- struct decode_cache *c = &ctxt->decode;
- int rc = X86EMUL_CONTINUE;
- int mode = ctxt->mode;
- int def_op_bytes, def_ad_bytes, group;
-
-
- /* we cannot decode insn before we complete previous rep insn */
- WARN_ON(ctxt->restart);
-
- c->eip = ctxt->eip;
- c->fetch.start = c->fetch.end = c->eip;
- ctxt->cs_base = seg_base(ctxt, ops, VCPU_SREG_CS);
-
- switch (mode) {
- case X86EMUL_MODE_REAL:
- case X86EMUL_MODE_VM86:
- case X86EMUL_MODE_PROT16:
- def_op_bytes = def_ad_bytes = 2;
- break;
- case X86EMUL_MODE_PROT32:
- def_op_bytes = def_ad_bytes = 4;
- break;
-#ifdef CONFIG_X86_64
- case X86EMUL_MODE_PROT64:
- def_op_bytes = 4;
- def_ad_bytes = 8;
- break;
-#endif
- default:
- return -1;
- }
-
- c->op_bytes = def_op_bytes;
- c->ad_bytes = def_ad_bytes;
-
- /* Legacy prefixes. */
- for (;;) {
- switch (c->b = insn_fetch(u8, 1, c->eip)) {
- case 0x66: /* operand-size override */
- /* switch between 2/4 bytes */
- c->op_bytes = def_op_bytes ^ 6;
- break;
- case 0x67: /* address-size override */
- if (mode == X86EMUL_MODE_PROT64)
- /* switch between 4/8 bytes */
- c->ad_bytes = def_ad_bytes ^ 12;
- else
- /* switch between 2/4 bytes */
- c->ad_bytes = def_ad_bytes ^ 6;
- break;
- case 0x26: /* ES override */
- case 0x2e: /* CS override */
- case 0x36: /* SS override */
- case 0x3e: /* DS override */
- set_seg_override(c, (c->b >> 3) & 3);
- break;
- case 0x64: /* FS override */
- case 0x65: /* GS override */
- set_seg_override(c, c->b & 7);
- break;
- case 0x40 ... 0x4f: /* REX */
- if (mode != X86EMUL_MODE_PROT64)
- goto done_prefixes;
- c->rex_prefix = c->b;
- continue;
- case 0xf0: /* LOCK */
- c->lock_prefix = 1;
- break;
- case 0xf2: /* REPNE/REPNZ */
- c->rep_prefix = REPNE_PREFIX;
- break;
- case 0xf3: /* REP/REPE/REPZ */
- c->rep_prefix = REPE_PREFIX;
- break;
- default:
- goto done_prefixes;
- }
-
- /* Any legacy prefix after a REX prefix nullifies its effect. */
-
- c->rex_prefix = 0;
- }
-
-done_prefixes:
-
- /* REX prefix. */
- if (c->rex_prefix)
- if (c->rex_prefix & 8)
- c->op_bytes = 8; /* REX.W */
-
- /* Opcode byte(s). */
- c->d = opcode_table[c->b];
- if (c->d == 0) {
- /* Two-byte opcode? */
- if (c->b == 0x0f) {
- c->twobyte = 1;
- c->b = insn_fetch(u8, 1, c->eip);
- c->d = twobyte_table[c->b];
- }
- }
-
- if (c->d & Group) {
- group = c->d & GroupMask;
- c->modrm = insn_fetch(u8, 1, c->eip);
- --c->eip;
-
- group = (group << 3) + ((c->modrm >> 3) & 7);
- if ((c->d & GroupDual) && (c->modrm >> 6) == 3)
- c->d = group2_table[group];
- else
- c->d = group_table[group];
- }
-
- /* Unrecognised? */
- if (c->d == 0) {
- DPRINTF("Cannot emulate %02x\n", c->b);
- return -1;
- }
-
- if (mode == X86EMUL_MODE_PROT64 && (c->d & Stack))
- c->op_bytes = 8;
-
- /* ModRM and SIB bytes. */
- if (c->d & ModRM)
- rc = decode_modrm(ctxt, ops);
- else if (c->d & MemAbs)
- rc = decode_abs(ctxt, ops);
- if (rc != X86EMUL_CONTINUE)
- goto done;
-
- if (!c->has_seg_override)
- set_seg_override(c, VCPU_SREG_DS);
-
- if (!(!c->twobyte && c->b == 0x8d))
- c->modrm_ea += seg_override_base(ctxt, ops, c);
-
- if (c->ad_bytes != 8)
- c->modrm_ea = (u32)c->modrm_ea;
-
- if (c->rip_relative)
- c->modrm_ea += c->eip;
-
- /*
- * Decode and fetch the source operand: register, memory
- * or immediate.
- */
- switch (c->d & SrcMask) {
- case SrcNone:
- break;
- case SrcReg:
- decode_register_operand(&c->src, c, 0);
- break;
- case SrcMem16:
- c->src.bytes = 2;
- goto srcmem_common;
- case SrcMem32:
- c->src.bytes = 4;
- goto srcmem_common;
- case SrcMem:
- c->src.bytes = (c->d & ByteOp) ? 1 :
- c->op_bytes;
- /* Don't fetch the address for invlpg: it could be unmapped. */
- if (c->twobyte && c->b == 0x01 && c->modrm_reg == 7)
- break;
- srcmem_common:
- /*
- * For instructions with a ModR/M byte, switch to register
- * access if Mod = 3.
- */
- if ((c->d & ModRM) && c->modrm_mod == 3) {
- c->src.type = OP_REG;
- c->src.val = c->modrm_val;
- c->src.ptr = c->modrm_ptr;
- break;
- }
- c->src.type = OP_MEM;
- c->src.ptr = (unsigned long *)c->modrm_ea;
- c->src.val = 0;
- break;
- case SrcImm:
- case SrcImmU:
- c->src.type = OP_IMM;
- c->src.ptr = (unsigned long *)c->eip;
- c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
- if (c->src.bytes == 8)
- c->src.bytes = 4;
- /* NB. Immediates are sign-extended as necessary. */
- switch (c->src.bytes) {
- case 1:
- c->src.val = insn_fetch(s8, 1, c->eip);
- break;
- case 2:
- c->src.val = insn_fetch(s16, 2, c->eip);
- break;
- case 4:
- c->src.val = insn_fetch(s32, 4, c->eip);
- break;
- }
- if ((c->d & SrcMask) == SrcImmU) {
- switch (c->src.bytes) {
- case 1:
- c->src.val &= 0xff;
- break;
- case 2:
- c->src.val &= 0xffff;
- break;
- case 4:
- c->src.val &= 0xffffffff;
- break;
- }
- }
- break;
- case SrcImmByte:
- case SrcImmUByte:
- c->src.type = OP_IMM;
- c->src.ptr = (unsigned long *)c->eip;
- c->src.bytes = 1;
- if ((c->d & SrcMask) == SrcImmByte)
- c->src.val = insn_fetch(s8, 1, c->eip);
- else
- c->src.val = insn_fetch(u8, 1, c->eip);
- break;
- case SrcAcc:
- c->src.type = OP_REG;
- c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
- c->src.ptr = &c->regs[VCPU_REGS_RAX];
- switch (c->src.bytes) {
- case 1:
- c->src.val = *(u8 *)c->src.ptr;
- break;
- case 2:
- c->src.val = *(u16 *)c->src.ptr;
- break;
- case 4:
- c->src.val = *(u32 *)c->src.ptr;
- break;
- case 8:
- c->src.val = *(u64 *)c->src.ptr;
- break;
- }
- break;
- case SrcOne:
- c->src.bytes = 1;
- c->src.val = 1;
- break;
- case SrcSI:
- c->src.type = OP_MEM;
- c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
- c->src.ptr = (unsigned long *)
- register_address(c, seg_override_base(ctxt, ops, c),
- c->regs[VCPU_REGS_RSI]);
- c->src.val = 0;
- break;
- case SrcImmFAddr:
- c->src.type = OP_IMM;
- c->src.ptr = (unsigned long *)c->eip;
- c->src.bytes = c->op_bytes + 2;
- insn_fetch_arr(c->src.valptr, c->src.bytes, c->eip);
- break;
- case SrcMemFAddr:
- c->src.type = OP_MEM;
- c->src.ptr = (unsigned long *)c->modrm_ea;
- c->src.bytes = c->op_bytes + 2;
- break;
- }
+ long sv = 0, mask;
- /*
- * Decode and fetch the second source operand: register, memory
- * or immediate.
- */
- switch (c->d & Src2Mask) {
- case Src2None:
- break;
- case Src2CL:
- c->src2.bytes = 1;
- c->src2.val = c->regs[VCPU_REGS_RCX] & 0x8;
- break;
- case Src2ImmByte:
- c->src2.type = OP_IMM;
- c->src2.ptr = (unsigned long *)c->eip;
- c->src2.bytes = 1;
- c->src2.val = insn_fetch(u8, 1, c->eip);
- break;
- case Src2One:
- c->src2.bytes = 1;
- c->src2.val = 1;
- break;
- }
+ if (c->dst.type == OP_MEM && c->src.type == OP_REG) {
+ mask = ~(c->dst.bytes * 8 - 1);
- /* Decode and fetch the destination operand: register or memory. */
- switch (c->d & DstMask) {
- case ImplicitOps:
- /* Special instructions do their own operand decoding. */
- return 0;
- case DstReg:
- decode_register_operand(&c->dst, c,
- c->twobyte && (c->b == 0xb6 || c->b == 0xb7));
- break;
- case DstMem:
- case DstMem64:
- if ((c->d & ModRM) && c->modrm_mod == 3) {
- c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
- c->dst.type = OP_REG;
- c->dst.val = c->dst.orig_val = c->modrm_val;
- c->dst.ptr = c->modrm_ptr;
- break;
- }
- c->dst.type = OP_MEM;
- c->dst.ptr = (unsigned long *)c->modrm_ea;
- if ((c->d & DstMask) == DstMem64)
- c->dst.bytes = 8;
- else
- c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
- c->dst.val = 0;
- if (c->d & BitOp) {
- unsigned long mask = ~(c->dst.bytes * 8 - 1);
+ if (c->src.bytes == 2)
+ sv = (s16)c->src.val & (s16)mask;
+ else if (c->src.bytes == 4)
+ sv = (s32)c->src.val & (s32)mask;
- c->dst.ptr = (void *)c->dst.ptr +
- (c->src.val & mask) / 8;
- }
- break;
- case DstAcc:
- c->dst.type = OP_REG;
- c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
- c->dst.ptr = &c->regs[VCPU_REGS_RAX];
- switch (c->dst.bytes) {
- case 1:
- c->dst.val = *(u8 *)c->dst.ptr;
- break;
- case 2:
- c->dst.val = *(u16 *)c->dst.ptr;
- break;
- case 4:
- c->dst.val = *(u32 *)c->dst.ptr;
- break;
- case 8:
- c->dst.val = *(u64 *)c->dst.ptr;
- break;
- }
- c->dst.orig_val = c->dst.val;
- break;
- case DstDI:
- c->dst.type = OP_MEM;
- c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
- c->dst.ptr = (unsigned long *)
- register_address(c, es_base(ctxt, ops),
- c->regs[VCPU_REGS_RDI]);
- c->dst.val = 0;
- break;
+ c->dst.addr.mem += (sv >> 3);
}
-done:
- return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0;
+ /* only subword offset */
+ c->src.val &= (c->dst.bytes << 3) - 1;
}
static int read_emulated(struct x86_emulate_ctxt *ctxt,
@@ -1337,7 +832,7 @@ static int read_emulated(struct x86_emulate_ctxt *ctxt,
rc = ops->read_emulated(addr, mc->data + mc->end, n, &err,
ctxt->vcpu);
if (rc == X86EMUL_PROPAGATE_FAULT)
- emulate_pf(ctxt, addr, err);
+ emulate_pf(ctxt);
if (rc != X86EMUL_CONTINUE)
return rc;
mc->end += n;
@@ -1424,7 +919,7 @@ static int read_segment_descriptor(struct x86_emulate_ctxt *ctxt,
addr = dt.address + index * 8;
ret = ops->read_std(addr, desc, sizeof *desc, ctxt->vcpu, &err);
if (ret == X86EMUL_PROPAGATE_FAULT)
- emulate_pf(ctxt, addr, err);
+ emulate_pf(ctxt);
return ret;
}
@@ -1450,7 +945,7 @@ static int write_segment_descriptor(struct x86_emulate_ctxt *ctxt,
addr = dt.address + index * 8;
ret = ops->write_std(addr, desc, sizeof *desc, ctxt->vcpu, &err);
if (ret == X86EMUL_PROPAGATE_FAULT)
- emulate_pf(ctxt, addr, err);
+ emulate_pf(ctxt);
return ret;
}
@@ -1573,6 +1068,25 @@ exception:
return X86EMUL_PROPAGATE_FAULT;
}
+static void write_register_operand(struct operand *op)
+{
+ /* The 4-byte case *is* correct: in 64-bit mode we zero-extend. */
+ switch (op->bytes) {
+ case 1:
+ *(u8 *)op->addr.reg = (u8)op->val;
+ break;
+ case 2:
+ *(u16 *)op->addr.reg = (u16)op->val;
+ break;
+ case 4:
+ *op->addr.reg = (u32)op->val;
+ break; /* 64b: zero-extend */
+ case 8:
+ *op->addr.reg = op->val;
+ break;
+ }
+}
+
static inline int writeback(struct x86_emulate_ctxt *ctxt,
struct x86_emulate_ops *ops)
{
@@ -1582,28 +1096,12 @@ static inline int writeback(struct x86_emulate_ctxt *ctxt,
switch (c->dst.type) {
case OP_REG:
- /* The 4-byte case *is* correct:
- * in 64-bit mode we zero-extend.
- */
- switch (c->dst.bytes) {
- case 1:
- *(u8 *)c->dst.ptr = (u8)c->dst.val;
- break;
- case 2:
- *(u16 *)c->dst.ptr = (u16)c->dst.val;
- break;
- case 4:
- *c->dst.ptr = (u32)c->dst.val;
- break; /* 64b: zero-ext */
- case 8:
- *c->dst.ptr = c->dst.val;
- break;
- }
+ write_register_operand(&c->dst);
break;
case OP_MEM:
if (c->lock_prefix)
rc = ops->cmpxchg_emulated(
- (unsigned long)c->dst.ptr,
+ c->dst.addr.mem,
&c->dst.orig_val,
&c->dst.val,
c->dst.bytes,
@@ -1611,14 +1109,13 @@ static inline int writeback(struct x86_emulate_ctxt *ctxt,
ctxt->vcpu);
else
rc = ops->write_emulated(
- (unsigned long)c->dst.ptr,
+ c->dst.addr.mem,
&c->dst.val,
c->dst.bytes,
&err,
ctxt->vcpu);
if (rc == X86EMUL_PROPAGATE_FAULT)
- emulate_pf(ctxt,
- (unsigned long)c->dst.ptr, err);
+ emulate_pf(ctxt);
if (rc != X86EMUL_CONTINUE)
return rc;
break;
@@ -1640,8 +1137,8 @@ static inline void emulate_push(struct x86_emulate_ctxt *ctxt,
c->dst.bytes = c->op_bytes;
c->dst.val = c->src.val;
register_address_increment(c, &c->regs[VCPU_REGS_RSP], -c->op_bytes);
- c->dst.ptr = (void *) register_address(c, ss_base(ctxt, ops),
- c->regs[VCPU_REGS_RSP]);
+ c->dst.addr.mem = register_address(c, ss_base(ctxt, ops),
+ c->regs[VCPU_REGS_RSP]);
}
static int emulate_pop(struct x86_emulate_ctxt *ctxt,
@@ -1701,6 +1198,9 @@ static int emulate_popf(struct x86_emulate_ctxt *ctxt,
*(unsigned long *)dest =
(ctxt->eflags & ~change_mask) | (val & change_mask);
+ if (rc == X86EMUL_PROPAGATE_FAULT)
+ emulate_pf(ctxt);
+
return rc;
}
@@ -1778,6 +1278,150 @@ static int emulate_popa(struct x86_emulate_ctxt *ctxt,
return rc;
}
+int emulate_int_real(struct x86_emulate_ctxt *ctxt,
+ struct x86_emulate_ops *ops, int irq)
+{
+ struct decode_cache *c = &ctxt->decode;
+ int rc;
+ struct desc_ptr dt;
+ gva_t cs_addr;
+ gva_t eip_addr;
+ u16 cs, eip;
+ u32 err;
+
+ /* TODO: Add limit checks */
+ c->src.val = ctxt->eflags;
+ emulate_push(ctxt, ops);
+ rc = writeback(ctxt, ops);
+ if (rc != X86EMUL_CONTINUE)
+ return rc;
+
+ ctxt->eflags &= ~(EFLG_IF | EFLG_TF | EFLG_AC);
+
+ c->src.val = ops->get_segment_selector(VCPU_SREG_CS, ctxt->vcpu);
+ emulate_push(ctxt, ops);
+ rc = writeback(ctxt, ops);
+ if (rc != X86EMUL_CONTINUE)
+ return rc;
+
+ c->src.val = c->eip;
+ emulate_push(ctxt, ops);
+ rc = writeback(ctxt, ops);
+ if (rc != X86EMUL_CONTINUE)
+ return rc;
+
+ c->dst.type = OP_NONE;
+
+ ops->get_idt(&dt, ctxt->vcpu);
+
+ eip_addr = dt.address + (irq << 2);
+ cs_addr = dt.address + (irq << 2) + 2;
+
+ rc = ops->read_std(cs_addr, &cs, 2, ctxt->vcpu, &err);
+ if (rc != X86EMUL_CONTINUE)
+ return rc;
+
+ rc = ops->read_std(eip_addr, &eip, 2, ctxt->vcpu, &err);
+ if (rc != X86EMUL_CONTINUE)
+ return rc;
+
+ rc = load_segment_descriptor(ctxt, ops, cs, VCPU_SREG_CS);
+ if (rc != X86EMUL_CONTINUE)
+ return rc;
+
+ c->eip = eip;
+
+ return rc;
+}
+
+static int emulate_int(struct x86_emulate_ctxt *ctxt,
+ struct x86_emulate_ops *ops, int irq)
+{
+ switch(ctxt->mode) {
+ case X86EMUL_MODE_REAL:
+ return emulate_int_real(ctxt, ops, irq);
+ case X86EMUL_MODE_VM86:
+ case X86EMUL_MODE_PROT16:
+ case X86EMUL_MODE_PROT32:
+ case X86EMUL_MODE_PROT64:
+ default:
+ /* Protected mode interrupts unimplemented yet */
+ return X86EMUL_UNHANDLEABLE;
+ }
+}
+
+static int emulate_iret_real(struct x86_emulate_ctxt *ctxt,
+ struct x86_emulate_ops *ops)
+{
+ struct decode_cache *c = &ctxt->decode;
+ int rc = X86EMUL_CONTINUE;
+ unsigned long temp_eip = 0;
+ unsigned long temp_eflags = 0;
+ unsigned long cs = 0;
+ unsigned long mask = EFLG_CF | EFLG_PF | EFLG_AF | EFLG_ZF | EFLG_SF | EFLG_TF |
+ EFLG_IF | EFLG_DF | EFLG_OF | EFLG_IOPL | EFLG_NT | EFLG_RF |
+ EFLG_AC | EFLG_ID | (1 << 1); /* Last one is the reserved bit */
+ unsigned long vm86_mask = EFLG_VM | EFLG_VIF | EFLG_VIP;
+
+ /* TODO: Add stack limit check */
+
+ rc = emulate_pop(ctxt, ops, &temp_eip, c->op_bytes);
+
+ if (rc != X86EMUL_CONTINUE)
+ return rc;
+
+ if (temp_eip & ~0xffff) {
+ emulate_gp(ctxt, 0);
+ return X86EMUL_PROPAGATE_FAULT;
+ }
+
+ rc = emulate_pop(ctxt, ops, &cs, c->op_bytes);
+
+ if (rc != X86EMUL_CONTINUE)
+ return rc;
+
+ rc = emulate_pop(ctxt, ops, &temp_eflags, c->op_bytes);
+
+ if (rc != X86EMUL_CONTINUE)
+ return rc;
+
+ rc = load_segment_descriptor(ctxt, ops, (u16)cs, VCPU_SREG_CS);
+
+ if (rc != X86EMUL_CONTINUE)
+ return rc;
+
+ c->eip = temp_eip;
+
+
+ if (c->op_bytes == 4)
+ ctxt->eflags = ((temp_eflags & mask) | (ctxt->eflags & vm86_mask));
+ else if (c->op_bytes == 2) {
+ ctxt->eflags &= ~0xffff;
+ ctxt->eflags |= temp_eflags;
+ }
+
+ ctxt->eflags &= ~EFLG_RESERVED_ZEROS_MASK; /* Clear reserved zeros */
+ ctxt->eflags |= EFLG_RESERVED_ONE_MASK;
+
+ return rc;
+}
+
+static inline int emulate_iret(struct x86_emulate_ctxt *ctxt,
+ struct x86_emulate_ops* ops)
+{
+ switch(ctxt->mode) {
+ case X86EMUL_MODE_REAL:
+ return emulate_iret_real(ctxt, ops);
+ case X86EMUL_MODE_VM86:
+ case X86EMUL_MODE_PROT16:
+ case X86EMUL_MODE_PROT32:
+ case X86EMUL_MODE_PROT64:
+ default:
+ /* iret from protected mode unimplemented yet */
+ return X86EMUL_UNHANDLEABLE;
+ }
+}
+
static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt,
struct x86_emulate_ops *ops)
{
@@ -1819,6 +1463,9 @@ static inline int emulate_grp3(struct x86_emulate_ctxt *ctxt,
struct x86_emulate_ops *ops)
{
struct decode_cache *c = &ctxt->decode;
+ unsigned long *rax = &c->regs[VCPU_REGS_RAX];
+ unsigned long *rdx = &c->regs[VCPU_REGS_RDX];
+ u8 de = 0;
switch (c->modrm_reg) {
case 0 ... 1: /* test */
@@ -1830,10 +1477,26 @@ static inline int emulate_grp3(struct x86_emulate_ctxt *ctxt,
case 3: /* neg */
emulate_1op("neg", c->dst, ctxt->eflags);
break;
+ case 4: /* mul */
+ emulate_1op_rax_rdx("mul", c->src, *rax, *rdx, ctxt->eflags);
+ break;
+ case 5: /* imul */
+ emulate_1op_rax_rdx("imul", c->src, *rax, *rdx, ctxt->eflags);
+ break;
+ case 6: /* div */
+ emulate_1op_rax_rdx_ex("div", c->src, *rax, *rdx,
+ ctxt->eflags, de);
+ break;
+ case 7: /* idiv */
+ emulate_1op_rax_rdx_ex("idiv", c->src, *rax, *rdx,
+ ctxt->eflags, de);
+ break;
default:
- return 0;
+ return X86EMUL_UNHANDLEABLE;
}
- return 1;
+ if (de)
+ return emulate_de(ctxt);
+ return X86EMUL_CONTINUE;
}
static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt,
@@ -1905,6 +1568,23 @@ static int emulate_ret_far(struct x86_emulate_ctxt *ctxt,
return rc;
}
+static int emulate_load_segment(struct x86_emulate_ctxt *ctxt,
+ struct x86_emulate_ops *ops, int seg)
+{
+ struct decode_cache *c = &ctxt->decode;
+ unsigned short sel;
+ int rc;
+
+ memcpy(&sel, c->src.valptr + c->op_bytes, 2);
+
+ rc = load_segment_descriptor(ctxt, ops, sel, seg);
+ if (rc != X86EMUL_CONTINUE)
+ return rc;
+
+ c->dst.val = c->src.val;
+ return rc;
+}
+
static inline void
setup_syscalls_segments(struct x86_emulate_ctxt *ctxt,
struct x86_emulate_ops *ops, struct desc_struct *cs,
@@ -2160,9 +1840,15 @@ static bool emulator_io_permited(struct x86_emulate_ctxt *ctxt,
struct x86_emulate_ops *ops,
u16 port, u16 len)
{
+ if (ctxt->perm_ok)
+ return true;
+
if (emulator_bad_iopl(ctxt, ops))
if (!emulator_io_port_access_allowed(ctxt, ops, port, len))
return false;
+
+ ctxt->perm_ok = true;
+
return true;
}
@@ -2254,7 +1940,7 @@ static int task_switch_16(struct x86_emulate_ctxt *ctxt,
&err);
if (ret == X86EMUL_PROPAGATE_FAULT) {
/* FIXME: need to provide precise fault address */
- emulate_pf(ctxt, old_tss_base, err);
+ emulate_pf(ctxt);
return ret;
}
@@ -2264,7 +1950,7 @@ static int task_switch_16(struct x86_emulate_ctxt *ctxt,
&err);
if (ret == X86EMUL_PROPAGATE_FAULT) {
/* FIXME: need to provide precise fault address */
- emulate_pf(ctxt, old_tss_base, err);
+ emulate_pf(ctxt);
return ret;
}
@@ -2272,7 +1958,7 @@ static int task_switch_16(struct x86_emulate_ctxt *ctxt,
&err);
if (ret == X86EMUL_PROPAGATE_FAULT) {
/* FIXME: need to provide precise fault address */
- emulate_pf(ctxt, new_tss_base, err);
+ emulate_pf(ctxt);
return ret;
}
@@ -2285,7 +1971,7 @@ static int task_switch_16(struct x86_emulate_ctxt *ctxt,
ctxt->vcpu, &err);
if (ret == X86EMUL_PROPAGATE_FAULT) {
/* FIXME: need to provide precise fault address */
- emulate_pf(ctxt, new_tss_base, err);
+ emulate_pf(ctxt);
return ret;
}
}
@@ -2396,7 +2082,7 @@ static int task_switch_32(struct x86_emulate_ctxt *ctxt,
&err);
if (ret == X86EMUL_PROPAGATE_FAULT) {
/* FIXME: need to provide precise fault address */
- emulate_pf(ctxt, old_tss_base, err);
+ emulate_pf(ctxt);
return ret;
}
@@ -2406,7 +2092,7 @@ static int task_switch_32(struct x86_emulate_ctxt *ctxt,
&err);
if (ret == X86EMUL_PROPAGATE_FAULT) {
/* FIXME: need to provide precise fault address */
- emulate_pf(ctxt, old_tss_base, err);
+ emulate_pf(ctxt);
return ret;
}
@@ -2414,7 +2100,7 @@ static int task_switch_32(struct x86_emulate_ctxt *ctxt,
&err);
if (ret == X86EMUL_PROPAGATE_FAULT) {
/* FIXME: need to provide precise fault address */
- emulate_pf(ctxt, new_tss_base, err);
+ emulate_pf(ctxt);
return ret;
}
@@ -2427,7 +2113,7 @@ static int task_switch_32(struct x86_emulate_ctxt *ctxt,
ctxt->vcpu, &err);
if (ret == X86EMUL_PROPAGATE_FAULT) {
/* FIXME: need to provide precise fault address */
- emulate_pf(ctxt, new_tss_base, err);
+ emulate_pf(ctxt);
return ret;
}
}
@@ -2523,10 +2209,10 @@ static int emulator_do_task_switch(struct x86_emulate_ctxt *ctxt,
}
int emulator_task_switch(struct x86_emulate_ctxt *ctxt,
- struct x86_emulate_ops *ops,
u16 tss_selector, int reason,
bool has_error_code, u32 error_code)
{
+ struct x86_emulate_ops *ops = ctxt->ops;
struct decode_cache *c = &ctxt->decode;
int rc;
@@ -2552,16 +2238,784 @@ static void string_addr_inc(struct x86_emulate_ctxt *ctxt, unsigned long base,
int df = (ctxt->eflags & EFLG_DF) ? -1 : 1;
register_address_increment(c, &c->regs[reg], df * op->bytes);
- op->ptr = (unsigned long *)register_address(c, base, c->regs[reg]);
+ op->addr.mem = register_address(c, base, c->regs[reg]);
+}
+
+static int em_push(struct x86_emulate_ctxt *ctxt)
+{
+ emulate_push(ctxt, ctxt->ops);
+ return X86EMUL_CONTINUE;
+}
+
+static int em_das(struct x86_emulate_ctxt *ctxt)
+{
+ struct decode_cache *c = &ctxt->decode;
+ u8 al, old_al;
+ bool af, cf, old_cf;
+
+ cf = ctxt->eflags & X86_EFLAGS_CF;
+ al = c->dst.val;
+
+ old_al = al;
+ old_cf = cf;
+ cf = false;
+ af = ctxt->eflags & X86_EFLAGS_AF;
+ if ((al & 0x0f) > 9 || af) {
+ al -= 6;
+ cf = old_cf | (al >= 250);
+ af = true;
+ } else {
+ af = false;
+ }
+ if (old_al > 0x99 || old_cf) {
+ al -= 0x60;
+ cf = true;
+ }
+
+ c->dst.val = al;
+ /* Set PF, ZF, SF */
+ c->src.type = OP_IMM;
+ c->src.val = 0;
+ c->src.bytes = 1;
+ emulate_2op_SrcV("or", c->src, c->dst, ctxt->eflags);
+ ctxt->eflags &= ~(X86_EFLAGS_AF | X86_EFLAGS_CF);
+ if (cf)
+ ctxt->eflags |= X86_EFLAGS_CF;
+ if (af)
+ ctxt->eflags |= X86_EFLAGS_AF;
+ return X86EMUL_CONTINUE;
+}
+
+static int em_call_far(struct x86_emulate_ctxt *ctxt)
+{
+ struct decode_cache *c = &ctxt->decode;
+ u16 sel, old_cs;
+ ulong old_eip;
+ int rc;
+
+ old_cs = ctxt->ops->get_segment_selector(VCPU_SREG_CS, ctxt->vcpu);
+ old_eip = c->eip;
+
+ memcpy(&sel, c->src.valptr + c->op_bytes, 2);
+ if (load_segment_descriptor(ctxt, ctxt->ops, sel, VCPU_SREG_CS))
+ return X86EMUL_CONTINUE;
+
+ c->eip = 0;
+ memcpy(&c->eip, c->src.valptr, c->op_bytes);
+
+ c->src.val = old_cs;
+ emulate_push(ctxt, ctxt->ops);
+ rc = writeback(ctxt, ctxt->ops);
+ if (rc != X86EMUL_CONTINUE)
+ return rc;
+
+ c->src.val = old_eip;
+ emulate_push(ctxt, ctxt->ops);
+ rc = writeback(ctxt, ctxt->ops);
+ if (rc != X86EMUL_CONTINUE)
+ return rc;
+
+ c->dst.type = OP_NONE;
+
+ return X86EMUL_CONTINUE;
+}
+
+static int em_ret_near_imm(struct x86_emulate_ctxt *ctxt)
+{
+ struct decode_cache *c = &ctxt->decode;
+ int rc;
+
+ c->dst.type = OP_REG;
+ c->dst.addr.reg = &c->eip;
+ c->dst.bytes = c->op_bytes;
+ rc = emulate_pop(ctxt, ctxt->ops, &c->dst.val, c->op_bytes);
+ if (rc != X86EMUL_CONTINUE)
+ return rc;
+ register_address_increment(c, &c->regs[VCPU_REGS_RSP], c->src.val);
+ return X86EMUL_CONTINUE;
+}
+
+static int em_imul(struct x86_emulate_ctxt *ctxt)
+{
+ struct decode_cache *c = &ctxt->decode;
+
+ emulate_2op_SrcV_nobyte("imul", c->src, c->dst, ctxt->eflags);
+ return X86EMUL_CONTINUE;
+}
+
+static int em_imul_3op(struct x86_emulate_ctxt *ctxt)
+{
+ struct decode_cache *c = &ctxt->decode;
+
+ c->dst.val = c->src2.val;
+ return em_imul(ctxt);
+}
+
+static int em_cwd(struct x86_emulate_ctxt *ctxt)
+{
+ struct decode_cache *c = &ctxt->decode;
+
+ c->dst.type = OP_REG;
+ c->dst.bytes = c->src.bytes;
+ c->dst.addr.reg = &c->regs[VCPU_REGS_RDX];
+ c->dst.val = ~((c->src.val >> (c->src.bytes * 8 - 1)) - 1);
+
+ return X86EMUL_CONTINUE;
+}
+
+static int em_rdtsc(struct x86_emulate_ctxt *ctxt)
+{
+ unsigned cpl = ctxt->ops->cpl(ctxt->vcpu);
+ struct decode_cache *c = &ctxt->decode;
+ u64 tsc = 0;
+
+ if (cpl > 0 && (ctxt->ops->get_cr(4, ctxt->vcpu) & X86_CR4_TSD)) {
+ emulate_gp(ctxt, 0);
+ return X86EMUL_PROPAGATE_FAULT;
+ }
+ ctxt->ops->get_msr(ctxt->vcpu, MSR_IA32_TSC, &tsc);
+ c->regs[VCPU_REGS_RAX] = (u32)tsc;
+ c->regs[VCPU_REGS_RDX] = tsc >> 32;
+ return X86EMUL_CONTINUE;
+}
+
+static int em_mov(struct x86_emulate_ctxt *ctxt)
+{
+ struct decode_cache *c = &ctxt->decode;
+ c->dst.val = c->src.val;
+ return X86EMUL_CONTINUE;
+}
+
+#define D(_y) { .flags = (_y) }
+#define N D(0)
+#define G(_f, _g) { .flags = ((_f) | Group), .u.group = (_g) }
+#define GD(_f, _g) { .flags = ((_f) | Group | GroupDual), .u.gdual = (_g) }
+#define I(_f, _e) { .flags = (_f), .u.execute = (_e) }
+
+#define D2bv(_f) D((_f) | ByteOp), D(_f)
+#define I2bv(_f, _e) I((_f) | ByteOp, _e), I(_f, _e)
+
+#define D6ALU(_f) D2bv((_f) | DstMem | SrcReg | ModRM), \
+ D2bv(((_f) | DstReg | SrcMem | ModRM) & ~Lock), \
+ D2bv(((_f) & ~Lock) | DstAcc | SrcImm)
+
+
+static struct opcode group1[] = {
+ X7(D(Lock)), N
+};
+
+static struct opcode group1A[] = {
+ D(DstMem | SrcNone | ModRM | Mov | Stack), N, N, N, N, N, N, N,
+};
+
+static struct opcode group3[] = {
+ D(DstMem | SrcImm | ModRM), D(DstMem | SrcImm | ModRM),
+ D(DstMem | SrcNone | ModRM | Lock), D(DstMem | SrcNone | ModRM | Lock),
+ X4(D(SrcMem | ModRM)),
+};
+
+static struct opcode group4[] = {
+ D(ByteOp | DstMem | SrcNone | ModRM | Lock), D(ByteOp | DstMem | SrcNone | ModRM | Lock),
+ N, N, N, N, N, N,
+};
+
+static struct opcode group5[] = {
+ D(DstMem | SrcNone | ModRM | Lock), D(DstMem | SrcNone | ModRM | Lock),
+ D(SrcMem | ModRM | Stack),
+ I(SrcMemFAddr | ModRM | ImplicitOps | Stack, em_call_far),
+ D(SrcMem | ModRM | Stack), D(SrcMemFAddr | ModRM | ImplicitOps),
+ D(SrcMem | ModRM | Stack), N,
+};
+
+static struct group_dual group7 = { {
+ N, N, D(ModRM | SrcMem | Priv), D(ModRM | SrcMem | Priv),
+ D(SrcNone | ModRM | DstMem | Mov), N,
+ D(SrcMem16 | ModRM | Mov | Priv),
+ D(SrcMem | ModRM | ByteOp | Priv | NoAccess),
+}, {
+ D(SrcNone | ModRM | Priv), N, N, D(SrcNone | ModRM | Priv),
+ D(SrcNone | ModRM | DstMem | Mov), N,
+ D(SrcMem16 | ModRM | Mov | Priv), N,
+} };
+
+static struct opcode group8[] = {
+ N, N, N, N,
+ D(DstMem | SrcImmByte | ModRM), D(DstMem | SrcImmByte | ModRM | Lock),
+ D(DstMem | SrcImmByte | ModRM | Lock), D(DstMem | SrcImmByte | ModRM | Lock),
+};
+
+static struct group_dual group9 = { {
+ N, D(DstMem64 | ModRM | Lock), N, N, N, N, N, N,
+}, {
+ N, N, N, N, N, N, N, N,
+} };
+
+static struct opcode group11[] = {
+ I(DstMem | SrcImm | ModRM | Mov, em_mov), X7(D(Undefined)),
+};
+
+static struct opcode opcode_table[256] = {
+ /* 0x00 - 0x07 */
+ D6ALU(Lock),
+ D(ImplicitOps | Stack | No64), D(ImplicitOps | Stack | No64),
+ /* 0x08 - 0x0F */
+ D6ALU(Lock),
+ D(ImplicitOps | Stack | No64), N,
+ /* 0x10 - 0x17 */
+ D6ALU(Lock),
+ D(ImplicitOps | Stack | No64), D(ImplicitOps | Stack | No64),
+ /* 0x18 - 0x1F */
+ D6ALU(Lock),
+ D(ImplicitOps | Stack | No64), D(ImplicitOps | Stack | No64),
+ /* 0x20 - 0x27 */
+ D6ALU(Lock), N, N,
+ /* 0x28 - 0x2F */
+ D6ALU(Lock), N, I(ByteOp | DstAcc | No64, em_das),
+ /* 0x30 - 0x37 */
+ D6ALU(Lock), N, N,
+ /* 0x38 - 0x3F */
+ D6ALU(0), N, N,
+ /* 0x40 - 0x4F */
+ X16(D(DstReg)),
+ /* 0x50 - 0x57 */
+ X8(I(SrcReg | Stack, em_push)),
+ /* 0x58 - 0x5F */
+ X8(D(DstReg | Stack)),
+ /* 0x60 - 0x67 */
+ D(ImplicitOps | Stack | No64), D(ImplicitOps | Stack | No64),
+ N, D(DstReg | SrcMem32 | ModRM | Mov) /* movsxd (x86/64) */ ,
+ N, N, N, N,
+ /* 0x68 - 0x6F */
+ I(SrcImm | Mov | Stack, em_push),
+ I(DstReg | SrcMem | ModRM | Src2Imm, em_imul_3op),
+ I(SrcImmByte | Mov | Stack, em_push),
+ I(DstReg | SrcMem | ModRM | Src2ImmByte, em_imul_3op),
+ D2bv(DstDI | Mov | String), /* insb, insw/insd */
+ D2bv(SrcSI | ImplicitOps | String), /* outsb, outsw/outsd */
+ /* 0x70 - 0x7F */
+ X16(D(SrcImmByte)),
+ /* 0x80 - 0x87 */
+ G(ByteOp | DstMem | SrcImm | ModRM | Group, group1),
+ G(DstMem | SrcImm | ModRM | Group, group1),
+ G(ByteOp | DstMem | SrcImm | ModRM | No64 | Group, group1),
+ G(DstMem | SrcImmByte | ModRM | Group, group1),
+ D2bv(DstMem | SrcReg | ModRM), D2bv(DstMem | SrcReg | ModRM | Lock),
+ /* 0x88 - 0x8F */
+ I2bv(DstMem | SrcReg | ModRM | Mov, em_mov),
+ I2bv(DstReg | SrcMem | ModRM | Mov, em_mov),
+ D(DstMem | SrcNone | ModRM | Mov), D(ModRM | SrcMem | NoAccess | DstReg),
+ D(ImplicitOps | SrcMem16 | ModRM), G(0, group1A),
+ /* 0x90 - 0x97 */
+ X8(D(SrcAcc | DstReg)),
+ /* 0x98 - 0x9F */
+ D(DstAcc | SrcNone), I(ImplicitOps | SrcAcc, em_cwd),
+ I(SrcImmFAddr | No64, em_call_far), N,
+ D(ImplicitOps | Stack), D(ImplicitOps | Stack), N, N,
+ /* 0xA0 - 0xA7 */
+ I2bv(DstAcc | SrcMem | Mov | MemAbs, em_mov),
+ I2bv(DstMem | SrcAcc | Mov | MemAbs, em_mov),
+ I2bv(SrcSI | DstDI | Mov | String, em_mov),
+ D2bv(SrcSI | DstDI | String),
+ /* 0xA8 - 0xAF */
+ D2bv(DstAcc | SrcImm),
+ I2bv(SrcAcc | DstDI | Mov | String, em_mov),
+ I2bv(SrcSI | DstAcc | Mov | String, em_mov),
+ D2bv(SrcAcc | DstDI | String),
+ /* 0xB0 - 0xB7 */
+ X8(I(ByteOp | DstReg | SrcImm | Mov, em_mov)),
+ /* 0xB8 - 0xBF */
+ X8(I(DstReg | SrcImm | Mov, em_mov)),
+ /* 0xC0 - 0xC7 */
+ D2bv(DstMem | SrcImmByte | ModRM),
+ I(ImplicitOps | Stack | SrcImmU16, em_ret_near_imm),
+ D(ImplicitOps | Stack),
+ D(DstReg | SrcMemFAddr | ModRM | No64), D(DstReg | SrcMemFAddr | ModRM | No64),
+ G(ByteOp, group11), G(0, group11),
+ /* 0xC8 - 0xCF */
+ N, N, N, D(ImplicitOps | Stack),
+ D(ImplicitOps), D(SrcImmByte), D(ImplicitOps | No64), D(ImplicitOps),
+ /* 0xD0 - 0xD7 */
+ D2bv(DstMem | SrcOne | ModRM), D2bv(DstMem | ModRM),
+ N, N, N, N,
+ /* 0xD8 - 0xDF */
+ N, N, N, N, N, N, N, N,
+ /* 0xE0 - 0xE7 */
+ X4(D(SrcImmByte)),
+ D2bv(SrcImmUByte | DstAcc), D2bv(SrcAcc | DstImmUByte),
+ /* 0xE8 - 0xEF */
+ D(SrcImm | Stack), D(SrcImm | ImplicitOps),
+ D(SrcImmFAddr | No64), D(SrcImmByte | ImplicitOps),
+ D2bv(SrcNone | DstAcc), D2bv(SrcAcc | ImplicitOps),
+ /* 0xF0 - 0xF7 */
+ N, N, N, N,
+ D(ImplicitOps | Priv), D(ImplicitOps), G(ByteOp, group3), G(0, group3),
+ /* 0xF8 - 0xFF */
+ D(ImplicitOps), D(ImplicitOps), D(ImplicitOps), D(ImplicitOps),
+ D(ImplicitOps), D(ImplicitOps), G(0, group4), G(0, group5),
+};
+
+static struct opcode twobyte_table[256] = {
+ /* 0x00 - 0x0F */
+ N, GD(0, &group7), N, N,
+ N, D(ImplicitOps), D(ImplicitOps | Priv), N,
+ D(ImplicitOps | Priv), D(ImplicitOps | Priv), N, N,
+ N, D(ImplicitOps | ModRM), N, N,
+ /* 0x10 - 0x1F */
+ N, N, N, N, N, N, N, N, D(ImplicitOps | ModRM), N, N, N, N, N, N, N,
+ /* 0x20 - 0x2F */
+ D(ModRM | DstMem | Priv | Op3264), D(ModRM | DstMem | Priv | Op3264),
+ D(ModRM | SrcMem | Priv | Op3264), D(ModRM | SrcMem | Priv | Op3264),
+ N, N, N, N,
+ N, N, N, N, N, N, N, N,
+ /* 0x30 - 0x3F */
+ D(ImplicitOps | Priv), I(ImplicitOps, em_rdtsc),
+ D(ImplicitOps | Priv), N,
+ D(ImplicitOps), D(ImplicitOps | Priv), N, N,
+ N, N, N, N, N, N, N, N,
+ /* 0x40 - 0x4F */
+ X16(D(DstReg | SrcMem | ModRM | Mov)),
+ /* 0x50 - 0x5F */
+ N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
+ /* 0x60 - 0x6F */
+ N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
+ /* 0x70 - 0x7F */
+ N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
+ /* 0x80 - 0x8F */
+ X16(D(SrcImm)),
+ /* 0x90 - 0x9F */
+ X16(D(ByteOp | DstMem | SrcNone | ModRM| Mov)),
+ /* 0xA0 - 0xA7 */
+ D(ImplicitOps | Stack), D(ImplicitOps | Stack),
+ N, D(DstMem | SrcReg | ModRM | BitOp),
+ D(DstMem | SrcReg | Src2ImmByte | ModRM),
+ D(DstMem | SrcReg | Src2CL | ModRM), N, N,
+ /* 0xA8 - 0xAF */
+ D(ImplicitOps | Stack), D(ImplicitOps | Stack),
+ N, D(DstMem | SrcReg | ModRM | BitOp | Lock),
+ D(DstMem | SrcReg | Src2ImmByte | ModRM),
+ D(DstMem | SrcReg | Src2CL | ModRM),
+ D(ModRM), I(DstReg | SrcMem | ModRM, em_imul),
+ /* 0xB0 - 0xB7 */
+ D2bv(DstMem | SrcReg | ModRM | Lock),
+ D(DstReg | SrcMemFAddr | ModRM), D(DstMem | SrcReg | ModRM | BitOp | Lock),
+ D(DstReg | SrcMemFAddr | ModRM), D(DstReg | SrcMemFAddr | ModRM),
+ D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov),
+ /* 0xB8 - 0xBF */
+ N, N,
+ G(BitOp, group8), D(DstMem | SrcReg | ModRM | BitOp | Lock),
+ D(DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
+ D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov),
+ /* 0xC0 - 0xCF */
+ D2bv(DstMem | SrcReg | ModRM | Lock),
+ N, D(DstMem | SrcReg | ModRM | Mov),
+ N, N, N, GD(0, &group9),
+ N, N, N, N, N, N, N, N,
+ /* 0xD0 - 0xDF */
+ N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
+ /* 0xE0 - 0xEF */
+ N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
+ /* 0xF0 - 0xFF */
+ N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N
+};
+
+#undef D
+#undef N
+#undef G
+#undef GD
+#undef I
+
+#undef D2bv
+#undef I2bv
+#undef D6ALU
+
+static unsigned imm_size(struct decode_cache *c)
+{
+ unsigned size;
+
+ size = (c->d & ByteOp) ? 1 : c->op_bytes;
+ if (size == 8)
+ size = 4;
+ return size;
+}
+
+static int decode_imm(struct x86_emulate_ctxt *ctxt, struct operand *op,
+ unsigned size, bool sign_extension)
+{
+ struct decode_cache *c = &ctxt->decode;
+ struct x86_emulate_ops *ops = ctxt->ops;
+ int rc = X86EMUL_CONTINUE;
+
+ op->type = OP_IMM;
+ op->bytes = size;
+ op->addr.mem = c->eip;
+ /* NB. Immediates are sign-extended as necessary. */
+ switch (op->bytes) {
+ case 1:
+ op->val = insn_fetch(s8, 1, c->eip);
+ break;
+ case 2:
+ op->val = insn_fetch(s16, 2, c->eip);
+ break;
+ case 4:
+ op->val = insn_fetch(s32, 4, c->eip);
+ break;
+ }
+ if (!sign_extension) {
+ switch (op->bytes) {
+ case 1:
+ op->val &= 0xff;
+ break;
+ case 2:
+ op->val &= 0xffff;
+ break;
+ case 4:
+ op->val &= 0xffffffff;
+ break;
+ }
+ }
+done:
+ return rc;
}
int
-x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
+x86_decode_insn(struct x86_emulate_ctxt *ctxt)
{
+ struct x86_emulate_ops *ops = ctxt->ops;
+ struct decode_cache *c = &ctxt->decode;
+ int rc = X86EMUL_CONTINUE;
+ int mode = ctxt->mode;
+ int def_op_bytes, def_ad_bytes, dual, goffset;
+ struct opcode opcode, *g_mod012, *g_mod3;
+ struct operand memop = { .type = OP_NONE };
+
+ c->eip = ctxt->eip;
+ c->fetch.start = c->fetch.end = c->eip;
+ ctxt->cs_base = seg_base(ctxt, ops, VCPU_SREG_CS);
+
+ switch (mode) {
+ case X86EMUL_MODE_REAL:
+ case X86EMUL_MODE_VM86:
+ case X86EMUL_MODE_PROT16:
+ def_op_bytes = def_ad_bytes = 2;
+ break;
+ case X86EMUL_MODE_PROT32:
+ def_op_bytes = def_ad_bytes = 4;
+ break;
+#ifdef CONFIG_X86_64
+ case X86EMUL_MODE_PROT64:
+ def_op_bytes = 4;
+ def_ad_bytes = 8;
+ break;
+#endif
+ default:
+ return -1;
+ }
+
+ c->op_bytes = def_op_bytes;
+ c->ad_bytes = def_ad_bytes;
+
+ /* Legacy prefixes. */
+ for (;;) {
+ switch (c->b = insn_fetch(u8, 1, c->eip)) {
+ case 0x66: /* operand-size override */
+ /* switch between 2/4 bytes */
+ c->op_bytes = def_op_bytes ^ 6;
+ break;
+ case 0x67: /* address-size override */
+ if (mode == X86EMUL_MODE_PROT64)
+ /* switch between 4/8 bytes */
+ c->ad_bytes = def_ad_bytes ^ 12;
+ else
+ /* switch between 2/4 bytes */
+ c->ad_bytes = def_ad_bytes ^ 6;
+ break;
+ case 0x26: /* ES override */
+ case 0x2e: /* CS override */
+ case 0x36: /* SS override */
+ case 0x3e: /* DS override */
+ set_seg_override(c, (c->b >> 3) & 3);
+ break;
+ case 0x64: /* FS override */
+ case 0x65: /* GS override */
+ set_seg_override(c, c->b & 7);
+ break;
+ case 0x40 ... 0x4f: /* REX */
+ if (mode != X86EMUL_MODE_PROT64)
+ goto done_prefixes;
+ c->rex_prefix = c->b;
+ continue;
+ case 0xf0: /* LOCK */
+ c->lock_prefix = 1;
+ break;
+ case 0xf2: /* REPNE/REPNZ */
+ c->rep_prefix = REPNE_PREFIX;
+ break;
+ case 0xf3: /* REP/REPE/REPZ */
+ c->rep_prefix = REPE_PREFIX;
+ break;
+ default:
+ goto done_prefixes;
+ }
+
+ /* Any legacy prefix after a REX prefix nullifies its effect. */
+
+ c->rex_prefix = 0;
+ }
+
+done_prefixes:
+
+ /* REX prefix. */
+ if (c->rex_prefix & 8)
+ c->op_bytes = 8; /* REX.W */
+
+ /* Opcode byte(s). */
+ opcode = opcode_table[c->b];
+ /* Two-byte opcode? */
+ if (c->b == 0x0f) {
+ c->twobyte = 1;
+ c->b = insn_fetch(u8, 1, c->eip);
+ opcode = twobyte_table[c->b];
+ }
+ c->d = opcode.flags;
+
+ if (c->d & Group) {
+ dual = c->d & GroupDual;
+ c->modrm = insn_fetch(u8, 1, c->eip);
+ --c->eip;
+
+ if (c->d & GroupDual) {
+ g_mod012 = opcode.u.gdual->mod012;
+ g_mod3 = opcode.u.gdual->mod3;
+ } else
+ g_mod012 = g_mod3 = opcode.u.group;
+
+ c->d &= ~(Group | GroupDual);
+
+ goffset = (c->modrm >> 3) & 7;
+
+ if ((c->modrm >> 6) == 3)
+ opcode = g_mod3[goffset];
+ else
+ opcode = g_mod012[goffset];
+ c->d |= opcode.flags;
+ }
+
+ c->execute = opcode.u.execute;
+
+ /* Unrecognised? */
+ if (c->d == 0 || (c->d & Undefined)) {
+ DPRINTF("Cannot emulate %02x\n", c->b);
+ return -1;
+ }
+
+ if (mode == X86EMUL_MODE_PROT64 && (c->d & Stack))
+ c->op_bytes = 8;
+
+ if (c->d & Op3264) {
+ if (mode == X86EMUL_MODE_PROT64)
+ c->op_bytes = 8;
+ else
+ c->op_bytes = 4;
+ }
+
+ /* ModRM and SIB bytes. */
+ if (c->d & ModRM) {
+ rc = decode_modrm(ctxt, ops, &memop);
+ if (!c->has_seg_override)
+ set_seg_override(c, c->modrm_seg);
+ } else if (c->d & MemAbs)
+ rc = decode_abs(ctxt, ops, &memop);
+ if (rc != X86EMUL_CONTINUE)
+ goto done;
+
+ if (!c->has_seg_override)
+ set_seg_override(c, VCPU_SREG_DS);
+
+ if (memop.type == OP_MEM && !(!c->twobyte && c->b == 0x8d))
+ memop.addr.mem += seg_override_base(ctxt, ops, c);
+
+ if (memop.type == OP_MEM && c->ad_bytes != 8)
+ memop.addr.mem = (u32)memop.addr.mem;
+
+ if (memop.type == OP_MEM && c->rip_relative)
+ memop.addr.mem += c->eip;
+
+ /*
+ * Decode and fetch the source operand: register, memory
+ * or immediate.
+ */
+ switch (c->d & SrcMask) {
+ case SrcNone:
+ break;
+ case SrcReg:
+ decode_register_operand(&c->src, c, 0);
+ break;
+ case SrcMem16:
+ memop.bytes = 2;
+ goto srcmem_common;
+ case SrcMem32:
+ memop.bytes = 4;
+ goto srcmem_common;
+ case SrcMem:
+ memop.bytes = (c->d & ByteOp) ? 1 :
+ c->op_bytes;
+ srcmem_common:
+ c->src = memop;
+ break;
+ case SrcImmU16:
+ rc = decode_imm(ctxt, &c->src, 2, false);
+ break;
+ case SrcImm:
+ rc = decode_imm(ctxt, &c->src, imm_size(c), true);
+ break;
+ case SrcImmU:
+ rc = decode_imm(ctxt, &c->src, imm_size(c), false);
+ break;
+ case SrcImmByte:
+ rc = decode_imm(ctxt, &c->src, 1, true);
+ break;
+ case SrcImmUByte:
+ rc = decode_imm(ctxt, &c->src, 1, false);
+ break;
+ case SrcAcc:
+ c->src.type = OP_REG;
+ c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
+ c->src.addr.reg = &c->regs[VCPU_REGS_RAX];
+ fetch_register_operand(&c->src);
+ break;
+ case SrcOne:
+ c->src.bytes = 1;
+ c->src.val = 1;
+ break;
+ case SrcSI:
+ c->src.type = OP_MEM;
+ c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
+ c->src.addr.mem =
+ register_address(c, seg_override_base(ctxt, ops, c),
+ c->regs[VCPU_REGS_RSI]);
+ c->src.val = 0;
+ break;
+ case SrcImmFAddr:
+ c->src.type = OP_IMM;
+ c->src.addr.mem = c->eip;
+ c->src.bytes = c->op_bytes + 2;
+ insn_fetch_arr(c->src.valptr, c->src.bytes, c->eip);
+ break;
+ case SrcMemFAddr:
+ memop.bytes = c->op_bytes + 2;
+ goto srcmem_common;
+ break;
+ }
+
+ if (rc != X86EMUL_CONTINUE)
+ goto done;
+
+ /*
+ * Decode and fetch the second source operand: register, memory
+ * or immediate.
+ */
+ switch (c->d & Src2Mask) {
+ case Src2None:
+ break;
+ case Src2CL:
+ c->src2.bytes = 1;
+ c->src2.val = c->regs[VCPU_REGS_RCX] & 0x8;
+ break;
+ case Src2ImmByte:
+ rc = decode_imm(ctxt, &c->src2, 1, true);
+ break;
+ case Src2One:
+ c->src2.bytes = 1;
+ c->src2.val = 1;
+ break;
+ case Src2Imm:
+ rc = decode_imm(ctxt, &c->src2, imm_size(c), true);
+ break;
+ }
+
+ if (rc != X86EMUL_CONTINUE)
+ goto done;
+
+ /* Decode and fetch the destination operand: register or memory. */
+ switch (c->d & DstMask) {
+ case DstReg:
+ decode_register_operand(&c->dst, c,
+ c->twobyte && (c->b == 0xb6 || c->b == 0xb7));
+ break;
+ case DstImmUByte:
+ c->dst.type = OP_IMM;
+ c->dst.addr.mem = c->eip;
+ c->dst.bytes = 1;
+ c->dst.val = insn_fetch(u8, 1, c->eip);
+ break;
+ case DstMem:
+ case DstMem64:
+ c->dst = memop;
+ if ((c->d & DstMask) == DstMem64)
+ c->dst.bytes = 8;
+ else
+ c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
+ if (c->d & BitOp)
+ fetch_bit_operand(c);
+ c->dst.orig_val = c->dst.val;
+ break;
+ case DstAcc:
+ c->dst.type = OP_REG;
+ c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
+ c->dst.addr.reg = &c->regs[VCPU_REGS_RAX];
+ fetch_register_operand(&c->dst);
+ c->dst.orig_val = c->dst.val;
+ break;
+ case DstDI:
+ c->dst.type = OP_MEM;
+ c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
+ c->dst.addr.mem =
+ register_address(c, es_base(ctxt, ops),
+ c->regs[VCPU_REGS_RDI]);
+ c->dst.val = 0;
+ break;
+ case ImplicitOps:
+ /* Special instructions do their own operand decoding. */
+ default:
+ c->dst.type = OP_NONE; /* Disable writeback. */
+ return 0;
+ }
+
+done:
+ return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0;
+}
+
+static bool string_insn_completed(struct x86_emulate_ctxt *ctxt)
+{
+ struct decode_cache *c = &ctxt->decode;
+
+ /* The second termination condition only applies for REPE
+ * and REPNE. Test if the repeat string operation prefix is
+ * REPE/REPZ or REPNE/REPNZ and if it's the case it tests the
+ * corresponding termination condition according to:
+ * - if REPE/REPZ and ZF = 0 then done
+ * - if REPNE/REPNZ and ZF = 1 then done
+ */
+ if (((c->b == 0xa6) || (c->b == 0xa7) ||
+ (c->b == 0xae) || (c->b == 0xaf))
+ && (((c->rep_prefix == REPE_PREFIX) &&
+ ((ctxt->eflags & EFLG_ZF) == 0))
+ || ((c->rep_prefix == REPNE_PREFIX) &&
+ ((ctxt->eflags & EFLG_ZF) == EFLG_ZF))))
+ return true;
+
+ return false;
+}
+
+int
+x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
+{
+ struct x86_emulate_ops *ops = ctxt->ops;
u64 msr_data;
struct decode_cache *c = &ctxt->decode;
int rc = X86EMUL_CONTINUE;
int saved_dst_type = c->dst.type;
+ int irq; /* Used for int 3, int, and into */
ctxt->decode.mem_read.pos = 0;
@@ -2576,6 +3030,11 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
goto done;
}
+ if ((c->d & SrcMask) == SrcMemFAddr && c->src.type != OP_MEM) {
+ emulate_ud(ctxt);
+ goto done;
+ }
+
/* Privileged instruction can be executed only in CPL=0 */
if ((c->d & Priv) && ops->cpl(ctxt->vcpu)) {
emulate_gp(ctxt, 0);
@@ -2583,35 +3042,15 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
}
if (c->rep_prefix && (c->d & String)) {
- ctxt->restart = true;
/* All REP prefixes have the same first termination condition */
if (address_mask(c, c->regs[VCPU_REGS_RCX]) == 0) {
- string_done:
- ctxt->restart = false;
ctxt->eip = c->eip;
goto done;
}
- /* The second termination condition only applies for REPE
- * and REPNE. Test if the repeat string operation prefix is
- * REPE/REPZ or REPNE/REPNZ and if it's the case it tests the
- * corresponding termination condition according to:
- * - if REPE/REPZ and ZF = 0 then done
- * - if REPNE/REPNZ and ZF = 1 then done
- */
- if ((c->b == 0xa6) || (c->b == 0xa7) ||
- (c->b == 0xae) || (c->b == 0xaf)) {
- if ((c->rep_prefix == REPE_PREFIX) &&
- ((ctxt->eflags & EFLG_ZF) == 0))
- goto string_done;
- if ((c->rep_prefix == REPNE_PREFIX) &&
- ((ctxt->eflags & EFLG_ZF) == EFLG_ZF))
- goto string_done;
- }
- c->eip = ctxt->eip;
}
- if (c->src.type == OP_MEM) {
- rc = read_emulated(ctxt, ops, (unsigned long)c->src.ptr,
+ if ((c->src.type == OP_MEM) && !(c->d & NoAccess)) {
+ rc = read_emulated(ctxt, ops, c->src.addr.mem,
c->src.valptr, c->src.bytes);
if (rc != X86EMUL_CONTINUE)
goto done;
@@ -2619,7 +3058,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
}
if (c->src2.type == OP_MEM) {
- rc = read_emulated(ctxt, ops, (unsigned long)c->src2.ptr,
+ rc = read_emulated(ctxt, ops, c->src2.addr.mem,
&c->src2.val, c->src2.bytes);
if (rc != X86EMUL_CONTINUE)
goto done;
@@ -2631,7 +3070,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
if ((c->dst.type == OP_MEM) && !(c->d & Mov)) {
/* optimisation - avoid slow emulated read if Mov */
- rc = read_emulated(ctxt, ops, (unsigned long)c->dst.ptr,
+ rc = read_emulated(ctxt, ops, c->dst.addr.mem,
&c->dst.val, c->dst.bytes);
if (rc != X86EMUL_CONTINUE)
goto done;
@@ -2640,6 +3079,13 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
special_insn:
+ if (c->execute) {
+ rc = c->execute(ctxt);
+ if (rc != X86EMUL_CONTINUE)
+ goto done;
+ goto writeback;
+ }
+
if (c->twobyte)
goto twobyte_insn;
@@ -2653,8 +3099,6 @@ special_insn:
break;
case 0x07: /* pop es */
rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_ES);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
case 0x08 ... 0x0d:
or: /* or */
@@ -2672,8 +3116,6 @@ special_insn:
break;
case 0x17: /* pop ss */
rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_SS);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
case 0x18 ... 0x1d:
sbb: /* sbb */
@@ -2684,8 +3126,6 @@ special_insn:
break;
case 0x1f: /* pop ds */
rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_DS);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
case 0x20 ... 0x25:
and: /* and */
@@ -2709,58 +3149,29 @@ special_insn:
case 0x48 ... 0x4f: /* dec r16/r32 */
emulate_1op("dec", c->dst, ctxt->eflags);
break;
- case 0x50 ... 0x57: /* push reg */
- emulate_push(ctxt, ops);
- break;
case 0x58 ... 0x5f: /* pop reg */
pop_instruction:
rc = emulate_pop(ctxt, ops, &c->dst.val, c->op_bytes);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
case 0x60: /* pusha */
rc = emulate_pusha(ctxt, ops);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
case 0x61: /* popa */
rc = emulate_popa(ctxt, ops);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
case 0x63: /* movsxd */
if (ctxt->mode != X86EMUL_MODE_PROT64)
goto cannot_emulate;
c->dst.val = (s32) c->src.val;
break;
- case 0x68: /* push imm */
- case 0x6a: /* push imm8 */
- emulate_push(ctxt, ops);
- break;
case 0x6c: /* insb */
case 0x6d: /* insw/insd */
- c->dst.bytes = min(c->dst.bytes, 4u);
- if (!emulator_io_permited(ctxt, ops, c->regs[VCPU_REGS_RDX],
- c->dst.bytes)) {
- emulate_gp(ctxt, 0);
- goto done;
- }
- if (!pio_in_emulated(ctxt, ops, c->dst.bytes,
- c->regs[VCPU_REGS_RDX], &c->dst.val))
- goto done; /* IO is needed, skip writeback */
- break;
+ c->src.val = c->regs[VCPU_REGS_RDX];
+ goto do_io_in;
case 0x6e: /* outsb */
case 0x6f: /* outsw/outsd */
- c->src.bytes = min(c->src.bytes, 4u);
- if (!emulator_io_permited(ctxt, ops, c->regs[VCPU_REGS_RDX],
- c->src.bytes)) {
- emulate_gp(ctxt, 0);
- goto done;
- }
- ops->pio_out_emulated(c->src.bytes, c->regs[VCPU_REGS_RDX],
- &c->src.val, 1, ctxt->vcpu);
-
- c->dst.type = OP_NONE; /* nothing to writeback */
+ c->dst.val = c->regs[VCPU_REGS_RDX];
+ goto do_io_out;
break;
case 0x70 ... 0x7f: /* jcc (short) */
if (test_cc(c->b, ctxt->eflags))
@@ -2793,29 +3204,15 @@ special_insn:
case 0x86 ... 0x87: /* xchg */
xchg:
/* Write back the register source. */
- switch (c->dst.bytes) {
- case 1:
- *(u8 *) c->src.ptr = (u8) c->dst.val;
- break;
- case 2:
- *(u16 *) c->src.ptr = (u16) c->dst.val;
- break;
- case 4:
- *c->src.ptr = (u32) c->dst.val;
- break; /* 64b reg: zero-extend */
- case 8:
- *c->src.ptr = c->dst.val;
- break;
- }
+ c->src.val = c->dst.val;
+ write_register_operand(&c->src);
/*
* Write back the memory destination with implicit LOCK
* prefix.
*/
- c->dst.val = c->src.val;
+ c->dst.val = c->src.orig_val;
c->lock_prefix = 1;
break;
- case 0x88 ... 0x8b: /* mov */
- goto mov;
case 0x8c: /* mov r/m, sreg */
if (c->modrm_reg > VCPU_SREG_GS) {
emulate_ud(ctxt);
@@ -2824,7 +3221,7 @@ special_insn:
c->dst.val = ops->get_segment_selector(c->modrm_reg, ctxt->vcpu);
break;
case 0x8d: /* lea r16/r32, m */
- c->dst.val = c->modrm_ea;
+ c->dst.val = c->src.addr.mem;
break;
case 0x8e: { /* mov seg, r/m16 */
uint16_t sel;
@@ -2847,76 +3244,87 @@ special_insn:
}
case 0x8f: /* pop (sole member of Grp1a) */
rc = emulate_grp1a(ctxt, ops);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
- case 0x90: /* nop / xchg r8,rax */
- if (c->dst.ptr == (unsigned long *)&c->regs[VCPU_REGS_RAX]) {
- c->dst.type = OP_NONE; /* nop */
+ case 0x90 ... 0x97: /* nop / xchg reg, rax */
+ if (c->dst.addr.reg == &c->regs[VCPU_REGS_RAX])
break;
- }
- case 0x91 ... 0x97: /* xchg reg,rax */
- c->src.type = OP_REG;
- c->src.bytes = c->op_bytes;
- c->src.ptr = (unsigned long *) &c->regs[VCPU_REGS_RAX];
- c->src.val = *(c->src.ptr);
goto xchg;
+ case 0x98: /* cbw/cwde/cdqe */
+ switch (c->op_bytes) {
+ case 2: c->dst.val = (s8)c->dst.val; break;
+ case 4: c->dst.val = (s16)c->dst.val; break;
+ case 8: c->dst.val = (s32)c->dst.val; break;
+ }
+ break;
case 0x9c: /* pushf */
c->src.val = (unsigned long) ctxt->eflags;
emulate_push(ctxt, ops);
break;
case 0x9d: /* popf */
c->dst.type = OP_REG;
- c->dst.ptr = (unsigned long *) &ctxt->eflags;
+ c->dst.addr.reg = &ctxt->eflags;
c->dst.bytes = c->op_bytes;
rc = emulate_popf(ctxt, ops, &c->dst.val, c->op_bytes);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
- case 0xa0 ... 0xa3: /* mov */
- case 0xa4 ... 0xa5: /* movs */
- goto mov;
case 0xa6 ... 0xa7: /* cmps */
c->dst.type = OP_NONE; /* Disable writeback. */
- DPRINTF("cmps: mem1=0x%p mem2=0x%p\n", c->src.ptr, c->dst.ptr);
+ DPRINTF("cmps: mem1=0x%p mem2=0x%p\n", c->src.addr.mem, c->dst.addr.mem);
goto cmp;
case 0xa8 ... 0xa9: /* test ax, imm */
goto test;
- case 0xaa ... 0xab: /* stos */
- c->dst.val = c->regs[VCPU_REGS_RAX];
- break;
- case 0xac ... 0xad: /* lods */
- goto mov;
case 0xae ... 0xaf: /* scas */
- DPRINTF("Urk! I don't handle SCAS.\n");
- goto cannot_emulate;
- case 0xb0 ... 0xbf: /* mov r, imm */
- goto mov;
+ goto cmp;
case 0xc0 ... 0xc1:
emulate_grp2(ctxt);
break;
case 0xc3: /* ret */
c->dst.type = OP_REG;
- c->dst.ptr = &c->eip;
+ c->dst.addr.reg = &c->eip;
c->dst.bytes = c->op_bytes;
goto pop_instruction;
- case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */
- mov:
- c->dst.val = c->src.val;
+ case 0xc4: /* les */
+ rc = emulate_load_segment(ctxt, ops, VCPU_SREG_ES);
+ break;
+ case 0xc5: /* lds */
+ rc = emulate_load_segment(ctxt, ops, VCPU_SREG_DS);
break;
case 0xcb: /* ret far */
rc = emulate_ret_far(ctxt, ops);
- if (rc != X86EMUL_CONTINUE)
- goto done;
+ break;
+ case 0xcc: /* int3 */
+ irq = 3;
+ goto do_interrupt;
+ case 0xcd: /* int n */
+ irq = c->src.val;
+ do_interrupt:
+ rc = emulate_int(ctxt, ops, irq);
+ break;
+ case 0xce: /* into */
+ if (ctxt->eflags & EFLG_OF) {
+ irq = 4;
+ goto do_interrupt;
+ }
+ break;
+ case 0xcf: /* iret */
+ rc = emulate_iret(ctxt, ops);
break;
case 0xd0 ... 0xd1: /* Grp2 */
- c->src.val = 1;
emulate_grp2(ctxt);
break;
case 0xd2 ... 0xd3: /* Grp2 */
c->src.val = c->regs[VCPU_REGS_RCX];
emulate_grp2(ctxt);
break;
+ case 0xe0 ... 0xe2: /* loop/loopz/loopnz */
+ register_address_increment(c, &c->regs[VCPU_REGS_RCX], -1);
+ if (address_mask(c, c->regs[VCPU_REGS_RCX]) != 0 &&
+ (c->b == 0xe2 || test_cc(c->b ^ 0x5, ctxt->eflags)))
+ jmp_rel(c, c->src.val);
+ break;
+ case 0xe3: /* jcxz/jecxz/jrcxz */
+ if (address_mask(c, c->regs[VCPU_REGS_RCX]) == 0)
+ jmp_rel(c, c->src.val);
+ break;
case 0xe4: /* inb */
case 0xe5: /* in */
goto do_io_in;
@@ -2964,15 +3372,16 @@ special_insn:
break;
case 0xee: /* out dx,al */
case 0xef: /* out dx,(e/r)ax */
- c->src.val = c->regs[VCPU_REGS_RDX];
+ c->dst.val = c->regs[VCPU_REGS_RDX];
do_io_out:
- c->dst.bytes = min(c->dst.bytes, 4u);
- if (!emulator_io_permited(ctxt, ops, c->src.val, c->dst.bytes)) {
+ c->src.bytes = min(c->src.bytes, 4u);
+ if (!emulator_io_permited(ctxt, ops, c->dst.val,
+ c->src.bytes)) {
emulate_gp(ctxt, 0);
goto done;
}
- ops->pio_out_emulated(c->dst.bytes, c->src.val, &c->dst.val, 1,
- ctxt->vcpu);
+ ops->pio_out_emulated(c->src.bytes, c->dst.val,
+ &c->src.val, 1, ctxt->vcpu);
c->dst.type = OP_NONE; /* Disable writeback. */
break;
case 0xf4: /* hlt */
@@ -2981,24 +3390,22 @@ special_insn:
case 0xf5: /* cmc */
/* complement carry flag from eflags reg */
ctxt->eflags ^= EFLG_CF;
- c->dst.type = OP_NONE; /* Disable writeback. */
break;
case 0xf6 ... 0xf7: /* Grp3 */
- if (!emulate_grp3(ctxt, ops))
- goto cannot_emulate;
+ rc = emulate_grp3(ctxt, ops);
break;
case 0xf8: /* clc */
ctxt->eflags &= ~EFLG_CF;
- c->dst.type = OP_NONE; /* Disable writeback. */
+ break;
+ case 0xf9: /* stc */
+ ctxt->eflags |= EFLG_CF;
break;
case 0xfa: /* cli */
if (emulator_bad_iopl(ctxt, ops)) {
emulate_gp(ctxt, 0);
goto done;
- } else {
+ } else
ctxt->eflags &= ~X86_EFLAGS_IF;
- c->dst.type = OP_NONE; /* Disable writeback. */
- }
break;
case 0xfb: /* sti */
if (emulator_bad_iopl(ctxt, ops)) {
@@ -3007,29 +3414,29 @@ special_insn:
} else {
ctxt->interruptibility = KVM_X86_SHADOW_INT_STI;
ctxt->eflags |= X86_EFLAGS_IF;
- c->dst.type = OP_NONE; /* Disable writeback. */
}
break;
case 0xfc: /* cld */
ctxt->eflags &= ~EFLG_DF;
- c->dst.type = OP_NONE; /* Disable writeback. */
break;
case 0xfd: /* std */
ctxt->eflags |= EFLG_DF;
- c->dst.type = OP_NONE; /* Disable writeback. */
break;
case 0xfe: /* Grp4 */
grp45:
rc = emulate_grp45(ctxt, ops);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
case 0xff: /* Grp5 */
if (c->modrm_reg == 5)
goto jump_far;
goto grp45;
+ default:
+ goto cannot_emulate;
}
+ if (rc != X86EMUL_CONTINUE)
+ goto done;
+
writeback:
rc = writeback(ctxt, ops);
if (rc != X86EMUL_CONTINUE)
@@ -3050,25 +3457,32 @@ writeback:
&c->dst);
if (c->rep_prefix && (c->d & String)) {
- struct read_cache *rc = &ctxt->decode.io_read;
+ struct read_cache *r = &ctxt->decode.io_read;
register_address_increment(c, &c->regs[VCPU_REGS_RCX], -1);
- /*
- * Re-enter guest when pio read ahead buffer is empty or,
- * if it is not used, after each 1024 iteration.
- */
- if ((rc->end == 0 && !(c->regs[VCPU_REGS_RCX] & 0x3ff)) ||
- (rc->end != 0 && rc->end == rc->pos))
- ctxt->restart = false;
+
+ if (!string_insn_completed(ctxt)) {
+ /*
+ * Re-enter guest when pio read ahead buffer is empty
+ * or, if it is not used, after each 1024 iteration.
+ */
+ if ((r->end != 0 || c->regs[VCPU_REGS_RCX] & 0x3ff) &&
+ (r->end == 0 || r->end != r->pos)) {
+ /*
+ * Reset read cache. Usually happens before
+ * decode, but since instruction is restarted
+ * we have to do it here.
+ */
+ ctxt->decode.mem_read.end = 0;
+ return EMULATION_RESTART;
+ }
+ goto done; /* skip rip writeback */
+ }
}
- /*
- * reset read cache here in case string instruction is restared
- * without decoding
- */
- ctxt->decode.mem_read.end = 0;
+
ctxt->eip = c->eip;
done:
- return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0;
+ return (rc == X86EMUL_UNHANDLEABLE) ? EMULATION_FAILED : EMULATION_OK;
twobyte_insn:
switch (c->b) {
@@ -3091,7 +3505,7 @@ twobyte_insn:
c->dst.type = OP_NONE;
break;
case 2: /* lgdt */
- rc = read_descriptor(ctxt, ops, c->src.ptr,
+ rc = read_descriptor(ctxt, ops, c->src.addr.mem,
&size, &address, c->op_bytes);
if (rc != X86EMUL_CONTINUE)
goto done;
@@ -3104,14 +3518,12 @@ twobyte_insn:
switch (c->modrm_rm) {
case 1:
rc = kvm_fix_hypercall(ctxt->vcpu);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
default:
goto cannot_emulate;
}
} else {
- rc = read_descriptor(ctxt, ops, c->src.ptr,
+ rc = read_descriptor(ctxt, ops, c->src.addr.mem,
&size, &address,
c->op_bytes);
if (rc != X86EMUL_CONTINUE)
@@ -3126,7 +3538,7 @@ twobyte_insn:
c->dst.val = ops->get_cr(0, ctxt->vcpu);
break;
case 6: /* lmsw */
- ops->set_cr(0, (ops->get_cr(0, ctxt->vcpu) & ~0x0ful) |
+ ops->set_cr(0, (ops->get_cr(0, ctxt->vcpu) & ~0x0eul) |
(c->src.val & 0x0f), ctxt->vcpu);
c->dst.type = OP_NONE;
break;
@@ -3134,7 +3546,7 @@ twobyte_insn:
emulate_ud(ctxt);
goto done;
case 7: /* invlpg*/
- emulate_invlpg(ctxt->vcpu, c->modrm_ea);
+ emulate_invlpg(ctxt->vcpu, c->src.addr.mem);
/* Disable writeback. */
c->dst.type = OP_NONE;
break;
@@ -3144,23 +3556,16 @@ twobyte_insn:
break;
case 0x05: /* syscall */
rc = emulate_syscall(ctxt, ops);
- if (rc != X86EMUL_CONTINUE)
- goto done;
- else
- goto writeback;
break;
case 0x06:
emulate_clts(ctxt->vcpu);
- c->dst.type = OP_NONE;
break;
case 0x09: /* wbinvd */
kvm_emulate_wbinvd(ctxt->vcpu);
- c->dst.type = OP_NONE;
break;
case 0x08: /* invd */
case 0x0d: /* GrpP (prefetch) */
case 0x18: /* Grp16 (prefetch/nop) */
- c->dst.type = OP_NONE;
break;
case 0x20: /* mov cr, reg */
switch (c->modrm_reg) {
@@ -3170,8 +3575,7 @@ twobyte_insn:
emulate_ud(ctxt);
goto done;
}
- c->regs[c->modrm_rm] = ops->get_cr(c->modrm_reg, ctxt->vcpu);
- c->dst.type = OP_NONE; /* no writeback */
+ c->dst.val = ops->get_cr(c->modrm_reg, ctxt->vcpu);
break;
case 0x21: /* mov from dr to reg */
if ((ops->get_cr(4, ctxt->vcpu) & X86_CR4_DE) &&
@@ -3179,11 +3583,10 @@ twobyte_insn:
emulate_ud(ctxt);
goto done;
}
- ops->get_dr(c->modrm_reg, &c->regs[c->modrm_rm], ctxt->vcpu);
- c->dst.type = OP_NONE; /* no writeback */
+ ops->get_dr(c->modrm_reg, &c->dst.val, ctxt->vcpu);
break;
case 0x22: /* mov reg, cr */
- if (ops->set_cr(c->modrm_reg, c->modrm_val, ctxt->vcpu)) {
+ if (ops->set_cr(c->modrm_reg, c->src.val, ctxt->vcpu)) {
emulate_gp(ctxt, 0);
goto done;
}
@@ -3196,7 +3599,7 @@ twobyte_insn:
goto done;
}
- if (ops->set_dr(c->modrm_reg, c->regs[c->modrm_rm] &
+ if (ops->set_dr(c->modrm_reg, c->src.val &
((ctxt->mode == X86EMUL_MODE_PROT64) ?
~0ULL : ~0U), ctxt->vcpu) < 0) {
/* #UD condition is already handled by the code above */
@@ -3215,7 +3618,6 @@ twobyte_insn:
goto done;
}
rc = X86EMUL_CONTINUE;
- c->dst.type = OP_NONE;
break;
case 0x32:
/* rdmsr */
@@ -3227,21 +3629,12 @@ twobyte_insn:
c->regs[VCPU_REGS_RDX] = msr_data >> 32;
}
rc = X86EMUL_CONTINUE;
- c->dst.type = OP_NONE;
break;
case 0x34: /* sysenter */
rc = emulate_sysenter(ctxt, ops);
- if (rc != X86EMUL_CONTINUE)
- goto done;
- else
- goto writeback;
break;
case 0x35: /* sysexit */
rc = emulate_sysexit(ctxt, ops);
- if (rc != X86EMUL_CONTINUE)
- goto done;
- else
- goto writeback;
break;
case 0x40 ... 0x4f: /* cmov */
c->dst.val = c->dst.orig_val = c->src.val;
@@ -3251,15 +3644,15 @@ twobyte_insn:
case 0x80 ... 0x8f: /* jnz rel, etc*/
if (test_cc(c->b, ctxt->eflags))
jmp_rel(c, c->src.val);
- c->dst.type = OP_NONE;
+ break;
+ case 0x90 ... 0x9f: /* setcc r/m8 */
+ c->dst.val = test_cc(c->b, ctxt->eflags);
break;
case 0xa0: /* push fs */
emulate_push_sreg(ctxt, ops, VCPU_SREG_FS);
break;
case 0xa1: /* pop fs */
rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_FS);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
case 0xa3:
bt: /* bt */
@@ -3277,13 +3670,9 @@ twobyte_insn:
break;
case 0xa9: /* pop gs */
rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_GS);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
case 0xab:
bts: /* bts */
- /* only subword offset */
- c->src.val &= (c->dst.bytes << 3) - 1;
emulate_2op_SrcV_nobyte("bts", c->src, c->dst, ctxt->eflags);
break;
case 0xac: /* shrd imm8, r, r/m */
@@ -3306,15 +3695,22 @@ twobyte_insn:
} else {
/* Failure: write the value we saw to EAX. */
c->dst.type = OP_REG;
- c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX];
+ c->dst.addr.reg = (unsigned long *)&c->regs[VCPU_REGS_RAX];
}
break;
+ case 0xb2: /* lss */
+ rc = emulate_load_segment(ctxt, ops, VCPU_SREG_SS);
+ break;
case 0xb3:
btr: /* btr */
- /* only subword offset */
- c->src.val &= (c->dst.bytes << 3) - 1;
emulate_2op_SrcV_nobyte("btr", c->src, c->dst, ctxt->eflags);
break;
+ case 0xb4: /* lfs */
+ rc = emulate_load_segment(ctxt, ops, VCPU_SREG_FS);
+ break;
+ case 0xb5: /* lgs */
+ rc = emulate_load_segment(ctxt, ops, VCPU_SREG_GS);
+ break;
case 0xb6 ... 0xb7: /* movzx */
c->dst.bytes = c->op_bytes;
c->dst.val = (c->d & ByteOp) ? (u8) c->src.val
@@ -3334,15 +3730,43 @@ twobyte_insn:
break;
case 0xbb:
btc: /* btc */
- /* only subword offset */
- c->src.val &= (c->dst.bytes << 3) - 1;
emulate_2op_SrcV_nobyte("btc", c->src, c->dst, ctxt->eflags);
break;
+ case 0xbc: { /* bsf */
+ u8 zf;
+ __asm__ ("bsf %2, %0; setz %1"
+ : "=r"(c->dst.val), "=q"(zf)
+ : "r"(c->src.val));
+ ctxt->eflags &= ~X86_EFLAGS_ZF;
+ if (zf) {
+ ctxt->eflags |= X86_EFLAGS_ZF;
+ c->dst.type = OP_NONE; /* Disable writeback. */
+ }
+ break;
+ }
+ case 0xbd: { /* bsr */
+ u8 zf;
+ __asm__ ("bsr %2, %0; setz %1"
+ : "=r"(c->dst.val), "=q"(zf)
+ : "r"(c->src.val));
+ ctxt->eflags &= ~X86_EFLAGS_ZF;
+ if (zf) {
+ ctxt->eflags |= X86_EFLAGS_ZF;
+ c->dst.type = OP_NONE; /* Disable writeback. */
+ }
+ break;
+ }
case 0xbe ... 0xbf: /* movsx */
c->dst.bytes = c->op_bytes;
c->dst.val = (c->d & ByteOp) ? (s8) c->src.val :
(s16) c->src.val;
break;
+ case 0xc0 ... 0xc1: /* xadd */
+ emulate_2op_SrcV("add", c->src, c->dst, ctxt->eflags);
+ /* Write back the register source. */
+ c->src.val = c->dst.orig_val;
+ write_register_operand(&c->src);
+ break;
case 0xc3: /* movnti */
c->dst.bytes = c->op_bytes;
c->dst.val = (c->op_bytes == 4) ? (u32) c->src.val :
@@ -3350,10 +3774,14 @@ twobyte_insn:
break;
case 0xc7: /* Grp9 (cmpxchg8b) */
rc = emulate_grp9(ctxt, ops);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
+ default:
+ goto cannot_emulate;
}
+
+ if (rc != X86EMUL_CONTINUE)
+ goto done;
+
goto writeback;
cannot_emulate:
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index ddeb2314b522..efad72385058 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -5,7 +5,7 @@
* Copyright (c) 2006 Intel Corporation
* Copyright (c) 2007 Keir Fraser, XenSource Inc
* Copyright (c) 2008 Intel Corporation
- * Copyright 2009 Red Hat, Inc. and/or its affilates.
+ * Copyright 2009 Red Hat, Inc. and/or its affiliates.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -232,15 +232,6 @@ static void pit_latch_status(struct kvm *kvm, int channel)
}
}
-int pit_has_pending_timer(struct kvm_vcpu *vcpu)
-{
- struct kvm_pit *pit = vcpu->kvm->arch.vpit;
-
- if (pit && kvm_vcpu_is_bsp(vcpu) && pit->pit_state.irq_ack)
- return atomic_read(&pit->pit_state.pit_timer.pending);
- return 0;
-}
-
static void kvm_pit_ack_irq(struct kvm_irq_ack_notifier *kian)
{
struct kvm_kpit_state *ps = container_of(kian, struct kvm_kpit_state,
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c
index 4b7b73ce2098..f628234fbeca 100644
--- a/arch/x86/kvm/i8259.c
+++ b/arch/x86/kvm/i8259.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2003-2004 Fabrice Bellard
* Copyright (c) 2007 Intel Corporation
- * Copyright 2009 Red Hat, Inc. and/or its affilates.
+ * Copyright 2009 Red Hat, Inc. and/or its affiliates.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -39,7 +39,7 @@ static void pic_irq_request(struct kvm *kvm, int level);
static void pic_lock(struct kvm_pic *s)
__acquires(&s->lock)
{
- raw_spin_lock(&s->lock);
+ spin_lock(&s->lock);
}
static void pic_unlock(struct kvm_pic *s)
@@ -51,7 +51,7 @@ static void pic_unlock(struct kvm_pic *s)
s->wakeup_needed = false;
- raw_spin_unlock(&s->lock);
+ spin_unlock(&s->lock);
if (wakeup) {
kvm_for_each_vcpu(i, vcpu, s->kvm) {
@@ -67,6 +67,7 @@ static void pic_unlock(struct kvm_pic *s)
if (!found)
return;
+ kvm_make_request(KVM_REQ_EVENT, found);
kvm_vcpu_kick(found);
}
}
@@ -308,13 +309,17 @@ static void pic_ioport_write(void *opaque, u32 addr, u32 val)
addr &= 1;
if (addr == 0) {
if (val & 0x10) {
- kvm_pic_reset(s); /* init */
- /*
- * deassert a pending interrupt
- */
- pic_irq_request(s->pics_state->kvm, 0);
- s->init_state = 1;
s->init4 = val & 1;
+ s->last_irr = 0;
+ s->imr = 0;
+ s->priority_add = 0;
+ s->special_mask = 0;
+ s->read_reg_select = 0;
+ if (!s->init4) {
+ s->special_fully_nested_mode = 0;
+ s->auto_eoi = 0;
+ }
+ s->init_state = 1;
if (val & 0x02)
printk(KERN_ERR "single mode not supported");
if (val & 0x08)
@@ -564,7 +569,7 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm)
s = kzalloc(sizeof(struct kvm_pic), GFP_KERNEL);
if (!s)
return NULL;
- raw_spin_lock_init(&s->lock);
+ spin_lock_init(&s->lock);
s->kvm = kvm;
s->pics[0].elcr_mask = 0xf8;
s->pics[1].elcr_mask = 0xde;
diff --git a/arch/x86/kvm/irq.c b/arch/x86/kvm/irq.c
index 2095a049835e..7e06ba1618bd 100644
--- a/arch/x86/kvm/irq.c
+++ b/arch/x86/kvm/irq.c
@@ -1,7 +1,7 @@
/*
* irq.c: API for in kernel interrupt controller
* Copyright (c) 2007, Intel Corporation.
- * Copyright 2009 Red Hat, Inc. and/or its affilates.
+ * Copyright 2009 Red Hat, Inc. and/or its affiliates.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -33,12 +33,7 @@
*/
int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
{
- int ret;
-
- ret = pit_has_pending_timer(vcpu);
- ret |= apic_has_pending_timer(vcpu);
-
- return ret;
+ return apic_has_pending_timer(vcpu);
}
EXPORT_SYMBOL(kvm_cpu_has_pending_timer);
diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h
index 63c314502993..ba910d149410 100644
--- a/arch/x86/kvm/irq.h
+++ b/arch/x86/kvm/irq.h
@@ -60,7 +60,7 @@ struct kvm_kpic_state {
};
struct kvm_pic {
- raw_spinlock_t lock;
+ spinlock_t lock;
bool wakeup_needed;
unsigned pending_acks;
struct kvm *kvm;
diff --git a/arch/x86/kvm/kvm_cache_regs.h b/arch/x86/kvm/kvm_cache_regs.h
index 6491ac8e755b..975bb45329a1 100644
--- a/arch/x86/kvm/kvm_cache_regs.h
+++ b/arch/x86/kvm/kvm_cache_regs.h
@@ -42,7 +42,14 @@ static inline u64 kvm_pdptr_read(struct kvm_vcpu *vcpu, int index)
(unsigned long *)&vcpu->arch.regs_avail))
kvm_x86_ops->cache_reg(vcpu, VCPU_EXREG_PDPTR);
- return vcpu->arch.pdptrs[index];
+ return vcpu->arch.walk_mmu->pdptrs[index];
+}
+
+static inline u64 kvm_pdptr_read_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, int index)
+{
+ load_pdptrs(vcpu, mmu, mmu->get_cr3(vcpu));
+
+ return mmu->pdptrs[index];
}
static inline ulong kvm_read_cr0_bits(struct kvm_vcpu *vcpu, ulong mask)
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 77d8c0f4817d..413f8973a855 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -5,7 +5,7 @@
* Copyright (C) 2006 Qumranet, Inc.
* Copyright (C) 2007 Novell
* Copyright (C) 2007 Intel
- * Copyright 2009 Red Hat, Inc. and/or its affilates.
+ * Copyright 2009 Red Hat, Inc. and/or its affiliates.
*
* Authors:
* Dor Laor <dor.laor@qumranet.com>
@@ -259,9 +259,10 @@ static inline int apic_find_highest_isr(struct kvm_lapic *apic)
static void apic_update_ppr(struct kvm_lapic *apic)
{
- u32 tpr, isrv, ppr;
+ u32 tpr, isrv, ppr, old_ppr;
int isr;
+ old_ppr = apic_get_reg(apic, APIC_PROCPRI);
tpr = apic_get_reg(apic, APIC_TASKPRI);
isr = apic_find_highest_isr(apic);
isrv = (isr != -1) ? isr : 0;
@@ -274,7 +275,10 @@ static void apic_update_ppr(struct kvm_lapic *apic)
apic_debug("vlapic %p, ppr 0x%x, isr 0x%x, isrv 0x%x",
apic, ppr, isr, isrv);
- apic_set_reg(apic, APIC_PROCPRI, ppr);
+ if (old_ppr != ppr) {
+ apic_set_reg(apic, APIC_PROCPRI, ppr);
+ kvm_make_request(KVM_REQ_EVENT, apic->vcpu);
+ }
}
static void apic_set_tpr(struct kvm_lapic *apic, u32 tpr)
@@ -391,6 +395,7 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
break;
}
+ kvm_make_request(KVM_REQ_EVENT, vcpu);
kvm_vcpu_kick(vcpu);
break;
@@ -416,6 +421,7 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
"INIT on a runnable vcpu %d\n",
vcpu->vcpu_id);
vcpu->arch.mp_state = KVM_MP_STATE_INIT_RECEIVED;
+ kvm_make_request(KVM_REQ_EVENT, vcpu);
kvm_vcpu_kick(vcpu);
} else {
apic_debug("Ignoring de-assert INIT to vcpu %d\n",
@@ -430,6 +436,7 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
result = 1;
vcpu->arch.sipi_vector = vector;
vcpu->arch.mp_state = KVM_MP_STATE_SIPI_RECEIVED;
+ kvm_make_request(KVM_REQ_EVENT, vcpu);
kvm_vcpu_kick(vcpu);
}
break;
@@ -475,6 +482,7 @@ static void apic_set_eoi(struct kvm_lapic *apic)
trigger_mode = IOAPIC_EDGE_TRIG;
if (!(apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_DIRECTED_EOI))
kvm_ioapic_update_eoi(apic->vcpu->kvm, vector, trigger_mode);
+ kvm_make_request(KVM_REQ_EVENT, apic->vcpu);
}
static void apic_send_ipi(struct kvm_lapic *apic)
@@ -1056,14 +1064,13 @@ int kvm_create_lapic(struct kvm_vcpu *vcpu)
vcpu->arch.apic = apic;
- apic->regs_page = alloc_page(GFP_KERNEL);
+ apic->regs_page = alloc_page(GFP_KERNEL|__GFP_ZERO);
if (apic->regs_page == NULL) {
printk(KERN_ERR "malloc apic regs error for vcpu %x\n",
vcpu->vcpu_id);
goto nomem_free_apic;
}
apic->regs = page_address(apic->regs_page);
- memset(apic->regs, 0, PAGE_SIZE);
apic->vcpu = vcpu;
hrtimer_init(&apic->lapic_timer.timer, CLOCK_MONOTONIC,
@@ -1152,6 +1159,7 @@ void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu)
update_divide_count(apic);
start_apic_timer(apic);
apic->irr_pending = true;
+ kvm_make_request(KVM_REQ_EVENT, vcpu);
}
void __kvm_migrate_apic_timer(struct kvm_vcpu *vcpu)
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 311f6dad8951..908ea5464a51 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -7,7 +7,7 @@
* MMU support
*
* Copyright (C) 2006 Qumranet, Inc.
- * Copyright 2010 Red Hat, Inc. and/or its affilates.
+ * Copyright 2010 Red Hat, Inc. and/or its affiliates.
*
* Authors:
* Yaniv Kamay <yaniv@qumranet.com>
@@ -49,15 +49,25 @@
*/
bool tdp_enabled = false;
-#undef MMU_DEBUG
+enum {
+ AUDIT_PRE_PAGE_FAULT,
+ AUDIT_POST_PAGE_FAULT,
+ AUDIT_PRE_PTE_WRITE,
+ AUDIT_POST_PTE_WRITE,
+ AUDIT_PRE_SYNC,
+ AUDIT_POST_SYNC
+};
-#undef AUDIT
+char *audit_point_name[] = {
+ "pre page fault",
+ "post page fault",
+ "pre pte write",
+ "post pte write",
+ "pre sync",
+ "post sync"
+};
-#ifdef AUDIT
-static void kvm_mmu_audit(struct kvm_vcpu *vcpu, const char *msg);
-#else
-static void kvm_mmu_audit(struct kvm_vcpu *vcpu, const char *msg) {}
-#endif
+#undef MMU_DEBUG
#ifdef MMU_DEBUG
@@ -71,7 +81,7 @@ static void kvm_mmu_audit(struct kvm_vcpu *vcpu, const char *msg) {}
#endif
-#if defined(MMU_DEBUG) || defined(AUDIT)
+#ifdef MMU_DEBUG
static int dbg = 0;
module_param(dbg, bool, 0644);
#endif
@@ -89,6 +99,8 @@ module_param(oos_shadow, bool, 0644);
}
#endif
+#define PTE_PREFETCH_NUM 8
+
#define PT_FIRST_AVAIL_BITS_SHIFT 9
#define PT64_SECOND_AVAIL_BITS_SHIFT 52
@@ -178,6 +190,7 @@ typedef void (*mmu_parent_walk_fn) (struct kvm_mmu_page *sp, u64 *spte);
static struct kmem_cache *pte_chain_cache;
static struct kmem_cache *rmap_desc_cache;
static struct kmem_cache *mmu_page_header_cache;
+static struct percpu_counter kvm_total_used_mmu_pages;
static u64 __read_mostly shadow_trap_nonpresent_pte;
static u64 __read_mostly shadow_notrap_nonpresent_pte;
@@ -299,18 +312,50 @@ static u64 __xchg_spte(u64 *sptep, u64 new_spte)
#endif
}
+static bool spte_has_volatile_bits(u64 spte)
+{
+ if (!shadow_accessed_mask)
+ return false;
+
+ if (!is_shadow_present_pte(spte))
+ return false;
+
+ if ((spte & shadow_accessed_mask) &&
+ (!is_writable_pte(spte) || (spte & shadow_dirty_mask)))
+ return false;
+
+ return true;
+}
+
+static bool spte_is_bit_cleared(u64 old_spte, u64 new_spte, u64 bit_mask)
+{
+ return (old_spte & bit_mask) && !(new_spte & bit_mask);
+}
+
static void update_spte(u64 *sptep, u64 new_spte)
{
- u64 old_spte;
+ u64 mask, old_spte = *sptep;
+
+ WARN_ON(!is_rmap_spte(new_spte));
+
+ new_spte |= old_spte & shadow_dirty_mask;
- if (!shadow_accessed_mask || (new_spte & shadow_accessed_mask) ||
- !is_rmap_spte(*sptep))
+ mask = shadow_accessed_mask;
+ if (is_writable_pte(old_spte))
+ mask |= shadow_dirty_mask;
+
+ if (!spte_has_volatile_bits(old_spte) || (new_spte & mask) == mask)
__set_spte(sptep, new_spte);
- else {
+ else
old_spte = __xchg_spte(sptep, new_spte);
- if (old_spte & shadow_accessed_mask)
- mark_page_accessed(pfn_to_page(spte_to_pfn(old_spte)));
- }
+
+ if (!shadow_accessed_mask)
+ return;
+
+ if (spte_is_bit_cleared(old_spte, new_spte, shadow_accessed_mask))
+ kvm_set_pfn_accessed(spte_to_pfn(old_spte));
+ if (spte_is_bit_cleared(old_spte, new_spte, shadow_dirty_mask))
+ kvm_set_pfn_dirty(spte_to_pfn(old_spte));
}
static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache,
@@ -367,7 +412,7 @@ static int mmu_topup_memory_caches(struct kvm_vcpu *vcpu)
if (r)
goto out;
r = mmu_topup_memory_cache(&vcpu->arch.mmu_rmap_desc_cache,
- rmap_desc_cache, 4);
+ rmap_desc_cache, 4 + PTE_PREFETCH_NUM);
if (r)
goto out;
r = mmu_topup_memory_cache_page(&vcpu->arch.mmu_page_cache, 8);
@@ -591,6 +636,7 @@ static int rmap_add(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn)
desc->sptes[0] = (u64 *)*rmapp;
desc->sptes[1] = spte;
*rmapp = (unsigned long)desc | 1;
+ ++count;
} else {
rmap_printk("rmap_add: %p %llx many->many\n", spte, *spte);
desc = (struct kvm_rmap_desc *)(*rmapp & ~1ul);
@@ -603,7 +649,7 @@ static int rmap_add(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn)
desc = desc->more;
}
for (i = 0; desc->sptes[i]; ++i)
- ;
+ ++count;
desc->sptes[i] = spte;
}
return count;
@@ -645,18 +691,17 @@ static void rmap_remove(struct kvm *kvm, u64 *spte)
gfn = kvm_mmu_page_get_gfn(sp, spte - sp->spt);
rmapp = gfn_to_rmap(kvm, gfn, sp->role.level);
if (!*rmapp) {
- printk(KERN_ERR "rmap_remove: %p %llx 0->BUG\n", spte, *spte);
+ printk(KERN_ERR "rmap_remove: %p 0->BUG\n", spte);
BUG();
} else if (!(*rmapp & 1)) {
- rmap_printk("rmap_remove: %p %llx 1->0\n", spte, *spte);
+ rmap_printk("rmap_remove: %p 1->0\n", spte);
if ((u64 *)*rmapp != spte) {
- printk(KERN_ERR "rmap_remove: %p %llx 1->BUG\n",
- spte, *spte);
+ printk(KERN_ERR "rmap_remove: %p 1->BUG\n", spte);
BUG();
}
*rmapp = 0;
} else {
- rmap_printk("rmap_remove: %p %llx many->many\n", spte, *spte);
+ rmap_printk("rmap_remove: %p many->many\n", spte);
desc = (struct kvm_rmap_desc *)(*rmapp & ~1ul);
prev_desc = NULL;
while (desc) {
@@ -670,7 +715,7 @@ static void rmap_remove(struct kvm *kvm, u64 *spte)
prev_desc = desc;
desc = desc->more;
}
- pr_err("rmap_remove: %p %llx many->many\n", spte, *spte);
+ pr_err("rmap_remove: %p many->many\n", spte);
BUG();
}
}
@@ -680,18 +725,18 @@ static void set_spte_track_bits(u64 *sptep, u64 new_spte)
pfn_t pfn;
u64 old_spte = *sptep;
- if (!shadow_accessed_mask || !is_shadow_present_pte(old_spte) ||
- old_spte & shadow_accessed_mask) {
+ if (!spte_has_volatile_bits(old_spte))
__set_spte(sptep, new_spte);
- } else
+ else
old_spte = __xchg_spte(sptep, new_spte);
if (!is_rmap_spte(old_spte))
return;
+
pfn = spte_to_pfn(old_spte);
if (!shadow_accessed_mask || old_spte & shadow_accessed_mask)
kvm_set_pfn_accessed(pfn);
- if (is_writable_pte(old_spte))
+ if (!shadow_dirty_mask || (old_spte & shadow_dirty_mask))
kvm_set_pfn_dirty(pfn);
}
@@ -746,13 +791,6 @@ static int rmap_write_protect(struct kvm *kvm, u64 gfn)
}
spte = rmap_next(kvm, rmapp, spte);
}
- if (write_protected) {
- pfn_t pfn;
-
- spte = rmap_next(kvm, rmapp, NULL);
- pfn = spte_to_pfn(*spte);
- kvm_set_pfn_dirty(pfn);
- }
/* check for huge page mappings */
for (i = PT_DIRECTORY_LEVEL;
@@ -947,6 +985,18 @@ static int is_empty_shadow_page(u64 *spt)
}
#endif
+/*
+ * This value is the sum of all of the kvm instances's
+ * kvm->arch.n_used_mmu_pages values. We need a global,
+ * aggregate version in order to make the slab shrinker
+ * faster
+ */
+static inline void kvm_mod_used_mmu_pages(struct kvm *kvm, int nr)
+{
+ kvm->arch.n_used_mmu_pages += nr;
+ percpu_counter_add(&kvm_total_used_mmu_pages, nr);
+}
+
static void kvm_mmu_free_page(struct kvm *kvm, struct kvm_mmu_page *sp)
{
ASSERT(is_empty_shadow_page(sp->spt));
@@ -956,7 +1006,7 @@ static void kvm_mmu_free_page(struct kvm *kvm, struct kvm_mmu_page *sp)
if (!sp->role.direct)
__free_page(virt_to_page(sp->gfns));
kmem_cache_free(mmu_page_header_cache, sp);
- ++kvm->arch.n_free_mmu_pages;
+ kvm_mod_used_mmu_pages(kvm, -1);
}
static unsigned kvm_page_table_hashfn(gfn_t gfn)
@@ -979,7 +1029,7 @@ static struct kvm_mmu_page *kvm_mmu_alloc_page(struct kvm_vcpu *vcpu,
bitmap_zero(sp->slot_bitmap, KVM_MEMORY_SLOTS + KVM_PRIVATE_MEM_SLOTS);
sp->multimapped = 0;
sp->parent_pte = parent_pte;
- --vcpu->kvm->arch.n_free_mmu_pages;
+ kvm_mod_used_mmu_pages(vcpu->kvm, +1);
return sp;
}
@@ -1403,7 +1453,8 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
if (role.direct)
role.cr4_pae = 0;
role.access = access;
- if (!tdp_enabled && vcpu->arch.mmu.root_level <= PT32_ROOT_LEVEL) {
+ if (!vcpu->arch.mmu.direct_map
+ && vcpu->arch.mmu.root_level <= PT32_ROOT_LEVEL) {
quadrant = gaddr >> (PAGE_SHIFT + (PT64_PT_BITS * level));
quadrant &= (1 << ((PT32_PT_BITS - PT64_PT_BITS) * level)) - 1;
role.quadrant = quadrant;
@@ -1458,6 +1509,12 @@ static void shadow_walk_init(struct kvm_shadow_walk_iterator *iterator,
iterator->addr = addr;
iterator->shadow_addr = vcpu->arch.mmu.root_hpa;
iterator->level = vcpu->arch.mmu.shadow_root_level;
+
+ if (iterator->level == PT64_ROOT_LEVEL &&
+ vcpu->arch.mmu.root_level < PT64_ROOT_LEVEL &&
+ !vcpu->arch.mmu.direct_map)
+ --iterator->level;
+
if (iterator->level == PT32E_ROOT_LEVEL) {
iterator->shadow_addr
= vcpu->arch.mmu.pae_root[(addr >> 30) & 3];
@@ -1665,41 +1722,31 @@ static void kvm_mmu_commit_zap_page(struct kvm *kvm,
/*
* Changing the number of mmu pages allocated to the vm
- * Note: if kvm_nr_mmu_pages is too small, you will get dead lock
+ * Note: if goal_nr_mmu_pages is too small, you will get dead lock
*/
-void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int kvm_nr_mmu_pages)
+void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int goal_nr_mmu_pages)
{
- int used_pages;
LIST_HEAD(invalid_list);
-
- used_pages = kvm->arch.n_alloc_mmu_pages - kvm->arch.n_free_mmu_pages;
- used_pages = max(0, used_pages);
-
/*
* If we set the number of mmu pages to be smaller be than the
* number of actived pages , we must to free some mmu pages before we
* change the value
*/
- if (used_pages > kvm_nr_mmu_pages) {
- while (used_pages > kvm_nr_mmu_pages &&
+ if (kvm->arch.n_used_mmu_pages > goal_nr_mmu_pages) {
+ while (kvm->arch.n_used_mmu_pages > goal_nr_mmu_pages &&
!list_empty(&kvm->arch.active_mmu_pages)) {
struct kvm_mmu_page *page;
page = container_of(kvm->arch.active_mmu_pages.prev,
struct kvm_mmu_page, link);
- used_pages -= kvm_mmu_prepare_zap_page(kvm, page,
- &invalid_list);
+ kvm_mmu_prepare_zap_page(kvm, page, &invalid_list);
+ kvm_mmu_commit_zap_page(kvm, &invalid_list);
}
- kvm_mmu_commit_zap_page(kvm, &invalid_list);
- kvm_nr_mmu_pages = used_pages;
- kvm->arch.n_free_mmu_pages = 0;
+ goal_nr_mmu_pages = kvm->arch.n_used_mmu_pages;
}
- else
- kvm->arch.n_free_mmu_pages += kvm_nr_mmu_pages
- - kvm->arch.n_alloc_mmu_pages;
- kvm->arch.n_alloc_mmu_pages = kvm_nr_mmu_pages;
+ kvm->arch.n_max_mmu_pages = goal_nr_mmu_pages;
}
static int kvm_mmu_unprotect_page(struct kvm *kvm, gfn_t gfn)
@@ -1709,11 +1756,11 @@ static int kvm_mmu_unprotect_page(struct kvm *kvm, gfn_t gfn)
LIST_HEAD(invalid_list);
int r;
- pgprintk("%s: looking for gfn %lx\n", __func__, gfn);
+ pgprintk("%s: looking for gfn %llx\n", __func__, gfn);
r = 0;
for_each_gfn_indirect_valid_sp(kvm, sp, gfn, node) {
- pgprintk("%s: gfn %lx role %x\n", __func__, gfn,
+ pgprintk("%s: gfn %llx role %x\n", __func__, gfn,
sp->role.word);
r = 1;
kvm_mmu_prepare_zap_page(kvm, sp, &invalid_list);
@@ -1729,7 +1776,7 @@ static void mmu_unshadow(struct kvm *kvm, gfn_t gfn)
LIST_HEAD(invalid_list);
for_each_gfn_indirect_valid_sp(kvm, sp, gfn, node) {
- pgprintk("%s: zap %lx %x\n",
+ pgprintk("%s: zap %llx %x\n",
__func__, gfn, sp->role.word);
kvm_mmu_prepare_zap_page(kvm, sp, &invalid_list);
}
@@ -1925,7 +1972,7 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
* whether the guest actually used the pte (in order to detect
* demand paging).
*/
- spte = shadow_base_present_pte | shadow_dirty_mask;
+ spte = shadow_base_present_pte;
if (!speculative)
spte |= shadow_accessed_mask;
if (!dirty)
@@ -1948,8 +1995,8 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
spte |= (u64)pfn << PAGE_SHIFT;
if ((pte_access & ACC_WRITE_MASK)
- || (!tdp_enabled && write_fault && !is_write_protection(vcpu)
- && !user_fault)) {
+ || (!vcpu->arch.mmu.direct_map && write_fault
+ && !is_write_protection(vcpu) && !user_fault)) {
if (level > PT_PAGE_TABLE_LEVEL &&
has_wrprotected_page(vcpu->kvm, gfn, level)) {
@@ -1960,7 +2007,8 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
spte |= PT_WRITABLE_MASK;
- if (!tdp_enabled && !(pte_access & ACC_WRITE_MASK))
+ if (!vcpu->arch.mmu.direct_map
+ && !(pte_access & ACC_WRITE_MASK))
spte &= ~PT_USER_MASK;
/*
@@ -1973,7 +2021,7 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
goto set_pte;
if (mmu_need_write_protect(vcpu, gfn, can_unsync)) {
- pgprintk("%s: found shadow page for %lx, marking ro\n",
+ pgprintk("%s: found shadow page for %llx, marking ro\n",
__func__, gfn);
ret = 1;
pte_access &= ~ACC_WRITE_MASK;
@@ -1986,8 +2034,6 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
mark_page_dirty(vcpu->kvm, gfn);
set_pte:
- if (is_writable_pte(*sptep) && !is_writable_pte(spte))
- kvm_set_pfn_dirty(pfn);
update_spte(sptep, spte);
done:
return ret;
@@ -2004,7 +2050,7 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
int rmap_count;
pgprintk("%s: spte %llx access %x write_fault %d"
- " user_fault %d gfn %lx\n",
+ " user_fault %d gfn %llx\n",
__func__, *sptep, pt_access,
write_fault, user_fault, gfn);
@@ -2023,7 +2069,7 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
__set_spte(sptep, shadow_trap_nonpresent_pte);
kvm_flush_remote_tlbs(vcpu->kvm);
} else if (pfn != spte_to_pfn(*sptep)) {
- pgprintk("hfn old %lx new %lx\n",
+ pgprintk("hfn old %llx new %llx\n",
spte_to_pfn(*sptep), pfn);
drop_spte(vcpu->kvm, sptep, shadow_trap_nonpresent_pte);
kvm_flush_remote_tlbs(vcpu->kvm);
@@ -2040,7 +2086,7 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
}
pgprintk("%s: setting spte %llx\n", __func__, *sptep);
- pgprintk("instantiating %s PTE (%s) at %ld (%llx) addr %p\n",
+ pgprintk("instantiating %s PTE (%s) at %llx (%llx) addr %p\n",
is_large_pte(*sptep)? "2MB" : "4kB",
*sptep & PT_PRESENT_MASK ?"RW":"R", gfn,
*sptep, sptep);
@@ -2064,6 +2110,105 @@ static void nonpaging_new_cr3(struct kvm_vcpu *vcpu)
{
}
+static struct kvm_memory_slot *
+pte_prefetch_gfn_to_memslot(struct kvm_vcpu *vcpu, gfn_t gfn, bool no_dirty_log)
+{
+ struct kvm_memory_slot *slot;
+
+ slot = gfn_to_memslot(vcpu->kvm, gfn);
+ if (!slot || slot->flags & KVM_MEMSLOT_INVALID ||
+ (no_dirty_log && slot->dirty_bitmap))
+ slot = NULL;
+
+ return slot;
+}
+
+static pfn_t pte_prefetch_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn,
+ bool no_dirty_log)
+{
+ struct kvm_memory_slot *slot;
+ unsigned long hva;
+
+ slot = pte_prefetch_gfn_to_memslot(vcpu, gfn, no_dirty_log);
+ if (!slot) {
+ get_page(bad_page);
+ return page_to_pfn(bad_page);
+ }
+
+ hva = gfn_to_hva_memslot(slot, gfn);
+
+ return hva_to_pfn_atomic(vcpu->kvm, hva);
+}
+
+static int direct_pte_prefetch_many(struct kvm_vcpu *vcpu,
+ struct kvm_mmu_page *sp,
+ u64 *start, u64 *end)
+{
+ struct page *pages[PTE_PREFETCH_NUM];
+ unsigned access = sp->role.access;
+ int i, ret;
+ gfn_t gfn;
+
+ gfn = kvm_mmu_page_get_gfn(sp, start - sp->spt);
+ if (!pte_prefetch_gfn_to_memslot(vcpu, gfn, access & ACC_WRITE_MASK))
+ return -1;
+
+ ret = gfn_to_page_many_atomic(vcpu->kvm, gfn, pages, end - start);
+ if (ret <= 0)
+ return -1;
+
+ for (i = 0; i < ret; i++, gfn++, start++)
+ mmu_set_spte(vcpu, start, ACC_ALL,
+ access, 0, 0, 1, NULL,
+ sp->role.level, gfn,
+ page_to_pfn(pages[i]), true, true);
+
+ return 0;
+}
+
+static void __direct_pte_prefetch(struct kvm_vcpu *vcpu,
+ struct kvm_mmu_page *sp, u64 *sptep)
+{
+ u64 *spte, *start = NULL;
+ int i;
+
+ WARN_ON(!sp->role.direct);
+
+ i = (sptep - sp->spt) & ~(PTE_PREFETCH_NUM - 1);
+ spte = sp->spt + i;
+
+ for (i = 0; i < PTE_PREFETCH_NUM; i++, spte++) {
+ if (*spte != shadow_trap_nonpresent_pte || spte == sptep) {
+ if (!start)
+ continue;
+ if (direct_pte_prefetch_many(vcpu, sp, start, spte) < 0)
+ break;
+ start = NULL;
+ } else if (!start)
+ start = spte;
+ }
+}
+
+static void direct_pte_prefetch(struct kvm_vcpu *vcpu, u64 *sptep)
+{
+ struct kvm_mmu_page *sp;
+
+ /*
+ * Since it's no accessed bit on EPT, it's no way to
+ * distinguish between actually accessed translations
+ * and prefetched, so disable pte prefetch if EPT is
+ * enabled.
+ */
+ if (!shadow_accessed_mask)
+ return;
+
+ sp = page_header(__pa(sptep));
+ if (sp->role.level > PT_PAGE_TABLE_LEVEL)
+ return;
+
+ __direct_pte_prefetch(vcpu, sp, sptep);
+}
+
static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
int level, gfn_t gfn, pfn_t pfn)
{
@@ -2077,6 +2222,7 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
mmu_set_spte(vcpu, iterator.sptep, ACC_ALL, ACC_ALL,
0, write, 1, &pt_write,
level, gfn, pfn, false, true);
+ direct_pte_prefetch(vcpu, iterator.sptep);
++vcpu->stat.pf_fixed;
break;
}
@@ -2098,28 +2244,31 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
__set_spte(iterator.sptep,
__pa(sp->spt)
| PT_PRESENT_MASK | PT_WRITABLE_MASK
- | shadow_user_mask | shadow_x_mask);
+ | shadow_user_mask | shadow_x_mask
+ | shadow_accessed_mask);
}
}
return pt_write;
}
-static void kvm_send_hwpoison_signal(struct kvm *kvm, gfn_t gfn)
+static void kvm_send_hwpoison_signal(unsigned long address, struct task_struct *tsk)
{
- char buf[1];
- void __user *hva;
- int r;
+ siginfo_t info;
+
+ info.si_signo = SIGBUS;
+ info.si_errno = 0;
+ info.si_code = BUS_MCEERR_AR;
+ info.si_addr = (void __user *)address;
+ info.si_addr_lsb = PAGE_SHIFT;
- /* Touch the page, so send SIGBUS */
- hva = (void __user *)gfn_to_hva(kvm, gfn);
- r = copy_from_user(buf, hva, 1);
+ send_sig_info(SIGBUS, &info, tsk);
}
static int kvm_handle_bad_page(struct kvm *kvm, gfn_t gfn, pfn_t pfn)
{
kvm_release_pfn_clean(pfn);
if (is_hwpoison_pfn(pfn)) {
- kvm_send_hwpoison_signal(kvm, gfn);
+ kvm_send_hwpoison_signal(gfn_to_hva(kvm, gfn), current);
return 0;
} else if (is_fault_pfn(pfn))
return -EFAULT;
@@ -2179,7 +2328,9 @@ static void mmu_free_roots(struct kvm_vcpu *vcpu)
if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
return;
spin_lock(&vcpu->kvm->mmu_lock);
- if (vcpu->arch.mmu.shadow_root_level == PT64_ROOT_LEVEL) {
+ if (vcpu->arch.mmu.shadow_root_level == PT64_ROOT_LEVEL &&
+ (vcpu->arch.mmu.root_level == PT64_ROOT_LEVEL ||
+ vcpu->arch.mmu.direct_map)) {
hpa_t root = vcpu->arch.mmu.root_hpa;
sp = page_header(root);
@@ -2222,80 +2373,158 @@ static int mmu_check_root(struct kvm_vcpu *vcpu, gfn_t root_gfn)
return ret;
}
-static int mmu_alloc_roots(struct kvm_vcpu *vcpu)
+static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu)
{
- int i;
- gfn_t root_gfn;
struct kvm_mmu_page *sp;
- int direct = 0;
- u64 pdptr;
-
- root_gfn = vcpu->arch.cr3 >> PAGE_SHIFT;
+ unsigned i;
if (vcpu->arch.mmu.shadow_root_level == PT64_ROOT_LEVEL) {
+ spin_lock(&vcpu->kvm->mmu_lock);
+ kvm_mmu_free_some_pages(vcpu);
+ sp = kvm_mmu_get_page(vcpu, 0, 0, PT64_ROOT_LEVEL,
+ 1, ACC_ALL, NULL);
+ ++sp->root_count;
+ spin_unlock(&vcpu->kvm->mmu_lock);
+ vcpu->arch.mmu.root_hpa = __pa(sp->spt);
+ } else if (vcpu->arch.mmu.shadow_root_level == PT32E_ROOT_LEVEL) {
+ for (i = 0; i < 4; ++i) {
+ hpa_t root = vcpu->arch.mmu.pae_root[i];
+
+ ASSERT(!VALID_PAGE(root));
+ spin_lock(&vcpu->kvm->mmu_lock);
+ kvm_mmu_free_some_pages(vcpu);
+ sp = kvm_mmu_get_page(vcpu, i << 30, i << 30,
+ PT32_ROOT_LEVEL, 1, ACC_ALL,
+ NULL);
+ root = __pa(sp->spt);
+ ++sp->root_count;
+ spin_unlock(&vcpu->kvm->mmu_lock);
+ vcpu->arch.mmu.pae_root[i] = root | PT_PRESENT_MASK;
+ }
+ vcpu->arch.mmu.root_hpa = __pa(vcpu->arch.mmu.pae_root);
+ } else
+ BUG();
+
+ return 0;
+}
+
+static int mmu_alloc_shadow_roots(struct kvm_vcpu *vcpu)
+{
+ struct kvm_mmu_page *sp;
+ u64 pdptr, pm_mask;
+ gfn_t root_gfn;
+ int i;
+
+ root_gfn = vcpu->arch.mmu.get_cr3(vcpu) >> PAGE_SHIFT;
+
+ if (mmu_check_root(vcpu, root_gfn))
+ return 1;
+
+ /*
+ * Do we shadow a long mode page table? If so we need to
+ * write-protect the guests page table root.
+ */
+ if (vcpu->arch.mmu.root_level == PT64_ROOT_LEVEL) {
hpa_t root = vcpu->arch.mmu.root_hpa;
ASSERT(!VALID_PAGE(root));
- if (mmu_check_root(vcpu, root_gfn))
- return 1;
- if (tdp_enabled) {
- direct = 1;
- root_gfn = 0;
- }
+
spin_lock(&vcpu->kvm->mmu_lock);
kvm_mmu_free_some_pages(vcpu);
- sp = kvm_mmu_get_page(vcpu, root_gfn, 0,
- PT64_ROOT_LEVEL, direct,
- ACC_ALL, NULL);
+ sp = kvm_mmu_get_page(vcpu, root_gfn, 0, PT64_ROOT_LEVEL,
+ 0, ACC_ALL, NULL);
root = __pa(sp->spt);
++sp->root_count;
spin_unlock(&vcpu->kvm->mmu_lock);
vcpu->arch.mmu.root_hpa = root;
return 0;
}
- direct = !is_paging(vcpu);
+
+ /*
+ * We shadow a 32 bit page table. This may be a legacy 2-level
+ * or a PAE 3-level page table. In either case we need to be aware that
+ * the shadow page table may be a PAE or a long mode page table.
+ */
+ pm_mask = PT_PRESENT_MASK;
+ if (vcpu->arch.mmu.shadow_root_level == PT64_ROOT_LEVEL)
+ pm_mask |= PT_ACCESSED_MASK | PT_WRITABLE_MASK | PT_USER_MASK;
+
for (i = 0; i < 4; ++i) {
hpa_t root = vcpu->arch.mmu.pae_root[i];
ASSERT(!VALID_PAGE(root));
if (vcpu->arch.mmu.root_level == PT32E_ROOT_LEVEL) {
- pdptr = kvm_pdptr_read(vcpu, i);
+ pdptr = kvm_pdptr_read_mmu(vcpu, &vcpu->arch.mmu, i);
if (!is_present_gpte(pdptr)) {
vcpu->arch.mmu.pae_root[i] = 0;
continue;
}
root_gfn = pdptr >> PAGE_SHIFT;
- } else if (vcpu->arch.mmu.root_level == 0)
- root_gfn = 0;
- if (mmu_check_root(vcpu, root_gfn))
- return 1;
- if (tdp_enabled) {
- direct = 1;
- root_gfn = i << 30;
+ if (mmu_check_root(vcpu, root_gfn))
+ return 1;
}
spin_lock(&vcpu->kvm->mmu_lock);
kvm_mmu_free_some_pages(vcpu);
sp = kvm_mmu_get_page(vcpu, root_gfn, i << 30,
- PT32_ROOT_LEVEL, direct,
+ PT32_ROOT_LEVEL, 0,
ACC_ALL, NULL);
root = __pa(sp->spt);
++sp->root_count;
spin_unlock(&vcpu->kvm->mmu_lock);
- vcpu->arch.mmu.pae_root[i] = root | PT_PRESENT_MASK;
+ vcpu->arch.mmu.pae_root[i] = root | pm_mask;
}
vcpu->arch.mmu.root_hpa = __pa(vcpu->arch.mmu.pae_root);
+
+ /*
+ * If we shadow a 32 bit page table with a long mode page
+ * table we enter this path.
+ */
+ if (vcpu->arch.mmu.shadow_root_level == PT64_ROOT_LEVEL) {
+ if (vcpu->arch.mmu.lm_root == NULL) {
+ /*
+ * The additional page necessary for this is only
+ * allocated on demand.
+ */
+
+ u64 *lm_root;
+
+ lm_root = (void*)get_zeroed_page(GFP_KERNEL);
+ if (lm_root == NULL)
+ return 1;
+
+ lm_root[0] = __pa(vcpu->arch.mmu.pae_root) | pm_mask;
+
+ vcpu->arch.mmu.lm_root = lm_root;
+ }
+
+ vcpu->arch.mmu.root_hpa = __pa(vcpu->arch.mmu.lm_root);
+ }
+
return 0;
}
+static int mmu_alloc_roots(struct kvm_vcpu *vcpu)
+{
+ if (vcpu->arch.mmu.direct_map)
+ return mmu_alloc_direct_roots(vcpu);
+ else
+ return mmu_alloc_shadow_roots(vcpu);
+}
+
static void mmu_sync_roots(struct kvm_vcpu *vcpu)
{
int i;
struct kvm_mmu_page *sp;
+ if (vcpu->arch.mmu.direct_map)
+ return;
+
if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
return;
- if (vcpu->arch.mmu.shadow_root_level == PT64_ROOT_LEVEL) {
+
+ trace_kvm_mmu_audit(vcpu, AUDIT_PRE_SYNC);
+ if (vcpu->arch.mmu.root_level == PT64_ROOT_LEVEL) {
hpa_t root = vcpu->arch.mmu.root_hpa;
sp = page_header(root);
mmu_sync_children(vcpu, sp);
@@ -2310,6 +2539,7 @@ static void mmu_sync_roots(struct kvm_vcpu *vcpu)
mmu_sync_children(vcpu, sp);
}
}
+ trace_kvm_mmu_audit(vcpu, AUDIT_POST_SYNC);
}
void kvm_mmu_sync_roots(struct kvm_vcpu *vcpu)
@@ -2327,6 +2557,14 @@ static gpa_t nonpaging_gva_to_gpa(struct kvm_vcpu *vcpu, gva_t vaddr,
return vaddr;
}
+static gpa_t nonpaging_gva_to_gpa_nested(struct kvm_vcpu *vcpu, gva_t vaddr,
+ u32 access, u32 *error)
+{
+ if (error)
+ *error = 0;
+ return vcpu->arch.nested_mmu.translate_gpa(vcpu, vaddr, access);
+}
+
static int nonpaging_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
u32 error_code)
{
@@ -2393,10 +2631,9 @@ static void nonpaging_free(struct kvm_vcpu *vcpu)
mmu_free_roots(vcpu);
}
-static int nonpaging_init_context(struct kvm_vcpu *vcpu)
+static int nonpaging_init_context(struct kvm_vcpu *vcpu,
+ struct kvm_mmu *context)
{
- struct kvm_mmu *context = &vcpu->arch.mmu;
-
context->new_cr3 = nonpaging_new_cr3;
context->page_fault = nonpaging_page_fault;
context->gva_to_gpa = nonpaging_gva_to_gpa;
@@ -2407,6 +2644,8 @@ static int nonpaging_init_context(struct kvm_vcpu *vcpu)
context->root_level = 0;
context->shadow_root_level = PT32E_ROOT_LEVEL;
context->root_hpa = INVALID_PAGE;
+ context->direct_map = true;
+ context->nx = false;
return 0;
}
@@ -2422,11 +2661,14 @@ static void paging_new_cr3(struct kvm_vcpu *vcpu)
mmu_free_roots(vcpu);
}
-static void inject_page_fault(struct kvm_vcpu *vcpu,
- u64 addr,
- u32 err_code)
+static unsigned long get_cr3(struct kvm_vcpu *vcpu)
+{
+ return vcpu->arch.cr3;
+}
+
+static void inject_page_fault(struct kvm_vcpu *vcpu)
{
- kvm_inject_page_fault(vcpu, addr, err_code);
+ vcpu->arch.mmu.inject_page_fault(vcpu);
}
static void paging_free(struct kvm_vcpu *vcpu)
@@ -2434,12 +2676,12 @@ static void paging_free(struct kvm_vcpu *vcpu)
nonpaging_free(vcpu);
}
-static bool is_rsvd_bits_set(struct kvm_vcpu *vcpu, u64 gpte, int level)
+static bool is_rsvd_bits_set(struct kvm_mmu *mmu, u64 gpte, int level)
{
int bit7;
bit7 = (gpte >> 7) & 1;
- return (gpte & vcpu->arch.mmu.rsvd_bits_mask[bit7][level-1]) != 0;
+ return (gpte & mmu->rsvd_bits_mask[bit7][level-1]) != 0;
}
#define PTTYPE 64
@@ -2450,13 +2692,14 @@ static bool is_rsvd_bits_set(struct kvm_vcpu *vcpu, u64 gpte, int level)
#include "paging_tmpl.h"
#undef PTTYPE
-static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, int level)
+static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu,
+ struct kvm_mmu *context,
+ int level)
{
- struct kvm_mmu *context = &vcpu->arch.mmu;
int maxphyaddr = cpuid_maxphyaddr(vcpu);
u64 exb_bit_rsvd = 0;
- if (!is_nx(vcpu))
+ if (!context->nx)
exb_bit_rsvd = rsvd_bits(63, 63);
switch (level) {
case PT32_ROOT_LEVEL:
@@ -2511,9 +2754,13 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, int level)
}
}
-static int paging64_init_context_common(struct kvm_vcpu *vcpu, int level)
+static int paging64_init_context_common(struct kvm_vcpu *vcpu,
+ struct kvm_mmu *context,
+ int level)
{
- struct kvm_mmu *context = &vcpu->arch.mmu;
+ context->nx = is_nx(vcpu);
+
+ reset_rsvds_bits_mask(vcpu, context, level);
ASSERT(is_pae(vcpu));
context->new_cr3 = paging_new_cr3;
@@ -2526,20 +2773,23 @@ static int paging64_init_context_common(struct kvm_vcpu *vcpu, int level)
context->root_level = level;
context->shadow_root_level = level;
context->root_hpa = INVALID_PAGE;
+ context->direct_map = false;
return 0;
}
-static int paging64_init_context(struct kvm_vcpu *vcpu)
+static int paging64_init_context(struct kvm_vcpu *vcpu,
+ struct kvm_mmu *context)
{
- reset_rsvds_bits_mask(vcpu, PT64_ROOT_LEVEL);
- return paging64_init_context_common(vcpu, PT64_ROOT_LEVEL);
+ return paging64_init_context_common(vcpu, context, PT64_ROOT_LEVEL);
}
-static int paging32_init_context(struct kvm_vcpu *vcpu)
+static int paging32_init_context(struct kvm_vcpu *vcpu,
+ struct kvm_mmu *context)
{
- struct kvm_mmu *context = &vcpu->arch.mmu;
+ context->nx = false;
+
+ reset_rsvds_bits_mask(vcpu, context, PT32_ROOT_LEVEL);
- reset_rsvds_bits_mask(vcpu, PT32_ROOT_LEVEL);
context->new_cr3 = paging_new_cr3;
context->page_fault = paging32_page_fault;
context->gva_to_gpa = paging32_gva_to_gpa;
@@ -2550,18 +2800,19 @@ static int paging32_init_context(struct kvm_vcpu *vcpu)
context->root_level = PT32_ROOT_LEVEL;
context->shadow_root_level = PT32E_ROOT_LEVEL;
context->root_hpa = INVALID_PAGE;
+ context->direct_map = false;
return 0;
}
-static int paging32E_init_context(struct kvm_vcpu *vcpu)
+static int paging32E_init_context(struct kvm_vcpu *vcpu,
+ struct kvm_mmu *context)
{
- reset_rsvds_bits_mask(vcpu, PT32E_ROOT_LEVEL);
- return paging64_init_context_common(vcpu, PT32E_ROOT_LEVEL);
+ return paging64_init_context_common(vcpu, context, PT32E_ROOT_LEVEL);
}
static int init_kvm_tdp_mmu(struct kvm_vcpu *vcpu)
{
- struct kvm_mmu *context = &vcpu->arch.mmu;
+ struct kvm_mmu *context = vcpu->arch.walk_mmu;
context->new_cr3 = nonpaging_new_cr3;
context->page_fault = tdp_page_fault;
@@ -2571,20 +2822,29 @@ static int init_kvm_tdp_mmu(struct kvm_vcpu *vcpu)
context->invlpg = nonpaging_invlpg;
context->shadow_root_level = kvm_x86_ops->get_tdp_level();
context->root_hpa = INVALID_PAGE;
+ context->direct_map = true;
+ context->set_cr3 = kvm_x86_ops->set_tdp_cr3;
+ context->get_cr3 = get_cr3;
+ context->inject_page_fault = kvm_inject_page_fault;
+ context->nx = is_nx(vcpu);
if (!is_paging(vcpu)) {
+ context->nx = false;
context->gva_to_gpa = nonpaging_gva_to_gpa;
context->root_level = 0;
} else if (is_long_mode(vcpu)) {
- reset_rsvds_bits_mask(vcpu, PT64_ROOT_LEVEL);
+ context->nx = is_nx(vcpu);
+ reset_rsvds_bits_mask(vcpu, context, PT64_ROOT_LEVEL);
context->gva_to_gpa = paging64_gva_to_gpa;
context->root_level = PT64_ROOT_LEVEL;
} else if (is_pae(vcpu)) {
- reset_rsvds_bits_mask(vcpu, PT32E_ROOT_LEVEL);
+ context->nx = is_nx(vcpu);
+ reset_rsvds_bits_mask(vcpu, context, PT32E_ROOT_LEVEL);
context->gva_to_gpa = paging64_gva_to_gpa;
context->root_level = PT32E_ROOT_LEVEL;
} else {
- reset_rsvds_bits_mask(vcpu, PT32_ROOT_LEVEL);
+ context->nx = false;
+ reset_rsvds_bits_mask(vcpu, context, PT32_ROOT_LEVEL);
context->gva_to_gpa = paging32_gva_to_gpa;
context->root_level = PT32_ROOT_LEVEL;
}
@@ -2592,33 +2852,83 @@ static int init_kvm_tdp_mmu(struct kvm_vcpu *vcpu)
return 0;
}
-static int init_kvm_softmmu(struct kvm_vcpu *vcpu)
+int kvm_init_shadow_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context)
{
int r;
-
ASSERT(vcpu);
ASSERT(!VALID_PAGE(vcpu->arch.mmu.root_hpa));
if (!is_paging(vcpu))
- r = nonpaging_init_context(vcpu);
+ r = nonpaging_init_context(vcpu, context);
else if (is_long_mode(vcpu))
- r = paging64_init_context(vcpu);
+ r = paging64_init_context(vcpu, context);
else if (is_pae(vcpu))
- r = paging32E_init_context(vcpu);
+ r = paging32E_init_context(vcpu, context);
else
- r = paging32_init_context(vcpu);
+ r = paging32_init_context(vcpu, context);
vcpu->arch.mmu.base_role.cr4_pae = !!is_pae(vcpu);
- vcpu->arch.mmu.base_role.cr0_wp = is_write_protection(vcpu);
+ vcpu->arch.mmu.base_role.cr0_wp = is_write_protection(vcpu);
return r;
}
+EXPORT_SYMBOL_GPL(kvm_init_shadow_mmu);
+
+static int init_kvm_softmmu(struct kvm_vcpu *vcpu)
+{
+ int r = kvm_init_shadow_mmu(vcpu, vcpu->arch.walk_mmu);
+
+ vcpu->arch.walk_mmu->set_cr3 = kvm_x86_ops->set_cr3;
+ vcpu->arch.walk_mmu->get_cr3 = get_cr3;
+ vcpu->arch.walk_mmu->inject_page_fault = kvm_inject_page_fault;
+
+ return r;
+}
+
+static int init_kvm_nested_mmu(struct kvm_vcpu *vcpu)
+{
+ struct kvm_mmu *g_context = &vcpu->arch.nested_mmu;
+
+ g_context->get_cr3 = get_cr3;
+ g_context->inject_page_fault = kvm_inject_page_fault;
+
+ /*
+ * Note that arch.mmu.gva_to_gpa translates l2_gva to l1_gpa. The
+ * translation of l2_gpa to l1_gpa addresses is done using the
+ * arch.nested_mmu.gva_to_gpa function. Basically the gva_to_gpa
+ * functions between mmu and nested_mmu are swapped.
+ */
+ if (!is_paging(vcpu)) {
+ g_context->nx = false;
+ g_context->root_level = 0;
+ g_context->gva_to_gpa = nonpaging_gva_to_gpa_nested;
+ } else if (is_long_mode(vcpu)) {
+ g_context->nx = is_nx(vcpu);
+ reset_rsvds_bits_mask(vcpu, g_context, PT64_ROOT_LEVEL);
+ g_context->root_level = PT64_ROOT_LEVEL;
+ g_context->gva_to_gpa = paging64_gva_to_gpa_nested;
+ } else if (is_pae(vcpu)) {
+ g_context->nx = is_nx(vcpu);
+ reset_rsvds_bits_mask(vcpu, g_context, PT32E_ROOT_LEVEL);
+ g_context->root_level = PT32E_ROOT_LEVEL;
+ g_context->gva_to_gpa = paging64_gva_to_gpa_nested;
+ } else {
+ g_context->nx = false;
+ reset_rsvds_bits_mask(vcpu, g_context, PT32_ROOT_LEVEL);
+ g_context->root_level = PT32_ROOT_LEVEL;
+ g_context->gva_to_gpa = paging32_gva_to_gpa_nested;
+ }
+
+ return 0;
+}
static int init_kvm_mmu(struct kvm_vcpu *vcpu)
{
vcpu->arch.update_pte.pfn = bad_pfn;
- if (tdp_enabled)
+ if (mmu_is_nested(vcpu))
+ return init_kvm_nested_mmu(vcpu);
+ else if (tdp_enabled)
return init_kvm_tdp_mmu(vcpu);
else
return init_kvm_softmmu(vcpu);
@@ -2653,7 +2963,7 @@ int kvm_mmu_load(struct kvm_vcpu *vcpu)
if (r)
goto out;
/* set_cr3() should ensure TLB has been flushed */
- kvm_x86_ops->set_cr3(vcpu, vcpu->arch.mmu.root_hpa);
+ vcpu->arch.mmu.set_cr3(vcpu, vcpu->arch.mmu.root_hpa);
out:
return r;
}
@@ -2663,6 +2973,7 @@ void kvm_mmu_unload(struct kvm_vcpu *vcpu)
{
mmu_free_roots(vcpu);
}
+EXPORT_SYMBOL_GPL(kvm_mmu_unload);
static void mmu_pte_write_zap_pte(struct kvm_vcpu *vcpu,
struct kvm_mmu_page *sp,
@@ -2695,7 +3006,7 @@ static void mmu_pte_write_new_pte(struct kvm_vcpu *vcpu,
return;
}
- if (is_rsvd_bits_set(vcpu, *(u64 *)new, PT_PAGE_TABLE_LEVEL))
+ if (is_rsvd_bits_set(&vcpu->arch.mmu, *(u64 *)new, PT_PAGE_TABLE_LEVEL))
return;
++vcpu->kvm->stat.mmu_pte_updated;
@@ -2837,7 +3148,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
kvm_mmu_access_page(vcpu, gfn);
kvm_mmu_free_some_pages(vcpu);
++vcpu->kvm->stat.mmu_pte_write;
- kvm_mmu_audit(vcpu, "pre pte write");
+ trace_kvm_mmu_audit(vcpu, AUDIT_PRE_PTE_WRITE);
if (guest_initiated) {
if (gfn == vcpu->arch.last_pt_write_gfn
&& !last_updated_pte_accessed(vcpu)) {
@@ -2910,7 +3221,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
}
mmu_pte_write_flush_tlb(vcpu, zap_page, remote_flush, local_flush);
kvm_mmu_commit_zap_page(vcpu->kvm, &invalid_list);
- kvm_mmu_audit(vcpu, "post pte write");
+ trace_kvm_mmu_audit(vcpu, AUDIT_POST_PTE_WRITE);
spin_unlock(&vcpu->kvm->mmu_lock);
if (!is_error_pfn(vcpu->arch.update_pte.pfn)) {
kvm_release_pfn_clean(vcpu->arch.update_pte.pfn);
@@ -2923,7 +3234,7 @@ int kvm_mmu_unprotect_page_virt(struct kvm_vcpu *vcpu, gva_t gva)
gpa_t gpa;
int r;
- if (tdp_enabled)
+ if (vcpu->arch.mmu.direct_map)
return 0;
gpa = kvm_mmu_gva_to_gpa_read(vcpu, gva, NULL);
@@ -2937,21 +3248,18 @@ EXPORT_SYMBOL_GPL(kvm_mmu_unprotect_page_virt);
void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
{
- int free_pages;
LIST_HEAD(invalid_list);
- free_pages = vcpu->kvm->arch.n_free_mmu_pages;
- while (free_pages < KVM_REFILL_PAGES &&
+ while (kvm_mmu_available_pages(vcpu->kvm) < KVM_REFILL_PAGES &&
!list_empty(&vcpu->kvm->arch.active_mmu_pages)) {
struct kvm_mmu_page *sp;
sp = container_of(vcpu->kvm->arch.active_mmu_pages.prev,
struct kvm_mmu_page, link);
- free_pages += kvm_mmu_prepare_zap_page(vcpu->kvm, sp,
- &invalid_list);
+ kvm_mmu_prepare_zap_page(vcpu->kvm, sp, &invalid_list);
+ kvm_mmu_commit_zap_page(vcpu->kvm, &invalid_list);
++vcpu->kvm->stat.mmu_recycled;
}
- kvm_mmu_commit_zap_page(vcpu->kvm, &invalid_list);
}
int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t cr2, u32 error_code)
@@ -3013,6 +3321,8 @@ EXPORT_SYMBOL_GPL(kvm_disable_tdp);
static void free_mmu_pages(struct kvm_vcpu *vcpu)
{
free_page((unsigned long)vcpu->arch.mmu.pae_root);
+ if (vcpu->arch.mmu.lm_root != NULL)
+ free_page((unsigned long)vcpu->arch.mmu.lm_root);
}
static int alloc_mmu_pages(struct kvm_vcpu *vcpu)
@@ -3054,15 +3364,6 @@ int kvm_mmu_setup(struct kvm_vcpu *vcpu)
return init_kvm_mmu(vcpu);
}
-void kvm_mmu_destroy(struct kvm_vcpu *vcpu)
-{
- ASSERT(vcpu);
-
- destroy_kvm_mmu(vcpu);
- free_mmu_pages(vcpu);
- mmu_free_memory_caches(vcpu);
-}
-
void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot)
{
struct kvm_mmu_page *sp;
@@ -3112,23 +3413,22 @@ static int mmu_shrink(struct shrinker *shrink, int nr_to_scan, gfp_t gfp_mask)
{
struct kvm *kvm;
struct kvm *kvm_freed = NULL;
- int cache_count = 0;
+
+ if (nr_to_scan == 0)
+ goto out;
spin_lock(&kvm_lock);
list_for_each_entry(kvm, &vm_list, vm_list) {
- int npages, idx, freed_pages;
+ int idx, freed_pages;
LIST_HEAD(invalid_list);
idx = srcu_read_lock(&kvm->srcu);
spin_lock(&kvm->mmu_lock);
- npages = kvm->arch.n_alloc_mmu_pages -
- kvm->arch.n_free_mmu_pages;
- cache_count += npages;
- if (!kvm_freed && nr_to_scan > 0 && npages > 0) {
+ if (!kvm_freed && nr_to_scan > 0 &&
+ kvm->arch.n_used_mmu_pages > 0) {
freed_pages = kvm_mmu_remove_some_alloc_mmu_pages(kvm,
&invalid_list);
- cache_count -= freed_pages;
kvm_freed = kvm;
}
nr_to_scan--;
@@ -3142,7 +3442,8 @@ static int mmu_shrink(struct shrinker *shrink, int nr_to_scan, gfp_t gfp_mask)
spin_unlock(&kvm_lock);
- return cache_count;
+out:
+ return percpu_counter_read_positive(&kvm_total_used_mmu_pages);
}
static struct shrinker mmu_shrinker = {
@@ -3163,6 +3464,7 @@ static void mmu_destroy_caches(void)
void kvm_mmu_module_exit(void)
{
mmu_destroy_caches();
+ percpu_counter_destroy(&kvm_total_used_mmu_pages);
unregister_shrinker(&mmu_shrinker);
}
@@ -3185,6 +3487,9 @@ int kvm_mmu_module_init(void)
if (!mmu_page_header_cache)
goto nomem;
+ if (percpu_counter_init(&kvm_total_used_mmu_pages, 0))
+ goto nomem;
+
register_shrinker(&mmu_shrinker);
return 0;
@@ -3355,271 +3660,18 @@ int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4])
}
EXPORT_SYMBOL_GPL(kvm_mmu_get_spte_hierarchy);
-#ifdef AUDIT
-
-static const char *audit_msg;
-
-static gva_t canonicalize(gva_t gva)
-{
-#ifdef CONFIG_X86_64
- gva = (long long)(gva << 16) >> 16;
+#ifdef CONFIG_KVM_MMU_AUDIT
+#include "mmu_audit.c"
+#else
+static void mmu_audit_disable(void) { }
#endif
- return gva;
-}
-
-
-typedef void (*inspect_spte_fn) (struct kvm *kvm, u64 *sptep);
-
-static void __mmu_spte_walk(struct kvm *kvm, struct kvm_mmu_page *sp,
- inspect_spte_fn fn)
-{
- int i;
-
- for (i = 0; i < PT64_ENT_PER_PAGE; ++i) {
- u64 ent = sp->spt[i];
-
- if (is_shadow_present_pte(ent)) {
- if (!is_last_spte(ent, sp->role.level)) {
- struct kvm_mmu_page *child;
- child = page_header(ent & PT64_BASE_ADDR_MASK);
- __mmu_spte_walk(kvm, child, fn);
- } else
- fn(kvm, &sp->spt[i]);
- }
- }
-}
-
-static void mmu_spte_walk(struct kvm_vcpu *vcpu, inspect_spte_fn fn)
-{
- int i;
- struct kvm_mmu_page *sp;
-
- if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
- return;
- if (vcpu->arch.mmu.shadow_root_level == PT64_ROOT_LEVEL) {
- hpa_t root = vcpu->arch.mmu.root_hpa;
- sp = page_header(root);
- __mmu_spte_walk(vcpu->kvm, sp, fn);
- return;
- }
- for (i = 0; i < 4; ++i) {
- hpa_t root = vcpu->arch.mmu.pae_root[i];
-
- if (root && VALID_PAGE(root)) {
- root &= PT64_BASE_ADDR_MASK;
- sp = page_header(root);
- __mmu_spte_walk(vcpu->kvm, sp, fn);
- }
- }
- return;
-}
-
-static void audit_mappings_page(struct kvm_vcpu *vcpu, u64 page_pte,
- gva_t va, int level)
-{
- u64 *pt = __va(page_pte & PT64_BASE_ADDR_MASK);
- int i;
- gva_t va_delta = 1ul << (PAGE_SHIFT + 9 * (level - 1));
-
- for (i = 0; i < PT64_ENT_PER_PAGE; ++i, va += va_delta) {
- u64 ent = pt[i];
-
- if (ent == shadow_trap_nonpresent_pte)
- continue;
-
- va = canonicalize(va);
- if (is_shadow_present_pte(ent) && !is_last_spte(ent, level))
- audit_mappings_page(vcpu, ent, va, level - 1);
- else {
- gpa_t gpa = kvm_mmu_gva_to_gpa_read(vcpu, va, NULL);
- gfn_t gfn = gpa >> PAGE_SHIFT;
- pfn_t pfn = gfn_to_pfn(vcpu->kvm, gfn);
- hpa_t hpa = (hpa_t)pfn << PAGE_SHIFT;
- if (is_error_pfn(pfn)) {
- kvm_release_pfn_clean(pfn);
- continue;
- }
-
- if (is_shadow_present_pte(ent)
- && (ent & PT64_BASE_ADDR_MASK) != hpa)
- printk(KERN_ERR "xx audit error: (%s) levels %d"
- " gva %lx gpa %llx hpa %llx ent %llx %d\n",
- audit_msg, vcpu->arch.mmu.root_level,
- va, gpa, hpa, ent,
- is_shadow_present_pte(ent));
- else if (ent == shadow_notrap_nonpresent_pte
- && !is_error_hpa(hpa))
- printk(KERN_ERR "audit: (%s) notrap shadow,"
- " valid guest gva %lx\n", audit_msg, va);
- kvm_release_pfn_clean(pfn);
-
- }
- }
-}
-
-static void audit_mappings(struct kvm_vcpu *vcpu)
-{
- unsigned i;
-
- if (vcpu->arch.mmu.root_level == 4)
- audit_mappings_page(vcpu, vcpu->arch.mmu.root_hpa, 0, 4);
- else
- for (i = 0; i < 4; ++i)
- if (vcpu->arch.mmu.pae_root[i] & PT_PRESENT_MASK)
- audit_mappings_page(vcpu,
- vcpu->arch.mmu.pae_root[i],
- i << 30,
- 2);
-}
-
-static int count_rmaps(struct kvm_vcpu *vcpu)
-{
- struct kvm *kvm = vcpu->kvm;
- struct kvm_memslots *slots;
- int nmaps = 0;
- int i, j, k, idx;
-
- idx = srcu_read_lock(&kvm->srcu);
- slots = kvm_memslots(kvm);
- for (i = 0; i < KVM_MEMORY_SLOTS; ++i) {
- struct kvm_memory_slot *m = &slots->memslots[i];
- struct kvm_rmap_desc *d;
-
- for (j = 0; j < m->npages; ++j) {
- unsigned long *rmapp = &m->rmap[j];
-
- if (!*rmapp)
- continue;
- if (!(*rmapp & 1)) {
- ++nmaps;
- continue;
- }
- d = (struct kvm_rmap_desc *)(*rmapp & ~1ul);
- while (d) {
- for (k = 0; k < RMAP_EXT; ++k)
- if (d->sptes[k])
- ++nmaps;
- else
- break;
- d = d->more;
- }
- }
- }
- srcu_read_unlock(&kvm->srcu, idx);
- return nmaps;
-}
-
-void inspect_spte_has_rmap(struct kvm *kvm, u64 *sptep)
-{
- unsigned long *rmapp;
- struct kvm_mmu_page *rev_sp;
- gfn_t gfn;
-
- if (is_writable_pte(*sptep)) {
- rev_sp = page_header(__pa(sptep));
- gfn = kvm_mmu_page_get_gfn(rev_sp, sptep - rev_sp->spt);
-
- if (!gfn_to_memslot(kvm, gfn)) {
- if (!printk_ratelimit())
- return;
- printk(KERN_ERR "%s: no memslot for gfn %ld\n",
- audit_msg, gfn);
- printk(KERN_ERR "%s: index %ld of sp (gfn=%lx)\n",
- audit_msg, (long int)(sptep - rev_sp->spt),
- rev_sp->gfn);
- dump_stack();
- return;
- }
-
- rmapp = gfn_to_rmap(kvm, gfn, rev_sp->role.level);
- if (!*rmapp) {
- if (!printk_ratelimit())
- return;
- printk(KERN_ERR "%s: no rmap for writable spte %llx\n",
- audit_msg, *sptep);
- dump_stack();
- }
- }
-
-}
-
-void audit_writable_sptes_have_rmaps(struct kvm_vcpu *vcpu)
-{
- mmu_spte_walk(vcpu, inspect_spte_has_rmap);
-}
-
-static void check_writable_mappings_rmap(struct kvm_vcpu *vcpu)
-{
- struct kvm_mmu_page *sp;
- int i;
-
- list_for_each_entry(sp, &vcpu->kvm->arch.active_mmu_pages, link) {
- u64 *pt = sp->spt;
-
- if (sp->role.level != PT_PAGE_TABLE_LEVEL)
- continue;
-
- for (i = 0; i < PT64_ENT_PER_PAGE; ++i) {
- u64 ent = pt[i];
-
- if (!(ent & PT_PRESENT_MASK))
- continue;
- if (!is_writable_pte(ent))
- continue;
- inspect_spte_has_rmap(vcpu->kvm, &pt[i]);
- }
- }
- return;
-}
-
-static void audit_rmap(struct kvm_vcpu *vcpu)
-{
- check_writable_mappings_rmap(vcpu);
- count_rmaps(vcpu);
-}
-
-static void audit_write_protection(struct kvm_vcpu *vcpu)
-{
- struct kvm_mmu_page *sp;
- struct kvm_memory_slot *slot;
- unsigned long *rmapp;
- u64 *spte;
- gfn_t gfn;
-
- list_for_each_entry(sp, &vcpu->kvm->arch.active_mmu_pages, link) {
- if (sp->role.direct)
- continue;
- if (sp->unsync)
- continue;
-
- slot = gfn_to_memslot(vcpu->kvm, sp->gfn);
- rmapp = &slot->rmap[gfn - slot->base_gfn];
-
- spte = rmap_next(vcpu->kvm, rmapp, NULL);
- while (spte) {
- if (is_writable_pte(*spte))
- printk(KERN_ERR "%s: (%s) shadow page has "
- "writable mappings: gfn %lx role %x\n",
- __func__, audit_msg, sp->gfn,
- sp->role.word);
- spte = rmap_next(vcpu->kvm, rmapp, spte);
- }
- }
-}
-
-static void kvm_mmu_audit(struct kvm_vcpu *vcpu, const char *msg)
+void kvm_mmu_destroy(struct kvm_vcpu *vcpu)
{
- int olddbg = dbg;
+ ASSERT(vcpu);
- dbg = 0;
- audit_msg = msg;
- audit_rmap(vcpu);
- audit_write_protection(vcpu);
- if (strcmp("pre pte write", audit_msg) != 0)
- audit_mappings(vcpu);
- audit_writable_sptes_have_rmaps(vcpu);
- dbg = olddbg;
+ destroy_kvm_mmu(vcpu);
+ free_mmu_pages(vcpu);
+ mmu_free_memory_caches(vcpu);
+ mmu_audit_disable();
}
-
-#endif
diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h
index be66759321a5..7086ca85d3e7 100644
--- a/arch/x86/kvm/mmu.h
+++ b/arch/x86/kvm/mmu.h
@@ -49,10 +49,17 @@
#define PFERR_FETCH_MASK (1U << 4)
int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4]);
+int kvm_init_shadow_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context);
+
+static inline unsigned int kvm_mmu_available_pages(struct kvm *kvm)
+{
+ return kvm->arch.n_max_mmu_pages -
+ kvm->arch.n_used_mmu_pages;
+}
static inline void kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
{
- if (unlikely(vcpu->kvm->arch.n_free_mmu_pages < KVM_MIN_FREE_MMU_PAGES))
+ if (unlikely(kvm_mmu_available_pages(vcpu->kvm)< KVM_MIN_FREE_MMU_PAGES))
__kvm_mmu_free_some_pages(vcpu);
}
diff --git a/arch/x86/kvm/mmu_audit.c b/arch/x86/kvm/mmu_audit.c
new file mode 100644
index 000000000000..ba2bcdde6221
--- /dev/null
+++ b/arch/x86/kvm/mmu_audit.c
@@ -0,0 +1,299 @@
+/*
+ * mmu_audit.c:
+ *
+ * Audit code for KVM MMU
+ *
+ * Copyright (C) 2006 Qumranet, Inc.
+ * Copyright 2010 Red Hat, Inc. and/or its affiliates.
+ *
+ * Authors:
+ * Yaniv Kamay <yaniv@qumranet.com>
+ * Avi Kivity <avi@qumranet.com>
+ * Marcelo Tosatti <mtosatti@redhat.com>
+ * Xiao Guangrong <xiaoguangrong@cn.fujitsu.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include <linux/ratelimit.h>
+
+static int audit_point;
+
+#define audit_printk(fmt, args...) \
+ printk(KERN_ERR "audit: (%s) error: " \
+ fmt, audit_point_name[audit_point], ##args)
+
+typedef void (*inspect_spte_fn) (struct kvm_vcpu *vcpu, u64 *sptep, int level);
+
+static void __mmu_spte_walk(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
+ inspect_spte_fn fn, int level)
+{
+ int i;
+
+ for (i = 0; i < PT64_ENT_PER_PAGE; ++i) {
+ u64 *ent = sp->spt;
+
+ fn(vcpu, ent + i, level);
+
+ if (is_shadow_present_pte(ent[i]) &&
+ !is_last_spte(ent[i], level)) {
+ struct kvm_mmu_page *child;
+
+ child = page_header(ent[i] & PT64_BASE_ADDR_MASK);
+ __mmu_spte_walk(vcpu, child, fn, level - 1);
+ }
+ }
+}
+
+static void mmu_spte_walk(struct kvm_vcpu *vcpu, inspect_spte_fn fn)
+{
+ int i;
+ struct kvm_mmu_page *sp;
+
+ if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
+ return;
+
+ if (vcpu->arch.mmu.root_level == PT64_ROOT_LEVEL) {
+ hpa_t root = vcpu->arch.mmu.root_hpa;
+
+ sp = page_header(root);
+ __mmu_spte_walk(vcpu, sp, fn, PT64_ROOT_LEVEL);
+ return;
+ }
+
+ for (i = 0; i < 4; ++i) {
+ hpa_t root = vcpu->arch.mmu.pae_root[i];
+
+ if (root && VALID_PAGE(root)) {
+ root &= PT64_BASE_ADDR_MASK;
+ sp = page_header(root);
+ __mmu_spte_walk(vcpu, sp, fn, 2);
+ }
+ }
+
+ return;
+}
+
+typedef void (*sp_handler) (struct kvm *kvm, struct kvm_mmu_page *sp);
+
+static void walk_all_active_sps(struct kvm *kvm, sp_handler fn)
+{
+ struct kvm_mmu_page *sp;
+
+ list_for_each_entry(sp, &kvm->arch.active_mmu_pages, link)
+ fn(kvm, sp);
+}
+
+static void audit_mappings(struct kvm_vcpu *vcpu, u64 *sptep, int level)
+{
+ struct kvm_mmu_page *sp;
+ gfn_t gfn;
+ pfn_t pfn;
+ hpa_t hpa;
+
+ sp = page_header(__pa(sptep));
+
+ if (sp->unsync) {
+ if (level != PT_PAGE_TABLE_LEVEL) {
+ audit_printk("unsync sp: %p level = %d\n", sp, level);
+ return;
+ }
+
+ if (*sptep == shadow_notrap_nonpresent_pte) {
+ audit_printk("notrap spte in unsync sp: %p\n", sp);
+ return;
+ }
+ }
+
+ if (sp->role.direct && *sptep == shadow_notrap_nonpresent_pte) {
+ audit_printk("notrap spte in direct sp: %p\n", sp);
+ return;
+ }
+
+ if (!is_shadow_present_pte(*sptep) || !is_last_spte(*sptep, level))
+ return;
+
+ gfn = kvm_mmu_page_get_gfn(sp, sptep - sp->spt);
+ pfn = gfn_to_pfn_atomic(vcpu->kvm, gfn);
+
+ if (is_error_pfn(pfn)) {
+ kvm_release_pfn_clean(pfn);
+ return;
+ }
+
+ hpa = pfn << PAGE_SHIFT;
+ if ((*sptep & PT64_BASE_ADDR_MASK) != hpa)
+ audit_printk("levels %d pfn %llx hpa %llx ent %llxn",
+ vcpu->arch.mmu.root_level, pfn, hpa, *sptep);
+}
+
+static void inspect_spte_has_rmap(struct kvm *kvm, u64 *sptep)
+{
+ unsigned long *rmapp;
+ struct kvm_mmu_page *rev_sp;
+ gfn_t gfn;
+
+
+ rev_sp = page_header(__pa(sptep));
+ gfn = kvm_mmu_page_get_gfn(rev_sp, sptep - rev_sp->spt);
+
+ if (!gfn_to_memslot(kvm, gfn)) {
+ if (!printk_ratelimit())
+ return;
+ audit_printk("no memslot for gfn %llx\n", gfn);
+ audit_printk("index %ld of sp (gfn=%llx)\n",
+ (long int)(sptep - rev_sp->spt), rev_sp->gfn);
+ dump_stack();
+ return;
+ }
+
+ rmapp = gfn_to_rmap(kvm, gfn, rev_sp->role.level);
+ if (!*rmapp) {
+ if (!printk_ratelimit())
+ return;
+ audit_printk("no rmap for writable spte %llx\n", *sptep);
+ dump_stack();
+ }
+}
+
+static void audit_sptes_have_rmaps(struct kvm_vcpu *vcpu, u64 *sptep, int level)
+{
+ if (is_shadow_present_pte(*sptep) && is_last_spte(*sptep, level))
+ inspect_spte_has_rmap(vcpu->kvm, sptep);
+}
+
+static void audit_spte_after_sync(struct kvm_vcpu *vcpu, u64 *sptep, int level)
+{
+ struct kvm_mmu_page *sp = page_header(__pa(sptep));
+
+ if (audit_point == AUDIT_POST_SYNC && sp->unsync)
+ audit_printk("meet unsync sp(%p) after sync root.\n", sp);
+}
+
+static void check_mappings_rmap(struct kvm *kvm, struct kvm_mmu_page *sp)
+{
+ int i;
+
+ if (sp->role.level != PT_PAGE_TABLE_LEVEL)
+ return;
+
+ for (i = 0; i < PT64_ENT_PER_PAGE; ++i) {
+ if (!is_rmap_spte(sp->spt[i]))
+ continue;
+
+ inspect_spte_has_rmap(kvm, sp->spt + i);
+ }
+}
+
+static void audit_write_protection(struct kvm *kvm, struct kvm_mmu_page *sp)
+{
+ struct kvm_memory_slot *slot;
+ unsigned long *rmapp;
+ u64 *spte;
+
+ if (sp->role.direct || sp->unsync || sp->role.invalid)
+ return;
+
+ slot = gfn_to_memslot(kvm, sp->gfn);
+ rmapp = &slot->rmap[sp->gfn - slot->base_gfn];
+
+ spte = rmap_next(kvm, rmapp, NULL);
+ while (spte) {
+ if (is_writable_pte(*spte))
+ audit_printk("shadow page has writable mappings: gfn "
+ "%llx role %x\n", sp->gfn, sp->role.word);
+ spte = rmap_next(kvm, rmapp, spte);
+ }
+}
+
+static void audit_sp(struct kvm *kvm, struct kvm_mmu_page *sp)
+{
+ check_mappings_rmap(kvm, sp);
+ audit_write_protection(kvm, sp);
+}
+
+static void audit_all_active_sps(struct kvm *kvm)
+{
+ walk_all_active_sps(kvm, audit_sp);
+}
+
+static void audit_spte(struct kvm_vcpu *vcpu, u64 *sptep, int level)
+{
+ audit_sptes_have_rmaps(vcpu, sptep, level);
+ audit_mappings(vcpu, sptep, level);
+ audit_spte_after_sync(vcpu, sptep, level);
+}
+
+static void audit_vcpu_spte(struct kvm_vcpu *vcpu)
+{
+ mmu_spte_walk(vcpu, audit_spte);
+}
+
+static void kvm_mmu_audit(void *ignore, struct kvm_vcpu *vcpu, int point)
+{
+ static DEFINE_RATELIMIT_STATE(ratelimit_state, 5 * HZ, 10);
+
+ if (!__ratelimit(&ratelimit_state))
+ return;
+
+ audit_point = point;
+ audit_all_active_sps(vcpu->kvm);
+ audit_vcpu_spte(vcpu);
+}
+
+static bool mmu_audit;
+
+static void mmu_audit_enable(void)
+{
+ int ret;
+
+ if (mmu_audit)
+ return;
+
+ ret = register_trace_kvm_mmu_audit(kvm_mmu_audit, NULL);
+ WARN_ON(ret);
+
+ mmu_audit = true;
+}
+
+static void mmu_audit_disable(void)
+{
+ if (!mmu_audit)
+ return;
+
+ unregister_trace_kvm_mmu_audit(kvm_mmu_audit, NULL);
+ tracepoint_synchronize_unregister();
+ mmu_audit = false;
+}
+
+static int mmu_audit_set(const char *val, const struct kernel_param *kp)
+{
+ int ret;
+ unsigned long enable;
+
+ ret = strict_strtoul(val, 10, &enable);
+ if (ret < 0)
+ return -EINVAL;
+
+ switch (enable) {
+ case 0:
+ mmu_audit_disable();
+ break;
+ case 1:
+ mmu_audit_enable();
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct kernel_param_ops audit_param_ops = {
+ .set = mmu_audit_set,
+ .get = param_get_bool,
+};
+
+module_param_cb(mmu_audit, &audit_param_ops, &mmu_audit, 0644);
diff --git a/arch/x86/kvm/mmutrace.h b/arch/x86/kvm/mmutrace.h
index 3aab0f0930ef..b60b4fdb3eda 100644
--- a/arch/x86/kvm/mmutrace.h
+++ b/arch/x86/kvm/mmutrace.h
@@ -195,6 +195,25 @@ DEFINE_EVENT(kvm_mmu_page_class, kvm_mmu_prepare_zap_page,
TP_ARGS(sp)
);
+
+TRACE_EVENT(
+ kvm_mmu_audit,
+ TP_PROTO(struct kvm_vcpu *vcpu, int audit_point),
+ TP_ARGS(vcpu, audit_point),
+
+ TP_STRUCT__entry(
+ __field(struct kvm_vcpu *, vcpu)
+ __field(int, audit_point)
+ ),
+
+ TP_fast_assign(
+ __entry->vcpu = vcpu;
+ __entry->audit_point = audit_point;
+ ),
+
+ TP_printk("vcpu:%d %s", __entry->vcpu->cpu,
+ audit_point_name[__entry->audit_point])
+);
#endif /* _TRACE_KVMMMU_H */
#undef TRACE_INCLUDE_PATH
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index 51ef9097960d..cd7a833a3b52 100644
--- a/arch/x86/kvm/paging_tmpl.h
+++ b/arch/x86/kvm/paging_tmpl.h
@@ -7,7 +7,7 @@
* MMU support
*
* Copyright (C) 2006 Qumranet, Inc.
- * Copyright 2010 Red Hat, Inc. and/or its affilates.
+ * Copyright 2010 Red Hat, Inc. and/or its affiliates.
*
* Authors:
* Yaniv Kamay <yaniv@qumranet.com>
@@ -67,6 +67,7 @@ struct guest_walker {
int level;
gfn_t table_gfn[PT_MAX_FULL_LEVELS];
pt_element_t ptes[PT_MAX_FULL_LEVELS];
+ pt_element_t prefetch_ptes[PTE_PREFETCH_NUM];
gpa_t pte_gpa[PT_MAX_FULL_LEVELS];
unsigned pt_access;
unsigned pte_access;
@@ -104,7 +105,7 @@ static unsigned FNAME(gpte_access)(struct kvm_vcpu *vcpu, pt_element_t gpte)
access = (gpte & (PT_WRITABLE_MASK | PT_USER_MASK)) | ACC_EXEC_MASK;
#if PTTYPE == 64
- if (is_nx(vcpu))
+ if (vcpu->arch.mmu.nx)
access &= ~(gpte >> PT64_NX_SHIFT);
#endif
return access;
@@ -113,26 +114,32 @@ static unsigned FNAME(gpte_access)(struct kvm_vcpu *vcpu, pt_element_t gpte)
/*
* Fetch a guest pte for a guest virtual address
*/
-static int FNAME(walk_addr)(struct guest_walker *walker,
- struct kvm_vcpu *vcpu, gva_t addr,
- int write_fault, int user_fault, int fetch_fault)
+static int FNAME(walk_addr_generic)(struct guest_walker *walker,
+ struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
+ gva_t addr, u32 access)
{
pt_element_t pte;
gfn_t table_gfn;
unsigned index, pt_access, uninitialized_var(pte_access);
gpa_t pte_gpa;
bool eperm, present, rsvd_fault;
+ int offset, write_fault, user_fault, fetch_fault;
+
+ write_fault = access & PFERR_WRITE_MASK;
+ user_fault = access & PFERR_USER_MASK;
+ fetch_fault = access & PFERR_FETCH_MASK;
trace_kvm_mmu_pagetable_walk(addr, write_fault, user_fault,
fetch_fault);
walk:
present = true;
eperm = rsvd_fault = false;
- walker->level = vcpu->arch.mmu.root_level;
- pte = vcpu->arch.cr3;
+ walker->level = mmu->root_level;
+ pte = mmu->get_cr3(vcpu);
+
#if PTTYPE == 64
- if (!is_long_mode(vcpu)) {
- pte = kvm_pdptr_read(vcpu, (addr >> 30) & 3);
+ if (walker->level == PT32E_ROOT_LEVEL) {
+ pte = kvm_pdptr_read_mmu(vcpu, mmu, (addr >> 30) & 3);
trace_kvm_mmu_paging_element(pte, walker->level);
if (!is_present_gpte(pte)) {
present = false;
@@ -142,7 +149,7 @@ walk:
}
#endif
ASSERT((!is_long_mode(vcpu) && is_pae(vcpu)) ||
- (vcpu->arch.cr3 & CR3_NONPAE_RESERVED_BITS) == 0);
+ (mmu->get_cr3(vcpu) & CR3_NONPAE_RESERVED_BITS) == 0);
pt_access = ACC_ALL;
@@ -150,12 +157,14 @@ walk:
index = PT_INDEX(addr, walker->level);
table_gfn = gpte_to_gfn(pte);
- pte_gpa = gfn_to_gpa(table_gfn);
- pte_gpa += index * sizeof(pt_element_t);
+ offset = index * sizeof(pt_element_t);
+ pte_gpa = gfn_to_gpa(table_gfn) + offset;
walker->table_gfn[walker->level - 1] = table_gfn;
walker->pte_gpa[walker->level - 1] = pte_gpa;
- if (kvm_read_guest(vcpu->kvm, pte_gpa, &pte, sizeof(pte))) {
+ if (kvm_read_guest_page_mmu(vcpu, mmu, table_gfn, &pte,
+ offset, sizeof(pte),
+ PFERR_USER_MASK|PFERR_WRITE_MASK)) {
present = false;
break;
}
@@ -167,7 +176,7 @@ walk:
break;
}
- if (is_rsvd_bits_set(vcpu, pte, walker->level)) {
+ if (is_rsvd_bits_set(&vcpu->arch.mmu, pte, walker->level)) {
rsvd_fault = true;
break;
}
@@ -204,17 +213,28 @@ walk:
(PTTYPE == 64 || is_pse(vcpu))) ||
((walker->level == PT_PDPE_LEVEL) &&
is_large_pte(pte) &&
- is_long_mode(vcpu))) {
+ mmu->root_level == PT64_ROOT_LEVEL)) {
int lvl = walker->level;
+ gpa_t real_gpa;
+ gfn_t gfn;
+ u32 ac;
- walker->gfn = gpte_to_gfn_lvl(pte, lvl);
- walker->gfn += (addr & PT_LVL_OFFSET_MASK(lvl))
- >> PAGE_SHIFT;
+ gfn = gpte_to_gfn_lvl(pte, lvl);
+ gfn += (addr & PT_LVL_OFFSET_MASK(lvl)) >> PAGE_SHIFT;
if (PTTYPE == 32 &&
walker->level == PT_DIRECTORY_LEVEL &&
is_cpuid_PSE36())
- walker->gfn += pse36_gfn_delta(pte);
+ gfn += pse36_gfn_delta(pte);
+
+ ac = write_fault | fetch_fault | user_fault;
+
+ real_gpa = mmu->translate_gpa(vcpu, gfn_to_gpa(gfn),
+ ac);
+ if (real_gpa == UNMAPPED_GVA)
+ return 0;
+
+ walker->gfn = real_gpa >> PAGE_SHIFT;
break;
}
@@ -249,18 +269,36 @@ error:
walker->error_code = 0;
if (present)
walker->error_code |= PFERR_PRESENT_MASK;
- if (write_fault)
- walker->error_code |= PFERR_WRITE_MASK;
- if (user_fault)
- walker->error_code |= PFERR_USER_MASK;
- if (fetch_fault && is_nx(vcpu))
+
+ walker->error_code |= write_fault | user_fault;
+
+ if (fetch_fault && mmu->nx)
walker->error_code |= PFERR_FETCH_MASK;
if (rsvd_fault)
walker->error_code |= PFERR_RSVD_MASK;
+
+ vcpu->arch.fault.address = addr;
+ vcpu->arch.fault.error_code = walker->error_code;
+
trace_kvm_mmu_walker_error(walker->error_code);
return 0;
}
+static int FNAME(walk_addr)(struct guest_walker *walker,
+ struct kvm_vcpu *vcpu, gva_t addr, u32 access)
+{
+ return FNAME(walk_addr_generic)(walker, vcpu, &vcpu->arch.mmu, addr,
+ access);
+}
+
+static int FNAME(walk_addr_nested)(struct guest_walker *walker,
+ struct kvm_vcpu *vcpu, gva_t addr,
+ u32 access)
+{
+ return FNAME(walk_addr_generic)(walker, vcpu, &vcpu->arch.nested_mmu,
+ addr, access);
+}
+
static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
u64 *spte, const void *pte)
{
@@ -302,14 +340,87 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
static bool FNAME(gpte_changed)(struct kvm_vcpu *vcpu,
struct guest_walker *gw, int level)
{
- int r;
pt_element_t curr_pte;
-
- r = kvm_read_guest_atomic(vcpu->kvm, gw->pte_gpa[level - 1],
+ gpa_t base_gpa, pte_gpa = gw->pte_gpa[level - 1];
+ u64 mask;
+ int r, index;
+
+ if (level == PT_PAGE_TABLE_LEVEL) {
+ mask = PTE_PREFETCH_NUM * sizeof(pt_element_t) - 1;
+ base_gpa = pte_gpa & ~mask;
+ index = (pte_gpa - base_gpa) / sizeof(pt_element_t);
+
+ r = kvm_read_guest_atomic(vcpu->kvm, base_gpa,
+ gw->prefetch_ptes, sizeof(gw->prefetch_ptes));
+ curr_pte = gw->prefetch_ptes[index];
+ } else
+ r = kvm_read_guest_atomic(vcpu->kvm, pte_gpa,
&curr_pte, sizeof(curr_pte));
+
return r || curr_pte != gw->ptes[level - 1];
}
+static void FNAME(pte_prefetch)(struct kvm_vcpu *vcpu, struct guest_walker *gw,
+ u64 *sptep)
+{
+ struct kvm_mmu_page *sp;
+ struct kvm_mmu *mmu = &vcpu->arch.mmu;
+ pt_element_t *gptep = gw->prefetch_ptes;
+ u64 *spte;
+ int i;
+
+ sp = page_header(__pa(sptep));
+
+ if (sp->role.level > PT_PAGE_TABLE_LEVEL)
+ return;
+
+ if (sp->role.direct)
+ return __direct_pte_prefetch(vcpu, sp, sptep);
+
+ i = (sptep - sp->spt) & ~(PTE_PREFETCH_NUM - 1);
+ spte = sp->spt + i;
+
+ for (i = 0; i < PTE_PREFETCH_NUM; i++, spte++) {
+ pt_element_t gpte;
+ unsigned pte_access;
+ gfn_t gfn;
+ pfn_t pfn;
+ bool dirty;
+
+ if (spte == sptep)
+ continue;
+
+ if (*spte != shadow_trap_nonpresent_pte)
+ continue;
+
+ gpte = gptep[i];
+
+ if (!is_present_gpte(gpte) ||
+ is_rsvd_bits_set(mmu, gpte, PT_PAGE_TABLE_LEVEL)) {
+ if (!sp->unsync)
+ __set_spte(spte, shadow_notrap_nonpresent_pte);
+ continue;
+ }
+
+ if (!(gpte & PT_ACCESSED_MASK))
+ continue;
+
+ pte_access = sp->role.access & FNAME(gpte_access)(vcpu, gpte);
+ gfn = gpte_to_gfn(gpte);
+ dirty = is_dirty_gpte(gpte);
+ pfn = pte_prefetch_gfn_to_pfn(vcpu, gfn,
+ (pte_access & ACC_WRITE_MASK) && dirty);
+ if (is_error_pfn(pfn)) {
+ kvm_release_pfn_clean(pfn);
+ break;
+ }
+
+ mmu_set_spte(vcpu, spte, sp->role.access, pte_access, 0, 0,
+ dirty, NULL, PT_PAGE_TABLE_LEVEL, gfn,
+ pfn, true, true);
+ }
+}
+
/*
* Fetch a shadow pte for a specific level in the paging hierarchy.
*/
@@ -391,6 +502,7 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
mmu_set_spte(vcpu, it.sptep, access, gw->pte_access & access,
user_fault, write_fault, dirty, ptwrite, it.level,
gw->gfn, pfn, false, true);
+ FNAME(pte_prefetch)(vcpu, gw, it.sptep);
return it.sptep;
@@ -420,7 +532,6 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
{
int write_fault = error_code & PFERR_WRITE_MASK;
int user_fault = error_code & PFERR_USER_MASK;
- int fetch_fault = error_code & PFERR_FETCH_MASK;
struct guest_walker walker;
u64 *sptep;
int write_pt = 0;
@@ -430,7 +541,6 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
unsigned long mmu_seq;
pgprintk("%s: addr %lx err %x\n", __func__, addr, error_code);
- kvm_mmu_audit(vcpu, "pre page fault");
r = mmu_topup_memory_caches(vcpu);
if (r)
@@ -439,15 +549,14 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
/*
* Look up the guest pte for the faulting address.
*/
- r = FNAME(walk_addr)(&walker, vcpu, addr, write_fault, user_fault,
- fetch_fault);
+ r = FNAME(walk_addr)(&walker, vcpu, addr, error_code);
/*
* The page is not mapped by the guest. Let the guest handle it.
*/
if (!r) {
pgprintk("%s: guest page fault\n", __func__);
- inject_page_fault(vcpu, addr, walker.error_code);
+ inject_page_fault(vcpu);
vcpu->arch.last_pt_write_count = 0; /* reset fork detector */
return 0;
}
@@ -468,6 +577,8 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
spin_lock(&vcpu->kvm->mmu_lock);
if (mmu_notifier_retry(vcpu, mmu_seq))
goto out_unlock;
+
+ trace_kvm_mmu_audit(vcpu, AUDIT_PRE_PAGE_FAULT);
kvm_mmu_free_some_pages(vcpu);
sptep = FNAME(fetch)(vcpu, addr, &walker, user_fault, write_fault,
level, &write_pt, pfn);
@@ -479,7 +590,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
vcpu->arch.last_pt_write_count = 0; /* reset fork detector */
++vcpu->stat.pf_fixed;
- kvm_mmu_audit(vcpu, "post page fault (fixed)");
+ trace_kvm_mmu_audit(vcpu, AUDIT_POST_PAGE_FAULT);
spin_unlock(&vcpu->kvm->mmu_lock);
return write_pt;
@@ -556,10 +667,25 @@ static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr, u32 access,
gpa_t gpa = UNMAPPED_GVA;
int r;
- r = FNAME(walk_addr)(&walker, vcpu, vaddr,
- !!(access & PFERR_WRITE_MASK),
- !!(access & PFERR_USER_MASK),
- !!(access & PFERR_FETCH_MASK));
+ r = FNAME(walk_addr)(&walker, vcpu, vaddr, access);
+
+ if (r) {
+ gpa = gfn_to_gpa(walker.gfn);
+ gpa |= vaddr & ~PAGE_MASK;
+ } else if (error)
+ *error = walker.error_code;
+
+ return gpa;
+}
+
+static gpa_t FNAME(gva_to_gpa_nested)(struct kvm_vcpu *vcpu, gva_t vaddr,
+ u32 access, u32 *error)
+{
+ struct guest_walker walker;
+ gpa_t gpa = UNMAPPED_GVA;
+ int r;
+
+ r = FNAME(walk_addr_nested)(&walker, vcpu, vaddr, access);
if (r) {
gpa = gfn_to_gpa(walker.gfn);
@@ -638,7 +764,7 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
return -EINVAL;
gfn = gpte_to_gfn(gpte);
- if (is_rsvd_bits_set(vcpu, gpte, PT_PAGE_TABLE_LEVEL)
+ if (is_rsvd_bits_set(&vcpu->arch.mmu, gpte, PT_PAGE_TABLE_LEVEL)
|| gfn != sp->gfns[i] || !is_present_gpte(gpte)
|| !(gpte & PT_ACCESSED_MASK)) {
u64 nonpresent;
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index bc5b9b8d4a33..82e144a4e514 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -4,7 +4,7 @@
* AMD SVM support
*
* Copyright (C) 2006 Qumranet, Inc.
- * Copyright 2010 Red Hat, Inc. and/or its affilates.
+ * Copyright 2010 Red Hat, Inc. and/or its affiliates.
*
* Authors:
* Yaniv Kamay <yaniv@qumranet.com>
@@ -88,6 +88,14 @@ struct nested_state {
/* A VMEXIT is required but not yet emulated */
bool exit_required;
+ /*
+ * If we vmexit during an instruction emulation we need this to restore
+ * the l1 guest rip after the emulation
+ */
+ unsigned long vmexit_rip;
+ unsigned long vmexit_rsp;
+ unsigned long vmexit_rax;
+
/* cache for intercepts of the guest */
u16 intercept_cr_read;
u16 intercept_cr_write;
@@ -96,6 +104,8 @@ struct nested_state {
u32 intercept_exceptions;
u64 intercept;
+ /* Nested Paging related state */
+ u64 nested_cr3;
};
#define MSRPM_OFFSETS 16
@@ -284,6 +294,15 @@ static inline void flush_guest_tlb(struct kvm_vcpu *vcpu)
force_new_asid(vcpu);
}
+static int get_npt_level(void)
+{
+#ifdef CONFIG_X86_64
+ return PT64_ROOT_LEVEL;
+#else
+ return PT32E_ROOT_LEVEL;
+#endif
+}
+
static void svm_set_efer(struct kvm_vcpu *vcpu, u64 efer)
{
vcpu->arch.efer = efer;
@@ -701,6 +720,29 @@ static void init_sys_seg(struct vmcb_seg *seg, uint32_t type)
seg->base = 0;
}
+static void svm_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
+{
+ struct vcpu_svm *svm = to_svm(vcpu);
+ u64 g_tsc_offset = 0;
+
+ if (is_nested(svm)) {
+ g_tsc_offset = svm->vmcb->control.tsc_offset -
+ svm->nested.hsave->control.tsc_offset;
+ svm->nested.hsave->control.tsc_offset = offset;
+ }
+
+ svm->vmcb->control.tsc_offset = offset + g_tsc_offset;
+}
+
+static void svm_adjust_tsc_offset(struct kvm_vcpu *vcpu, s64 adjustment)
+{
+ struct vcpu_svm *svm = to_svm(vcpu);
+
+ svm->vmcb->control.tsc_offset += adjustment;
+ if (is_nested(svm))
+ svm->nested.hsave->control.tsc_offset += adjustment;
+}
+
static void init_vmcb(struct vcpu_svm *svm)
{
struct vmcb_control_area *control = &svm->vmcb->control;
@@ -766,7 +808,6 @@ static void init_vmcb(struct vcpu_svm *svm)
control->iopm_base_pa = iopm_base;
control->msrpm_base_pa = __pa(svm->msrpm);
- control->tsc_offset = 0;
control->int_ctl = V_INTR_MASKING_MASK;
init_seg(&save->es);
@@ -794,7 +835,7 @@ static void init_vmcb(struct vcpu_svm *svm)
init_sys_seg(&save->ldtr, SEG_TYPE_LDT);
init_sys_seg(&save->tr, SEG_TYPE_BUSY_TSS16);
- save->efer = EFER_SVME;
+ svm_set_efer(&svm->vcpu, 0);
save->dr6 = 0xffff0ff0;
save->dr7 = 0x400;
save->rflags = 2;
@@ -805,8 +846,8 @@ static void init_vmcb(struct vcpu_svm *svm)
* This is the guest-visible cr0 value.
* svm_set_cr0() sets PG and WP and clears NW and CD on save->cr0.
*/
- svm->vcpu.arch.cr0 = X86_CR0_NW | X86_CR0_CD | X86_CR0_ET;
- (void)kvm_set_cr0(&svm->vcpu, svm->vcpu.arch.cr0);
+ svm->vcpu.arch.cr0 = 0;
+ (void)kvm_set_cr0(&svm->vcpu, X86_CR0_NW | X86_CR0_CD | X86_CR0_ET);
save->cr4 = X86_CR4_PAE;
/* rdx = ?? */
@@ -902,6 +943,7 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
svm->vmcb_pa = page_to_pfn(page) << PAGE_SHIFT;
svm->asid_generation = 0;
init_vmcb(svm);
+ kvm_write_tsc(&svm->vcpu, 0);
err = fx_init(&svm->vcpu);
if (err)
@@ -947,20 +989,6 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
int i;
if (unlikely(cpu != vcpu->cpu)) {
- u64 delta;
-
- if (check_tsc_unstable()) {
- /*
- * Make sure that the guest sees a monotonically
- * increasing TSC.
- */
- delta = vcpu->arch.host_tsc - native_read_tsc();
- svm->vmcb->control.tsc_offset += delta;
- if (is_nested(svm))
- svm->nested.hsave->control.tsc_offset += delta;
- }
- vcpu->cpu = cpu;
- kvm_migrate_timers(vcpu);
svm->asid_generation = 0;
}
@@ -976,8 +1004,6 @@ static void svm_vcpu_put(struct kvm_vcpu *vcpu)
++vcpu->stat.host_state_reload;
for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++)
wrmsrl(host_save_user_msrs[i], svm->host_user_msrs[i]);
-
- vcpu->arch.host_tsc = native_read_tsc();
}
static unsigned long svm_get_rflags(struct kvm_vcpu *vcpu)
@@ -995,7 +1021,7 @@ static void svm_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg)
switch (reg) {
case VCPU_EXREG_PDPTR:
BUG_ON(!npt_enabled);
- load_pdptrs(vcpu, vcpu->arch.cr3);
+ load_pdptrs(vcpu, vcpu->arch.walk_mmu, vcpu->arch.cr3);
break;
default:
BUG();
@@ -1206,8 +1232,12 @@ static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
if (old == new) {
/* cr0 write with ts and mp unchanged */
svm->vmcb->control.exit_code = SVM_EXIT_CR0_SEL_WRITE;
- if (nested_svm_exit_handled(svm) == NESTED_EXIT_DONE)
+ if (nested_svm_exit_handled(svm) == NESTED_EXIT_DONE) {
+ svm->nested.vmexit_rip = kvm_rip_read(vcpu);
+ svm->nested.vmexit_rsp = kvm_register_read(vcpu, VCPU_REGS_RSP);
+ svm->nested.vmexit_rax = kvm_register_read(vcpu, VCPU_REGS_RAX);
return;
+ }
}
}
@@ -1581,6 +1611,54 @@ static int vmmcall_interception(struct vcpu_svm *svm)
return 1;
}
+static unsigned long nested_svm_get_tdp_cr3(struct kvm_vcpu *vcpu)
+{
+ struct vcpu_svm *svm = to_svm(vcpu);
+
+ return svm->nested.nested_cr3;
+}
+
+static void nested_svm_set_tdp_cr3(struct kvm_vcpu *vcpu,
+ unsigned long root)
+{
+ struct vcpu_svm *svm = to_svm(vcpu);
+
+ svm->vmcb->control.nested_cr3 = root;
+ force_new_asid(vcpu);
+}
+
+static void nested_svm_inject_npf_exit(struct kvm_vcpu *vcpu)
+{
+ struct vcpu_svm *svm = to_svm(vcpu);
+
+ svm->vmcb->control.exit_code = SVM_EXIT_NPF;
+ svm->vmcb->control.exit_code_hi = 0;
+ svm->vmcb->control.exit_info_1 = vcpu->arch.fault.error_code;
+ svm->vmcb->control.exit_info_2 = vcpu->arch.fault.address;
+
+ nested_svm_vmexit(svm);
+}
+
+static int nested_svm_init_mmu_context(struct kvm_vcpu *vcpu)
+{
+ int r;
+
+ r = kvm_init_shadow_mmu(vcpu, &vcpu->arch.mmu);
+
+ vcpu->arch.mmu.set_cr3 = nested_svm_set_tdp_cr3;
+ vcpu->arch.mmu.get_cr3 = nested_svm_get_tdp_cr3;
+ vcpu->arch.mmu.inject_page_fault = nested_svm_inject_npf_exit;
+ vcpu->arch.mmu.shadow_root_level = get_npt_level();
+ vcpu->arch.walk_mmu = &vcpu->arch.nested_mmu;
+
+ return r;
+}
+
+static void nested_svm_uninit_mmu_context(struct kvm_vcpu *vcpu)
+{
+ vcpu->arch.walk_mmu = &vcpu->arch.mmu;
+}
+
static int nested_svm_check_permissions(struct vcpu_svm *svm)
{
if (!(svm->vcpu.arch.efer & EFER_SVME)
@@ -1629,6 +1707,14 @@ static inline bool nested_svm_intr(struct vcpu_svm *svm)
if (!(svm->vcpu.arch.hflags & HF_HIF_MASK))
return false;
+ /*
+ * if vmexit was already requested (by intercepted exception
+ * for instance) do not overwrite it with "external interrupt"
+ * vmexit.
+ */
+ if (svm->nested.exit_required)
+ return false;
+
svm->vmcb->control.exit_code = SVM_EXIT_INTR;
svm->vmcb->control.exit_info_1 = 0;
svm->vmcb->control.exit_info_2 = 0;
@@ -1896,6 +1982,7 @@ static int nested_svm_vmexit(struct vcpu_svm *svm)
nested_vmcb->save.ds = vmcb->save.ds;
nested_vmcb->save.gdtr = vmcb->save.gdtr;
nested_vmcb->save.idtr = vmcb->save.idtr;
+ nested_vmcb->save.efer = svm->vcpu.arch.efer;
nested_vmcb->save.cr0 = kvm_read_cr0(&svm->vcpu);
nested_vmcb->save.cr3 = svm->vcpu.arch.cr3;
nested_vmcb->save.cr2 = vmcb->save.cr2;
@@ -1917,6 +2004,7 @@ static int nested_svm_vmexit(struct vcpu_svm *svm)
nested_vmcb->control.exit_info_2 = vmcb->control.exit_info_2;
nested_vmcb->control.exit_int_info = vmcb->control.exit_int_info;
nested_vmcb->control.exit_int_info_err = vmcb->control.exit_int_info_err;
+ nested_vmcb->control.next_rip = vmcb->control.next_rip;
/*
* If we emulate a VMRUN/#VMEXIT in the same host #vmexit cycle we have
@@ -1947,6 +2035,8 @@ static int nested_svm_vmexit(struct vcpu_svm *svm)
kvm_clear_exception_queue(&svm->vcpu);
kvm_clear_interrupt_queue(&svm->vcpu);
+ svm->nested.nested_cr3 = 0;
+
/* Restore selected save entries */
svm->vmcb->save.es = hsave->save.es;
svm->vmcb->save.cs = hsave->save.cs;
@@ -1973,6 +2063,7 @@ static int nested_svm_vmexit(struct vcpu_svm *svm)
nested_svm_unmap(page);
+ nested_svm_uninit_mmu_context(&svm->vcpu);
kvm_mmu_reset_context(&svm->vcpu);
kvm_mmu_load(&svm->vcpu);
@@ -2012,6 +2103,20 @@ static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm)
return true;
}
+static bool nested_vmcb_checks(struct vmcb *vmcb)
+{
+ if ((vmcb->control.intercept & (1ULL << INTERCEPT_VMRUN)) == 0)
+ return false;
+
+ if (vmcb->control.asid == 0)
+ return false;
+
+ if (vmcb->control.nested_ctl && !npt_enabled)
+ return false;
+
+ return true;
+}
+
static bool nested_svm_vmrun(struct vcpu_svm *svm)
{
struct vmcb *nested_vmcb;
@@ -2026,7 +2131,18 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
if (!nested_vmcb)
return false;
- trace_kvm_nested_vmrun(svm->vmcb->save.rip - 3, vmcb_gpa,
+ if (!nested_vmcb_checks(nested_vmcb)) {
+ nested_vmcb->control.exit_code = SVM_EXIT_ERR;
+ nested_vmcb->control.exit_code_hi = 0;
+ nested_vmcb->control.exit_info_1 = 0;
+ nested_vmcb->control.exit_info_2 = 0;
+
+ nested_svm_unmap(page);
+
+ return false;
+ }
+
+ trace_kvm_nested_vmrun(svm->vmcb->save.rip, vmcb_gpa,
nested_vmcb->save.rip,
nested_vmcb->control.int_ctl,
nested_vmcb->control.event_inj,
@@ -2055,7 +2171,7 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
hsave->save.cr0 = kvm_read_cr0(&svm->vcpu);
hsave->save.cr4 = svm->vcpu.arch.cr4;
hsave->save.rflags = vmcb->save.rflags;
- hsave->save.rip = svm->next_rip;
+ hsave->save.rip = kvm_rip_read(&svm->vcpu);
hsave->save.rsp = vmcb->save.rsp;
hsave->save.rax = vmcb->save.rax;
if (npt_enabled)
@@ -2070,6 +2186,12 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
else
svm->vcpu.arch.hflags &= ~HF_HIF_MASK;
+ if (nested_vmcb->control.nested_ctl) {
+ kvm_mmu_unload(&svm->vcpu);
+ svm->nested.nested_cr3 = nested_vmcb->control.nested_cr3;
+ nested_svm_init_mmu_context(&svm->vcpu);
+ }
+
/* Load the nested guest state */
svm->vmcb->save.es = nested_vmcb->save.es;
svm->vmcb->save.cs = nested_vmcb->save.cs;
@@ -2227,8 +2349,8 @@ static int vmrun_interception(struct vcpu_svm *svm)
if (nested_svm_check_permissions(svm))
return 1;
- svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
- skip_emulated_instruction(&svm->vcpu);
+ /* Save rip after vmrun instruction */
+ kvm_rip_write(&svm->vcpu, kvm_rip_read(&svm->vcpu) + 3);
if (!nested_svm_vmrun(svm))
return 1;
@@ -2257,6 +2379,7 @@ static int stgi_interception(struct vcpu_svm *svm)
svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
skip_emulated_instruction(&svm->vcpu);
+ kvm_make_request(KVM_REQ_EVENT, &svm->vcpu);
enable_gif(svm);
@@ -2399,6 +2522,23 @@ static int emulate_on_interception(struct vcpu_svm *svm)
return emulate_instruction(&svm->vcpu, 0, 0, 0) == EMULATE_DONE;
}
+static int cr0_write_interception(struct vcpu_svm *svm)
+{
+ struct kvm_vcpu *vcpu = &svm->vcpu;
+ int r;
+
+ r = emulate_instruction(&svm->vcpu, 0, 0, 0);
+
+ if (svm->nested.vmexit_rip) {
+ kvm_register_write(vcpu, VCPU_REGS_RIP, svm->nested.vmexit_rip);
+ kvm_register_write(vcpu, VCPU_REGS_RSP, svm->nested.vmexit_rsp);
+ kvm_register_write(vcpu, VCPU_REGS_RAX, svm->nested.vmexit_rax);
+ svm->nested.vmexit_rip = 0;
+ }
+
+ return r == EMULATE_DONE;
+}
+
static int cr8_write_interception(struct vcpu_svm *svm)
{
struct kvm_run *kvm_run = svm->vcpu.run;
@@ -2542,20 +2682,9 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
struct vcpu_svm *svm = to_svm(vcpu);
switch (ecx) {
- case MSR_IA32_TSC: {
- u64 tsc_offset = data - native_read_tsc();
- u64 g_tsc_offset = 0;
-
- if (is_nested(svm)) {
- g_tsc_offset = svm->vmcb->control.tsc_offset -
- svm->nested.hsave->control.tsc_offset;
- svm->nested.hsave->control.tsc_offset = tsc_offset;
- }
-
- svm->vmcb->control.tsc_offset = tsc_offset + g_tsc_offset;
-
+ case MSR_IA32_TSC:
+ kvm_write_tsc(vcpu, data);
break;
- }
case MSR_STAR:
svm->vmcb->save.star = data;
break;
@@ -2643,6 +2772,7 @@ static int interrupt_window_interception(struct vcpu_svm *svm)
{
struct kvm_run *kvm_run = svm->vcpu.run;
+ kvm_make_request(KVM_REQ_EVENT, &svm->vcpu);
svm_clear_vintr(svm);
svm->vmcb->control.int_ctl &= ~V_IRQ_MASK;
/*
@@ -2672,7 +2802,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = {
[SVM_EXIT_READ_CR4] = emulate_on_interception,
[SVM_EXIT_READ_CR8] = emulate_on_interception,
[SVM_EXIT_CR0_SEL_WRITE] = emulate_on_interception,
- [SVM_EXIT_WRITE_CR0] = emulate_on_interception,
+ [SVM_EXIT_WRITE_CR0] = cr0_write_interception,
[SVM_EXIT_WRITE_CR3] = emulate_on_interception,
[SVM_EXIT_WRITE_CR4] = emulate_on_interception,
[SVM_EXIT_WRITE_CR8] = cr8_write_interception,
@@ -2871,7 +3001,8 @@ static int handle_exit(struct kvm_vcpu *vcpu)
if (is_external_interrupt(svm->vmcb->control.exit_int_info) &&
exit_code != SVM_EXIT_EXCP_BASE + PF_VECTOR &&
- exit_code != SVM_EXIT_NPF && exit_code != SVM_EXIT_TASK_SWITCH)
+ exit_code != SVM_EXIT_NPF && exit_code != SVM_EXIT_TASK_SWITCH &&
+ exit_code != SVM_EXIT_INTR && exit_code != SVM_EXIT_NMI)
printk(KERN_ERR "%s: unexpected exit_ini_info 0x%x "
"exit_code 0x%x\n",
__func__, svm->vmcb->control.exit_int_info,
@@ -3088,8 +3219,10 @@ static void svm_complete_interrupts(struct vcpu_svm *svm)
svm->int3_injected = 0;
- if (svm->vcpu.arch.hflags & HF_IRET_MASK)
+ if (svm->vcpu.arch.hflags & HF_IRET_MASK) {
svm->vcpu.arch.hflags &= ~(HF_NMI_MASK | HF_IRET_MASK);
+ kvm_make_request(KVM_REQ_EVENT, &svm->vcpu);
+ }
svm->vcpu.arch.nmi_injected = false;
kvm_clear_exception_queue(&svm->vcpu);
@@ -3098,6 +3231,8 @@ static void svm_complete_interrupts(struct vcpu_svm *svm)
if (!(exitintinfo & SVM_EXITINTINFO_VALID))
return;
+ kvm_make_request(KVM_REQ_EVENT, &svm->vcpu);
+
vector = exitintinfo & SVM_EXITINTINFO_VEC_MASK;
type = exitintinfo & SVM_EXITINTINFO_TYPE_MASK;
@@ -3134,6 +3269,17 @@ static void svm_complete_interrupts(struct vcpu_svm *svm)
}
}
+static void svm_cancel_injection(struct kvm_vcpu *vcpu)
+{
+ struct vcpu_svm *svm = to_svm(vcpu);
+ struct vmcb_control_area *control = &svm->vmcb->control;
+
+ control->exit_int_info = control->event_inj;
+ control->exit_int_info_err = control->event_inj_err;
+ control->event_inj = 0;
+ svm_complete_interrupts(svm);
+}
+
#ifdef CONFIG_X86_64
#define R "r"
#else
@@ -3163,13 +3309,10 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
sync_lapic_to_cr8(vcpu);
save_host_msrs(vcpu);
- fs_selector = kvm_read_fs();
- gs_selector = kvm_read_gs();
+ savesegment(fs, fs_selector);
+ savesegment(gs, gs_selector);
ldt_selector = kvm_read_ldt();
svm->vmcb->save.cr2 = vcpu->arch.cr2;
- /* required for live migration with NPT */
- if (npt_enabled)
- svm->vmcb->save.cr3 = vcpu->arch.cr3;
clgi();
@@ -3251,10 +3394,15 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp;
vcpu->arch.regs[VCPU_REGS_RIP] = svm->vmcb->save.rip;
- kvm_load_fs(fs_selector);
- kvm_load_gs(gs_selector);
- kvm_load_ldt(ldt_selector);
load_host_msrs(vcpu);
+ loadsegment(fs, fs_selector);
+#ifdef CONFIG_X86_64
+ load_gs_index(gs_selector);
+ wrmsrl(MSR_KERNEL_GS_BASE, current->thread.gs);
+#else
+ loadsegment(gs, gs_selector);
+#endif
+ kvm_load_ldt(ldt_selector);
reload_tss(vcpu);
@@ -3286,16 +3434,22 @@ static void svm_set_cr3(struct kvm_vcpu *vcpu, unsigned long root)
{
struct vcpu_svm *svm = to_svm(vcpu);
- if (npt_enabled) {
- svm->vmcb->control.nested_cr3 = root;
- force_new_asid(vcpu);
- return;
- }
-
svm->vmcb->save.cr3 = root;
force_new_asid(vcpu);
}
+static void set_tdp_cr3(struct kvm_vcpu *vcpu, unsigned long root)
+{
+ struct vcpu_svm *svm = to_svm(vcpu);
+
+ svm->vmcb->control.nested_cr3 = root;
+
+ /* Also sync guest cr3 here in case we live migrate */
+ svm->vmcb->save.cr3 = vcpu->arch.cr3;
+
+ force_new_asid(vcpu);
+}
+
static int is_disabled(void)
{
u64 vm_cr;
@@ -3328,15 +3482,6 @@ static bool svm_cpu_has_accelerated_tpr(void)
return false;
}
-static int get_npt_level(void)
-{
-#ifdef CONFIG_X86_64
- return PT64_ROOT_LEVEL;
-#else
- return PT32E_ROOT_LEVEL;
-#endif
-}
-
static u64 svm_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
{
return 0;
@@ -3349,12 +3494,25 @@ static void svm_cpuid_update(struct kvm_vcpu *vcpu)
static void svm_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry)
{
switch (func) {
+ case 0x80000001:
+ if (nested)
+ entry->ecx |= (1 << 2); /* Set SVM bit */
+ break;
case 0x8000000A:
entry->eax = 1; /* SVM revision 1 */
entry->ebx = 8; /* Lets support 8 ASIDs in case we add proper
ASID emulation to nested SVM */
entry->ecx = 0; /* Reserved */
- entry->edx = 0; /* Do not support any additional features */
+ entry->edx = 0; /* Per default do not support any
+ additional features */
+
+ /* Support next_rip if host supports it */
+ if (svm_has(SVM_FEATURE_NRIP))
+ entry->edx |= SVM_FEATURE_NRIP;
+
+ /* Support NPT for the guest if enabled */
+ if (npt_enabled)
+ entry->edx |= SVM_FEATURE_NPT;
break;
}
@@ -3492,6 +3650,7 @@ static struct kvm_x86_ops svm_x86_ops = {
.set_irq = svm_set_irq,
.set_nmi = svm_inject_nmi,
.queue_exception = svm_queue_exception,
+ .cancel_injection = svm_cancel_injection,
.interrupt_allowed = svm_interrupt_allowed,
.nmi_allowed = svm_nmi_allowed,
.get_nmi_mask = svm_get_nmi_mask,
@@ -3514,6 +3673,11 @@ static struct kvm_x86_ops svm_x86_ops = {
.set_supported_cpuid = svm_set_supported_cpuid,
.has_wbinvd_exit = svm_has_wbinvd_exit,
+
+ .write_tsc_offset = svm_write_tsc_offset,
+ .adjust_tsc_offset = svm_adjust_tsc_offset,
+
+ .set_tdp_cr3 = set_tdp_cr3,
};
static int __init svm_init(void)
diff --git a/arch/x86/kvm/timer.c b/arch/x86/kvm/timer.c
index e16a0dbe74d8..fc7a101c4a35 100644
--- a/arch/x86/kvm/timer.c
+++ b/arch/x86/kvm/timer.c
@@ -6,7 +6,7 @@
*
* timer support
*
- * Copyright 2010 Red Hat, Inc. and/or its affilates.
+ * Copyright 2010 Red Hat, Inc. and/or its affiliates.
*
* This work is licensed under the terms of the GNU GPL, version 2. See
* the COPYING file in the top-level directory.
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 49b25eee25ac..8da0e45ff7c9 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -5,7 +5,7 @@
* machines without emulation or binary translation.
*
* Copyright (C) 2006 Qumranet, Inc.
- * Copyright 2010 Red Hat, Inc. and/or its affilates.
+ * Copyright 2010 Red Hat, Inc. and/or its affiliates.
*
* Authors:
* Avi Kivity <avi@qumranet.com>
@@ -125,6 +125,7 @@ struct vcpu_vmx {
unsigned long host_rsp;
int launched;
u8 fail;
+ u32 exit_intr_info;
u32 idt_vectoring_info;
struct shared_msr_entry *guest_msrs;
int nmsrs;
@@ -154,11 +155,6 @@ struct vcpu_vmx {
u32 limit;
u32 ar;
} tr, es, ds, fs, gs;
- struct {
- bool pending;
- u8 vector;
- unsigned rip;
- } irq;
} rmode;
int vpid;
bool emulation_required;
@@ -505,7 +501,6 @@ static void __vcpu_clear(void *arg)
vmcs_clear(vmx->vmcs);
if (per_cpu(current_vmcs, cpu) == vmx->vmcs)
per_cpu(current_vmcs, cpu) = NULL;
- rdtscll(vmx->vcpu.arch.host_tsc);
list_del(&vmx->local_vcpus_link);
vmx->vcpu.cpu = -1;
vmx->launched = 0;
@@ -706,11 +701,10 @@ static void reload_tss(void)
/*
* VT restores TR but not its size. Useless.
*/
- struct desc_ptr gdt;
+ struct desc_ptr *gdt = &__get_cpu_var(host_gdt);
struct desc_struct *descs;
- native_store_gdt(&gdt);
- descs = (void *)gdt.address;
+ descs = (void *)gdt->address;
descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
load_TR_desc();
}
@@ -753,7 +747,7 @@ static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset)
static unsigned long segment_base(u16 selector)
{
- struct desc_ptr gdt;
+ struct desc_ptr *gdt = &__get_cpu_var(host_gdt);
struct desc_struct *d;
unsigned long table_base;
unsigned long v;
@@ -761,8 +755,7 @@ static unsigned long segment_base(u16 selector)
if (!(selector & ~3))
return 0;
- native_store_gdt(&gdt);
- table_base = gdt.address;
+ table_base = gdt->address;
if (selector & 4) { /* from ldt */
u16 ldt_selector = kvm_read_ldt();
@@ -803,7 +796,7 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu)
*/
vmx->host_state.ldt_sel = kvm_read_ldt();
vmx->host_state.gs_ldt_reload_needed = vmx->host_state.ldt_sel;
- vmx->host_state.fs_sel = kvm_read_fs();
+ savesegment(fs, vmx->host_state.fs_sel);
if (!(vmx->host_state.fs_sel & 7)) {
vmcs_write16(HOST_FS_SELECTOR, vmx->host_state.fs_sel);
vmx->host_state.fs_reload_needed = 0;
@@ -811,7 +804,7 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu)
vmcs_write16(HOST_FS_SELECTOR, 0);
vmx->host_state.fs_reload_needed = 1;
}
- vmx->host_state.gs_sel = kvm_read_gs();
+ savesegment(gs, vmx->host_state.gs_sel);
if (!(vmx->host_state.gs_sel & 7))
vmcs_write16(HOST_GS_SELECTOR, vmx->host_state.gs_sel);
else {
@@ -841,27 +834,21 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu)
static void __vmx_load_host_state(struct vcpu_vmx *vmx)
{
- unsigned long flags;
-
if (!vmx->host_state.loaded)
return;
++vmx->vcpu.stat.host_state_reload;
vmx->host_state.loaded = 0;
if (vmx->host_state.fs_reload_needed)
- kvm_load_fs(vmx->host_state.fs_sel);
+ loadsegment(fs, vmx->host_state.fs_sel);
if (vmx->host_state.gs_ldt_reload_needed) {
kvm_load_ldt(vmx->host_state.ldt_sel);
- /*
- * If we have to reload gs, we must take care to
- * preserve our gs base.
- */
- local_irq_save(flags);
- kvm_load_gs(vmx->host_state.gs_sel);
#ifdef CONFIG_X86_64
- wrmsrl(MSR_GS_BASE, vmcs_readl(HOST_GS_BASE));
+ load_gs_index(vmx->host_state.gs_sel);
+ wrmsrl(MSR_KERNEL_GS_BASE, current->thread.gs);
+#else
+ loadsegment(gs, vmx->host_state.gs_sel);
#endif
- local_irq_restore(flags);
}
reload_tss();
#ifdef CONFIG_X86_64
@@ -889,7 +876,6 @@ static void vmx_load_host_state(struct vcpu_vmx *vmx)
static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
- u64 tsc_this, delta, new_offset;
u64 phys_addr = __pa(per_cpu(vmxarea, cpu));
if (!vmm_exclusive)
@@ -903,37 +889,24 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
}
if (vcpu->cpu != cpu) {
- struct desc_ptr dt;
+ struct desc_ptr *gdt = &__get_cpu_var(host_gdt);
unsigned long sysenter_esp;
- kvm_migrate_timers(vcpu);
kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
local_irq_disable();
list_add(&vmx->local_vcpus_link,
&per_cpu(vcpus_on_cpu, cpu));
local_irq_enable();
- vcpu->cpu = cpu;
/*
* Linux uses per-cpu TSS and GDT, so set these when switching
* processors.
*/
vmcs_writel(HOST_TR_BASE, kvm_read_tr_base()); /* 22.2.4 */
- native_store_gdt(&dt);
- vmcs_writel(HOST_GDTR_BASE, dt.address); /* 22.2.4 */
+ vmcs_writel(HOST_GDTR_BASE, gdt->address); /* 22.2.4 */
rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp);
vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */
-
- /*
- * Make sure the time stamp counter is monotonous.
- */
- rdtscll(tsc_this);
- if (tsc_this < vcpu->arch.host_tsc) {
- delta = vcpu->arch.host_tsc - tsc_this;
- new_offset = vmcs_read64(TSC_OFFSET) + delta;
- vmcs_write64(TSC_OFFSET, new_offset);
- }
}
}
@@ -1050,16 +1023,8 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
}
if (vmx->rmode.vm86_active) {
- vmx->rmode.irq.pending = true;
- vmx->rmode.irq.vector = nr;
- vmx->rmode.irq.rip = kvm_rip_read(vcpu);
- if (kvm_exception_is_soft(nr))
- vmx->rmode.irq.rip +=
- vmx->vcpu.arch.event_exit_inst_len;
- intr_info |= INTR_TYPE_SOFT_INTR;
- vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info);
- vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1);
- kvm_rip_write(vcpu, vmx->rmode.irq.rip - 1);
+ if (kvm_inject_realmode_interrupt(vcpu, nr) != EMULATE_DONE)
+ kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);
return;
}
@@ -1155,12 +1120,17 @@ static u64 guest_read_tsc(void)
}
/*
- * writes 'guest_tsc' into guest's timestamp counter "register"
- * guest_tsc = host_tsc + tsc_offset ==> tsc_offset = guest_tsc - host_tsc
+ * writes 'offset' into guest's timestamp counter offset register
*/
-static void guest_write_tsc(u64 guest_tsc, u64 host_tsc)
+static void vmx_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
{
- vmcs_write64(TSC_OFFSET, guest_tsc - host_tsc);
+ vmcs_write64(TSC_OFFSET, offset);
+}
+
+static void vmx_adjust_tsc_offset(struct kvm_vcpu *vcpu, s64 adjustment)
+{
+ u64 offset = vmcs_read64(TSC_OFFSET);
+ vmcs_write64(TSC_OFFSET, offset + adjustment);
}
/*
@@ -1233,7 +1203,6 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
struct shared_msr_entry *msr;
- u64 host_tsc;
int ret = 0;
switch (msr_index) {
@@ -1263,8 +1232,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
vmcs_writel(GUEST_SYSENTER_ESP, data);
break;
case MSR_IA32_TSC:
- rdtscll(host_tsc);
- guest_write_tsc(data, host_tsc);
+ kvm_write_tsc(vcpu, data);
break;
case MSR_IA32_CR_PAT:
if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PAT) {
@@ -1862,20 +1830,20 @@ static void ept_load_pdptrs(struct kvm_vcpu *vcpu)
return;
if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) {
- vmcs_write64(GUEST_PDPTR0, vcpu->arch.pdptrs[0]);
- vmcs_write64(GUEST_PDPTR1, vcpu->arch.pdptrs[1]);
- vmcs_write64(GUEST_PDPTR2, vcpu->arch.pdptrs[2]);
- vmcs_write64(GUEST_PDPTR3, vcpu->arch.pdptrs[3]);
+ vmcs_write64(GUEST_PDPTR0, vcpu->arch.mmu.pdptrs[0]);
+ vmcs_write64(GUEST_PDPTR1, vcpu->arch.mmu.pdptrs[1]);
+ vmcs_write64(GUEST_PDPTR2, vcpu->arch.mmu.pdptrs[2]);
+ vmcs_write64(GUEST_PDPTR3, vcpu->arch.mmu.pdptrs[3]);
}
}
static void ept_save_pdptrs(struct kvm_vcpu *vcpu)
{
if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) {
- vcpu->arch.pdptrs[0] = vmcs_read64(GUEST_PDPTR0);
- vcpu->arch.pdptrs[1] = vmcs_read64(GUEST_PDPTR1);
- vcpu->arch.pdptrs[2] = vmcs_read64(GUEST_PDPTR2);
- vcpu->arch.pdptrs[3] = vmcs_read64(GUEST_PDPTR3);
+ vcpu->arch.mmu.pdptrs[0] = vmcs_read64(GUEST_PDPTR0);
+ vcpu->arch.mmu.pdptrs[1] = vmcs_read64(GUEST_PDPTR1);
+ vcpu->arch.mmu.pdptrs[2] = vmcs_read64(GUEST_PDPTR2);
+ vcpu->arch.mmu.pdptrs[3] = vmcs_read64(GUEST_PDPTR3);
}
__set_bit(VCPU_EXREG_PDPTR,
@@ -2521,7 +2489,7 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
{
u32 host_sysenter_cs, msr_low, msr_high;
u32 junk;
- u64 host_pat, tsc_this, tsc_base;
+ u64 host_pat;
unsigned long a;
struct desc_ptr dt;
int i;
@@ -2589,8 +2557,8 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
vmcs_write16(HOST_CS_SELECTOR, __KERNEL_CS); /* 22.2.4 */
vmcs_write16(HOST_DS_SELECTOR, __KERNEL_DS); /* 22.2.4 */
vmcs_write16(HOST_ES_SELECTOR, __KERNEL_DS); /* 22.2.4 */
- vmcs_write16(HOST_FS_SELECTOR, kvm_read_fs()); /* 22.2.4 */
- vmcs_write16(HOST_GS_SELECTOR, kvm_read_gs()); /* 22.2.4 */
+ vmcs_write16(HOST_FS_SELECTOR, 0); /* 22.2.4 */
+ vmcs_write16(HOST_GS_SELECTOR, 0); /* 22.2.4 */
vmcs_write16(HOST_SS_SELECTOR, __KERNEL_DS); /* 22.2.4 */
#ifdef CONFIG_X86_64
rdmsrl(MSR_FS_BASE, a);
@@ -2662,12 +2630,7 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
vmx->vcpu.arch.cr4_guest_owned_bits |= X86_CR4_PGE;
vmcs_writel(CR4_GUEST_HOST_MASK, ~vmx->vcpu.arch.cr4_guest_owned_bits);
- tsc_base = vmx->vcpu.kvm->arch.vm_init_tsc;
- rdtscll(tsc_this);
- if (tsc_this < vmx->vcpu.kvm->arch.vm_init_tsc)
- tsc_base = tsc_this;
-
- guest_write_tsc(0, tsc_base);
+ kvm_write_tsc(&vmx->vcpu, 0);
return 0;
}
@@ -2840,16 +2803,8 @@ static void vmx_inject_irq(struct kvm_vcpu *vcpu)
++vcpu->stat.irq_injections;
if (vmx->rmode.vm86_active) {
- vmx->rmode.irq.pending = true;
- vmx->rmode.irq.vector = irq;
- vmx->rmode.irq.rip = kvm_rip_read(vcpu);
- if (vcpu->arch.interrupt.soft)
- vmx->rmode.irq.rip +=
- vmx->vcpu.arch.event_exit_inst_len;
- vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
- irq | INTR_TYPE_SOFT_INTR | INTR_INFO_VALID_MASK);
- vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1);
- kvm_rip_write(vcpu, vmx->rmode.irq.rip - 1);
+ if (kvm_inject_realmode_interrupt(vcpu, irq) != EMULATE_DONE)
+ kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);
return;
}
intr = irq | INTR_INFO_VALID_MASK;
@@ -2881,14 +2836,8 @@ static void vmx_inject_nmi(struct kvm_vcpu *vcpu)
++vcpu->stat.nmi_injections;
if (vmx->rmode.vm86_active) {
- vmx->rmode.irq.pending = true;
- vmx->rmode.irq.vector = NMI_VECTOR;
- vmx->rmode.irq.rip = kvm_rip_read(vcpu);
- vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
- NMI_VECTOR | INTR_TYPE_SOFT_INTR |
- INTR_INFO_VALID_MASK);
- vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1);
- kvm_rip_write(vcpu, vmx->rmode.irq.rip - 1);
+ if (kvm_inject_realmode_interrupt(vcpu, NMI_VECTOR) != EMULATE_DONE)
+ kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);
return;
}
vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
@@ -3352,6 +3301,7 @@ static int handle_wrmsr(struct kvm_vcpu *vcpu)
static int handle_tpr_below_threshold(struct kvm_vcpu *vcpu)
{
+ kvm_make_request(KVM_REQ_EVENT, vcpu);
return 1;
}
@@ -3364,6 +3314,8 @@ static int handle_interrupt_window(struct kvm_vcpu *vcpu)
cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
+ kvm_make_request(KVM_REQ_EVENT, vcpu);
+
++vcpu->stat.irq_window_exits;
/*
@@ -3620,6 +3572,7 @@ static int handle_nmi_window(struct kvm_vcpu *vcpu)
cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_NMI_PENDING;
vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
++vcpu->stat.nmi_window_exits;
+ kvm_make_request(KVM_REQ_EVENT, vcpu);
return 1;
}
@@ -3629,8 +3582,17 @@ static int handle_invalid_guest_state(struct kvm_vcpu *vcpu)
struct vcpu_vmx *vmx = to_vmx(vcpu);
enum emulation_result err = EMULATE_DONE;
int ret = 1;
+ u32 cpu_exec_ctrl;
+ bool intr_window_requested;
+
+ cpu_exec_ctrl = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
+ intr_window_requested = cpu_exec_ctrl & CPU_BASED_VIRTUAL_INTR_PENDING;
while (!guest_state_valid(vcpu)) {
+ if (intr_window_requested
+ && (kvm_get_rflags(&vmx->vcpu) & X86_EFLAGS_IF))
+ return handle_interrupt_window(&vmx->vcpu);
+
err = emulate_instruction(vcpu, 0, 0, 0);
if (err == EMULATE_DO_MMIO) {
@@ -3796,18 +3758,9 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr)
vmcs_write32(TPR_THRESHOLD, irr);
}
-static void vmx_complete_interrupts(struct vcpu_vmx *vmx)
+static void vmx_complete_atomic_exit(struct vcpu_vmx *vmx)
{
- u32 exit_intr_info;
- u32 idt_vectoring_info = vmx->idt_vectoring_info;
- bool unblock_nmi;
- u8 vector;
- int type;
- bool idtv_info_valid;
-
- exit_intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
-
- vmx->exit_reason = vmcs_read32(VM_EXIT_REASON);
+ u32 exit_intr_info = vmx->exit_intr_info;
/* Handle machine checks before interrupts are enabled */
if ((vmx->exit_reason == EXIT_REASON_MCE_DURING_VMENTRY)
@@ -3822,8 +3775,16 @@ static void vmx_complete_interrupts(struct vcpu_vmx *vmx)
asm("int $2");
kvm_after_handle_nmi(&vmx->vcpu);
}
+}
- idtv_info_valid = idt_vectoring_info & VECTORING_INFO_VALID_MASK;
+static void vmx_recover_nmi_blocking(struct vcpu_vmx *vmx)
+{
+ u32 exit_intr_info = vmx->exit_intr_info;
+ bool unblock_nmi;
+ u8 vector;
+ bool idtv_info_valid;
+
+ idtv_info_valid = vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK;
if (cpu_has_virtual_nmis()) {
unblock_nmi = (exit_intr_info & INTR_INFO_UNBLOCK_NMI) != 0;
@@ -3845,6 +3806,18 @@ static void vmx_complete_interrupts(struct vcpu_vmx *vmx)
} else if (unlikely(vmx->soft_vnmi_blocked))
vmx->vnmi_blocked_time +=
ktime_to_ns(ktime_sub(ktime_get(), vmx->entry_time));
+}
+
+static void __vmx_complete_interrupts(struct vcpu_vmx *vmx,
+ u32 idt_vectoring_info,
+ int instr_len_field,
+ int error_code_field)
+{
+ u8 vector;
+ int type;
+ bool idtv_info_valid;
+
+ idtv_info_valid = idt_vectoring_info & VECTORING_INFO_VALID_MASK;
vmx->vcpu.arch.nmi_injected = false;
kvm_clear_exception_queue(&vmx->vcpu);
@@ -3853,6 +3826,8 @@ static void vmx_complete_interrupts(struct vcpu_vmx *vmx)
if (!idtv_info_valid)
return;
+ kvm_make_request(KVM_REQ_EVENT, &vmx->vcpu);
+
vector = idt_vectoring_info & VECTORING_INFO_VECTOR_MASK;
type = idt_vectoring_info & VECTORING_INFO_TYPE_MASK;
@@ -3869,18 +3844,18 @@ static void vmx_complete_interrupts(struct vcpu_vmx *vmx)
break;
case INTR_TYPE_SOFT_EXCEPTION:
vmx->vcpu.arch.event_exit_inst_len =
- vmcs_read32(VM_EXIT_INSTRUCTION_LEN);
+ vmcs_read32(instr_len_field);
/* fall through */
case INTR_TYPE_HARD_EXCEPTION:
if (idt_vectoring_info & VECTORING_INFO_DELIVER_CODE_MASK) {
- u32 err = vmcs_read32(IDT_VECTORING_ERROR_CODE);
+ u32 err = vmcs_read32(error_code_field);
kvm_queue_exception_e(&vmx->vcpu, vector, err);
} else
kvm_queue_exception(&vmx->vcpu, vector);
break;
case INTR_TYPE_SOFT_INTR:
vmx->vcpu.arch.event_exit_inst_len =
- vmcs_read32(VM_EXIT_INSTRUCTION_LEN);
+ vmcs_read32(instr_len_field);
/* fall through */
case INTR_TYPE_EXT_INTR:
kvm_queue_interrupt(&vmx->vcpu, vector,
@@ -3891,27 +3866,21 @@ static void vmx_complete_interrupts(struct vcpu_vmx *vmx)
}
}
-/*
- * Failure to inject an interrupt should give us the information
- * in IDT_VECTORING_INFO_FIELD. However, if the failure occurs
- * when fetching the interrupt redirection bitmap in the real-mode
- * tss, this doesn't happen. So we do it ourselves.
- */
-static void fixup_rmode_irq(struct vcpu_vmx *vmx)
+static void vmx_complete_interrupts(struct vcpu_vmx *vmx)
{
- vmx->rmode.irq.pending = 0;
- if (kvm_rip_read(&vmx->vcpu) + 1 != vmx->rmode.irq.rip)
- return;
- kvm_rip_write(&vmx->vcpu, vmx->rmode.irq.rip);
- if (vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK) {
- vmx->idt_vectoring_info &= ~VECTORING_INFO_TYPE_MASK;
- vmx->idt_vectoring_info |= INTR_TYPE_EXT_INTR;
- return;
- }
- vmx->idt_vectoring_info =
- VECTORING_INFO_VALID_MASK
- | INTR_TYPE_EXT_INTR
- | vmx->rmode.irq.vector;
+ __vmx_complete_interrupts(vmx, vmx->idt_vectoring_info,
+ VM_EXIT_INSTRUCTION_LEN,
+ IDT_VECTORING_ERROR_CODE);
+}
+
+static void vmx_cancel_injection(struct kvm_vcpu *vcpu)
+{
+ __vmx_complete_interrupts(to_vmx(vcpu),
+ vmcs_read32(VM_ENTRY_INTR_INFO_FIELD),
+ VM_ENTRY_INSTRUCTION_LEN,
+ VM_ENTRY_EXCEPTION_ERROR_CODE);
+
+ vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, 0);
}
#ifdef CONFIG_X86_64
@@ -4038,7 +4007,7 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu)
#endif
[cr2]"i"(offsetof(struct vcpu_vmx, vcpu.arch.cr2))
: "cc", "memory"
- , R"bx", R"di", R"si"
+ , R"ax", R"bx", R"di", R"si"
#ifdef CONFIG_X86_64
, "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
#endif
@@ -4049,12 +4018,15 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu)
vcpu->arch.regs_dirty = 0;
vmx->idt_vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD);
- if (vmx->rmode.irq.pending)
- fixup_rmode_irq(vmx);
asm("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
vmx->launched = 1;
+ vmx->exit_reason = vmcs_read32(VM_EXIT_REASON);
+ vmx->exit_intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
+
+ vmx_complete_atomic_exit(vmx);
+ vmx_recover_nmi_blocking(vmx);
vmx_complete_interrupts(vmx);
}
@@ -4125,6 +4097,7 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
cpu = get_cpu();
vmx_vcpu_load(&vmx->vcpu, cpu);
+ vmx->vcpu.cpu = cpu;
err = vmx_vcpu_setup(vmx);
vmx_vcpu_put(&vmx->vcpu);
put_cpu();
@@ -4340,6 +4313,7 @@ static struct kvm_x86_ops vmx_x86_ops = {
.set_irq = vmx_inject_irq,
.set_nmi = vmx_inject_nmi,
.queue_exception = vmx_queue_exception,
+ .cancel_injection = vmx_cancel_injection,
.interrupt_allowed = vmx_interrupt_allowed,
.nmi_allowed = vmx_nmi_allowed,
.get_nmi_mask = vmx_get_nmi_mask,
@@ -4362,6 +4336,11 @@ static struct kvm_x86_ops vmx_x86_ops = {
.set_supported_cpuid = vmx_set_supported_cpuid,
.has_wbinvd_exit = cpu_has_vmx_wbinvd_exit,
+
+ .write_tsc_offset = vmx_write_tsc_offset,
+ .adjust_tsc_offset = vmx_adjust_tsc_offset,
+
+ .set_tdp_cr3 = vmx_set_cr3,
};
static int __init vmx_init(void)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 3a09c625d526..2288ad829b32 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -6,7 +6,7 @@
* Copyright (C) 2006 Qumranet, Inc.
* Copyright (C) 2008 Qumranet, Inc.
* Copyright IBM Corporation, 2008
- * Copyright 2010 Red Hat, Inc. and/or its affilates.
+ * Copyright 2010 Red Hat, Inc. and/or its affiliates.
*
* Authors:
* Avi Kivity <avi@qumranet.com>
@@ -55,6 +55,8 @@
#include <asm/mce.h>
#include <asm/i387.h>
#include <asm/xcr.h>
+#include <asm/pvclock.h>
+#include <asm/div64.h>
#define MAX_IO_MSRS 256
#define CR0_RESERVED_BITS \
@@ -71,7 +73,7 @@
#define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR)
#define KVM_MAX_MCE_BANKS 32
-#define KVM_MCE_CAP_SUPPORTED MCG_CTL_P
+#define KVM_MCE_CAP_SUPPORTED (MCG_CTL_P | MCG_SER_P)
/* EFER defaults:
* - enable syscall per default because its emulated by KVM
@@ -282,6 +284,8 @@ static void kvm_multiple_exception(struct kvm_vcpu *vcpu,
u32 prev_nr;
int class1, class2;
+ kvm_make_request(KVM_REQ_EVENT, vcpu);
+
if (!vcpu->arch.exception.pending) {
queue:
vcpu->arch.exception.pending = true;
@@ -327,16 +331,28 @@ void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned nr)
}
EXPORT_SYMBOL_GPL(kvm_requeue_exception);
-void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long addr,
- u32 error_code)
+void kvm_inject_page_fault(struct kvm_vcpu *vcpu)
{
+ unsigned error_code = vcpu->arch.fault.error_code;
+
++vcpu->stat.pf_guest;
- vcpu->arch.cr2 = addr;
+ vcpu->arch.cr2 = vcpu->arch.fault.address;
kvm_queue_exception_e(vcpu, PF_VECTOR, error_code);
}
+void kvm_propagate_fault(struct kvm_vcpu *vcpu)
+{
+ if (mmu_is_nested(vcpu) && !vcpu->arch.fault.nested)
+ vcpu->arch.nested_mmu.inject_page_fault(vcpu);
+ else
+ vcpu->arch.mmu.inject_page_fault(vcpu);
+
+ vcpu->arch.fault.nested = false;
+}
+
void kvm_inject_nmi(struct kvm_vcpu *vcpu)
{
+ kvm_make_request(KVM_REQ_EVENT, vcpu);
vcpu->arch.nmi_pending = 1;
}
EXPORT_SYMBOL_GPL(kvm_inject_nmi);
@@ -367,18 +383,49 @@ bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl)
EXPORT_SYMBOL_GPL(kvm_require_cpl);
/*
+ * This function will be used to read from the physical memory of the currently
+ * running guest. The difference to kvm_read_guest_page is that this function
+ * can read from guest physical or from the guest's guest physical memory.
+ */
+int kvm_read_guest_page_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
+ gfn_t ngfn, void *data, int offset, int len,
+ u32 access)
+{
+ gfn_t real_gfn;
+ gpa_t ngpa;
+
+ ngpa = gfn_to_gpa(ngfn);
+ real_gfn = mmu->translate_gpa(vcpu, ngpa, access);
+ if (real_gfn == UNMAPPED_GVA)
+ return -EFAULT;
+
+ real_gfn = gpa_to_gfn(real_gfn);
+
+ return kvm_read_guest_page(vcpu->kvm, real_gfn, data, offset, len);
+}
+EXPORT_SYMBOL_GPL(kvm_read_guest_page_mmu);
+
+int kvm_read_nested_guest_page(struct kvm_vcpu *vcpu, gfn_t gfn,
+ void *data, int offset, int len, u32 access)
+{
+ return kvm_read_guest_page_mmu(vcpu, vcpu->arch.walk_mmu, gfn,
+ data, offset, len, access);
+}
+
+/*
* Load the pae pdptrs. Return true is they are all valid.
*/
-int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
+int load_pdptrs(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, unsigned long cr3)
{
gfn_t pdpt_gfn = cr3 >> PAGE_SHIFT;
unsigned offset = ((cr3 & (PAGE_SIZE-1)) >> 5) << 2;
int i;
int ret;
- u64 pdpte[ARRAY_SIZE(vcpu->arch.pdptrs)];
+ u64 pdpte[ARRAY_SIZE(mmu->pdptrs)];
- ret = kvm_read_guest_page(vcpu->kvm, pdpt_gfn, pdpte,
- offset * sizeof(u64), sizeof(pdpte));
+ ret = kvm_read_guest_page_mmu(vcpu, mmu, pdpt_gfn, pdpte,
+ offset * sizeof(u64), sizeof(pdpte),
+ PFERR_USER_MASK|PFERR_WRITE_MASK);
if (ret < 0) {
ret = 0;
goto out;
@@ -392,7 +439,7 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
}
ret = 1;
- memcpy(vcpu->arch.pdptrs, pdpte, sizeof(vcpu->arch.pdptrs));
+ memcpy(mmu->pdptrs, pdpte, sizeof(mmu->pdptrs));
__set_bit(VCPU_EXREG_PDPTR,
(unsigned long *)&vcpu->arch.regs_avail);
__set_bit(VCPU_EXREG_PDPTR,
@@ -405,8 +452,10 @@ EXPORT_SYMBOL_GPL(load_pdptrs);
static bool pdptrs_changed(struct kvm_vcpu *vcpu)
{
- u64 pdpte[ARRAY_SIZE(vcpu->arch.pdptrs)];
+ u64 pdpte[ARRAY_SIZE(vcpu->arch.walk_mmu->pdptrs)];
bool changed = true;
+ int offset;
+ gfn_t gfn;
int r;
if (is_long_mode(vcpu) || !is_pae(vcpu))
@@ -416,10 +465,13 @@ static bool pdptrs_changed(struct kvm_vcpu *vcpu)
(unsigned long *)&vcpu->arch.regs_avail))
return true;
- r = kvm_read_guest(vcpu->kvm, vcpu->arch.cr3 & ~31u, pdpte, sizeof(pdpte));
+ gfn = (vcpu->arch.cr3 & ~31u) >> PAGE_SHIFT;
+ offset = (vcpu->arch.cr3 & ~31u) & (PAGE_SIZE - 1);
+ r = kvm_read_nested_guest_page(vcpu, gfn, pdpte, offset, sizeof(pdpte),
+ PFERR_USER_MASK | PFERR_WRITE_MASK);
if (r < 0)
goto out;
- changed = memcmp(pdpte, vcpu->arch.pdptrs, sizeof(pdpte)) != 0;
+ changed = memcmp(pdpte, vcpu->arch.walk_mmu->pdptrs, sizeof(pdpte)) != 0;
out:
return changed;
@@ -458,7 +510,8 @@ int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
return 1;
} else
#endif
- if (is_pae(vcpu) && !load_pdptrs(vcpu, vcpu->arch.cr3))
+ if (is_pae(vcpu) && !load_pdptrs(vcpu, vcpu->arch.walk_mmu,
+ vcpu->arch.cr3))
return 1;
}
@@ -547,7 +600,7 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
return 1;
} else if (is_paging(vcpu) && (cr4 & X86_CR4_PAE)
&& ((cr4 ^ old_cr4) & pdptr_bits)
- && !load_pdptrs(vcpu, vcpu->arch.cr3))
+ && !load_pdptrs(vcpu, vcpu->arch.walk_mmu, vcpu->arch.cr3))
return 1;
if (cr4 & X86_CR4_VMXE)
@@ -580,7 +633,8 @@ int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
if (is_pae(vcpu)) {
if (cr3 & CR3_PAE_RESERVED_BITS)
return 1;
- if (is_paging(vcpu) && !load_pdptrs(vcpu, cr3))
+ if (is_paging(vcpu) &&
+ !load_pdptrs(vcpu, vcpu->arch.walk_mmu, cr3))
return 1;
}
/*
@@ -737,7 +791,7 @@ static u32 msrs_to_save[] = {
#ifdef CONFIG_X86_64
MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR,
#endif
- MSR_IA32_TSC, MSR_IA32_PERF_STATUS, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA
+ MSR_IA32_TSC, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA
};
static unsigned num_msrs_to_save;
@@ -838,7 +892,7 @@ static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock)
/*
* The guest calculates current wall clock time by adding
- * system time (updated by kvm_write_guest_time below) to the
+ * system time (updated by kvm_guest_time_update below) to the
* wall clock specified here. guest system time equals host
* system time for us, thus we must fill in host boot time here.
*/
@@ -866,65 +920,229 @@ static uint32_t div_frac(uint32_t dividend, uint32_t divisor)
return quotient;
}
-static void kvm_set_time_scale(uint32_t tsc_khz, struct pvclock_vcpu_time_info *hv_clock)
+static void kvm_get_time_scale(uint32_t scaled_khz, uint32_t base_khz,
+ s8 *pshift, u32 *pmultiplier)
{
- uint64_t nsecs = 1000000000LL;
+ uint64_t scaled64;
int32_t shift = 0;
uint64_t tps64;
uint32_t tps32;
- tps64 = tsc_khz * 1000LL;
- while (tps64 > nsecs*2) {
+ tps64 = base_khz * 1000LL;
+ scaled64 = scaled_khz * 1000LL;
+ while (tps64 > scaled64*2 || tps64 & 0xffffffff00000000ULL) {
tps64 >>= 1;
shift--;
}
tps32 = (uint32_t)tps64;
- while (tps32 <= (uint32_t)nsecs) {
- tps32 <<= 1;
+ while (tps32 <= scaled64 || scaled64 & 0xffffffff00000000ULL) {
+ if (scaled64 & 0xffffffff00000000ULL || tps32 & 0x80000000)
+ scaled64 >>= 1;
+ else
+ tps32 <<= 1;
shift++;
}
- hv_clock->tsc_shift = shift;
- hv_clock->tsc_to_system_mul = div_frac(nsecs, tps32);
+ *pshift = shift;
+ *pmultiplier = div_frac(scaled64, tps32);
- pr_debug("%s: tsc_khz %u, tsc_shift %d, tsc_mul %u\n",
- __func__, tsc_khz, hv_clock->tsc_shift,
- hv_clock->tsc_to_system_mul);
+ pr_debug("%s: base_khz %u => %u, shift %d, mul %u\n",
+ __func__, base_khz, scaled_khz, shift, *pmultiplier);
+}
+
+static inline u64 get_kernel_ns(void)
+{
+ struct timespec ts;
+
+ WARN_ON(preemptible());
+ ktime_get_ts(&ts);
+ monotonic_to_bootbased(&ts);
+ return timespec_to_ns(&ts);
}
static DEFINE_PER_CPU(unsigned long, cpu_tsc_khz);
+unsigned long max_tsc_khz;
-static void kvm_write_guest_time(struct kvm_vcpu *v)
+static inline int kvm_tsc_changes_freq(void)
+{
+ int cpu = get_cpu();
+ int ret = !boot_cpu_has(X86_FEATURE_CONSTANT_TSC) &&
+ cpufreq_quick_get(cpu) != 0;
+ put_cpu();
+ return ret;
+}
+
+static inline u64 nsec_to_cycles(u64 nsec)
+{
+ u64 ret;
+
+ WARN_ON(preemptible());
+ if (kvm_tsc_changes_freq())
+ printk_once(KERN_WARNING
+ "kvm: unreliable cycle conversion on adjustable rate TSC\n");
+ ret = nsec * __get_cpu_var(cpu_tsc_khz);
+ do_div(ret, USEC_PER_SEC);
+ return ret;
+}
+
+static void kvm_arch_set_tsc_khz(struct kvm *kvm, u32 this_tsc_khz)
+{
+ /* Compute a scale to convert nanoseconds in TSC cycles */
+ kvm_get_time_scale(this_tsc_khz, NSEC_PER_SEC / 1000,
+ &kvm->arch.virtual_tsc_shift,
+ &kvm->arch.virtual_tsc_mult);
+ kvm->arch.virtual_tsc_khz = this_tsc_khz;
+}
+
+static u64 compute_guest_tsc(struct kvm_vcpu *vcpu, s64 kernel_ns)
+{
+ u64 tsc = pvclock_scale_delta(kernel_ns-vcpu->arch.last_tsc_nsec,
+ vcpu->kvm->arch.virtual_tsc_mult,
+ vcpu->kvm->arch.virtual_tsc_shift);
+ tsc += vcpu->arch.last_tsc_write;
+ return tsc;
+}
+
+void kvm_write_tsc(struct kvm_vcpu *vcpu, u64 data)
+{
+ struct kvm *kvm = vcpu->kvm;
+ u64 offset, ns, elapsed;
+ unsigned long flags;
+ s64 sdiff;
+
+ spin_lock_irqsave(&kvm->arch.tsc_write_lock, flags);
+ offset = data - native_read_tsc();
+ ns = get_kernel_ns();
+ elapsed = ns - kvm->arch.last_tsc_nsec;
+ sdiff = data - kvm->arch.last_tsc_write;
+ if (sdiff < 0)
+ sdiff = -sdiff;
+
+ /*
+ * Special case: close write to TSC within 5 seconds of
+ * another CPU is interpreted as an attempt to synchronize
+ * The 5 seconds is to accomodate host load / swapping as
+ * well as any reset of TSC during the boot process.
+ *
+ * In that case, for a reliable TSC, we can match TSC offsets,
+ * or make a best guest using elapsed value.
+ */
+ if (sdiff < nsec_to_cycles(5ULL * NSEC_PER_SEC) &&
+ elapsed < 5ULL * NSEC_PER_SEC) {
+ if (!check_tsc_unstable()) {
+ offset = kvm->arch.last_tsc_offset;
+ pr_debug("kvm: matched tsc offset for %llu\n", data);
+ } else {
+ u64 delta = nsec_to_cycles(elapsed);
+ offset += delta;
+ pr_debug("kvm: adjusted tsc offset by %llu\n", delta);
+ }
+ ns = kvm->arch.last_tsc_nsec;
+ }
+ kvm->arch.last_tsc_nsec = ns;
+ kvm->arch.last_tsc_write = data;
+ kvm->arch.last_tsc_offset = offset;
+ kvm_x86_ops->write_tsc_offset(vcpu, offset);
+ spin_unlock_irqrestore(&kvm->arch.tsc_write_lock, flags);
+
+ /* Reset of TSC must disable overshoot protection below */
+ vcpu->arch.hv_clock.tsc_timestamp = 0;
+ vcpu->arch.last_tsc_write = data;
+ vcpu->arch.last_tsc_nsec = ns;
+}
+EXPORT_SYMBOL_GPL(kvm_write_tsc);
+
+static int kvm_guest_time_update(struct kvm_vcpu *v)
{
- struct timespec ts;
unsigned long flags;
struct kvm_vcpu_arch *vcpu = &v->arch;
void *shared_kaddr;
unsigned long this_tsc_khz;
+ s64 kernel_ns, max_kernel_ns;
+ u64 tsc_timestamp;
- if ((!vcpu->time_page))
- return;
+ /* Keep irq disabled to prevent changes to the clock */
+ local_irq_save(flags);
+ kvm_get_msr(v, MSR_IA32_TSC, &tsc_timestamp);
+ kernel_ns = get_kernel_ns();
+ this_tsc_khz = __get_cpu_var(cpu_tsc_khz);
- this_tsc_khz = get_cpu_var(cpu_tsc_khz);
- if (unlikely(vcpu->hv_clock_tsc_khz != this_tsc_khz)) {
- kvm_set_time_scale(this_tsc_khz, &vcpu->hv_clock);
- vcpu->hv_clock_tsc_khz = this_tsc_khz;
+ if (unlikely(this_tsc_khz == 0)) {
+ local_irq_restore(flags);
+ kvm_make_request(KVM_REQ_CLOCK_UPDATE, v);
+ return 1;
+ }
+
+ /*
+ * We may have to catch up the TSC to match elapsed wall clock
+ * time for two reasons, even if kvmclock is used.
+ * 1) CPU could have been running below the maximum TSC rate
+ * 2) Broken TSC compensation resets the base at each VCPU
+ * entry to avoid unknown leaps of TSC even when running
+ * again on the same CPU. This may cause apparent elapsed
+ * time to disappear, and the guest to stand still or run
+ * very slowly.
+ */
+ if (vcpu->tsc_catchup) {
+ u64 tsc = compute_guest_tsc(v, kernel_ns);
+ if (tsc > tsc_timestamp) {
+ kvm_x86_ops->adjust_tsc_offset(v, tsc - tsc_timestamp);
+ tsc_timestamp = tsc;
+ }
}
- put_cpu_var(cpu_tsc_khz);
- /* Keep irq disabled to prevent changes to the clock */
- local_irq_save(flags);
- kvm_get_msr(v, MSR_IA32_TSC, &vcpu->hv_clock.tsc_timestamp);
- ktime_get_ts(&ts);
- monotonic_to_bootbased(&ts);
local_irq_restore(flags);
- /* With all the info we got, fill in the values */
+ if (!vcpu->time_page)
+ return 0;
- vcpu->hv_clock.system_time = ts.tv_nsec +
- (NSEC_PER_SEC * (u64)ts.tv_sec) + v->kvm->arch.kvmclock_offset;
+ /*
+ * Time as measured by the TSC may go backwards when resetting the base
+ * tsc_timestamp. The reason for this is that the TSC resolution is
+ * higher than the resolution of the other clock scales. Thus, many
+ * possible measurments of the TSC correspond to one measurement of any
+ * other clock, and so a spread of values is possible. This is not a
+ * problem for the computation of the nanosecond clock; with TSC rates
+ * around 1GHZ, there can only be a few cycles which correspond to one
+ * nanosecond value, and any path through this code will inevitably
+ * take longer than that. However, with the kernel_ns value itself,
+ * the precision may be much lower, down to HZ granularity. If the
+ * first sampling of TSC against kernel_ns ends in the low part of the
+ * range, and the second in the high end of the range, we can get:
+ *
+ * (TSC - offset_low) * S + kns_old > (TSC - offset_high) * S + kns_new
+ *
+ * As the sampling errors potentially range in the thousands of cycles,
+ * it is possible such a time value has already been observed by the
+ * guest. To protect against this, we must compute the system time as
+ * observed by the guest and ensure the new system time is greater.
+ */
+ max_kernel_ns = 0;
+ if (vcpu->hv_clock.tsc_timestamp && vcpu->last_guest_tsc) {
+ max_kernel_ns = vcpu->last_guest_tsc -
+ vcpu->hv_clock.tsc_timestamp;
+ max_kernel_ns = pvclock_scale_delta(max_kernel_ns,
+ vcpu->hv_clock.tsc_to_system_mul,
+ vcpu->hv_clock.tsc_shift);
+ max_kernel_ns += vcpu->last_kernel_ns;
+ }
+ if (unlikely(vcpu->hw_tsc_khz != this_tsc_khz)) {
+ kvm_get_time_scale(NSEC_PER_SEC / 1000, this_tsc_khz,
+ &vcpu->hv_clock.tsc_shift,
+ &vcpu->hv_clock.tsc_to_system_mul);
+ vcpu->hw_tsc_khz = this_tsc_khz;
+ }
+
+ if (max_kernel_ns > kernel_ns)
+ kernel_ns = max_kernel_ns;
+
+ /* With all the info we got, fill in the values */
+ vcpu->hv_clock.tsc_timestamp = tsc_timestamp;
+ vcpu->hv_clock.system_time = kernel_ns + v->kvm->arch.kvmclock_offset;
+ vcpu->last_kernel_ns = kernel_ns;
+ vcpu->last_guest_tsc = tsc_timestamp;
vcpu->hv_clock.flags = 0;
/*
@@ -942,16 +1160,7 @@ static void kvm_write_guest_time(struct kvm_vcpu *v)
kunmap_atomic(shared_kaddr, KM_USER0);
mark_page_dirty(v->kvm, vcpu->time >> PAGE_SHIFT);
-}
-
-static int kvm_request_guest_time_update(struct kvm_vcpu *v)
-{
- struct kvm_vcpu_arch *vcpu = &v->arch;
-
- if (!vcpu->time_page)
- return 0;
- kvm_make_request(KVM_REQ_KVMCLOCK_UPDATE, v);
- return 1;
+ return 0;
}
static bool msr_mtrr_valid(unsigned msr)
@@ -1277,6 +1486,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
}
vcpu->arch.time = data;
+ kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
/* we verify if the enable bit is set... */
if (!(data & 1))
@@ -1292,8 +1502,6 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
kvm_release_page_clean(vcpu->arch.time_page);
vcpu->arch.time_page = NULL;
}
-
- kvm_request_guest_time_update(vcpu);
break;
}
case MSR_IA32_MCG_CTL:
@@ -1330,6 +1538,16 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
pr_unimpl(vcpu, "unimplemented perfctr wrmsr: "
"0x%x data 0x%llx\n", msr, data);
break;
+ case MSR_K7_CLK_CTL:
+ /*
+ * Ignore all writes to this no longer documented MSR.
+ * Writes are only relevant for old K7 processors,
+ * all pre-dating SVM, but a recommended workaround from
+ * AMD for these chips. It is possible to speicify the
+ * affected processor models on the command line, hence
+ * the need to ignore the workaround.
+ */
+ break;
case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
if (kvm_hv_msr_partition_wide(msr)) {
int r;
@@ -1522,6 +1740,20 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
case 0xcd: /* fsb frequency */
data = 3;
break;
+ /*
+ * MSR_EBC_FREQUENCY_ID
+ * Conservative value valid for even the basic CPU models.
+ * Models 0,1: 000 in bits 23:21 indicating a bus speed of
+ * 100MHz, model 2 000 in bits 18:16 indicating 100MHz,
+ * and 266MHz for model 3, or 4. Set Core Clock
+ * Frequency to System Bus Frequency Ratio to 1 (bits
+ * 31:24) even though these are only valid for CPU
+ * models > 2, however guests may end up dividing or
+ * multiplying by zero otherwise.
+ */
+ case MSR_EBC_FREQUENCY_ID:
+ data = 1 << 24;
+ break;
case MSR_IA32_APICBASE:
data = kvm_get_apic_base(vcpu);
break;
@@ -1555,6 +1787,18 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
case MSR_IA32_MCG_STATUS:
case MSR_IA32_MC0_CTL ... MSR_IA32_MC0_CTL + 4 * KVM_MAX_MCE_BANKS - 1:
return get_msr_mce(vcpu, msr, pdata);
+ case MSR_K7_CLK_CTL:
+ /*
+ * Provide expected ramp-up count for K7. All other
+ * are set to zero, indicating minimum divisors for
+ * every field.
+ *
+ * This prevents guest kernels on AMD host with CPU
+ * type 6, model 8 and higher from exploding due to
+ * the rdmsr failing.
+ */
+ data = 0x20000000;
+ break;
case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
if (kvm_hv_msr_partition_wide(msr)) {
int r;
@@ -1808,19 +2052,28 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
}
kvm_x86_ops->vcpu_load(vcpu, cpu);
- if (unlikely(per_cpu(cpu_tsc_khz, cpu) == 0)) {
- unsigned long khz = cpufreq_quick_get(cpu);
- if (!khz)
- khz = tsc_khz;
- per_cpu(cpu_tsc_khz, cpu) = khz;
+ if (unlikely(vcpu->cpu != cpu) || check_tsc_unstable()) {
+ /* Make sure TSC doesn't go backwards */
+ s64 tsc_delta = !vcpu->arch.last_host_tsc ? 0 :
+ native_read_tsc() - vcpu->arch.last_host_tsc;
+ if (tsc_delta < 0)
+ mark_tsc_unstable("KVM discovered backwards TSC");
+ if (check_tsc_unstable()) {
+ kvm_x86_ops->adjust_tsc_offset(vcpu, -tsc_delta);
+ vcpu->arch.tsc_catchup = 1;
+ kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
+ }
+ if (vcpu->cpu != cpu)
+ kvm_migrate_timers(vcpu);
+ vcpu->cpu = cpu;
}
- kvm_request_guest_time_update(vcpu);
}
void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
{
kvm_x86_ops->vcpu_put(vcpu);
kvm_put_guest_fpu(vcpu);
+ vcpu->arch.last_host_tsc = native_read_tsc();
}
static int is_efer_nx(void)
@@ -1991,13 +2244,14 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
0 /* Reserved */ | F(CX16) | 0 /* xTPR Update, PDCM */ |
0 /* Reserved, DCA */ | F(XMM4_1) |
F(XMM4_2) | F(X2APIC) | F(MOVBE) | F(POPCNT) |
- 0 /* Reserved, AES */ | F(XSAVE) | 0 /* OSXSAVE */ | F(AVX);
+ 0 /* Reserved*/ | F(AES) | F(XSAVE) | 0 /* OSXSAVE */ | F(AVX) |
+ F(F16C);
/* cpuid 0x80000001.ecx */
const u32 kvm_supported_word6_x86_features =
- F(LAHF_LM) | F(CMP_LEGACY) | F(SVM) | 0 /* ExtApicSpace */ |
+ F(LAHF_LM) | F(CMP_LEGACY) | 0 /*SVM*/ | 0 /* ExtApicSpace */ |
F(CR8_LEGACY) | F(ABM) | F(SSE4A) | F(MISALIGNSSE) |
- F(3DNOWPREFETCH) | 0 /* OSVW */ | 0 /* IBS */ | F(SSE5) |
- 0 /* SKINIT */ | 0 /* WDT */;
+ F(3DNOWPREFETCH) | 0 /* OSVW */ | 0 /* IBS */ | F(XOP) |
+ 0 /* SKINIT, WDT, LWP */ | F(FMA4) | F(TBM);
/* all calls to cpuid_count() should be made on the same cpu */
get_cpu();
@@ -2203,6 +2457,7 @@ static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
return -ENXIO;
kvm_queue_interrupt(vcpu, irq->irq, false);
+ kvm_make_request(KVM_REQ_EVENT, vcpu);
return 0;
}
@@ -2356,6 +2611,8 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
if (events->flags & KVM_VCPUEVENT_VALID_SIPI_VECTOR)
vcpu->arch.sipi_vector = events->sipi_vector;
+ kvm_make_request(KVM_REQ_EVENT, vcpu);
+
return 0;
}
@@ -2759,7 +3016,7 @@ static int kvm_vm_ioctl_set_nr_mmu_pages(struct kvm *kvm,
static int kvm_vm_ioctl_get_nr_mmu_pages(struct kvm *kvm)
{
- return kvm->arch.n_alloc_mmu_pages;
+ return kvm->arch.n_max_mmu_pages;
}
static int kvm_vm_ioctl_get_irqchip(struct kvm *kvm, struct kvm_irqchip *chip)
@@ -2795,18 +3052,18 @@ static int kvm_vm_ioctl_set_irqchip(struct kvm *kvm, struct kvm_irqchip *chip)
r = 0;
switch (chip->chip_id) {
case KVM_IRQCHIP_PIC_MASTER:
- raw_spin_lock(&pic_irqchip(kvm)->lock);
+ spin_lock(&pic_irqchip(kvm)->lock);
memcpy(&pic_irqchip(kvm)->pics[0],
&chip->chip.pic,
sizeof(struct kvm_pic_state));
- raw_spin_unlock(&pic_irqchip(kvm)->lock);
+ spin_unlock(&pic_irqchip(kvm)->lock);
break;
case KVM_IRQCHIP_PIC_SLAVE:
- raw_spin_lock(&pic_irqchip(kvm)->lock);
+ spin_lock(&pic_irqchip(kvm)->lock);
memcpy(&pic_irqchip(kvm)->pics[1],
&chip->chip.pic,
sizeof(struct kvm_pic_state));
- raw_spin_unlock(&pic_irqchip(kvm)->lock);
+ spin_unlock(&pic_irqchip(kvm)->lock);
break;
case KVM_IRQCHIP_IOAPIC:
r = kvm_set_ioapic(kvm, &chip->chip.ioapic);
@@ -3200,7 +3457,6 @@ long kvm_arch_vm_ioctl(struct file *filp,
break;
}
case KVM_SET_CLOCK: {
- struct timespec now;
struct kvm_clock_data user_ns;
u64 now_ns;
s64 delta;
@@ -3214,20 +3470,21 @@ long kvm_arch_vm_ioctl(struct file *filp,
goto out;
r = 0;
- ktime_get_ts(&now);
- now_ns = timespec_to_ns(&now);
+ local_irq_disable();
+ now_ns = get_kernel_ns();
delta = user_ns.clock - now_ns;
+ local_irq_enable();
kvm->arch.kvmclock_offset = delta;
break;
}
case KVM_GET_CLOCK: {
- struct timespec now;
struct kvm_clock_data user_ns;
u64 now_ns;
- ktime_get_ts(&now);
- now_ns = timespec_to_ns(&now);
+ local_irq_disable();
+ now_ns = get_kernel_ns();
user_ns.clock = kvm->arch.kvmclock_offset + now_ns;
+ local_irq_enable();
user_ns.flags = 0;
r = -EFAULT;
@@ -3291,30 +3548,51 @@ void kvm_get_segment(struct kvm_vcpu *vcpu,
kvm_x86_ops->get_segment(vcpu, var, seg);
}
+static gpa_t translate_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u32 access)
+{
+ return gpa;
+}
+
+static gpa_t translate_nested_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u32 access)
+{
+ gpa_t t_gpa;
+ u32 error;
+
+ BUG_ON(!mmu_is_nested(vcpu));
+
+ /* NPT walks are always user-walks */
+ access |= PFERR_USER_MASK;
+ t_gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gpa, access, &error);
+ if (t_gpa == UNMAPPED_GVA)
+ vcpu->arch.fault.nested = true;
+
+ return t_gpa;
+}
+
gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva, u32 *error)
{
u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0;
- return vcpu->arch.mmu.gva_to_gpa(vcpu, gva, access, error);
+ return vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, access, error);
}
gpa_t kvm_mmu_gva_to_gpa_fetch(struct kvm_vcpu *vcpu, gva_t gva, u32 *error)
{
u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0;
access |= PFERR_FETCH_MASK;
- return vcpu->arch.mmu.gva_to_gpa(vcpu, gva, access, error);
+ return vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, access, error);
}
gpa_t kvm_mmu_gva_to_gpa_write(struct kvm_vcpu *vcpu, gva_t gva, u32 *error)
{
u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0;
access |= PFERR_WRITE_MASK;
- return vcpu->arch.mmu.gva_to_gpa(vcpu, gva, access, error);
+ return vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, access, error);
}
/* uses this to access any guest's mapped memory without checking CPL */
gpa_t kvm_mmu_gva_to_gpa_system(struct kvm_vcpu *vcpu, gva_t gva, u32 *error)
{
- return vcpu->arch.mmu.gva_to_gpa(vcpu, gva, 0, error);
+ return vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, 0, error);
}
static int kvm_read_guest_virt_helper(gva_t addr, void *val, unsigned int bytes,
@@ -3325,7 +3603,8 @@ static int kvm_read_guest_virt_helper(gva_t addr, void *val, unsigned int bytes,
int r = X86EMUL_CONTINUE;
while (bytes) {
- gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr, access, error);
+ gpa_t gpa = vcpu->arch.walk_mmu->gva_to_gpa(vcpu, addr, access,
+ error);
unsigned offset = addr & (PAGE_SIZE-1);
unsigned toread = min(bytes, (unsigned)PAGE_SIZE - offset);
int ret;
@@ -3380,8 +3659,9 @@ static int kvm_write_guest_virt_system(gva_t addr, void *val,
int r = X86EMUL_CONTINUE;
while (bytes) {
- gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr,
- PFERR_WRITE_MASK, error);
+ gpa_t gpa = vcpu->arch.walk_mmu->gva_to_gpa(vcpu, addr,
+ PFERR_WRITE_MASK,
+ error);
unsigned offset = addr & (PAGE_SIZE-1);
unsigned towrite = min(bytes, (unsigned)PAGE_SIZE - offset);
int ret;
@@ -3623,7 +3903,7 @@ static int emulator_pio_in_emulated(int size, unsigned short port, void *val,
if (vcpu->arch.pio.count)
goto data_avail;
- trace_kvm_pio(1, port, size, 1);
+ trace_kvm_pio(0, port, size, 1);
vcpu->arch.pio.port = port;
vcpu->arch.pio.in = 1;
@@ -3651,7 +3931,7 @@ static int emulator_pio_out_emulated(int size, unsigned short port,
const void *val, unsigned int count,
struct kvm_vcpu *vcpu)
{
- trace_kvm_pio(0, port, size, 1);
+ trace_kvm_pio(1, port, size, 1);
vcpu->arch.pio.port = port;
vcpu->arch.pio.in = 0;
@@ -3790,6 +4070,11 @@ static void emulator_get_gdt(struct desc_ptr *dt, struct kvm_vcpu *vcpu)
kvm_x86_ops->get_gdt(vcpu, dt);
}
+static void emulator_get_idt(struct desc_ptr *dt, struct kvm_vcpu *vcpu)
+{
+ kvm_x86_ops->get_idt(vcpu, dt);
+}
+
static unsigned long emulator_get_cached_segment_base(int seg,
struct kvm_vcpu *vcpu)
{
@@ -3883,6 +4168,7 @@ static struct x86_emulate_ops emulate_ops = {
.set_segment_selector = emulator_set_segment_selector,
.get_cached_segment_base = emulator_get_cached_segment_base,
.get_gdt = emulator_get_gdt,
+ .get_idt = emulator_get_idt,
.get_cr = emulator_get_cr,
.set_cr = emulator_set_cr,
.cpl = emulator_get_cpl,
@@ -3918,13 +4204,64 @@ static void inject_emulated_exception(struct kvm_vcpu *vcpu)
{
struct x86_emulate_ctxt *ctxt = &vcpu->arch.emulate_ctxt;
if (ctxt->exception == PF_VECTOR)
- kvm_inject_page_fault(vcpu, ctxt->cr2, ctxt->error_code);
+ kvm_propagate_fault(vcpu);
else if (ctxt->error_code_valid)
kvm_queue_exception_e(vcpu, ctxt->exception, ctxt->error_code);
else
kvm_queue_exception(vcpu, ctxt->exception);
}
+static void init_emulate_ctxt(struct kvm_vcpu *vcpu)
+{
+ struct decode_cache *c = &vcpu->arch.emulate_ctxt.decode;
+ int cs_db, cs_l;
+
+ cache_all_regs(vcpu);
+
+ kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
+
+ vcpu->arch.emulate_ctxt.vcpu = vcpu;
+ vcpu->arch.emulate_ctxt.eflags = kvm_x86_ops->get_rflags(vcpu);
+ vcpu->arch.emulate_ctxt.eip = kvm_rip_read(vcpu);
+ vcpu->arch.emulate_ctxt.mode =
+ (!is_protmode(vcpu)) ? X86EMUL_MODE_REAL :
+ (vcpu->arch.emulate_ctxt.eflags & X86_EFLAGS_VM)
+ ? X86EMUL_MODE_VM86 : cs_l
+ ? X86EMUL_MODE_PROT64 : cs_db
+ ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
+ memset(c, 0, sizeof(struct decode_cache));
+ memcpy(c->regs, vcpu->arch.regs, sizeof c->regs);
+}
+
+int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq)
+{
+ struct decode_cache *c = &vcpu->arch.emulate_ctxt.decode;
+ int ret;
+
+ init_emulate_ctxt(vcpu);
+
+ vcpu->arch.emulate_ctxt.decode.op_bytes = 2;
+ vcpu->arch.emulate_ctxt.decode.ad_bytes = 2;
+ vcpu->arch.emulate_ctxt.decode.eip = vcpu->arch.emulate_ctxt.eip;
+ ret = emulate_int_real(&vcpu->arch.emulate_ctxt, &emulate_ops, irq);
+
+ if (ret != X86EMUL_CONTINUE)
+ return EMULATE_FAIL;
+
+ vcpu->arch.emulate_ctxt.eip = c->eip;
+ memcpy(vcpu->arch.regs, c->regs, sizeof c->regs);
+ kvm_rip_write(vcpu, vcpu->arch.emulate_ctxt.eip);
+ kvm_x86_ops->set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags);
+
+ if (irq == NMI_VECTOR)
+ vcpu->arch.nmi_pending = false;
+ else
+ vcpu->arch.interrupt.pending = false;
+
+ return EMULATE_DONE;
+}
+EXPORT_SYMBOL_GPL(kvm_inject_realmode_interrupt);
+
static int handle_emulation_failure(struct kvm_vcpu *vcpu)
{
++vcpu->stat.insn_emulation_fail;
@@ -3981,24 +4318,15 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
cache_all_regs(vcpu);
if (!(emulation_type & EMULTYPE_NO_DECODE)) {
- int cs_db, cs_l;
- kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
-
- vcpu->arch.emulate_ctxt.vcpu = vcpu;
- vcpu->arch.emulate_ctxt.eflags = kvm_x86_ops->get_rflags(vcpu);
- vcpu->arch.emulate_ctxt.eip = kvm_rip_read(vcpu);
- vcpu->arch.emulate_ctxt.mode =
- (!is_protmode(vcpu)) ? X86EMUL_MODE_REAL :
- (vcpu->arch.emulate_ctxt.eflags & X86_EFLAGS_VM)
- ? X86EMUL_MODE_VM86 : cs_l
- ? X86EMUL_MODE_PROT64 : cs_db
- ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
- memset(c, 0, sizeof(struct decode_cache));
- memcpy(c->regs, vcpu->arch.regs, sizeof c->regs);
+ init_emulate_ctxt(vcpu);
vcpu->arch.emulate_ctxt.interruptibility = 0;
vcpu->arch.emulate_ctxt.exception = -1;
+ vcpu->arch.emulate_ctxt.perm_ok = false;
+
+ r = x86_decode_insn(&vcpu->arch.emulate_ctxt);
+ if (r == X86EMUL_PROPAGATE_FAULT)
+ goto done;
- r = x86_decode_insn(&vcpu->arch.emulate_ctxt, &emulate_ops);
trace_kvm_emulate_insn_start(vcpu);
/* Only allow emulation of specific instructions on #UD
@@ -4048,41 +4376,39 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
memcpy(c->regs, vcpu->arch.regs, sizeof c->regs);
restart:
- r = x86_emulate_insn(&vcpu->arch.emulate_ctxt, &emulate_ops);
+ r = x86_emulate_insn(&vcpu->arch.emulate_ctxt);
- if (r) { /* emulation failed */
+ if (r == EMULATION_FAILED) {
if (reexecute_instruction(vcpu, cr2))
return EMULATE_DONE;
return handle_emulation_failure(vcpu);
}
- toggle_interruptibility(vcpu, vcpu->arch.emulate_ctxt.interruptibility);
- kvm_x86_ops->set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags);
- memcpy(vcpu->arch.regs, c->regs, sizeof c->regs);
- kvm_rip_write(vcpu, vcpu->arch.emulate_ctxt.eip);
-
+done:
if (vcpu->arch.emulate_ctxt.exception >= 0) {
inject_emulated_exception(vcpu);
- return EMULATE_DONE;
- }
-
- if (vcpu->arch.pio.count) {
+ r = EMULATE_DONE;
+ } else if (vcpu->arch.pio.count) {
if (!vcpu->arch.pio.in)
vcpu->arch.pio.count = 0;
- return EMULATE_DO_MMIO;
- }
-
- if (vcpu->mmio_needed) {
+ r = EMULATE_DO_MMIO;
+ } else if (vcpu->mmio_needed) {
if (vcpu->mmio_is_write)
vcpu->mmio_needed = 0;
- return EMULATE_DO_MMIO;
- }
-
- if (vcpu->arch.emulate_ctxt.restart)
+ r = EMULATE_DO_MMIO;
+ } else if (r == EMULATION_RESTART)
goto restart;
+ else
+ r = EMULATE_DONE;
- return EMULATE_DONE;
+ toggle_interruptibility(vcpu, vcpu->arch.emulate_ctxt.interruptibility);
+ kvm_x86_ops->set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags);
+ kvm_make_request(KVM_REQ_EVENT, vcpu);
+ memcpy(vcpu->arch.regs, c->regs, sizeof c->regs);
+ kvm_rip_write(vcpu, vcpu->arch.emulate_ctxt.eip);
+
+ return r;
}
EXPORT_SYMBOL_GPL(emulate_instruction);
@@ -4096,9 +4422,23 @@ int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port)
}
EXPORT_SYMBOL_GPL(kvm_fast_pio_out);
-static void bounce_off(void *info)
+static void tsc_bad(void *info)
+{
+ __get_cpu_var(cpu_tsc_khz) = 0;
+}
+
+static void tsc_khz_changed(void *data)
{
- /* nothing */
+ struct cpufreq_freqs *freq = data;
+ unsigned long khz = 0;
+
+ if (data)
+ khz = freq->new;
+ else if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
+ khz = cpufreq_quick_get(raw_smp_processor_id());
+ if (!khz)
+ khz = tsc_khz;
+ __get_cpu_var(cpu_tsc_khz) = khz;
}
static int kvmclock_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
@@ -4109,21 +4449,60 @@ static int kvmclock_cpufreq_notifier(struct notifier_block *nb, unsigned long va
struct kvm_vcpu *vcpu;
int i, send_ipi = 0;
+ /*
+ * We allow guests to temporarily run on slowing clocks,
+ * provided we notify them after, or to run on accelerating
+ * clocks, provided we notify them before. Thus time never
+ * goes backwards.
+ *
+ * However, we have a problem. We can't atomically update
+ * the frequency of a given CPU from this function; it is
+ * merely a notifier, which can be called from any CPU.
+ * Changing the TSC frequency at arbitrary points in time
+ * requires a recomputation of local variables related to
+ * the TSC for each VCPU. We must flag these local variables
+ * to be updated and be sure the update takes place with the
+ * new frequency before any guests proceed.
+ *
+ * Unfortunately, the combination of hotplug CPU and frequency
+ * change creates an intractable locking scenario; the order
+ * of when these callouts happen is undefined with respect to
+ * CPU hotplug, and they can race with each other. As such,
+ * merely setting per_cpu(cpu_tsc_khz) = X during a hotadd is
+ * undefined; you can actually have a CPU frequency change take
+ * place in between the computation of X and the setting of the
+ * variable. To protect against this problem, all updates of
+ * the per_cpu tsc_khz variable are done in an interrupt
+ * protected IPI, and all callers wishing to update the value
+ * must wait for a synchronous IPI to complete (which is trivial
+ * if the caller is on the CPU already). This establishes the
+ * necessary total order on variable updates.
+ *
+ * Note that because a guest time update may take place
+ * anytime after the setting of the VCPU's request bit, the
+ * correct TSC value must be set before the request. However,
+ * to ensure the update actually makes it to any guest which
+ * starts running in hardware virtualization between the set
+ * and the acquisition of the spinlock, we must also ping the
+ * CPU after setting the request bit.
+ *
+ */
+
if (val == CPUFREQ_PRECHANGE && freq->old > freq->new)
return 0;
if (val == CPUFREQ_POSTCHANGE && freq->old < freq->new)
return 0;
- per_cpu(cpu_tsc_khz, freq->cpu) = freq->new;
+
+ smp_call_function_single(freq->cpu, tsc_khz_changed, freq, 1);
spin_lock(&kvm_lock);
list_for_each_entry(kvm, &vm_list, vm_list) {
kvm_for_each_vcpu(i, vcpu, kvm) {
if (vcpu->cpu != freq->cpu)
continue;
- if (!kvm_request_guest_time_update(vcpu))
- continue;
+ kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
if (vcpu->cpu != smp_processor_id())
- send_ipi++;
+ send_ipi = 1;
}
}
spin_unlock(&kvm_lock);
@@ -4141,32 +4520,57 @@ static int kvmclock_cpufreq_notifier(struct notifier_block *nb, unsigned long va
* guest context is entered kvmclock will be updated,
* so the guest will not see stale values.
*/
- smp_call_function_single(freq->cpu, bounce_off, NULL, 1);
+ smp_call_function_single(freq->cpu, tsc_khz_changed, freq, 1);
}
return 0;
}
static struct notifier_block kvmclock_cpufreq_notifier_block = {
- .notifier_call = kvmclock_cpufreq_notifier
+ .notifier_call = kvmclock_cpufreq_notifier
+};
+
+static int kvmclock_cpu_notifier(struct notifier_block *nfb,
+ unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (unsigned long)hcpu;
+
+ switch (action) {
+ case CPU_ONLINE:
+ case CPU_DOWN_FAILED:
+ smp_call_function_single(cpu, tsc_khz_changed, NULL, 1);
+ break;
+ case CPU_DOWN_PREPARE:
+ smp_call_function_single(cpu, tsc_bad, NULL, 1);
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block kvmclock_cpu_notifier_block = {
+ .notifier_call = kvmclock_cpu_notifier,
+ .priority = -INT_MAX
};
static void kvm_timer_init(void)
{
int cpu;
+ max_tsc_khz = tsc_khz;
+ register_hotcpu_notifier(&kvmclock_cpu_notifier_block);
if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) {
+#ifdef CONFIG_CPU_FREQ
+ struct cpufreq_policy policy;
+ memset(&policy, 0, sizeof(policy));
+ cpufreq_get_policy(&policy, get_cpu());
+ if (policy.cpuinfo.max_freq)
+ max_tsc_khz = policy.cpuinfo.max_freq;
+#endif
cpufreq_register_notifier(&kvmclock_cpufreq_notifier_block,
CPUFREQ_TRANSITION_NOTIFIER);
- for_each_online_cpu(cpu) {
- unsigned long khz = cpufreq_get(cpu);
- if (!khz)
- khz = tsc_khz;
- per_cpu(cpu_tsc_khz, cpu) = khz;
- }
- } else {
- for_each_possible_cpu(cpu)
- per_cpu(cpu_tsc_khz, cpu) = tsc_khz;
}
+ pr_debug("kvm: max_tsc_khz = %ld\n", max_tsc_khz);
+ for_each_online_cpu(cpu)
+ smp_call_function_single(cpu, tsc_khz_changed, NULL, 1);
}
static DEFINE_PER_CPU(struct kvm_vcpu *, current_vcpu);
@@ -4268,6 +4672,7 @@ void kvm_arch_exit(void)
if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
cpufreq_unregister_notifier(&kvmclock_cpufreq_notifier_block,
CPUFREQ_TRANSITION_NOTIFIER);
+ unregister_hotcpu_notifier(&kvmclock_cpu_notifier_block);
kvm_x86_ops = NULL;
kvm_mmu_module_exit();
}
@@ -4683,8 +5088,11 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
kvm_mmu_unload(vcpu);
if (kvm_check_request(KVM_REQ_MIGRATE_TIMER, vcpu))
__kvm_migrate_timers(vcpu);
- if (kvm_check_request(KVM_REQ_KVMCLOCK_UPDATE, vcpu))
- kvm_write_guest_time(vcpu);
+ if (kvm_check_request(KVM_REQ_CLOCK_UPDATE, vcpu)) {
+ r = kvm_guest_time_update(vcpu);
+ if (unlikely(r))
+ goto out;
+ }
if (kvm_check_request(KVM_REQ_MMU_SYNC, vcpu))
kvm_mmu_sync_roots(vcpu);
if (kvm_check_request(KVM_REQ_TLB_FLUSH, vcpu))
@@ -4709,6 +5117,21 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
if (unlikely(r))
goto out;
+ if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win) {
+ inject_pending_event(vcpu);
+
+ /* enable NMI/IRQ window open exits if needed */
+ if (vcpu->arch.nmi_pending)
+ kvm_x86_ops->enable_nmi_window(vcpu);
+ else if (kvm_cpu_has_interrupt(vcpu) || req_int_win)
+ kvm_x86_ops->enable_irq_window(vcpu);
+
+ if (kvm_lapic_enabled(vcpu)) {
+ update_cr8_intercept(vcpu);
+ kvm_lapic_sync_to_vapic(vcpu);
+ }
+ }
+
preempt_disable();
kvm_x86_ops->prepare_guest_switch(vcpu);
@@ -4727,23 +5150,11 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
smp_wmb();
local_irq_enable();
preempt_enable();
+ kvm_x86_ops->cancel_injection(vcpu);
r = 1;
goto out;
}
- inject_pending_event(vcpu);
-
- /* enable NMI/IRQ window open exits if needed */
- if (vcpu->arch.nmi_pending)
- kvm_x86_ops->enable_nmi_window(vcpu);
- else if (kvm_cpu_has_interrupt(vcpu) || req_int_win)
- kvm_x86_ops->enable_irq_window(vcpu);
-
- if (kvm_lapic_enabled(vcpu)) {
- update_cr8_intercept(vcpu);
- kvm_lapic_sync_to_vapic(vcpu);
- }
-
srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
kvm_guest_enter();
@@ -4769,6 +5180,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
if (hw_breakpoint_active())
hw_breakpoint_restore();
+ kvm_get_msr(vcpu, MSR_IA32_TSC, &vcpu->arch.last_guest_tsc);
+
atomic_set(&vcpu->guest_mode, 0);
smp_wmb();
local_irq_enable();
@@ -4898,8 +5311,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
if (!irqchip_in_kernel(vcpu->kvm))
kvm_set_cr8(vcpu, kvm_run->cr8);
- if (vcpu->arch.pio.count || vcpu->mmio_needed ||
- vcpu->arch.emulate_ctxt.restart) {
+ if (vcpu->arch.pio.count || vcpu->mmio_needed) {
if (vcpu->mmio_needed) {
memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8);
vcpu->mmio_read_completed = 1;
@@ -4980,6 +5392,8 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
vcpu->arch.exception.pending = false;
+ kvm_make_request(KVM_REQ_EVENT, vcpu);
+
return 0;
}
@@ -5043,6 +5457,7 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
struct kvm_mp_state *mp_state)
{
vcpu->arch.mp_state = mp_state->mp_state;
+ kvm_make_request(KVM_REQ_EVENT, vcpu);
return 0;
}
@@ -5050,24 +5465,11 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason,
bool has_error_code, u32 error_code)
{
struct decode_cache *c = &vcpu->arch.emulate_ctxt.decode;
- int cs_db, cs_l, ret;
- cache_all_regs(vcpu);
-
- kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
+ int ret;
- vcpu->arch.emulate_ctxt.vcpu = vcpu;
- vcpu->arch.emulate_ctxt.eflags = kvm_x86_ops->get_rflags(vcpu);
- vcpu->arch.emulate_ctxt.eip = kvm_rip_read(vcpu);
- vcpu->arch.emulate_ctxt.mode =
- (!is_protmode(vcpu)) ? X86EMUL_MODE_REAL :
- (vcpu->arch.emulate_ctxt.eflags & X86_EFLAGS_VM)
- ? X86EMUL_MODE_VM86 : cs_l
- ? X86EMUL_MODE_PROT64 : cs_db
- ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
- memset(c, 0, sizeof(struct decode_cache));
- memcpy(c->regs, vcpu->arch.regs, sizeof c->regs);
+ init_emulate_ctxt(vcpu);
- ret = emulator_task_switch(&vcpu->arch.emulate_ctxt, &emulate_ops,
+ ret = emulator_task_switch(&vcpu->arch.emulate_ctxt,
tss_selector, reason, has_error_code,
error_code);
@@ -5077,6 +5479,7 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason,
memcpy(vcpu->arch.regs, c->regs, sizeof c->regs);
kvm_rip_write(vcpu, vcpu->arch.emulate_ctxt.eip);
kvm_x86_ops->set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags);
+ kvm_make_request(KVM_REQ_EVENT, vcpu);
return EMULATE_DONE;
}
EXPORT_SYMBOL_GPL(kvm_task_switch);
@@ -5112,7 +5515,7 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
mmu_reset_needed |= kvm_read_cr4(vcpu) != sregs->cr4;
kvm_x86_ops->set_cr4(vcpu, sregs->cr4);
if (!is_long_mode(vcpu) && is_pae(vcpu)) {
- load_pdptrs(vcpu, vcpu->arch.cr3);
+ load_pdptrs(vcpu, vcpu->arch.walk_mmu, vcpu->arch.cr3);
mmu_reset_needed = 1;
}
@@ -5147,6 +5550,8 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
!is_protmode(vcpu))
vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
+ kvm_make_request(KVM_REQ_EVENT, vcpu);
+
return 0;
}
@@ -5333,6 +5738,10 @@ void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
unsigned int id)
{
+ if (check_tsc_unstable() && atomic_read(&kvm->online_vcpus) != 0)
+ printk_once(KERN_WARNING
+ "kvm: SMP vm created on host with unstable TSC; "
+ "guest TSC will not be reliable\n");
return kvm_x86_ops->vcpu_create(kvm, id);
}
@@ -5375,22 +5784,22 @@ int kvm_arch_vcpu_reset(struct kvm_vcpu *vcpu)
vcpu->arch.dr6 = DR6_FIXED_1;
vcpu->arch.dr7 = DR7_FIXED_1;
+ kvm_make_request(KVM_REQ_EVENT, vcpu);
+
return kvm_x86_ops->vcpu_reset(vcpu);
}
int kvm_arch_hardware_enable(void *garbage)
{
- /*
- * Since this may be called from a hotplug notifcation,
- * we can't get the CPU frequency directly.
- */
- if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) {
- int cpu = raw_smp_processor_id();
- per_cpu(cpu_tsc_khz, cpu) = 0;
- }
+ struct kvm *kvm;
+ struct kvm_vcpu *vcpu;
+ int i;
kvm_shared_msr_cpu_online();
-
+ list_for_each_entry(kvm, &vm_list, vm_list)
+ kvm_for_each_vcpu(i, vcpu, kvm)
+ if (vcpu->cpu == smp_processor_id())
+ kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
return kvm_x86_ops->hardware_enable(garbage);
}
@@ -5424,7 +5833,11 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
BUG_ON(vcpu->kvm == NULL);
kvm = vcpu->kvm;
+ vcpu->arch.emulate_ctxt.ops = &emulate_ops;
+ vcpu->arch.walk_mmu = &vcpu->arch.mmu;
vcpu->arch.mmu.root_hpa = INVALID_PAGE;
+ vcpu->arch.mmu.translate_gpa = translate_gpa;
+ vcpu->arch.nested_mmu.translate_gpa = translate_nested_gpa;
if (!irqchip_in_kernel(kvm) || kvm_vcpu_is_bsp(vcpu))
vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
else
@@ -5437,6 +5850,9 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
}
vcpu->arch.pio_data = page_address(page);
+ if (!kvm->arch.virtual_tsc_khz)
+ kvm_arch_set_tsc_khz(kvm, max_tsc_khz);
+
r = kvm_mmu_create(vcpu);
if (r < 0)
goto fail_free_pio_data;
@@ -5496,7 +5912,7 @@ struct kvm *kvm_arch_create_vm(void)
/* Reserve bit 0 of irq_sources_bitmap for userspace irq source */
set_bit(KVM_USERSPACE_IRQ_SOURCE_ID, &kvm->arch.irq_sources_bitmap);
- rdtscll(kvm->arch.vm_init_tsc);
+ spin_lock_init(&kvm->arch.tsc_write_lock);
return kvm;
}
@@ -5683,6 +6099,7 @@ void kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
kvm_is_linear_rip(vcpu, vcpu->arch.singlestep_rip))
rflags |= X86_EFLAGS_TF;
kvm_x86_ops->set_rflags(vcpu, rflags);
+ kvm_make_request(KVM_REQ_EVENT, vcpu);
}
EXPORT_SYMBOL_GPL(kvm_set_rflags);
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index b7a404722d2b..2cea414489f3 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -50,6 +50,11 @@ static inline int is_long_mode(struct kvm_vcpu *vcpu)
#endif
}
+static inline bool mmu_is_nested(struct kvm_vcpu *vcpu)
+{
+ return vcpu->arch.walk_mmu == &vcpu->arch.nested_mmu;
+}
+
static inline int is_pae(struct kvm_vcpu *vcpu)
{
return kvm_read_cr4_bits(vcpu, X86_CR4_PAE);
@@ -67,5 +72,8 @@ static inline int is_paging(struct kvm_vcpu *vcpu)
void kvm_before_handle_nmi(struct kvm_vcpu *vcpu);
void kvm_after_handle_nmi(struct kvm_vcpu *vcpu);
+int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq);
+
+void kvm_write_tsc(struct kvm_vcpu *vcpu, u64 data);
#endif
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index 9d5f55848455..73b1e1a1f489 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -791,22 +791,22 @@ static void lguest_flush_tlb_kernel(void)
* simple as setting a bit. We don't actually "ack" interrupts as such, we
* just mask and unmask them. I wonder if we should be cleverer?
*/
-static void disable_lguest_irq(unsigned int irq)
+static void disable_lguest_irq(struct irq_data *data)
{
- set_bit(irq, lguest_data.blocked_interrupts);
+ set_bit(data->irq, lguest_data.blocked_interrupts);
}
-static void enable_lguest_irq(unsigned int irq)
+static void enable_lguest_irq(struct irq_data *data)
{
- clear_bit(irq, lguest_data.blocked_interrupts);
+ clear_bit(data->irq, lguest_data.blocked_interrupts);
}
/* This structure describes the lguest IRQ controller. */
static struct irq_chip lguest_irq_controller = {
.name = "lguest",
- .mask = disable_lguest_irq,
- .mask_ack = disable_lguest_irq,
- .unmask = enable_lguest_irq,
+ .irq_mask = disable_lguest_irq,
+ .irq_mask_ack = disable_lguest_irq,
+ .irq_unmask = enable_lguest_irq,
};
/*
@@ -838,12 +838,12 @@ static void __init lguest_init_IRQ(void)
* rather than set them in lguest_init_IRQ we are called here every time an
* lguest device needs an interrupt.
*
- * FIXME: irq_to_desc_alloc_node() can fail due to lack of memory, we should
+ * FIXME: irq_alloc_desc_at() can fail due to lack of memory, we should
* pass that up!
*/
void lguest_setup_irq(unsigned int irq)
{
- irq_to_desc_alloc_node(irq, 0);
+ irq_alloc_desc_at(irq, 0);
set_irq_chip_and_handler_name(irq, &lguest_irq_controller,
handle_level_irq, "level");
}
diff --git a/arch/x86/lib/memcpy_32.c b/arch/x86/lib/memcpy_32.c
index 5415a9d06f53..b908a59eccf5 100644
--- a/arch/x86/lib/memcpy_32.c
+++ b/arch/x86/lib/memcpy_32.c
@@ -22,22 +22,187 @@ EXPORT_SYMBOL(memset);
void *memmove(void *dest, const void *src, size_t n)
{
- int d0, d1, d2;
-
- if (dest < src) {
- memcpy(dest, src, n);
- } else {
- __asm__ __volatile__(
- "std\n\t"
- "rep\n\t"
- "movsb\n\t"
- "cld"
- : "=&c" (d0), "=&S" (d1), "=&D" (d2)
- :"0" (n),
- "1" (n-1+src),
- "2" (n-1+dest)
- :"memory");
- }
- return dest;
+ int d0,d1,d2,d3,d4,d5;
+ char *ret = dest;
+
+ __asm__ __volatile__(
+ /* Handle more 16bytes in loop */
+ "cmp $0x10, %0\n\t"
+ "jb 1f\n\t"
+
+ /* Decide forward/backward copy mode */
+ "cmp %2, %1\n\t"
+ "jb 2f\n\t"
+
+ /*
+ * movs instruction have many startup latency
+ * so we handle small size by general register.
+ */
+ "cmp $680, %0\n\t"
+ "jb 3f\n\t"
+ /*
+ * movs instruction is only good for aligned case.
+ */
+ "mov %1, %3\n\t"
+ "xor %2, %3\n\t"
+ "and $0xff, %3\n\t"
+ "jz 4f\n\t"
+ "3:\n\t"
+ "sub $0x10, %0\n\t"
+
+ /*
+ * We gobble 16byts forward in each loop.
+ */
+ "3:\n\t"
+ "sub $0x10, %0\n\t"
+ "mov 0*4(%1), %3\n\t"
+ "mov 1*4(%1), %4\n\t"
+ "mov %3, 0*4(%2)\n\t"
+ "mov %4, 1*4(%2)\n\t"
+ "mov 2*4(%1), %3\n\t"
+ "mov 3*4(%1), %4\n\t"
+ "mov %3, 2*4(%2)\n\t"
+ "mov %4, 3*4(%2)\n\t"
+ "lea 0x10(%1), %1\n\t"
+ "lea 0x10(%2), %2\n\t"
+ "jae 3b\n\t"
+ "add $0x10, %0\n\t"
+ "jmp 1f\n\t"
+
+ /*
+ * Handle data forward by movs.
+ */
+ ".p2align 4\n\t"
+ "4:\n\t"
+ "mov -4(%1, %0), %3\n\t"
+ "lea -4(%2, %0), %4\n\t"
+ "shr $2, %0\n\t"
+ "rep movsl\n\t"
+ "mov %3, (%4)\n\t"
+ "jmp 11f\n\t"
+ /*
+ * Handle data backward by movs.
+ */
+ ".p2align 4\n\t"
+ "6:\n\t"
+ "mov (%1), %3\n\t"
+ "mov %2, %4\n\t"
+ "lea -4(%1, %0), %1\n\t"
+ "lea -4(%2, %0), %2\n\t"
+ "shr $2, %0\n\t"
+ "std\n\t"
+ "rep movsl\n\t"
+ "mov %3,(%4)\n\t"
+ "cld\n\t"
+ "jmp 11f\n\t"
+
+ /*
+ * Start to prepare for backward copy.
+ */
+ ".p2align 4\n\t"
+ "2:\n\t"
+ "cmp $680, %0\n\t"
+ "jb 5f\n\t"
+ "mov %1, %3\n\t"
+ "xor %2, %3\n\t"
+ "and $0xff, %3\n\t"
+ "jz 6b\n\t"
+
+ /*
+ * Calculate copy position to tail.
+ */
+ "5:\n\t"
+ "add %0, %1\n\t"
+ "add %0, %2\n\t"
+ "sub $0x10, %0\n\t"
+
+ /*
+ * We gobble 16byts backward in each loop.
+ */
+ "7:\n\t"
+ "sub $0x10, %0\n\t"
+
+ "mov -1*4(%1), %3\n\t"
+ "mov -2*4(%1), %4\n\t"
+ "mov %3, -1*4(%2)\n\t"
+ "mov %4, -2*4(%2)\n\t"
+ "mov -3*4(%1), %3\n\t"
+ "mov -4*4(%1), %4\n\t"
+ "mov %3, -3*4(%2)\n\t"
+ "mov %4, -4*4(%2)\n\t"
+ "lea -0x10(%1), %1\n\t"
+ "lea -0x10(%2), %2\n\t"
+ "jae 7b\n\t"
+ /*
+ * Calculate copy position to head.
+ */
+ "add $0x10, %0\n\t"
+ "sub %0, %1\n\t"
+ "sub %0, %2\n\t"
+
+ /*
+ * Move data from 8 bytes to 15 bytes.
+ */
+ ".p2align 4\n\t"
+ "1:\n\t"
+ "cmp $8, %0\n\t"
+ "jb 8f\n\t"
+ "mov 0*4(%1), %3\n\t"
+ "mov 1*4(%1), %4\n\t"
+ "mov -2*4(%1, %0), %5\n\t"
+ "mov -1*4(%1, %0), %1\n\t"
+
+ "mov %3, 0*4(%2)\n\t"
+ "mov %4, 1*4(%2)\n\t"
+ "mov %5, -2*4(%2, %0)\n\t"
+ "mov %1, -1*4(%2, %0)\n\t"
+ "jmp 11f\n\t"
+
+ /*
+ * Move data from 4 bytes to 7 bytes.
+ */
+ ".p2align 4\n\t"
+ "8:\n\t"
+ "cmp $4, %0\n\t"
+ "jb 9f\n\t"
+ "mov 0*4(%1), %3\n\t"
+ "mov -1*4(%1, %0), %4\n\t"
+ "mov %3, 0*4(%2)\n\t"
+ "mov %4, -1*4(%2, %0)\n\t"
+ "jmp 11f\n\t"
+
+ /*
+ * Move data from 2 bytes to 3 bytes.
+ */
+ ".p2align 4\n\t"
+ "9:\n\t"
+ "cmp $2, %0\n\t"
+ "jb 10f\n\t"
+ "movw 0*2(%1), %%dx\n\t"
+ "movw -1*2(%1, %0), %%bx\n\t"
+ "movw %%dx, 0*2(%2)\n\t"
+ "movw %%bx, -1*2(%2, %0)\n\t"
+ "jmp 11f\n\t"
+
+ /*
+ * Move data for 1 byte.
+ */
+ ".p2align 4\n\t"
+ "10:\n\t"
+ "cmp $1, %0\n\t"
+ "jb 11f\n\t"
+ "movb (%1), %%cl\n\t"
+ "movb %%cl, (%2)\n\t"
+ ".p2align 4\n\t"
+ "11:"
+ : "=&c" (d0), "=&S" (d1), "=&D" (d2),
+ "=r" (d3),"=r" (d4), "=r"(d5)
+ :"0" (n),
+ "1" (src),
+ "2" (dest)
+ :"memory");
+
+ return ret;
+
}
EXPORT_SYMBOL(memmove);
diff --git a/arch/x86/lib/memcpy_64.S b/arch/x86/lib/memcpy_64.S
index bcbcd1e0f7d5..75ef61e35e38 100644
--- a/arch/x86/lib/memcpy_64.S
+++ b/arch/x86/lib/memcpy_64.S
@@ -40,84 +40,132 @@
ENTRY(__memcpy)
ENTRY(memcpy)
CFI_STARTPROC
+ movq %rdi, %rax
/*
- * Put the number of full 64-byte blocks into %ecx.
- * Tail portion is handled at the end:
+ * Use 32bit CMP here to avoid long NOP padding.
*/
- movq %rdi, %rax
- movl %edx, %ecx
- shrl $6, %ecx
- jz .Lhandle_tail
+ cmp $0x20, %edx
+ jb .Lhandle_tail
- .p2align 4
-.Lloop_64:
/*
- * We decrement the loop index here - and the zero-flag is
- * checked at the end of the loop (instructions inbetween do
- * not change the zero flag):
+ * We check whether memory false dependece could occur,
+ * then jump to corresponding copy mode.
*/
- decl %ecx
+ cmp %dil, %sil
+ jl .Lcopy_backward
+ subl $0x20, %edx
+.Lcopy_forward_loop:
+ subq $0x20, %rdx
/*
- * Move in blocks of 4x16 bytes:
+ * Move in blocks of 4x8 bytes:
*/
- movq 0*8(%rsi), %r11
- movq 1*8(%rsi), %r8
- movq %r11, 0*8(%rdi)
- movq %r8, 1*8(%rdi)
-
- movq 2*8(%rsi), %r9
- movq 3*8(%rsi), %r10
- movq %r9, 2*8(%rdi)
- movq %r10, 3*8(%rdi)
-
- movq 4*8(%rsi), %r11
- movq 5*8(%rsi), %r8
- movq %r11, 4*8(%rdi)
- movq %r8, 5*8(%rdi)
-
- movq 6*8(%rsi), %r9
- movq 7*8(%rsi), %r10
- movq %r9, 6*8(%rdi)
- movq %r10, 7*8(%rdi)
-
- leaq 64(%rsi), %rsi
- leaq 64(%rdi), %rdi
-
- jnz .Lloop_64
+ movq 0*8(%rsi), %r8
+ movq 1*8(%rsi), %r9
+ movq 2*8(%rsi), %r10
+ movq 3*8(%rsi), %r11
+ leaq 4*8(%rsi), %rsi
+
+ movq %r8, 0*8(%rdi)
+ movq %r9, 1*8(%rdi)
+ movq %r10, 2*8(%rdi)
+ movq %r11, 3*8(%rdi)
+ leaq 4*8(%rdi), %rdi
+ jae .Lcopy_forward_loop
+ addq $0x20, %rdx
+ jmp .Lhandle_tail
+
+.Lcopy_backward:
+ /*
+ * Calculate copy position to tail.
+ */
+ addq %rdx, %rsi
+ addq %rdx, %rdi
+ subq $0x20, %rdx
+ /*
+ * At most 3 ALU operations in one cycle,
+ * so append NOPS in the same 16bytes trunk.
+ */
+ .p2align 4
+.Lcopy_backward_loop:
+ subq $0x20, %rdx
+ movq -1*8(%rsi), %r8
+ movq -2*8(%rsi), %r9
+ movq -3*8(%rsi), %r10
+ movq -4*8(%rsi), %r11
+ leaq -4*8(%rsi), %rsi
+ movq %r8, -1*8(%rdi)
+ movq %r9, -2*8(%rdi)
+ movq %r10, -3*8(%rdi)
+ movq %r11, -4*8(%rdi)
+ leaq -4*8(%rdi), %rdi
+ jae .Lcopy_backward_loop
+ /*
+ * Calculate copy position to head.
+ */
+ addq $0x20, %rdx
+ subq %rdx, %rsi
+ subq %rdx, %rdi
.Lhandle_tail:
- movl %edx, %ecx
- andl $63, %ecx
- shrl $3, %ecx
- jz .Lhandle_7
+ cmpq $16, %rdx
+ jb .Lless_16bytes
+ /*
+ * Move data from 16 bytes to 31 bytes.
+ */
+ movq 0*8(%rsi), %r8
+ movq 1*8(%rsi), %r9
+ movq -2*8(%rsi, %rdx), %r10
+ movq -1*8(%rsi, %rdx), %r11
+ movq %r8, 0*8(%rdi)
+ movq %r9, 1*8(%rdi)
+ movq %r10, -2*8(%rdi, %rdx)
+ movq %r11, -1*8(%rdi, %rdx)
+ retq
.p2align 4
-.Lloop_8:
- decl %ecx
- movq (%rsi), %r8
- movq %r8, (%rdi)
- leaq 8(%rdi), %rdi
- leaq 8(%rsi), %rsi
- jnz .Lloop_8
-
-.Lhandle_7:
- movl %edx, %ecx
- andl $7, %ecx
- jz .Lend
+.Lless_16bytes:
+ cmpq $8, %rdx
+ jb .Lless_8bytes
+ /*
+ * Move data from 8 bytes to 15 bytes.
+ */
+ movq 0*8(%rsi), %r8
+ movq -1*8(%rsi, %rdx), %r9
+ movq %r8, 0*8(%rdi)
+ movq %r9, -1*8(%rdi, %rdx)
+ retq
+ .p2align 4
+.Lless_8bytes:
+ cmpq $4, %rdx
+ jb .Lless_3bytes
+ /*
+ * Move data from 4 bytes to 7 bytes.
+ */
+ movl (%rsi), %ecx
+ movl -4(%rsi, %rdx), %r8d
+ movl %ecx, (%rdi)
+ movl %r8d, -4(%rdi, %rdx)
+ retq
.p2align 4
+.Lless_3bytes:
+ cmpl $0, %edx
+ je .Lend
+ /*
+ * Move data from 1 bytes to 3 bytes.
+ */
.Lloop_1:
movb (%rsi), %r8b
movb %r8b, (%rdi)
incq %rdi
incq %rsi
- decl %ecx
+ decl %edx
jnz .Lloop_1
.Lend:
- ret
+ retq
CFI_ENDPROC
ENDPROC(memcpy)
ENDPROC(__memcpy)
diff --git a/arch/x86/lib/memmove_64.c b/arch/x86/lib/memmove_64.c
index 0a33909bf122..6d0f0ec41b34 100644
--- a/arch/x86/lib/memmove_64.c
+++ b/arch/x86/lib/memmove_64.c
@@ -8,14 +8,185 @@
#undef memmove
void *memmove(void *dest, const void *src, size_t count)
{
- if (dest < src) {
- return memcpy(dest, src, count);
- } else {
- char *p = dest + count;
- const char *s = src + count;
- while (count--)
- *--p = *--s;
- }
- return dest;
+ unsigned long d0,d1,d2,d3,d4,d5,d6,d7;
+ char *ret;
+
+ __asm__ __volatile__(
+ /* Handle more 32bytes in loop */
+ "mov %2, %3\n\t"
+ "cmp $0x20, %0\n\t"
+ "jb 1f\n\t"
+
+ /* Decide forward/backward copy mode */
+ "cmp %2, %1\n\t"
+ "jb 2f\n\t"
+
+ /*
+ * movsq instruction have many startup latency
+ * so we handle small size by general register.
+ */
+ "cmp $680, %0\n\t"
+ "jb 3f\n\t"
+ /*
+ * movsq instruction is only good for aligned case.
+ */
+ "cmpb %%dil, %%sil\n\t"
+ "je 4f\n\t"
+ "3:\n\t"
+ "sub $0x20, %0\n\t"
+ /*
+ * We gobble 32byts forward in each loop.
+ */
+ "5:\n\t"
+ "sub $0x20, %0\n\t"
+ "movq 0*8(%1), %4\n\t"
+ "movq 1*8(%1), %5\n\t"
+ "movq 2*8(%1), %6\n\t"
+ "movq 3*8(%1), %7\n\t"
+ "leaq 4*8(%1), %1\n\t"
+
+ "movq %4, 0*8(%2)\n\t"
+ "movq %5, 1*8(%2)\n\t"
+ "movq %6, 2*8(%2)\n\t"
+ "movq %7, 3*8(%2)\n\t"
+ "leaq 4*8(%2), %2\n\t"
+ "jae 5b\n\t"
+ "addq $0x20, %0\n\t"
+ "jmp 1f\n\t"
+ /*
+ * Handle data forward by movsq.
+ */
+ ".p2align 4\n\t"
+ "4:\n\t"
+ "movq %0, %8\n\t"
+ "movq -8(%1, %0), %4\n\t"
+ "lea -8(%2, %0), %5\n\t"
+ "shrq $3, %8\n\t"
+ "rep movsq\n\t"
+ "movq %4, (%5)\n\t"
+ "jmp 13f\n\t"
+ /*
+ * Handle data backward by movsq.
+ */
+ ".p2align 4\n\t"
+ "7:\n\t"
+ "movq %0, %8\n\t"
+ "movq (%1), %4\n\t"
+ "movq %2, %5\n\t"
+ "leaq -8(%1, %0), %1\n\t"
+ "leaq -8(%2, %0), %2\n\t"
+ "shrq $3, %8\n\t"
+ "std\n\t"
+ "rep movsq\n\t"
+ "cld\n\t"
+ "movq %4, (%5)\n\t"
+ "jmp 13f\n\t"
+
+ /*
+ * Start to prepare for backward copy.
+ */
+ ".p2align 4\n\t"
+ "2:\n\t"
+ "cmp $680, %0\n\t"
+ "jb 6f \n\t"
+ "cmp %%dil, %%sil\n\t"
+ "je 7b \n\t"
+ "6:\n\t"
+ /*
+ * Calculate copy position to tail.
+ */
+ "addq %0, %1\n\t"
+ "addq %0, %2\n\t"
+ "subq $0x20, %0\n\t"
+ /*
+ * We gobble 32byts backward in each loop.
+ */
+ "8:\n\t"
+ "subq $0x20, %0\n\t"
+ "movq -1*8(%1), %4\n\t"
+ "movq -2*8(%1), %5\n\t"
+ "movq -3*8(%1), %6\n\t"
+ "movq -4*8(%1), %7\n\t"
+ "leaq -4*8(%1), %1\n\t"
+
+ "movq %4, -1*8(%2)\n\t"
+ "movq %5, -2*8(%2)\n\t"
+ "movq %6, -3*8(%2)\n\t"
+ "movq %7, -4*8(%2)\n\t"
+ "leaq -4*8(%2), %2\n\t"
+ "jae 8b\n\t"
+ /*
+ * Calculate copy position to head.
+ */
+ "addq $0x20, %0\n\t"
+ "subq %0, %1\n\t"
+ "subq %0, %2\n\t"
+ "1:\n\t"
+ "cmpq $16, %0\n\t"
+ "jb 9f\n\t"
+ /*
+ * Move data from 16 bytes to 31 bytes.
+ */
+ "movq 0*8(%1), %4\n\t"
+ "movq 1*8(%1), %5\n\t"
+ "movq -2*8(%1, %0), %6\n\t"
+ "movq -1*8(%1, %0), %7\n\t"
+ "movq %4, 0*8(%2)\n\t"
+ "movq %5, 1*8(%2)\n\t"
+ "movq %6, -2*8(%2, %0)\n\t"
+ "movq %7, -1*8(%2, %0)\n\t"
+ "jmp 13f\n\t"
+ ".p2align 4\n\t"
+ "9:\n\t"
+ "cmpq $8, %0\n\t"
+ "jb 10f\n\t"
+ /*
+ * Move data from 8 bytes to 15 bytes.
+ */
+ "movq 0*8(%1), %4\n\t"
+ "movq -1*8(%1, %0), %5\n\t"
+ "movq %4, 0*8(%2)\n\t"
+ "movq %5, -1*8(%2, %0)\n\t"
+ "jmp 13f\n\t"
+ "10:\n\t"
+ "cmpq $4, %0\n\t"
+ "jb 11f\n\t"
+ /*
+ * Move data from 4 bytes to 7 bytes.
+ */
+ "movl (%1), %4d\n\t"
+ "movl -4(%1, %0), %5d\n\t"
+ "movl %4d, (%2)\n\t"
+ "movl %5d, -4(%2, %0)\n\t"
+ "jmp 13f\n\t"
+ "11:\n\t"
+ "cmp $2, %0\n\t"
+ "jb 12f\n\t"
+ /*
+ * Move data from 2 bytes to 3 bytes.
+ */
+ "movw (%1), %4w\n\t"
+ "movw -2(%1, %0), %5w\n\t"
+ "movw %4w, (%2)\n\t"
+ "movw %5w, -2(%2, %0)\n\t"
+ "jmp 13f\n\t"
+ "12:\n\t"
+ "cmp $1, %0\n\t"
+ "jb 13f\n\t"
+ /*
+ * Move data for 1 byte.
+ */
+ "movb (%1), %4b\n\t"
+ "movb %4b, (%2)\n\t"
+ "13:\n\t"
+ : "=&d" (d0), "=&S" (d1), "=&D" (d2), "=&a" (ret) ,
+ "=r"(d3), "=r"(d4), "=r"(d5), "=r"(d6), "=&c" (d7)
+ :"0" (count),
+ "1" (src),
+ "2" (dest)
+ :"memory");
+
+ return ret;
+
}
EXPORT_SYMBOL(memmove);
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
index a4c768397baa..55543397a8a7 100644
--- a/arch/x86/mm/Makefile
+++ b/arch/x86/mm/Makefile
@@ -26,4 +26,6 @@ obj-$(CONFIG_NUMA) += numa.o numa_$(BITS).o
obj-$(CONFIG_K8_NUMA) += k8topology_64.o
obj-$(CONFIG_ACPI_NUMA) += srat_$(BITS).o
+obj-$(CONFIG_HAVE_MEMBLOCK) += memblock.o
+
obj-$(CONFIG_MEMTEST) += memtest.o
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 4c4508e8a204..79b0b372d2d0 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -229,7 +229,16 @@ void vmalloc_sync_all(void)
spin_lock_irqsave(&pgd_lock, flags);
list_for_each_entry(page, &pgd_list, lru) {
- if (!vmalloc_sync_one(page_address(page), address))
+ spinlock_t *pgt_lock;
+ pmd_t *ret;
+
+ pgt_lock = &pgd_page_get_mm(page)->page_table_lock;
+
+ spin_lock(pgt_lock);
+ ret = vmalloc_sync_one(page_address(page), address);
+ spin_unlock(pgt_lock);
+
+ if (!ret)
break;
}
spin_unlock_irqrestore(&pgd_lock, flags);
@@ -251,6 +260,8 @@ static noinline __kprobes int vmalloc_fault(unsigned long address)
if (!(address >= VMALLOC_START && address < VMALLOC_END))
return -1;
+ WARN_ON_ONCE(in_nmi());
+
/*
* Synchronize this task's top level page-table
* with the 'reference' page table.
@@ -326,29 +337,7 @@ out:
void vmalloc_sync_all(void)
{
- unsigned long address;
-
- for (address = VMALLOC_START & PGDIR_MASK; address <= VMALLOC_END;
- address += PGDIR_SIZE) {
-
- const pgd_t *pgd_ref = pgd_offset_k(address);
- unsigned long flags;
- struct page *page;
-
- if (pgd_none(*pgd_ref))
- continue;
-
- spin_lock_irqsave(&pgd_lock, flags);
- list_for_each_entry(page, &pgd_list, lru) {
- pgd_t *pgd;
- pgd = (pgd_t *)page_address(page) + pgd_index(address);
- if (pgd_none(*pgd))
- set_pgd(pgd, *pgd_ref);
- else
- BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
- }
- spin_unlock_irqrestore(&pgd_lock, flags);
- }
+ sync_global_pgds(VMALLOC_START & PGDIR_MASK, VMALLOC_END);
}
/*
@@ -369,6 +358,8 @@ static noinline __kprobes int vmalloc_fault(unsigned long address)
if (!(address >= VMALLOC_START && address < VMALLOC_END))
return -1;
+ WARN_ON_ONCE(in_nmi());
+
/*
* Copy kernel mappings over when needed. This can also
* happen within a race in page table update. In the later
@@ -894,8 +885,14 @@ spurious_fault(unsigned long error_code, unsigned long address)
if (pmd_large(*pmd))
return spurious_fault_check(error_code, (pte_t *) pmd);
+ /*
+ * Note: don't use pte_present() here, since it returns true
+ * if the _PAGE_PROTNONE bit is set. However, this aliases the
+ * _PAGE_GLOBAL bit, which for kernel pages give false positives
+ * when CONFIG_DEBUG_PAGEALLOC is used.
+ */
pte = pte_offset_kernel(pmd, address);
- if (!pte_present(*pte))
+ if (!(pte_flags(*pte) & _PAGE_PRESENT))
return 0;
ret = spurious_fault_check(error_code, pte);
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index b278535b14aa..c0e28a13de7d 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -2,6 +2,7 @@
#include <linux/initrd.h>
#include <linux/ioport.h>
#include <linux/swap.h>
+#include <linux/memblock.h>
#include <asm/cacheflush.h>
#include <asm/e820.h>
@@ -33,6 +34,7 @@ static void __init find_early_table_space(unsigned long end, int use_pse,
int use_gbpages)
{
unsigned long puds, pmds, ptes, tables, start;
+ phys_addr_t base;
puds = (end + PUD_SIZE - 1) >> PUD_SHIFT;
tables = roundup(puds * sizeof(pud_t), PAGE_SIZE);
@@ -75,12 +77,12 @@ static void __init find_early_table_space(unsigned long end, int use_pse,
#else
start = 0x8000;
#endif
- e820_table_start = find_e820_area(start, max_pfn_mapped<<PAGE_SHIFT,
+ base = memblock_find_in_range(start, max_pfn_mapped<<PAGE_SHIFT,
tables, PAGE_SIZE);
- if (e820_table_start == -1UL)
+ if (base == MEMBLOCK_ERROR)
panic("Cannot find space for the kernel page tables");
- e820_table_start >>= PAGE_SHIFT;
+ e820_table_start = base >> PAGE_SHIFT;
e820_table_end = e820_table_start;
e820_table_top = e820_table_start + (tables >> PAGE_SHIFT);
@@ -299,7 +301,7 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
__flush_tlb_all();
if (!after_bootmem && e820_table_end > e820_table_start)
- reserve_early(e820_table_start << PAGE_SHIFT,
+ memblock_x86_reserve_range(e820_table_start << PAGE_SHIFT,
e820_table_end << PAGE_SHIFT, "PGTABLE");
if (!after_bootmem)
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index bca79091b9d6..0e969f9f401b 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -25,6 +25,7 @@
#include <linux/pfn.h>
#include <linux/poison.h>
#include <linux/bootmem.h>
+#include <linux/memblock.h>
#include <linux/proc_fs.h>
#include <linux/memory_hotplug.h>
#include <linux/initrd.h>
@@ -67,7 +68,7 @@ static __init void *alloc_low_page(void)
panic("alloc_low_page: ran out of memory");
adr = __va(pfn * PAGE_SIZE);
- memset(adr, 0, PAGE_SIZE);
+ clear_page(adr);
return adr;
}
@@ -422,49 +423,28 @@ static void __init add_one_highpage_init(struct page *page)
totalhigh_pages++;
}
-struct add_highpages_data {
- unsigned long start_pfn;
- unsigned long end_pfn;
-};
-
-static int __init add_highpages_work_fn(unsigned long start_pfn,
- unsigned long end_pfn, void *datax)
+void __init add_highpages_with_active_regions(int nid,
+ unsigned long start_pfn, unsigned long end_pfn)
{
- int node_pfn;
- struct page *page;
- unsigned long final_start_pfn, final_end_pfn;
- struct add_highpages_data *data;
+ struct range *range;
+ int nr_range;
+ int i;
- data = (struct add_highpages_data *)datax;
+ nr_range = __get_free_all_memory_range(&range, nid, start_pfn, end_pfn);
- final_start_pfn = max(start_pfn, data->start_pfn);
- final_end_pfn = min(end_pfn, data->end_pfn);
- if (final_start_pfn >= final_end_pfn)
- return 0;
+ for (i = 0; i < nr_range; i++) {
+ struct page *page;
+ int node_pfn;
- for (node_pfn = final_start_pfn; node_pfn < final_end_pfn;
- node_pfn++) {
- if (!pfn_valid(node_pfn))
- continue;
- page = pfn_to_page(node_pfn);
- add_one_highpage_init(page);
+ for (node_pfn = range[i].start; node_pfn < range[i].end;
+ node_pfn++) {
+ if (!pfn_valid(node_pfn))
+ continue;
+ page = pfn_to_page(node_pfn);
+ add_one_highpage_init(page);
+ }
}
-
- return 0;
-
}
-
-void __init add_highpages_with_active_regions(int nid, unsigned long start_pfn,
- unsigned long end_pfn)
-{
- struct add_highpages_data data;
-
- data.start_pfn = start_pfn;
- data.end_pfn = end_pfn;
-
- work_with_active_regions(nid, add_highpages_work_fn, &data);
-}
-
#else
static inline void permanent_kmaps_init(pgd_t *pgd_base)
{
@@ -548,48 +528,6 @@ static void __init pagetable_init(void)
permanent_kmaps_init(pgd_base);
}
-#ifdef CONFIG_ACPI_SLEEP
-/*
- * ACPI suspend needs this for resume, because things like the intel-agp
- * driver might have split up a kernel 4MB mapping.
- */
-char swsusp_pg_dir[PAGE_SIZE]
- __attribute__ ((aligned(PAGE_SIZE)));
-
-static inline void save_pg_dir(void)
-{
- memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
-}
-#else /* !CONFIG_ACPI_SLEEP */
-static inline void save_pg_dir(void)
-{
-}
-#endif /* !CONFIG_ACPI_SLEEP */
-
-void zap_low_mappings(bool early)
-{
- int i;
-
- /*
- * Zap initial low-memory mappings.
- *
- * Note that "pgd_clear()" doesn't do it for
- * us, because pgd_clear() is a no-op on i386.
- */
- for (i = 0; i < KERNEL_PGD_BOUNDARY; i++) {
-#ifdef CONFIG_X86_PAE
- set_pgd(swapper_pg_dir+i, __pgd(1 + __pa(empty_zero_page)));
-#else
- set_pgd(swapper_pg_dir+i, __pgd(0));
-#endif
- }
-
- if (early)
- __flush_tlb();
- else
- flush_tlb_all();
-}
-
pteval_t __supported_pte_mask __read_mostly = ~(_PAGE_NX | _PAGE_GLOBAL | _PAGE_IOMAP);
EXPORT_SYMBOL_GPL(__supported_pte_mask);
@@ -712,14 +650,14 @@ void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn,
highstart_pfn = highend_pfn = max_pfn;
if (max_pfn > max_low_pfn)
highstart_pfn = max_low_pfn;
- e820_register_active_regions(0, 0, highend_pfn);
+ memblock_x86_register_active_regions(0, 0, highend_pfn);
sparse_memory_present_with_active_regions(0);
printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
pages_to_mb(highend_pfn - highstart_pfn));
num_physpages = highend_pfn;
high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1;
#else
- e820_register_active_regions(0, 0, max_low_pfn);
+ memblock_x86_register_active_regions(0, 0, max_low_pfn);
sparse_memory_present_with_active_regions(0);
num_physpages = max_low_pfn;
high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1;
@@ -750,68 +688,12 @@ static void __init zone_sizes_init(void)
free_area_init_nodes(max_zone_pfns);
}
-#ifndef CONFIG_NO_BOOTMEM
-static unsigned long __init setup_node_bootmem(int nodeid,
- unsigned long start_pfn,
- unsigned long end_pfn,
- unsigned long bootmap)
-{
- unsigned long bootmap_size;
-
- /* don't touch min_low_pfn */
- bootmap_size = init_bootmem_node(NODE_DATA(nodeid),
- bootmap >> PAGE_SHIFT,
- start_pfn, end_pfn);
- printk(KERN_INFO " node %d low ram: %08lx - %08lx\n",
- nodeid, start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT);
- printk(KERN_INFO " node %d bootmap %08lx - %08lx\n",
- nodeid, bootmap, bootmap + bootmap_size);
- free_bootmem_with_active_regions(nodeid, end_pfn);
-
- return bootmap + bootmap_size;
-}
-#endif
-
void __init setup_bootmem_allocator(void)
{
-#ifndef CONFIG_NO_BOOTMEM
- int nodeid;
- unsigned long bootmap_size, bootmap;
- /*
- * Initialize the boot-time allocator (with low memory only):
- */
- bootmap_size = bootmem_bootmap_pages(max_low_pfn)<<PAGE_SHIFT;
- bootmap = find_e820_area(0, max_pfn_mapped<<PAGE_SHIFT, bootmap_size,
- PAGE_SIZE);
- if (bootmap == -1L)
- panic("Cannot find bootmem map of size %ld\n", bootmap_size);
- reserve_early(bootmap, bootmap + bootmap_size, "BOOTMAP");
-#endif
-
printk(KERN_INFO " mapped low ram: 0 - %08lx\n",
max_pfn_mapped<<PAGE_SHIFT);
printk(KERN_INFO " low ram: 0 - %08lx\n", max_low_pfn<<PAGE_SHIFT);
-#ifndef CONFIG_NO_BOOTMEM
- for_each_online_node(nodeid) {
- unsigned long start_pfn, end_pfn;
-
-#ifdef CONFIG_NEED_MULTIPLE_NODES
- start_pfn = node_start_pfn[nodeid];
- end_pfn = node_end_pfn[nodeid];
- if (start_pfn > max_low_pfn)
- continue;
- if (end_pfn > max_low_pfn)
- end_pfn = max_low_pfn;
-#else
- start_pfn = 0;
- end_pfn = max_low_pfn;
-#endif
- bootmap = setup_node_bootmem(nodeid, start_pfn, end_pfn,
- bootmap);
- }
-#endif
-
after_bootmem = 1;
}
@@ -958,9 +840,6 @@ void __init mem_init(void)
if (boot_cpu_data.wp_works_ok < 0)
test_wp_bit();
-
- save_pg_dir();
- zap_low_mappings(true);
}
#ifdef CONFIG_MEMORY_HOTPLUG
@@ -1070,8 +949,3 @@ void mark_rodata_ro(void)
}
#endif
-int __init reserve_bootmem_generic(unsigned long phys, unsigned long len,
- int flags)
-{
- return reserve_bootmem(phys, len, flags);
-}
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 9a6674689a20..84346200e783 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -21,6 +21,7 @@
#include <linux/initrd.h>
#include <linux/pagemap.h>
#include <linux/bootmem.h>
+#include <linux/memblock.h>
#include <linux/proc_fs.h>
#include <linux/pci.h>
#include <linux/pfn.h>
@@ -52,8 +53,6 @@
#include <asm/init.h>
#include <linux/bootmem.h>
-static unsigned long dma_reserve __initdata;
-
static int __init parse_direct_gbpages_off(char *arg)
{
direct_gbpages = 0;
@@ -98,6 +97,43 @@ static int __init nonx32_setup(char *str)
__setup("noexec32=", nonx32_setup);
/*
+ * When memory was added/removed make sure all the processes MM have
+ * suitable PGD entries in the local PGD level page.
+ */
+void sync_global_pgds(unsigned long start, unsigned long end)
+{
+ unsigned long address;
+
+ for (address = start; address <= end; address += PGDIR_SIZE) {
+ const pgd_t *pgd_ref = pgd_offset_k(address);
+ unsigned long flags;
+ struct page *page;
+
+ if (pgd_none(*pgd_ref))
+ continue;
+
+ spin_lock_irqsave(&pgd_lock, flags);
+ list_for_each_entry(page, &pgd_list, lru) {
+ pgd_t *pgd;
+ spinlock_t *pgt_lock;
+
+ pgd = (pgd_t *)page_address(page) + pgd_index(address);
+ pgt_lock = &pgd_page_get_mm(page)->page_table_lock;
+ spin_lock(pgt_lock);
+
+ if (pgd_none(*pgd))
+ set_pgd(pgd, *pgd_ref);
+ else
+ BUG_ON(pgd_page_vaddr(*pgd)
+ != pgd_page_vaddr(*pgd_ref));
+
+ spin_unlock(pgt_lock);
+ }
+ spin_unlock_irqrestore(&pgd_lock, flags);
+ }
+}
+
+/*
* NOTE: This function is marked __ref because it calls __init function
* (alloc_bootmem_pages). It's safe to do it ONLY when after_bootmem == 0.
*/
@@ -293,7 +329,7 @@ static __ref void *alloc_low_page(unsigned long *phys)
panic("alloc_low_page: ran out of memory");
adr = early_memremap(pfn * PAGE_SIZE, PAGE_SIZE);
- memset(adr, 0, PAGE_SIZE);
+ clear_page(adr);
*phys = pfn * PAGE_SIZE;
return adr;
}
@@ -534,11 +570,13 @@ kernel_physical_mapping_init(unsigned long start,
unsigned long end,
unsigned long page_size_mask)
{
-
+ bool pgd_changed = false;
unsigned long next, last_map_addr = end;
+ unsigned long addr;
start = (unsigned long)__va(start);
end = (unsigned long)__va(end);
+ addr = start;
for (; start < end; start = next) {
pgd_t *pgd = pgd_offset_k(start);
@@ -563,7 +601,12 @@ kernel_physical_mapping_init(unsigned long start,
spin_lock(&init_mm.page_table_lock);
pgd_populate(&init_mm, pgd, __va(pud_phys));
spin_unlock(&init_mm.page_table_lock);
+ pgd_changed = true;
}
+
+ if (pgd_changed)
+ sync_global_pgds(addr, end);
+
__flush_tlb_all();
return last_map_addr;
@@ -573,23 +616,7 @@ kernel_physical_mapping_init(unsigned long start,
void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn,
int acpi, int k8)
{
-#ifndef CONFIG_NO_BOOTMEM
- unsigned long bootmap_size, bootmap;
-
- bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT;
- bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size,
- PAGE_SIZE);
- if (bootmap == -1L)
- panic("Cannot find bootmem map of size %ld\n", bootmap_size);
- reserve_early(bootmap, bootmap + bootmap_size, "BOOTMAP");
- /* don't touch min_low_pfn */
- bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap >> PAGE_SHIFT,
- 0, end_pfn);
- e820_register_active_regions(0, start_pfn, end_pfn);
- free_bootmem_with_active_regions(0, end_pfn);
-#else
- e820_register_active_regions(0, start_pfn, end_pfn);
-#endif
+ memblock_x86_register_active_regions(0, start_pfn, end_pfn);
}
#endif
@@ -799,52 +826,6 @@ void mark_rodata_ro(void)
#endif
-int __init reserve_bootmem_generic(unsigned long phys, unsigned long len,
- int flags)
-{
-#ifdef CONFIG_NUMA
- int nid, next_nid;
- int ret;
-#endif
- unsigned long pfn = phys >> PAGE_SHIFT;
-
- if (pfn >= max_pfn) {
- /*
- * This can happen with kdump kernels when accessing
- * firmware tables:
- */
- if (pfn < max_pfn_mapped)
- return -EFAULT;
-
- printk(KERN_ERR "reserve_bootmem: illegal reserve %lx %lu\n",
- phys, len);
- return -EFAULT;
- }
-
- /* Should check here against the e820 map to avoid double free */
-#ifdef CONFIG_NUMA
- nid = phys_to_nid(phys);
- next_nid = phys_to_nid(phys + len - 1);
- if (nid == next_nid)
- ret = reserve_bootmem_node(NODE_DATA(nid), phys, len, flags);
- else
- ret = reserve_bootmem(phys, len, flags);
-
- if (ret != 0)
- return ret;
-
-#else
- reserve_bootmem(phys, len, flags);
-#endif
-
- if (phys+len <= MAX_DMA_PFN*PAGE_SIZE) {
- dma_reserve += len / PAGE_SIZE;
- set_dma_reserve(dma_reserve);
- }
-
- return 0;
-}
-
int kern_addr_valid(unsigned long addr)
{
unsigned long above = ((long)addr) >> __VIRTUAL_MASK_SHIFT;
@@ -1003,6 +984,7 @@ vmemmap_populate(struct page *start_page, unsigned long size, int node)
}
}
+ sync_global_pgds((unsigned long)start_page, end);
return 0;
}
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 3ba6e0608c55..0369843511dc 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -362,6 +362,11 @@ static inline pte_t * __init early_ioremap_pte(unsigned long addr)
return &bm_pte[pte_index(addr)];
}
+bool __init is_early_ioremap_ptep(pte_t *ptep)
+{
+ return ptep >= &bm_pte[0] && ptep < &bm_pte[PAGE_SIZE/sizeof(pte_t)];
+}
+
static unsigned long slot_virt[FIX_BTMAPS_SLOTS] __initdata;
void __init early_ioremap_init(void)
diff --git a/arch/x86/mm/k8topology_64.c b/arch/x86/mm/k8topology_64.c
index 970ed579d4e4..804a3b6c6e14 100644
--- a/arch/x86/mm/k8topology_64.c
+++ b/arch/x86/mm/k8topology_64.c
@@ -11,6 +11,8 @@
#include <linux/string.h>
#include <linux/module.h>
#include <linux/nodemask.h>
+#include <linux/memblock.h>
+
#include <asm/io.h>
#include <linux/pci_ids.h>
#include <linux/acpi.h>
@@ -22,7 +24,7 @@
#include <asm/numa.h>
#include <asm/mpspec.h>
#include <asm/apic.h>
-#include <asm/k8.h>
+#include <asm/amd_nb.h>
static struct bootnode __initdata nodes[8];
static nodemask_t __initdata nodes_parsed = NODE_MASK_NONE;
@@ -54,8 +56,8 @@ static __init int find_northbridge(void)
static __init void early_get_boot_cpu_id(void)
{
/*
- * need to get boot_cpu_id so can use that to create apicid_to_node
- * in k8_scan_nodes()
+ * need to get the APIC ID of the BSP so can use that to
+ * create apicid_to_node in k8_scan_nodes()
*/
#ifdef CONFIG_X86_MPPARSE
/*
@@ -212,7 +214,7 @@ int __init k8_scan_nodes(void)
bits = boot_cpu_data.x86_coreid_bits;
cores = (1<<bits);
apicid_base = 0;
- /* need to get boot_cpu_id early for system with apicid lifting */
+ /* get the APIC ID of the BSP early for systems with apicid lifting */
early_get_boot_cpu_id();
if (boot_cpu_physical_apicid > 0) {
pr_info("BSP APIC ID: %02x\n", boot_cpu_physical_apicid);
@@ -222,7 +224,7 @@ int __init k8_scan_nodes(void)
for_each_node_mask(i, node_possible_map) {
int j;
- e820_register_active_regions(i,
+ memblock_x86_register_active_regions(i,
nodes[i].start >> PAGE_SHIFT,
nodes[i].end >> PAGE_SHIFT);
for (j = apicid_base; j < cores + apicid_base; j++)
diff --git a/arch/x86/mm/kmemcheck/kmemcheck.c b/arch/x86/mm/kmemcheck/kmemcheck.c
index b3b531a4f8e5..d87dd6d042d6 100644
--- a/arch/x86/mm/kmemcheck/kmemcheck.c
+++ b/arch/x86/mm/kmemcheck/kmemcheck.c
@@ -631,6 +631,8 @@ bool kmemcheck_fault(struct pt_regs *regs, unsigned long address,
if (!pte)
return false;
+ WARN_ON_ONCE(in_nmi());
+
if (error_code & 2)
kmemcheck_access(regs, address, KMEMCHECK_WRITE);
else
diff --git a/arch/x86/mm/kmemcheck/opcode.c b/arch/x86/mm/kmemcheck/opcode.c
index 63c19e27aa6f..324aa3f07237 100644
--- a/arch/x86/mm/kmemcheck/opcode.c
+++ b/arch/x86/mm/kmemcheck/opcode.c
@@ -9,7 +9,7 @@ static bool opcode_is_prefix(uint8_t b)
b == 0xf0 || b == 0xf2 || b == 0xf3
/* Group 2 */
|| b == 0x2e || b == 0x36 || b == 0x3e || b == 0x26
- || b == 0x64 || b == 0x65 || b == 0x2e || b == 0x3e
+ || b == 0x64 || b == 0x65
/* Group 3 */
|| b == 0x66
/* Group 4 */
diff --git a/arch/x86/mm/memblock.c b/arch/x86/mm/memblock.c
new file mode 100644
index 000000000000..aa1169392b83
--- /dev/null
+++ b/arch/x86/mm/memblock.c
@@ -0,0 +1,348 @@
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/bitops.h>
+#include <linux/memblock.h>
+#include <linux/bootmem.h>
+#include <linux/mm.h>
+#include <linux/range.h>
+
+/* Check for already reserved areas */
+static bool __init check_with_memblock_reserved_size(u64 *addrp, u64 *sizep, u64 align)
+{
+ struct memblock_region *r;
+ u64 addr = *addrp, last;
+ u64 size = *sizep;
+ bool changed = false;
+
+again:
+ last = addr + size;
+ for_each_memblock(reserved, r) {
+ if (last > r->base && addr < r->base) {
+ size = r->base - addr;
+ changed = true;
+ goto again;
+ }
+ if (last > (r->base + r->size) && addr < (r->base + r->size)) {
+ addr = round_up(r->base + r->size, align);
+ size = last - addr;
+ changed = true;
+ goto again;
+ }
+ if (last <= (r->base + r->size) && addr >= r->base) {
+ *sizep = 0;
+ return false;
+ }
+ }
+ if (changed) {
+ *addrp = addr;
+ *sizep = size;
+ }
+ return changed;
+}
+
+/*
+ * Find next free range after start, and size is returned in *sizep
+ */
+u64 __init memblock_x86_find_in_range_size(u64 start, u64 *sizep, u64 align)
+{
+ struct memblock_region *r;
+
+ for_each_memblock(memory, r) {
+ u64 ei_start = r->base;
+ u64 ei_last = ei_start + r->size;
+ u64 addr;
+
+ addr = round_up(ei_start, align);
+ if (addr < start)
+ addr = round_up(start, align);
+ if (addr >= ei_last)
+ continue;
+ *sizep = ei_last - addr;
+ while (check_with_memblock_reserved_size(&addr, sizep, align))
+ ;
+
+ if (*sizep)
+ return addr;
+ }
+
+ return MEMBLOCK_ERROR;
+}
+
+static __init struct range *find_range_array(int count)
+{
+ u64 end, size, mem;
+ struct range *range;
+
+ size = sizeof(struct range) * count;
+ end = memblock.current_limit;
+
+ mem = memblock_find_in_range(0, end, size, sizeof(struct range));
+ if (mem == MEMBLOCK_ERROR)
+ panic("can not find more space for range array");
+
+ /*
+ * This range is tempoaray, so don't reserve it, it will not be
+ * overlapped because We will not alloccate new buffer before
+ * We discard this one
+ */
+ range = __va(mem);
+ memset(range, 0, size);
+
+ return range;
+}
+
+static void __init memblock_x86_subtract_reserved(struct range *range, int az)
+{
+ u64 final_start, final_end;
+ struct memblock_region *r;
+
+ /* Take out region array itself at first*/
+ memblock_free_reserved_regions();
+
+ memblock_dbg("Subtract (%ld early reservations)\n", memblock.reserved.cnt);
+
+ for_each_memblock(reserved, r) {
+ memblock_dbg(" [%010llx-%010llx]\n", (u64)r->base, (u64)r->base + r->size - 1);
+ final_start = PFN_DOWN(r->base);
+ final_end = PFN_UP(r->base + r->size);
+ if (final_start >= final_end)
+ continue;
+ subtract_range(range, az, final_start, final_end);
+ }
+
+ /* Put region array back ? */
+ memblock_reserve_reserved_regions();
+}
+
+struct count_data {
+ int nr;
+};
+
+static int __init count_work_fn(unsigned long start_pfn,
+ unsigned long end_pfn, void *datax)
+{
+ struct count_data *data = datax;
+
+ data->nr++;
+
+ return 0;
+}
+
+static int __init count_early_node_map(int nodeid)
+{
+ struct count_data data;
+
+ data.nr = 0;
+ work_with_active_regions(nodeid, count_work_fn, &data);
+
+ return data.nr;
+}
+
+int __init __get_free_all_memory_range(struct range **rangep, int nodeid,
+ unsigned long start_pfn, unsigned long end_pfn)
+{
+ int count;
+ struct range *range;
+ int nr_range;
+
+ count = (memblock.reserved.cnt + count_early_node_map(nodeid)) * 2;
+
+ range = find_range_array(count);
+ nr_range = 0;
+
+ /*
+ * Use early_node_map[] and memblock.reserved.region to get range array
+ * at first
+ */
+ nr_range = add_from_early_node_map(range, count, nr_range, nodeid);
+ subtract_range(range, count, 0, start_pfn);
+ subtract_range(range, count, end_pfn, -1ULL);
+
+ memblock_x86_subtract_reserved(range, count);
+ nr_range = clean_sort_range(range, count);
+
+ *rangep = range;
+ return nr_range;
+}
+
+int __init get_free_all_memory_range(struct range **rangep, int nodeid)
+{
+ unsigned long end_pfn = -1UL;
+
+#ifdef CONFIG_X86_32
+ end_pfn = max_low_pfn;
+#endif
+ return __get_free_all_memory_range(rangep, nodeid, 0, end_pfn);
+}
+
+static u64 __init __memblock_x86_memory_in_range(u64 addr, u64 limit, bool get_free)
+{
+ int i, count;
+ struct range *range;
+ int nr_range;
+ u64 final_start, final_end;
+ u64 free_size;
+ struct memblock_region *r;
+
+ count = (memblock.reserved.cnt + memblock.memory.cnt) * 2;
+
+ range = find_range_array(count);
+ nr_range = 0;
+
+ addr = PFN_UP(addr);
+ limit = PFN_DOWN(limit);
+
+ for_each_memblock(memory, r) {
+ final_start = PFN_UP(r->base);
+ final_end = PFN_DOWN(r->base + r->size);
+ if (final_start >= final_end)
+ continue;
+ if (final_start >= limit || final_end <= addr)
+ continue;
+
+ nr_range = add_range(range, count, nr_range, final_start, final_end);
+ }
+ subtract_range(range, count, 0, addr);
+ subtract_range(range, count, limit, -1ULL);
+
+ /* Subtract memblock.reserved.region in range ? */
+ if (!get_free)
+ goto sort_and_count_them;
+ for_each_memblock(reserved, r) {
+ final_start = PFN_DOWN(r->base);
+ final_end = PFN_UP(r->base + r->size);
+ if (final_start >= final_end)
+ continue;
+ if (final_start >= limit || final_end <= addr)
+ continue;
+
+ subtract_range(range, count, final_start, final_end);
+ }
+
+sort_and_count_them:
+ nr_range = clean_sort_range(range, count);
+
+ free_size = 0;
+ for (i = 0; i < nr_range; i++)
+ free_size += range[i].end - range[i].start;
+
+ return free_size << PAGE_SHIFT;
+}
+
+u64 __init memblock_x86_free_memory_in_range(u64 addr, u64 limit)
+{
+ return __memblock_x86_memory_in_range(addr, limit, true);
+}
+
+u64 __init memblock_x86_memory_in_range(u64 addr, u64 limit)
+{
+ return __memblock_x86_memory_in_range(addr, limit, false);
+}
+
+void __init memblock_x86_reserve_range(u64 start, u64 end, char *name)
+{
+ if (start == end)
+ return;
+
+ if (WARN_ONCE(start > end, "memblock_x86_reserve_range: wrong range [%#llx, %#llx)\n", start, end))
+ return;
+
+ memblock_dbg(" memblock_x86_reserve_range: [%#010llx-%#010llx] %16s\n", start, end - 1, name);
+
+ memblock_reserve(start, end - start);
+}
+
+void __init memblock_x86_free_range(u64 start, u64 end)
+{
+ if (start == end)
+ return;
+
+ if (WARN_ONCE(start > end, "memblock_x86_free_range: wrong range [%#llx, %#llx)\n", start, end))
+ return;
+
+ memblock_dbg(" memblock_x86_free_range: [%#010llx-%#010llx]\n", start, end - 1);
+
+ memblock_free(start, end - start);
+}
+
+/*
+ * Need to call this function after memblock_x86_register_active_regions,
+ * so early_node_map[] is filled already.
+ */
+u64 __init memblock_x86_find_in_range_node(int nid, u64 start, u64 end, u64 size, u64 align)
+{
+ u64 addr;
+ addr = find_memory_core_early(nid, size, align, start, end);
+ if (addr != MEMBLOCK_ERROR)
+ return addr;
+
+ /* Fallback, should already have start end within node range */
+ return memblock_find_in_range(start, end, size, align);
+}
+
+/*
+ * Finds an active region in the address range from start_pfn to last_pfn and
+ * returns its range in ei_startpfn and ei_endpfn for the memblock entry.
+ */
+static int __init memblock_x86_find_active_region(const struct memblock_region *ei,
+ unsigned long start_pfn,
+ unsigned long last_pfn,
+ unsigned long *ei_startpfn,
+ unsigned long *ei_endpfn)
+{
+ u64 align = PAGE_SIZE;
+
+ *ei_startpfn = round_up(ei->base, align) >> PAGE_SHIFT;
+ *ei_endpfn = round_down(ei->base + ei->size, align) >> PAGE_SHIFT;
+
+ /* Skip map entries smaller than a page */
+ if (*ei_startpfn >= *ei_endpfn)
+ return 0;
+
+ /* Skip if map is outside the node */
+ if (*ei_endpfn <= start_pfn || *ei_startpfn >= last_pfn)
+ return 0;
+
+ /* Check for overlaps */
+ if (*ei_startpfn < start_pfn)
+ *ei_startpfn = start_pfn;
+ if (*ei_endpfn > last_pfn)
+ *ei_endpfn = last_pfn;
+
+ return 1;
+}
+
+/* Walk the memblock.memory map and register active regions within a node */
+void __init memblock_x86_register_active_regions(int nid, unsigned long start_pfn,
+ unsigned long last_pfn)
+{
+ unsigned long ei_startpfn;
+ unsigned long ei_endpfn;
+ struct memblock_region *r;
+
+ for_each_memblock(memory, r)
+ if (memblock_x86_find_active_region(r, start_pfn, last_pfn,
+ &ei_startpfn, &ei_endpfn))
+ add_active_range(nid, ei_startpfn, ei_endpfn);
+}
+
+/*
+ * Find the hole size (in bytes) in the memory range.
+ * @start: starting address of the memory range to scan
+ * @end: ending address of the memory range to scan
+ */
+u64 __init memblock_x86_hole_size(u64 start, u64 end)
+{
+ unsigned long start_pfn = start >> PAGE_SHIFT;
+ unsigned long last_pfn = end >> PAGE_SHIFT;
+ unsigned long ei_startpfn, ei_endpfn, ram = 0;
+ struct memblock_region *r;
+
+ for_each_memblock(memory, r)
+ if (memblock_x86_find_active_region(r, start_pfn, last_pfn,
+ &ei_startpfn, &ei_endpfn))
+ ram += ei_endpfn - ei_startpfn;
+
+ return end - start - ((u64)ram << PAGE_SHIFT);
+}
diff --git a/arch/x86/mm/memtest.c b/arch/x86/mm/memtest.c
index 18d244f70205..92faf3a1c53e 100644
--- a/arch/x86/mm/memtest.c
+++ b/arch/x86/mm/memtest.c
@@ -6,8 +6,7 @@
#include <linux/smp.h>
#include <linux/init.h>
#include <linux/pfn.h>
-
-#include <asm/e820.h>
+#include <linux/memblock.h>
static u64 patterns[] __initdata = {
0,
@@ -35,7 +34,7 @@ static void __init reserve_bad_mem(u64 pattern, u64 start_bad, u64 end_bad)
(unsigned long long) pattern,
(unsigned long long) start_bad,
(unsigned long long) end_bad);
- reserve_early(start_bad, end_bad, "BAD RAM");
+ memblock_x86_reserve_range(start_bad, end_bad, "BAD RAM");
}
static void __init memtest(u64 pattern, u64 start_phys, u64 size)
@@ -74,7 +73,7 @@ static void __init do_one_pass(u64 pattern, u64 start, u64 end)
u64 size = 0;
while (start < end) {
- start = find_e820_area_size(start, &size, 1);
+ start = memblock_x86_find_in_range_size(start, &size, 1);
/* done ? */
if (start >= end)
diff --git a/arch/x86/mm/numa_32.c b/arch/x86/mm/numa_32.c
index 809baaaf48b1..84a3e4c9f277 100644
--- a/arch/x86/mm/numa_32.c
+++ b/arch/x86/mm/numa_32.c
@@ -24,6 +24,7 @@
#include <linux/mm.h>
#include <linux/bootmem.h>
+#include <linux/memblock.h>
#include <linux/mmzone.h>
#include <linux/highmem.h>
#include <linux/initrd.h>
@@ -120,7 +121,7 @@ int __init get_memcfg_numa_flat(void)
node_start_pfn[0] = 0;
node_end_pfn[0] = max_pfn;
- e820_register_active_regions(0, 0, max_pfn);
+ memblock_x86_register_active_regions(0, 0, max_pfn);
memory_present(0, 0, max_pfn);
node_remap_size[0] = node_memmap_size_bytes(0, 0, max_pfn);
@@ -161,14 +162,14 @@ static void __init allocate_pgdat(int nid)
NODE_DATA(nid) = (pg_data_t *)node_remap_start_vaddr[nid];
else {
unsigned long pgdat_phys;
- pgdat_phys = find_e820_area(min_low_pfn<<PAGE_SHIFT,
+ pgdat_phys = memblock_find_in_range(min_low_pfn<<PAGE_SHIFT,
max_pfn_mapped<<PAGE_SHIFT,
sizeof(pg_data_t),
PAGE_SIZE);
NODE_DATA(nid) = (pg_data_t *)(pfn_to_kaddr(pgdat_phys>>PAGE_SHIFT));
memset(buf, 0, sizeof(buf));
sprintf(buf, "NODE_DATA %d", nid);
- reserve_early(pgdat_phys, pgdat_phys + sizeof(pg_data_t), buf);
+ memblock_x86_reserve_range(pgdat_phys, pgdat_phys + sizeof(pg_data_t), buf);
}
printk(KERN_DEBUG "allocate_pgdat: node %d NODE_DATA %08lx\n",
nid, (unsigned long)NODE_DATA(nid));
@@ -291,15 +292,15 @@ static __init unsigned long calculate_numa_remap_pages(void)
PTRS_PER_PTE);
node_kva_target <<= PAGE_SHIFT;
do {
- node_kva_final = find_e820_area(node_kva_target,
+ node_kva_final = memblock_find_in_range(node_kva_target,
((u64)node_end_pfn[nid])<<PAGE_SHIFT,
((u64)size)<<PAGE_SHIFT,
LARGE_PAGE_BYTES);
node_kva_target -= LARGE_PAGE_BYTES;
- } while (node_kva_final == -1ULL &&
+ } while (node_kva_final == MEMBLOCK_ERROR &&
(node_kva_target>>PAGE_SHIFT) > (node_start_pfn[nid]));
- if (node_kva_final == -1ULL)
+ if (node_kva_final == MEMBLOCK_ERROR)
panic("Can not get kva ram\n");
node_remap_size[nid] = size;
@@ -318,15 +319,13 @@ static __init unsigned long calculate_numa_remap_pages(void)
* but we could have some hole in high memory, and it will only
* check page_is_ram(pfn) && !page_is_reserved_early(pfn) to decide
* to use it as free.
- * So reserve_early here, hope we don't run out of that array
+ * So memblock_x86_reserve_range here, hope we don't run out of that array
*/
- reserve_early(node_kva_final,
+ memblock_x86_reserve_range(node_kva_final,
node_kva_final+(((u64)size)<<PAGE_SHIFT),
"KVA RAM");
node_remap_start_pfn[nid] = node_kva_final>>PAGE_SHIFT;
- remove_active_range(nid, node_remap_start_pfn[nid],
- node_remap_start_pfn[nid] + size);
}
printk(KERN_INFO "Reserving total of %lx pages for numa KVA remap\n",
reserve_pages);
@@ -367,14 +366,14 @@ void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn,
kva_target_pfn = round_down(max_low_pfn - kva_pages, PTRS_PER_PTE);
do {
- kva_start_pfn = find_e820_area(kva_target_pfn<<PAGE_SHIFT,
+ kva_start_pfn = memblock_find_in_range(kva_target_pfn<<PAGE_SHIFT,
max_low_pfn<<PAGE_SHIFT,
kva_pages<<PAGE_SHIFT,
PTRS_PER_PTE<<PAGE_SHIFT) >> PAGE_SHIFT;
kva_target_pfn -= PTRS_PER_PTE;
- } while (kva_start_pfn == -1UL && kva_target_pfn > min_low_pfn);
+ } while (kva_start_pfn == MEMBLOCK_ERROR && kva_target_pfn > min_low_pfn);
- if (kva_start_pfn == -1UL)
+ if (kva_start_pfn == MEMBLOCK_ERROR)
panic("Can not get kva space\n");
printk(KERN_INFO "kva_start_pfn ~ %lx max_low_pfn ~ %lx\n",
@@ -382,7 +381,7 @@ void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn,
printk(KERN_INFO "max_pfn = %lx\n", max_pfn);
/* avoid clash with initrd */
- reserve_early(kva_start_pfn<<PAGE_SHIFT,
+ memblock_x86_reserve_range(kva_start_pfn<<PAGE_SHIFT,
(kva_start_pfn + kva_pages)<<PAGE_SHIFT,
"KVA PG");
#ifdef CONFIG_HIGHMEM
@@ -419,9 +418,6 @@ void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn,
for_each_online_node(nid) {
memset(NODE_DATA(nid), 0, sizeof(struct pglist_data));
NODE_DATA(nid)->node_id = nid;
-#ifndef CONFIG_NO_BOOTMEM
- NODE_DATA(nid)->bdata = &bootmem_node_data[nid];
-#endif
}
setup_bootmem_allocator();
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c
index a7bcc23ef96c..60f498511dd6 100644
--- a/arch/x86/mm/numa_64.c
+++ b/arch/x86/mm/numa_64.c
@@ -7,6 +7,7 @@
#include <linux/string.h>
#include <linux/init.h>
#include <linux/bootmem.h>
+#include <linux/memblock.h>
#include <linux/mmzone.h>
#include <linux/ctype.h>
#include <linux/module.h>
@@ -18,7 +19,7 @@
#include <asm/dma.h>
#include <asm/numa.h>
#include <asm/acpi.h>
-#include <asm/k8.h>
+#include <asm/amd_nb.h>
struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
EXPORT_SYMBOL(node_data);
@@ -86,16 +87,16 @@ static int __init allocate_cachealigned_memnodemap(void)
addr = 0x8000;
nodemap_size = roundup(sizeof(s16) * memnodemapsize, L1_CACHE_BYTES);
- nodemap_addr = find_e820_area(addr, max_pfn<<PAGE_SHIFT,
+ nodemap_addr = memblock_find_in_range(addr, max_pfn<<PAGE_SHIFT,
nodemap_size, L1_CACHE_BYTES);
- if (nodemap_addr == -1UL) {
+ if (nodemap_addr == MEMBLOCK_ERROR) {
printk(KERN_ERR
"NUMA: Unable to allocate Memory to Node hash map\n");
nodemap_addr = nodemap_size = 0;
return -1;
}
memnodemap = phys_to_virt(nodemap_addr);
- reserve_early(nodemap_addr, nodemap_addr + nodemap_size, "MEMNODEMAP");
+ memblock_x86_reserve_range(nodemap_addr, nodemap_addr + nodemap_size, "MEMNODEMAP");
printk(KERN_DEBUG "NUMA: Allocated memnodemap from %lx - %lx\n",
nodemap_addr, nodemap_addr + nodemap_size);
@@ -171,8 +172,8 @@ static void * __init early_node_mem(int nodeid, unsigned long start,
if (start < (MAX_DMA32_PFN<<PAGE_SHIFT) &&
end > (MAX_DMA32_PFN<<PAGE_SHIFT))
start = MAX_DMA32_PFN<<PAGE_SHIFT;
- mem = find_e820_area(start, end, size, align);
- if (mem != -1L)
+ mem = memblock_x86_find_in_range_node(nodeid, start, end, size, align);
+ if (mem != MEMBLOCK_ERROR)
return __va(mem);
/* extend the search scope */
@@ -181,8 +182,8 @@ static void * __init early_node_mem(int nodeid, unsigned long start,
start = MAX_DMA32_PFN<<PAGE_SHIFT;
else
start = MAX_DMA_PFN<<PAGE_SHIFT;
- mem = find_e820_area(start, end, size, align);
- if (mem != -1L)
+ mem = memblock_x86_find_in_range_node(nodeid, start, end, size, align);
+ if (mem != MEMBLOCK_ERROR)
return __va(mem);
printk(KERN_ERR "Cannot find %lu bytes in node %d\n",
@@ -198,10 +199,6 @@ setup_node_bootmem(int nodeid, unsigned long start, unsigned long end)
unsigned long start_pfn, last_pfn, nodedata_phys;
const int pgdat_size = roundup(sizeof(pg_data_t), PAGE_SIZE);
int nid;
-#ifndef CONFIG_NO_BOOTMEM
- unsigned long bootmap_start, bootmap_pages, bootmap_size;
- void *bootmap;
-#endif
if (!end)
return;
@@ -226,7 +223,7 @@ setup_node_bootmem(int nodeid, unsigned long start, unsigned long end)
if (node_data[nodeid] == NULL)
return;
nodedata_phys = __pa(node_data[nodeid]);
- reserve_early(nodedata_phys, nodedata_phys + pgdat_size, "NODE_DATA");
+ memblock_x86_reserve_range(nodedata_phys, nodedata_phys + pgdat_size, "NODE_DATA");
printk(KERN_INFO " NODE_DATA [%016lx - %016lx]\n", nodedata_phys,
nodedata_phys + pgdat_size - 1);
nid = phys_to_nid(nodedata_phys);
@@ -238,47 +235,6 @@ setup_node_bootmem(int nodeid, unsigned long start, unsigned long end)
NODE_DATA(nodeid)->node_start_pfn = start_pfn;
NODE_DATA(nodeid)->node_spanned_pages = last_pfn - start_pfn;
-#ifndef CONFIG_NO_BOOTMEM
- NODE_DATA(nodeid)->bdata = &bootmem_node_data[nodeid];
-
- /*
- * Find a place for the bootmem map
- * nodedata_phys could be on other nodes by alloc_bootmem,
- * so need to sure bootmap_start not to be small, otherwise
- * early_node_mem will get that with find_e820_area instead
- * of alloc_bootmem, that could clash with reserved range
- */
- bootmap_pages = bootmem_bootmap_pages(last_pfn - start_pfn);
- bootmap_start = roundup(nodedata_phys + pgdat_size, PAGE_SIZE);
- /*
- * SMP_CACHE_BYTES could be enough, but init_bootmem_node like
- * to use that to align to PAGE_SIZE
- */
- bootmap = early_node_mem(nodeid, bootmap_start, end,
- bootmap_pages<<PAGE_SHIFT, PAGE_SIZE);
- if (bootmap == NULL) {
- free_early(nodedata_phys, nodedata_phys + pgdat_size);
- node_data[nodeid] = NULL;
- return;
- }
- bootmap_start = __pa(bootmap);
- reserve_early(bootmap_start, bootmap_start+(bootmap_pages<<PAGE_SHIFT),
- "BOOTMAP");
-
- bootmap_size = init_bootmem_node(NODE_DATA(nodeid),
- bootmap_start >> PAGE_SHIFT,
- start_pfn, last_pfn);
-
- printk(KERN_INFO " bootmap [%016lx - %016lx] pages %lx\n",
- bootmap_start, bootmap_start + bootmap_size - 1,
- bootmap_pages);
- nid = phys_to_nid(bootmap_start);
- if (nid != nodeid)
- printk(KERN_INFO " bootmap(%d) on node %d\n", nodeid, nid);
-
- free_bootmem_with_active_regions(nodeid, end);
-#endif
-
node_set_online(nodeid);
}
@@ -416,7 +372,7 @@ static int __init split_nodes_interleave(u64 addr, u64 max_addr,
nr_nodes = MAX_NUMNODES;
}
- size = (max_addr - addr - e820_hole_size(addr, max_addr)) / nr_nodes;
+ size = (max_addr - addr - memblock_x86_hole_size(addr, max_addr)) / nr_nodes;
/*
* Calculate the number of big nodes that can be allocated as a result
* of consolidating the remainder.
@@ -452,7 +408,7 @@ static int __init split_nodes_interleave(u64 addr, u64 max_addr,
* non-reserved memory is less than the per-node size.
*/
while (end - physnodes[i].start -
- e820_hole_size(physnodes[i].start, end) < size) {
+ memblock_x86_hole_size(physnodes[i].start, end) < size) {
end += FAKE_NODE_MIN_SIZE;
if (end > physnodes[i].end) {
end = physnodes[i].end;
@@ -466,7 +422,7 @@ static int __init split_nodes_interleave(u64 addr, u64 max_addr,
* this one must extend to the boundary.
*/
if (end < dma32_end && dma32_end - end -
- e820_hole_size(end, dma32_end) < FAKE_NODE_MIN_SIZE)
+ memblock_x86_hole_size(end, dma32_end) < FAKE_NODE_MIN_SIZE)
end = dma32_end;
/*
@@ -475,7 +431,7 @@ static int __init split_nodes_interleave(u64 addr, u64 max_addr,
* physical node.
*/
if (physnodes[i].end - end -
- e820_hole_size(end, physnodes[i].end) < size)
+ memblock_x86_hole_size(end, physnodes[i].end) < size)
end = physnodes[i].end;
/*
@@ -503,7 +459,7 @@ static u64 __init find_end_of_node(u64 start, u64 max_addr, u64 size)
{
u64 end = start + size;
- while (end - start - e820_hole_size(start, end) < size) {
+ while (end - start - memblock_x86_hole_size(start, end) < size) {
end += FAKE_NODE_MIN_SIZE;
if (end > max_addr) {
end = max_addr;
@@ -532,7 +488,7 @@ static int __init split_nodes_size_interleave(u64 addr, u64 max_addr, u64 size)
* creates a uniform distribution of node sizes across the entire
* machine (but not necessarily over physical nodes).
*/
- min_size = (max_addr - addr - e820_hole_size(addr, max_addr)) /
+ min_size = (max_addr - addr - memblock_x86_hole_size(addr, max_addr)) /
MAX_NUMNODES;
min_size = max(min_size, FAKE_NODE_MIN_SIZE);
if ((min_size & FAKE_NODE_MIN_HASH_MASK) < min_size)
@@ -565,7 +521,7 @@ static int __init split_nodes_size_interleave(u64 addr, u64 max_addr, u64 size)
* this one must extend to the boundary.
*/
if (end < dma32_end && dma32_end - end -
- e820_hole_size(end, dma32_end) < FAKE_NODE_MIN_SIZE)
+ memblock_x86_hole_size(end, dma32_end) < FAKE_NODE_MIN_SIZE)
end = dma32_end;
/*
@@ -574,7 +530,7 @@ static int __init split_nodes_size_interleave(u64 addr, u64 max_addr, u64 size)
* physical node.
*/
if (physnodes[i].end - end -
- e820_hole_size(end, physnodes[i].end) < size)
+ memblock_x86_hole_size(end, physnodes[i].end) < size)
end = physnodes[i].end;
/*
@@ -638,7 +594,7 @@ static int __init numa_emulation(unsigned long start_pfn,
*/
remove_all_active_ranges();
for_each_node_mask(i, node_possible_map) {
- e820_register_active_regions(i, nodes[i].start >> PAGE_SHIFT,
+ memblock_x86_register_active_regions(i, nodes[i].start >> PAGE_SHIFT,
nodes[i].end >> PAGE_SHIFT);
setup_node_bootmem(i, nodes[i].start, nodes[i].end);
}
@@ -691,7 +647,7 @@ void __init initmem_init(unsigned long start_pfn, unsigned long last_pfn,
node_set(0, node_possible_map);
for (i = 0; i < nr_cpu_ids; i++)
numa_set_node(i, 0);
- e820_register_active_regions(0, start_pfn, last_pfn);
+ memblock_x86_register_active_regions(0, start_pfn, last_pfn);
setup_node_bootmem(0, start_pfn << PAGE_SHIFT, last_pfn << PAGE_SHIFT);
}
@@ -703,9 +659,7 @@ unsigned long __init numa_free_all_bootmem(void)
for_each_online_node(i)
pages += free_all_bootmem_node(NODE_DATA(i));
-#ifdef CONFIG_NO_BOOTMEM
pages += free_all_memory_core_early(MAX_NUMNODES);
-#endif
return pages;
}
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
index 5c4ee422590e..8be8c7d7bc89 100644
--- a/arch/x86/mm/pgtable.c
+++ b/arch/x86/mm/pgtable.c
@@ -87,7 +87,19 @@ static inline void pgd_list_del(pgd_t *pgd)
#define UNSHARED_PTRS_PER_PGD \
(SHARED_KERNEL_PMD ? KERNEL_PGD_BOUNDARY : PTRS_PER_PGD)
-static void pgd_ctor(pgd_t *pgd)
+
+static void pgd_set_mm(pgd_t *pgd, struct mm_struct *mm)
+{
+ BUILD_BUG_ON(sizeof(virt_to_page(pgd)->index) < sizeof(mm));
+ virt_to_page(pgd)->index = (pgoff_t)mm;
+}
+
+struct mm_struct *pgd_page_get_mm(struct page *page)
+{
+ return (struct mm_struct *)page->index;
+}
+
+static void pgd_ctor(struct mm_struct *mm, pgd_t *pgd)
{
/* If the pgd points to a shared pagetable level (either the
ptes in non-PAE, or shared PMD in PAE), then just copy the
@@ -98,15 +110,13 @@ static void pgd_ctor(pgd_t *pgd)
clone_pgd_range(pgd + KERNEL_PGD_BOUNDARY,
swapper_pg_dir + KERNEL_PGD_BOUNDARY,
KERNEL_PGD_PTRS);
- paravirt_alloc_pmd_clone(__pa(pgd) >> PAGE_SHIFT,
- __pa(swapper_pg_dir) >> PAGE_SHIFT,
- KERNEL_PGD_BOUNDARY,
- KERNEL_PGD_PTRS);
}
/* list required to sync kernel mapping updates */
- if (!SHARED_KERNEL_PMD)
+ if (!SHARED_KERNEL_PMD) {
+ pgd_set_mm(pgd, mm);
pgd_list_add(pgd);
+ }
}
static void pgd_dtor(pgd_t *pgd)
@@ -272,7 +282,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
*/
spin_lock_irqsave(&pgd_lock, flags);
- pgd_ctor(pgd);
+ pgd_ctor(mm, pgd);
pgd_prepopulate_pmd(mm, pgd, pmds);
spin_unlock_irqrestore(&pgd_lock, flags);
diff --git a/arch/x86/mm/srat_32.c b/arch/x86/mm/srat_32.c
index 9324f13492d5..a17dffd136c1 100644
--- a/arch/x86/mm/srat_32.c
+++ b/arch/x86/mm/srat_32.c
@@ -25,6 +25,7 @@
*/
#include <linux/mm.h>
#include <linux/bootmem.h>
+#include <linux/memblock.h>
#include <linux/mmzone.h>
#include <linux/acpi.h>
#include <linux/nodemask.h>
@@ -264,7 +265,7 @@ int __init get_memcfg_from_srat(void)
if (node_read_chunk(chunk->nid, chunk))
continue;
- e820_register_active_regions(chunk->nid, chunk->start_pfn,
+ memblock_x86_register_active_regions(chunk->nid, chunk->start_pfn,
min(chunk->end_pfn, max_pfn));
}
/* for out of order entries in SRAT */
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c
index f9897f7a9ef1..a35cb9d8b060 100644
--- a/arch/x86/mm/srat_64.c
+++ b/arch/x86/mm/srat_64.c
@@ -16,6 +16,7 @@
#include <linux/module.h>
#include <linux/topology.h>
#include <linux/bootmem.h>
+#include <linux/memblock.h>
#include <linux/mm.h>
#include <asm/proto.h>
#include <asm/numa.h>
@@ -98,15 +99,15 @@ void __init acpi_numa_slit_init(struct acpi_table_slit *slit)
unsigned long phys;
length = slit->header.length;
- phys = find_e820_area(0, max_pfn_mapped<<PAGE_SHIFT, length,
+ phys = memblock_find_in_range(0, max_pfn_mapped<<PAGE_SHIFT, length,
PAGE_SIZE);
- if (phys == -1L)
+ if (phys == MEMBLOCK_ERROR)
panic(" Can not save slit!\n");
acpi_slit = __va(phys);
memcpy(acpi_slit, slit, length);
- reserve_early(phys, phys + length, "ACPI SLIT");
+ memblock_x86_reserve_range(phys, phys + length, "ACPI SLIT");
}
/* Callback for Proximity Domain -> x2APIC mapping */
@@ -324,7 +325,7 @@ static int __init nodes_cover_memory(const struct bootnode *nodes)
pxmram = 0;
}
- e820ram = max_pfn - (e820_hole_size(0, max_pfn<<PAGE_SHIFT)>>PAGE_SHIFT);
+ e820ram = max_pfn - (memblock_x86_hole_size(0, max_pfn<<PAGE_SHIFT)>>PAGE_SHIFT);
/* We seem to lose 3 pages somewhere. Allow 1M of slack. */
if ((long)(e820ram - pxmram) >= (1<<(20 - PAGE_SHIFT))) {
printk(KERN_ERR
@@ -420,9 +421,11 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
return -1;
}
- for_each_node_mask(i, nodes_parsed)
- e820_register_active_regions(i, nodes[i].start >> PAGE_SHIFT,
- nodes[i].end >> PAGE_SHIFT);
+ for (i = 0; i < num_node_memblks; i++)
+ memblock_x86_register_active_regions(memblk_nodeid[i],
+ node_memblk_range[i].start >> PAGE_SHIFT,
+ node_memblk_range[i].end >> PAGE_SHIFT);
+
/* for out of order entries in SRAT */
sort_node_map();
if (!nodes_cover_memory(nodes)) {
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index c03f14ab6667..49358481c733 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -5,6 +5,7 @@
#include <linux/smp.h>
#include <linux/interrupt.h>
#include <linux/module.h>
+#include <linux/cpu.h>
#include <asm/tlbflush.h>
#include <asm/mmu_context.h>
@@ -52,6 +53,8 @@ union smp_flush_state {
want false sharing in the per cpu data segment. */
static union smp_flush_state flush_state[NUM_INVALIDATE_TLB_VECTORS];
+static DEFINE_PER_CPU_READ_MOSTLY(int, tlb_vector_offset);
+
/*
* We cannot call mmdrop() because we are in interrupt context,
* instead update mm->cpu_vm_mask.
@@ -173,7 +176,7 @@ static void flush_tlb_others_ipi(const struct cpumask *cpumask,
union smp_flush_state *f;
/* Caller has disabled preemption */
- sender = smp_processor_id() % NUM_INVALIDATE_TLB_VECTORS;
+ sender = this_cpu_read(tlb_vector_offset);
f = &flush_state[sender];
/*
@@ -218,6 +221,47 @@ void native_flush_tlb_others(const struct cpumask *cpumask,
flush_tlb_others_ipi(cpumask, mm, va);
}
+static void __cpuinit calculate_tlb_offset(void)
+{
+ int cpu, node, nr_node_vecs;
+ /*
+ * we are changing tlb_vector_offset for each CPU in runtime, but this
+ * will not cause inconsistency, as the write is atomic under X86. we
+ * might see more lock contentions in a short time, but after all CPU's
+ * tlb_vector_offset are changed, everything should go normal
+ *
+ * Note: if NUM_INVALIDATE_TLB_VECTORS % nr_online_nodes !=0, we might
+ * waste some vectors.
+ **/
+ if (nr_online_nodes > NUM_INVALIDATE_TLB_VECTORS)
+ nr_node_vecs = 1;
+ else
+ nr_node_vecs = NUM_INVALIDATE_TLB_VECTORS/nr_online_nodes;
+
+ for_each_online_node(node) {
+ int node_offset = (node % NUM_INVALIDATE_TLB_VECTORS) *
+ nr_node_vecs;
+ int cpu_offset = 0;
+ for_each_cpu(cpu, cpumask_of_node(node)) {
+ per_cpu(tlb_vector_offset, cpu) = node_offset +
+ cpu_offset;
+ cpu_offset++;
+ cpu_offset = cpu_offset % nr_node_vecs;
+ }
+ }
+}
+
+static int tlb_cpuhp_notify(struct notifier_block *n,
+ unsigned long action, void *hcpu)
+{
+ switch (action & 0xf) {
+ case CPU_ONLINE:
+ case CPU_DEAD:
+ calculate_tlb_offset();
+ }
+ return NOTIFY_OK;
+}
+
static int __cpuinit init_smp_flush(void)
{
int i;
@@ -225,6 +269,8 @@ static int __cpuinit init_smp_flush(void)
for (i = 0; i < ARRAY_SIZE(flush_state); i++)
raw_spin_lock_init(&flush_state[i].tlbstate_lock);
+ calculate_tlb_offset();
+ hotcpu_notifier(tlb_cpuhp_notify, 0);
return 0;
}
core_initcall(init_smp_flush);
diff --git a/arch/x86/oprofile/backtrace.c b/arch/x86/oprofile/backtrace.c
index 3855096c59b8..2d49d4e19a36 100644
--- a/arch/x86/oprofile/backtrace.c
+++ b/arch/x86/oprofile/backtrace.c
@@ -14,6 +14,7 @@
#include <asm/ptrace.h>
#include <asm/uaccess.h>
#include <asm/stacktrace.h>
+#include <linux/compat.h>
static void backtrace_warning_symbol(void *data, char *msg,
unsigned long symbol)
@@ -48,14 +49,12 @@ static struct stacktrace_ops backtrace_ops = {
.walk_stack = print_context_stack,
};
-struct frame_head {
- struct frame_head *bp;
- unsigned long ret;
-} __attribute__((packed));
-
-static struct frame_head *dump_user_backtrace(struct frame_head *head)
+#ifdef CONFIG_COMPAT
+static struct stack_frame_ia32 *
+dump_user_backtrace_32(struct stack_frame_ia32 *head)
{
- struct frame_head bufhead[2];
+ struct stack_frame_ia32 bufhead[2];
+ struct stack_frame_ia32 *fp;
/* Also check accessibility of one struct frame_head beyond */
if (!access_ok(VERIFY_READ, head, sizeof(bufhead)))
@@ -63,20 +62,66 @@ static struct frame_head *dump_user_backtrace(struct frame_head *head)
if (__copy_from_user_inatomic(bufhead, head, sizeof(bufhead)))
return NULL;
- oprofile_add_trace(bufhead[0].ret);
+ fp = (struct stack_frame_ia32 *) compat_ptr(bufhead[0].next_frame);
+
+ oprofile_add_trace(bufhead[0].return_address);
+
+ /* frame pointers should strictly progress back up the stack
+ * (towards higher addresses) */
+ if (head >= fp)
+ return NULL;
+
+ return fp;
+}
+
+static inline int
+x86_backtrace_32(struct pt_regs * const regs, unsigned int depth)
+{
+ struct stack_frame_ia32 *head;
+
+ /* User process is 32-bit */
+ if (!current || !test_thread_flag(TIF_IA32))
+ return 0;
+
+ head = (struct stack_frame_ia32 *) regs->bp;
+ while (depth-- && head)
+ head = dump_user_backtrace_32(head);
+
+ return 1;
+}
+
+#else
+static inline int
+x86_backtrace_32(struct pt_regs * const regs, unsigned int depth)
+{
+ return 0;
+}
+#endif /* CONFIG_COMPAT */
+
+static struct stack_frame *dump_user_backtrace(struct stack_frame *head)
+{
+ struct stack_frame bufhead[2];
+
+ /* Also check accessibility of one struct stack_frame beyond */
+ if (!access_ok(VERIFY_READ, head, sizeof(bufhead)))
+ return NULL;
+ if (__copy_from_user_inatomic(bufhead, head, sizeof(bufhead)))
+ return NULL;
+
+ oprofile_add_trace(bufhead[0].return_address);
/* frame pointers should strictly progress back up the stack
* (towards higher addresses) */
- if (head >= bufhead[0].bp)
+ if (head >= bufhead[0].next_frame)
return NULL;
- return bufhead[0].bp;
+ return bufhead[0].next_frame;
}
void
x86_backtrace(struct pt_regs * const regs, unsigned int depth)
{
- struct frame_head *head = (struct frame_head *)frame_pointer(regs);
+ struct stack_frame *head = (struct stack_frame *)frame_pointer(regs);
if (!user_mode_vm(regs)) {
unsigned long stack = kernel_stack_pointer(regs);
@@ -86,6 +131,9 @@ x86_backtrace(struct pt_regs * const regs, unsigned int depth)
return;
}
+ if (x86_backtrace_32(regs, depth))
+ return;
+
while (depth-- && head)
head = dump_user_backtrace(head);
}
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c
index 009b819f48d0..bd1489c3ce09 100644
--- a/arch/x86/oprofile/nmi_int.c
+++ b/arch/x86/oprofile/nmi_int.c
@@ -674,6 +674,7 @@ static int __init ppro_init(char **cpu_type)
case 0x0f:
case 0x16:
case 0x17:
+ case 0x1d:
*cpu_type = "i386/core_2";
break;
case 0x1a:
@@ -694,9 +695,6 @@ static int __init ppro_init(char **cpu_type)
return 1;
}
-/* in order to get sysfs right */
-static int using_nmi;
-
int __init op_nmi_init(struct oprofile_operations *ops)
{
__u8 vendor = boot_cpu_data.x86_vendor;
@@ -704,8 +702,6 @@ int __init op_nmi_init(struct oprofile_operations *ops)
char *cpu_type = NULL;
int ret = 0;
- using_nmi = 0;
-
if (!cpu_has_apic)
return -ENODEV;
@@ -789,13 +785,11 @@ int __init op_nmi_init(struct oprofile_operations *ops)
if (ret)
return ret;
- using_nmi = 1;
printk(KERN_INFO "oprofile: using NMI interrupt.\n");
return 0;
}
void op_nmi_exit(void)
{
- if (using_nmi)
- exit_sysfs();
+ exit_sysfs();
}
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c
index b67a6b5aa8d4..42fb46f83883 100644
--- a/arch/x86/oprofile/op_model_amd.c
+++ b/arch/x86/oprofile/op_model_amd.c
@@ -64,15 +64,22 @@ static u64 ibs_op_ctl;
* IBS cpuid feature detection
*/
-#define IBS_CPUID_FEATURES 0x8000001b
+#define IBS_CPUID_FEATURES 0x8000001b
/*
* Same bit mask as for IBS cpuid feature flags (Fn8000_001B_EAX), but
* bit 0 is used to indicate the existence of IBS.
*/
-#define IBS_CAPS_AVAIL (1LL<<0)
-#define IBS_CAPS_RDWROPCNT (1LL<<3)
-#define IBS_CAPS_OPCNT (1LL<<4)
+#define IBS_CAPS_AVAIL (1U<<0)
+#define IBS_CAPS_RDWROPCNT (1U<<3)
+#define IBS_CAPS_OPCNT (1U<<4)
+
+/*
+ * IBS APIC setup
+ */
+#define IBSCTL 0x1cc
+#define IBSCTL_LVT_OFFSET_VALID (1ULL<<8)
+#define IBSCTL_LVT_OFFSET_MASK 0x0F
/*
* IBS randomization macros
@@ -266,6 +273,74 @@ static void op_amd_stop_ibs(void)
wrmsrl(MSR_AMD64_IBSOPCTL, 0);
}
+static inline int eilvt_is_available(int offset)
+{
+ /* check if we may assign a vector */
+ return !setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_NMI, 1);
+}
+
+static inline int ibs_eilvt_valid(void)
+{
+ u64 val;
+ int offset;
+
+ rdmsrl(MSR_AMD64_IBSCTL, val);
+ if (!(val & IBSCTL_LVT_OFFSET_VALID)) {
+ pr_err(FW_BUG "cpu %d, invalid IBS "
+ "interrupt offset %d (MSR%08X=0x%016llx)",
+ smp_processor_id(), offset,
+ MSR_AMD64_IBSCTL, val);
+ return 0;
+ }
+
+ offset = val & IBSCTL_LVT_OFFSET_MASK;
+
+ if (eilvt_is_available(offset))
+ return !0;
+
+ pr_err(FW_BUG "cpu %d, IBS interrupt offset %d "
+ "not available (MSR%08X=0x%016llx)",
+ smp_processor_id(), offset,
+ MSR_AMD64_IBSCTL, val);
+
+ return 0;
+}
+
+static inline int get_ibs_offset(void)
+{
+ u64 val;
+
+ rdmsrl(MSR_AMD64_IBSCTL, val);
+ if (!(val & IBSCTL_LVT_OFFSET_VALID))
+ return -EINVAL;
+
+ return val & IBSCTL_LVT_OFFSET_MASK;
+}
+
+static void setup_APIC_ibs(void)
+{
+ int offset;
+
+ offset = get_ibs_offset();
+ if (offset < 0)
+ goto failed;
+
+ if (!setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_NMI, 0))
+ return;
+failed:
+ pr_warn("oprofile: IBS APIC setup failed on cpu #%d\n",
+ smp_processor_id());
+}
+
+static void clear_APIC_ibs(void)
+{
+ int offset;
+
+ offset = get_ibs_offset();
+ if (offset >= 0)
+ setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_FIX, 1);
+}
+
#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
static void op_mux_switch_ctrl(struct op_x86_model_spec const *model,
@@ -376,13 +451,13 @@ static void op_amd_setup_ctrs(struct op_x86_model_spec const *model,
}
if (ibs_caps)
- setup_APIC_eilvt_ibs(0, APIC_EILVT_MSG_NMI, 0);
+ setup_APIC_ibs();
}
static void op_amd_cpu_shutdown(void)
{
if (ibs_caps)
- setup_APIC_eilvt_ibs(0, APIC_EILVT_MSG_FIX, 1);
+ clear_APIC_ibs();
}
static int op_amd_check_ctrs(struct pt_regs * const regs,
@@ -445,16 +520,11 @@ static void op_amd_stop(struct op_msrs const * const msrs)
op_amd_stop_ibs();
}
-static int __init_ibs_nmi(void)
+static int setup_ibs_ctl(int ibs_eilvt_off)
{
-#define IBSCTL_LVTOFFSETVAL (1 << 8)
-#define IBSCTL 0x1cc
struct pci_dev *cpu_cfg;
int nodes;
u32 value = 0;
- u8 ibs_eilvt_off;
-
- ibs_eilvt_off = setup_APIC_eilvt_ibs(0, APIC_EILVT_MSG_FIX, 1);
nodes = 0;
cpu_cfg = NULL;
@@ -466,21 +536,60 @@ static int __init_ibs_nmi(void)
break;
++nodes;
pci_write_config_dword(cpu_cfg, IBSCTL, ibs_eilvt_off
- | IBSCTL_LVTOFFSETVAL);
+ | IBSCTL_LVT_OFFSET_VALID);
pci_read_config_dword(cpu_cfg, IBSCTL, &value);
- if (value != (ibs_eilvt_off | IBSCTL_LVTOFFSETVAL)) {
+ if (value != (ibs_eilvt_off | IBSCTL_LVT_OFFSET_VALID)) {
pci_dev_put(cpu_cfg);
printk(KERN_DEBUG "Failed to setup IBS LVT offset, "
- "IBSCTL = 0x%08x", value);
- return 1;
+ "IBSCTL = 0x%08x\n", value);
+ return -EINVAL;
}
} while (1);
if (!nodes) {
- printk(KERN_DEBUG "No CPU node configured for IBS");
- return 1;
+ printk(KERN_DEBUG "No CPU node configured for IBS\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int force_ibs_eilvt_setup(void)
+{
+ int i;
+ int ret;
+
+ /* find the next free available EILVT entry */
+ for (i = 1; i < 4; i++) {
+ if (!eilvt_is_available(i))
+ continue;
+ ret = setup_ibs_ctl(i);
+ if (ret)
+ return ret;
+ return 0;
}
+ printk(KERN_DEBUG "No EILVT entry available\n");
+
+ return -EBUSY;
+}
+
+static int __init_ibs_nmi(void)
+{
+ int ret;
+
+ if (ibs_eilvt_valid())
+ return 0;
+
+ ret = force_ibs_eilvt_setup();
+ if (ret)
+ return ret;
+
+ if (!ibs_eilvt_valid())
+ return -EFAULT;
+
+ pr_err(FW_BUG "workaround enabled for IBS LVT offset\n");
+
return 0;
}
diff --git a/arch/x86/pci/olpc.c b/arch/x86/pci/olpc.c
index b34815408f58..13700ec8e2e4 100644
--- a/arch/x86/pci/olpc.c
+++ b/arch/x86/pci/olpc.c
@@ -304,7 +304,7 @@ static struct pci_raw_ops pci_olpc_conf = {
int __init pci_olpc_init(void)
{
- printk(KERN_INFO "PCI: Using configuration type OLPC\n");
+ printk(KERN_INFO "PCI: Using configuration type OLPC XO-1\n");
raw_pci_ops = &pci_olpc_conf;
is_lx = is_geode_lx();
return 0;
diff --git a/arch/x86/xen/debugfs.c b/arch/x86/xen/debugfs.c
index 1304bcec8ee5..7c0fedd98ea0 100644
--- a/arch/x86/xen/debugfs.c
+++ b/arch/x86/xen/debugfs.c
@@ -106,6 +106,7 @@ static const struct file_operations u32_array_fops = {
.open = u32_array_open,
.release= xen_array_release,
.read = u32_array_read,
+ .llseek = no_llseek,
};
struct dentry *xen_debugfs_create_u32_array(const char *name, mode_t mode,
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 7d46c8441418..63b83ceebd1a 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -30,6 +30,7 @@
#include <linux/console.h>
#include <linux/pci.h>
#include <linux/gfp.h>
+#include <linux/memblock.h>
#include <xen/xen.h>
#include <xen/interface/xen.h>
@@ -1183,6 +1184,8 @@ asmlinkage void __init xen_start_kernel(void)
local_irq_disable();
early_boot_irqs_off();
+ memblock_init();
+
xen_raw_console_write("mapping kernel into physical memory\n");
pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages);
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 42086ac406af..f72d18c69221 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -45,6 +45,7 @@
#include <linux/vmalloc.h>
#include <linux/module.h>
#include <linux/gfp.h>
+#include <linux/memblock.h>
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
@@ -55,6 +56,7 @@
#include <asm/e820.h>
#include <asm/linkage.h>
#include <asm/page.h>
+#include <asm/init.h>
#include <asm/xen/hypercall.h>
#include <asm/xen/hypervisor.h>
@@ -359,7 +361,8 @@ void make_lowmem_page_readonly(void *vaddr)
unsigned int level;
pte = lookup_address(address, &level);
- BUG_ON(pte == NULL);
+ if (pte == NULL)
+ return; /* vaddr missing */
ptev = pte_wrprotect(*pte);
@@ -374,7 +377,8 @@ void make_lowmem_page_readwrite(void *vaddr)
unsigned int level;
pte = lookup_address(address, &level);
- BUG_ON(pte == NULL);
+ if (pte == NULL)
+ return; /* vaddr missing */
ptev = pte_mkwrite(*pte);
@@ -1508,13 +1512,25 @@ static void xen_pgd_free(struct mm_struct *mm, pgd_t *pgd)
#endif
}
-#ifdef CONFIG_X86_32
static __init pte_t mask_rw_pte(pte_t *ptep, pte_t pte)
{
+ unsigned long pfn = pte_pfn(pte);
+
+#ifdef CONFIG_X86_32
/* If there's an existing pte, then don't allow _PAGE_RW to be set */
if (pte_val_ma(*ptep) & _PAGE_PRESENT)
pte = __pte_ma(((pte_val_ma(*ptep) & _PAGE_RW) | ~_PAGE_RW) &
pte_val_ma(pte));
+#endif
+
+ /*
+ * If the new pfn is within the range of the newly allocated
+ * kernel pagetable, and it isn't being mapped into an
+ * early_ioremap fixmap slot, make sure it is RO.
+ */
+ if (!is_early_ioremap_ptep(ptep) &&
+ pfn >= e820_table_start && pfn < e820_table_end)
+ pte = pte_wrprotect(pte);
return pte;
}
@@ -1527,7 +1543,6 @@ static __init void xen_set_pte_init(pte_t *ptep, pte_t pte)
xen_set_pte(ptep, pte);
}
-#endif
static void pin_pagetable_pfn(unsigned cmd, unsigned long pfn)
{
@@ -1814,7 +1829,7 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
__xen_write_cr3(true, __pa(pgd));
xen_mc_issue(PARAVIRT_LAZY_CPU);
- reserve_early(__pa(xen_start_info->pt_base),
+ memblock_x86_reserve_range(__pa(xen_start_info->pt_base),
__pa(xen_start_info->pt_base +
xen_start_info->nr_pt_frames * PAGE_SIZE),
"XEN PAGETABLES");
@@ -1852,7 +1867,7 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE, PFN_DOWN(__pa(swapper_pg_dir)));
- reserve_early(__pa(xen_start_info->pt_base),
+ memblock_x86_reserve_range(__pa(xen_start_info->pt_base),
__pa(xen_start_info->pt_base +
xen_start_info->nr_pt_frames * PAGE_SIZE),
"XEN PAGETABLES");
@@ -1969,14 +1984,9 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
.alloc_pte = xen_alloc_pte_init,
.release_pte = xen_release_pte_init,
.alloc_pmd = xen_alloc_pmd_init,
- .alloc_pmd_clone = paravirt_nop,
.release_pmd = xen_release_pmd_init,
-#ifdef CONFIG_X86_64
- .set_pte = xen_set_pte,
-#else
.set_pte = xen_set_pte_init,
-#endif
.set_pte_at = xen_set_pte_at,
.set_pmd = xen_set_pmd_hyper,
diff --git a/arch/x86/xen/pci-swiotlb-xen.c b/arch/x86/xen/pci-swiotlb-xen.c
index a013ec9d0c54..22471001b74c 100644
--- a/arch/x86/xen/pci-swiotlb-xen.c
+++ b/arch/x86/xen/pci-swiotlb-xen.c
@@ -5,6 +5,7 @@
#include <asm/xen/hypervisor.h>
#include <xen/xen.h>
+#include <asm/iommu_table.h>
int xen_swiotlb __read_mostly;
@@ -56,3 +57,7 @@ void __init pci_xen_swiotlb_init(void)
dma_ops = &xen_swiotlb_dma_ops;
}
}
+IOMMU_INIT_FINISH(pci_xen_swiotlb_detect,
+ 0,
+ pci_xen_swiotlb_init,
+ 0);
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index 328b00305426..9729c903404b 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -8,6 +8,7 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/pm.h>
+#include <linux/memblock.h>
#include <asm/elf.h>
#include <asm/vdso.h>
@@ -129,7 +130,7 @@ char * __init xen_memory_setup(void)
* - xen_start_info
* See comment above "struct start_info" in <xen/interface/xen.h>
*/
- reserve_early(__pa(xen_start_info->mfn_list),
+ memblock_x86_reserve_range(__pa(xen_start_info->mfn_list),
__pa(xen_start_info->pt_base),
"XEN START INFO");
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c
index e0500646585d..23e061b9327b 100644
--- a/arch/x86/xen/spinlock.c
+++ b/arch/x86/xen/spinlock.c
@@ -224,7 +224,7 @@ static noinline int xen_spin_lock_slow(struct arch_spinlock *lock, bool irq_enab
goto out;
}
- flags = __raw_local_save_flags();
+ flags = arch_local_save_flags();
if (irq_enable) {
ADD_STATS(taken_slow_irqenable, 1);
raw_local_irq_enable();
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
index 1a5353a753fc..b2bb5aa3b054 100644
--- a/arch/x86/xen/time.c
+++ b/arch/x86/xen/time.c
@@ -489,8 +489,9 @@ static void xen_hvm_setup_cpu_clockevents(void)
__init void xen_hvm_init_time_ops(void)
{
/* vector callback is needed otherwise we cannot receive interrupts
- * on cpu > 0 */
- if (!xen_have_vector_callback && num_present_cpus() > 1)
+ * on cpu > 0 and at this point we don't know how many cpus are
+ * available */
+ if (!xen_have_vector_callback)
return;
if (!xen_feature(XENFEAT_hvm_safe_pvclock)) {
printk(KERN_INFO "Xen doesn't support pvclock on HVM,"
diff --git a/arch/xtensa/include/asm/irqflags.h b/arch/xtensa/include/asm/irqflags.h
new file mode 100644
index 000000000000..dae9a8bdcb17
--- /dev/null
+++ b/arch/xtensa/include/asm/irqflags.h
@@ -0,0 +1,58 @@
+/*
+ * Xtensa IRQ flags handling functions
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_IRQFLAGS_H
+#define _XTENSA_IRQFLAGS_H
+
+#include <linux/types.h>
+
+static inline unsigned long arch_local_save_flags(void)
+{
+ unsigned long flags;
+ asm volatile("rsr %0,"__stringify(PS) : "=a" (flags));
+ return flags;
+}
+
+static inline unsigned long arch_local_irq_save(void)
+{
+ unsigned long flags;
+ asm volatile("rsil %0, "__stringify(LOCKLEVEL)
+ : "=a" (flags) :: "memory");
+ return flags;
+}
+
+static inline void arch_local_irq_disable(void)
+{
+ arch_local_irq_save();
+}
+
+static inline void arch_local_irq_enable(void)
+{
+ unsigned long flags;
+ asm volatile("rsil %0, 0" : "=a" (flags) :: "memory");
+}
+
+static inline void arch_local_irq_restore(unsigned long flags)
+{
+ asm volatile("wsr %0, "__stringify(PS)" ; rsync"
+ :: "a" (flags) : "memory");
+}
+
+static inline bool arch_irqs_disabled_flags(unsigned long flags)
+{
+ return (flags & 0xf) != 0;
+}
+
+static inline bool arch_irqs_disabled(void)
+{
+ return arch_irqs_disabled_flags(arch_local_save_flags());
+}
+
+#endif /* _XTENSA_IRQFLAGS_H */
diff --git a/arch/xtensa/include/asm/system.h b/arch/xtensa/include/asm/system.h
index 62b1e8f3c13c..1e7e09ab6cd7 100644
--- a/arch/xtensa/include/asm/system.h
+++ b/arch/xtensa/include/asm/system.h
@@ -12,41 +12,10 @@
#define _XTENSA_SYSTEM_H
#include <linux/stringify.h>
+#include <linux/irqflags.h>
#include <asm/processor.h>
-/* interrupt control */
-
-#define local_save_flags(x) \
- __asm__ __volatile__ ("rsr %0,"__stringify(PS) : "=a" (x));
-#define local_irq_restore(x) do { \
- __asm__ __volatile__ ("wsr %0, "__stringify(PS)" ; rsync" \
- :: "a" (x) : "memory"); } while(0);
-#define local_irq_save(x) do { \
- __asm__ __volatile__ ("rsil %0, "__stringify(LOCKLEVEL) \
- : "=a" (x) :: "memory");} while(0);
-
-static inline void local_irq_disable(void)
-{
- unsigned long flags;
- __asm__ __volatile__ ("rsil %0, "__stringify(LOCKLEVEL)
- : "=a" (flags) :: "memory");
-}
-static inline void local_irq_enable(void)
-{
- unsigned long flags;
- __asm__ __volatile__ ("rsil %0, 0" : "=a" (flags) :: "memory");
-
-}
-
-static inline int irqs_disabled(void)
-{
- unsigned long flags;
- local_save_flags(flags);
- return flags & 0xf;
-}
-
-
#define smp_read_barrier_depends() do { } while(0)
#define read_barrier_depends() do { } while(0)
diff --git a/arch/xtensa/include/asm/uaccess.h b/arch/xtensa/include/asm/uaccess.h
index b8528426ab1f..5b0c18c1cce1 100644
--- a/arch/xtensa/include/asm/uaccess.h
+++ b/arch/xtensa/include/asm/uaccess.h
@@ -4,7 +4,7 @@
* User space memory access functions
*
* These routines provide basic accessing functions to the user memory
- * space for the kernel. This header file provides fuctions such as:
+ * space for the kernel. This header file provides functions such as:
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c
index c64a5d387de5..87508886cbbd 100644
--- a/arch/xtensa/kernel/irq.c
+++ b/arch/xtensa/kernel/irq.c
@@ -92,7 +92,7 @@ int show_interrupts(struct seq_file *p, void *v)
for_each_online_cpu(j)
seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
#endif
- seq_printf(p, " %14s", irq_desc[i].chip->typename);
+ seq_printf(p, " %14s", irq_desc[i].chip->name);
seq_printf(p, " %s", action->name);
for (action=action->next; action; action = action->next)