aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/Kconfig17
-rw-r--r--arch/alpha/Kconfig8
-rw-r--r--arch/alpha/include/asm/core_mcpcia.h2
-rw-r--r--arch/alpha/include/asm/core_t2.h54
-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/pgtable.h2
-rw-r--r--arch/alpha/include/asm/system.h28
-rw-r--r--arch/alpha/kernel/core_t2.c11
-rw-r--r--arch/alpha/kernel/machvec_impl.h3
-rw-r--r--arch/alpha/kernel/pci_iommu.c4
-rw-r--r--arch/alpha/kernel/perf_event.c128
-rw-r--r--arch/alpha/kernel/ptrace.c7
-rw-r--r--arch/alpha/kernel/time.c30
-rw-r--r--arch/arm/Kconfig101
-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/da8xx_omapl_defconfig3
-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_defconfig10
-rw-r--r--arch/arm/configs/n8x0_defconfig94
-rw-r--r--arch/arm/configs/omap2plus_defconfig (renamed from arch/arm/configs/omap3_defconfig)51
-rw-r--r--arch/arm/configs/omap_4430sdp_defconfig125
-rw-r--r--arch/arm/configs/omap_generic_2420_defconfig37
-rw-r--r--arch/arm/configs/pcontrol_g20_defconfig175
-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/cache-l2x0.h13
-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/highmem.h6
-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/kgdb.h5
-rw-r--r--arch/arm/include/asm/mach/arch.h9
-rw-r--r--arch/arm/include/asm/memblock.h7
-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/outercache.h24
-rw-r--r--arch/arm/include/asm/perf_event.h12
-rw-r--r--arch/arm/include/asm/pgtable.h40
-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/kgdb.c2
-rw-r--r--arch/arm/kernel/machine_kexec.c3
-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.c267
-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.S40
-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/Kconfig27
-rw-r--r--arch/arm/mach-at91/Makefile17
-rw-r--r--arch/arm/mach-at91/at91sam9260.c7
-rw-r--r--arch/arm/mach-at91/at91sam9261.c7
-rw-r--r--arch/arm/mach-at91/at91sam9263.c7
-rw-r--r--arch/arm/mach-at91/at91sam9_alt_reset.S48
-rw-r--r--arch/arm/mach-at91/at91sam9g45_devices.c165
-rw-r--r--arch/arm/mach-at91/at91sam9rl.c7
-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-pcontrol-g20.c322
-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.c30
-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/generic.h3
-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.h4
-rw-r--r--arch/arm/mach-at91/pm.c15
-rw-r--r--arch/arm/mach-at91/pm.h5
-rw-r--r--arch/arm/mach-at91/pm_slowclock.S1
-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/Kconfig76
-rw-r--r--arch/arm/mach-davinci/Makefile4
-rw-r--r--arch/arm/mach-davinci/aemif.c133
-rw-r--r--arch/arm/mach-davinci/board-da830-evm.c26
-rw-r--r--arch/arm/mach-davinci/board-da850-evm.c94
-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.c13
-rw-r--r--arch/arm/mach-davinci/board-dm644x-evm.c22
-rw-r--r--arch/arm/mach-davinci/board-dm646x-evm.c25
-rw-r--r--arch/arm/mach-davinci/board-mityomapl138.c422
-rw-r--r--arch/arm/mach-davinci/board-neuros-osd2.c9
-rw-r--r--arch/arm/mach-davinci/board-omapl138-hawk.c62
-rw-r--r--arch/arm/mach-davinci/board-sffsdr.c9
-rw-r--r--arch/arm/mach-davinci/board-tnetv107x-evm.c58
-rw-r--r--arch/arm/mach-davinci/clock.c75
-rw-r--r--arch/arm/mach-davinci/clock.h5
-rw-r--r--arch/arm/mach-davinci/cpufreq.c28
-rw-r--r--arch/arm/mach-davinci/da850.c76
-rw-r--r--arch/arm/mach-davinci/devices-da8xx.c70
-rw-r--r--arch/arm/mach-davinci/devices-tnetv107x.c50
-rw-r--r--arch/arm/mach-davinci/devices.c2
-rw-r--r--arch/arm/mach-davinci/dm365.c23
-rw-r--r--arch/arm/mach-davinci/dm644x.c23
-rw-r--r--arch/arm/mach-davinci/dm646x.c22
-rw-r--r--arch/arm/mach-davinci/dma.c8
-rw-r--r--arch/arm/mach-davinci/include/mach/aemif.h36
-rw-r--r--arch/arm/mach-davinci/include/mach/da8xx.h7
-rw-r--r--arch/arm/mach-davinci/include/mach/debug-macro.S46
-rw-r--r--arch/arm/mach-davinci/include/mach/dm365.h2
-rw-r--r--arch/arm/mach-davinci/include/mach/dm644x.h2
-rw-r--r--arch/arm/mach-davinci/include/mach/dm646x.h2
-rw-r--r--arch/arm/mach-davinci/include/mach/nand.h6
-rw-r--r--arch/arm/mach-davinci/include/mach/psc.h1
-rw-r--r--arch/arm/mach-davinci/include/mach/tnetv107x.h3
-rw-r--r--arch/arm/mach-davinci/include/mach/uncompress.h2
-rw-r--r--arch/arm/mach-davinci/tnetv107x.c11
-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/clock.c3
-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/Kconfig14
-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/include/mach/dma-v1.h8
-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.c48
-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/core.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.c159
-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/Kconfig60
-rw-r--r--arch/arm/mach-msm/Makefile21
-rw-r--r--arch/arm/mach-msm/board-halibut.c3
-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.S15
-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.c378
-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.c25
-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/Kconfig7
-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.c17
-rw-r--r--arch/arm/mach-mx3/Kconfig13
-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.c79
-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.c40
-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.c69
-rw-r--r--arch/arm/mach-mx3/mach-pcm037.c4
-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-mx3/mx31moboard-marxbot.c1
-rw-r--r--arch/arm/mach-mx3/mx31moboard-smartbot.c1
-rw-r--r--arch/arm/mach-mx5/Kconfig44
-rw-r--r--arch/arm/mach-mx5/Makefile4
-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.c119
-rw-r--r--arch/arm/mach-mx5/board-mx51_efikamx.c119
-rw-r--r--arch/arm/mach-mx5/clock-mx51.c413
-rw-r--r--arch/arm/mach-mx5/cpu.c19
-rw-r--r--arch/arm/mach-mx5/cpu_op-mx51.c29
-rw-r--r--arch/arm/mach-mx5/cpu_op-mx51.h14
-rw-r--r--arch/arm/mach-mx5/devices-imx51.h44
-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/Makefile2
-rw-r--r--arch/arm/mach-omap1/board-ams-delta.c71
-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-mmc.c3
-rw-r--r--arch/arm/mach-omap1/board-h2.c2
-rw-r--r--arch/arm/mach-omap1/board-h3-mmc.c3
-rw-r--r--arch/arm/mach-omap1/board-h3.c2
-rw-r--r--arch/arm/mach-omap1/board-htcherald.c323
-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-mmc.c3
-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/devices.c70
-rw-r--r--arch/arm/mach-omap1/include/mach/camera.h11
-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-omap1/pm_bus.c98
-rw-r--r--arch/arm/mach-omap2/Kconfig54
-rw-r--r--arch/arm/mach-omap2/Makefile32
-rw-r--r--arch/arm/mach-omap2/board-2430sdp.c5
-rw-r--r--arch/arm/mach-omap2/board-3430sdp.c14
-rw-r--r--arch/arm/mach-omap2/board-3630sdp.c5
-rw-r--r--arch/arm/mach-omap2/board-4430sdp.c96
-rw-r--r--arch/arm/mach-omap2/board-am3517evm.c70
-rw-r--r--arch/arm/mach-omap2/board-apollon.c4
-rw-r--r--arch/arm/mach-omap2/board-cm-t35.c11
-rw-r--r--arch/arm/mach-omap2/board-cm-t3517.c292
-rw-r--r--arch/arm/mach-omap2/board-devkit8000.c9
-rw-r--r--arch/arm/mach-omap2/board-flash.c3
-rw-r--r--arch/arm/mach-omap2/board-flash.h (renamed from arch/arm/mach-omap2/include/mach/board-flash.h)2
-rw-r--r--arch/arm/mach-omap2/board-generic.c18
-rw-r--r--arch/arm/mach-omap2/board-h4.c4
-rw-r--r--arch/arm/mach-omap2/board-igep0020.c371
-rw-r--r--arch/arm/mach-omap2/board-igep0030.c400
-rw-r--r--arch/arm/mach-omap2/board-ldp.c10
-rw-r--r--arch/arm/mach-omap2/board-n8x0.c71
-rw-r--r--arch/arm/mach-omap2/board-omap3beagle.c108
-rw-r--r--arch/arm/mach-omap2/board-omap3evm.c11
-rw-r--r--arch/arm/mach-omap2/board-omap3logic.c241
-rw-r--r--arch/arm/mach-omap2/board-omap3pandora.c57
-rw-r--r--arch/arm/mach-omap2/board-omap3stalker.c11
-rw-r--r--arch/arm/mach-omap2/board-omap3touchbook.c9
-rw-r--r--arch/arm/mach-omap2/board-omap4panda.c126
-rw-r--r--arch/arm/mach-omap2/board-overo.c7
-rw-r--r--arch/arm/mach-omap2/board-rx51-peripherals.c16
-rw-r--r--arch/arm/mach-omap2/board-rx51-sdram.c2
-rw-r--r--arch/arm/mach-omap2/board-rx51-video.c2
-rw-r--r--arch/arm/mach-omap2/board-rx51.c2
-rw-r--r--arch/arm/mach-omap2/board-zoom-debugboard.c2
-rw-r--r--arch/arm/mach-omap2/board-zoom-peripherals.c62
-rw-r--r--arch/arm/mach-omap2/board-zoom2.c3
-rw-r--r--arch/arm/mach-omap2/board-zoom3.c3
-rw-r--r--arch/arm/mach-omap2/clock.c2
-rw-r--r--arch/arm/mach-omap2/clock2420_data.c42
-rw-r--r--arch/arm/mach-omap2/clock2430_data.c66
-rw-r--r--arch/arm/mach-omap2/clock3xxx_data.c36
-rw-r--r--arch/arm/mach-omap2/clock44xx_data.c1312
-rw-r--r--arch/arm/mach-omap2/clockdomain.c110
-rw-r--r--arch/arm/mach-omap2/cm-regbits-34xx.h2
-rw-r--r--arch/arm/mach-omap2/cm-regbits-44xx.h1287
-rw-r--r--arch/arm/mach-omap2/cm44xx.h90
-rw-r--r--arch/arm/mach-omap2/cm4xxx.c9
-rw-r--r--arch/arm/mach-omap2/common.c135
-rw-r--r--arch/arm/mach-omap2/control.c33
-rw-r--r--arch/arm/mach-omap2/control.h (renamed from arch/arm/plat-omap/include/plat/control.h)49
-rw-r--r--arch/arm/mach-omap2/cpuidle34xx.c58
-rw-r--r--arch/arm/mach-omap2/devices.c198
-rw-r--r--arch/arm/mach-omap2/dsp.c85
-rw-r--r--arch/arm/mach-omap2/gpmc-smsc911x.c113
-rw-r--r--arch/arm/mach-omap2/hsmmc.c92
-rw-r--r--arch/arm/mach-omap2/hsmmc.h5
-rw-r--r--arch/arm/mach-omap2/id.c115
-rw-r--r--arch/arm/mach-omap2/include/mach/board-rx51.h11
-rw-r--r--arch/arm/mach-omap2/include/mach/board-zoom.h4
-rw-r--r--arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h391
-rw-r--r--arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h1409
-rw-r--r--arch/arm/mach-omap2/include/mach/ctrl_module_pad_wkup_44xx.h236
-rw-r--r--arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h92
-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/io.c8
-rw-r--r--arch/arm/mach-omap2/io.h7
-rw-r--r--arch/arm/mach-omap2/irq.c1
-rw-r--r--arch/arm/mach-omap2/mailbox.c8
-rw-r--r--arch/arm/mach-omap2/mcbsp.c105
-rw-r--r--arch/arm/mach-omap2/mux.c23
-rw-r--r--arch/arm/mach-omap2/mux.h2
-rw-r--r--arch/arm/mach-omap2/mux2420.c2
-rw-r--r--arch/arm/mach-omap2/mux2430.c2
-rw-r--r--arch/arm/mach-omap2/mux34xx.c12
-rw-r--r--arch/arm/mach-omap2/omap4-common.c23
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c599
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2420_data.c257
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2430_data.c257
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c319
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c850
-rw-r--r--arch/arm/mach-omap2/pm-debug.c44
-rw-r--r--arch/arm/mach-omap2/pm.c75
-rw-r--r--arch/arm/mach-omap2/pm.h11
-rw-r--r--arch/arm/mach-omap2/pm24xx.c4
-rw-r--r--arch/arm/mach-omap2/pm34xx.c126
-rw-r--r--arch/arm/mach-omap2/pm_bus.c85
-rw-r--r--arch/arm/mach-omap2/powerdomains44xx.h2
-rw-r--r--arch/arm/mach-omap2/prcm-common.h5
-rw-r--r--arch/arm/mach-omap2/prcm.c33
-rw-r--r--arch/arm/mach-omap2/prm-regbits-34xx.h1
-rw-r--r--arch/arm/mach-omap2/prm-regbits-44xx.h1314
-rw-r--r--arch/arm/mach-omap2/prm.h18
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.c110
-rw-r--r--arch/arm/mach-omap2/prm44xx.c116
-rw-r--r--arch/arm/mach-omap2/prm44xx.h14
-rw-r--r--arch/arm/mach-omap2/serial.c578
-rw-r--r--arch/arm/mach-omap2/sleep34xx.S2
-rw-r--r--arch/arm/mach-omap2/sram34xx.S6
-rw-r--r--arch/arm/mach-omap2/timer-gp.c8
-rw-r--r--arch/arm/mach-omap2/timer-gp.h (renamed from arch/arm/plat-omap/include/plat/timer-gp.h)3
-rw-r--r--arch/arm/mach-omap2/usb-fs.c6
-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.c7
-rw-r--r--arch/arm/mach-pxa/eseries.c19
-rw-r--r--arch/arm/mach-pxa/ezx.c24
-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.c5
-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/pcm990-baseboard.c2
-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/h1940-bluetooth.c13
-rw-r--r--arch/arm/mach-s3c2410/include/mach/debug-macro.S11
-rw-r--r--arch/arm/mach-s3c2410/include/mach/gpio.h10
-rw-r--r--arch/arm/mach-s3c2410/include/mach/h1940-latch.h57
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h2
-rw-r--r--arch/arm/mach-s3c2410/include/mach/vmalloc.h2
-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.c171
-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-s3c2412/s3c2412.c3
-rw-r--r--arch/arm/mach-s3c2416/Kconfig6
-rw-r--r--arch/arm/mach-s3c2416/Makefile2
-rw-r--r--arch/arm/mach-s3c2416/irq.c2
-rw-r--r--arch/arm/mach-s3c2416/mach-smdk2416.c2
-rw-r--r--arch/arm/mach-s3c2416/pm.c84
-rw-r--r--arch/arm/mach-s3c2416/s3c2416.c3
-rw-r--r--arch/arm/mach-s3c2440/Kconfig7
-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.c220
-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-s3c2440/s3c244x.c3
-rw-r--r--arch/arm/mach-s3c2443/mach-smdk2443.c2
-rw-r--r--arch/arm/mach-s3c2443/s3c2443.c3
-rw-r--r--arch/arm/mach-s3c24a0/include/mach/debug-macro.S11
-rw-r--r--arch/arm/mach-s3c24a0/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-s3c64xx/Kconfig22
-rw-r--r--arch/arm/mach-s3c64xx/Makefile1
-rw-r--r--arch/arm/mach-s3c64xx/dev-audio.c63
-rw-r--r--arch/arm/mach-s3c64xx/gpiolib.c8
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/debug-macro.S11
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/vmalloc.h2
-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-mini6410.c357
-rw-r--r--arch/arm/mach-s3c64xx/mach-ncp.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-real6410.c200
-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-s3c64xx/setup-fb-24bpp.c13
-rw-r--r--arch/arm/mach-s3c64xx/setup-ide.c11
-rw-r--r--arch/arm/mach-s3c64xx/setup-keypad.c16
-rw-r--r--arch/arm/mach-s3c64xx/setup-sdhci-gpio.c41
-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.c117
-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-s5p6440/setup-i2c0.c30
-rw-r--r--arch/arm/mach-s5p6440/setup-i2c1.c30
-rw-r--r--arch/arm/mach-s5p6442/Kconfig1
-rw-r--r--arch/arm/mach-s5p6442/clock.c28
-rw-r--r--arch/arm/mach-s5p6442/cpu.c27
-rw-r--r--arch/arm/mach-s5p6442/dev-audio.c30
-rw-r--r--arch/arm/mach-s5p6442/dev-spi.c6
-rw-r--r--arch/arm/mach-s5p6442/dma.c2
-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/include/mach/regs-clock.h1
-rw-r--r--arch/arm/mach-s5p6442/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-s5p6442/mach-smdk6442.c2
-rw-r--r--arch/arm/mach-s5p64x0/Kconfig55
-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.c629
-rw-r--r--arch/arm/mach-s5p64x0/clock-s5p6450.c658
-rw-r--r--arch/arm/mach-s5p64x0/clock.c235
-rw-r--r--arch/arm/mach-s5p64x0/cpu.c209
-rw-r--r--arch/arm/mach-s5p64x0/dev-audio.c152
-rw-r--r--arch/arm/mach-s5p64x0/dev-spi.c222
-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.h65
-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)7
-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.c38
-rw-r--r--arch/arm/mach-s5p64x0/setup-i2c1.c38
-rw-r--r--arch/arm/mach-s5pc100/Kconfig1
-rw-r--r--arch/arm/mach-s5pc100/Makefile2
-rw-r--r--arch/arm/mach-s5pc100/clock.c174
-rw-r--r--arch/arm/mach-s5pc100/cpu.c25
-rw-r--r--arch/arm/mach-s5pc100/dev-audio.c86
-rw-r--r--arch/arm/mach-s5pc100/dev-spi.c22
-rw-r--r--arch/arm/mach-s5pc100/dma.c4
-rw-r--r--arch/arm/mach-s5pc100/gpiolib.c216
-rw-r--r--arch/arm/mach-s5pc100/include/mach/debug-macro.S11
-rw-r--r--arch/arm/mach-s5pc100/include/mach/gpio.h7
-rw-r--r--arch/arm/mach-s5pc100/include/mach/irqs.h13
-rw-r--r--arch/arm/mach-s5pc100/include/mach/map.h13
-rw-r--r--arch/arm/mach-s5pc100/include/mach/regs-gpio.h49
-rw-r--r--arch/arm/mach-s5pc100/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-s5pc100/irq-gpio.c266
-rw-r--r--arch/arm/mach-s5pc100/mach-smdkc100.c6
-rw-r--r--arch/arm/mach-s5pc100/setup-fb-24bpp.c30
-rw-r--r--arch/arm/mach-s5pc100/setup-i2c0.c6
-rw-r--r--arch/arm/mach-s5pc100/setup-i2c1.c6
-rw-r--r--arch/arm/mach-s5pc100/setup-ide.c41
-rw-r--r--arch/arm/mach-s5pc100/setup-keypad.c15
-rw-r--r--arch/arm/mach-s5pc100/setup-sdhci-gpio.c35
-rw-r--r--arch/arm/mach-s5pv210/Kconfig46
-rw-r--r--arch/arm/mach-s5pv210/Makefile4
-rw-r--r--arch/arm/mach-s5pv210/clock.c207
-rw-r--r--arch/arm/mach-s5pv210/cpu.c37
-rw-r--r--arch/arm/mach-s5pv210/cpufreq.c484
-rw-r--r--arch/arm/mach-s5pv210/dev-audio.c86
-rw-r--r--arch/arm/mach-s5pv210/dev-spi.c19
-rw-r--r--arch/arm/mach-s5pv210/dma.c4
-rw-r--r--arch/arm/mach-s5pv210/gpiolib.c14
-rw-r--r--arch/arm/mach-s5pv210/include/mach/debug-macro.S11
-rw-r--r--arch/arm/mach-s5pv210/include/mach/irqs.h12
-rw-r--r--arch/arm/mach-s5pv210/include/mach/map.h23
-rw-r--r--arch/arm/mach-s5pv210/include/mach/pm-core.h43
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-clock.h39
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-gpio.h7
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-sys.h19
-rw-r--r--arch/arm/mach-s5pv210/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-s5pv210/mach-aquila.c173
-rw-r--r--arch/arm/mach-s5pv210/mach-goni.c385
-rw-r--r--arch/arm/mach-s5pv210/mach-smdkc110.c6
-rw-r--r--arch/arm/mach-s5pv210/mach-smdkv210.c6
-rw-r--r--arch/arm/mach-s5pv210/mach-torbreck.c131
-rw-r--r--arch/arm/mach-s5pv210/pm.c166
-rw-r--r--arch/arm/mach-s5pv210/setup-fb-24bpp.c34
-rw-r--r--arch/arm/mach-s5pv210/setup-i2c0.c6
-rw-r--r--arch/arm/mach-s5pv210/setup-i2c1.c6
-rw-r--r--arch/arm/mach-s5pv210/setup-i2c2.c6
-rw-r--r--arch/arm/mach-s5pv210/setup-ide.c49
-rw-r--r--arch/arm/mach-s5pv210/setup-keypad.c14
-rw-r--r--arch/arm/mach-s5pv210/setup-sdhci-gpio.c57
-rw-r--r--arch/arm/mach-s5pv210/sleep.S170
-rw-r--r--arch/arm/mach-s5pv310/Kconfig95
-rw-r--r--arch/arm/mach-s5pv310/Makefile10
-rw-r--r--arch/arm/mach-s5pv310/clock.c635
-rw-r--r--arch/arm/mach-s5pv310/cpu.c71
-rw-r--r--arch/arm/mach-s5pv310/gpiolib.c304
-rw-r--r--arch/arm/mach-s5pv310/hotplug.c144
-rw-r--r--arch/arm/mach-s5pv310/include/mach/debug-macro.S11
-rw-r--r--arch/arm/mach-s5pv310/include/mach/irqs.h46
-rw-r--r--arch/arm/mach-s5pv310/include/mach/map.h26
-rw-r--r--arch/arm/mach-s5pv310/include/mach/regs-clock.h32
-rw-r--r--arch/arm/mach-s5pv310/include/mach/regs-gpio.h42
-rw-r--r--arch/arm/mach-s5pv310/include/mach/regs-srom.h50
-rw-r--r--arch/arm/mach-s5pv310/include/mach/smp.h9
-rw-r--r--arch/arm/mach-s5pv310/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-s5pv310/irq-combiner.c6
-rw-r--r--arch/arm/mach-s5pv310/irq-eint.c228
-rw-r--r--arch/arm/mach-s5pv310/mach-smdkc210.c202
-rw-r--r--arch/arm/mach-s5pv310/mach-smdkv310.c123
-rw-r--r--arch/arm/mach-s5pv310/mach-universal_c210.c83
-rw-r--r--arch/arm/mach-s5pv310/setup-i2c0.c6
-rw-r--r--arch/arm/mach-s5pv310/setup-i2c1.c6
-rw-r--r--arch/arm/mach-s5pv310/setup-i2c2.c6
-rw-r--r--arch/arm/mach-s5pv310/setup-i2c3.c23
-rw-r--r--arch/arm/mach-s5pv310/setup-i2c4.c23
-rw-r--r--arch/arm/mach-s5pv310/setup-i2c5.c23
-rw-r--r--arch/arm/mach-s5pv310/setup-i2c6.c23
-rw-r--r--arch/arm/mach-s5pv310/setup-i2c7.c23
-rw-r--r--arch/arm/mach-s5pv310/setup-sdhci-gpio.c152
-rw-r--r--arch/arm/mach-s5pv310/setup-sdhci.c69
-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.c7
-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.c347
-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-shmobile/clock-sh7367.c2
-rw-r--r--arch/arm/mach-shmobile/clock-sh7372.c78
-rw-r--r--arch/arm/mach-shmobile/clock-sh7377.c2
-rw-r--r--arch/arm/mach-shmobile/include/mach/sh7372.h10
-rw-r--r--arch/arm/mach-shmobile/intc-sh7372.c28
-rw-r--r--arch/arm/mach-shmobile/pfc-sh7372.c8
-rw-r--r--arch/arm/mach-shmobile/setup-sh7367.c1
-rw-r--r--arch/arm/mach-shmobile/setup-sh7372.c94
-rw-r--r--arch/arm/mach-shmobile/setup-sh7377.c1
-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/Kconfig11
-rw-r--r--arch/arm/mach-tegra/Makefile9
-rw-r--r--arch/arm/mach-tegra/board-harmony-pcie.c57
-rw-r--r--arch/arm/mach-tegra/board-harmony.c2
-rw-r--r--arch/arm/mach-tegra/board.h1
-rw-r--r--arch/arm/mach-tegra/clock.c267
-rw-r--r--arch/arm/mach-tegra/clock.h58
-rw-r--r--arch/arm/mach-tegra/common.c13
-rw-r--r--arch/arm/mach-tegra/cpu-tegra.c185
-rw-r--r--arch/arm/mach-tegra/dma.c752
-rw-r--r--arch/arm/mach-tegra/fuse.c84
-rw-r--r--arch/arm/mach-tegra/fuse.h24
-rw-r--r--arch/arm/mach-tegra/gpio.c104
-rw-r--r--arch/arm/mach-tegra/include/mach/clk.h5
-rw-r--r--arch/arm/mach-tegra/include/mach/debug-macro.S26
-rw-r--r--arch/arm/mach-tegra/include/mach/dma.h155
-rw-r--r--arch/arm/mach-tegra/include/mach/gpio.h4
-rw-r--r--arch/arm/mach-tegra/include/mach/hardware.h4
-rw-r--r--arch/arm/mach-tegra/include/mach/io.h18
-rw-r--r--arch/arm/mach-tegra/include/mach/iomap.h33
-rw-r--r--arch/arm/mach-tegra/include/mach/irqs.h2
-rw-r--r--arch/arm/mach-tegra/include/mach/legacy_irq.h31
-rw-r--r--arch/arm/mach-tegra/include/mach/pinmux-t2.h174
-rw-r--r--arch/arm/mach-tegra/include/mach/pinmux.h210
-rw-r--r--arch/arm/mach-tegra/include/mach/smp.h10
-rw-r--r--arch/arm/mach-tegra/io.c6
-rw-r--r--arch/arm/mach-tegra/irq.c137
-rw-r--r--arch/arm/mach-tegra/legacy_irq.c114
-rw-r--r--arch/arm/mach-tegra/pcie.c915
-rw-r--r--arch/arm/mach-tegra/pinmux-t2-tables.c260
-rw-r--r--arch/arm/mach-tegra/pinmux.c354
-rw-r--r--arch/arm/mach-tegra/tegra2_clocks.c826
-rw-r--r--arch/arm/mach-tegra/tegra2_dvfs.c86
-rw-r--r--arch/arm/mach-tegra/tegra2_dvfs.h20
-rw-r--r--arch/arm/mach-tegra/timer.c1
-rw-r--r--arch/arm/mach-u300/clock.c6
-rw-r--r--arch/arm/mach-u300/core.c47
-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/include/mach/u300-regs.h2
-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/cpu.c45
-rw-r--r--arch/arm/mach-ux500/devices-db8500.c127
-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.c2
-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-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/Kconfig8
-rw-r--r--arch/arm/mm/cache-fa.S12
-rw-r--r--arch/arm/mm/cache-l2x0.c78
-rw-r--r--arch/arm/mm/cache-v3.S10
-rw-r--r--arch/arm/mm/cache-v4.S10
-rw-r--r--arch/arm/mm/cache-v4wb.S12
-rw-r--r--arch/arm/mm/cache-v4wt.S12
-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.c40
-rw-r--r--arch/arm/mm/fault.c13
-rw-r--r--arch/arm/mm/flush.c69
-rw-r--r--arch/arm/mm/highmem.c24
-rw-r--r--arch/arm/mm/init.c186
-rw-r--r--arch/arm/mm/mmap.c22
-rw-r--r--arch/arm/mm/mmu.c119
-rw-r--r--arch/arm/mm/pgd.c4
-rw-r--r--arch/arm/mm/proc-arm1020.S17
-rw-r--r--arch/arm/mm/proc-arm1020e.S17
-rw-r--r--arch/arm/mm/proc-arm1022.S17
-rw-r--r--arch/arm/mm/proc-arm1026.S17
-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.S14
-rw-r--r--arch/arm/mm/proc-arm922.S14
-rw-r--r--arch/arm/mm/proc-arm925.S14
-rw-r--r--arch/arm/mm/proc-arm926.S14
-rw-r--r--arch/arm/mm/proc-arm940.S14
-rw-r--r--arch/arm/mm/proc-arm946.S14
-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.S15
-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.S47
-rw-r--r--arch/arm/mm/proc-xsc3.S14
-rw-r--r--arch/arm/mm/proc-xscale.S14
-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.c311
-rw-r--r--arch/arm/plat-mxc/Kconfig16
-rw-r--r--arch/arm/plat-mxc/Makefile3
-rw-r--r--arch/arm/plat-mxc/audmux-v2.c9
-rw-r--r--arch/arm/plat-mxc/cpufreq.c206
-rw-r--r--arch/arm/plat-mxc/devices/Kconfig16
-rw-r--r--arch/arm/plat-mxc/devices/Makefile10
-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-gpio_keys.c27
-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.c34
-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.h116
-rw-r--r--arch/arm/plat-mxc/include/mach/dma.h67
-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.h122
-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.h12
-rw-r--r--arch/arm/plat-mxc/include/mach/mx35.h40
-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/mxc.h13
-rw-r--r--arch/arm/plat-mxc/include/mach/sdma.h17
-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-nomadik/include/plat/ste_dma40.h135
-rw-r--r--arch/arm/plat-omap/Kconfig2
-rw-r--r--arch/arm/plat-omap/Makefile4
-rw-r--r--arch/arm/plat-omap/clock.c5
-rw-r--r--arch/arm/plat-omap/common.c292
-rw-r--r--arch/arm/plat-omap/counter_32k.c183
-rw-r--r--arch/arm/plat-omap/cpu-omap.c4
-rw-r--r--arch/arm/plat-omap/devices.c32
-rw-r--r--arch/arm/plat-omap/dma.c50
-rw-r--r--arch/arm/plat-omap/dmtimer.c2
-rw-r--r--arch/arm/plat-omap/fb.c22
-rw-r--r--arch/arm/plat-omap/fb.h10
-rw-r--r--arch/arm/plat-omap/gpio.c10
-rw-r--r--arch/arm/plat-omap/include/plat/common.h5
-rw-r--r--arch/arm/plat-omap/include/plat/cpu.h41
-rw-r--r--arch/arm/plat-omap/include/plat/display.h31
-rw-r--r--arch/arm/plat-omap/include/plat/dma.h6
-rw-r--r--arch/arm/plat-omap/include/plat/dmtimer.h2
-rw-r--r--arch/arm/plat-omap/include/plat/dsp.h31
-rw-r--r--arch/arm/plat-omap/include/plat/gpmc-smsc911x.h35
-rw-r--r--arch/arm/plat-omap/include/plat/i2c.h4
-rw-r--r--arch/arm/plat-omap/include/plat/irqs.h2
-rw-r--r--arch/arm/plat-omap/include/plat/mcbsp.h22
-rw-r--r--arch/arm/plat-omap/include/plat/mmc.h12
-rw-r--r--arch/arm/plat-omap/include/plat/omap-serial.h128
-rw-r--r--arch/arm/plat-omap/include/plat/omap24xx.h2
-rw-r--r--arch/arm/plat-omap/include/plat/omap4-keypad.h14
-rw-r--r--arch/arm/plat-omap/include/plat/omap_device.h4
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h62
-rw-r--r--arch/arm/plat-omap/include/plat/powerdomain.h2
-rw-r--r--arch/arm/plat-omap/include/plat/prcm.h2
-rw-r--r--arch/arm/plat-omap/include/plat/sdrc.h1
-rw-r--r--arch/arm/plat-omap/include/plat/smp.h12
-rw-r--r--arch/arm/plat-omap/include/plat/sram.h1
-rw-r--r--arch/arm/plat-omap/include/plat/uncompress.h5
-rw-r--r--arch/arm/plat-omap/include/plat/usb.h23
-rw-r--r--arch/arm/plat-omap/include/plat/vrfb.h16
-rw-r--r--arch/arm/plat-omap/iommu-debug.c2
-rw-r--r--arch/arm/plat-omap/mcbsp.c26
-rw-r--r--arch/arm/plat-omap/omap_device.c110
-rw-r--r--arch/arm/plat-omap/sram.c37
-rw-r--r--arch/arm/plat-omap/sram.h6
-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-pxa/include/plat/pxa3xx_nand.h18
-rw-r--r--arch/arm/plat-pxa/include/plat/sdhci.h32
-rw-r--r--arch/arm/plat-s3c24xx/Kconfig1
-rw-r--r--arch/arm/plat-s3c24xx/common-smdk.c2
-rw-r--r--arch/arm/plat-s3c24xx/gpiolib.c10
-rw-r--r--arch/arm/plat-s5p/Kconfig14
-rw-r--r--arch/arm/plat-s5p/Makefile4
-rw-r--r--arch/arm/plat-s5p/clock.c48
-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/irqs.h18
-rw-r--r--arch/arm/plat-s5p/include/plat/map-s5p.h40
-rw-r--r--arch/arm/plat-s5p/include/plat/pll.h7
-rw-r--r--arch/arm/plat-s5p/include/plat/s5p-clock.h12
-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-s5p/irq-eint.c10
-rw-r--r--arch/arm/plat-s5p/irq-gpioint.c237
-rw-r--r--arch/arm/plat-s5p/irq-pm.c93
-rw-r--r--arch/arm/plat-s5p/pm.c52
-rw-r--r--arch/arm/plat-samsung/Kconfig25
-rw-r--r--arch/arm/plat-samsung/Makefile5
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc.c8
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc1.c8
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc2.c8
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc3.c12
-rw-r--r--arch/arm/plat-samsung/dev-i2c2.c4
-rw-r--r--arch/arm/plat-samsung/dev-i2c3.c68
-rw-r--r--arch/arm/plat-samsung/dev-i2c4.c68
-rw-r--r--arch/arm/plat-samsung/dev-i2c5.c68
-rw-r--r--arch/arm/plat-samsung/dev-i2c6.c68
-rw-r--r--arch/arm/plat-samsung/dev-i2c7.c68
-rw-r--r--arch/arm/plat-samsung/gpio-config.c50
-rw-r--r--arch/arm/plat-samsung/gpio.c8
-rw-r--r--arch/arm/plat-samsung/include/plat/adc.h2
-rw-r--r--arch/arm/plat-samsung/include/plat/audio.h9
-rw-r--r--arch/arm/plat-samsung/include/plat/cpu.h2
-rw-r--r--arch/arm/plat-samsung/include/plat/devs.h14
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h6
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-cfg.h56
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-core.h15
-rw-r--r--arch/arm/plat-samsung/include/plat/iic.h10
-rw-r--r--arch/arm/plat-samsung/include/plat/map-base.h4
-rw-r--r--arch/arm/plat-samsung/include/plat/nand-core.h28
-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-samsung/include/plat/sdhci.h64
-rw-r--r--arch/arm/plat-samsung/pm-gpio.c4
-rw-r--r--arch/arm/plat-samsung/s3c-pl330.c34
-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/Kconfig10
-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/include/asm/pgtable.h2
-rw-r--r--arch/avr32/kernel/ptrace.c11
-rw-r--r--arch/blackfin/Kconfig19
-rw-r--r--arch/blackfin/Kconfig.debug11
-rw-r--r--arch/blackfin/Makefile3
-rw-r--r--arch/blackfin/configs/BF518F-EZBRD_defconfig2
-rw-r--r--arch/blackfin/configs/BF526-EZBRD_defconfig2
-rw-r--r--arch/blackfin/configs/BF527-AD7160-EVAL_defconfig105
-rw-r--r--arch/blackfin/configs/BF527-EZKIT-V2_defconfig3
-rw-r--r--arch/blackfin/configs/BF527-EZKIT_defconfig3
-rw-r--r--arch/blackfin/configs/BF527-TLL6527M_defconfig179
-rw-r--r--arch/blackfin/configs/BF533-EZKIT_defconfig2
-rw-r--r--arch/blackfin/configs/BF533-STAMP_defconfig2
-rw-r--r--arch/blackfin/configs/BF537-STAMP_defconfig3
-rw-r--r--arch/blackfin/configs/BF538-EZKIT_defconfig3
-rw-r--r--arch/blackfin/configs/BF548-EZKIT_defconfig4
-rw-r--r--arch/blackfin/configs/BF561-ACVILON_defconfig4
-rw-r--r--arch/blackfin/configs/BF561-EZKIT_defconfig1
-rw-r--r--arch/blackfin/configs/BlackStamp_defconfig3
-rw-r--r--arch/blackfin/configs/CM-BF527_defconfig4
-rw-r--r--arch/blackfin/configs/CM-BF533_defconfig3
-rw-r--r--arch/blackfin/configs/CM-BF537E_defconfig3
-rw-r--r--arch/blackfin/configs/CM-BF537U_defconfig3
-rw-r--r--arch/blackfin/configs/CM-BF548_defconfig3
-rw-r--r--arch/blackfin/configs/CM-BF561_defconfig3
-rw-r--r--arch/blackfin/configs/H8606_defconfig3
-rw-r--r--arch/blackfin/configs/IP0X_defconfig3
-rw-r--r--arch/blackfin/configs/PNAV-10_defconfig2
-rw-r--r--arch/blackfin/configs/SRV1_defconfig3
-rw-r--r--arch/blackfin/configs/TCM-BF518_defconfig1
-rw-r--r--arch/blackfin/configs/TCM-BF537_defconfig2
-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.h53
-rw-r--r--arch/blackfin/include/asm/bfin_twi.h45
-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/entry.h8
-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.c3
-rw-r--r--arch/blackfin/kernel/kgdb_test.c1
-rw-r--r--arch/blackfin/kernel/process.c9
-rw-r--r--arch/blackfin/kernel/ptrace.c28
-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.c65
-rw-r--r--arch/blackfin/mach-bf518/boards/tcm-bf518.c26
-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.c36
-rw-r--r--arch/blackfin/mach-bf527/boards/ezbrd.c30
-rw-r--r--arch/blackfin/mach-bf527/boards/ezkit.c49
-rw-r--r--arch/blackfin/mach-bf527/boards/tll6527m.c1008
-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.c34
-rw-r--r--arch/blackfin/mach-bf537/boards/cm_bf537u.c34
-rw-r--r--arch/blackfin/mach-bf537/boards/minotaur.c24
-rw-r--r--arch/blackfin/mach-bf537/boards/pnav10.c36
-rw-r--r--arch/blackfin/mach-bf537/boards/stamp.c623
-rw-r--r--arch/blackfin/mach-bf537/boards/tcm_bf537.c34
-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/Makefile1
-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/irqpanic.c106
-rw-r--r--arch/blackfin/mach-common/pm.c10
-rw-r--r--arch/blackfin/mm/init.c3
-rw-r--r--arch/cris/Kconfig7
-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-v10/kernel/ptrace.c20
-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/arch-v32/kernel/ptrace.c16
-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/pgtable.h2
-rw-r--r--arch/cris/include/asm/system.h1
-rw-r--r--arch/cris/kernel/profile.c1
-rw-r--r--arch/frv/Kconfig7
-rw-r--r--arch/frv/include/asm/highmem.h25
-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/pgtable.h9
-rw-r--r--arch/frv/include/asm/system.h136
-rw-r--r--arch/frv/kernel/ptrace.c32
-rw-r--r--arch/frv/lib/Makefile2
-rw-r--r--arch/frv/lib/perf_event.c19
-rw-r--r--arch/frv/mb93090-mb00/pci-dma.c4
-rw-r--r--arch/frv/mm/cache-page.c8
-rw-r--r--arch/frv/mm/highmem.c51
-rw-r--r--arch/h8300/Kconfig7
-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/ptrace.c33
-rw-r--r--arch/ia64/Kconfig19
-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/cputime.h6
-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/pgtable.h2
-rw-r--r--arch/ia64/include/asm/siginfo.h1
-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.c21
-rw-r--r--arch/ia64/kernel/ptrace.c3
-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/Kconfig9
-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/pgtable.h2
-rw-r--r--arch/m32r/include/asm/system.h66
-rw-r--r--arch/m32r/kernel/irq.c2
-rw-r--r--arch/m32r/kernel/ptrace.c11
-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/Kconfig10
-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.h11
-rw-r--r--arch/m68k/include/asm/entry_no.h12
-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/motorola_pgtable.h2
-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/sun3_pgtable.h2
-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/ptrace.c51
-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.c3
-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/Kconfig18
-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.c104
-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/Kconfig22
-rw-r--r--arch/microblaze/Kconfig.debug2
-rw-r--r--arch/microblaze/Makefile11
-rw-r--r--arch/microblaze/include/asm/byteorder.h4
-rw-r--r--arch/microblaze/include/asm/checksum.h9
-rw-r--r--arch/microblaze/include/asm/cpuinfo.h5
-rw-r--r--arch/microblaze/include/asm/elf.h2
-rw-r--r--arch/microblaze/include/asm/gpio.h5
-rw-r--r--arch/microblaze/include/asm/io.h2
-rw-r--r--arch/microblaze/include/asm/irqflags.h193
-rw-r--r--arch/microblaze/include/asm/memblock.h3
-rw-r--r--arch/microblaze/include/asm/page.h3
-rw-r--r--arch/microblaze/include/asm/pci.h2
-rw-r--r--arch/microblaze/include/asm/pgalloc.h3
-rw-r--r--arch/microblaze/include/asm/pgtable.h14
-rw-r--r--arch/microblaze/include/asm/prom.h1
-rw-r--r--arch/microblaze/include/asm/pvr.h14
-rw-r--r--arch/microblaze/include/asm/seccomp.h16
-rw-r--r--arch/microblaze/include/asm/setup.h6
-rw-r--r--arch/microblaze/include/asm/thread_info.h20
-rw-r--r--arch/microblaze/include/asm/unaligned.h12
-rw-r--r--arch/microblaze/include/asm/unistd.h5
-rw-r--r--arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c1
-rw-r--r--arch/microblaze/kernel/cpu/cpuinfo-static.c1
-rw-r--r--arch/microblaze/kernel/cpu/cpuinfo.c2
-rw-r--r--arch/microblaze/kernel/cpu/mb.c3
-rw-r--r--arch/microblaze/kernel/cpu/pvr.c2
-rw-r--r--arch/microblaze/kernel/early_printk.c87
-rw-r--r--arch/microblaze/kernel/entry.S21
-rw-r--r--arch/microblaze/kernel/exceptions.c25
-rw-r--r--arch/microblaze/kernel/heartbeat.c11
-rw-r--r--arch/microblaze/kernel/intc.c14
-rw-r--r--arch/microblaze/kernel/kgdb.c7
-rw-r--r--arch/microblaze/kernel/microblaze_ksyms.c32
-rw-r--r--arch/microblaze/kernel/prom.c44
-rw-r--r--arch/microblaze/kernel/ptrace.c5
-rw-r--r--arch/microblaze/kernel/setup.c6
-rw-r--r--arch/microblaze/kernel/syscall_table.S3
-rw-r--r--arch/microblaze/kernel/timer.c41
-rw-r--r--arch/microblaze/kernel/vmlinux.lds.S5
-rw-r--r--arch/microblaze/lib/Makefile10
-rw-r--r--arch/microblaze/lib/ashldi3.c29
-rw-r--r--arch/microblaze/lib/ashrdi3.c31
-rw-r--r--arch/microblaze/lib/divsi3.S73
-rw-r--r--arch/microblaze/lib/libgcc.h25
-rw-r--r--arch/microblaze/lib/lshrdi3.c29
-rw-r--r--arch/microblaze/lib/memcpy.c46
-rw-r--r--arch/microblaze/lib/memmove.c59
-rw-r--r--arch/microblaze/lib/memset.c22
-rw-r--r--arch/microblaze/lib/modsi3.S73
-rw-r--r--arch/microblaze/lib/muldi3.S121
-rw-r--r--arch/microblaze/lib/mulsi3.S46
-rw-r--r--arch/microblaze/lib/udivsi3.S84
-rw-r--r--arch/microblaze/lib/umodsi3.S86
-rw-r--r--arch/microblaze/mm/init.c30
-rw-r--r--arch/microblaze/pci/pci-common.c21
-rw-r--r--arch/microblaze/platform/generic/system.dts3
-rw-r--r--arch/microblaze/platform/platform.c3
-rw-r--r--arch/mips/Kconfig100
-rw-r--r--arch/mips/Kconfig.debug9
-rw-r--r--arch/mips/Makefile4
-rw-r--r--arch/mips/alchemy/common/platform.c28
-rw-r--r--arch/mips/alchemy/common/power.c35
-rw-r--r--arch/mips/alchemy/devboards/bcsr.c1
-rw-r--r--arch/mips/ar7/gpio.c243
-rw-r--r--arch/mips/ar7/irq.c1
-rw-r--r--arch/mips/ar7/platform.c56
-rw-r--r--arch/mips/ar7/prom.c2
-rw-r--r--arch/mips/ar7/setup.c14
-rw-r--r--arch/mips/bcm63xx/cpu.c30
-rw-r--r--arch/mips/bcm63xx/irq.c1
-rw-r--r--arch/mips/cavium-octeon/Kconfig23
-rw-r--r--arch/mips/cavium-octeon/csrc-octeon.c34
-rw-r--r--arch/mips/cavium-octeon/dma-octeon.c581
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-l2c.c810
-rw-r--r--arch/mips/cavium-octeon/octeon-platform.c112
-rw-r--r--arch/mips/cavium-octeon/serial.c3
-rw-r--r--arch/mips/cavium-octeon/setup.c120
-rw-r--r--arch/mips/dec/setup.c1
-rw-r--r--arch/mips/include/asm/atomic.h208
-rw-r--r--arch/mips/include/asm/bitops.h270
-rw-r--r--arch/mips/include/asm/bootinfo.h12
-rw-r--r--arch/mips/include/asm/cmpxchg.h7
-rw-r--r--arch/mips/include/asm/cpu.h26
-rw-r--r--arch/mips/include/asm/device.h15
-rw-r--r--arch/mips/include/asm/dma-mapping.h96
-rw-r--r--arch/mips/include/asm/dma.h3
-rw-r--r--arch/mips/include/asm/highmem.h18
-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/local.h2
-rw-r--r--arch/mips/include/asm/mach-ar7/ar7.h47
-rw-r--r--arch/mips/include/asm/mach-ar7/gpio.h3
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h97
-rw-r--r--arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h8
-rw-r--r--arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h24
-rw-r--r--arch/mips/include/asm/mach-ip27/dma-coherence.h5
-rw-r--r--arch/mips/include/asm/mach-ip32/dma-coherence.h5
-rw-r--r--arch/mips/include/asm/mach-jazz/dma-coherence.h9
-rw-r--r--arch/mips/include/asm/mach-loongson/loongson.h1
-rw-r--r--arch/mips/include/asm/mipsregs.h51
-rw-r--r--arch/mips/include/asm/octeon/cvmx-agl-defs.h616
-rw-r--r--arch/mips/include/asm/octeon/cvmx-asm.h11
-rw-r--r--arch/mips/include/asm/octeon/cvmx-ciu-defs.h857
-rw-r--r--arch/mips/include/asm/octeon/cvmx-gpio-defs.h74
-rw-r--r--arch/mips/include/asm/octeon/cvmx-iob-defs.h242
-rw-r--r--arch/mips/include/asm/octeon/cvmx-ipd-defs.h314
-rw-r--r--arch/mips/include/asm/octeon/cvmx-l2c-defs.h738
-rw-r--r--arch/mips/include/asm/octeon/cvmx-l2c.h225
-rw-r--r--arch/mips/include/asm/octeon/cvmx-l2d-defs.h38
-rw-r--r--arch/mips/include/asm/octeon/cvmx-l2t-defs.h5
-rw-r--r--arch/mips/include/asm/octeon/cvmx-led-defs.h41
-rw-r--r--arch/mips/include/asm/octeon/cvmx-mio-defs.h807
-rw-r--r--arch/mips/include/asm/octeon/cvmx-mixx-defs.h200
-rw-r--r--arch/mips/include/asm/octeon/cvmx-npei-defs.h681
-rw-r--r--arch/mips/include/asm/octeon/cvmx-npi-defs.h362
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pci-defs.h265
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pciercx-defs.h435
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pescx-defs.h50
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pexp-defs.h378
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pow-defs.h157
-rw-r--r--arch/mips/include/asm/octeon/cvmx-rnm-defs.h67
-rw-r--r--arch/mips/include/asm/octeon/cvmx-smix-defs.h46
-rw-r--r--arch/mips/include/asm/octeon/cvmx-uctlx-defs.h261
-rw-r--r--arch/mips/include/asm/octeon/octeon-model.h36
-rw-r--r--arch/mips/include/asm/octeon/octeon.h1
-rw-r--r--arch/mips/include/asm/octeon/pci-octeon.h10
-rw-r--r--arch/mips/include/asm/pci/bridge.h2
-rw-r--r--arch/mips/include/asm/perf_event.h25
-rw-r--r--arch/mips/include/asm/pgtable-32.h3
-rw-r--r--arch/mips/include/asm/pgtable-64.h7
-rw-r--r--arch/mips/include/asm/processor.h40
-rw-r--r--arch/mips/include/asm/prom.h31
-rw-r--r--arch/mips/include/asm/system.h52
-rw-r--r--arch/mips/include/asm/thread_info.h2
-rw-r--r--arch/mips/include/asm/uaccess.h4
-rw-r--r--arch/mips/jazz/irq.c1
-rw-r--r--arch/mips/kernel/Makefile4
-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/cpu-probe.c82
-rw-r--r--arch/mips/kernel/i8253.c1
-rw-r--r--arch/mips/kernel/i8259.c1
-rw-r--r--arch/mips/kernel/irq-gic.c2
-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.c24
-rw-r--r--arch/mips/kernel/irq_cpu.c1
-rw-r--r--arch/mips/kernel/irq_txx9.c1
-rw-r--r--arch/mips/kernel/mips-mt-fpaff.c2
-rw-r--r--arch/mips/kernel/perf_event.c601
-rw-r--r--arch/mips/kernel/perf_event_mipsxx.c1052
-rw-r--r--arch/mips/kernel/prom.c112
-rw-r--r--arch/mips/kernel/ptrace.c25
-rw-r--r--arch/mips/kernel/rtlx.c3
-rw-r--r--arch/mips/kernel/setup.c3
-rw-r--r--arch/mips/kernel/smtc.c4
-rw-r--r--arch/mips/kernel/traps.c33
-rw-r--r--arch/mips/kernel/unaligned.c7
-rw-r--r--arch/mips/kernel/vpe.c3
-rw-r--r--arch/mips/loongson/Kconfig2
-rw-r--r--arch/mips/math-emu/cp1emu.c4
-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/c-octeon.c16
-rw-r--r--arch/mips/mm/c-r4k.c21
-rw-r--r--arch/mips/mm/dma-default.c165
-rw-r--r--arch/mips/mm/fault.c11
-rw-r--r--arch/mips/mm/highmem.c51
-rw-r--r--arch/mips/mm/sc-mips.c34
-rw-r--r--arch/mips/mm/tlbex.c11
-rw-r--r--arch/mips/mm/uasm.c20
-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-octeon.c60
-rw-r--r--arch/mips/pci/pcie-octeon.c5
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c1
-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/Kconfig286
-rw-r--r--arch/mn10300/Makefile6
-rw-r--r--arch/mn10300/boot/compressed/head.S69
-rw-r--r--arch/mn10300/configs/asb2303_defconfig2
-rw-r--r--arch/mn10300/configs/asb2364_defconfig98
-rw-r--r--arch/mn10300/include/asm/atomic.h350
-rw-r--r--arch/mn10300/include/asm/bitops.h14
-rw-r--r--arch/mn10300/include/asm/cache.h14
-rw-r--r--arch/mn10300/include/asm/cacheflush.h164
-rw-r--r--arch/mn10300/include/asm/cpu-regs.h91
-rw-r--r--arch/mn10300/include/asm/dmactl-regs.h87
-rw-r--r--arch/mn10300/include/asm/elf.h12
-rw-r--r--arch/mn10300/include/asm/exceptions.h8
-rw-r--r--arch/mn10300/include/asm/fpu.h157
-rw-r--r--arch/mn10300/include/asm/frame.inc20
-rw-r--r--arch/mn10300/include/asm/gdb-stub.h2
-rw-r--r--arch/mn10300/include/asm/hardirq.h3
-rw-r--r--arch/mn10300/include/asm/highmem.h46
-rw-r--r--arch/mn10300/include/asm/intctl-regs.h37
-rw-r--r--arch/mn10300/include/asm/io.h13
-rw-r--r--arch/mn10300/include/asm/ioctls.h84
-rw-r--r--arch/mn10300/include/asm/irq.h12
-rw-r--r--arch/mn10300/include/asm/irq_regs.h6
-rw-r--r--arch/mn10300/include/asm/irqflags.h216
-rw-r--r--arch/mn10300/include/asm/mmu_context.h73
-rw-r--r--arch/mn10300/include/asm/pgalloc.h1
-rw-r--r--arch/mn10300/include/asm/pgtable.h90
-rw-r--r--arch/mn10300/include/asm/processor.h66
-rw-r--r--arch/mn10300/include/asm/ptrace.h13
-rw-r--r--arch/mn10300/include/asm/reset-regs.h2
-rw-r--r--arch/mn10300/include/asm/rtc.h11
-rw-r--r--arch/mn10300/include/asm/rwlock.h125
-rw-r--r--arch/mn10300/include/asm/serial-regs.h51
-rw-r--r--arch/mn10300/include/asm/serial.h8
-rw-r--r--arch/mn10300/include/asm/smp.h91
-rw-r--r--arch/mn10300/include/asm/smsc911x.h1
-rw-r--r--arch/mn10300/include/asm/spinlock.h179
-rw-r--r--arch/mn10300/include/asm/spinlock_types.h20
-rw-r--r--arch/mn10300/include/asm/system.h182
-rw-r--r--arch/mn10300/include/asm/thread_info.h18
-rw-r--r--arch/mn10300/include/asm/timer-regs.h191
-rw-r--r--arch/mn10300/include/asm/timex.h20
-rw-r--r--arch/mn10300/include/asm/tlbflush.h174
-rw-r--r--arch/mn10300/include/asm/uaccess.h6
-rw-r--r--arch/mn10300/kernel/Makefile15
-rw-r--r--arch/mn10300/kernel/asm-offsets.c11
-rw-r--r--arch/mn10300/kernel/cevt-mn10300.c131
-rw-r--r--arch/mn10300/kernel/csrc-mn10300.c35
-rw-r--r--arch/mn10300/kernel/entry.S147
-rw-r--r--arch/mn10300/kernel/fpu-low.S265
-rw-r--r--arch/mn10300/kernel/fpu-nofpu-low.S39
-rw-r--r--arch/mn10300/kernel/fpu-nofpu.c30
-rw-r--r--arch/mn10300/kernel/fpu.c141
-rw-r--r--arch/mn10300/kernel/gdb-io-serial-low.S5
-rw-r--r--arch/mn10300/kernel/gdb-io-serial.c37
-rw-r--r--arch/mn10300/kernel/gdb-io-ttysm.c24
-rw-r--r--arch/mn10300/kernel/gdb-stub.c17
-rw-r--r--arch/mn10300/kernel/head.S202
-rw-r--r--arch/mn10300/kernel/internal.h25
-rw-r--r--arch/mn10300/kernel/irq.c276
-rw-r--r--arch/mn10300/kernel/kprobes.c4
-rw-r--r--arch/mn10300/kernel/mn10300-serial-low.S6
-rw-r--r--arch/mn10300/kernel/mn10300-serial.c210
-rw-r--r--arch/mn10300/kernel/mn10300-watchdog-low.S9
-rw-r--r--arch/mn10300/kernel/mn10300-watchdog.c100
-rw-r--r--arch/mn10300/kernel/process.c61
-rw-r--r--arch/mn10300/kernel/profile.c2
-rw-r--r--arch/mn10300/kernel/ptrace.c20
-rw-r--r--arch/mn10300/kernel/rtc.c41
-rw-r--r--arch/mn10300/kernel/setup.c79
-rw-r--r--arch/mn10300/kernel/signal.c20
-rw-r--r--arch/mn10300/kernel/smp-low.S97
-rw-r--r--arch/mn10300/kernel/smp.c1152
-rw-r--r--arch/mn10300/kernel/switch_to.S7
-rw-r--r--arch/mn10300/kernel/time.c112
-rw-r--r--arch/mn10300/kernel/traps.c42
-rw-r--r--arch/mn10300/kernel/vmlinux.lds.S2
-rw-r--r--arch/mn10300/lib/bitops.c4
-rw-r--r--arch/mn10300/lib/delay.c8
-rw-r--r--arch/mn10300/lib/do_csum.S49
-rw-r--r--arch/mn10300/mm/Kconfig.cache101
-rw-r--r--arch/mn10300/mm/Makefile14
-rw-r--r--arch/mn10300/mm/cache-flush-by-reg.S308
-rw-r--r--arch/mn10300/mm/cache-flush-by-tag.S251
-rw-r--r--arch/mn10300/mm/cache-flush-icache.c155
-rw-r--r--arch/mn10300/mm/cache-flush-mn10300.S192
-rw-r--r--arch/mn10300/mm/cache-inv-by-reg.S356
-rw-r--r--arch/mn10300/mm/cache-inv-by-tag.S348
-rw-r--r--arch/mn10300/mm/cache-inv-icache.c129
-rw-r--r--arch/mn10300/mm/cache-mn10300.S289
-rw-r--r--arch/mn10300/mm/cache-smp-flush.c156
-rw-r--r--arch/mn10300/mm/cache-smp-inv.c153
-rw-r--r--arch/mn10300/mm/cache-smp.c105
-rw-r--r--arch/mn10300/mm/cache-smp.h69
-rw-r--r--arch/mn10300/mm/cache.c95
-rw-r--r--arch/mn10300/mm/fault.c17
-rw-r--r--arch/mn10300/mm/init.c26
-rw-r--r--arch/mn10300/mm/misalignment.c3
-rw-r--r--arch/mn10300/mm/mmu-context.c41
-rw-r--r--arch/mn10300/mm/pgtable.c2
-rw-r--r--arch/mn10300/mm/tlb-mn10300.S59
-rw-r--r--arch/mn10300/mm/tlb-smp.c214
-rw-r--r--arch/mn10300/proc-mn103e010/include/proc/cache.h9
-rw-r--r--arch/mn10300/proc-mn103e010/include/proc/clock.h2
-rw-r--r--arch/mn10300/proc-mn103e010/include/proc/dmactl-regs.h102
-rw-r--r--arch/mn10300/proc-mn103e010/include/proc/intctl-regs.h29
-rw-r--r--arch/mn10300/proc-mn103e010/include/proc/proc.h2
-rw-r--r--arch/mn10300/proc-mn103e010/proc-init.c37
-rw-r--r--arch/mn10300/proc-mn2ws0050/Makefile5
-rw-r--r--arch/mn10300/proc-mn2ws0050/include/proc/cache.h48
-rw-r--r--arch/mn10300/proc-mn2ws0050/include/proc/clock.h20
-rw-r--r--arch/mn10300/proc-mn2ws0050/include/proc/dmactl-regs.h103
-rw-r--r--arch/mn10300/proc-mn2ws0050/include/proc/intctl-regs.h29
-rw-r--r--arch/mn10300/proc-mn2ws0050/include/proc/irq.h49
-rw-r--r--arch/mn10300/proc-mn2ws0050/include/proc/nand-regs.h120
-rw-r--r--arch/mn10300/proc-mn2ws0050/include/proc/proc.h18
-rw-r--r--arch/mn10300/proc-mn2ws0050/include/proc/smp-regs.h51
-rw-r--r--arch/mn10300/proc-mn2ws0050/proc-init.c134
-rw-r--r--arch/mn10300/unit-asb2303/include/unit/clock.h25
-rw-r--r--arch/mn10300/unit-asb2303/include/unit/serial.h5
-rw-r--r--arch/mn10300/unit-asb2303/include/unit/timex.h109
-rw-r--r--arch/mn10300/unit-asb2303/unit-init.c10
-rw-r--r--arch/mn10300/unit-asb2305/include/unit/clock.h25
-rw-r--r--arch/mn10300/unit-asb2305/include/unit/serial.h5
-rw-r--r--arch/mn10300/unit-asb2305/include/unit/timex.h109
-rw-r--r--arch/mn10300/unit-asb2305/pci-asb2305.c16
-rw-r--r--arch/mn10300/unit-asb2305/pci.c2
-rw-r--r--arch/mn10300/unit-asb2305/unit-init.c6
-rw-r--r--arch/mn10300/unit-asb2364/Makefile12
-rw-r--r--arch/mn10300/unit-asb2364/include/unit/clock.h29
-rw-r--r--arch/mn10300/unit-asb2364/include/unit/fpga-regs.h52
-rw-r--r--arch/mn10300/unit-asb2364/include/unit/irq.h35
-rw-r--r--arch/mn10300/unit-asb2364/include/unit/leds.h54
-rw-r--r--arch/mn10300/unit-asb2364/include/unit/serial.h151
-rw-r--r--arch/mn10300/unit-asb2364/include/unit/smsc911x.h171
-rw-r--r--arch/mn10300/unit-asb2364/include/unit/timex.h159
-rw-r--r--arch/mn10300/unit-asb2364/irq-fpga.c96
-rw-r--r--arch/mn10300/unit-asb2364/leds.c98
-rw-r--r--arch/mn10300/unit-asb2364/smsc911x.c58
-rw-r--r--arch/mn10300/unit-asb2364/unit-init.c88
-rw-r--r--arch/parisc/Kconfig12
-rw-r--r--arch/parisc/include/asm/cache.h2
-rw-r--r--arch/parisc/include/asm/cacheflush.h8
-rw-r--r--arch/parisc/include/asm/irq.h2
-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/pgtable.h2
-rw-r--r--arch/parisc/include/asm/system.h19
-rw-r--r--arch/parisc/include/asm/unistd.h3
-rw-r--r--arch/parisc/kernel/irq.c41
-rw-r--r--arch/parisc/kernel/pdc_cons.c141
-rw-r--r--arch/parisc/kernel/perf.c4
-rw-r--r--arch/parisc/kernel/ptrace.c13
-rw-r--r--arch/parisc/kernel/syscall_table.S1
-rw-r--r--arch/parisc/kernel/unaligned.c3
-rw-r--r--arch/parisc/kernel/unwind.c5
-rw-r--r--arch/parisc/math-emu/Makefile2
-rw-r--r--arch/powerpc/Kconfig14
-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/cputime.h12
-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/fsl_lbc.h34
-rw-r--r--arch/powerpc/include/asm/fsldma.h137
-rw-r--r--arch/powerpc/include/asm/highmem.h9
-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/kgdb.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/pgtable-ppc32.h8
-rw-r--r--arch/powerpc/include/asm/pgtable-ppc64.h2
-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/kgdb.c188
-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/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.c68
-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.c14
-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/highmem.c37
-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/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/cell/spufs/inode.c10
-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_lbc.c244
-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.c141
-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/Kbuild6
-rw-r--r--arch/s390/Kconfig78
-rw-r--r--arch/s390/Makefile5
-rw-r--r--arch/s390/crypto/crypt_s390.h2
-rw-r--r--arch/s390/crypto/prng.c1
-rw-r--r--arch/s390/hypfs/hypfs_diag.c20
-rw-r--r--arch/s390/hypfs/hypfs_vm.c1
-rw-r--r--arch/s390/hypfs/inode.c9
-rw-r--r--arch/s390/include/asm/Kbuild1
-rw-r--r--arch/s390/include/asm/ccwdev.h12
-rw-r--r--arch/s390/include/asm/cpu.h2
-rw-r--r--arch/s390/include/asm/cputime.h10
-rw-r--r--arch/s390/include/asm/dasd.h40
-rw-r--r--arch/s390/include/asm/hardirq.h4
-rw-r--r--arch/s390/include/asm/hugetlb.h26
-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/lowcore.h11
-rw-r--r--arch/s390/include/asm/page.h8
-rw-r--r--arch/s390/include/asm/perf_event.h3
-rw-r--r--arch/s390/include/asm/pgalloc.h4
-rw-r--r--arch/s390/include/asm/pgtable.h62
-rw-r--r--arch/s390/include/asm/processor.h2
-rw-r--r--arch/s390/include/asm/ptrace.h3
-rw-r--r--arch/s390/include/asm/qdio.h13
-rw-r--r--arch/s390/include/asm/s390_ext.h2
-rw-r--r--arch/s390/include/asm/scatterlist.h2
-rw-r--r--arch/s390/include/asm/setup.h3
-rw-r--r--arch/s390/include/asm/syscall.h4
-rw-r--r--arch/s390/include/asm/sysinfo.h40
-rw-r--r--arch/s390/include/asm/system.h54
-rw-r--r--arch/s390/include/asm/tlb.h13
-rw-r--r--arch/s390/include/asm/topology.h29
-rw-r--r--arch/s390/kernel/asm-offsets.c9
-rw-r--r--arch/s390/kernel/compat_ptrace.h3
-rw-r--r--arch/s390/kernel/debug.c1
-rw-r--r--arch/s390/kernel/dis.c145
-rw-r--r--arch/s390/kernel/early.c47
-rw-r--r--arch/s390/kernel/entry.S45
-rw-r--r--arch/s390/kernel/entry.h4
-rw-r--r--arch/s390/kernel/entry64.S46
-rw-r--r--arch/s390/kernel/head.S8
-rw-r--r--arch/s390/kernel/kprobes.c9
-rw-r--r--arch/s390/kernel/mem_detect.c4
-rw-r--r--arch/s390/kernel/process.c10
-rw-r--r--arch/s390/kernel/processor.c2
-rw-r--r--arch/s390/kernel/ptrace.c3
-rw-r--r--arch/s390/kernel/s390_ext.c9
-rw-r--r--arch/s390/kernel/setup.c25
-rw-r--r--arch/s390/kernel/smp.c5
-rw-r--r--arch/s390/kernel/sysinfo.c43
-rw-r--r--arch/s390/kernel/time.c17
-rw-r--r--arch/s390/kernel/topology.c243
-rw-r--r--arch/s390/kernel/traps.c173
-rw-r--r--arch/s390/kernel/vdso.c6
-rw-r--r--arch/s390/kernel/vdso32/clock_getres.S6
-rw-r--r--arch/s390/kernel/vdso32/clock_gettime.S4
-rw-r--r--arch/s390/kernel/vdso64/clock_getres.S6
-rw-r--r--arch/s390/kernel/vdso64/clock_gettime.S4
-rw-r--r--arch/s390/kernel/vtime.c3
-rw-r--r--arch/s390/kvm/kvm-s390.c4
-rw-r--r--arch/s390/kvm/priv.c4
-rw-r--r--arch/s390/mm/Makefile2
-rw-r--r--arch/s390/mm/cmm.c7
-rw-r--r--arch/s390/mm/fault.c77
-rw-r--r--arch/s390/mm/gup.c225
-rw-r--r--arch/s390/mm/hugetlbpage.c2
-rw-r--r--arch/s390/mm/init.c55
-rw-r--r--arch/s390/mm/maccess.c4
-rw-r--r--arch/s390/mm/pgtable.c173
-rw-r--r--arch/score/Kconfig5
-rw-r--r--arch/score/include/asm/irqflags.h187
-rw-r--r--arch/score/include/asm/pgtable.h3
-rw-r--r--arch/score/kernel/ptrace.c7
-rw-r--r--arch/sh/Kconfig41
-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-ap325rxa/setup.c30
-rw-r--r--arch/sh/boards/mach-cayman/irq.c16
-rw-r--r--arch/sh/boards/mach-dreamcast/irq.c17
-rw-r--r--arch/sh/boards/mach-ecovec24/setup.c70
-rw-r--r--arch/sh/boards/mach-kfr2r09/setup.c30
-rw-r--r--arch/sh/boards/mach-landisk/gio.c1
-rw-r--r--arch/sh/boards/mach-landisk/irq.c15
-rw-r--r--arch/sh/boards/mach-microdev/irq.c30
-rw-r--r--arch/sh/boards/mach-migor/setup.c60
-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-se/7206/irq.c20
-rw-r--r--arch/sh/boards/mach-se/7343/irq.c15
-rw-r--r--arch/sh/boards/mach-se/7722/irq.c15
-rw-r--r--arch/sh/boards/mach-se/7724/irq.c13
-rw-r--r--arch/sh/boards/mach-se/7724/setup.c55
-rw-r--r--arch/sh/boards/mach-systemh/irq.c57
-rw-r--r--arch/sh/boards/mach-x3proto/Makefile2
-rw-r--r--arch/sh/boards/mach-x3proto/gpio.c136
-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/cchips/hd6446x/hd64461.c19
-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/pgtable.h2
-rw-r--r--arch/sh/include/asm/pgtable_32.h5
-rw-r--r--arch/sh/include/asm/pgtable_64.h11
-rw-r--r--arch/sh/include/asm/processor.h1
-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/init.c2
-rw-r--r--arch/sh/kernel/cpu/irq/imask.c14
-rw-r--r--arch/sh/kernel/cpu/irq/intc-sh5.c49
-rw-r--r--arch/sh/kernel/cpu/irq/ipr.c29
-rw-r--r--arch/sh/kernel/cpu/sh4/perf_event.c2
-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.c22
-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.c41
-rw-r--r--arch/sh/kernel/irq_32.c12
-rw-r--r--arch/sh/kernel/irq_64.c16
-rw-r--r--arch/sh/kernel/kdebugfs.c16
-rw-r--r--arch/sh/kernel/kprobes.c100
-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.c72
-rw-r--r--arch/sh/kernel/ptrace_64.c113
-rw-r--r--arch/sh/kernel/reboot.c4
-rw-r--r--arch/sh/kernel/setup.c26
-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/Makefile5
-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/gup.c273
-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/Makefile6
-rw-r--r--arch/sh/oprofile/backtrace.c2
-rw-r--r--arch/sh/oprofile/common.c120
-rw-r--r--arch/sh/oprofile/op_impl.h33
-rw-r--r--arch/sh/tools/mach-types2
-rw-r--r--arch/sparc/Kconfig11
-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/highmem.h4
-rw-r--r--arch/sparc/include/asm/io_32.h31
-rw-r--r--arch/sparc/include/asm/io_64.h31
-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/pci_64.h2
-rw-r--r--arch/sparc/include/asm/perf_event.h4
-rw-r--r--arch/sparc/include/asm/pgtable_32.h3
-rw-r--r--arch/sparc/include/asm/pgtable_64.h2
-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.c17
-rw-r--r--arch/sparc/kernel/jump_label.c47
-rw-r--r--arch/sparc/kernel/leon_kernel.c2
-rw-r--r--arch/sparc/kernel/leon_smp.c4
-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/ptrace_32.c57
-rw-r--r--arch/sparc/kernel/ptrace_64.c15
-rw-r--r--arch/sparc/kernel/rtrap_32.S6
-rw-r--r--arch/sparc/kernel/rtrap_64.S36
-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/fault_32.c12
-rw-r--r--arch/sparc/mm/highmem.c48
-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/Kconfig25
-rw-r--r--arch/tile/Makefile19
-rw-r--r--arch/tile/include/arch/sim.h619
-rw-r--r--arch/tile/include/arch/sim_def.h548
-rw-r--r--arch/tile/include/arch/spr_def.h85
-rw-r--r--arch/tile/include/arch/spr_def_32.h39
-rw-r--r--arch/tile/include/asm/backtrace.h5
-rw-r--r--arch/tile/include/asm/bitops.h1
-rw-r--r--arch/tile/include/asm/compat.h15
-rw-r--r--arch/tile/include/asm/highmem.h10
-rw-r--r--arch/tile/include/asm/irqflags.h100
-rw-r--r--arch/tile/include/asm/mman.h1
-rw-r--r--arch/tile/include/asm/page.h27
-rw-r--r--arch/tile/include/asm/pgtable.h5
-rw-r--r--arch/tile/include/asm/processor.h11
-rw-r--r--arch/tile/include/asm/ptrace.h4
-rw-r--r--arch/tile/include/asm/syscalls.h73
-rw-r--r--arch/tile/include/asm/system.h14
-rw-r--r--arch/tile/include/asm/traps.h4
-rw-r--r--arch/tile/include/hv/hypervisor.h30
-rw-r--r--arch/tile/kernel/backtrace.c4
-rw-r--r--arch/tile/kernel/compat.c10
-rw-r--r--arch/tile/kernel/compat_signal.c10
-rw-r--r--arch/tile/kernel/entry.S34
-rw-r--r--arch/tile/kernel/hardwall.c1
-rw-r--r--arch/tile/kernel/head_32.S5
-rw-r--r--arch/tile/kernel/intvec_32.S101
-rw-r--r--arch/tile/kernel/irq.c20
-rw-r--r--arch/tile/kernel/messaging.c2
-rw-r--r--arch/tile/kernel/process.c50
-rw-r--r--arch/tile/kernel/ptrace.c87
-rw-r--r--arch/tile/kernel/regs_32.S2
-rw-r--r--arch/tile/kernel/setup.c36
-rw-r--r--arch/tile/kernel/signal.c6
-rw-r--r--arch/tile/kernel/single_step.c73
-rw-r--r--arch/tile/kernel/smp.c2
-rw-r--r--arch/tile/kernel/stack.c35
-rw-r--r--arch/tile/kernel/sys.c9
-rw-r--r--arch/tile/kernel/traps.c4
-rw-r--r--arch/tile/kvm/Kconfig38
-rw-r--r--arch/tile/lib/Makefile4
-rw-r--r--arch/tile/lib/atomic_32.c8
-rw-r--r--arch/tile/lib/exports.c3
-rw-r--r--arch/tile/lib/memcpy_32.S206
-rw-r--r--arch/tile/lib/memmove.c (renamed from arch/tile/lib/memmove_32.c)0
-rw-r--r--arch/tile/lib/memset_32.c1
-rw-r--r--arch/tile/lib/strlen_32.c2
-rw-r--r--arch/tile/mm/fault.c12
-rw-r--r--arch/tile/mm/highmem.c86
-rw-r--r--arch/tile/mm/homecache.c11
-rw-r--r--arch/tile/mm/init.c2
-rw-r--r--arch/um/Kconfig.common2
-rw-r--r--arch/um/Kconfig.um6
-rw-r--r--arch/um/defconfig1
-rw-r--r--arch/um/drivers/harddog_kern.c14
-rw-r--r--arch/um/drivers/hostaudio_kern.c12
-rw-r--r--arch/um/drivers/mconsole_kern.c1
-rw-r--r--arch/um/drivers/mmapper_kern.c1
-rw-r--r--arch/um/drivers/random.c1
-rw-r--r--arch/um/drivers/ubd_kern.c11
-rw-r--r--arch/um/include/asm/dma-mapping.h112
-rw-r--r--arch/um/include/asm/pgtable.h2
-rw-r--r--arch/um/include/asm/system.h49
-rw-r--r--arch/um/kernel/dyn.lds.S14
-rw-r--r--arch/um/kernel/exec.c2
-rw-r--r--arch/um/kernel/irq.c21
-rw-r--r--arch/um/kernel/ptrace.c23
-rw-r--r--arch/um/kernel/uml.lds.S19
-rw-r--r--arch/um/os-Linux/time.c2
-rw-r--r--arch/um/sys-i386/ptrace.c4
-rw-r--r--arch/um/sys-x86_64/ptrace.c11
-rw-r--r--arch/x86/Kbuild1
-rw-r--r--arch/x86/Kconfig154
-rw-r--r--arch/x86/Kconfig.debug14
-rw-r--r--arch/x86/Makefile8
-rw-r--r--arch/x86/Makefile_32.cpu13
-rw-r--r--arch/x86/boot/compressed/misc.c29
-rw-r--r--arch/x86/include/asm/acpi.h3
-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/highmem.h11
-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.h15
-rw-r--r--arch/x86/include/asm/io_apic.h7
-rw-r--r--arch/x86/include/asm/iomap.h4
-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.h81
-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.h2
-rw-r--r--arch/x86/include/asm/mwait.h15
-rw-r--r--arch/x86/include/asm/olpc.h2
-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/pci.h33
-rw-r--r--arch/x86/include/asm/pci_x86.h1
-rw-r--r--arch/x86/include/asm/percpu.h14
-rw-r--r--arch/x86/include/asm/perf_event.h19
-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.h16
-rw-r--r--arch/x86/include/asm/pgtable_64.h4
-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/smp.h9
-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/uv/uv_hub.h21
-rw-r--r--arch/x86/include/asm/vmi.h269
-rw-r--r--arch/x86/include/asm/vmi_time.h98
-rw-r--r--arch/x86/include/asm/x86_init.h9
-rw-r--r--arch/x86/include/asm/xen/hypercall.h17
-rw-r--r--arch/x86/include/asm/xen/page.h12
-rw-r--r--arch/x86/include/asm/xen/pci.h65
-rw-r--r--arch/x86/kernel/Makefile20
-rw-r--r--arch/x86/kernel/acpi/boot.c60
-rw-r--r--arch/x86/kernel/acpi/cstate.c11
-rw-r--r--arch/x86/kernel/acpi/sleep.c15
-rw-r--r--arch/x86/kernel/alternative.c32
-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.c891
-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/apic/x2apic_uv_x.c24
-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.c24
-rw-r--r--arch/x86/kernel/cpu/cpu.h1
-rw-r--r--arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c1
-rw-r--r--arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c2
-rw-r--r--arch/x86/kernel/cpu/cpufreq/longrun.c4
-rw-r--r--arch/x86/kernel/cpu/intel.c6
-rw-r--r--arch/x86/kernel/cpu/intel_cacheinfo.c15
-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.c27
-rw-r--r--arch/x86/kernel/cpu/mcheck/therm_throt.c2
-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.c306
-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.c229
-rw-r--r--arch/x86/kernel/cpu/perf_event_p4.c292
-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_32.c2
-rw-r--r--arch/x86/kernel/crash_dump_64.c3
-rw-r--r--arch/x86/kernel/dumpstack_32.c6
-rw-r--r--arch/x86/kernel/dumpstack_64.c8
-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/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.c25
-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.c14
-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.c3
-rw-r--r--arch/x86/kernel/mpparse.c5
-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/ptrace.c17
-rw-r--r--arch/x86/kernel/pvclock.c3
-rw-r--r--arch/x86/kernel/quirks.c2
-rw-r--r--arch/x86/kernel/reboot.c14
-rw-r--r--arch/x86/kernel/setup.c235
-rw-r--r--arch/x86/kernel/setup_percpu.c8
-rw-r--r--arch/x86/kernel/smp.c15
-rw-r--r--arch/x86/kernel/smpboot.c137
-rw-r--r--arch/x86/kernel/sys_i386_32.c4
-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/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/kernel/x86_init.c7
-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.c283
-rw-r--r--arch/x86/kvm/timer.c2
-rw-r--r--arch/x86/kvm/vmx.c219
-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.c110
-rw-r--r--arch/x86/mm/highmem_32.c76
-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.c117
-rw-r--r--arch/x86/mm/iomap_32.c43
-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.c91
-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.c11
-rw-r--r--arch/x86/mm/tlb.c48
-rw-r--r--arch/x86/oprofile/backtrace.c70
-rw-r--r--arch/x86/oprofile/nmi_int.c15
-rw-r--r--arch/x86/oprofile/op_model_amd.c261
-rw-r--r--arch/x86/pci/Makefile1
-rw-r--r--arch/x86/pci/common.c17
-rw-r--r--arch/x86/pci/i386.c19
-rw-r--r--arch/x86/pci/irq.c11
-rw-r--r--arch/x86/pci/mmconfig-shared.c4
-rw-r--r--arch/x86/pci/olpc.c2
-rw-r--r--arch/x86/pci/xen.c414
-rw-r--r--arch/x86/platform/Makefile8
-rw-r--r--arch/x86/platform/efi/Makefile1
-rw-r--r--arch/x86/platform/efi/efi.c (renamed from arch/x86/kernel/efi.c)5
-rw-r--r--arch/x86/platform/efi/efi_32.c (renamed from arch/x86/kernel/efi_32.c)0
-rw-r--r--arch/x86/platform/efi/efi_64.c (renamed from arch/x86/kernel/efi_64.c)0
-rw-r--r--arch/x86/platform/efi/efi_stub_32.S (renamed from arch/x86/kernel/efi_stub_32.S)0
-rw-r--r--arch/x86/platform/efi/efi_stub_64.S (renamed from arch/x86/kernel/efi_stub_64.S)0
-rw-r--r--arch/x86/platform/mrst/Makefile1
-rw-r--r--arch/x86/platform/mrst/mrst.c (renamed from arch/x86/kernel/mrst.c)0
-rw-r--r--arch/x86/platform/olpc/Makefile3
-rw-r--r--arch/x86/platform/olpc/olpc-xo1.c140
-rw-r--r--arch/x86/platform/olpc/olpc.c (renamed from arch/x86/kernel/olpc.c)89
-rw-r--r--arch/x86/platform/olpc/olpc_ofw.c (renamed from arch/x86/kernel/olpc_ofw.c)6
-rw-r--r--arch/x86/platform/scx200/Makefile2
-rw-r--r--arch/x86/platform/scx200/scx200_32.c (renamed from arch/x86/kernel/scx200_32.c)0
-rw-r--r--arch/x86/platform/sfi/Makefile1
-rw-r--r--arch/x86/platform/sfi/sfi.c (renamed from arch/x86/kernel/sfi.c)4
-rw-r--r--arch/x86/platform/uv/Makefile1
-rw-r--r--arch/x86/platform/uv/bios_uv.c (renamed from arch/x86/kernel/bios_uv.c)0
-rw-r--r--arch/x86/platform/uv/tlb_uv.c (renamed from arch/x86/kernel/tlb_uv.c)12
-rw-r--r--arch/x86/platform/uv/uv_irq.c (renamed from arch/x86/kernel/uv_irq.c)55
-rw-r--r--arch/x86/platform/uv/uv_sysfs.c (renamed from arch/x86/kernel/uv_sysfs.c)0
-rw-r--r--arch/x86/platform/uv/uv_time.c (renamed from arch/x86/kernel/uv_time.c)0
-rw-r--r--arch/x86/platform/visws/Makefile1
-rw-r--r--arch/x86/platform/visws/visws_quirks.c (renamed from arch/x86/kernel/visws_quirks.c)140
-rw-r--r--arch/x86/xen/Kconfig21
-rw-r--r--arch/x86/xen/debugfs.c1
-rw-r--r--arch/x86/xen/enlighten.c27
-rw-r--r--arch/x86/xen/mmu.c580
-rw-r--r--arch/x86/xen/mmu.h1
-rw-r--r--arch/x86/xen/pci-swiotlb-xen.c9
-rw-r--r--arch/x86/xen/setup.c120
-rw-r--r--arch/x86/xen/smp.c32
-rw-r--r--arch/x86/xen/spinlock.c2
-rw-r--r--arch/x86/xen/xen-ops.h3
-rw-r--r--arch/xtensa/Kconfig5
-rw-r--r--arch/xtensa/include/asm/irqflags.h58
-rw-r--r--arch/xtensa/include/asm/pgtable.h3
-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
-rw-r--r--arch/xtensa/kernel/ptrace.c14
2762 files changed, 104871 insertions, 38681 deletions
diff --git a/arch/Kconfig b/arch/Kconfig
index fe48fc7a3eba..8bf0fa652eb6 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -42,6 +42,20 @@ config KPROBES
for kernel debugging, non-intrusive instrumentation and testing.
If in doubt, say "N".
+config JUMP_LABEL
+ bool "Optimize trace point call sites"
+ depends on HAVE_ARCH_JUMP_LABEL
+ help
+ If it is detected that the compiler has support for "asm goto",
+ the kernel will compile trace point locations with just a
+ nop instruction. When trace points are enabled, the nop will
+ be converted to a jump to the trace function. This technique
+ lowers overhead and stress on the branch prediction of the
+ processor.
+
+ On i386, options added to the compiler flags may increase
+ the size of the kernel slightly.
+
config OPTPROBES
def_bool y
depends on KPROBES && HAVE_OPTPROBES
@@ -158,4 +172,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..943fe6930f77 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -1,7 +1,3 @@
-#
-# For a description of the syntax of this configuration file,
-# see Documentation/kbuild/kconfig-language.txt.
-#
config ALPHA
bool
default y
@@ -9,6 +5,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
@@ -54,6 +51,9 @@ config ZONE_DMA
bool
default y
+config ARCH_DMA_ADDR_T_64BIT
+ def_bool y
+
config NEED_DMA_MAP_STATE
def_bool y
diff --git a/arch/alpha/include/asm/core_mcpcia.h b/arch/alpha/include/asm/core_mcpcia.h
index 21ac53383b37..9f67a056b461 100644
--- a/arch/alpha/include/asm/core_mcpcia.h
+++ b/arch/alpha/include/asm/core_mcpcia.h
@@ -247,7 +247,7 @@ struct el_MCPCIA_uncorrected_frame_mcheck {
#define vip volatile int __force *
#define vuip volatile unsigned int __force *
-#ifdef MCPCIA_ONE_HAE_WINDOW
+#ifndef MCPCIA_ONE_HAE_WINDOW
#define MCPCIA_FROB_MMIO \
if (__mcpcia_is_mmio(hose)) { \
set_hae(hose & 0xffffffff); \
diff --git a/arch/alpha/include/asm/core_t2.h b/arch/alpha/include/asm/core_t2.h
index 471c07292e0b..91b46801b290 100644
--- a/arch/alpha/include/asm/core_t2.h
+++ b/arch/alpha/include/asm/core_t2.h
@@ -1,6 +1,9 @@
#ifndef __ALPHA_T2__H__
#define __ALPHA_T2__H__
+/* Fit everything into one 128MB HAE window. */
+#define T2_ONE_HAE_WINDOW 1
+
#include <linux/types.h>
#include <linux/spinlock.h>
#include <asm/compiler.h>
@@ -19,7 +22,7 @@
*
*/
-#define T2_MEM_R1_MASK 0x07ffffff /* Mem sparse region 1 mask is 26 bits */
+#define T2_MEM_R1_MASK 0x07ffffff /* Mem sparse region 1 mask is 27 bits */
/* GAMMA-SABLE is a SABLE with EV5-based CPUs */
/* All LYNX machines, EV4 or EV5, use the GAMMA bias also */
@@ -85,7 +88,9 @@
#define T2_DIR (IDENT_ADDR + GAMMA_BIAS + 0x38e0004a0UL)
#define T2_ICE (IDENT_ADDR + GAMMA_BIAS + 0x38e0004c0UL)
+#ifndef T2_ONE_HAE_WINDOW
#define T2_HAE_ADDRESS T2_HAE_1
+#endif
/* T2 CSRs are in the non-cachable primary IO space from 3.8000.0000 to
3.8fff.ffff
@@ -429,13 +434,15 @@ extern inline void t2_outl(u32 b, unsigned long addr)
*
*/
+#ifdef T2_ONE_HAE_WINDOW
+#define t2_set_hae
+#else
#define t2_set_hae { \
- msb = addr >> 27; \
+ unsigned long msb = addr >> 27; \
addr &= T2_MEM_R1_MASK; \
set_hae(msb); \
}
-
-extern raw_spinlock_t t2_hae_lock;
+#endif
/*
* NOTE: take T2_DENSE_MEM off in each readX/writeX routine, since
@@ -446,28 +453,22 @@ extern raw_spinlock_t t2_hae_lock;
__EXTERN_INLINE u8 t2_readb(const volatile void __iomem *xaddr)
{
unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
- unsigned long result, msb;
- unsigned long flags;
- raw_spin_lock_irqsave(&t2_hae_lock, flags);
+ unsigned long result;
t2_set_hae;
result = *(vip) ((addr << 5) + T2_SPARSE_MEM + 0x00);
- raw_spin_unlock_irqrestore(&t2_hae_lock, flags);
return __kernel_extbl(result, addr & 3);
}
__EXTERN_INLINE u16 t2_readw(const volatile void __iomem *xaddr)
{
unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
- unsigned long result, msb;
- unsigned long flags;
- raw_spin_lock_irqsave(&t2_hae_lock, flags);
+ unsigned long result;
t2_set_hae;
result = *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x08);
- raw_spin_unlock_irqrestore(&t2_hae_lock, flags);
return __kernel_extwl(result, addr & 3);
}
@@ -478,59 +479,47 @@ __EXTERN_INLINE u16 t2_readw(const volatile void __iomem *xaddr)
__EXTERN_INLINE u32 t2_readl(const volatile void __iomem *xaddr)
{
unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
- unsigned long result, msb;
- unsigned long flags;
- raw_spin_lock_irqsave(&t2_hae_lock, flags);
+ unsigned long result;
t2_set_hae;
result = *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x18);
- raw_spin_unlock_irqrestore(&t2_hae_lock, flags);
return result & 0xffffffffUL;
}
__EXTERN_INLINE u64 t2_readq(const volatile void __iomem *xaddr)
{
unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
- unsigned long r0, r1, work, msb;
- unsigned long flags;
- raw_spin_lock_irqsave(&t2_hae_lock, flags);
+ unsigned long r0, r1, work;
t2_set_hae;
work = (addr << 5) + T2_SPARSE_MEM + 0x18;
r0 = *(vuip)(work);
r1 = *(vuip)(work + (4 << 5));
- raw_spin_unlock_irqrestore(&t2_hae_lock, flags);
return r1 << 32 | r0;
}
__EXTERN_INLINE void t2_writeb(u8 b, volatile void __iomem *xaddr)
{
unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
- unsigned long msb, w;
- unsigned long flags;
- raw_spin_lock_irqsave(&t2_hae_lock, flags);
+ unsigned long w;
t2_set_hae;
w = __kernel_insbl(b, addr & 3);
*(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x00) = w;
- raw_spin_unlock_irqrestore(&t2_hae_lock, flags);
}
__EXTERN_INLINE void t2_writew(u16 b, volatile void __iomem *xaddr)
{
unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
- unsigned long msb, w;
- unsigned long flags;
- raw_spin_lock_irqsave(&t2_hae_lock, flags);
+ unsigned long w;
t2_set_hae;
w = __kernel_inswl(b, addr & 3);
*(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x08) = w;
- raw_spin_unlock_irqrestore(&t2_hae_lock, flags);
}
/*
@@ -540,29 +529,22 @@ __EXTERN_INLINE void t2_writew(u16 b, volatile void __iomem *xaddr)
__EXTERN_INLINE void t2_writel(u32 b, volatile void __iomem *xaddr)
{
unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
- unsigned long msb;
- unsigned long flags;
- raw_spin_lock_irqsave(&t2_hae_lock, flags);
t2_set_hae;
*(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x18) = b;
- raw_spin_unlock_irqrestore(&t2_hae_lock, flags);
}
__EXTERN_INLINE void t2_writeq(u64 b, volatile void __iomem *xaddr)
{
unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
- unsigned long msb, work;
- unsigned long flags;
- raw_spin_lock_irqsave(&t2_hae_lock, flags);
+ unsigned long work;
t2_set_hae;
work = (addr << 5) + T2_SPARSE_MEM + 0x18;
*(vuip)work = b;
*(vuip)(work + (4 << 5)) = b >> 32;
- raw_spin_unlock_irqrestore(&t2_hae_lock, flags);
}
__EXTERN_INLINE void __iomem *t2_ioportmap(unsigned long addr)
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/pgtable.h b/arch/alpha/include/asm/pgtable.h
index 71a243294142..de98a732683d 100644
--- a/arch/alpha/include/asm/pgtable.h
+++ b/arch/alpha/include/asm/pgtable.h
@@ -318,9 +318,7 @@ extern inline pte_t * pte_offset_kernel(pmd_t * dir, unsigned long address)
}
#define pte_offset_map(dir,addr) pte_offset_kernel((dir),(addr))
-#define pte_offset_map_nested(dir,addr) pte_offset_kernel((dir),(addr))
#define pte_unmap(pte) do { } while (0)
-#define pte_unmap_nested(pte) do { } while (0)
extern pgd_t swapper_pg_dir[1024];
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/core_t2.c b/arch/alpha/kernel/core_t2.c
index e6d90568b65d..2f770e994289 100644
--- a/arch/alpha/kernel/core_t2.c
+++ b/arch/alpha/kernel/core_t2.c
@@ -74,8 +74,6 @@
# define DBG(args)
#endif
-DEFINE_RAW_SPINLOCK(t2_hae_lock);
-
static volatile unsigned int t2_mcheck_any_expected;
static volatile unsigned int t2_mcheck_last_taken;
@@ -406,6 +404,7 @@ void __init
t2_init_arch(void)
{
struct pci_controller *hose;
+ struct resource *hae_mem;
unsigned long temp;
unsigned int i;
@@ -433,7 +432,13 @@ t2_init_arch(void)
*/
pci_isa_hose = hose = alloc_pci_controller();
hose->io_space = &ioport_resource;
- hose->mem_space = &iomem_resource;
+ hae_mem = alloc_resource();
+ hae_mem->start = 0;
+ hae_mem->end = T2_MEM_R1_MASK;
+ hae_mem->name = pci_hae0_name;
+ if (request_resource(&iomem_resource, hae_mem) < 0)
+ printk(KERN_ERR "Failed to request HAE_MEM\n");
+ hose->mem_space = hae_mem;
hose->index = 0;
hose->sparse_mem_base = T2_SPARSE_MEM - IDENT_ADDR;
diff --git a/arch/alpha/kernel/machvec_impl.h b/arch/alpha/kernel/machvec_impl.h
index 512685f78097..7fa62488bd16 100644
--- a/arch/alpha/kernel/machvec_impl.h
+++ b/arch/alpha/kernel/machvec_impl.h
@@ -25,6 +25,9 @@
#ifdef MCPCIA_ONE_HAE_WINDOW
#define MCPCIA_HAE_ADDRESS (&alpha_mv.hae_cache)
#endif
+#ifdef T2_ONE_HAE_WINDOW
+#define T2_HAE_ADDRESS (&alpha_mv.hae_cache)
+#endif
/* Only a few systems don't define IACK_SC, handling all interrupts through
the SRM console. But splitting out that one case from IO() below
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index d1dbd9acd1df..022c2748fa41 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -223,7 +223,7 @@ iommu_arena_free(struct pci_iommu_arena *arena, long ofs, long n)
*/
static int pci_dac_dma_supported(struct pci_dev *dev, u64 mask)
{
- dma64_addr_t dac_offset = alpha_mv.pci_dac_offset;
+ dma_addr_t dac_offset = alpha_mv.pci_dac_offset;
int ok = 1;
/* If this is not set, the machine doesn't support DAC at all. */
@@ -756,7 +756,7 @@ static void alpha_pci_unmap_sg(struct device *dev, struct scatterlist *sg,
spin_lock_irqsave(&arena->lock, flags);
for (end = sg + nents; sg < end; ++sg) {
- dma64_addr_t addr;
+ dma_addr_t addr;
size_t size;
long npages, ofs;
dma_addr_t tend;
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/ptrace.c b/arch/alpha/kernel/ptrace.c
index baa903602f6a..e2af5eb59bb4 100644
--- a/arch/alpha/kernel/ptrace.c
+++ b/arch/alpha/kernel/ptrace.c
@@ -269,7 +269,8 @@ void ptrace_disable(struct task_struct *child)
user_disable_single_step(child);
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
unsigned long tmp;
size_t copied;
@@ -292,7 +293,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
case PTRACE_PEEKUSR:
force_successful_syscall_return();
ret = get_reg(child, addr);
- DBG(DBG_MEM, ("peek $%ld->%#lx\n", addr, ret));
+ DBG(DBG_MEM, ("peek $%lu->%#lx\n", addr, ret));
break;
/* When I and D space are separate, this will have to be fixed. */
@@ -302,7 +303,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
case PTRACE_POKEUSR: /* write the specified register */
- DBG(DBG_MEM, ("poke $%ld<-%#lx\n", addr, data));
+ DBG(DBG_MEM, ("poke $%lu<-%#lx\n", addr, data));
ret = put_reg(child, addr, data);
break;
default:
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 9c26ba7244fb..a19a5266d5fc 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1,10 +1,3 @@
-#
-# For a description of the syntax of this configuration file,
-# see Documentation/kbuild/kconfig-language.txt.
-#
-
-mainmenu "Linux Kernel Configuration"
-
config ARM
bool
default y
@@ -19,13 +12,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 +142,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 +510,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.
@@ -565,6 +566,7 @@ config ARCH_TEGRA
select HAVE_CLK
select COMMON_CLKDEV
select ARCH_HAS_BARRIERS if CACHE_L2X0
+ select ARCH_HAS_CPUFREQ
help
This enables support for NVIDIA Tegra based systems (Tegra APX,
Tegra 6xx and Tegra 2 series).
@@ -587,6 +589,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 +681,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 +691,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"
@@ -716,9 +720,11 @@ config ARCH_S5PC100
config ARCH_S5PV210
bool "Samsung S5PV210/S5PC110"
select CPU_V7
+ select ARCH_SPARSEMEM_ENABLE
select GENERIC_GPIO
select HAVE_CLK
select ARM_L1_CACHE_SHIFT_6
+ select ARCH_HAS_CPUFREQ
select ARCH_USES_GETTIMEOFFSET
select HAVE_S3C2410_I2C
select HAVE_S3C_RTC
@@ -729,9 +735,13 @@ config ARCH_S5PV210
config ARCH_S5PV310
bool "Samsung S5PV310/S5PC210"
select CPU_V7
+ select ARCH_SPARSEMEM_ENABLE
select GENERIC_GPIO
select HAVE_CLK
select GENERIC_CLOCKEVENTS
+ select HAVE_S3C_RTC
+ select HAVE_S3C2410_I2C
+ select HAVE_S3C2410_WATCHDOG
help
Samsung S5PV310 series based systems
@@ -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
@@ -812,7 +831,7 @@ config ARCH_OMAP
select GENERIC_CLOCKEVENTS
select ARCH_HAS_HOLES_MEMORYMODEL
help
- Support for TI's OMAP platform (OMAP1 and OMAP2).
+ Support for TI's OMAP platform (OMAP1/2/3/4).
config PLAT_SPEAR
bool "ST SPEAr"
@@ -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.
@@ -1181,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
@@ -1201,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
@@ -1255,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
@@ -1271,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
@@ -1477,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
@@ -1623,6 +1668,12 @@ if ARCH_HAS_CPUFREQ
source "drivers/cpufreq/Kconfig"
+config CPU_FREQ_IMX
+ tristate "CPUfreq driver for i.MX CPUs"
+ depends on ARCH_MXC && CPU_FREQ
+ help
+ This enables the CPUfreq driver for i.MX CPUs.
+
config CPU_FREQ_SA1100
bool
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/da8xx_omapl_defconfig b/arch/arm/configs/da8xx_omapl_defconfig
index ba6670556f78..cdc40c4b8c48 100644
--- a/arch/arm/configs/da8xx_omapl_defconfig
+++ b/arch/arm/configs/da8xx_omapl_defconfig
@@ -17,6 +17,8 @@ CONFIG_MODVERSIONS=y
CONFIG_ARCH_DAVINCI=y
CONFIG_ARCH_DAVINCI_DA830=y
CONFIG_ARCH_DAVINCI_DA850=y
+CONFIG_MACH_MITYOMAPL138=y
+CONFIG_MACH_OMAPL138_HAWKBOARD=y
CONFIG_DAVINCI_RESET_CLOCKS=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
@@ -79,6 +81,7 @@ CONFIG_I2C_DAVINCI=y
# CONFIG_HWMON is not set
CONFIG_WATCHDOG=y
CONFIG_REGULATOR=y
+CONFIG_REGULATOR_DUMMY=y
CONFIG_REGULATOR_TPS6507X=y
CONFIG_FB=y
CONFIG_FB_DA8XX=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..5c7a87260fab 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
@@ -81,6 +82,7 @@ CONFIG_FEC=y
CONFIG_INPUT_FF_MEMLESS=m
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_GPIO=y
CONFIG_INPUT_EVBUG=m
CONFIG_MOUSE_PS2=m
CONFIG_MOUSE_PS2_ELANTECH=y
@@ -100,7 +102,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 +118,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 +135,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 +151,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 +158,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/n8x0_defconfig b/arch/arm/configs/n8x0_defconfig
deleted file mode 100644
index 56aebb69411d..000000000000
--- a/arch/arm/configs/n8x0_defconfig
+++ /dev/null
@@ -1,94 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=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_ARCH_OMAP=y
-CONFIG_ARCH_OMAP2=y
-CONFIG_OMAP_RESET_CLOCKS=y
-# CONFIG_OMAP_MUX is not set
-# CONFIG_OMAP_MCBSP is not set
-CONFIG_OMAP_MBOX_FWK=y
-CONFIG_OMAP_32K_TIMER=y
-CONFIG_ARCH_OMAP2420=y
-CONFIG_MACH_NOKIA_N8X0=y
-CONFIG_AEABI=y
-CONFIG_LEDS=y
-CONFIG_ZBOOT_ROM_TEXT=0x10C08000
-CONFIG_ZBOOT_ROM_BSS=0x10200000
-CONFIG_CMDLINE="root=/dev/mmcblk0p2 console=ttyS2,115200n8 debug earlyprintk rootwait"
-CONFIG_FPE_NWFPE=y
-CONFIG_VFP=y
-CONFIG_PM=y
-CONFIG_PM_RUNTIME=y
-CONFIG_NET=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_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_ONENAND=y
-CONFIG_MTD_ONENAND_OMAP2=y
-CONFIG_MTD_ONENAND_OTP=y
-CONFIG_BLK_DEV_RAM=y
-# CONFIG_MISC_DEVICES is not set
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-# CONFIG_I2C_COMPAT is not set
-# CONFIG_I2C_HELPER_AUTO is not set
-CONFIG_I2C_OMAP=y
-CONFIG_SPI=y
-CONFIG_SPI_OMAP24XX=y
-# CONFIG_HWMON is not set
-CONFIG_MENELAUS=y
-CONFIG_REGULATOR=y
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_HID_SUPPORT is not set
-CONFIG_USB=y
-CONFIG_USB_DEBUG=y
-CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_SUSPEND=y
-# CONFIG_USB_OTG_WHITELIST is not set
-CONFIG_USB_MUSB_HDRC=y
-CONFIG_USB_MUSB_OTG=y
-CONFIG_USB_GADGET_MUSB_HDRC=y
-# CONFIG_MUSB_PIO_ONLY is not set
-CONFIG_USB_MUSB_DEBUG=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_GADGET_DEBUG=y
-CONFIG_USB_GADGET_DEBUG_FILES=y
-CONFIG_USB_ETH=m
-CONFIG_USB_ETH_EEM=y
-CONFIG_MMC=y
-CONFIG_MMC_OMAP=y
-CONFIG_EXT3_FS=y
-CONFIG_INOTIFY=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_JFFS2_LZO=y
-CONFIG_PRINTK_TIME=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
-CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/omap3_defconfig b/arch/arm/configs/omap2plus_defconfig
index 5db9a6be2054..ccedde1371c3 100644
--- a/arch/arm/configs/omap3_defconfig
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -53,18 +53,18 @@ CONFIG_MACH_SBC3530=y
CONFIG_MACH_OMAP_3630SDP=y
CONFIG_MACH_OMAP_4430SDP=y
CONFIG_ARM_THUMBEE=y
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_ERRATA_411920=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
+CONFIG_SMP=y
+# CONFIG_LOCAL_TIMERS is not set
CONFIG_AEABI=y
CONFIG_LEDS=y
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="root=/dev/mmcblk0p2 rootwait console=ttyS2,115200"
+CONFIG_CMDLINE="root=/dev/mmcblk0p2 rootwait console=ttyO2,115200"
CONFIG_KEXEC=y
-CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_STAT_DETAILS=y
-CONFIG_CPU_FREQ_GOV_USERSPACE=y
-CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_FPE_NWFPE=y
CONFIG_VFP=y
CONFIG_NEON=y
@@ -87,23 +87,23 @@ CONFIG_IP_PNP_RARP=y
# CONFIG_INET_LRO is not set
# CONFIG_IPV6 is not set
CONFIG_NETFILTER=y
-CONFIG_BT=y
-CONFIG_BT_L2CAP=y
-CONFIG_BT_SCO=y
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
CONFIG_BT_RFCOMM=y
CONFIG_BT_RFCOMM_TTY=y
-CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP=m
CONFIG_BT_BNEP_MC_FILTER=y
CONFIG_BT_BNEP_PROTO_FILTER=y
-CONFIG_BT_HIDP=y
-CONFIG_BT_HCIUART=y
+CONFIG_BT_HIDP=m
+CONFIG_BT_HCIUART=m
CONFIG_BT_HCIUART_H4=y
CONFIG_BT_HCIUART_BCSP=y
CONFIG_BT_HCIUART_LL=y
-CONFIG_BT_HCIBCM203X=y
-CONFIG_BT_HCIBPA10X=y
-CONFIG_CFG80211=y
-CONFIG_MAC80211=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_CFG80211=m
+CONFIG_MAC80211=m
CONFIG_MAC80211_RC_PID=y
CONFIG_MAC80211_RC_DEFAULT_PID=y
CONFIG_MAC80211_LEDS=y
@@ -137,9 +137,11 @@ CONFIG_SMSC_PHY=y
CONFIG_NET_ETHERNET=y
CONFIG_SMC91X=y
CONFIG_SMSC911X=y
-CONFIG_LIBERTAS=y
-CONFIG_LIBERTAS_USB=y
-CONFIG_LIBERTAS_SDIO=y
+CONFIG_KS8851=y
+CONFIG_KS8851_MLL=y
+CONFIG_LIBERTAS=m
+CONFIG_LIBERTAS_USB=m
+CONFIG_LIBERTAS_SDIO=m
CONFIG_LIBERTAS_DEBUG=y
CONFIG_USB_USBNET=y
CONFIG_USB_ALI_M5632=y
@@ -201,8 +203,8 @@ CONFIG_FONTS=y
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
CONFIG_LOGO=y
-CONFIG_SOUND=y
-CONFIG_SND=y
+CONFIG_SOUND=m
+CONFIG_SND=m
CONFIG_SND_MIXER_OSS=y
CONFIG_SND_PCM_OSS=y
CONFIG_SND_VERBOSE_PRINTK=y
@@ -218,9 +220,9 @@ CONFIG_USB_DEVICEFS=y
CONFIG_USB_SUSPEND=y
# CONFIG_USB_OTG_WHITELIST is not set
CONFIG_USB_MON=y
-CONFIG_USB_MUSB_HDRC=y
-CONFIG_USB_MUSB_OTG=y
-CONFIG_USB_GADGET_MUSB_HDRC=y
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_MUSB_OTG is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
CONFIG_USB_MUSB_DEBUG=y
CONFIG_USB_WDM=y
CONFIG_USB_STORAGE=y
@@ -276,12 +278,11 @@ CONFIG_DEBUG_KERNEL=y
CONFIG_SCHEDSTATS=y
CONFIG_TIMER_STATS=y
CONFIG_PROVE_LOCKING=y
-CONFIG_LOCK_STAT=y
+# CONFIG_LOCK_STAT is not set
CONFIG_DEBUG_SPINLOCK_SLEEP=y
# CONFIG_DEBUG_BUGVERBOSE is not set
CONFIG_DEBUG_INFO=y
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_DEBUG_LL=y
CONFIG_SECURITY=y
CONFIG_CRYPTO_MICHAEL_MIC=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/arm/configs/omap_4430sdp_defconfig b/arch/arm/configs/omap_4430sdp_defconfig
deleted file mode 100644
index 14c1e18c648f..000000000000
--- a/arch/arm/configs/omap_4430sdp_defconfig
+++ /dev/null
@@ -1,125 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EMBEDDED=y
-# CONFIG_SYSCTL_SYSCALL is not set
-# CONFIG_ELF_CORE is not set
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_OMAP=y
-CONFIG_ARCH_OMAP4=y
-# CONFIG_ARCH_OMAP2PLUS_TYPICAL is not set
-# CONFIG_ARCH_OMAP2 is not set
-# CONFIG_ARCH_OMAP3 is not set
-# CONFIG_OMAP_MUX is not set
-CONFIG_OMAP_32K_TIMER=y
-CONFIG_OMAP_DM_TIMER=y
-CONFIG_MACH_OMAP_4430SDP=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_PL310_ERRATA_588369=y
-CONFIG_SMP=y
-CONFIG_NR_CPUS=2
-# CONFIG_LOCAL_TIMERS is not set
-CONFIG_PREEMPT=y
-CONFIG_AEABI=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="root=/dev/ram0 rw mem=128M console=ttyS2,115200n8 initrd=0x81600000,20M ramdisk_size=20480"
-CONFIG_VFP=y
-CONFIG_NEON=y
-CONFIG_BINFMT_MISC=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-# CONFIG_IPV6 is not set
-# CONFIG_WIRELESS is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_FW_LOADER is not set
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=16384
-# CONFIG_MISC_DEVICES is not set
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_KS8851=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_SERIO is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=32
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_MANY_PORTS=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_8250_DETECT_IRQ=y
-CONFIG_SERIAL_8250_RSA=y
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_HW_RANDOM=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_OMAP=y
-CONFIG_SPI=y
-CONFIG_SPI_OMAP24XX=y
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_OMAP_WATCHDOG=y
-CONFIG_TWL4030_CORE=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_TWL4030=y
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-CONFIG_MMC=y
-CONFIG_MMC_OMAP_HS=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_TWL4030=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_FS_XATTR is not set
-CONFIG_INOTIFY=y
-CONFIG_QUOTA=y
-CONFIG_QFMT_V2=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFS_V3_ACL=y
-CONFIG_NFS_V4=y
-CONFIG_ROOT_NFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_ENABLE_WARN_DEPRECATED is not set
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DETECT_SOFTLOCKUP is not set
-CONFIG_DETECT_HUNG_TASK=y
-# CONFIG_SCHED_DEBUG is not set
-# CONFIG_DEBUG_PREEMPT 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_ARM_UNWIND is not set
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_PCBC=m
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-CONFIG_CRC_CCITT=y
-CONFIG_CRC_T10DIF=y
-CONFIG_LIBCRC32C=y
diff --git a/arch/arm/configs/omap_generic_2420_defconfig b/arch/arm/configs/omap_generic_2420_defconfig
deleted file mode 100644
index ac08e51180dd..000000000000
--- a/arch/arm/configs/omap_generic_2420_defconfig
+++ /dev/null
@@ -1,37 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_OMAP=y
-CONFIG_ARCH_OMAP2=y
-# CONFIG_OMAP_MUX is not set
-CONFIG_MACH_OMAP_GENERIC=y
-CONFIG_ARCH_OMAP2420=y
-CONFIG_LEDS=y
-CONFIG_ZBOOT_ROM_TEXT=0x10C08000
-CONFIG_ZBOOT_ROM_BSS=0x10200000
-CONFIG_FPE_NWFPE=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_VIDEO_OUTPUT_CONTROL=m
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_INOTIFY=y
-CONFIG_ROMFS_FS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
-CONFIG_DEBUG_LL=y
-CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/pcontrol_g20_defconfig b/arch/arm/configs/pcontrol_g20_defconfig
new file mode 100644
index 000000000000..b42ee62c4d77
--- /dev/null
+++ b/arch/arm/configs/pcontrol_g20_defconfig
@@ -0,0 +1,175 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_CROSS_COMPILE="/opt/arm-2010q1/bin/arm-none-linux-gnueabi-"
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_TREE_PREEMPT_RCU=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_NAMESPACES=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_KALLSYMS is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_DEFAULT_DEADLINE=y
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91SAM9G20=y
+CONFIG_MACH_PCONTROL_G20=y
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS0,115200 mem=128M mtdparts=atmel_nand:128k(bootstrap)ro,256k(uboot)ro,128k(env1)ro,128k(env2)ro,2M(linux),-(root) root=/dev/mmcblk0p1 rootwait rw"
+CONFIG_VFP=y
+CONFIG_BINFMT_MISC=y
+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_IPV6 is not set
+CONFIG_VLAN_8021Q=y
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FW_LOADER 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_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHRAM=m
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_ATMEL_TCLIB=y
+CONFIG_EEPROM_AT24=m
+CONFIG_SCSI=m
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=m
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_MACVLAN=m
+CONFIG_TUN=m
+CONFIG_SMSC_PHY=m
+CONFIG_BROADCOM_PHY=m
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MACB=y
+CONFIG_SMSC911X=m
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+CONFIG_PPP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_MPPE=m
+CONFIG_INPUT_POLLDEV=y
+CONFIG_INPUT_SPARSEKMAP=y
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=m
+CONFIG_INPUT_EVBUG=m
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=m
+CONFIG_KEYBOARD_MATRIX=m
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=m
+CONFIG_INPUT_GPIO_ROTARY_ENCODER=m
+# CONFIG_SERIO is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_SERIAL_MAX3100=m
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_R3964=m
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_I2C_GPIO=m
+CONFIG_SPI=y
+CONFIG_SPI_ATMEL=m
+CONFIG_SPI_SPIDEV=m
+CONFIG_GPIO_SYSFS=y
+CONFIG_W1=m
+CONFIG_W1_MASTER_GPIO=m
+CONFIG_W1_SLAVE_DS2431=m
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_AT91SAM9X_WATCHDOG=y
+# CONFIG_MFD_SUPPORT is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=m
+CONFIG_USB_LIBUSUAL=y
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_GADGET=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_USB_G_HID=m
+CONFIG_MMC=y
+CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_ATMELMCI=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AT91SAM9=y
+CONFIG_AUXDISPLAY=y
+CONFIG_UIO=y
+CONFIG_UIO_PDRV=y
+CONFIG_STAGING=y
+# CONFIG_STAGING_EXCLUDE_BUILD is not set
+CONFIG_IIO=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V4=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_UTF8=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ANSI_CPRNG=y
+# CONFIG_CRYPTO_HW is not set
+CONFIG_CRC_CCITT=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/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h
index 6bcba48800fe..cc42d5fdee17 100644
--- a/arch/arm/include/asm/hardware/cache-l2x0.h
+++ b/arch/arm/include/asm/hardware/cache-l2x0.h
@@ -21,9 +21,6 @@
#define __ASM_ARM_HARDWARE_L2X0_H
#define L2X0_CACHE_ID 0x000
-#define L2X0_CACHE_ID_PART_MASK (0xf << 6)
-#define L2X0_CACHE_ID_PART_L210 (1 << 6)
-#define L2X0_CACHE_ID_PART_L310 (3 << 6)
#define L2X0_CACHE_TYPE 0x004
#define L2X0_CTRL 0x100
#define L2X0_AUX_CTRL 0x104
@@ -53,6 +50,16 @@
#define L2X0_LINE_DATA 0xF10
#define L2X0_LINE_TAG 0xF30
#define L2X0_DEBUG_CTRL 0xF40
+#define L2X0_PREFETCH_CTRL 0xF60
+#define L2X0_POWER_CTRL 0xF80
+#define L2X0_DYNAMIC_CLK_GATING_EN (1 << 1)
+#define L2X0_STNDBY_MODE_EN (1 << 0)
+
+/* Registers shifts and masks */
+#define L2X0_CACHE_ID_PART_MASK (0xf << 6)
+#define L2X0_CACHE_ID_PART_L210 (1 << 6)
+#define L2X0_CACHE_ID_PART_L310 (3 << 6)
+#define L2X0_AUX_CTRL_WAY_SIZE_MASK (0x3 << 17)
#ifndef __ASSEMBLY__
extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask);
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/highmem.h b/arch/arm/include/asm/highmem.h
index 5aff58126602..1fc684e70ab6 100644
--- a/arch/arm/include/asm/highmem.h
+++ b/arch/arm/include/asm/highmem.h
@@ -35,9 +35,9 @@ extern void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte);
#ifdef CONFIG_HIGHMEM
extern void *kmap(struct page *page);
extern void kunmap(struct page *page);
-extern void *kmap_atomic(struct page *page, enum km_type type);
-extern void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type);
-extern void *kmap_atomic_pfn(unsigned long pfn, enum km_type type);
+extern void *__kmap_atomic(struct page *page);
+extern void __kunmap_atomic(void *kvaddr);
+extern void *kmap_atomic_pfn(unsigned long pfn);
extern struct page *kmap_atomic_to_page(const void *ptr);
#endif
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/kgdb.h b/arch/arm/include/asm/kgdb.h
index 08265993227f..48066ce9ea34 100644
--- a/arch/arm/include/asm/kgdb.h
+++ b/arch/arm/include/asm/kgdb.h
@@ -70,7 +70,8 @@ extern int kgdb_fault_expected;
#define _GP_REGS 16
#define _FP_REGS 8
#define _EXTRA_REGS 2
-#define DBG_MAX_REG_NUM (_GP_REGS + (_FP_REGS * 3) + _EXTRA_REGS)
+#define GDB_MAX_REGS (_GP_REGS + (_FP_REGS * 3) + _EXTRA_REGS)
+#define DBG_MAX_REG_NUM (_GP_REGS + _FP_REGS + _EXTRA_REGS)
#define KGDB_MAX_NO_CPUS 1
#define BUFMAX 400
@@ -93,7 +94,7 @@ extern int kgdb_fault_expected;
#define _SPT 13
#define _LR 14
#define _PC 15
-#define _CPSR (DBG_MAX_REG_NUM - 1)
+#define _CPSR (GDB_MAX_REGS - 1)
/*
* So that we can denote the end of a frame for tracing,
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/memblock.h b/arch/arm/include/asm/memblock.h
index fdbc43b2e6c0..b8da2e415e4e 100644
--- a/arch/arm/include/asm/memblock.h
+++ b/arch/arm/include/asm/memblock.h
@@ -1,13 +1,6 @@
#ifndef _ASM_ARM_MEMBLOCK_H
#define _ASM_ARM_MEMBLOCK_H
-#ifdef CONFIG_MMU
-extern phys_addr_t lowmem_end_addr;
-#define MEMBLOCK_REAL_LIMIT lowmem_end_addr
-#else
-#define MEMBLOCK_REAL_LIMIT 0
-#endif
-
struct meminfo;
struct machine_desc;
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/outercache.h b/arch/arm/include/asm/outercache.h
index 25f76bae57ab..fc1900925275 100644
--- a/arch/arm/include/asm/outercache.h
+++ b/arch/arm/include/asm/outercache.h
@@ -25,6 +25,9 @@ struct outer_cache_fns {
void (*inv_range)(unsigned long, unsigned long);
void (*clean_range)(unsigned long, unsigned long);
void (*flush_range)(unsigned long, unsigned long);
+ void (*flush_all)(void);
+ void (*inv_all)(void);
+ void (*disable)(void);
#ifdef CONFIG_OUTER_CACHE_SYNC
void (*sync)(void);
#endif
@@ -50,6 +53,24 @@ static inline void outer_flush_range(unsigned long start, unsigned long end)
outer_cache.flush_range(start, end);
}
+static inline void outer_flush_all(void)
+{
+ if (outer_cache.flush_all)
+ outer_cache.flush_all();
+}
+
+static inline void outer_inv_all(void)
+{
+ if (outer_cache.inv_all)
+ outer_cache.inv_all();
+}
+
+static inline void outer_disable(void)
+{
+ if (outer_cache.disable)
+ outer_cache.disable();
+}
+
#else
static inline void outer_inv_range(unsigned long start, unsigned long end)
@@ -58,6 +79,9 @@ static inline void outer_clean_range(unsigned long start, unsigned long end)
{ }
static inline void outer_flush_range(unsigned long start, unsigned long end)
{ }
+static inline void outer_flush_all(void) { }
+static inline void outer_inv_all(void) { }
+static inline void outer_disable(void) { }
#endif
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..b155414192da 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -263,24 +263,37 @@ extern struct page *empty_zero_page;
#define pte_page(pte) (pfn_to_page(pte_pfn(pte)))
#define pte_offset_kernel(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr))
-#define pte_offset_map(dir,addr) (__pte_map(dir, KM_PTE0) + __pte_index(addr))
-#define pte_offset_map_nested(dir,addr) (__pte_map(dir, KM_PTE1) + __pte_index(addr))
-#define pte_unmap(pte) __pte_unmap(pte, KM_PTE0)
-#define pte_unmap_nested(pte) __pte_unmap(pte, KM_PTE1)
+#define pte_offset_map(dir,addr) (__pte_map(dir) + __pte_index(addr))
+#define pte_unmap(pte) __pte_unmap(pte)
#ifndef CONFIG_HIGHPTE
-#define __pte_map(dir,km) pmd_page_vaddr(*(dir))
-#define __pte_unmap(pte,km) do { } while (0)
+#define __pte_map(dir) pmd_page_vaddr(*(dir))
+#define __pte_unmap(pte) do { } while (0)
#else
-#define __pte_map(dir,km) ((pte_t *)kmap_atomic(pmd_page(*(dir)), km) + PTRS_PER_PTE)
-#define __pte_unmap(pte,km) kunmap_atomic((pte - PTRS_PER_PTE), km)
+#define __pte_map(dir) ((pte_t *)kmap_atomic(pmd_page(*(dir))) + PTRS_PER_PTE)
+#define __pte_unmap(pte) kunmap_atomic((pte - PTRS_PER_PTE))
#endif
#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 +303,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/kgdb.c b/arch/arm/kernel/kgdb.c
index d6e8b4d2e60d..778c2f7024ff 100644
--- a/arch/arm/kernel/kgdb.c
+++ b/arch/arm/kernel/kgdb.c
@@ -79,7 +79,7 @@ sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
return;
/* Initialize to zero */
- for (regno = 0; regno < DBG_MAX_REG_NUM; regno++)
+ for (regno = 0; regno < GDB_MAX_REGS; regno++)
gdb_regs[regno] = 0;
/* Otherwise, we have only some registers from switch_to() */
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 1fc74cbd1a19..3a8fd5140d7a 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -78,7 +78,10 @@ void machine_kexec(struct kimage *image)
local_fiq_disable();
setup_mm_for_reboot(0); /* mode is not used, so just pass 0*/
flush_cache_all();
+ outer_flush_all();
+ outer_disable();
cpu_proc_fin();
+ outer_inv_all();
flush_cache_all();
cpu_reset(reboot_code_buffer_phys);
}
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..3e97483abcf0 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,13 +849,241 @@ static int ptrace_setvfpregs(struct task_struct *tsk, void __user *data)
}
#endif
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+#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,
+ unsigned long addr, unsigned long data)
{
int ret;
+ unsigned long __user *datap = (unsigned long __user *) data;
switch (request) {
case PTRACE_PEEKUSR:
- ret = ptrace_read_user(child, addr, (unsigned long __user *)data);
+ ret = ptrace_read_user(child, addr, datap);
break;
case PTRACE_POKEUSR:
@@ -861,34 +1091,34 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
case PTRACE_GETREGS:
- ret = ptrace_getregs(child, (void __user *)data);
+ ret = ptrace_getregs(child, datap);
break;
case PTRACE_SETREGS:
- ret = ptrace_setregs(child, (void __user *)data);
+ ret = ptrace_setregs(child, datap);
break;
case PTRACE_GETFPREGS:
- ret = ptrace_getfpregs(child, (void __user *)data);
+ ret = ptrace_getfpregs(child, datap);
break;
case PTRACE_SETFPREGS:
- ret = ptrace_setfpregs(child, (void __user *)data);
+ ret = ptrace_setfpregs(child, datap);
break;
#ifdef CONFIG_IWMMXT
case PTRACE_GETWMMXREGS:
- ret = ptrace_getwmmxregs(child, (void __user *)data);
+ ret = ptrace_getwmmxregs(child, datap);
break;
case PTRACE_SETWMMXREGS:
- ret = ptrace_setwmmxregs(child, (void __user *)data);
+ ret = ptrace_setwmmxregs(child, datap);
break;
#endif
case PTRACE_GET_THREAD_AREA:
ret = put_user(task_thread_info(child)->tp_value,
- (unsigned long __user *) data);
+ datap);
break;
case PTRACE_SET_SYSCALL:
@@ -898,21 +1128,32 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
#ifdef CONFIG_CRUNCH
case PTRACE_GETCRUNCHREGS:
- ret = ptrace_getcrunchregs(child, (void __user *)data);
+ ret = ptrace_getcrunchregs(child, datap);
break;
case PTRACE_SETCRUNCHREGS:
- ret = ptrace_setcrunchregs(child, (void __user *)data);
+ ret = ptrace_setcrunchregs(child, datap);
break;
#endif
#ifdef CONFIG_VFP
case PTRACE_GETVFPREGS:
- ret = ptrace_getvfpregs(child, (void __user *)data);
+ ret = ptrace_getvfpregs(child, datap);
break;
case PTRACE_SETVFPREGS:
- ret = ptrace_setvfpregs(child, (void __user *)data);
+ ret = ptrace_setvfpregs(child, datap);
+ 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
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..cead8893b46b 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)
@@ -99,13 +113,13 @@ SECTIONS
*(.rodata.*)
*(.glue_7)
*(.glue_7t)
+ . = ALIGN(4);
*(.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 +137,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 +253,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..c015b684b4fe 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
@@ -364,6 +375,12 @@ config MACH_STAMP9G20
evaluation board.
<http://www.taskit.de/en/>
+config MACH_PCONTROL_G20
+ bool "PControl G20 CPU module"
+ help
+ Select this if you are using taskit's Stamp9G20 CPU module on this
+ carrier board, beeing the decentralized unit of a building automation
+ system; featuring nvram, eth-switch, iso-rs485, display, io
endif
if (ARCH_AT91SAM9260 || ARCH_AT91SAM9G20)
@@ -383,8 +400,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..821eb842795f 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -11,12 +11,12 @@ obj-$(CONFIG_AT91_PMC_UNIT) += clock.o
# CPU-specific support
obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.o
-obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o
-obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o
-obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o
-obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o
-obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o
-obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o at91sam9_alt_reset.o
+obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o at91sam9_alt_reset.o
+obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o at91sam9_alt_reset.o
+obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o at91sam9_alt_reset.o
+obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o at91sam9_alt_reset.o
+obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o at91sam9_alt_reset.o
obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o
obj-$(CONFIG_ARCH_AT572D940HF) += at572d940hf.o at91sam926x_time.o at572d940hf_devices.o sam9_smc.o
@@ -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,16 +62,16 @@ 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
+obj-$(CONFIG_MACH_PCONTROL_G20) += board-pcontrol-g20.o
# AT91SAM9260/AT91SAM9G20 board-specific support
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/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
index 0894f1077be7..195208b30024 100644
--- a/arch/arm/mach-at91/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -279,11 +279,6 @@ static struct at91_gpio_bank at91sam9260_gpio[] = {
}
};
-static void at91sam9260_reset(void)
-{
- at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
-}
-
static void at91sam9260_poweroff(void)
{
at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
@@ -327,7 +322,7 @@ void __init at91sam9260_initialize(unsigned long main_clock)
else
iotable_init(at91sam9260_sram_desc, ARRAY_SIZE(at91sam9260_sram_desc));
- at91_arch_reset = at91sam9260_reset;
+ at91_arch_reset = at91sam9_alt_reset;
pm_power_off = at91sam9260_poweroff;
at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1)
| (1 << AT91SAM9260_ID_IRQ2);
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
index 4ecf37996c77..fcad88668504 100644
--- a/arch/arm/mach-at91/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -257,11 +257,6 @@ static struct at91_gpio_bank at91sam9261_gpio[] = {
}
};
-static void at91sam9261_reset(void)
-{
- at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
-}
-
static void at91sam9261_poweroff(void)
{
at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
@@ -283,7 +278,7 @@ void __init at91sam9261_initialize(unsigned long main_clock)
iotable_init(at91sam9261_sram_desc, ARRAY_SIZE(at91sam9261_sram_desc));
- at91_arch_reset = at91sam9261_reset;
+ at91_arch_reset = at91sam9_alt_reset;
pm_power_off = at91sam9261_poweroff;
at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1)
| (1 << AT91SAM9261_ID_IRQ2);
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
index 942792d630d8..249f900954d8 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -269,11 +269,6 @@ static struct at91_gpio_bank at91sam9263_gpio[] = {
}
};
-static void at91sam9263_reset(void)
-{
- at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
-}
-
static void at91sam9263_poweroff(void)
{
at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
@@ -289,7 +284,7 @@ void __init at91sam9263_initialize(unsigned long main_clock)
/* Map peripherals */
iotable_init(at91sam9263_io_desc, ARRAY_SIZE(at91sam9263_io_desc));
- at91_arch_reset = at91sam9263_reset;
+ at91_arch_reset = at91sam9_alt_reset;
pm_power_off = at91sam9263_poweroff;
at91_extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1);
diff --git a/arch/arm/mach-at91/at91sam9_alt_reset.S b/arch/arm/mach-at91/at91sam9_alt_reset.S
new file mode 100644
index 000000000000..e0256deb91fb
--- /dev/null
+++ b/arch/arm/mach-at91/at91sam9_alt_reset.S
@@ -0,0 +1,48 @@
+/*
+ * reset AT91SAM9G20 as per errata
+ *
+ * (C) BitBox Ltd 2010
+ *
+ * unless the SDRAM is cleanly shutdown before we hit the
+ * reset register it can be left driving the data bus and
+ * killing the chance of a subsequent boot from NAND
+ *
+ * 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/linkage.h>
+#include <asm/system.h>
+#include <mach/hardware.h>
+#include <mach/at91sam9_sdramc.h>
+#include <mach/at91_rstc.h>
+
+ .arm
+
+ .globl at91sam9_alt_reset
+
+at91sam9_alt_reset: mrc p15, 0, r0, c1, c0, 0
+ orr r0, r0, #CR_I
+ mcr p15, 0, r0, c1, c0, 0 @ enable I-cache
+
+ ldr r0, .at91_va_base_sdramc @ preload constants
+ ldr r1, .at91_va_base_rstc_cr
+
+ mov r2, #1
+ mov r3, #AT91_SDRAMC_LPCB_POWER_DOWN
+ ldr r4, =AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST
+
+ .balign 32 @ align to cache line
+
+ str r2, [r0, #AT91_SDRAMC_TR] @ disable SDRAM access
+ str r3, [r0, #AT91_SDRAMC_LPR] @ power down SDRAM
+ str r4, [r1] @ reset processor
+
+ b .
+
+.at91_va_base_sdramc:
+ .word AT91_VA_BASE_SYS + AT91_SDRAMC0
+.at91_va_base_rstc_cr:
+ .word AT91_VA_BASE_SYS + AT91_RSTC_CR
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
index 1276babf84d5..1e8f275c17f6 100644
--- a/arch/arm/mach-at91/at91sam9g45_devices.c
+++ b/arch/arm/mach-at91/at91sam9g45_devices.c
@@ -15,6 +15,7 @@
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/i2c-gpio.h>
+#include <linux/atmel-mci.h>
#include <linux/fb.h>
#include <video/atmel_lcdc.h>
@@ -25,6 +26,7 @@
#include <mach/at91sam9g45_matrix.h>
#include <mach/at91sam9_smc.h>
#include <mach/at_hdmac.h>
+#include <mach/atmel-mci.h>
#include "generic.h"
@@ -350,6 +352,169 @@ void __init at91_add_device_eth(struct at91_eth_data *data) {}
/* --------------------------------------------------------------------
+ * MMC / SD
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
+static u64 mmc_dmamask = DMA_BIT_MASK(32);
+static struct mci_platform_data mmc0_data, mmc1_data;
+
+static struct resource mmc0_resources[] = {
+ [0] = {
+ .start = AT91SAM9G45_BASE_MCI0,
+ .end = AT91SAM9G45_BASE_MCI0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9G45_ID_MCI0,
+ .end = AT91SAM9G45_ID_MCI0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9g45_mmc0_device = {
+ .name = "atmel_mci",
+ .id = 0,
+ .dev = {
+ .dma_mask = &mmc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &mmc0_data,
+ },
+ .resource = mmc0_resources,
+ .num_resources = ARRAY_SIZE(mmc0_resources),
+};
+
+static struct resource mmc1_resources[] = {
+ [0] = {
+ .start = AT91SAM9G45_BASE_MCI1,
+ .end = AT91SAM9G45_BASE_MCI1 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9G45_ID_MCI1,
+ .end = AT91SAM9G45_ID_MCI1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9g45_mmc1_device = {
+ .name = "atmel_mci",
+ .id = 1,
+ .dev = {
+ .dma_mask = &mmc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &mmc1_data,
+ },
+ .resource = mmc1_resources,
+ .num_resources = ARRAY_SIZE(mmc1_resources),
+};
+
+/* Consider only one slot : slot 0 */
+void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data)
+{
+
+ if (!data)
+ return;
+
+ /* Must have at least one usable slot */
+ if (!data->slot[0].bus_width)
+ return;
+
+#if defined(CONFIG_AT_HDMAC) || defined(CONFIG_AT_HDMAC_MODULE)
+ {
+ struct at_dma_slave *atslave;
+ struct mci_dma_data *alt_atslave;
+
+ alt_atslave = kzalloc(sizeof(struct mci_dma_data), GFP_KERNEL);
+ atslave = &alt_atslave->sdata;
+
+ /* DMA slave channel configuration */
+ atslave->dma_dev = &at_hdmac_device.dev;
+ atslave->reg_width = AT_DMA_SLAVE_WIDTH_32BIT;
+ atslave->cfg = ATC_FIFOCFG_HALFFIFO
+ | ATC_SRC_H2SEL_HW | ATC_DST_H2SEL_HW;
+ atslave->ctrla = ATC_SCSIZE_16 | ATC_DCSIZE_16;
+ if (mmc_id == 0) /* MCI0 */
+ atslave->cfg |= ATC_SRC_PER(AT_DMA_ID_MCI0)
+ | ATC_DST_PER(AT_DMA_ID_MCI0);
+
+ else /* MCI1 */
+ atslave->cfg |= ATC_SRC_PER(AT_DMA_ID_MCI1)
+ | ATC_DST_PER(AT_DMA_ID_MCI1);
+
+ data->dma_slave = alt_atslave;
+ }
+#endif
+
+
+ /* input/irq */
+ if (data->slot[0].detect_pin) {
+ at91_set_gpio_input(data->slot[0].detect_pin, 1);
+ at91_set_deglitch(data->slot[0].detect_pin, 1);
+ }
+ if (data->slot[0].wp_pin)
+ at91_set_gpio_input(data->slot[0].wp_pin, 1);
+
+ if (mmc_id == 0) { /* MCI0 */
+
+ /* CLK */
+ at91_set_A_periph(AT91_PIN_PA0, 0);
+
+ /* CMD */
+ at91_set_A_periph(AT91_PIN_PA1, 1);
+
+ /* DAT0, maybe DAT1..DAT3 and maybe DAT4..DAT7 */
+ at91_set_A_periph(AT91_PIN_PA2, 1);
+ if (data->slot[0].bus_width == 4) {
+ at91_set_A_periph(AT91_PIN_PA3, 1);
+ at91_set_A_periph(AT91_PIN_PA4, 1);
+ at91_set_A_periph(AT91_PIN_PA5, 1);
+ if (data->slot[0].bus_width == 8) {
+ at91_set_A_periph(AT91_PIN_PA6, 1);
+ at91_set_A_periph(AT91_PIN_PA7, 1);
+ at91_set_A_periph(AT91_PIN_PA8, 1);
+ at91_set_A_periph(AT91_PIN_PA9, 1);
+ }
+ }
+
+ mmc0_data = *data;
+ at91_clock_associate("mci0_clk", &at91sam9g45_mmc0_device.dev, "mci_clk");
+ platform_device_register(&at91sam9g45_mmc0_device);
+
+ } else { /* MCI1 */
+
+ /* CLK */
+ at91_set_A_periph(AT91_PIN_PA31, 0);
+
+ /* CMD */
+ at91_set_A_periph(AT91_PIN_PA22, 1);
+
+ /* DAT0, maybe DAT1..DAT3 and maybe DAT4..DAT7 */
+ at91_set_A_periph(AT91_PIN_PA23, 1);
+ if (data->slot[0].bus_width == 4) {
+ at91_set_A_periph(AT91_PIN_PA24, 1);
+ at91_set_A_periph(AT91_PIN_PA25, 1);
+ at91_set_A_periph(AT91_PIN_PA26, 1);
+ if (data->slot[0].bus_width == 8) {
+ at91_set_A_periph(AT91_PIN_PA27, 1);
+ at91_set_A_periph(AT91_PIN_PA28, 1);
+ at91_set_A_periph(AT91_PIN_PA29, 1);
+ at91_set_A_periph(AT91_PIN_PA30, 1);
+ }
+ }
+
+ mmc1_data = *data;
+ at91_clock_associate("mci1_clk", &at91sam9g45_mmc1_device.dev, "mci_clk");
+ platform_device_register(&at91sam9g45_mmc1_device);
+
+ }
+}
+#else
+void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
* NAND / SmartMedia
* -------------------------------------------------------------------- */
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c
index 211c5c14a1e6..6a9d24e5ed8e 100644
--- a/arch/arm/mach-at91/at91sam9rl.c
+++ b/arch/arm/mach-at91/at91sam9rl.c
@@ -242,11 +242,6 @@ static struct at91_gpio_bank at91sam9rl_gpio[] = {
}
};
-static void at91sam9rl_reset(void)
-{
- at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
-}
-
static void at91sam9rl_poweroff(void)
{
at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
@@ -281,7 +276,7 @@ void __init at91sam9rl_initialize(unsigned long main_clock)
/* Map SRAM */
iotable_init(at91sam9rl_sram_desc, ARRAY_SIZE(at91sam9rl_sram_desc));
- at91_arch_reset = at91sam9rl_reset;
+ at91_arch_reset = at91sam9_alt_reset;
pm_power_off = at91sam9rl_poweroff;
at91_extern_irq = (1 << AT91SAM9RL_ID_IRQ0);
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-pcontrol-g20.c b/arch/arm/mach-at91/board-pcontrol-g20.c
new file mode 100644
index 000000000000..bba5a560e02b
--- /dev/null
+++ b/arch/arm/mach-at91/board-pcontrol-g20.c
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2010 Christian Glindkamp <christian.glindkamp@taskit.de>
+ * taskit GmbH
+ *
+ * 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
+ */
+/*
+ * copied and adjusted from board-stamp9g20.c
+ * by Peter Gsellmann <pgsellmann@portner-elektronik.at>
+ */
+
+#include <linux/mm.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/w1-gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/board.h>
+#include <mach/at91sam9_smc.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+
+static void __init pcontrol_g20_map_io(void)
+{
+ /* Initialize processor: 18.432 MHz crystal */
+ at91sam9260_initialize(18432000);
+
+ /* DGBU on ttyS0. (Rx, Tx) only TTL -> JTAG connector X7 17,19 ) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) piggyback A2 */
+ at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS
+ | ATMEL_UART_RTS);
+
+ /* USART1 on ttyS2. (Rx, Tx, CTS, RTS) isolated RS485 X5 */
+ at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS
+ | ATMEL_UART_RTS);
+
+ /* USART2 on ttyS3. (Rx, Tx) 9bit-Bus Multidrop-mode X4 */
+ at91_register_uart(AT91SAM9260_ID_US4, 3, 0);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+
+static void __init init_irq(void)
+{
+ at91sam9260_init_interrupts(NULL);
+}
+
+
+/*
+ * NAND flash 512MiB 1,8V 8-bit, sector size 128 KiB
+ */
+static struct atmel_nand_data __initdata nand_data = {
+ .ale = 21,
+ .cle = 22,
+ .rdy_pin = AT91_PIN_PC13,
+ .enable_pin = AT91_PIN_PC14,
+};
+
+/*
+ * Bus timings; unit = 7.57ns
+ */
+static struct sam9_smc_config __initdata 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 | AT91_SMC_DBW_8,
+ .tdf_cycles = 3,
+};
+
+static struct sam9_smc_config __initdata pcontrol_smc_config[2] = { {
+ .ncs_read_setup = 16,
+ .nrd_setup = 18,
+ .ncs_write_setup = 16,
+ .nwe_setup = 18,
+
+ .ncs_read_pulse = 63,
+ .nrd_pulse = 55,
+ .ncs_write_pulse = 63,
+ .nwe_pulse = 55,
+
+ .read_cycle = 127,
+ .write_cycle = 127,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE
+ | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_SELECT
+ | AT91_SMC_DBW_8 | AT91_SMC_PS_4
+ | AT91_SMC_TDFMODE,
+ .tdf_cycles = 3,
+}, {
+ .ncs_read_setup = 0,
+ .nrd_setup = 0,
+ .ncs_write_setup = 0,
+ .nwe_setup = 1,
+
+ .ncs_read_pulse = 8,
+ .nrd_pulse = 8,
+ .ncs_write_pulse = 5,
+ .nwe_pulse = 4,
+
+ .read_cycle = 8,
+ .write_cycle = 7,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE
+ | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_SELECT
+ | AT91_SMC_DBW_16 | AT91_SMC_PS_8
+ | AT91_SMC_TDFMODE,
+ .tdf_cycles = 1,
+} };
+
+static void __init add_device_nand(void)
+{
+ /* configure chip-select 3 (NAND) */
+ sam9_smc_configure(3, &nand_smc_config);
+ at91_add_device_nand(&nand_data);
+}
+
+
+static void __init add_device_pcontrol(void)
+{
+ /* configure chip-select 4 (IO compatible to 8051 X4 ) */
+ sam9_smc_configure(4, &pcontrol_smc_config[0]);
+ /* configure chip-select 7 (FerroRAM 256KiBx16bit MR2A16A D4 ) */
+ sam9_smc_configure(7, &pcontrol_smc_config[1]);
+}
+
+
+/*
+ * MCI (SD/MMC)
+ * det_pin, wp_pin and vcc_pin are not connected
+ */
+#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
+static struct mci_platform_data __initdata mmc_data = {
+ .slot[0] = {
+ .bus_width = 4,
+ },
+};
+#else
+static struct at91_mmc_data __initdata mmc_data = {
+ .wire4 = 1,
+};
+#endif
+
+
+/*
+ * USB Host port
+ */
+static struct at91_usbh_data __initdata usbh_data = {
+ .ports = 2,
+};
+
+
+/*
+ * USB Device port
+ */
+static struct at91_udc_data __initdata pcontrol_g20_udc_data = {
+ .vbus_pin = AT91_PIN_PA22, /* Detect +5V bus voltage */
+ .pullup_pin = AT91_PIN_PA4, /* K-state, active low */
+};
+
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata macb_data = {
+ .phy_irq_pin = AT91_PIN_PA28,
+ .is_rmii = 1,
+};
+
+
+/*
+ * I2C devices: eeprom and phy/switch
+ */
+static struct i2c_board_info __initdata pcontrol_g20_i2c_devices[] = {
+{ /* D7 address width=2, 8KiB */
+ I2C_BOARD_INFO("24c64", 0x50)
+}, { /* D8 address width=1, 1 byte has 32 bits! */
+ I2C_BOARD_INFO("lan9303", 0x0a)
+}, };
+
+
+/*
+ * LEDs
+ */
+static struct gpio_led pcontrol_g20_leds[] = {
+ {
+ .name = "LED1", /* red H5 */
+ .gpio = AT91_PIN_PB18,
+ .active_low = 1,
+ .default_trigger = "none", /* supervisor */
+ }, {
+ .name = "LED2", /* yellow H7 */
+ .gpio = AT91_PIN_PB19,
+ .active_low = 1,
+ .default_trigger = "mmc0", /* SD-card activity */
+ }, {
+ .name = "LED3", /* green H2 */
+ .gpio = AT91_PIN_PB20,
+ .active_low = 1,
+ .default_trigger = "heartbeat", /* blinky */
+ }, {
+ .name = "LED4", /* red H3 */
+ .gpio = AT91_PIN_PC6,
+ .active_low = 1,
+ .default_trigger = "none", /* connection lost */
+ }, {
+ .name = "LED5", /* yellow H6 */
+ .gpio = AT91_PIN_PC7,
+ .active_low = 1,
+ .default_trigger = "none", /* unsent data */
+ }, {
+ .name = "LED6", /* green H1 */
+ .gpio = AT91_PIN_PC9,
+ .active_low = 1,
+ .default_trigger = "none", /* snafu */
+ }
+};
+
+
+/*
+ * SPI devices
+ */
+static struct spi_board_info pcontrol_g20_spi_devices[] = {
+ {
+ .modalias = "spidev", /* HMI port X4 */
+ .chip_select = 1,
+ .max_speed_hz = 50 * 1000 * 1000,
+ .bus_num = 0,
+ }, {
+ .modalias = "spidev", /* piggyback A2 */
+ .chip_select = 0,
+ .max_speed_hz = 50 * 1000 * 1000,
+ .bus_num = 1,
+ },
+};
+
+
+/*
+ * Dallas 1-Wire DS2431
+ */
+static struct w1_gpio_platform_data w1_gpio_pdata = {
+ .pin = AT91_PIN_PA29,
+ .is_open_drain = 1,
+};
+
+static struct platform_device w1_device = {
+ .name = "w1-gpio",
+ .id = -1,
+ .dev.platform_data = &w1_gpio_pdata,
+};
+
+static void add_wire1(void)
+{
+ at91_set_GPIO_periph(w1_gpio_pdata.pin, 1);
+ at91_set_multi_drive(w1_gpio_pdata.pin, 1);
+ platform_device_register(&w1_device);
+}
+
+
+static void __init pcontrol_g20_board_init(void)
+{
+ at91_add_device_serial();
+ add_device_nand();
+#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
+ at91_add_device_mci(0, &mmc_data);
+#else
+ at91_add_device_mmc(0, &mmc_data);
+#endif
+ at91_add_device_usbh(&usbh_data);
+ at91_add_device_eth(&macb_data);
+ at91_add_device_i2c(pcontrol_g20_i2c_devices,
+ ARRAY_SIZE(pcontrol_g20_i2c_devices));
+ add_wire1();
+ add_device_pcontrol();
+ at91_add_device_spi(pcontrol_g20_spi_devices,
+ ARRAY_SIZE(pcontrol_g20_spi_devices));
+ at91_add_device_udc(&pcontrol_g20_udc_data);
+ at91_gpio_leds(pcontrol_g20_leds,
+ ARRAY_SIZE(pcontrol_g20_leds));
+ /* piggyback A2 */
+ at91_set_gpio_output(AT91_PIN_PB31, 1);
+}
+
+
+MACHINE_START(PCONTROL_G20, "PControl G20")
+ /* Maintainer: pgsellmann@portner-elektronik.at */
+ .boot_params = AT91_SDRAM_BASE + 0x100,
+ .timer = &at91sam926x_timer,
+ .map_io = pcontrol_g20_map_io,
+ .init_irq = init_irq,
+ .init_machine = pcontrol_g20_board_init,
+MACHINE_END
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..86ff4b52db32 100644
--- a/arch/arm/mach-at91/board-sam9m10g45ek.c
+++ b/arch/arm/mach-at91/board-sam9m10g45ek.c
@@ -24,7 +24,9 @@
#include <linux/input.h>
#include <linux/leds.h>
#include <linux/clk.h>
+#include <linux/atmel-mci.h>
+#include <mach/hardware.h>
#include <video/atmel_lcdc.h>
#include <asm/setup.h>
@@ -98,6 +100,25 @@ static struct spi_board_info ek_spi_devices[] = {
/*
+ * MCI (SD/MMC)
+ */
+static struct mci_platform_data __initdata mci0_data = {
+ .slot[0] = {
+ .bus_width = 4,
+ .detect_pin = AT91_PIN_PD10,
+ },
+};
+
+static struct mci_platform_data __initdata mci1_data = {
+ .slot[0] = {
+ .bus_width = 4,
+ .detect_pin = AT91_PIN_PD11,
+ .wp_pin = AT91_PIN_PD29,
+ },
+};
+
+
+/*
* MACB Ethernet device
*/
static struct at91_eth_data __initdata ek_macb_data = {
@@ -135,7 +156,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,
@@ -380,6 +401,9 @@ static void __init ek_board_init(void)
at91_add_device_usba(&ek_usba_udc_data);
/* SPI */
at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
+ /* MMC */
+ at91_add_device_mci(0, &mci0_data);
+ at91_add_device_mci(1, &mci1_data);
/* Ethernet */
at91_add_device_eth(&ek_macb_data);
/* NAND */
@@ -399,10 +423,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/generic.h b/arch/arm/mach-at91/generic.h
index 65c3dc5ba0d0..0c66deb2db39 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -46,6 +46,9 @@ extern void __init at91_clock_associate(const char *id, struct device *dev, cons
extern void at91_irq_suspend(void);
extern void at91_irq_resume(void);
+/* reset */
+extern void at91sam9_alt_reset(void);
+
/* GPIO */
#define AT91RM9200_PQFP 3 /* AT91RM9200 PQFP package has 3 banks */
#define AT91RM9200_BGA 4 /* AT91RM9200 BGA package has 4 banks */
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 ee8db152592e..36af14bc13bb 100644
--- a/arch/arm/mach-at91/include/mach/system.h
+++ b/arch/arm/mach-at91/include/mach/system.h
@@ -32,7 +32,11 @@ static inline void arch_idle(void)
* Disable the processor clock. The processor will be automatically
* re-enabled by an interrupt or by a reset.
*/
+#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.
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 615668986480..dafbacc25eb1 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -258,16 +258,23 @@ static int at91_pm_enter(suspend_state_t state)
* NOTE: the Wait-for-Interrupt instruction needs to be
* in icache so no SDRAM accesses are needed until the
* wakeup IRQ occurs and self-refresh is terminated.
+ * For ARM 926 based chips, this requirement is weaker
+ * as at91sam9 can access a RAM in self-refresh mode.
*/
- asm("b 1f; .align 5; 1:");
- asm("mcr p15, 0, r0, c7, c10, 4"); /* drain write buffer */
+ asm volatile ( "mov r0, #0\n\t"
+ "b 1f\n\t"
+ ".align 5\n\t"
+ "1: mcr p15, 0, r0, c7, c10, 4\n\t"
+ : /* no output */
+ : /* no input */
+ : "r0");
saved_lpr = sdram_selfrefresh_enable();
- asm("mcr p15, 0, r0, c7, c0, 4"); /* wait for interrupt */
+ wait_for_interrupt_enable();
sdram_selfrefresh_disable(saved_lpr);
break;
case PM_SUSPEND_ON:
- asm("mcr p15, 0, r0, c7, c0, 4"); /* wait for interrupt */
+ cpu_do_idle();
break;
default:
diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
index 8c87d0c1b8f8..ce9a20699111 100644
--- a/arch/arm/mach-at91/pm.h
+++ b/arch/arm/mach-at91/pm.h
@@ -21,6 +21,8 @@ static inline u32 sdram_selfrefresh_enable(void)
}
#define sdram_selfrefresh_disable(saved_lpr) at91_sys_write(AT91_SDRAMC_LPR, saved_lpr)
+#define wait_for_interrupt_enable() asm volatile ("mcr p15, 0, %0, c7, c0, 4" \
+ : : "r" (0))
#elif defined(CONFIG_ARCH_AT91CAP9)
#include <mach/at91cap9_ddrsdr.h>
@@ -38,6 +40,7 @@ static inline u32 sdram_selfrefresh_enable(void)
}
#define sdram_selfrefresh_disable(saved_lpr) at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr)
+#define wait_for_interrupt_enable() cpu_do_idle()
#elif defined(CONFIG_ARCH_AT91SAM9G45)
#include <mach/at91sam9_ddrsdr.h>
@@ -74,6 +77,7 @@ static inline u32 sdram_selfrefresh_enable(void)
at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0); \
at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1); \
} while (0)
+#define wait_for_interrupt_enable() cpu_do_idle()
#else
#include <mach/at91sam9_sdramc.h>
@@ -98,5 +102,6 @@ static inline u32 sdram_selfrefresh_enable(void)
}
#define sdram_selfrefresh_disable(saved_lpr) at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr)
+#define wait_for_interrupt_enable() cpu_do_idle()
#endif
diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S
index b6b00a1f6125..f7922a436172 100644
--- a/arch/arm/mach-at91/pm_slowclock.S
+++ b/arch/arm/mach-at91/pm_slowclock.S
@@ -124,6 +124,7 @@ ENTRY(at91_slow_clock)
ldr r5, .at91_va_base_ramc1
/* Drain write buffer */
+ mov r0, #0
mcr p15, 0, r0, c7, c10, 4
#ifdef CONFIG_ARCH_AT91RM9200
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/Kconfig b/arch/arm/mach-davinci/Kconfig
index 71f90f864748..b77b860b36d7 100644
--- a/arch/arm/mach-davinci/Kconfig
+++ b/arch/arm/mach-davinci/Kconfig
@@ -20,23 +20,23 @@ config ARCH_DAVINCI_DM644x
select ARCH_DAVINCI_DMx
config ARCH_DAVINCI_DM355
- bool "DaVinci 355 based system"
+ bool "DaVinci 355 based system"
select AINTC
select ARCH_DAVINCI_DMx
config ARCH_DAVINCI_DM646x
- bool "DaVinci 646x based system"
+ bool "DaVinci 646x based system"
select AINTC
select ARCH_DAVINCI_DMx
config ARCH_DAVINCI_DA830
- bool "DA830/OMAP-L137 based system"
+ bool "DA830/OMAP-L137/AM17x based system"
select CP_INTC
select ARCH_DAVINCI_DA8XX
select CPU_DCACHE_WRITETHROUGH # needed on silicon revs 1.0, 1.1
config ARCH_DAVINCI_DA850
- bool "DA850/OMAP-L138 based system"
+ bool "DA850/OMAP-L138/AM18x based system"
select CP_INTC
select ARCH_DAVINCI_DA8XX
select ARCH_HAS_CPUFREQ
@@ -115,21 +115,21 @@ config MACH_DAVINCI_DM365_EVM
for development is a DM365 EVM
config MACH_DAVINCI_DA830_EVM
- bool "TI DA830/OMAP-L137 Reference Platform"
+ bool "TI DA830/OMAP-L137/AM17x Reference Platform"
default ARCH_DAVINCI_DA830
depends on ARCH_DAVINCI_DA830
select GPIO_PCF857X
help
- Say Y here to select the TI DA830/OMAP-L137 Evaluation Module.
+ Say Y here to select the TI DA830/OMAP-L137/AM17x Evaluation Module.
choice
- prompt "Select DA830/OMAP-L137 UI board peripheral"
+ prompt "Select DA830/OMAP-L137/AM17x UI board peripheral"
depends on MACH_DAVINCI_DA830_EVM
help
- The presence of UI card on the DA830/OMAP-L137 EVM is detected
- automatically based on successful probe of the I2C based GPIO
- expander on that board. This option selected in this menu has
- an effect only in case of a successful UI card detection.
+ The presence of UI card on the DA830/OMAP-L137/AM17x EVM is
+ detected automatically based on successful probe of the I2C
+ based GPIO expander on that board. This option selected in this
+ menu has an effect only in case of a successful UI card detection.
config DA830_UI_LCD
bool "LCD"
@@ -140,23 +140,23 @@ config DA830_UI_LCD
config DA830_UI_NAND
bool "NAND flash"
help
- Say Y here to use the NAND flash. Do not forget to setup
+ Say Y here to use the NAND flash. Do not forget to setup
the switch correctly.
endchoice
config MACH_DAVINCI_DA850_EVM
- bool "TI DA850/OMAP-L138 Reference Platform"
+ bool "TI DA850/OMAP-L138/AM18x Reference Platform"
default ARCH_DAVINCI_DA850
depends on ARCH_DAVINCI_DA850
select GPIO_PCA953X
help
- Say Y here to select the TI DA850/OMAP-L138 Evaluation Module.
+ Say Y here to select the TI DA850/OMAP-L138/AM18x Evaluation Module.
choice
prompt "Select peripherals connected to expander on UI board"
depends on MACH_DAVINCI_DA850_EVM
help
- The presence of User Interface (UI) card on the DA850/OMAP-L138
+ The presence of User Interface (UI) card on the DA850/OMAP-L138/AM18x
EVM is detected automatically based on successful probe of the I2C
based GPIO expander on that card. This option selected in this
menu has an effect only in case of a successful UI card detection.
@@ -165,13 +165,13 @@ config DA850_UI_NONE
bool "No peripheral is enabled"
help
Say Y if you do not want to enable any of the peripherals connected
- to TCA6416 expander on DA850/OMAP-L138 EVM UI card
+ to TCA6416 expander on DA850/OMAP-L138/AM18x EVM UI card
config DA850_UI_RMII
bool "RMII Ethernet PHY"
help
- Say Y if you want to use the RMII PHY on the DA850/OMAP-L138 EVM.
- This PHY is found on the UI daughter card that is supplied with
+ Say Y if you want to use the RMII PHY on the DA850/OMAP-L138/AM18x
+ EVM. This PHY is found on the UI daughter card that is supplied with
the EVM.
NOTE: Please take care while choosing this option, MII PHY will
not be functional if RMII mode is selected.
@@ -185,6 +185,22 @@ config MACH_TNETV107X
help
Say Y here to select the TI TNETV107X Evaluation Module.
+config MACH_MITYOMAPL138
+ bool "Critical Link MityDSP-L138/MityARM-1808 SoM"
+ depends on ARCH_DAVINCI_DA850
+ help
+ Say Y here to select the Critical Link MityDSP-L138/MityARM-1808
+ System on Module. Information on this SoM may be found at
+ http://www.mitydsp.com
+
+config MACH_OMAPL138_HAWKBOARD
+ bool "TI AM1808 / OMAPL-138 Hawkboard platform"
+ depends on ARCH_DAVINCI_DA850
+ help
+ Say Y here to select the TI AM1808 / OMAPL-138 Hawkboard platform .
+ Information of this board may be found at
+ http://www.hawkboard.org/
+
config DAVINCI_MUX
bool "DAVINCI multiplexing support"
depends on ARCH_DAVINCI
@@ -195,20 +211,20 @@ config DAVINCI_MUX
say Y.
config DAVINCI_MUX_DEBUG
- bool "Multiplexing debug output"
- depends on DAVINCI_MUX
- help
- Makes the multiplexing functions print out a lot of debug info.
- This is useful if you want to find out the correct values of the
- multiplexing registers.
+ bool "Multiplexing debug output"
+ depends on DAVINCI_MUX
+ help
+ Makes the multiplexing functions print out a lot of debug info.
+ This is useful if you want to find out the correct values of the
+ multiplexing registers.
config DAVINCI_MUX_WARNINGS
- bool "Warn about pins the bootloader didn't set up"
- depends on DAVINCI_MUX
- help
- Choose Y here to warn whenever driver initialization logic needs
- to change the pin multiplexing setup. When there are no warnings
- printed, it's safe to deselect DAVINCI_MUX for your product.
+ bool "Warn about pins the bootloader didn't set up"
+ depends on DAVINCI_MUX
+ help
+ Choose Y here to warn whenever driver initialization logic needs
+ to change the pin multiplexing setup. When there are no warnings
+ printed, it's safe to deselect DAVINCI_MUX for your product.
config DAVINCI_RESET_CLOCKS
bool "Reset unused clocks during boot"
diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile
index eab4c0fd667a..0b87a1ca2bb3 100644
--- a/arch/arm/mach-davinci/Makefile
+++ b/arch/arm/mach-davinci/Makefile
@@ -5,7 +5,7 @@
# Common objects
obj-y := time.o clock.o serial.o io.o psc.o \
- gpio.o dma.o usb.o common.o sram.o
+ gpio.o dma.o usb.o common.o sram.o aemif.o
obj-$(CONFIG_DAVINCI_MUX) += mux.o
@@ -33,6 +33,8 @@ obj-$(CONFIG_MACH_DAVINCI_DM365_EVM) += board-dm365-evm.o
obj-$(CONFIG_MACH_DAVINCI_DA830_EVM) += board-da830-evm.o
obj-$(CONFIG_MACH_DAVINCI_DA850_EVM) += board-da850-evm.o
obj-$(CONFIG_MACH_TNETV107X) += board-tnetv107x-evm.o
+obj-$(CONFIG_MACH_MITYOMAPL138) += board-mityomapl138.o
+obj-$(CONFIG_MACH_OMAPL138_HAWKBOARD) += board-omapl138-hawk.o
# Power Management
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
diff --git a/arch/arm/mach-davinci/aemif.c b/arch/arm/mach-davinci/aemif.c
new file mode 100644
index 000000000000..9c3f500fc12f
--- /dev/null
+++ b/arch/arm/mach-davinci/aemif.c
@@ -0,0 +1,133 @@
+/*
+ * AEMIF support for DaVinci SoCs
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated. http://www.ti.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/io.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/time.h>
+
+#include <mach/aemif.h>
+
+/* Timing value configuration */
+
+#define TA(x) ((x) << 2)
+#define RHOLD(x) ((x) << 4)
+#define RSTROBE(x) ((x) << 7)
+#define RSETUP(x) ((x) << 13)
+#define WHOLD(x) ((x) << 17)
+#define WSTROBE(x) ((x) << 20)
+#define WSETUP(x) ((x) << 26)
+
+#define TA_MAX 0x3
+#define RHOLD_MAX 0x7
+#define RSTROBE_MAX 0x3f
+#define RSETUP_MAX 0xf
+#define WHOLD_MAX 0x7
+#define WSTROBE_MAX 0x3f
+#define WSETUP_MAX 0xf
+
+#define TIMING_MASK (TA(TA_MAX) | \
+ RHOLD(RHOLD_MAX) | \
+ RSTROBE(RSTROBE_MAX) | \
+ RSETUP(RSETUP_MAX) | \
+ WHOLD(WHOLD_MAX) | \
+ WSTROBE(WSTROBE_MAX) | \
+ WSETUP(WSETUP_MAX))
+
+/*
+ * aemif_calc_rate - calculate timing data.
+ * @wanted: The cycle time needed in nanoseconds.
+ * @clk: The input clock rate in kHz.
+ * @max: The maximum divider value that can be programmed.
+ *
+ * On success, returns the calculated timing value minus 1 for easy
+ * programming into AEMIF timing registers, else negative errno.
+ */
+static int aemif_calc_rate(int wanted, unsigned long clk, int max)
+{
+ int result;
+
+ result = DIV_ROUND_UP((wanted * clk), NSEC_PER_MSEC) - 1;
+
+ pr_debug("%s: result %d from %ld, %d\n", __func__, result, clk, wanted);
+
+ /* It is generally OK to have a more relaxed timing than requested... */
+ if (result < 0)
+ result = 0;
+
+ /* ... But configuring tighter timings is not an option. */
+ else if (result > max)
+ result = -EINVAL;
+
+ return result;
+}
+
+/**
+ * davinci_aemif_setup_timing - setup timing values for a given AEMIF interface
+ * @t: timing values to be progammed
+ * @base: The virtual base address of the AEMIF interface
+ * @cs: chip-select to program the timing values for
+ *
+ * This function programs the given timing values (in real clock) into the
+ * AEMIF registers taking the AEMIF clock into account.
+ *
+ * This function does not use any locking while programming the AEMIF
+ * because it is expected that there is only one user of a given
+ * chip-select.
+ *
+ * Returns 0 on success, else negative errno.
+ */
+int davinci_aemif_setup_timing(struct davinci_aemif_timing *t,
+ void __iomem *base, unsigned cs)
+{
+ unsigned set, val;
+ unsigned ta, rhold, rstrobe, rsetup, whold, wstrobe, wsetup;
+ unsigned offset = A1CR_OFFSET + cs * 4;
+ struct clk *aemif_clk;
+ unsigned long clkrate;
+
+ if (!t)
+ return 0; /* Nothing to do */
+
+ aemif_clk = clk_get(NULL, "aemif");
+ if (IS_ERR(aemif_clk))
+ return PTR_ERR(aemif_clk);
+
+ clkrate = clk_get_rate(aemif_clk);
+
+ clkrate /= 1000; /* turn clock into kHz for ease of use */
+
+ ta = aemif_calc_rate(t->ta, clkrate, TA_MAX);
+ rhold = aemif_calc_rate(t->rhold, clkrate, RHOLD_MAX);
+ rstrobe = aemif_calc_rate(t->rstrobe, clkrate, RSTROBE_MAX);
+ rsetup = aemif_calc_rate(t->rsetup, clkrate, RSETUP_MAX);
+ whold = aemif_calc_rate(t->whold, clkrate, WHOLD_MAX);
+ wstrobe = aemif_calc_rate(t->wstrobe, clkrate, WSTROBE_MAX);
+ wsetup = aemif_calc_rate(t->wsetup, clkrate, WSETUP_MAX);
+
+ if (ta < 0 || rhold < 0 || rstrobe < 0 || rsetup < 0 ||
+ whold < 0 || wstrobe < 0 || wsetup < 0) {
+ pr_err("%s: cannot get suitable timings\n", __func__);
+ return -EINVAL;
+ }
+
+ set = TA(ta) | RHOLD(rhold) | RSTROBE(rstrobe) | RSETUP(rsetup) |
+ WHOLD(whold) | WSTROBE(wstrobe) | WSETUP(wsetup);
+
+ val = __raw_readl(base + offset);
+ val &= ~TIMING_MASK;
+ val |= set;
+ __raw_writel(val, base + offset);
+
+ return 0;
+}
+EXPORT_SYMBOL(davinci_aemif_setup_timing);
diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c
index c3994f341e49..b52a3a1abd94 100644
--- a/arch/arm/mach-davinci/board-da830-evm.c
+++ b/arch/arm/mach-davinci/board-da830-evm.c
@@ -29,10 +29,9 @@
#include <mach/nand.h>
#include <mach/da8xx.h>
#include <mach/usb.h>
+#include <mach/aemif.h>
-#define DA830_EVM_PHY_MASK 0x0
-#define DA830_EVM_MDIO_FREQUENCY 2200000 /* PHY bus frequency */
-
+#define DA830_EVM_PHY_ID ""
/*
* USB1 VBUS is controlled by GPIO1[15], over-current is reported on GPIO2[4].
*/
@@ -360,6 +359,16 @@ static struct nand_bbt_descr da830_evm_nand_bbt_mirror_descr = {
.pattern = da830_evm_nand_mirror_pattern
};
+static struct davinci_aemif_timing da830_evm_nandflash_timing = {
+ .wsetup = 24,
+ .wstrobe = 21,
+ .whold = 14,
+ .rsetup = 19,
+ .rstrobe = 50,
+ .rhold = 0,
+ .ta = 20,
+};
+
static struct davinci_nand_pdata da830_evm_nand_pdata = {
.parts = da830_evm_nand_partitions,
.nr_parts = ARRAY_SIZE(da830_evm_nand_partitions),
@@ -368,6 +377,7 @@ static struct davinci_nand_pdata da830_evm_nand_pdata = {
.options = NAND_USE_FLASH_BBT,
.bbt_td = &da830_evm_nand_bbt_main_descr,
.bbt_md = &da830_evm_nand_bbt_mirror_descr,
+ .timing = &da830_evm_nandflash_timing,
};
static struct resource da830_evm_nand_resources[] = {
@@ -546,9 +556,8 @@ static __init void da830_evm_init(void)
da830_evm_usb_init();
- soc_info->emac_pdata->phy_mask = DA830_EVM_PHY_MASK;
- soc_info->emac_pdata->mdio_max_freq = DA830_EVM_MDIO_FREQUENCY;
soc_info->emac_pdata->rmii_en = 1;
+ soc_info->emac_pdata->phy_id = DA830_EVM_PHY_ID;
ret = davinci_cfg_reg_list(da830_cpgmac_pins);
if (ret)
@@ -586,6 +595,9 @@ static __init void da830_evm_init(void)
#ifdef CONFIG_SERIAL_8250_CONSOLE
static int __init da830_evm_console_init(void)
{
+ if (!machine_is_davinci_da830_evm())
+ return 0;
+
return add_preferred_console("ttyS", 2, "115200");
}
console_initcall(da830_evm_console_init);
@@ -596,9 +608,7 @@ static void __init da830_evm_map_io(void)
da830_init();
}
-MACHINE_START(DAVINCI_DA830_EVM, "DaVinci DA830/OMAP-L137 EVM")
- .phys_io = IO_PHYS,
- .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
+MACHINE_START(DAVINCI_DA830_EVM, "DaVinci DA830/OMAP-L137/AM17x EVM")
.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..c6e11c682e4c 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -26,7 +26,6 @@
#include <linux/mtd/physmap.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/tps6507x.h>
-#include <linux/mfd/tps6507x.h>
#include <linux/input/tps6507x-ts.h>
#include <asm/mach-types.h>
@@ -36,10 +35,9 @@
#include <mach/da8xx.h>
#include <mach/nand.h>
#include <mach/mux.h>
+#include <mach/aemif.h>
-#define DA850_EVM_PHY_MASK 0x1
-#define DA850_EVM_MDIO_FREQUENCY 2200000 /* PHY bus frequency */
-
+#define DA850_EVM_PHY_ID "0:00"
#define DA850_LCD_PWR_PIN GPIO_TO_PIN(2, 8)
#define DA850_LCD_BL_PIN GPIO_TO_PIN(2, 15)
@@ -110,7 +108,7 @@ static struct platform_device da850_pm_device = {
* to boot, using TI's tools to install the secondary boot loader
* (UBL) and U-Boot.
*/
-struct mtd_partition da850_evm_nandflash_partition[] = {
+static struct mtd_partition da850_evm_nandflash_partition[] = {
{
.name = "u-boot env",
.offset = 0,
@@ -143,12 +141,23 @@ struct mtd_partition da850_evm_nandflash_partition[] = {
},
};
+static struct davinci_aemif_timing da850_evm_nandflash_timing = {
+ .wsetup = 24,
+ .wstrobe = 21,
+ .whold = 14,
+ .rsetup = 19,
+ .rstrobe = 50,
+ .rhold = 0,
+ .ta = 20,
+};
+
static struct davinci_nand_pdata da850_evm_nandflash_data = {
.parts = da850_evm_nandflash_partition,
.nr_parts = ARRAY_SIZE(da850_evm_nandflash_partition),
.ecc_mode = NAND_ECC_HW,
.ecc_bits = 4,
.options = NAND_USE_FLASH_BBT,
+ .timing = &da850_evm_nandflash_timing,
};
static struct resource da850_evm_nandflash_resource[] = {
@@ -196,6 +205,30 @@ static void __init da850_evm_init_nor(void)
iounmap(aemif_addr);
}
+static const short da850_evm_nand_pins[] = {
+ DA850_EMA_D_0, DA850_EMA_D_1, DA850_EMA_D_2, DA850_EMA_D_3,
+ DA850_EMA_D_4, DA850_EMA_D_5, DA850_EMA_D_6, DA850_EMA_D_7,
+ DA850_EMA_A_1, DA850_EMA_A_2, DA850_NEMA_CS_3, DA850_NEMA_CS_4,
+ DA850_NEMA_WE, DA850_NEMA_OE,
+ -1
+};
+
+static const short da850_evm_nor_pins[] = {
+ DA850_EMA_BA_1, DA850_EMA_CLK, DA850_EMA_WAIT_1, DA850_NEMA_CS_2,
+ DA850_NEMA_WE, DA850_NEMA_OE, DA850_EMA_D_0, DA850_EMA_D_1,
+ DA850_EMA_D_2, DA850_EMA_D_3, DA850_EMA_D_4, DA850_EMA_D_5,
+ DA850_EMA_D_6, DA850_EMA_D_7, DA850_EMA_D_8, DA850_EMA_D_9,
+ DA850_EMA_D_10, DA850_EMA_D_11, DA850_EMA_D_12, DA850_EMA_D_13,
+ DA850_EMA_D_14, DA850_EMA_D_15, DA850_EMA_A_0, DA850_EMA_A_1,
+ DA850_EMA_A_2, DA850_EMA_A_3, DA850_EMA_A_4, DA850_EMA_A_5,
+ DA850_EMA_A_6, DA850_EMA_A_7, DA850_EMA_A_8, DA850_EMA_A_9,
+ DA850_EMA_A_10, DA850_EMA_A_11, DA850_EMA_A_12, DA850_EMA_A_13,
+ DA850_EMA_A_14, DA850_EMA_A_15, DA850_EMA_A_16, DA850_EMA_A_17,
+ DA850_EMA_A_18, DA850_EMA_A_19, DA850_EMA_A_20, DA850_EMA_A_21,
+ DA850_EMA_A_22, DA850_EMA_A_23,
+ -1
+};
+
static u32 ui_card_detected;
#if defined(CONFIG_MMC_DAVINCI) || \
@@ -205,17 +238,17 @@ static u32 ui_card_detected;
#define HAS_MMC 0
#endif
-static __init void da850_evm_setup_nor_nand(void)
+static inline void da850_evm_setup_nor_nand(void)
{
int ret = 0;
if (ui_card_detected & !HAS_MMC) {
- ret = davinci_cfg_reg_list(da850_nand_pins);
+ ret = davinci_cfg_reg_list(da850_evm_nand_pins);
if (ret)
pr_warning("da850_evm_init: nand mux setup failed: "
"%d\n", ret);
- ret = davinci_cfg_reg_list(da850_nor_pins);
+ ret = davinci_cfg_reg_list(da850_evm_nor_pins);
if (ret)
pr_warning("da850_evm_init: nor mux setup failed: %d\n",
ret);
@@ -406,7 +439,7 @@ static int da850_lcd_hw_init(void)
/* TPS65070 voltage regulator support */
/* 3.3V */
-struct regulator_consumer_supply tps65070_dcdc1_consumers[] = {
+static struct regulator_consumer_supply tps65070_dcdc1_consumers[] = {
{
.supply = "usb0_vdda33",
},
@@ -416,7 +449,7 @@ struct regulator_consumer_supply tps65070_dcdc1_consumers[] = {
};
/* 3.3V or 1.8V */
-struct regulator_consumer_supply tps65070_dcdc2_consumers[] = {
+static struct regulator_consumer_supply tps65070_dcdc2_consumers[] = {
{
.supply = "dvdd3318_a",
},
@@ -429,14 +462,14 @@ struct regulator_consumer_supply tps65070_dcdc2_consumers[] = {
};
/* 1.2V */
-struct regulator_consumer_supply tps65070_dcdc3_consumers[] = {
+static struct regulator_consumer_supply tps65070_dcdc3_consumers[] = {
{
.supply = "cvdd",
},
};
/* 1.8V LDO */
-struct regulator_consumer_supply tps65070_ldo1_consumers[] = {
+static struct regulator_consumer_supply tps65070_ldo1_consumers[] = {
{
.supply = "sata_vddr",
},
@@ -452,7 +485,7 @@ struct regulator_consumer_supply tps65070_ldo1_consumers[] = {
};
/* 1.2V LDO */
-struct regulator_consumer_supply tps65070_ldo2_consumers[] = {
+static struct regulator_consumer_supply tps65070_ldo2_consumers[] = {
{
.supply = "sata_vdd",
},
@@ -475,7 +508,7 @@ static struct tps6507x_reg_platform_data tps6507x_platform_data = {
.defdcdc_default = true,
};
-struct regulator_init_data tps65070_regulator_data[] = {
+static struct regulator_init_data tps65070_regulator_data[] = {
/* dcdc1 */
{
.constraints = {
@@ -576,6 +609,23 @@ static const short da850_evm_lcdc_pins[] = {
-1
};
+static const short da850_evm_mii_pins[] = {
+ DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3,
+ DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER,
+ DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3,
+ DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK,
+ DA850_MDIO_D,
+ -1
+};
+
+static const short da850_evm_rmii_pins[] = {
+ DA850_RMII_TXD_0, DA850_RMII_TXD_1, DA850_RMII_TXEN,
+ DA850_RMII_CRS_DV, DA850_RMII_RXD_0, DA850_RMII_RXD_1,
+ DA850_RMII_RXER, DA850_RMII_MHZ_50_CLK, DA850_MDIO_CLK,
+ DA850_MDIO_D,
+ -1
+};
+
static int __init da850_evm_config_emac(void)
{
void __iomem *cfg_chip3_base;
@@ -593,12 +643,12 @@ static int __init da850_evm_config_emac(void)
if (rmii_en) {
val |= BIT(8);
- ret = davinci_cfg_reg_list(da850_rmii_pins);
+ ret = davinci_cfg_reg_list(da850_evm_rmii_pins);
pr_info("EMAC: RMII PHY configured, MII PHY will not be"
" functional\n");
} else {
val &= ~BIT(8);
- ret = davinci_cfg_reg_list(da850_cpgmac_pins);
+ ret = davinci_cfg_reg_list(da850_evm_mii_pins);
pr_info("EMAC: MII PHY configured, RMII PHY will not be"
" functional\n");
}
@@ -625,8 +675,7 @@ static int __init da850_evm_config_emac(void)
/* Enable/Disable MII MDIO clock */
gpio_direction_output(DA850_MII_MDIO_CLKEN_PIN, rmii_en);
- soc_info->emac_pdata->phy_mask = DA850_EVM_PHY_MASK;
- soc_info->emac_pdata->mdio_max_freq = DA850_EVM_MDIO_FREQUENCY;
+ soc_info->emac_pdata->phy_id = DA850_EVM_PHY_ID;
ret = da8xx_register_emac();
if (ret)
@@ -787,7 +836,7 @@ static __init void da850_evm_init(void)
if (ret)
pr_warning("da850_evm_init: rtc setup failed: %d\n", ret);
- ret = da850_register_cpufreq();
+ ret = da850_register_cpufreq("pll0_sysclk3");
if (ret)
pr_warning("da850_evm_init: cpufreq registration failed: %d\n",
ret);
@@ -806,6 +855,9 @@ static __init void da850_evm_init(void)
#ifdef CONFIG_SERIAL_8250_CONSOLE
static int __init da850_evm_console_init(void)
{
+ if (!machine_is_davinci_da850_evm())
+ return 0;
+
return add_preferred_console("ttyS", 2, "115200");
}
console_initcall(da850_evm_console_init);
@@ -816,9 +868,7 @@ static void __init da850_evm_map_io(void)
da850_init();
}
-MACHINE_START(DAVINCI_DA850_EVM, "DaVinci DA850/OMAP-L138 EVM")
- .phys_io = IO_PHYS,
- .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
+MACHINE_START(DAVINCI_DA850_EVM, "DaVinci DA850/OMAP-L138/AM18x EVM")
.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..c67f684ee3e5 100644
--- a/arch/arm/mach-davinci/board-dm365-evm.c
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -54,9 +54,7 @@ static inline int have_tvp7002(void)
return 0;
}
-#define DM365_EVM_PHY_MASK (0x2)
-#define DM365_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */
-
+#define DM365_EVM_PHY_ID "0:01"
/*
* A MAX-II CPLD is used for various board control functions.
*/
@@ -175,7 +173,9 @@ static struct at24_platform_data eeprom_info = {
.context = (void *)0x7f00,
};
-static struct snd_platform_data dm365_evm_snd_data;
+static struct snd_platform_data dm365_evm_snd_data = {
+ .asp_chan_q = EVENTQ_3,
+};
static struct i2c_board_info i2c_info[] = {
{
@@ -533,8 +533,7 @@ fail:
/* ... and ENET ... */
dm365evm_emac_configure();
- soc_info->emac_pdata->phy_mask = DM365_EVM_PHY_MASK;
- soc_info->emac_pdata->mdio_max_freq = DM365_EVM_MDIO_FREQUENCY;
+ soc_info->emac_pdata->phy_id = DM365_EVM_PHY_ID;
resets &= ~BIT(3);
/* ... and AIC33 */
@@ -613,8 +612,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..0ca90b834586 100644
--- a/arch/arm/mach-davinci/board-dm644x-evm.c
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -37,10 +37,9 @@
#include <mach/nand.h>
#include <mach/mmc.h>
#include <mach/usb.h>
+#include <mach/aemif.h>
-#define DM644X_EVM_PHY_MASK (0x2)
-#define DM644X_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */
-
+#define DM644X_EVM_PHY_ID "0:01"
#define LXT971_PHY_ID (0x001378e2)
#define LXT971_PHY_MASK (0xfffffff0)
@@ -137,11 +136,22 @@ static struct mtd_partition davinci_evm_nandflash_partition[] = {
*/
};
+static struct davinci_aemif_timing davinci_evm_nandflash_timing = {
+ .wsetup = 20,
+ .wstrobe = 40,
+ .whold = 20,
+ .rsetup = 10,
+ .rstrobe = 40,
+ .rhold = 10,
+ .ta = 40,
+};
+
static struct davinci_nand_pdata davinci_evm_nandflash_data = {
.parts = davinci_evm_nandflash_partition,
.nr_parts = ARRAY_SIZE(davinci_evm_nandflash_partition),
.ecc_mode = NAND_ECC_HW,
.options = NAND_USE_FLASH_BBT,
+ .timing = &davinci_evm_nandflash_timing,
};
static struct resource davinci_evm_nandflash_resource[] = {
@@ -695,9 +705,7 @@ static __init void davinci_evm_init(void)
davinci_serial_init(&uart_config);
dm644x_init_asp(&dm644x_evm_snd_data);
- soc_info->emac_pdata->phy_mask = DM644X_EVM_PHY_MASK;
- soc_info->emac_pdata->mdio_max_freq = DM644X_EVM_MDIO_FREQUENCY;
-
+ soc_info->emac_pdata->phy_id = DM644X_EVM_PHY_ID;
/* Register the fixup for PHY on DaVinci */
phy_register_fixup_for_uid(LXT971_PHY_ID, LXT971_PHY_MASK,
davinci_phy_fixup);
@@ -706,8 +714,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..f6ac9ba74878 100644
--- a/arch/arm/mach-davinci/board-dm646x-evm.c
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -42,6 +42,7 @@
#include <mach/nand.h>
#include <mach/clock.h>
#include <mach/cdce949.h>
+#include <mach/aemif.h>
#include "clock.h"
@@ -71,6 +72,16 @@ static struct mtd_partition davinci_nand_partitions[] = {
}
};
+static struct davinci_aemif_timing dm6467tevm_nandflash_timing = {
+ .wsetup = 29,
+ .wstrobe = 24,
+ .whold = 14,
+ .rsetup = 19,
+ .rstrobe = 33,
+ .rhold = 0,
+ .ta = 29,
+};
+
static struct davinci_nand_pdata davinci_nand_data = {
.mask_cle = 0x80000,
.mask_ale = 0x40000,
@@ -718,9 +729,7 @@ static struct davinci_uart_config uart_config __initdata = {
.enabled_uarts = (1 << 0),
};
-#define DM646X_EVM_PHY_MASK (0x2)
-#define DM646X_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */
-
+#define DM646X_EVM_PHY_ID "0:01"
/*
* The following EDMA channels/slots are not being used by drivers (for
* example: Timer, GPIO, UART events etc) on dm646x, hence they are being
@@ -763,6 +772,9 @@ static __init void evm_init(void)
dm646x_init_mcasp0(&dm646x_evm_snd_data[0]);
dm646x_init_mcasp1(&dm646x_evm_snd_data[1]);
+ if (machine_is_davinci_dm6467tevm())
+ davinci_nand_data.timing = &dm6467tevm_nandflash_timing;
+
platform_device_register(&davinci_nand_device);
dm646x_init_edma(dm646x_edma_rsv);
@@ -770,8 +782,7 @@ static __init void evm_init(void)
if (HAS_ATA)
davinci_init_ide();
- soc_info->emac_pdata->phy_mask = DM646X_EVM_PHY_MASK;
- soc_info->emac_pdata->mdio_max_freq = DM646X_EVM_MDIO_FREQUENCY;
+ soc_info->emac_pdata->phy_id = DM646X_EVM_PHY_ID;
}
#define DM646X_EVM_REF_FREQ 27000000
@@ -786,8 +797,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 +805,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-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c
new file mode 100644
index 000000000000..0bb5f0ce4fdc
--- /dev/null
+++ b/arch/arm/mach-davinci/board-mityomapl138.c
@@ -0,0 +1,422 @@
+/*
+ * Critical Link MityOMAP-L138 SoM
+ *
+ * Copyright (C) 2010 Critical Link LLC - http://www.criticallink.com
+ *
+ * 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/console.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/partitions.h>
+#include <linux/regulator/machine.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/etherdevice.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/common.h>
+#include <mach/cp_intc.h>
+#include <mach/da8xx.h>
+#include <mach/nand.h>
+#include <mach/mux.h>
+
+#define MITYOMAPL138_PHY_ID "0:03"
+
+#define FACTORY_CONFIG_MAGIC 0x012C0138
+#define FACTORY_CONFIG_VERSION 0x00010001
+
+/* Data Held in On-Board I2C device */
+struct factory_config {
+ u32 magic;
+ u32 version;
+ u8 mac[6];
+ u32 fpga_type;
+ u32 spare;
+ u32 serialnumber;
+ char partnum[32];
+};
+
+static struct factory_config factory_config;
+
+static void read_factory_config(struct memory_accessor *a, void *context)
+{
+ int ret;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ ret = a->read(a, (char *)&factory_config, 0, sizeof(factory_config));
+ if (ret != sizeof(struct factory_config)) {
+ pr_warning("MityOMAPL138: Read Factory Config Failed: %d\n",
+ ret);
+ return;
+ }
+
+ if (factory_config.magic != FACTORY_CONFIG_MAGIC) {
+ pr_warning("MityOMAPL138: Factory Config Magic Wrong (%X)\n",
+ factory_config.magic);
+ return;
+ }
+
+ if (factory_config.version != FACTORY_CONFIG_VERSION) {
+ pr_warning("MityOMAPL138: Factory Config Version Wrong (%X)\n",
+ factory_config.version);
+ return;
+ }
+
+ pr_info("MityOMAPL138: Found MAC = %pM\n", factory_config.mac);
+ pr_info("MityOMAPL138: Part Number = %s\n", factory_config.partnum);
+ if (is_valid_ether_addr(factory_config.mac))
+ memcpy(soc_info->emac_pdata->mac_addr,
+ factory_config.mac, ETH_ALEN);
+ else
+ pr_warning("MityOMAPL138: Invalid MAC found "
+ "in factory config block\n");
+}
+
+static struct at24_platform_data mityomapl138_fd_chip = {
+ .byte_len = 256,
+ .page_size = 8,
+ .flags = AT24_FLAG_READONLY | AT24_FLAG_IRUGO,
+ .setup = read_factory_config,
+ .context = NULL,
+};
+
+static struct davinci_i2c_platform_data mityomap_i2c_0_pdata = {
+ .bus_freq = 100, /* kHz */
+ .bus_delay = 0, /* usec */
+};
+
+/* TPS65023 voltage regulator support */
+/* 1.2V Core */
+static struct regulator_consumer_supply tps65023_dcdc1_consumers[] = {
+ {
+ .supply = "cvdd",
+ },
+};
+
+/* 1.8V */
+static struct regulator_consumer_supply tps65023_dcdc2_consumers[] = {
+ {
+ .supply = "usb0_vdda18",
+ },
+ {
+ .supply = "usb1_vdda18",
+ },
+ {
+ .supply = "ddr_dvdd18",
+ },
+ {
+ .supply = "sata_vddr",
+ },
+};
+
+/* 1.2V */
+static struct regulator_consumer_supply tps65023_dcdc3_consumers[] = {
+ {
+ .supply = "sata_vdd",
+ },
+ {
+ .supply = "usb_cvdd",
+ },
+ {
+ .supply = "pll0_vdda",
+ },
+ {
+ .supply = "pll1_vdda",
+ },
+};
+
+/* 1.8V Aux LDO, not used */
+static struct regulator_consumer_supply tps65023_ldo1_consumers[] = {
+ {
+ .supply = "1.8v_aux",
+ },
+};
+
+/* FPGA VCC Aux (2.5 or 3.3) LDO */
+static struct regulator_consumer_supply tps65023_ldo2_consumers[] = {
+ {
+ .supply = "vccaux",
+ },
+};
+
+static struct regulator_init_data tps65023_regulator_data[] = {
+ /* dcdc1 */
+ {
+ .constraints = {
+ .min_uV = 1150000,
+ .max_uV = 1350000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(tps65023_dcdc1_consumers),
+ .consumer_supplies = tps65023_dcdc1_consumers,
+ },
+ /* dcdc2 */
+ {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(tps65023_dcdc2_consumers),
+ .consumer_supplies = tps65023_dcdc2_consumers,
+ },
+ /* dcdc3 */
+ {
+ .constraints = {
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(tps65023_dcdc3_consumers),
+ .consumer_supplies = tps65023_dcdc3_consumers,
+ },
+ /* ldo1 */
+ {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(tps65023_ldo1_consumers),
+ .consumer_supplies = tps65023_ldo1_consumers,
+ },
+ /* ldo2 */
+ {
+ .constraints = {
+ .min_uV = 2500000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(tps65023_ldo2_consumers),
+ .consumer_supplies = tps65023_ldo2_consumers,
+ },
+};
+
+static struct i2c_board_info __initdata mityomap_tps65023_info[] = {
+ {
+ I2C_BOARD_INFO("tps65023", 0x48),
+ .platform_data = &tps65023_regulator_data[0],
+ },
+ {
+ I2C_BOARD_INFO("24c02", 0x50),
+ .platform_data = &mityomapl138_fd_chip,
+ },
+};
+
+static int __init pmic_tps65023_init(void)
+{
+ return i2c_register_board_info(1, mityomap_tps65023_info,
+ ARRAY_SIZE(mityomap_tps65023_info));
+}
+
+/*
+ * MityDSP-L138 includes a 256 MByte large-page NAND flash
+ * (128K blocks).
+ */
+static struct mtd_partition mityomapl138_nandflash_partition[] = {
+ {
+ .name = "rootfs",
+ .offset = 0,
+ .size = SZ_128M,
+ .mask_flags = 0, /* MTD_WRITEABLE, */
+ },
+ {
+ .name = "homefs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ },
+};
+
+static struct davinci_nand_pdata mityomapl138_nandflash_data = {
+ .parts = mityomapl138_nandflash_partition,
+ .nr_parts = ARRAY_SIZE(mityomapl138_nandflash_partition),
+ .ecc_mode = NAND_ECC_HW,
+ .options = NAND_USE_FLASH_BBT | NAND_BUSWIDTH_16,
+ .ecc_bits = 1, /* 4 bit mode is not supported with 16 bit NAND */
+};
+
+static struct resource mityomapl138_nandflash_resource[] = {
+ {
+ .start = DA8XX_AEMIF_CS3_BASE,
+ .end = DA8XX_AEMIF_CS3_BASE + SZ_512K + 2 * SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = DA8XX_AEMIF_CTL_BASE,
+ .end = DA8XX_AEMIF_CTL_BASE + SZ_32K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device mityomapl138_nandflash_device = {
+ .name = "davinci_nand",
+ .id = 0,
+ .dev = {
+ .platform_data = &mityomapl138_nandflash_data,
+ },
+ .num_resources = ARRAY_SIZE(mityomapl138_nandflash_resource),
+ .resource = mityomapl138_nandflash_resource,
+};
+
+static struct platform_device *mityomapl138_devices[] __initdata = {
+ &mityomapl138_nandflash_device,
+};
+
+static void __init mityomapl138_setup_nand(void)
+{
+ platform_add_devices(mityomapl138_devices,
+ ARRAY_SIZE(mityomapl138_devices));
+}
+
+static struct davinci_uart_config mityomapl138_uart_config __initdata = {
+ .enabled_uarts = 0x7,
+};
+
+static const short mityomap_mii_pins[] = {
+ DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3,
+ DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER,
+ DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3,
+ DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK,
+ DA850_MDIO_D,
+ -1
+};
+
+static const short mityomap_rmii_pins[] = {
+ DA850_RMII_TXD_0, DA850_RMII_TXD_1, DA850_RMII_TXEN,
+ DA850_RMII_CRS_DV, DA850_RMII_RXD_0, DA850_RMII_RXD_1,
+ DA850_RMII_RXER, DA850_RMII_MHZ_50_CLK, DA850_MDIO_CLK,
+ DA850_MDIO_D,
+ -1
+};
+
+static void __init mityomapl138_config_emac(void)
+{
+ void __iomem *cfg_chip3_base;
+ int ret;
+ u32 val;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ soc_info->emac_pdata->rmii_en = 0; /* hardcoded for now */
+
+ cfg_chip3_base = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG);
+ val = __raw_readl(cfg_chip3_base);
+
+ if (soc_info->emac_pdata->rmii_en) {
+ val |= BIT(8);
+ ret = davinci_cfg_reg_list(mityomap_rmii_pins);
+ pr_info("RMII PHY configured\n");
+ } else {
+ val &= ~BIT(8);
+ ret = davinci_cfg_reg_list(mityomap_mii_pins);
+ pr_info("MII PHY configured\n");
+ }
+
+ if (ret) {
+ pr_warning("mii/rmii mux setup failed: %d\n", ret);
+ return;
+ }
+
+ /* configure the CFGCHIP3 register for RMII or MII */
+ __raw_writel(val, cfg_chip3_base);
+
+ soc_info->emac_pdata->phy_id = MITYOMAPL138_PHY_ID;
+
+ ret = da8xx_register_emac();
+ if (ret)
+ pr_warning("emac registration failed: %d\n", ret);
+}
+
+static struct davinci_pm_config da850_pm_pdata = {
+ .sleepcount = 128,
+};
+
+static struct platform_device da850_pm_device = {
+ .name = "pm-davinci",
+ .dev = {
+ .platform_data = &da850_pm_pdata,
+ },
+ .id = -1,
+};
+
+static void __init mityomapl138_init(void)
+{
+ int ret;
+
+ /* for now, no special EDMA channels are reserved */
+ ret = da850_register_edma(NULL);
+ if (ret)
+ pr_warning("edma registration failed: %d\n", ret);
+
+ ret = da8xx_register_watchdog();
+ if (ret)
+ pr_warning("watchdog registration failed: %d\n", ret);
+
+ davinci_serial_init(&mityomapl138_uart_config);
+
+ ret = da8xx_register_i2c(0, &mityomap_i2c_0_pdata);
+ if (ret)
+ pr_warning("i2c0 registration failed: %d\n", ret);
+
+ ret = pmic_tps65023_init();
+ if (ret)
+ pr_warning("TPS65023 PMIC init failed: %d\n", ret);
+
+ mityomapl138_setup_nand();
+
+ mityomapl138_config_emac();
+
+ ret = da8xx_register_rtc();
+ if (ret)
+ pr_warning("rtc setup failed: %d\n", ret);
+
+ ret = da850_register_cpufreq("pll0_sysclk3");
+ if (ret)
+ pr_warning("cpufreq registration failed: %d\n", ret);
+
+ ret = da8xx_register_cpuidle();
+ if (ret)
+ pr_warning("cpuidle registration failed: %d\n", ret);
+
+ ret = da850_register_pm(&da850_pm_device);
+ if (ret)
+ pr_warning("da850_evm_init: suspend registration failed: %d\n",
+ ret);
+}
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+static int __init mityomapl138_console_init(void)
+{
+ if (!machine_is_mityomapl138())
+ return 0;
+
+ return add_preferred_console("ttyS", 1, "115200");
+}
+console_initcall(mityomapl138_console_init);
+#endif
+
+static void __init mityomapl138_map_io(void)
+{
+ da850_init();
+}
+
+MACHINE_START(MITYOMAPL138, "MityDSP-L138/MityARM-1808")
+ .boot_params = (DA8XX_DDR_BASE + 0x100),
+ .map_io = mityomapl138_map_io,
+ .init_irq = cp_intc_init,
+ .timer = &davinci_timer,
+ .init_machine = mityomapl138_init,
+MACHINE_END
diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c
index 4c30e929bbf9..6c389ff1020e 100644
--- a/arch/arm/mach-davinci/board-neuros-osd2.c
+++ b/arch/arm/mach-davinci/board-neuros-osd2.c
@@ -39,9 +39,7 @@
#include <mach/mmc.h>
#include <mach/usb.h>
-#define NEUROS_OSD2_PHY_MASK 0x2
-#define NEUROS_OSD2_MDIO_FREQUENCY 2200000 /* PHY bus frequency */
-
+#define NEUROS_OSD2_PHY_ID "0:01"
#define LXT971_PHY_ID 0x001378e2
#define LXT971_PHY_MASK 0xfffffff0
@@ -252,8 +250,7 @@ static __init void davinci_ntosd2_init(void)
davinci_serial_init(&uart_config);
dm644x_init_asp(&dm644x_ntosd2_snd_data);
- soc_info->emac_pdata->phy_mask = NEUROS_OSD2_PHY_MASK;
- soc_info->emac_pdata->mdio_max_freq = NEUROS_OSD2_MDIO_FREQUENCY;
+ soc_info->emac_pdata->phy_id = NEUROS_OSD2_PHY_ID;
davinci_setup_usb(1000, 8);
/*
@@ -275,8 +272,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-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c
new file mode 100644
index 000000000000..0b8dbdb79fe0
--- /dev/null
+++ b/arch/arm/mach-davinci/board-omapl138-hawk.c
@@ -0,0 +1,62 @@
+/*
+ * Hawkboard.org based on TI's OMAP-L138 Platform
+ *
+ * Initial code: Syed Mohammed Khasim
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * 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/console.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/cp_intc.h>
+#include <mach/da8xx.h>
+
+static struct davinci_uart_config omapl138_hawk_uart_config __initdata = {
+ .enabled_uarts = 0x7,
+};
+
+static __init void omapl138_hawk_init(void)
+{
+ int ret;
+
+ davinci_serial_init(&omapl138_hawk_uart_config);
+
+ ret = da8xx_register_watchdog();
+ if (ret)
+ pr_warning("omapl138_hawk_init: "
+ "watchdog registration failed: %d\n",
+ ret);
+}
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+static int __init omapl138_hawk_console_init(void)
+{
+ if (!machine_is_omapl138_hawkboard())
+ return 0;
+
+ return add_preferred_console("ttyS", 2, "115200");
+}
+console_initcall(omapl138_hawk_console_init);
+#endif
+
+static void __init omapl138_hawk_map_io(void)
+{
+ da850_init();
+}
+
+MACHINE_START(OMAPL138_HAWKBOARD, "AM18x/OMAP-L138 Hawkboard")
+ .boot_params = (DA8XX_DDR_BASE + 0x100),
+ .map_io = omapl138_hawk_map_io,
+ .init_irq = cp_intc_init,
+ .timer = &davinci_timer,
+ .init_machine = omapl138_hawk_init,
+MACHINE_END
diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c
index 23e664a1a802..61ac96d8f00d 100644
--- a/arch/arm/mach-davinci/board-sffsdr.c
+++ b/arch/arm/mach-davinci/board-sffsdr.c
@@ -42,9 +42,7 @@
#include <mach/mux.h>
#include <mach/usb.h>
-#define SFFSDR_PHY_MASK (0x2)
-#define SFFSDR_MDIO_FREQUENCY (2200000) /* PHY bus frequency */
-
+#define SFFSDR_PHY_ID "0:01"
static struct mtd_partition davinci_sffsdr_nandflash_partition[] = {
/* U-Boot Environment: Block 0
* UBL: Block 1
@@ -143,8 +141,7 @@ static __init void davinci_sffsdr_init(void)
ARRAY_SIZE(davinci_sffsdr_devices));
sffsdr_init_i2c();
davinci_serial_init(&uart_config);
- soc_info->emac_pdata->phy_mask = SFFSDR_PHY_MASK;
- soc_info->emac_pdata->mdio_max_freq = SFFSDR_MDIO_FREQUENCY;
+ soc_info->emac_pdata->phy_id = SFFSDR_PHY_ID;
davinci_setup_usb(0, 0); /* We support only peripheral mode. */
/* mux VLYNQ pins */
@@ -154,8 +151,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..a6db85460227 100644
--- a/arch/arm/mach-davinci/board-tnetv107x-evm.c
+++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c
@@ -23,6 +23,9 @@
#include <linux/ratelimit.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
+#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
+
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
@@ -141,10 +144,63 @@ static struct davinci_uart_config serial_config __initconst = {
.enabled_uarts = BIT(1),
};
+static const uint32_t keymap[] = {
+ KEY(0, 0, KEY_NUMERIC_1),
+ KEY(0, 1, KEY_NUMERIC_2),
+ KEY(0, 2, KEY_NUMERIC_3),
+ KEY(0, 3, KEY_FN_F1),
+ KEY(0, 4, KEY_MENU),
+
+ KEY(1, 0, KEY_NUMERIC_4),
+ KEY(1, 1, KEY_NUMERIC_5),
+ KEY(1, 2, KEY_NUMERIC_6),
+ KEY(1, 3, KEY_UP),
+ KEY(1, 4, KEY_FN_F2),
+
+ KEY(2, 0, KEY_NUMERIC_7),
+ KEY(2, 1, KEY_NUMERIC_8),
+ KEY(2, 2, KEY_NUMERIC_9),
+ KEY(2, 3, KEY_LEFT),
+ KEY(2, 4, KEY_ENTER),
+
+ KEY(3, 0, KEY_NUMERIC_STAR),
+ KEY(3, 1, KEY_NUMERIC_0),
+ KEY(3, 2, KEY_NUMERIC_POUND),
+ KEY(3, 3, KEY_DOWN),
+ KEY(3, 4, KEY_RIGHT),
+
+ KEY(4, 0, KEY_FN_F3),
+ KEY(4, 1, KEY_FN_F4),
+ KEY(4, 2, KEY_MUTE),
+ KEY(4, 3, KEY_HOME),
+ KEY(4, 4, KEY_BACK),
+
+ KEY(5, 0, KEY_VOLUMEDOWN),
+ KEY(5, 1, KEY_VOLUMEUP),
+ KEY(5, 2, KEY_F1),
+ KEY(5, 3, KEY_F2),
+ KEY(5, 4, KEY_F3),
+};
+
+static const struct matrix_keymap_data keymap_data = {
+ .keymap = keymap,
+ .keymap_size = ARRAY_SIZE(keymap),
+};
+
+static struct matrix_keypad_platform_data keypad_config = {
+ .keymap_data = &keymap_data,
+ .num_row_gpios = 6,
+ .num_col_gpios = 5,
+ .debounce_ms = 0, /* minimum */
+ .active_low = 0, /* pull up realization */
+ .no_autorepeat = 0,
+};
+
static struct tnetv107x_device_info evm_device_info __initconst = {
.serial_config = &serial_config,
.mmc_config[1] = &mmc_config, /* controller 1 */
.nand_config[0] = &nand_config, /* chip select 0 */
+ .keypad_config = &keypad_config,
};
static __init void tnetv107x_evm_board_init(void)
@@ -164,8 +220,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/clock.c b/arch/arm/mach-davinci/clock.c
index 054c303caead..01ba080433db 100644
--- a/arch/arm/mach-davinci/clock.c
+++ b/arch/arm/mach-davinci/clock.c
@@ -236,7 +236,7 @@ static int __init clk_disable_unused(void)
if (!davinci_psc_is_clk_active(ck->gpsc, ck->lpsc))
continue;
- pr_info("Clocks: disable unused %s\n", ck->name);
+ pr_debug("Clocks: disable unused %s\n", ck->name);
davinci_psc_config(psc_domain(ck), ck->gpsc, ck->lpsc,
(ck->flags & PSC_SWRSTDISABLE) ?
@@ -287,6 +287,79 @@ static unsigned long clk_sysclk_recalc(struct clk *clk)
return rate;
}
+int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned v;
+ struct pll_data *pll;
+ unsigned long input;
+ unsigned ratio = 0;
+
+ /* If this is the PLL base clock, wrong function to call */
+ if (clk->pll_data)
+ return -EINVAL;
+
+ /* There must be a parent... */
+ if (WARN_ON(!clk->parent))
+ return -EINVAL;
+
+ /* ... the parent must be a PLL... */
+ if (WARN_ON(!clk->parent->pll_data))
+ return -EINVAL;
+
+ /* ... and this clock must have a divider. */
+ if (WARN_ON(!clk->div_reg))
+ return -EINVAL;
+
+ pll = clk->parent->pll_data;
+
+ input = clk->parent->rate;
+
+ /* If pre-PLL, source clock is before the multiplier and divider(s) */
+ if (clk->flags & PRE_PLL)
+ input = pll->input_rate;
+
+ if (input > rate) {
+ /*
+ * Can afford to provide an output little higher than requested
+ * only if maximum rate supported by hardware on this sysclk
+ * is known.
+ */
+ if (clk->maxrate) {
+ ratio = DIV_ROUND_CLOSEST(input, rate);
+ if (input / ratio > clk->maxrate)
+ ratio = 0;
+ }
+
+ if (ratio == 0)
+ ratio = DIV_ROUND_UP(input, rate);
+
+ ratio--;
+ }
+
+ if (ratio > PLLDIV_RATIO_MASK)
+ return -EINVAL;
+
+ do {
+ v = __raw_readl(pll->base + PLLSTAT);
+ } while (v & PLLSTAT_GOSTAT);
+
+ v = __raw_readl(pll->base + clk->div_reg);
+ v &= ~PLLDIV_RATIO_MASK;
+ v |= ratio | PLLDIV_EN;
+ __raw_writel(v, pll->base + clk->div_reg);
+
+ v = __raw_readl(pll->base + PLLCMD);
+ v |= PLLCMD_GOSET;
+ __raw_writel(v, pll->base + PLLCMD);
+
+ do {
+ v = __raw_readl(pll->base + PLLSTAT);
+ } while (v & PLLSTAT_GOSTAT);
+
+ return 0;
+}
+EXPORT_SYMBOL(davinci_set_sysclk_rate);
+
static unsigned long clk_leafclk_recalc(struct clk *clk)
{
if (WARN_ON(!clk->parent))
diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h
index 01e36483ac3d..11099980b58b 100644
--- a/arch/arm/mach-davinci/clock.h
+++ b/arch/arm/mach-davinci/clock.h
@@ -70,6 +70,9 @@
#include <linux/list.h>
#include <asm/clkdev.h>
+#define PLLSTAT_GOSTAT BIT(0)
+#define PLLCMD_GOSET BIT(0)
+
struct pll_data {
u32 phys_base;
void __iomem *base;
@@ -86,6 +89,7 @@ struct clk {
struct module *owner;
const char *name;
unsigned long rate;
+ unsigned long maxrate; /* H/W supported max rate */
u8 usecount;
u8 lpsc;
u8 gpsc;
@@ -118,6 +122,7 @@ struct clk {
int davinci_clk_init(struct clk_lookup *clocks);
int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
unsigned int mult, unsigned int postdiv);
+int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate);
extern struct platform_device davinci_wdt_device;
extern void davinci_watchdog_reset(struct platform_device *);
diff --git a/arch/arm/mach-davinci/cpufreq.c b/arch/arm/mach-davinci/cpufreq.c
index d3fa6de1e20f..343de73161fa 100644
--- a/arch/arm/mach-davinci/cpufreq.c
+++ b/arch/arm/mach-davinci/cpufreq.c
@@ -34,6 +34,8 @@
struct davinci_cpufreq {
struct device *dev;
struct clk *armclk;
+ struct clk *asyncclk;
+ unsigned long asyncrate;
};
static struct davinci_cpufreq cpufreq;
@@ -104,15 +106,27 @@ static int davinci_target(struct cpufreq_policy *policy,
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
/* if moving to higher frequency, up the voltage beforehand */
- if (pdata->set_voltage && freqs.new > freqs.old)
- pdata->set_voltage(idx);
+ if (pdata->set_voltage && freqs.new > freqs.old) {
+ ret = pdata->set_voltage(idx);
+ if (ret)
+ goto out;
+ }
ret = clk_set_rate(armclk, idx);
+ if (ret)
+ goto out;
+
+ if (cpufreq.asyncclk) {
+ ret = clk_set_rate(cpufreq.asyncclk, cpufreq.asyncrate);
+ if (ret)
+ goto out;
+ }
/* if moving to lower freq, lower the voltage after lowering freq */
if (pdata->set_voltage && freqs.new < freqs.old)
pdata->set_voltage(idx);
+out:
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
return ret;
@@ -185,6 +199,7 @@ static struct cpufreq_driver davinci_driver = {
static int __init davinci_cpufreq_probe(struct platform_device *pdev)
{
struct davinci_cpufreq_config *pdata = pdev->dev.platform_data;
+ struct clk *asyncclk;
if (!pdata)
return -EINVAL;
@@ -199,6 +214,12 @@ static int __init davinci_cpufreq_probe(struct platform_device *pdev)
return PTR_ERR(cpufreq.armclk);
}
+ asyncclk = clk_get(cpufreq.dev, "async");
+ if (!IS_ERR(asyncclk)) {
+ cpufreq.asyncclk = asyncclk;
+ cpufreq.asyncrate = clk_get_rate(asyncclk);
+ }
+
return cpufreq_register_driver(&davinci_driver);
}
@@ -206,6 +227,9 @@ static int __exit davinci_cpufreq_remove(struct platform_device *pdev)
{
clk_put(cpufreq.armclk);
+ if (cpufreq.asyncclk)
+ clk_put(cpufreq.asyncclk);
+
return cpufreq_unregister_driver(&davinci_driver);
}
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 68ed58a48252..63916b902760 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -86,6 +86,8 @@ static struct clk pll0_sysclk3 = {
.parent = &pll0_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV3,
+ .set_rate = davinci_set_sysclk_rate,
+ .maxrate = 100000000,
};
static struct clk pll0_sysclk4 = {
@@ -323,12 +325,19 @@ static struct clk lcdc_clk = {
.gpsc = 1,
};
-static struct clk mmcsd_clk = {
- .name = "mmcsd",
+static struct clk mmcsd0_clk = {
+ .name = "mmcsd0",
.parent = &pll0_sysclk2,
.lpsc = DA8XX_LPSC0_MMC_SD,
};
+static struct clk mmcsd1_clk = {
+ .name = "mmcsd1",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA850_LPSC1_MMC_SD1,
+ .gpsc = 1,
+};
+
static struct clk aemif_clk = {
.name = "aemif",
.parent = &pll0_sysclk3,
@@ -375,7 +384,8 @@ static struct clk_lookup da850_clks[] = {
CLK("davinci_emac.1", NULL, &emac_clk),
CLK("davinci-mcasp.0", NULL, &mcasp_clk),
CLK("da8xx_lcdc.0", NULL, &lcdc_clk),
- CLK("davinci_mmc.0", NULL, &mmcsd_clk),
+ CLK("davinci_mmc.0", NULL, &mmcsd0_clk),
+ CLK("davinci_mmc.1", NULL, &mmcsd1_clk),
CLK(NULL, "aemif", &aemif_clk),
CLK(NULL, NULL, NULL),
};
@@ -572,15 +582,9 @@ const short da850_cpgmac_pins[] __initdata = {
DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER,
DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3,
DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK,
- DA850_MDIO_D,
- -1
-};
-
-const short da850_rmii_pins[] __initdata = {
- DA850_RMII_TXD_0, DA850_RMII_TXD_1, DA850_RMII_TXEN,
- DA850_RMII_CRS_DV, DA850_RMII_RXD_0, DA850_RMII_RXD_1,
- DA850_RMII_RXER, DA850_RMII_MHZ_50_CLK, DA850_MDIO_CLK,
- DA850_MDIO_D,
+ DA850_MDIO_D, DA850_RMII_TXD_0, DA850_RMII_TXD_1, DA850_RMII_TXEN,
+ DA850_RMII_CRS_DV, DA850_RMII_RXD_0, DA850_RMII_RXD_1, DA850_RMII_RXER,
+ DA850_RMII_MHZ_50_CLK,
-1
};
@@ -607,27 +611,19 @@ const short da850_mmcsd0_pins[] __initdata = {
-1
};
-const short da850_nand_pins[] __initdata = {
- DA850_EMA_D_7, DA850_EMA_D_6, DA850_EMA_D_5, DA850_EMA_D_4,
- DA850_EMA_D_3, DA850_EMA_D_2, DA850_EMA_D_1, DA850_EMA_D_0,
- DA850_EMA_A_1, DA850_EMA_A_2, DA850_NEMA_CS_3, DA850_NEMA_CS_4,
- DA850_NEMA_WE, DA850_NEMA_OE,
- -1
-};
-
-const short da850_nor_pins[] __initdata = {
+const short da850_emif25_pins[] __initdata = {
DA850_EMA_BA_1, DA850_EMA_CLK, DA850_EMA_WAIT_1, DA850_NEMA_CS_2,
- DA850_NEMA_WE, DA850_NEMA_OE, DA850_EMA_D_0, DA850_EMA_D_1,
- DA850_EMA_D_2, DA850_EMA_D_3, DA850_EMA_D_4, DA850_EMA_D_5,
- DA850_EMA_D_6, DA850_EMA_D_7, DA850_EMA_D_8, DA850_EMA_D_9,
- DA850_EMA_D_10, DA850_EMA_D_11, DA850_EMA_D_12, DA850_EMA_D_13,
- DA850_EMA_D_14, DA850_EMA_D_15, DA850_EMA_A_0, DA850_EMA_A_1,
- DA850_EMA_A_2, DA850_EMA_A_3, DA850_EMA_A_4, DA850_EMA_A_5,
- DA850_EMA_A_6, DA850_EMA_A_7, DA850_EMA_A_8, DA850_EMA_A_9,
- DA850_EMA_A_10, DA850_EMA_A_11, DA850_EMA_A_12, DA850_EMA_A_13,
- DA850_EMA_A_14, DA850_EMA_A_15, DA850_EMA_A_16, DA850_EMA_A_17,
- DA850_EMA_A_18, DA850_EMA_A_19, DA850_EMA_A_20, DA850_EMA_A_21,
- DA850_EMA_A_22, DA850_EMA_A_23,
+ DA850_NEMA_CS_3, DA850_NEMA_CS_4, DA850_NEMA_WE, DA850_NEMA_OE,
+ DA850_EMA_D_0, DA850_EMA_D_1, DA850_EMA_D_2, DA850_EMA_D_3,
+ DA850_EMA_D_4, DA850_EMA_D_5, DA850_EMA_D_6, DA850_EMA_D_7,
+ DA850_EMA_D_8, DA850_EMA_D_9, DA850_EMA_D_10, DA850_EMA_D_11,
+ DA850_EMA_D_12, DA850_EMA_D_13, DA850_EMA_D_14, DA850_EMA_D_15,
+ DA850_EMA_A_0, DA850_EMA_A_1, DA850_EMA_A_2, DA850_EMA_A_3,
+ DA850_EMA_A_4, DA850_EMA_A_5, DA850_EMA_A_6, DA850_EMA_A_7,
+ DA850_EMA_A_8, DA850_EMA_A_9, DA850_EMA_A_10, DA850_EMA_A_11,
+ DA850_EMA_A_12, DA850_EMA_A_13, DA850_EMA_A_14, DA850_EMA_A_15,
+ DA850_EMA_A_16, DA850_EMA_A_17, DA850_EMA_A_18, DA850_EMA_A_19,
+ DA850_EMA_A_20, DA850_EMA_A_21, DA850_EMA_A_22, DA850_EMA_A_23,
-1
};
@@ -851,7 +847,7 @@ static const struct da850_opp da850_opp_300 = {
.prediv = 1,
.mult = 25,
.postdiv = 2,
- .cvdd_min = 1140000,
+ .cvdd_min = 1200000,
.cvdd_max = 1320000,
};
@@ -860,7 +856,7 @@ static const struct da850_opp da850_opp_200 = {
.prediv = 1,
.mult = 25,
.postdiv = 3,
- .cvdd_min = 1050000,
+ .cvdd_min = 1100000,
.cvdd_max = 1160000,
};
@@ -869,7 +865,7 @@ static const struct da850_opp da850_opp_96 = {
.prediv = 1,
.mult = 20,
.postdiv = 5,
- .cvdd_min = 950000,
+ .cvdd_min = 1000000,
.cvdd_max = 1050000,
};
@@ -929,10 +925,16 @@ static struct platform_device da850_cpufreq_device = {
.dev = {
.platform_data = &cpufreq_info,
},
+ .id = -1,
};
-int __init da850_register_cpufreq(void)
+int __init da850_register_cpufreq(char *async_clk)
{
+ /* cpufreq driver can help keep an "async" clock constant */
+ if (async_clk)
+ clk_add_alias("async", da850_cpufreq_device.name,
+ async_clk, NULL);
+
return platform_device_register(&da850_cpufreq_device);
}
@@ -983,7 +985,7 @@ static int da850_set_pll0rate(struct clk *clk, unsigned long index)
return 0;
}
#else
-int __init da850_register_cpufreq(void)
+int __init da850_register_cpufreq(char *async_clk)
{
return 0;
}
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
index 52bc7b1c6ca3..9eec63070e0c 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -24,6 +24,7 @@
#include "clock.h"
#define DA8XX_TPCC_BASE 0x01c00000
+#define DA850_MMCSD1_BASE 0x01e1b000
#define DA850_TPCC1_BASE 0x01e30000
#define DA8XX_TPTC0_BASE 0x01c08000
#define DA8XX_TPTC1_BASE 0x01c08400
@@ -41,7 +42,6 @@
#define DA8XX_EMAC_CTRL_REG_OFFSET 0x3000
#define DA8XX_EMAC_MOD_REG_OFFSET 0x2000
#define DA8XX_EMAC_RAM_OFFSET 0x0000
-#define DA8XX_MDIO_REG_OFFSET 0x4000
#define DA8XX_EMAC_CTRL_RAM_SIZE SZ_8K
void __iomem *da8xx_syscfg0_base;
@@ -351,7 +351,7 @@ int __init da8xx_register_watchdog(void)
static struct resource da8xx_emac_resources[] = {
{
.start = DA8XX_EMAC_CPPI_PORT_BASE,
- .end = DA8XX_EMAC_CPPI_PORT_BASE + 0x5000 - 1,
+ .end = DA8XX_EMAC_CPPI_PORT_BASE + SZ_16K - 1,
.flags = IORESOURCE_MEM,
},
{
@@ -380,7 +380,6 @@ struct emac_platform_data da8xx_emac_pdata = {
.ctrl_reg_offset = DA8XX_EMAC_CTRL_REG_OFFSET,
.ctrl_mod_reg_offset = DA8XX_EMAC_MOD_REG_OFFSET,
.ctrl_ram_offset = DA8XX_EMAC_RAM_OFFSET,
- .mdio_reg_offset = DA8XX_MDIO_REG_OFFSET,
.ctrl_ram_size = DA8XX_EMAC_CTRL_RAM_SIZE,
.version = EMAC_VERSION_2,
};
@@ -395,9 +394,34 @@ static struct platform_device da8xx_emac_device = {
.resource = da8xx_emac_resources,
};
+static struct resource da8xx_mdio_resources[] = {
+ {
+ .start = DA8XX_EMAC_MDIO_BASE,
+ .end = DA8XX_EMAC_MDIO_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device da8xx_mdio_device = {
+ .name = "davinci_mdio",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(da8xx_mdio_resources),
+ .resource = da8xx_mdio_resources,
+};
+
int __init da8xx_register_emac(void)
{
- return platform_device_register(&da8xx_emac_device);
+ int ret;
+
+ ret = platform_device_register(&da8xx_mdio_device);
+ if (ret < 0)
+ return ret;
+ ret = platform_device_register(&da8xx_emac_device);
+ if (ret < 0)
+ return ret;
+ ret = clk_add_alias(NULL, dev_name(&da8xx_mdio_device.dev),
+ NULL, &da8xx_emac_device.dev);
+ return ret;
}
static struct resource da830_mcasp1_resources[] = {
@@ -566,6 +590,44 @@ int __init da8xx_register_mmcsd0(struct davinci_mmc_config *config)
return platform_device_register(&da8xx_mmcsd0_device);
}
+#ifdef CONFIG_ARCH_DAVINCI_DA850
+static struct resource da850_mmcsd1_resources[] = {
+ { /* registers */
+ .start = DA850_MMCSD1_BASE,
+ .end = DA850_MMCSD1_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ { /* interrupt */
+ .start = IRQ_DA850_MMCSDINT0_1,
+ .end = IRQ_DA850_MMCSDINT0_1,
+ .flags = IORESOURCE_IRQ,
+ },
+ { /* DMA RX */
+ .start = EDMA_CTLR_CHAN(1, 28),
+ .end = EDMA_CTLR_CHAN(1, 28),
+ .flags = IORESOURCE_DMA,
+ },
+ { /* DMA TX */
+ .start = EDMA_CTLR_CHAN(1, 29),
+ .end = EDMA_CTLR_CHAN(1, 29),
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device da850_mmcsd1_device = {
+ .name = "davinci_mmc",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(da850_mmcsd1_resources),
+ .resource = da850_mmcsd1_resources,
+};
+
+int __init da850_register_mmcsd1(struct davinci_mmc_config *config)
+{
+ da850_mmcsd1_device.dev.platform_data = config;
+ return platform_device_register(&da850_mmcsd1_device);
+}
+#endif
+
static struct resource da8xx_rtc_resources[] = {
{
.start = DA8XX_RTC_BASE,
diff --git a/arch/arm/mach-davinci/devices-tnetv107x.c b/arch/arm/mach-davinci/devices-tnetv107x.c
index 2718a3a90dff..c9a86d8130d1 100644
--- a/arch/arm/mach-davinci/devices-tnetv107x.c
+++ b/arch/arm/mach-davinci/devices-tnetv107x.c
@@ -31,8 +31,10 @@
#define TNETV107X_TPTC0_BASE 0x01c10000
#define TNETV107X_TPTC1_BASE 0x01c10400
#define TNETV107X_WDOG_BASE 0x08086700
+#define TNETV107X_TSC_BASE 0x08088500
#define TNETV107X_SDIO0_BASE 0x08088700
#define TNETV107X_SDIO1_BASE 0x08088800
+#define TNETV107X_KEYPAD_BASE 0x08088a00
#define TNETV107X_ASYNC_EMIF_CNTRL_BASE 0x08200000
#define TNETV107X_ASYNC_EMIF_DATA_CE0_BASE 0x30000000
#define TNETV107X_ASYNC_EMIF_DATA_CE1_BASE 0x40000000
@@ -298,12 +300,55 @@ static int __init nand_init(int chipsel, struct davinci_nand_pdata *data)
return platform_device_register(pdev);
}
+static struct resource keypad_resources[] = {
+ {
+ .start = TNETV107X_KEYPAD_BASE,
+ .end = TNETV107X_KEYPAD_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_TNETV107X_KEYPAD,
+ .flags = IORESOURCE_IRQ,
+ .name = "press",
+ },
+ {
+ .start = IRQ_TNETV107X_KEYPAD_FREE,
+ .flags = IORESOURCE_IRQ,
+ .name = "release",
+ },
+};
+
+static struct platform_device keypad_device = {
+ .name = "tnetv107x-keypad",
+ .num_resources = ARRAY_SIZE(keypad_resources),
+ .resource = keypad_resources,
+};
+
+static struct resource tsc_resources[] = {
+ {
+ .start = TNETV107X_TSC_BASE,
+ .end = TNETV107X_TSC_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_TNETV107X_TSC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tsc_device = {
+ .name = "tnetv107x-ts",
+ .num_resources = ARRAY_SIZE(tsc_resources),
+ .resource = tsc_resources,
+};
+
void __init tnetv107x_devices_init(struct tnetv107x_device_info *info)
{
int i;
platform_device_register(&edma_device);
platform_device_register(&tnetv107x_wdt_device);
+ platform_device_register(&tsc_device);
if (info->serial_config)
davinci_serial_init(info->serial_config);
@@ -317,4 +362,9 @@ void __init tnetv107x_devices_init(struct tnetv107x_device_info *info)
for (i = 0; i < 4; i++)
if (info->nand_config[i])
nand_init(i, info->nand_config[i]);
+
+ if (info->keypad_config) {
+ keypad_device.dev.platform_data = info->keypad_config;
+ platform_device_register(&keypad_device);
+ }
}
diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c
index de40e9c787e1..22ebc64bc9d9 100644
--- a/arch/arm/mach-davinci/devices.c
+++ b/arch/arm/mach-davinci/devices.c
@@ -213,7 +213,7 @@ void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config)
IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE + 0x7c);
/* Configure pull down control */
- __raw_writel((__raw_readl(pupdctl1) & ~0x400),
+ __raw_writel((__raw_readl(pupdctl1) & ~0xfc0),
pupdctl1);
mmcsd1_resources[0].start = DM365_MMCSD1_BASE;
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index 7781e35daec3..a12065e87266 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -691,7 +691,6 @@ static struct emac_platform_data dm365_emac_pdata = {
.ctrl_reg_offset = DM365_EMAC_CNTRL_OFFSET,
.ctrl_mod_reg_offset = DM365_EMAC_CNTRL_MOD_OFFSET,
.ctrl_ram_offset = DM365_EMAC_CNTRL_RAM_OFFSET,
- .mdio_reg_offset = DM365_EMAC_MDIO_OFFSET,
.ctrl_ram_size = DM365_EMAC_CNTRL_RAM_SIZE,
.version = EMAC_VERSION_2,
};
@@ -699,7 +698,7 @@ static struct emac_platform_data dm365_emac_pdata = {
static struct resource dm365_emac_resources[] = {
{
.start = DM365_EMAC_BASE,
- .end = DM365_EMAC_BASE + 0x47ff,
+ .end = DM365_EMAC_BASE + SZ_16K - 1,
.flags = IORESOURCE_MEM,
},
{
@@ -734,6 +733,21 @@ static struct platform_device dm365_emac_device = {
.resource = dm365_emac_resources,
};
+static struct resource dm365_mdio_resources[] = {
+ {
+ .start = DM365_EMAC_MDIO_BASE,
+ .end = DM365_EMAC_MDIO_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm365_mdio_device = {
+ .name = "davinci_mdio",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(dm365_mdio_resources),
+ .resource = dm365_mdio_resources,
+};
+
static u8 dm365_default_priorities[DAVINCI_N_AINTC_IRQ] = {
[IRQ_VDINT0] = 2,
[IRQ_VDINT1] = 6,
@@ -1219,7 +1233,12 @@ static int __init dm365_init_devices(void)
davinci_cfg_reg(DM365_INT_EDMA_CC);
platform_device_register(&dm365_edma_device);
+
+ platform_device_register(&dm365_mdio_device);
platform_device_register(&dm365_emac_device);
+ clk_add_alias(NULL, dev_name(&dm365_mdio_device.dev),
+ NULL, &dm365_emac_device.dev);
+
/* Add isif clock alias */
clk_add_alias("master", dm365_isif_dev.name, "vpss_master", NULL);
platform_device_register(&dm365_vpss_device);
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index 5e5b0a7831fb..0608dd776a16 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -322,7 +322,6 @@ static struct emac_platform_data dm644x_emac_pdata = {
.ctrl_reg_offset = DM644X_EMAC_CNTRL_OFFSET,
.ctrl_mod_reg_offset = DM644X_EMAC_CNTRL_MOD_OFFSET,
.ctrl_ram_offset = DM644X_EMAC_CNTRL_RAM_OFFSET,
- .mdio_reg_offset = DM644X_EMAC_MDIO_OFFSET,
.ctrl_ram_size = DM644X_EMAC_CNTRL_RAM_SIZE,
.version = EMAC_VERSION_1,
};
@@ -330,7 +329,7 @@ static struct emac_platform_data dm644x_emac_pdata = {
static struct resource dm644x_emac_resources[] = {
{
.start = DM644X_EMAC_BASE,
- .end = DM644X_EMAC_BASE + 0x47ff,
+ .end = DM644X_EMAC_BASE + SZ_16K - 1,
.flags = IORESOURCE_MEM,
},
{
@@ -350,6 +349,21 @@ static struct platform_device dm644x_emac_device = {
.resource = dm644x_emac_resources,
};
+static struct resource dm644x_mdio_resources[] = {
+ {
+ .start = DM644X_EMAC_MDIO_BASE,
+ .end = DM644X_EMAC_MDIO_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm644x_mdio_device = {
+ .name = "davinci_mdio",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(dm644x_mdio_resources),
+ .resource = dm644x_mdio_resources,
+};
+
/*
* Device specific mux setup
*
@@ -776,7 +790,12 @@ static int __init dm644x_init_devices(void)
clk_add_alias("master", dm644x_ccdc_dev.name, "vpss_master", NULL);
clk_add_alias("slave", dm644x_ccdc_dev.name, "vpss_slave", NULL);
platform_device_register(&dm644x_edma_device);
+
+ platform_device_register(&dm644x_mdio_device);
platform_device_register(&dm644x_emac_device);
+ clk_add_alias(NULL, dev_name(&dm644x_mdio_device.dev),
+ NULL, &dm644x_emac_device.dev);
+
platform_device_register(&dm644x_vpss_device);
platform_device_register(&dm644x_ccdc_dev);
platform_device_register(&vpfe_capture_dev);
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index 26e8a9c7f50b..1e0f809644bb 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -358,7 +358,6 @@ static struct emac_platform_data dm646x_emac_pdata = {
.ctrl_reg_offset = DM646X_EMAC_CNTRL_OFFSET,
.ctrl_mod_reg_offset = DM646X_EMAC_CNTRL_MOD_OFFSET,
.ctrl_ram_offset = DM646X_EMAC_CNTRL_RAM_OFFSET,
- .mdio_reg_offset = DM646X_EMAC_MDIO_OFFSET,
.ctrl_ram_size = DM646X_EMAC_CNTRL_RAM_SIZE,
.version = EMAC_VERSION_2,
};
@@ -366,7 +365,7 @@ static struct emac_platform_data dm646x_emac_pdata = {
static struct resource dm646x_emac_resources[] = {
{
.start = DM646X_EMAC_BASE,
- .end = DM646X_EMAC_BASE + 0x47ff,
+ .end = DM646X_EMAC_BASE + SZ_16K - 1,
.flags = IORESOURCE_MEM,
},
{
@@ -401,6 +400,21 @@ static struct platform_device dm646x_emac_device = {
.resource = dm646x_emac_resources,
};
+static struct resource dm646x_mdio_resources[] = {
+ {
+ .start = DM646X_EMAC_MDIO_BASE,
+ .end = DM646X_EMAC_MDIO_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm646x_mdio_device = {
+ .name = "davinci_mdio",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(dm646x_mdio_resources),
+ .resource = dm646x_mdio_resources,
+};
+
/*
* Device specific mux setup
*
@@ -896,7 +910,11 @@ static int __init dm646x_init_devices(void)
if (!cpu_is_davinci_dm646x())
return 0;
+ platform_device_register(&dm646x_mdio_device);
platform_device_register(&dm646x_emac_device);
+ clk_add_alias(NULL, dev_name(&dm646x_mdio_device.dev),
+ NULL, &dm646x_emac_device.dev);
+
return 0;
}
postcore_initcall(dm646x_init_devices);
diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c
index 2ede598b77dd..6b9669869c46 100644
--- a/arch/arm/mach-davinci/dma.c
+++ b/arch/arm/mach-davinci/dma.c
@@ -354,10 +354,12 @@ static int irq2ctlr(int irq)
static irqreturn_t dma_irq_handler(int irq, void *data)
{
int i;
- unsigned ctlr;
+ int ctlr;
unsigned int cnt = 0;
ctlr = irq2ctlr(irq);
+ if (ctlr < 0)
+ return IRQ_NONE;
dev_dbg(data, "dma_irq_handler\n");
@@ -408,10 +410,12 @@ static irqreturn_t dma_irq_handler(int irq, void *data)
static irqreturn_t dma_ccerr_handler(int irq, void *data)
{
int i;
- unsigned ctlr;
+ int ctlr;
unsigned int cnt = 0;
ctlr = irq2ctlr(irq);
+ if (ctlr < 0)
+ return IRQ_NONE;
dev_dbg(data, "dma_ccerr_handler\n");
diff --git a/arch/arm/mach-davinci/include/mach/aemif.h b/arch/arm/mach-davinci/include/mach/aemif.h
new file mode 100644
index 000000000000..05b293443097
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/aemif.h
@@ -0,0 +1,36 @@
+/*
+ * TI DaVinci AEMIF support
+ *
+ * Copyright 2010 (C) Texas Instruments, Inc. http://www.ti.com/
+ *
+ * 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_DAVINCI_AEMIF_H
+#define _MACH_DAVINCI_AEMIF_H
+
+#define NRCSR_OFFSET 0x00
+#define AWCCR_OFFSET 0x04
+#define A1CR_OFFSET 0x10
+
+#define ACR_ASIZE_MASK 0x3
+#define ACR_EW_MASK BIT(30)
+#define ACR_SS_MASK BIT(31)
+
+/* All timings in nanoseconds */
+struct davinci_aemif_timing {
+ u8 wsetup;
+ u8 wstrobe;
+ u8 whold;
+
+ u8 rsetup;
+ u8 rstrobe;
+ u8 rhold;
+
+ u8 ta;
+};
+
+int davinci_aemif_setup_timing(struct davinci_aemif_timing *t,
+ void __iomem *base, unsigned cs);
+#endif
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
index 3c07059f526e..4247b3f53b33 100644
--- a/arch/arm/mach-davinci/include/mach/da8xx.h
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -76,9 +76,10 @@ int da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata);
int da8xx_register_emac(void);
int da8xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata);
int da8xx_register_mmcsd0(struct davinci_mmc_config *config);
+int da850_register_mmcsd1(struct davinci_mmc_config *config);
void __init da8xx_register_mcasp(int id, struct snd_platform_data *pdata);
int da8xx_register_rtc(void);
-int da850_register_cpufreq(void);
+int da850_register_cpufreq(char *async_clk);
int da8xx_register_cpuidle(void);
void __iomem * __init da8xx_get_mem_ctlr(void);
int da850_register_pm(struct platform_device *pdev);
@@ -121,11 +122,9 @@ extern const short da850_uart2_pins[];
extern const short da850_i2c0_pins[];
extern const short da850_i2c1_pins[];
extern const short da850_cpgmac_pins[];
-extern const short da850_rmii_pins[];
extern const short da850_mcasp_pins[];
extern const short da850_lcdcntl_pins[];
extern const short da850_mmcsd0_pins[];
-extern const short da850_nand_pins[];
-extern const short da850_nor_pins[];
+extern const short da850_emif25_pins[];
#endif /* __ASM_ARCH_DAVINCI_DA8XX_H */
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-davinci/include/mach/dm365.h b/arch/arm/mach-davinci/include/mach/dm365.h
index ea5df3b49ec4..2563bf4e93a1 100644
--- a/arch/arm/mach-davinci/include/mach/dm365.h
+++ b/arch/arm/mach-davinci/include/mach/dm365.h
@@ -21,10 +21,10 @@
#include <media/davinci/vpfe_capture.h>
#define DM365_EMAC_BASE (0x01D07000)
+#define DM365_EMAC_MDIO_BASE (DM365_EMAC_BASE + 0x4000)
#define DM365_EMAC_CNTRL_OFFSET (0x0000)
#define DM365_EMAC_CNTRL_MOD_OFFSET (0x3000)
#define DM365_EMAC_CNTRL_RAM_OFFSET (0x1000)
-#define DM365_EMAC_MDIO_OFFSET (0x4000)
#define DM365_EMAC_CNTRL_RAM_SIZE (0x2000)
/* Base of key scan register bank */
diff --git a/arch/arm/mach-davinci/include/mach/dm644x.h b/arch/arm/mach-davinci/include/mach/dm644x.h
index 6fca568a0fd2..5a1b26d4e68b 100644
--- a/arch/arm/mach-davinci/include/mach/dm644x.h
+++ b/arch/arm/mach-davinci/include/mach/dm644x.h
@@ -28,10 +28,10 @@
#include <media/davinci/vpfe_capture.h>
#define DM644X_EMAC_BASE (0x01C80000)
+#define DM644X_EMAC_MDIO_BASE (DM644X_EMAC_BASE + 0x4000)
#define DM644X_EMAC_CNTRL_OFFSET (0x0000)
#define DM644X_EMAC_CNTRL_MOD_OFFSET (0x1000)
#define DM644X_EMAC_CNTRL_RAM_OFFSET (0x2000)
-#define DM644X_EMAC_MDIO_OFFSET (0x4000)
#define DM644X_EMAC_CNTRL_RAM_SIZE (0x2000)
#define DM644X_ASYNC_EMIF_CONTROL_BASE 0x01E00000
diff --git a/arch/arm/mach-davinci/include/mach/dm646x.h b/arch/arm/mach-davinci/include/mach/dm646x.h
index 0a27ee9a70e1..7a27f3f13913 100644
--- a/arch/arm/mach-davinci/include/mach/dm646x.h
+++ b/arch/arm/mach-davinci/include/mach/dm646x.h
@@ -19,10 +19,10 @@
#include <linux/davinci_emac.h>
#define DM646X_EMAC_BASE (0x01C80000)
+#define DM646X_EMAC_MDIO_BASE (DM646X_EMAC_BASE + 0x4000)
#define DM646X_EMAC_CNTRL_OFFSET (0x0000)
#define DM646X_EMAC_CNTRL_MOD_OFFSET (0x1000)
#define DM646X_EMAC_CNTRL_RAM_OFFSET (0x2000)
-#define DM646X_EMAC_MDIO_OFFSET (0x4000)
#define DM646X_EMAC_CNTRL_RAM_SIZE (0x2000)
#define DM646X_ASYNC_EMIF_CONTROL_BASE 0x20008000
diff --git a/arch/arm/mach-davinci/include/mach/nand.h b/arch/arm/mach-davinci/include/mach/nand.h
index b2ad8090bd10..025151049f05 100644
--- a/arch/arm/mach-davinci/include/mach/nand.h
+++ b/arch/arm/mach-davinci/include/mach/nand.h
@@ -30,9 +30,6 @@
#include <linux/mtd/nand.h>
-#define NRCSR_OFFSET 0x00
-#define AWCCR_OFFSET 0x04
-#define A1CR_OFFSET 0x10
#define NANDFCR_OFFSET 0x60
#define NANDFSR_OFFSET 0x64
#define NANDF1ECC_OFFSET 0x70
@@ -83,6 +80,9 @@ struct davinci_nand_pdata { /* platform_data */
/* Main and mirror bbt descriptor overrides */
struct nand_bbt_descr *bbt_td;
struct nand_bbt_descr *bbt_md;
+
+ /* Access timings */
+ struct davinci_aemif_timing *timing;
};
#endif /* __ARCH_ARM_DAVINCI_NAND_H */
diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/include/mach/psc.h
index 983da6e4554c..62b0858f68ca 100644
--- a/arch/arm/mach-davinci/include/mach/psc.h
+++ b/arch/arm/mach-davinci/include/mach/psc.h
@@ -172,6 +172,7 @@
#define DA8XX_LPSC1_UART2 13
#define DA8XX_LPSC1_LCDC 16
#define DA8XX_LPSC1_PWM 17
+#define DA850_LPSC1_MMC_SD1 18
#define DA8XX_LPSC1_ECAP 20
#define DA830_LPSC1_EQEP 21
#define DA850_LPSC1_TPTC2 21
diff --git a/arch/arm/mach-davinci/include/mach/tnetv107x.h b/arch/arm/mach-davinci/include/mach/tnetv107x.h
index c72064733123..5a681d880dcb 100644
--- a/arch/arm/mach-davinci/include/mach/tnetv107x.h
+++ b/arch/arm/mach-davinci/include/mach/tnetv107x.h
@@ -33,6 +33,8 @@
#ifndef __ASSEMBLY__
#include <linux/serial_8250.h>
+#include <linux/input/matrix_keypad.h>
+
#include <mach/mmc.h>
#include <mach/nand.h>
#include <mach/serial.h>
@@ -41,6 +43,7 @@ struct tnetv107x_device_info {
struct davinci_uart_config *serial_config;
struct davinci_mmc_config *mmc_config[2]; /* 2 controllers */
struct davinci_nand_pdata *nand_config[4]; /* 4 chipsels */
+ struct matrix_keypad_platform_data *keypad_config;
};
extern struct platform_device tnetv107x_wdt_device;
diff --git a/arch/arm/mach-davinci/include/mach/uncompress.h b/arch/arm/mach-davinci/include/mach/uncompress.h
index 15a6192ad6eb..47723e8d75a4 100644
--- a/arch/arm/mach-davinci/include/mach/uncompress.h
+++ b/arch/arm/mach-davinci/include/mach/uncompress.h
@@ -88,6 +88,8 @@ static inline void __arch_decomp_setup(unsigned long arch_id)
/* DA8xx boards */
DEBUG_LL_DA8XX(davinci_da830_evm, 2);
DEBUG_LL_DA8XX(davinci_da850_evm, 2);
+ DEBUG_LL_DA8XX(mityomapl138, 1);
+ DEBUG_LL_DA8XX(omapl138_hawkboard, 2);
/* TNETV107x boards */
DEBUG_LL_TNETV107X(tnetv107x, 1);
diff --git a/arch/arm/mach-davinci/tnetv107x.c b/arch/arm/mach-davinci/tnetv107x.c
index 864e60482c53..daeae06430b9 100644
--- a/arch/arm/mach-davinci/tnetv107x.c
+++ b/arch/arm/mach-davinci/tnetv107x.c
@@ -104,7 +104,7 @@ static u32 pll_ext_freq[] = {
};
/* PSC control registers */
-static u32 psc_regs[] __initconst = { TNETV107X_PSC_BASE };
+static u32 psc_regs[] = { TNETV107X_PSC_BASE };
/* Host map for interrupt controller */
static u32 intc_host_map[] = { 0x01010000, 0x01010101, -1 };
@@ -581,7 +581,14 @@ static struct davinci_id ids[] = {
.part_no = 0xb8a1,
.manufacturer = 0x017,
.cpu_id = DAVINCI_CPU_ID_TNETV107X,
- .name = "tnetv107x rev1.0",
+ .name = "tnetv107x rev 1.0",
+ },
+ {
+ .variant = 0x1,
+ .part_no = 0xb8a1,
+ .manufacturer = 0x017,
+ .cpu_id = DAVINCI_CPU_ID_TNETV107X,
+ .name = "tnetv107x rev 1.1/1.2",
},
};
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/clock.c b/arch/arm/mach-ep93xx/clock.c
index 4566bd1c8660..ef06c66a6f16 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -358,8 +358,7 @@ static int calc_clk_div(struct clk *clk, unsigned long rate,
int i, found = 0, __div = 0, __pdiv = 0;
/* Don't exceed the maximum rate */
- max_rate = max(max(clk_pll1.rate / 4, clk_pll2.rate / 4),
- clk_xtali.rate / 4);
+ max_rate = max3(clk_pll1.rate / 4, clk_pll2.rate / 4, clk_xtali.rate / 4);
rate = min(rate, max_rate);
/*
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 f5f81f9719bd..d96dc1c5da20 100644
--- a/arch/arm/mach-ep93xx/simone.c
+++ b/arch/arm/mach-ep93xx/simone.c
@@ -66,8 +66,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 2f7e2728970d..197f9e241cff 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -147,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
@@ -164,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
@@ -174,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/include/mach/dma-v1.h b/arch/arm/mach-imx/include/mach/dma-v1.h
index 287431cc13e5..ac6fd713828a 100644
--- a/arch/arm/mach-imx/include/mach/dma-v1.h
+++ b/arch/arm/mach-imx/include/mach/dma-v1.h
@@ -27,6 +27,8 @@
#define imx_has_dma_v1() (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())
+#include <mach/dma.h>
+
#define IMX_DMA_CHANNELS 16
#define DMA_MODE_READ 0
@@ -96,12 +98,6 @@ int imx_dma_request(int channel, const char *name);
void imx_dma_free(int channel);
-enum imx_dma_prio {
- DMA_PRIO_HIGH = 0,
- DMA_PRIO_MEDIUM = 1,
- DMA_PRIO_LOW = 2
-};
-
int imx_dma_request_by_prio(const char *name, enum imx_dma_prio prio);
#endif /* __MACH_DMA_V1_H__ */
diff --git a/arch/arm/mach-imx/mach-cpuimx27.c b/arch/arm/mach-imx/mach-cpuimx27.c
index 6830afd1d2ba..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_imx0(&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..84a5ba03f1ba 100644
--- a/arch/arm/mach-imx/mach-mx27_3ds.c
+++ b/arch/arm/mach-imx/mach-mx27_3ds.c
@@ -23,17 +23,21 @@
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/input/matrix_keypad.h>
+#include <linux/irq.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
#include <mach/hardware.h>
#include <mach/common.h>
#include <mach/iomux-mx27.h>
+#include <mach/mmc.h>
#include "devices-imx27.h"
#include "devices.h"
-static unsigned int mx27pdk_pins[] = {
+#define SD1_EN_GPIO (GPIO_PORTB + 25)
+
+static const int mx27pdk_pins[] __initconst = {
/* UART1 */
PE12_PF_UART1_TXD,
PE13_PF_UART1_RXD,
@@ -58,16 +62,20 @@ static unsigned int mx27pdk_pins[] = {
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,
+ SD1_EN_GPIO | GPIO_GPIO | GPIO_OUT,
};
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
*/
@@ -89,13 +97,39 @@ static struct matrix_keymap_data mx27_3ds_keymap_data = {
.keymap_size = ARRAY_SIZE(mx27_3ds_keymap),
};
+static int mx27_3ds_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
+ void *data)
+{
+ return request_irq(IRQ_GPIOB(26), detect_irq, IRQF_TRIGGER_FALLING |
+ IRQF_TRIGGER_RISING, "sdhc1-card-detect", data);
+}
+
+static void mx27_3ds_sdhc1_exit(struct device *dev, void *data)
+{
+ free_irq(IRQ_GPIOB(26), data);
+}
+
+static struct imxmmc_platform_data sdhc1_pdata = {
+ .init = mx27_3ds_sdhc1_init,
+ .exit = mx27_3ds_sdhc1_exit,
+};
+
+static void mx27_3ds_sdhc1_enable_level_translator(void)
+{
+ /* Turn on TXB0108 OE pin */
+ gpio_request(SD1_EN_GPIO, "sd1_enable");
+ gpio_direction_output(SD1_EN_GPIO, 1);
+}
+
static void __init mx27pdk_init(void)
{
mxc_gpio_setup_multiple_pins(mx27pdk_pins, ARRAY_SIZE(mx27pdk_pins),
"mx27pdk");
+ mx27_3ds_sdhc1_enable_level_translator();
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);
+ mxc_register_device(&mxc_sdhc_device0, &sdhc1_pdata);
}
static void __init mx27pdk_timer_init(void)
@@ -109,8 +143,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/core.c b/arch/arm/mach-ixp2000/core.c
index babb22597163..e24e3d05397f 100644
--- a/arch/arm/mach-ixp2000/core.c
+++ b/arch/arm/mach-ixp2000/core.c
@@ -197,7 +197,7 @@ unsigned long ixp2000_gettimeoffset (void)
return offset / ticks_per_usec;
}
-static int ixp2000_timer_interrupt(int irq, void *dev_id)
+static irqreturn_t ixp2000_timer_interrupt(int irq, void *dev_id)
{
/* clear timer 1 */
ixp2000_reg_wrb(IXP2000_T1_CLR, 1);
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..5ea66f1f4178 100644
--- a/arch/arm/mach-kirkwood/netspace_v2-setup.c
+++ b/arch/arm/mach-kirkwood/netspace_v2-setup.c
@@ -24,56 +24,20 @@
#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 <linux/gpio-fan.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 +48,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 +55,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,17 +138,43 @@ static struct platform_device netspace_v2_leds = {
};
/*****************************************************************************
- * Timer
+ * GPIO fan
****************************************************************************/
-static void netspace_v2_timer_init(void)
-{
- kirkwood_tclk = 166666667;
- orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk);
-}
+/* Designed for fan 40x40x16: ADDA AD0412LB-D50 6000rpm@12v */
+static struct gpio_fan_speed netspace_max_v2_fan_speed[] = {
+ { 0, 0 },
+ { 1500, 15 },
+ { 1700, 14 },
+ { 1800, 13 },
+ { 2100, 12 },
+ { 3100, 11 },
+ { 3300, 10 },
+ { 4300, 9 },
+ { 5500, 8 },
+};
+
+static unsigned netspace_max_v2_fan_ctrl[] = { 22, 7, 33, 23 };
+
+static struct gpio_fan_alarm netspace_max_v2_fan_alarm = {
+ .gpio = 25,
+ .active_low = 1,
+};
-struct sys_timer netspace_v2_timer = {
- .init = netspace_v2_timer_init,
+static struct gpio_fan_platform_data netspace_max_v2_fan_data = {
+ .num_ctrl = ARRAY_SIZE(netspace_max_v2_fan_ctrl),
+ .ctrl = netspace_max_v2_fan_ctrl,
+ .alarm = &netspace_max_v2_fan_alarm,
+ .num_speed = ARRAY_SIZE(netspace_max_v2_fan_speed),
+ .speed = netspace_max_v2_fan_speed,
+};
+
+static struct platform_device netspace_max_v2_gpio_fan = {
+ .name = "gpio-fan",
+ .id = -1,
+ .dev = {
+ .platform_data = &netspace_max_v2_fan_data,
+ },
};
/*****************************************************************************
@@ -291,22 +231,23 @@ 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);
platform_device_register(&netspace_v2_gpio_buttons);
+ if (machine_is_netspace_max_v2())
+ platform_device_register(&netspace_max_v2_gpio_fan);
if (gpio_request(NETSPACE_V2_GPIO_POWER_OFF, "power-off") == 0 &&
gpio_direction_output(NETSPACE_V2_GPIO_POWER_OFF, 0) == 0)
@@ -317,36 +258,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..dbbcfeb919db 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -6,26 +6,45 @@ choice
config ARCH_MSM7X00A
bool "MSM7x00A / MSM7x01A"
+ select MACH_TROUT if !MACH_HALIBUT
select ARCH_MSM_ARM11
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"
+ select MACH_MSM7X30_SURF # if !
select ARCH_MSM_SCORPION
select MSM_SMD
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"
+ select MACH_QSD8X50_SURF if !MACH_QSD8X50A_ST1_5
select ARCH_MSM_SCORPION
select MSM_SMD
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 MACH_MSM8X60_SURF if (!MACH_MSM8X60_RUMI3 && !MACH_MSM8X60_SIM \
+ && !MACH_MSM8X60_FFA)
+ select ARM_GIC
+ select CPU_V7
+ select MSM_V2_TLMM
+ select MSM_GPIOMUX
+
endchoice
config MSM_SOC_REV_A
@@ -36,6 +55,9 @@ config ARCH_MSM_ARM11
config ARCH_MSM_SCORPION
bool
+config HAS_MSM_DEBUG_UART_PHYS
+ bool
+
config MSM_VIC
bool
@@ -74,6 +96,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 +128,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 +146,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..75dabb16c802 100644
--- a/arch/arm/mach-msm/board-halibut.c
+++ b/arch/arm/mach-msm/board-halibut.c
@@ -83,7 +83,6 @@ static void __init halibut_fixup(struct machine_desc *desc, struct tag *tags,
{
mi->nr_banks=1;
mi->bank[0].start = PHYS_OFFSET;
- mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET);
mi->bank[0].size = (101*1024*1024);
}
@@ -95,8 +94,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..646b99ebc773 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
+#if defined(CONFIG_HAS_MSM_DEBUG_UART_PHYS) && !defined(CONFIG_MSM_DEBUG_UART_NONE)
+ .macro addruart, rp, rv
+ ldr \rp, =MSM_DEBUG_UART_PHYS
+ ldr \rv, =MSM_DEBUG_UART_BASE
.endm
.macro senduart,rd,rx
@@ -40,7 +37,9 @@
beq 1001b
.endm
#else
- .macro addruart, rx, tmp
+ .macro addruart, rp, rv
+ mov \rv, #0xff000000
+ orr \rv, \rv, #0x00f00000
.endm
.macro senduart,rd,rx
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..9019cee2907b
--- /dev/null
+++ b/arch/arm/mach-msm/iommu_dev.c
@@ -0,0 +1,378 @@
+/* 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, *r2;
+ 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;
+
+ r2 = request_mem_region(r->start, len, r->name);
+ if (!r2) {
+ pr_err("Could not request memory region: "
+ "start=%p, len=%d\n", (void *) r->start, len);
+ ret = -EBUSY;
+ goto fail;
+ }
+
+ regs_base = ioremap(r2->start, len);
+
+ if (!regs_base) {
+ pr_err("Could not ioremap: start=%p, len=%d\n",
+ (void *) r2->start, len);
+ ret = -EBUSY;
+ goto fail_mem;
+ }
+
+ irq = platform_get_irq_byname(pdev, "secure_irq");
+ if (irq < 0) {
+ ret = -ENODEV;
+ goto fail_io;
+ }
+
+ mb();
+
+ if (GET_IDR(regs_base) == 0) {
+ pr_err("Invalid IDR value detected\n");
+ ret = -ENODEV;
+ goto fail_io;
+ }
+
+ 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_io;
+ }
+
+ 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_io:
+ iounmap(regs_base);
+fail_mem:
+ release_mem_region(r->start, len);
+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..950100f19d07 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;
@@ -122,7 +137,7 @@ static struct msm_clock msm_clocks[] = {
.rating = 200,
.read = msm_gpt_read,
.mask = CLOCKSOURCE_MASK(32),
- .shift = 24,
+ .shift = 17,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
},
.irq = {
@@ -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..38ca09a5df9d 100644
--- a/arch/arm/mach-mx25/Kconfig
+++ b/arch/arm/mach-mx25/Kconfig
@@ -6,12 +6,15 @@ config MACH_MX25_3DS
bool "Support MX25PDK (3DS) Platform"
select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_ESDHC
config MACH_EUKREA_CPUIMX25
bool "Support Eukrea CPUIMX25 Platform"
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 +23,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..f8be1eb0c062 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>
@@ -97,9 +96,17 @@ static struct pad_desc mx25pdk_pads[] = {
MX25_PAD_KPP_COL1__KPP_COL1,
MX25_PAD_KPP_COL2__KPP_COL2,
MX25_PAD_KPP_COL3__KPP_COL3,
+
+ /* SD1 */
+ MX25_PAD_SD1_CMD__SD1_CMD,
+ MX25_PAD_SD1_CLK__SD1_CLK,
+ MX25_PAD_SD1_DATA0__SD1_DATA0,
+ MX25_PAD_SD1_DATA1__SD1_DATA1,
+ MX25_PAD_SD1_DATA2__SD1_DATA2,
+ MX25_PAD_SD1_DATA3__SD1_DATA3,
};
-static struct fec_platform_data mx25_fec_pdata = {
+static const struct fec_platform_data mx25_fec_pdata __initconst = {
.phy = PHY_INTERFACE_MODE_RMII,
};
@@ -192,8 +199,10 @@ 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);
+
+ imx25_add_esdhc(0, NULL);
}
static void __init mx25pdk_timer_init(void)
@@ -207,8 +216,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..5000ac1f93e3 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
@@ -139,7 +143,10 @@ config MACH_ARMADILLO5X0
config MACH_MX35_3DS
bool "Support MX35PDK platform"
select ARCH_MX35
+ select MXC_DEBUG_BOARD
select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_ESDHC
default n
help
Include support for MX35PDK platform. This includes specific
@@ -159,6 +166,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 +179,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..d4da9496089a 100644
--- a/arch/arm/mach-mx3/devices.c
+++ b/arch/arm/mach-mx3/devices.c
@@ -72,24 +72,24 @@ struct platform_device mxc_w1_master_device = {
#ifdef CONFIG_ARCH_MX31
static struct resource mxcsdhc0_resources[] = {
{
- .start = MMC_SDHC1_BASE_ADDR,
- .end = MMC_SDHC1_BASE_ADDR + SZ_16K - 1,
+ .start = MX31_MMC_SDHC1_BASE_ADDR,
+ .end = MX31_MMC_SDHC1_BASE_ADDR + SZ_16K - 1,
.flags = IORESOURCE_MEM,
}, {
- .start = MXC_INT_MMC_SDHC1,
- .end = MXC_INT_MMC_SDHC1,
+ .start = MX31_INT_MMC_SDHC1,
+ .end = MX31_INT_MMC_SDHC1,
.flags = IORESOURCE_IRQ,
},
};
static struct resource mxcsdhc1_resources[] = {
{
- .start = MMC_SDHC2_BASE_ADDR,
- .end = MMC_SDHC2_BASE_ADDR + SZ_16K - 1,
+ .start = MX31_MMC_SDHC2_BASE_ADDR,
+ .end = MX31_MMC_SDHC2_BASE_ADDR + SZ_16K - 1,
.flags = IORESOURCE_MEM,
}, {
- .start = MXC_INT_MMC_SDHC2,
- .end = MXC_INT_MMC_SDHC2,
+ .start = MX31_INT_MMC_SDHC2,
+ .end = MX31_INT_MMC_SDHC2,
.flags = IORESOURCE_IRQ,
},
};
@@ -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..0ad9e7821082 100644
--- a/arch/arm/mach-mx3/mach-mx31_3ds.c
+++ b/arch/arm/mach-mx3/mach-mx31_3ds.c
@@ -38,39 +38,9 @@
#include "devices-imx31.h"
#include "devices.h"
-/* Definitions for components on the Debug board */
-
-/* Base address of CPLD controller on the Debug board */
-#define DEBUG_BASE_ADDRESS CS5_IO_ADDRESS(MX3x_CS5_BASE_ADDR)
-
-/* LAN9217 ethernet base address */
-#define LAN9217_BASE_ADDR MX3x_CS5_BASE_ADDR
-
-/* CPLD config and interrupt base address */
-#define CPLD_ADDR (DEBUG_BASE_ADDRESS + 0x20000)
-
-/* status, interrupt */
-#define CPLD_INT_STATUS_REG (CPLD_ADDR + 0x10)
-#define CPLD_INT_MASK_REG (CPLD_ADDR + 0x38)
-#define CPLD_INT_RESET_REG (CPLD_ADDR + 0x20)
-/* magic word for debug CPLD */
-#define CPLD_MAGIC_NUMBER1_REG (CPLD_ADDR + 0x40)
-#define CPLD_MAGIC_NUMBER2_REG (CPLD_ADDR + 0x48)
-/* CPLD code version */
-#define CPLD_CODE_VER_REG (CPLD_ADDR + 0x50)
-/* magic word for debug CPLD */
-#define CPLD_MAGIC_NUMBER3_REG (CPLD_ADDR + 0x58)
-
/* CPLD IRQ line for external uart, external ethernet etc */
#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_1)
-#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START)
-#define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_EXP_IO_BASE)
-
-#define EXPIO_INT_ENET (MXC_EXP_IO_BASE + 0)
-
-#define MXC_MAX_EXP_IO_LINES 16
-
/*
* This file contains the board-specific initialization routines.
*/
@@ -272,7 +242,7 @@ static void __init mxc_board_init(void)
imx31_add_imx_uart0(&uart_pdata);
imx31_add_mxc_nand(&mx31_3ds_nand_board_info);
- imx31_add_spi_imx0(&spi1_pdata);
+ imx31_add_spi_imx1(&spi1_pdata);
spi_register_board_info(mx31_3ds_spi_devs,
ARRAY_SIZE(mx31_3ds_spi_devs));
@@ -281,9 +251,9 @@ static void __init mxc_board_init(void)
mx31_3ds_usbotg_init();
mxc_register_device(&mxc_otg_udc_device, &usbotg_pdata);
- if (!mxc_expio_init(CS5_BASE_ADDR, EXPIO_PARENT_INT))
- printk(KERN_WARNING "Init of the debugboard failed, all "
- "devices on the board are unusable.\n");
+ if (mxc_expio_init(MX31_CS5_BASE_ADDR, EXPIO_PARENT_INT))
+ printk(KERN_WARNING "Init of the debug board failed, all "
+ "devices on the debug board are unusable.\n");
}
static void __init mx31_3ds_timer_init(void)
@@ -301,8 +271,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..b66a75aa2e88 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,16 +38,47 @@
#include <mach/hardware.h>
#include <mach/common.h>
#include <mach/iomux-mx35.h>
+#include <mach/irqs.h>
+#include <mach/3ds_debugboard.h>
+#include <mach/mxc_ehci.h>
#include "devices-imx35.h"
#include "devices.h"
+#define EXPIO_PARENT_INT (MXC_INTERNAL_IRQS + GPIO_PORTA + 1)
+
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 +109,31 @@ 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,
+ /* 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,
};
/* 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 +141,21 @@ 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);
+ imx35_add_esdhc(0, NULL);
+
+ if (mxc_expio_init(MX35_CS5_BASE_ADDR, EXPIO_PARENT_INT))
+ pr_warn("Init of the debugboard failed, all "
+ "devices on the debugboard are unusable.\n");
}
static void __init mx35pdk_timer_init(void)
@@ -108,8 +169,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..2ff3f661a48e 100644
--- a/arch/arm/mach-mx3/mach-pcm037.c
+++ b/arch/arm/mach-mx3/mach-pcm037.c
@@ -311,7 +311,6 @@ static struct soc_camera_link iclink_mt9v022 = {
.bus_id = 0, /* Must match with the camera ID */
.board_info = &pcm037_i2c_camera[1],
.i2c_adapter_id = 2,
- .module_name = "mt9v022",
};
static struct soc_camera_link iclink_mt9t031 = {
@@ -319,7 +318,6 @@ static struct soc_camera_link iclink_mt9t031 = {
.power = pcm037_camera_power,
.board_info = &pcm037_i2c_camera[0],
.i2c_adapter_id = 2,
- .module_name = "mt9t031",
};
static struct i2c_board_info pcm037_i2c_devices[] = {
@@ -680,8 +678,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-mx3/mx31moboard-marxbot.c b/arch/arm/mach-mx3/mx31moboard-marxbot.c
index 0551eb39d97e..18069cb7d068 100644
--- a/arch/arm/mach-mx3/mx31moboard-marxbot.c
+++ b/arch/arm/mach-mx3/mx31moboard-marxbot.c
@@ -179,7 +179,6 @@ static struct soc_camera_link base_iclink = {
.reset = marxbot_basecam_reset,
.board_info = &marxbot_i2c_devices[0],
.i2c_adapter_id = 0,
- .module_name = "mt9t031",
};
static struct platform_device marxbot_camera[] = {
diff --git a/arch/arm/mach-mx3/mx31moboard-smartbot.c b/arch/arm/mach-mx3/mx31moboard-smartbot.c
index 417757e78c65..04760a53005a 100644
--- a/arch/arm/mach-mx3/mx31moboard-smartbot.c
+++ b/arch/arm/mach-mx3/mx31moboard-smartbot.c
@@ -88,7 +88,6 @@ static struct soc_camera_link base_iclink = {
.reset = smartbot_cam_reset,
.board_info = &smartbot_i2c_devices[0],
.i2c_adapter_id = 0,
- .module_name = "mt9t031",
};
static struct platform_device smartbot_camera[] = {
diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig
index 0848db5dd364..3ec910a7a182 100644
--- a/arch/arm/mach-mx5/Kconfig
+++ b/arch/arm/mach-mx5/Kconfig
@@ -5,11 +5,16 @@ config ARCH_MX51
default y
select MXC_TZIC
select ARCH_MXC_IOMUX_V3
+ select ARCH_MXC_AUDMUX_V2
+ select ARCH_HAS_CPUFREQ
comment "MX5 platforms:"
config MACH_MX51_BABBAGE
bool "Support MX51 BABBAGE platforms"
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_ESDHC
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 +22,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 +31,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 +47,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..462f177eddfe 100644
--- a/arch/arm/mach-mx5/Makefile
+++ b/arch/arm/mach-mx5/Makefile
@@ -5,7 +5,11 @@
# Object file lists.
obj-y := cpu.o mm.o clock-mx51.o devices.o
+obj-$(CONFIG_CPU_FREQ_IMX) += cpu_op-mx51.o
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..acbe30df2e69 100644
--- a/arch/arm/mach-mx5/board-mx51_babbage.c
+++ b/arch/arm/mach-mx5/board-mx51_babbage.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2009-2010 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
@@ -17,12 +17,13 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/fsl_devices.h>
+#include <linux/fec.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.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 +32,15 @@
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
+#include "devices-imx51.h"
#include "devices.h"
+#include "cpu_op-mx51.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 */
+#define BABBAGE_POWER_KEY (1*32 + 21) /* GPIO_2_21 */
/* USB_CTRL_1 */
#define MX51_USB_CTRL_1_OFFSET 0x10
@@ -45,8 +50,19 @@
#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 gpio_keys_button babbage_buttons[] = {
+ {
+ .gpio = BABBAGE_POWER_KEY,
+ .code = BTN_0,
+ .desc = "PWR",
+ .active_low = 1,
+ .wakeup = 1,
+ },
+};
+
+static const struct gpio_keys_platform_data imx_button_data __initconst = {
+ .buttons = babbage_buttons,
+ .nbuttons = ARRAY_SIZE(babbage_buttons),
};
static struct pad_desc mx51babbage_pads[] = {
@@ -93,19 +109,57 @@ 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,
+
+ /* 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,
};
/* 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 +167,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 +225,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 +248,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 +266,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;
@@ -246,14 +316,24 @@ __setup("otg_mode=", babbage_otg_mode);
static void __init mxc_board_init(void)
{
struct pad_desc usbh1stp = MX51_PAD_USBH1_STP__USBH1_STP;
+ struct pad_desc power_key = MX51_PAD_EIM_A27__GPIO_2_21;
+#if defined(CONFIG_CPU_FREQ_IMX)
+ get_cpu_op = mx51_get_cpu_op;
+#endif
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);
+
+ /* Set the PAD settings for the pwr key. */
+ power_key.pad_ctrl = MX51_GPIO_PAD_CTRL_2;
+ mxc_iomux_v3_setup_pad(&power_key);
+ imx51_add_gpio_keys(&imx_button_data);
- 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)
@@ -268,6 +348,9 @@ static void __init mxc_board_init(void)
/* setback USBH1_STP to be function */
mxc_iomux_v3_setup_pad(&usbh1stp);
babbage_usbhub_reset();
+
+ imx51_add_esdhc(0, NULL);
+ imx51_add_esdhc(1, NULL);
}
static void __init mx51_babbage_timer_init(void)
@@ -281,9 +364,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..8ac36d882927 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);
}
/*
@@ -330,7 +362,7 @@ static int _clk_lp_apm_set_parent(struct clk *clk, struct clk *parent)
return 0;
}
-static unsigned long clk_arm_get_rate(struct clk *clk)
+static unsigned long clk_cpu_get_rate(struct clk *clk)
{
u32 cacrr, div;
unsigned long parent_rate;
@@ -342,6 +374,22 @@ static unsigned long clk_arm_get_rate(struct clk *clk)
return parent_rate / div;
}
+static int clk_cpu_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, cpu_podf;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+ cpu_podf = parent_rate / rate - 1;
+ /* use post divider to change freq */
+ reg = __raw_readl(MXC_CCM_CACRR);
+ reg &= ~MXC_CCM_CACRR_ARM_PODF_MASK;
+ reg |= cpu_podf << MXC_CCM_CACRR_ARM_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CACRR);
+
+ return 0;
+}
+
static int _clk_periph_apm_set_parent(struct clk *clk, struct clk *parent)
{
u32 reg, mux;
@@ -542,60 +590,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 +668,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,
@@ -693,7 +752,8 @@ static struct clk periph_apm_clk = {
static struct clk cpu_clk = {
.parent = &pll1_sw_clk,
- .get_rate = clk_arm_get_rate,
+ .get_rate = clk_cpu_get_rate,
+ .set_rate = clk_cpu_set_rate,
};
static struct clk ahb_clk = {
@@ -715,18 +775,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 +810,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 +1000,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 +1069,19 @@ 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)
+ _REGISTER_CLOCK(NULL, "cpu_clk", cpu_clk)
};
static void clk_tree_init(void)
@@ -880,6 +1125,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/cpu_op-mx51.c b/arch/arm/mach-mx5/cpu_op-mx51.c
new file mode 100644
index 000000000000..9d34c3d4c024
--- /dev/null
+++ b/arch/arm/mach-mx5/cpu_op-mx51.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2010 Freescale Semiconductor, 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/types.h>
+#include <mach/hardware.h>
+#include <linux/kernel.h>
+
+static struct cpu_op mx51_cpu_op[] = {
+ {
+ .cpu_rate = 160000000,},
+ {
+ .cpu_rate = 800000000,},
+};
+
+struct cpu_op *mx51_get_cpu_op(int *op)
+{
+ *op = ARRAY_SIZE(mx51_cpu_op);
+ return mx51_cpu_op;
+}
diff --git a/arch/arm/mach-mx5/cpu_op-mx51.h b/arch/arm/mach-mx5/cpu_op-mx51.h
new file mode 100644
index 000000000000..97477fecb469
--- /dev/null
+++ b/arch/arm/mach-mx5/cpu_op-mx51.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2010 Freescale Semiconductor, 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
+ */
+
+extern struct cpu_op *mx51_get_cpu_op(int *op);
diff --git a/arch/arm/mach-mx5/devices-imx51.h b/arch/arm/mach-mx5/devices-imx51.h
new file mode 100644
index 000000000000..8c50cb5d05f5
--- /dev/null
+++ b/arch/arm/mach-mx5/devices-imx51.h
@@ -0,0 +1,44 @@
+/*
+ * 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)
+
+#define imx51_add_gpio_keys(pdata) imx_add_gpio_keys(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/Makefile b/arch/arm/mach-omap1/Makefile
index facfaeb1ae5c..9a304d854e33 100644
--- a/arch/arm/mach-omap1/Makefile
+++ b/arch/arm/mach-omap1/Makefile
@@ -12,7 +12,7 @@ obj-$(CONFIG_OMAP_MPU_TIMER) += time.o
obj-$(CONFIG_OMAP_32K_TIMER) += timer32k.o
# Power Management
-obj-$(CONFIG_PM) += pm.o sleep.o
+obj-$(CONFIG_PM) += pm.o sleep.o pm_bus.o
# DSP
obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox_mach.o
diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
index 41992ab71961..1d4163b9f0b7 100644
--- a/arch/arm/mach-omap1/board-ams-delta.c
+++ b/arch/arm/mach-omap1/board-ams-delta.c
@@ -16,9 +16,12 @@
#include <linux/init.h>
#include <linux/input.h>
#include <linux/interrupt.h>
+#include <linux/leds.h>
#include <linux/platform_device.h>
#include <linux/serial_8250.h>
+#include <media/soc_camera.h>
+
#include <asm/serial.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
@@ -32,6 +35,7 @@
#include <plat/usb.h>
#include <plat/board.h>
#include <plat/common.h>
+#include <mach/camera.h>
#include <mach/ams-delta-fiq.h>
@@ -213,10 +217,56 @@ static struct platform_device ams_delta_led_device = {
.id = -1
};
+static struct i2c_board_info ams_delta_camera_board_info[] = {
+ {
+ I2C_BOARD_INFO("ov6650", 0x60),
+ },
+};
+
+#ifdef CONFIG_LEDS_TRIGGERS
+DEFINE_LED_TRIGGER(ams_delta_camera_led_trigger);
+
+static int ams_delta_camera_power(struct device *dev, int power)
+{
+ /*
+ * turn on camera LED
+ */
+ if (power)
+ led_trigger_event(ams_delta_camera_led_trigger, LED_FULL);
+ else
+ led_trigger_event(ams_delta_camera_led_trigger, LED_OFF);
+ return 0;
+}
+#else
+#define ams_delta_camera_power NULL
+#endif
+
+static struct soc_camera_link __initdata ams_delta_iclink = {
+ .bus_id = 0, /* OMAP1 SoC camera bus */
+ .i2c_adapter_id = 1,
+ .board_info = &ams_delta_camera_board_info[0],
+ .module_name = "ov6650",
+ .power = ams_delta_camera_power,
+};
+
+static struct platform_device ams_delta_camera_device = {
+ .name = "soc-camera-pdrv",
+ .id = 0,
+ .dev = {
+ .platform_data = &ams_delta_iclink,
+ },
+};
+
+static struct omap1_cam_platform_data ams_delta_camera_platform_data = {
+ .camexclk_khz = 12000, /* default 12MHz clock, no extra DPLL */
+ .lclk_khz_max = 1334, /* results in 5fps CIF, 10fps QCIF */
+};
+
static struct platform_device *ams_delta_devices[] __initdata = {
&ams_delta_kp_device,
&ams_delta_lcd_device,
&ams_delta_led_device,
+ &ams_delta_camera_device,
};
static void __init ams_delta_init(void)
@@ -225,6 +275,20 @@ static void __init ams_delta_init(void)
omap_cfg_reg(UART1_TX);
omap_cfg_reg(UART1_RTS);
+ /* parallel camera interface */
+ omap_cfg_reg(H19_1610_CAM_EXCLK);
+ omap_cfg_reg(J15_1610_CAM_LCLK);
+ omap_cfg_reg(L18_1610_CAM_VS);
+ omap_cfg_reg(L15_1610_CAM_HS);
+ omap_cfg_reg(L19_1610_CAM_D0);
+ omap_cfg_reg(K14_1610_CAM_D1);
+ omap_cfg_reg(K15_1610_CAM_D2);
+ omap_cfg_reg(K19_1610_CAM_D3);
+ omap_cfg_reg(K18_1610_CAM_D4);
+ omap_cfg_reg(J14_1610_CAM_D5);
+ omap_cfg_reg(J19_1610_CAM_D6);
+ omap_cfg_reg(J18_1610_CAM_D7);
+
iotable_init(ams_delta_io_desc, ARRAY_SIZE(ams_delta_io_desc));
omap_board_config = ams_delta_config;
@@ -236,6 +300,11 @@ static void __init ams_delta_init(void)
ams_delta_latch2_write(~0, 0);
omap1_usb_init(&ams_delta_usb_config);
+ omap1_set_camera_info(&ams_delta_camera_platform_data);
+#ifdef CONFIG_LEDS_TRIGGERS
+ led_trigger_register_simple("ams_delta_camera",
+ &ams_delta_camera_led_trigger);
+#endif
platform_add_devices(ams_delta_devices, ARRAY_SIZE(ams_delta_devices));
#ifdef CONFIG_AMS_DELTA_FIQ
@@ -297,8 +366,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-mmc.c b/arch/arm/mach-omap1/board-h2-mmc.c
index b30c4990744d..f2fc43d8382b 100644
--- a/arch/arm/mach-omap1/board-h2-mmc.c
+++ b/arch/arm/mach-omap1/board-h2-mmc.c
@@ -58,8 +58,7 @@ static struct omap_mmc_platform_data mmc1_data = {
.dma_mask = 0xffffffff,
.slots[0] = {
.set_power = mmc_set_power,
- .ocr_mask = MMC_VDD_28_29 | MMC_VDD_30_31 |
- MMC_VDD_32_33 | MMC_VDD_33_34,
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
.name = "mmcblk",
},
};
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-mmc.c b/arch/arm/mach-omap1/board-h3-mmc.c
index 54b0f063e263..2098525e7cc5 100644
--- a/arch/arm/mach-omap1/board-h3-mmc.c
+++ b/arch/arm/mach-omap1/board-h3-mmc.c
@@ -40,8 +40,7 @@ static struct omap_mmc_platform_data mmc1_data = {
.dma_mask = 0xffffffff,
.slots[0] = {
.set_power = mmc_set_power,
- .ocr_mask = MMC_VDD_28_29 | MMC_VDD_30_31 |
- MMC_VDD_32_33 | MMC_VDD_33_34,
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
.name = "mmcblk",
},
};
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..071af3e47789 100644
--- a/arch/arm/mach-omap1/board-htcherald.c
+++ b/arch/arm/mach-omap1/board-htcherald.c
@@ -30,6 +30,13 @@
#include <linux/input.h>
#include <linux/io.h>
#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/htcpld.h>
+#include <linux/leds.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -39,6 +46,7 @@
#include <plat/board.h>
#include <plat/keypad.h>
#include <plat/usb.h>
+#include <plat/mmc.h>
#include <mach/irqs.h>
@@ -52,13 +60,123 @@
#define OMAP_LCDC_CTRL_LCD_EN (1 << 0)
#define OMAP_LCDC_STAT_DONE (1 << 0)
-static struct omap_lcd_config htcherald_lcd_config __initdata = {
- .ctrl_name = "internal",
-};
+/* GPIO definitions for the power button and keyboard slide switch */
+#define HTCHERALD_GPIO_POWER 139
+#define HTCHERALD_GPIO_SLIDE 174
+#define HTCHERALD_GIRQ_BTNS 141
-static struct omap_board_config_kernel htcherald_config[] __initdata = {
- { OMAP_TAG_LCD, &htcherald_lcd_config },
-};
+/* GPIO definitions for the touchscreen */
+#define HTCHERALD_GPIO_TS 76
+
+/* HTCPLD definitions */
+
+/*
+ * CPLD Logic
+ *
+ * Chip 3 - 0x03
+ *
+ * Function 7 6 5 4 3 2 1 0
+ * ------------------------------------
+ * DPAD light x x x x x x x 1
+ * SoundDev x x x x 1 x x x
+ * Screen white 1 x x x x x x x
+ * MMC power on x x x x x 1 x x
+ * Happy times (n) 0 x x x x 1 x x
+ *
+ * Chip 4 - 0x04
+ *
+ * Function 7 6 5 4 3 2 1 0
+ * ------------------------------------
+ * Keyboard light x x x x x x x 1
+ * LCD Bright (4) x x x x x 1 1 x
+ * LCD Bright (3) x x x x x 0 1 x
+ * LCD Bright (2) x x x x x 1 0 x
+ * LCD Bright (1) x x x x x 0 0 x
+ * LCD Off x x x x 0 x x x
+ * LCD image (fb) 1 x x x x x x x
+ * LCD image (white) 0 x x x x x x x
+ * Caps lock LED x x 1 x x x x x
+ *
+ * Chip 5 - 0x05
+ *
+ * Function 7 6 5 4 3 2 1 0
+ * ------------------------------------
+ * Red (solid) x x x x x 1 x x
+ * Red (flash) x x x x x x 1 x
+ * Green (GSM flash) x x x x 1 x x x
+ * Green (GSM solid) x x x 1 x x x x
+ * Green (wifi flash) x x 1 x x x x x
+ * Blue (bt flash) x 1 x x x x x x
+ * DPAD Int Enable 1 x x x x x x 0
+ *
+ * (Combinations of the above can be made for different colors.)
+ * The direction pad interrupt enable must be set each time the
+ * interrupt is handled.
+ *
+ * Chip 6 - 0x06
+ *
+ * Function 7 6 5 4 3 2 1 0
+ * ------------------------------------
+ * Vibrator x x x x 1 x x x
+ * Alt LED x x x 1 x x x x
+ * Screen white 1 x x x x x x x
+ * Screen white x x 1 x x x x x
+ * Screen white x 0 x x x x x x
+ * Enable kbd dpad x x x x x x 0 x
+ * Happy Times 0 1 0 x x x 0 x
+ */
+
+/*
+ * HTCPLD GPIO lines start 16 after OMAP_MAX_GPIO_LINES to account
+ * for the 16 MPUIO lines.
+ */
+#define HTCPLD_GPIO_START_OFFSET (OMAP_MAX_GPIO_LINES + 16)
+#define HTCPLD_IRQ(chip, offset) (OMAP_IRQ_END + 8 * (chip) + (offset))
+#define HTCPLD_BASE(chip, offset) \
+ (HTCPLD_GPIO_START_OFFSET + 8 * (chip) + (offset))
+
+#define HTCPLD_GPIO_LED_DPAD HTCPLD_BASE(0, 0)
+#define HTCPLD_GPIO_LED_KBD HTCPLD_BASE(1, 0)
+#define HTCPLD_GPIO_LED_CAPS HTCPLD_BASE(1, 5)
+#define HTCPLD_GPIO_LED_RED_FLASH HTCPLD_BASE(2, 1)
+#define HTCPLD_GPIO_LED_RED_SOLID HTCPLD_BASE(2, 2)
+#define HTCPLD_GPIO_LED_GREEN_FLASH HTCPLD_BASE(2, 3)
+#define HTCPLD_GPIO_LED_GREEN_SOLID HTCPLD_BASE(2, 4)
+#define HTCPLD_GPIO_LED_WIFI HTCPLD_BASE(2, 5)
+#define HTCPLD_GPIO_LED_BT HTCPLD_BASE(2, 6)
+#define HTCPLD_GPIO_LED_VIBRATE HTCPLD_BASE(3, 3)
+#define HTCPLD_GPIO_LED_ALT HTCPLD_BASE(3, 4)
+
+#define HTCPLD_GPIO_RIGHT_KBD HTCPLD_BASE(6, 7)
+#define HTCPLD_GPIO_UP_KBD HTCPLD_BASE(6, 6)
+#define HTCPLD_GPIO_LEFT_KBD HTCPLD_BASE(6, 5)
+#define HTCPLD_GPIO_DOWN_KBD HTCPLD_BASE(6, 4)
+
+#define HTCPLD_GPIO_RIGHT_DPAD HTCPLD_BASE(7, 7)
+#define HTCPLD_GPIO_UP_DPAD HTCPLD_BASE(7, 6)
+#define HTCPLD_GPIO_LEFT_DPAD HTCPLD_BASE(7, 5)
+#define HTCPLD_GPIO_DOWN_DPAD HTCPLD_BASE(7, 4)
+#define HTCPLD_GPIO_ENTER_DPAD HTCPLD_BASE(7, 3)
+
+/*
+ * The htcpld chip requires a gpio write to a specific line
+ * to re-enable interrupts after one has occurred.
+ */
+#define HTCPLD_GPIO_INT_RESET_HI HTCPLD_BASE(2, 7)
+#define HTCPLD_GPIO_INT_RESET_LO HTCPLD_BASE(2, 0)
+
+/* Chip 5 */
+#define HTCPLD_IRQ_RIGHT_KBD HTCPLD_IRQ(0, 7)
+#define HTCPLD_IRQ_UP_KBD HTCPLD_IRQ(0, 6)
+#define HTCPLD_IRQ_LEFT_KBD HTCPLD_IRQ(0, 5)
+#define HTCPLD_IRQ_DOWN_KBD HTCPLD_IRQ(0, 4)
+
+/* Chip 6 */
+#define HTCPLD_IRQ_RIGHT_DPAD HTCPLD_IRQ(1, 7)
+#define HTCPLD_IRQ_UP_DPAD HTCPLD_IRQ(1, 6)
+#define HTCPLD_IRQ_LEFT_DPAD HTCPLD_IRQ(1, 5)
+#define HTCPLD_IRQ_DOWN_DPAD HTCPLD_IRQ(1, 4)
+#define HTCPLD_IRQ_ENTER_DPAD HTCPLD_IRQ(1, 3)
/* Keyboard definition */
@@ -140,6 +258,129 @@ static struct platform_device kp_device = {
.resource = kp_resources,
};
+/* GPIO buttons for keyboard slide and power button */
+static struct gpio_keys_button herald_gpio_keys_table[] = {
+ {BTN_0, HTCHERALD_GPIO_POWER, 1, "POWER", EV_KEY, 1, 20},
+ {SW_LID, HTCHERALD_GPIO_SLIDE, 0, "SLIDE", EV_SW, 1, 20},
+
+ {KEY_LEFT, HTCPLD_GPIO_LEFT_KBD, 1, "LEFT", EV_KEY, 1, 20},
+ {KEY_RIGHT, HTCPLD_GPIO_RIGHT_KBD, 1, "RIGHT", EV_KEY, 1, 20},
+ {KEY_UP, HTCPLD_GPIO_UP_KBD, 1, "UP", EV_KEY, 1, 20},
+ {KEY_DOWN, HTCPLD_GPIO_DOWN_KBD, 1, "DOWN", EV_KEY, 1, 20},
+
+ {KEY_LEFT, HTCPLD_GPIO_LEFT_DPAD, 1, "DLEFT", EV_KEY, 1, 20},
+ {KEY_RIGHT, HTCPLD_GPIO_RIGHT_DPAD, 1, "DRIGHT", EV_KEY, 1, 20},
+ {KEY_UP, HTCPLD_GPIO_UP_DPAD, 1, "DUP", EV_KEY, 1, 20},
+ {KEY_DOWN, HTCPLD_GPIO_DOWN_DPAD, 1, "DDOWN", EV_KEY, 1, 20},
+ {KEY_ENTER, HTCPLD_GPIO_ENTER_DPAD, 1, "DENTER", EV_KEY, 1, 20},
+};
+
+static struct gpio_keys_platform_data herald_gpio_keys_data = {
+ .buttons = herald_gpio_keys_table,
+ .nbuttons = ARRAY_SIZE(herald_gpio_keys_table),
+ .rep = 1,
+};
+
+static struct platform_device herald_gpiokeys_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &herald_gpio_keys_data,
+ },
+};
+
+/* LEDs for the Herald. These connect to the HTCPLD GPIO device. */
+static struct gpio_led gpio_leds[] = {
+ {"dpad", NULL, HTCPLD_GPIO_LED_DPAD, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
+ {"kbd", NULL, HTCPLD_GPIO_LED_KBD, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
+ {"vibrate", NULL, HTCPLD_GPIO_LED_VIBRATE, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
+ {"green_solid", NULL, HTCPLD_GPIO_LED_GREEN_SOLID, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
+ {"green_flash", NULL, HTCPLD_GPIO_LED_GREEN_FLASH, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
+ {"red_solid", "mmc0", HTCPLD_GPIO_LED_RED_SOLID, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
+ {"red_flash", NULL, HTCPLD_GPIO_LED_RED_FLASH, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
+ {"wifi", NULL, HTCPLD_GPIO_LED_WIFI, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
+ {"bt", NULL, HTCPLD_GPIO_LED_BT, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
+ {"caps", NULL, HTCPLD_GPIO_LED_CAPS, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
+ {"alt", NULL, HTCPLD_GPIO_LED_ALT, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
+};
+
+static struct gpio_led_platform_data gpio_leds_data = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device gpio_leds_device = {
+ .name = "leds-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &gpio_leds_data,
+ },
+};
+
+/* HTC PLD chips */
+
+static struct resource htcpld_resources[] = {
+ [0] = {
+ .start = OMAP_GPIO_IRQ(HTCHERALD_GIRQ_BTNS),
+ .end = OMAP_GPIO_IRQ(HTCHERALD_GIRQ_BTNS),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct htcpld_chip_platform_data htcpld_chips[] = {
+ [0] = {
+ .addr = 0x03,
+ .reset = 0x04,
+ .num_gpios = 8,
+ .gpio_out_base = HTCPLD_BASE(0, 0),
+ .gpio_in_base = HTCPLD_BASE(4, 0),
+ },
+ [1] = {
+ .addr = 0x04,
+ .reset = 0x8e,
+ .num_gpios = 8,
+ .gpio_out_base = HTCPLD_BASE(1, 0),
+ .gpio_in_base = HTCPLD_BASE(5, 0),
+ },
+ [2] = {
+ .addr = 0x05,
+ .reset = 0x80,
+ .num_gpios = 8,
+ .gpio_out_base = HTCPLD_BASE(2, 0),
+ .gpio_in_base = HTCPLD_BASE(6, 0),
+ .irq_base = HTCPLD_IRQ(0, 0),
+ .num_irqs = 8,
+ },
+ [3] = {
+ .addr = 0x06,
+ .reset = 0x40,
+ .num_gpios = 8,
+ .gpio_out_base = HTCPLD_BASE(3, 0),
+ .gpio_in_base = HTCPLD_BASE(7, 0),
+ .irq_base = HTCPLD_IRQ(1, 0),
+ .num_irqs = 8,
+ },
+};
+
+struct htcpld_core_platform_data htcpld_pfdata = {
+ .int_reset_gpio_hi = HTCPLD_GPIO_INT_RESET_HI,
+ .int_reset_gpio_lo = HTCPLD_GPIO_INT_RESET_LO,
+ .i2c_adapter_id = 1,
+
+ .chip = htcpld_chips,
+ .num_chip = ARRAY_SIZE(htcpld_chips),
+};
+
+static struct platform_device htcpld_device = {
+ .name = "i2c-htcpld",
+ .id = -1,
+ .resource = htcpld_resources,
+ .num_resources = ARRAY_SIZE(htcpld_resources),
+ .dev = {
+ .platform_data = &htcpld_pfdata,
+ },
+};
+
/* USB Device */
static struct omap_usb_config htcherald_usb_config __initdata = {
.otg = 0,
@@ -150,14 +391,71 @@ static struct omap_usb_config htcherald_usb_config __initdata = {
};
/* LCD Device resources */
+static struct omap_lcd_config htcherald_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+
+static struct omap_board_config_kernel htcherald_config[] __initdata = {
+ { OMAP_TAG_LCD, &htcherald_lcd_config },
+};
+
static struct platform_device lcd_device = {
.name = "lcd_htcherald",
.id = -1,
};
+/* MMC Card */
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+static struct omap_mmc_platform_data htc_mmc1_data = {
+ .nr_slots = 1,
+ .switch_slot = NULL,
+ .slots[0] = {
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .name = "mmcblk",
+ .nomux = 1,
+ .wires = 4,
+ .switch_pin = -1,
+ },
+};
+
+static struct omap_mmc_platform_data *htc_mmc_data[1];
+#endif
+
+
+/* Platform devices for the Herald */
static struct platform_device *devices[] __initdata = {
&kp_device,
&lcd_device,
+ &htcpld_device,
+ &gpio_leds_device,
+ &herald_gpiokeys_device,
+};
+
+/*
+ * Touchscreen
+ */
+static const struct ads7846_platform_data htcherald_ts_platform_data = {
+ .model = 7846,
+ .keep_vref_on = 1,
+ .x_plate_ohms = 496,
+ .gpio_pendown = HTCHERALD_GPIO_TS,
+ .pressure_max = 100000,
+ .pressure_min = 5000,
+ .x_min = 528,
+ .x_max = 3760,
+ .y_min = 624,
+ .y_max = 3760,
+};
+
+static struct spi_board_info __initdata htcherald_spi_board_info[] = {
+ {
+ .modalias = "ads7846",
+ .platform_data = &htcherald_ts_platform_data,
+ .irq = OMAP_GPIO_IRQ(HTCHERALD_GPIO_TS),
+ .max_speed_hz = 2500000,
+ .bus_num = 2,
+ .chip_select = 1,
+ }
};
/*
@@ -278,6 +576,7 @@ static void __init htcherald_init(void)
{
printk(KERN_INFO "HTC Herald init.\n");
+ /* Do board initialization before we register all the devices */
omap_gpio_init();
omap_board_config = htcherald_config;
@@ -288,6 +587,16 @@ static void __init htcherald_init(void)
htcherald_usb_enable();
omap1_usb_init(&htcherald_usb_config);
+
+ spi_register_board_info(htcherald_spi_board_info,
+ ARRAY_SIZE(htcherald_spi_board_info));
+
+ omap_register_i2c_bus(1, 100, NULL, 0);
+
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+ htc_mmc_data[0] = &htc_mmc1_data;
+ omap1_init_mmc(htc_mmc_data, 1);
+#endif
}
static void __init htcherald_init_irq(void)
@@ -300,8 +609,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-mmc.c b/arch/arm/mach-omap1/board-sx1-mmc.c
index 5b33ae8141bc..e8ddd86e3fda 100644
--- a/arch/arm/mach-omap1/board-sx1-mmc.c
+++ b/arch/arm/mach-omap1/board-sx1-mmc.c
@@ -44,8 +44,7 @@ static struct omap_mmc_platform_data mmc1_data = {
.nr_slots = 1,
.slots[0] = {
.set_power = mmc_set_power,
- .ocr_mask = MMC_VDD_28_29 | MMC_VDD_30_31 |
- MMC_VDD_32_33 | MMC_VDD_33_34,
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
.name = "mmcblk",
},
};
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/devices.c b/arch/arm/mach-omap1/devices.c
index b583121b04b9..ea0d80a89da7 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -9,6 +9,7 @@
* (at your option) any later version.
*/
+#include <linux/dma-mapping.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
@@ -192,6 +193,48 @@ static inline void omap_init_spi100k(void)
}
#endif
+
+#define OMAP1_CAMERA_BASE 0xfffb6800
+#define OMAP1_CAMERA_IOSIZE 0x1c
+
+static struct resource omap1_camera_resources[] = {
+ [0] = {
+ .start = OMAP1_CAMERA_BASE,
+ .end = OMAP1_CAMERA_BASE + OMAP1_CAMERA_IOSIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = INT_CAMERA,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 omap1_camera_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device omap1_camera_device = {
+ .name = "omap1-camera",
+ .id = 0, /* This is used to put cameras on this interface */
+ .dev = {
+ .dma_mask = &omap1_camera_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(omap1_camera_resources),
+ .resource = omap1_camera_resources,
+};
+
+void __init omap1_camera_init(void *info)
+{
+ struct platform_device *dev = &omap1_camera_device;
+ int ret;
+
+ dev->dev.platform_data = info;
+
+ ret = platform_device_register(dev);
+ if (ret)
+ dev_err(&dev->dev, "unable to register device: %d\n", ret);
+}
+
+
/*-------------------------------------------------------------------------*/
static inline void omap_init_sti(void) {}
@@ -258,3 +301,30 @@ static int __init omap1_init_devices(void)
}
arch_initcall(omap1_init_devices);
+#if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE)
+
+static struct resource wdt_resources[] = {
+ {
+ .start = 0xfffeb000,
+ .end = 0xfffeb07F,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device omap_wdt_device = {
+ .name = "omap_wdt",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(wdt_resources),
+ .resource = wdt_resources,
+};
+
+static int __init omap_init_wdt(void)
+{
+ if (!cpu_is_omap16xx())
+ return;
+
+ platform_device_register(&omap_wdt_device);
+ return 0;
+}
+subsys_initcall(omap_init_wdt);
+#endif
diff --git a/arch/arm/mach-omap1/include/mach/camera.h b/arch/arm/mach-omap1/include/mach/camera.h
new file mode 100644
index 000000000000..fd54b452eb22
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/camera.h
@@ -0,0 +1,11 @@
+#ifndef __ASM_ARCH_CAMERA_H_
+#define __ASM_ARCH_CAMERA_H_
+
+void omap1_camera_init(void *);
+
+static inline void omap1_set_camera_info(struct omap1_cam_platform_data *info)
+{
+ omap1_camera_init(info);
+}
+
+#endif /* __ASM_ARCH_CAMERA_H_ */
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-omap1/pm_bus.c b/arch/arm/mach-omap1/pm_bus.c
new file mode 100644
index 000000000000..8b66392be745
--- /dev/null
+++ b/arch/arm/mach-omap1/pm_bus.c
@@ -0,0 +1,98 @@
+/*
+ * Runtime PM support code for OMAP1
+ *
+ * Author: Kevin Hilman, Deep Root Systems, LLC
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <plat/omap_device.h>
+#include <plat/omap-pm.h>
+
+#ifdef CONFIG_PM_RUNTIME
+static int omap1_pm_runtime_suspend(struct device *dev)
+{
+ struct clk *iclk, *fclk;
+ int ret = 0;
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ ret = pm_generic_runtime_suspend(dev);
+
+ fclk = clk_get(dev, "fck");
+ if (!IS_ERR(fclk)) {
+ clk_disable(fclk);
+ clk_put(fclk);
+ }
+
+ iclk = clk_get(dev, "ick");
+ if (!IS_ERR(iclk)) {
+ clk_disable(iclk);
+ clk_put(iclk);
+ }
+
+ return 0;
+};
+
+static int omap1_pm_runtime_resume(struct device *dev)
+{
+ int ret = 0;
+ struct clk *iclk, *fclk;
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ iclk = clk_get(dev, "ick");
+ if (!IS_ERR(iclk)) {
+ clk_enable(iclk);
+ clk_put(iclk);
+ }
+
+ fclk = clk_get(dev, "fck");
+ if (!IS_ERR(fclk)) {
+ clk_enable(fclk);
+ clk_put(fclk);
+ }
+
+ return pm_generic_runtime_resume(dev);
+};
+
+static int __init omap1_pm_runtime_init(void)
+{
+ const struct dev_pm_ops *pm;
+ struct dev_pm_ops *omap_pm;
+
+ pm = platform_bus_get_pm_ops();
+ if (!pm) {
+ pr_err("%s: unable to get dev_pm_ops from platform_bus\n",
+ __func__);
+ return -ENODEV;
+ }
+
+ omap_pm = kmemdup(pm, sizeof(struct dev_pm_ops), GFP_KERNEL);
+ if (!omap_pm) {
+ pr_err("%s: unable to alloc memory for new dev_pm_ops\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ omap_pm->runtime_suspend = omap1_pm_runtime_suspend;
+ omap_pm->runtime_resume = omap1_pm_runtime_resume;
+
+ platform_bus_set_pm_ops(omap_pm);
+
+ return 0;
+}
+core_initcall(omap1_pm_runtime_init);
+#endif /* CONFIG_PM_RUNTIME */
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index b48bacf0a7aa..ab784bfde908 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -11,9 +11,8 @@ config ARCH_OMAP2PLUS_TYPICAL
select PM_RUNTIME
select VFP
select NEON if ARCH_OMAP3 || ARCH_OMAP4
- select SERIAL_8250
- select SERIAL_CORE_CONSOLE
- select SERIAL_8250_CONSOLE
+ select SERIAL_OMAP
+ select SERIAL_OMAP_CONSOLE
select I2C
select I2C_OMAP
select MFD
@@ -35,7 +34,7 @@ config ARCH_OMAP3
default y
select CPU_V7
select USB_ARCH_HAS_EHCI
- select ARM_L1_CACHE_SHIFT_6
+ select ARM_L1_CACHE_SHIFT_6 if !ARCH_OMAP4
config ARCH_OMAP4
bool "TI OMAP4"
@@ -43,6 +42,8 @@ config ARCH_OMAP4
depends on ARCH_OMAP2PLUS
select CPU_V7
select ARM_GIC
+ select PL310_ERRATA_588369
+ select ARM_ERRATA_720789
comment "OMAP Core Type"
depends on ARCH_OMAP2
@@ -99,20 +100,20 @@ config MACH_OMAP2_TUSB6010
config MACH_OMAP_H4
bool "OMAP 2420 H4 board"
- depends on ARCH_OMAP2
+ depends on ARCH_OMAP2420
default y
select OMAP_PACKAGE_ZAF
select OMAP_DEBUG_DEVICES
config MACH_OMAP_APOLLON
bool "OMAP 2420 Apollon board"
- depends on ARCH_OMAP2
+ depends on ARCH_OMAP2420
default y
select OMAP_PACKAGE_ZAC
config MACH_OMAP_2430SDP
bool "OMAP 2430 SDP board"
- depends on ARCH_OMAP2
+ depends on ARCH_OMAP2430
default y
select OMAP_PACKAGE_ZAC
@@ -135,6 +136,26 @@ config MACH_OMAP_LDP
default y
select OMAP_PACKAGE_CBB
+config MACH_OMAP3530_LV_SOM
+ bool "OMAP3 Logic 3530 LV SOM board"
+ depends on ARCH_OMAP3
+ select OMAP_PACKAGE_CBB
+ default y
+ help
+ Support for the LogicPD OMAP3530 SOM Development kit
+ for full description please see the products webpage at
+ http://www.logicpd.com/products/development-kits/texas-instruments-zoom%E2%84%A2-omap35x-development-kit
+
+config MACH_OMAP3_TORPEDO
+ bool "OMAP3 Logic 35x Torpedo board"
+ depends on ARCH_OMAP3
+ select OMAP_PACKAGE_CBB
+ default y
+ help
+ Support for the LogicPD OMAP35x Torpedo Development kit
+ for full description please see the products webpage at
+ http://www.logicpd.com/products/development-kits/zoom-omap35x-torpedo-development-kit
+
config MACH_OVERO
bool "Gumstix Overo board"
depends on ARCH_OMAP3
@@ -200,12 +221,18 @@ config MACH_OMAP_ZOOM2
depends on ARCH_OMAP3
default y
select OMAP_PACKAGE_CBB
+ select SERIAL_8250
+ select SERIAL_CORE_CONSOLE
+ select SERIAL_8250_CONSOLE
config MACH_OMAP_ZOOM3
bool "OMAP3630 Zoom3 board"
depends on ARCH_OMAP3
default y
select OMAP_PACKAGE_CBP
+ select SERIAL_8250
+ select SERIAL_CORE_CONSOLE
+ select SERIAL_8250_CONSOLE
config MACH_CM_T35
bool "CompuLab CM-T35 module"
@@ -214,12 +241,25 @@ config MACH_CM_T35
select OMAP_PACKAGE_CUS
select OMAP_MUX
+config MACH_CM_T3517
+ bool "CompuLab CM-T3517 module"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+ select OMAP_MUX
+
config MACH_IGEP0020
bool "IGEP v2 board"
depends on ARCH_OMAP3
default y
select OMAP_PACKAGE_CBB
+config MACH_IGEP0030
+ bool "IGEP OMAP3 module"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+
config MACH_SBC3530
bool "OMAP3 SBC STALKER board"
depends on ARCH_OMAP3
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 88d3a1e920f5..60e51bcf53bd 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -3,9 +3,10 @@
#
# Common support
-obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o pm.o
+obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o pm.o \
+ common.o
-omap-2-3-common = irq.o sdrc.o
+omap-2-3-common = irq.o sdrc.o prm2xxx_3xxx.o
hwmod-common = omap_hwmod.o \
omap_hwmod_common_data.o
prcm-common = prcm.o powerdomain.o
@@ -15,7 +16,7 @@ clock-common = clock.o clock_common_data.o \
obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(hwmod-common)
obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(prcm-common) $(hwmod-common)
-obj-$(CONFIG_ARCH_OMAP4) += $(prcm-common) $(hwmod-common)
+obj-$(CONFIG_ARCH_OMAP4) += $(prcm-common) prm44xx.o $(hwmod-common)
obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
@@ -49,14 +50,18 @@ obj-$(CONFIG_ARCH_OMAP2) += sdrc2xxx.o
# Power Management
ifeq ($(CONFIG_PM),y)
obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
-obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o
-obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o cpuidle34xx.o
-obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o
+obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o pm_bus.o
+obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o cpuidle34xx.o pm_bus.o
+obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o pm_bus.o
obj-$(CONFIG_PM_DEBUG) += pm-debug.o
AFLAGS_sleep24xx.o :=-Wa,-march=armv6
AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a
+ifeq ($(CONFIG_PM_VERBOSE),y)
+CFLAGS_pm_bus.o += -DDEBUG
+endif
+
endif
# PRCM
@@ -87,6 +92,7 @@ obj-$(CONFIG_ARCH_OMAP2430) += opp2430_data.o
obj-$(CONFIG_ARCH_OMAP2420) += omap_hwmod_2420_data.o
obj-$(CONFIG_ARCH_OMAP2430) += omap_hwmod_2430_data.o
obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP4) += omap_hwmod_44xx_data.o
# EMU peripherals
obj-$(CONFIG_OMAP3_EMU) += emu.o
@@ -102,6 +108,10 @@ obj-y += $(iommu-m) $(iommu-y)
i2c-omap-$(CONFIG_I2C_OMAP) := i2c.o
obj-y += $(i2c-omap-m) $(i2c-omap-y)
+ifneq ($(CONFIG_TIDSPBRIDGE),)
+obj-y += dsp.o
+endif
+
# Specific board support
obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o
obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o
@@ -115,6 +125,10 @@ obj-$(CONFIG_MACH_DEVKIT8000) += board-devkit8000.o \
obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o \
board-flash.o \
hsmmc.o
+obj-$(CONFIG_MACH_OMAP3530_LV_SOM) += board-omap3logic.o \
+ hsmmc.o
+obj-$(CONFIG_MACH_OMAP3_TORPEDO) += board-omap3logic.o \
+ hsmmc.o
obj-$(CONFIG_MACH_OVERO) += board-overo.o \
hsmmc.o
obj-$(CONFIG_MACH_OMAP3EVM) += board-omap3evm.o \
@@ -146,8 +160,11 @@ obj-$(CONFIG_MACH_OMAP_3630SDP) += board-3630sdp.o \
hsmmc.o
obj-$(CONFIG_MACH_CM_T35) += board-cm-t35.o \
hsmmc.o
+obj-$(CONFIG_MACH_CM_T3517) += board-cm-t3517.o
obj-$(CONFIG_MACH_IGEP0020) += board-igep0020.o \
hsmmc.o
+obj-$(CONFIG_MACH_IGEP0030) += board-igep0030.o \
+ hsmmc.o
obj-$(CONFIG_MACH_OMAP3_TOUCHBOOK) += board-omap3touchbook.o \
hsmmc.o
obj-$(CONFIG_MACH_OMAP_4430SDP) += board-4430sdp.o \
@@ -174,3 +191,6 @@ obj-y += $(nand-m) $(nand-y)
smc91x-$(CONFIG_SMC91X) := gpmc-smc91x.o
obj-y += $(smc91x-m) $(smc91x-y)
+
+smsc911x-$(CONFIG_SMSC911X) := gpmc-smsc911x.o
+obj-y += $(smsc911x-m) $(smsc911x-y)
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index 8538e4131d27..b527f8d187ad 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -19,6 +19,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
+#include <linux/mmc/host.h>
#include <linux/delay.h>
#include <linux/i2c/twl.h>
#include <linux/err.h>
@@ -190,7 +191,7 @@ static int __init omap2430_i2c_init(void)
static struct omap2_hsmmc_info mmc[] __initdata = {
{
.mmc = 1,
- .wires = 4,
+ .caps = MMC_CAP_4_BIT_DATA,
.gpio_cd = -EINVAL,
.gpio_wp = -EINVAL,
.ext_clock = 1,
@@ -253,8 +254,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..4e3742c512b8 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -24,6 +24,7 @@
#include <linux/regulator/machine.h>
#include <linux/io.h>
#include <linux/gpio.h>
+#include <linux/mmc/host.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
@@ -38,15 +39,14 @@
#include <plat/gpmc.h>
#include <plat/display.h>
-#include <plat/control.h>
#include <plat/gpmc-smc91x.h>
-#include <mach/board-flash.h>
-
+#include "board-flash.h"
#include "mux.h"
#include "sdram-qimonda-hyb18m512160af-6.h"
#include "hsmmc.h"
#include "pm.h"
+#include "control.h"
#define CONFIG_DISABLE_HFCLK 1
@@ -76,7 +76,7 @@ static struct cpuidle_params omap3_cpuidle_params_table[] = {
{1, 10000, 30000, 300000},
};
-static int board_keymap[] = {
+static uint32_t board_keymap[] = {
KEY(0, 0, KEY_LEFT),
KEY(0, 1, KEY_RIGHT),
KEY(0, 2, KEY_A),
@@ -353,12 +353,12 @@ static struct omap2_hsmmc_info mmc[] = {
/* 8 bits (default) requires S6.3 == ON,
* so the SIM card isn't used; else 4 bits.
*/
- .wires = 8,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
.gpio_wp = 4,
},
{
.mmc = 2,
- .wires = 8,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
.gpio_wp = 7,
},
{} /* Terminator */
@@ -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..bbcf580fa097 100644
--- a/arch/arm/mach-omap2/board-3630sdp.c
+++ b/arch/arm/mach-omap2/board-3630sdp.c
@@ -21,8 +21,8 @@
#include <plat/usb.h>
#include <mach/board-zoom.h>
-#include <mach/board-flash.h>
+#include "board-flash.h"
#include "mux.h"
#include "sdram-hynix-h8mbx00u0mer-0em.h"
@@ -208,7 +208,6 @@ static struct flash_partitions sdp_flash_partitions[] = {
static void __init omap_sdp_init(void)
{
omap3_mux_init(board_mux, OMAP_PACKAGE_CBP);
- omap_serial_init();
zoom_peripherals_init();
board_smc91x_init();
board_flash_init(sdp_flash_partitions, chip_sel_sdp);
@@ -217,8 +216,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..df5a425a49d1 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -20,6 +20,7 @@
#include <linux/usb/otg.h>
#include <linux/spi/spi.h>
#include <linux/i2c/twl.h>
+#include <linux/gpio_keys.h>
#include <linux/regulator/machine.h>
#include <linux/leds.h>
@@ -31,15 +32,18 @@
#include <plat/board.h>
#include <plat/common.h>
-#include <plat/control.h>
-#include <plat/timer-gp.h>
#include <plat/usb.h>
#include <plat/mmc.h>
+
#include "hsmmc.h"
+#include "timer-gp.h"
+#include "control.h"
#define ETH_KS8851_IRQ 34
#define ETH_KS8851_POWER_ON 48
#define ETH_KS8851_QUART 138
+#define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO 184
+#define OMAP4_SFH7741_ENABLE_GPIO 188
static struct gpio_led sdp4430_gpio_leds[] = {
{
@@ -77,11 +81,47 @@ static struct gpio_led sdp4430_gpio_leds[] = {
};
+static struct gpio_keys_button sdp4430_gpio_keys[] = {
+ {
+ .desc = "Proximity Sensor",
+ .type = EV_SW,
+ .code = SW_FRONT_PROXIMITY,
+ .gpio = OMAP4_SFH7741_SENSOR_OUTPUT_GPIO,
+ .active_low = 0,
+ }
+};
+
static struct gpio_led_platform_data sdp4430_led_data = {
.leds = sdp4430_gpio_leds,
.num_leds = ARRAY_SIZE(sdp4430_gpio_leds),
};
+static int omap_prox_activate(struct device *dev)
+{
+ gpio_set_value(OMAP4_SFH7741_ENABLE_GPIO , 1);
+ return 0;
+}
+
+static void omap_prox_deactivate(struct device *dev)
+{
+ gpio_set_value(OMAP4_SFH7741_ENABLE_GPIO , 0);
+}
+
+static struct gpio_keys_platform_data sdp4430_gpio_keys_data = {
+ .buttons = sdp4430_gpio_keys,
+ .nbuttons = ARRAY_SIZE(sdp4430_gpio_keys),
+ .enable = omap_prox_activate,
+ .disable = omap_prox_deactivate,
+};
+
+static struct platform_device sdp4430_gpio_keys_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &sdp4430_gpio_keys_data,
+ },
+};
+
static struct platform_device sdp4430_leds_gpio = {
.name = "leds-gpio",
.id = -1,
@@ -161,6 +201,7 @@ static struct platform_device sdp4430_lcd_device = {
static struct platform_device *sdp4430_devices[] __initdata = {
&sdp4430_lcd_device,
+ &sdp4430_gpio_keys_device,
&sdp4430_leds_gpio,
};
@@ -193,15 +234,16 @@ static struct omap_musb_board_data musb_board_data = {
static struct omap2_hsmmc_info mmc[] = {
{
.mmc = 1,
- .wires = 8,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
.gpio_wp = -EINVAL,
},
{
.mmc = 2,
- .wires = 8,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
.gpio_cd = -EINVAL,
.gpio_wp = -EINVAL,
.nonremovable = true,
+ .ocr_mask = MMC_VDD_29_30,
},
{} /* Terminator */
};
@@ -227,16 +269,27 @@ static int omap4_twl6030_hsmmc_late_init(struct device *dev)
struct omap_mmc_platform_data *pdata = dev->platform_data;
/* Setting MMC1 Card detect Irq */
- if (pdev->id == 0)
+ if (pdev->id == 0) {
+ ret = twl6030_mmc_card_detect_config();
+ if (ret)
+ pr_err("Failed configuring MMC1 card detect\n");
pdata->slots[0].card_detect_irq = TWL6030_IRQ_BASE +
MMCDETECT_INTR_OFFSET;
+ pdata->slots[0].card_detect = twl6030_mmc_card_detect;
+ }
return ret;
}
static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev)
{
- struct omap_mmc_platform_data *pdata = dev->platform_data;
+ struct omap_mmc_platform_data *pdata;
+ /* dev can be null if CONFIG_MMC_OMAP_HS is not set */
+ if (!dev) {
+ pr_err("Failed %s\n", __func__);
+ return;
+ }
+ pdata = dev->platform_data;
pdata->init = omap4_twl6030_hsmmc_late_init;
}
@@ -412,6 +465,11 @@ static struct i2c_board_info __initdata sdp4430_i2c_3_boardinfo[] = {
I2C_BOARD_INFO("tmp105", 0x48),
},
};
+static struct i2c_board_info __initdata sdp4430_i2c_4_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("hmc5843", 0x1e),
+ },
+};
static int __init omap4_i2c_init(void)
{
/*
@@ -423,14 +481,36 @@ static int __init omap4_i2c_init(void)
omap_register_i2c_bus(2, 400, NULL, 0);
omap_register_i2c_bus(3, 400, sdp4430_i2c_3_boardinfo,
ARRAY_SIZE(sdp4430_i2c_3_boardinfo));
- omap_register_i2c_bus(4, 400, NULL, 0);
+ omap_register_i2c_bus(4, 400, sdp4430_i2c_4_boardinfo,
+ ARRAY_SIZE(sdp4430_i2c_4_boardinfo));
return 0;
}
+
+static void __init omap_sfh7741prox_init(void)
+{
+ int error;
+
+ error = gpio_request(OMAP4_SFH7741_ENABLE_GPIO, "sfh7741");
+ if (error < 0) {
+ pr_err("%s:failed to request GPIO %d, error %d\n",
+ __func__, OMAP4_SFH7741_ENABLE_GPIO, error);
+ return;
+ }
+
+ error = gpio_direction_output(OMAP4_SFH7741_ENABLE_GPIO , 0);
+ if (error < 0) {
+ pr_err("%s: GPIO configuration failed: GPIO %d,error %d\n",
+ __func__, OMAP4_SFH7741_ENABLE_GPIO, error);
+ gpio_free(OMAP4_SFH7741_ENABLE_GPIO);
+ }
+}
+
static void __init omap_4430sdp_init(void)
{
int status;
omap4_i2c_init();
+ omap_sfh7741prox_init();
platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices));
omap_serial_init();
omap4_twl6030_hsmmc_init(mmc);
@@ -458,8 +538,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..07399505312b 100644
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -18,6 +18,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/i2c/pca953x.h>
@@ -32,25 +33,43 @@
#include <plat/board.h>
#include <plat/common.h>
-#include <plat/control.h>
#include <plat/usb.h>
#include <plat/display.h>
#include "mux.h"
+#include "control.h"
-#define AM35XX_EVM_PHY_MASK (0xF)
#define AM35XX_EVM_MDIO_FREQUENCY (1000000)
+static struct mdio_platform_data am3517_evm_mdio_pdata = {
+ .bus_freq = AM35XX_EVM_MDIO_FREQUENCY,
+};
+
+static struct resource am3517_mdio_resources[] = {
+ {
+ .start = AM35XX_IPSS_EMAC_BASE + AM35XX_EMAC_MDIO_OFFSET,
+ .end = AM35XX_IPSS_EMAC_BASE + AM35XX_EMAC_MDIO_OFFSET +
+ SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device am3517_mdio_device = {
+ .name = "davinci_mdio",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(am3517_mdio_resources),
+ .resource = am3517_mdio_resources,
+ .dev.platform_data = &am3517_evm_mdio_pdata,
+};
+
static struct emac_platform_data am3517_evm_emac_pdata = {
- .phy_mask = AM35XX_EVM_PHY_MASK,
- .mdio_max_freq = AM35XX_EVM_MDIO_FREQUENCY,
.rmii_en = 1,
};
static struct resource am3517_emac_resources[] = {
{
.start = AM35XX_IPSS_EMAC_BASE,
- .end = AM35XX_IPSS_EMAC_BASE + 0x3FFFF,
+ .end = AM35XX_IPSS_EMAC_BASE + 0x2FFFF,
.flags = IORESOURCE_MEM,
},
{
@@ -106,14 +125,13 @@ static void am3517_disable_ethernet_int(void)
regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
}
-void am3517_evm_ethernet_init(struct emac_platform_data *pdata)
+static void am3517_evm_ethernet_init(struct emac_platform_data *pdata)
{
unsigned int regval;
pdata->ctrl_reg_offset = AM35XX_EMAC_CNTRL_OFFSET;
pdata->ctrl_mod_reg_offset = AM35XX_EMAC_CNTRL_MOD_OFFSET;
pdata->ctrl_ram_offset = AM35XX_EMAC_CNTRL_RAM_OFFSET;
- pdata->mdio_reg_offset = AM35XX_EMAC_MDIO_OFFSET;
pdata->ctrl_ram_size = AM35XX_EMAC_CNTRL_RAM_SIZE;
pdata->version = EMAC_VERSION_2;
pdata->hw_ram_addr = AM35XX_EMAC_HW_RAM_ADDR;
@@ -121,6 +139,9 @@ void am3517_evm_ethernet_init(struct emac_platform_data *pdata)
pdata->interrupt_disable = am3517_disable_ethernet_int;
am3517_emac_device.dev.platform_data = pdata;
platform_device_register(&am3517_emac_device);
+ platform_device_register(&am3517_mdio_device);
+ clk_add_alias(NULL, dev_name(&am3517_mdio_device.dev),
+ NULL, &am3517_emac_device.dev);
regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
regval = regval & (~(AM35XX_CPGMACSS_SW_RST));
@@ -139,7 +160,6 @@ void am3517_evm_ethernet_init(struct emac_platform_data *pdata)
static struct i2c_board_info __initdata am3517evm_i2c1_boardinfo[] = {
{
I2C_BOARD_INFO("s35390a", 0x30),
- .type = "s35390a",
},
};
@@ -347,7 +367,7 @@ static struct omap_dss_board_info am3517_evm_dss_data = {
.default_device = &am3517_evm_lcd_device,
};
-struct platform_device am3517_evm_dss_device = {
+static struct platform_device am3517_evm_dss_device = {
.name = "omapdss",
.id = -1,
.dev = {
@@ -375,6 +395,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 +438,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 +506,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..2c6db1aaeb29 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -39,9 +39,9 @@
#include <plat/board.h>
#include <plat/common.h>
#include <plat/gpmc.h>
-#include <plat/control.h>
#include "mux.h"
+#include "control.h"
/* LED & Switch macros */
#define LED0_GPIO13 13
@@ -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..63f764e2af3f 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -31,6 +31,7 @@
#include <linux/i2c/at24.h>
#include <linux/i2c/twl.h>
#include <linux/regulator/machine.h>
+#include <linux/mmc/host.h>
#include <linux/spi/spi.h>
#include <linux/spi/tdo24m.h>
@@ -237,8 +238,6 @@ static inline void cm_t35_init_nand(void) {}
defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
#include <linux/spi/ads7846.h>
-#include <plat/mcspi.h>
-
static struct omap2_mcspi_device_config ads7846_mcspi_config = {
.turbo_mode = 0,
.single_channel = 1, /* 0: slave, 1: master */
@@ -558,7 +557,7 @@ static struct twl4030_usb_data cm_t35_usb_data = {
.usb_mode = T2_USB_MODE_ULPI,
};
-static int cm_t35_keymap[] = {
+static uint32_t cm_t35_keymap[] = {
KEY(0, 0, KEY_A), KEY(0, 1, KEY_B), KEY(0, 2, KEY_LEFT),
KEY(1, 0, KEY_UP), KEY(1, 1, KEY_ENTER), KEY(1, 2, KEY_DOWN),
KEY(2, 0, KEY_RIGHT), KEY(2, 1, KEY_C), KEY(2, 2, KEY_D),
@@ -579,14 +578,14 @@ static struct twl4030_keypad_data cm_t35_kp_data = {
static struct omap2_hsmmc_info mmc[] = {
{
.mmc = 1,
- .wires = 4,
+ .caps = MMC_CAP_4_BIT_DATA,
.gpio_cd = -EINVAL,
.gpio_wp = -EINVAL,
},
{
.mmc = 2,
- .wires = 4,
+ .caps = MMC_CAP_4_BIT_DATA,
.transceiver = 1,
.gpio_cd = -EINVAL,
.gpio_wp = -EINVAL,
@@ -809,8 +808,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-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c
new file mode 100644
index 000000000000..1dd303e9a267
--- /dev/null
+++ b/arch/arm/mach-omap2/board-cm-t3517.c
@@ -0,0 +1,292 @@
+/*
+ * linux/arch/arm/mach-omap2/board-cm-t3517.c
+ *
+ * Support for the CompuLab CM-T3517 modules
+ *
+ * Copyright (C) 2010 CompuLab, Ltd.
+ * Author: 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.
+ *
+ * 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/rtc-v3020.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/can/platform/ti_hecc.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/usb.h>
+#include <plat/nand.h>
+#include <plat/gpmc.h>
+
+#include <mach/am35xx.h>
+
+#include "mux.h"
+#include "control.h"
+
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+static struct gpio_led cm_t3517_leds[] = {
+ [0] = {
+ .gpio = 186,
+ .name = "cm-t3517:green",
+ .default_trigger = "heartbeat",
+ .active_low = 0,
+ },
+};
+
+static struct gpio_led_platform_data cm_t3517_led_pdata = {
+ .num_leds = ARRAY_SIZE(cm_t3517_leds),
+ .leds = cm_t3517_leds,
+};
+
+static struct platform_device cm_t3517_led_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &cm_t3517_led_pdata,
+ },
+};
+
+static void __init cm_t3517_init_leds(void)
+{
+ platform_device_register(&cm_t3517_led_device);
+}
+#else
+static inline void cm_t3517_init_leds(void) {}
+#endif
+
+#if defined(CONFIG_CAN_TI_HECC) || defined(CONFIG_CAN_TI_HECC_MODULE)
+static struct resource cm_t3517_hecc_resources[] = {
+ {
+ .start = AM35XX_IPSS_HECC_BASE,
+ .end = AM35XX_IPSS_HECC_BASE + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_35XX_HECC0_IRQ,
+ .end = INT_35XX_HECC0_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct ti_hecc_platform_data cm_t3517_hecc_pdata = {
+ .scc_hecc_offset = AM35XX_HECC_SCC_HECC_OFFSET,
+ .scc_ram_offset = AM35XX_HECC_SCC_RAM_OFFSET,
+ .hecc_ram_offset = AM35XX_HECC_RAM_OFFSET,
+ .mbx_offset = AM35XX_HECC_MBOX_OFFSET,
+ .int_line = AM35XX_HECC_INT_LINE,
+ .version = AM35XX_HECC_VERSION,
+};
+
+static struct platform_device cm_t3517_hecc_device = {
+ .name = "ti_hecc",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(cm_t3517_hecc_resources),
+ .resource = cm_t3517_hecc_resources,
+ .dev = {
+ .platform_data = &cm_t3517_hecc_pdata,
+ },
+};
+
+static void cm_t3517_init_hecc(void)
+{
+ platform_device_register(&cm_t3517_hecc_device);
+}
+#else
+static inline void cm_t3517_init_hecc(void) {}
+#endif
+
+#if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE)
+#define RTC_IO_GPIO (153)
+#define RTC_WR_GPIO (154)
+#define RTC_RD_GPIO (160)
+#define RTC_CS_GPIO (163)
+
+struct v3020_platform_data cm_t3517_v3020_pdata = {
+ .use_gpio = 1,
+ .gpio_cs = RTC_CS_GPIO,
+ .gpio_wr = RTC_WR_GPIO,
+ .gpio_rd = RTC_RD_GPIO,
+ .gpio_io = RTC_IO_GPIO,
+};
+
+static struct platform_device cm_t3517_rtc_device = {
+ .name = "v3020",
+ .id = -1,
+ .dev = {
+ .platform_data = &cm_t3517_v3020_pdata,
+ }
+};
+
+static void __init cm_t3517_init_rtc(void)
+{
+ platform_device_register(&cm_t3517_rtc_device);
+}
+#else
+static inline void cm_t3517_init_rtc(void) {}
+#endif
+
+#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_EHCI_HCD_MODULE)
+#define HSUSB1_RESET_GPIO (146)
+#define HSUSB2_RESET_GPIO (147)
+#define USB_HUB_RESET_GPIO (152)
+
+static struct ehci_hcd_omap_platform_data cm_t3517_ehci_pdata __initdata = {
+ .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
+ .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
+ .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
+
+ .phy_reset = true,
+ .reset_gpio_port[0] = HSUSB1_RESET_GPIO,
+ .reset_gpio_port[1] = HSUSB2_RESET_GPIO,
+ .reset_gpio_port[2] = -EINVAL,
+};
+
+static int cm_t3517_init_usbh(void)
+{
+ int err;
+
+ err = gpio_request(USB_HUB_RESET_GPIO, "usb hub rst");
+ if (err) {
+ pr_err("CM-T3517: usb hub rst gpio request failed: %d\n", err);
+ } else {
+ gpio_direction_output(USB_HUB_RESET_GPIO, 0);
+ udelay(10);
+ gpio_set_value(USB_HUB_RESET_GPIO, 1);
+ msleep(1);
+ }
+
+ usb_ehci_init(&cm_t3517_ehci_pdata);
+
+ return 0;
+}
+#else
+static inline int cm_t3517_init_usbh(void)
+{
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE)
+#define NAND_BLOCK_SIZE SZ_128K
+
+static struct mtd_partition cm_t3517_nand_partitions[] = {
+ {
+ .name = "xloader",
+ .offset = 0, /* Offset = 0x00000 */
+ .size = 4 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE
+ },
+ {
+ .name = "uboot",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
+ .size = 15 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "uboot environment",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */
+ .size = 2 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "linux",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */
+ .size = 32 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "rootfs",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct omap_nand_platform_data cm_t3517_nand_data = {
+ .parts = cm_t3517_nand_partitions,
+ .nr_parts = ARRAY_SIZE(cm_t3517_nand_partitions),
+ .dma_channel = -1, /* disable DMA in OMAP NAND driver */
+ .cs = 0,
+};
+
+static void __init cm_t3517_init_nand(void)
+{
+ if (gpmc_nand_init(&cm_t3517_nand_data) < 0)
+ pr_err("CM-T3517: NAND initialization failed\n");
+}
+#else
+static inline void cm_t3517_init_nand(void) {}
+#endif
+
+static struct omap_board_config_kernel cm_t3517_config[] __initdata = {
+};
+
+static void __init cm_t3517_init_irq(void)
+{
+ omap_board_config = cm_t3517_config;
+ omap_board_config_size = ARRAY_SIZE(cm_t3517_config);
+
+ omap2_init_common_hw(NULL, NULL);
+ omap_init_irq();
+ omap_gpio_init();
+}
+
+static struct omap_board_mux board_mux[] __initdata = {
+ /* GPIO186 - Green LED */
+ OMAP3_MUX(SYS_CLKOUT2, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+ /* RTC GPIOs: IO, WR#, RD#, CS# */
+ OMAP3_MUX(MCBSP4_DR, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCBSP4_DX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCBSP_CLKS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+ OMAP3_MUX(UART3_CTS_RCTX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+ /* HSUSB1 RESET */
+ OMAP3_MUX(UART2_TX, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+ /* HSUSB2 RESET */
+ OMAP3_MUX(UART2_RX, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+ /* CM-T3517 USB HUB nRESET */
+ OMAP3_MUX(MCBSP4_CLKX, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+static void __init cm_t3517_init(void)
+{
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ omap_serial_init();
+ cm_t3517_init_leds();
+ cm_t3517_init_nand();
+ cm_t3517_init_rtc();
+ cm_t3517_init_usbh();
+ cm_t3517_init_hecc();
+}
+
+MACHINE_START(CM_T3517, "Compulab CM-T3517")
+ .boot_params = 0x80000100,
+ .map_io = omap3_map_io,
+ .reserve = omap_reserve,
+ .init_irq = cm_t3517_init_irq,
+ .init_machine = cm_t3517_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index a07086d6a0b2..067f4379c87f 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -28,6 +28,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand.h>
+#include <linux/mmc/host.h>
#include <linux/regulator/machine.h>
#include <linux/i2c/twl.h>
@@ -44,7 +45,6 @@
#include <plat/gpmc.h>
#include <plat/nand.h>
#include <plat/usb.h>
-#include <plat/timer-gp.h>
#include <plat/display.h>
#include <plat/mcspi.h>
@@ -58,6 +58,7 @@
#include "mux.h"
#include "hsmmc.h"
+#include "timer-gp.h"
#define NAND_BLOCK_SIZE SZ_128K
@@ -105,7 +106,7 @@ static struct omap_nand_platform_data devkit8000_nand_data = {
static struct omap2_hsmmc_info mmc[] = {
{
.mmc = 1,
- .wires = 8,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
.gpio_wp = 29,
},
{} /* Terminator */
@@ -198,7 +199,7 @@ static struct platform_device devkit8000_dss_device = {
static struct regulator_consumer_supply devkit8000_vdda_dac_supply =
REGULATOR_SUPPLY("vdda_dac", "omapdss");
-static int board_keymap[] = {
+static uint32_t board_keymap[] = {
KEY(0, 0, KEY_1),
KEY(1, 0, KEY_2),
KEY(2, 0, KEY_3),
@@ -800,8 +801,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-flash.c b/arch/arm/mach-omap2/board-flash.c
index ac834aa7abf6..fd38c05bb47f 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -21,7 +21,8 @@
#include <plat/nand.h>
#include <plat/onenand.h>
#include <plat/tc.h>
-#include <mach/board-flash.h>
+
+#include "board-flash.h"
#define REG_FPGA_REV 0x10
#define REG_FPGA_DIP_SWITCH_INPUT2 0x60
diff --git a/arch/arm/mach-omap2/include/mach/board-flash.h b/arch/arm/mach-omap2/board-flash.h
index b2242ae2bb6f..69befe00dd2f 100644
--- a/arch/arm/mach-omap2/include/mach/board-flash.h
+++ b/arch/arm/mach-omap2/board-flash.h
@@ -26,3 +26,5 @@ struct flash_partitions {
extern void board_flash_init(struct flash_partitions [],
char chip_sel[][GPMC_CS_NUM]);
+extern void board_nand_init(struct mtd_partition *nand_parts,
+ u8 nr_parts, u8 cs);
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 3482b99e8c86..b1c2c9a11c38 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -48,14 +48,24 @@ static void __init omap_generic_init(void)
static void __init omap_generic_map_io(void)
{
- omap2_set_globals_242x(); /* should be 242x, 243x, or 343x */
- omap242x_map_common_io();
+ if (cpu_is_omap242x()) {
+ omap2_set_globals_242x();
+ omap242x_map_common_io();
+ } else if (cpu_is_omap243x()) {
+ omap2_set_globals_243x();
+ omap243x_map_common_io();
+ } else if (cpu_is_omap34xx()) {
+ omap2_set_globals_3xxx();
+ omap34xx_map_common_io();
+ } else if (cpu_is_omap44xx()) {
+ omap2_set_globals_443x();
+ omap44xx_map_common_io();
+ }
}
+/* XXX This machine entry name should be updated */
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..929993b4bf26 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -31,7 +31,6 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <plat/control.h>
#include <mach/gpio.h>
#include <plat/usb.h>
#include <plat/board.h>
@@ -42,6 +41,7 @@
#include <plat/gpmc.h>
#include "mux.h"
+#include "control.h"
#define H4_FLASH_CS 0
#define H4_SMC91X_CS 1
@@ -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..5e035a58b809 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -20,6 +20,7 @@
#include <linux/regulator/machine.h>
#include <linux/i2c/twl.h>
+#include <linux/mmc/host.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -38,12 +39,61 @@
#define IGEP2_SMSC911X_CS 5
#define IGEP2_SMSC911X_GPIO 176
#define IGEP2_GPIO_USBH_NRESET 24
-#define IGEP2_GPIO_LED0_GREEN 26
-#define IGEP2_GPIO_LED0_RED 27
-#define IGEP2_GPIO_LED1_RED 28
-#define IGEP2_GPIO_DVI_PUP 170
-#define IGEP2_GPIO_WIFI_NPD 94
-#define IGEP2_GPIO_WIFI_NRESET 95
+#define IGEP2_GPIO_LED0_GREEN 26
+#define IGEP2_GPIO_LED0_RED 27
+#define IGEP2_GPIO_LED1_RED 28
+#define IGEP2_GPIO_DVI_PUP 170
+
+#define IGEP2_RB_GPIO_WIFI_NPD 94
+#define IGEP2_RB_GPIO_WIFI_NRESET 95
+#define IGEP2_RB_GPIO_BT_NRESET 137
+#define IGEP2_RC_GPIO_WIFI_NPD 138
+#define IGEP2_RC_GPIO_WIFI_NRESET 139
+#define IGEP2_RC_GPIO_BT_NRESET 137
+
+/*
+ * IGEP2 Hardware Revision Table
+ *
+ * --------------------------------------------------------------------------
+ * | Id. | Hw Rev. | HW0 (28) | WIFI_NPD | WIFI_NRESET | BT_NRESET |
+ * --------------------------------------------------------------------------
+ * | 0 | B | high | gpio94 | gpio95 | - |
+ * | 0 | B/C (B-compatible) | high | gpio94 | gpio95 | gpio137 |
+ * | 1 | C | low | gpio138 | gpio139 | gpio137 |
+ * --------------------------------------------------------------------------
+ */
+
+#define IGEP2_BOARD_HWREV_B 0
+#define IGEP2_BOARD_HWREV_C 1
+
+static u8 hwrev;
+
+static void __init igep2_get_revision(void)
+{
+ u8 ret;
+
+ omap_mux_init_gpio(IGEP2_GPIO_LED1_RED, OMAP_PIN_INPUT);
+
+ if ((gpio_request(IGEP2_GPIO_LED1_RED, "GPIO_HW0_REV") == 0) &&
+ (gpio_direction_input(IGEP2_GPIO_LED1_RED) == 0)) {
+ ret = gpio_get_value(IGEP2_GPIO_LED1_RED);
+ if (ret == 0) {
+ pr_info("IGEP2: Hardware Revision C (B-NON compatible)\n");
+ hwrev = IGEP2_BOARD_HWREV_C;
+ } else if (ret == 1) {
+ pr_info("IGEP2: Hardware Revision B/C (B compatible)\n");
+ hwrev = IGEP2_BOARD_HWREV_B;
+ } else {
+ pr_err("IGEP2: Unknown Hardware Revision\n");
+ hwrev = -1;
+ }
+ } else {
+ pr_warning("IGEP2: Could not obtain gpio GPIO_HW0_REV\n");
+ pr_err("IGEP2: Unknown Hardware Revision\n");
+ }
+
+ gpio_free(IGEP2_GPIO_LED1_RED);
+}
#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
@@ -107,7 +157,7 @@ static struct platform_device igep2_onenand_device = {
},
};
-void __init igep2_flash_init(void)
+static void __init igep2_flash_init(void)
{
u8 cs = 0;
u8 onenandcs = GPMC_CS_NUM + 1;
@@ -141,7 +191,7 @@ void __init igep2_flash_init(void)
}
#else
-void __init igep2_flash_init(void) {}
+static void __init igep2_flash_init(void) {}
#endif
#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
@@ -211,10 +261,6 @@ static struct regulator_consumer_supply igep2_vmmc1_supply = {
.supply = "vmmc",
};
-static struct regulator_consumer_supply igep2_vmmc2_supply = {
- .supply = "vmmc",
-};
-
/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */
static struct regulator_init_data igep2_vmmc1 = {
.constraints = {
@@ -230,37 +276,95 @@ static struct regulator_init_data igep2_vmmc1 = {
.consumer_supplies = &igep2_vmmc1_supply,
};
-/* VMMC2 for OMAP VDD_MMC2 (i/o) and MMC2 WIFI */
-static struct regulator_init_data igep2_vmmc2 = {
- .constraints = {
- .min_uV = 1850000,
- .max_uV = 3150000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
- | REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
- .num_consumer_supplies = 1,
- .consumer_supplies = &igep2_vmmc2_supply,
-};
-
static struct omap2_hsmmc_info mmc[] = {
{
.mmc = 1,
- .wires = 4,
+ .caps = MMC_CAP_4_BIT_DATA,
.gpio_cd = -EINVAL,
.gpio_wp = -EINVAL,
},
+#if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE)
{
.mmc = 2,
- .wires = 4,
+ .caps = MMC_CAP_4_BIT_DATA,
.gpio_cd = -EINVAL,
.gpio_wp = -EINVAL,
},
+#endif
{} /* Terminator */
};
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+#include <linux/leds.h>
+
+static struct gpio_led igep2_gpio_leds[] = {
+ [0] = {
+ .name = "gpio-led:red:d0",
+ .gpio = IGEP2_GPIO_LED0_RED,
+ .default_trigger = "default-off"
+ },
+ [1] = {
+ .name = "gpio-led:green:d0",
+ .gpio = IGEP2_GPIO_LED0_GREEN,
+ .default_trigger = "default-off",
+ },
+ [2] = {
+ .name = "gpio-led:red:d1",
+ .gpio = IGEP2_GPIO_LED1_RED,
+ .default_trigger = "default-off",
+ },
+ [3] = {
+ .name = "gpio-led:green:d1",
+ .default_trigger = "heartbeat",
+ .gpio = -EINVAL, /* gets replaced */
+ },
+};
+
+static struct gpio_led_platform_data igep2_led_pdata = {
+ .leds = igep2_gpio_leds,
+ .num_leds = ARRAY_SIZE(igep2_gpio_leds),
+};
+
+static struct platform_device igep2_led_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &igep2_led_pdata,
+ },
+};
+
+static void __init igep2_leds_init(void)
+{
+ platform_device_register(&igep2_led_device);
+}
+
+#else
+static inline void igep2_leds_init(void)
+{
+ if ((gpio_request(IGEP2_GPIO_LED0_RED, "gpio-led:red:d0") == 0) &&
+ (gpio_direction_output(IGEP2_GPIO_LED0_RED, 1) == 0)) {
+ gpio_export(IGEP2_GPIO_LED0_RED, 0);
+ gpio_set_value(IGEP2_GPIO_LED0_RED, 0);
+ } else
+ pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_RED\n");
+
+ if ((gpio_request(IGEP2_GPIO_LED0_GREEN, "gpio-led:green:d0") == 0) &&
+ (gpio_direction_output(IGEP2_GPIO_LED0_GREEN, 1) == 0)) {
+ gpio_export(IGEP2_GPIO_LED0_GREEN, 0);
+ gpio_set_value(IGEP2_GPIO_LED0_GREEN, 0);
+ } else
+ pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_GREEN\n");
+
+ if ((gpio_request(IGEP2_GPIO_LED1_RED, "gpio-led:red:d1") == 0) &&
+ (gpio_direction_output(IGEP2_GPIO_LED1_RED, 1) == 0)) {
+ gpio_export(IGEP2_GPIO_LED1_RED, 0);
+ gpio_set_value(IGEP2_GPIO_LED1_RED, 0);
+ } else
+ pr_warning("IGEP v2: Could not obtain gpio GPIO_LED1_RED\n");
+
+}
+#endif
+
static int igep2_twl_gpio_setup(struct device *dev,
unsigned gpio, unsigned ngpio)
{
@@ -268,20 +372,48 @@ static int igep2_twl_gpio_setup(struct device *dev,
mmc[0].gpio_cd = gpio + 0;
omap2_hsmmc_init(mmc);
- /* link regulators to MMC adapters ... we "know" the
+ /*
+ * link regulators to MMC adapters ... we "know" the
* regulators will be set up only *after* we return.
- */
+ */
igep2_vmmc1_supply.dev = mmc[0].dev;
- igep2_vmmc2_supply.dev = mmc[1].dev;
+
+ /*
+ * REVISIT: need ehci-omap hooks for external VBUS
+ * power switch and overcurrent detect
+ */
+ if ((gpio_request(gpio + 1, "GPIO_EHCI_NOC") < 0) ||
+ (gpio_direction_input(gpio + 1) < 0))
+ pr_err("IGEP2: Could not obtain gpio for EHCI NOC");
+
+ /*
+ * TWL4030_GPIO_MAX + 0 == ledA, GPIO_USBH_CPEN
+ * (out, active low)
+ */
+ if ((gpio_request(gpio + TWL4030_GPIO_MAX, "GPIO_USBH_CPEN") < 0) ||
+ (gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0) < 0))
+ pr_err("IGEP2: Could not obtain gpio for USBH_CPEN");
+
+ /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
+#if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE)
+ if ((gpio_request(gpio+TWL4030_GPIO_MAX+1, "gpio-led:green:d1") == 0)
+ && (gpio_direction_output(gpio + TWL4030_GPIO_MAX + 1, 1) == 0)) {
+ gpio_export(gpio + TWL4030_GPIO_MAX + 1, 0);
+ gpio_set_value(gpio + TWL4030_GPIO_MAX + 1, 0);
+ } else
+ pr_warning("IGEP v2: Could not obtain gpio GPIO_LED1_GREEN\n");
+#else
+ igep2_gpio_leds[3].gpio = gpio + TWL4030_GPIO_MAX + 1;
+#endif
return 0;
};
-static struct twl4030_gpio_platform_data igep2_gpio_data = {
+static struct twl4030_gpio_platform_data igep2_twl4030_gpio_pdata = {
.gpio_base = OMAP_MAX_GPIO_LINES,
.irq_base = TWL4030_GPIO_IRQ_BASE,
.irq_end = TWL4030_GPIO_IRQ_END,
- .use_leds = false,
+ .use_leds = true,
.setup = igep2_twl_gpio_setup,
};
@@ -355,47 +487,6 @@ static void __init igep2_display_init(void)
pr_err("IGEP v2: Could not obtain gpio GPIO_DVI_PUP\n");
}
-#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
-#include <linux/leds.h>
-
-static struct gpio_led igep2_gpio_leds[] = {
- {
- .name = "led0:red",
- .gpio = IGEP2_GPIO_LED0_RED,
- },
- {
- .name = "led0:green",
- .default_trigger = "heartbeat",
- .gpio = IGEP2_GPIO_LED0_GREEN,
- },
- {
- .name = "led1:red",
- .gpio = IGEP2_GPIO_LED1_RED,
- },
-};
-
-static struct gpio_led_platform_data igep2_led_pdata = {
- .leds = igep2_gpio_leds,
- .num_leds = ARRAY_SIZE(igep2_gpio_leds),
-};
-
-static struct platform_device igep2_led_device = {
- .name = "leds-gpio",
- .id = -1,
- .dev = {
- .platform_data = &igep2_led_pdata,
- },
-};
-
-static void __init igep2_init_led(void)
-{
- platform_device_register(&igep2_led_device);
-}
-
-#else
-static inline void igep2_init_led(void) {}
-#endif
-
static struct platform_device *igep2_devices[] __initdata = {
&igep2_dss_device,
};
@@ -425,14 +516,13 @@ static struct twl4030_platform_data igep2_twldata = {
/* platform_data for children goes here */
.usb = &igep2_usb_data,
.codec = &igep2_codec_data,
- .gpio = &igep2_gpio_data,
+ .gpio = &igep2_twl4030_gpio_pdata,
.vmmc1 = &igep2_vmmc1,
- .vmmc2 = &igep2_vmmc2,
.vpll2 = &igep2_vpll2,
};
-static struct i2c_board_info __initdata igep2_i2c_boardinfo[] = {
+static struct i2c_board_info __initdata igep2_i2c1_boardinfo[] = {
{
I2C_BOARD_INFO("twl4030", 0x48),
.flags = I2C_CLIENT_WAKE,
@@ -441,14 +531,29 @@ static struct i2c_board_info __initdata igep2_i2c_boardinfo[] = {
},
};
-static int __init igep2_i2c_init(void)
+static struct i2c_board_info __initdata igep2_i2c3_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("eeprom", 0x50),
+ },
+};
+
+static void __init igep2_i2c_init(void)
{
- omap_register_i2c_bus(1, 2600, igep2_i2c_boardinfo,
- ARRAY_SIZE(igep2_i2c_boardinfo));
- /* Bus 3 is attached to the DVI port where devices like the pico DLP
- * projector don't work reliably with 400kHz */
- omap_register_i2c_bus(3, 100, NULL, 0);
- return 0;
+ int ret;
+
+ ret = omap_register_i2c_bus(1, 2600, igep2_i2c1_boardinfo,
+ ARRAY_SIZE(igep2_i2c1_boardinfo));
+ if (ret)
+ pr_warning("IGEP2: Could not register I2C1 bus (%d)\n", ret);
+
+ /*
+ * Bus 3 is attached to the DVI port where devices like the pico DLP
+ * projector don't work reliably with 400kHz
+ */
+ ret = omap_register_i2c_bus(3, 100, igep2_i2c3_boardinfo,
+ ARRAY_SIZE(igep2_i2c3_boardinfo));
+ if (ret)
+ pr_warning("IGEP2: Could not register I2C3 bus (%d)\n", ret);
}
static struct omap_musb_board_data musb_board_data = {
@@ -476,9 +581,57 @@ static struct omap_board_mux board_mux[] __initdata = {
#define board_mux NULL
#endif
+#if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE)
+
+static void __init igep2_wlan_bt_init(void)
+{
+ unsigned npd, wreset, btreset;
+
+ /* GPIO's for WLAN-BT combo depends on hardware revision */
+ if (hwrev == IGEP2_BOARD_HWREV_B) {
+ npd = IGEP2_RB_GPIO_WIFI_NPD;
+ wreset = IGEP2_RB_GPIO_WIFI_NRESET;
+ btreset = IGEP2_RB_GPIO_BT_NRESET;
+ } else if (hwrev == IGEP2_BOARD_HWREV_C) {
+ npd = IGEP2_RC_GPIO_WIFI_NPD;
+ wreset = IGEP2_RC_GPIO_WIFI_NRESET;
+ btreset = IGEP2_RC_GPIO_BT_NRESET;
+ } else
+ return;
+
+ /* Set GPIO's for WLAN-BT combo module */
+ if ((gpio_request(npd, "GPIO_WIFI_NPD") == 0) &&
+ (gpio_direction_output(npd, 1) == 0)) {
+ gpio_export(npd, 0);
+ } else
+ pr_warning("IGEP2: Could not obtain gpio GPIO_WIFI_NPD\n");
+
+ if ((gpio_request(wreset, "GPIO_WIFI_NRESET") == 0) &&
+ (gpio_direction_output(wreset, 1) == 0)) {
+ gpio_export(wreset, 0);
+ gpio_set_value(wreset, 0);
+ udelay(10);
+ gpio_set_value(wreset, 1);
+ } else
+ pr_warning("IGEP2: Could not obtain gpio GPIO_WIFI_NRESET\n");
+
+ if ((gpio_request(btreset, "GPIO_BT_NRESET") == 0) &&
+ (gpio_direction_output(btreset, 1) == 0)) {
+ gpio_export(btreset, 0);
+ } else
+ pr_warning("IGEP2: Could not obtain gpio GPIO_BT_NRESET\n");
+}
+#else
+static inline void __init igep2_wlan_bt_init(void) { }
+#endif
+
static void __init igep2_init(void)
{
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+
+ /* Get IGEP2 hardware revision */
+ igep2_get_revision();
+ /* Register I2C busses and drivers */
igep2_i2c_init();
platform_add_devices(igep2_devices, ARRAY_SIZE(igep2_devices));
omap_serial_init();
@@ -486,55 +639,19 @@ static void __init igep2_init(void)
usb_ehci_init(&ehci_pdata);
igep2_flash_init();
- igep2_init_led();
+ igep2_leds_init();
igep2_display_init();
igep2_init_smsc911x();
- /* GPIO userspace leds */
-#if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE)
- if ((gpio_request(IGEP2_GPIO_LED0_RED, "led0:red") == 0) &&
- (gpio_direction_output(IGEP2_GPIO_LED0_RED, 1) == 0)) {
- gpio_export(IGEP2_GPIO_LED0_RED, 0);
- gpio_set_value(IGEP2_GPIO_LED0_RED, 0);
- } else
- pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_RED\n");
-
- if ((gpio_request(IGEP2_GPIO_LED0_GREEN, "led0:green") == 0) &&
- (gpio_direction_output(IGEP2_GPIO_LED0_GREEN, 1) == 0)) {
- gpio_export(IGEP2_GPIO_LED0_GREEN, 0);
- gpio_set_value(IGEP2_GPIO_LED0_GREEN, 0);
- } else
- pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_GREEN\n");
-
- if ((gpio_request(IGEP2_GPIO_LED1_RED, "led1:red") == 0) &&
- (gpio_direction_output(IGEP2_GPIO_LED1_RED, 1) == 0)) {
- gpio_export(IGEP2_GPIO_LED1_RED, 0);
- gpio_set_value(IGEP2_GPIO_LED1_RED, 0);
- } else
- pr_warning("IGEP v2: Could not obtain gpio GPIO_LED1_RED\n");
-#endif
-
- /* GPIO W-LAN + Bluetooth combo module */
- if ((gpio_request(IGEP2_GPIO_WIFI_NPD, "GPIO_WIFI_NPD") == 0) &&
- (gpio_direction_output(IGEP2_GPIO_WIFI_NPD, 1) == 0)) {
- gpio_export(IGEP2_GPIO_WIFI_NPD, 0);
-/* gpio_set_value(IGEP2_GPIO_WIFI_NPD, 0); */
- } else
- pr_warning("IGEP v2: Could not obtain gpio GPIO_WIFI_NPD\n");
+ /*
+ * WLAN-BT combo module from MuRata wich has a Marvell WLAN
+ * (88W8686) + CSR Bluetooth chipset. Uses SDIO interface.
+ */
+ igep2_wlan_bt_init();
- if ((gpio_request(IGEP2_GPIO_WIFI_NRESET, "GPIO_WIFI_NRESET") == 0) &&
- (gpio_direction_output(IGEP2_GPIO_WIFI_NRESET, 1) == 0)) {
- gpio_export(IGEP2_GPIO_WIFI_NRESET, 0);
- gpio_set_value(IGEP2_GPIO_WIFI_NRESET, 0);
- udelay(10);
- gpio_set_value(IGEP2_GPIO_WIFI_NRESET, 1);
- } else
- pr_warning("IGEP v2: Could not obtain gpio GPIO_WIFI_NRESET\n");
}
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-igep0030.c b/arch/arm/mach-omap2/board-igep0030.c
new file mode 100644
index 000000000000..22b0b253e16b
--- /dev/null
+++ b/arch/arm/mach-omap2/board-igep0030.c
@@ -0,0 +1,400 @@
+/*
+ * Copyright (C) 2010 - ISEE 2007 SL
+ *
+ * Modified from mach-omap2/board-generic.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
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+
+#include <linux/regulator/machine.h>
+#include <linux/i2c/twl.h>
+#include <linux/mmc/host.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/gpmc.h>
+#include <plat/usb.h>
+#include <plat/onenand.h>
+
+#include "mux.h"
+#include "hsmmc.h"
+#include "sdram-numonyx-m65kxxxxam.h"
+
+#define IGEP3_GPIO_LED0_GREEN 54
+#define IGEP3_GPIO_LED0_RED 53
+#define IGEP3_GPIO_LED1_RED 16
+
+#define IGEP3_GPIO_WIFI_NPD 138
+#define IGEP3_GPIO_WIFI_NRESET 139
+#define IGEP3_GPIO_BT_NRESET 137
+
+#define IGEP3_GPIO_USBH_NRESET 115
+
+
+#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
+ defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
+
+#define ONENAND_MAP 0x20000000
+
+/*
+ * x2 Flash built-in COMBO POP MEMORY
+ * Since the device is equipped with two DataRAMs, and two-plane NAND
+ * Flash memory array, these two component enables simultaneous program
+ * of 4KiB. Plane1 has only even blocks such as block0, block2, block4
+ * while Plane2 has only odd blocks such as block1, block3, block5.
+ * So MTD regards it as 4KiB page size and 256KiB block size 64*(2*2048)
+ */
+
+static struct mtd_partition igep3_onenand_partitions[] = {
+ {
+ .name = "X-Loader",
+ .offset = 0,
+ .size = 2 * (64*(2*2048))
+ },
+ {
+ .name = "U-Boot",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 6 * (64*(2*2048)),
+ },
+ {
+ .name = "Environment",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 2 * (64*(2*2048)),
+ },
+ {
+ .name = "Kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 12 * (64*(2*2048)),
+ },
+ {
+ .name = "File System",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct omap_onenand_platform_data igep3_onenand_pdata = {
+ .parts = igep3_onenand_partitions,
+ .nr_parts = ARRAY_SIZE(igep3_onenand_partitions),
+ .onenand_setup = NULL,
+ .dma_channel = -1, /* disable DMA in OMAP OneNAND driver */
+};
+
+static struct platform_device igep3_onenand_device = {
+ .name = "omap2-onenand",
+ .id = -1,
+ .dev = {
+ .platform_data = &igep3_onenand_pdata,
+ },
+};
+
+void __init igep3_flash_init(void)
+{
+ u8 cs = 0;
+ u8 onenandcs = GPMC_CS_NUM + 1;
+
+ for (cs = 0; cs < GPMC_CS_NUM; cs++) {
+ u32 ret;
+ ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+
+ /* Check if NAND/oneNAND is configured */
+ if ((ret & 0xC00) == 0x800)
+ /* NAND found */
+ pr_err("IGEP3: Unsupported NAND found\n");
+ else {
+ ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
+
+ if ((ret & 0x3F) == (ONENAND_MAP >> 24))
+ /* OneNAND found */
+ onenandcs = cs;
+ }
+ }
+
+ if (onenandcs > GPMC_CS_NUM) {
+ pr_err("IGEP3: Unable to find configuration in GPMC\n");
+ return;
+ }
+
+ igep3_onenand_pdata.cs = onenandcs;
+
+ if (platform_device_register(&igep3_onenand_device) < 0)
+ pr_err("IGEP3: Unable to register OneNAND device\n");
+}
+
+#else
+void __init igep3_flash_init(void) {}
+#endif
+
+static struct regulator_consumer_supply igep3_vmmc1_supply = {
+ .supply = "vmmc",
+};
+
+/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */
+static struct regulator_init_data igep3_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &igep3_vmmc1_supply,
+};
+
+static struct omap2_hsmmc_info mmc[] = {
+ [0] = {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ },
+#if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE)
+ [1] = {
+ .mmc = 2,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ },
+#endif
+ {} /* Terminator */
+};
+
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+#include <linux/leds.h>
+
+static struct gpio_led igep3_gpio_leds[] = {
+ [0] = {
+ .name = "gpio-led:red:d0",
+ .gpio = IGEP3_GPIO_LED0_RED,
+ .default_trigger = "default-off"
+ },
+ [1] = {
+ .name = "gpio-led:green:d0",
+ .gpio = IGEP3_GPIO_LED0_GREEN,
+ .default_trigger = "default-off",
+ },
+ [2] = {
+ .name = "gpio-led:red:d1",
+ .gpio = IGEP3_GPIO_LED1_RED,
+ .default_trigger = "default-off",
+ },
+ [3] = {
+ .name = "gpio-led:green:d1",
+ .default_trigger = "heartbeat",
+ .gpio = -EINVAL, /* gets replaced */
+ },
+};
+
+static struct gpio_led_platform_data igep3_led_pdata = {
+ .leds = igep3_gpio_leds,
+ .num_leds = ARRAY_SIZE(igep3_gpio_leds),
+};
+
+static struct platform_device igep3_led_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &igep3_led_pdata,
+ },
+};
+
+static void __init igep3_leds_init(void)
+{
+ platform_device_register(&igep3_led_device);
+}
+
+#else
+static inline void igep3_leds_init(void)
+{
+ if ((gpio_request(IGEP3_GPIO_LED0_RED, "gpio-led:red:d0") == 0) &&
+ (gpio_direction_output(IGEP3_GPIO_LED0_RED, 1) == 0)) {
+ gpio_export(IGEP3_GPIO_LED0_RED, 0);
+ gpio_set_value(IGEP3_GPIO_LED0_RED, 1);
+ } else
+ pr_warning("IGEP3: Could not obtain gpio GPIO_LED0_RED\n");
+
+ if ((gpio_request(IGEP3_GPIO_LED0_GREEN, "gpio-led:green:d0") == 0) &&
+ (gpio_direction_output(IGEP3_GPIO_LED0_GREEN, 1) == 0)) {
+ gpio_export(IGEP3_GPIO_LED0_GREEN, 0);
+ gpio_set_value(IGEP3_GPIO_LED0_GREEN, 1);
+ } else
+ pr_warning("IGEP3: Could not obtain gpio GPIO_LED0_GREEN\n");
+
+ if ((gpio_request(IGEP3_GPIO_LED1_RED, "gpio-led:red:d1") == 0) &&
+ (gpio_direction_output(IGEP3_GPIO_LED1_RED, 1) == 0)) {
+ gpio_export(IGEP3_GPIO_LED1_RED, 0);
+ gpio_set_value(IGEP3_GPIO_LED1_RED, 1);
+ } else
+ pr_warning("IGEP3: Could not obtain gpio GPIO_LED1_RED\n");
+}
+#endif
+
+static int igep3_twl4030_gpio_setup(struct device *dev,
+ unsigned gpio, unsigned ngpio)
+{
+ /* gpio + 0 is "mmc0_cd" (input/IRQ) */
+ mmc[0].gpio_cd = gpio + 0;
+ omap2_hsmmc_init(mmc);
+
+ /*
+ * link regulators to MMC adapters ... we "know" the
+ * regulators will be set up only *after* we return.
+ */
+ igep3_vmmc1_supply.dev = mmc[0].dev;
+
+ /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
+#if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE)
+ if ((gpio_request(gpio+TWL4030_GPIO_MAX+1, "gpio-led:green:d1") == 0)
+ && (gpio_direction_output(gpio + TWL4030_GPIO_MAX + 1, 1) == 0)) {
+ gpio_export(gpio + TWL4030_GPIO_MAX + 1, 0);
+ gpio_set_value(gpio + TWL4030_GPIO_MAX + 1, 0);
+ } else
+ pr_warning("IGEP3: Could not obtain gpio GPIO_LED1_GREEN\n");
+#else
+ igep3_gpio_leds[3].gpio = gpio + TWL4030_GPIO_MAX + 1;
+#endif
+
+ return 0;
+};
+
+static struct twl4030_gpio_platform_data igep3_twl4030_gpio_pdata = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .use_leds = true,
+ .setup = igep3_twl4030_gpio_setup,
+};
+
+static struct twl4030_usb_data igep3_twl4030_usb_data = {
+ .usb_mode = T2_USB_MODE_ULPI,
+};
+
+static void __init igep3_init_irq(void)
+{
+ omap2_init_common_hw(m65kxxxxam_sdrc_params, m65kxxxxam_sdrc_params);
+ omap_init_irq();
+ omap_gpio_init();
+}
+
+static struct twl4030_platform_data igep3_twl4030_pdata = {
+ .irq_base = TWL4030_IRQ_BASE,
+ .irq_end = TWL4030_IRQ_END,
+
+ /* platform_data for children goes here */
+ .usb = &igep3_twl4030_usb_data,
+ .gpio = &igep3_twl4030_gpio_pdata,
+ .vmmc1 = &igep3_vmmc1,
+};
+
+static struct i2c_board_info __initdata igep3_i2c_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("twl4030", 0x48),
+ .flags = I2C_CLIENT_WAKE,
+ .irq = INT_34XX_SYS_NIRQ,
+ .platform_data = &igep3_twl4030_pdata,
+ },
+};
+
+static int __init igep3_i2c_init(void)
+{
+ omap_register_i2c_bus(1, 2600, igep3_i2c_boardinfo,
+ ARRAY_SIZE(igep3_i2c_boardinfo));
+
+ return 0;
+}
+
+static struct omap_musb_board_data musb_board_data = {
+ .interface_type = MUSB_INTERFACE_ULPI,
+ .mode = MUSB_OTG,
+ .power = 100,
+};
+
+#if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE)
+
+static void __init igep3_wifi_bt_init(void)
+{
+ /* Configure MUX values for W-LAN + Bluetooth GPIO's */
+ omap_mux_init_gpio(IGEP3_GPIO_WIFI_NPD, OMAP_PIN_OUTPUT);
+ omap_mux_init_gpio(IGEP3_GPIO_WIFI_NRESET, OMAP_PIN_OUTPUT);
+ omap_mux_init_gpio(IGEP3_GPIO_BT_NRESET, OMAP_PIN_OUTPUT);
+
+ /* Set GPIO's for W-LAN + Bluetooth combo module */
+ if ((gpio_request(IGEP3_GPIO_WIFI_NPD, "GPIO_WIFI_NPD") == 0) &&
+ (gpio_direction_output(IGEP3_GPIO_WIFI_NPD, 1) == 0)) {
+ gpio_export(IGEP3_GPIO_WIFI_NPD, 0);
+ } else
+ pr_warning("IGEP3: Could not obtain gpio GPIO_WIFI_NPD\n");
+
+ if ((gpio_request(IGEP3_GPIO_WIFI_NRESET, "GPIO_WIFI_NRESET") == 0) &&
+ (gpio_direction_output(IGEP3_GPIO_WIFI_NRESET, 1) == 0)) {
+ gpio_export(IGEP3_GPIO_WIFI_NRESET, 0);
+ gpio_set_value(IGEP3_GPIO_WIFI_NRESET, 0);
+ udelay(10);
+ gpio_set_value(IGEP3_GPIO_WIFI_NRESET, 1);
+ } else
+ pr_warning("IGEP3: Could not obtain gpio GPIO_WIFI_NRESET\n");
+
+ if ((gpio_request(IGEP3_GPIO_BT_NRESET, "GPIO_BT_NRESET") == 0) &&
+ (gpio_direction_output(IGEP3_GPIO_BT_NRESET, 1) == 0)) {
+ gpio_export(IGEP3_GPIO_BT_NRESET, 0);
+ } else
+ pr_warning("IGEP3: Could not obtain gpio GPIO_BT_NRESET\n");
+}
+#else
+void __init igep3_wifi_bt_init(void) {}
+#endif
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define board_mux NULL
+#endif
+
+static void __init igep3_init(void)
+{
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+
+ /* Register I2C busses and drivers */
+ igep3_i2c_init();
+
+ omap_serial_init();
+ usb_musb_init(&musb_board_data);
+
+ igep3_flash_init();
+ igep3_leds_init();
+
+ /*
+ * WLAN-BT combo module from MuRata wich has a Marvell WLAN
+ * (88W8686) + CSR Bluetooth chipset. Uses SDIO interface.
+ */
+ igep3_wifi_bt_init();
+
+}
+
+MACHINE_START(IGEP0030, "IGEP OMAP3 module")
+ .boot_params = 0x80000100,
+ .map_io = omap3_map_io,
+ .init_irq = igep3_init_irq,
+ .init_machine = igep3_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index 00d9b13b01c5..001fd9713f39 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -27,6 +27,7 @@
#include <linux/i2c/twl.h>
#include <linux/io.h>
#include <linux/smsc911x.h>
+#include <linux/mmc/host.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
@@ -41,11 +42,12 @@
#include <mach/board-zoom.h>
#include <asm/delay.h>
-#include <plat/control.h>
#include <plat/usb.h>
+#include "board-flash.h"
#include "mux.h"
#include "hsmmc.h"
+#include "control.h"
#define LDP_SMSC911X_CS 1
#define LDP_SMSC911X_GPIO 152
@@ -82,7 +84,7 @@ static struct platform_device ldp_smsc911x_device = {
},
};
-static int board_keymap[] = {
+static uint32_t board_keymap[] = {
KEY(0, 0, KEY_1),
KEY(1, 0, KEY_2),
KEY(2, 0, KEY_3),
@@ -362,7 +364,7 @@ static int __init omap_i2c_init(void)
static struct omap2_hsmmc_info mmc[] __initdata = {
{
.mmc = 1,
- .wires = 4,
+ .caps = MMC_CAP_4_BIT_DATA,
.gpio_cd = -EINVAL,
.gpio_wp = -EINVAL,
},
@@ -442,8 +444,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..e823c7042ab3 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -20,6 +20,7 @@
#include <linux/i2c.h>
#include <linux/spi/spi.h>
#include <linux/usb/musb.h>
+#include <sound/tlv320aic3x.h>
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
@@ -383,15 +384,6 @@ static void n8x0_mmc_callback(void *data, u8 card_mask)
omap_mmc_notify_cover_event(mmc_device, index, *openp);
}
-void n8x0_mmc_slot1_cover_handler(void *arg, int closed_state)
-{
- if (mmc_device == NULL)
- return;
-
- slot1_cover_open = !closed_state;
- omap_mmc_notify_cover_event(mmc_device, 0, closed_state);
-}
-
static int n8x0_mmc_late_init(struct device *dev)
{
int r, bit, *openp;
@@ -511,7 +503,7 @@ static struct omap_mmc_platform_data mmc1_data = {
static struct omap_mmc_platform_data *mmc_data[OMAP24XX_NR_MMC];
-void __init n8x0_mmc_init(void)
+static void __init n8x0_mmc_init(void)
{
int err;
@@ -560,11 +552,6 @@ void __init n8x0_mmc_init(void)
void __init n8x0_mmc_init(void)
{
}
-
-void n8x0_mmc_slot1_cover_handler(void *arg, int state)
-{
-}
-
#endif /* CONFIG_MMC_OMAP */
#ifdef CONFIG_MENELAUS
@@ -614,29 +601,35 @@ static int n8x0_menelaus_late_init(struct device *dev)
return 0;
}
-static struct i2c_board_info __initdata n8x0_i2c_board_info_1[] = {
+#else
+static int n8x0_menelaus_late_init(struct device *dev)
+{
+ return 0;
+}
+#endif
+
+static struct menelaus_platform_data n8x0_menelaus_platform_data __initdata = {
+ .late_init = n8x0_menelaus_late_init,
+};
+
+static struct i2c_board_info __initdata n8x0_i2c_board_info_1[] __initdata = {
{
I2C_BOARD_INFO("menelaus", 0x72),
.irq = INT_24XX_SYS_NIRQ,
+ .platform_data = &n8x0_menelaus_platform_data,
},
};
-static struct menelaus_platform_data n8x0_menelaus_platform_data = {
- .late_init = n8x0_menelaus_late_init,
+static struct aic3x_pdata n810_aic33_data __initdata = {
+ .gpio_reset = 118,
};
-static void __init n8x0_menelaus_init(void)
-{
- n8x0_i2c_board_info_1[0].platform_data = &n8x0_menelaus_platform_data;
- omap_register_i2c_bus(1, 400, n8x0_i2c_board_info_1,
- ARRAY_SIZE(n8x0_i2c_board_info_1));
-}
-
-#else
-static inline void __init n8x0_menelaus_init(void)
-{
-}
-#endif
+static struct i2c_board_info n810_i2c_board_info_2[] __initdata = {
+ {
+ I2C_BOARD_INFO("tlv320aic3x", 0x18),
+ .platform_data = &n810_aic33_data,
+ },
+};
static void __init n8x0_map_io(void)
{
@@ -653,6 +646,11 @@ static void __init n8x0_init_irq(void)
#ifdef CONFIG_OMAP_MUX
static struct omap_board_mux board_mux[] __initdata = {
+ /* I2S codec port pins for McBSP block */
+ OMAP2420_MUX(EAC_AC_SCLK, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+ OMAP2420_MUX(EAC_AC_FS, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+ OMAP2420_MUX(EAC_AC_DIN, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+ OMAP2420_MUX(EAC_AC_DOUT, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT),
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
#else
@@ -665,17 +663,20 @@ static void __init n8x0_init_machine(void)
/* FIXME: add n810 spi devices */
spi_register_board_info(n800_spi_board_info,
ARRAY_SIZE(n800_spi_board_info));
+ omap_register_i2c_bus(1, 400, n8x0_i2c_board_info_1,
+ ARRAY_SIZE(n8x0_i2c_board_info_1));
+ omap_register_i2c_bus(2, 400, NULL, 0);
+ if (machine_is_nokia_n810())
+ i2c_register_board_info(2, n810_i2c_board_info_2,
+ ARRAY_SIZE(n810_i2c_board_info_2));
omap_serial_init();
- n8x0_menelaus_init();
n8x0_onenand_init();
n8x0_mmc_init();
n8x0_usb_init();
}
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 +686,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 +695,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..14f42240ae79 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -27,6 +27,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand.h>
+#include <linux/mmc/host.h>
#include <linux/regulator/machine.h>
#include <linux/i2c/twl.h>
@@ -43,13 +44,100 @@
#include <plat/gpmc.h>
#include <plat/nand.h>
#include <plat/usb.h>
-#include <plat/timer-gp.h>
#include "mux.h"
#include "hsmmc.h"
+#include "timer-gp.h"
#define NAND_BLOCK_SIZE SZ_128K
+/*
+ * OMAP3 Beagle revision
+ * Run time detection of Beagle revision is done by reading GPIO.
+ * GPIO ID -
+ * AXBX = GPIO173, GPIO172, GPIO171: 1 1 1
+ * C1_3 = GPIO173, GPIO172, GPIO171: 1 1 0
+ * C4 = GPIO173, GPIO172, GPIO171: 1 0 1
+ * XM = GPIO173, GPIO172, GPIO171: 0 0 0
+ */
+enum {
+ OMAP3BEAGLE_BOARD_UNKN = 0,
+ OMAP3BEAGLE_BOARD_AXBX,
+ OMAP3BEAGLE_BOARD_C1_3,
+ OMAP3BEAGLE_BOARD_C4,
+ OMAP3BEAGLE_BOARD_XM,
+};
+
+static u8 omap3_beagle_version;
+
+static u8 omap3_beagle_get_rev(void)
+{
+ return omap3_beagle_version;
+}
+
+static void __init omap3_beagle_init_rev(void)
+{
+ int ret;
+ u16 beagle_rev = 0;
+
+ omap_mux_init_gpio(171, OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_gpio(172, OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_gpio(173, OMAP_PIN_INPUT_PULLUP);
+
+ ret = gpio_request(171, "rev_id_0");
+ if (ret < 0)
+ goto fail0;
+
+ ret = gpio_request(172, "rev_id_1");
+ if (ret < 0)
+ goto fail1;
+
+ ret = gpio_request(173, "rev_id_2");
+ if (ret < 0)
+ goto fail2;
+
+ gpio_direction_input(171);
+ gpio_direction_input(172);
+ gpio_direction_input(173);
+
+ beagle_rev = gpio_get_value(171) | (gpio_get_value(172) << 1)
+ | (gpio_get_value(173) << 2);
+
+ switch (beagle_rev) {
+ case 7:
+ printk(KERN_INFO "OMAP3 Beagle Rev: Ax/Bx\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_AXBX;
+ break;
+ case 6:
+ printk(KERN_INFO "OMAP3 Beagle Rev: C1/C2/C3\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_C1_3;
+ break;
+ case 5:
+ printk(KERN_INFO "OMAP3 Beagle Rev: C4\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_C4;
+ break;
+ case 0:
+ printk(KERN_INFO "OMAP3 Beagle Rev: xM\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XM;
+ break;
+ default:
+ printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd\n", beagle_rev);
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN;
+ }
+
+ return;
+
+fail2:
+ gpio_free(172);
+fail1:
+ gpio_free(171);
+fail0:
+ printk(KERN_ERR "Unable to get revision detection GPIO pins\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN;
+
+ return;
+}
+
static struct mtd_partition omap3beagle_nand_partitions[] = {
/* All the partition sizes are listed in terms of NAND block size */
{
@@ -166,7 +254,7 @@ static void __init beagle_display_init(void)
static struct omap2_hsmmc_info mmc[] = {
{
.mmc = 1,
- .wires = 8,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
.gpio_wp = 29,
},
{} /* Terminator */
@@ -185,7 +273,10 @@ static struct gpio_led gpio_leds[];
static int beagle_twl_gpio_setup(struct device *dev,
unsigned gpio, unsigned ngpio)
{
- if (system_rev >= 0x20 && system_rev <= 0x34301000) {
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ mmc[0].gpio_wp = -EINVAL;
+ } else if ((omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C1_3) ||
+ (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C4)) {
omap_mux_init_gpio(23, OMAP_PIN_INPUT);
mmc[0].gpio_wp = 23;
} else {
@@ -322,13 +413,19 @@ static struct i2c_board_info __initdata beagle_i2c_boardinfo[] = {
},
};
+static struct i2c_board_info __initdata beagle_i2c_eeprom[] = {
+ {
+ I2C_BOARD_INFO("eeprom", 0x50),
+ },
+};
+
static int __init omap3_beagle_i2c_init(void)
{
omap_register_i2c_bus(1, 2600, beagle_i2c_boardinfo,
ARRAY_SIZE(beagle_i2c_boardinfo));
/* Bus 3 is attached to the DVI port where devices like the pico DLP
* projector don't work reliably with 400kHz */
- omap_register_i2c_bus(3, 100, NULL, 0);
+ omap_register_i2c_bus(3, 100, beagle_i2c_eeprom, ARRAY_SIZE(beagle_i2c_eeprom));
return 0;
}
@@ -464,6 +561,7 @@ static struct omap_musb_board_data musb_board_data = {
static void __init omap3_beagle_init(void)
{
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ omap3_beagle_init_rev();
omap3_beagle_i2c_init();
platform_add_devices(omap3_beagle_devices,
ARRAY_SIZE(omap3_beagle_devices));
@@ -487,8 +585,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..b04365c6bb10 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -31,6 +31,7 @@
#include <linux/smsc911x.h>
#include <linux/regulator/machine.h>
+#include <linux/mmc/host.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
@@ -370,7 +371,7 @@ static struct regulator_init_data omap3evm_vsim = {
static struct omap2_hsmmc_info mmc[] = {
{
.mmc = 1,
- .wires = 4,
+ .caps = MMC_CAP_4_BIT_DATA,
.gpio_cd = -EINVAL,
.gpio_wp = 63,
},
@@ -446,7 +447,7 @@ static struct twl4030_usb_data omap3evm_usb_data = {
.usb_mode = T2_USB_MODE_ULPI,
};
-static int board_keymap[] = {
+static uint32_t board_keymap[] = {
KEY(0, 0, KEY_LEFT),
KEY(0, 1, KEY_DOWN),
KEY(0, 2, KEY_ENTER),
@@ -584,7 +585,7 @@ static int ads7846_get_pendown_state(void)
return !gpio_get_value(OMAP3_EVM_TS_GPIO);
}
-struct ads7846_platform_data ads7846_config = {
+static struct ads7846_platform_data ads7846_config = {
.x_max = 0x0fff,
.y_max = 0x0fff,
.x_plate_ohms = 180,
@@ -603,7 +604,7 @@ static struct omap2_mcspi_device_config ads7846_mcspi_config = {
.single_channel = 1, /* 0: slave, 1: master */
};
-struct spi_board_info omap3evm_spi_board_info[] = {
+static struct spi_board_info omap3evm_spi_board_info[] = {
[0] = {
.modalias = "ads7846",
.bus_num = 1,
@@ -714,8 +715,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-omap3logic.c b/arch/arm/mach-omap2/board-omap3logic.c
new file mode 100644
index 000000000000..5f7d2c1e7ef5
--- /dev/null
+++ b/arch/arm/mach-omap2/board-omap3logic.c
@@ -0,0 +1,241 @@
+/*
+ * linux/arch/arm/mach-omap2/board-omap3logic.c
+ *
+ * Copyright (C) 2010 Li-Pro.Net
+ * Stephan Linz <linz@li-pro.net>
+ *
+ * Copyright (C) 2010 Logic Product Development, Inc.
+ * Peter Barada <peter.barada@logicpd.com>
+ *
+ * Modified from Beagle, EVM, and RX51
+ *
+ * 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/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <linux/regulator/machine.h>
+
+#include <linux/i2c/twl.h>
+#include <linux/mmc/host.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include "mux.h"
+#include "hsmmc.h"
+#include "timer-gp.h"
+#include "control.h"
+
+#include <plat/mux.h>
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/gpmc-smsc911x.h>
+#include <plat/gpmc.h>
+#include <plat/sdrc.h>
+
+#define OMAP3LOGIC_SMSC911X_CS 1
+
+#define OMAP3530_LV_SOM_MMC_GPIO_CD 110
+#define OMAP3530_LV_SOM_MMC_GPIO_WP 126
+#define OMAP3530_LV_SOM_SMSC911X_GPIO_IRQ 152
+
+#define OMAP3_TORPEDO_MMC_GPIO_CD 127
+#define OMAP3_TORPEDO_SMSC911X_GPIO_IRQ 129
+
+static struct regulator_consumer_supply omap3logic_vmmc1_supply = {
+ .supply = "vmmc",
+};
+
+/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
+static struct regulator_init_data omap3logic_vmmc1 = {
+ .constraints = {
+ .name = "VMMC1",
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &omap3logic_vmmc1_supply,
+};
+
+static struct twl4030_gpio_platform_data omap3logic_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .use_leds = true,
+ .pullups = BIT(1),
+ .pulldowns = BIT(2) | BIT(6) | BIT(7) | BIT(8)
+ | BIT(13) | BIT(15) | BIT(16) | BIT(17),
+};
+
+static struct twl4030_platform_data omap3logic_twldata = {
+ .irq_base = TWL4030_IRQ_BASE,
+ .irq_end = TWL4030_IRQ_END,
+
+ /* platform_data for children goes here */
+ .gpio = &omap3logic_gpio_data,
+ .vmmc1 = &omap3logic_vmmc1,
+};
+
+static struct i2c_board_info __initdata omap3logic_i2c_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("twl4030", 0x48),
+ .flags = I2C_CLIENT_WAKE,
+ .irq = INT_34XX_SYS_NIRQ,
+ .platform_data = &omap3logic_twldata,
+ },
+};
+
+static int __init omap3logic_i2c_init(void)
+{
+ omap_register_i2c_bus(1, 2600, omap3logic_i2c_boardinfo,
+ ARRAY_SIZE(omap3logic_i2c_boardinfo));
+ return 0;
+}
+
+static struct omap2_hsmmc_info __initdata board_mmc_info[] = {
+ {
+ .name = "external",
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ },
+ {} /* Terminator */
+};
+
+static void __init board_mmc_init(void)
+{
+ if (machine_is_omap3530_lv_som()) {
+ /* OMAP3530 LV SOM board */
+ board_mmc_info[0].gpio_cd = OMAP3530_LV_SOM_MMC_GPIO_CD;
+ board_mmc_info[0].gpio_wp = OMAP3530_LV_SOM_MMC_GPIO_WP;
+ omap_mux_init_signal("gpio_110", OMAP_PIN_OUTPUT);
+ omap_mux_init_signal("gpio_126", OMAP_PIN_OUTPUT);
+ } else if (machine_is_omap3_torpedo()) {
+ /* OMAP3 Torpedo board */
+ board_mmc_info[0].gpio_cd = OMAP3_TORPEDO_MMC_GPIO_CD;
+ omap_mux_init_signal("gpio_127", OMAP_PIN_OUTPUT);
+ } else {
+ /* unsupported board */
+ printk(KERN_ERR "%s(): unknown machine type\n", __func__);
+ return;
+ }
+
+ omap2_hsmmc_init(board_mmc_info);
+ /* link regulators to MMC adapters */
+ omap3logic_vmmc1_supply.dev = board_mmc_info[0].dev;
+}
+
+static struct omap_smsc911x_platform_data __initdata board_smsc911x_data = {
+ .cs = OMAP3LOGIC_SMSC911X_CS,
+ .gpio_irq = -EINVAL,
+ .gpio_reset = -EINVAL,
+ .flags = IORESOURCE_IRQ_LOWLEVEL,
+};
+
+/* TODO/FIXME (comment by Peter Barada, LogicPD):
+ * Fix the PBIAS voltage for Torpedo MMC1 pins that
+ * are used for other needs (IRQs, etc). */
+static void omap3torpedo_fix_pbias_voltage(void)
+{
+ u16 control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE;
+ u32 reg;
+
+ if (machine_is_omap3_torpedo())
+ {
+ /* Set the bias for the pin */
+ reg = omap_ctrl_readl(control_pbias_offset);
+
+ reg &= ~OMAP343X_PBIASLITEPWRDNZ1;
+ omap_ctrl_writel(reg, control_pbias_offset);
+
+ /* 100ms delay required for PBIAS configuration */
+ msleep(100);
+
+ reg |= OMAP343X_PBIASLITEVMODE1;
+ reg |= OMAP343X_PBIASLITEPWRDNZ1;
+ omap_ctrl_writel(reg | 0x300, control_pbias_offset);
+ }
+}
+
+static inline void __init board_smsc911x_init(void)
+{
+ if (machine_is_omap3530_lv_som()) {
+ /* OMAP3530 LV SOM board */
+ board_smsc911x_data.gpio_irq =
+ OMAP3530_LV_SOM_SMSC911X_GPIO_IRQ;
+ omap_mux_init_signal("gpio_152", OMAP_PIN_INPUT);
+ } else if (machine_is_omap3_torpedo()) {
+ /* OMAP3 Torpedo board */
+ board_smsc911x_data.gpio_irq = OMAP3_TORPEDO_SMSC911X_GPIO_IRQ;
+ omap_mux_init_signal("gpio_129", OMAP_PIN_INPUT);
+ } else {
+ /* unsupported board */
+ printk(KERN_ERR "%s(): unknown machine type\n", __func__);
+ return;
+ }
+
+ gpmc_smsc911x_init(&board_smsc911x_data);
+}
+
+static void __init omap3logic_init_irq(void)
+{
+ omap2_init_common_hw(NULL, NULL);
+ omap_init_irq();
+ omap_gpio_init();
+}
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define board_mux NULL
+#endif
+
+static void __init omap3logic_init(void)
+{
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ omap3torpedo_fix_pbias_voltage();
+ omap3logic_i2c_init();
+ omap_serial_init();
+ board_mmc_init();
+ board_smsc911x_init();
+
+ /* Ensure SDRC pins are mux'd for self-refresh */
+ omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
+ omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
+}
+
+MACHINE_START(OMAP3_TORPEDO, "Logic OMAP3 Torpedo board")
+ .boot_params = 0x80000100,
+ .map_io = omap3_map_io,
+ .init_irq = omap3logic_init_irq,
+ .init_machine = omap3logic_init,
+ .timer = &omap_timer,
+MACHINE_END
+
+MACHINE_START(OMAP3530_LV_SOM, "OMAP Logic 3530 LV SOM board")
+ .boot_params = 0x80000100,
+ .map_io = omap3_map_io,
+ .init_irq = omap3logic_init_irq,
+ .init_machine = omap3logic_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index dd3af2be13be..89ed1be2d62e 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -25,14 +25,16 @@
#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>
#include <linux/input.h>
#include <linux/input/matrix_keypad.h>
#include <linux/gpio_keys.h>
+#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
+#include <linux/regulator/fixed.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -276,14 +278,14 @@ static void pandora_wl1251_init_card(struct mmc_card *card)
static struct omap2_hsmmc_info omap3pandora_mmc[] = {
{
.mmc = 1,
- .wires = 4,
+ .caps = MMC_CAP_4_BIT_DATA,
.gpio_cd = -EINVAL,
.gpio_wp = 126,
.ext_clock = 0,
},
{
.mmc = 2,
- .wires = 4,
+ .caps = MMC_CAP_4_BIT_DATA,
.gpio_cd = -EINVAL,
.gpio_wp = 127,
.ext_clock = 1,
@@ -291,7 +293,7 @@ static struct omap2_hsmmc_info omap3pandora_mmc[] = {
},
{
.mmc = 3,
- .wires = 4,
+ .caps = MMC_CAP_4_BIT_DATA,
.gpio_cd = -EINVAL,
.gpio_wp = -EINVAL,
.init_card = pandora_wl1251_init_card,
@@ -344,6 +346,9 @@ static struct regulator_consumer_supply pandora_vmmc1_supply =
static struct regulator_consumer_supply pandora_vmmc2_supply =
REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.1");
+static struct regulator_consumer_supply pandora_vmmc3_supply =
+ REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.2");
+
static struct regulator_consumer_supply pandora_vdda_dac_supply =
REGULATOR_SUPPLY("vdda_dac", "omapdss");
@@ -488,6 +493,33 @@ static struct regulator_init_data pandora_vsim = {
.consumer_supplies = &pandora_adac_supply,
};
+/* Fixed regulator internal to Wifi module */
+static struct regulator_init_data pandora_vmmc3 = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &pandora_vmmc3_supply,
+};
+
+static struct fixed_voltage_config pandora_vwlan = {
+ .supply_name = "vwlan",
+ .microvolts = 1800000, /* 1.8V */
+ .gpio = PANDORA_WIFI_NRESET_GPIO,
+ .startup_delay = 50000, /* 50ms */
+ .enable_high = 1,
+ .enabled_at_boot = 0,
+ .init_data = &pandora_vmmc3,
+};
+
+static struct platform_device pandora_vwlan_device = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &pandora_vwlan,
+ },
+};
+
static struct twl4030_usb_data omap3pandora_usb_data = {
.usb_mode = T2_USB_MODE_ULPI,
};
@@ -501,6 +533,8 @@ static struct twl4030_codec_data omap3pandora_codec_data = {
.audio = &omap3pandora_audio_data,
};
+static struct twl4030_bci_platform_data pandora_bci_data;
+
static struct twl4030_platform_data omap3pandora_twldata = {
.irq_base = TWL4030_IRQ_BASE,
.irq_end = TWL4030_IRQ_END,
@@ -516,6 +550,7 @@ static struct twl4030_platform_data omap3pandora_twldata = {
.vaux4 = &pandora_vaux4,
.vsim = &pandora_vsim,
.keypad = &pandora_kp_data,
+ .bci = &pandora_bci_data,
};
static struct i2c_board_info __initdata omap3pandora_i2c_boardinfo[] = {
@@ -644,19 +679,8 @@ static void pandora_wl1251_init(void)
if (pandora_wl1251_pdata.irq < 0)
goto fail_irq;
- ret = gpio_request(PANDORA_WIFI_NRESET_GPIO, "wl1251 nreset");
- if (ret < 0)
- goto fail_irq;
-
- /* start powered so that it probes with MMC subsystem */
- ret = gpio_direction_output(PANDORA_WIFI_NRESET_GPIO, 1);
- if (ret < 0)
- goto fail_nreset;
-
return;
-fail_nreset:
- gpio_free(PANDORA_WIFI_NRESET_GPIO);
fail_irq:
gpio_free(PANDORA_WIFI_IRQ_GPIO);
fail:
@@ -668,6 +692,7 @@ static struct platform_device *omap3pandora_devices[] __initdata = {
&pandora_keys_gpio,
&pandora_dss_device,
&pandora_wl1251_data,
+ &pandora_vwlan_device,
};
static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
@@ -717,8 +742,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..f25272125413 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -26,6 +26,7 @@
#include <linux/regulator/machine.h>
#include <linux/i2c/twl.h>
+#include <linux/mmc/host.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
@@ -38,7 +39,6 @@
#include <plat/gpmc.h>
#include <plat/nand.h>
#include <plat/usb.h>
-#include <plat/timer-gp.h>
#include <plat/display.h>
#include <plat/mcspi.h>
@@ -52,6 +52,7 @@
#include "sdram-micron-mt46h32m32lf-6.h"
#include "mux.h"
#include "hsmmc.h"
+#include "timer-gp.h"
#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
#define OMAP3STALKER_ETHR_START 0x2c000000
@@ -275,7 +276,7 @@ static struct regulator_init_data omap3stalker_vsim = {
static struct omap2_hsmmc_info mmc[] = {
{
.mmc = 1,
- .wires = 4,
+ .caps = MMC_CAP_4_BIT_DATA,
.gpio_cd = -EINVAL,
.gpio_wp = 23,
},
@@ -389,7 +390,7 @@ static struct twl4030_usb_data omap3stalker_usb_data = {
.usb_mode = T2_USB_MODE_ULPI,
};
-static int board_keymap[] = {
+static uint32_t board_keymap[] = {
KEY(0, 0, KEY_LEFT),
KEY(0, 1, KEY_DOWN),
KEY(0, 2, KEY_ENTER),
@@ -564,7 +565,7 @@ static struct omap2_mcspi_device_config ads7846_mcspi_config = {
.single_channel = 1, /* 0: slave, 1: master */
};
-struct spi_board_info omap3stalker_spi_board_info[] = {
+static struct spi_board_info omap3stalker_spi_board_info[] = {
[0] = {
.modalias = "ads7846",
.bus_num = 1,
@@ -654,8 +655,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..41104bb8774c 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -27,6 +27,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand.h>
+#include <linux/mmc/host.h>
#include <plat/mcspi.h>
#include <linux/spi/spi.h>
@@ -47,10 +48,10 @@
#include <plat/gpmc.h>
#include <plat/nand.h>
#include <plat/usb.h>
-#include <plat/timer-gp.h>
#include "mux.h"
#include "hsmmc.h"
+#include "timer-gp.h"
#include <asm/setup.h>
@@ -61,7 +62,7 @@
#define TB_BL_PWM_TIMER 9
#define TB_KILL_POWER_GPIO 168
-unsigned long touchbook_revision;
+static unsigned long touchbook_revision;
static struct mtd_partition omap3touchbook_nand_partitions[] = {
/* All the partition sizes are listed in terms of NAND block size */
@@ -108,7 +109,7 @@ static struct omap_nand_platform_data omap3touchbook_nand_data = {
static struct omap2_hsmmc_info mmc[] = {
{
.mmc = 1,
- .wires = 8,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
.gpio_wp = 29,
},
{} /* Terminator */
@@ -538,8 +539,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..1ecd0a6cefb7 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -20,6 +20,7 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/leds.h>
#include <linux/gpio.h>
#include <linux/usb/otg.h>
#include <linux/i2c/twl.h>
@@ -33,12 +34,45 @@
#include <plat/board.h>
#include <plat/common.h>
-#include <plat/control.h>
-#include <plat/timer-gp.h>
#include <plat/usb.h>
#include <plat/mmc.h>
+#include "timer-gp.h"
+
#include "hsmmc.h"
+#include "control.h"
+
+#define GPIO_HUB_POWER 1
+#define GPIO_HUB_NRESET 62
+
+static struct gpio_led gpio_leds[] = {
+ {
+ .name = "pandaboard::status1",
+ .default_trigger = "heartbeat",
+ .gpio = 7,
+ },
+ {
+ .name = "pandaboard::status2",
+ .default_trigger = "mmc0",
+ .gpio = 8,
+ },
+};
+static struct gpio_led_platform_data gpio_led_info = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_led_info,
+ },
+};
+
+static struct platform_device *panda_devices[] __initdata = {
+ &leds_gpio,
+};
static void __init omap4_panda_init_irq(void)
{
@@ -47,6 +81,56 @@ static void __init omap4_panda_init_irq(void)
omap_gpio_init();
}
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+ .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
+ .port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN,
+ .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
+ .phy_reset = false,
+ .reset_gpio_port[0] = -EINVAL,
+ .reset_gpio_port[1] = -EINVAL,
+ .reset_gpio_port[2] = -EINVAL
+};
+
+static void __init omap4_ehci_init(void)
+{
+ int ret;
+
+
+ /* disable the power to the usb hub prior to init */
+ ret = gpio_request(GPIO_HUB_POWER, "hub_power");
+ if (ret) {
+ pr_err("Cannot request GPIO %d\n", GPIO_HUB_POWER);
+ goto error1;
+ }
+ gpio_export(GPIO_HUB_POWER, 0);
+ gpio_direction_output(GPIO_HUB_POWER, 0);
+ gpio_set_value(GPIO_HUB_POWER, 0);
+
+ /* reset phy+hub */
+ ret = gpio_request(GPIO_HUB_NRESET, "hub_nreset");
+ if (ret) {
+ pr_err("Cannot request GPIO %d\n", GPIO_HUB_NRESET);
+ goto error2;
+ }
+ gpio_export(GPIO_HUB_NRESET, 0);
+ gpio_direction_output(GPIO_HUB_NRESET, 0);
+ gpio_set_value(GPIO_HUB_NRESET, 0);
+ gpio_set_value(GPIO_HUB_NRESET, 1);
+
+ usb_ehci_init(&ehci_pdata);
+
+ /* enable power to hub */
+ gpio_set_value(GPIO_HUB_POWER, 1);
+ return;
+
+error2:
+ gpio_free(GPIO_HUB_POWER);
+error1:
+ pr_err("Unable to initialize EHCI power/reset\n");
+ return;
+
+}
+
static struct omap_musb_board_data musb_board_data = {
.interface_type = MUSB_INTERFACE_UTMI,
.mode = MUSB_PERIPHERAL,
@@ -56,7 +140,7 @@ static struct omap_musb_board_data musb_board_data = {
static struct omap2_hsmmc_info mmc[] = {
{
.mmc = 1,
- .wires = 8,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
.gpio_wp = -EINVAL,
},
{} /* Terminator */
@@ -67,10 +151,6 @@ static struct regulator_consumer_supply omap4_panda_vmmc_supply[] = {
.supply = "vmmc",
.dev_name = "mmci-omap-hs.0",
},
- {
- .supply = "vmmc",
- .dev_name = "mmci-omap-hs.1",
- },
};
static int omap4_twl6030_hsmmc_late_init(struct device *dev)
@@ -80,16 +160,32 @@ static int omap4_twl6030_hsmmc_late_init(struct device *dev)
struct platform_device, dev);
struct omap_mmc_platform_data *pdata = dev->platform_data;
+ if (!pdata) {
+ dev_err(dev, "%s: NULL platform data\n", __func__);
+ return -EINVAL;
+ }
/* Setting MMC1 Card detect Irq */
- if (pdev->id == 0)
- pdata->slots[0].card_detect_irq = TWL6030_IRQ_BASE +
- MMCDETECT_INTR_OFFSET;
+ if (pdev->id == 0) {
+ ret = twl6030_mmc_card_detect_config();
+ if (ret)
+ dev_err(dev, "%s: Error card detect config(%d)\n",
+ __func__, ret);
+ else
+ pdata->slots[0].card_detect = twl6030_mmc_card_detect;
+ }
return ret;
}
static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev)
{
- struct omap_mmc_platform_data *pdata = dev->platform_data;
+ struct omap_mmc_platform_data *pdata;
+
+ /* dev can be null if CONFIG_MMC_OMAP_HS is not set */
+ if (!dev) {
+ pr_err("Failed omap4_twl6030_hsmmc_set_late_init\n");
+ return;
+ }
+ pdata = dev->platform_data;
pdata->init = omap4_twl6030_hsmmc_late_init;
}
@@ -156,7 +252,7 @@ static struct regulator_init_data omap4_panda_vmmc = {
| REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
},
- .num_consumer_supplies = 2,
+ .num_consumer_supplies = 1,
.consumer_supplies = omap4_panda_vmmc_supply,
};
@@ -274,13 +370,13 @@ static int __init omap4_panda_i2c_init(void)
}
static void __init omap4_panda_init(void)
{
- int status;
-
omap4_panda_i2c_init();
+ platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices));
omap_serial_init();
omap4_twl6030_hsmmc_init(mmc);
/* OMAP4 Panda uses internal transceiver so register nop transceiver */
usb_nop_xceiv_register();
+ omap4_ehci_init();
/* FIXME: allow multi-omap to boot until musb is updated for omap4 */
if (!cpu_is_omap44xx())
usb_musb_init(&musb_board_data);
@@ -294,8 +390,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..7053bc0b46db 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -32,6 +32,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
+#include <linux/mmc/host.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -303,13 +304,13 @@ static void __init overo_flash_init(void)
static struct omap2_hsmmc_info mmc[] = {
{
.mmc = 1,
- .wires = 4,
+ .caps = MMC_CAP_4_BIT_DATA,
.gpio_cd = -EINVAL,
.gpio_wp = -EINVAL,
},
{
.mmc = 2,
- .wires = 4,
+ .caps = MMC_CAP_4_BIT_DATA,
.gpio_cd = -EINVAL,
.gpio_wp = -EINVAL,
.transceiver = true,
@@ -501,8 +502,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 11ce4b24befd..3fec4d62a91a 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>
@@ -33,6 +33,8 @@
#include <plat/onenand.h>
#include <plat/gpmc-smc91x.h>
+#include <mach/board-rx51.h>
+
#include <sound/tlv320aic3x.h>
#include <sound/tpa6130a2-plat.h>
@@ -105,6 +107,10 @@ static struct spi_board_info rx51_peripherals_spi_board_info[] __initdata = {
},
};
+static struct platform_device rx51_charger_device = {
+ .name = "isp1704_charger",
+};
+
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
#define RX51_GPIO_CAMERA_LENS_COVER 110
@@ -185,7 +191,7 @@ static void __init rx51_add_gpio_keys(void)
}
#endif /* CONFIG_KEYBOARD_GPIO || CONFIG_KEYBOARD_GPIO_MODULE */
-static int board_keymap[] = {
+static uint32_t board_keymap[] = {
/*
* Note that KEY(x, 8, KEY_XXX) entries represent "entrire row
* connected to the ground" matrix state.
@@ -303,7 +309,7 @@ static struct omap2_hsmmc_info mmc[] __initdata = {
{
.name = "external",
.mmc = 1,
- .wires = 4,
+ .caps = MMC_CAP_4_BIT_DATA,
.cover_only = true,
.gpio_cd = 160,
.gpio_wp = -EINVAL,
@@ -312,7 +318,8 @@ static struct omap2_hsmmc_info mmc[] __initdata = {
{
.name = "internal",
.mmc = 2,
- .wires = 8, /* See also rx51_mmc2_remux */
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+ /* See also rx51_mmc2_remux */
.gpio_cd = -EINVAL,
.gpio_wp = -EINVAL,
.nonremovable = true,
@@ -916,5 +923,6 @@ void __init rx51_peripherals_init(void)
spi_register_board_info(rx51_peripherals_spi_board_info,
ARRAY_SIZE(rx51_peripherals_spi_board_info));
omap2_hsmmc_init(mmc);
+ platform_device_register(&rx51_charger_device);
}
diff --git a/arch/arm/mach-omap2/board-rx51-sdram.c b/arch/arm/mach-omap2/board-rx51-sdram.c
index f392844195d2..a43b2c5c838b 100644
--- a/arch/arm/mach-omap2/board-rx51-sdram.c
+++ b/arch/arm/mach-omap2/board-rx51-sdram.c
@@ -43,7 +43,7 @@ struct sdram_timings {
u32 tWTR;
};
-struct omap_sdrc_params rx51_sdrc_params[4];
+static struct omap_sdrc_params rx51_sdrc_params[4];
static const struct sdram_timings rx51_timings[] = {
{
diff --git a/arch/arm/mach-omap2/board-rx51-video.c b/arch/arm/mach-omap2/board-rx51-video.c
index 5a1005ba9815..85503fed4e13 100644
--- a/arch/arm/mach-omap2/board-rx51-video.c
+++ b/arch/arm/mach-omap2/board-rx51-video.c
@@ -20,6 +20,8 @@
#include <plat/vram.h>
#include <plat/mcspi.h>
+#include <mach/board-rx51.h>
+
#include "mux.h"
#define RX51_LCD_RESET_GPIO 90
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-debugboard.c b/arch/arm/mach-omap2/board-zoom-debugboard.c
index 1d7f827b0408..007ebdc6c993 100644
--- a/arch/arm/mach-omap2/board-zoom-debugboard.c
+++ b/arch/arm/mach-omap2/board-zoom-debugboard.c
@@ -16,6 +16,8 @@
#include <plat/gpmc.h>
+#include <mach/board-zoom.h>
+
#define ZOOM_SMSC911X_CS 7
#define ZOOM_SMSC911X_GPIO 158
#define ZOOM_QUADUART_CS 3
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
index 3c6530475710..86c9b2102952 100644
--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -16,6 +16,9 @@
#include <linux/gpio.h>
#include <linux/i2c/twl.h>
#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/wl12xx.h>
+#include <linux/mmc/host.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -29,8 +32,11 @@
#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[] = {
+static uint32_t board_keymap[] = {
KEY(0, 0, KEY_E),
KEY(0, 1, KEY_R),
KEY(0, 2, KEY_T),
@@ -108,6 +114,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 = {
@@ -153,23 +164,63 @@ 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",
.mmc = 1,
- .wires = 4,
+ .caps = MMC_CAP_4_BIT_DATA,
.gpio_wp = -EINVAL,
.power_saving = true,
},
{
.name = "internal",
.mmc = 2,
- .wires = 8,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
.gpio_cd = -EINVAL,
.gpio_wp = -EINVAL,
.nonremovable = true,
.power_saving = true,
},
+ {
+ .name = "wl1271",
+ .mmc = 3,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_wp = -EINVAL,
+ .gpio_cd = -EINVAL,
+ .nonremovable = true,
+ },
{} /* Terminator */
};
@@ -291,7 +342,12 @@ 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();
+ omap_serial_init();
}
diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-omap2/board-zoom2.c
index 00c8f835649f..2992a9f3a585 100644
--- a/arch/arm/mach-omap2/board-zoom2.c
+++ b/arch/arm/mach-omap2/board-zoom2.c
@@ -24,6 +24,7 @@
#include <mach/board-zoom.h>
+#include "board-flash.h"
#include "mux.h"
#include "sdram-micron-mt46h32m32lf-6.h"
@@ -107,8 +108,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..5adde12c0395 100644
--- a/arch/arm/mach-omap2/board-zoom3.c
+++ b/arch/arm/mach-omap2/board-zoom3.c
@@ -22,6 +22,7 @@
#include <plat/board.h>
#include <plat/usb.h>
+#include "board-flash.h"
#include "mux.h"
#include "sdram-hynix-h8mbx00u0mer-0em.h"
@@ -123,8 +124,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/clock.c b/arch/arm/mach-omap2/clock.c
index 605f531783a8..b5babf5440e4 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -395,7 +395,7 @@ void omap2_clk_disable_unused(struct clk *clk)
if ((regval32 & (1 << clk->enable_bit)) == v)
return;
- printk(KERN_DEBUG "Disabling unused clock \"%s\"\n", clk->name);
+ pr_debug("Disabling unused clock \"%s\"\n", clk->name);
if (cpu_is_omap34xx()) {
omap2_clk_enable(clk);
omap2_clk_disable(clk);
diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
index 37d65d62ed8f..21f856252ad8 100644
--- a/arch/arm/mach-omap2/clock2420_data.c
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -27,6 +27,7 @@
#include "prm-regbits-24xx.h"
#include "cm-regbits-24xx.h"
#include "sdrc.h"
+#include "control.h"
#define OMAP_CM_REGADDR OMAP2420_CM_REGADDR
@@ -89,6 +90,12 @@ static struct clk alt_ck = { /* Typical 54M or 48M, may not exist */
.clkdm_name = "wkup_clkdm",
};
+/* Optional external clock input for McBSP CLKS */
+static struct clk mcbsp_clks = {
+ .name = "mcbsp_clks",
+ .ops = &clkops_null,
+};
+
/*
* Analog domain root source clocks
*/
@@ -1135,14 +1142,34 @@ static struct clk mcbsp1_ick = {
.recalc = &followparent_recalc,
};
+static const struct clksel_rate common_mcbsp_96m_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate common_mcbsp_mcbsp_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel mcbsp_fck_clksel[] = {
+ { .parent = &func_96m_ck, .rates = common_mcbsp_96m_rates },
+ { .parent = &mcbsp_clks, .rates = common_mcbsp_mcbsp_rates },
+ { .parent = NULL }
+};
+
static struct clk mcbsp1_fck = {
.name = "mcbsp1_fck",
.ops = &clkops_omap2_dflt_wait,
.parent = &func_96m_ck,
+ .init = &omap2_init_clksel_parent,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_MCBSP1_SHIFT,
- .recalc = &followparent_recalc,
+ .clksel_reg = OMAP242X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
+ .clksel_mask = OMAP2_MCBSP1_CLKS_MASK,
+ .clksel = mcbsp_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
};
static struct clk mcbsp2_ick = {
@@ -1159,10 +1186,14 @@ static struct clk mcbsp2_fck = {
.name = "mcbsp2_fck",
.ops = &clkops_omap2_dflt_wait,
.parent = &func_96m_ck,
+ .init = &omap2_init_clksel_parent,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_MCBSP2_SHIFT,
- .recalc = &followparent_recalc,
+ .clksel_reg = OMAP242X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
+ .clksel_mask = OMAP2_MCBSP2_CLKS_MASK,
+ .clksel = mcbsp_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
};
static struct clk mcspi1_ick = {
@@ -1721,6 +1752,9 @@ static struct omap_clk omap2420_clks[] = {
CLK(NULL, "osc_ck", &osc_ck, CK_242X),
CLK(NULL, "sys_ck", &sys_ck, CK_242X),
CLK(NULL, "alt_ck", &alt_ck, CK_242X),
+ CLK("omap-mcbsp.1", "pad_fck", &mcbsp_clks, CK_242X),
+ CLK("omap-mcbsp.2", "pad_fck", &mcbsp_clks, CK_242X),
+ CLK(NULL, "mcbsp_clks", &mcbsp_clks, CK_242X),
/* internal analog sources */
CLK(NULL, "dpll_ck", &dpll_ck, CK_242X),
CLK(NULL, "apll96_ck", &apll96_ck, CK_242X),
@@ -1728,6 +1762,8 @@ static struct omap_clk omap2420_clks[] = {
/* internal prcm root sources */
CLK(NULL, "func_54m_ck", &func_54m_ck, CK_242X),
CLK(NULL, "core_ck", &core_ck, CK_242X),
+ CLK("omap-mcbsp.1", "prcm_fck", &func_96m_ck, CK_242X),
+ CLK("omap-mcbsp.2", "prcm_fck", &func_96m_ck, CK_242X),
CLK(NULL, "func_96m_ck", &func_96m_ck, CK_242X),
CLK(NULL, "func_48m_ck", &func_48m_ck, CK_242X),
CLK(NULL, "func_12m_ck", &func_12m_ck, CK_242X),
@@ -1838,7 +1874,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..e32afcbdfb88 100644
--- a/arch/arm/mach-omap2/clock2430_data.c
+++ b/arch/arm/mach-omap2/clock2430_data.c
@@ -27,6 +27,7 @@
#include "prm-regbits-24xx.h"
#include "cm-regbits-24xx.h"
#include "sdrc.h"
+#include "control.h"
#define OMAP_CM_REGADDR OMAP2430_CM_REGADDR
@@ -89,6 +90,12 @@ static struct clk alt_ck = { /* Typical 54M or 48M, may not exist */
.clkdm_name = "wkup_clkdm",
};
+/* Optional external clock input for McBSP CLKS */
+static struct clk mcbsp_clks = {
+ .name = "mcbsp_clks",
+ .ops = &clkops_null,
+};
+
/*
* Analog domain root source clocks
*/
@@ -1123,14 +1130,34 @@ static struct clk mcbsp1_ick = {
.recalc = &followparent_recalc,
};
+static const struct clksel_rate common_mcbsp_96m_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate common_mcbsp_mcbsp_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel mcbsp_fck_clksel[] = {
+ { .parent = &func_96m_ck, .rates = common_mcbsp_96m_rates },
+ { .parent = &mcbsp_clks, .rates = common_mcbsp_mcbsp_rates },
+ { .parent = NULL }
+};
+
static struct clk mcbsp1_fck = {
.name = "mcbsp1_fck",
.ops = &clkops_omap2_dflt_wait,
.parent = &func_96m_ck,
+ .init = &omap2_init_clksel_parent,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_MCBSP1_SHIFT,
- .recalc = &followparent_recalc,
+ .clksel_reg = OMAP243X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
+ .clksel_mask = OMAP2_MCBSP1_CLKS_MASK,
+ .clksel = mcbsp_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
};
static struct clk mcbsp2_ick = {
@@ -1147,10 +1174,14 @@ static struct clk mcbsp2_fck = {
.name = "mcbsp2_fck",
.ops = &clkops_omap2_dflt_wait,
.parent = &func_96m_ck,
+ .init = &omap2_init_clksel_parent,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_MCBSP2_SHIFT,
- .recalc = &followparent_recalc,
+ .clksel_reg = OMAP243X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
+ .clksel_mask = OMAP2_MCBSP2_CLKS_MASK,
+ .clksel = mcbsp_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
};
static struct clk mcbsp3_ick = {
@@ -1167,10 +1198,14 @@ static struct clk mcbsp3_fck = {
.name = "mcbsp3_fck",
.ops = &clkops_omap2_dflt_wait,
.parent = &func_96m_ck,
+ .init = &omap2_init_clksel_parent,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP2430_EN_MCBSP3_SHIFT,
- .recalc = &followparent_recalc,
+ .clksel_reg = OMAP243X_CTRL_REGADDR(OMAP243X_CONTROL_DEVCONF1),
+ .clksel_mask = OMAP2_MCBSP3_CLKS_MASK,
+ .clksel = mcbsp_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
};
static struct clk mcbsp4_ick = {
@@ -1187,10 +1222,14 @@ static struct clk mcbsp4_fck = {
.name = "mcbsp4_fck",
.ops = &clkops_omap2_dflt_wait,
.parent = &func_96m_ck,
+ .init = &omap2_init_clksel_parent,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP2430_EN_MCBSP4_SHIFT,
- .recalc = &followparent_recalc,
+ .clksel_reg = OMAP243X_CTRL_REGADDR(OMAP243X_CONTROL_DEVCONF1),
+ .clksel_mask = OMAP2_MCBSP4_CLKS_MASK,
+ .clksel = mcbsp_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
};
static struct clk mcbsp5_ick = {
@@ -1207,10 +1246,14 @@ static struct clk mcbsp5_fck = {
.name = "mcbsp5_fck",
.ops = &clkops_omap2_dflt_wait,
.parent = &func_96m_ck,
+ .init = &omap2_init_clksel_parent,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP2430_EN_MCBSP5_SHIFT,
- .recalc = &followparent_recalc,
+ .clksel_reg = OMAP243X_CTRL_REGADDR(OMAP243X_CONTROL_DEVCONF1),
+ .clksel_mask = OMAP2_MCBSP5_CLKS_MASK,
+ .clksel = mcbsp_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
};
static struct clk mcspi1_ick = {
@@ -1808,6 +1851,12 @@ static struct omap_clk omap2430_clks[] = {
CLK(NULL, "osc_ck", &osc_ck, CK_243X),
CLK(NULL, "sys_ck", &sys_ck, CK_243X),
CLK(NULL, "alt_ck", &alt_ck, CK_243X),
+ CLK("omap-mcbsp.1", "pad_fck", &mcbsp_clks, CK_243X),
+ CLK("omap-mcbsp.2", "pad_fck", &mcbsp_clks, CK_243X),
+ CLK("omap-mcbsp.3", "pad_fck", &mcbsp_clks, CK_243X),
+ CLK("omap-mcbsp.4", "pad_fck", &mcbsp_clks, CK_243X),
+ CLK("omap-mcbsp.5", "pad_fck", &mcbsp_clks, CK_243X),
+ CLK(NULL, "mcbsp_clks", &mcbsp_clks, CK_243X),
/* internal analog sources */
CLK(NULL, "dpll_ck", &dpll_ck, CK_243X),
CLK(NULL, "apll96_ck", &apll96_ck, CK_243X),
@@ -1815,6 +1864,11 @@ static struct omap_clk omap2430_clks[] = {
/* internal prcm root sources */
CLK(NULL, "func_54m_ck", &func_54m_ck, CK_243X),
CLK(NULL, "core_ck", &core_ck, CK_243X),
+ CLK("omap-mcbsp.1", "prcm_fck", &func_96m_ck, CK_243X),
+ CLK("omap-mcbsp.2", "prcm_fck", &func_96m_ck, CK_243X),
+ CLK("omap-mcbsp.3", "prcm_fck", &func_96m_ck, CK_243X),
+ CLK("omap-mcbsp.4", "prcm_fck", &func_96m_ck, CK_243X),
+ CLK("omap-mcbsp.5", "prcm_fck", &func_96m_ck, CK_243X),
CLK(NULL, "func_96m_ck", &func_96m_ck, CK_243X),
CLK(NULL, "func_48m_ck", &func_48m_ck, CK_243X),
CLK(NULL, "func_12m_ck", &func_12m_ck, CK_243X),
@@ -1926,7 +1980,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..d85ecd5aebfd 100644
--- a/arch/arm/mach-omap2/clock3xxx_data.c
+++ b/arch/arm/mach-omap2/clock3xxx_data.c
@@ -20,7 +20,6 @@
#include <linux/clk.h>
#include <linux/list.h>
-#include <plat/control.h>
#include <plat/clkdev_omap.h>
#include "clock.h"
@@ -33,6 +32,7 @@
#include "cm-regbits-34xx.h"
#include "prm.h"
#include "prm-regbits-34xx.h"
+#include "control.h"
/*
* clocks
@@ -2465,6 +2465,16 @@ static struct clk uart3_fck = {
.recalc = &followparent_recalc,
};
+static struct clk uart4_fck = {
+ .name = "uart4_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &per_48m_fck,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3630_EN_UART4_SHIFT,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
static struct clk gpt2_fck = {
.name = "gpt2_fck",
.ops = &clkops_omap2_dflt_wait,
@@ -2715,6 +2725,16 @@ static struct clk uart3_ick = {
.recalc = &followparent_recalc,
};
+static struct clk uart4_ick = {
+ .name = "uart4_ick",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &per_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3630_EN_UART4_SHIFT,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
static struct clk gpt9_ick = {
.name = "gpt9_ick",
.ops = &clkops_omap2_dflt_wait,
@@ -3188,6 +3208,11 @@ static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "osc_sys_ck", &osc_sys_ck, CK_3XXX),
CLK(NULL, "sys_ck", &sys_ck, CK_3XXX),
CLK(NULL, "sys_altclk", &sys_altclk, CK_3XXX),
+ CLK("omap-mcbsp.1", "pad_fck", &mcbsp_clks, CK_3XXX),
+ CLK("omap-mcbsp.2", "pad_fck", &mcbsp_clks, CK_3XXX),
+ CLK("omap-mcbsp.3", "pad_fck", &mcbsp_clks, CK_3XXX),
+ CLK("omap-mcbsp.4", "pad_fck", &mcbsp_clks, CK_3XXX),
+ CLK("omap-mcbsp.5", "pad_fck", &mcbsp_clks, CK_3XXX),
CLK(NULL, "mcbsp_clks", &mcbsp_clks, CK_3XXX),
CLK(NULL, "sys_clkout1", &sys_clkout1, CK_3XXX),
CLK(NULL, "dpll1_ck", &dpll1_ck, CK_3XXX),
@@ -3253,6 +3278,8 @@ static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "cpefuse_fck", &cpefuse_fck, CK_3430ES2 | CK_AM35XX),
CLK(NULL, "ts_fck", &ts_fck, CK_3430ES2 | CK_AM35XX),
CLK(NULL, "usbtll_fck", &usbtll_fck, CK_3430ES2 | CK_AM35XX),
+ CLK("omap-mcbsp.1", "prcm_fck", &core_96m_fck, CK_3XXX),
+ CLK("omap-mcbsp.5", "prcm_fck", &core_96m_fck, CK_3XXX),
CLK(NULL, "core_96m_fck", &core_96m_fck, CK_3XXX),
CLK("mmci-omap-hs.2", "fck", &mmchs3_fck, CK_3430ES2 | CK_AM35XX),
CLK("mmci-omap-hs.1", "fck", &mmchs2_fck, CK_3XXX),
@@ -3288,7 +3315,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),
@@ -3346,9 +3373,13 @@ static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "omap_32ksync_ick", &omap_32ksync_ick, CK_3XXX),
CLK(NULL, "gpt12_ick", &gpt12_ick, CK_3XXX),
CLK(NULL, "gpt1_ick", &gpt1_ick, CK_3XXX),
+ CLK("omap-mcbsp.2", "prcm_fck", &per_96m_fck, CK_3XXX),
+ CLK("omap-mcbsp.3", "prcm_fck", &per_96m_fck, CK_3XXX),
+ CLK("omap-mcbsp.4", "prcm_fck", &per_96m_fck, CK_3XXX),
CLK(NULL, "per_96m_fck", &per_96m_fck, CK_3XXX),
CLK(NULL, "per_48m_fck", &per_48m_fck, CK_3XXX),
CLK(NULL, "uart3_fck", &uart3_fck, CK_3XXX),
+ CLK(NULL, "uart4_fck", &uart4_fck, CK_36XX),
CLK(NULL, "gpt2_fck", &gpt2_fck, CK_3XXX),
CLK(NULL, "gpt3_fck", &gpt3_fck, CK_3XXX),
CLK(NULL, "gpt4_fck", &gpt4_fck, CK_3XXX),
@@ -3372,6 +3403,7 @@ static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "gpio2_ick", &gpio2_ick, CK_3XXX),
CLK(NULL, "wdt3_ick", &wdt3_ick, CK_3XXX),
CLK(NULL, "uart3_ick", &uart3_ick, CK_3XXX),
+ CLK(NULL, "uart4_ick", &uart4_ick, CK_36XX),
CLK(NULL, "gpt9_ick", &gpt9_ick, CK_3XXX),
CLK(NULL, "gpt8_ick", &gpt8_ick, CK_3XXX),
CLK(NULL, "gpt7_ick", &gpt7_ick, CK_3XXX),
diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c
index e10db7a90cb2..1599836ba3d9 100644
--- a/arch/arm/mach-omap2/clock44xx_data.c
+++ b/arch/arm/mach-omap2/clock44xx_data.c
@@ -17,13 +17,15 @@
* 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.
+ *
+ * XXX Some of the ES1 clocks have been removed/changed; once support
+ * is added for discriminating clocks by ES level, these should be added back
+ * in.
*/
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/clk.h>
-
-#include <plat/control.h>
#include <plat/clkdev_omap.h>
#include "clock.h"
@@ -32,6 +34,7 @@
#include "cm-regbits-44xx.h"
#include "prm.h"
#include "prm-regbits-44xx.h"
+#include "control.h"
/* Root clocks */
@@ -175,21 +178,27 @@ static struct clk sys_clkin_ck = {
.recalc = &omap2_clksel_recalc,
};
+static struct clk tie_low_clock_ck = {
+ .name = "tie_low_clock_ck",
+ .rate = 0,
+ .ops = &clkops_null,
+};
+
static struct clk utmi_phy_clkout_ck = {
.name = "utmi_phy_clkout_ck",
- .rate = 12000000,
+ .rate = 60000000,
.ops = &clkops_null,
};
static struct clk xclk60mhsp1_ck = {
.name = "xclk60mhsp1_ck",
- .rate = 12000000,
+ .rate = 60000000,
.ops = &clkops_null,
};
static struct clk xclk60mhsp2_ck = {
.name = "xclk60mhsp2_ck",
- .rate = 12000000,
+ .rate = 60000000,
.ops = &clkops_null,
};
@@ -201,39 +210,23 @@ static struct clk xclk60motg_ck = {
/* Module clocks and DPLL outputs */
-static const struct clksel_rate div2_1to2_rates[] = {
- { .div = 1, .val = 0, .flags = RATE_IN_4430 },
- { .div = 2, .val = 1, .flags = RATE_IN_4430 },
- { .div = 0 },
-};
-
-static const struct clksel dpll_sys_ref_clk_div[] = {
- { .parent = &sys_clkin_ck, .rates = div2_1to2_rates },
+static const struct clksel abe_dpll_bypass_clk_mux_sel[] = {
+ { .parent = &sys_clkin_ck, .rates = div_1_0_rates },
+ { .parent = &sys_32k_ck, .rates = div_1_1_rates },
{ .parent = NULL },
};
-static struct clk dpll_sys_ref_clk = {
- .name = "dpll_sys_ref_clk",
+static struct clk abe_dpll_bypass_clk_mux_ck = {
+ .name = "abe_dpll_bypass_clk_mux_ck",
.parent = &sys_clkin_ck,
- .clksel = dpll_sys_ref_clk_div,
- .clksel_reg = OMAP4430_CM_DPLL_SYS_REF_CLKSEL,
- .clksel_mask = OMAP4430_CLKSEL_0_0_MASK,
.ops = &clkops_null,
- .recalc = &omap2_clksel_recalc,
- .round_rate = &omap2_clksel_round_rate,
- .set_rate = &omap2_clksel_set_rate,
-};
-
-static const struct clksel abe_dpll_refclk_mux_sel[] = {
- { .parent = &dpll_sys_ref_clk, .rates = div_1_0_rates },
- { .parent = &sys_32k_ck, .rates = div_1_1_rates },
- { .parent = NULL },
+ .recalc = &followparent_recalc,
};
static struct clk abe_dpll_refclk_mux_ck = {
.name = "abe_dpll_refclk_mux_ck",
- .parent = &dpll_sys_ref_clk,
- .clksel = abe_dpll_refclk_mux_sel,
+ .parent = &sys_clkin_ck,
+ .clksel = abe_dpll_bypass_clk_mux_sel,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP4430_CM_ABE_PLL_REF_CLKSEL,
.clksel_mask = OMAP4430_CLKSEL_0_0_MASK,
@@ -244,7 +237,7 @@ static struct clk abe_dpll_refclk_mux_ck = {
/* DPLL_ABE */
static struct dpll_data dpll_abe_dd = {
.mult_div1_reg = OMAP4430_CM_CLKSEL_DPLL_ABE,
- .clk_bypass = &sys_clkin_ck,
+ .clk_bypass = &abe_dpll_bypass_clk_mux_ck,
.clk_ref = &abe_dpll_refclk_mux_ck,
.control_reg = OMAP4430_CM_CLKMODE_DPLL_ABE,
.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
@@ -310,6 +303,12 @@ static struct clk abe_clk = {
.set_rate = &omap2_clksel_set_rate,
};
+static const struct clksel_rate div2_1to2_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_4430 },
+ { .div = 2, .val = 1, .flags = RATE_IN_4430 },
+ { .div = 0 },
+};
+
static const struct clksel aess_fclk_div[] = {
{ .parent = &abe_clk, .rates = div2_1to2_rates },
{ .parent = NULL },
@@ -380,14 +379,14 @@ static struct clk dpll_abe_m3_ck = {
};
static const struct clksel core_hsd_byp_clk_mux_sel[] = {
- { .parent = &dpll_sys_ref_clk, .rates = div_1_0_rates },
+ { .parent = &sys_clkin_ck, .rates = div_1_0_rates },
{ .parent = &dpll_abe_m3_ck, .rates = div_1_1_rates },
{ .parent = NULL },
};
static struct clk core_hsd_byp_clk_mux_ck = {
.name = "core_hsd_byp_clk_mux_ck",
- .parent = &dpll_sys_ref_clk,
+ .parent = &sys_clkin_ck,
.clksel = core_hsd_byp_clk_mux_sel,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP4430_CM_CLKSEL_DPLL_CORE,
@@ -400,7 +399,7 @@ static struct clk core_hsd_byp_clk_mux_ck = {
static struct dpll_data dpll_core_dd = {
.mult_div1_reg = OMAP4430_CM_CLKSEL_DPLL_CORE,
.clk_bypass = &core_hsd_byp_clk_mux_ck,
- .clk_ref = &dpll_sys_ref_clk,
+ .clk_ref = &sys_clkin_ck,
.control_reg = OMAP4430_CM_CLKMODE_DPLL_CORE,
.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
.autoidle_reg = OMAP4430_CM_AUTOIDLE_DPLL_CORE,
@@ -418,7 +417,7 @@ static struct dpll_data dpll_core_dd = {
static struct clk dpll_core_ck = {
.name = "dpll_core_ck",
- .parent = &dpll_sys_ref_clk,
+ .parent = &sys_clkin_ck,
.dpll_data = &dpll_core_dd,
.init = &omap2_init_dpll_parent,
.ops = &clkops_null,
@@ -596,14 +595,14 @@ static struct clk dpll_core_m7_ck = {
};
static const struct clksel iva_hsd_byp_clk_mux_sel[] = {
- { .parent = &dpll_sys_ref_clk, .rates = div_1_0_rates },
+ { .parent = &sys_clkin_ck, .rates = div_1_0_rates },
{ .parent = &div_iva_hs_clk, .rates = div_1_1_rates },
{ .parent = NULL },
};
static struct clk iva_hsd_byp_clk_mux_ck = {
.name = "iva_hsd_byp_clk_mux_ck",
- .parent = &dpll_sys_ref_clk,
+ .parent = &sys_clkin_ck,
.ops = &clkops_null,
.recalc = &followparent_recalc,
};
@@ -612,7 +611,7 @@ static struct clk iva_hsd_byp_clk_mux_ck = {
static struct dpll_data dpll_iva_dd = {
.mult_div1_reg = OMAP4430_CM_CLKSEL_DPLL_IVA,
.clk_bypass = &iva_hsd_byp_clk_mux_ck,
- .clk_ref = &dpll_sys_ref_clk,
+ .clk_ref = &sys_clkin_ck,
.control_reg = OMAP4430_CM_CLKMODE_DPLL_IVA,
.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
.autoidle_reg = OMAP4430_CM_AUTOIDLE_DPLL_IVA,
@@ -630,7 +629,7 @@ static struct dpll_data dpll_iva_dd = {
static struct clk dpll_iva_ck = {
.name = "dpll_iva_ck",
- .parent = &dpll_sys_ref_clk,
+ .parent = &sys_clkin_ck,
.dpll_data = &dpll_iva_dd,
.init = &omap2_init_dpll_parent,
.ops = &clkops_omap3_noncore_dpll_ops,
@@ -672,7 +671,7 @@ static struct clk dpll_iva_m5_ck = {
static struct dpll_data dpll_mpu_dd = {
.mult_div1_reg = OMAP4430_CM_CLKSEL_DPLL_MPU,
.clk_bypass = &div_mpu_hs_clk,
- .clk_ref = &dpll_sys_ref_clk,
+ .clk_ref = &sys_clkin_ck,
.control_reg = OMAP4430_CM_CLKMODE_DPLL_MPU,
.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
.autoidle_reg = OMAP4430_CM_AUTOIDLE_DPLL_MPU,
@@ -690,7 +689,7 @@ static struct dpll_data dpll_mpu_dd = {
static struct clk dpll_mpu_ck = {
.name = "dpll_mpu_ck",
- .parent = &dpll_sys_ref_clk,
+ .parent = &sys_clkin_ck,
.dpll_data = &dpll_mpu_dd,
.init = &omap2_init_dpll_parent,
.ops = &clkops_omap3_noncore_dpll_ops,
@@ -724,14 +723,14 @@ static struct clk per_hs_clk_div_ck = {
};
static const struct clksel per_hsd_byp_clk_mux_sel[] = {
- { .parent = &dpll_sys_ref_clk, .rates = div_1_0_rates },
+ { .parent = &sys_clkin_ck, .rates = div_1_0_rates },
{ .parent = &per_hs_clk_div_ck, .rates = div_1_1_rates },
{ .parent = NULL },
};
static struct clk per_hsd_byp_clk_mux_ck = {
.name = "per_hsd_byp_clk_mux_ck",
- .parent = &dpll_sys_ref_clk,
+ .parent = &sys_clkin_ck,
.clksel = per_hsd_byp_clk_mux_sel,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP4430_CM_CLKSEL_DPLL_PER,
@@ -744,7 +743,7 @@ static struct clk per_hsd_byp_clk_mux_ck = {
static struct dpll_data dpll_per_dd = {
.mult_div1_reg = OMAP4430_CM_CLKSEL_DPLL_PER,
.clk_bypass = &per_hsd_byp_clk_mux_ck,
- .clk_ref = &dpll_sys_ref_clk,
+ .clk_ref = &sys_clkin_ck,
.control_reg = OMAP4430_CM_CLKMODE_DPLL_PER,
.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
.autoidle_reg = OMAP4430_CM_AUTOIDLE_DPLL_PER,
@@ -762,7 +761,7 @@ static struct dpll_data dpll_per_dd = {
static struct clk dpll_per_ck = {
.name = "dpll_per_ck",
- .parent = &dpll_sys_ref_clk,
+ .parent = &sys_clkin_ck,
.dpll_data = &dpll_per_dd,
.init = &omap2_init_dpll_parent,
.ops = &clkops_omap3_noncore_dpll_ops,
@@ -858,8 +857,8 @@ static struct clk dpll_per_m7_ck = {
/* DPLL_UNIPRO */
static struct dpll_data dpll_unipro_dd = {
.mult_div1_reg = OMAP4430_CM_CLKSEL_DPLL_UNIPRO,
- .clk_bypass = &dpll_sys_ref_clk,
- .clk_ref = &dpll_sys_ref_clk,
+ .clk_bypass = &sys_clkin_ck,
+ .clk_ref = &sys_clkin_ck,
.control_reg = OMAP4430_CM_CLKMODE_DPLL_UNIPRO,
.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
.autoidle_reg = OMAP4430_CM_AUTOIDLE_DPLL_UNIPRO,
@@ -877,7 +876,7 @@ static struct dpll_data dpll_unipro_dd = {
static struct clk dpll_unipro_ck = {
.name = "dpll_unipro_ck",
- .parent = &dpll_sys_ref_clk,
+ .parent = &sys_clkin_ck,
.dpll_data = &dpll_unipro_dd,
.init = &omap2_init_dpll_parent,
.ops = &clkops_omap3_noncore_dpll_ops,
@@ -914,7 +913,8 @@ static struct clk usb_hs_clk_div_ck = {
static struct dpll_data dpll_usb_dd = {
.mult_div1_reg = OMAP4430_CM_CLKSEL_DPLL_USB,
.clk_bypass = &usb_hs_clk_div_ck,
- .clk_ref = &dpll_sys_ref_clk,
+ .flags = DPLL_J_TYPE | DPLL_NO_DCO_SEL,
+ .clk_ref = &sys_clkin_ck,
.control_reg = OMAP4430_CM_CLKMODE_DPLL_USB,
.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
.autoidle_reg = OMAP4430_CM_AUTOIDLE_DPLL_USB,
@@ -927,13 +927,12 @@ static struct dpll_data dpll_usb_dd = {
.max_multiplier = OMAP4430_MAX_DPLL_MULT,
.max_divider = OMAP4430_MAX_DPLL_DIV,
.min_divider = 1,
- .flags = DPLL_J_TYPE | DPLL_NO_DCO_SEL
};
static struct clk dpll_usb_ck = {
.name = "dpll_usb_ck",
- .parent = &dpll_sys_ref_clk,
+ .parent = &sys_clkin_ck,
.dpll_data = &dpll_usb_dd,
.init = &omap2_init_dpll_parent,
.ops = &clkops_omap3_noncore_dpll_ops,
@@ -1222,7 +1221,7 @@ static struct clk per_abe_24m_fclk = {
static const struct clksel pmd_stm_clock_mux_sel[] = {
{ .parent = &sys_clkin_ck, .rates = div_1_0_rates },
{ .parent = &dpll_core_m6_ck, .rates = div_1_1_rates },
- { .parent = &dpll_per_m7_ck, .rates = div_1_2_rates },
+ { .parent = &tie_low_clock_ck, .rates = div_1_2_rates },
{ .parent = NULL },
};
@@ -1240,10 +1239,15 @@ static struct clk pmd_trace_clk_mux_ck = {
.recalc = &followparent_recalc,
};
+static const struct clksel syc_clk_div_div[] = {
+ { .parent = &sys_clkin_ck, .rates = div2_1to2_rates },
+ { .parent = NULL },
+};
+
static struct clk syc_clk_div_ck = {
.name = "syc_clk_div_ck",
.parent = &sys_clkin_ck,
- .clksel = dpll_sys_ref_clk_div,
+ .clksel = syc_clk_div_div,
.clksel_reg = OMAP4430_CM_ABE_DSS_SYS_CLKSEL,
.clksel_mask = OMAP4430_CLKSEL_0_0_MASK,
.ops = &clkops_null,
@@ -1284,13 +1288,13 @@ static struct clk aess_fck = {
.recalc = &followparent_recalc,
};
-static struct clk cust_efuse_fck = {
- .name = "cust_efuse_fck",
+static struct clk bandgap_fclk = {
+ .name = "bandgap_fclk",
.ops = &clkops_omap2_dflt,
- .enable_reg = OMAP4430_CM_CEFUSE_CEFUSE_CLKCTRL,
- .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
- .clkdm_name = "l4_cefuse_clkdm",
- .parent = &sys_clkin_ck,
+ .enable_reg = OMAP4430_CM_WKUP_BANDGAP_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_BGAP_32K_SHIFT,
+ .clkdm_name = "l4_wkup_clkdm",
+ .parent = &sys_32k_ck,
.recalc = &followparent_recalc,
};
@@ -1344,6 +1348,56 @@ static struct clk dmic_fck = {
.clkdm_name = "abe_clkdm",
};
+static struct clk dsp_fck = {
+ .name = "dsp_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_TESLA_TESLA_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .clkdm_name = "tesla_clkdm",
+ .parent = &dpll_iva_m4_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk dss_sys_clk = {
+ .name = "dss_sys_clk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_SYS_CLK_SHIFT,
+ .clkdm_name = "l3_dss_clkdm",
+ .parent = &syc_clk_div_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk dss_tv_clk = {
+ .name = "dss_tv_clk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_TV_CLK_SHIFT,
+ .clkdm_name = "l3_dss_clkdm",
+ .parent = &extalt_clkin_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk dss_dss_clk = {
+ .name = "dss_dss_clk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_DSSCLK_SHIFT,
+ .clkdm_name = "l3_dss_clkdm",
+ .parent = &dpll_per_m5_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk dss_48mhz_clk = {
+ .name = "dss_48mhz_clk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_48MHZ_CLK_SHIFT,
+ .clkdm_name = "l3_dss_clkdm",
+ .parent = &func_48mc_fclk,
+ .recalc = &followparent_recalc,
+};
+
static struct clk dss_fck = {
.name = "dss_fck",
.ops = &clkops_omap2_dflt,
@@ -1354,18 +1408,18 @@ static struct clk dss_fck = {
.recalc = &followparent_recalc,
};
-static struct clk ducati_ick = {
- .name = "ducati_ick",
+static struct clk efuse_ctrl_cust_fck = {
+ .name = "efuse_ctrl_cust_fck",
.ops = &clkops_omap2_dflt,
- .enable_reg = OMAP4430_CM_DUCATI_DUCATI_CLKCTRL,
- .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
- .clkdm_name = "ducati_clkdm",
- .parent = &ducati_clk_mux_ck,
+ .enable_reg = OMAP4430_CM_CEFUSE_CEFUSE_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_cefuse_clkdm",
+ .parent = &sys_clkin_ck,
.recalc = &followparent_recalc,
};
-static struct clk emif1_ick = {
- .name = "emif1_ick",
+static struct clk emif1_fck = {
+ .name = "emif1_fck",
.ops = &clkops_omap2_dflt,
.enable_reg = OMAP4430_CM_MEMIF_EMIF_1_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
@@ -1375,8 +1429,8 @@ static struct clk emif1_ick = {
.recalc = &followparent_recalc,
};
-static struct clk emif2_ick = {
- .name = "emif2_ick",
+static struct clk emif2_fck = {
+ .name = "emif2_fck",
.ops = &clkops_omap2_dflt,
.enable_reg = OMAP4430_CM_MEMIF_EMIF_2_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
@@ -1407,42 +1461,24 @@ static struct clk fdif_fck = {
.clkdm_name = "iss_clkdm",
};
-static const struct clksel per_sgx_fclk_div[] = {
- { .parent = &dpll_per_m2x2_ck, .rates = div3_1to4_rates },
- { .parent = NULL },
-};
-
-static struct clk per_sgx_fclk = {
- .name = "per_sgx_fclk",
- .parent = &dpll_per_m2x2_ck,
- .clksel = per_sgx_fclk_div,
- .clksel_reg = OMAP4430_CM_GFX_GFX_CLKCTRL,
- .clksel_mask = OMAP4430_CLKSEL_PER_192M_MASK,
- .ops = &clkops_null,
- .recalc = &omap2_clksel_recalc,
- .round_rate = &omap2_clksel_round_rate,
- .set_rate = &omap2_clksel_set_rate,
-};
-
-static const struct clksel sgx_clk_mux_sel[] = {
- { .parent = &dpll_core_m7_ck, .rates = div_1_0_rates },
- { .parent = &per_sgx_fclk, .rates = div_1_1_rates },
- { .parent = NULL },
+static struct clk fpka_fck = {
+ .name = "fpka_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4SEC_PKAEIP29_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_secure_clkdm",
+ .parent = &l4_div_ck,
+ .recalc = &followparent_recalc,
};
-/* Merged sgx_clk_mux into gfx */
-static struct clk gfx_fck = {
- .name = "gfx_fck",
- .parent = &dpll_core_m7_ck,
- .clksel = sgx_clk_mux_sel,
- .init = &omap2_init_clksel_parent,
- .clksel_reg = OMAP4430_CM_GFX_GFX_CLKCTRL,
- .clksel_mask = OMAP4430_CLKSEL_SGX_FCLK_MASK,
+static struct clk gpio1_dbclk = {
+ .name = "gpio1_dbclk",
.ops = &clkops_omap2_dflt,
- .recalc = &omap2_clksel_recalc,
- .enable_reg = OMAP4430_CM_GFX_GFX_CLKCTRL,
- .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
- .clkdm_name = "l3_gfx_clkdm",
+ .enable_reg = OMAP4430_CM_WKUP_GPIO1_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
+ .clkdm_name = "l4_wkup_clkdm",
+ .parent = &sys_32k_ck,
+ .recalc = &followparent_recalc,
};
static struct clk gpio1_ick = {
@@ -1455,6 +1491,16 @@ static struct clk gpio1_ick = {
.recalc = &followparent_recalc,
};
+static struct clk gpio2_dbclk = {
+ .name = "gpio2_dbclk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_GPIO2_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &sys_32k_ck,
+ .recalc = &followparent_recalc,
+};
+
static struct clk gpio2_ick = {
.name = "gpio2_ick",
.ops = &clkops_omap2_dflt,
@@ -1465,6 +1511,16 @@ static struct clk gpio2_ick = {
.recalc = &followparent_recalc,
};
+static struct clk gpio3_dbclk = {
+ .name = "gpio3_dbclk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_GPIO3_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &sys_32k_ck,
+ .recalc = &followparent_recalc,
+};
+
static struct clk gpio3_ick = {
.name = "gpio3_ick",
.ops = &clkops_omap2_dflt,
@@ -1475,6 +1531,16 @@ static struct clk gpio3_ick = {
.recalc = &followparent_recalc,
};
+static struct clk gpio4_dbclk = {
+ .name = "gpio4_dbclk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_GPIO4_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &sys_32k_ck,
+ .recalc = &followparent_recalc,
+};
+
static struct clk gpio4_ick = {
.name = "gpio4_ick",
.ops = &clkops_omap2_dflt,
@@ -1485,6 +1551,16 @@ static struct clk gpio4_ick = {
.recalc = &followparent_recalc,
};
+static struct clk gpio5_dbclk = {
+ .name = "gpio5_dbclk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_GPIO5_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &sys_32k_ck,
+ .recalc = &followparent_recalc,
+};
+
static struct clk gpio5_ick = {
.name = "gpio5_ick",
.ops = &clkops_omap2_dflt,
@@ -1495,6 +1571,16 @@ static struct clk gpio5_ick = {
.recalc = &followparent_recalc,
};
+static struct clk gpio6_dbclk = {
+ .name = "gpio6_dbclk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_GPIO6_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &sys_32k_ck,
+ .recalc = &followparent_recalc,
+};
+
static struct clk gpio6_ick = {
.name = "gpio6_ick",
.ops = &clkops_omap2_dflt,
@@ -1515,214 +1601,25 @@ static struct clk gpmc_ick = {
.recalc = &followparent_recalc,
};
-static const struct clksel dmt1_clk_mux_sel[] = {
- { .parent = &sys_clkin_ck, .rates = div_1_0_rates },
- { .parent = &sys_32k_ck, .rates = div_1_1_rates },
- { .parent = NULL },
-};
-
-/*
- * Merged dmt1_clk_mux into gptimer1
- * gptimer1 renamed temporarily into gpt1 to match OMAP3 convention
- */
-static struct clk gpt1_fck = {
- .name = "gpt1_fck",
- .parent = &sys_clkin_ck,
- .clksel = dmt1_clk_mux_sel,
- .init = &omap2_init_clksel_parent,
- .clksel_reg = OMAP4430_CM_WKUP_TIMER1_CLKCTRL,
- .clksel_mask = OMAP4430_CLKSEL_MASK,
- .ops = &clkops_omap2_dflt,
- .recalc = &omap2_clksel_recalc,
- .enable_reg = OMAP4430_CM_WKUP_TIMER1_CLKCTRL,
- .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
- .clkdm_name = "l4_wkup_clkdm",
-};
-
-/*
- * Merged cm2_dm10_mux into gptimer10
- * gptimer10 renamed temporarily into gpt10 to match OMAP3 convention
- */
-static struct clk gpt10_fck = {
- .name = "gpt10_fck",
- .parent = &sys_clkin_ck,
- .clksel = dmt1_clk_mux_sel,
- .init = &omap2_init_clksel_parent,
- .clksel_reg = OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL,
- .clksel_mask = OMAP4430_CLKSEL_MASK,
- .ops = &clkops_omap2_dflt,
- .recalc = &omap2_clksel_recalc,
- .enable_reg = OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL,
- .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
- .clkdm_name = "l4_per_clkdm",
-};
-
-/*
- * Merged cm2_dm11_mux into gptimer11
- * gptimer11 renamed temporarily into gpt11 to match OMAP3 convention
- */
-static struct clk gpt11_fck = {
- .name = "gpt11_fck",
- .parent = &sys_clkin_ck,
- .clksel = dmt1_clk_mux_sel,
- .init = &omap2_init_clksel_parent,
- .clksel_reg = OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL,
- .clksel_mask = OMAP4430_CLKSEL_MASK,
- .ops = &clkops_omap2_dflt,
- .recalc = &omap2_clksel_recalc,
- .enable_reg = OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL,
- .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
- .clkdm_name = "l4_per_clkdm",
-};
-
-/*
- * Merged cm2_dm2_mux into gptimer2
- * gptimer2 renamed temporarily into gpt2 to match OMAP3 convention
- */
-static struct clk gpt2_fck = {
- .name = "gpt2_fck",
- .parent = &sys_clkin_ck,
- .clksel = dmt1_clk_mux_sel,
- .init = &omap2_init_clksel_parent,
- .clksel_reg = OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL,
- .clksel_mask = OMAP4430_CLKSEL_MASK,
- .ops = &clkops_omap2_dflt,
- .recalc = &omap2_clksel_recalc,
- .enable_reg = OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL,
- .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
- .clkdm_name = "l4_per_clkdm",
-};
-
-/*
- * Merged cm2_dm3_mux into gptimer3
- * gptimer3 renamed temporarily into gpt3 to match OMAP3 convention
- */
-static struct clk gpt3_fck = {
- .name = "gpt3_fck",
- .parent = &sys_clkin_ck,
- .clksel = dmt1_clk_mux_sel,
- .init = &omap2_init_clksel_parent,
- .clksel_reg = OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL,
- .clksel_mask = OMAP4430_CLKSEL_MASK,
- .ops = &clkops_omap2_dflt,
- .recalc = &omap2_clksel_recalc,
- .enable_reg = OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL,
- .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
- .clkdm_name = "l4_per_clkdm",
-};
-
-/*
- * Merged cm2_dm4_mux into gptimer4
- * gptimer4 renamed temporarily into gpt4 to match OMAP3 convention
- */
-static struct clk gpt4_fck = {
- .name = "gpt4_fck",
- .parent = &sys_clkin_ck,
- .clksel = dmt1_clk_mux_sel,
- .init = &omap2_init_clksel_parent,
- .clksel_reg = OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL,
- .clksel_mask = OMAP4430_CLKSEL_MASK,
- .ops = &clkops_omap2_dflt,
- .recalc = &omap2_clksel_recalc,
- .enable_reg = OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL,
- .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
- .clkdm_name = "l4_per_clkdm",
-};
-
-static const struct clksel timer5_sync_mux_sel[] = {
- { .parent = &syc_clk_div_ck, .rates = div_1_0_rates },
- { .parent = &sys_32k_ck, .rates = div_1_1_rates },
+static const struct clksel sgx_clk_mux_sel[] = {
+ { .parent = &dpll_core_m7_ck, .rates = div_1_0_rates },
+ { .parent = &dpll_per_m7_ck, .rates = div_1_1_rates },
{ .parent = NULL },
};
-/*
- * Merged timer5_sync_mux into gptimer5
- * gptimer5 renamed temporarily into gpt5 to match OMAP3 convention
- */
-static struct clk gpt5_fck = {
- .name = "gpt5_fck",
- .parent = &syc_clk_div_ck,
- .clksel = timer5_sync_mux_sel,
- .init = &omap2_init_clksel_parent,
- .clksel_reg = OMAP4430_CM1_ABE_TIMER5_CLKCTRL,
- .clksel_mask = OMAP4430_CLKSEL_MASK,
- .ops = &clkops_omap2_dflt,
- .recalc = &omap2_clksel_recalc,
- .enable_reg = OMAP4430_CM1_ABE_TIMER5_CLKCTRL,
- .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
- .clkdm_name = "abe_clkdm",
-};
-
-/*
- * Merged timer6_sync_mux into gptimer6
- * gptimer6 renamed temporarily into gpt6 to match OMAP3 convention
- */
-static struct clk gpt6_fck = {
- .name = "gpt6_fck",
- .parent = &syc_clk_div_ck,
- .clksel = timer5_sync_mux_sel,
- .init = &omap2_init_clksel_parent,
- .clksel_reg = OMAP4430_CM1_ABE_TIMER6_CLKCTRL,
- .clksel_mask = OMAP4430_CLKSEL_MASK,
- .ops = &clkops_omap2_dflt,
- .recalc = &omap2_clksel_recalc,
- .enable_reg = OMAP4430_CM1_ABE_TIMER6_CLKCTRL,
- .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
- .clkdm_name = "abe_clkdm",
-};
-
-/*
- * Merged timer7_sync_mux into gptimer7
- * gptimer7 renamed temporarily into gpt7 to match OMAP3 convention
- */
-static struct clk gpt7_fck = {
- .name = "gpt7_fck",
- .parent = &syc_clk_div_ck,
- .clksel = timer5_sync_mux_sel,
- .init = &omap2_init_clksel_parent,
- .clksel_reg = OMAP4430_CM1_ABE_TIMER7_CLKCTRL,
- .clksel_mask = OMAP4430_CLKSEL_MASK,
- .ops = &clkops_omap2_dflt,
- .recalc = &omap2_clksel_recalc,
- .enable_reg = OMAP4430_CM1_ABE_TIMER7_CLKCTRL,
- .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
- .clkdm_name = "abe_clkdm",
-};
-
-/*
- * Merged timer8_sync_mux into gptimer8
- * gptimer8 renamed temporarily into gpt8 to match OMAP3 convention
- */
-static struct clk gpt8_fck = {
- .name = "gpt8_fck",
- .parent = &syc_clk_div_ck,
- .clksel = timer5_sync_mux_sel,
- .init = &omap2_init_clksel_parent,
- .clksel_reg = OMAP4430_CM1_ABE_TIMER8_CLKCTRL,
- .clksel_mask = OMAP4430_CLKSEL_MASK,
- .ops = &clkops_omap2_dflt,
- .recalc = &omap2_clksel_recalc,
- .enable_reg = OMAP4430_CM1_ABE_TIMER8_CLKCTRL,
- .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
- .clkdm_name = "abe_clkdm",
-};
-
-/*
- * Merged cm2_dm9_mux into gptimer9
- * gptimer9 renamed temporarily into gpt9 to match OMAP3 convention
- */
-static struct clk gpt9_fck = {
- .name = "gpt9_fck",
- .parent = &sys_clkin_ck,
- .clksel = dmt1_clk_mux_sel,
+/* Merged sgx_clk_mux into gpu */
+static struct clk gpu_fck = {
+ .name = "gpu_fck",
+ .parent = &dpll_core_m7_ck,
+ .clksel = sgx_clk_mux_sel,
.init = &omap2_init_clksel_parent,
- .clksel_reg = OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL,
- .clksel_mask = OMAP4430_CLKSEL_MASK,
+ .clksel_reg = OMAP4430_CM_GFX_GFX_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_SGX_FCLK_MASK,
.ops = &clkops_omap2_dflt,
.recalc = &omap2_clksel_recalc,
- .enable_reg = OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL,
+ .enable_reg = OMAP4430_CM_GFX_GFX_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
- .clkdm_name = "l4_per_clkdm",
+ .clkdm_name = "l3_gfx_clkdm",
};
static struct clk hdq1w_fck = {
@@ -1735,11 +1632,16 @@ static struct clk hdq1w_fck = {
.recalc = &followparent_recalc,
};
+static const struct clksel hsi_fclk_div[] = {
+ { .parent = &dpll_per_m2x2_ck, .rates = div3_1to4_rates },
+ { .parent = NULL },
+};
+
/* Merged hsi_fclk into hsi */
-static struct clk hsi_ick = {
- .name = "hsi_ick",
+static struct clk hsi_fck = {
+ .name = "hsi_fck",
.parent = &dpll_per_m2x2_ck,
- .clksel = per_sgx_fclk_div,
+ .clksel = hsi_fclk_div,
.clksel_reg = OMAP4430_CM_L3INIT_HSI_CLKCTRL,
.clksel_mask = OMAP4430_CLKSEL_24_25_MASK,
.ops = &clkops_omap2_dflt,
@@ -1791,6 +1693,26 @@ static struct clk i2c4_fck = {
.recalc = &followparent_recalc,
};
+static struct clk ipu_fck = {
+ .name = "ipu_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_DUCATI_DUCATI_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .clkdm_name = "ducati_clkdm",
+ .parent = &ducati_clk_mux_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk iss_ctrlclk = {
+ .name = "iss_ctrlclk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_CAM_ISS_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_CTRLCLK_SHIFT,
+ .clkdm_name = "iss_clkdm",
+ .parent = &func_96m_fclk,
+ .recalc = &followparent_recalc,
+};
+
static struct clk iss_fck = {
.name = "iss_fck",
.ops = &clkops_omap2_dflt,
@@ -1801,8 +1723,8 @@ static struct clk iss_fck = {
.recalc = &followparent_recalc,
};
-static struct clk ivahd_ick = {
- .name = "ivahd_ick",
+static struct clk iva_fck = {
+ .name = "iva_fck",
.ops = &clkops_omap2_dflt,
.enable_reg = OMAP4430_CM_IVAHD_IVAHD_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
@@ -1811,8 +1733,8 @@ static struct clk ivahd_ick = {
.recalc = &followparent_recalc,
};
-static struct clk keyboard_fck = {
- .name = "keyboard_fck",
+static struct clk kbd_fck = {
+ .name = "kbd_fck",
.ops = &clkops_omap2_dflt,
.enable_reg = OMAP4430_CM_WKUP_KEYBOARD_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
@@ -1821,8 +1743,8 @@ static struct clk keyboard_fck = {
.recalc = &followparent_recalc,
};
-static struct clk l3_instr_interconnect_ick = {
- .name = "l3_instr_interconnect_ick",
+static struct clk l3_instr_ick = {
+ .name = "l3_instr_ick",
.ops = &clkops_omap2_dflt,
.enable_reg = OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
@@ -1831,8 +1753,8 @@ static struct clk l3_instr_interconnect_ick = {
.recalc = &followparent_recalc,
};
-static struct clk l3_interconnect_3_ick = {
- .name = "l3_interconnect_3_ick",
+static struct clk l3_main_3_ick = {
+ .name = "l3_main_3_ick",
.ops = &clkops_omap2_dflt,
.enable_reg = OMAP4430_CM_L3INSTR_L3_3_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
@@ -2005,6 +1927,16 @@ static struct clk mcbsp4_fck = {
.clkdm_name = "l4_per_clkdm",
};
+static struct clk mcpdm_fck = {
+ .name = "mcpdm_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM1_ABE_PDM_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "abe_clkdm",
+ .parent = &pad_clks_ck,
+ .recalc = &followparent_recalc,
+};
+
static struct clk mcspi1_fck = {
.name = "mcspi1_fck",
.ops = &clkops_omap2_dflt,
@@ -2105,33 +2037,33 @@ static struct clk mmc5_fck = {
.recalc = &followparent_recalc,
};
-static struct clk ocp_wp1_ick = {
- .name = "ocp_wp1_ick",
+static struct clk ocp2scp_usb_phy_phy_48m = {
+ .name = "ocp2scp_usb_phy_phy_48m",
.ops = &clkops_omap2_dflt,
- .enable_reg = OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL,
- .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
- .clkdm_name = "l3_instr_clkdm",
- .parent = &l3_div_ck,
+ .enable_reg = OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_PHY_48M_SHIFT,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &func_48m_fclk,
.recalc = &followparent_recalc,
};
-static struct clk pdm_fck = {
- .name = "pdm_fck",
+static struct clk ocp2scp_usb_phy_ick = {
+ .name = "ocp2scp_usb_phy_ick",
.ops = &clkops_omap2_dflt,
- .enable_reg = OMAP4430_CM1_ABE_PDM_CLKCTRL,
- .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
- .clkdm_name = "abe_clkdm",
- .parent = &pad_clks_ck,
+ .enable_reg = OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &l4_div_ck,
.recalc = &followparent_recalc,
};
-static struct clk pkaeip29_fck = {
- .name = "pkaeip29_fck",
+static struct clk ocp_wp_noc_ick = {
+ .name = "ocp_wp_noc_ick",
.ops = &clkops_omap2_dflt,
- .enable_reg = OMAP4430_CM_L4SEC_PKAEIP29_CLKCTRL,
- .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
- .clkdm_name = "l4_secure_clkdm",
- .parent = &l4_div_ck,
+ .enable_reg = OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .clkdm_name = "l3_instr_clkdm",
+ .parent = &l3_div_ck,
.recalc = &followparent_recalc,
};
@@ -2145,8 +2077,8 @@ static struct clk rng_ick = {
.recalc = &followparent_recalc,
};
-static struct clk sha2md51_fck = {
- .name = "sha2md51_fck",
+static struct clk sha2md5_fck = {
+ .name = "sha2md5_fck",
.ops = &clkops_omap2_dflt,
.enable_reg = OMAP4430_CM_L4SEC_SHA2MD51_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
@@ -2155,8 +2087,8 @@ static struct clk sha2md51_fck = {
.recalc = &followparent_recalc,
};
-static struct clk sl2_ick = {
- .name = "sl2_ick",
+static struct clk sl2if_ick = {
+ .name = "sl2if_ick",
.ops = &clkops_omap2_dflt,
.enable_reg = OMAP4430_CM_IVAHD_SL2_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
@@ -2165,6 +2097,46 @@ static struct clk sl2_ick = {
.recalc = &followparent_recalc,
};
+static struct clk slimbus1_fclk_1 = {
+ .name = "slimbus1_fclk_1",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_FCLK1_SHIFT,
+ .clkdm_name = "abe_clkdm",
+ .parent = &func_24m_clk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk slimbus1_fclk_0 = {
+ .name = "slimbus1_fclk_0",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_FCLK0_SHIFT,
+ .clkdm_name = "abe_clkdm",
+ .parent = &abe_24m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk slimbus1_fclk_2 = {
+ .name = "slimbus1_fclk_2",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_FCLK2_SHIFT,
+ .clkdm_name = "abe_clkdm",
+ .parent = &pad_clks_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk slimbus1_slimbus_clk = {
+ .name = "slimbus1_slimbus_clk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_SLIMBUS_CLK_11_11_SHIFT,
+ .clkdm_name = "abe_clkdm",
+ .parent = &slimbus_clk,
+ .recalc = &followparent_recalc,
+};
+
static struct clk slimbus1_fck = {
.name = "slimbus1_fck",
.ops = &clkops_omap2_dflt,
@@ -2175,6 +2147,36 @@ static struct clk slimbus1_fck = {
.recalc = &followparent_recalc,
};
+static struct clk slimbus2_fclk_1 = {
+ .name = "slimbus2_fclk_1",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_PERABE24M_GFCLK_SHIFT,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &per_abe_24m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk slimbus2_fclk_0 = {
+ .name = "slimbus2_fclk_0",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_PER24MC_GFCLK_SHIFT,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &func_24mc_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk slimbus2_slimbus_clk = {
+ .name = "slimbus2_slimbus_clk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_SLIMBUS_CLK_SHIFT,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &pad_slimbus_core_clks_ck,
+ .recalc = &followparent_recalc,
+};
+
static struct clk slimbus2_fck = {
.name = "slimbus2_fck",
.ops = &clkops_omap2_dflt,
@@ -2185,8 +2187,8 @@ static struct clk slimbus2_fck = {
.recalc = &followparent_recalc,
};
-static struct clk sr_core_fck = {
- .name = "sr_core_fck",
+static struct clk smartreflex_core_fck = {
+ .name = "smartreflex_core_fck",
.ops = &clkops_omap2_dflt,
.enable_reg = OMAP4430_CM_ALWON_SR_CORE_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
@@ -2195,8 +2197,8 @@ static struct clk sr_core_fck = {
.recalc = &followparent_recalc,
};
-static struct clk sr_iva_fck = {
- .name = "sr_iva_fck",
+static struct clk smartreflex_iva_fck = {
+ .name = "smartreflex_iva_fck",
.ops = &clkops_omap2_dflt,
.enable_reg = OMAP4430_CM_ALWON_SR_IVA_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
@@ -2205,8 +2207,8 @@ static struct clk sr_iva_fck = {
.recalc = &followparent_recalc,
};
-static struct clk sr_mpu_fck = {
- .name = "sr_mpu_fck",
+static struct clk smartreflex_mpu_fck = {
+ .name = "smartreflex_mpu_fck",
.ops = &clkops_omap2_dflt,
.enable_reg = OMAP4430_CM_ALWON_SR_MPU_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
@@ -2215,14 +2217,175 @@ static struct clk sr_mpu_fck = {
.recalc = &followparent_recalc,
};
-static struct clk tesla_ick = {
- .name = "tesla_ick",
+/* Merged dmt1_clk_mux into timer1 */
+static struct clk timer1_fck = {
+ .name = "timer1_fck",
+ .parent = &sys_clkin_ck,
+ .clksel = abe_dpll_bypass_clk_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_WKUP_TIMER1_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_MASK,
.ops = &clkops_omap2_dflt,
- .enable_reg = OMAP4430_CM_TESLA_TESLA_CLKCTRL,
- .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
- .clkdm_name = "tesla_clkdm",
- .parent = &dpll_iva_m4_ck,
- .recalc = &followparent_recalc,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM_WKUP_TIMER1_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_wkup_clkdm",
+};
+
+/* Merged cm2_dm10_mux into timer10 */
+static struct clk timer10_fck = {
+ .name = "timer10_fck",
+ .parent = &sys_clkin_ck,
+ .clksel = abe_dpll_bypass_clk_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+};
+
+/* Merged cm2_dm11_mux into timer11 */
+static struct clk timer11_fck = {
+ .name = "timer11_fck",
+ .parent = &sys_clkin_ck,
+ .clksel = abe_dpll_bypass_clk_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+};
+
+/* Merged cm2_dm2_mux into timer2 */
+static struct clk timer2_fck = {
+ .name = "timer2_fck",
+ .parent = &sys_clkin_ck,
+ .clksel = abe_dpll_bypass_clk_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+};
+
+/* Merged cm2_dm3_mux into timer3 */
+static struct clk timer3_fck = {
+ .name = "timer3_fck",
+ .parent = &sys_clkin_ck,
+ .clksel = abe_dpll_bypass_clk_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+};
+
+/* Merged cm2_dm4_mux into timer4 */
+static struct clk timer4_fck = {
+ .name = "timer4_fck",
+ .parent = &sys_clkin_ck,
+ .clksel = abe_dpll_bypass_clk_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+};
+
+static const struct clksel timer5_sync_mux_sel[] = {
+ { .parent = &syc_clk_div_ck, .rates = div_1_0_rates },
+ { .parent = &sys_32k_ck, .rates = div_1_1_rates },
+ { .parent = NULL },
+};
+
+/* Merged timer5_sync_mux into timer5 */
+static struct clk timer5_fck = {
+ .name = "timer5_fck",
+ .parent = &syc_clk_div_ck,
+ .clksel = timer5_sync_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM1_ABE_TIMER5_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM1_ABE_TIMER5_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "abe_clkdm",
+};
+
+/* Merged timer6_sync_mux into timer6 */
+static struct clk timer6_fck = {
+ .name = "timer6_fck",
+ .parent = &syc_clk_div_ck,
+ .clksel = timer5_sync_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM1_ABE_TIMER6_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM1_ABE_TIMER6_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "abe_clkdm",
+};
+
+/* Merged timer7_sync_mux into timer7 */
+static struct clk timer7_fck = {
+ .name = "timer7_fck",
+ .parent = &syc_clk_div_ck,
+ .clksel = timer5_sync_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM1_ABE_TIMER7_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM1_ABE_TIMER7_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "abe_clkdm",
+};
+
+/* Merged timer8_sync_mux into timer8 */
+static struct clk timer8_fck = {
+ .name = "timer8_fck",
+ .parent = &syc_clk_div_ck,
+ .clksel = timer5_sync_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM1_ABE_TIMER8_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM1_ABE_TIMER8_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "abe_clkdm",
+};
+
+/* Merged cm2_dm9_mux into timer9 */
+static struct clk timer9_fck = {
+ .name = "timer9_fck",
+ .parent = &sys_clkin_ck,
+ .clksel = abe_dpll_bypass_clk_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
};
static struct clk uart1_fck = {
@@ -2265,105 +2428,148 @@ static struct clk uart4_fck = {
.recalc = &followparent_recalc,
};
-static struct clk unipro1_fck = {
- .name = "unipro1_fck",
+static struct clk usb_host_fs_fck = {
+ .name = "usb_host_fs_fck",
.ops = &clkops_omap2_dflt,
- .enable_reg = OMAP4430_CM_L3INIT_UNIPRO1_CLKCTRL,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_HOST_FS_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
.clkdm_name = "l3_init_clkdm",
- .parent = &func_96m_fclk,
+ .parent = &func_48mc_fclk,
.recalc = &followparent_recalc,
};
-static struct clk usb_host_fck = {
- .name = "usb_host_fck",
+static struct clk usb_host_hs_utmi_p3_clk = {
+ .name = "usb_host_hs_utmi_p3_clk",
.ops = &clkops_omap2_dflt,
.enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
- .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_UTMI_P3_CLK_SHIFT,
.clkdm_name = "l3_init_clkdm",
.parent = &init_60m_fclk,
.recalc = &followparent_recalc,
};
-static struct clk usb_host_fs_fck = {
- .name = "usb_host_fs_fck",
+static struct clk usb_host_hs_hsic60m_p1_clk = {
+ .name = "usb_host_hs_hsic60m_p1_clk",
.ops = &clkops_omap2_dflt,
- .enable_reg = OMAP4430_CM_L3INIT_USB_HOST_FS_CLKCTRL,
- .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_HSIC60M_P1_CLK_SHIFT,
.clkdm_name = "l3_init_clkdm",
- .parent = &func_48mc_fclk,
+ .parent = &init_60m_fclk,
.recalc = &followparent_recalc,
};
-static struct clk usb_otg_ick = {
- .name = "usb_otg_ick",
+static struct clk usb_host_hs_hsic60m_p2_clk = {
+ .name = "usb_host_hs_hsic60m_p2_clk",
.ops = &clkops_omap2_dflt,
- .enable_reg = OMAP4430_CM_L3INIT_USB_OTG_CLKCTRL,
- .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_HSIC60M_P2_CLK_SHIFT,
.clkdm_name = "l3_init_clkdm",
- .parent = &l3_div_ck,
+ .parent = &init_60m_fclk,
.recalc = &followparent_recalc,
};
-static struct clk usb_tll_ick = {
- .name = "usb_tll_ick",
+static const struct clksel utmi_p1_gfclk_sel[] = {
+ { .parent = &init_60m_fclk, .rates = div_1_0_rates },
+ { .parent = &xclk60mhsp1_ck, .rates = div_1_1_rates },
+ { .parent = NULL },
+};
+
+static struct clk utmi_p1_gfclk = {
+ .name = "utmi_p1_gfclk",
+ .parent = &init_60m_fclk,
+ .clksel = utmi_p1_gfclk_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_UTMI_P1_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk usb_host_hs_utmi_p1_clk = {
+ .name = "usb_host_hs_utmi_p1_clk",
.ops = &clkops_omap2_dflt,
- .enable_reg = OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL,
- .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_UTMI_P1_CLK_SHIFT,
.clkdm_name = "l3_init_clkdm",
- .parent = &l4_div_ck,
+ .parent = &utmi_p1_gfclk,
.recalc = &followparent_recalc,
};
-static struct clk usbphyocp2scp_ick = {
- .name = "usbphyocp2scp_ick",
+static const struct clksel utmi_p2_gfclk_sel[] = {
+ { .parent = &init_60m_fclk, .rates = div_1_0_rates },
+ { .parent = &xclk60mhsp2_ck, .rates = div_1_1_rates },
+ { .parent = NULL },
+};
+
+static struct clk utmi_p2_gfclk = {
+ .name = "utmi_p2_gfclk",
+ .parent = &init_60m_fclk,
+ .clksel = utmi_p2_gfclk_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_UTMI_P2_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk usb_host_hs_utmi_p2_clk = {
+ .name = "usb_host_hs_utmi_p2_clk",
.ops = &clkops_omap2_dflt,
- .enable_reg = OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL,
- .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_UTMI_P2_CLK_SHIFT,
.clkdm_name = "l3_init_clkdm",
- .parent = &l4_div_ck,
+ .parent = &utmi_p2_gfclk,
.recalc = &followparent_recalc,
};
-static struct clk usim_fck = {
- .name = "usim_fck",
+static struct clk usb_host_hs_hsic480m_p1_clk = {
+ .name = "usb_host_hs_hsic480m_p1_clk",
.ops = &clkops_omap2_dflt,
- .enable_reg = OMAP4430_CM_WKUP_USIM_CLKCTRL,
- .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
- .clkdm_name = "l4_wkup_clkdm",
- .parent = &sys_32k_ck,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_HSIC480M_P1_CLK_SHIFT,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &dpll_usb_m2_ck,
.recalc = &followparent_recalc,
};
-static struct clk wdt2_fck = {
- .name = "wdt2_fck",
+static struct clk usb_host_hs_hsic480m_p2_clk = {
+ .name = "usb_host_hs_hsic480m_p2_clk",
.ops = &clkops_omap2_dflt,
- .enable_reg = OMAP4430_CM_WKUP_WDT2_CLKCTRL,
- .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
- .clkdm_name = "l4_wkup_clkdm",
- .parent = &sys_32k_ck,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_HSIC480M_P2_CLK_SHIFT,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &dpll_usb_m2_ck,
.recalc = &followparent_recalc,
};
-static struct clk wdt3_fck = {
- .name = "wdt3_fck",
+static struct clk usb_host_hs_func48mclk = {
+ .name = "usb_host_hs_func48mclk",
.ops = &clkops_omap2_dflt,
- .enable_reg = OMAP4430_CM1_ABE_WDT3_CLKCTRL,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_FUNC48MCLK_SHIFT,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &func_48mc_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk usb_host_hs_fck = {
+ .name = "usb_host_hs_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_SWCTRL,
- .clkdm_name = "abe_clkdm",
- .parent = &sys_32k_ck,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &init_60m_fclk,
.recalc = &followparent_recalc,
};
-/* Remaining optional clocks */
static const struct clksel otg_60m_gfclk_sel[] = {
{ .parent = &utmi_phy_clkout_ck, .rates = div_1_0_rates },
{ .parent = &xclk60motg_ck, .rates = div_1_1_rates },
{ .parent = NULL },
};
-static struct clk otg_60m_gfclk_ck = {
- .name = "otg_60m_gfclk_ck",
+static struct clk otg_60m_gfclk = {
+ .name = "otg_60m_gfclk",
.parent = &utmi_phy_clkout_ck,
.clksel = otg_60m_gfclk_sel,
.init = &omap2_init_clksel_parent,
@@ -2373,38 +2579,74 @@ static struct clk otg_60m_gfclk_ck = {
.recalc = &omap2_clksel_recalc,
};
-static const struct clksel stm_clk_div_div[] = {
- { .parent = &pmd_stm_clock_mux_ck, .rates = div3_1to4_rates },
- { .parent = NULL },
+static struct clk usb_otg_hs_xclk = {
+ .name = "usb_otg_hs_xclk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_OTG_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_XCLK_SHIFT,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &otg_60m_gfclk,
+ .recalc = &followparent_recalc,
};
-static struct clk stm_clk_div_ck = {
- .name = "stm_clk_div_ck",
- .parent = &pmd_stm_clock_mux_ck,
- .clksel = stm_clk_div_div,
- .clksel_reg = OMAP4430_CM_EMU_DEBUGSS_CLKCTRL,
- .clksel_mask = OMAP4430_CLKSEL_PMD_STM_CLK_MASK,
- .ops = &clkops_null,
- .recalc = &omap2_clksel_recalc,
- .round_rate = &omap2_clksel_round_rate,
- .set_rate = &omap2_clksel_set_rate,
+static struct clk usb_otg_hs_ick = {
+ .name = "usb_otg_hs_ick",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_OTG_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &l3_div_ck,
+ .recalc = &followparent_recalc,
};
-static const struct clksel trace_clk_div_div[] = {
- { .parent = &pmd_trace_clk_mux_ck, .rates = div3_1to4_rates },
- { .parent = NULL },
+static struct clk usb_phy_cm_clk32k = {
+ .name = "usb_phy_cm_clk32k",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_ALWON_USBPHY_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_CLK32K_SHIFT,
+ .clkdm_name = "l4_ao_clkdm",
+ .parent = &sys_32k_ck,
+ .recalc = &followparent_recalc,
};
-static struct clk trace_clk_div_ck = {
- .name = "trace_clk_div_ck",
- .parent = &pmd_trace_clk_mux_ck,
- .clksel = trace_clk_div_div,
- .clksel_reg = OMAP4430_CM_EMU_DEBUGSS_CLKCTRL,
- .clksel_mask = OMAP4430_CLKSEL_PMD_TRACE_CLK_MASK,
- .ops = &clkops_null,
- .recalc = &omap2_clksel_recalc,
- .round_rate = &omap2_clksel_round_rate,
- .set_rate = &omap2_clksel_set_rate,
+static struct clk usb_tll_hs_usb_ch2_clk = {
+ .name = "usb_tll_hs_usb_ch2_clk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_USB_CH2_CLK_SHIFT,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &init_60m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk usb_tll_hs_usb_ch0_clk = {
+ .name = "usb_tll_hs_usb_ch0_clk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_USB_CH0_CLK_SHIFT,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &init_60m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk usb_tll_hs_usb_ch1_clk = {
+ .name = "usb_tll_hs_usb_ch1_clk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_USB_CH1_CLK_SHIFT,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &init_60m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk usb_tll_hs_ick = {
+ .name = "usb_tll_hs_ick",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &l4_div_ck,
+ .recalc = &followparent_recalc,
};
static const struct clksel_rate div2_14to18_rates[] = {
@@ -2418,8 +2660,8 @@ static const struct clksel usim_fclk_div[] = {
{ .parent = NULL },
};
-static struct clk usim_fclk = {
- .name = "usim_fclk",
+static struct clk usim_ck = {
+ .name = "usim_ck",
.parent = &dpll_per_m4_ck,
.clksel = usim_fclk_div,
.clksel_reg = OMAP4430_CM_WKUP_USIM_CLKCTRL,
@@ -2430,38 +2672,79 @@ static struct clk usim_fclk = {
.set_rate = &omap2_clksel_set_rate,
};
-static const struct clksel utmi_p1_gfclk_sel[] = {
- { .parent = &init_60m_fclk, .rates = div_1_0_rates },
- { .parent = &xclk60mhsp1_ck, .rates = div_1_1_rates },
+static struct clk usim_fclk = {
+ .name = "usim_fclk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_WKUP_USIM_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_FCLK_SHIFT,
+ .clkdm_name = "l4_wkup_clkdm",
+ .parent = &usim_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk usim_fck = {
+ .name = "usim_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_WKUP_USIM_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .clkdm_name = "l4_wkup_clkdm",
+ .parent = &sys_32k_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk wd_timer2_fck = {
+ .name = "wd_timer2_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_WKUP_WDT2_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_wkup_clkdm",
+ .parent = &sys_32k_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk wd_timer3_fck = {
+ .name = "wd_timer3_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM1_ABE_WDT3_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "abe_clkdm",
+ .parent = &sys_32k_ck,
+ .recalc = &followparent_recalc,
+};
+
+/* Remaining optional clocks */
+static const struct clksel stm_clk_div_div[] = {
+ { .parent = &pmd_stm_clock_mux_ck, .rates = div3_1to4_rates },
{ .parent = NULL },
};
-static struct clk utmi_p1_gfclk_ck = {
- .name = "utmi_p1_gfclk_ck",
- .parent = &init_60m_fclk,
- .clksel = utmi_p1_gfclk_sel,
- .init = &omap2_init_clksel_parent,
- .clksel_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
- .clksel_mask = OMAP4430_CLKSEL_UTMI_P1_MASK,
+static struct clk stm_clk_div_ck = {
+ .name = "stm_clk_div_ck",
+ .parent = &pmd_stm_clock_mux_ck,
+ .clksel = stm_clk_div_div,
+ .clksel_reg = OMAP4430_CM_EMU_DEBUGSS_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_PMD_STM_CLK_MASK,
.ops = &clkops_null,
.recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
};
-static const struct clksel utmi_p2_gfclk_sel[] = {
- { .parent = &init_60m_fclk, .rates = div_1_0_rates },
- { .parent = &xclk60mhsp2_ck, .rates = div_1_1_rates },
+static const struct clksel trace_clk_div_div[] = {
+ { .parent = &pmd_trace_clk_mux_ck, .rates = div3_1to4_rates },
{ .parent = NULL },
};
-static struct clk utmi_p2_gfclk_ck = {
- .name = "utmi_p2_gfclk_ck",
- .parent = &init_60m_fclk,
- .clksel = utmi_p2_gfclk_sel,
- .init = &omap2_init_clksel_parent,
- .clksel_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
- .clksel_mask = OMAP4430_CLKSEL_UTMI_P2_MASK,
+static struct clk trace_clk_div_ck = {
+ .name = "trace_clk_div_ck",
+ .parent = &pmd_trace_clk_mux_ck,
+ .clksel = trace_clk_div_div,
+ .clksel_reg = OMAP4430_CM_EMU_DEBUGSS_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_PMD_TRACE_CLK_MASK,
.ops = &clkops_null,
.recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
};
/*
@@ -2483,11 +2766,12 @@ static struct omap_clk omap44xx_clks[] = {
CLK(NULL, "virt_27000000_ck", &virt_27000000_ck, CK_443X),
CLK(NULL, "virt_38400000_ck", &virt_38400000_ck, CK_443X),
CLK(NULL, "sys_clkin_ck", &sys_clkin_ck, CK_443X),
+ CLK(NULL, "tie_low_clock_ck", &tie_low_clock_ck, CK_443X),
CLK(NULL, "utmi_phy_clkout_ck", &utmi_phy_clkout_ck, CK_443X),
CLK(NULL, "xclk60mhsp1_ck", &xclk60mhsp1_ck, CK_443X),
CLK(NULL, "xclk60mhsp2_ck", &xclk60mhsp2_ck, CK_443X),
CLK(NULL, "xclk60motg_ck", &xclk60motg_ck, CK_443X),
- CLK(NULL, "dpll_sys_ref_clk", &dpll_sys_ref_clk, CK_443X),
+ CLK(NULL, "abe_dpll_bypass_clk_mux_ck", &abe_dpll_bypass_clk_mux_ck, CK_443X),
CLK(NULL, "abe_dpll_refclk_mux_ck", &abe_dpll_refclk_mux_ck, CK_443X),
CLK(NULL, "dpll_abe_ck", &dpll_abe_ck, CK_443X),
CLK(NULL, "dpll_abe_m2x2_ck", &dpll_abe_m2x2_ck, CK_443X),
@@ -2557,46 +2841,48 @@ static struct omap_clk omap44xx_clks[] = {
CLK(NULL, "aes1_fck", &aes1_fck, CK_443X),
CLK(NULL, "aes2_fck", &aes2_fck, CK_443X),
CLK(NULL, "aess_fck", &aess_fck, CK_443X),
- CLK(NULL, "cust_efuse_fck", &cust_efuse_fck, CK_443X),
+ CLK(NULL, "bandgap_fclk", &bandgap_fclk, CK_443X),
CLK(NULL, "des3des_fck", &des3des_fck, CK_443X),
CLK(NULL, "dmic_sync_mux_ck", &dmic_sync_mux_ck, CK_443X),
CLK(NULL, "dmic_fck", &dmic_fck, CK_443X),
+ CLK(NULL, "dsp_fck", &dsp_fck, CK_443X),
+ CLK(NULL, "dss_sys_clk", &dss_sys_clk, CK_443X),
+ CLK(NULL, "dss_tv_clk", &dss_tv_clk, CK_443X),
+ CLK(NULL, "dss_dss_clk", &dss_dss_clk, CK_443X),
+ CLK(NULL, "dss_48mhz_clk", &dss_48mhz_clk, CK_443X),
CLK(NULL, "dss_fck", &dss_fck, CK_443X),
- CLK(NULL, "ducati_ick", &ducati_ick, CK_443X),
- CLK(NULL, "emif1_ick", &emif1_ick, CK_443X),
- CLK(NULL, "emif2_ick", &emif2_ick, CK_443X),
+ CLK(NULL, "efuse_ctrl_cust_fck", &efuse_ctrl_cust_fck, CK_443X),
+ CLK(NULL, "emif1_fck", &emif1_fck, CK_443X),
+ CLK(NULL, "emif2_fck", &emif2_fck, CK_443X),
CLK(NULL, "fdif_fck", &fdif_fck, CK_443X),
- CLK(NULL, "per_sgx_fclk", &per_sgx_fclk, CK_443X),
- CLK(NULL, "gfx_fck", &gfx_fck, CK_443X),
+ CLK(NULL, "fpka_fck", &fpka_fck, CK_443X),
+ CLK(NULL, "gpio1_dbck", &gpio1_dbclk, CK_443X),
CLK(NULL, "gpio1_ick", &gpio1_ick, CK_443X),
+ CLK(NULL, "gpio2_dbck", &gpio2_dbclk, CK_443X),
CLK(NULL, "gpio2_ick", &gpio2_ick, CK_443X),
+ CLK(NULL, "gpio3_dbck", &gpio3_dbclk, CK_443X),
CLK(NULL, "gpio3_ick", &gpio3_ick, CK_443X),
+ CLK(NULL, "gpio4_dbck", &gpio4_dbclk, CK_443X),
CLK(NULL, "gpio4_ick", &gpio4_ick, CK_443X),
+ CLK(NULL, "gpio5_dbck", &gpio5_dbclk, CK_443X),
CLK(NULL, "gpio5_ick", &gpio5_ick, CK_443X),
+ CLK(NULL, "gpio6_dbck", &gpio6_dbclk, CK_443X),
CLK(NULL, "gpio6_ick", &gpio6_ick, CK_443X),
CLK(NULL, "gpmc_ick", &gpmc_ick, CK_443X),
- CLK(NULL, "gpt1_fck", &gpt1_fck, CK_443X),
- CLK(NULL, "gpt10_fck", &gpt10_fck, CK_443X),
- CLK(NULL, "gpt11_fck", &gpt11_fck, CK_443X),
- CLK(NULL, "gpt2_fck", &gpt2_fck, CK_443X),
- CLK(NULL, "gpt3_fck", &gpt3_fck, CK_443X),
- CLK(NULL, "gpt4_fck", &gpt4_fck, CK_443X),
- CLK(NULL, "gpt5_fck", &gpt5_fck, CK_443X),
- CLK(NULL, "gpt6_fck", &gpt6_fck, CK_443X),
- CLK(NULL, "gpt7_fck", &gpt7_fck, CK_443X),
- CLK(NULL, "gpt8_fck", &gpt8_fck, CK_443X),
- CLK(NULL, "gpt9_fck", &gpt9_fck, CK_443X),
+ CLK(NULL, "gpu_fck", &gpu_fck, CK_443X),
CLK("omap2_hdq.0", "fck", &hdq1w_fck, CK_443X),
- CLK(NULL, "hsi_ick", &hsi_ick, CK_443X),
+ CLK(NULL, "hsi_fck", &hsi_fck, CK_443X),
CLK("i2c_omap.1", "fck", &i2c1_fck, CK_443X),
CLK("i2c_omap.2", "fck", &i2c2_fck, CK_443X),
CLK("i2c_omap.3", "fck", &i2c3_fck, CK_443X),
CLK("i2c_omap.4", "fck", &i2c4_fck, CK_443X),
+ CLK(NULL, "ipu_fck", &ipu_fck, CK_443X),
+ CLK(NULL, "iss_ctrlclk", &iss_ctrlclk, CK_443X),
CLK(NULL, "iss_fck", &iss_fck, CK_443X),
- CLK(NULL, "ivahd_ick", &ivahd_ick, CK_443X),
- CLK(NULL, "keyboard_fck", &keyboard_fck, CK_443X),
- CLK(NULL, "l3_instr_interconnect_ick", &l3_instr_interconnect_ick, CK_443X),
- CLK(NULL, "l3_interconnect_3_ick", &l3_interconnect_3_ick, CK_443X),
+ CLK(NULL, "iva_fck", &iva_fck, CK_443X),
+ CLK(NULL, "kbd_fck", &kbd_fck, CK_443X),
+ CLK(NULL, "l3_instr_ick", &l3_instr_ick, CK_443X),
+ CLK(NULL, "l3_main_3_ick", &l3_main_3_ick, CK_443X),
CLK(NULL, "mcasp_sync_mux_ck", &mcasp_sync_mux_ck, CK_443X),
CLK(NULL, "mcasp_fck", &mcasp_fck, CK_443X),
CLK(NULL, "mcbsp1_sync_mux_ck", &mcbsp1_sync_mux_ck, CK_443X),
@@ -2607,6 +2893,7 @@ static struct omap_clk omap44xx_clks[] = {
CLK("omap-mcbsp.3", "fck", &mcbsp3_fck, CK_443X),
CLK(NULL, "mcbsp4_sync_mux_ck", &mcbsp4_sync_mux_ck, CK_443X),
CLK("omap-mcbsp.4", "fck", &mcbsp4_fck, CK_443X),
+ CLK(NULL, "mcpdm_fck", &mcpdm_fck, CK_443X),
CLK("omap2_mcspi.1", "fck", &mcspi1_fck, CK_443X),
CLK("omap2_mcspi.2", "fck", &mcspi2_fck, CK_443X),
CLK("omap2_mcspi.3", "fck", &mcspi3_fck, CK_443X),
@@ -2616,43 +2903,66 @@ static struct omap_clk omap44xx_clks[] = {
CLK("mmci-omap-hs.2", "fck", &mmc3_fck, CK_443X),
CLK("mmci-omap-hs.3", "fck", &mmc4_fck, CK_443X),
CLK("mmci-omap-hs.4", "fck", &mmc5_fck, CK_443X),
- CLK(NULL, "ocp_wp1_ick", &ocp_wp1_ick, CK_443X),
- CLK(NULL, "pdm_fck", &pdm_fck, CK_443X),
- CLK(NULL, "pkaeip29_fck", &pkaeip29_fck, CK_443X),
+ CLK(NULL, "ocp2scp_usb_phy_phy_48m", &ocp2scp_usb_phy_phy_48m, CK_443X),
+ CLK(NULL, "ocp2scp_usb_phy_ick", &ocp2scp_usb_phy_ick, CK_443X),
+ CLK(NULL, "ocp_wp_noc_ick", &ocp_wp_noc_ick, CK_443X),
CLK("omap_rng", "ick", &rng_ick, CK_443X),
- CLK(NULL, "sha2md51_fck", &sha2md51_fck, CK_443X),
- CLK(NULL, "sl2_ick", &sl2_ick, CK_443X),
+ CLK(NULL, "sha2md5_fck", &sha2md5_fck, CK_443X),
+ CLK(NULL, "sl2if_ick", &sl2if_ick, CK_443X),
+ CLK(NULL, "slimbus1_fclk_1", &slimbus1_fclk_1, CK_443X),
+ CLK(NULL, "slimbus1_fclk_0", &slimbus1_fclk_0, CK_443X),
+ CLK(NULL, "slimbus1_fclk_2", &slimbus1_fclk_2, CK_443X),
+ CLK(NULL, "slimbus1_slimbus_clk", &slimbus1_slimbus_clk, CK_443X),
CLK(NULL, "slimbus1_fck", &slimbus1_fck, CK_443X),
+ CLK(NULL, "slimbus2_fclk_1", &slimbus2_fclk_1, CK_443X),
+ CLK(NULL, "slimbus2_fclk_0", &slimbus2_fclk_0, CK_443X),
+ CLK(NULL, "slimbus2_slimbus_clk", &slimbus2_slimbus_clk, CK_443X),
CLK(NULL, "slimbus2_fck", &slimbus2_fck, CK_443X),
- CLK(NULL, "sr_core_fck", &sr_core_fck, CK_443X),
- CLK(NULL, "sr_iva_fck", &sr_iva_fck, CK_443X),
- CLK(NULL, "sr_mpu_fck", &sr_mpu_fck, CK_443X),
- CLK(NULL, "tesla_ick", &tesla_ick, CK_443X),
+ CLK(NULL, "smartreflex_core_fck", &smartreflex_core_fck, CK_443X),
+ CLK(NULL, "smartreflex_iva_fck", &smartreflex_iva_fck, CK_443X),
+ CLK(NULL, "smartreflex_mpu_fck", &smartreflex_mpu_fck, CK_443X),
+ CLK(NULL, "gpt1_fck", &timer1_fck, CK_443X),
+ CLK(NULL, "gpt10_fck", &timer10_fck, CK_443X),
+ CLK(NULL, "gpt11_fck", &timer11_fck, CK_443X),
+ CLK(NULL, "gpt2_fck", &timer2_fck, CK_443X),
+ CLK(NULL, "gpt3_fck", &timer3_fck, CK_443X),
+ CLK(NULL, "gpt4_fck", &timer4_fck, CK_443X),
+ CLK(NULL, "gpt5_fck", &timer5_fck, CK_443X),
+ CLK(NULL, "gpt6_fck", &timer6_fck, CK_443X),
+ CLK(NULL, "gpt7_fck", &timer7_fck, CK_443X),
+ CLK(NULL, "gpt8_fck", &timer8_fck, CK_443X),
+ CLK(NULL, "gpt9_fck", &timer9_fck, CK_443X),
CLK(NULL, "uart1_fck", &uart1_fck, CK_443X),
CLK(NULL, "uart2_fck", &uart2_fck, CK_443X),
CLK(NULL, "uart3_fck", &uart3_fck, CK_443X),
CLK(NULL, "uart4_fck", &uart4_fck, CK_443X),
- CLK(NULL, "unipro1_fck", &unipro1_fck, CK_443X),
- CLK(NULL, "usb_host_fck", &usb_host_fck, CK_443X),
CLK(NULL, "usb_host_fs_fck", &usb_host_fs_fck, CK_443X),
- CLK("musb_hdrc", "ick", &usb_otg_ick, CK_443X),
- CLK(NULL, "usb_tll_ick", &usb_tll_ick, CK_443X),
- CLK(NULL, "usbphyocp2scp_ick", &usbphyocp2scp_ick, CK_443X),
+ CLK(NULL, "usb_host_hs_utmi_p3_clk", &usb_host_hs_utmi_p3_clk, CK_443X),
+ CLK(NULL, "usb_host_hs_hsic60m_p1_clk", &usb_host_hs_hsic60m_p1_clk, CK_443X),
+ CLK(NULL, "usb_host_hs_hsic60m_p2_clk", &usb_host_hs_hsic60m_p2_clk, CK_443X),
+ CLK(NULL, "utmi_p1_gfclk", &utmi_p1_gfclk, CK_443X),
+ CLK(NULL, "usb_host_hs_utmi_p1_clk", &usb_host_hs_utmi_p1_clk, CK_443X),
+ CLK(NULL, "utmi_p2_gfclk", &utmi_p2_gfclk, CK_443X),
+ CLK(NULL, "usb_host_hs_utmi_p2_clk", &usb_host_hs_utmi_p2_clk, CK_443X),
+ CLK(NULL, "usb_host_hs_hsic480m_p1_clk", &usb_host_hs_hsic480m_p1_clk, CK_443X),
+ CLK(NULL, "usb_host_hs_hsic480m_p2_clk", &usb_host_hs_hsic480m_p2_clk, CK_443X),
+ CLK(NULL, "usb_host_hs_func48mclk", &usb_host_hs_func48mclk, CK_443X),
+ CLK(NULL, "usb_host_hs_fck", &usb_host_hs_fck, CK_443X),
+ CLK(NULL, "otg_60m_gfclk", &otg_60m_gfclk, CK_443X),
+ CLK(NULL, "usb_otg_hs_xclk", &usb_otg_hs_xclk, CK_443X),
+ CLK("musb_hdrc", "ick", &usb_otg_hs_ick, CK_443X),
+ CLK(NULL, "usb_phy_cm_clk32k", &usb_phy_cm_clk32k, CK_443X),
+ CLK(NULL, "usb_tll_hs_usb_ch2_clk", &usb_tll_hs_usb_ch2_clk, CK_443X),
+ CLK(NULL, "usb_tll_hs_usb_ch0_clk", &usb_tll_hs_usb_ch0_clk, CK_443X),
+ CLK(NULL, "usb_tll_hs_usb_ch1_clk", &usb_tll_hs_usb_ch1_clk, CK_443X),
+ CLK(NULL, "usb_tll_hs_ick", &usb_tll_hs_ick, CK_443X),
+ CLK(NULL, "usim_ck", &usim_ck, CK_443X),
+ CLK(NULL, "usim_fclk", &usim_fclk, CK_443X),
CLK(NULL, "usim_fck", &usim_fck, CK_443X),
- CLK("omap_wdt", "fck", &wdt2_fck, CK_443X),
- CLK(NULL, "wdt3_fck", &wdt3_fck, CK_443X),
- CLK(NULL, "otg_60m_gfclk_ck", &otg_60m_gfclk_ck, CK_443X),
+ CLK("omap_wdt", "fck", &wd_timer2_fck, CK_443X),
+ CLK(NULL, "wd_timer3_fck", &wd_timer3_fck, CK_443X),
CLK(NULL, "stm_clk_div_ck", &stm_clk_div_ck, CK_443X),
CLK(NULL, "trace_clk_div_ck", &trace_clk_div_ck, CK_443X),
- CLK(NULL, "usim_fclk", &usim_fclk, CK_443X),
- CLK(NULL, "utmi_p1_gfclk_ck", &utmi_p1_gfclk_ck, CK_443X),
- CLK(NULL, "utmi_p2_gfclk_ck", &utmi_p2_gfclk_ck, CK_443X),
- CLK(NULL, "gpio1_dbck", &dummy_ck, CK_443X),
- CLK(NULL, "gpio2_dbck", &dummy_ck, CK_443X),
- CLK(NULL, "gpio3_dbck", &dummy_ck, CK_443X),
- CLK(NULL, "gpio4_dbck", &dummy_ck, CK_443X),
- CLK(NULL, "gpio5_dbck", &dummy_ck, CK_443X),
- CLK(NULL, "gpio6_dbck", &dummy_ck, CK_443X),
CLK(NULL, "gpmc_ck", &dummy_ck, CK_443X),
CLK(NULL, "gpt1_ick", &dummy_ck, CK_443X),
CLK(NULL, "gpt2_ick", &dummy_ck, CK_443X),
@@ -2669,19 +2979,19 @@ static struct omap_clk omap44xx_clks[] = {
CLK("i2c_omap.2", "ick", &dummy_ck, CK_443X),
CLK("i2c_omap.3", "ick", &dummy_ck, CK_443X),
CLK("i2c_omap.4", "ick", &dummy_ck, CK_443X),
+ CLK("mmci-omap-hs.0", "ick", &dummy_ck, CK_443X),
+ CLK("mmci-omap-hs.1", "ick", &dummy_ck, CK_443X),
+ CLK("mmci-omap-hs.2", "ick", &dummy_ck, CK_443X),
+ CLK("mmci-omap-hs.3", "ick", &dummy_ck, CK_443X),
+ CLK("mmci-omap-hs.4", "ick", &dummy_ck, CK_443X),
CLK("omap-mcbsp.1", "ick", &dummy_ck, CK_443X),
CLK("omap-mcbsp.2", "ick", &dummy_ck, CK_443X),
CLK("omap-mcbsp.3", "ick", &dummy_ck, CK_443X),
CLK("omap-mcbsp.4", "ick", &dummy_ck, CK_443X),
- CLK("omap2_mcspi.1", "ick", &dummy_ck, CK_443X),
- CLK("omap2_mcspi.2", "ick", &dummy_ck, CK_443X),
- CLK("omap2_mcspi.3", "ick", &dummy_ck, CK_443X),
- CLK("omap2_mcspi.4", "ick", &dummy_ck, CK_443X),
- CLK("mmci-omap-hs.0", "ick", &dummy_ck, CK_443X),
- CLK("mmci-omap-hs.1", "ick", &dummy_ck, CK_443X),
- CLK("mmci-omap-hs.2", "ick", &dummy_ck, CK_443X),
- CLK("mmci-omap-hs.3", "ick", &dummy_ck, CK_443X),
- CLK("mmci-omap-hs.4", "ick", &dummy_ck, CK_443X),
+ CLK("omap2_mcspi.1", "ick", &dummy_ck, CK_443X),
+ CLK("omap2_mcspi.2", "ick", &dummy_ck, CK_443X),
+ CLK("omap2_mcspi.3", "ick", &dummy_ck, CK_443X),
+ CLK("omap2_mcspi.4", "ick", &dummy_ck, CK_443X),
CLK(NULL, "uart1_ick", &dummy_ck, CK_443X),
CLK(NULL, "uart2_ick", &dummy_ck, CK_443X),
CLK(NULL, "uart3_ick", &dummy_ck, CK_443X),
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index 5d80cb897489..6fb61b1a0d46 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -258,97 +258,6 @@ static void _omap2_clkdm_set_hwsup(struct clockdomain *clkdm, int enable)
}
-/**
- * _init_wkdep_usecount - initialize wkdep usecounts to match hardware
- * @clkdm: clockdomain to initialize wkdep usecounts
- *
- * Initialize the wakeup dependency usecount variables for clockdomain @clkdm.
- * If a wakeup dependency is present in the hardware, the usecount will be
- * set to 1; otherwise, it will be set to 0. Software should clear all
- * software wakeup dependencies prior to calling this function if it wishes
- * to ensure that all usecounts start at 0. No return value.
- */
-static void _init_wkdep_usecount(struct clockdomain *clkdm)
-{
- u32 v;
- struct clkdm_dep *cd;
-
- if (!clkdm->wkdep_srcs)
- return;
-
- for (cd = clkdm->wkdep_srcs; cd->clkdm_name; cd++) {
- if (!omap_chip_is(cd->omap_chip))
- continue;
-
- if (!cd->clkdm && cd->clkdm_name)
- cd->clkdm = _clkdm_lookup(cd->clkdm_name);
-
- if (!cd->clkdm) {
- WARN(!cd->clkdm, "clockdomain: %s: wkdep clkdm %s not "
- "found\n", clkdm->name, cd->clkdm_name);
- continue;
- }
-
- v = prm_read_mod_bits_shift(clkdm->pwrdm.ptr->prcm_offs,
- PM_WKDEP,
- (1 << cd->clkdm->dep_bit));
-
- if (v)
- pr_debug("clockdomain: %s: wakeup dependency already "
- "set to wake up when %s wakes\n",
- clkdm->name, cd->clkdm->name);
-
- atomic_set(&cd->wkdep_usecount, (v) ? 1 : 0);
- }
-}
-
-/**
- * _init_sleepdep_usecount - initialize sleepdep usecounts to match hardware
- * @clkdm: clockdomain to initialize sleepdep usecounts
- *
- * Initialize the sleep dependency usecount variables for clockdomain @clkdm.
- * If a sleep dependency is present in the hardware, the usecount will be
- * set to 1; otherwise, it will be set to 0. Software should clear all
- * software sleep dependencies prior to calling this function if it wishes
- * to ensure that all usecounts start at 0. No return value.
- */
-static void _init_sleepdep_usecount(struct clockdomain *clkdm)
-{
- u32 v;
- struct clkdm_dep *cd;
-
- if (!cpu_is_omap34xx())
- return;
-
- if (!clkdm->sleepdep_srcs)
- return;
-
- for (cd = clkdm->sleepdep_srcs; cd->clkdm_name; cd++) {
- if (!omap_chip_is(cd->omap_chip))
- continue;
-
- if (!cd->clkdm && cd->clkdm_name)
- cd->clkdm = _clkdm_lookup(cd->clkdm_name);
-
- if (!cd->clkdm) {
- WARN(!cd->clkdm, "clockdomain: %s: sleepdep clkdm %s "
- "not found\n", clkdm->name, cd->clkdm_name);
- continue;
- }
-
- v = prm_read_mod_bits_shift(clkdm->pwrdm.ptr->prcm_offs,
- OMAP3430_CM_SLEEPDEP,
- (1 << cd->clkdm->dep_bit));
-
- if (v)
- pr_debug("clockdomain: %s: sleep dependency already "
- "set to prevent from idling until %s "
- "idles\n", clkdm->name, cd->clkdm->name);
-
- atomic_set(&cd->sleepdep_usecount, (v) ? 1 : 0);
- }
-};
-
/* Public functions */
/**
@@ -379,12 +288,17 @@ void clkdm_init(struct clockdomain **clkdms,
_autodep_lookup(autodep);
/*
- * Ensure that the *dep_usecount registers reflect the current
- * state of the PRCM.
+ * Put all clockdomains into software-supervised mode; PM code
+ * should later enable hardware-supervised mode as appropriate
*/
list_for_each_entry(clkdm, &clkdm_list, node) {
- _init_wkdep_usecount(clkdm);
- _init_sleepdep_usecount(clkdm);
+ if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
+ omap2_clkdm_wakeup(clkdm);
+ else if (clkdm->flags & CLKDM_CAN_DISABLE_AUTO)
+ omap2_clkdm_deny_idle(clkdm);
+
+ clkdm_clear_all_wkdeps(clkdm);
+ clkdm_clear_all_sleepdeps(clkdm);
}
}
@@ -592,6 +506,9 @@ int clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
if (!omap_chip_is(cd->omap_chip))
continue;
+ if (!cd->clkdm && cd->clkdm_name)
+ cd->clkdm = _clkdm_lookup(cd->clkdm_name);
+
/* PRM accesses are slow, so minimize them */
mask |= 1 << cd->clkdm->dep_bit;
atomic_set(&cd->wkdep_usecount, 0);
@@ -752,6 +669,9 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
if (!omap_chip_is(cd->omap_chip))
continue;
+ if (!cd->clkdm && cd->clkdm_name)
+ cd->clkdm = _clkdm_lookup(cd->clkdm_name);
+
/* PRM accesses are slow, so minimize them */
mask |= 1 << cd->clkdm->dep_bit;
atomic_set(&cd->sleepdep_usecount, 0);
diff --git a/arch/arm/mach-omap2/cm-regbits-34xx.h b/arch/arm/mach-omap2/cm-regbits-34xx.h
index fe82b79d5f3b..4f959a7d881c 100644
--- a/arch/arm/mach-omap2/cm-regbits-34xx.h
+++ b/arch/arm/mach-omap2/cm-regbits-34xx.h
@@ -649,6 +649,8 @@
#define OMAP3430_ST_MCBSP2_MASK (1 << 0)
/* CM_AUTOIDLE_PER */
+#define OMAP3630_AUTO_UART4_MASK (1 << 18)
+#define OMAP3630_AUTO_UART4_SHIFT 18
#define OMAP3430_AUTO_GPIO6_MASK (1 << 17)
#define OMAP3430_AUTO_GPIO6_SHIFT 17
#define OMAP3430_AUTO_GPIO5_MASK (1 << 16)
diff --git a/arch/arm/mach-omap2/cm-regbits-44xx.h b/arch/arm/mach-omap2/cm-regbits-44xx.h
index ac8458e43252..0b72be433776 100644
--- a/arch/arm/mach-omap2/cm-regbits-44xx.h
+++ b/arch/arm/mach-omap2/cm-regbits-44xx.h
@@ -1,8 +1,8 @@
/*
* OMAP44xx Clock Management register bits
*
- * Copyright (C) 2009 Texas Instruments, Inc.
- * Copyright (C) 2009 Nokia Corporation
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ * Copyright (C) 2009-2010 Nokia Corporation
*
* Paul Walmsley (paul@pwsan.com)
* Rajendra Nayak (rnayak@ti.com)
@@ -25,453 +25,459 @@
#include "cm.h"
-/* Used by CM_L3_1_DYNAMICDEP, CM_MPU_DYNAMICDEP, CM_TESLA_DYNAMICDEP */
+/*
+ * Used by CM_L3_1_DYNAMICDEP, CM_L3_1_DYNAMICDEP_RESTORE, CM_MPU_DYNAMICDEP,
+ * CM_TESLA_DYNAMICDEP
+ */
#define OMAP4430_ABE_DYNDEP_SHIFT 3
-#define OMAP4430_ABE_DYNDEP_MASK BITFIELD(3, 3)
+#define OMAP4430_ABE_DYNDEP_MASK (1 << 3)
/*
- * Used by CM_D2D_STATICDEP, CM_DUCATI_STATICDEP, CM_SDMA_STATICDEP,
- * CM_L3INIT_STATICDEP, CM_SDMA_STATICDEP_RESTORE, CM_MPU_STATICDEP,
- * CM_TESLA_STATICDEP
+ * Used by CM_D2D_STATICDEP, CM_D2D_STATICDEP_RESTORE, CM_DUCATI_STATICDEP,
+ * CM_L3INIT_STATICDEP, CM_MPU_STATICDEP, CM_SDMA_STATICDEP,
+ * CM_SDMA_STATICDEP_RESTORE, CM_TESLA_STATICDEP
*/
#define OMAP4430_ABE_STATDEP_SHIFT 3
-#define OMAP4430_ABE_STATDEP_MASK BITFIELD(3, 3)
+#define OMAP4430_ABE_STATDEP_MASK (1 << 3)
-/* Used by CM_L4CFG_DYNAMICDEP */
+/* Used by CM_L4CFG_DYNAMICDEP, CM_L4CFG_DYNAMICDEP_RESTORE */
#define OMAP4430_ALWONCORE_DYNDEP_SHIFT 16
-#define OMAP4430_ALWONCORE_DYNDEP_MASK BITFIELD(16, 16)
+#define OMAP4430_ALWONCORE_DYNDEP_MASK (1 << 16)
/* Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP, CM_TESLA_STATICDEP */
#define OMAP4430_ALWONCORE_STATDEP_SHIFT 16
-#define OMAP4430_ALWONCORE_STATDEP_MASK BITFIELD(16, 16)
+#define OMAP4430_ALWONCORE_STATDEP_MASK (1 << 16)
/*
- * Used by CM_AUTOIDLE_DPLL_PER, CM_AUTOIDLE_DPLL_UNIPRO, CM_AUTOIDLE_DPLL_USB,
- * CM_AUTOIDLE_DPLL_CORE_RESTORE, CM_AUTOIDLE_DPLL_ABE, CM_AUTOIDLE_DPLL_CORE,
- * CM_AUTOIDLE_DPLL_DDRPHY, CM_AUTOIDLE_DPLL_IVA, CM_AUTOIDLE_DPLL_MPU
+ * Used by CM_AUTOIDLE_DPLL_ABE, CM_AUTOIDLE_DPLL_CORE,
+ * CM_AUTOIDLE_DPLL_CORE_RESTORE, CM_AUTOIDLE_DPLL_DDRPHY,
+ * CM_AUTOIDLE_DPLL_IVA, CM_AUTOIDLE_DPLL_MPU, CM_AUTOIDLE_DPLL_PER,
+ * CM_AUTOIDLE_DPLL_UNIPRO, CM_AUTOIDLE_DPLL_USB
*/
#define OMAP4430_AUTO_DPLL_MODE_SHIFT 0
-#define OMAP4430_AUTO_DPLL_MODE_MASK BITFIELD(0, 2)
+#define OMAP4430_AUTO_DPLL_MODE_MASK (0x7 << 0)
-/* Used by CM_L4CFG_DYNAMICDEP */
+/* Used by CM_L4CFG_DYNAMICDEP, CM_L4CFG_DYNAMICDEP_RESTORE */
#define OMAP4430_CEFUSE_DYNDEP_SHIFT 17
-#define OMAP4430_CEFUSE_DYNDEP_MASK BITFIELD(17, 17)
+#define OMAP4430_CEFUSE_DYNDEP_MASK (1 << 17)
/* Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP, CM_TESLA_STATICDEP */
#define OMAP4430_CEFUSE_STATDEP_SHIFT 17
-#define OMAP4430_CEFUSE_STATDEP_MASK BITFIELD(17, 17)
+#define OMAP4430_CEFUSE_STATDEP_MASK (1 << 17)
/* Used by CM1_ABE_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_ABE_24M_GFCLK_SHIFT 13
-#define OMAP4430_CLKACTIVITY_ABE_24M_GFCLK_MASK BITFIELD(13, 13)
+#define OMAP4430_CLKACTIVITY_ABE_24M_GFCLK_MASK (1 << 13)
/* Used by CM1_ABE_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_ABE_ALWON_32K_CLK_SHIFT 12
-#define OMAP4430_CLKACTIVITY_ABE_ALWON_32K_CLK_MASK BITFIELD(12, 12)
+#define OMAP4430_CLKACTIVITY_ABE_ALWON_32K_CLK_MASK (1 << 12)
/* Used by CM_WKUP_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_ABE_LP_CLK_SHIFT 9
-#define OMAP4430_CLKACTIVITY_ABE_LP_CLK_MASK BITFIELD(9, 9)
+#define OMAP4430_CLKACTIVITY_ABE_LP_CLK_MASK (1 << 9)
/* Used by CM1_ABE_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_ABE_SYSCLK_SHIFT 11
-#define OMAP4430_CLKACTIVITY_ABE_SYSCLK_MASK BITFIELD(11, 11)
+#define OMAP4430_CLKACTIVITY_ABE_SYSCLK_MASK (1 << 11)
/* Used by CM1_ABE_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_ABE_X2_CLK_SHIFT 8
-#define OMAP4430_CLKACTIVITY_ABE_X2_CLK_MASK BITFIELD(8, 8)
+#define OMAP4430_CLKACTIVITY_ABE_X2_CLK_MASK (1 << 8)
/* Used by CM_MEMIF_CLKSTCTRL, CM_MEMIF_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_ASYNC_DLL_CLK_SHIFT 11
-#define OMAP4430_CLKACTIVITY_ASYNC_DLL_CLK_MASK BITFIELD(11, 11)
+#define OMAP4430_CLKACTIVITY_ASYNC_DLL_CLK_MASK (1 << 11)
/* Used by CM_MEMIF_CLKSTCTRL, CM_MEMIF_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_ASYNC_PHY1_CLK_SHIFT 12
-#define OMAP4430_CLKACTIVITY_ASYNC_PHY1_CLK_MASK BITFIELD(12, 12)
+#define OMAP4430_CLKACTIVITY_ASYNC_PHY1_CLK_MASK (1 << 12)
/* Used by CM_MEMIF_CLKSTCTRL, CM_MEMIF_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_ASYNC_PHY2_CLK_SHIFT 13
-#define OMAP4430_CLKACTIVITY_ASYNC_PHY2_CLK_MASK BITFIELD(13, 13)
+#define OMAP4430_CLKACTIVITY_ASYNC_PHY2_CLK_MASK (1 << 13)
/* Used by CM_CAM_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_CAM_PHY_CTRL_GCLK_SHIFT 9
-#define OMAP4430_CLKACTIVITY_CAM_PHY_CTRL_GCLK_MASK BITFIELD(9, 9)
+#define OMAP4430_CLKACTIVITY_CAM_PHY_CTRL_GCLK_MASK (1 << 9)
+
+/* Used by CM_ALWON_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_CORE_ALWON_32K_GFCLK_SHIFT 12
+#define OMAP4430_CLKACTIVITY_CORE_ALWON_32K_GFCLK_MASK (1 << 12)
/* Used by CM_EMU_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_CORE_DPLL_EMU_CLK_SHIFT 9
-#define OMAP4430_CLKACTIVITY_CORE_DPLL_EMU_CLK_MASK BITFIELD(9, 9)
+#define OMAP4430_CLKACTIVITY_CORE_DPLL_EMU_CLK_MASK (1 << 9)
/* Used by CM_CEFUSE_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_CUST_EFUSE_SYS_CLK_SHIFT 9
-#define OMAP4430_CLKACTIVITY_CUST_EFUSE_SYS_CLK_MASK BITFIELD(9, 9)
+#define OMAP4430_CLKACTIVITY_CUST_EFUSE_SYS_CLK_MASK (1 << 9)
/* Used by CM_MEMIF_CLKSTCTRL, CM_MEMIF_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_DLL_CLK_SHIFT 9
-#define OMAP4430_CLKACTIVITY_DLL_CLK_MASK BITFIELD(9, 9)
+#define OMAP4430_CLKACTIVITY_DLL_CLK_MASK (1 << 9)
/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_DMT10_GFCLK_SHIFT 9
-#define OMAP4430_CLKACTIVITY_DMT10_GFCLK_MASK BITFIELD(9, 9)
+#define OMAP4430_CLKACTIVITY_DMT10_GFCLK_MASK (1 << 9)
/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_DMT11_GFCLK_SHIFT 10
-#define OMAP4430_CLKACTIVITY_DMT11_GFCLK_MASK BITFIELD(10, 10)
+#define OMAP4430_CLKACTIVITY_DMT11_GFCLK_MASK (1 << 10)
/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_DMT2_GFCLK_SHIFT 11
-#define OMAP4430_CLKACTIVITY_DMT2_GFCLK_MASK BITFIELD(11, 11)
+#define OMAP4430_CLKACTIVITY_DMT2_GFCLK_MASK (1 << 11)
/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_DMT3_GFCLK_SHIFT 12
-#define OMAP4430_CLKACTIVITY_DMT3_GFCLK_MASK BITFIELD(12, 12)
+#define OMAP4430_CLKACTIVITY_DMT3_GFCLK_MASK (1 << 12)
/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_DMT4_GFCLK_SHIFT 13
-#define OMAP4430_CLKACTIVITY_DMT4_GFCLK_MASK BITFIELD(13, 13)
+#define OMAP4430_CLKACTIVITY_DMT4_GFCLK_MASK (1 << 13)
/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_DMT9_GFCLK_SHIFT 14
-#define OMAP4430_CLKACTIVITY_DMT9_GFCLK_MASK BITFIELD(14, 14)
+#define OMAP4430_CLKACTIVITY_DMT9_GFCLK_MASK (1 << 14)
/* Used by CM_DSS_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_DSS_ALWON_SYS_CLK_SHIFT 10
-#define OMAP4430_CLKACTIVITY_DSS_ALWON_SYS_CLK_MASK BITFIELD(10, 10)
+#define OMAP4430_CLKACTIVITY_DSS_ALWON_SYS_CLK_MASK (1 << 10)
/* Used by CM_DSS_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_DSS_FCLK_SHIFT 9
-#define OMAP4430_CLKACTIVITY_DSS_FCLK_MASK BITFIELD(9, 9)
+#define OMAP4430_CLKACTIVITY_DSS_FCLK_MASK (1 << 9)
/* Used by CM_DUCATI_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_DUCATI_GCLK_SHIFT 8
-#define OMAP4430_CLKACTIVITY_DUCATI_GCLK_MASK BITFIELD(8, 8)
-
-/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_EMAC_50MHZ_CLK_SHIFT 10
-#define OMAP4430_CLKACTIVITY_EMAC_50MHZ_CLK_MASK BITFIELD(10, 10)
+#define OMAP4430_CLKACTIVITY_DUCATI_GCLK_MASK (1 << 8)
/* Used by CM_EMU_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_EMU_SYS_CLK_SHIFT 8
-#define OMAP4430_CLKACTIVITY_EMU_SYS_CLK_MASK BITFIELD(8, 8)
+#define OMAP4430_CLKACTIVITY_EMU_SYS_CLK_MASK (1 << 8)
/* Used by CM_CAM_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_FDIF_GFCLK_SHIFT 10
-#define OMAP4430_CLKACTIVITY_FDIF_GFCLK_MASK BITFIELD(10, 10)
+#define OMAP4430_CLKACTIVITY_FDIF_GFCLK_MASK (1 << 10)
/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_FUNC_12M_GFCLK_SHIFT 15
-#define OMAP4430_CLKACTIVITY_FUNC_12M_GFCLK_MASK BITFIELD(15, 15)
+#define OMAP4430_CLKACTIVITY_FUNC_12M_GFCLK_MASK (1 << 15)
/* Used by CM1_ABE_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_FUNC_24M_GFCLK_SHIFT 10
-#define OMAP4430_CLKACTIVITY_FUNC_24M_GFCLK_MASK BITFIELD(10, 10)
+#define OMAP4430_CLKACTIVITY_FUNC_24M_GFCLK_MASK (1 << 10)
/* Used by CM_DSS_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_HDMI_PHY_48MHZ_GFCLK_SHIFT 11
-#define OMAP4430_CLKACTIVITY_HDMI_PHY_48MHZ_GFCLK_MASK BITFIELD(11, 11)
+#define OMAP4430_CLKACTIVITY_HDMI_PHY_48MHZ_GFCLK_MASK (1 << 11)
/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_HSIC_P1_480M_GFCLK_SHIFT 20
-#define OMAP4430_CLKACTIVITY_HSIC_P1_480M_GFCLK_MASK BITFIELD(20, 20)
+#define OMAP4430_CLKACTIVITY_HSIC_P1_480M_GFCLK_MASK (1 << 20)
/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_HSIC_P1_GFCLK_SHIFT 26
-#define OMAP4430_CLKACTIVITY_HSIC_P1_GFCLK_MASK BITFIELD(26, 26)
+#define OMAP4430_CLKACTIVITY_HSIC_P1_GFCLK_MASK (1 << 26)
/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_HSIC_P2_480M_GFCLK_SHIFT 21
-#define OMAP4430_CLKACTIVITY_HSIC_P2_480M_GFCLK_MASK BITFIELD(21, 21)
+#define OMAP4430_CLKACTIVITY_HSIC_P2_480M_GFCLK_MASK (1 << 21)
/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_HSIC_P2_GFCLK_SHIFT 27
-#define OMAP4430_CLKACTIVITY_HSIC_P2_GFCLK_MASK BITFIELD(27, 27)
-
-/* Used by CM_L3INIT_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_INIT_32K_GFCLK_SHIFT 31
-#define OMAP4430_CLKACTIVITY_INIT_32K_GFCLK_MASK BITFIELD(31, 31)
+#define OMAP4430_CLKACTIVITY_HSIC_P2_GFCLK_MASK (1 << 27)
/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_INIT_48MC_GFCLK_SHIFT 13
-#define OMAP4430_CLKACTIVITY_INIT_48MC_GFCLK_MASK BITFIELD(13, 13)
+#define OMAP4430_CLKACTIVITY_INIT_48MC_GFCLK_MASK (1 << 13)
/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_INIT_48M_GFCLK_SHIFT 12
-#define OMAP4430_CLKACTIVITY_INIT_48M_GFCLK_MASK BITFIELD(12, 12)
+#define OMAP4430_CLKACTIVITY_INIT_48M_GFCLK_MASK (1 << 12)
/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_INIT_60M_P1_GFCLK_SHIFT 28
-#define OMAP4430_CLKACTIVITY_INIT_60M_P1_GFCLK_MASK BITFIELD(28, 28)
+#define OMAP4430_CLKACTIVITY_INIT_60M_P1_GFCLK_MASK (1 << 28)
/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_INIT_60M_P2_GFCLK_SHIFT 29
-#define OMAP4430_CLKACTIVITY_INIT_60M_P2_GFCLK_MASK BITFIELD(29, 29)
+#define OMAP4430_CLKACTIVITY_INIT_60M_P2_GFCLK_MASK (1 << 29)
/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_INIT_96M_GFCLK_SHIFT 11
-#define OMAP4430_CLKACTIVITY_INIT_96M_GFCLK_MASK BITFIELD(11, 11)
+#define OMAP4430_CLKACTIVITY_INIT_96M_GFCLK_MASK (1 << 11)
/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_INIT_HSI_GFCLK_SHIFT 16
-#define OMAP4430_CLKACTIVITY_INIT_HSI_GFCLK_MASK BITFIELD(16, 16)
+#define OMAP4430_CLKACTIVITY_INIT_HSI_GFCLK_MASK (1 << 16)
/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_INIT_HSMMC1_GFCLK_SHIFT 17
-#define OMAP4430_CLKACTIVITY_INIT_HSMMC1_GFCLK_MASK BITFIELD(17, 17)
+#define OMAP4430_CLKACTIVITY_INIT_HSMMC1_GFCLK_MASK (1 << 17)
/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_INIT_HSMMC2_GFCLK_SHIFT 18
-#define OMAP4430_CLKACTIVITY_INIT_HSMMC2_GFCLK_MASK BITFIELD(18, 18)
+#define OMAP4430_CLKACTIVITY_INIT_HSMMC2_GFCLK_MASK (1 << 18)
/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_INIT_HSMMC6_GFCLK_SHIFT 19
-#define OMAP4430_CLKACTIVITY_INIT_HSMMC6_GFCLK_MASK BITFIELD(19, 19)
+#define OMAP4430_CLKACTIVITY_INIT_HSMMC6_GFCLK_MASK (1 << 19)
/* Used by CM_CAM_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_ISS_GCLK_SHIFT 8
-#define OMAP4430_CLKACTIVITY_ISS_GCLK_MASK BITFIELD(8, 8)
+#define OMAP4430_CLKACTIVITY_ISS_GCLK_MASK (1 << 8)
/* Used by CM_IVAHD_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_IVAHD_ROOT_CLK_SHIFT 8
-#define OMAP4430_CLKACTIVITY_IVAHD_ROOT_CLK_MASK BITFIELD(8, 8)
+#define OMAP4430_CLKACTIVITY_IVAHD_ROOT_CLK_MASK (1 << 8)
-/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_L3INIT_DPLL_ALWON_CLK_SHIFT 14
-#define OMAP4430_CLKACTIVITY_L3INIT_DPLL_ALWON_CLK_MASK BITFIELD(14, 14)
+/* Used by CM_D2D_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_L3X2_D2D_GICLK_SHIFT 10
+#define OMAP4430_CLKACTIVITY_L3X2_D2D_GICLK_MASK (1 << 10)
/* Used by CM_L3_1_CLKSTCTRL, CM_L3_1_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_L3_1_GICLK_SHIFT 8
-#define OMAP4430_CLKACTIVITY_L3_1_GICLK_MASK BITFIELD(8, 8)
+#define OMAP4430_CLKACTIVITY_L3_1_GICLK_MASK (1 << 8)
/* Used by CM_L3_2_CLKSTCTRL, CM_L3_2_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_L3_2_GICLK_SHIFT 8
-#define OMAP4430_CLKACTIVITY_L3_2_GICLK_MASK BITFIELD(8, 8)
+#define OMAP4430_CLKACTIVITY_L3_2_GICLK_MASK (1 << 8)
/* Used by CM_D2D_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L3_D2D_GICLK_SHIFT 8
-#define OMAP4430_CLKACTIVITY_L3_D2D_GICLK_MASK BITFIELD(8, 8)
+#define OMAP4430_CLKACTIVITY_L3_D2D_GICLK_MASK (1 << 8)
/* Used by CM_SDMA_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L3_DMA_GICLK_SHIFT 8
-#define OMAP4430_CLKACTIVITY_L3_DMA_GICLK_MASK BITFIELD(8, 8)
+#define OMAP4430_CLKACTIVITY_L3_DMA_GICLK_MASK (1 << 8)
/* Used by CM_DSS_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L3_DSS_GICLK_SHIFT 8
-#define OMAP4430_CLKACTIVITY_L3_DSS_GICLK_MASK BITFIELD(8, 8)
+#define OMAP4430_CLKACTIVITY_L3_DSS_GICLK_MASK (1 << 8)
/* Used by CM_MEMIF_CLKSTCTRL, CM_MEMIF_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_L3_EMIF_GICLK_SHIFT 8
-#define OMAP4430_CLKACTIVITY_L3_EMIF_GICLK_MASK BITFIELD(8, 8)
+#define OMAP4430_CLKACTIVITY_L3_EMIF_GICLK_MASK (1 << 8)
/* Used by CM_GFX_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L3_GFX_GICLK_SHIFT 8
-#define OMAP4430_CLKACTIVITY_L3_GFX_GICLK_MASK BITFIELD(8, 8)
+#define OMAP4430_CLKACTIVITY_L3_GFX_GICLK_MASK (1 << 8)
/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_L3_INIT_GICLK_SHIFT 8
-#define OMAP4430_CLKACTIVITY_L3_INIT_GICLK_MASK BITFIELD(8, 8)
+#define OMAP4430_CLKACTIVITY_L3_INIT_GICLK_MASK (1 << 8)
/* Used by CM_L3INSTR_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L3_INSTR_GICLK_SHIFT 8
-#define OMAP4430_CLKACTIVITY_L3_INSTR_GICLK_MASK BITFIELD(8, 8)
+#define OMAP4430_CLKACTIVITY_L3_INSTR_GICLK_MASK (1 << 8)
/* Used by CM_L4SEC_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L3_SECURE_GICLK_SHIFT 8
-#define OMAP4430_CLKACTIVITY_L3_SECURE_GICLK_MASK BITFIELD(8, 8)
+#define OMAP4430_CLKACTIVITY_L3_SECURE_GICLK_MASK (1 << 8)
/* Used by CM_ALWON_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L4_AO_ICLK_SHIFT 8
-#define OMAP4430_CLKACTIVITY_L4_AO_ICLK_MASK BITFIELD(8, 8)
+#define OMAP4430_CLKACTIVITY_L4_AO_ICLK_MASK (1 << 8)
/* Used by CM_CEFUSE_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L4_CEFUSE_GICLK_SHIFT 8
-#define OMAP4430_CLKACTIVITY_L4_CEFUSE_GICLK_MASK BITFIELD(8, 8)
+#define OMAP4430_CLKACTIVITY_L4_CEFUSE_GICLK_MASK (1 << 8)
/* Used by CM_L4CFG_CLKSTCTRL, CM_L4CFG_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_L4_CFG_GICLK_SHIFT 8
-#define OMAP4430_CLKACTIVITY_L4_CFG_GICLK_MASK BITFIELD(8, 8)
+#define OMAP4430_CLKACTIVITY_L4_CFG_GICLK_MASK (1 << 8)
/* Used by CM_D2D_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L4_D2D_GICLK_SHIFT 9
-#define OMAP4430_CLKACTIVITY_L4_D2D_GICLK_MASK BITFIELD(9, 9)
+#define OMAP4430_CLKACTIVITY_L4_D2D_GICLK_MASK (1 << 9)
/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_L4_INIT_GICLK_SHIFT 9
-#define OMAP4430_CLKACTIVITY_L4_INIT_GICLK_MASK BITFIELD(9, 9)
+#define OMAP4430_CLKACTIVITY_L4_INIT_GICLK_MASK (1 << 9)
/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_L4_PER_GICLK_SHIFT 8
-#define OMAP4430_CLKACTIVITY_L4_PER_GICLK_MASK BITFIELD(8, 8)
+#define OMAP4430_CLKACTIVITY_L4_PER_GICLK_MASK (1 << 8)
/* Used by CM_L4SEC_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L4_SECURE_GICLK_SHIFT 9
-#define OMAP4430_CLKACTIVITY_L4_SECURE_GICLK_MASK BITFIELD(9, 9)
+#define OMAP4430_CLKACTIVITY_L4_SECURE_GICLK_MASK (1 << 9)
/* Used by CM_WKUP_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L4_WKUP_GICLK_SHIFT 12
-#define OMAP4430_CLKACTIVITY_L4_WKUP_GICLK_MASK BITFIELD(12, 12)
+#define OMAP4430_CLKACTIVITY_L4_WKUP_GICLK_MASK (1 << 12)
/* Used by CM_MPU_CLKSTCTRL, CM_MPU_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_MPU_DPLL_CLK_SHIFT 8
-#define OMAP4430_CLKACTIVITY_MPU_DPLL_CLK_MASK BITFIELD(8, 8)
+#define OMAP4430_CLKACTIVITY_MPU_DPLL_CLK_MASK (1 << 8)
/* Used by CM1_ABE_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_OCP_ABE_GICLK_SHIFT 9
-#define OMAP4430_CLKACTIVITY_OCP_ABE_GICLK_MASK BITFIELD(9, 9)
+#define OMAP4430_CLKACTIVITY_OCP_ABE_GICLK_MASK (1 << 9)
/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_PER_24MC_GFCLK_SHIFT 16
-#define OMAP4430_CLKACTIVITY_PER_24MC_GFCLK_MASK BITFIELD(16, 16)
+#define OMAP4430_CLKACTIVITY_PER_24MC_GFCLK_MASK (1 << 16)
/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_PER_32K_GFCLK_SHIFT 17
-#define OMAP4430_CLKACTIVITY_PER_32K_GFCLK_MASK BITFIELD(17, 17)
+#define OMAP4430_CLKACTIVITY_PER_32K_GFCLK_MASK (1 << 17)
/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_PER_48M_GFCLK_SHIFT 18
-#define OMAP4430_CLKACTIVITY_PER_48M_GFCLK_MASK BITFIELD(18, 18)
+#define OMAP4430_CLKACTIVITY_PER_48M_GFCLK_MASK (1 << 18)
/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_PER_96M_GFCLK_SHIFT 19
-#define OMAP4430_CLKACTIVITY_PER_96M_GFCLK_MASK BITFIELD(19, 19)
+#define OMAP4430_CLKACTIVITY_PER_96M_GFCLK_MASK (1 << 19)
/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_PER_ABE_24M_GFCLK_SHIFT 25
-#define OMAP4430_CLKACTIVITY_PER_ABE_24M_GFCLK_MASK BITFIELD(25, 25)
-
-/* Used by CM_EMU_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_PER_DPLL_EMU_CLK_SHIFT 10
-#define OMAP4430_CLKACTIVITY_PER_DPLL_EMU_CLK_MASK BITFIELD(10, 10)
+#define OMAP4430_CLKACTIVITY_PER_ABE_24M_GFCLK_MASK (1 << 25)
/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_PER_MCASP2_GFCLK_SHIFT 20
-#define OMAP4430_CLKACTIVITY_PER_MCASP2_GFCLK_MASK BITFIELD(20, 20)
+#define OMAP4430_CLKACTIVITY_PER_MCASP2_GFCLK_MASK (1 << 20)
/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_PER_MCASP3_GFCLK_SHIFT 21
-#define OMAP4430_CLKACTIVITY_PER_MCASP3_GFCLK_MASK BITFIELD(21, 21)
+#define OMAP4430_CLKACTIVITY_PER_MCASP3_GFCLK_MASK (1 << 21)
/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_PER_MCBSP4_GFCLK_SHIFT 22
-#define OMAP4430_CLKACTIVITY_PER_MCBSP4_GFCLK_MASK BITFIELD(22, 22)
+#define OMAP4430_CLKACTIVITY_PER_MCBSP4_GFCLK_MASK (1 << 22)
/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_PER_SYS_GFCLK_SHIFT 24
-#define OMAP4430_CLKACTIVITY_PER_SYS_GFCLK_MASK BITFIELD(24, 24)
+#define OMAP4430_CLKACTIVITY_PER_SYS_GFCLK_MASK (1 << 24)
/* Used by CM_MEMIF_CLKSTCTRL, CM_MEMIF_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_PHY_ROOT_CLK_SHIFT 10
-#define OMAP4430_CLKACTIVITY_PHY_ROOT_CLK_MASK BITFIELD(10, 10)
+#define OMAP4430_CLKACTIVITY_PHY_ROOT_CLK_MASK (1 << 10)
/* Used by CM_GFX_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_SGX_GFCLK_SHIFT 9
-#define OMAP4430_CLKACTIVITY_SGX_GFCLK_MASK BITFIELD(9, 9)
+#define OMAP4430_CLKACTIVITY_SGX_GFCLK_MASK (1 << 9)
/* Used by CM_ALWON_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_SR_CORE_SYSCLK_SHIFT 11
-#define OMAP4430_CLKACTIVITY_SR_CORE_SYSCLK_MASK BITFIELD(11, 11)
+#define OMAP4430_CLKACTIVITY_SR_CORE_SYSCLK_MASK (1 << 11)
/* Used by CM_ALWON_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_SR_IVA_SYSCLK_SHIFT 10
-#define OMAP4430_CLKACTIVITY_SR_IVA_SYSCLK_MASK BITFIELD(10, 10)
+#define OMAP4430_CLKACTIVITY_SR_IVA_SYSCLK_MASK (1 << 10)
/* Used by CM_ALWON_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_SR_MPU_SYSCLK_SHIFT 9
-#define OMAP4430_CLKACTIVITY_SR_MPU_SYSCLK_MASK BITFIELD(9, 9)
+#define OMAP4430_CLKACTIVITY_SR_MPU_SYSCLK_MASK (1 << 9)
/* Used by CM_WKUP_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_SYS_CLK_SHIFT 8
-#define OMAP4430_CLKACTIVITY_SYS_CLK_MASK BITFIELD(8, 8)
+#define OMAP4430_CLKACTIVITY_SYS_CLK_MASK (1 << 8)
/* Used by CM_TESLA_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_TESLA_ROOT_CLK_SHIFT 8
-#define OMAP4430_CLKACTIVITY_TESLA_ROOT_CLK_MASK BITFIELD(8, 8)
+#define OMAP4430_CLKACTIVITY_TESLA_ROOT_CLK_MASK (1 << 8)
/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_TLL_CH0_GFCLK_SHIFT 22
-#define OMAP4430_CLKACTIVITY_TLL_CH0_GFCLK_MASK BITFIELD(22, 22)
+#define OMAP4430_CLKACTIVITY_TLL_CH0_GFCLK_MASK (1 << 22)
/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_TLL_CH1_GFCLK_SHIFT 23
-#define OMAP4430_CLKACTIVITY_TLL_CH1_GFCLK_MASK BITFIELD(23, 23)
+#define OMAP4430_CLKACTIVITY_TLL_CH1_GFCLK_MASK (1 << 23)
/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_TLL_CH2_GFCLK_SHIFT 24
-#define OMAP4430_CLKACTIVITY_TLL_CH2_GFCLK_MASK BITFIELD(24, 24)
+#define OMAP4430_CLKACTIVITY_TLL_CH2_GFCLK_MASK (1 << 24)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_UNIPRO_DPLL_CLK_SHIFT 10
+#define OMAP4430_CLKACTIVITY_UNIPRO_DPLL_CLK_MASK (1 << 10)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_USB_DPLL_CLK_SHIFT 14
+#define OMAP4430_CLKACTIVITY_USB_DPLL_CLK_MASK (1 << 14)
/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_USB_DPLL_HS_CLK_SHIFT 15
-#define OMAP4430_CLKACTIVITY_USB_DPLL_HS_CLK_MASK BITFIELD(15, 15)
+#define OMAP4430_CLKACTIVITY_USB_DPLL_HS_CLK_MASK (1 << 15)
/* Used by CM_WKUP_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_USIM_GFCLK_SHIFT 10
-#define OMAP4430_CLKACTIVITY_USIM_GFCLK_MASK BITFIELD(10, 10)
+#define OMAP4430_CLKACTIVITY_USIM_GFCLK_MASK (1 << 10)
/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_UTMI_P3_GFCLK_SHIFT 30
-#define OMAP4430_CLKACTIVITY_UTMI_P3_GFCLK_MASK BITFIELD(30, 30)
+#define OMAP4430_CLKACTIVITY_UTMI_P3_GFCLK_MASK (1 << 30)
/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
#define OMAP4430_CLKACTIVITY_UTMI_ROOT_GFCLK_SHIFT 25
-#define OMAP4430_CLKACTIVITY_UTMI_ROOT_GFCLK_MASK BITFIELD(25, 25)
+#define OMAP4430_CLKACTIVITY_UTMI_ROOT_GFCLK_MASK (1 << 25)
/* Used by CM_WKUP_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_WKUP_32K_GFCLK_SHIFT 11
-#define OMAP4430_CLKACTIVITY_WKUP_32K_GFCLK_MASK BITFIELD(11, 11)
+#define OMAP4430_CLKACTIVITY_WKUP_32K_GFCLK_MASK (1 << 11)
/*
- * Used by CM_WKUP_TIMER1_CLKCTRL, CM_L4PER_DMTIMER10_CLKCTRL,
+ * Used by CM1_ABE_TIMER5_CLKCTRL, CM1_ABE_TIMER6_CLKCTRL,
+ * CM1_ABE_TIMER7_CLKCTRL, CM1_ABE_TIMER8_CLKCTRL, CM_L3INIT_MMC1_CLKCTRL,
+ * CM_L3INIT_MMC2_CLKCTRL, CM_L3INIT_MMC6_CLKCTRL, CM_L4PER_DMTIMER10_CLKCTRL,
* CM_L4PER_DMTIMER11_CLKCTRL, CM_L4PER_DMTIMER2_CLKCTRL,
* CM_L4PER_DMTIMER3_CLKCTRL, CM_L4PER_DMTIMER4_CLKCTRL,
* CM_L4PER_DMTIMER9_CLKCTRL, CM_L4PER_MCASP2_CLKCTRL, CM_L4PER_MCASP3_CLKCTRL,
- * CM_L3INIT_MMC1_CLKCTRL, CM_L3INIT_MMC2_CLKCTRL, CM_L3INIT_MMC6_CLKCTRL,
- * CM1_ABE_TIMER5_CLKCTRL, CM1_ABE_TIMER6_CLKCTRL, CM1_ABE_TIMER7_CLKCTRL,
- * CM1_ABE_TIMER8_CLKCTRL
+ * CM_WKUP_TIMER1_CLKCTRL
*/
#define OMAP4430_CLKSEL_SHIFT 24
-#define OMAP4430_CLKSEL_MASK BITFIELD(24, 24)
+#define OMAP4430_CLKSEL_MASK (1 << 24)
/*
* Renamed from CLKSEL Used by CM_ABE_DSS_SYS_CLKSEL, CM_ABE_PLL_REF_CLKSEL,
- * CM_DPLL_SYS_REF_CLKSEL, CM_L4_WKUP_CLKSEL, CM_CLKSEL_DUCATI_ISS_ROOT,
- * CM_CLKSEL_USB_60MHZ
+ * CM_L4_WKUP_CLKSEL, CM_CLKSEL_DUCATI_ISS_ROOT, CM_CLKSEL_USB_60MHZ
*/
#define OMAP4430_CLKSEL_0_0_SHIFT 0
-#define OMAP4430_CLKSEL_0_0_MASK BITFIELD(0, 0)
+#define OMAP4430_CLKSEL_0_0_MASK (1 << 0)
/* Renamed from CLKSEL Used by CM_BYPCLK_DPLL_IVA, CM_BYPCLK_DPLL_MPU */
#define OMAP4430_CLKSEL_0_1_SHIFT 0
-#define OMAP4430_CLKSEL_0_1_MASK BITFIELD(0, 1)
+#define OMAP4430_CLKSEL_0_1_MASK (0x3 << 0)
/* Renamed from CLKSEL Used by CM_L3INIT_HSI_CLKCTRL */
#define OMAP4430_CLKSEL_24_25_SHIFT 24
-#define OMAP4430_CLKSEL_24_25_MASK BITFIELD(24, 25)
+#define OMAP4430_CLKSEL_24_25_MASK (0x3 << 24)
/* Used by CM_L3INIT_USB_OTG_CLKCTRL */
#define OMAP4430_CLKSEL_60M_SHIFT 24
-#define OMAP4430_CLKSEL_60M_MASK BITFIELD(24, 24)
+#define OMAP4430_CLKSEL_60M_MASK (1 << 24)
/* Used by CM1_ABE_AESS_CLKCTRL */
#define OMAP4430_CLKSEL_AESS_FCLK_SHIFT 24
-#define OMAP4430_CLKSEL_AESS_FCLK_MASK BITFIELD(24, 24)
+#define OMAP4430_CLKSEL_AESS_FCLK_MASK (1 << 24)
-/* Used by CM_CLKSEL_CORE_RESTORE, CM_CLKSEL_CORE */
+/* Used by CM_CLKSEL_CORE, CM_CLKSEL_CORE_RESTORE */
#define OMAP4430_CLKSEL_CORE_SHIFT 0
-#define OMAP4430_CLKSEL_CORE_MASK BITFIELD(0, 0)
+#define OMAP4430_CLKSEL_CORE_MASK (1 << 0)
-/* Renamed from CLKSEL_CORE Used by CM_SHADOW_FREQ_CONFIG2 */
+/*
+ * Renamed from CLKSEL_CORE Used by CM_SHADOW_FREQ_CONFIG2_RESTORE,
+ * CM_SHADOW_FREQ_CONFIG2
+ */
#define OMAP4430_CLKSEL_CORE_1_1_SHIFT 1
-#define OMAP4430_CLKSEL_CORE_1_1_MASK BITFIELD(1, 1)
+#define OMAP4430_CLKSEL_CORE_1_1_MASK (1 << 1)
/* Used by CM_WKUP_USIM_CLKCTRL */
#define OMAP4430_CLKSEL_DIV_SHIFT 24
-#define OMAP4430_CLKSEL_DIV_MASK BITFIELD(24, 24)
+#define OMAP4430_CLKSEL_DIV_MASK (1 << 24)
/* Used by CM_CAM_FDIF_CLKCTRL */
#define OMAP4430_CLKSEL_FCLK_SHIFT 24
-#define OMAP4430_CLKSEL_FCLK_MASK BITFIELD(24, 25)
+#define OMAP4430_CLKSEL_FCLK_MASK (0x3 << 24)
/* Used by CM_L4PER_MCBSP4_CLKCTRL */
#define OMAP4430_CLKSEL_INTERNAL_SOURCE_SHIFT 25
-#define OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK BITFIELD(25, 25)
+#define OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK (1 << 25)
/*
* Renamed from CLKSEL_INTERNAL_SOURCE Used by CM1_ABE_DMIC_CLKCTRL,
@@ -479,836 +485,869 @@
* CM1_ABE_MCBSP3_CLKCTRL
*/
#define OMAP4430_CLKSEL_INTERNAL_SOURCE_CM1_ABE_DMIC_SHIFT 26
-#define OMAP4430_CLKSEL_INTERNAL_SOURCE_CM1_ABE_DMIC_MASK BITFIELD(26, 27)
+#define OMAP4430_CLKSEL_INTERNAL_SOURCE_CM1_ABE_DMIC_MASK (0x3 << 26)
-/* Used by CM_CLKSEL_CORE_RESTORE, CM_CLKSEL_CORE */
+/* Used by CM_CLKSEL_CORE, CM_CLKSEL_CORE_RESTORE */
#define OMAP4430_CLKSEL_L3_SHIFT 4
-#define OMAP4430_CLKSEL_L3_MASK BITFIELD(4, 4)
+#define OMAP4430_CLKSEL_L3_MASK (1 << 4)
-/* Renamed from CLKSEL_L3 Used by CM_SHADOW_FREQ_CONFIG2 */
+/*
+ * Renamed from CLKSEL_L3 Used by CM_SHADOW_FREQ_CONFIG2_RESTORE,
+ * CM_SHADOW_FREQ_CONFIG2
+ */
#define OMAP4430_CLKSEL_L3_SHADOW_SHIFT 2
-#define OMAP4430_CLKSEL_L3_SHADOW_MASK BITFIELD(2, 2)
+#define OMAP4430_CLKSEL_L3_SHADOW_MASK (1 << 2)
-/* Used by CM_CLKSEL_CORE_RESTORE, CM_CLKSEL_CORE */
+/* Used by CM_CLKSEL_CORE, CM_CLKSEL_CORE_RESTORE */
#define OMAP4430_CLKSEL_L4_SHIFT 8
-#define OMAP4430_CLKSEL_L4_MASK BITFIELD(8, 8)
+#define OMAP4430_CLKSEL_L4_MASK (1 << 8)
/* Used by CM_CLKSEL_ABE */
#define OMAP4430_CLKSEL_OPP_SHIFT 0
-#define OMAP4430_CLKSEL_OPP_MASK BITFIELD(0, 1)
-
-/* Used by CM_GFX_GFX_CLKCTRL */
-#define OMAP4430_CLKSEL_PER_192M_SHIFT 25
-#define OMAP4430_CLKSEL_PER_192M_MASK BITFIELD(25, 26)
+#define OMAP4430_CLKSEL_OPP_MASK (0x3 << 0)
/* Used by CM_EMU_DEBUGSS_CLKCTRL */
#define OMAP4430_CLKSEL_PMD_STM_CLK_SHIFT 27
-#define OMAP4430_CLKSEL_PMD_STM_CLK_MASK BITFIELD(27, 29)
+#define OMAP4430_CLKSEL_PMD_STM_CLK_MASK (0x7 << 27)
/* Used by CM_EMU_DEBUGSS_CLKCTRL */
#define OMAP4430_CLKSEL_PMD_TRACE_CLK_SHIFT 24
-#define OMAP4430_CLKSEL_PMD_TRACE_CLK_MASK BITFIELD(24, 26)
+#define OMAP4430_CLKSEL_PMD_TRACE_CLK_MASK (0x7 << 24)
/* Used by CM_GFX_GFX_CLKCTRL */
#define OMAP4430_CLKSEL_SGX_FCLK_SHIFT 24
-#define OMAP4430_CLKSEL_SGX_FCLK_MASK BITFIELD(24, 24)
+#define OMAP4430_CLKSEL_SGX_FCLK_MASK (1 << 24)
/*
* Used by CM1_ABE_DMIC_CLKCTRL, CM1_ABE_MCASP_CLKCTRL, CM1_ABE_MCBSP1_CLKCTRL,
* CM1_ABE_MCBSP2_CLKCTRL, CM1_ABE_MCBSP3_CLKCTRL
*/
#define OMAP4430_CLKSEL_SOURCE_SHIFT 24
-#define OMAP4430_CLKSEL_SOURCE_MASK BITFIELD(24, 25)
+#define OMAP4430_CLKSEL_SOURCE_MASK (0x3 << 24)
/* Renamed from CLKSEL_SOURCE Used by CM_L4PER_MCBSP4_CLKCTRL */
#define OMAP4430_CLKSEL_SOURCE_24_24_SHIFT 24
-#define OMAP4430_CLKSEL_SOURCE_24_24_MASK BITFIELD(24, 24)
+#define OMAP4430_CLKSEL_SOURCE_24_24_MASK (1 << 24)
/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
#define OMAP4430_CLKSEL_UTMI_P1_SHIFT 24
-#define OMAP4430_CLKSEL_UTMI_P1_MASK BITFIELD(24, 24)
+#define OMAP4430_CLKSEL_UTMI_P1_MASK (1 << 24)
/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
#define OMAP4430_CLKSEL_UTMI_P2_SHIFT 25
-#define OMAP4430_CLKSEL_UTMI_P2_MASK BITFIELD(25, 25)
+#define OMAP4430_CLKSEL_UTMI_P2_MASK (1 << 25)
/*
- * Used by CM_WKUP_CLKSTCTRL, CM_EMU_CLKSTCTRL, CM_D2D_CLKSTCTRL,
- * CM_DUCATI_CLKSTCTRL, CM_L3INSTR_CLKSTCTRL, CM_L3_1_CLKSTCTRL,
- * CM_L3_2_CLKSTCTRL, CM_L4CFG_CLKSTCTRL, CM_MEMIF_CLKSTCTRL,
- * CM_SDMA_CLKSTCTRL, CM_GFX_CLKSTCTRL, CM_L4PER_CLKSTCTRL, CM_L4SEC_CLKSTCTRL,
- * CM_L3INIT_CLKSTCTRL, CM_CAM_CLKSTCTRL, CM_CEFUSE_CLKSTCTRL,
- * CM_L3INIT_CLKSTCTRL_RESTORE, CM_L3_1_CLKSTCTRL_RESTORE,
- * CM_L3_2_CLKSTCTRL_RESTORE, CM_L4CFG_CLKSTCTRL_RESTORE,
- * CM_L4PER_CLKSTCTRL_RESTORE, CM_MEMIF_CLKSTCTRL_RESTORE, CM_ALWON_CLKSTCTRL,
- * CM_IVAHD_CLKSTCTRL, CM_DSS_CLKSTCTRL, CM_MPU_CLKSTCTRL, CM_TESLA_CLKSTCTRL,
- * CM1_ABE_CLKSTCTRL, CM_MPU_CLKSTCTRL_RESTORE
+ * Used by CM1_ABE_CLKSTCTRL, CM_ALWON_CLKSTCTRL, CM_CAM_CLKSTCTRL,
+ * CM_CEFUSE_CLKSTCTRL, CM_D2D_CLKSTCTRL, CM_DSS_CLKSTCTRL,
+ * CM_DUCATI_CLKSTCTRL, CM_EMU_CLKSTCTRL, CM_GFX_CLKSTCTRL, CM_IVAHD_CLKSTCTRL,
+ * CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE, CM_L3INSTR_CLKSTCTRL,
+ * CM_L3_1_CLKSTCTRL, CM_L3_1_CLKSTCTRL_RESTORE, CM_L3_2_CLKSTCTRL,
+ * CM_L3_2_CLKSTCTRL_RESTORE, CM_L4CFG_CLKSTCTRL, CM_L4CFG_CLKSTCTRL_RESTORE,
+ * CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE, CM_L4SEC_CLKSTCTRL,
+ * CM_MEMIF_CLKSTCTRL, CM_MEMIF_CLKSTCTRL_RESTORE, CM_MPU_CLKSTCTRL,
+ * CM_MPU_CLKSTCTRL_RESTORE, CM_SDMA_CLKSTCTRL, CM_TESLA_CLKSTCTRL,
+ * CM_WKUP_CLKSTCTRL
*/
#define OMAP4430_CLKTRCTRL_SHIFT 0
-#define OMAP4430_CLKTRCTRL_MASK BITFIELD(0, 1)
+#define OMAP4430_CLKTRCTRL_MASK (0x3 << 0)
/* Used by CM_EMU_OVERRIDE_DPLL_CORE */
#define OMAP4430_CORE_DPLL_EMU_DIV_SHIFT 0
-#define OMAP4430_CORE_DPLL_EMU_DIV_MASK BITFIELD(0, 6)
+#define OMAP4430_CORE_DPLL_EMU_DIV_MASK (0x7f << 0)
/* Used by CM_EMU_OVERRIDE_DPLL_CORE */
#define OMAP4430_CORE_DPLL_EMU_MULT_SHIFT 8
-#define OMAP4430_CORE_DPLL_EMU_MULT_MASK BITFIELD(8, 18)
+#define OMAP4430_CORE_DPLL_EMU_MULT_MASK (0x7ff << 8)
+
+/* Used by REVISION_CM1, REVISION_CM2 */
+#define OMAP4430_CUSTOM_SHIFT 6
+#define OMAP4430_CUSTOM_MASK (0x3 << 6)
-/* Used by CM_L3_2_DYNAMICDEP, CM_L4CFG_DYNAMICDEP */
+/*
+ * Used by CM_L3_2_DYNAMICDEP, CM_L3_2_DYNAMICDEP_RESTORE, CM_L4CFG_DYNAMICDEP,
+ * CM_L4CFG_DYNAMICDEP_RESTORE
+ */
#define OMAP4430_D2D_DYNDEP_SHIFT 18
-#define OMAP4430_D2D_DYNDEP_MASK BITFIELD(18, 18)
+#define OMAP4430_D2D_DYNDEP_MASK (1 << 18)
/* Used by CM_MPU_STATICDEP */
#define OMAP4430_D2D_STATDEP_SHIFT 18
-#define OMAP4430_D2D_STATDEP_MASK BITFIELD(18, 18)
+#define OMAP4430_D2D_STATDEP_MASK (1 << 18)
/*
- * Used by CM_SSC_DELTAMSTEP_DPLL_PER, CM_SSC_DELTAMSTEP_DPLL_UNIPRO,
- * CM_SSC_DELTAMSTEP_DPLL_USB, CM_SSC_DELTAMSTEP_DPLL_CORE_RESTORE,
- * CM_SSC_DELTAMSTEP_DPLL_ABE, CM_SSC_DELTAMSTEP_DPLL_CORE,
- * CM_SSC_DELTAMSTEP_DPLL_DDRPHY, CM_SSC_DELTAMSTEP_DPLL_IVA,
- * CM_SSC_DELTAMSTEP_DPLL_MPU
+ * Used by CM_SSC_DELTAMSTEP_DPLL_ABE, CM_SSC_DELTAMSTEP_DPLL_CORE,
+ * CM_SSC_DELTAMSTEP_DPLL_CORE_RESTORE, CM_SSC_DELTAMSTEP_DPLL_DDRPHY,
+ * CM_SSC_DELTAMSTEP_DPLL_IVA, CM_SSC_DELTAMSTEP_DPLL_MPU,
+ * CM_SSC_DELTAMSTEP_DPLL_PER, CM_SSC_DELTAMSTEP_DPLL_UNIPRO,
+ * CM_SSC_DELTAMSTEP_DPLL_USB
*/
#define OMAP4430_DELTAMSTEP_SHIFT 0
-#define OMAP4430_DELTAMSTEP_MASK BITFIELD(0, 19)
+#define OMAP4430_DELTAMSTEP_MASK (0xfffff << 0)
-/* Used by CM_SHADOW_FREQ_CONFIG1_RESTORE, CM_SHADOW_FREQ_CONFIG1 */
+/* Used by CM_SHADOW_FREQ_CONFIG1, CM_SHADOW_FREQ_CONFIG1_RESTORE */
#define OMAP4430_DLL_OVERRIDE_SHIFT 2
-#define OMAP4430_DLL_OVERRIDE_MASK BITFIELD(2, 2)
+#define OMAP4430_DLL_OVERRIDE_MASK (1 << 2)
/* Renamed from DLL_OVERRIDE Used by CM_DLL_CTRL */
#define OMAP4430_DLL_OVERRIDE_0_0_SHIFT 0
-#define OMAP4430_DLL_OVERRIDE_0_0_MASK BITFIELD(0, 0)
+#define OMAP4430_DLL_OVERRIDE_0_0_MASK (1 << 0)
-/* Used by CM_SHADOW_FREQ_CONFIG1_RESTORE, CM_SHADOW_FREQ_CONFIG1 */
+/* Used by CM_SHADOW_FREQ_CONFIG1, CM_SHADOW_FREQ_CONFIG1_RESTORE */
#define OMAP4430_DLL_RESET_SHIFT 3
-#define OMAP4430_DLL_RESET_MASK BITFIELD(3, 3)
+#define OMAP4430_DLL_RESET_MASK (1 << 3)
/*
- * Used by CM_CLKSEL_DPLL_PER, CM_CLKSEL_DPLL_UNIPRO, CM_CLKSEL_DPLL_USB,
- * CM_CLKSEL_DPLL_CORE_RESTORE, CM_CLKSEL_DPLL_ABE, CM_CLKSEL_DPLL_CORE,
- * CM_CLKSEL_DPLL_DDRPHY, CM_CLKSEL_DPLL_IVA, CM_CLKSEL_DPLL_MPU
+ * Used by CM_CLKSEL_DPLL_ABE, CM_CLKSEL_DPLL_CORE,
+ * CM_CLKSEL_DPLL_CORE_RESTORE, CM_CLKSEL_DPLL_DDRPHY, CM_CLKSEL_DPLL_IVA,
+ * CM_CLKSEL_DPLL_MPU, CM_CLKSEL_DPLL_PER, CM_CLKSEL_DPLL_UNIPRO,
+ * CM_CLKSEL_DPLL_USB
*/
#define OMAP4430_DPLL_BYP_CLKSEL_SHIFT 23
-#define OMAP4430_DPLL_BYP_CLKSEL_MASK BITFIELD(23, 23)
+#define OMAP4430_DPLL_BYP_CLKSEL_MASK (1 << 23)
/* Used by CM_CLKDCOLDO_DPLL_USB */
#define OMAP4430_DPLL_CLKDCOLDO_GATE_CTRL_SHIFT 8
-#define OMAP4430_DPLL_CLKDCOLDO_GATE_CTRL_MASK BITFIELD(8, 8)
+#define OMAP4430_DPLL_CLKDCOLDO_GATE_CTRL_MASK (1 << 8)
-/* Used by CM_CLKSEL_DPLL_CORE_RESTORE, CM_CLKSEL_DPLL_CORE */
+/* Used by CM_CLKSEL_DPLL_CORE, CM_CLKSEL_DPLL_CORE_RESTORE */
#define OMAP4430_DPLL_CLKOUTHIF_CLKSEL_SHIFT 20
-#define OMAP4430_DPLL_CLKOUTHIF_CLKSEL_MASK BITFIELD(20, 20)
+#define OMAP4430_DPLL_CLKOUTHIF_CLKSEL_MASK (1 << 20)
/*
- * Used by CM_DIV_M3_DPLL_PER, CM_DIV_M3_DPLL_CORE_RESTORE, CM_DIV_M3_DPLL_ABE,
- * CM_DIV_M3_DPLL_CORE
+ * Used by CM_DIV_M3_DPLL_ABE, CM_DIV_M3_DPLL_CORE,
+ * CM_DIV_M3_DPLL_CORE_RESTORE, CM_DIV_M3_DPLL_PER
*/
#define OMAP4430_DPLL_CLKOUTHIF_DIV_SHIFT 0
-#define OMAP4430_DPLL_CLKOUTHIF_DIV_MASK BITFIELD(0, 4)
+#define OMAP4430_DPLL_CLKOUTHIF_DIV_MASK (0x1f << 0)
/*
- * Used by CM_DIV_M3_DPLL_PER, CM_DIV_M3_DPLL_CORE_RESTORE, CM_DIV_M3_DPLL_ABE,
- * CM_DIV_M3_DPLL_CORE
+ * Used by CM_DIV_M3_DPLL_ABE, CM_DIV_M3_DPLL_CORE,
+ * CM_DIV_M3_DPLL_CORE_RESTORE, CM_DIV_M3_DPLL_PER
*/
#define OMAP4430_DPLL_CLKOUTHIF_DIVCHACK_SHIFT 5
-#define OMAP4430_DPLL_CLKOUTHIF_DIVCHACK_MASK BITFIELD(5, 5)
+#define OMAP4430_DPLL_CLKOUTHIF_DIVCHACK_MASK (1 << 5)
/*
- * Used by CM_DIV_M3_DPLL_PER, CM_DIV_M3_DPLL_CORE_RESTORE, CM_DIV_M3_DPLL_ABE,
- * CM_DIV_M3_DPLL_CORE
+ * Used by CM_DIV_M3_DPLL_ABE, CM_DIV_M3_DPLL_CORE,
+ * CM_DIV_M3_DPLL_CORE_RESTORE, CM_DIV_M3_DPLL_PER
*/
#define OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT 8
-#define OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_MASK BITFIELD(8, 8)
+#define OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_MASK (1 << 8)
-/* Used by CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_UNIPRO, CM_DIV_M2_DPLL_ABE */
+/* Used by CM_DIV_M2_DPLL_ABE, CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_UNIPRO */
#define OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_SHIFT 10
-#define OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK BITFIELD(10, 10)
+#define OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK (1 << 10)
/*
- * Used by CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_UNIPRO,
- * CM_DIV_M2_DPLL_CORE_RESTORE, CM_DIV_M2_DPLL_ABE, CM_DIV_M2_DPLL_CORE,
- * CM_DIV_M2_DPLL_DDRPHY, CM_DIV_M2_DPLL_MPU
+ * Used by CM_DIV_M2_DPLL_ABE, CM_DIV_M2_DPLL_CORE,
+ * CM_DIV_M2_DPLL_CORE_RESTORE, CM_DIV_M2_DPLL_DDRPHY, CM_DIV_M2_DPLL_MPU,
+ * CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_UNIPRO
*/
#define OMAP4430_DPLL_CLKOUT_DIV_SHIFT 0
-#define OMAP4430_DPLL_CLKOUT_DIV_MASK BITFIELD(0, 4)
+#define OMAP4430_DPLL_CLKOUT_DIV_MASK (0x1f << 0)
/* Renamed from DPLL_CLKOUT_DIV Used by CM_DIV_M2_DPLL_USB */
#define OMAP4430_DPLL_CLKOUT_DIV_0_6_SHIFT 0
-#define OMAP4430_DPLL_CLKOUT_DIV_0_6_MASK BITFIELD(0, 6)
+#define OMAP4430_DPLL_CLKOUT_DIV_0_6_MASK (0x7f << 0)
/*
- * Used by CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_UNIPRO,
- * CM_DIV_M2_DPLL_CORE_RESTORE, CM_DIV_M2_DPLL_ABE, CM_DIV_M2_DPLL_CORE,
- * CM_DIV_M2_DPLL_DDRPHY, CM_DIV_M2_DPLL_MPU
+ * Used by CM_DIV_M2_DPLL_ABE, CM_DIV_M2_DPLL_CORE,
+ * CM_DIV_M2_DPLL_CORE_RESTORE, CM_DIV_M2_DPLL_DDRPHY, CM_DIV_M2_DPLL_MPU,
+ * CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_UNIPRO
*/
#define OMAP4430_DPLL_CLKOUT_DIVCHACK_SHIFT 5
-#define OMAP4430_DPLL_CLKOUT_DIVCHACK_MASK BITFIELD(5, 5)
+#define OMAP4430_DPLL_CLKOUT_DIVCHACK_MASK (1 << 5)
/* Renamed from DPLL_CLKOUT_DIVCHACK Used by CM_DIV_M2_DPLL_USB */
#define OMAP4430_DPLL_CLKOUT_DIVCHACK_M2_USB_SHIFT 7
-#define OMAP4430_DPLL_CLKOUT_DIVCHACK_M2_USB_MASK BITFIELD(7, 7)
+#define OMAP4430_DPLL_CLKOUT_DIVCHACK_M2_USB_MASK (1 << 7)
/*
- * Used by CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_USB, CM_DIV_M2_DPLL_CORE_RESTORE,
- * CM_DIV_M2_DPLL_ABE, CM_DIV_M2_DPLL_CORE, CM_DIV_M2_DPLL_DDRPHY,
- * CM_DIV_M2_DPLL_MPU
+ * Used by CM_DIV_M2_DPLL_ABE, CM_DIV_M2_DPLL_CORE,
+ * CM_DIV_M2_DPLL_CORE_RESTORE, CM_DIV_M2_DPLL_DDRPHY, CM_DIV_M2_DPLL_MPU,
+ * CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_USB
*/
#define OMAP4430_DPLL_CLKOUT_GATE_CTRL_SHIFT 8
-#define OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK BITFIELD(8, 8)
+#define OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK (1 << 8)
-/* Used by CM_SHADOW_FREQ_CONFIG1_RESTORE, CM_SHADOW_FREQ_CONFIG1 */
+/* Used by CM_SHADOW_FREQ_CONFIG1, CM_SHADOW_FREQ_CONFIG1_RESTORE */
#define OMAP4430_DPLL_CORE_DPLL_EN_SHIFT 8
-#define OMAP4430_DPLL_CORE_DPLL_EN_MASK BITFIELD(8, 10)
+#define OMAP4430_DPLL_CORE_DPLL_EN_MASK (0x7 << 8)
-/* Used by CM_SHADOW_FREQ_CONFIG1_RESTORE, CM_SHADOW_FREQ_CONFIG1 */
+/* Used by CM_SHADOW_FREQ_CONFIG1, CM_SHADOW_FREQ_CONFIG1_RESTORE */
#define OMAP4430_DPLL_CORE_M2_DIV_SHIFT 11
-#define OMAP4430_DPLL_CORE_M2_DIV_MASK BITFIELD(11, 15)
+#define OMAP4430_DPLL_CORE_M2_DIV_MASK (0x1f << 11)
-/* Used by CM_SHADOW_FREQ_CONFIG2 */
+/* Used by CM_SHADOW_FREQ_CONFIG2, CM_SHADOW_FREQ_CONFIG2_RESTORE */
#define OMAP4430_DPLL_CORE_M5_DIV_SHIFT 3
-#define OMAP4430_DPLL_CORE_M5_DIV_MASK BITFIELD(3, 7)
-
-/* Used by CM_SHADOW_FREQ_CONFIG1_RESTORE, CM_SHADOW_FREQ_CONFIG1 */
-#define OMAP4430_DPLL_CORE_SYS_REF_CLKSEL_SHIFT 1
-#define OMAP4430_DPLL_CORE_SYS_REF_CLKSEL_MASK BITFIELD(1, 1)
+#define OMAP4430_DPLL_CORE_M5_DIV_MASK (0x1f << 3)
/*
- * Used by CM_CLKSEL_DPLL_PER, CM_CLKSEL_DPLL_UNIPRO,
- * CM_CLKSEL_DPLL_CORE_RESTORE, CM_CLKSEL_DPLL_ABE, CM_CLKSEL_DPLL_CORE,
- * CM_CLKSEL_DPLL_DDRPHY, CM_CLKSEL_DPLL_IVA, CM_CLKSEL_DPLL_MPU
+ * Used by CM_CLKSEL_DPLL_ABE, CM_CLKSEL_DPLL_CORE,
+ * CM_CLKSEL_DPLL_CORE_RESTORE, CM_CLKSEL_DPLL_DDRPHY, CM_CLKSEL_DPLL_IVA,
+ * CM_CLKSEL_DPLL_MPU, CM_CLKSEL_DPLL_PER, CM_CLKSEL_DPLL_UNIPRO
*/
#define OMAP4430_DPLL_DIV_SHIFT 0
-#define OMAP4430_DPLL_DIV_MASK BITFIELD(0, 6)
+#define OMAP4430_DPLL_DIV_MASK (0x7f << 0)
/* Renamed from DPLL_DIV Used by CM_CLKSEL_DPLL_USB */
#define OMAP4430_DPLL_DIV_0_7_SHIFT 0
-#define OMAP4430_DPLL_DIV_0_7_MASK BITFIELD(0, 7)
+#define OMAP4430_DPLL_DIV_0_7_MASK (0xff << 0)
/*
- * Used by CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_USB,
- * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
- * CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA, CM_CLKMODE_DPLL_MPU
+ * Used by CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
+ * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA,
+ * CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER
*/
#define OMAP4430_DPLL_DRIFTGUARD_EN_SHIFT 8
-#define OMAP4430_DPLL_DRIFTGUARD_EN_MASK BITFIELD(8, 8)
+#define OMAP4430_DPLL_DRIFTGUARD_EN_MASK (1 << 8)
/* Renamed from DPLL_DRIFTGUARD_EN Used by CM_CLKMODE_DPLL_UNIPRO */
#define OMAP4430_DPLL_DRIFTGUARD_EN_3_3_SHIFT 3
-#define OMAP4430_DPLL_DRIFTGUARD_EN_3_3_MASK BITFIELD(3, 3)
+#define OMAP4430_DPLL_DRIFTGUARD_EN_3_3_MASK (1 << 3)
/*
- * Used by CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_UNIPRO, CM_CLKMODE_DPLL_USB,
- * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
- * CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA, CM_CLKMODE_DPLL_MPU
+ * Used by CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
+ * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA,
+ * CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_UNIPRO,
+ * CM_CLKMODE_DPLL_USB
*/
#define OMAP4430_DPLL_EN_SHIFT 0
-#define OMAP4430_DPLL_EN_MASK BITFIELD(0, 2)
+#define OMAP4430_DPLL_EN_MASK (0x7 << 0)
/*
- * Used by CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_UNIPRO,
- * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
- * CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA, CM_CLKMODE_DPLL_MPU
+ * Used by CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
+ * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA,
+ * CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_UNIPRO
*/
#define OMAP4430_DPLL_LPMODE_EN_SHIFT 10
-#define OMAP4430_DPLL_LPMODE_EN_MASK BITFIELD(10, 10)
+#define OMAP4430_DPLL_LPMODE_EN_MASK (1 << 10)
/*
- * Used by CM_CLKSEL_DPLL_PER, CM_CLKSEL_DPLL_UNIPRO,
- * CM_CLKSEL_DPLL_CORE_RESTORE, CM_CLKSEL_DPLL_ABE, CM_CLKSEL_DPLL_CORE,
- * CM_CLKSEL_DPLL_DDRPHY, CM_CLKSEL_DPLL_IVA, CM_CLKSEL_DPLL_MPU
+ * Used by CM_CLKSEL_DPLL_ABE, CM_CLKSEL_DPLL_CORE,
+ * CM_CLKSEL_DPLL_CORE_RESTORE, CM_CLKSEL_DPLL_DDRPHY, CM_CLKSEL_DPLL_IVA,
+ * CM_CLKSEL_DPLL_MPU, CM_CLKSEL_DPLL_PER, CM_CLKSEL_DPLL_UNIPRO
*/
#define OMAP4430_DPLL_MULT_SHIFT 8
-#define OMAP4430_DPLL_MULT_MASK BITFIELD(8, 18)
+#define OMAP4430_DPLL_MULT_MASK (0x7ff << 8)
/* Renamed from DPLL_MULT Used by CM_CLKSEL_DPLL_USB */
#define OMAP4430_DPLL_MULT_USB_SHIFT 8
-#define OMAP4430_DPLL_MULT_USB_MASK BITFIELD(8, 19)
+#define OMAP4430_DPLL_MULT_USB_MASK (0xfff << 8)
/*
- * Used by CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_UNIPRO,
- * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
- * CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA, CM_CLKMODE_DPLL_MPU
+ * Used by CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
+ * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA,
+ * CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_UNIPRO
*/
#define OMAP4430_DPLL_REGM4XEN_SHIFT 11
-#define OMAP4430_DPLL_REGM4XEN_MASK BITFIELD(11, 11)
+#define OMAP4430_DPLL_REGM4XEN_MASK (1 << 11)
/* Used by CM_CLKSEL_DPLL_USB */
#define OMAP4430_DPLL_SD_DIV_SHIFT 24
-#define OMAP4430_DPLL_SD_DIV_MASK BITFIELD(24, 31)
+#define OMAP4430_DPLL_SD_DIV_MASK (0xff << 24)
/*
- * Used by CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_UNIPRO, CM_CLKMODE_DPLL_USB,
- * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
- * CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA, CM_CLKMODE_DPLL_MPU
+ * Used by CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
+ * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA,
+ * CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_UNIPRO,
+ * CM_CLKMODE_DPLL_USB
*/
#define OMAP4430_DPLL_SSC_ACK_SHIFT 13
-#define OMAP4430_DPLL_SSC_ACK_MASK BITFIELD(13, 13)
+#define OMAP4430_DPLL_SSC_ACK_MASK (1 << 13)
/*
- * Used by CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_UNIPRO, CM_CLKMODE_DPLL_USB,
- * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
- * CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA, CM_CLKMODE_DPLL_MPU
+ * Used by CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
+ * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA,
+ * CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_UNIPRO,
+ * CM_CLKMODE_DPLL_USB
*/
#define OMAP4430_DPLL_SSC_DOWNSPREAD_SHIFT 14
-#define OMAP4430_DPLL_SSC_DOWNSPREAD_MASK BITFIELD(14, 14)
+#define OMAP4430_DPLL_SSC_DOWNSPREAD_MASK (1 << 14)
/*
- * Used by CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_UNIPRO, CM_CLKMODE_DPLL_USB,
- * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
- * CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA, CM_CLKMODE_DPLL_MPU
+ * Used by CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
+ * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA,
+ * CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_UNIPRO,
+ * CM_CLKMODE_DPLL_USB
*/
#define OMAP4430_DPLL_SSC_EN_SHIFT 12
-#define OMAP4430_DPLL_SSC_EN_MASK BITFIELD(12, 12)
+#define OMAP4430_DPLL_SSC_EN_MASK (1 << 12)
-/* Used by CM_L3_2_DYNAMICDEP, CM_L4CFG_DYNAMICDEP, CM_L4PER_DYNAMICDEP */
+/*
+ * Used by CM_L3_2_DYNAMICDEP, CM_L3_2_DYNAMICDEP_RESTORE, CM_L4CFG_DYNAMICDEP,
+ * CM_L4CFG_DYNAMICDEP_RESTORE, CM_L4PER_DYNAMICDEP, CM_L4PER_DYNAMICDEP_RESTORE
+ */
#define OMAP4430_DSS_DYNDEP_SHIFT 8
-#define OMAP4430_DSS_DYNDEP_MASK BITFIELD(8, 8)
+#define OMAP4430_DSS_DYNDEP_MASK (1 << 8)
/*
- * Used by CM_DUCATI_STATICDEP, CM_SDMA_STATICDEP, CM_SDMA_STATICDEP_RESTORE,
- * CM_MPU_STATICDEP
+ * Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP, CM_SDMA_STATICDEP,
+ * CM_SDMA_STATICDEP_RESTORE
*/
#define OMAP4430_DSS_STATDEP_SHIFT 8
-#define OMAP4430_DSS_STATDEP_MASK BITFIELD(8, 8)
+#define OMAP4430_DSS_STATDEP_MASK (1 << 8)
-/* Used by CM_L3_2_DYNAMICDEP */
+/* Used by CM_L3_2_DYNAMICDEP, CM_L3_2_DYNAMICDEP_RESTORE */
#define OMAP4430_DUCATI_DYNDEP_SHIFT 0
-#define OMAP4430_DUCATI_DYNDEP_MASK BITFIELD(0, 0)
+#define OMAP4430_DUCATI_DYNDEP_MASK (1 << 0)
-/* Used by CM_SDMA_STATICDEP, CM_SDMA_STATICDEP_RESTORE, CM_MPU_STATICDEP */
+/* Used by CM_MPU_STATICDEP, CM_SDMA_STATICDEP, CM_SDMA_STATICDEP_RESTORE */
#define OMAP4430_DUCATI_STATDEP_SHIFT 0
-#define OMAP4430_DUCATI_STATDEP_MASK BITFIELD(0, 0)
+#define OMAP4430_DUCATI_STATDEP_MASK (1 << 0)
-/* Used by CM_SHADOW_FREQ_CONFIG1_RESTORE, CM_SHADOW_FREQ_CONFIG1 */
+/* Used by CM_SHADOW_FREQ_CONFIG1, CM_SHADOW_FREQ_CONFIG1_RESTORE */
#define OMAP4430_FREQ_UPDATE_SHIFT 0
-#define OMAP4430_FREQ_UPDATE_MASK BITFIELD(0, 0)
+#define OMAP4430_FREQ_UPDATE_MASK (1 << 0)
+
+/* Used by REVISION_CM1, REVISION_CM2 */
+#define OMAP4430_FUNC_SHIFT 16
+#define OMAP4430_FUNC_MASK (0xfff << 16)
-/* Used by CM_L3_2_DYNAMICDEP */
+/* Used by CM_L3_2_DYNAMICDEP, CM_L3_2_DYNAMICDEP_RESTORE */
#define OMAP4430_GFX_DYNDEP_SHIFT 10
-#define OMAP4430_GFX_DYNDEP_MASK BITFIELD(10, 10)
+#define OMAP4430_GFX_DYNDEP_MASK (1 << 10)
/* Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP */
#define OMAP4430_GFX_STATDEP_SHIFT 10
-#define OMAP4430_GFX_STATDEP_MASK BITFIELD(10, 10)
+#define OMAP4430_GFX_STATDEP_MASK (1 << 10)
-/* Used by CM_SHADOW_FREQ_CONFIG2 */
+/* Used by CM_SHADOW_FREQ_CONFIG2, CM_SHADOW_FREQ_CONFIG2_RESTORE */
#define OMAP4430_GPMC_FREQ_UPDATE_SHIFT 0
-#define OMAP4430_GPMC_FREQ_UPDATE_MASK BITFIELD(0, 0)
+#define OMAP4430_GPMC_FREQ_UPDATE_MASK (1 << 0)
/*
- * Used by CM_DIV_M4_DPLL_PER, CM_DIV_M4_DPLL_CORE_RESTORE,
- * CM_DIV_M4_DPLL_CORE, CM_DIV_M4_DPLL_DDRPHY, CM_DIV_M4_DPLL_IVA
+ * Used by CM_DIV_M4_DPLL_CORE, CM_DIV_M4_DPLL_CORE_RESTORE,
+ * CM_DIV_M4_DPLL_DDRPHY, CM_DIV_M4_DPLL_IVA, CM_DIV_M4_DPLL_PER
*/
#define OMAP4430_HSDIVIDER_CLKOUT1_DIV_SHIFT 0
-#define OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK BITFIELD(0, 4)
+#define OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK (0x1f << 0)
/*
- * Used by CM_DIV_M4_DPLL_PER, CM_DIV_M4_DPLL_CORE_RESTORE,
- * CM_DIV_M4_DPLL_CORE, CM_DIV_M4_DPLL_DDRPHY, CM_DIV_M4_DPLL_IVA
+ * Used by CM_DIV_M4_DPLL_CORE, CM_DIV_M4_DPLL_CORE_RESTORE,
+ * CM_DIV_M4_DPLL_DDRPHY, CM_DIV_M4_DPLL_IVA, CM_DIV_M4_DPLL_PER
*/
#define OMAP4430_HSDIVIDER_CLKOUT1_DIVCHACK_SHIFT 5
-#define OMAP4430_HSDIVIDER_CLKOUT1_DIVCHACK_MASK BITFIELD(5, 5)
+#define OMAP4430_HSDIVIDER_CLKOUT1_DIVCHACK_MASK (1 << 5)
/*
- * Used by CM_DIV_M4_DPLL_PER, CM_DIV_M4_DPLL_CORE_RESTORE,
- * CM_DIV_M4_DPLL_CORE, CM_DIV_M4_DPLL_DDRPHY, CM_DIV_M4_DPLL_IVA
+ * Used by CM_DIV_M4_DPLL_CORE, CM_DIV_M4_DPLL_CORE_RESTORE,
+ * CM_DIV_M4_DPLL_DDRPHY, CM_DIV_M4_DPLL_IVA, CM_DIV_M4_DPLL_PER
*/
#define OMAP4430_HSDIVIDER_CLKOUT1_GATE_CTRL_SHIFT 8
-#define OMAP4430_HSDIVIDER_CLKOUT1_GATE_CTRL_MASK BITFIELD(8, 8)
+#define OMAP4430_HSDIVIDER_CLKOUT1_GATE_CTRL_MASK (1 << 8)
/*
- * Used by CM_DIV_M4_DPLL_PER, CM_DIV_M4_DPLL_CORE_RESTORE,
- * CM_DIV_M4_DPLL_CORE, CM_DIV_M4_DPLL_DDRPHY, CM_DIV_M4_DPLL_IVA
+ * Used by CM_DIV_M4_DPLL_CORE, CM_DIV_M4_DPLL_CORE_RESTORE,
+ * CM_DIV_M4_DPLL_DDRPHY, CM_DIV_M4_DPLL_IVA, CM_DIV_M4_DPLL_PER
*/
#define OMAP4430_HSDIVIDER_CLKOUT1_PWDN_SHIFT 12
-#define OMAP4430_HSDIVIDER_CLKOUT1_PWDN_MASK BITFIELD(12, 12)
+#define OMAP4430_HSDIVIDER_CLKOUT1_PWDN_MASK (1 << 12)
/*
- * Used by CM_DIV_M5_DPLL_PER, CM_DIV_M5_DPLL_CORE_RESTORE,
- * CM_DIV_M5_DPLL_CORE, CM_DIV_M5_DPLL_DDRPHY, CM_DIV_M5_DPLL_IVA
+ * Used by CM_DIV_M5_DPLL_CORE, CM_DIV_M5_DPLL_CORE_RESTORE,
+ * CM_DIV_M5_DPLL_DDRPHY, CM_DIV_M5_DPLL_IVA, CM_DIV_M5_DPLL_PER
*/
#define OMAP4430_HSDIVIDER_CLKOUT2_DIV_SHIFT 0
-#define OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK BITFIELD(0, 4)
+#define OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK (0x1f << 0)
/*
- * Used by CM_DIV_M5_DPLL_PER, CM_DIV_M5_DPLL_CORE_RESTORE,
- * CM_DIV_M5_DPLL_CORE, CM_DIV_M5_DPLL_DDRPHY, CM_DIV_M5_DPLL_IVA
+ * Used by CM_DIV_M5_DPLL_CORE, CM_DIV_M5_DPLL_CORE_RESTORE,
+ * CM_DIV_M5_DPLL_DDRPHY, CM_DIV_M5_DPLL_IVA, CM_DIV_M5_DPLL_PER
*/
#define OMAP4430_HSDIVIDER_CLKOUT2_DIVCHACK_SHIFT 5
-#define OMAP4430_HSDIVIDER_CLKOUT2_DIVCHACK_MASK BITFIELD(5, 5)
+#define OMAP4430_HSDIVIDER_CLKOUT2_DIVCHACK_MASK (1 << 5)
/*
- * Used by CM_DIV_M5_DPLL_PER, CM_DIV_M5_DPLL_CORE_RESTORE,
- * CM_DIV_M5_DPLL_CORE, CM_DIV_M5_DPLL_DDRPHY, CM_DIV_M5_DPLL_IVA
+ * Used by CM_DIV_M5_DPLL_CORE, CM_DIV_M5_DPLL_CORE_RESTORE,
+ * CM_DIV_M5_DPLL_DDRPHY, CM_DIV_M5_DPLL_IVA, CM_DIV_M5_DPLL_PER
*/
#define OMAP4430_HSDIVIDER_CLKOUT2_GATE_CTRL_SHIFT 8
-#define OMAP4430_HSDIVIDER_CLKOUT2_GATE_CTRL_MASK BITFIELD(8, 8)
+#define OMAP4430_HSDIVIDER_CLKOUT2_GATE_CTRL_MASK (1 << 8)
/*
- * Used by CM_DIV_M5_DPLL_PER, CM_DIV_M5_DPLL_CORE_RESTORE,
- * CM_DIV_M5_DPLL_CORE, CM_DIV_M5_DPLL_DDRPHY, CM_DIV_M5_DPLL_IVA
+ * Used by CM_DIV_M5_DPLL_CORE, CM_DIV_M5_DPLL_CORE_RESTORE,
+ * CM_DIV_M5_DPLL_DDRPHY, CM_DIV_M5_DPLL_IVA, CM_DIV_M5_DPLL_PER
*/
#define OMAP4430_HSDIVIDER_CLKOUT2_PWDN_SHIFT 12
-#define OMAP4430_HSDIVIDER_CLKOUT2_PWDN_MASK BITFIELD(12, 12)
+#define OMAP4430_HSDIVIDER_CLKOUT2_PWDN_MASK (1 << 12)
/*
- * Used by CM_DIV_M6_DPLL_PER, CM_DIV_M6_DPLL_CORE_RESTORE,
- * CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_DDRPHY
+ * Used by CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_CORE_RESTORE,
+ * CM_DIV_M6_DPLL_DDRPHY, CM_DIV_M6_DPLL_PER
*/
#define OMAP4430_HSDIVIDER_CLKOUT3_DIV_SHIFT 0
-#define OMAP4430_HSDIVIDER_CLKOUT3_DIV_MASK BITFIELD(0, 4)
+#define OMAP4430_HSDIVIDER_CLKOUT3_DIV_MASK (0x1f << 0)
/*
- * Used by CM_DIV_M6_DPLL_PER, CM_DIV_M6_DPLL_CORE_RESTORE,
- * CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_DDRPHY
+ * Used by CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_CORE_RESTORE,
+ * CM_DIV_M6_DPLL_DDRPHY, CM_DIV_M6_DPLL_PER
*/
#define OMAP4430_HSDIVIDER_CLKOUT3_DIVCHACK_SHIFT 5
-#define OMAP4430_HSDIVIDER_CLKOUT3_DIVCHACK_MASK BITFIELD(5, 5)
+#define OMAP4430_HSDIVIDER_CLKOUT3_DIVCHACK_MASK (1 << 5)
/*
- * Used by CM_DIV_M6_DPLL_PER, CM_DIV_M6_DPLL_CORE_RESTORE,
- * CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_DDRPHY
+ * Used by CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_CORE_RESTORE,
+ * CM_DIV_M6_DPLL_DDRPHY, CM_DIV_M6_DPLL_PER
*/
#define OMAP4430_HSDIVIDER_CLKOUT3_GATE_CTRL_SHIFT 8
-#define OMAP4430_HSDIVIDER_CLKOUT3_GATE_CTRL_MASK BITFIELD(8, 8)
+#define OMAP4430_HSDIVIDER_CLKOUT3_GATE_CTRL_MASK (1 << 8)
/*
- * Used by CM_DIV_M6_DPLL_PER, CM_DIV_M6_DPLL_CORE_RESTORE,
- * CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_DDRPHY
+ * Used by CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_CORE_RESTORE,
+ * CM_DIV_M6_DPLL_DDRPHY, CM_DIV_M6_DPLL_PER
*/
#define OMAP4430_HSDIVIDER_CLKOUT3_PWDN_SHIFT 12
-#define OMAP4430_HSDIVIDER_CLKOUT3_PWDN_MASK BITFIELD(12, 12)
+#define OMAP4430_HSDIVIDER_CLKOUT3_PWDN_MASK (1 << 12)
/*
- * Used by CM_DIV_M7_DPLL_PER, CM_DIV_M7_DPLL_CORE_RESTORE,
- * CM_DIV_M7_DPLL_CORE
+ * Used by CM_DIV_M7_DPLL_CORE, CM_DIV_M7_DPLL_CORE_RESTORE,
+ * CM_DIV_M7_DPLL_PER
*/
#define OMAP4430_HSDIVIDER_CLKOUT4_DIV_SHIFT 0
-#define OMAP4430_HSDIVIDER_CLKOUT4_DIV_MASK BITFIELD(0, 4)
+#define OMAP4430_HSDIVIDER_CLKOUT4_DIV_MASK (0x1f << 0)
/*
- * Used by CM_DIV_M7_DPLL_PER, CM_DIV_M7_DPLL_CORE_RESTORE,
- * CM_DIV_M7_DPLL_CORE
+ * Used by CM_DIV_M7_DPLL_CORE, CM_DIV_M7_DPLL_CORE_RESTORE,
+ * CM_DIV_M7_DPLL_PER
*/
#define OMAP4430_HSDIVIDER_CLKOUT4_DIVCHACK_SHIFT 5
-#define OMAP4430_HSDIVIDER_CLKOUT4_DIVCHACK_MASK BITFIELD(5, 5)
+#define OMAP4430_HSDIVIDER_CLKOUT4_DIVCHACK_MASK (1 << 5)
/*
- * Used by CM_DIV_M7_DPLL_PER, CM_DIV_M7_DPLL_CORE_RESTORE,
- * CM_DIV_M7_DPLL_CORE
+ * Used by CM_DIV_M7_DPLL_CORE, CM_DIV_M7_DPLL_CORE_RESTORE,
+ * CM_DIV_M7_DPLL_PER
*/
#define OMAP4430_HSDIVIDER_CLKOUT4_GATE_CTRL_SHIFT 8
-#define OMAP4430_HSDIVIDER_CLKOUT4_GATE_CTRL_MASK BITFIELD(8, 8)
+#define OMAP4430_HSDIVIDER_CLKOUT4_GATE_CTRL_MASK (1 << 8)
/*
- * Used by CM_DIV_M7_DPLL_PER, CM_DIV_M7_DPLL_CORE_RESTORE,
- * CM_DIV_M7_DPLL_CORE
+ * Used by CM_DIV_M7_DPLL_CORE, CM_DIV_M7_DPLL_CORE_RESTORE,
+ * CM_DIV_M7_DPLL_PER
*/
#define OMAP4430_HSDIVIDER_CLKOUT4_PWDN_SHIFT 12
-#define OMAP4430_HSDIVIDER_CLKOUT4_PWDN_MASK BITFIELD(12, 12)
-
-/*
- * Used by PRM_PRM_PROFILING_CLKCTRL, CM_WKUP_GPIO1_CLKCTRL,
- * CM_WKUP_KEYBOARD_CLKCTRL, CM_WKUP_L4WKUP_CLKCTRL, CM_WKUP_RTC_CLKCTRL,
- * CM_WKUP_SARRAM_CLKCTRL, CM_WKUP_SYNCTIMER_CLKCTRL, CM_WKUP_TIMER12_CLKCTRL,
- * CM_WKUP_TIMER1_CLKCTRL, CM_WKUP_USIM_CLKCTRL, CM_WKUP_WDT1_CLKCTRL,
- * CM_WKUP_WDT2_CLKCTRL, CM_EMU_DEBUGSS_CLKCTRL, CM_D2D_MODEM_ICR_CLKCTRL,
- * CM_D2D_SAD2D_CLKCTRL, CM_D2D_SAD2D_FW_CLKCTRL, CM_DUCATI_DUCATI_CLKCTRL,
- * CM_L3INSTR_L3_3_CLKCTRL, CM_L3INSTR_L3_INSTR_CLKCTRL,
- * CM_L3INSTR_OCP_WP1_CLKCTRL, CM_L3_1_L3_1_CLKCTRL, CM_L3_2_GPMC_CLKCTRL,
- * CM_L3_2_L3_2_CLKCTRL, CM_L3_2_OCMC_RAM_CLKCTRL, CM_L4CFG_HW_SEM_CLKCTRL,
- * CM_L4CFG_L4_CFG_CLKCTRL, CM_L4CFG_MAILBOX_CLKCTRL, CM_L4CFG_SAR_ROM_CLKCTRL,
- * CM_MEMIF_DMM_CLKCTRL, CM_MEMIF_EMIF_1_CLKCTRL, CM_MEMIF_EMIF_2_CLKCTRL,
- * CM_MEMIF_EMIF_FW_CLKCTRL, CM_MEMIF_EMIF_H1_CLKCTRL,
- * CM_MEMIF_EMIF_H2_CLKCTRL, CM_SDMA_SDMA_CLKCTRL, CM_GFX_GFX_CLKCTRL,
- * CM_L4PER_ADC_CLKCTRL, CM_L4PER_DMTIMER10_CLKCTRL,
- * CM_L4PER_DMTIMER11_CLKCTRL, CM_L4PER_DMTIMER2_CLKCTRL,
- * CM_L4PER_DMTIMER3_CLKCTRL, CM_L4PER_DMTIMER4_CLKCTRL,
- * CM_L4PER_DMTIMER9_CLKCTRL, CM_L4PER_ELM_CLKCTRL, CM_L4PER_GPIO2_CLKCTRL,
- * CM_L4PER_GPIO3_CLKCTRL, CM_L4PER_GPIO4_CLKCTRL, CM_L4PER_GPIO5_CLKCTRL,
- * CM_L4PER_GPIO6_CLKCTRL, CM_L4PER_HDQ1W_CLKCTRL, CM_L4PER_HECC1_CLKCTRL,
- * CM_L4PER_HECC2_CLKCTRL, CM_L4PER_I2C1_CLKCTRL, CM_L4PER_I2C2_CLKCTRL,
- * CM_L4PER_I2C3_CLKCTRL, CM_L4PER_I2C4_CLKCTRL, CM_L4PER_I2C5_CLKCTRL,
- * CM_L4PER_L4PER_CLKCTRL, CM_L4PER_MCASP2_CLKCTRL, CM_L4PER_MCASP3_CLKCTRL,
- * CM_L4PER_MCBSP4_CLKCTRL, CM_L4PER_MCSPI1_CLKCTRL, CM_L4PER_MCSPI2_CLKCTRL,
- * CM_L4PER_MCSPI3_CLKCTRL, CM_L4PER_MCSPI4_CLKCTRL, CM_L4PER_MGATE_CLKCTRL,
- * CM_L4PER_MMCSD3_CLKCTRL, CM_L4PER_MMCSD4_CLKCTRL, CM_L4PER_MMCSD5_CLKCTRL,
- * CM_L4PER_MSPROHG_CLKCTRL, CM_L4PER_SLIMBUS2_CLKCTRL, CM_L4PER_UART1_CLKCTRL,
- * CM_L4PER_UART2_CLKCTRL, CM_L4PER_UART3_CLKCTRL, CM_L4PER_UART4_CLKCTRL,
- * CM_L4SEC_AES1_CLKCTRL, CM_L4SEC_AES2_CLKCTRL, CM_L4SEC_CRYPTODMA_CLKCTRL,
- * CM_L4SEC_DES3DES_CLKCTRL, CM_L4SEC_PKAEIP29_CLKCTRL, CM_L4SEC_RNG_CLKCTRL,
- * CM_L4SEC_SHA2MD51_CLKCTRL, CM_L3INIT_CCPTX_CLKCTRL, CM_L3INIT_EMAC_CLKCTRL,
+#define OMAP4430_HSDIVIDER_CLKOUT4_PWDN_MASK (1 << 12)
+
+/*
+ * Used by CM1_ABE_AESS_CLKCTRL, CM1_ABE_DMIC_CLKCTRL, CM1_ABE_L4ABE_CLKCTRL,
+ * CM1_ABE_MCASP_CLKCTRL, CM1_ABE_MCBSP1_CLKCTRL, CM1_ABE_MCBSP2_CLKCTRL,
+ * CM1_ABE_MCBSP3_CLKCTRL, CM1_ABE_PDM_CLKCTRL, CM1_ABE_SLIMBUS_CLKCTRL,
+ * CM1_ABE_TIMER5_CLKCTRL, CM1_ABE_TIMER6_CLKCTRL, CM1_ABE_TIMER7_CLKCTRL,
+ * CM1_ABE_TIMER8_CLKCTRL, CM1_ABE_WDT3_CLKCTRL, CM_ALWON_MDMINTC_CLKCTRL,
+ * CM_ALWON_SR_CORE_CLKCTRL, CM_ALWON_SR_IVA_CLKCTRL, CM_ALWON_SR_MPU_CLKCTRL,
+ * CM_CAM_FDIF_CLKCTRL, CM_CAM_ISS_CLKCTRL, CM_CEFUSE_CEFUSE_CLKCTRL,
+ * CM_CM1_PROFILING_CLKCTRL, CM_CM1_PROFILING_CLKCTRL_RESTORE,
+ * CM_CM2_PROFILING_CLKCTRL, CM_CM2_PROFILING_CLKCTRL_RESTORE,
+ * CM_D2D_MODEM_ICR_CLKCTRL, CM_D2D_SAD2D_CLKCTRL, CM_D2D_SAD2D_FW_CLKCTRL,
+ * CM_DSS_DEISS_CLKCTRL, CM_DSS_DSS_CLKCTRL, CM_DUCATI_DUCATI_CLKCTRL,
+ * CM_EMU_DEBUGSS_CLKCTRL, CM_GFX_GFX_CLKCTRL, CM_IVAHD_IVAHD_CLKCTRL,
+ * CM_IVAHD_SL2_CLKCTRL, CM_L3INIT_CCPTX_CLKCTRL, CM_L3INIT_EMAC_CLKCTRL,
* CM_L3INIT_HSI_CLKCTRL, CM_L3INIT_MMC1_CLKCTRL, CM_L3INIT_MMC2_CLKCTRL,
* CM_L3INIT_MMC6_CLKCTRL, CM_L3INIT_P1500_CLKCTRL, CM_L3INIT_PCIESS_CLKCTRL,
* CM_L3INIT_SATA_CLKCTRL, CM_L3INIT_TPPSS_CLKCTRL, CM_L3INIT_UNIPRO1_CLKCTRL,
* CM_L3INIT_USBPHYOCP2SCP_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL,
- * CM_L3INIT_USB_HOST_FS_CLKCTRL, CM_L3INIT_USB_OTG_CLKCTRL,
- * CM_L3INIT_USB_TLL_CLKCTRL, CM_L3INIT_XHPI_CLKCTRL, CM_CAM_FDIF_CLKCTRL,
- * CM_CAM_ISS_CLKCTRL, CM_CEFUSE_CEFUSE_CLKCTRL,
- * CM_L3INIT_USB_HOST_CLKCTRL_RESTORE, CM_L3INIT_USB_TLL_CLKCTRL_RESTORE,
- * CM_L3INSTR_L3_3_CLKCTRL_RESTORE, CM_L3INSTR_L3_INSTR_CLKCTRL_RESTORE,
- * CM_L3INSTR_OCP_WP1_CLKCTRL_RESTORE, CM_L4PER_GPIO2_CLKCTRL_RESTORE,
- * CM_L4PER_GPIO3_CLKCTRL_RESTORE, CM_L4PER_GPIO4_CLKCTRL_RESTORE,
- * CM_L4PER_GPIO5_CLKCTRL_RESTORE, CM_L4PER_GPIO6_CLKCTRL_RESTORE,
- * CM_ALWON_MDMINTC_CLKCTRL, CM_ALWON_SR_CORE_CLKCTRL, CM_ALWON_SR_IVA_CLKCTRL,
- * CM_ALWON_SR_MPU_CLKCTRL, CM_IVAHD_IVAHD_CLKCTRL, CM_IVAHD_SL2_CLKCTRL,
- * CM_DSS_DEISS_CLKCTRL, CM_DSS_DSS_CLKCTRL, CM_CM2_PROFILING_CLKCTRL,
- * CM_MPU_MPU_CLKCTRL, CM_TESLA_TESLA_CLKCTRL, CM1_ABE_AESS_CLKCTRL,
- * CM1_ABE_DMIC_CLKCTRL, CM1_ABE_L4ABE_CLKCTRL, CM1_ABE_MCASP_CLKCTRL,
- * CM1_ABE_MCBSP1_CLKCTRL, CM1_ABE_MCBSP2_CLKCTRL, CM1_ABE_MCBSP3_CLKCTRL,
- * CM1_ABE_PDM_CLKCTRL, CM1_ABE_SLIMBUS_CLKCTRL, CM1_ABE_TIMER5_CLKCTRL,
- * CM1_ABE_TIMER6_CLKCTRL, CM1_ABE_TIMER7_CLKCTRL, CM1_ABE_TIMER8_CLKCTRL,
- * CM1_ABE_WDT3_CLKCTRL, CM_CM1_PROFILING_CLKCTRL
+ * CM_L3INIT_USB_HOST_CLKCTRL_RESTORE, CM_L3INIT_USB_HOST_FS_CLKCTRL,
+ * CM_L3INIT_USB_OTG_CLKCTRL, CM_L3INIT_USB_TLL_CLKCTRL,
+ * CM_L3INIT_USB_TLL_CLKCTRL_RESTORE, CM_L3INIT_XHPI_CLKCTRL,
+ * CM_L3INSTR_L3_3_CLKCTRL, CM_L3INSTR_L3_3_CLKCTRL_RESTORE,
+ * CM_L3INSTR_L3_INSTR_CLKCTRL, CM_L3INSTR_L3_INSTR_CLKCTRL_RESTORE,
+ * CM_L3INSTR_OCP_WP1_CLKCTRL, CM_L3INSTR_OCP_WP1_CLKCTRL_RESTORE,
+ * CM_L3_1_L3_1_CLKCTRL, CM_L3_2_GPMC_CLKCTRL, CM_L3_2_L3_2_CLKCTRL,
+ * CM_L3_2_OCMC_RAM_CLKCTRL, CM_L4CFG_HW_SEM_CLKCTRL, CM_L4CFG_L4_CFG_CLKCTRL,
+ * CM_L4CFG_MAILBOX_CLKCTRL, CM_L4CFG_SAR_ROM_CLKCTRL, CM_L4PER_ADC_CLKCTRL,
+ * CM_L4PER_DMTIMER10_CLKCTRL, CM_L4PER_DMTIMER11_CLKCTRL,
+ * CM_L4PER_DMTIMER2_CLKCTRL, CM_L4PER_DMTIMER3_CLKCTRL,
+ * CM_L4PER_DMTIMER4_CLKCTRL, CM_L4PER_DMTIMER9_CLKCTRL, CM_L4PER_ELM_CLKCTRL,
+ * CM_L4PER_GPIO2_CLKCTRL, CM_L4PER_GPIO2_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO3_CLKCTRL, CM_L4PER_GPIO3_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO4_CLKCTRL, CM_L4PER_GPIO4_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO5_CLKCTRL, CM_L4PER_GPIO5_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO6_CLKCTRL, CM_L4PER_GPIO6_CLKCTRL_RESTORE,
+ * CM_L4PER_HDQ1W_CLKCTRL, CM_L4PER_HECC1_CLKCTRL, CM_L4PER_HECC2_CLKCTRL,
+ * CM_L4PER_I2C1_CLKCTRL, CM_L4PER_I2C2_CLKCTRL, CM_L4PER_I2C3_CLKCTRL,
+ * CM_L4PER_I2C4_CLKCTRL, CM_L4PER_I2C5_CLKCTRL, CM_L4PER_L4PER_CLKCTRL,
+ * CM_L4PER_MCASP2_CLKCTRL, CM_L4PER_MCASP3_CLKCTRL, CM_L4PER_MCBSP4_CLKCTRL,
+ * CM_L4PER_MCSPI1_CLKCTRL, CM_L4PER_MCSPI2_CLKCTRL, CM_L4PER_MCSPI3_CLKCTRL,
+ * CM_L4PER_MCSPI4_CLKCTRL, CM_L4PER_MGATE_CLKCTRL, CM_L4PER_MMCSD3_CLKCTRL,
+ * CM_L4PER_MMCSD4_CLKCTRL, CM_L4PER_MMCSD5_CLKCTRL, CM_L4PER_MSPROHG_CLKCTRL,
+ * CM_L4PER_SLIMBUS2_CLKCTRL, CM_L4PER_UART1_CLKCTRL, CM_L4PER_UART2_CLKCTRL,
+ * CM_L4PER_UART3_CLKCTRL, CM_L4PER_UART4_CLKCTRL, CM_L4SEC_AES1_CLKCTRL,
+ * CM_L4SEC_AES2_CLKCTRL, CM_L4SEC_CRYPTODMA_CLKCTRL, CM_L4SEC_DES3DES_CLKCTRL,
+ * CM_L4SEC_PKAEIP29_CLKCTRL, CM_L4SEC_RNG_CLKCTRL, CM_L4SEC_SHA2MD51_CLKCTRL,
+ * CM_MEMIF_DMM_CLKCTRL, CM_MEMIF_EMIF_1_CLKCTRL, CM_MEMIF_EMIF_2_CLKCTRL,
+ * CM_MEMIF_EMIF_FW_CLKCTRL, CM_MEMIF_EMIF_H1_CLKCTRL,
+ * CM_MEMIF_EMIF_H2_CLKCTRL, CM_MPU_MPU_CLKCTRL, CM_SDMA_SDMA_CLKCTRL,
+ * CM_TESLA_TESLA_CLKCTRL, CM_WKUP_GPIO1_CLKCTRL, CM_WKUP_KEYBOARD_CLKCTRL,
+ * CM_WKUP_L4WKUP_CLKCTRL, CM_WKUP_RTC_CLKCTRL, CM_WKUP_SARRAM_CLKCTRL,
+ * CM_WKUP_SYNCTIMER_CLKCTRL, CM_WKUP_TIMER12_CLKCTRL, CM_WKUP_TIMER1_CLKCTRL,
+ * CM_WKUP_USIM_CLKCTRL, CM_WKUP_WDT1_CLKCTRL, CM_WKUP_WDT2_CLKCTRL
*/
#define OMAP4430_IDLEST_SHIFT 16
-#define OMAP4430_IDLEST_MASK BITFIELD(16, 17)
+#define OMAP4430_IDLEST_MASK (0x3 << 16)
-/* Used by CM_DUCATI_DYNAMICDEP, CM_L3_2_DYNAMICDEP, CM_L4CFG_DYNAMICDEP */
+/*
+ * Used by CM_DUCATI_DYNAMICDEP, CM_L3_2_DYNAMICDEP,
+ * CM_L3_2_DYNAMICDEP_RESTORE, CM_L4CFG_DYNAMICDEP, CM_L4CFG_DYNAMICDEP_RESTORE
+ */
#define OMAP4430_ISS_DYNDEP_SHIFT 9
-#define OMAP4430_ISS_DYNDEP_MASK BITFIELD(9, 9)
+#define OMAP4430_ISS_DYNDEP_MASK (1 << 9)
/*
- * Used by CM_DUCATI_STATICDEP, CM_SDMA_STATICDEP, CM_SDMA_STATICDEP_RESTORE,
- * CM_MPU_STATICDEP, CM_TESLA_STATICDEP
+ * Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP, CM_SDMA_STATICDEP,
+ * CM_SDMA_STATICDEP_RESTORE, CM_TESLA_STATICDEP
*/
#define OMAP4430_ISS_STATDEP_SHIFT 9
-#define OMAP4430_ISS_STATDEP_MASK BITFIELD(9, 9)
+#define OMAP4430_ISS_STATDEP_MASK (1 << 9)
-/* Used by CM_L3_2_DYNAMICDEP, CM_TESLA_DYNAMICDEP */
+/* Used by CM_L3_2_DYNAMICDEP, CM_L3_2_DYNAMICDEP_RESTORE, CM_TESLA_DYNAMICDEP */
#define OMAP4430_IVAHD_DYNDEP_SHIFT 2
-#define OMAP4430_IVAHD_DYNDEP_MASK BITFIELD(2, 2)
+#define OMAP4430_IVAHD_DYNDEP_MASK (1 << 2)
/*
- * Used by CM_D2D_STATICDEP, CM_DUCATI_STATICDEP, CM_SDMA_STATICDEP,
- * CM_GFX_STATICDEP, CM_L3INIT_STATICDEP, CM_CAM_STATICDEP,
- * CM_SDMA_STATICDEP_RESTORE, CM_DSS_STATICDEP, CM_MPU_STATICDEP,
- * CM_TESLA_STATICDEP
+ * Used by CM_CAM_STATICDEP, CM_D2D_STATICDEP, CM_D2D_STATICDEP_RESTORE,
+ * CM_DSS_STATICDEP, CM_DUCATI_STATICDEP, CM_GFX_STATICDEP,
+ * CM_L3INIT_STATICDEP, CM_MPU_STATICDEP, CM_SDMA_STATICDEP,
+ * CM_SDMA_STATICDEP_RESTORE, CM_TESLA_STATICDEP
*/
#define OMAP4430_IVAHD_STATDEP_SHIFT 2
-#define OMAP4430_IVAHD_STATDEP_MASK BITFIELD(2, 2)
+#define OMAP4430_IVAHD_STATDEP_MASK (1 << 2)
-/* Used by CM_L3_2_DYNAMICDEP, CM_L4CFG_DYNAMICDEP, CM_L4PER_DYNAMICDEP */
+/*
+ * Used by CM_L3_2_DYNAMICDEP, CM_L3_2_DYNAMICDEP_RESTORE, CM_L4CFG_DYNAMICDEP,
+ * CM_L4CFG_DYNAMICDEP_RESTORE, CM_L4PER_DYNAMICDEP, CM_L4PER_DYNAMICDEP_RESTORE
+ */
#define OMAP4430_L3INIT_DYNDEP_SHIFT 7
-#define OMAP4430_L3INIT_DYNDEP_MASK BITFIELD(7, 7)
+#define OMAP4430_L3INIT_DYNDEP_MASK (1 << 7)
/*
- * Used by CM_D2D_STATICDEP, CM_DUCATI_STATICDEP, CM_SDMA_STATICDEP,
- * CM_SDMA_STATICDEP_RESTORE, CM_MPU_STATICDEP, CM_TESLA_STATICDEP
+ * Used by CM_D2D_STATICDEP, CM_D2D_STATICDEP_RESTORE, CM_DUCATI_STATICDEP,
+ * CM_MPU_STATICDEP, CM_SDMA_STATICDEP, CM_SDMA_STATICDEP_RESTORE,
+ * CM_TESLA_STATICDEP
*/
#define OMAP4430_L3INIT_STATDEP_SHIFT 7
-#define OMAP4430_L3INIT_STATDEP_MASK BITFIELD(7, 7)
+#define OMAP4430_L3INIT_STATDEP_MASK (1 << 7)
/*
- * Used by CM_L3_2_DYNAMICDEP, CM_L4CFG_DYNAMICDEP, CM_L3INIT_DYNAMICDEP,
- * CM_DSS_DYNAMICDEP, CM_MPU_DYNAMICDEP, CM_TESLA_DYNAMICDEP
+ * Used by CM_DSS_DYNAMICDEP, CM_L3INIT_DYNAMICDEP, CM_L3_2_DYNAMICDEP,
+ * CM_L3_2_DYNAMICDEP_RESTORE, CM_L4CFG_DYNAMICDEP,
+ * CM_L4CFG_DYNAMICDEP_RESTORE, CM_MPU_DYNAMICDEP, CM_TESLA_DYNAMICDEP
*/
#define OMAP4430_L3_1_DYNDEP_SHIFT 5
-#define OMAP4430_L3_1_DYNDEP_MASK BITFIELD(5, 5)
+#define OMAP4430_L3_1_DYNDEP_MASK (1 << 5)
/*
- * Used by CM_D2D_STATICDEP, CM_DUCATI_STATICDEP, CM_SDMA_STATICDEP,
- * CM_GFX_STATICDEP, CM_L4SEC_STATICDEP, CM_L3INIT_STATICDEP, CM_CAM_STATICDEP,
- * CM_SDMA_STATICDEP_RESTORE, CM_IVAHD_STATICDEP, CM_DSS_STATICDEP,
- * CM_MPU_STATICDEP, CM_TESLA_STATICDEP
+ * Used by CM_CAM_STATICDEP, CM_D2D_STATICDEP, CM_D2D_STATICDEP_RESTORE,
+ * CM_DSS_STATICDEP, CM_DUCATI_STATICDEP, CM_GFX_STATICDEP, CM_IVAHD_STATICDEP,
+ * CM_L3INIT_STATICDEP, CM_L4SEC_STATICDEP, CM_MPU_STATICDEP,
+ * CM_SDMA_STATICDEP, CM_SDMA_STATICDEP_RESTORE, CM_TESLA_STATICDEP
*/
#define OMAP4430_L3_1_STATDEP_SHIFT 5
-#define OMAP4430_L3_1_STATDEP_MASK BITFIELD(5, 5)
+#define OMAP4430_L3_1_STATDEP_MASK (1 << 5)
/*
- * Used by CM_EMU_DYNAMICDEP, CM_D2D_DYNAMICDEP, CM_DUCATI_DYNAMICDEP,
- * CM_L3_1_DYNAMICDEP, CM_L4CFG_DYNAMICDEP, CM_SDMA_DYNAMICDEP,
- * CM_GFX_DYNAMICDEP, CM_L4SEC_DYNAMICDEP, CM_L3INIT_DYNAMICDEP,
- * CM_CAM_DYNAMICDEP, CM_IVAHD_DYNAMICDEP
+ * Used by CM_CAM_DYNAMICDEP, CM_D2D_DYNAMICDEP, CM_D2D_DYNAMICDEP_RESTORE,
+ * CM_DUCATI_DYNAMICDEP, CM_EMU_DYNAMICDEP, CM_GFX_DYNAMICDEP,
+ * CM_IVAHD_DYNAMICDEP, CM_L3INIT_DYNAMICDEP, CM_L3_1_DYNAMICDEP,
+ * CM_L3_1_DYNAMICDEP_RESTORE, CM_L4CFG_DYNAMICDEP,
+ * CM_L4CFG_DYNAMICDEP_RESTORE, CM_L4SEC_DYNAMICDEP, CM_SDMA_DYNAMICDEP
*/
#define OMAP4430_L3_2_DYNDEP_SHIFT 6
-#define OMAP4430_L3_2_DYNDEP_MASK BITFIELD(6, 6)
+#define OMAP4430_L3_2_DYNDEP_MASK (1 << 6)
/*
- * Used by CM_D2D_STATICDEP, CM_DUCATI_STATICDEP, CM_SDMA_STATICDEP,
- * CM_GFX_STATICDEP, CM_L4SEC_STATICDEP, CM_L3INIT_STATICDEP, CM_CAM_STATICDEP,
- * CM_SDMA_STATICDEP_RESTORE, CM_IVAHD_STATICDEP, CM_DSS_STATICDEP,
- * CM_MPU_STATICDEP, CM_TESLA_STATICDEP
+ * Used by CM_CAM_STATICDEP, CM_D2D_STATICDEP, CM_D2D_STATICDEP_RESTORE,
+ * CM_DSS_STATICDEP, CM_DUCATI_STATICDEP, CM_GFX_STATICDEP, CM_IVAHD_STATICDEP,
+ * CM_L3INIT_STATICDEP, CM_L4SEC_STATICDEP, CM_MPU_STATICDEP,
+ * CM_SDMA_STATICDEP, CM_SDMA_STATICDEP_RESTORE, CM_TESLA_STATICDEP
*/
#define OMAP4430_L3_2_STATDEP_SHIFT 6
-#define OMAP4430_L3_2_STATDEP_MASK BITFIELD(6, 6)
+#define OMAP4430_L3_2_STATDEP_MASK (1 << 6)
-/* Used by CM_L3_1_DYNAMICDEP */
+/* Used by CM_L3_1_DYNAMICDEP, CM_L3_1_DYNAMICDEP_RESTORE */
#define OMAP4430_L4CFG_DYNDEP_SHIFT 12
-#define OMAP4430_L4CFG_DYNDEP_MASK BITFIELD(12, 12)
+#define OMAP4430_L4CFG_DYNDEP_MASK (1 << 12)
/*
- * Used by CM_D2D_STATICDEP, CM_DUCATI_STATICDEP, CM_SDMA_STATICDEP,
- * CM_L3INIT_STATICDEP, CM_SDMA_STATICDEP_RESTORE, CM_MPU_STATICDEP,
- * CM_TESLA_STATICDEP
+ * Used by CM_D2D_STATICDEP, CM_D2D_STATICDEP_RESTORE, CM_DUCATI_STATICDEP,
+ * CM_L3INIT_STATICDEP, CM_MPU_STATICDEP, CM_SDMA_STATICDEP,
+ * CM_SDMA_STATICDEP_RESTORE, CM_TESLA_STATICDEP
*/
#define OMAP4430_L4CFG_STATDEP_SHIFT 12
-#define OMAP4430_L4CFG_STATDEP_MASK BITFIELD(12, 12)
+#define OMAP4430_L4CFG_STATDEP_MASK (1 << 12)
-/* Used by CM_L3_2_DYNAMICDEP */
+/* Used by CM_L3_2_DYNAMICDEP, CM_L3_2_DYNAMICDEP_RESTORE */
#define OMAP4430_L4PER_DYNDEP_SHIFT 13
-#define OMAP4430_L4PER_DYNDEP_MASK BITFIELD(13, 13)
+#define OMAP4430_L4PER_DYNDEP_MASK (1 << 13)
/*
- * Used by CM_D2D_STATICDEP, CM_DUCATI_STATICDEP, CM_SDMA_STATICDEP,
- * CM_L4SEC_STATICDEP, CM_L3INIT_STATICDEP, CM_SDMA_STATICDEP_RESTORE,
- * CM_MPU_STATICDEP, CM_TESLA_STATICDEP
+ * Used by CM_D2D_STATICDEP, CM_D2D_STATICDEP_RESTORE, CM_DUCATI_STATICDEP,
+ * CM_L3INIT_STATICDEP, CM_L4SEC_STATICDEP, CM_MPU_STATICDEP,
+ * CM_SDMA_STATICDEP, CM_SDMA_STATICDEP_RESTORE, CM_TESLA_STATICDEP
*/
#define OMAP4430_L4PER_STATDEP_SHIFT 13
-#define OMAP4430_L4PER_STATDEP_MASK BITFIELD(13, 13)
+#define OMAP4430_L4PER_STATDEP_MASK (1 << 13)
-/* Used by CM_L3_2_DYNAMICDEP, CM_L4PER_DYNAMICDEP */
+/*
+ * Used by CM_L3_2_DYNAMICDEP, CM_L3_2_DYNAMICDEP_RESTORE, CM_L4PER_DYNAMICDEP,
+ * CM_L4PER_DYNAMICDEP_RESTORE
+ */
#define OMAP4430_L4SEC_DYNDEP_SHIFT 14
-#define OMAP4430_L4SEC_DYNDEP_MASK BITFIELD(14, 14)
+#define OMAP4430_L4SEC_DYNDEP_MASK (1 << 14)
/*
- * Used by CM_DUCATI_STATICDEP, CM_SDMA_STATICDEP, CM_L3INIT_STATICDEP,
- * CM_SDMA_STATICDEP_RESTORE, CM_MPU_STATICDEP
+ * Used by CM_DUCATI_STATICDEP, CM_L3INIT_STATICDEP, CM_MPU_STATICDEP,
+ * CM_SDMA_STATICDEP, CM_SDMA_STATICDEP_RESTORE
*/
#define OMAP4430_L4SEC_STATDEP_SHIFT 14
-#define OMAP4430_L4SEC_STATDEP_MASK BITFIELD(14, 14)
+#define OMAP4430_L4SEC_STATDEP_MASK (1 << 14)
-/* Used by CM_L4CFG_DYNAMICDEP */
+/* Used by CM_L4CFG_DYNAMICDEP, CM_L4CFG_DYNAMICDEP_RESTORE */
#define OMAP4430_L4WKUP_DYNDEP_SHIFT 15
-#define OMAP4430_L4WKUP_DYNDEP_MASK BITFIELD(15, 15)
+#define OMAP4430_L4WKUP_DYNDEP_MASK (1 << 15)
/*
- * Used by CM_DUCATI_STATICDEP, CM_SDMA_STATICDEP, CM_L3INIT_STATICDEP,
- * CM_SDMA_STATICDEP_RESTORE, CM_MPU_STATICDEP, CM_TESLA_STATICDEP
+ * Used by CM_DUCATI_STATICDEP, CM_L3INIT_STATICDEP, CM_MPU_STATICDEP,
+ * CM_SDMA_STATICDEP, CM_SDMA_STATICDEP_RESTORE, CM_TESLA_STATICDEP
*/
#define OMAP4430_L4WKUP_STATDEP_SHIFT 15
-#define OMAP4430_L4WKUP_STATDEP_MASK BITFIELD(15, 15)
+#define OMAP4430_L4WKUP_STATDEP_MASK (1 << 15)
/*
- * Used by CM_D2D_DYNAMICDEP, CM_L3_1_DYNAMICDEP, CM_L4CFG_DYNAMICDEP,
- * CM_MPU_DYNAMICDEP
+ * Used by CM_D2D_DYNAMICDEP, CM_D2D_DYNAMICDEP_RESTORE, CM_L3_1_DYNAMICDEP,
+ * CM_L3_1_DYNAMICDEP_RESTORE, CM_L4CFG_DYNAMICDEP,
+ * CM_L4CFG_DYNAMICDEP_RESTORE, CM_MPU_DYNAMICDEP
*/
#define OMAP4430_MEMIF_DYNDEP_SHIFT 4
-#define OMAP4430_MEMIF_DYNDEP_MASK BITFIELD(4, 4)
+#define OMAP4430_MEMIF_DYNDEP_MASK (1 << 4)
/*
- * Used by CM_D2D_STATICDEP, CM_DUCATI_STATICDEP, CM_SDMA_STATICDEP,
- * CM_GFX_STATICDEP, CM_L4SEC_STATICDEP, CM_L3INIT_STATICDEP, CM_CAM_STATICDEP,
- * CM_SDMA_STATICDEP_RESTORE, CM_IVAHD_STATICDEP, CM_DSS_STATICDEP,
- * CM_MPU_STATICDEP, CM_TESLA_STATICDEP
+ * Used by CM_CAM_STATICDEP, CM_D2D_STATICDEP, CM_D2D_STATICDEP_RESTORE,
+ * CM_DSS_STATICDEP, CM_DUCATI_STATICDEP, CM_GFX_STATICDEP, CM_IVAHD_STATICDEP,
+ * CM_L3INIT_STATICDEP, CM_L4SEC_STATICDEP, CM_MPU_STATICDEP,
+ * CM_SDMA_STATICDEP, CM_SDMA_STATICDEP_RESTORE, CM_TESLA_STATICDEP
*/
#define OMAP4430_MEMIF_STATDEP_SHIFT 4
-#define OMAP4430_MEMIF_STATDEP_MASK BITFIELD(4, 4)
+#define OMAP4430_MEMIF_STATDEP_MASK (1 << 4)
/*
- * Used by CM_SSC_MODFREQDIV_DPLL_PER, CM_SSC_MODFREQDIV_DPLL_UNIPRO,
- * CM_SSC_MODFREQDIV_DPLL_USB, CM_SSC_MODFREQDIV_DPLL_CORE_RESTORE,
- * CM_SSC_MODFREQDIV_DPLL_ABE, CM_SSC_MODFREQDIV_DPLL_CORE,
- * CM_SSC_MODFREQDIV_DPLL_DDRPHY, CM_SSC_MODFREQDIV_DPLL_IVA,
- * CM_SSC_MODFREQDIV_DPLL_MPU
+ * Used by CM_SSC_MODFREQDIV_DPLL_ABE, CM_SSC_MODFREQDIV_DPLL_CORE,
+ * CM_SSC_MODFREQDIV_DPLL_CORE_RESTORE, CM_SSC_MODFREQDIV_DPLL_DDRPHY,
+ * CM_SSC_MODFREQDIV_DPLL_IVA, CM_SSC_MODFREQDIV_DPLL_MPU,
+ * CM_SSC_MODFREQDIV_DPLL_PER, CM_SSC_MODFREQDIV_DPLL_UNIPRO,
+ * CM_SSC_MODFREQDIV_DPLL_USB
*/
#define OMAP4430_MODFREQDIV_EXPONENT_SHIFT 8
-#define OMAP4430_MODFREQDIV_EXPONENT_MASK BITFIELD(8, 10)
+#define OMAP4430_MODFREQDIV_EXPONENT_MASK (0x7 << 8)
/*
- * Used by CM_SSC_MODFREQDIV_DPLL_PER, CM_SSC_MODFREQDIV_DPLL_UNIPRO,
- * CM_SSC_MODFREQDIV_DPLL_USB, CM_SSC_MODFREQDIV_DPLL_CORE_RESTORE,
- * CM_SSC_MODFREQDIV_DPLL_ABE, CM_SSC_MODFREQDIV_DPLL_CORE,
- * CM_SSC_MODFREQDIV_DPLL_DDRPHY, CM_SSC_MODFREQDIV_DPLL_IVA,
- * CM_SSC_MODFREQDIV_DPLL_MPU
+ * Used by CM_SSC_MODFREQDIV_DPLL_ABE, CM_SSC_MODFREQDIV_DPLL_CORE,
+ * CM_SSC_MODFREQDIV_DPLL_CORE_RESTORE, CM_SSC_MODFREQDIV_DPLL_DDRPHY,
+ * CM_SSC_MODFREQDIV_DPLL_IVA, CM_SSC_MODFREQDIV_DPLL_MPU,
+ * CM_SSC_MODFREQDIV_DPLL_PER, CM_SSC_MODFREQDIV_DPLL_UNIPRO,
+ * CM_SSC_MODFREQDIV_DPLL_USB
*/
#define OMAP4430_MODFREQDIV_MANTISSA_SHIFT 0
-#define OMAP4430_MODFREQDIV_MANTISSA_MASK BITFIELD(0, 6)
-
-/*
- * Used by PRM_PRM_PROFILING_CLKCTRL, CM_WKUP_GPIO1_CLKCTRL,
- * CM_WKUP_KEYBOARD_CLKCTRL, CM_WKUP_L4WKUP_CLKCTRL, CM_WKUP_RTC_CLKCTRL,
- * CM_WKUP_SARRAM_CLKCTRL, CM_WKUP_SYNCTIMER_CLKCTRL, CM_WKUP_TIMER12_CLKCTRL,
- * CM_WKUP_TIMER1_CLKCTRL, CM_WKUP_USIM_CLKCTRL, CM_WKUP_WDT1_CLKCTRL,
- * CM_WKUP_WDT2_CLKCTRL, CM_EMU_DEBUGSS_CLKCTRL, CM_D2D_MODEM_ICR_CLKCTRL,
- * CM_D2D_SAD2D_CLKCTRL, CM_D2D_SAD2D_FW_CLKCTRL, CM_DUCATI_DUCATI_CLKCTRL,
- * CM_L3INSTR_L3_3_CLKCTRL, CM_L3INSTR_L3_INSTR_CLKCTRL,
- * CM_L3INSTR_OCP_WP1_CLKCTRL, CM_L3_1_L3_1_CLKCTRL, CM_L3_2_GPMC_CLKCTRL,
- * CM_L3_2_L3_2_CLKCTRL, CM_L3_2_OCMC_RAM_CLKCTRL, CM_L4CFG_HW_SEM_CLKCTRL,
- * CM_L4CFG_L4_CFG_CLKCTRL, CM_L4CFG_MAILBOX_CLKCTRL, CM_L4CFG_SAR_ROM_CLKCTRL,
- * CM_MEMIF_DMM_CLKCTRL, CM_MEMIF_EMIF_1_CLKCTRL, CM_MEMIF_EMIF_2_CLKCTRL,
- * CM_MEMIF_EMIF_FW_CLKCTRL, CM_MEMIF_EMIF_H1_CLKCTRL,
- * CM_MEMIF_EMIF_H2_CLKCTRL, CM_SDMA_SDMA_CLKCTRL, CM_GFX_GFX_CLKCTRL,
- * CM_L4PER_ADC_CLKCTRL, CM_L4PER_DMTIMER10_CLKCTRL,
- * CM_L4PER_DMTIMER11_CLKCTRL, CM_L4PER_DMTIMER2_CLKCTRL,
- * CM_L4PER_DMTIMER3_CLKCTRL, CM_L4PER_DMTIMER4_CLKCTRL,
- * CM_L4PER_DMTIMER9_CLKCTRL, CM_L4PER_ELM_CLKCTRL, CM_L4PER_GPIO2_CLKCTRL,
- * CM_L4PER_GPIO3_CLKCTRL, CM_L4PER_GPIO4_CLKCTRL, CM_L4PER_GPIO5_CLKCTRL,
- * CM_L4PER_GPIO6_CLKCTRL, CM_L4PER_HDQ1W_CLKCTRL, CM_L4PER_HECC1_CLKCTRL,
- * CM_L4PER_HECC2_CLKCTRL, CM_L4PER_I2C1_CLKCTRL, CM_L4PER_I2C2_CLKCTRL,
- * CM_L4PER_I2C3_CLKCTRL, CM_L4PER_I2C4_CLKCTRL, CM_L4PER_I2C5_CLKCTRL,
- * CM_L4PER_L4PER_CLKCTRL, CM_L4PER_MCASP2_CLKCTRL, CM_L4PER_MCASP3_CLKCTRL,
- * CM_L4PER_MCBSP4_CLKCTRL, CM_L4PER_MCSPI1_CLKCTRL, CM_L4PER_MCSPI2_CLKCTRL,
- * CM_L4PER_MCSPI3_CLKCTRL, CM_L4PER_MCSPI4_CLKCTRL, CM_L4PER_MGATE_CLKCTRL,
- * CM_L4PER_MMCSD3_CLKCTRL, CM_L4PER_MMCSD4_CLKCTRL, CM_L4PER_MMCSD5_CLKCTRL,
- * CM_L4PER_MSPROHG_CLKCTRL, CM_L4PER_SLIMBUS2_CLKCTRL, CM_L4PER_UART1_CLKCTRL,
- * CM_L4PER_UART2_CLKCTRL, CM_L4PER_UART3_CLKCTRL, CM_L4PER_UART4_CLKCTRL,
- * CM_L4SEC_AES1_CLKCTRL, CM_L4SEC_AES2_CLKCTRL, CM_L4SEC_CRYPTODMA_CLKCTRL,
- * CM_L4SEC_DES3DES_CLKCTRL, CM_L4SEC_PKAEIP29_CLKCTRL, CM_L4SEC_RNG_CLKCTRL,
- * CM_L4SEC_SHA2MD51_CLKCTRL, CM_L3INIT_CCPTX_CLKCTRL, CM_L3INIT_EMAC_CLKCTRL,
+#define OMAP4430_MODFREQDIV_MANTISSA_MASK (0x7f << 0)
+
+/*
+ * Used by CM1_ABE_AESS_CLKCTRL, CM1_ABE_DMIC_CLKCTRL, CM1_ABE_L4ABE_CLKCTRL,
+ * CM1_ABE_MCASP_CLKCTRL, CM1_ABE_MCBSP1_CLKCTRL, CM1_ABE_MCBSP2_CLKCTRL,
+ * CM1_ABE_MCBSP3_CLKCTRL, CM1_ABE_PDM_CLKCTRL, CM1_ABE_SLIMBUS_CLKCTRL,
+ * CM1_ABE_TIMER5_CLKCTRL, CM1_ABE_TIMER6_CLKCTRL, CM1_ABE_TIMER7_CLKCTRL,
+ * CM1_ABE_TIMER8_CLKCTRL, CM1_ABE_WDT3_CLKCTRL, CM_ALWON_MDMINTC_CLKCTRL,
+ * CM_ALWON_SR_CORE_CLKCTRL, CM_ALWON_SR_IVA_CLKCTRL, CM_ALWON_SR_MPU_CLKCTRL,
+ * CM_CAM_FDIF_CLKCTRL, CM_CAM_ISS_CLKCTRL, CM_CEFUSE_CEFUSE_CLKCTRL,
+ * CM_CM1_PROFILING_CLKCTRL, CM_CM1_PROFILING_CLKCTRL_RESTORE,
+ * CM_CM2_PROFILING_CLKCTRL, CM_CM2_PROFILING_CLKCTRL_RESTORE,
+ * CM_D2D_MODEM_ICR_CLKCTRL, CM_D2D_SAD2D_CLKCTRL, CM_D2D_SAD2D_FW_CLKCTRL,
+ * CM_DSS_DEISS_CLKCTRL, CM_DSS_DSS_CLKCTRL, CM_DUCATI_DUCATI_CLKCTRL,
+ * CM_EMU_DEBUGSS_CLKCTRL, CM_GFX_GFX_CLKCTRL, CM_IVAHD_IVAHD_CLKCTRL,
+ * CM_IVAHD_SL2_CLKCTRL, CM_L3INIT_CCPTX_CLKCTRL, CM_L3INIT_EMAC_CLKCTRL,
* CM_L3INIT_HSI_CLKCTRL, CM_L3INIT_MMC1_CLKCTRL, CM_L3INIT_MMC2_CLKCTRL,
* CM_L3INIT_MMC6_CLKCTRL, CM_L3INIT_P1500_CLKCTRL, CM_L3INIT_PCIESS_CLKCTRL,
* CM_L3INIT_SATA_CLKCTRL, CM_L3INIT_TPPSS_CLKCTRL, CM_L3INIT_UNIPRO1_CLKCTRL,
* CM_L3INIT_USBPHYOCP2SCP_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL,
- * CM_L3INIT_USB_HOST_FS_CLKCTRL, CM_L3INIT_USB_OTG_CLKCTRL,
- * CM_L3INIT_USB_TLL_CLKCTRL, CM_L3INIT_XHPI_CLKCTRL, CM_CAM_FDIF_CLKCTRL,
- * CM_CAM_ISS_CLKCTRL, CM_CEFUSE_CEFUSE_CLKCTRL,
- * CM_L3INIT_USB_HOST_CLKCTRL_RESTORE, CM_L3INIT_USB_TLL_CLKCTRL_RESTORE,
- * CM_L3INSTR_L3_3_CLKCTRL_RESTORE, CM_L3INSTR_L3_INSTR_CLKCTRL_RESTORE,
- * CM_L3INSTR_OCP_WP1_CLKCTRL_RESTORE, CM_L4PER_GPIO2_CLKCTRL_RESTORE,
- * CM_L4PER_GPIO3_CLKCTRL_RESTORE, CM_L4PER_GPIO4_CLKCTRL_RESTORE,
- * CM_L4PER_GPIO5_CLKCTRL_RESTORE, CM_L4PER_GPIO6_CLKCTRL_RESTORE,
- * CM_ALWON_MDMINTC_CLKCTRL, CM_ALWON_SR_CORE_CLKCTRL, CM_ALWON_SR_IVA_CLKCTRL,
- * CM_ALWON_SR_MPU_CLKCTRL, CM_IVAHD_IVAHD_CLKCTRL, CM_IVAHD_SL2_CLKCTRL,
- * CM_DSS_DEISS_CLKCTRL, CM_DSS_DSS_CLKCTRL, CM_CM2_PROFILING_CLKCTRL,
- * CM_MPU_MPU_CLKCTRL, CM_TESLA_TESLA_CLKCTRL, CM1_ABE_AESS_CLKCTRL,
- * CM1_ABE_DMIC_CLKCTRL, CM1_ABE_L4ABE_CLKCTRL, CM1_ABE_MCASP_CLKCTRL,
- * CM1_ABE_MCBSP1_CLKCTRL, CM1_ABE_MCBSP2_CLKCTRL, CM1_ABE_MCBSP3_CLKCTRL,
- * CM1_ABE_PDM_CLKCTRL, CM1_ABE_SLIMBUS_CLKCTRL, CM1_ABE_TIMER5_CLKCTRL,
- * CM1_ABE_TIMER6_CLKCTRL, CM1_ABE_TIMER7_CLKCTRL, CM1_ABE_TIMER8_CLKCTRL,
- * CM1_ABE_WDT3_CLKCTRL, CM_CM1_PROFILING_CLKCTRL
+ * CM_L3INIT_USB_HOST_CLKCTRL_RESTORE, CM_L3INIT_USB_HOST_FS_CLKCTRL,
+ * CM_L3INIT_USB_OTG_CLKCTRL, CM_L3INIT_USB_TLL_CLKCTRL,
+ * CM_L3INIT_USB_TLL_CLKCTRL_RESTORE, CM_L3INIT_XHPI_CLKCTRL,
+ * CM_L3INSTR_L3_3_CLKCTRL, CM_L3INSTR_L3_3_CLKCTRL_RESTORE,
+ * CM_L3INSTR_L3_INSTR_CLKCTRL, CM_L3INSTR_L3_INSTR_CLKCTRL_RESTORE,
+ * CM_L3INSTR_OCP_WP1_CLKCTRL, CM_L3INSTR_OCP_WP1_CLKCTRL_RESTORE,
+ * CM_L3_1_L3_1_CLKCTRL, CM_L3_2_GPMC_CLKCTRL, CM_L3_2_L3_2_CLKCTRL,
+ * CM_L3_2_OCMC_RAM_CLKCTRL, CM_L4CFG_HW_SEM_CLKCTRL, CM_L4CFG_L4_CFG_CLKCTRL,
+ * CM_L4CFG_MAILBOX_CLKCTRL, CM_L4CFG_SAR_ROM_CLKCTRL, CM_L4PER_ADC_CLKCTRL,
+ * CM_L4PER_DMTIMER10_CLKCTRL, CM_L4PER_DMTIMER11_CLKCTRL,
+ * CM_L4PER_DMTIMER2_CLKCTRL, CM_L4PER_DMTIMER3_CLKCTRL,
+ * CM_L4PER_DMTIMER4_CLKCTRL, CM_L4PER_DMTIMER9_CLKCTRL, CM_L4PER_ELM_CLKCTRL,
+ * CM_L4PER_GPIO2_CLKCTRL, CM_L4PER_GPIO2_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO3_CLKCTRL, CM_L4PER_GPIO3_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO4_CLKCTRL, CM_L4PER_GPIO4_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO5_CLKCTRL, CM_L4PER_GPIO5_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO6_CLKCTRL, CM_L4PER_GPIO6_CLKCTRL_RESTORE,
+ * CM_L4PER_HDQ1W_CLKCTRL, CM_L4PER_HECC1_CLKCTRL, CM_L4PER_HECC2_CLKCTRL,
+ * CM_L4PER_I2C1_CLKCTRL, CM_L4PER_I2C2_CLKCTRL, CM_L4PER_I2C3_CLKCTRL,
+ * CM_L4PER_I2C4_CLKCTRL, CM_L4PER_I2C5_CLKCTRL, CM_L4PER_L4PER_CLKCTRL,
+ * CM_L4PER_MCASP2_CLKCTRL, CM_L4PER_MCASP3_CLKCTRL, CM_L4PER_MCBSP4_CLKCTRL,
+ * CM_L4PER_MCSPI1_CLKCTRL, CM_L4PER_MCSPI2_CLKCTRL, CM_L4PER_MCSPI3_CLKCTRL,
+ * CM_L4PER_MCSPI4_CLKCTRL, CM_L4PER_MGATE_CLKCTRL, CM_L4PER_MMCSD3_CLKCTRL,
+ * CM_L4PER_MMCSD4_CLKCTRL, CM_L4PER_MMCSD5_CLKCTRL, CM_L4PER_MSPROHG_CLKCTRL,
+ * CM_L4PER_SLIMBUS2_CLKCTRL, CM_L4PER_UART1_CLKCTRL, CM_L4PER_UART2_CLKCTRL,
+ * CM_L4PER_UART3_CLKCTRL, CM_L4PER_UART4_CLKCTRL, CM_L4SEC_AES1_CLKCTRL,
+ * CM_L4SEC_AES2_CLKCTRL, CM_L4SEC_CRYPTODMA_CLKCTRL, CM_L4SEC_DES3DES_CLKCTRL,
+ * CM_L4SEC_PKAEIP29_CLKCTRL, CM_L4SEC_RNG_CLKCTRL, CM_L4SEC_SHA2MD51_CLKCTRL,
+ * CM_MEMIF_DMM_CLKCTRL, CM_MEMIF_EMIF_1_CLKCTRL, CM_MEMIF_EMIF_2_CLKCTRL,
+ * CM_MEMIF_EMIF_FW_CLKCTRL, CM_MEMIF_EMIF_H1_CLKCTRL,
+ * CM_MEMIF_EMIF_H2_CLKCTRL, CM_MPU_MPU_CLKCTRL, CM_SDMA_SDMA_CLKCTRL,
+ * CM_TESLA_TESLA_CLKCTRL, CM_WKUP_GPIO1_CLKCTRL, CM_WKUP_KEYBOARD_CLKCTRL,
+ * CM_WKUP_L4WKUP_CLKCTRL, CM_WKUP_RTC_CLKCTRL, CM_WKUP_SARRAM_CLKCTRL,
+ * CM_WKUP_SYNCTIMER_CLKCTRL, CM_WKUP_TIMER12_CLKCTRL, CM_WKUP_TIMER1_CLKCTRL,
+ * CM_WKUP_USIM_CLKCTRL, CM_WKUP_WDT1_CLKCTRL, CM_WKUP_WDT2_CLKCTRL
*/
#define OMAP4430_MODULEMODE_SHIFT 0
-#define OMAP4430_MODULEMODE_MASK BITFIELD(0, 1)
+#define OMAP4430_MODULEMODE_MASK (0x3 << 0)
/* Used by CM_DSS_DSS_CLKCTRL */
#define OMAP4430_OPTFCLKEN_48MHZ_CLK_SHIFT 9
-#define OMAP4430_OPTFCLKEN_48MHZ_CLK_MASK BITFIELD(9, 9)
+#define OMAP4430_OPTFCLKEN_48MHZ_CLK_MASK (1 << 9)
/* Used by CM_WKUP_BANDGAP_CLKCTRL */
#define OMAP4430_OPTFCLKEN_BGAP_32K_SHIFT 8
-#define OMAP4430_OPTFCLKEN_BGAP_32K_MASK BITFIELD(8, 8)
+#define OMAP4430_OPTFCLKEN_BGAP_32K_MASK (1 << 8)
-/* Used by CM_L3INIT_USBPHYOCP2SCP_CLKCTRL */
-#define OMAP4430_OPTFCLKEN_CLK32K_SHIFT 9
-#define OMAP4430_OPTFCLKEN_CLK32K_MASK BITFIELD(9, 9)
+/* Used by CM_ALWON_USBPHY_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_CLK32K_SHIFT 8
+#define OMAP4430_OPTFCLKEN_CLK32K_MASK (1 << 8)
/* Used by CM_CAM_ISS_CLKCTRL */
#define OMAP4430_OPTFCLKEN_CTRLCLK_SHIFT 8
-#define OMAP4430_OPTFCLKEN_CTRLCLK_MASK BITFIELD(8, 8)
+#define OMAP4430_OPTFCLKEN_CTRLCLK_MASK (1 << 8)
/*
- * Used by CM_WKUP_GPIO1_CLKCTRL, CM_L4PER_GPIO2_CLKCTRL,
- * CM_L4PER_GPIO3_CLKCTRL, CM_L4PER_GPIO4_CLKCTRL, CM_L4PER_GPIO5_CLKCTRL,
- * CM_L4PER_GPIO6_CLKCTRL, CM_L4PER_GPIO2_CLKCTRL_RESTORE,
- * CM_L4PER_GPIO3_CLKCTRL_RESTORE, CM_L4PER_GPIO4_CLKCTRL_RESTORE,
- * CM_L4PER_GPIO5_CLKCTRL_RESTORE, CM_L4PER_GPIO6_CLKCTRL_RESTORE
+ * Used by CM_L4PER_GPIO2_CLKCTRL, CM_L4PER_GPIO2_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO3_CLKCTRL, CM_L4PER_GPIO3_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO4_CLKCTRL, CM_L4PER_GPIO4_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO5_CLKCTRL, CM_L4PER_GPIO5_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO6_CLKCTRL, CM_L4PER_GPIO6_CLKCTRL_RESTORE, CM_WKUP_GPIO1_CLKCTRL
*/
#define OMAP4430_OPTFCLKEN_DBCLK_SHIFT 8
-#define OMAP4430_OPTFCLKEN_DBCLK_MASK BITFIELD(8, 8)
+#define OMAP4430_OPTFCLKEN_DBCLK_MASK (1 << 8)
/* Used by CM_MEMIF_DLL_CLKCTRL, CM_MEMIF_DLL_H_CLKCTRL */
#define OMAP4430_OPTFCLKEN_DLL_CLK_SHIFT 8
-#define OMAP4430_OPTFCLKEN_DLL_CLK_MASK BITFIELD(8, 8)
+#define OMAP4430_OPTFCLKEN_DLL_CLK_MASK (1 << 8)
/* Used by CM_DSS_DSS_CLKCTRL */
#define OMAP4430_OPTFCLKEN_DSSCLK_SHIFT 8
-#define OMAP4430_OPTFCLKEN_DSSCLK_MASK BITFIELD(8, 8)
+#define OMAP4430_OPTFCLKEN_DSSCLK_MASK (1 << 8)
+
+/* Used by CM_WKUP_USIM_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_FCLK_SHIFT 8
+#define OMAP4430_OPTFCLKEN_FCLK_MASK (1 << 8)
/* Used by CM1_ABE_SLIMBUS_CLKCTRL */
#define OMAP4430_OPTFCLKEN_FCLK0_SHIFT 8
-#define OMAP4430_OPTFCLKEN_FCLK0_MASK BITFIELD(8, 8)
+#define OMAP4430_OPTFCLKEN_FCLK0_MASK (1 << 8)
/* Used by CM1_ABE_SLIMBUS_CLKCTRL */
#define OMAP4430_OPTFCLKEN_FCLK1_SHIFT 9
-#define OMAP4430_OPTFCLKEN_FCLK1_MASK BITFIELD(9, 9)
+#define OMAP4430_OPTFCLKEN_FCLK1_MASK (1 << 9)
/* Used by CM1_ABE_SLIMBUS_CLKCTRL */
#define OMAP4430_OPTFCLKEN_FCLK2_SHIFT 10
-#define OMAP4430_OPTFCLKEN_FCLK2_MASK BITFIELD(10, 10)
+#define OMAP4430_OPTFCLKEN_FCLK2_MASK (1 << 10)
/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
#define OMAP4430_OPTFCLKEN_FUNC48MCLK_SHIFT 15
-#define OMAP4430_OPTFCLKEN_FUNC48MCLK_MASK BITFIELD(15, 15)
+#define OMAP4430_OPTFCLKEN_FUNC48MCLK_MASK (1 << 15)
/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
#define OMAP4430_OPTFCLKEN_HSIC480M_P1_CLK_SHIFT 13
-#define OMAP4430_OPTFCLKEN_HSIC480M_P1_CLK_MASK BITFIELD(13, 13)
+#define OMAP4430_OPTFCLKEN_HSIC480M_P1_CLK_MASK (1 << 13)
/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
#define OMAP4430_OPTFCLKEN_HSIC480M_P2_CLK_SHIFT 14
-#define OMAP4430_OPTFCLKEN_HSIC480M_P2_CLK_MASK BITFIELD(14, 14)
+#define OMAP4430_OPTFCLKEN_HSIC480M_P2_CLK_MASK (1 << 14)
/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
#define OMAP4430_OPTFCLKEN_HSIC60M_P1_CLK_SHIFT 11
-#define OMAP4430_OPTFCLKEN_HSIC60M_P1_CLK_MASK BITFIELD(11, 11)
+#define OMAP4430_OPTFCLKEN_HSIC60M_P1_CLK_MASK (1 << 11)
/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
#define OMAP4430_OPTFCLKEN_HSIC60M_P2_CLK_SHIFT 12
-#define OMAP4430_OPTFCLKEN_HSIC60M_P2_CLK_MASK BITFIELD(12, 12)
+#define OMAP4430_OPTFCLKEN_HSIC60M_P2_CLK_MASK (1 << 12)
/* Used by CM_L4PER_SLIMBUS2_CLKCTRL */
#define OMAP4430_OPTFCLKEN_PER24MC_GFCLK_SHIFT 8
-#define OMAP4430_OPTFCLKEN_PER24MC_GFCLK_MASK BITFIELD(8, 8)
+#define OMAP4430_OPTFCLKEN_PER24MC_GFCLK_MASK (1 << 8)
/* Used by CM_L4PER_SLIMBUS2_CLKCTRL */
#define OMAP4430_OPTFCLKEN_PERABE24M_GFCLK_SHIFT 9
-#define OMAP4430_OPTFCLKEN_PERABE24M_GFCLK_MASK BITFIELD(9, 9)
+#define OMAP4430_OPTFCLKEN_PERABE24M_GFCLK_MASK (1 << 9)
/* Used by CM_L3INIT_USBPHYOCP2SCP_CLKCTRL */
#define OMAP4430_OPTFCLKEN_PHY_48M_SHIFT 8
-#define OMAP4430_OPTFCLKEN_PHY_48M_MASK BITFIELD(8, 8)
+#define OMAP4430_OPTFCLKEN_PHY_48M_MASK (1 << 8)
/* Used by CM_L4PER_SLIMBUS2_CLKCTRL */
#define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_SHIFT 10
-#define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_MASK BITFIELD(10, 10)
+#define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_MASK (1 << 10)
/* Renamed from OPTFCLKEN_SLIMBUS_CLK Used by CM1_ABE_SLIMBUS_CLKCTRL */
#define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_11_11_SHIFT 11
-#define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_11_11_MASK BITFIELD(11, 11)
+#define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_11_11_MASK (1 << 11)
/* Used by CM_DSS_DSS_CLKCTRL */
#define OMAP4430_OPTFCLKEN_SYS_CLK_SHIFT 10
-#define OMAP4430_OPTFCLKEN_SYS_CLK_MASK BITFIELD(10, 10)
+#define OMAP4430_OPTFCLKEN_SYS_CLK_MASK (1 << 10)
/* Used by CM_DSS_DSS_CLKCTRL */
#define OMAP4430_OPTFCLKEN_TV_CLK_SHIFT 11
-#define OMAP4430_OPTFCLKEN_TV_CLK_MASK BITFIELD(11, 11)
+#define OMAP4430_OPTFCLKEN_TV_CLK_MASK (1 << 11)
/* Used by CM_L3INIT_UNIPRO1_CLKCTRL */
#define OMAP4430_OPTFCLKEN_TXPHYCLK_SHIFT 8
-#define OMAP4430_OPTFCLKEN_TXPHYCLK_MASK BITFIELD(8, 8)
+#define OMAP4430_OPTFCLKEN_TXPHYCLK_MASK (1 << 8)
/* Used by CM_L3INIT_USB_TLL_CLKCTRL, CM_L3INIT_USB_TLL_CLKCTRL_RESTORE */
#define OMAP4430_OPTFCLKEN_USB_CH0_CLK_SHIFT 8
-#define OMAP4430_OPTFCLKEN_USB_CH0_CLK_MASK BITFIELD(8, 8)
+#define OMAP4430_OPTFCLKEN_USB_CH0_CLK_MASK (1 << 8)
/* Used by CM_L3INIT_USB_TLL_CLKCTRL, CM_L3INIT_USB_TLL_CLKCTRL_RESTORE */
#define OMAP4430_OPTFCLKEN_USB_CH1_CLK_SHIFT 9
-#define OMAP4430_OPTFCLKEN_USB_CH1_CLK_MASK BITFIELD(9, 9)
+#define OMAP4430_OPTFCLKEN_USB_CH1_CLK_MASK (1 << 9)
/* Used by CM_L3INIT_USB_TLL_CLKCTRL, CM_L3INIT_USB_TLL_CLKCTRL_RESTORE */
#define OMAP4430_OPTFCLKEN_USB_CH2_CLK_SHIFT 10
-#define OMAP4430_OPTFCLKEN_USB_CH2_CLK_MASK BITFIELD(10, 10)
+#define OMAP4430_OPTFCLKEN_USB_CH2_CLK_MASK (1 << 10)
/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
#define OMAP4430_OPTFCLKEN_UTMI_P1_CLK_SHIFT 8
-#define OMAP4430_OPTFCLKEN_UTMI_P1_CLK_MASK BITFIELD(8, 8)
+#define OMAP4430_OPTFCLKEN_UTMI_P1_CLK_MASK (1 << 8)
/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
#define OMAP4430_OPTFCLKEN_UTMI_P2_CLK_SHIFT 9
-#define OMAP4430_OPTFCLKEN_UTMI_P2_CLK_MASK BITFIELD(9, 9)
+#define OMAP4430_OPTFCLKEN_UTMI_P2_CLK_MASK (1 << 9)
/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
#define OMAP4430_OPTFCLKEN_UTMI_P3_CLK_SHIFT 10
-#define OMAP4430_OPTFCLKEN_UTMI_P3_CLK_MASK BITFIELD(10, 10)
+#define OMAP4430_OPTFCLKEN_UTMI_P3_CLK_MASK (1 << 10)
/* Used by CM_L3INIT_USB_OTG_CLKCTRL */
#define OMAP4430_OPTFCLKEN_XCLK_SHIFT 8
-#define OMAP4430_OPTFCLKEN_XCLK_MASK BITFIELD(8, 8)
+#define OMAP4430_OPTFCLKEN_XCLK_MASK (1 << 8)
-/* Used by CM_EMU_OVERRIDE_DPLL_PER, CM_EMU_OVERRIDE_DPLL_CORE */
+/* Used by CM_EMU_OVERRIDE_DPLL_CORE */
#define OMAP4430_OVERRIDE_ENABLE_SHIFT 19
-#define OMAP4430_OVERRIDE_ENABLE_MASK BITFIELD(19, 19)
+#define OMAP4430_OVERRIDE_ENABLE_MASK (1 << 19)
/* Used by CM_CLKSEL_ABE */
#define OMAP4430_PAD_CLKS_GATE_SHIFT 8
-#define OMAP4430_PAD_CLKS_GATE_MASK BITFIELD(8, 8)
+#define OMAP4430_PAD_CLKS_GATE_MASK (1 << 8)
/* Used by CM_CORE_DVFS_CURRENT, CM_IVA_DVFS_CURRENT */
#define OMAP4430_PERF_CURRENT_SHIFT 0
-#define OMAP4430_PERF_CURRENT_MASK BITFIELD(0, 7)
+#define OMAP4430_PERF_CURRENT_MASK (0xff << 0)
/*
* Used by CM_CORE_DVFS_PERF1, CM_CORE_DVFS_PERF2, CM_CORE_DVFS_PERF3,
@@ -1316,159 +1355,173 @@
* CM_IVA_DVFS_PERF_TESLA
*/
#define OMAP4430_PERF_REQ_SHIFT 0
-#define OMAP4430_PERF_REQ_MASK BITFIELD(0, 7)
-
-/* Used by CM_EMU_OVERRIDE_DPLL_PER */
-#define OMAP4430_PER_DPLL_EMU_DIV_SHIFT 0
-#define OMAP4430_PER_DPLL_EMU_DIV_MASK BITFIELD(0, 6)
-
-/* Used by CM_EMU_OVERRIDE_DPLL_PER */
-#define OMAP4430_PER_DPLL_EMU_MULT_SHIFT 8
-#define OMAP4430_PER_DPLL_EMU_MULT_MASK BITFIELD(8, 18)
+#define OMAP4430_PERF_REQ_MASK (0xff << 0)
/* Used by CM_RESTORE_ST */
#define OMAP4430_PHASE1_COMPLETED_SHIFT 0
-#define OMAP4430_PHASE1_COMPLETED_MASK BITFIELD(0, 0)
+#define OMAP4430_PHASE1_COMPLETED_MASK (1 << 0)
/* Used by CM_RESTORE_ST */
#define OMAP4430_PHASE2A_COMPLETED_SHIFT 1
-#define OMAP4430_PHASE2A_COMPLETED_MASK BITFIELD(1, 1)
+#define OMAP4430_PHASE2A_COMPLETED_MASK (1 << 1)
/* Used by CM_RESTORE_ST */
#define OMAP4430_PHASE2B_COMPLETED_SHIFT 2
-#define OMAP4430_PHASE2B_COMPLETED_MASK BITFIELD(2, 2)
+#define OMAP4430_PHASE2B_COMPLETED_MASK (1 << 2)
/* Used by CM_EMU_DEBUGSS_CLKCTRL */
#define OMAP4430_PMD_STM_MUX_CTRL_SHIFT 20
-#define OMAP4430_PMD_STM_MUX_CTRL_MASK BITFIELD(20, 21)
+#define OMAP4430_PMD_STM_MUX_CTRL_MASK (0x3 << 20)
/* Used by CM_EMU_DEBUGSS_CLKCTRL */
#define OMAP4430_PMD_TRACE_MUX_CTRL_SHIFT 22
-#define OMAP4430_PMD_TRACE_MUX_CTRL_MASK BITFIELD(22, 23)
+#define OMAP4430_PMD_TRACE_MUX_CTRL_MASK (0x3 << 22)
-/* Used by CM_DYN_DEP_PRESCAL */
+/* Used by CM_DYN_DEP_PRESCAL, CM_DYN_DEP_PRESCAL_RESTORE */
#define OMAP4430_PRESCAL_SHIFT 0
-#define OMAP4430_PRESCAL_MASK BITFIELD(0, 5)
+#define OMAP4430_PRESCAL_MASK (0x3f << 0)
-/* Used by REVISION_CM2, REVISION_CM1 */
-#define OMAP4430_REV_SHIFT 0
-#define OMAP4430_REV_MASK BITFIELD(0, 7)
+/* Used by REVISION_CM1, REVISION_CM2 */
+#define OMAP4430_R_RTL_SHIFT 11
+#define OMAP4430_R_RTL_MASK (0x1f << 11)
/*
- * Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_TLL_CLKCTRL,
- * CM_L3INIT_USB_HOST_CLKCTRL_RESTORE, CM_L3INIT_USB_TLL_CLKCTRL_RESTORE
+ * Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE,
+ * CM_L3INIT_USB_TLL_CLKCTRL, CM_L3INIT_USB_TLL_CLKCTRL_RESTORE
*/
#define OMAP4430_SAR_MODE_SHIFT 4
-#define OMAP4430_SAR_MODE_MASK BITFIELD(4, 4)
+#define OMAP4430_SAR_MODE_MASK (1 << 4)
/* Used by CM_SCALE_FCLK */
#define OMAP4430_SCALE_FCLK_SHIFT 0
-#define OMAP4430_SCALE_FCLK_MASK BITFIELD(0, 0)
+#define OMAP4430_SCALE_FCLK_MASK (1 << 0)
+
+/* Used by REVISION_CM1, REVISION_CM2 */
+#define OMAP4430_SCHEME_SHIFT 30
+#define OMAP4430_SCHEME_MASK (0x3 << 30)
-/* Used by CM_L4CFG_DYNAMICDEP */
+/* Used by CM_L4CFG_DYNAMICDEP, CM_L4CFG_DYNAMICDEP_RESTORE */
#define OMAP4430_SDMA_DYNDEP_SHIFT 11
-#define OMAP4430_SDMA_DYNDEP_MASK BITFIELD(11, 11)
+#define OMAP4430_SDMA_DYNDEP_MASK (1 << 11)
/* Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP */
#define OMAP4430_SDMA_STATDEP_SHIFT 11
-#define OMAP4430_SDMA_STATDEP_MASK BITFIELD(11, 11)
+#define OMAP4430_SDMA_STATDEP_MASK (1 << 11)
/* Used by CM_CLKSEL_ABE */
#define OMAP4430_SLIMBUS_CLK_GATE_SHIFT 10
-#define OMAP4430_SLIMBUS_CLK_GATE_MASK BITFIELD(10, 10)
+#define OMAP4430_SLIMBUS_CLK_GATE_MASK (1 << 10)
/*
- * Used by CM_EMU_DEBUGSS_CLKCTRL, CM_D2D_SAD2D_CLKCTRL,
- * CM_DUCATI_DUCATI_CLKCTRL, CM_SDMA_SDMA_CLKCTRL, CM_GFX_GFX_CLKCTRL,
- * CM_L4SEC_CRYPTODMA_CLKCTRL, CM_L3INIT_CCPTX_CLKCTRL, CM_L3INIT_EMAC_CLKCTRL,
+ * Used by CM1_ABE_AESS_CLKCTRL, CM_CAM_FDIF_CLKCTRL, CM_CAM_ISS_CLKCTRL,
+ * CM_D2D_SAD2D_CLKCTRL, CM_DSS_DEISS_CLKCTRL, CM_DSS_DSS_CLKCTRL,
+ * CM_DUCATI_DUCATI_CLKCTRL, CM_EMU_DEBUGSS_CLKCTRL, CM_GFX_GFX_CLKCTRL,
+ * CM_IVAHD_IVAHD_CLKCTRL, CM_L3INIT_CCPTX_CLKCTRL, CM_L3INIT_EMAC_CLKCTRL,
* CM_L3INIT_HSI_CLKCTRL, CM_L3INIT_MMC1_CLKCTRL, CM_L3INIT_MMC2_CLKCTRL,
* CM_L3INIT_MMC6_CLKCTRL, CM_L3INIT_P1500_CLKCTRL, CM_L3INIT_PCIESS_CLKCTRL,
* CM_L3INIT_SATA_CLKCTRL, CM_L3INIT_TPPSS_CLKCTRL, CM_L3INIT_UNIPRO1_CLKCTRL,
- * CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_FS_CLKCTRL,
- * CM_L3INIT_USB_OTG_CLKCTRL, CM_L3INIT_XHPI_CLKCTRL, CM_CAM_FDIF_CLKCTRL,
- * CM_CAM_ISS_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE,
- * CM_IVAHD_IVAHD_CLKCTRL, CM_DSS_DEISS_CLKCTRL, CM_DSS_DSS_CLKCTRL,
- * CM_MPU_MPU_CLKCTRL, CM_TESLA_TESLA_CLKCTRL, CM1_ABE_AESS_CLKCTRL
+ * CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE,
+ * CM_L3INIT_USB_HOST_FS_CLKCTRL, CM_L3INIT_USB_OTG_CLKCTRL,
+ * CM_L3INIT_XHPI_CLKCTRL, CM_L4SEC_CRYPTODMA_CLKCTRL, CM_MPU_MPU_CLKCTRL,
+ * CM_SDMA_SDMA_CLKCTRL, CM_TESLA_TESLA_CLKCTRL
*/
#define OMAP4430_STBYST_SHIFT 18
-#define OMAP4430_STBYST_MASK BITFIELD(18, 18)
+#define OMAP4430_STBYST_MASK (1 << 18)
/*
- * Used by CM_IDLEST_DPLL_PER, CM_IDLEST_DPLL_UNIPRO, CM_IDLEST_DPLL_USB,
- * CM_IDLEST_DPLL_ABE, CM_IDLEST_DPLL_CORE, CM_IDLEST_DPLL_DDRPHY,
- * CM_IDLEST_DPLL_IVA, CM_IDLEST_DPLL_MPU
+ * Used by CM_IDLEST_DPLL_ABE, CM_IDLEST_DPLL_CORE, CM_IDLEST_DPLL_DDRPHY,
+ * CM_IDLEST_DPLL_IVA, CM_IDLEST_DPLL_MPU, CM_IDLEST_DPLL_PER,
+ * CM_IDLEST_DPLL_UNIPRO, CM_IDLEST_DPLL_USB
*/
#define OMAP4430_ST_DPLL_CLK_SHIFT 0
-#define OMAP4430_ST_DPLL_CLK_MASK BITFIELD(0, 0)
+#define OMAP4430_ST_DPLL_CLK_MASK (1 << 0)
/* Used by CM_CLKDCOLDO_DPLL_USB */
#define OMAP4430_ST_DPLL_CLKDCOLDO_SHIFT 9
-#define OMAP4430_ST_DPLL_CLKDCOLDO_MASK BITFIELD(9, 9)
+#define OMAP4430_ST_DPLL_CLKDCOLDO_MASK (1 << 9)
/*
- * Used by CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_USB, CM_DIV_M2_DPLL_CORE_RESTORE,
- * CM_DIV_M2_DPLL_ABE, CM_DIV_M2_DPLL_CORE, CM_DIV_M2_DPLL_DDRPHY,
- * CM_DIV_M2_DPLL_MPU
+ * Used by CM_DIV_M2_DPLL_ABE, CM_DIV_M2_DPLL_CORE,
+ * CM_DIV_M2_DPLL_CORE_RESTORE, CM_DIV_M2_DPLL_DDRPHY, CM_DIV_M2_DPLL_MPU,
+ * CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_USB
*/
#define OMAP4430_ST_DPLL_CLKOUT_SHIFT 9
-#define OMAP4430_ST_DPLL_CLKOUT_MASK BITFIELD(9, 9)
+#define OMAP4430_ST_DPLL_CLKOUT_MASK (1 << 9)
/*
- * Used by CM_DIV_M3_DPLL_PER, CM_DIV_M3_DPLL_CORE_RESTORE, CM_DIV_M3_DPLL_ABE,
- * CM_DIV_M3_DPLL_CORE
+ * Used by CM_DIV_M3_DPLL_ABE, CM_DIV_M3_DPLL_CORE,
+ * CM_DIV_M3_DPLL_CORE_RESTORE, CM_DIV_M3_DPLL_PER
*/
#define OMAP4430_ST_DPLL_CLKOUTHIF_SHIFT 9
-#define OMAP4430_ST_DPLL_CLKOUTHIF_MASK BITFIELD(9, 9)
+#define OMAP4430_ST_DPLL_CLKOUTHIF_MASK (1 << 9)
-/* Used by CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_UNIPRO, CM_DIV_M2_DPLL_ABE */
+/* Used by CM_DIV_M2_DPLL_ABE, CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_UNIPRO */
#define OMAP4430_ST_DPLL_CLKOUTX2_SHIFT 11
-#define OMAP4430_ST_DPLL_CLKOUTX2_MASK BITFIELD(11, 11)
+#define OMAP4430_ST_DPLL_CLKOUTX2_MASK (1 << 11)
/*
- * Used by CM_DIV_M4_DPLL_PER, CM_DIV_M4_DPLL_CORE_RESTORE,
- * CM_DIV_M4_DPLL_CORE, CM_DIV_M4_DPLL_DDRPHY, CM_DIV_M4_DPLL_IVA
+ * Used by CM_DIV_M4_DPLL_CORE, CM_DIV_M4_DPLL_CORE_RESTORE,
+ * CM_DIV_M4_DPLL_DDRPHY, CM_DIV_M4_DPLL_IVA, CM_DIV_M4_DPLL_PER
*/
#define OMAP4430_ST_HSDIVIDER_CLKOUT1_SHIFT 9
-#define OMAP4430_ST_HSDIVIDER_CLKOUT1_MASK BITFIELD(9, 9)
+#define OMAP4430_ST_HSDIVIDER_CLKOUT1_MASK (1 << 9)
/*
- * Used by CM_DIV_M5_DPLL_PER, CM_DIV_M5_DPLL_CORE_RESTORE,
- * CM_DIV_M5_DPLL_CORE, CM_DIV_M5_DPLL_DDRPHY, CM_DIV_M5_DPLL_IVA
+ * Used by CM_DIV_M5_DPLL_CORE, CM_DIV_M5_DPLL_CORE_RESTORE,
+ * CM_DIV_M5_DPLL_DDRPHY, CM_DIV_M5_DPLL_IVA, CM_DIV_M5_DPLL_PER
*/
#define OMAP4430_ST_HSDIVIDER_CLKOUT2_SHIFT 9
-#define OMAP4430_ST_HSDIVIDER_CLKOUT2_MASK BITFIELD(9, 9)
+#define OMAP4430_ST_HSDIVIDER_CLKOUT2_MASK (1 << 9)
/*
- * Used by CM_DIV_M6_DPLL_PER, CM_DIV_M6_DPLL_CORE_RESTORE,
- * CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_DDRPHY
+ * Used by CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_CORE_RESTORE,
+ * CM_DIV_M6_DPLL_DDRPHY, CM_DIV_M6_DPLL_PER
*/
#define OMAP4430_ST_HSDIVIDER_CLKOUT3_SHIFT 9
-#define OMAP4430_ST_HSDIVIDER_CLKOUT3_MASK BITFIELD(9, 9)
+#define OMAP4430_ST_HSDIVIDER_CLKOUT3_MASK (1 << 9)
/*
- * Used by CM_DIV_M7_DPLL_PER, CM_DIV_M7_DPLL_CORE_RESTORE,
- * CM_DIV_M7_DPLL_CORE
+ * Used by CM_DIV_M7_DPLL_CORE, CM_DIV_M7_DPLL_CORE_RESTORE,
+ * CM_DIV_M7_DPLL_PER
*/
#define OMAP4430_ST_HSDIVIDER_CLKOUT4_SHIFT 9
-#define OMAP4430_ST_HSDIVIDER_CLKOUT4_MASK BITFIELD(9, 9)
+#define OMAP4430_ST_HSDIVIDER_CLKOUT4_MASK (1 << 9)
+
+/*
+ * Used by CM_IDLEST_DPLL_ABE, CM_IDLEST_DPLL_CORE, CM_IDLEST_DPLL_DDRPHY,
+ * CM_IDLEST_DPLL_IVA, CM_IDLEST_DPLL_MPU, CM_IDLEST_DPLL_PER,
+ * CM_IDLEST_DPLL_UNIPRO, CM_IDLEST_DPLL_USB
+ */
+#define OMAP4430_ST_MN_BYPASS_SHIFT 8
+#define OMAP4430_ST_MN_BYPASS_MASK (1 << 8)
/* Used by CM_SYS_CLKSEL */
#define OMAP4430_SYS_CLKSEL_SHIFT 0
-#define OMAP4430_SYS_CLKSEL_MASK BITFIELD(0, 2)
+#define OMAP4430_SYS_CLKSEL_MASK (0x7 << 0)
-/* Used by CM_L4CFG_DYNAMICDEP */
+/* Used by CM_L4CFG_DYNAMICDEP, CM_L4CFG_DYNAMICDEP_RESTORE */
#define OMAP4430_TESLA_DYNDEP_SHIFT 1
-#define OMAP4430_TESLA_DYNDEP_MASK BITFIELD(1, 1)
+#define OMAP4430_TESLA_DYNDEP_MASK (1 << 1)
/* Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP */
#define OMAP4430_TESLA_STATDEP_SHIFT 1
-#define OMAP4430_TESLA_STATDEP_MASK BITFIELD(1, 1)
+#define OMAP4430_TESLA_STATDEP_MASK (1 << 1)
/*
- * Used by CM_EMU_DYNAMICDEP, CM_D2D_DYNAMICDEP, CM_DUCATI_DYNAMICDEP,
- * CM_L3_1_DYNAMICDEP, CM_L3_2_DYNAMICDEP, CM_L4CFG_DYNAMICDEP,
- * CM_L4PER_DYNAMICDEP, CM_MPU_DYNAMICDEP, CM_TESLA_DYNAMICDEP
+ * Used by CM_D2D_DYNAMICDEP, CM_D2D_DYNAMICDEP_RESTORE, CM_DUCATI_DYNAMICDEP,
+ * CM_EMU_DYNAMICDEP, CM_L3_1_DYNAMICDEP, CM_L3_1_DYNAMICDEP_RESTORE,
+ * CM_L3_2_DYNAMICDEP, CM_L3_2_DYNAMICDEP_RESTORE, CM_L4CFG_DYNAMICDEP,
+ * CM_L4CFG_DYNAMICDEP_RESTORE, CM_L4PER_DYNAMICDEP,
+ * CM_L4PER_DYNAMICDEP_RESTORE, CM_MPU_DYNAMICDEP, CM_TESLA_DYNAMICDEP
*/
#define OMAP4430_WINDOWSIZE_SHIFT 24
-#define OMAP4430_WINDOWSIZE_MASK BITFIELD(24, 27)
+#define OMAP4430_WINDOWSIZE_MASK (0xf << 24)
+
+/* Used by REVISION_CM1, REVISION_CM2 */
+#define OMAP4430_X_MAJOR_SHIFT 8
+#define OMAP4430_X_MAJOR_MASK (0x7 << 8)
+
+/* Used by REVISION_CM1, REVISION_CM2 */
+#define OMAP4430_Y_MINOR_SHIFT 0
+#define OMAP4430_Y_MINOR_MASK (0x3f << 0)
#endif
diff --git a/arch/arm/mach-omap2/cm44xx.h b/arch/arm/mach-omap2/cm44xx.h
index 336d94889e5b..3c35a87cb90c 100644
--- a/arch/arm/mach-omap2/cm44xx.h
+++ b/arch/arm/mach-omap2/cm44xx.h
@@ -195,6 +195,42 @@
#define OMAP4_CM1_ABE_WDT3_CLKCTRL_OFFSET 0x0088
#define OMAP4430_CM1_ABE_WDT3_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0088)
+/* CM1.RESTORE_CM1 register offsets */
+#define OMAP4_CM_CLKSEL_CORE_RESTORE_OFFSET 0x0000
+#define OMAP4430_CM_CLKSEL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0000)
+#define OMAP4_CM_DIV_M2_DPLL_CORE_RESTORE_OFFSET 0x0004
+#define OMAP4430_CM_DIV_M2_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0004)
+#define OMAP4_CM_DIV_M3_DPLL_CORE_RESTORE_OFFSET 0x0008
+#define OMAP4430_CM_DIV_M3_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0008)
+#define OMAP4_CM_DIV_M4_DPLL_CORE_RESTORE_OFFSET 0x000c
+#define OMAP4430_CM_DIV_M4_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x000c)
+#define OMAP4_CM_DIV_M5_DPLL_CORE_RESTORE_OFFSET 0x0010
+#define OMAP4430_CM_DIV_M5_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0010)
+#define OMAP4_CM_DIV_M6_DPLL_CORE_RESTORE_OFFSET 0x0014
+#define OMAP4430_CM_DIV_M6_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0014)
+#define OMAP4_CM_DIV_M7_DPLL_CORE_RESTORE_OFFSET 0x0018
+#define OMAP4430_CM_DIV_M7_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0018)
+#define OMAP4_CM_CLKSEL_DPLL_CORE_RESTORE_OFFSET 0x001c
+#define OMAP4430_CM_CLKSEL_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x001c)
+#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_CORE_RESTORE_OFFSET 0x0020
+#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0020)
+#define OMAP4_CM_SSC_MODFREQDIV_DPLL_CORE_RESTORE_OFFSET 0x0024
+#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0024)
+#define OMAP4_CM_CLKMODE_DPLL_CORE_RESTORE_OFFSET 0x0028
+#define OMAP4430_CM_CLKMODE_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0028)
+#define OMAP4_CM_SHADOW_FREQ_CONFIG2_RESTORE_OFFSET 0x002c
+#define OMAP4430_CM_SHADOW_FREQ_CONFIG2_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x002c)
+#define OMAP4_CM_SHADOW_FREQ_CONFIG1_RESTORE_OFFSET 0x0030
+#define OMAP4430_CM_SHADOW_FREQ_CONFIG1_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0030)
+#define OMAP4_CM_AUTOIDLE_DPLL_CORE_RESTORE_OFFSET 0x0034
+#define OMAP4430_CM_AUTOIDLE_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0034)
+#define OMAP4_CM_MPU_CLKSTCTRL_RESTORE_OFFSET 0x0038
+#define OMAP4430_CM_MPU_CLKSTCTRL_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0038)
+#define OMAP4_CM_CM1_PROFILING_CLKCTRL_RESTORE_OFFSET 0x003c
+#define OMAP4430_CM_CM1_PROFILING_CLKCTRL_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x003c)
+#define OMAP4_CM_DYN_DEP_PRESCAL_RESTORE_OFFSET 0x0040
+#define OMAP4430_CM_DYN_DEP_PRESCAL_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0040)
+
/* CM2 */
/* CM2.OCP_SOCKET_CM2 register offsets */
@@ -252,8 +288,6 @@
#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0068)
#define OMAP4_CM_SSC_MODFREQDIV_DPLL_PER_OFFSET 0x006c
#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x006c)
-#define OMAP4_CM_EMU_OVERRIDE_DPLL_PER_OFFSET 0x0070
-#define OMAP4430_CM_EMU_OVERRIDE_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0070)
#define OMAP4_CM_CLKMODE_DPLL_USB_OFFSET 0x0080
#define OMAP4430_CM_CLKMODE_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0080)
#define OMAP4_CM_IDLEST_DPLL_USB_OFFSET 0x0084
@@ -296,6 +330,8 @@
#define OMAP4430_CM_ALWON_SR_IVA_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_MOD, 0x0030)
#define OMAP4_CM_ALWON_SR_CORE_CLKCTRL_OFFSET 0x0038
#define OMAP4430_CM_ALWON_SR_CORE_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_MOD, 0x0038)
+#define OMAP4_CM_ALWON_USBPHY_CLKCTRL_OFFSET 0x0040
+#define OMAP4430_CM_ALWON_USBPHY_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_MOD, 0x0040)
/* CM2.CORE_CM2 register offsets */
#define OMAP4_CM_L3_1_CLKSTCTRL_OFFSET 0x0000
@@ -578,4 +614,54 @@
#define OMAP4430_CM_CEFUSE_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CEFUSE_MOD, 0x0000)
#define OMAP4_CM_CEFUSE_CEFUSE_CLKCTRL_OFFSET 0x0020
#define OMAP4430_CM_CEFUSE_CEFUSE_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CEFUSE_MOD, 0x0020)
+
+/* CM2.RESTORE_CM2 register offsets */
+#define OMAP4_CM_L3_1_CLKSTCTRL_RESTORE_OFFSET 0x0000
+#define OMAP4430_CM_L3_1_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0000)
+#define OMAP4_CM_L3_2_CLKSTCTRL_RESTORE_OFFSET 0x0004
+#define OMAP4430_CM_L3_2_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0004)
+#define OMAP4_CM_L4CFG_CLKSTCTRL_RESTORE_OFFSET 0x0008
+#define OMAP4430_CM_L4CFG_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0008)
+#define OMAP4_CM_MEMIF_CLKSTCTRL_RESTORE_OFFSET 0x000c
+#define OMAP4430_CM_MEMIF_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x000c)
+#define OMAP4_CM_L4PER_CLKSTCTRL_RESTORE_OFFSET 0x0010
+#define OMAP4430_CM_L4PER_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0010)
+#define OMAP4_CM_L3INIT_CLKSTCTRL_RESTORE_OFFSET 0x0014
+#define OMAP4430_CM_L3INIT_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0014)
+#define OMAP4_CM_L3INSTR_L3_3_CLKCTRL_RESTORE_OFFSET 0x0018
+#define OMAP4430_CM_L3INSTR_L3_3_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0018)
+#define OMAP4_CM_L3INSTR_L3_INSTR_CLKCTRL_RESTORE_OFFSET 0x001c
+#define OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x001c)
+#define OMAP4_CM_L3INSTR_OCP_WP1_CLKCTRL_RESTORE_OFFSET 0x0020
+#define OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0020)
+#define OMAP4_CM_CM2_PROFILING_CLKCTRL_RESTORE_OFFSET 0x0024
+#define OMAP4430_CM_CM2_PROFILING_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0024)
+#define OMAP4_CM_D2D_STATICDEP_RESTORE_OFFSET 0x0028
+#define OMAP4430_CM_D2D_STATICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0028)
+#define OMAP4_CM_L3_1_DYNAMICDEP_RESTORE_OFFSET 0x002c
+#define OMAP4430_CM_L3_1_DYNAMICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x002c)
+#define OMAP4_CM_L3_2_DYNAMICDEP_RESTORE_OFFSET 0x0030
+#define OMAP4430_CM_L3_2_DYNAMICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0030)
+#define OMAP4_CM_D2D_DYNAMICDEP_RESTORE_OFFSET 0x0034
+#define OMAP4430_CM_D2D_DYNAMICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0034)
+#define OMAP4_CM_L4CFG_DYNAMICDEP_RESTORE_OFFSET 0x0038
+#define OMAP4430_CM_L4CFG_DYNAMICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0038)
+#define OMAP4_CM_L4PER_DYNAMICDEP_RESTORE_OFFSET 0x003c
+#define OMAP4430_CM_L4PER_DYNAMICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x003c)
+#define OMAP4_CM_L4PER_GPIO2_CLKCTRL_RESTORE_OFFSET 0x0040
+#define OMAP4430_CM_L4PER_GPIO2_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0040)
+#define OMAP4_CM_L4PER_GPIO3_CLKCTRL_RESTORE_OFFSET 0x0044
+#define OMAP4430_CM_L4PER_GPIO3_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0044)
+#define OMAP4_CM_L4PER_GPIO4_CLKCTRL_RESTORE_OFFSET 0x0048
+#define OMAP4430_CM_L4PER_GPIO4_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0048)
+#define OMAP4_CM_L4PER_GPIO5_CLKCTRL_RESTORE_OFFSET 0x004c
+#define OMAP4430_CM_L4PER_GPIO5_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x004c)
+#define OMAP4_CM_L4PER_GPIO6_CLKCTRL_RESTORE_OFFSET 0x0050
+#define OMAP4430_CM_L4PER_GPIO6_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0050)
+#define OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_RESTORE_OFFSET 0x0054
+#define OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0054)
+#define OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_RESTORE_OFFSET 0x0058
+#define OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0058)
+#define OMAP4_CM_SDMA_STATICDEP_RESTORE_OFFSET 0x005c
+#define OMAP4430_CM_SDMA_STATICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x005c)
#endif
diff --git a/arch/arm/mach-omap2/cm4xxx.c b/arch/arm/mach-omap2/cm4xxx.c
index b101091e95d6..f8a660a1a4a6 100644
--- a/arch/arm/mach-omap2/cm4xxx.c
+++ b/arch/arm/mach-omap2/cm4xxx.c
@@ -43,7 +43,6 @@
* using separate functional clock
* 0x3 disabled: Module is disabled and cannot be accessed
*
- * TODO: Need to handle module accessible in idle state
*/
int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg)
{
@@ -52,9 +51,11 @@ int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg)
if (!clkctrl_reg)
return 0;
- omap_test_timeout(((__raw_readl(clkctrl_reg) &
- OMAP4430_IDLEST_MASK) == 0),
- MAX_MODULE_READY_TIME, i);
+ omap_test_timeout((
+ ((__raw_readl(clkctrl_reg) & OMAP4430_IDLEST_MASK) == 0) ||
+ (((__raw_readl(clkctrl_reg) & OMAP4430_IDLEST_MASK) >>
+ OMAP4430_IDLEST_SHIFT) == 0x2)),
+ MAX_MODULE_READY_TIME, i);
return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
}
diff --git a/arch/arm/mach-omap2/common.c b/arch/arm/mach-omap2/common.c
new file mode 100644
index 000000000000..778929f7e92d
--- /dev/null
+++ b/arch/arm/mach-omap2/common.c
@@ -0,0 +1,135 @@
+/*
+ * linux/arch/arm/mach-omap2/common.c
+ *
+ * Code common to all OMAP2+ machines.
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Copyright (C) 2010 Nokia Corporation
+ * Tony Lindgren <tony@atomide.com>
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.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/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/common.h>
+#include <plat/board.h>
+#include <plat/mux.h>
+
+#include <plat/clock.h>
+
+#include "sdrc.h"
+#include "control.h"
+
+/* Global address base setup code */
+
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+
+static void __init __omap2_set_globals(struct omap_globals *omap2_globals)
+{
+ omap2_set_globals_tap(omap2_globals);
+ omap2_set_globals_sdrc(omap2_globals);
+ omap2_set_globals_control(omap2_globals);
+ omap2_set_globals_prcm(omap2_globals);
+}
+
+#endif
+
+#if defined(CONFIG_ARCH_OMAP2420)
+
+static struct omap_globals omap242x_globals = {
+ .class = OMAP242X_CLASS,
+ .tap = OMAP2_L4_IO_ADDRESS(0x48014000),
+ .sdrc = OMAP2420_SDRC_BASE,
+ .sms = OMAP2420_SMS_BASE,
+ .ctrl = OMAP242X_CTRL_BASE,
+ .prm = OMAP2420_PRM_BASE,
+ .cm = OMAP2420_CM_BASE,
+ .uart1_phys = OMAP2_UART1_BASE,
+ .uart2_phys = OMAP2_UART2_BASE,
+ .uart3_phys = OMAP2_UART3_BASE,
+};
+
+void __init omap2_set_globals_242x(void)
+{
+ __omap2_set_globals(&omap242x_globals);
+}
+#endif
+
+#if defined(CONFIG_ARCH_OMAP2430)
+
+static struct omap_globals omap243x_globals = {
+ .class = OMAP243X_CLASS,
+ .tap = OMAP2_L4_IO_ADDRESS(0x4900a000),
+ .sdrc = OMAP243X_SDRC_BASE,
+ .sms = OMAP243X_SMS_BASE,
+ .ctrl = OMAP243X_CTRL_BASE,
+ .prm = OMAP2430_PRM_BASE,
+ .cm = OMAP2430_CM_BASE,
+ .uart1_phys = OMAP2_UART1_BASE,
+ .uart2_phys = OMAP2_UART2_BASE,
+ .uart3_phys = OMAP2_UART3_BASE,
+};
+
+void __init omap2_set_globals_243x(void)
+{
+ __omap2_set_globals(&omap243x_globals);
+}
+#endif
+
+#if defined(CONFIG_ARCH_OMAP3)
+
+static struct omap_globals omap3_globals = {
+ .class = OMAP343X_CLASS,
+ .tap = OMAP2_L4_IO_ADDRESS(0x4830A000),
+ .sdrc = OMAP343X_SDRC_BASE,
+ .sms = OMAP343X_SMS_BASE,
+ .ctrl = OMAP343X_CTRL_BASE,
+ .prm = OMAP3430_PRM_BASE,
+ .cm = OMAP3430_CM_BASE,
+ .uart1_phys = OMAP3_UART1_BASE,
+ .uart2_phys = OMAP3_UART2_BASE,
+ .uart3_phys = OMAP3_UART3_BASE,
+ .uart4_phys = OMAP3_UART4_BASE, /* Only on 3630 */
+};
+
+void __init omap2_set_globals_3xxx(void)
+{
+ __omap2_set_globals(&omap3_globals);
+}
+
+void __init omap3_map_io(void)
+{
+ omap2_set_globals_3xxx();
+ omap34xx_map_common_io();
+}
+#endif
+
+#if defined(CONFIG_ARCH_OMAP4)
+static struct omap_globals omap4_globals = {
+ .class = OMAP443X_CLASS,
+ .tap = OMAP2_L4_IO_ADDRESS(OMAP443X_SCM_BASE),
+ .ctrl = OMAP443X_SCM_BASE,
+ .ctrl_pad = OMAP443X_CTRL_BASE,
+ .prm = OMAP4430_PRM_BASE,
+ .cm = OMAP4430_CM_BASE,
+ .cm2 = OMAP4430_CM2_BASE,
+ .uart1_phys = OMAP4_UART1_BASE,
+ .uart2_phys = OMAP4_UART2_BASE,
+ .uart3_phys = OMAP4_UART3_BASE,
+ .uart4_phys = OMAP4_UART4_BASE,
+};
+
+void __init omap2_set_globals_443x(void)
+{
+ omap2_set_globals_tap(&omap4_globals);
+ omap2_set_globals_control(&omap4_globals);
+ omap2_set_globals_prcm(&omap4_globals);
+}
+#endif
+
diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index a8d20eef2306..1fa3294b6048 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -16,15 +16,18 @@
#include <linux/io.h>
#include <plat/common.h>
-#include <plat/control.h>
#include <plat/sdrc.h>
+
#include "cm-regbits-34xx.h"
#include "prm-regbits-34xx.h"
#include "cm.h"
#include "prm.h"
#include "sdrc.h"
+#include "pm.h"
+#include "control.h"
static void __iomem *omap2_ctrl_base;
+static void __iomem *omap4_ctrl_pad_base;
#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
struct omap3_scratchpad {
@@ -137,6 +140,7 @@ static struct omap3_control_regs control_context;
#endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */
#define OMAP_CTRL_REGADDR(reg) (omap2_ctrl_base + (reg))
+#define OMAP4_CTRL_PAD_REGADDR(reg) (omap4_ctrl_pad_base + (reg))
void __init omap2_set_globals_control(struct omap_globals *omap2_globals)
{
@@ -145,6 +149,12 @@ void __init omap2_set_globals_control(struct omap_globals *omap2_globals)
omap2_ctrl_base = ioremap(omap2_globals->ctrl, SZ_4K);
WARN_ON(!omap2_ctrl_base);
}
+
+ /* Static mapping, never released */
+ if (omap2_globals->ctrl_pad) {
+ omap4_ctrl_pad_base = ioremap(omap2_globals->ctrl_pad, SZ_4K);
+ WARN_ON(!omap4_ctrl_pad_base);
+ }
}
void __iomem *omap_ctrl_base_get(void)
@@ -182,6 +192,23 @@ void omap_ctrl_writel(u32 val, u16 offset)
__raw_writel(val, OMAP_CTRL_REGADDR(offset));
}
+/*
+ * On OMAP4 control pad are not addressable from control
+ * core base. So the common omap_ctrl_read/write APIs breaks
+ * Hence export separate APIs to manage the omap4 pad control
+ * registers. This APIs will work only for OMAP4
+ */
+
+u32 omap4_ctrl_pad_readl(u16 offset)
+{
+ return __raw_readl(OMAP4_CTRL_PAD_REGADDR(offset));
+}
+
+void omap4_ctrl_pad_writel(u32 val, u16 offset)
+{
+ __raw_writel(val, OMAP4_CTRL_PAD_REGADDR(offset));
+}
+
#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
/*
* Clears the scratchpad contents in case of cold boot-
@@ -190,7 +217,7 @@ void omap_ctrl_writel(u32 val, u16 offset)
void omap3_clear_scratchpad_contents(void)
{
u32 max_offset = OMAP343X_SCRATCHPAD_ROM_OFFSET;
- u32 *v_addr;
+ void __iomem *v_addr;
u32 offset = 0;
v_addr = OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD_ROM);
if (prm_read_mod_reg(OMAP3430_GR_MOD, OMAP3_PRM_RSTST_OFFSET) &
@@ -206,7 +233,7 @@ void omap3_clear_scratchpad_contents(void)
/* Populate the scratchpad structure with restore structure */
void omap3_save_scratchpad_contents(void)
{
- void * __iomem scratchpad_address;
+ void __iomem *scratchpad_address;
u32 arm_context_addr;
struct omap3_scratchpad scratchpad_contents;
struct omap3_scratchpad_prcm_block prcm_block_contents;
diff --git a/arch/arm/plat-omap/include/plat/control.h b/arch/arm/mach-omap2/control.h
index 131bf405c2f6..b6c6b7c450b3 100644
--- a/arch/arm/plat-omap/include/plat/control.h
+++ b/arch/arm/mach-omap2/control.h
@@ -1,10 +1,10 @@
/*
- * arch/arm/plat-omap/include/mach/control.h
+ * arch/arm/mach-omap2/control.h
*
* OMAP2/3/4 System Control Module definitions
*
- * Copyright (C) 2007-2009 Texas Instruments, Inc.
- * Copyright (C) 2007-2008 Nokia Corporation
+ * Copyright (C) 2007-2010 Texas Instruments, Inc.
+ * Copyright (C) 2007-2008, 2010 Nokia Corporation
*
* Written by Paul Walmsley
*
@@ -13,10 +13,14 @@
* the Free Software Foundation.
*/
-#ifndef __ASM_ARCH_CONTROL_H
-#define __ASM_ARCH_CONTROL_H
+#ifndef __ARCH_ARM_MACH_OMAP2_CONTROL_H
+#define __ARCH_ARM_MACH_OMAP2_CONTROL_H
#include <mach/io.h>
+#include <mach/ctrl_module_core_44xx.h>
+#include <mach/ctrl_module_wkup_44xx.h>
+#include <mach/ctrl_module_pad_core_44xx.h>
+#include <mach/ctrl_module_pad_wkup_44xx.h>
#ifndef __ASSEMBLY__
#define OMAP242X_CTRL_REGADDR(reg) \
@@ -204,12 +208,6 @@
#define OMAP3_PADCONF_SAD2D_MSTANDBY 0x250
#define OMAP3_PADCONF_SAD2D_IDLEACK 0x254
-/* 44xx control status register offset */
-#define OMAP44XX_CONTROL_STATUS 0x2c4
-
-/* 44xx-only CONTROL_GENERAL register offsets */
-#define OMAP44XX_CONTROL_MMC1 0x628
-#define OMAP44XX_CONTROL_PBIAS_LITE 0x600
/*
* REVISIT: This list of registers is not comprehensive - there are more
* that should be added.
@@ -225,6 +223,8 @@
#define OMAP2_MMCSDIO1ADPCLKISEL (1 << 24) /* MMC1 loop back clock */
#define OMAP24XX_USBSTANDBYCTRL (1 << 15)
#define OMAP2_MCBSP2_CLKS_MASK (1 << 6)
+#define OMAP2_MCBSP1_FSR_MASK (1 << 4)
+#define OMAP2_MCBSP1_CLKR_MASK (1 << 3)
#define OMAP2_MCBSP1_CLKS_MASK (1 << 2)
/* CONTROL_DEVCONF1 bits */
@@ -255,23 +255,6 @@
#define OMAP2_PBIASLITEPWRDNZ0 (1 << 1)
#define OMAP2_PBIASLITEVMODE0 (1 << 0)
-/* CONTROL_PBIAS_LITE bits for OMAP4 */
-#define OMAP4_MMC1_PWRDNZ (1 << 26)
-#define OMAP4_MMC1_PBIASLITE_HIZ_MODE (1 << 25)
-#define OMAP4_MMC1_PBIASLITE_SUPPLY_HI_OUT (1 << 24)
-#define OMAP4_MMC1_PBIASLITE_VMODE_ERROR (1 << 23)
-#define OMAP4_MMC1_PBIASLITE_PWRDNZ (1 << 22)
-#define OMAP4_MMC1_PBIASLITE_VMODE (1 << 21)
-#define OMAP4_USBC1_ICUSB_PWRDNZ (1 << 20)
-
-#define OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP0 (1 << 31)
-#define OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP1 (1 << 30)
-#define OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP2 (1 << 29)
-#define OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP3 (1 << 28)
-#define OMAP4_CONTROL_SDMMC1_DR0_SPEEDCTRL (1 << 27)
-#define OMAP4_CONTROL_SDMMC1_DR1_SPEEDCTRL (1 << 26)
-#define OMAP4_CONTROL_SDMMC1_DR2_SPEEDCTRL (1 << 25)
-
/* CONTROL_PROG_IO1 bits */
#define OMAP3630_PRG_SDMMC1_SPEEDCTRL (1 << 20)
@@ -338,12 +321,12 @@
#define FEAT_L2CACHE_256KB 3
#define OMAP3_ISP_SHIFT 5
-#define OMAP3_ISP_MASK (1<< OMAP3_ISP_SHIFT)
+#define OMAP3_ISP_MASK (1 << OMAP3_ISP_SHIFT)
#define FEAT_ISP 0
#define FEAT_ISP_NONE 1
#define OMAP3_NEON_SHIFT 4
-#define OMAP3_NEON_MASK (1<< OMAP3_NEON_SHIFT)
+#define OMAP3_NEON_MASK (1 << OMAP3_NEON_SHIFT)
#define FEAT_NEON 0
#define FEAT_NEON_NONE 1
@@ -354,9 +337,11 @@ extern void __iomem *omap_ctrl_base_get(void);
extern u8 omap_ctrl_readb(u16 offset);
extern u16 omap_ctrl_readw(u16 offset);
extern u32 omap_ctrl_readl(u16 offset);
+extern u32 omap4_ctrl_pad_readl(u16 offset);
extern void omap_ctrl_writeb(u8 val, u16 offset);
extern void omap_ctrl_writew(u16 val, u16 offset);
extern void omap_ctrl_writel(u32 val, u16 offset);
+extern void omap4_ctrl_pad_writel(u32 val, u16 offset);
extern void omap3_save_scratchpad_contents(void);
extern void omap3_clear_scratchpad_contents(void);
@@ -371,11 +356,13 @@ extern void omap3_control_restore_context(void);
#define omap_ctrl_readb(x) 0
#define omap_ctrl_readw(x) 0
#define omap_ctrl_readl(x) 0
+#define omap4_ctrl_pad_readl(x) 0
#define omap_ctrl_writeb(x, y) WARN_ON(1)
#define omap_ctrl_writew(x, y) WARN_ON(1)
#define omap_ctrl_writel(x, y) WARN_ON(1)
+#define omap4_ctrl_pad_writel(x, y) WARN_ON(1)
#endif
#endif /* __ASSEMBLY__ */
-#endif /* __ASM_ARCH_CONTROL_H */
+#endif /* __ARCH_ARM_MACH_OMAP2_CONTROL_H */
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index 3d3d035db9af..0d50b45d041c 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -29,10 +29,10 @@
#include <plat/irqs.h>
#include <plat/powerdomain.h>
#include <plat/clockdomain.h>
-#include <plat/control.h>
#include <plat/serial.h>
#include "pm.h"
+#include "control.h"
#ifdef CONFIG_CPU_IDLE
@@ -60,7 +60,8 @@ struct omap3_processor_cx {
struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES];
struct omap3_processor_cx current_cx_state;
-struct powerdomain *mpu_pd, *core_pd;
+struct powerdomain *mpu_pd, *core_pd, *per_pd;
+struct powerdomain *cam_pd;
/*
* The latencies/thresholds for various C states have
@@ -233,14 +234,60 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
struct cpuidle_state *state)
{
struct cpuidle_state *new_state = next_valid_state(dev, state);
+ u32 core_next_state, per_next_state = 0, per_saved_state = 0;
+ u32 cam_state;
+ struct omap3_processor_cx *cx;
+ int ret;
if ((state->flags & CPUIDLE_FLAG_CHECK_BM) && omap3_idle_bm_check()) {
BUG_ON(!dev->safe_state);
new_state = dev->safe_state;
+ goto select_state;
}
+ cx = cpuidle_get_statedata(state);
+ core_next_state = cx->core_state;
+
+ /*
+ * FIXME: we currently manage device-specific idle states
+ * for PER and CORE in combination with CPU-specific
+ * idle states. This is wrong, and device-specific
+ * idle managment needs to be separated out into
+ * its own code.
+ */
+
+ /*
+ * Prevent idle completely if CAM is active.
+ * CAM does not have wakeup capability in OMAP3.
+ */
+ cam_state = pwrdm_read_pwrst(cam_pd);
+ if (cam_state == PWRDM_POWER_ON) {
+ new_state = dev->safe_state;
+ goto select_state;
+ }
+
+ /*
+ * Prevent PER off if CORE is not in retention or off as this
+ * would disable PER wakeups completely.
+ */
+ per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd);
+ if ((per_next_state == PWRDM_POWER_OFF) &&
+ (core_next_state > PWRDM_POWER_RET))
+ per_next_state = PWRDM_POWER_RET;
+
+ /* Are we changing PER target state? */
+ if (per_next_state != per_saved_state)
+ pwrdm_set_next_pwrst(per_pd, per_next_state);
+
+select_state:
dev->last_state = new_state;
- return omap3_enter_idle(dev, new_state);
+ ret = omap3_enter_idle(dev, new_state);
+
+ /* Restore original PER state if it was modified */
+ if (per_next_state != per_saved_state)
+ pwrdm_set_next_pwrst(per_pd, per_saved_state);
+
+ return ret;
}
DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
@@ -328,7 +375,8 @@ void omap_init_power_states(void)
cpuidle_params_table[OMAP3_STATE_C2].threshold;
omap3_power_states[OMAP3_STATE_C2].mpu_state = PWRDM_POWER_ON;
omap3_power_states[OMAP3_STATE_C2].core_state = PWRDM_POWER_ON;
- omap3_power_states[OMAP3_STATE_C2].flags = CPUIDLE_FLAG_TIME_VALID;
+ omap3_power_states[OMAP3_STATE_C2].flags = CPUIDLE_FLAG_TIME_VALID |
+ CPUIDLE_FLAG_CHECK_BM;
/* C3 . MPU CSWR + Core inactive */
omap3_power_states[OMAP3_STATE_C3].valid =
@@ -426,6 +474,8 @@ int __init omap3_idle_init(void)
mpu_pd = pwrdm_lookup("mpu_pwrdm");
core_pd = pwrdm_lookup("core_pwrdm");
+ per_pd = pwrdm_lookup("per_pwrdm");
+ cam_pd = pwrdm_lookup("cam_pwrdm");
omap_init_power_states();
cpuidle_register_driver(&omap3_idle_driver);
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 512ae4696a6c..5a0c148e23bc 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -9,12 +9,12 @@
* (at your option) any later version.
*/
-#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/clk.h>
+#include <linux/err.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
@@ -22,15 +22,17 @@
#include <asm/mach/map.h>
#include <asm/pmu.h>
-#include <plat/control.h>
#include <plat/tc.h>
#include <plat/board.h>
#include <plat/mcbsp.h>
#include <mach/gpio.h>
#include <plat/mmc.h>
#include <plat/dma.h>
+#include <plat/omap_hwmod.h>
+#include <plat/omap_device.h>
#include "mux.h"
+#include "control.h"
#if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE)
@@ -536,6 +538,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_OMAP2
+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_OMAP3
+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)
@@ -662,7 +734,7 @@ static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
omap_mux_init_signal("sdmmc_dat0", 0);
omap_mux_init_signal("sdmmc_dat_dir0", 0);
omap_mux_init_signal("sdmmc_cmd_dir", 0);
- if (mmc_controller->slots[0].wires == 4) {
+ if (mmc_controller->slots[0].caps & MMC_CAP_4_BIT_DATA) {
omap_mux_init_signal("sdmmc_dat1", 0);
omap_mux_init_signal("sdmmc_dat2", 0);
omap_mux_init_signal("sdmmc_dat3", 0);
@@ -690,8 +762,8 @@ static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
OMAP_PIN_INPUT_PULLUP);
omap_mux_init_signal("sdmmc1_dat0",
OMAP_PIN_INPUT_PULLUP);
- if (mmc_controller->slots[0].wires == 4 ||
- mmc_controller->slots[0].wires == 8) {
+ if (mmc_controller->slots[0].caps &
+ (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) {
omap_mux_init_signal("sdmmc1_dat1",
OMAP_PIN_INPUT_PULLUP);
omap_mux_init_signal("sdmmc1_dat2",
@@ -699,7 +771,8 @@ static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
omap_mux_init_signal("sdmmc1_dat3",
OMAP_PIN_INPUT_PULLUP);
}
- if (mmc_controller->slots[0].wires == 8) {
+ if (mmc_controller->slots[0].caps &
+ MMC_CAP_8_BIT_DATA) {
omap_mux_init_signal("sdmmc1_dat4",
OMAP_PIN_INPUT_PULLUP);
omap_mux_init_signal("sdmmc1_dat5",
@@ -723,8 +796,8 @@ static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
* For 8 wire configurations, Lines DAT4, 5, 6 and 7 need to be muxed
* in the board-*.c files
*/
- if (mmc_controller->slots[0].wires == 4 ||
- mmc_controller->slots[0].wires == 8) {
+ if (mmc_controller->slots[0].caps &
+ (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) {
omap_mux_init_signal("sdmmc2_dat1",
OMAP_PIN_INPUT_PULLUP);
omap_mux_init_signal("sdmmc2_dat2",
@@ -732,7 +805,8 @@ static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
omap_mux_init_signal("sdmmc2_dat3",
OMAP_PIN_INPUT_PULLUP);
}
- if (mmc_controller->slots[0].wires == 8) {
+ if (mmc_controller->slots[0].caps &
+ MMC_CAP_8_BIT_DATA) {
omap_mux_init_signal("sdmmc2_dat4.sdmmc2_dat4",
OMAP_PIN_INPUT_PULLUP);
omap_mux_init_signal("sdmmc2_dat5.sdmmc2_dat5",
@@ -783,13 +857,13 @@ void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
case 3:
if (!cpu_is_omap44xx())
return;
- base = OMAP4_MMC4_BASE + OMAP4_MMC_REG_OFFSET;
+ base = OMAP4_MMC4_BASE;
irq = OMAP44XX_IRQ_MMC4;
break;
case 4:
if (!cpu_is_omap44xx())
return;
- base = OMAP4_MMC5_BASE + OMAP4_MMC_REG_OFFSET;
+ base = OMAP4_MMC5_BASE;
irq = OMAP44XX_IRQ_MMC5;
break;
default:
@@ -800,10 +874,8 @@ void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
size = OMAP2420_MMC_SIZE;
name = "mmci-omap";
} else if (cpu_is_omap44xx()) {
- if (i < 3) {
- base += OMAP4_MMC_REG_OFFSET;
+ if (i < 3)
irq += OMAP44XX_IRQ_GIC_START;
- }
size = OMAP4_HSMMC_SIZE;
name = "mmci-omap-hs";
} else {
@@ -879,11 +951,72 @@ static inline void omap_init_vout(void) {}
/*-------------------------------------------------------------------------*/
+/*
+ * Inorder to avoid any assumptions from bootloader regarding WDT
+ * settings, WDT module is reset during init. This enables the watchdog
+ * timer. Hence it is required to disable the watchdog after the WDT reset
+ * during init. Otherwise the system would reboot as per the default
+ * watchdog timer registers settings.
+ */
+#define OMAP_WDT_WPS (0x34)
+#define OMAP_WDT_SPR (0x48)
+
+static int omap2_disable_wdt(struct omap_hwmod *oh, void *unused)
+{
+ void __iomem *base;
+ int ret;
+
+ if (!oh) {
+ pr_err("%s: Could not look up wdtimer_hwmod\n", __func__);
+ return -EINVAL;
+ }
+
+ base = omap_hwmod_get_mpu_rt_va(oh);
+ if (!base) {
+ pr_err("%s: Could not get the base address for %s\n",
+ oh->name, __func__);
+ return -EINVAL;
+ }
+
+ /* Enable the clocks before accessing the WDT registers */
+ ret = omap_hwmod_enable(oh);
+ if (ret) {
+ pr_err("%s: Could not enable clocks for %s\n",
+ oh->name, __func__);
+ return ret;
+ }
+
+ /* sequence required to disable watchdog */
+ __raw_writel(0xAAAA, base + OMAP_WDT_SPR);
+ while (__raw_readl(base + OMAP_WDT_WPS) & 0x10)
+ cpu_relax();
+
+ __raw_writel(0x5555, base + OMAP_WDT_SPR);
+ while (__raw_readl(base + OMAP_WDT_WPS) & 0x10)
+ cpu_relax();
+
+ ret = omap_hwmod_idle(oh);
+ if (ret)
+ pr_err("%s: Could not disable clocks for %s\n",
+ oh->name, __func__);
+
+ return ret;
+}
+
+static void __init omap_disable_wdt(void)
+{
+ if (cpu_class_is_omap2())
+ omap_hwmod_for_each_by_class("wd_timer",
+ omap2_disable_wdt, NULL);
+ return;
+}
+
static int __init omap2_init_devices(void)
{
/* please keep these calls, and their implementations above,
* in alphabetical order so they're easier to sort through.
*/
+ omap_disable_wdt();
omap_hsmmc_reset();
omap_init_audio();
omap_init_camera();
@@ -893,8 +1026,45 @@ static int __init omap2_init_devices(void)
omap_hdq_init();
omap_init_sti();
omap_init_sham();
+ omap_init_aes();
omap_init_vout();
return 0;
}
arch_initcall(omap2_init_devices);
+
+#if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE)
+struct omap_device_pm_latency omap_wdt_latency[] = {
+ [0] = {
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ },
+};
+
+static int __init omap_init_wdt(void)
+{
+ int id = -1;
+ struct omap_device *od;
+ struct omap_hwmod *oh;
+ char *oh_name = "wd_timer2";
+ char *dev_name = "omap_wdt";
+
+ if (!cpu_class_is_omap2())
+ return 0;
+
+ oh = omap_hwmod_lookup(oh_name);
+ if (!oh) {
+ pr_err("Could not look up wd_timer%d hwmod\n", id);
+ return -EINVAL;
+ }
+
+ od = omap_device_build(dev_name, id, oh, NULL, 0,
+ omap_wdt_latency,
+ ARRAY_SIZE(omap_wdt_latency), 0);
+ WARN(IS_ERR(od), "Cant build omap_device for %s:%s.\n",
+ dev_name, oh->name);
+ return 0;
+}
+subsys_initcall(omap_init_wdt);
+#endif
diff --git a/arch/arm/mach-omap2/dsp.c b/arch/arm/mach-omap2/dsp.c
new file mode 100644
index 000000000000..6feeeae6c21b
--- /dev/null
+++ b/arch/arm/mach-omap2/dsp.c
@@ -0,0 +1,85 @@
+/*
+ * TI's OMAP DSP platform device registration
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.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 "prm.h"
+#include "cm.h"
+#ifdef CONFIG_BRIDGE_DVFS
+#include <plat/omap-pm.h>
+#endif
+
+#include <plat/dsp.h>
+
+extern phys_addr_t omap_dsp_get_mempool_base(void);
+
+static struct platform_device *omap_dsp_pdev;
+
+static struct omap_dsp_platform_data omap_dsp_pdata __initdata = {
+#ifdef CONFIG_BRIDGE_DVFS
+ .dsp_set_min_opp = omap_pm_dsp_set_min_opp,
+ .dsp_get_opp = omap_pm_dsp_get_opp,
+ .cpu_set_freq = omap_pm_cpu_set_freq,
+ .cpu_get_freq = omap_pm_cpu_get_freq,
+#endif
+ .dsp_prm_read = prm_read_mod_reg,
+ .dsp_prm_write = prm_write_mod_reg,
+ .dsp_prm_rmw_bits = prm_rmw_mod_reg_bits,
+ .dsp_cm_read = cm_read_mod_reg,
+ .dsp_cm_write = cm_write_mod_reg,
+ .dsp_cm_rmw_bits = cm_rmw_mod_reg_bits,
+};
+
+static int __init omap_dsp_init(void)
+{
+ struct platform_device *pdev;
+ int err = -ENOMEM;
+ struct omap_dsp_platform_data *pdata = &omap_dsp_pdata;
+
+ pdata->phys_mempool_base = omap_dsp_get_mempool_base();
+
+ if (pdata->phys_mempool_base) {
+ pdata->phys_mempool_size = CONFIG_TIDSPBRIDGE_MEMPOOL_SIZE;
+ pr_info("%s: %x bytes @ %x\n", __func__,
+ pdata->phys_mempool_size, pdata->phys_mempool_base);
+ }
+
+ pdev = platform_device_alloc("omap-dsp", -1);
+ if (!pdev)
+ goto err_out;
+
+ err = platform_device_add_data(pdev, pdata, sizeof(*pdata));
+ if (err)
+ goto err_out;
+
+ err = platform_device_add(pdev);
+ if (err)
+ goto err_out;
+
+ omap_dsp_pdev = pdev;
+ return 0;
+
+err_out:
+ platform_device_put(pdev);
+ return err;
+}
+module_init(omap_dsp_init);
+
+static void __exit omap_dsp_exit(void)
+{
+ platform_device_unregister(omap_dsp_pdev);
+}
+module_exit(omap_dsp_exit);
+
+MODULE_AUTHOR("Hiroshi DOYU");
+MODULE_DESCRIPTION("TI's OMAP DSP platform device registration");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-omap2/gpmc-smsc911x.c b/arch/arm/mach-omap2/gpmc-smsc911x.c
new file mode 100644
index 000000000000..703f150dd01d
--- /dev/null
+++ b/arch/arm/mach-omap2/gpmc-smsc911x.c
@@ -0,0 +1,113 @@
+/*
+ * linux/arch/arm/mach-omap2/gpmc-smsc911x.c
+ *
+ * Copyright (C) 2009 Li-Pro.Net
+ * Stephan Linz <linz@li-pro.net>
+ *
+ * Modified from linux/arch/arm/mach-omap2/gpmc-smc91x.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
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/smsc911x.h>
+
+#include <plat/board.h>
+#include <plat/gpmc.h>
+#include <plat/gpmc-smsc911x.h>
+
+static struct omap_smsc911x_platform_data *gpmc_cfg;
+
+static struct resource gpmc_smsc911x_resources[] = {
+ [0] = {
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct smsc911x_platform_config gpmc_smsc911x_config = {
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+ .flags = SMSC911X_USE_16BIT,
+};
+
+static struct platform_device gpmc_smsc911x_device = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(gpmc_smsc911x_resources),
+ .resource = gpmc_smsc911x_resources,
+ .dev = {
+ .platform_data = &gpmc_smsc911x_config,
+ },
+};
+
+/*
+ * Initialize smsc911x device connected to the GPMC. Note that we
+ * assume that pin multiplexing is done in the board-*.c file,
+ * or in the bootloader.
+ */
+void __init gpmc_smsc911x_init(struct omap_smsc911x_platform_data *board_data)
+{
+ unsigned long cs_mem_base;
+ int ret;
+
+ gpmc_cfg = board_data;
+
+ if (gpmc_cs_request(gpmc_cfg->cs, SZ_16M, &cs_mem_base) < 0) {
+ printk(KERN_ERR "Failed to request GPMC mem for smsc911x\n");
+ return;
+ }
+
+ gpmc_smsc911x_resources[0].start = cs_mem_base + 0x0;
+ gpmc_smsc911x_resources[0].end = cs_mem_base + 0xff;
+
+ if (gpio_request(gpmc_cfg->gpio_irq, "smsc911x irq") < 0) {
+ printk(KERN_ERR "Failed to request GPIO%d for smsc911x IRQ\n",
+ gpmc_cfg->gpio_irq);
+ goto free1;
+ }
+
+ gpio_direction_input(gpmc_cfg->gpio_irq);
+ gpmc_smsc911x_resources[1].start = gpio_to_irq(gpmc_cfg->gpio_irq);
+ gpmc_smsc911x_resources[1].flags |=
+ (gpmc_cfg->flags & IRQF_TRIGGER_MASK);
+
+ if (gpio_is_valid(gpmc_cfg->gpio_reset)) {
+ ret = gpio_request(gpmc_cfg->gpio_reset, "smsc911x reset");
+ if (ret) {
+ printk(KERN_ERR "Failed to request GPIO%d for smsc911x reset\n",
+ gpmc_cfg->gpio_reset);
+ goto free2;
+ }
+
+ gpio_direction_output(gpmc_cfg->gpio_reset, 1);
+ gpio_set_value(gpmc_cfg->gpio_reset, 0);
+ msleep(100);
+ gpio_set_value(gpmc_cfg->gpio_reset, 1);
+ }
+
+ if (platform_device_register(&gpmc_smsc911x_device) < 0) {
+ printk(KERN_ERR "Unable to register smsc911x device\n");
+ gpio_free(gpmc_cfg->gpio_reset);
+ goto free2;
+ }
+
+ return;
+
+free2:
+ gpio_free(gpmc_cfg->gpio_irq);
+free1:
+ gpmc_cs_free(gpmc_cfg->cs);
+
+ printk(KERN_ERR "Could not initialize smsc911x\n");
+}
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index c8f647b6205e..34272e4863fd 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -14,11 +14,11 @@
#include <linux/string.h>
#include <linux/delay.h>
#include <mach/hardware.h>
-#include <plat/control.h>
#include <plat/mmc.h>
#include <plat/omap-pm.h>
#include "hsmmc.h"
+#include "control.h"
#if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
@@ -135,10 +135,11 @@ static void omap4_hsmmc1_before_set_reg(struct device *dev, int slot,
*
* FIXME handle VMMC1A as needed ...
*/
- reg = omap_ctrl_readl(control_pbias_offset);
- reg &= ~(OMAP4_MMC1_PBIASLITE_PWRDNZ | OMAP4_MMC1_PWRDNZ |
- OMAP4_USBC1_ICUSB_PWRDNZ);
- omap_ctrl_writel(reg, control_pbias_offset);
+ reg = omap4_ctrl_pad_readl(control_pbias_offset);
+ reg &= ~(OMAP4_MMC1_PBIASLITE_PWRDNZ_MASK |
+ OMAP4_MMC1_PWRDNZ_MASK |
+ OMAP4_USBC1_ICUSB_PWRDNZ_MASK);
+ omap4_ctrl_pad_writel(reg, control_pbias_offset);
}
static void omap4_hsmmc1_after_set_reg(struct device *dev, int slot,
@@ -147,30 +148,33 @@ static void omap4_hsmmc1_after_set_reg(struct device *dev, int slot,
u32 reg;
if (power_on) {
- reg = omap_ctrl_readl(control_pbias_offset);
- reg |= OMAP4_MMC1_PBIASLITE_PWRDNZ;
+ reg = omap4_ctrl_pad_readl(control_pbias_offset);
+ reg |= OMAP4_MMC1_PBIASLITE_PWRDNZ_MASK;
if ((1 << vdd) <= MMC_VDD_165_195)
- reg &= ~OMAP4_MMC1_PBIASLITE_VMODE;
+ reg &= ~OMAP4_MMC1_PBIASLITE_VMODE_MASK;
else
- reg |= OMAP4_MMC1_PBIASLITE_VMODE;
- reg |= (OMAP4_MMC1_PBIASLITE_PWRDNZ | OMAP4_MMC1_PWRDNZ |
- OMAP4_USBC1_ICUSB_PWRDNZ);
- omap_ctrl_writel(reg, control_pbias_offset);
+ reg |= OMAP4_MMC1_PBIASLITE_VMODE_MASK;
+ reg |= (OMAP4_MMC1_PBIASLITE_PWRDNZ_MASK |
+ OMAP4_MMC1_PWRDNZ_MASK |
+ OMAP4_USBC1_ICUSB_PWRDNZ_MASK);
+ omap4_ctrl_pad_writel(reg, control_pbias_offset);
/* 4 microsec delay for comparator to generate an error*/
udelay(4);
- reg = omap_ctrl_readl(control_pbias_offset);
- if (reg & OMAP4_MMC1_PBIASLITE_VMODE_ERROR) {
+ reg = omap4_ctrl_pad_readl(control_pbias_offset);
+ if (reg & OMAP4_MMC1_PBIASLITE_VMODE_ERROR_MASK) {
pr_err("Pbias Voltage is not same as LDO\n");
/* Caution : On VMODE_ERROR Power Down MMC IO */
- reg &= ~(OMAP4_MMC1_PWRDNZ | OMAP4_USBC1_ICUSB_PWRDNZ);
- omap_ctrl_writel(reg, control_pbias_offset);
+ reg &= ~(OMAP4_MMC1_PWRDNZ_MASK |
+ OMAP4_USBC1_ICUSB_PWRDNZ_MASK);
+ omap4_ctrl_pad_writel(reg, control_pbias_offset);
}
} else {
- reg = omap_ctrl_readl(control_pbias_offset);
- reg |= (OMAP4_MMC1_PBIASLITE_PWRDNZ |
- OMAP4_MMC1_PBIASLITE_VMODE | OMAP4_MMC1_PWRDNZ |
- OMAP4_USBC1_ICUSB_PWRDNZ);
- omap_ctrl_writel(reg, control_pbias_offset);
+ reg = omap4_ctrl_pad_readl(control_pbias_offset);
+ reg |= (OMAP4_MMC1_PBIASLITE_PWRDNZ_MASK |
+ OMAP4_MMC1_PWRDNZ_MASK |
+ OMAP4_MMC1_PBIASLITE_VMODE_MASK |
+ OMAP4_USBC1_ICUSB_PWRDNZ_MASK);
+ omap4_ctrl_pad_writel(reg, control_pbias_offset);
}
}
@@ -218,17 +222,18 @@ void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
control_devconf1_offset = OMAP343X_CONTROL_DEVCONF1;
}
} else {
- control_pbias_offset = OMAP44XX_CONTROL_PBIAS_LITE;
- control_mmc1 = OMAP44XX_CONTROL_MMC1;
- reg = omap_ctrl_readl(control_mmc1);
- reg |= (OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP0 |
- OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP1);
- reg &= ~(OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP2 |
- OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP3);
- reg |= (OMAP4_CONTROL_SDMMC1_DR0_SPEEDCTRL |
- OMAP4_CONTROL_SDMMC1_DR1_SPEEDCTRL |
- OMAP4_CONTROL_SDMMC1_DR2_SPEEDCTRL);
- omap_ctrl_writel(reg, control_mmc1);
+ control_pbias_offset =
+ OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_PBIASLITE;
+ control_mmc1 = OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MMC1;
+ reg = omap4_ctrl_pad_readl(control_mmc1);
+ reg |= (OMAP4_SDMMC1_PUSTRENGTH_GRP0_MASK |
+ OMAP4_SDMMC1_PUSTRENGTH_GRP1_MASK);
+ reg &= ~(OMAP4_SDMMC1_PUSTRENGTH_GRP2_MASK |
+ OMAP4_SDMMC1_PUSTRENGTH_GRP3_MASK);
+ reg |= (OMAP4_USBC1_DR0_SPEEDCTRL_MASK|
+ OMAP4_SDMMC1_DR1_SPEEDCTRL_MASK |
+ OMAP4_SDMMC1_DR2_SPEEDCTRL_MASK);
+ omap4_ctrl_pad_writel(reg, control_mmc1);
}
for (c = controllers; c->mmc; c++) {
@@ -258,9 +263,13 @@ void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
"mmc%islot%i", c->mmc, 1);
mmc->slots[0].name = hc->name;
mmc->nr_slots = 1;
- mmc->slots[0].wires = c->wires;
+ mmc->slots[0].caps = c->caps;
mmc->slots[0].internal_clock = !c->ext_clock;
mmc->dma_mask = 0xffffffff;
+ if (cpu_is_omap44xx())
+ mmc->reg_offset = OMAP4_MMC_REG_OFFSET;
+ else
+ mmc->reg_offset = 0;
mmc->get_context_loss_count = hsmmc_get_context_loss;
@@ -298,6 +307,9 @@ void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
else
mmc->slots[0].features |= HSMMC_HAS_PBIAS;
+ if (cpu_is_omap44xx() && (omap_rev() > OMAP4430_REV_ES1_0))
+ mmc->slots[0].features |= HSMMC_HAS_UPDATED_RESET;
+
switch (c->mmc) {
case 1:
if (mmc->slots[0].features & HSMMC_HAS_PBIAS) {
@@ -316,16 +328,20 @@ void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
}
/* Omap3630 HSMMC1 supports only 4-bit */
- if (cpu_is_omap3630() && c->wires > 4) {
- c->wires = 4;
- mmc->slots[0].wires = c->wires;
+ if (cpu_is_omap3630() &&
+ (c->caps & MMC_CAP_8_BIT_DATA)) {
+ c->caps &= ~MMC_CAP_8_BIT_DATA;
+ c->caps |= MMC_CAP_4_BIT_DATA;
+ mmc->slots[0].caps = c->caps;
}
break;
case 2:
if (c->ext_clock)
c->transceiver = 1;
- if (c->transceiver && c->wires > 4)
- c->wires = 4;
+ if (c->transceiver && (c->caps & MMC_CAP_8_BIT_DATA)) {
+ c->caps &= ~MMC_CAP_8_BIT_DATA;
+ c->caps |= MMC_CAP_4_BIT_DATA;
+ }
/* FALLTHROUGH */
case 3:
if (mmc->slots[0].features & HSMMC_HAS_PBIAS) {
diff --git a/arch/arm/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h
index 1fe6f0187177..f119348827d4 100644
--- a/arch/arm/mach-omap2/hsmmc.h
+++ b/arch/arm/mach-omap2/hsmmc.h
@@ -10,7 +10,8 @@ struct mmc_card;
struct omap2_hsmmc_info {
u8 mmc; /* controller 1/2/3 */
- u8 wires; /* 1/4/8 wires */
+ u32 caps; /* 4/8 wires and any additional host
+ * capabilities OR'd (ref. linux/mmc/host.h) */
bool transceiver; /* MMC-2 option */
bool ext_clock; /* use external pin for input clock */
bool cover_only; /* No card detect - just cover switch */
@@ -23,7 +24,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/id.c b/arch/arm/mach-omap2/id.c
index 9a879f959509..5f9086c65e48 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -22,11 +22,12 @@
#include <asm/cputype.h>
#include <plat/common.h>
-#include <plat/control.h>
#include <plat/cpu.h>
#include <mach/id.h>
+#include "control.h"
+
static struct omap_chip_id omap_chip;
static unsigned int omap_revision;
@@ -60,7 +61,7 @@ int omap_type(void)
} else if (cpu_is_omap34xx()) {
val = omap_ctrl_readl(OMAP343X_CONTROL_STATUS);
} else if (cpu_is_omap44xx()) {
- val = omap_ctrl_readl(OMAP44XX_CONTROL_STATUS);
+ val = omap_ctrl_readl(OMAP4_CTRL_MODULE_CORE_STATUS);
} else {
pr_err("Cannot detect omap type!\n");
goto out;
@@ -298,7 +299,6 @@ static void __init omap4_check_revision(void)
u32 idcode;
u16 hawkeye;
u8 rev;
- char *rev_name = "ES1.0";
/*
* The IC rev detection is done with hawkeye and rev.
@@ -309,14 +309,39 @@ static void __init omap4_check_revision(void)
hawkeye = (idcode >> 12) & 0xffff;
rev = (idcode >> 28) & 0xff;
- if ((hawkeye == 0xb852) && (rev == 0x0)) {
- omap_revision = OMAP4430_REV_ES1_0;
- omap_chip.oc |= CHIP_IS_OMAP4430ES1;
- pr_info("OMAP%04x %s\n", omap_rev() >> 16, rev_name);
- return;
+ /*
+ * Few initial ES2.0 samples IDCODE is same as ES1.0
+ * Use ARM register to detect the correct ES version
+ */
+ if (!rev) {
+ idcode = read_cpuid(CPUID_ID);
+ rev = (idcode & 0xf) - 1;
+ }
+
+ switch (hawkeye) {
+ case 0xb852:
+ switch (rev) {
+ case 0:
+ omap_revision = OMAP4430_REV_ES1_0;
+ omap_chip.oc |= CHIP_IS_OMAP4430ES1;
+ break;
+ case 1:
+ omap_revision = OMAP4430_REV_ES2_0;
+ omap_chip.oc |= CHIP_IS_OMAP4430ES2;
+ break;
+ default:
+ omap_revision = OMAP4430_REV_ES2_0;
+ omap_chip.oc |= CHIP_IS_OMAP4430ES2;
+ }
+ break;
+ default:
+ /* Unknown default to latest silicon rev as default*/
+ omap_revision = OMAP4430_REV_ES2_0;
+ omap_chip.oc |= CHIP_IS_OMAP4430ES2;
}
- pr_err("Unknown OMAP4 CPU id\n");
+ pr_info("OMAP%04x ES%d.0\n",
+ omap_rev() >> 16, ((omap_rev() >> 12) & 0xf) + 1);
}
#define OMAP3_SHOW_FEATURE(feat) \
@@ -361,30 +386,54 @@ static void __init omap3_cpuinfo(void)
strcpy(cpu_name, "OMAP3503");
}
- switch (rev) {
- case OMAP_REVBITS_00:
- strcpy(cpu_rev, "1.0");
- break;
- case OMAP_REVBITS_01:
- strcpy(cpu_rev, "1.1");
- break;
- case OMAP_REVBITS_02:
- strcpy(cpu_rev, "1.2");
- break;
- case OMAP_REVBITS_10:
- strcpy(cpu_rev, "2.0");
- break;
- case OMAP_REVBITS_20:
- strcpy(cpu_rev, "2.1");
- break;
- case OMAP_REVBITS_30:
- strcpy(cpu_rev, "3.0");
- break;
- case OMAP_REVBITS_40:
- /* FALLTHROUGH */
- default:
- /* Use the latest known revision as default */
- strcpy(cpu_rev, "3.1");
+ if (cpu_is_omap3630()) {
+ switch (rev) {
+ case OMAP_REVBITS_00:
+ strcpy(cpu_rev, "1.0");
+ break;
+ case OMAP_REVBITS_01:
+ strcpy(cpu_rev, "1.1");
+ break;
+ case OMAP_REVBITS_02:
+ /* FALLTHROUGH */
+ default:
+ /* Use the latest known revision as default */
+ strcpy(cpu_rev, "1.2");
+ }
+ } else if (cpu_is_omap3505() || cpu_is_omap3517()) {
+ switch (rev) {
+ case OMAP_REVBITS_00:
+ strcpy(cpu_rev, "1.0");
+ break;
+ case OMAP_REVBITS_01:
+ /* FALLTHROUGH */
+ default:
+ /* Use the latest known revision as default */
+ strcpy(cpu_rev, "1.1");
+ }
+ } else {
+ switch (rev) {
+ case OMAP_REVBITS_00:
+ strcpy(cpu_rev, "1.0");
+ break;
+ case OMAP_REVBITS_01:
+ strcpy(cpu_rev, "2.0");
+ break;
+ case OMAP_REVBITS_02:
+ strcpy(cpu_rev, "2.1");
+ break;
+ case OMAP_REVBITS_03:
+ strcpy(cpu_rev, "3.0");
+ break;
+ case OMAP_REVBITS_04:
+ strcpy(cpu_rev, "3.1");
+ break;
+ case OMAP_REVBITS_05:
+ /* FALLTHROUGH */
+ default:
+ /* Use the latest known revision as default */
+ strcpy(cpu_rev, "3.1.2");
+ }
}
/* Print verbose information */
diff --git a/arch/arm/mach-omap2/include/mach/board-rx51.h b/arch/arm/mach-omap2/include/mach/board-rx51.h
new file mode 100644
index 000000000000..b76f49e7eed5
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/board-rx51.h
@@ -0,0 +1,11 @@
+/*
+ * Defines for rx51 boards
+ */
+
+#ifndef _OMAP_BOARD_RX51_H
+#define _OMAP_BOARD_RX51_H
+
+extern void __init rx51_peripherals_init(void);
+extern void __init rx51_video_mem_init(void);
+
+#endif
diff --git a/arch/arm/mach-omap2/include/mach/board-zoom.h b/arch/arm/mach-omap2/include/mach/board-zoom.h
index 80591fda8f8f..f93ca3928c3b 100644
--- a/arch/arm/mach-omap2/include/mach/board-zoom.h
+++ b/arch/arm/mach-omap2/include/mach/board-zoom.h
@@ -1,12 +1,8 @@
/*
* Defines for zoom boards
*/
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-
#define ZOOM_NAND_CS 0
-extern void __init board_nand_init(struct mtd_partition *, u8 nr_parts, u8 cs);
extern int __init zoom_debugboard_init(void);
extern void __init zoom_peripherals_init(void);
diff --git a/arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h b/arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h
new file mode 100644
index 000000000000..2f7ac70a20d8
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h
@@ -0,0 +1,391 @@
+/*
+ * OMAP44xx CTRL_MODULE_CORE registers and bitfields
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ *
+ * Benoit Cousson (b-cousson@ti.com)
+ * Santosh Shilimkar (santosh.shilimkar@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * 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 __ARCH_ARM_MACH_OMAP2_CTRL_MODULE_CORE_44XX_H
+#define __ARCH_ARM_MACH_OMAP2_CTRL_MODULE_CORE_44XX_H
+
+
+/* Base address */
+#define OMAP4_CTRL_MODULE_CORE 0x4a002000
+
+/* Registers offset */
+#define OMAP4_CTRL_MODULE_CORE_IP_REVISION 0x0000
+#define OMAP4_CTRL_MODULE_CORE_IP_HWINFO 0x0004
+#define OMAP4_CTRL_MODULE_CORE_IP_SYSCONFIG 0x0010
+#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_DIE_ID_0 0x0200
+#define OMAP4_CTRL_MODULE_CORE_ID_CODE 0x0204
+#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_DIE_ID_1 0x0208
+#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_DIE_ID_2 0x020c
+#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_DIE_ID_3 0x0210
+#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_0 0x0214
+#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_1 0x0218
+#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_USB_CONF 0x021c
+#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_OPP_VDD_WKUP 0x0228
+#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_OPP_BGAP 0x0260
+#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_OPP_DPLL_0 0x0264
+#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_OPP_DPLL_1 0x0268
+#define OMAP4_CTRL_MODULE_CORE_STATUS 0x02c4
+#define OMAP4_CTRL_MODULE_CORE_DEV_CONF 0x0300
+#define OMAP4_CTRL_MODULE_CORE_LDOVBB_IVA_VOLTAGE_CTRL 0x0314
+#define OMAP4_CTRL_MODULE_CORE_LDOVBB_MPU_VOLTAGE_CTRL 0x0318
+#define OMAP4_CTRL_MODULE_CORE_LDOSRAM_IVA_VOLTAGE_CTRL 0x0320
+#define OMAP4_CTRL_MODULE_CORE_LDOSRAM_MPU_VOLTAGE_CTRL 0x0324
+#define OMAP4_CTRL_MODULE_CORE_LDOSRAM_CORE_VOLTAGE_CTRL 0x0328
+#define OMAP4_CTRL_MODULE_CORE_TEMP_SENSOR 0x032c
+#define OMAP4_CTRL_MODULE_CORE_DPLL_NWELL_TRIM_0 0x0330
+#define OMAP4_CTRL_MODULE_CORE_DPLL_NWELL_TRIM_1 0x0334
+#define OMAP4_CTRL_MODULE_CORE_USBOTGHS_CONTROL 0x033c
+#define OMAP4_CTRL_MODULE_CORE_DSS_CONTROL 0x0340
+#define OMAP4_CTRL_MODULE_CORE_HWOBS_CONTROL 0x0350
+#define OMAP4_CTRL_MODULE_CORE_DEBOBS_FINAL_MUX_SEL 0x0400
+#define OMAP4_CTRL_MODULE_CORE_DEBOBS_MMR_MPU 0x0408
+#define OMAP4_CTRL_MODULE_CORE_CONF_SDMA_REQ_SEL0 0x042c
+#define OMAP4_CTRL_MODULE_CORE_CONF_SDMA_REQ_SEL1 0x0430
+#define OMAP4_CTRL_MODULE_CORE_CONF_SDMA_REQ_SEL2 0x0434
+#define OMAP4_CTRL_MODULE_CORE_CONF_SDMA_REQ_SEL3 0x0438
+#define OMAP4_CTRL_MODULE_CORE_CONF_CLK_SEL0 0x0440
+#define OMAP4_CTRL_MODULE_CORE_CONF_CLK_SEL1 0x0444
+#define OMAP4_CTRL_MODULE_CORE_CONF_CLK_SEL2 0x0448
+#define OMAP4_CTRL_MODULE_CORE_CONF_DPLL_FREQLOCK_SEL 0x044c
+#define OMAP4_CTRL_MODULE_CORE_CONF_DPLL_TINITZ_SEL 0x0450
+#define OMAP4_CTRL_MODULE_CORE_CONF_DPLL_PHASELOCK_SEL 0x0454
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_0 0x0480
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_1 0x0484
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_2 0x0488
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_3 0x048c
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_4 0x0490
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_5 0x0494
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_6 0x0498
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_7 0x049c
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_8 0x04a0
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_9 0x04a4
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_10 0x04a8
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_11 0x04ac
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_12 0x04b0
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_13 0x04b4
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_14 0x04b8
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_15 0x04bc
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_16 0x04c0
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_17 0x04c4
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_18 0x04c8
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_19 0x04cc
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_20 0x04d0
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_21 0x04d4
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_22 0x04d8
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_23 0x04dc
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_24 0x04e0
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_25 0x04e4
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_26 0x04e8
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_27 0x04ec
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_28 0x04f0
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_29 0x04f4
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_30 0x04f8
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_31 0x04fc
+
+/* Registers shifts and masks */
+
+/* IP_REVISION */
+#define OMAP4_IP_REV_SCHEME_SHIFT 30
+#define OMAP4_IP_REV_SCHEME_MASK (0x3 << 30)
+#define OMAP4_IP_REV_FUNC_SHIFT 16
+#define OMAP4_IP_REV_FUNC_MASK (0xfff << 16)
+#define OMAP4_IP_REV_RTL_SHIFT 11
+#define OMAP4_IP_REV_RTL_MASK (0x1f << 11)
+#define OMAP4_IP_REV_MAJOR_SHIFT 8
+#define OMAP4_IP_REV_MAJOR_MASK (0x7 << 8)
+#define OMAP4_IP_REV_CUSTOM_SHIFT 6
+#define OMAP4_IP_REV_CUSTOM_MASK (0x3 << 6)
+#define OMAP4_IP_REV_MINOR_SHIFT 0
+#define OMAP4_IP_REV_MINOR_MASK (0x3f << 0)
+
+/* IP_HWINFO */
+#define OMAP4_IP_HWINFO_SHIFT 0
+#define OMAP4_IP_HWINFO_MASK (0xffffffff << 0)
+
+/* IP_SYSCONFIG */
+#define OMAP4_IP_SYSCONFIG_IDLEMODE_SHIFT 2
+#define OMAP4_IP_SYSCONFIG_IDLEMODE_MASK (0x3 << 2)
+
+/* STD_FUSE_DIE_ID_0 */
+#define OMAP4_STD_FUSE_DIE_ID_0_SHIFT 0
+#define OMAP4_STD_FUSE_DIE_ID_0_MASK (0xffffffff << 0)
+
+/* ID_CODE */
+#define OMAP4_STD_FUSE_IDCODE_SHIFT 0
+#define OMAP4_STD_FUSE_IDCODE_MASK (0xffffffff << 0)
+
+/* STD_FUSE_DIE_ID_1 */
+#define OMAP4_STD_FUSE_DIE_ID_1_SHIFT 0
+#define OMAP4_STD_FUSE_DIE_ID_1_MASK (0xffffffff << 0)
+
+/* STD_FUSE_DIE_ID_2 */
+#define OMAP4_STD_FUSE_DIE_ID_2_SHIFT 0
+#define OMAP4_STD_FUSE_DIE_ID_2_MASK (0xffffffff << 0)
+
+/* STD_FUSE_DIE_ID_3 */
+#define OMAP4_STD_FUSE_DIE_ID_3_SHIFT 0
+#define OMAP4_STD_FUSE_DIE_ID_3_MASK (0xffffffff << 0)
+
+/* STD_FUSE_PROD_ID_0 */
+#define OMAP4_STD_FUSE_PROD_ID_0_SHIFT 0
+#define OMAP4_STD_FUSE_PROD_ID_0_MASK (0xffffffff << 0)
+
+/* STD_FUSE_PROD_ID_1 */
+#define OMAP4_STD_FUSE_PROD_ID_1_SHIFT 0
+#define OMAP4_STD_FUSE_PROD_ID_1_MASK (0xffffffff << 0)
+
+/* STD_FUSE_USB_CONF */
+#define OMAP4_USB_PROD_ID_SHIFT 16
+#define OMAP4_USB_PROD_ID_MASK (0xffff << 16)
+#define OMAP4_USB_VENDOR_ID_SHIFT 0
+#define OMAP4_USB_VENDOR_ID_MASK (0xffff << 0)
+
+/* STD_FUSE_OPP_VDD_WKUP */
+#define OMAP4_STD_FUSE_OPP_VDD_WKUP_SHIFT 0
+#define OMAP4_STD_FUSE_OPP_VDD_WKUP_MASK (0xffffffff << 0)
+
+/* STD_FUSE_OPP_BGAP */
+#define OMAP4_STD_FUSE_OPP_BGAP_SHIFT 0
+#define OMAP4_STD_FUSE_OPP_BGAP_MASK (0xffffffff << 0)
+
+/* STD_FUSE_OPP_DPLL_0 */
+#define OMAP4_STD_FUSE_OPP_DPLL_0_SHIFT 0
+#define OMAP4_STD_FUSE_OPP_DPLL_0_MASK (0xffffffff << 0)
+
+/* STD_FUSE_OPP_DPLL_1 */
+#define OMAP4_STD_FUSE_OPP_DPLL_1_SHIFT 0
+#define OMAP4_STD_FUSE_OPP_DPLL_1_MASK (0xffffffff << 0)
+
+/* STATUS */
+#define OMAP4_ATTILA_CONF_SHIFT 11
+#define OMAP4_ATTILA_CONF_MASK (0x3 << 11)
+#define OMAP4_DEVICE_TYPE_SHIFT 8
+#define OMAP4_DEVICE_TYPE_MASK (0x7 << 8)
+#define OMAP4_SYS_BOOT_SHIFT 0
+#define OMAP4_SYS_BOOT_MASK (0xff << 0)
+
+/* DEV_CONF */
+#define OMAP4_DEV_CONF_SHIFT 1
+#define OMAP4_DEV_CONF_MASK (0x7fffffff << 1)
+#define OMAP4_USBPHY_PD_SHIFT 0
+#define OMAP4_USBPHY_PD_MASK (1 << 0)
+
+/* LDOVBB_IVA_VOLTAGE_CTRL */
+#define OMAP4_LDOVBBIVA_RBB_MUX_CTRL_SHIFT 26
+#define OMAP4_LDOVBBIVA_RBB_MUX_CTRL_MASK (1 << 26)
+#define OMAP4_LDOVBBIVA_RBB_VSET_IN_SHIFT 21
+#define OMAP4_LDOVBBIVA_RBB_VSET_IN_MASK (0x1f << 21)
+#define OMAP4_LDOVBBIVA_RBB_VSET_OUT_SHIFT 16
+#define OMAP4_LDOVBBIVA_RBB_VSET_OUT_MASK (0x1f << 16)
+#define OMAP4_LDOVBBIVA_FBB_MUX_CTRL_SHIFT 10
+#define OMAP4_LDOVBBIVA_FBB_MUX_CTRL_MASK (1 << 10)
+#define OMAP4_LDOVBBIVA_FBB_VSET_IN_SHIFT 5
+#define OMAP4_LDOVBBIVA_FBB_VSET_IN_MASK (0x1f << 5)
+#define OMAP4_LDOVBBIVA_FBB_VSET_OUT_SHIFT 0
+#define OMAP4_LDOVBBIVA_FBB_VSET_OUT_MASK (0x1f << 0)
+
+/* LDOVBB_MPU_VOLTAGE_CTRL */
+#define OMAP4_LDOVBBMPU_RBB_MUX_CTRL_SHIFT 26
+#define OMAP4_LDOVBBMPU_RBB_MUX_CTRL_MASK (1 << 26)
+#define OMAP4_LDOVBBMPU_RBB_VSET_IN_SHIFT 21
+#define OMAP4_LDOVBBMPU_RBB_VSET_IN_MASK (0x1f << 21)
+#define OMAP4_LDOVBBMPU_RBB_VSET_OUT_SHIFT 16
+#define OMAP4_LDOVBBMPU_RBB_VSET_OUT_MASK (0x1f << 16)
+#define OMAP4_LDOVBBMPU_FBB_MUX_CTRL_SHIFT 10
+#define OMAP4_LDOVBBMPU_FBB_MUX_CTRL_MASK (1 << 10)
+#define OMAP4_LDOVBBMPU_FBB_VSET_IN_SHIFT 5
+#define OMAP4_LDOVBBMPU_FBB_VSET_IN_MASK (0x1f << 5)
+#define OMAP4_LDOVBBMPU_FBB_VSET_OUT_SHIFT 0
+#define OMAP4_LDOVBBMPU_FBB_VSET_OUT_MASK (0x1f << 0)
+
+/* LDOSRAM_IVA_VOLTAGE_CTRL */
+#define OMAP4_LDOSRAMIVA_RETMODE_MUX_CTRL_SHIFT 26
+#define OMAP4_LDOSRAMIVA_RETMODE_MUX_CTRL_MASK (1 << 26)
+#define OMAP4_LDOSRAMIVA_RETMODE_VSET_IN_SHIFT 21
+#define OMAP4_LDOSRAMIVA_RETMODE_VSET_IN_MASK (0x1f << 21)
+#define OMAP4_LDOSRAMIVA_RETMODE_VSET_OUT_SHIFT 16
+#define OMAP4_LDOSRAMIVA_RETMODE_VSET_OUT_MASK (0x1f << 16)
+#define OMAP4_LDOSRAMIVA_ACTMODE_MUX_CTRL_SHIFT 10
+#define OMAP4_LDOSRAMIVA_ACTMODE_MUX_CTRL_MASK (1 << 10)
+#define OMAP4_LDOSRAMIVA_ACTMODE_VSET_IN_SHIFT 5
+#define OMAP4_LDOSRAMIVA_ACTMODE_VSET_IN_MASK (0x1f << 5)
+#define OMAP4_LDOSRAMIVA_ACTMODE_VSET_OUT_SHIFT 0
+#define OMAP4_LDOSRAMIVA_ACTMODE_VSET_OUT_MASK (0x1f << 0)
+
+/* LDOSRAM_MPU_VOLTAGE_CTRL */
+#define OMAP4_LDOSRAMMPU_RETMODE_MUX_CTRL_SHIFT 26
+#define OMAP4_LDOSRAMMPU_RETMODE_MUX_CTRL_MASK (1 << 26)
+#define OMAP4_LDOSRAMMPU_RETMODE_VSET_IN_SHIFT 21
+#define OMAP4_LDOSRAMMPU_RETMODE_VSET_IN_MASK (0x1f << 21)
+#define OMAP4_LDOSRAMMPU_RETMODE_VSET_OUT_SHIFT 16
+#define OMAP4_LDOSRAMMPU_RETMODE_VSET_OUT_MASK (0x1f << 16)
+#define OMAP4_LDOSRAMMPU_ACTMODE_MUX_CTRL_SHIFT 10
+#define OMAP4_LDOSRAMMPU_ACTMODE_MUX_CTRL_MASK (1 << 10)
+#define OMAP4_LDOSRAMMPU_ACTMODE_VSET_IN_SHIFT 5
+#define OMAP4_LDOSRAMMPU_ACTMODE_VSET_IN_MASK (0x1f << 5)
+#define OMAP4_LDOSRAMMPU_ACTMODE_VSET_OUT_SHIFT 0
+#define OMAP4_LDOSRAMMPU_ACTMODE_VSET_OUT_MASK (0x1f << 0)
+
+/* LDOSRAM_CORE_VOLTAGE_CTRL */
+#define OMAP4_LDOSRAMCORE_RETMODE_MUX_CTRL_SHIFT 26
+#define OMAP4_LDOSRAMCORE_RETMODE_MUX_CTRL_MASK (1 << 26)
+#define OMAP4_LDOSRAMCORE_RETMODE_VSET_IN_SHIFT 21
+#define OMAP4_LDOSRAMCORE_RETMODE_VSET_IN_MASK (0x1f << 21)
+#define OMAP4_LDOSRAMCORE_RETMODE_VSET_OUT_SHIFT 16
+#define OMAP4_LDOSRAMCORE_RETMODE_VSET_OUT_MASK (0x1f << 16)
+#define OMAP4_LDOSRAMCORE_ACTMODE_MUX_CTRL_SHIFT 10
+#define OMAP4_LDOSRAMCORE_ACTMODE_MUX_CTRL_MASK (1 << 10)
+#define OMAP4_LDOSRAMCORE_ACTMODE_VSET_IN_SHIFT 5
+#define OMAP4_LDOSRAMCORE_ACTMODE_VSET_IN_MASK (0x1f << 5)
+#define OMAP4_LDOSRAMCORE_ACTMODE_VSET_OUT_SHIFT 0
+#define OMAP4_LDOSRAMCORE_ACTMODE_VSET_OUT_MASK (0x1f << 0)
+
+/* TEMP_SENSOR */
+#define OMAP4_BGAP_TEMPSOFF_SHIFT 12
+#define OMAP4_BGAP_TEMPSOFF_MASK (1 << 12)
+#define OMAP4_BGAP_TSHUT_SHIFT 11
+#define OMAP4_BGAP_TSHUT_MASK (1 << 11)
+#define OMAP4_BGAP_TEMP_SENSOR_CONTCONV_SHIFT 10
+#define OMAP4_BGAP_TEMP_SENSOR_CONTCONV_MASK (1 << 10)
+#define OMAP4_BGAP_TEMP_SENSOR_SOC_SHIFT 9
+#define OMAP4_BGAP_TEMP_SENSOR_SOC_MASK (1 << 9)
+#define OMAP4_BGAP_TEMP_SENSOR_EOCZ_SHIFT 8
+#define OMAP4_BGAP_TEMP_SENSOR_EOCZ_MASK (1 << 8)
+#define OMAP4_BGAP_TEMP_SENSOR_DTEMP_SHIFT 0
+#define OMAP4_BGAP_TEMP_SENSOR_DTEMP_MASK (0xff << 0)
+
+/* DPLL_NWELL_TRIM_0 */
+#define OMAP4_DPLL_ABE_NWELL_TRIM_MUX_CTRL_SHIFT 29
+#define OMAP4_DPLL_ABE_NWELL_TRIM_MUX_CTRL_MASK (1 << 29)
+#define OMAP4_DPLL_ABE_NWELL_TRIM_SHIFT 24
+#define OMAP4_DPLL_ABE_NWELL_TRIM_MASK (0x1f << 24)
+#define OMAP4_DPLL_PER_NWELL_TRIM_MUX_CTRL_SHIFT 23
+#define OMAP4_DPLL_PER_NWELL_TRIM_MUX_CTRL_MASK (1 << 23)
+#define OMAP4_DPLL_PER_NWELL_TRIM_SHIFT 18
+#define OMAP4_DPLL_PER_NWELL_TRIM_MASK (0x1f << 18)
+#define OMAP4_DPLL_CORE_NWELL_TRIM_MUX_CTRL_SHIFT 17
+#define OMAP4_DPLL_CORE_NWELL_TRIM_MUX_CTRL_MASK (1 << 17)
+#define OMAP4_DPLL_CORE_NWELL_TRIM_SHIFT 12
+#define OMAP4_DPLL_CORE_NWELL_TRIM_MASK (0x1f << 12)
+#define OMAP4_DPLL_IVA_NWELL_TRIM_MUX_CTRL_SHIFT 11
+#define OMAP4_DPLL_IVA_NWELL_TRIM_MUX_CTRL_MASK (1 << 11)
+#define OMAP4_DPLL_IVA_NWELL_TRIM_SHIFT 6
+#define OMAP4_DPLL_IVA_NWELL_TRIM_MASK (0x1f << 6)
+#define OMAP4_DPLL_MPU_NWELL_TRIM_MUX_CTRL_SHIFT 5
+#define OMAP4_DPLL_MPU_NWELL_TRIM_MUX_CTRL_MASK (1 << 5)
+#define OMAP4_DPLL_MPU_NWELL_TRIM_SHIFT 0
+#define OMAP4_DPLL_MPU_NWELL_TRIM_MASK (0x1f << 0)
+
+/* DPLL_NWELL_TRIM_1 */
+#define OMAP4_DPLL_UNIPRO_NWELL_TRIM_MUX_CTRL_SHIFT 29
+#define OMAP4_DPLL_UNIPRO_NWELL_TRIM_MUX_CTRL_MASK (1 << 29)
+#define OMAP4_DPLL_UNIPRO_NWELL_TRIM_SHIFT 24
+#define OMAP4_DPLL_UNIPRO_NWELL_TRIM_MASK (0x1f << 24)
+#define OMAP4_DPLL_USB_NWELL_TRIM_MUX_CTRL_SHIFT 23
+#define OMAP4_DPLL_USB_NWELL_TRIM_MUX_CTRL_MASK (1 << 23)
+#define OMAP4_DPLL_USB_NWELL_TRIM_SHIFT 18
+#define OMAP4_DPLL_USB_NWELL_TRIM_MASK (0x1f << 18)
+#define OMAP4_DPLL_HDMI_NWELL_TRIM_MUX_CTRL_SHIFT 17
+#define OMAP4_DPLL_HDMI_NWELL_TRIM_MUX_CTRL_MASK (1 << 17)
+#define OMAP4_DPLL_HDMI_NWELL_TRIM_SHIFT 12
+#define OMAP4_DPLL_HDMI_NWELL_TRIM_MASK (0x1f << 12)
+#define OMAP4_DPLL_DSI2_NWELL_TRIM_MUX_CTRL_SHIFT 11
+#define OMAP4_DPLL_DSI2_NWELL_TRIM_MUX_CTRL_MASK (1 << 11)
+#define OMAP4_DPLL_DSI2_NWELL_TRIM_SHIFT 6
+#define OMAP4_DPLL_DSI2_NWELL_TRIM_MASK (0x1f << 6)
+#define OMAP4_DPLL_DSI1_NWELL_TRIM_MUX_CTRL_SHIFT 5
+#define OMAP4_DPLL_DSI1_NWELL_TRIM_MUX_CTRL_MASK (1 << 5)
+#define OMAP4_DPLL_DSI1_NWELL_TRIM_SHIFT 0
+#define OMAP4_DPLL_DSI1_NWELL_TRIM_MASK (0x1f << 0)
+
+/* USBOTGHS_CONTROL */
+#define OMAP4_DISCHRGVBUS_SHIFT 8
+#define OMAP4_DISCHRGVBUS_MASK (1 << 8)
+#define OMAP4_CHRGVBUS_SHIFT 7
+#define OMAP4_CHRGVBUS_MASK (1 << 7)
+#define OMAP4_DRVVBUS_SHIFT 6
+#define OMAP4_DRVVBUS_MASK (1 << 6)
+#define OMAP4_IDPULLUP_SHIFT 5
+#define OMAP4_IDPULLUP_MASK (1 << 5)
+#define OMAP4_IDDIG_SHIFT 4
+#define OMAP4_IDDIG_MASK (1 << 4)
+#define OMAP4_SESSEND_SHIFT 3
+#define OMAP4_SESSEND_MASK (1 << 3)
+#define OMAP4_VBUSVALID_SHIFT 2
+#define OMAP4_VBUSVALID_MASK (1 << 2)
+#define OMAP4_BVALID_SHIFT 1
+#define OMAP4_BVALID_MASK (1 << 1)
+#define OMAP4_AVALID_SHIFT 0
+#define OMAP4_AVALID_MASK (1 << 0)
+
+/* DSS_CONTROL */
+#define OMAP4_DSS_MUX6_SELECT_SHIFT 0
+#define OMAP4_DSS_MUX6_SELECT_MASK (1 << 0)
+
+/* HWOBS_CONTROL */
+#define OMAP4_HWOBS_CLKDIV_SEL_SHIFT 3
+#define OMAP4_HWOBS_CLKDIV_SEL_MASK (0x1f << 3)
+#define OMAP4_HWOBS_ALL_ZERO_MODE_SHIFT 2
+#define OMAP4_HWOBS_ALL_ZERO_MODE_MASK (1 << 2)
+#define OMAP4_HWOBS_ALL_ONE_MODE_SHIFT 1
+#define OMAP4_HWOBS_ALL_ONE_MODE_MASK (1 << 1)
+#define OMAP4_HWOBS_MACRO_ENABLE_SHIFT 0
+#define OMAP4_HWOBS_MACRO_ENABLE_MASK (1 << 0)
+
+/* DEBOBS_FINAL_MUX_SEL */
+#define OMAP4_SELECT_SHIFT 0
+#define OMAP4_SELECT_MASK (0xffffffff << 0)
+
+/* DEBOBS_MMR_MPU */
+#define OMAP4_SELECT_DEBOBS_MMR_MPU_SHIFT 0
+#define OMAP4_SELECT_DEBOBS_MMR_MPU_MASK (0xf << 0)
+
+/* CONF_SDMA_REQ_SEL0 */
+#define OMAP4_MULT_SHIFT 0
+#define OMAP4_MULT_MASK (0x7f << 0)
+
+/* CONF_CLK_SEL0 */
+#define OMAP4_MULT_CONF_CLK_SEL0_SHIFT 0
+#define OMAP4_MULT_CONF_CLK_SEL0_MASK (0x7 << 0)
+
+/* CONF_CLK_SEL1 */
+#define OMAP4_MULT_CONF_CLK_SEL1_SHIFT 0
+#define OMAP4_MULT_CONF_CLK_SEL1_MASK (0x7 << 0)
+
+/* CONF_CLK_SEL2 */
+#define OMAP4_MULT_CONF_CLK_SEL2_SHIFT 0
+#define OMAP4_MULT_CONF_CLK_SEL2_MASK (0x7 << 0)
+
+/* CONF_DPLL_FREQLOCK_SEL */
+#define OMAP4_MULT_CONF_DPLL_FREQLOCK_SEL_SHIFT 0
+#define OMAP4_MULT_CONF_DPLL_FREQLOCK_SEL_MASK (0x7 << 0)
+
+/* CONF_DPLL_TINITZ_SEL */
+#define OMAP4_MULT_CONF_DPLL_TINITZ_SEL_SHIFT 0
+#define OMAP4_MULT_CONF_DPLL_TINITZ_SEL_MASK (0x7 << 0)
+
+/* CONF_DPLL_PHASELOCK_SEL */
+#define OMAP4_MULT_CONF_DPLL_PHASELOCK_SEL_SHIFT 0
+#define OMAP4_MULT_CONF_DPLL_PHASELOCK_SEL_MASK (0x7 << 0)
+
+/* CONF_DEBUG_SEL_TST_0 */
+#define OMAP4_MODE_SHIFT 0
+#define OMAP4_MODE_MASK (0xf << 0)
+
+#endif
diff --git a/arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h b/arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h
new file mode 100644
index 000000000000..c88420de1151
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h
@@ -0,0 +1,1409 @@
+/*
+ * OMAP44xx CTRL_MODULE_PAD_CORE registers and bitfields
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ *
+ * Benoit Cousson (b-cousson@ti.com)
+ * Santosh Shilimkar (santosh.shilimkar@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * 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 __ARCH_ARM_MACH_OMAP2_CTRL_MODULE_PAD_CORE_44XX_H
+#define __ARCH_ARM_MACH_OMAP2_CTRL_MODULE_PAD_CORE_44XX_H
+
+
+/* Base address */
+#define OMAP4_CTRL_MODULE_PAD_CORE 0x4a100000
+
+/* Registers offset */
+#define OMAP4_CTRL_MODULE_PAD_CORE_IP_REVISION 0x0000
+#define OMAP4_CTRL_MODULE_PAD_CORE_IP_HWINFO 0x0004
+#define OMAP4_CTRL_MODULE_PAD_CORE_IP_SYSCONFIG 0x0010
+#define OMAP4_CTRL_MODULE_PAD_CORE_PADCONF_WAKEUPEVENT_0 0x01d8
+#define OMAP4_CTRL_MODULE_PAD_CORE_PADCONF_WAKEUPEVENT_1 0x01dc
+#define OMAP4_CTRL_MODULE_PAD_CORE_PADCONF_WAKEUPEVENT_2 0x01e0
+#define OMAP4_CTRL_MODULE_PAD_CORE_PADCONF_WAKEUPEVENT_3 0x01e4
+#define OMAP4_CTRL_MODULE_PAD_CORE_PADCONF_WAKEUPEVENT_4 0x01e8
+#define OMAP4_CTRL_MODULE_PAD_CORE_PADCONF_WAKEUPEVENT_5 0x01ec
+#define OMAP4_CTRL_MODULE_PAD_CORE_PADCONF_WAKEUPEVENT_6 0x01f0
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_PADCONF_GLOBAL 0x05a0
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_PADCONF_MODE 0x05a4
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SMART1IO_PADCONF_0 0x05a8
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SMART1IO_PADCONF_1 0x05ac
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SMART2IO_PADCONF_0 0x05b0
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SMART2IO_PADCONF_1 0x05b4
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SMART3IO_PADCONF_0 0x05b8
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SMART3IO_PADCONF_1 0x05bc
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SMART3IO_PADCONF_2 0x05c0
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_USBB_HSIC 0x05c4
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SLIMBUS 0x05c8
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_PBIASLITE 0x0600
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_I2C_0 0x0604
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_CAMERA_RX 0x0608
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_AVDAC 0x060c
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_HDMI_TX_PHY 0x0610
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MMC2 0x0614
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_DSIPHY 0x0618
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MCBSPLP 0x061c
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_USB2PHYCORE 0x0620
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_I2C_1 0x0624
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MMC1 0x0628
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_HSI 0x062c
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_USB 0x0630
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_HDQ 0x0634
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO1_0 0x0638
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO1_1 0x063c
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO1_2 0x0640
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO1_3 0x0644
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO2_0 0x0648
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO2_1 0x064c
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO2_2 0x0650
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO2_3 0x0654
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_BUS_HOLD 0x0658
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_C2C 0x065c
+#define OMAP4_CTRL_MODULE_PAD_CORE_CORE_CONTROL_SPARE_RW 0x0660
+#define OMAP4_CTRL_MODULE_PAD_CORE_CORE_CONTROL_SPARE_R 0x0664
+#define OMAP4_CTRL_MODULE_PAD_CORE_CORE_CONTROL_SPARE_R_C0 0x0668
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_EFUSE_1 0x0700
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_EFUSE_2 0x0704
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_EFUSE_3 0x0708
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_EFUSE_4 0x070c
+
+/* Registers shifts and masks */
+
+/* IP_REVISION */
+#define OMAP4_IP_REV_SCHEME_SHIFT 30
+#define OMAP4_IP_REV_SCHEME_MASK (0x3 << 30)
+#define OMAP4_IP_REV_FUNC_SHIFT 16
+#define OMAP4_IP_REV_FUNC_MASK (0xfff << 16)
+#define OMAP4_IP_REV_RTL_SHIFT 11
+#define OMAP4_IP_REV_RTL_MASK (0x1f << 11)
+#define OMAP4_IP_REV_MAJOR_SHIFT 8
+#define OMAP4_IP_REV_MAJOR_MASK (0x7 << 8)
+#define OMAP4_IP_REV_CUSTOM_SHIFT 6
+#define OMAP4_IP_REV_CUSTOM_MASK (0x3 << 6)
+#define OMAP4_IP_REV_MINOR_SHIFT 0
+#define OMAP4_IP_REV_MINOR_MASK (0x3f << 0)
+
+/* IP_HWINFO */
+#define OMAP4_IP_HWINFO_SHIFT 0
+#define OMAP4_IP_HWINFO_MASK (0xffffffff << 0)
+
+/* IP_SYSCONFIG */
+#define OMAP4_IP_SYSCONFIG_IDLEMODE_SHIFT 2
+#define OMAP4_IP_SYSCONFIG_IDLEMODE_MASK (0x3 << 2)
+
+/* PADCONF_WAKEUPEVENT_0 */
+#define OMAP4_GPMC_CLK_DUPLICATEWAKEUPEVENT_SHIFT 31
+#define OMAP4_GPMC_CLK_DUPLICATEWAKEUPEVENT_MASK (1 << 31)
+#define OMAP4_GPMC_NWP_DUPLICATEWAKEUPEVENT_SHIFT 30
+#define OMAP4_GPMC_NWP_DUPLICATEWAKEUPEVENT_MASK (1 << 30)
+#define OMAP4_GPMC_NCS3_DUPLICATEWAKEUPEVENT_SHIFT 29
+#define OMAP4_GPMC_NCS3_DUPLICATEWAKEUPEVENT_MASK (1 << 29)
+#define OMAP4_GPMC_NCS2_DUPLICATEWAKEUPEVENT_SHIFT 28
+#define OMAP4_GPMC_NCS2_DUPLICATEWAKEUPEVENT_MASK (1 << 28)
+#define OMAP4_GPMC_NCS1_DUPLICATEWAKEUPEVENT_SHIFT 27
+#define OMAP4_GPMC_NCS1_DUPLICATEWAKEUPEVENT_MASK (1 << 27)
+#define OMAP4_GPMC_NCS0_DUPLICATEWAKEUPEVENT_SHIFT 26
+#define OMAP4_GPMC_NCS0_DUPLICATEWAKEUPEVENT_MASK (1 << 26)
+#define OMAP4_GPMC_A25_DUPLICATEWAKEUPEVENT_SHIFT 25
+#define OMAP4_GPMC_A25_DUPLICATEWAKEUPEVENT_MASK (1 << 25)
+#define OMAP4_GPMC_A24_DUPLICATEWAKEUPEVENT_SHIFT 24
+#define OMAP4_GPMC_A24_DUPLICATEWAKEUPEVENT_MASK (1 << 24)
+#define OMAP4_GPMC_A23_DUPLICATEWAKEUPEVENT_SHIFT 23
+#define OMAP4_GPMC_A23_DUPLICATEWAKEUPEVENT_MASK (1 << 23)
+#define OMAP4_GPMC_A22_DUPLICATEWAKEUPEVENT_SHIFT 22
+#define OMAP4_GPMC_A22_DUPLICATEWAKEUPEVENT_MASK (1 << 22)
+#define OMAP4_GPMC_A21_DUPLICATEWAKEUPEVENT_SHIFT 21
+#define OMAP4_GPMC_A21_DUPLICATEWAKEUPEVENT_MASK (1 << 21)
+#define OMAP4_GPMC_A20_DUPLICATEWAKEUPEVENT_SHIFT 20
+#define OMAP4_GPMC_A20_DUPLICATEWAKEUPEVENT_MASK (1 << 20)
+#define OMAP4_GPMC_A19_DUPLICATEWAKEUPEVENT_SHIFT 19
+#define OMAP4_GPMC_A19_DUPLICATEWAKEUPEVENT_MASK (1 << 19)
+#define OMAP4_GPMC_A18_DUPLICATEWAKEUPEVENT_SHIFT 18
+#define OMAP4_GPMC_A18_DUPLICATEWAKEUPEVENT_MASK (1 << 18)
+#define OMAP4_GPMC_A17_DUPLICATEWAKEUPEVENT_SHIFT 17
+#define OMAP4_GPMC_A17_DUPLICATEWAKEUPEVENT_MASK (1 << 17)
+#define OMAP4_GPMC_A16_DUPLICATEWAKEUPEVENT_SHIFT 16
+#define OMAP4_GPMC_A16_DUPLICATEWAKEUPEVENT_MASK (1 << 16)
+#define OMAP4_GPMC_AD15_DUPLICATEWAKEUPEVENT_SHIFT 15
+#define OMAP4_GPMC_AD15_DUPLICATEWAKEUPEVENT_MASK (1 << 15)
+#define OMAP4_GPMC_AD14_DUPLICATEWAKEUPEVENT_SHIFT 14
+#define OMAP4_GPMC_AD14_DUPLICATEWAKEUPEVENT_MASK (1 << 14)
+#define OMAP4_GPMC_AD13_DUPLICATEWAKEUPEVENT_SHIFT 13
+#define OMAP4_GPMC_AD13_DUPLICATEWAKEUPEVENT_MASK (1 << 13)
+#define OMAP4_GPMC_AD12_DUPLICATEWAKEUPEVENT_SHIFT 12
+#define OMAP4_GPMC_AD12_DUPLICATEWAKEUPEVENT_MASK (1 << 12)
+#define OMAP4_GPMC_AD11_DUPLICATEWAKEUPEVENT_SHIFT 11
+#define OMAP4_GPMC_AD11_DUPLICATEWAKEUPEVENT_MASK (1 << 11)
+#define OMAP4_GPMC_AD10_DUPLICATEWAKEUPEVENT_SHIFT 10
+#define OMAP4_GPMC_AD10_DUPLICATEWAKEUPEVENT_MASK (1 << 10)
+#define OMAP4_GPMC_AD9_DUPLICATEWAKEUPEVENT_SHIFT 9
+#define OMAP4_GPMC_AD9_DUPLICATEWAKEUPEVENT_MASK (1 << 9)
+#define OMAP4_GPMC_AD8_DUPLICATEWAKEUPEVENT_SHIFT 8
+#define OMAP4_GPMC_AD8_DUPLICATEWAKEUPEVENT_MASK (1 << 8)
+#define OMAP4_GPMC_AD7_DUPLICATEWAKEUPEVENT_SHIFT 7
+#define OMAP4_GPMC_AD7_DUPLICATEWAKEUPEVENT_MASK (1 << 7)
+#define OMAP4_GPMC_AD6_DUPLICATEWAKEUPEVENT_SHIFT 6
+#define OMAP4_GPMC_AD6_DUPLICATEWAKEUPEVENT_MASK (1 << 6)
+#define OMAP4_GPMC_AD5_DUPLICATEWAKEUPEVENT_SHIFT 5
+#define OMAP4_GPMC_AD5_DUPLICATEWAKEUPEVENT_MASK (1 << 5)
+#define OMAP4_GPMC_AD4_DUPLICATEWAKEUPEVENT_SHIFT 4
+#define OMAP4_GPMC_AD4_DUPLICATEWAKEUPEVENT_MASK (1 << 4)
+#define OMAP4_GPMC_AD3_DUPLICATEWAKEUPEVENT_SHIFT 3
+#define OMAP4_GPMC_AD3_DUPLICATEWAKEUPEVENT_MASK (1 << 3)
+#define OMAP4_GPMC_AD2_DUPLICATEWAKEUPEVENT_SHIFT 2
+#define OMAP4_GPMC_AD2_DUPLICATEWAKEUPEVENT_MASK (1 << 2)
+#define OMAP4_GPMC_AD1_DUPLICATEWAKEUPEVENT_SHIFT 1
+#define OMAP4_GPMC_AD1_DUPLICATEWAKEUPEVENT_MASK (1 << 1)
+#define OMAP4_GPMC_AD0_DUPLICATEWAKEUPEVENT_SHIFT 0
+#define OMAP4_GPMC_AD0_DUPLICATEWAKEUPEVENT_MASK (1 << 0)
+
+/* PADCONF_WAKEUPEVENT_1 */
+#define OMAP4_CAM_STROBE_DUPLICATEWAKEUPEVENT_SHIFT 31
+#define OMAP4_CAM_STROBE_DUPLICATEWAKEUPEVENT_MASK (1 << 31)
+#define OMAP4_CAM_SHUTTER_DUPLICATEWAKEUPEVENT_SHIFT 30
+#define OMAP4_CAM_SHUTTER_DUPLICATEWAKEUPEVENT_MASK (1 << 30)
+#define OMAP4_CSI22_DY1_DUPLICATEWAKEUPEVENT_SHIFT 29
+#define OMAP4_CSI22_DY1_DUPLICATEWAKEUPEVENT_MASK (1 << 29)
+#define OMAP4_CSI22_DX1_DUPLICATEWAKEUPEVENT_SHIFT 28
+#define OMAP4_CSI22_DX1_DUPLICATEWAKEUPEVENT_MASK (1 << 28)
+#define OMAP4_CSI22_DY0_DUPLICATEWAKEUPEVENT_SHIFT 27
+#define OMAP4_CSI22_DY0_DUPLICATEWAKEUPEVENT_MASK (1 << 27)
+#define OMAP4_CSI22_DX0_DUPLICATEWAKEUPEVENT_SHIFT 26
+#define OMAP4_CSI22_DX0_DUPLICATEWAKEUPEVENT_MASK (1 << 26)
+#define OMAP4_CSI21_DY4_DUPLICATEWAKEUPEVENT_SHIFT 25
+#define OMAP4_CSI21_DY4_DUPLICATEWAKEUPEVENT_MASK (1 << 25)
+#define OMAP4_CSI21_DX4_DUPLICATEWAKEUPEVENT_SHIFT 24
+#define OMAP4_CSI21_DX4_DUPLICATEWAKEUPEVENT_MASK (1 << 24)
+#define OMAP4_CSI21_DY3_DUPLICATEWAKEUPEVENT_SHIFT 23
+#define OMAP4_CSI21_DY3_DUPLICATEWAKEUPEVENT_MASK (1 << 23)
+#define OMAP4_CSI21_DX3_DUPLICATEWAKEUPEVENT_SHIFT 22
+#define OMAP4_CSI21_DX3_DUPLICATEWAKEUPEVENT_MASK (1 << 22)
+#define OMAP4_CSI21_DY2_DUPLICATEWAKEUPEVENT_SHIFT 21
+#define OMAP4_CSI21_DY2_DUPLICATEWAKEUPEVENT_MASK (1 << 21)
+#define OMAP4_CSI21_DX2_DUPLICATEWAKEUPEVENT_SHIFT 20
+#define OMAP4_CSI21_DX2_DUPLICATEWAKEUPEVENT_MASK (1 << 20)
+#define OMAP4_CSI21_DY1_DUPLICATEWAKEUPEVENT_SHIFT 19
+#define OMAP4_CSI21_DY1_DUPLICATEWAKEUPEVENT_MASK (1 << 19)
+#define OMAP4_CSI21_DX1_DUPLICATEWAKEUPEVENT_SHIFT 18
+#define OMAP4_CSI21_DX1_DUPLICATEWAKEUPEVENT_MASK (1 << 18)
+#define OMAP4_CSI21_DY0_DUPLICATEWAKEUPEVENT_SHIFT 17
+#define OMAP4_CSI21_DY0_DUPLICATEWAKEUPEVENT_MASK (1 << 17)
+#define OMAP4_CSI21_DX0_DUPLICATEWAKEUPEVENT_SHIFT 16
+#define OMAP4_CSI21_DX0_DUPLICATEWAKEUPEVENT_MASK (1 << 16)
+#define OMAP4_HDMI_DDC_SDA_DUPLICATEWAKEUPEVENT_SHIFT 15
+#define OMAP4_HDMI_DDC_SDA_DUPLICATEWAKEUPEVENT_MASK (1 << 15)
+#define OMAP4_HDMI_DDC_SCL_DUPLICATEWAKEUPEVENT_SHIFT 14
+#define OMAP4_HDMI_DDC_SCL_DUPLICATEWAKEUPEVENT_MASK (1 << 14)
+#define OMAP4_HDMI_CEC_DUPLICATEWAKEUPEVENT_SHIFT 13
+#define OMAP4_HDMI_CEC_DUPLICATEWAKEUPEVENT_MASK (1 << 13)
+#define OMAP4_HDMI_HPD_DUPLICATEWAKEUPEVENT_SHIFT 12
+#define OMAP4_HDMI_HPD_DUPLICATEWAKEUPEVENT_MASK (1 << 12)
+#define OMAP4_C2C_DATA15_DUPLICATEWAKEUPEVENT_SHIFT 11
+#define OMAP4_C2C_DATA15_DUPLICATEWAKEUPEVENT_MASK (1 << 11)
+#define OMAP4_C2C_DATA14_DUPLICATEWAKEUPEVENT_SHIFT 10
+#define OMAP4_C2C_DATA14_DUPLICATEWAKEUPEVENT_MASK (1 << 10)
+#define OMAP4_C2C_DATA13_DUPLICATEWAKEUPEVENT_SHIFT 9
+#define OMAP4_C2C_DATA13_DUPLICATEWAKEUPEVENT_MASK (1 << 9)
+#define OMAP4_C2C_DATA12_DUPLICATEWAKEUPEVENT_SHIFT 8
+#define OMAP4_C2C_DATA12_DUPLICATEWAKEUPEVENT_MASK (1 << 8)
+#define OMAP4_C2C_DATA11_DUPLICATEWAKEUPEVENT_SHIFT 7
+#define OMAP4_C2C_DATA11_DUPLICATEWAKEUPEVENT_MASK (1 << 7)
+#define OMAP4_GPMC_WAIT1_DUPLICATEWAKEUPEVENT_SHIFT 6
+#define OMAP4_GPMC_WAIT1_DUPLICATEWAKEUPEVENT_MASK (1 << 6)
+#define OMAP4_GPMC_WAIT0_DUPLICATEWAKEUPEVENT_SHIFT 5
+#define OMAP4_GPMC_WAIT0_DUPLICATEWAKEUPEVENT_MASK (1 << 5)
+#define OMAP4_GPMC_NBE1_DUPLICATEWAKEUPEVENT_SHIFT 4
+#define OMAP4_GPMC_NBE1_DUPLICATEWAKEUPEVENT_MASK (1 << 4)
+#define OMAP4_GPMC_NBE0_CLE_DUPLICATEWAKEUPEVENT_SHIFT 3
+#define OMAP4_GPMC_NBE0_CLE_DUPLICATEWAKEUPEVENT_MASK (1 << 3)
+#define OMAP4_GPMC_NWE_DUPLICATEWAKEUPEVENT_SHIFT 2
+#define OMAP4_GPMC_NWE_DUPLICATEWAKEUPEVENT_MASK (1 << 2)
+#define OMAP4_GPMC_NOE_DUPLICATEWAKEUPEVENT_SHIFT 1
+#define OMAP4_GPMC_NOE_DUPLICATEWAKEUPEVENT_MASK (1 << 1)
+#define OMAP4_GPMC_NADV_ALE_DUPLICATEWAKEUPEVENT_SHIFT 0
+#define OMAP4_GPMC_NADV_ALE_DUPLICATEWAKEUPEVENT_MASK (1 << 0)
+
+/* PADCONF_WAKEUPEVENT_2 */
+#define OMAP4_ABE_MCBSP1_CLKX_DUPLICATEWAKEUPEVENT_SHIFT 31
+#define OMAP4_ABE_MCBSP1_CLKX_DUPLICATEWAKEUPEVENT_MASK (1 << 31)
+#define OMAP4_ABE_MCBSP2_FSX_DUPLICATEWAKEUPEVENT_SHIFT 30
+#define OMAP4_ABE_MCBSP2_FSX_DUPLICATEWAKEUPEVENT_MASK (1 << 30)
+#define OMAP4_ABE_MCBSP2_DX_DUPLICATEWAKEUPEVENT_SHIFT 29
+#define OMAP4_ABE_MCBSP2_DX_DUPLICATEWAKEUPEVENT_MASK (1 << 29)
+#define OMAP4_ABE_MCBSP2_DR_DUPLICATEWAKEUPEVENT_SHIFT 28
+#define OMAP4_ABE_MCBSP2_DR_DUPLICATEWAKEUPEVENT_MASK (1 << 28)
+#define OMAP4_ABE_MCBSP2_CLKX_DUPLICATEWAKEUPEVENT_SHIFT 27
+#define OMAP4_ABE_MCBSP2_CLKX_DUPLICATEWAKEUPEVENT_MASK (1 << 27)
+#define OMAP4_SDMMC1_DAT7_DUPLICATEWAKEUPEVENT_SHIFT 26
+#define OMAP4_SDMMC1_DAT7_DUPLICATEWAKEUPEVENT_MASK (1 << 26)
+#define OMAP4_SDMMC1_DAT6_DUPLICATEWAKEUPEVENT_SHIFT 25
+#define OMAP4_SDMMC1_DAT6_DUPLICATEWAKEUPEVENT_MASK (1 << 25)
+#define OMAP4_SDMMC1_DAT5_DUPLICATEWAKEUPEVENT_SHIFT 24
+#define OMAP4_SDMMC1_DAT5_DUPLICATEWAKEUPEVENT_MASK (1 << 24)
+#define OMAP4_SDMMC1_DAT4_DUPLICATEWAKEUPEVENT_SHIFT 23
+#define OMAP4_SDMMC1_DAT4_DUPLICATEWAKEUPEVENT_MASK (1 << 23)
+#define OMAP4_SDMMC1_DAT3_DUPLICATEWAKEUPEVENT_SHIFT 22
+#define OMAP4_SDMMC1_DAT3_DUPLICATEWAKEUPEVENT_MASK (1 << 22)
+#define OMAP4_SDMMC1_DAT2_DUPLICATEWAKEUPEVENT_SHIFT 21
+#define OMAP4_SDMMC1_DAT2_DUPLICATEWAKEUPEVENT_MASK (1 << 21)
+#define OMAP4_SDMMC1_DAT1_DUPLICATEWAKEUPEVENT_SHIFT 20
+#define OMAP4_SDMMC1_DAT1_DUPLICATEWAKEUPEVENT_MASK (1 << 20)
+#define OMAP4_SDMMC1_DAT0_DUPLICATEWAKEUPEVENT_SHIFT 19
+#define OMAP4_SDMMC1_DAT0_DUPLICATEWAKEUPEVENT_MASK (1 << 19)
+#define OMAP4_SDMMC1_CMD_DUPLICATEWAKEUPEVENT_SHIFT 18
+#define OMAP4_SDMMC1_CMD_DUPLICATEWAKEUPEVENT_MASK (1 << 18)
+#define OMAP4_SDMMC1_CLK_DUPLICATEWAKEUPEVENT_SHIFT 17
+#define OMAP4_SDMMC1_CLK_DUPLICATEWAKEUPEVENT_MASK (1 << 17)
+#define OMAP4_USBC1_ICUSB_DM_DUPLICATEWAKEUPEVENT_SHIFT 16
+#define OMAP4_USBC1_ICUSB_DM_DUPLICATEWAKEUPEVENT_MASK (1 << 16)
+#define OMAP4_USBC1_ICUSB_DP_DUPLICATEWAKEUPEVENT_SHIFT 15
+#define OMAP4_USBC1_ICUSB_DP_DUPLICATEWAKEUPEVENT_MASK (1 << 15)
+#define OMAP4_USBB1_HSIC_STROBE_DUPLICATEWAKEUPEVENT_SHIFT 14
+#define OMAP4_USBB1_HSIC_STROBE_DUPLICATEWAKEUPEVENT_MASK (1 << 14)
+#define OMAP4_USBB1_HSIC_DATA_DUPLICATEWAKEUPEVENT_SHIFT 13
+#define OMAP4_USBB1_HSIC_DATA_DUPLICATEWAKEUPEVENT_MASK (1 << 13)
+#define OMAP4_USBB1_ULPITLL_DAT7_DUPLICATEWAKEUPEVENT_SHIFT 12
+#define OMAP4_USBB1_ULPITLL_DAT7_DUPLICATEWAKEUPEVENT_MASK (1 << 12)
+#define OMAP4_USBB1_ULPITLL_DAT6_DUPLICATEWAKEUPEVENT_SHIFT 11
+#define OMAP4_USBB1_ULPITLL_DAT6_DUPLICATEWAKEUPEVENT_MASK (1 << 11)
+#define OMAP4_USBB1_ULPITLL_DAT5_DUPLICATEWAKEUPEVENT_SHIFT 10
+#define OMAP4_USBB1_ULPITLL_DAT5_DUPLICATEWAKEUPEVENT_MASK (1 << 10)
+#define OMAP4_USBB1_ULPITLL_DAT4_DUPLICATEWAKEUPEVENT_SHIFT 9
+#define OMAP4_USBB1_ULPITLL_DAT4_DUPLICATEWAKEUPEVENT_MASK (1 << 9)
+#define OMAP4_USBB1_ULPITLL_DAT3_DUPLICATEWAKEUPEVENT_SHIFT 8
+#define OMAP4_USBB1_ULPITLL_DAT3_DUPLICATEWAKEUPEVENT_MASK (1 << 8)
+#define OMAP4_USBB1_ULPITLL_DAT2_DUPLICATEWAKEUPEVENT_SHIFT 7
+#define OMAP4_USBB1_ULPITLL_DAT2_DUPLICATEWAKEUPEVENT_MASK (1 << 7)
+#define OMAP4_USBB1_ULPITLL_DAT1_DUPLICATEWAKEUPEVENT_SHIFT 6
+#define OMAP4_USBB1_ULPITLL_DAT1_DUPLICATEWAKEUPEVENT_MASK (1 << 6)
+#define OMAP4_USBB1_ULPITLL_DAT0_DUPLICATEWAKEUPEVENT_SHIFT 5
+#define OMAP4_USBB1_ULPITLL_DAT0_DUPLICATEWAKEUPEVENT_MASK (1 << 5)
+#define OMAP4_USBB1_ULPITLL_NXT_DUPLICATEWAKEUPEVENT_SHIFT 4
+#define OMAP4_USBB1_ULPITLL_NXT_DUPLICATEWAKEUPEVENT_MASK (1 << 4)
+#define OMAP4_USBB1_ULPITLL_DIR_DUPLICATEWAKEUPEVENT_SHIFT 3
+#define OMAP4_USBB1_ULPITLL_DIR_DUPLICATEWAKEUPEVENT_MASK (1 << 3)
+#define OMAP4_USBB1_ULPITLL_STP_DUPLICATEWAKEUPEVENT_SHIFT 2
+#define OMAP4_USBB1_ULPITLL_STP_DUPLICATEWAKEUPEVENT_MASK (1 << 2)
+#define OMAP4_USBB1_ULPITLL_CLK_DUPLICATEWAKEUPEVENT_SHIFT 1
+#define OMAP4_USBB1_ULPITLL_CLK_DUPLICATEWAKEUPEVENT_MASK (1 << 1)
+#define OMAP4_CAM_GLOBALRESET_DUPLICATEWAKEUPEVENT_SHIFT 0
+#define OMAP4_CAM_GLOBALRESET_DUPLICATEWAKEUPEVENT_MASK (1 << 0)
+
+/* PADCONF_WAKEUPEVENT_3 */
+#define OMAP4_MCSPI1_CS3_DUPLICATEWAKEUPEVENT_SHIFT 31
+#define OMAP4_MCSPI1_CS3_DUPLICATEWAKEUPEVENT_MASK (1 << 31)
+#define OMAP4_MCSPI1_CS2_DUPLICATEWAKEUPEVENT_SHIFT 30
+#define OMAP4_MCSPI1_CS2_DUPLICATEWAKEUPEVENT_MASK (1 << 30)
+#define OMAP4_MCSPI1_CS1_DUPLICATEWAKEUPEVENT_SHIFT 29
+#define OMAP4_MCSPI1_CS1_DUPLICATEWAKEUPEVENT_MASK (1 << 29)
+#define OMAP4_MCSPI1_CS0_DUPLICATEWAKEUPEVENT_SHIFT 28
+#define OMAP4_MCSPI1_CS0_DUPLICATEWAKEUPEVENT_MASK (1 << 28)
+#define OMAP4_MCSPI1_SIMO_DUPLICATEWAKEUPEVENT_SHIFT 27
+#define OMAP4_MCSPI1_SIMO_DUPLICATEWAKEUPEVENT_MASK (1 << 27)
+#define OMAP4_MCSPI1_SOMI_DUPLICATEWAKEUPEVENT_SHIFT 26
+#define OMAP4_MCSPI1_SOMI_DUPLICATEWAKEUPEVENT_MASK (1 << 26)
+#define OMAP4_MCSPI1_CLK_DUPLICATEWAKEUPEVENT_SHIFT 25
+#define OMAP4_MCSPI1_CLK_DUPLICATEWAKEUPEVENT_MASK (1 << 25)
+#define OMAP4_I2C4_SDA_DUPLICATEWAKEUPEVENT_SHIFT 24
+#define OMAP4_I2C4_SDA_DUPLICATEWAKEUPEVENT_MASK (1 << 24)
+#define OMAP4_I2C4_SCL_DUPLICATEWAKEUPEVENT_SHIFT 23
+#define OMAP4_I2C4_SCL_DUPLICATEWAKEUPEVENT_MASK (1 << 23)
+#define OMAP4_I2C3_SDA_DUPLICATEWAKEUPEVENT_SHIFT 22
+#define OMAP4_I2C3_SDA_DUPLICATEWAKEUPEVENT_MASK (1 << 22)
+#define OMAP4_I2C3_SCL_DUPLICATEWAKEUPEVENT_SHIFT 21
+#define OMAP4_I2C3_SCL_DUPLICATEWAKEUPEVENT_MASK (1 << 21)
+#define OMAP4_I2C2_SDA_DUPLICATEWAKEUPEVENT_SHIFT 20
+#define OMAP4_I2C2_SDA_DUPLICATEWAKEUPEVENT_MASK (1 << 20)
+#define OMAP4_I2C2_SCL_DUPLICATEWAKEUPEVENT_SHIFT 19
+#define OMAP4_I2C2_SCL_DUPLICATEWAKEUPEVENT_MASK (1 << 19)
+#define OMAP4_I2C1_SDA_DUPLICATEWAKEUPEVENT_SHIFT 18
+#define OMAP4_I2C1_SDA_DUPLICATEWAKEUPEVENT_MASK (1 << 18)
+#define OMAP4_I2C1_SCL_DUPLICATEWAKEUPEVENT_SHIFT 17
+#define OMAP4_I2C1_SCL_DUPLICATEWAKEUPEVENT_MASK (1 << 17)
+#define OMAP4_HDQ_SIO_DUPLICATEWAKEUPEVENT_SHIFT 16
+#define OMAP4_HDQ_SIO_DUPLICATEWAKEUPEVENT_MASK (1 << 16)
+#define OMAP4_UART2_TX_DUPLICATEWAKEUPEVENT_SHIFT 15
+#define OMAP4_UART2_TX_DUPLICATEWAKEUPEVENT_MASK (1 << 15)
+#define OMAP4_UART2_RX_DUPLICATEWAKEUPEVENT_SHIFT 14
+#define OMAP4_UART2_RX_DUPLICATEWAKEUPEVENT_MASK (1 << 14)
+#define OMAP4_UART2_RTS_DUPLICATEWAKEUPEVENT_SHIFT 13
+#define OMAP4_UART2_RTS_DUPLICATEWAKEUPEVENT_MASK (1 << 13)
+#define OMAP4_UART2_CTS_DUPLICATEWAKEUPEVENT_SHIFT 12
+#define OMAP4_UART2_CTS_DUPLICATEWAKEUPEVENT_MASK (1 << 12)
+#define OMAP4_ABE_DMIC_DIN3_DUPLICATEWAKEUPEVENT_SHIFT 11
+#define OMAP4_ABE_DMIC_DIN3_DUPLICATEWAKEUPEVENT_MASK (1 << 11)
+#define OMAP4_ABE_DMIC_DIN2_DUPLICATEWAKEUPEVENT_SHIFT 10
+#define OMAP4_ABE_DMIC_DIN2_DUPLICATEWAKEUPEVENT_MASK (1 << 10)
+#define OMAP4_ABE_DMIC_DIN1_DUPLICATEWAKEUPEVENT_SHIFT 9
+#define OMAP4_ABE_DMIC_DIN1_DUPLICATEWAKEUPEVENT_MASK (1 << 9)
+#define OMAP4_ABE_DMIC_CLK1_DUPLICATEWAKEUPEVENT_SHIFT 8
+#define OMAP4_ABE_DMIC_CLK1_DUPLICATEWAKEUPEVENT_MASK (1 << 8)
+#define OMAP4_ABE_CLKS_DUPLICATEWAKEUPEVENT_SHIFT 7
+#define OMAP4_ABE_CLKS_DUPLICATEWAKEUPEVENT_MASK (1 << 7)
+#define OMAP4_ABE_PDM_LB_CLK_DUPLICATEWAKEUPEVENT_SHIFT 6
+#define OMAP4_ABE_PDM_LB_CLK_DUPLICATEWAKEUPEVENT_MASK (1 << 6)
+#define OMAP4_ABE_PDM_FRAME_DUPLICATEWAKEUPEVENT_SHIFT 5
+#define OMAP4_ABE_PDM_FRAME_DUPLICATEWAKEUPEVENT_MASK (1 << 5)
+#define OMAP4_ABE_PDM_DL_DATA_DUPLICATEWAKEUPEVENT_SHIFT 4
+#define OMAP4_ABE_PDM_DL_DATA_DUPLICATEWAKEUPEVENT_MASK (1 << 4)
+#define OMAP4_ABE_PDM_UL_DATA_DUPLICATEWAKEUPEVENT_SHIFT 3
+#define OMAP4_ABE_PDM_UL_DATA_DUPLICATEWAKEUPEVENT_MASK (1 << 3)
+#define OMAP4_ABE_MCBSP1_FSX_DUPLICATEWAKEUPEVENT_SHIFT 2
+#define OMAP4_ABE_MCBSP1_FSX_DUPLICATEWAKEUPEVENT_MASK (1 << 2)
+#define OMAP4_ABE_MCBSP1_DX_DUPLICATEWAKEUPEVENT_SHIFT 1
+#define OMAP4_ABE_MCBSP1_DX_DUPLICATEWAKEUPEVENT_MASK (1 << 1)
+#define OMAP4_ABE_MCBSP1_DR_DUPLICATEWAKEUPEVENT_SHIFT 0
+#define OMAP4_ABE_MCBSP1_DR_DUPLICATEWAKEUPEVENT_MASK (1 << 0)
+
+/* PADCONF_WAKEUPEVENT_4 */
+#define OMAP4_UNIPRO_TY0_DUPLICATEWAKEUPEVENT_SHIFT 31
+#define OMAP4_UNIPRO_TY0_DUPLICATEWAKEUPEVENT_MASK (1 << 31)
+#define OMAP4_UNIPRO_TX0_DUPLICATEWAKEUPEVENT_SHIFT 30
+#define OMAP4_UNIPRO_TX0_DUPLICATEWAKEUPEVENT_MASK (1 << 30)
+#define OMAP4_USBB2_HSIC_STROBE_DUPLICATEWAKEUPEVENT_SHIFT 29
+#define OMAP4_USBB2_HSIC_STROBE_DUPLICATEWAKEUPEVENT_MASK (1 << 29)
+#define OMAP4_USBB2_HSIC_DATA_DUPLICATEWAKEUPEVENT_SHIFT 28
+#define OMAP4_USBB2_HSIC_DATA_DUPLICATEWAKEUPEVENT_MASK (1 << 28)
+#define OMAP4_USBB2_ULPITLL_DAT7_DUPLICATEWAKEUPEVENT_SHIFT 27
+#define OMAP4_USBB2_ULPITLL_DAT7_DUPLICATEWAKEUPEVENT_MASK (1 << 27)
+#define OMAP4_USBB2_ULPITLL_DAT6_DUPLICATEWAKEUPEVENT_SHIFT 26
+#define OMAP4_USBB2_ULPITLL_DAT6_DUPLICATEWAKEUPEVENT_MASK (1 << 26)
+#define OMAP4_USBB2_ULPITLL_DAT5_DUPLICATEWAKEUPEVENT_SHIFT 25
+#define OMAP4_USBB2_ULPITLL_DAT5_DUPLICATEWAKEUPEVENT_MASK (1 << 25)
+#define OMAP4_USBB2_ULPITLL_DAT4_DUPLICATEWAKEUPEVENT_SHIFT 24
+#define OMAP4_USBB2_ULPITLL_DAT4_DUPLICATEWAKEUPEVENT_MASK (1 << 24)
+#define OMAP4_USBB2_ULPITLL_DAT3_DUPLICATEWAKEUPEVENT_SHIFT 23
+#define OMAP4_USBB2_ULPITLL_DAT3_DUPLICATEWAKEUPEVENT_MASK (1 << 23)
+#define OMAP4_USBB2_ULPITLL_DAT2_DUPLICATEWAKEUPEVENT_SHIFT 22
+#define OMAP4_USBB2_ULPITLL_DAT2_DUPLICATEWAKEUPEVENT_MASK (1 << 22)
+#define OMAP4_USBB2_ULPITLL_DAT1_DUPLICATEWAKEUPEVENT_SHIFT 21
+#define OMAP4_USBB2_ULPITLL_DAT1_DUPLICATEWAKEUPEVENT_MASK (1 << 21)
+#define OMAP4_USBB2_ULPITLL_DAT0_DUPLICATEWAKEUPEVENT_SHIFT 20
+#define OMAP4_USBB2_ULPITLL_DAT0_DUPLICATEWAKEUPEVENT_MASK (1 << 20)
+#define OMAP4_USBB2_ULPITLL_NXT_DUPLICATEWAKEUPEVENT_SHIFT 19
+#define OMAP4_USBB2_ULPITLL_NXT_DUPLICATEWAKEUPEVENT_MASK (1 << 19)
+#define OMAP4_USBB2_ULPITLL_DIR_DUPLICATEWAKEUPEVENT_SHIFT 18
+#define OMAP4_USBB2_ULPITLL_DIR_DUPLICATEWAKEUPEVENT_MASK (1 << 18)
+#define OMAP4_USBB2_ULPITLL_STP_DUPLICATEWAKEUPEVENT_SHIFT 17
+#define OMAP4_USBB2_ULPITLL_STP_DUPLICATEWAKEUPEVENT_MASK (1 << 17)
+#define OMAP4_USBB2_ULPITLL_CLK_DUPLICATEWAKEUPEVENT_SHIFT 16
+#define OMAP4_USBB2_ULPITLL_CLK_DUPLICATEWAKEUPEVENT_MASK (1 << 16)
+#define OMAP4_UART4_TX_DUPLICATEWAKEUPEVENT_SHIFT 15
+#define OMAP4_UART4_TX_DUPLICATEWAKEUPEVENT_MASK (1 << 15)
+#define OMAP4_UART4_RX_DUPLICATEWAKEUPEVENT_SHIFT 14
+#define OMAP4_UART4_RX_DUPLICATEWAKEUPEVENT_MASK (1 << 14)
+#define OMAP4_MCSPI4_CS0_DUPLICATEWAKEUPEVENT_SHIFT 13
+#define OMAP4_MCSPI4_CS0_DUPLICATEWAKEUPEVENT_MASK (1 << 13)
+#define OMAP4_MCSPI4_SOMI_DUPLICATEWAKEUPEVENT_SHIFT 12
+#define OMAP4_MCSPI4_SOMI_DUPLICATEWAKEUPEVENT_MASK (1 << 12)
+#define OMAP4_MCSPI4_SIMO_DUPLICATEWAKEUPEVENT_SHIFT 11
+#define OMAP4_MCSPI4_SIMO_DUPLICATEWAKEUPEVENT_MASK (1 << 11)
+#define OMAP4_MCSPI4_CLK_DUPLICATEWAKEUPEVENT_SHIFT 10
+#define OMAP4_MCSPI4_CLK_DUPLICATEWAKEUPEVENT_MASK (1 << 10)
+#define OMAP4_SDMMC5_DAT3_DUPLICATEWAKEUPEVENT_SHIFT 9
+#define OMAP4_SDMMC5_DAT3_DUPLICATEWAKEUPEVENT_MASK (1 << 9)
+#define OMAP4_SDMMC5_DAT2_DUPLICATEWAKEUPEVENT_SHIFT 8
+#define OMAP4_SDMMC5_DAT2_DUPLICATEWAKEUPEVENT_MASK (1 << 8)
+#define OMAP4_SDMMC5_DAT1_DUPLICATEWAKEUPEVENT_SHIFT 7
+#define OMAP4_SDMMC5_DAT1_DUPLICATEWAKEUPEVENT_MASK (1 << 7)
+#define OMAP4_SDMMC5_DAT0_DUPLICATEWAKEUPEVENT_SHIFT 6
+#define OMAP4_SDMMC5_DAT0_DUPLICATEWAKEUPEVENT_MASK (1 << 6)
+#define OMAP4_SDMMC5_CMD_DUPLICATEWAKEUPEVENT_SHIFT 5
+#define OMAP4_SDMMC5_CMD_DUPLICATEWAKEUPEVENT_MASK (1 << 5)
+#define OMAP4_SDMMC5_CLK_DUPLICATEWAKEUPEVENT_SHIFT 4
+#define OMAP4_SDMMC5_CLK_DUPLICATEWAKEUPEVENT_MASK (1 << 4)
+#define OMAP4_UART3_TX_IRTX_DUPLICATEWAKEUPEVENT_SHIFT 3
+#define OMAP4_UART3_TX_IRTX_DUPLICATEWAKEUPEVENT_MASK (1 << 3)
+#define OMAP4_UART3_RX_IRRX_DUPLICATEWAKEUPEVENT_SHIFT 2
+#define OMAP4_UART3_RX_IRRX_DUPLICATEWAKEUPEVENT_MASK (1 << 2)
+#define OMAP4_UART3_RTS_SD_DUPLICATEWAKEUPEVENT_SHIFT 1
+#define OMAP4_UART3_RTS_SD_DUPLICATEWAKEUPEVENT_MASK (1 << 1)
+#define OMAP4_UART3_CTS_RCTX_DUPLICATEWAKEUPEVENT_SHIFT 0
+#define OMAP4_UART3_CTS_RCTX_DUPLICATEWAKEUPEVENT_MASK (1 << 0)
+
+/* PADCONF_WAKEUPEVENT_5 */
+#define OMAP4_DPM_EMU11_DUPLICATEWAKEUPEVENT_SHIFT 31
+#define OMAP4_DPM_EMU11_DUPLICATEWAKEUPEVENT_MASK (1 << 31)
+#define OMAP4_DPM_EMU10_DUPLICATEWAKEUPEVENT_SHIFT 30
+#define OMAP4_DPM_EMU10_DUPLICATEWAKEUPEVENT_MASK (1 << 30)
+#define OMAP4_DPM_EMU9_DUPLICATEWAKEUPEVENT_SHIFT 29
+#define OMAP4_DPM_EMU9_DUPLICATEWAKEUPEVENT_MASK (1 << 29)
+#define OMAP4_DPM_EMU8_DUPLICATEWAKEUPEVENT_SHIFT 28
+#define OMAP4_DPM_EMU8_DUPLICATEWAKEUPEVENT_MASK (1 << 28)
+#define OMAP4_DPM_EMU7_DUPLICATEWAKEUPEVENT_SHIFT 27
+#define OMAP4_DPM_EMU7_DUPLICATEWAKEUPEVENT_MASK (1 << 27)
+#define OMAP4_DPM_EMU6_DUPLICATEWAKEUPEVENT_SHIFT 26
+#define OMAP4_DPM_EMU6_DUPLICATEWAKEUPEVENT_MASK (1 << 26)
+#define OMAP4_DPM_EMU5_DUPLICATEWAKEUPEVENT_SHIFT 25
+#define OMAP4_DPM_EMU5_DUPLICATEWAKEUPEVENT_MASK (1 << 25)
+#define OMAP4_DPM_EMU4_DUPLICATEWAKEUPEVENT_SHIFT 24
+#define OMAP4_DPM_EMU4_DUPLICATEWAKEUPEVENT_MASK (1 << 24)
+#define OMAP4_DPM_EMU3_DUPLICATEWAKEUPEVENT_SHIFT 23
+#define OMAP4_DPM_EMU3_DUPLICATEWAKEUPEVENT_MASK (1 << 23)
+#define OMAP4_DPM_EMU2_DUPLICATEWAKEUPEVENT_SHIFT 22
+#define OMAP4_DPM_EMU2_DUPLICATEWAKEUPEVENT_MASK (1 << 22)
+#define OMAP4_DPM_EMU1_DUPLICATEWAKEUPEVENT_SHIFT 21
+#define OMAP4_DPM_EMU1_DUPLICATEWAKEUPEVENT_MASK (1 << 21)
+#define OMAP4_DPM_EMU0_DUPLICATEWAKEUPEVENT_SHIFT 20
+#define OMAP4_DPM_EMU0_DUPLICATEWAKEUPEVENT_MASK (1 << 20)
+#define OMAP4_SYS_BOOT5_DUPLICATEWAKEUPEVENT_SHIFT 19
+#define OMAP4_SYS_BOOT5_DUPLICATEWAKEUPEVENT_MASK (1 << 19)
+#define OMAP4_SYS_BOOT4_DUPLICATEWAKEUPEVENT_SHIFT 18
+#define OMAP4_SYS_BOOT4_DUPLICATEWAKEUPEVENT_MASK (1 << 18)
+#define OMAP4_SYS_BOOT3_DUPLICATEWAKEUPEVENT_SHIFT 17
+#define OMAP4_SYS_BOOT3_DUPLICATEWAKEUPEVENT_MASK (1 << 17)
+#define OMAP4_SYS_BOOT2_DUPLICATEWAKEUPEVENT_SHIFT 16
+#define OMAP4_SYS_BOOT2_DUPLICATEWAKEUPEVENT_MASK (1 << 16)
+#define OMAP4_SYS_BOOT1_DUPLICATEWAKEUPEVENT_SHIFT 15
+#define OMAP4_SYS_BOOT1_DUPLICATEWAKEUPEVENT_MASK (1 << 15)
+#define OMAP4_SYS_BOOT0_DUPLICATEWAKEUPEVENT_SHIFT 14
+#define OMAP4_SYS_BOOT0_DUPLICATEWAKEUPEVENT_MASK (1 << 14)
+#define OMAP4_SYS_NIRQ2_DUPLICATEWAKEUPEVENT_SHIFT 13
+#define OMAP4_SYS_NIRQ2_DUPLICATEWAKEUPEVENT_MASK (1 << 13)
+#define OMAP4_SYS_NIRQ1_DUPLICATEWAKEUPEVENT_SHIFT 12
+#define OMAP4_SYS_NIRQ1_DUPLICATEWAKEUPEVENT_MASK (1 << 12)
+#define OMAP4_FREF_CLK2_OUT_DUPLICATEWAKEUPEVENT_SHIFT 11
+#define OMAP4_FREF_CLK2_OUT_DUPLICATEWAKEUPEVENT_MASK (1 << 11)
+#define OMAP4_FREF_CLK1_OUT_DUPLICATEWAKEUPEVENT_SHIFT 10
+#define OMAP4_FREF_CLK1_OUT_DUPLICATEWAKEUPEVENT_MASK (1 << 10)
+#define OMAP4_UNIPRO_RY2_DUPLICATEWAKEUPEVENT_SHIFT 9
+#define OMAP4_UNIPRO_RY2_DUPLICATEWAKEUPEVENT_MASK (1 << 9)
+#define OMAP4_UNIPRO_RX2_DUPLICATEWAKEUPEVENT_SHIFT 8
+#define OMAP4_UNIPRO_RX2_DUPLICATEWAKEUPEVENT_MASK (1 << 8)
+#define OMAP4_UNIPRO_RY1_DUPLICATEWAKEUPEVENT_SHIFT 7
+#define OMAP4_UNIPRO_RY1_DUPLICATEWAKEUPEVENT_MASK (1 << 7)
+#define OMAP4_UNIPRO_RX1_DUPLICATEWAKEUPEVENT_SHIFT 6
+#define OMAP4_UNIPRO_RX1_DUPLICATEWAKEUPEVENT_MASK (1 << 6)
+#define OMAP4_UNIPRO_RY0_DUPLICATEWAKEUPEVENT_SHIFT 5
+#define OMAP4_UNIPRO_RY0_DUPLICATEWAKEUPEVENT_MASK (1 << 5)
+#define OMAP4_UNIPRO_RX0_DUPLICATEWAKEUPEVENT_SHIFT 4
+#define OMAP4_UNIPRO_RX0_DUPLICATEWAKEUPEVENT_MASK (1 << 4)
+#define OMAP4_UNIPRO_TY2_DUPLICATEWAKEUPEVENT_SHIFT 3
+#define OMAP4_UNIPRO_TY2_DUPLICATEWAKEUPEVENT_MASK (1 << 3)
+#define OMAP4_UNIPRO_TX2_DUPLICATEWAKEUPEVENT_SHIFT 2
+#define OMAP4_UNIPRO_TX2_DUPLICATEWAKEUPEVENT_MASK (1 << 2)
+#define OMAP4_UNIPRO_TY1_DUPLICATEWAKEUPEVENT_SHIFT 1
+#define OMAP4_UNIPRO_TY1_DUPLICATEWAKEUPEVENT_MASK (1 << 1)
+#define OMAP4_UNIPRO_TX1_DUPLICATEWAKEUPEVENT_SHIFT 0
+#define OMAP4_UNIPRO_TX1_DUPLICATEWAKEUPEVENT_MASK (1 << 0)
+
+/* PADCONF_WAKEUPEVENT_6 */
+#define OMAP4_DPM_EMU19_DUPLICATEWAKEUPEVENT_SHIFT 7
+#define OMAP4_DPM_EMU19_DUPLICATEWAKEUPEVENT_MASK (1 << 7)
+#define OMAP4_DPM_EMU18_DUPLICATEWAKEUPEVENT_SHIFT 6
+#define OMAP4_DPM_EMU18_DUPLICATEWAKEUPEVENT_MASK (1 << 6)
+#define OMAP4_DPM_EMU17_DUPLICATEWAKEUPEVENT_SHIFT 5
+#define OMAP4_DPM_EMU17_DUPLICATEWAKEUPEVENT_MASK (1 << 5)
+#define OMAP4_DPM_EMU16_DUPLICATEWAKEUPEVENT_SHIFT 4
+#define OMAP4_DPM_EMU16_DUPLICATEWAKEUPEVENT_MASK (1 << 4)
+#define OMAP4_DPM_EMU15_DUPLICATEWAKEUPEVENT_SHIFT 3
+#define OMAP4_DPM_EMU15_DUPLICATEWAKEUPEVENT_MASK (1 << 3)
+#define OMAP4_DPM_EMU14_DUPLICATEWAKEUPEVENT_SHIFT 2
+#define OMAP4_DPM_EMU14_DUPLICATEWAKEUPEVENT_MASK (1 << 2)
+#define OMAP4_DPM_EMU13_DUPLICATEWAKEUPEVENT_SHIFT 1
+#define OMAP4_DPM_EMU13_DUPLICATEWAKEUPEVENT_MASK (1 << 1)
+#define OMAP4_DPM_EMU12_DUPLICATEWAKEUPEVENT_SHIFT 0
+#define OMAP4_DPM_EMU12_DUPLICATEWAKEUPEVENT_MASK (1 << 0)
+
+/* CONTROL_PADCONF_GLOBAL */
+#define OMAP4_FORCE_OFFMODE_EN_SHIFT 31
+#define OMAP4_FORCE_OFFMODE_EN_MASK (1 << 31)
+
+/* CONTROL_PADCONF_MODE */
+#define OMAP4_VDDS_DV_BANK0_SHIFT 31
+#define OMAP4_VDDS_DV_BANK0_MASK (1 << 31)
+#define OMAP4_VDDS_DV_BANK1_SHIFT 30
+#define OMAP4_VDDS_DV_BANK1_MASK (1 << 30)
+#define OMAP4_VDDS_DV_BANK3_SHIFT 29
+#define OMAP4_VDDS_DV_BANK3_MASK (1 << 29)
+#define OMAP4_VDDS_DV_BANK4_SHIFT 28
+#define OMAP4_VDDS_DV_BANK4_MASK (1 << 28)
+#define OMAP4_VDDS_DV_BANK5_SHIFT 27
+#define OMAP4_VDDS_DV_BANK5_MASK (1 << 27)
+#define OMAP4_VDDS_DV_BANK6_SHIFT 26
+#define OMAP4_VDDS_DV_BANK6_MASK (1 << 26)
+#define OMAP4_VDDS_DV_C2C_SHIFT 25
+#define OMAP4_VDDS_DV_C2C_MASK (1 << 25)
+#define OMAP4_VDDS_DV_CAM_SHIFT 24
+#define OMAP4_VDDS_DV_CAM_MASK (1 << 24)
+#define OMAP4_VDDS_DV_GPMC_SHIFT 23
+#define OMAP4_VDDS_DV_GPMC_MASK (1 << 23)
+#define OMAP4_VDDS_DV_SDMMC2_SHIFT 22
+#define OMAP4_VDDS_DV_SDMMC2_MASK (1 << 22)
+
+/* CONTROL_SMART1IO_PADCONF_0 */
+#define OMAP4_ABE_DR0_SC_SHIFT 30
+#define OMAP4_ABE_DR0_SC_MASK (0x3 << 30)
+#define OMAP4_CAM_DR0_SC_SHIFT 28
+#define OMAP4_CAM_DR0_SC_MASK (0x3 << 28)
+#define OMAP4_FREF_DR2_SC_SHIFT 26
+#define OMAP4_FREF_DR2_SC_MASK (0x3 << 26)
+#define OMAP4_FREF_DR3_SC_SHIFT 24
+#define OMAP4_FREF_DR3_SC_MASK (0x3 << 24)
+#define OMAP4_GPIO_DR8_SC_SHIFT 22
+#define OMAP4_GPIO_DR8_SC_MASK (0x3 << 22)
+#define OMAP4_GPIO_DR9_SC_SHIFT 20
+#define OMAP4_GPIO_DR9_SC_MASK (0x3 << 20)
+#define OMAP4_GPMC_DR2_SC_SHIFT 18
+#define OMAP4_GPMC_DR2_SC_MASK (0x3 << 18)
+#define OMAP4_GPMC_DR3_SC_SHIFT 16
+#define OMAP4_GPMC_DR3_SC_MASK (0x3 << 16)
+#define OMAP4_GPMC_DR6_SC_SHIFT 14
+#define OMAP4_GPMC_DR6_SC_MASK (0x3 << 14)
+#define OMAP4_HDMI_DR0_SC_SHIFT 12
+#define OMAP4_HDMI_DR0_SC_MASK (0x3 << 12)
+#define OMAP4_MCSPI1_DR0_SC_SHIFT 10
+#define OMAP4_MCSPI1_DR0_SC_MASK (0x3 << 10)
+#define OMAP4_UART1_DR0_SC_SHIFT 8
+#define OMAP4_UART1_DR0_SC_MASK (0x3 << 8)
+#define OMAP4_UART3_DR0_SC_SHIFT 6
+#define OMAP4_UART3_DR0_SC_MASK (0x3 << 6)
+#define OMAP4_UART3_DR1_SC_SHIFT 4
+#define OMAP4_UART3_DR1_SC_MASK (0x3 << 4)
+#define OMAP4_UNIPRO_DR0_SC_SHIFT 2
+#define OMAP4_UNIPRO_DR0_SC_MASK (0x3 << 2)
+#define OMAP4_UNIPRO_DR1_SC_SHIFT 0
+#define OMAP4_UNIPRO_DR1_SC_MASK (0x3 << 0)
+
+/* CONTROL_SMART1IO_PADCONF_1 */
+#define OMAP4_ABE_DR0_LB_SHIFT 30
+#define OMAP4_ABE_DR0_LB_MASK (0x3 << 30)
+#define OMAP4_CAM_DR0_LB_SHIFT 28
+#define OMAP4_CAM_DR0_LB_MASK (0x3 << 28)
+#define OMAP4_FREF_DR2_LB_SHIFT 26
+#define OMAP4_FREF_DR2_LB_MASK (0x3 << 26)
+#define OMAP4_FREF_DR3_LB_SHIFT 24
+#define OMAP4_FREF_DR3_LB_MASK (0x3 << 24)
+#define OMAP4_GPIO_DR8_LB_SHIFT 22
+#define OMAP4_GPIO_DR8_LB_MASK (0x3 << 22)
+#define OMAP4_GPIO_DR9_LB_SHIFT 20
+#define OMAP4_GPIO_DR9_LB_MASK (0x3 << 20)
+#define OMAP4_GPMC_DR2_LB_SHIFT 18
+#define OMAP4_GPMC_DR2_LB_MASK (0x3 << 18)
+#define OMAP4_GPMC_DR3_LB_SHIFT 16
+#define OMAP4_GPMC_DR3_LB_MASK (0x3 << 16)
+#define OMAP4_GPMC_DR6_LB_SHIFT 14
+#define OMAP4_GPMC_DR6_LB_MASK (0x3 << 14)
+#define OMAP4_HDMI_DR0_LB_SHIFT 12
+#define OMAP4_HDMI_DR0_LB_MASK (0x3 << 12)
+#define OMAP4_MCSPI1_DR0_LB_SHIFT 10
+#define OMAP4_MCSPI1_DR0_LB_MASK (0x3 << 10)
+#define OMAP4_UART1_DR0_LB_SHIFT 8
+#define OMAP4_UART1_DR0_LB_MASK (0x3 << 8)
+#define OMAP4_UART3_DR0_LB_SHIFT 6
+#define OMAP4_UART3_DR0_LB_MASK (0x3 << 6)
+#define OMAP4_UART3_DR1_LB_SHIFT 4
+#define OMAP4_UART3_DR1_LB_MASK (0x3 << 4)
+#define OMAP4_UNIPRO_DR0_LB_SHIFT 2
+#define OMAP4_UNIPRO_DR0_LB_MASK (0x3 << 2)
+#define OMAP4_UNIPRO_DR1_LB_SHIFT 0
+#define OMAP4_UNIPRO_DR1_LB_MASK (0x3 << 0)
+
+/* CONTROL_SMART2IO_PADCONF_0 */
+#define OMAP4_C2C_DR0_LB_SHIFT 31
+#define OMAP4_C2C_DR0_LB_MASK (1 << 31)
+#define OMAP4_DPM_DR1_LB_SHIFT 30
+#define OMAP4_DPM_DR1_LB_MASK (1 << 30)
+#define OMAP4_DPM_DR2_LB_SHIFT 29
+#define OMAP4_DPM_DR2_LB_MASK (1 << 29)
+#define OMAP4_DPM_DR3_LB_SHIFT 28
+#define OMAP4_DPM_DR3_LB_MASK (1 << 28)
+#define OMAP4_GPIO_DR0_LB_SHIFT 27
+#define OMAP4_GPIO_DR0_LB_MASK (1 << 27)
+#define OMAP4_GPIO_DR1_LB_SHIFT 26
+#define OMAP4_GPIO_DR1_LB_MASK (1 << 26)
+#define OMAP4_GPIO_DR10_LB_SHIFT 25
+#define OMAP4_GPIO_DR10_LB_MASK (1 << 25)
+#define OMAP4_GPIO_DR2_LB_SHIFT 24
+#define OMAP4_GPIO_DR2_LB_MASK (1 << 24)
+#define OMAP4_GPMC_DR0_LB_SHIFT 23
+#define OMAP4_GPMC_DR0_LB_MASK (1 << 23)
+#define OMAP4_GPMC_DR1_LB_SHIFT 22
+#define OMAP4_GPMC_DR1_LB_MASK (1 << 22)
+#define OMAP4_GPMC_DR4_LB_SHIFT 21
+#define OMAP4_GPMC_DR4_LB_MASK (1 << 21)
+#define OMAP4_GPMC_DR5_LB_SHIFT 20
+#define OMAP4_GPMC_DR5_LB_MASK (1 << 20)
+#define OMAP4_GPMC_DR7_LB_SHIFT 19
+#define OMAP4_GPMC_DR7_LB_MASK (1 << 19)
+#define OMAP4_HSI2_DR0_LB_SHIFT 18
+#define OMAP4_HSI2_DR0_LB_MASK (1 << 18)
+#define OMAP4_HSI2_DR1_LB_SHIFT 17
+#define OMAP4_HSI2_DR1_LB_MASK (1 << 17)
+#define OMAP4_HSI2_DR2_LB_SHIFT 16
+#define OMAP4_HSI2_DR2_LB_MASK (1 << 16)
+#define OMAP4_KPD_DR0_LB_SHIFT 15
+#define OMAP4_KPD_DR0_LB_MASK (1 << 15)
+#define OMAP4_KPD_DR1_LB_SHIFT 14
+#define OMAP4_KPD_DR1_LB_MASK (1 << 14)
+#define OMAP4_PDM_DR0_LB_SHIFT 13
+#define OMAP4_PDM_DR0_LB_MASK (1 << 13)
+#define OMAP4_SDMMC2_DR0_LB_SHIFT 12
+#define OMAP4_SDMMC2_DR0_LB_MASK (1 << 12)
+#define OMAP4_SDMMC3_DR0_LB_SHIFT 11
+#define OMAP4_SDMMC3_DR0_LB_MASK (1 << 11)
+#define OMAP4_SDMMC4_DR0_LB_SHIFT 10
+#define OMAP4_SDMMC4_DR0_LB_MASK (1 << 10)
+#define OMAP4_SDMMC4_DR1_LB_SHIFT 9
+#define OMAP4_SDMMC4_DR1_LB_MASK (1 << 9)
+#define OMAP4_SPI3_DR0_LB_SHIFT 8
+#define OMAP4_SPI3_DR0_LB_MASK (1 << 8)
+#define OMAP4_SPI3_DR1_LB_SHIFT 7
+#define OMAP4_SPI3_DR1_LB_MASK (1 << 7)
+#define OMAP4_UART3_DR2_LB_SHIFT 6
+#define OMAP4_UART3_DR2_LB_MASK (1 << 6)
+#define OMAP4_UART3_DR3_LB_SHIFT 5
+#define OMAP4_UART3_DR3_LB_MASK (1 << 5)
+#define OMAP4_UART3_DR4_LB_SHIFT 4
+#define OMAP4_UART3_DR4_LB_MASK (1 << 4)
+#define OMAP4_UART3_DR5_LB_SHIFT 3
+#define OMAP4_UART3_DR5_LB_MASK (1 << 3)
+#define OMAP4_USBA0_DR1_LB_SHIFT 2
+#define OMAP4_USBA0_DR1_LB_MASK (1 << 2)
+#define OMAP4_USBA_DR2_LB_SHIFT 1
+#define OMAP4_USBA_DR2_LB_MASK (1 << 1)
+
+/* CONTROL_SMART2IO_PADCONF_1 */
+#define OMAP4_USBB1_DR0_LB_SHIFT 31
+#define OMAP4_USBB1_DR0_LB_MASK (1 << 31)
+#define OMAP4_USBB2_DR0_LB_SHIFT 30
+#define OMAP4_USBB2_DR0_LB_MASK (1 << 30)
+#define OMAP4_USBA0_DR0_LB_SHIFT 29
+#define OMAP4_USBA0_DR0_LB_MASK (1 << 29)
+
+/* CONTROL_SMART3IO_PADCONF_0 */
+#define OMAP4_DMIC_DR0_MB_SHIFT 30
+#define OMAP4_DMIC_DR0_MB_MASK (0x3 << 30)
+#define OMAP4_GPIO_DR3_MB_SHIFT 28
+#define OMAP4_GPIO_DR3_MB_MASK (0x3 << 28)
+#define OMAP4_GPIO_DR4_MB_SHIFT 26
+#define OMAP4_GPIO_DR4_MB_MASK (0x3 << 26)
+#define OMAP4_GPIO_DR5_MB_SHIFT 24
+#define OMAP4_GPIO_DR5_MB_MASK (0x3 << 24)
+#define OMAP4_GPIO_DR6_MB_SHIFT 22
+#define OMAP4_GPIO_DR6_MB_MASK (0x3 << 22)
+#define OMAP4_HSI_DR1_MB_SHIFT 20
+#define OMAP4_HSI_DR1_MB_MASK (0x3 << 20)
+#define OMAP4_HSI_DR2_MB_SHIFT 18
+#define OMAP4_HSI_DR2_MB_MASK (0x3 << 18)
+#define OMAP4_HSI_DR3_MB_SHIFT 16
+#define OMAP4_HSI_DR3_MB_MASK (0x3 << 16)
+#define OMAP4_MCBSP2_DR0_MB_SHIFT 14
+#define OMAP4_MCBSP2_DR0_MB_MASK (0x3 << 14)
+#define OMAP4_MCSPI4_DR0_MB_SHIFT 12
+#define OMAP4_MCSPI4_DR0_MB_MASK (0x3 << 12)
+#define OMAP4_MCSPI4_DR1_MB_SHIFT 10
+#define OMAP4_MCSPI4_DR1_MB_MASK (0x3 << 10)
+#define OMAP4_SDMMC3_DR0_MB_SHIFT 8
+#define OMAP4_SDMMC3_DR0_MB_MASK (0x3 << 8)
+#define OMAP4_SPI2_DR0_MB_SHIFT 0
+#define OMAP4_SPI2_DR0_MB_MASK (0x3 << 0)
+
+/* CONTROL_SMART3IO_PADCONF_1 */
+#define OMAP4_SPI2_DR1_MB_SHIFT 30
+#define OMAP4_SPI2_DR1_MB_MASK (0x3 << 30)
+#define OMAP4_SPI2_DR2_MB_SHIFT 28
+#define OMAP4_SPI2_DR2_MB_MASK (0x3 << 28)
+#define OMAP4_UART2_DR0_MB_SHIFT 26
+#define OMAP4_UART2_DR0_MB_MASK (0x3 << 26)
+#define OMAP4_UART2_DR1_MB_SHIFT 24
+#define OMAP4_UART2_DR1_MB_MASK (0x3 << 24)
+#define OMAP4_UART4_DR0_MB_SHIFT 22
+#define OMAP4_UART4_DR0_MB_MASK (0x3 << 22)
+#define OMAP4_HSI_DR0_MB_SHIFT 20
+#define OMAP4_HSI_DR0_MB_MASK (0x3 << 20)
+
+/* CONTROL_SMART3IO_PADCONF_2 */
+#define OMAP4_DMIC_DR0_LB_SHIFT 31
+#define OMAP4_DMIC_DR0_LB_MASK (1 << 31)
+#define OMAP4_GPIO_DR3_LB_SHIFT 30
+#define OMAP4_GPIO_DR3_LB_MASK (1 << 30)
+#define OMAP4_GPIO_DR4_LB_SHIFT 29
+#define OMAP4_GPIO_DR4_LB_MASK (1 << 29)
+#define OMAP4_GPIO_DR5_LB_SHIFT 28
+#define OMAP4_GPIO_DR5_LB_MASK (1 << 28)
+#define OMAP4_GPIO_DR6_LB_SHIFT 27
+#define OMAP4_GPIO_DR6_LB_MASK (1 << 27)
+#define OMAP4_HSI_DR1_LB_SHIFT 26
+#define OMAP4_HSI_DR1_LB_MASK (1 << 26)
+#define OMAP4_HSI_DR2_LB_SHIFT 25
+#define OMAP4_HSI_DR2_LB_MASK (1 << 25)
+#define OMAP4_HSI_DR3_LB_SHIFT 24
+#define OMAP4_HSI_DR3_LB_MASK (1 << 24)
+#define OMAP4_MCBSP2_DR0_LB_SHIFT 23
+#define OMAP4_MCBSP2_DR0_LB_MASK (1 << 23)
+#define OMAP4_MCSPI4_DR0_LB_SHIFT 22
+#define OMAP4_MCSPI4_DR0_LB_MASK (1 << 22)
+#define OMAP4_MCSPI4_DR1_LB_SHIFT 21
+#define OMAP4_MCSPI4_DR1_LB_MASK (1 << 21)
+#define OMAP4_SLIMBUS2_DR0_LB_SHIFT 18
+#define OMAP4_SLIMBUS2_DR0_LB_MASK (1 << 18)
+#define OMAP4_SPI2_DR0_LB_SHIFT 16
+#define OMAP4_SPI2_DR0_LB_MASK (1 << 16)
+#define OMAP4_SPI2_DR1_LB_SHIFT 15
+#define OMAP4_SPI2_DR1_LB_MASK (1 << 15)
+#define OMAP4_SPI2_DR2_LB_SHIFT 14
+#define OMAP4_SPI2_DR2_LB_MASK (1 << 14)
+#define OMAP4_UART2_DR0_LB_SHIFT 13
+#define OMAP4_UART2_DR0_LB_MASK (1 << 13)
+#define OMAP4_UART2_DR1_LB_SHIFT 12
+#define OMAP4_UART2_DR1_LB_MASK (1 << 12)
+#define OMAP4_UART4_DR0_LB_SHIFT 11
+#define OMAP4_UART4_DR0_LB_MASK (1 << 11)
+#define OMAP4_HSI_DR0_LB_SHIFT 10
+#define OMAP4_HSI_DR0_LB_MASK (1 << 10)
+
+/* CONTROL_USBB_HSIC */
+#define OMAP4_USBB2_DR1_SR_SHIFT 30
+#define OMAP4_USBB2_DR1_SR_MASK (0x3 << 30)
+#define OMAP4_USBB2_DR1_I_SHIFT 27
+#define OMAP4_USBB2_DR1_I_MASK (0x7 << 27)
+#define OMAP4_USBB1_DR1_SR_SHIFT 25
+#define OMAP4_USBB1_DR1_SR_MASK (0x3 << 25)
+#define OMAP4_USBB1_DR1_I_SHIFT 22
+#define OMAP4_USBB1_DR1_I_MASK (0x7 << 22)
+#define OMAP4_USBB1_HSIC_DATA_WD_SHIFT 20
+#define OMAP4_USBB1_HSIC_DATA_WD_MASK (0x3 << 20)
+#define OMAP4_USBB1_HSIC_STROBE_WD_SHIFT 18
+#define OMAP4_USBB1_HSIC_STROBE_WD_MASK (0x3 << 18)
+#define OMAP4_USBB2_HSIC_DATA_WD_SHIFT 16
+#define OMAP4_USBB2_HSIC_DATA_WD_MASK (0x3 << 16)
+#define OMAP4_USBB2_HSIC_STROBE_WD_SHIFT 14
+#define OMAP4_USBB2_HSIC_STROBE_WD_MASK (0x3 << 14)
+#define OMAP4_USBB1_HSIC_DATA_OFFMODE_WD_ENABLE_SHIFT 13
+#define OMAP4_USBB1_HSIC_DATA_OFFMODE_WD_ENABLE_MASK (1 << 13)
+#define OMAP4_USBB1_HSIC_DATA_OFFMODE_WD_SHIFT 11
+#define OMAP4_USBB1_HSIC_DATA_OFFMODE_WD_MASK (0x3 << 11)
+#define OMAP4_USBB1_HSIC_STROBE_OFFMODE_WD_ENABLE_SHIFT 10
+#define OMAP4_USBB1_HSIC_STROBE_OFFMODE_WD_ENABLE_MASK (1 << 10)
+#define OMAP4_USBB1_HSIC_STROBE_OFFMODE_WD_SHIFT 8
+#define OMAP4_USBB1_HSIC_STROBE_OFFMODE_WD_MASK (0x3 << 8)
+#define OMAP4_USBB2_HSIC_DATA_OFFMODE_WD_ENABLE_SHIFT 7
+#define OMAP4_USBB2_HSIC_DATA_OFFMODE_WD_ENABLE_MASK (1 << 7)
+#define OMAP4_USBB2_HSIC_DATA_OFFMODE_WD_SHIFT 5
+#define OMAP4_USBB2_HSIC_DATA_OFFMODE_WD_MASK (0x3 << 5)
+#define OMAP4_USBB2_HSIC_STROBE_OFFMODE_WD_ENABLE_SHIFT 4
+#define OMAP4_USBB2_HSIC_STROBE_OFFMODE_WD_ENABLE_MASK (1 << 4)
+#define OMAP4_USBB2_HSIC_STROBE_OFFMODE_WD_SHIFT 2
+#define OMAP4_USBB2_HSIC_STROBE_OFFMODE_WD_MASK (0x3 << 2)
+
+/* CONTROL_SLIMBUS */
+#define OMAP4_SLIMBUS1_DR0_MB_SHIFT 30
+#define OMAP4_SLIMBUS1_DR0_MB_MASK (0x3 << 30)
+#define OMAP4_SLIMBUS1_DR1_MB_SHIFT 28
+#define OMAP4_SLIMBUS1_DR1_MB_MASK (0x3 << 28)
+#define OMAP4_SLIMBUS2_DR0_MB_SHIFT 26
+#define OMAP4_SLIMBUS2_DR0_MB_MASK (0x3 << 26)
+#define OMAP4_SLIMBUS2_DR1_MB_SHIFT 24
+#define OMAP4_SLIMBUS2_DR1_MB_MASK (0x3 << 24)
+#define OMAP4_SLIMBUS2_DR2_MB_SHIFT 22
+#define OMAP4_SLIMBUS2_DR2_MB_MASK (0x3 << 22)
+#define OMAP4_SLIMBUS2_DR3_MB_SHIFT 20
+#define OMAP4_SLIMBUS2_DR3_MB_MASK (0x3 << 20)
+#define OMAP4_SLIMBUS1_DR0_LB_SHIFT 19
+#define OMAP4_SLIMBUS1_DR0_LB_MASK (1 << 19)
+#define OMAP4_SLIMBUS2_DR1_LB_SHIFT 18
+#define OMAP4_SLIMBUS2_DR1_LB_MASK (1 << 18)
+
+/* CONTROL_PBIASLITE */
+#define OMAP4_USIM_PBIASLITE_HIZ_MODE_SHIFT 31
+#define OMAP4_USIM_PBIASLITE_HIZ_MODE_MASK (1 << 31)
+#define OMAP4_USIM_PBIASLITE_SUPPLY_HI_OUT_SHIFT 30
+#define OMAP4_USIM_PBIASLITE_SUPPLY_HI_OUT_MASK (1 << 30)
+#define OMAP4_USIM_PBIASLITE_VMODE_ERROR_SHIFT 29
+#define OMAP4_USIM_PBIASLITE_VMODE_ERROR_MASK (1 << 29)
+#define OMAP4_USIM_PBIASLITE_PWRDNZ_SHIFT 28
+#define OMAP4_USIM_PBIASLITE_PWRDNZ_MASK (1 << 28)
+#define OMAP4_USIM_PBIASLITE_VMODE_SHIFT 27
+#define OMAP4_USIM_PBIASLITE_VMODE_MASK (1 << 27)
+#define OMAP4_MMC1_PWRDNZ_SHIFT 26
+#define OMAP4_MMC1_PWRDNZ_MASK (1 << 26)
+#define OMAP4_MMC1_PBIASLITE_HIZ_MODE_SHIFT 25
+#define OMAP4_MMC1_PBIASLITE_HIZ_MODE_MASK (1 << 25)
+#define OMAP4_MMC1_PBIASLITE_SUPPLY_HI_OUT_SHIFT 24
+#define OMAP4_MMC1_PBIASLITE_SUPPLY_HI_OUT_MASK (1 << 24)
+#define OMAP4_MMC1_PBIASLITE_VMODE_ERROR_SHIFT 23
+#define OMAP4_MMC1_PBIASLITE_VMODE_ERROR_MASK (1 << 23)
+#define OMAP4_MMC1_PBIASLITE_PWRDNZ_SHIFT 22
+#define OMAP4_MMC1_PBIASLITE_PWRDNZ_MASK (1 << 22)
+#define OMAP4_MMC1_PBIASLITE_VMODE_SHIFT 21
+#define OMAP4_MMC1_PBIASLITE_VMODE_MASK (1 << 21)
+#define OMAP4_USBC1_ICUSB_PWRDNZ_SHIFT 20
+#define OMAP4_USBC1_ICUSB_PWRDNZ_MASK (1 << 20)
+
+/* CONTROL_I2C_0 */
+#define OMAP4_I2C4_SDA_GLFENB_SHIFT 31
+#define OMAP4_I2C4_SDA_GLFENB_MASK (1 << 31)
+#define OMAP4_I2C4_SDA_LOAD_BITS_SHIFT 29
+#define OMAP4_I2C4_SDA_LOAD_BITS_MASK (0x3 << 29)
+#define OMAP4_I2C4_SDA_PULLUPRESX_SHIFT 28
+#define OMAP4_I2C4_SDA_PULLUPRESX_MASK (1 << 28)
+#define OMAP4_I2C3_SDA_GLFENB_SHIFT 27
+#define OMAP4_I2C3_SDA_GLFENB_MASK (1 << 27)
+#define OMAP4_I2C3_SDA_LOAD_BITS_SHIFT 25
+#define OMAP4_I2C3_SDA_LOAD_BITS_MASK (0x3 << 25)
+#define OMAP4_I2C3_SDA_PULLUPRESX_SHIFT 24
+#define OMAP4_I2C3_SDA_PULLUPRESX_MASK (1 << 24)
+#define OMAP4_I2C2_SDA_GLFENB_SHIFT 23
+#define OMAP4_I2C2_SDA_GLFENB_MASK (1 << 23)
+#define OMAP4_I2C2_SDA_LOAD_BITS_SHIFT 21
+#define OMAP4_I2C2_SDA_LOAD_BITS_MASK (0x3 << 21)
+#define OMAP4_I2C2_SDA_PULLUPRESX_SHIFT 20
+#define OMAP4_I2C2_SDA_PULLUPRESX_MASK (1 << 20)
+#define OMAP4_I2C1_SDA_GLFENB_SHIFT 19
+#define OMAP4_I2C1_SDA_GLFENB_MASK (1 << 19)
+#define OMAP4_I2C1_SDA_LOAD_BITS_SHIFT 17
+#define OMAP4_I2C1_SDA_LOAD_BITS_MASK (0x3 << 17)
+#define OMAP4_I2C1_SDA_PULLUPRESX_SHIFT 16
+#define OMAP4_I2C1_SDA_PULLUPRESX_MASK (1 << 16)
+#define OMAP4_I2C4_SCL_GLFENB_SHIFT 15
+#define OMAP4_I2C4_SCL_GLFENB_MASK (1 << 15)
+#define OMAP4_I2C4_SCL_LOAD_BITS_SHIFT 13
+#define OMAP4_I2C4_SCL_LOAD_BITS_MASK (0x3 << 13)
+#define OMAP4_I2C4_SCL_PULLUPRESX_SHIFT 12
+#define OMAP4_I2C4_SCL_PULLUPRESX_MASK (1 << 12)
+#define OMAP4_I2C3_SCL_GLFENB_SHIFT 11
+#define OMAP4_I2C3_SCL_GLFENB_MASK (1 << 11)
+#define OMAP4_I2C3_SCL_LOAD_BITS_SHIFT 9
+#define OMAP4_I2C3_SCL_LOAD_BITS_MASK (0x3 << 9)
+#define OMAP4_I2C3_SCL_PULLUPRESX_SHIFT 8
+#define OMAP4_I2C3_SCL_PULLUPRESX_MASK (1 << 8)
+#define OMAP4_I2C2_SCL_GLFENB_SHIFT 7
+#define OMAP4_I2C2_SCL_GLFENB_MASK (1 << 7)
+#define OMAP4_I2C2_SCL_LOAD_BITS_SHIFT 5
+#define OMAP4_I2C2_SCL_LOAD_BITS_MASK (0x3 << 5)
+#define OMAP4_I2C2_SCL_PULLUPRESX_SHIFT 4
+#define OMAP4_I2C2_SCL_PULLUPRESX_MASK (1 << 4)
+#define OMAP4_I2C1_SCL_GLFENB_SHIFT 3
+#define OMAP4_I2C1_SCL_GLFENB_MASK (1 << 3)
+#define OMAP4_I2C1_SCL_LOAD_BITS_SHIFT 1
+#define OMAP4_I2C1_SCL_LOAD_BITS_MASK (0x3 << 1)
+#define OMAP4_I2C1_SCL_PULLUPRESX_SHIFT 0
+#define OMAP4_I2C1_SCL_PULLUPRESX_MASK (1 << 0)
+
+/* CONTROL_CAMERA_RX */
+#define OMAP4_CAMERARX_UNIPRO_CTRLCLKEN_SHIFT 31
+#define OMAP4_CAMERARX_UNIPRO_CTRLCLKEN_MASK (1 << 31)
+#define OMAP4_CAMERARX_CSI22_LANEENABLE_SHIFT 29
+#define OMAP4_CAMERARX_CSI22_LANEENABLE_MASK (0x3 << 29)
+#define OMAP4_CAMERARX_CSI21_LANEENABLE_SHIFT 24
+#define OMAP4_CAMERARX_CSI21_LANEENABLE_MASK (0x1f << 24)
+#define OMAP4_CAMERARX_UNIPRO_CAMMODE_SHIFT 22
+#define OMAP4_CAMERARX_UNIPRO_CAMMODE_MASK (0x3 << 22)
+#define OMAP4_CAMERARX_CSI22_CTRLCLKEN_SHIFT 21
+#define OMAP4_CAMERARX_CSI22_CTRLCLKEN_MASK (1 << 21)
+#define OMAP4_CAMERARX_CSI22_CAMMODE_SHIFT 19
+#define OMAP4_CAMERARX_CSI22_CAMMODE_MASK (0x3 << 19)
+#define OMAP4_CAMERARX_CSI21_CTRLCLKEN_SHIFT 18
+#define OMAP4_CAMERARX_CSI21_CTRLCLKEN_MASK (1 << 18)
+#define OMAP4_CAMERARX_CSI21_CAMMODE_SHIFT 16
+#define OMAP4_CAMERARX_CSI21_CAMMODE_MASK (0x3 << 16)
+
+/* CONTROL_AVDAC */
+#define OMAP4_AVDAC_ACEN_SHIFT 31
+#define OMAP4_AVDAC_ACEN_MASK (1 << 31)
+#define OMAP4_AVDAC_TVOUTBYPASS_SHIFT 30
+#define OMAP4_AVDAC_TVOUTBYPASS_MASK (1 << 30)
+#define OMAP4_AVDAC_INPUTINV_SHIFT 29
+#define OMAP4_AVDAC_INPUTINV_MASK (1 << 29)
+#define OMAP4_AVDAC_CTL_SHIFT 13
+#define OMAP4_AVDAC_CTL_MASK (0xffff << 13)
+#define OMAP4_AVDAC_CTL_WR_ACK_SHIFT 12
+#define OMAP4_AVDAC_CTL_WR_ACK_MASK (1 << 12)
+
+/* CONTROL_HDMI_TX_PHY */
+#define OMAP4_HDMITXPHY_PADORDER_SHIFT 31
+#define OMAP4_HDMITXPHY_PADORDER_MASK (1 << 31)
+#define OMAP4_HDMITXPHY_TXVALID_SHIFT 30
+#define OMAP4_HDMITXPHY_TXVALID_MASK (1 << 30)
+#define OMAP4_HDMITXPHY_ENBYPASSCLK_SHIFT 29
+#define OMAP4_HDMITXPHY_ENBYPASSCLK_MASK (1 << 29)
+#define OMAP4_HDMITXPHY_PD_PULLUPDET_SHIFT 28
+#define OMAP4_HDMITXPHY_PD_PULLUPDET_MASK (1 << 28)
+
+/* CONTROL_MMC2 */
+#define OMAP4_MMC2_FEEDBACK_CLK_SEL_SHIFT 31
+#define OMAP4_MMC2_FEEDBACK_CLK_SEL_MASK (1 << 31)
+
+/* CONTROL_DSIPHY */
+#define OMAP4_DSI2_LANEENABLE_SHIFT 29
+#define OMAP4_DSI2_LANEENABLE_MASK (0x7 << 29)
+#define OMAP4_DSI1_LANEENABLE_SHIFT 24
+#define OMAP4_DSI1_LANEENABLE_MASK (0x1f << 24)
+#define OMAP4_DSI1_PIPD_SHIFT 19
+#define OMAP4_DSI1_PIPD_MASK (0x1f << 19)
+#define OMAP4_DSI2_PIPD_SHIFT 14
+#define OMAP4_DSI2_PIPD_MASK (0x1f << 14)
+
+/* CONTROL_MCBSPLP */
+#define OMAP4_ALBCTRLRX_FSX_SHIFT 31
+#define OMAP4_ALBCTRLRX_FSX_MASK (1 << 31)
+#define OMAP4_ALBCTRLRX_CLKX_SHIFT 30
+#define OMAP4_ALBCTRLRX_CLKX_MASK (1 << 30)
+#define OMAP4_ABE_MCBSP1_DR_EN_SHIFT 29
+#define OMAP4_ABE_MCBSP1_DR_EN_MASK (1 << 29)
+
+/* CONTROL_USB2PHYCORE */
+#define OMAP4_USB2PHY_AUTORESUME_EN_SHIFT 31
+#define OMAP4_USB2PHY_AUTORESUME_EN_MASK (1 << 31)
+#define OMAP4_USB2PHY_DISCHGDET_SHIFT 30
+#define OMAP4_USB2PHY_DISCHGDET_MASK (1 << 30)
+#define OMAP4_USB2PHY_GPIOMODE_SHIFT 29
+#define OMAP4_USB2PHY_GPIOMODE_MASK (1 << 29)
+#define OMAP4_USB2PHY_CHG_DET_EXT_CTL_SHIFT 28
+#define OMAP4_USB2PHY_CHG_DET_EXT_CTL_MASK (1 << 28)
+#define OMAP4_USB2PHY_RDM_PD_CHGDET_EN_SHIFT 27
+#define OMAP4_USB2PHY_RDM_PD_CHGDET_EN_MASK (1 << 27)
+#define OMAP4_USB2PHY_RDP_PU_CHGDET_EN_SHIFT 26
+#define OMAP4_USB2PHY_RDP_PU_CHGDET_EN_MASK (1 << 26)
+#define OMAP4_USB2PHY_CHG_VSRC_EN_SHIFT 25
+#define OMAP4_USB2PHY_CHG_VSRC_EN_MASK (1 << 25)
+#define OMAP4_USB2PHY_CHG_ISINK_EN_SHIFT 24
+#define OMAP4_USB2PHY_CHG_ISINK_EN_MASK (1 << 24)
+#define OMAP4_USB2PHY_CHG_DET_STATUS_SHIFT 21
+#define OMAP4_USB2PHY_CHG_DET_STATUS_MASK (0x7 << 21)
+#define OMAP4_USB2PHY_CHG_DET_DM_COMP_SHIFT 20
+#define OMAP4_USB2PHY_CHG_DET_DM_COMP_MASK (1 << 20)
+#define OMAP4_USB2PHY_CHG_DET_DP_COMP_SHIFT 19
+#define OMAP4_USB2PHY_CHG_DET_DP_COMP_MASK (1 << 19)
+#define OMAP4_USB2PHY_DATADET_SHIFT 18
+#define OMAP4_USB2PHY_DATADET_MASK (1 << 18)
+#define OMAP4_USB2PHY_SINKONDP_SHIFT 17
+#define OMAP4_USB2PHY_SINKONDP_MASK (1 << 17)
+#define OMAP4_USB2PHY_SRCONDM_SHIFT 16
+#define OMAP4_USB2PHY_SRCONDM_MASK (1 << 16)
+#define OMAP4_USB2PHY_RESTARTCHGDET_SHIFT 15
+#define OMAP4_USB2PHY_RESTARTCHGDET_MASK (1 << 15)
+#define OMAP4_USB2PHY_CHGDETDONE_SHIFT 14
+#define OMAP4_USB2PHY_CHGDETDONE_MASK (1 << 14)
+#define OMAP4_USB2PHY_CHGDETECTED_SHIFT 13
+#define OMAP4_USB2PHY_CHGDETECTED_MASK (1 << 13)
+#define OMAP4_USB2PHY_MCPCPUEN_SHIFT 12
+#define OMAP4_USB2PHY_MCPCPUEN_MASK (1 << 12)
+#define OMAP4_USB2PHY_MCPCMODEEN_SHIFT 11
+#define OMAP4_USB2PHY_MCPCMODEEN_MASK (1 << 11)
+#define OMAP4_USB2PHY_RESETDONEMCLK_SHIFT 10
+#define OMAP4_USB2PHY_RESETDONEMCLK_MASK (1 << 10)
+#define OMAP4_USB2PHY_UTMIRESETDONE_SHIFT 9
+#define OMAP4_USB2PHY_UTMIRESETDONE_MASK (1 << 9)
+#define OMAP4_USB2PHY_TXBITSTUFFENABLE_SHIFT 8
+#define OMAP4_USB2PHY_TXBITSTUFFENABLE_MASK (1 << 8)
+#define OMAP4_USB2PHY_DATAPOLARITYN_SHIFT 7
+#define OMAP4_USB2PHY_DATAPOLARITYN_MASK (1 << 7)
+#define OMAP4_USBDPLL_FREQLOCK_SHIFT 6
+#define OMAP4_USBDPLL_FREQLOCK_MASK (1 << 6)
+#define OMAP4_USB2PHY_RESETDONETCLK_SHIFT 5
+#define OMAP4_USB2PHY_RESETDONETCLK_MASK (1 << 5)
+
+/* CONTROL_I2C_1 */
+#define OMAP4_HDMI_DDC_SDA_GLFENB_SHIFT 31
+#define OMAP4_HDMI_DDC_SDA_GLFENB_MASK (1 << 31)
+#define OMAP4_HDMI_DDC_SDA_LOAD_BITS_SHIFT 29
+#define OMAP4_HDMI_DDC_SDA_LOAD_BITS_MASK (0x3 << 29)
+#define OMAP4_HDMI_DDC_SDA_PULLUPRESX_SHIFT 28
+#define OMAP4_HDMI_DDC_SDA_PULLUPRESX_MASK (1 << 28)
+#define OMAP4_HDMI_DDC_SCL_GLFENB_SHIFT 27
+#define OMAP4_HDMI_DDC_SCL_GLFENB_MASK (1 << 27)
+#define OMAP4_HDMI_DDC_SCL_LOAD_BITS_SHIFT 25
+#define OMAP4_HDMI_DDC_SCL_LOAD_BITS_MASK (0x3 << 25)
+#define OMAP4_HDMI_DDC_SCL_PULLUPRESX_SHIFT 24
+#define OMAP4_HDMI_DDC_SCL_PULLUPRESX_MASK (1 << 24)
+#define OMAP4_HDMI_DDC_SDA_HSMODE_SHIFT 23
+#define OMAP4_HDMI_DDC_SDA_HSMODE_MASK (1 << 23)
+#define OMAP4_HDMI_DDC_SDA_NMODE_SHIFT 22
+#define OMAP4_HDMI_DDC_SDA_NMODE_MASK (1 << 22)
+#define OMAP4_HDMI_DDC_SCL_HSMODE_SHIFT 21
+#define OMAP4_HDMI_DDC_SCL_HSMODE_MASK (1 << 21)
+#define OMAP4_HDMI_DDC_SCL_NMODE_SHIFT 20
+#define OMAP4_HDMI_DDC_SCL_NMODE_MASK (1 << 20)
+
+/* CONTROL_MMC1 */
+#define OMAP4_SDMMC1_PUSTRENGTH_GRP0_SHIFT 31
+#define OMAP4_SDMMC1_PUSTRENGTH_GRP0_MASK (1 << 31)
+#define OMAP4_SDMMC1_PUSTRENGTH_GRP1_SHIFT 30
+#define OMAP4_SDMMC1_PUSTRENGTH_GRP1_MASK (1 << 30)
+#define OMAP4_SDMMC1_PUSTRENGTH_GRP2_SHIFT 29
+#define OMAP4_SDMMC1_PUSTRENGTH_GRP2_MASK (1 << 29)
+#define OMAP4_SDMMC1_PUSTRENGTH_GRP3_SHIFT 28
+#define OMAP4_SDMMC1_PUSTRENGTH_GRP3_MASK (1 << 28)
+#define OMAP4_SDMMC1_DR0_SPEEDCTRL_SHIFT 27
+#define OMAP4_SDMMC1_DR0_SPEEDCTRL_MASK (1 << 27)
+#define OMAP4_SDMMC1_DR1_SPEEDCTRL_SHIFT 26
+#define OMAP4_SDMMC1_DR1_SPEEDCTRL_MASK (1 << 26)
+#define OMAP4_SDMMC1_DR2_SPEEDCTRL_SHIFT 25
+#define OMAP4_SDMMC1_DR2_SPEEDCTRL_MASK (1 << 25)
+#define OMAP4_USBC1_DR0_SPEEDCTRL_SHIFT 24
+#define OMAP4_USBC1_DR0_SPEEDCTRL_MASK (1 << 24)
+#define OMAP4_USB_FD_CDEN_SHIFT 23
+#define OMAP4_USB_FD_CDEN_MASK (1 << 23)
+#define OMAP4_USBC1_ICUSB_DP_PDDIS_SHIFT 22
+#define OMAP4_USBC1_ICUSB_DP_PDDIS_MASK (1 << 22)
+#define OMAP4_USBC1_ICUSB_DM_PDDIS_SHIFT 21
+#define OMAP4_USBC1_ICUSB_DM_PDDIS_MASK (1 << 21)
+
+/* CONTROL_HSI */
+#define OMAP4_HSI1_CALLOOP_SEL_SHIFT 31
+#define OMAP4_HSI1_CALLOOP_SEL_MASK (1 << 31)
+#define OMAP4_HSI1_CALMUX_SEL_SHIFT 30
+#define OMAP4_HSI1_CALMUX_SEL_MASK (1 << 30)
+#define OMAP4_HSI2_CALLOOP_SEL_SHIFT 29
+#define OMAP4_HSI2_CALLOOP_SEL_MASK (1 << 29)
+#define OMAP4_HSI2_CALMUX_SEL_SHIFT 28
+#define OMAP4_HSI2_CALMUX_SEL_MASK (1 << 28)
+
+/* CONTROL_USB */
+#define OMAP4_CARKIT_USBA0_ULPIPHY_DAT0_AUTO_EN_SHIFT 31
+#define OMAP4_CARKIT_USBA0_ULPIPHY_DAT0_AUTO_EN_MASK (1 << 31)
+#define OMAP4_CARKIT_USBA0_ULPIPHY_DAT1_AUTO_EN_SHIFT 30
+#define OMAP4_CARKIT_USBA0_ULPIPHY_DAT1_AUTO_EN_MASK (1 << 30)
+
+/* CONTROL_HDQ */
+#define OMAP4_HDQ_SIO_PWRDNZ_SHIFT 31
+#define OMAP4_HDQ_SIO_PWRDNZ_MASK (1 << 31)
+
+/* CONTROL_LPDDR2IO1_0 */
+#define OMAP4_LPDDR2IO1_GR4_SR_SHIFT 30
+#define OMAP4_LPDDR2IO1_GR4_SR_MASK (0x3 << 30)
+#define OMAP4_LPDDR2IO1_GR4_I_SHIFT 27
+#define OMAP4_LPDDR2IO1_GR4_I_MASK (0x7 << 27)
+#define OMAP4_LPDDR2IO1_GR4_WD_SHIFT 25
+#define OMAP4_LPDDR2IO1_GR4_WD_MASK (0x3 << 25)
+#define OMAP4_LPDDR2IO1_GR3_SR_SHIFT 22
+#define OMAP4_LPDDR2IO1_GR3_SR_MASK (0x3 << 22)
+#define OMAP4_LPDDR2IO1_GR3_I_SHIFT 19
+#define OMAP4_LPDDR2IO1_GR3_I_MASK (0x7 << 19)
+#define OMAP4_LPDDR2IO1_GR3_WD_SHIFT 17
+#define OMAP4_LPDDR2IO1_GR3_WD_MASK (0x3 << 17)
+#define OMAP4_LPDDR2IO1_GR2_SR_SHIFT 14
+#define OMAP4_LPDDR2IO1_GR2_SR_MASK (0x3 << 14)
+#define OMAP4_LPDDR2IO1_GR2_I_SHIFT 11
+#define OMAP4_LPDDR2IO1_GR2_I_MASK (0x7 << 11)
+#define OMAP4_LPDDR2IO1_GR2_WD_SHIFT 9
+#define OMAP4_LPDDR2IO1_GR2_WD_MASK (0x3 << 9)
+#define OMAP4_LPDDR2IO1_GR1_SR_SHIFT 6
+#define OMAP4_LPDDR2IO1_GR1_SR_MASK (0x3 << 6)
+#define OMAP4_LPDDR2IO1_GR1_I_SHIFT 3
+#define OMAP4_LPDDR2IO1_GR1_I_MASK (0x7 << 3)
+#define OMAP4_LPDDR2IO1_GR1_WD_SHIFT 1
+#define OMAP4_LPDDR2IO1_GR1_WD_MASK (0x3 << 1)
+
+/* CONTROL_LPDDR2IO1_1 */
+#define OMAP4_LPDDR2IO1_GR8_SR_SHIFT 30
+#define OMAP4_LPDDR2IO1_GR8_SR_MASK (0x3 << 30)
+#define OMAP4_LPDDR2IO1_GR8_I_SHIFT 27
+#define OMAP4_LPDDR2IO1_GR8_I_MASK (0x7 << 27)
+#define OMAP4_LPDDR2IO1_GR8_WD_SHIFT 25
+#define OMAP4_LPDDR2IO1_GR8_WD_MASK (0x3 << 25)
+#define OMAP4_LPDDR2IO1_GR7_SR_SHIFT 22
+#define OMAP4_LPDDR2IO1_GR7_SR_MASK (0x3 << 22)
+#define OMAP4_LPDDR2IO1_GR7_I_SHIFT 19
+#define OMAP4_LPDDR2IO1_GR7_I_MASK (0x7 << 19)
+#define OMAP4_LPDDR2IO1_GR7_WD_SHIFT 17
+#define OMAP4_LPDDR2IO1_GR7_WD_MASK (0x3 << 17)
+#define OMAP4_LPDDR2IO1_GR6_SR_SHIFT 14
+#define OMAP4_LPDDR2IO1_GR6_SR_MASK (0x3 << 14)
+#define OMAP4_LPDDR2IO1_GR6_I_SHIFT 11
+#define OMAP4_LPDDR2IO1_GR6_I_MASK (0x7 << 11)
+#define OMAP4_LPDDR2IO1_GR6_WD_SHIFT 9
+#define OMAP4_LPDDR2IO1_GR6_WD_MASK (0x3 << 9)
+#define OMAP4_LPDDR2IO1_GR5_SR_SHIFT 6
+#define OMAP4_LPDDR2IO1_GR5_SR_MASK (0x3 << 6)
+#define OMAP4_LPDDR2IO1_GR5_I_SHIFT 3
+#define OMAP4_LPDDR2IO1_GR5_I_MASK (0x7 << 3)
+#define OMAP4_LPDDR2IO1_GR5_WD_SHIFT 1
+#define OMAP4_LPDDR2IO1_GR5_WD_MASK (0x3 << 1)
+
+/* CONTROL_LPDDR2IO1_2 */
+#define OMAP4_LPDDR2IO1_GR11_SR_SHIFT 30
+#define OMAP4_LPDDR2IO1_GR11_SR_MASK (0x3 << 30)
+#define OMAP4_LPDDR2IO1_GR11_I_SHIFT 27
+#define OMAP4_LPDDR2IO1_GR11_I_MASK (0x7 << 27)
+#define OMAP4_LPDDR2IO1_GR11_WD_SHIFT 25
+#define OMAP4_LPDDR2IO1_GR11_WD_MASK (0x3 << 25)
+#define OMAP4_LPDDR2IO1_GR10_SR_SHIFT 22
+#define OMAP4_LPDDR2IO1_GR10_SR_MASK (0x3 << 22)
+#define OMAP4_LPDDR2IO1_GR10_I_SHIFT 19
+#define OMAP4_LPDDR2IO1_GR10_I_MASK (0x7 << 19)
+#define OMAP4_LPDDR2IO1_GR10_WD_SHIFT 17
+#define OMAP4_LPDDR2IO1_GR10_WD_MASK (0x3 << 17)
+#define OMAP4_LPDDR2IO1_GR9_SR_SHIFT 14
+#define OMAP4_LPDDR2IO1_GR9_SR_MASK (0x3 << 14)
+#define OMAP4_LPDDR2IO1_GR9_I_SHIFT 11
+#define OMAP4_LPDDR2IO1_GR9_I_MASK (0x7 << 11)
+#define OMAP4_LPDDR2IO1_GR9_WD_SHIFT 9
+#define OMAP4_LPDDR2IO1_GR9_WD_MASK (0x3 << 9)
+
+/* CONTROL_LPDDR2IO1_3 */
+#define OMAP4_LPDDR21_VREF_CA_CCAP0_SHIFT 31
+#define OMAP4_LPDDR21_VREF_CA_CCAP0_MASK (1 << 31)
+#define OMAP4_LPDDR21_VREF_CA_CCAP1_SHIFT 30
+#define OMAP4_LPDDR21_VREF_CA_CCAP1_MASK (1 << 30)
+#define OMAP4_LPDDR21_VREF_CA_INT_CCAP0_SHIFT 29
+#define OMAP4_LPDDR21_VREF_CA_INT_CCAP0_MASK (1 << 29)
+#define OMAP4_LPDDR21_VREF_CA_INT_CCAP1_SHIFT 28
+#define OMAP4_LPDDR21_VREF_CA_INT_CCAP1_MASK (1 << 28)
+#define OMAP4_LPDDR21_VREF_CA_INT_TAP0_SHIFT 27
+#define OMAP4_LPDDR21_VREF_CA_INT_TAP0_MASK (1 << 27)
+#define OMAP4_LPDDR21_VREF_CA_INT_TAP1_SHIFT 26
+#define OMAP4_LPDDR21_VREF_CA_INT_TAP1_MASK (1 << 26)
+#define OMAP4_LPDDR21_VREF_CA_TAP0_SHIFT 25
+#define OMAP4_LPDDR21_VREF_CA_TAP0_MASK (1 << 25)
+#define OMAP4_LPDDR21_VREF_CA_TAP1_SHIFT 24
+#define OMAP4_LPDDR21_VREF_CA_TAP1_MASK (1 << 24)
+#define OMAP4_LPDDR21_VREF_DQ0_INT_CCAP0_SHIFT 23
+#define OMAP4_LPDDR21_VREF_DQ0_INT_CCAP0_MASK (1 << 23)
+#define OMAP4_LPDDR21_VREF_DQ0_INT_CCAP1_SHIFT 22
+#define OMAP4_LPDDR21_VREF_DQ0_INT_CCAP1_MASK (1 << 22)
+#define OMAP4_LPDDR21_VREF_DQ0_INT_TAP0_SHIFT 21
+#define OMAP4_LPDDR21_VREF_DQ0_INT_TAP0_MASK (1 << 21)
+#define OMAP4_LPDDR21_VREF_DQ0_INT_TAP1_SHIFT 20
+#define OMAP4_LPDDR21_VREF_DQ0_INT_TAP1_MASK (1 << 20)
+#define OMAP4_LPDDR21_VREF_DQ1_INT_CCAP0_SHIFT 19
+#define OMAP4_LPDDR21_VREF_DQ1_INT_CCAP0_MASK (1 << 19)
+#define OMAP4_LPDDR21_VREF_DQ1_INT_CCAP1_SHIFT 18
+#define OMAP4_LPDDR21_VREF_DQ1_INT_CCAP1_MASK (1 << 18)
+#define OMAP4_LPDDR21_VREF_DQ1_INT_TAP0_SHIFT 17
+#define OMAP4_LPDDR21_VREF_DQ1_INT_TAP0_MASK (1 << 17)
+#define OMAP4_LPDDR21_VREF_DQ1_INT_TAP1_SHIFT 16
+#define OMAP4_LPDDR21_VREF_DQ1_INT_TAP1_MASK (1 << 16)
+#define OMAP4_LPDDR21_VREF_DQ_CCAP0_SHIFT 15
+#define OMAP4_LPDDR21_VREF_DQ_CCAP0_MASK (1 << 15)
+#define OMAP4_LPDDR21_VREF_DQ_CCAP1_SHIFT 14
+#define OMAP4_LPDDR21_VREF_DQ_CCAP1_MASK (1 << 14)
+#define OMAP4_LPDDR21_VREF_DQ_TAP0_SHIFT 13
+#define OMAP4_LPDDR21_VREF_DQ_TAP0_MASK (1 << 13)
+#define OMAP4_LPDDR21_VREF_DQ_TAP1_SHIFT 12
+#define OMAP4_LPDDR21_VREF_DQ_TAP1_MASK (1 << 12)
+
+/* CONTROL_LPDDR2IO2_0 */
+#define OMAP4_LPDDR2IO2_GR4_SR_SHIFT 30
+#define OMAP4_LPDDR2IO2_GR4_SR_MASK (0x3 << 30)
+#define OMAP4_LPDDR2IO2_GR4_I_SHIFT 27
+#define OMAP4_LPDDR2IO2_GR4_I_MASK (0x7 << 27)
+#define OMAP4_LPDDR2IO2_GR4_WD_SHIFT 25
+#define OMAP4_LPDDR2IO2_GR4_WD_MASK (0x3 << 25)
+#define OMAP4_LPDDR2IO2_GR3_SR_SHIFT 22
+#define OMAP4_LPDDR2IO2_GR3_SR_MASK (0x3 << 22)
+#define OMAP4_LPDDR2IO2_GR3_I_SHIFT 19
+#define OMAP4_LPDDR2IO2_GR3_I_MASK (0x7 << 19)
+#define OMAP4_LPDDR2IO2_GR3_WD_SHIFT 17
+#define OMAP4_LPDDR2IO2_GR3_WD_MASK (0x3 << 17)
+#define OMAP4_LPDDR2IO2_GR2_SR_SHIFT 14
+#define OMAP4_LPDDR2IO2_GR2_SR_MASK (0x3 << 14)
+#define OMAP4_LPDDR2IO2_GR2_I_SHIFT 11
+#define OMAP4_LPDDR2IO2_GR2_I_MASK (0x7 << 11)
+#define OMAP4_LPDDR2IO2_GR2_WD_SHIFT 9
+#define OMAP4_LPDDR2IO2_GR2_WD_MASK (0x3 << 9)
+#define OMAP4_LPDDR2IO2_GR1_SR_SHIFT 6
+#define OMAP4_LPDDR2IO2_GR1_SR_MASK (0x3 << 6)
+#define OMAP4_LPDDR2IO2_GR1_I_SHIFT 3
+#define OMAP4_LPDDR2IO2_GR1_I_MASK (0x7 << 3)
+#define OMAP4_LPDDR2IO2_GR1_WD_SHIFT 1
+#define OMAP4_LPDDR2IO2_GR1_WD_MASK (0x3 << 1)
+
+/* CONTROL_LPDDR2IO2_1 */
+#define OMAP4_LPDDR2IO2_GR8_SR_SHIFT 30
+#define OMAP4_LPDDR2IO2_GR8_SR_MASK (0x3 << 30)
+#define OMAP4_LPDDR2IO2_GR8_I_SHIFT 27
+#define OMAP4_LPDDR2IO2_GR8_I_MASK (0x7 << 27)
+#define OMAP4_LPDDR2IO2_GR8_WD_SHIFT 25
+#define OMAP4_LPDDR2IO2_GR8_WD_MASK (0x3 << 25)
+#define OMAP4_LPDDR2IO2_GR7_SR_SHIFT 22
+#define OMAP4_LPDDR2IO2_GR7_SR_MASK (0x3 << 22)
+#define OMAP4_LPDDR2IO2_GR7_I_SHIFT 19
+#define OMAP4_LPDDR2IO2_GR7_I_MASK (0x7 << 19)
+#define OMAP4_LPDDR2IO2_GR7_WD_SHIFT 17
+#define OMAP4_LPDDR2IO2_GR7_WD_MASK (0x3 << 17)
+#define OMAP4_LPDDR2IO2_GR6_SR_SHIFT 14
+#define OMAP4_LPDDR2IO2_GR6_SR_MASK (0x3 << 14)
+#define OMAP4_LPDDR2IO2_GR6_I_SHIFT 11
+#define OMAP4_LPDDR2IO2_GR6_I_MASK (0x7 << 11)
+#define OMAP4_LPDDR2IO2_GR6_WD_SHIFT 9
+#define OMAP4_LPDDR2IO2_GR6_WD_MASK (0x3 << 9)
+#define OMAP4_LPDDR2IO2_GR5_SR_SHIFT 6
+#define OMAP4_LPDDR2IO2_GR5_SR_MASK (0x3 << 6)
+#define OMAP4_LPDDR2IO2_GR5_I_SHIFT 3
+#define OMAP4_LPDDR2IO2_GR5_I_MASK (0x7 << 3)
+#define OMAP4_LPDDR2IO2_GR5_WD_SHIFT 1
+#define OMAP4_LPDDR2IO2_GR5_WD_MASK (0x3 << 1)
+
+/* CONTROL_LPDDR2IO2_2 */
+#define OMAP4_LPDDR2IO2_GR11_SR_SHIFT 30
+#define OMAP4_LPDDR2IO2_GR11_SR_MASK (0x3 << 30)
+#define OMAP4_LPDDR2IO2_GR11_I_SHIFT 27
+#define OMAP4_LPDDR2IO2_GR11_I_MASK (0x7 << 27)
+#define OMAP4_LPDDR2IO2_GR11_WD_SHIFT 25
+#define OMAP4_LPDDR2IO2_GR11_WD_MASK (0x3 << 25)
+#define OMAP4_LPDDR2IO2_GR10_SR_SHIFT 22
+#define OMAP4_LPDDR2IO2_GR10_SR_MASK (0x3 << 22)
+#define OMAP4_LPDDR2IO2_GR10_I_SHIFT 19
+#define OMAP4_LPDDR2IO2_GR10_I_MASK (0x7 << 19)
+#define OMAP4_LPDDR2IO2_GR10_WD_SHIFT 17
+#define OMAP4_LPDDR2IO2_GR10_WD_MASK (0x3 << 17)
+#define OMAP4_LPDDR2IO2_GR9_SR_SHIFT 14
+#define OMAP4_LPDDR2IO2_GR9_SR_MASK (0x3 << 14)
+#define OMAP4_LPDDR2IO2_GR9_I_SHIFT 11
+#define OMAP4_LPDDR2IO2_GR9_I_MASK (0x7 << 11)
+#define OMAP4_LPDDR2IO2_GR9_WD_SHIFT 9
+#define OMAP4_LPDDR2IO2_GR9_WD_MASK (0x3 << 9)
+
+/* CONTROL_LPDDR2IO2_3 */
+#define OMAP4_LPDDR22_VREF_CA_CCAP0_SHIFT 31
+#define OMAP4_LPDDR22_VREF_CA_CCAP0_MASK (1 << 31)
+#define OMAP4_LPDDR22_VREF_CA_CCAP1_SHIFT 30
+#define OMAP4_LPDDR22_VREF_CA_CCAP1_MASK (1 << 30)
+#define OMAP4_LPDDR22_VREF_CA_INT_CCAP0_SHIFT 29
+#define OMAP4_LPDDR22_VREF_CA_INT_CCAP0_MASK (1 << 29)
+#define OMAP4_LPDDR22_VREF_CA_INT_CCAP1_SHIFT 28
+#define OMAP4_LPDDR22_VREF_CA_INT_CCAP1_MASK (1 << 28)
+#define OMAP4_LPDDR22_VREF_CA_INT_TAP0_SHIFT 27
+#define OMAP4_LPDDR22_VREF_CA_INT_TAP0_MASK (1 << 27)
+#define OMAP4_LPDDR22_VREF_CA_INT_TAP1_SHIFT 26
+#define OMAP4_LPDDR22_VREF_CA_INT_TAP1_MASK (1 << 26)
+#define OMAP4_LPDDR22_VREF_CA_TAP0_SHIFT 25
+#define OMAP4_LPDDR22_VREF_CA_TAP0_MASK (1 << 25)
+#define OMAP4_LPDDR22_VREF_CA_TAP1_SHIFT 24
+#define OMAP4_LPDDR22_VREF_CA_TAP1_MASK (1 << 24)
+#define OMAP4_LPDDR22_VREF_DQ0_INT_CCAP0_SHIFT 23
+#define OMAP4_LPDDR22_VREF_DQ0_INT_CCAP0_MASK (1 << 23)
+#define OMAP4_LPDDR22_VREF_DQ0_INT_CCAP1_SHIFT 22
+#define OMAP4_LPDDR22_VREF_DQ0_INT_CCAP1_MASK (1 << 22)
+#define OMAP4_LPDDR22_VREF_DQ0_INT_TAP0_SHIFT 21
+#define OMAP4_LPDDR22_VREF_DQ0_INT_TAP0_MASK (1 << 21)
+#define OMAP4_LPDDR22_VREF_DQ0_INT_TAP1_SHIFT 20
+#define OMAP4_LPDDR22_VREF_DQ0_INT_TAP1_MASK (1 << 20)
+#define OMAP4_LPDDR22_VREF_DQ1_INT_CCAP0_SHIFT 19
+#define OMAP4_LPDDR22_VREF_DQ1_INT_CCAP0_MASK (1 << 19)
+#define OMAP4_LPDDR22_VREF_DQ1_INT_CCAP1_SHIFT 18
+#define OMAP4_LPDDR22_VREF_DQ1_INT_CCAP1_MASK (1 << 18)
+#define OMAP4_LPDDR22_VREF_DQ1_INT_TAP0_SHIFT 17
+#define OMAP4_LPDDR22_VREF_DQ1_INT_TAP0_MASK (1 << 17)
+#define OMAP4_LPDDR22_VREF_DQ1_INT_TAP1_SHIFT 16
+#define OMAP4_LPDDR22_VREF_DQ1_INT_TAP1_MASK (1 << 16)
+#define OMAP4_LPDDR22_VREF_DQ_CCAP0_SHIFT 15
+#define OMAP4_LPDDR22_VREF_DQ_CCAP0_MASK (1 << 15)
+#define OMAP4_LPDDR22_VREF_DQ_CCAP1_SHIFT 14
+#define OMAP4_LPDDR22_VREF_DQ_CCAP1_MASK (1 << 14)
+#define OMAP4_LPDDR22_VREF_DQ_TAP0_SHIFT 13
+#define OMAP4_LPDDR22_VREF_DQ_TAP0_MASK (1 << 13)
+#define OMAP4_LPDDR22_VREF_DQ_TAP1_SHIFT 12
+#define OMAP4_LPDDR22_VREF_DQ_TAP1_MASK (1 << 12)
+
+/* CONTROL_BUS_HOLD */
+#define OMAP4_ABE_DMIC_DIN3_EN_SHIFT 31
+#define OMAP4_ABE_DMIC_DIN3_EN_MASK (1 << 31)
+#define OMAP4_MCSPI1_CS3_EN_SHIFT 30
+#define OMAP4_MCSPI1_CS3_EN_MASK (1 << 30)
+
+/* CONTROL_C2C */
+#define OMAP4_MIRROR_MODE_EN_SHIFT 31
+#define OMAP4_MIRROR_MODE_EN_MASK (1 << 31)
+#define OMAP4_C2C_SPARE_SHIFT 24
+#define OMAP4_C2C_SPARE_MASK (0x7f << 24)
+
+/* CORE_CONTROL_SPARE_RW */
+#define OMAP4_CORE_CONTROL_SPARE_RW_SHIFT 0
+#define OMAP4_CORE_CONTROL_SPARE_RW_MASK (0xffffffff << 0)
+
+/* CORE_CONTROL_SPARE_R */
+#define OMAP4_CORE_CONTROL_SPARE_R_SHIFT 0
+#define OMAP4_CORE_CONTROL_SPARE_R_MASK (0xffffffff << 0)
+
+/* CORE_CONTROL_SPARE_R_C0 */
+#define OMAP4_CORE_CONTROL_SPARE_R_C0_SHIFT 31
+#define OMAP4_CORE_CONTROL_SPARE_R_C0_MASK (1 << 31)
+#define OMAP4_CORE_CONTROL_SPARE_R_C1_SHIFT 30
+#define OMAP4_CORE_CONTROL_SPARE_R_C1_MASK (1 << 30)
+#define OMAP4_CORE_CONTROL_SPARE_R_C2_SHIFT 29
+#define OMAP4_CORE_CONTROL_SPARE_R_C2_MASK (1 << 29)
+#define OMAP4_CORE_CONTROL_SPARE_R_C3_SHIFT 28
+#define OMAP4_CORE_CONTROL_SPARE_R_C3_MASK (1 << 28)
+#define OMAP4_CORE_CONTROL_SPARE_R_C4_SHIFT 27
+#define OMAP4_CORE_CONTROL_SPARE_R_C4_MASK (1 << 27)
+#define OMAP4_CORE_CONTROL_SPARE_R_C5_SHIFT 26
+#define OMAP4_CORE_CONTROL_SPARE_R_C5_MASK (1 << 26)
+#define OMAP4_CORE_CONTROL_SPARE_R_C6_SHIFT 25
+#define OMAP4_CORE_CONTROL_SPARE_R_C6_MASK (1 << 25)
+#define OMAP4_CORE_CONTROL_SPARE_R_C7_SHIFT 24
+#define OMAP4_CORE_CONTROL_SPARE_R_C7_MASK (1 << 24)
+
+/* CONTROL_EFUSE_1 */
+#define OMAP4_AVDAC_TRIM_BYTE3_SHIFT 24
+#define OMAP4_AVDAC_TRIM_BYTE3_MASK (0x7f << 24)
+#define OMAP4_AVDAC_TRIM_BYTE2_SHIFT 16
+#define OMAP4_AVDAC_TRIM_BYTE2_MASK (0xff << 16)
+#define OMAP4_AVDAC_TRIM_BYTE1_SHIFT 8
+#define OMAP4_AVDAC_TRIM_BYTE1_MASK (0xff << 8)
+#define OMAP4_AVDAC_TRIM_BYTE0_SHIFT 0
+#define OMAP4_AVDAC_TRIM_BYTE0_MASK (0xff << 0)
+
+/* CONTROL_EFUSE_2 */
+#define OMAP4_EFUSE_SMART2TEST_P0_SHIFT 31
+#define OMAP4_EFUSE_SMART2TEST_P0_MASK (1 << 31)
+#define OMAP4_EFUSE_SMART2TEST_P1_SHIFT 30
+#define OMAP4_EFUSE_SMART2TEST_P1_MASK (1 << 30)
+#define OMAP4_EFUSE_SMART2TEST_P2_SHIFT 29
+#define OMAP4_EFUSE_SMART2TEST_P2_MASK (1 << 29)
+#define OMAP4_EFUSE_SMART2TEST_P3_SHIFT 28
+#define OMAP4_EFUSE_SMART2TEST_P3_MASK (1 << 28)
+#define OMAP4_EFUSE_SMART2TEST_N0_SHIFT 27
+#define OMAP4_EFUSE_SMART2TEST_N0_MASK (1 << 27)
+#define OMAP4_EFUSE_SMART2TEST_N1_SHIFT 26
+#define OMAP4_EFUSE_SMART2TEST_N1_MASK (1 << 26)
+#define OMAP4_EFUSE_SMART2TEST_N2_SHIFT 25
+#define OMAP4_EFUSE_SMART2TEST_N2_MASK (1 << 25)
+#define OMAP4_EFUSE_SMART2TEST_N3_SHIFT 24
+#define OMAP4_EFUSE_SMART2TEST_N3_MASK (1 << 24)
+#define OMAP4_LPDDR2_PTV_N1_SHIFT 23
+#define OMAP4_LPDDR2_PTV_N1_MASK (1 << 23)
+#define OMAP4_LPDDR2_PTV_N2_SHIFT 22
+#define OMAP4_LPDDR2_PTV_N2_MASK (1 << 22)
+#define OMAP4_LPDDR2_PTV_N3_SHIFT 21
+#define OMAP4_LPDDR2_PTV_N3_MASK (1 << 21)
+#define OMAP4_LPDDR2_PTV_N4_SHIFT 20
+#define OMAP4_LPDDR2_PTV_N4_MASK (1 << 20)
+#define OMAP4_LPDDR2_PTV_N5_SHIFT 19
+#define OMAP4_LPDDR2_PTV_N5_MASK (1 << 19)
+#define OMAP4_LPDDR2_PTV_P1_SHIFT 18
+#define OMAP4_LPDDR2_PTV_P1_MASK (1 << 18)
+#define OMAP4_LPDDR2_PTV_P2_SHIFT 17
+#define OMAP4_LPDDR2_PTV_P2_MASK (1 << 17)
+#define OMAP4_LPDDR2_PTV_P3_SHIFT 16
+#define OMAP4_LPDDR2_PTV_P3_MASK (1 << 16)
+#define OMAP4_LPDDR2_PTV_P4_SHIFT 15
+#define OMAP4_LPDDR2_PTV_P4_MASK (1 << 15)
+#define OMAP4_LPDDR2_PTV_P5_SHIFT 14
+#define OMAP4_LPDDR2_PTV_P5_MASK (1 << 14)
+
+/* CONTROL_EFUSE_3 */
+#define OMAP4_STD_FUSE_SPARE_1_SHIFT 24
+#define OMAP4_STD_FUSE_SPARE_1_MASK (0xff << 24)
+#define OMAP4_STD_FUSE_SPARE_2_SHIFT 16
+#define OMAP4_STD_FUSE_SPARE_2_MASK (0xff << 16)
+#define OMAP4_STD_FUSE_SPARE_3_SHIFT 8
+#define OMAP4_STD_FUSE_SPARE_3_MASK (0xff << 8)
+#define OMAP4_STD_FUSE_SPARE_4_SHIFT 0
+#define OMAP4_STD_FUSE_SPARE_4_MASK (0xff << 0)
+
+/* CONTROL_EFUSE_4 */
+#define OMAP4_STD_FUSE_SPARE_5_SHIFT 24
+#define OMAP4_STD_FUSE_SPARE_5_MASK (0xff << 24)
+#define OMAP4_STD_FUSE_SPARE_6_SHIFT 16
+#define OMAP4_STD_FUSE_SPARE_6_MASK (0xff << 16)
+#define OMAP4_STD_FUSE_SPARE_7_SHIFT 8
+#define OMAP4_STD_FUSE_SPARE_7_MASK (0xff << 8)
+#define OMAP4_STD_FUSE_SPARE_8_SHIFT 0
+#define OMAP4_STD_FUSE_SPARE_8_MASK (0xff << 0)
+
+#endif
diff --git a/arch/arm/mach-omap2/include/mach/ctrl_module_pad_wkup_44xx.h b/arch/arm/mach-omap2/include/mach/ctrl_module_pad_wkup_44xx.h
new file mode 100644
index 000000000000..17c9b37042c0
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/ctrl_module_pad_wkup_44xx.h
@@ -0,0 +1,236 @@
+/*
+ * OMAP44xx CTRL_MODULE_PAD_WKUP registers and bitfields
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ *
+ * Benoit Cousson (b-cousson@ti.com)
+ * Santosh Shilimkar (santosh.shilimkar@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * 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 __ARCH_ARM_MACH_OMAP2_CTRL_MODULE_PAD_WKUP_44XX_H
+#define __ARCH_ARM_MACH_OMAP2_CTRL_MODULE_PAD_WKUP_44XX_H
+
+
+/* Base address */
+#define OMAP4_CTRL_MODULE_PAD_WKUP 0x4a31e000
+
+/* Registers offset */
+#define OMAP4_CTRL_MODULE_PAD_WKUP_IP_REVISION 0x0000
+#define OMAP4_CTRL_MODULE_PAD_WKUP_IP_HWINFO 0x0004
+#define OMAP4_CTRL_MODULE_PAD_WKUP_IP_SYSCONFIG 0x0010
+#define OMAP4_CTRL_MODULE_PAD_WKUP_PADCONF_WAKEUPEVENT_0 0x007c
+#define OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_SMART1NOPMIO_PADCONF_0 0x05a0
+#define OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_SMART1NOPMIO_PADCONF_1 0x05a4
+#define OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_PADCONF_MODE 0x05a8
+#define OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_XTAL_OSCILLATOR 0x05ac
+#define OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_USIMIO 0x0600
+#define OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_I2C_2 0x0604
+#define OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_JTAG 0x0608
+#define OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_SYS 0x060c
+#define OMAP4_CTRL_MODULE_PAD_WKUP_WKUP_CONTROL_SPARE_RW 0x0614
+#define OMAP4_CTRL_MODULE_PAD_WKUP_WKUP_CONTROL_SPARE_R 0x0618
+#define OMAP4_CTRL_MODULE_PAD_WKUP_WKUP_CONTROL_SPARE_R_C0 0x061c
+
+/* Registers shifts and masks */
+
+/* IP_REVISION */
+#define OMAP4_IP_REV_SCHEME_SHIFT 30
+#define OMAP4_IP_REV_SCHEME_MASK (0x3 << 30)
+#define OMAP4_IP_REV_FUNC_SHIFT 16
+#define OMAP4_IP_REV_FUNC_MASK (0xfff << 16)
+#define OMAP4_IP_REV_RTL_SHIFT 11
+#define OMAP4_IP_REV_RTL_MASK (0x1f << 11)
+#define OMAP4_IP_REV_MAJOR_SHIFT 8
+#define OMAP4_IP_REV_MAJOR_MASK (0x7 << 8)
+#define OMAP4_IP_REV_CUSTOM_SHIFT 6
+#define OMAP4_IP_REV_CUSTOM_MASK (0x3 << 6)
+#define OMAP4_IP_REV_MINOR_SHIFT 0
+#define OMAP4_IP_REV_MINOR_MASK (0x3f << 0)
+
+/* IP_HWINFO */
+#define OMAP4_IP_HWINFO_SHIFT 0
+#define OMAP4_IP_HWINFO_MASK (0xffffffff << 0)
+
+/* IP_SYSCONFIG */
+#define OMAP4_IP_SYSCONFIG_IDLEMODE_SHIFT 2
+#define OMAP4_IP_SYSCONFIG_IDLEMODE_MASK (0x3 << 2)
+
+/* PADCONF_WAKEUPEVENT_0 */
+#define OMAP4_JTAG_TDO_DUPLICATEWAKEUPEVENT_SHIFT 24
+#define OMAP4_JTAG_TDO_DUPLICATEWAKEUPEVENT_MASK (1 << 24)
+#define OMAP4_JTAG_TDI_DUPLICATEWAKEUPEVENT_SHIFT 23
+#define OMAP4_JTAG_TDI_DUPLICATEWAKEUPEVENT_MASK (1 << 23)
+#define OMAP4_JTAG_TMS_TMSC_DUPLICATEWAKEUPEVENT_SHIFT 22
+#define OMAP4_JTAG_TMS_TMSC_DUPLICATEWAKEUPEVENT_MASK (1 << 22)
+#define OMAP4_JTAG_RTCK_DUPLICATEWAKEUPEVENT_SHIFT 21
+#define OMAP4_JTAG_RTCK_DUPLICATEWAKEUPEVENT_MASK (1 << 21)
+#define OMAP4_JTAG_TCK_DUPLICATEWAKEUPEVENT_SHIFT 20
+#define OMAP4_JTAG_TCK_DUPLICATEWAKEUPEVENT_MASK (1 << 20)
+#define OMAP4_JTAG_NTRST_DUPLICATEWAKEUPEVENT_SHIFT 19
+#define OMAP4_JTAG_NTRST_DUPLICATEWAKEUPEVENT_MASK (1 << 19)
+#define OMAP4_SYS_BOOT7_DUPLICATEWAKEUPEVENT_SHIFT 18
+#define OMAP4_SYS_BOOT7_DUPLICATEWAKEUPEVENT_MASK (1 << 18)
+#define OMAP4_SYS_BOOT6_DUPLICATEWAKEUPEVENT_SHIFT 17
+#define OMAP4_SYS_BOOT6_DUPLICATEWAKEUPEVENT_MASK (1 << 17)
+#define OMAP4_SYS_PWRON_RESET_OUT_DUPLICATEWAKEUPEVENT_SHIFT 16
+#define OMAP4_SYS_PWRON_RESET_OUT_DUPLICATEWAKEUPEVENT_MASK (1 << 16)
+#define OMAP4_SYS_PWR_REQ_DUPLICATEWAKEUPEVENT_SHIFT 15
+#define OMAP4_SYS_PWR_REQ_DUPLICATEWAKEUPEVENT_MASK (1 << 15)
+#define OMAP4_SYS_NRESWARM_DUPLICATEWAKEUPEVENT_SHIFT 14
+#define OMAP4_SYS_NRESWARM_DUPLICATEWAKEUPEVENT_MASK (1 << 14)
+#define OMAP4_SYS_32K_DUPLICATEWAKEUPEVENT_SHIFT 13
+#define OMAP4_SYS_32K_DUPLICATEWAKEUPEVENT_MASK (1 << 13)
+#define OMAP4_FREF_CLK4_OUT_DUPLICATEWAKEUPEVENT_SHIFT 12
+#define OMAP4_FREF_CLK4_OUT_DUPLICATEWAKEUPEVENT_MASK (1 << 12)
+#define OMAP4_FREF_CLK4_REQ_DUPLICATEWAKEUPEVENT_SHIFT 11
+#define OMAP4_FREF_CLK4_REQ_DUPLICATEWAKEUPEVENT_MASK (1 << 11)
+#define OMAP4_FREF_CLK3_OUT_DUPLICATEWAKEUPEVENT_SHIFT 10
+#define OMAP4_FREF_CLK3_OUT_DUPLICATEWAKEUPEVENT_MASK (1 << 10)
+#define OMAP4_FREF_CLK3_REQ_DUPLICATEWAKEUPEVENT_SHIFT 9
+#define OMAP4_FREF_CLK3_REQ_DUPLICATEWAKEUPEVENT_MASK (1 << 9)
+#define OMAP4_FREF_CLK0_OUT_DUPLICATEWAKEUPEVENT_SHIFT 8
+#define OMAP4_FREF_CLK0_OUT_DUPLICATEWAKEUPEVENT_MASK (1 << 8)
+#define OMAP4_FREF_CLK_IOREQ_DUPLICATEWAKEUPEVENT_SHIFT 7
+#define OMAP4_FREF_CLK_IOREQ_DUPLICATEWAKEUPEVENT_MASK (1 << 7)
+#define OMAP4_SR_SDA_DUPLICATEWAKEUPEVENT_SHIFT 6
+#define OMAP4_SR_SDA_DUPLICATEWAKEUPEVENT_MASK (1 << 6)
+#define OMAP4_SR_SCL_DUPLICATEWAKEUPEVENT_SHIFT 5
+#define OMAP4_SR_SCL_DUPLICATEWAKEUPEVENT_MASK (1 << 5)
+#define OMAP4_SIM_PWRCTRL_DUPLICATEWAKEUPEVENT_SHIFT 4
+#define OMAP4_SIM_PWRCTRL_DUPLICATEWAKEUPEVENT_MASK (1 << 4)
+#define OMAP4_SIM_CD_DUPLICATEWAKEUPEVENT_SHIFT 3
+#define OMAP4_SIM_CD_DUPLICATEWAKEUPEVENT_MASK (1 << 3)
+#define OMAP4_SIM_RESET_DUPLICATEWAKEUPEVENT_SHIFT 2
+#define OMAP4_SIM_RESET_DUPLICATEWAKEUPEVENT_MASK (1 << 2)
+#define OMAP4_SIM_CLK_DUPLICATEWAKEUPEVENT_SHIFT 1
+#define OMAP4_SIM_CLK_DUPLICATEWAKEUPEVENT_MASK (1 << 1)
+#define OMAP4_SIM_IO_DUPLICATEWAKEUPEVENT_SHIFT 0
+#define OMAP4_SIM_IO_DUPLICATEWAKEUPEVENT_MASK (1 << 0)
+
+/* CONTROL_SMART1NOPMIO_PADCONF_0 */
+#define OMAP4_FREF_DR0_SC_SHIFT 30
+#define OMAP4_FREF_DR0_SC_MASK (0x3 << 30)
+#define OMAP4_FREF_DR1_SC_SHIFT 28
+#define OMAP4_FREF_DR1_SC_MASK (0x3 << 28)
+#define OMAP4_FREF_DR4_SC_SHIFT 26
+#define OMAP4_FREF_DR4_SC_MASK (0x3 << 26)
+#define OMAP4_FREF_DR5_SC_SHIFT 24
+#define OMAP4_FREF_DR5_SC_MASK (0x3 << 24)
+#define OMAP4_FREF_DR6_SC_SHIFT 22
+#define OMAP4_FREF_DR6_SC_MASK (0x3 << 22)
+#define OMAP4_FREF_DR7_SC_SHIFT 20
+#define OMAP4_FREF_DR7_SC_MASK (0x3 << 20)
+#define OMAP4_GPIO_DR7_SC_SHIFT 18
+#define OMAP4_GPIO_DR7_SC_MASK (0x3 << 18)
+#define OMAP4_DPM_DR0_SC_SHIFT 14
+#define OMAP4_DPM_DR0_SC_MASK (0x3 << 14)
+#define OMAP4_SIM_DR0_SC_SHIFT 12
+#define OMAP4_SIM_DR0_SC_MASK (0x3 << 12)
+
+/* CONTROL_SMART1NOPMIO_PADCONF_1 */
+#define OMAP4_FREF_DR0_LB_SHIFT 30
+#define OMAP4_FREF_DR0_LB_MASK (0x3 << 30)
+#define OMAP4_FREF_DR1_LB_SHIFT 28
+#define OMAP4_FREF_DR1_LB_MASK (0x3 << 28)
+#define OMAP4_FREF_DR4_LB_SHIFT 26
+#define OMAP4_FREF_DR4_LB_MASK (0x3 << 26)
+#define OMAP4_FREF_DR5_LB_SHIFT 24
+#define OMAP4_FREF_DR5_LB_MASK (0x3 << 24)
+#define OMAP4_FREF_DR6_LB_SHIFT 22
+#define OMAP4_FREF_DR6_LB_MASK (0x3 << 22)
+#define OMAP4_FREF_DR7_LB_SHIFT 20
+#define OMAP4_FREF_DR7_LB_MASK (0x3 << 20)
+#define OMAP4_GPIO_DR7_LB_SHIFT 18
+#define OMAP4_GPIO_DR7_LB_MASK (0x3 << 18)
+#define OMAP4_DPM_DR0_LB_SHIFT 14
+#define OMAP4_DPM_DR0_LB_MASK (0x3 << 14)
+#define OMAP4_SIM_DR0_LB_SHIFT 12
+#define OMAP4_SIM_DR0_LB_MASK (0x3 << 12)
+
+/* CONTROL_PADCONF_MODE */
+#define OMAP4_VDDS_DV_FREF_SHIFT 31
+#define OMAP4_VDDS_DV_FREF_MASK (1 << 31)
+#define OMAP4_VDDS_DV_BANK2_SHIFT 30
+#define OMAP4_VDDS_DV_BANK2_MASK (1 << 30)
+
+/* CONTROL_XTAL_OSCILLATOR */
+#define OMAP4_OSCILLATOR_BOOST_SHIFT 31
+#define OMAP4_OSCILLATOR_BOOST_MASK (1 << 31)
+#define OMAP4_OSCILLATOR_OS_OUT_SHIFT 30
+#define OMAP4_OSCILLATOR_OS_OUT_MASK (1 << 30)
+
+/* CONTROL_USIMIO */
+#define OMAP4_PAD_USIM_CLK_LOW_SHIFT 31
+#define OMAP4_PAD_USIM_CLK_LOW_MASK (1 << 31)
+#define OMAP4_PAD_USIM_RST_LOW_SHIFT 29
+#define OMAP4_PAD_USIM_RST_LOW_MASK (1 << 29)
+#define OMAP4_USIM_PWRDNZ_SHIFT 28
+#define OMAP4_USIM_PWRDNZ_MASK (1 << 28)
+
+/* CONTROL_I2C_2 */
+#define OMAP4_SR_SDA_GLFENB_SHIFT 31
+#define OMAP4_SR_SDA_GLFENB_MASK (1 << 31)
+#define OMAP4_SR_SDA_LOAD_BITS_SHIFT 29
+#define OMAP4_SR_SDA_LOAD_BITS_MASK (0x3 << 29)
+#define OMAP4_SR_SDA_PULLUPRESX_SHIFT 28
+#define OMAP4_SR_SDA_PULLUPRESX_MASK (1 << 28)
+#define OMAP4_SR_SCL_GLFENB_SHIFT 27
+#define OMAP4_SR_SCL_GLFENB_MASK (1 << 27)
+#define OMAP4_SR_SCL_LOAD_BITS_SHIFT 25
+#define OMAP4_SR_SCL_LOAD_BITS_MASK (0x3 << 25)
+#define OMAP4_SR_SCL_PULLUPRESX_SHIFT 24
+#define OMAP4_SR_SCL_PULLUPRESX_MASK (1 << 24)
+
+/* CONTROL_JTAG */
+#define OMAP4_JTAG_NTRST_EN_SHIFT 31
+#define OMAP4_JTAG_NTRST_EN_MASK (1 << 31)
+#define OMAP4_JTAG_TCK_EN_SHIFT 30
+#define OMAP4_JTAG_TCK_EN_MASK (1 << 30)
+#define OMAP4_JTAG_RTCK_EN_SHIFT 29
+#define OMAP4_JTAG_RTCK_EN_MASK (1 << 29)
+#define OMAP4_JTAG_TDI_EN_SHIFT 28
+#define OMAP4_JTAG_TDI_EN_MASK (1 << 28)
+#define OMAP4_JTAG_TDO_EN_SHIFT 27
+#define OMAP4_JTAG_TDO_EN_MASK (1 << 27)
+
+/* CONTROL_SYS */
+#define OMAP4_SYS_NRESWARM_PIPU_SHIFT 31
+#define OMAP4_SYS_NRESWARM_PIPU_MASK (1 << 31)
+
+/* WKUP_CONTROL_SPARE_RW */
+#define OMAP4_WKUP_CONTROL_SPARE_RW_SHIFT 0
+#define OMAP4_WKUP_CONTROL_SPARE_RW_MASK (0xffffffff << 0)
+
+/* WKUP_CONTROL_SPARE_R */
+#define OMAP4_WKUP_CONTROL_SPARE_R_SHIFT 0
+#define OMAP4_WKUP_CONTROL_SPARE_R_MASK (0xffffffff << 0)
+
+/* WKUP_CONTROL_SPARE_R_C0 */
+#define OMAP4_WKUP_CONTROL_SPARE_R_C0_SHIFT 31
+#define OMAP4_WKUP_CONTROL_SPARE_R_C0_MASK (1 << 31)
+#define OMAP4_WKUP_CONTROL_SPARE_R_C1_SHIFT 30
+#define OMAP4_WKUP_CONTROL_SPARE_R_C1_MASK (1 << 30)
+#define OMAP4_WKUP_CONTROL_SPARE_R_C2_SHIFT 29
+#define OMAP4_WKUP_CONTROL_SPARE_R_C2_MASK (1 << 29)
+#define OMAP4_WKUP_CONTROL_SPARE_R_C3_SHIFT 28
+#define OMAP4_WKUP_CONTROL_SPARE_R_C3_MASK (1 << 28)
+#define OMAP4_WKUP_CONTROL_SPARE_R_C4_SHIFT 27
+#define OMAP4_WKUP_CONTROL_SPARE_R_C4_MASK (1 << 27)
+#define OMAP4_WKUP_CONTROL_SPARE_R_C5_SHIFT 26
+#define OMAP4_WKUP_CONTROL_SPARE_R_C5_MASK (1 << 26)
+#define OMAP4_WKUP_CONTROL_SPARE_R_C6_SHIFT 25
+#define OMAP4_WKUP_CONTROL_SPARE_R_C6_MASK (1 << 25)
+#define OMAP4_WKUP_CONTROL_SPARE_R_C7_SHIFT 24
+#define OMAP4_WKUP_CONTROL_SPARE_R_C7_MASK (1 << 24)
+
+#endif
diff --git a/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h b/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
new file mode 100644
index 000000000000..a0af9baec3f7
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
@@ -0,0 +1,92 @@
+/*
+ * OMAP44xx CTRL_MODULE_WKUP registers and bitfields
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ *
+ * Benoit Cousson (b-cousson@ti.com)
+ * Santosh Shilimkar (santosh.shilimkar@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * 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 __ARCH_ARM_MACH_OMAP2_CTRL_MODULE_WKUP_44XX_H
+#define __ARCH_ARM_MACH_OMAP2_CTRL_MODULE_WKUP_44XX_H
+
+
+/* Base address */
+#define OMAP4_CTRL_MODULE_WKUP 0x4a30c000
+
+/* Registers offset */
+#define OMAP4_CTRL_MODULE_WKUP_IP_REVISION 0x0000
+#define OMAP4_CTRL_MODULE_WKUP_IP_HWINFO 0x0004
+#define OMAP4_CTRL_MODULE_WKUP_IP_SYSCONFIG 0x0010
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_0 0x0460
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_1 0x0464
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_2 0x0468
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_3 0x046c
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_4 0x0470
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_5 0x0474
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_6 0x0478
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_7 0x047c
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_8 0x0480
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_9 0x0484
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_10 0x0488
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_11 0x048c
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_12 0x0490
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_13 0x0494
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_14 0x0498
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_15 0x049c
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_16 0x04a0
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_17 0x04a4
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_18 0x04a8
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_19 0x04ac
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_20 0x04b0
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_21 0x04b4
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_22 0x04b8
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_23 0x04bc
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_24 0x04c0
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_25 0x04c4
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_26 0x04c8
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_27 0x04cc
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_28 0x04d0
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_29 0x04d4
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_30 0x04d8
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_31 0x04dc
+
+/* Registers shifts and masks */
+
+/* IP_REVISION */
+#define OMAP4_IP_REV_SCHEME_SHIFT 30
+#define OMAP4_IP_REV_SCHEME_MASK (0x3 << 30)
+#define OMAP4_IP_REV_FUNC_SHIFT 16
+#define OMAP4_IP_REV_FUNC_MASK (0xfff << 16)
+#define OMAP4_IP_REV_RTL_SHIFT 11
+#define OMAP4_IP_REV_RTL_MASK (0x1f << 11)
+#define OMAP4_IP_REV_MAJOR_SHIFT 8
+#define OMAP4_IP_REV_MAJOR_MASK (0x7 << 8)
+#define OMAP4_IP_REV_CUSTOM_SHIFT 6
+#define OMAP4_IP_REV_CUSTOM_MASK (0x3 << 6)
+#define OMAP4_IP_REV_MINOR_SHIFT 0
+#define OMAP4_IP_REV_MINOR_MASK (0x3f << 0)
+
+/* IP_HWINFO */
+#define OMAP4_IP_HWINFO_SHIFT 0
+#define OMAP4_IP_HWINFO_MASK (0xffffffff << 0)
+
+/* IP_SYSCONFIG */
+#define OMAP4_IP_SYSCONFIG_IDLEMODE_SHIFT 2
+#define OMAP4_IP_SYSCONFIG_IDLEMODE_MASK (0x3 << 2)
+
+/* CONF_DEBUG_SEL_TST_0 */
+#define OMAP4_WKUP_MODE_SHIFT 0
+#define OMAP4_WKUP_MODE_MASK (1 << 0)
+
+#endif
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/io.c b/arch/arm/mach-omap2/io.c
index b9ea70bce563..40562ddd3ee4 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -36,6 +36,7 @@
#include "clock2xxx.h"
#include "clock3xxx.h"
#include "clock44xx.h"
+#include "io.h"
#include <plat/omap-pm.h>
#include <plat/powerdomain.h>
@@ -323,6 +324,9 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
omap2430_hwmod_init();
else if (cpu_is_omap34xx())
omap3xxx_hwmod_init();
+ else if (cpu_is_omap44xx())
+ omap44xx_hwmod_init();
+
/* The OPP tables have to be registered before a clk init */
omap_pm_if_early_init(mpu_opps, dsp_opps, l3_opps);
@@ -342,9 +346,7 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
#ifndef CONFIG_PM_RUNTIME
skip_setup_idle = 1;
#endif
- if (cpu_is_omap24xx() || cpu_is_omap34xx()) /* FIXME: OMAP4 */
- omap_hwmod_late_init(skip_setup_idle);
-
+ omap_hwmod_late_init(skip_setup_idle);
if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
omap2_sdrc_init(sdrc_cs0, sdrc_cs1);
_omap2_init_reprogram_sdrc();
diff --git a/arch/arm/mach-omap2/io.h b/arch/arm/mach-omap2/io.h
new file mode 100644
index 000000000000..fd230c6cded5
--- /dev/null
+++ b/arch/arm/mach-omap2/io.h
@@ -0,0 +1,7 @@
+
+#ifndef __MACH_OMAP2_IO_H__
+#define __MACH_OMAP2_IO_H__
+
+extern int __init omap_sram_init(void);
+
+#endif /* __MACH_OMAP2_IO_H__ */
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
index 26aeef560aa3..32eeabe9d2ab 100644
--- a/arch/arm/mach-omap2/irq.c
+++ b/arch/arm/mach-omap2/irq.c
@@ -47,7 +47,6 @@ static struct omap_irq_bank {
} __attribute__ ((aligned(4))) irq_banks[] = {
{
/* MPU INTC */
- .base_reg = 0,
.nr_irqs = 96,
},
};
diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c
index 42dbfa46e656..40ddecab93a9 100644
--- a/arch/arm/mach-omap2/mailbox.c
+++ b/arch/arm/mach-omap2/mailbox.c
@@ -181,7 +181,7 @@ static int omap2_mbox_fifo_full(struct omap_mbox *mbox)
static void omap2_mbox_enable_irq(struct omap_mbox *mbox,
omap_mbox_type_t irq)
{
- struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv;
+ struct omap_mbox2_priv *p = mbox->priv;
u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
l = mbox_read_reg(p->irqenable);
@@ -192,7 +192,7 @@ static void omap2_mbox_enable_irq(struct omap_mbox *mbox,
static void omap2_mbox_disable_irq(struct omap_mbox *mbox,
omap_mbox_type_t irq)
{
- struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv;
+ struct omap_mbox2_priv *p = mbox->priv;
u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
l = mbox_read_reg(p->irqdisable);
l &= ~bit;
@@ -202,7 +202,7 @@ static void omap2_mbox_disable_irq(struct omap_mbox *mbox,
static void omap2_mbox_ack_irq(struct omap_mbox *mbox,
omap_mbox_type_t irq)
{
- struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv;
+ struct omap_mbox2_priv *p = mbox->priv;
u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
mbox_write_reg(bit, p->irqstatus);
@@ -214,7 +214,7 @@ static void omap2_mbox_ack_irq(struct omap_mbox *mbox,
static int omap2_mbox_is_irq(struct omap_mbox *mbox,
omap_mbox_type_t irq)
{
- struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv;
+ struct omap_mbox2_priv *p = mbox->priv;
u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
u32 enable = mbox_read_reg(p->irqenable);
u32 status = mbox_read_reg(p->irqstatus);
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c
index 467aae245781..f9c9df5b5ff1 100644
--- a/arch/arm/mach-omap2/mcbsp.c
+++ b/arch/arm/mach-omap2/mcbsp.c
@@ -23,29 +23,86 @@
#include <plat/cpu.h>
#include <plat/mcbsp.h>
-#include "mux.h"
+#include "control.h"
-static void omap2_mcbsp2_mux_setup(void)
+
+/* McBSP internal signal muxing functions */
+
+void omap2_mcbsp1_mux_clkr_src(u8 mux)
{
- omap_mux_init_signal("eac_ac_sclk.mcbsp2_clkx", OMAP_PULL_ENA);
- omap_mux_init_signal("eac_ac_fs.mcbsp2_fsx", OMAP_PULL_ENA);
- omap_mux_init_signal("eac_ac_din.mcbsp2_dr", OMAP_PULL_ENA);
- omap_mux_init_signal("eac_ac_dout.mcbsp2_dx", OMAP_PULL_ENA);
- omap_mux_init_gpio(117, OMAP_PULL_ENA);
- /*
- * TODO: Need to add MUX settings for OMAP 2430 SDP
- */
+ u32 v;
+
+ v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
+ if (mux == CLKR_SRC_CLKR)
+ v &= ~OMAP2_MCBSP1_CLKR_MASK;
+ else if (mux == CLKR_SRC_CLKX)
+ v |= OMAP2_MCBSP1_CLKR_MASK;
+ omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
}
+EXPORT_SYMBOL(omap2_mcbsp1_mux_clkr_src);
-static void omap2_mcbsp_request(unsigned int id)
+void omap2_mcbsp1_mux_fsr_src(u8 mux)
{
- if (cpu_is_omap2420() && (id == OMAP_MCBSP2))
- omap2_mcbsp2_mux_setup();
+ u32 v;
+
+ v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
+ if (mux == FSR_SRC_FSR)
+ v &= ~OMAP2_MCBSP1_FSR_MASK;
+ else if (mux == FSR_SRC_FSX)
+ v |= OMAP2_MCBSP1_FSR_MASK;
+ omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
}
+EXPORT_SYMBOL(omap2_mcbsp1_mux_fsr_src);
-static struct omap_mcbsp_ops omap2_mcbsp_ops = {
- .request = omap2_mcbsp_request,
-};
+/* McBSP CLKS source switching function */
+
+int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id)
+{
+ struct omap_mcbsp *mcbsp;
+ struct clk *fck_src;
+ char *fck_src_name;
+ int r;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ pr_err("%s: Invalid id (%d)\n", __func__, id + 1);
+ return -EINVAL;
+ }
+ mcbsp = id_to_mcbsp_ptr(id);
+
+ if (fck_src_id == MCBSP_CLKS_PAD_SRC)
+ fck_src_name = "pad_fck";
+ else if (fck_src_id == MCBSP_CLKS_PRCM_SRC)
+ fck_src_name = "prcm_fck";
+ else
+ return -EINVAL;
+
+ fck_src = clk_get(mcbsp->dev, fck_src_name);
+ if (IS_ERR_OR_NULL(fck_src)) {
+ pr_err("omap-mcbsp: %s: could not clk_get() %s\n", "clks",
+ fck_src_name);
+ return -EINVAL;
+ }
+
+ clk_disable(mcbsp->fclk);
+
+ r = clk_set_parent(mcbsp->fclk, fck_src);
+ if (IS_ERR_VALUE(r)) {
+ pr_err("omap-mcbsp: %s: could not clk_set_parent() to %s\n",
+ "clks", fck_src_name);
+ clk_put(fck_src);
+ return -EINVAL;
+ }
+
+ clk_enable(mcbsp->fclk);
+
+ clk_put(fck_src);
+
+ return 0;
+}
+EXPORT_SYMBOL(omap2_mcbsp_set_clks_src);
+
+
+/* Platform data */
#ifdef CONFIG_ARCH_OMAP2420
static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = {
@@ -55,7 +112,6 @@ static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = {
.dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX,
.rx_irq = INT_24XX_MCBSP1_IRQ_RX,
.tx_irq = INT_24XX_MCBSP1_IRQ_TX,
- .ops = &omap2_mcbsp_ops,
},
{
.phys_base = OMAP24XX_MCBSP2_BASE,
@@ -63,7 +119,6 @@ static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = {
.dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX,
.rx_irq = INT_24XX_MCBSP2_IRQ_RX,
.tx_irq = INT_24XX_MCBSP2_IRQ_TX,
- .ops = &omap2_mcbsp_ops,
},
};
#define OMAP2420_MCBSP_PDATA_SZ ARRAY_SIZE(omap2420_mcbsp_pdata)
@@ -82,7 +137,6 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
.dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX,
.rx_irq = INT_24XX_MCBSP1_IRQ_RX,
.tx_irq = INT_24XX_MCBSP1_IRQ_TX,
- .ops = &omap2_mcbsp_ops,
},
{
.phys_base = OMAP24XX_MCBSP2_BASE,
@@ -90,7 +144,6 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
.dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX,
.rx_irq = INT_24XX_MCBSP2_IRQ_RX,
.tx_irq = INT_24XX_MCBSP2_IRQ_TX,
- .ops = &omap2_mcbsp_ops,
},
{
.phys_base = OMAP2430_MCBSP3_BASE,
@@ -98,7 +151,6 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
.dma_tx_sync = OMAP24XX_DMA_MCBSP3_TX,
.rx_irq = INT_24XX_MCBSP3_IRQ_RX,
.tx_irq = INT_24XX_MCBSP3_IRQ_TX,
- .ops = &omap2_mcbsp_ops,
},
{
.phys_base = OMAP2430_MCBSP4_BASE,
@@ -106,7 +158,6 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
.dma_tx_sync = OMAP24XX_DMA_MCBSP4_TX,
.rx_irq = INT_24XX_MCBSP4_IRQ_RX,
.tx_irq = INT_24XX_MCBSP4_IRQ_TX,
- .ops = &omap2_mcbsp_ops,
},
{
.phys_base = OMAP2430_MCBSP5_BASE,
@@ -114,7 +165,6 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
.dma_tx_sync = OMAP24XX_DMA_MCBSP5_TX,
.rx_irq = INT_24XX_MCBSP5_IRQ_RX,
.tx_irq = INT_24XX_MCBSP5_IRQ_TX,
- .ops = &omap2_mcbsp_ops,
},
};
#define OMAP2430_MCBSP_PDATA_SZ ARRAY_SIZE(omap2430_mcbsp_pdata)
@@ -133,7 +183,6 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX,
.rx_irq = INT_24XX_MCBSP1_IRQ_RX,
.tx_irq = INT_24XX_MCBSP1_IRQ_TX,
- .ops = &omap2_mcbsp_ops,
.buffer_size = 0x80, /* The FIFO has 128 locations */
},
{
@@ -143,7 +192,6 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX,
.rx_irq = INT_24XX_MCBSP2_IRQ_RX,
.tx_irq = INT_24XX_MCBSP2_IRQ_TX,
- .ops = &omap2_mcbsp_ops,
.buffer_size = 0x500, /* The FIFO has 1024 + 256 locations */
},
{
@@ -153,7 +201,6 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.dma_tx_sync = OMAP24XX_DMA_MCBSP3_TX,
.rx_irq = INT_24XX_MCBSP3_IRQ_RX,
.tx_irq = INT_24XX_MCBSP3_IRQ_TX,
- .ops = &omap2_mcbsp_ops,
.buffer_size = 0x80, /* The FIFO has 128 locations */
},
{
@@ -162,7 +209,6 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.dma_tx_sync = OMAP24XX_DMA_MCBSP4_TX,
.rx_irq = INT_24XX_MCBSP4_IRQ_RX,
.tx_irq = INT_24XX_MCBSP4_IRQ_TX,
- .ops = &omap2_mcbsp_ops,
.buffer_size = 0x80, /* The FIFO has 128 locations */
},
{
@@ -171,7 +217,6 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.dma_tx_sync = OMAP24XX_DMA_MCBSP5_TX,
.rx_irq = INT_24XX_MCBSP5_IRQ_RX,
.tx_irq = INT_24XX_MCBSP5_IRQ_TX,
- .ops = &omap2_mcbsp_ops,
.buffer_size = 0x80, /* The FIFO has 128 locations */
},
};
@@ -189,28 +234,24 @@ static struct omap_mcbsp_platform_data omap44xx_mcbsp_pdata[] = {
.dma_rx_sync = OMAP44XX_DMA_MCBSP1_RX,
.dma_tx_sync = OMAP44XX_DMA_MCBSP1_TX,
.tx_irq = OMAP44XX_IRQ_MCBSP1,
- .ops = &omap2_mcbsp_ops,
},
{
.phys_base = OMAP44XX_MCBSP2_BASE,
.dma_rx_sync = OMAP44XX_DMA_MCBSP2_RX,
.dma_tx_sync = OMAP44XX_DMA_MCBSP2_TX,
.tx_irq = OMAP44XX_IRQ_MCBSP2,
- .ops = &omap2_mcbsp_ops,
},
{
.phys_base = OMAP44XX_MCBSP3_BASE,
.dma_rx_sync = OMAP44XX_DMA_MCBSP3_RX,
.dma_tx_sync = OMAP44XX_DMA_MCBSP3_TX,
.tx_irq = OMAP44XX_IRQ_MCBSP3,
- .ops = &omap2_mcbsp_ops,
},
{
.phys_base = OMAP44XX_MCBSP4_BASE,
.dma_rx_sync = OMAP44XX_DMA_MCBSP4_RX,
.dma_tx_sync = OMAP44XX_DMA_MCBSP4_TX,
.tx_irq = OMAP44XX_IRQ_MCBSP4,
- .ops = &omap2_mcbsp_ops,
},
};
#define OMAP44XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap44xx_mcbsp_pdata)
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index ab403b2ed26b..074536ae401f 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -23,12 +23,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
-#include <linux/module.h>
+#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <linux/ctype.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
@@ -36,8 +35,7 @@
#include <asm/system.h>
-#include <plat/control.h>
-
+#include "control.h"
#include "mux.h"
#define OMAP_MUX_BASE_OFFSET 0x30 /* Offset from CTRL_BASE */
@@ -87,7 +85,7 @@ static char *omap_mux_options;
int __init omap_mux_init_gpio(int gpio, int val)
{
struct omap_mux_entry *e;
- struct omap_mux *gpio_mux;
+ struct omap_mux *gpio_mux = NULL;
u16 old_mode;
u16 mux_mode;
int found = 0;
@@ -127,17 +125,16 @@ int __init omap_mux_init_gpio(int gpio, int val)
return 0;
}
-int __init omap_mux_init_signal(char *muxname, int val)
+int __init omap_mux_init_signal(const char *muxname, int val)
{
struct omap_mux_entry *e;
- char *m0_name = NULL, *mode_name = NULL;
- int found = 0;
+ const char *mode_name;
+ int found = 0, mode0_len = 0;
mode_name = strchr(muxname, '.');
if (mode_name) {
- *mode_name = '\0';
+ mode0_len = strlen(muxname) - strlen(mode_name);
mode_name++;
- m0_name = muxname;
} else {
mode_name = muxname;
}
@@ -147,9 +144,11 @@ int __init omap_mux_init_signal(char *muxname, int val)
char *m0_entry = m->muxnames[0];
int i;
- if (m0_name && strcmp(m0_name, m0_entry))
+ /* First check for full name in mode0.muxmode format */
+ if (mode0_len && strncmp(muxname, m0_entry, mode0_len))
continue;
+ /* Then check for muxmode only */
for (i = 0; i < OMAP_MUX_NR_MODES; i++) {
char *mode_cur = m->muxnames[i];
diff --git a/arch/arm/mach-omap2/mux.h b/arch/arm/mach-omap2/mux.h
index a8e040c2c7e9..350c04f27383 100644
--- a/arch/arm/mach-omap2/mux.h
+++ b/arch/arm/mach-omap2/mux.h
@@ -120,7 +120,7 @@ int omap_mux_init_gpio(int gpio, int val);
* @muxname: Mux name in mode0_name.signal_name format
* @val: Options for the mux register value
*/
-int omap_mux_init_signal(char *muxname, int val);
+int omap_mux_init_signal(const char *muxname, int val);
#else
diff --git a/arch/arm/mach-omap2/mux2420.c b/arch/arm/mach-omap2/mux2420.c
index fdb04a7eb8aa..414af5434456 100644
--- a/arch/arm/mach-omap2/mux2420.c
+++ b/arch/arm/mach-omap2/mux2420.c
@@ -507,7 +507,7 @@ static struct omap_mux __initdata omap2420_muxmodes[] = {
* Balls for 447-pin POP package
*/
#ifdef CONFIG_DEBUG_FS
-struct omap_ball __initdata omap2420_pop_ball[] = {
+static struct omap_ball __initdata omap2420_pop_ball[] = {
_OMAP2420_BALLENTRY(CAM_D0, "y4", NULL),
_OMAP2420_BALLENTRY(CAM_D1, "y3", NULL),
_OMAP2420_BALLENTRY(CAM_D2, "u7", NULL),
diff --git a/arch/arm/mach-omap2/mux2430.c b/arch/arm/mach-omap2/mux2430.c
index 7dcaaa8af32a..84d2c5a7ecd7 100644
--- a/arch/arm/mach-omap2/mux2430.c
+++ b/arch/arm/mach-omap2/mux2430.c
@@ -586,7 +586,7 @@ static struct omap_mux __initdata omap2430_muxmodes[] = {
* 447-pin s-PBGA Package, 0.00mm Ball Pitch (Bottom)
*/
#ifdef CONFIG_DEBUG_FS
-struct omap_ball __initdata omap2430_pop_ball[] = {
+static struct omap_ball __initdata omap2430_pop_ball[] = {
_OMAP2430_BALLENTRY(CAM_D0, "t8", NULL),
_OMAP2430_BALLENTRY(CAM_D1, "t4", NULL),
_OMAP2430_BALLENTRY(CAM_D10, "r4", NULL),
diff --git a/arch/arm/mach-omap2/mux34xx.c b/arch/arm/mach-omap2/mux34xx.c
index f64d7eea3451..574e54ea3ab7 100644
--- a/arch/arm/mach-omap2/mux34xx.c
+++ b/arch/arm/mach-omap2/mux34xx.c
@@ -931,7 +931,7 @@ struct omap_ball __initdata omap3_cbc_ball[] = {
* Signals different on CUS package compared to superset
*/
#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_OMAP_PACKAGE_CUS)
-struct omap_mux __initdata omap3_cus_subset[] = {
+static struct omap_mux __initdata omap3_cus_subset[] = {
_OMAP3_MUXENTRY(CAM_D10, 109,
"cam_d10", NULL, NULL, NULL,
"gpio_109", NULL, NULL, "safe_mode"),
@@ -1077,7 +1077,7 @@ struct omap_mux __initdata omap3_cus_subset[] = {
*/
#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) \
&& defined(CONFIG_OMAP_PACKAGE_CUS)
-struct omap_ball __initdata omap3_cus_ball[] = {
+static struct omap_ball __initdata omap3_cus_ball[] = {
_OMAP3_BALLENTRY(CAM_D0, "ab18", NULL),
_OMAP3_BALLENTRY(CAM_D1, "ac18", NULL),
_OMAP3_BALLENTRY(CAM_D10, "f21", NULL),
@@ -1269,7 +1269,7 @@ struct omap_ball __initdata omap3_cus_ball[] = {
* Signals different on CBB package comapared to superset
*/
#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_OMAP_PACKAGE_CBB)
-struct omap_mux __initdata omap3_cbb_subset[] = {
+static struct omap_mux __initdata omap3_cbb_subset[] = {
_OMAP3_MUXENTRY(CAM_D10, 109,
"cam_d10", NULL, NULL, NULL,
"gpio_109", NULL, NULL, "safe_mode"),
@@ -1390,7 +1390,7 @@ struct omap_mux __initdata omap3_cbb_subset[] = {
*/
#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) \
&& defined(CONFIG_OMAP_PACKAGE_CBB)
-struct omap_ball __initdata omap3_cbb_ball[] = {
+static struct omap_ball __initdata omap3_cbb_ball[] = {
_OMAP3_BALLENTRY(CAM_D0, "ag17", NULL),
_OMAP3_BALLENTRY(CAM_D1, "ah17", NULL),
_OMAP3_BALLENTRY(CAM_D10, "b25", NULL),
@@ -1600,7 +1600,7 @@ struct omap_ball __initdata omap3_cbb_ball[] = {
* Signals different on 36XX CBP package comapared to 34XX CBC package
*/
#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_OMAP_PACKAGE_CBP)
-struct omap_mux __initdata omap36xx_cbp_subset[] = {
+static struct omap_mux __initdata omap36xx_cbp_subset[] = {
_OMAP3_MUXENTRY(CAM_D0, 99,
"cam_d0", NULL, "csi2_dx2", NULL,
"gpio_99", NULL, NULL, "safe_mode"),
@@ -1818,7 +1818,7 @@ struct omap_mux __initdata omap36xx_cbp_subset[] = {
*/
#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) \
&& defined (CONFIG_OMAP_PACKAGE_CBP)
-struct omap_ball __initdata omap36xx_cbp_ball[] = {
+static struct omap_ball __initdata omap36xx_cbp_ball[] = {
_OMAP3_BALLENTRY(CAM_D0, "ag17", NULL),
_OMAP3_BALLENTRY(CAM_D1, "ah17", NULL),
_OMAP3_BALLENTRY(CAM_D10, "b25", NULL),
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c
index 13dc9794dcc2..2f895553e6a8 100644
--- a/arch/arm/mach-omap2/omap4-common.c
+++ b/arch/arm/mach-omap2/omap4-common.c
@@ -44,6 +44,13 @@ void __init gic_init_irq(void)
}
#ifdef CONFIG_CACHE_L2X0
+
+static void omap4_l2x0_disable(void)
+{
+ /* Disable PL310 L2 Cache controller */
+ omap_smc1(0x102, 0x0);
+}
+
static int __init omap_l2_cache_init(void)
{
/*
@@ -61,10 +68,20 @@ static int __init omap_l2_cache_init(void)
omap_smc1(0x102, 0x1);
/*
- * 32KB way size, 16-way associativity,
- * parity disabled
+ * 16-way associativity, parity disabled
+ * Way size - 32KB (es1.0)
+ * Way size - 64KB (es2.0 +)
*/
- l2x0_init(l2cache_base, 0x0e050000, 0xc0000fff);
+ if (omap_rev() == OMAP4430_REV_ES1_0)
+ l2x0_init(l2cache_base, 0x0e050000, 0xc0000fff);
+ else
+ l2x0_init(l2cache_base, 0x0e070000, 0xc0000fff);
+
+ /*
+ * Override default outer_cache.disable with a OMAP4
+ * specific one
+ */
+ outer_cache.disable = omap4_l2x0_disable;
return 0;
}
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index cb911d7d1a3c..5a30658444d0 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -13,10 +13,102 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
- * This code manages "OMAP modules" (on-chip devices) and their
- * integration with Linux device driver and bus code.
- *
- * References:
+ * Introduction
+ * ------------
+ * One way to view an OMAP SoC is as a collection of largely unrelated
+ * IP blocks connected by interconnects. The IP blocks include
+ * devices such as ARM processors, audio serial interfaces, UARTs,
+ * etc. Some of these devices, like the DSP, are created by TI;
+ * others, like the SGX, largely originate from external vendors. In
+ * TI's documentation, on-chip devices are referred to as "OMAP
+ * modules." Some of these IP blocks are identical across several
+ * OMAP versions. Others are revised frequently.
+ *
+ * These OMAP modules are tied together by various interconnects.
+ * Most of the address and data flow between modules is via OCP-based
+ * interconnects such as the L3 and L4 buses; but there are other
+ * interconnects that distribute the hardware clock tree, handle idle
+ * and reset signaling, supply power, and connect the modules to
+ * various pads or balls on the OMAP package.
+ *
+ * OMAP hwmod provides a consistent way to describe the on-chip
+ * hardware blocks and their integration into the rest of the chip.
+ * This description can be automatically generated from the TI
+ * hardware database. OMAP hwmod provides a standard, consistent API
+ * to reset, enable, idle, and disable these hardware blocks. And
+ * hwmod provides a way for other core code, such as the Linux device
+ * code or the OMAP power management and address space mapping code,
+ * to query the hardware database.
+ *
+ * Using hwmod
+ * -----------
+ * Drivers won't call hwmod functions directly. That is done by the
+ * omap_device code, and in rare occasions, by custom integration code
+ * in arch/arm/ *omap*. The omap_device code includes functions to
+ * build a struct platform_device using omap_hwmod data, and that is
+ * currently how hwmod data is communicated to drivers and to the
+ * Linux driver model. Most drivers will call omap_hwmod functions only
+ * indirectly, via pm_runtime*() functions.
+ *
+ * From a layering perspective, here is where the OMAP hwmod code
+ * fits into the kernel software stack:
+ *
+ * +-------------------------------+
+ * | Device driver code |
+ * | (e.g., drivers/) |
+ * +-------------------------------+
+ * | Linux driver model |
+ * | (platform_device / |
+ * | platform_driver data/code) |
+ * +-------------------------------+
+ * | OMAP core-driver integration |
+ * |(arch/arm/mach-omap2/devices.c)|
+ * +-------------------------------+
+ * | omap_device code |
+ * | (../plat-omap/omap_device.c) |
+ * +-------------------------------+
+ * ----> | omap_hwmod code/data | <-----
+ * | (../mach-omap2/omap_hwmod*) |
+ * +-------------------------------+
+ * | OMAP clock/PRCM/register fns |
+ * | (__raw_{read,write}l, clk*) |
+ * +-------------------------------+
+ *
+ * Device drivers should not contain any OMAP-specific code or data in
+ * them. They should only contain code to operate the IP block that
+ * the driver is responsible for. This is because these IP blocks can
+ * also appear in other SoCs, either from TI (such as DaVinci) or from
+ * other manufacturers; and drivers should be reusable across other
+ * platforms.
+ *
+ * The OMAP hwmod code also will attempt to reset and idle all on-chip
+ * devices upon boot. The goal here is for the kernel to be
+ * completely self-reliant and independent from bootloaders. This is
+ * to ensure a repeatable configuration, both to ensure consistent
+ * runtime behavior, and to make it easier for others to reproduce
+ * bugs.
+ *
+ * OMAP module activity states
+ * ---------------------------
+ * The hwmod code considers modules to be in one of several activity
+ * states. IP blocks start out in an UNKNOWN state, then once they
+ * are registered via the hwmod code, proceed to the REGISTERED state.
+ * Once their clock names are resolved to clock pointers, the module
+ * enters the CLKS_INITED state; and finally, once the module has been
+ * reset and the integration registers programmed, the INITIALIZED state
+ * is entered. The hwmod code will then place the module into either
+ * the IDLE state to save power, or in the case of a critical system
+ * module, the ENABLED state.
+ *
+ * OMAP core integration code can then call omap_hwmod*() functions
+ * directly to move the module between the IDLE, ENABLED, and DISABLED
+ * states, as needed. This is done during both the PM idle loop, and
+ * in the OMAP core integration code's implementation of the PM runtime
+ * functions.
+ *
+ * References
+ * ----------
+ * This is a partial list.
* - OMAP2420 Multimedia Processor Silicon Revision 2.1.1, 2.2 (SWPU064)
* - OMAP2430 Multimedia Device POP Silicon Revision 2.1 (SWPU090)
* - OMAP34xx Multimedia Device Silicon Revision 3.1 (SWPU108)
@@ -50,11 +142,13 @@
#include <plat/powerdomain.h>
#include <plat/clock.h>
#include <plat/omap_hwmod.h>
+#include <plat/prcm.h>
#include "cm.h"
+#include "prm.h"
-/* Maximum microseconds to wait for OMAP module to reset */
-#define MAX_MODULE_RESET_WAIT 10000
+/* Maximum microseconds to wait for OMAP module to softreset */
+#define MAX_MODULE_SOFTRESET_WAIT 10000
/* Name of the OMAP hwmod for the MPU */
#define MPU_INITIATOR_NAME "mpu"
@@ -90,7 +184,7 @@ static int _update_sysc_cache(struct omap_hwmod *oh)
/* XXX ensure module interface clock is up */
- oh->_sysc_cache = omap_hwmod_readl(oh, oh->class->sysc->sysc_offs);
+ oh->_sysc_cache = omap_hwmod_read(oh, oh->class->sysc->sysc_offs);
if (!(oh->class->sysc->sysc_flags & SYSC_NO_CACHE))
oh->_int_flags |= _HWMOD_SYSCONFIG_LOADED;
@@ -117,7 +211,7 @@ static void _write_sysconfig(u32 v, struct omap_hwmod *oh)
if (oh->_sysc_cache != v) {
oh->_sysc_cache = v;
- omap_hwmod_writel(v, oh, oh->class->sysc->sysc_offs);
+ omap_hwmod_write(v, oh, oh->class->sysc->sysc_offs);
}
}
@@ -544,6 +638,36 @@ static int _disable_clocks(struct omap_hwmod *oh)
return 0;
}
+static void _enable_optional_clocks(struct omap_hwmod *oh)
+{
+ struct omap_hwmod_opt_clk *oc;
+ int i;
+
+ pr_debug("omap_hwmod: %s: enabling optional clocks\n", oh->name);
+
+ for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
+ if (oc->_clk) {
+ pr_debug("omap_hwmod: enable %s:%s\n", oc->role,
+ oc->_clk->name);
+ clk_enable(oc->_clk);
+ }
+}
+
+static void _disable_optional_clocks(struct omap_hwmod *oh)
+{
+ struct omap_hwmod_opt_clk *oc;
+ int i;
+
+ pr_debug("omap_hwmod: %s: disabling optional clocks\n", oh->name);
+
+ for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
+ if (oc->_clk) {
+ pr_debug("omap_hwmod: disable %s:%s\n", oc->role,
+ oc->_clk->name);
+ clk_disable(oc->_clk);
+ }
+}
+
/**
* _find_mpu_port_index - find hwmod OCP slave port ID intended for MPU use
* @oh: struct omap_hwmod *
@@ -622,7 +746,7 @@ static void __iomem *_find_mpu_rt_base(struct omap_hwmod *oh, u8 index)
}
/**
- * _sysc_enable - try to bring a module out of idle via OCP_SYSCONFIG
+ * _enable_sysc - try to bring a module out of idle via OCP_SYSCONFIG
* @oh: struct omap_hwmod *
*
* If module is marked as SWSUP_SIDLE, force the module out of slave
@@ -630,7 +754,7 @@ static void __iomem *_find_mpu_rt_base(struct omap_hwmod *oh, u8 index)
* as SWSUP_MSUSPEND, force the module out of master standby;
* otherwise, configure it for smart-standby. No return value.
*/
-static void _sysc_enable(struct omap_hwmod *oh)
+static void _enable_sysc(struct omap_hwmod *oh)
{
u8 idlemode, sf;
u32 v;
@@ -653,14 +777,6 @@ static void _sysc_enable(struct omap_hwmod *oh)
_set_master_standbymode(oh, idlemode, &v);
}
- if (sf & SYSC_HAS_AUTOIDLE) {
- idlemode = (oh->flags & HWMOD_NO_OCP_AUTOIDLE) ?
- 0 : 1;
- _set_module_autoidle(oh, idlemode, &v);
- }
-
- /* XXX OCP ENAWAKEUP bit? */
-
/*
* XXX The clock framework should handle this, by
* calling into this code. But this must wait until the
@@ -671,10 +787,25 @@ static void _sysc_enable(struct omap_hwmod *oh)
_set_clockactivity(oh, oh->class->sysc->clockact, &v);
_write_sysconfig(v, oh);
+
+ /* If slave is in SMARTIDLE, also enable wakeup */
+ if ((sf & SYSC_HAS_SIDLEMODE) && !(oh->flags & HWMOD_SWSUP_SIDLE))
+ _enable_wakeup(oh);
+
+ /*
+ * Set the autoidle bit only after setting the smartidle bit
+ * Setting this will not have any impact on the other modules.
+ */
+ if (sf & SYSC_HAS_AUTOIDLE) {
+ idlemode = (oh->flags & HWMOD_NO_OCP_AUTOIDLE) ?
+ 0 : 1;
+ _set_module_autoidle(oh, idlemode, &v);
+ _write_sysconfig(v, oh);
+ }
}
/**
- * _sysc_idle - try to put a module into idle via OCP_SYSCONFIG
+ * _idle_sysc - try to put a module into idle via OCP_SYSCONFIG
* @oh: struct omap_hwmod *
*
* If module is marked as SWSUP_SIDLE, force the module into slave
@@ -682,7 +813,7 @@ static void _sysc_enable(struct omap_hwmod *oh)
* as SWSUP_MSUSPEND, force the module into master standby; otherwise,
* configure it for smart-standby. No return value.
*/
-static void _sysc_idle(struct omap_hwmod *oh)
+static void _idle_sysc(struct omap_hwmod *oh)
{
u8 idlemode, sf;
u32 v;
@@ -709,13 +840,13 @@ static void _sysc_idle(struct omap_hwmod *oh)
}
/**
- * _sysc_shutdown - force a module into idle via OCP_SYSCONFIG
+ * _shutdown_sysc - force a module into idle via OCP_SYSCONFIG
* @oh: struct omap_hwmod *
*
* Force the module into slave idle and master suspend. No return
* value.
*/
-static void _sysc_shutdown(struct omap_hwmod *oh)
+static void _shutdown_sysc(struct omap_hwmod *oh)
{
u32 v;
u8 sf;
@@ -767,10 +898,10 @@ static struct omap_hwmod *_lookup(const char *name)
* @data: not used; pass NULL
*
* Called by omap_hwmod_late_init() (after omap2_clk_init()).
- * Resolves all clock names embedded in the hwmod. Must be called
- * with omap_hwmod_mutex held. Returns -EINVAL if the omap_hwmod
- * has not yet been registered or if the clocks have already been
- * initialized, 0 on success, or a non-zero error on failure.
+ * Resolves all clock names embedded in the hwmod. Returns -EINVAL if
+ * the omap_hwmod has not yet been registered or if the clocks have
+ * already been initialized, 0 on success, or a non-zero error on
+ * failure.
*/
static int _init_clocks(struct omap_hwmod *oh, void *data)
{
@@ -834,56 +965,202 @@ static int _wait_target_ready(struct omap_hwmod *oh)
}
/**
+ * _lookup_hardreset - return the register bit shift for this hwmod/reset line
+ * @oh: struct omap_hwmod *
+ * @name: name of the reset line in the context of this hwmod
+ *
+ * Return the bit position of the reset line that match the
+ * input name. Return -ENOENT if not found.
+ */
+static u8 _lookup_hardreset(struct omap_hwmod *oh, const char *name)
+{
+ int i;
+
+ for (i = 0; i < oh->rst_lines_cnt; i++) {
+ const char *rst_line = oh->rst_lines[i].name;
+ if (!strcmp(rst_line, name)) {
+ u8 shift = oh->rst_lines[i].rst_shift;
+ pr_debug("omap_hwmod: %s: _lookup_hardreset: %s: %d\n",
+ oh->name, rst_line, shift);
+
+ return shift;
+ }
+ }
+
+ return -ENOENT;
+}
+
+/**
+ * _assert_hardreset - assert the HW reset line of submodules
+ * contained in the hwmod module.
+ * @oh: struct omap_hwmod *
+ * @name: name of the reset line to lookup and assert
+ *
+ * Some IP like dsp, ipu or iva contain processor that require
+ * an HW reset line to be assert / deassert in order to enable fully
+ * the IP.
+ */
+static int _assert_hardreset(struct omap_hwmod *oh, const char *name)
+{
+ u8 shift;
+
+ if (!oh)
+ return -EINVAL;
+
+ shift = _lookup_hardreset(oh, name);
+ if (IS_ERR_VALUE(shift))
+ return shift;
+
+ if (cpu_is_omap24xx() || cpu_is_omap34xx())
+ return omap2_prm_assert_hardreset(oh->prcm.omap2.module_offs,
+ shift);
+ else if (cpu_is_omap44xx())
+ return omap4_prm_assert_hardreset(oh->prcm.omap4.rstctrl_reg,
+ shift);
+ else
+ return -EINVAL;
+}
+
+/**
+ * _deassert_hardreset - deassert the HW reset line of submodules contained
+ * in the hwmod module.
+ * @oh: struct omap_hwmod *
+ * @name: name of the reset line to look up and deassert
+ *
+ * Some IP like dsp, ipu or iva contain processor that require
+ * an HW reset line to be assert / deassert in order to enable fully
+ * the IP.
+ */
+static int _deassert_hardreset(struct omap_hwmod *oh, const char *name)
+{
+ u8 shift;
+ int r;
+
+ if (!oh)
+ return -EINVAL;
+
+ shift = _lookup_hardreset(oh, name);
+ if (IS_ERR_VALUE(shift))
+ return shift;
+
+ if (cpu_is_omap24xx() || cpu_is_omap34xx())
+ r = omap2_prm_deassert_hardreset(oh->prcm.omap2.module_offs,
+ shift);
+ else if (cpu_is_omap44xx())
+ r = omap4_prm_deassert_hardreset(oh->prcm.omap4.rstctrl_reg,
+ shift);
+ else
+ return -EINVAL;
+
+ if (r == -EBUSY)
+ pr_warning("omap_hwmod: %s: failed to hardreset\n", oh->name);
+
+ return r;
+}
+
+/**
+ * _read_hardreset - read the HW reset line state of submodules
+ * contained in the hwmod module
+ * @oh: struct omap_hwmod *
+ * @name: name of the reset line to look up and read
+ *
+ * Return the state of the reset line.
+ */
+static int _read_hardreset(struct omap_hwmod *oh, const char *name)
+{
+ u8 shift;
+
+ if (!oh)
+ return -EINVAL;
+
+ shift = _lookup_hardreset(oh, name);
+ if (IS_ERR_VALUE(shift))
+ return shift;
+
+ if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
+ return omap2_prm_is_hardreset_asserted(oh->prcm.omap2.module_offs,
+ shift);
+ } else if (cpu_is_omap44xx()) {
+ return omap4_prm_is_hardreset_asserted(oh->prcm.omap4.rstctrl_reg,
+ shift);
+ } else {
+ return -EINVAL;
+ }
+}
+
+/**
* _reset - reset an omap_hwmod
* @oh: struct omap_hwmod *
*
* Resets an omap_hwmod @oh via the OCP_SYSCONFIG bit. hwmod must be
- * enabled for this to work. Must be called with omap_hwmod_mutex
- * held. Returns -EINVAL if the hwmod cannot be reset this way or if
- * the hwmod is in the wrong state, -ETIMEDOUT if the module did not
- * reset in time, or 0 upon success.
+ * enabled for this to work. Returns -EINVAL if the hwmod cannot be
+ * reset this way or if the hwmod is in the wrong state, -ETIMEDOUT if
+ * the module did not reset in time, or 0 upon success.
+ *
+ * In OMAP3 a specific SYSSTATUS register is used to get the reset status.
+ * Starting in OMAP4, some IPs does not have SYSSTATUS register and instead
+ * use the SYSCONFIG softreset bit to provide the status.
+ *
+ * Note that some IP like McBSP does have a reset control but no reset status.
*/
static int _reset(struct omap_hwmod *oh)
{
- u32 r, v;
+ u32 v;
int c = 0;
+ int ret = 0;
if (!oh->class->sysc ||
- !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET) ||
- (oh->class->sysc->sysc_flags & SYSS_MISSING))
+ !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET))
return -EINVAL;
/* clocks must be on for this operation */
if (oh->_state != _HWMOD_STATE_ENABLED) {
- WARN(1, "omap_hwmod: %s: reset can only be entered from "
- "enabled state\n", oh->name);
+ pr_warning("omap_hwmod: %s: reset can only be entered from "
+ "enabled state\n", oh->name);
return -EINVAL;
}
+ /* For some modules, all optionnal clocks need to be enabled as well */
+ if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
+ _enable_optional_clocks(oh);
+
pr_debug("omap_hwmod: %s: resetting\n", oh->name);
v = oh->_sysc_cache;
- r = _set_softreset(oh, &v);
- if (r)
- return r;
+ ret = _set_softreset(oh, &v);
+ if (ret)
+ goto dis_opt_clks;
_write_sysconfig(v, oh);
- omap_test_timeout((omap_hwmod_readl(oh, oh->class->sysc->syss_offs) &
- SYSS_RESETDONE_MASK),
- MAX_MODULE_RESET_WAIT, c);
-
- if (c == MAX_MODULE_RESET_WAIT)
- WARN(1, "omap_hwmod: %s: failed to reset in %d usec\n",
- oh->name, MAX_MODULE_RESET_WAIT);
+ if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS)
+ omap_test_timeout((omap_hwmod_read(oh,
+ oh->class->sysc->syss_offs)
+ & SYSS_RESETDONE_MASK),
+ MAX_MODULE_SOFTRESET_WAIT, c);
+ else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS)
+ omap_test_timeout(!(omap_hwmod_read(oh,
+ oh->class->sysc->sysc_offs)
+ & SYSC_TYPE2_SOFTRESET_MASK),
+ MAX_MODULE_SOFTRESET_WAIT, c);
+
+ if (c == MAX_MODULE_SOFTRESET_WAIT)
+ pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n",
+ oh->name, MAX_MODULE_SOFTRESET_WAIT);
else
- pr_debug("omap_hwmod: %s: reset in %d usec\n", oh->name, c);
+ pr_debug("omap_hwmod: %s: softreset in %d usec\n", oh->name, c);
/*
* XXX add _HWMOD_STATE_WEDGED for modules that don't come back from
* _wait_target_ready() or _reset()
*/
- return (c == MAX_MODULE_RESET_WAIT) ? -ETIMEDOUT : 0;
+ ret = (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : 0;
+
+dis_opt_clks:
+ if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
+ _disable_optional_clocks(oh);
+
+ return ret;
}
/**
@@ -891,9 +1168,11 @@ static int _reset(struct omap_hwmod *oh)
* @oh: struct omap_hwmod *
*
* Enables an omap_hwmod @oh such that the MPU can access the hwmod's
- * register target. Must be called with omap_hwmod_mutex held.
- * Returns -EINVAL if the hwmod is in the wrong state or passes along
- * the return value of _wait_target_ready().
+ * register target. (This function has a full name --
+ * _omap_hwmod_enable() rather than simply _enable() -- because it is
+ * currently required by the pm34xx.c idle loop.) Returns -EINVAL if
+ * the hwmod is in the wrong state or passes along the return value of
+ * _wait_target_ready().
*/
int _omap_hwmod_enable(struct omap_hwmod *oh)
{
@@ -909,6 +1188,15 @@ int _omap_hwmod_enable(struct omap_hwmod *oh)
pr_debug("omap_hwmod: %s: enabling\n", oh->name);
+ /*
+ * If an IP contains only one HW reset line, then de-assert it in order
+ * to allow to enable the clocks. Otherwise the PRCM will return
+ * Intransition status, and the init will failed.
+ */
+ if ((oh->_state == _HWMOD_STATE_INITIALIZED ||
+ oh->_state == _HWMOD_STATE_DISABLED) && oh->rst_lines_cnt == 1)
+ _deassert_hardreset(oh, oh->rst_lines[0].name);
+
/* XXX mux balls */
_add_initiator_dep(oh, mpu_oh);
@@ -922,7 +1210,7 @@ int _omap_hwmod_enable(struct omap_hwmod *oh)
if (oh->class->sysc) {
if (!(oh->_int_flags & _HWMOD_SYSCONFIG_LOADED))
_update_sysc_cache(oh);
- _sysc_enable(oh);
+ _enable_sysc(oh);
}
} else {
pr_debug("omap_hwmod: %s: _wait_target_ready: %d\n",
@@ -933,12 +1221,14 @@ int _omap_hwmod_enable(struct omap_hwmod *oh)
}
/**
- * _idle - idle an omap_hwmod
+ * _omap_hwmod_idle - idle an omap_hwmod
* @oh: struct omap_hwmod *
*
* Idles an omap_hwmod @oh. This should be called once the hwmod has
- * no further work. Returns -EINVAL if the hwmod is in the wrong
- * state or returns 0.
+ * no further work. (This function has a full name --
+ * _omap_hwmod_idle() rather than simply _idle() -- because it is
+ * currently required by the pm34xx.c idle loop.) Returns -EINVAL if
+ * the hwmod is in the wrong state or returns 0.
*/
int _omap_hwmod_idle(struct omap_hwmod *oh)
{
@@ -951,7 +1241,7 @@ int _omap_hwmod_idle(struct omap_hwmod *oh)
pr_debug("omap_hwmod: %s: idling\n", oh->name);
if (oh->class->sysc)
- _sysc_idle(oh);
+ _idle_sysc(oh);
_del_initiator_dep(oh, mpu_oh);
_disable_clocks(oh);
@@ -981,10 +1271,21 @@ static int _shutdown(struct omap_hwmod *oh)
pr_debug("omap_hwmod: %s: disabling\n", oh->name);
if (oh->class->sysc)
- _sysc_shutdown(oh);
- _del_initiator_dep(oh, mpu_oh);
- /* XXX what about the other system initiators here? DMA, tesla, d2d */
- _disable_clocks(oh);
+ _shutdown_sysc(oh);
+
+ /*
+ * If an IP contains only one HW reset line, then assert it
+ * before disabling the clocks and shutting down the IP.
+ */
+ if (oh->rst_lines_cnt == 1)
+ _assert_hardreset(oh, oh->rst_lines[0].name);
+
+ /* clocks and deps are already disabled in idle */
+ if (oh->_state == _HWMOD_STATE_ENABLED) {
+ _del_initiator_dep(oh, mpu_oh);
+ /* XXX what about the other system initiators here? dma, dsp */
+ _disable_clocks(oh);
+ }
/* XXX Should this code also force-disable the optional clocks? */
/* XXX mux any associated balls to safe mode */
@@ -1000,11 +1301,10 @@ static int _shutdown(struct omap_hwmod *oh)
* @skip_setup_idle_p: do not idle hwmods at the end of the fn if 1
*
* Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh
- * OCP_SYSCONFIG register. Must be called with omap_hwmod_mutex held.
- * @skip_setup_idle is intended to be used on a system that will not
- * call omap_hwmod_enable() to enable devices (e.g., a system without
- * PM runtime). Returns -EINVAL if the hwmod is in the wrong state or
- * returns 0.
+ * OCP_SYSCONFIG register. @skip_setup_idle is intended to be used on
+ * a system that will not call omap_hwmod_enable() to enable devices
+ * (e.g., a system without PM runtime). Returns -EINVAL if the hwmod
+ * is in the wrong state or returns 0.
*/
static int _setup(struct omap_hwmod *oh, void *data)
{
@@ -1034,8 +1334,19 @@ static int _setup(struct omap_hwmod *oh, void *data)
}
}
+ mutex_init(&oh->_mutex);
oh->_state = _HWMOD_STATE_INITIALIZED;
+ /*
+ * In the case of hwmod with hardreset that should not be
+ * de-assert at boot time, we have to keep the module
+ * initialized, because we cannot enable it properly with the
+ * reset asserted. Exit without warning because that behavior is
+ * expected.
+ */
+ if ((oh->flags & HWMOD_INIT_NO_RESET) && oh->rst_lines_cnt == 1)
+ return 0;
+
r = _omap_hwmod_enable(oh);
if (r) {
pr_warning("omap_hwmod: %s: cannot be enabled (%d)\n",
@@ -1044,16 +1355,16 @@ static int _setup(struct omap_hwmod *oh, void *data)
}
if (!(oh->flags & HWMOD_INIT_NO_RESET)) {
+ _reset(oh);
+
/*
- * XXX Do the OCP_SYSCONFIG bits need to be
- * reprogrammed after a reset? If not, then this can
- * be removed. If they do, then probably the
- * _omap_hwmod_enable() function should be split to avoid the
- * rewrite of the OCP_SYSCONFIG register.
+ * OCP_SYSCONFIG bits need to be reprogrammed after a softreset.
+ * The _omap_hwmod_enable() function should be split to
+ * avoid the rewrite of the OCP_SYSCONFIG register.
*/
if (oh->class->sysc) {
_update_sysc_cache(oh);
- _sysc_enable(oh);
+ _enable_sysc(oh);
}
}
@@ -1067,14 +1378,20 @@ static int _setup(struct omap_hwmod *oh, void *data)
/* Public functions */
-u32 omap_hwmod_readl(struct omap_hwmod *oh, u16 reg_offs)
+u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs)
{
- return __raw_readl(oh->_mpu_rt_va + reg_offs);
+ if (oh->flags & HWMOD_16BIT_REG)
+ return __raw_readw(oh->_mpu_rt_va + reg_offs);
+ else
+ return __raw_readl(oh->_mpu_rt_va + reg_offs);
}
-void omap_hwmod_writel(u32 v, struct omap_hwmod *oh, u16 reg_offs)
+void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs)
{
- __raw_writel(v, oh->_mpu_rt_va + reg_offs);
+ if (oh->flags & HWMOD_16BIT_REG)
+ __raw_writew(v, oh->_mpu_rt_va + reg_offs);
+ else
+ __raw_writel(v, oh->_mpu_rt_va + reg_offs);
}
/**
@@ -1309,7 +1626,7 @@ int omap_hwmod_unregister(struct omap_hwmod *oh)
* omap_hwmod_enable - enable an omap_hwmod
* @oh: struct omap_hwmod *
*
- * Enable an omap_hwomd @oh. Intended to be called by omap_device_enable().
+ * Enable an omap_hwmod @oh. Intended to be called by omap_device_enable().
* Returns -EINVAL on error or passes along the return value from _enable().
*/
int omap_hwmod_enable(struct omap_hwmod *oh)
@@ -1319,9 +1636,9 @@ int omap_hwmod_enable(struct omap_hwmod *oh)
if (!oh)
return -EINVAL;
- mutex_lock(&omap_hwmod_mutex);
+ mutex_lock(&oh->_mutex);
r = _omap_hwmod_enable(oh);
- mutex_unlock(&omap_hwmod_mutex);
+ mutex_unlock(&oh->_mutex);
return r;
}
@@ -1331,7 +1648,7 @@ int omap_hwmod_enable(struct omap_hwmod *oh)
* omap_hwmod_idle - idle an omap_hwmod
* @oh: struct omap_hwmod *
*
- * Idle an omap_hwomd @oh. Intended to be called by omap_device_idle().
+ * Idle an omap_hwmod @oh. Intended to be called by omap_device_idle().
* Returns -EINVAL on error or passes along the return value from _idle().
*/
int omap_hwmod_idle(struct omap_hwmod *oh)
@@ -1339,9 +1656,9 @@ int omap_hwmod_idle(struct omap_hwmod *oh)
if (!oh)
return -EINVAL;
- mutex_lock(&omap_hwmod_mutex);
+ mutex_lock(&oh->_mutex);
_omap_hwmod_idle(oh);
- mutex_unlock(&omap_hwmod_mutex);
+ mutex_unlock(&oh->_mutex);
return 0;
}
@@ -1350,7 +1667,7 @@ int omap_hwmod_idle(struct omap_hwmod *oh)
* omap_hwmod_shutdown - shutdown an omap_hwmod
* @oh: struct omap_hwmod *
*
- * Shutdown an omap_hwomd @oh. Intended to be called by
+ * Shutdown an omap_hwmod @oh. Intended to be called by
* omap_device_shutdown(). Returns -EINVAL on error or passes along
* the return value from _shutdown().
*/
@@ -1359,9 +1676,9 @@ int omap_hwmod_shutdown(struct omap_hwmod *oh)
if (!oh)
return -EINVAL;
- mutex_lock(&omap_hwmod_mutex);
+ mutex_lock(&oh->_mutex);
_shutdown(oh);
- mutex_unlock(&omap_hwmod_mutex);
+ mutex_unlock(&oh->_mutex);
return 0;
}
@@ -1374,9 +1691,9 @@ int omap_hwmod_shutdown(struct omap_hwmod *oh)
*/
int omap_hwmod_enable_clocks(struct omap_hwmod *oh)
{
- mutex_lock(&omap_hwmod_mutex);
+ mutex_lock(&oh->_mutex);
_enable_clocks(oh);
- mutex_unlock(&omap_hwmod_mutex);
+ mutex_unlock(&oh->_mutex);
return 0;
}
@@ -1389,9 +1706,9 @@ int omap_hwmod_enable_clocks(struct omap_hwmod *oh)
*/
int omap_hwmod_disable_clocks(struct omap_hwmod *oh)
{
- mutex_lock(&omap_hwmod_mutex);
+ mutex_lock(&oh->_mutex);
_disable_clocks(oh);
- mutex_unlock(&omap_hwmod_mutex);
+ mutex_unlock(&oh->_mutex);
return 0;
}
@@ -1421,7 +1738,7 @@ void omap_hwmod_ocp_barrier(struct omap_hwmod *oh)
* Forces posted writes to complete on the OCP thread handling
* register writes
*/
- omap_hwmod_readl(oh, oh->class->sysc->sysc_offs);
+ omap_hwmod_read(oh, oh->class->sysc->sysc_offs);
}
/**
@@ -1430,20 +1747,18 @@ void omap_hwmod_ocp_barrier(struct omap_hwmod *oh)
*
* Under some conditions, a driver may wish to reset the entire device.
* Called from omap_device code. Returns -EINVAL on error or passes along
- * the return value from _reset()/_enable().
+ * the return value from _reset().
*/
int omap_hwmod_reset(struct omap_hwmod *oh)
{
int r;
- if (!oh || !(oh->_state & _HWMOD_STATE_ENABLED))
+ if (!oh)
return -EINVAL;
- mutex_lock(&omap_hwmod_mutex);
+ mutex_lock(&oh->_mutex);
r = _reset(oh);
- if (!r)
- r = _omap_hwmod_enable(oh);
- mutex_unlock(&omap_hwmod_mutex);
+ mutex_unlock(&oh->_mutex);
return r;
}
@@ -1468,7 +1783,7 @@ int omap_hwmod_count_resources(struct omap_hwmod *oh)
{
int ret, i;
- ret = oh->mpu_irqs_cnt + oh->sdma_chs_cnt;
+ ret = oh->mpu_irqs_cnt + oh->sdma_reqs_cnt;
for (i = 0; i < oh->slaves_cnt; i++)
ret += oh->slaves[i]->addr_cnt;
@@ -1501,10 +1816,10 @@ int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res)
r++;
}
- for (i = 0; i < oh->sdma_chs_cnt; i++) {
- (res + r)->name = (oh->sdma_chs + i)->name;
- (res + r)->start = (oh->sdma_chs + i)->dma_ch;
- (res + r)->end = (oh->sdma_chs + i)->dma_ch;
+ for (i = 0; i < oh->sdma_reqs_cnt; i++) {
+ (res + r)->name = (oh->sdma_reqs + i)->name;
+ (res + r)->start = (oh->sdma_reqs + i)->dma_req;
+ (res + r)->end = (oh->sdma_reqs + i)->dma_req;
(res + r)->flags = IORESOURCE_DMA;
r++;
}
@@ -1644,9 +1959,9 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
!(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP))
return -EINVAL;
- mutex_lock(&omap_hwmod_mutex);
+ mutex_lock(&oh->_mutex);
_enable_wakeup(oh);
- mutex_unlock(&omap_hwmod_mutex);
+ mutex_unlock(&oh->_mutex);
return 0;
}
@@ -1669,14 +1984,92 @@ int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
!(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP))
return -EINVAL;
- mutex_lock(&omap_hwmod_mutex);
+ mutex_lock(&oh->_mutex);
_disable_wakeup(oh);
- mutex_unlock(&omap_hwmod_mutex);
+ mutex_unlock(&oh->_mutex);
return 0;
}
/**
+ * omap_hwmod_assert_hardreset - assert the HW reset line of submodules
+ * contained in the hwmod module.
+ * @oh: struct omap_hwmod *
+ * @name: name of the reset line to lookup and assert
+ *
+ * Some IP like dsp, ipu or iva contain processor that require
+ * an HW reset line to be assert / deassert in order to enable fully
+ * the IP. Returns -EINVAL if @oh is null or if the operation is not
+ * yet supported on this OMAP; otherwise, passes along the return value
+ * from _assert_hardreset().
+ */
+int omap_hwmod_assert_hardreset(struct omap_hwmod *oh, const char *name)
+{
+ int ret;
+
+ if (!oh)
+ return -EINVAL;
+
+ mutex_lock(&oh->_mutex);
+ ret = _assert_hardreset(oh, name);
+ mutex_unlock(&oh->_mutex);
+
+ return ret;
+}
+
+/**
+ * omap_hwmod_deassert_hardreset - deassert the HW reset line of submodules
+ * contained in the hwmod module.
+ * @oh: struct omap_hwmod *
+ * @name: name of the reset line to look up and deassert
+ *
+ * Some IP like dsp, ipu or iva contain processor that require
+ * an HW reset line to be assert / deassert in order to enable fully
+ * the IP. Returns -EINVAL if @oh is null or if the operation is not
+ * yet supported on this OMAP; otherwise, passes along the return value
+ * from _deassert_hardreset().
+ */
+int omap_hwmod_deassert_hardreset(struct omap_hwmod *oh, const char *name)
+{
+ int ret;
+
+ if (!oh)
+ return -EINVAL;
+
+ mutex_lock(&oh->_mutex);
+ ret = _deassert_hardreset(oh, name);
+ mutex_unlock(&oh->_mutex);
+
+ return ret;
+}
+
+/**
+ * omap_hwmod_read_hardreset - read the HW reset line state of submodules
+ * contained in the hwmod module
+ * @oh: struct omap_hwmod *
+ * @name: name of the reset line to look up and read
+ *
+ * Return the current state of the hwmod @oh's reset line named @name:
+ * returns -EINVAL upon parameter error or if this operation
+ * is unsupported on the current OMAP; otherwise, passes along the return
+ * value from _read_hardreset().
+ */
+int omap_hwmod_read_hardreset(struct omap_hwmod *oh, const char *name)
+{
+ int ret;
+
+ if (!oh)
+ return -EINVAL;
+
+ mutex_lock(&oh->_mutex);
+ ret = _read_hardreset(oh, name);
+ mutex_unlock(&oh->_mutex);
+
+ return ret;
+}
+
+
+/**
* omap_hwmod_for_each_by_class - call @fn for each hwmod of class @classname
* @classname: struct omap_hwmod_class name to search for
* @fn: callback function pointer to call for each hwmod in class @classname
diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
index 3cc768e8bc04..adf6e3632a2b 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
@@ -15,10 +15,12 @@
#include <mach/irqs.h>
#include <plat/cpu.h>
#include <plat/dma.h>
+#include <plat/serial.h>
#include "omap_hwmod_common_data.h"
#include "prm-regbits-24xx.h"
+#include "cm-regbits-24xx.h"
/*
* OMAP2420 hardware module integration data
@@ -33,6 +35,7 @@ static struct omap_hwmod omap2420_mpu_hwmod;
static struct omap_hwmod omap2420_iva_hwmod;
static struct omap_hwmod omap2420_l3_main_hwmod;
static struct omap_hwmod omap2420_l4_core_hwmod;
+static struct omap_hwmod omap2420_wd_timer2_hwmod;
/* L3 -> L4_CORE interface */
static struct omap_hwmod_ocp_if omap2420_l3_main__l4_core = {
@@ -71,6 +74,9 @@ static struct omap_hwmod omap2420_l3_main_hwmod = {
};
static struct omap_hwmod omap2420_l4_wkup_hwmod;
+static struct omap_hwmod omap2420_uart1_hwmod;
+static struct omap_hwmod omap2420_uart2_hwmod;
+static struct omap_hwmod omap2420_uart3_hwmod;
/* L4_CORE -> L4_WKUP interface */
static struct omap_hwmod_ocp_if omap2420_l4_core__l4_wkup = {
@@ -79,6 +85,60 @@ static struct omap_hwmod_ocp_if omap2420_l4_core__l4_wkup = {
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
+/* L4 CORE -> UART1 interface */
+static struct omap_hwmod_addr_space omap2420_uart1_addr_space[] = {
+ {
+ .pa_start = OMAP2_UART1_BASE,
+ .pa_end = OMAP2_UART1_BASE + SZ_8K - 1,
+ .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2_l4_core__uart1 = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_uart1_hwmod,
+ .clk = "uart1_ick",
+ .addr = omap2420_uart1_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2420_uart1_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 CORE -> UART2 interface */
+static struct omap_hwmod_addr_space omap2420_uart2_addr_space[] = {
+ {
+ .pa_start = OMAP2_UART2_BASE,
+ .pa_end = OMAP2_UART2_BASE + SZ_1K - 1,
+ .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2_l4_core__uart2 = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_uart2_hwmod,
+ .clk = "uart2_ick",
+ .addr = omap2420_uart2_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2420_uart2_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 PER -> UART3 interface */
+static struct omap_hwmod_addr_space omap2420_uart3_addr_space[] = {
+ {
+ .pa_start = OMAP2_UART3_BASE,
+ .pa_end = OMAP2_UART3_BASE + SZ_1K - 1,
+ .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2_l4_core__uart3 = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_uart3_hwmod,
+ .clk = "uart3_ick",
+ .addr = omap2420_uart3_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2420_uart3_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
/* Slave interfaces on the L4_CORE interconnect */
static struct omap_hwmod_ocp_if *omap2420_l4_core_slaves[] = {
&omap2420_l3_main__l4_core,
@@ -87,6 +147,9 @@ static struct omap_hwmod_ocp_if *omap2420_l4_core_slaves[] = {
/* Master interfaces on the L4_CORE interconnect */
static struct omap_hwmod_ocp_if *omap2420_l4_core_masters[] = {
&omap2420_l4_core__l4_wkup,
+ &omap2_l4_core__uart1,
+ &omap2_l4_core__uart2,
+ &omap2_l4_core__uart3,
};
/* L4 CORE */
@@ -165,12 +228,206 @@ static struct omap_hwmod omap2420_iva_hwmod = {
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
};
+/* l4_wkup -> wd_timer2 */
+static struct omap_hwmod_addr_space omap2420_wd_timer2_addrs[] = {
+ {
+ .pa_start = 0x48022000,
+ .pa_end = 0x4802207f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2420_l4_wkup__wd_timer2 = {
+ .master = &omap2420_l4_wkup_hwmod,
+ .slave = &omap2420_wd_timer2_hwmod,
+ .clk = "mpu_wdt_ick",
+ .addr = omap2420_wd_timer2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2420_wd_timer2_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/*
+ * 'wd_timer' class
+ * 32-bit watchdog upward counter that generates a pulse on the reset pin on
+ * overflow condition
+ */
+
+static struct omap_hwmod_class_sysconfig omap2420_wd_timer_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2420_wd_timer_hwmod_class = {
+ .name = "wd_timer",
+ .sysc = &omap2420_wd_timer_sysc,
+};
+
+/* wd_timer2 */
+static struct omap_hwmod_ocp_if *omap2420_wd_timer2_slaves[] = {
+ &omap2420_l4_wkup__wd_timer2,
+};
+
+static struct omap_hwmod omap2420_wd_timer2_hwmod = {
+ .name = "wd_timer2",
+ .class = &omap2420_wd_timer_hwmod_class,
+ .main_clk = "mpu_wdt_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_MPU_WDT_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_MPU_WDT_SHIFT,
+ },
+ },
+ .slaves = omap2420_wd_timer2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_wd_timer2_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+/* UART */
+
+static struct omap_hwmod_class_sysconfig uart_sysc = {
+ .rev_offs = 0x50,
+ .sysc_offs = 0x54,
+ .syss_offs = 0x58,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class uart_class = {
+ .name = "uart",
+ .sysc = &uart_sysc,
+};
+
+/* UART1 */
+
+static struct omap_hwmod_irq_info uart1_mpu_irqs[] = {
+ { .irq = INT_24XX_UART1_IRQ, },
+};
+
+static struct omap_hwmod_dma_info uart1_sdma_reqs[] = {
+ { .name = "rx", .dma_req = OMAP24XX_DMA_UART1_RX, },
+ { .name = "tx", .dma_req = OMAP24XX_DMA_UART1_TX, },
+};
+
+static struct omap_hwmod_ocp_if *omap2420_uart1_slaves[] = {
+ &omap2_l4_core__uart1,
+};
+
+static struct omap_hwmod omap2420_uart1_hwmod = {
+ .name = "uart1",
+ .mpu_irqs = uart1_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(uart1_mpu_irqs),
+ .sdma_reqs = uart1_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(uart1_sdma_reqs),
+ .main_clk = "uart1_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_UART1_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_EN_UART1_SHIFT,
+ },
+ },
+ .slaves = omap2420_uart1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_uart1_slaves),
+ .class = &uart_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+/* UART2 */
+
+static struct omap_hwmod_irq_info uart2_mpu_irqs[] = {
+ { .irq = INT_24XX_UART2_IRQ, },
+};
+
+static struct omap_hwmod_dma_info uart2_sdma_reqs[] = {
+ { .name = "rx", .dma_req = OMAP24XX_DMA_UART2_RX, },
+ { .name = "tx", .dma_req = OMAP24XX_DMA_UART2_TX, },
+};
+
+static struct omap_hwmod_ocp_if *omap2420_uart2_slaves[] = {
+ &omap2_l4_core__uart2,
+};
+
+static struct omap_hwmod omap2420_uart2_hwmod = {
+ .name = "uart2",
+ .mpu_irqs = uart2_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(uart2_mpu_irqs),
+ .sdma_reqs = uart2_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(uart2_sdma_reqs),
+ .main_clk = "uart2_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_UART2_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_EN_UART2_SHIFT,
+ },
+ },
+ .slaves = omap2420_uart2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_uart2_slaves),
+ .class = &uart_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+/* UART3 */
+
+static struct omap_hwmod_irq_info uart3_mpu_irqs[] = {
+ { .irq = INT_24XX_UART3_IRQ, },
+};
+
+static struct omap_hwmod_dma_info uart3_sdma_reqs[] = {
+ { .name = "rx", .dma_req = OMAP24XX_DMA_UART3_RX, },
+ { .name = "tx", .dma_req = OMAP24XX_DMA_UART3_TX, },
+};
+
+static struct omap_hwmod_ocp_if *omap2420_uart3_slaves[] = {
+ &omap2_l4_core__uart3,
+};
+
+static struct omap_hwmod omap2420_uart3_hwmod = {
+ .name = "uart3",
+ .mpu_irqs = uart3_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(uart3_mpu_irqs),
+ .sdma_reqs = uart3_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(uart3_sdma_reqs),
+ .main_clk = "uart3_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 2,
+ .module_bit = OMAP24XX_EN_UART3_SHIFT,
+ .idlest_reg_id = 2,
+ .idlest_idle_bit = OMAP24XX_EN_UART3_SHIFT,
+ },
+ },
+ .slaves = omap2420_uart3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_uart3_slaves),
+ .class = &uart_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
static __initdata struct omap_hwmod *omap2420_hwmods[] = {
&omap2420_l3_main_hwmod,
&omap2420_l4_core_hwmod,
&omap2420_l4_wkup_hwmod,
&omap2420_mpu_hwmod,
&omap2420_iva_hwmod,
+ &omap2420_wd_timer2_hwmod,
+ &omap2420_uart1_hwmod,
+ &omap2420_uart2_hwmod,
+ &omap2420_uart3_hwmod,
NULL,
};
diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
index 4526628ed287..12d939e456cf 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
@@ -15,10 +15,12 @@
#include <mach/irqs.h>
#include <plat/cpu.h>
#include <plat/dma.h>
+#include <plat/serial.h>
#include "omap_hwmod_common_data.h"
#include "prm-regbits-24xx.h"
+#include "cm-regbits-24xx.h"
/*
* OMAP2430 hardware module integration data
@@ -33,6 +35,7 @@ static struct omap_hwmod omap2430_mpu_hwmod;
static struct omap_hwmod omap2430_iva_hwmod;
static struct omap_hwmod omap2430_l3_main_hwmod;
static struct omap_hwmod omap2430_l4_core_hwmod;
+static struct omap_hwmod omap2430_wd_timer2_hwmod;
/* L3 -> L4_CORE interface */
static struct omap_hwmod_ocp_if omap2430_l3_main__l4_core = {
@@ -71,6 +74,9 @@ static struct omap_hwmod omap2430_l3_main_hwmod = {
};
static struct omap_hwmod omap2430_l4_wkup_hwmod;
+static struct omap_hwmod omap2430_uart1_hwmod;
+static struct omap_hwmod omap2430_uart2_hwmod;
+static struct omap_hwmod omap2430_uart3_hwmod;
/* L4_CORE -> L4_WKUP interface */
static struct omap_hwmod_ocp_if omap2430_l4_core__l4_wkup = {
@@ -79,6 +85,60 @@ static struct omap_hwmod_ocp_if omap2430_l4_core__l4_wkup = {
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
+/* L4 CORE -> UART1 interface */
+static struct omap_hwmod_addr_space omap2430_uart1_addr_space[] = {
+ {
+ .pa_start = OMAP2_UART1_BASE,
+ .pa_end = OMAP2_UART1_BASE + SZ_8K - 1,
+ .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2_l4_core__uart1 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_uart1_hwmod,
+ .clk = "uart1_ick",
+ .addr = omap2430_uart1_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2430_uart1_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 CORE -> UART2 interface */
+static struct omap_hwmod_addr_space omap2430_uart2_addr_space[] = {
+ {
+ .pa_start = OMAP2_UART2_BASE,
+ .pa_end = OMAP2_UART2_BASE + SZ_1K - 1,
+ .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2_l4_core__uart2 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_uart2_hwmod,
+ .clk = "uart2_ick",
+ .addr = omap2430_uart2_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2430_uart2_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 PER -> UART3 interface */
+static struct omap_hwmod_addr_space omap2430_uart3_addr_space[] = {
+ {
+ .pa_start = OMAP2_UART3_BASE,
+ .pa_end = OMAP2_UART3_BASE + SZ_1K - 1,
+ .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2_l4_core__uart3 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_uart3_hwmod,
+ .clk = "uart3_ick",
+ .addr = omap2430_uart3_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2430_uart3_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
/* Slave interfaces on the L4_CORE interconnect */
static struct omap_hwmod_ocp_if *omap2430_l4_core_slaves[] = {
&omap2430_l3_main__l4_core,
@@ -104,6 +164,9 @@ static struct omap_hwmod omap2430_l4_core_hwmod = {
/* Slave interfaces on the L4_WKUP interconnect */
static struct omap_hwmod_ocp_if *omap2430_l4_wkup_slaves[] = {
&omap2430_l4_core__l4_wkup,
+ &omap2_l4_core__uart1,
+ &omap2_l4_core__uart2,
+ &omap2_l4_core__uart3,
};
/* Master interfaces on the L4_WKUP interconnect */
@@ -165,12 +228,206 @@ static struct omap_hwmod omap2430_iva_hwmod = {
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
};
+/* l4_wkup -> wd_timer2 */
+static struct omap_hwmod_addr_space omap2430_wd_timer2_addrs[] = {
+ {
+ .pa_start = 0x49016000,
+ .pa_end = 0x4901607f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2430_l4_wkup__wd_timer2 = {
+ .master = &omap2430_l4_wkup_hwmod,
+ .slave = &omap2430_wd_timer2_hwmod,
+ .clk = "mpu_wdt_ick",
+ .addr = omap2430_wd_timer2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_wd_timer2_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/*
+ * 'wd_timer' class
+ * 32-bit watchdog upward counter that generates a pulse on the reset pin on
+ * overflow condition
+ */
+
+static struct omap_hwmod_class_sysconfig omap2430_wd_timer_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2430_wd_timer_hwmod_class = {
+ .name = "wd_timer",
+ .sysc = &omap2430_wd_timer_sysc,
+};
+
+/* wd_timer2 */
+static struct omap_hwmod_ocp_if *omap2430_wd_timer2_slaves[] = {
+ &omap2430_l4_wkup__wd_timer2,
+};
+
+static struct omap_hwmod omap2430_wd_timer2_hwmod = {
+ .name = "wd_timer2",
+ .class = &omap2430_wd_timer_hwmod_class,
+ .main_clk = "mpu_wdt_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_MPU_WDT_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_MPU_WDT_SHIFT,
+ },
+ },
+ .slaves = omap2430_wd_timer2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_wd_timer2_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* UART */
+
+static struct omap_hwmod_class_sysconfig uart_sysc = {
+ .rev_offs = 0x50,
+ .sysc_offs = 0x54,
+ .syss_offs = 0x58,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class uart_class = {
+ .name = "uart",
+ .sysc = &uart_sysc,
+};
+
+/* UART1 */
+
+static struct omap_hwmod_irq_info uart1_mpu_irqs[] = {
+ { .irq = INT_24XX_UART1_IRQ, },
+};
+
+static struct omap_hwmod_dma_info uart1_sdma_reqs[] = {
+ { .name = "rx", .dma_req = OMAP24XX_DMA_UART1_RX, },
+ { .name = "tx", .dma_req = OMAP24XX_DMA_UART1_TX, },
+};
+
+static struct omap_hwmod_ocp_if *omap2430_uart1_slaves[] = {
+ &omap2_l4_core__uart1,
+};
+
+static struct omap_hwmod omap2430_uart1_hwmod = {
+ .name = "uart1",
+ .mpu_irqs = uart1_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(uart1_mpu_irqs),
+ .sdma_reqs = uart1_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(uart1_sdma_reqs),
+ .main_clk = "uart1_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_UART1_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_EN_UART1_SHIFT,
+ },
+ },
+ .slaves = omap2430_uart1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_uart1_slaves),
+ .class = &uart_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* UART2 */
+
+static struct omap_hwmod_irq_info uart2_mpu_irqs[] = {
+ { .irq = INT_24XX_UART2_IRQ, },
+};
+
+static struct omap_hwmod_dma_info uart2_sdma_reqs[] = {
+ { .name = "rx", .dma_req = OMAP24XX_DMA_UART2_RX, },
+ { .name = "tx", .dma_req = OMAP24XX_DMA_UART2_TX, },
+};
+
+static struct omap_hwmod_ocp_if *omap2430_uart2_slaves[] = {
+ &omap2_l4_core__uart2,
+};
+
+static struct omap_hwmod omap2430_uart2_hwmod = {
+ .name = "uart2",
+ .mpu_irqs = uart2_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(uart2_mpu_irqs),
+ .sdma_reqs = uart2_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(uart2_sdma_reqs),
+ .main_clk = "uart2_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_UART2_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_EN_UART2_SHIFT,
+ },
+ },
+ .slaves = omap2430_uart2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_uart2_slaves),
+ .class = &uart_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* UART3 */
+
+static struct omap_hwmod_irq_info uart3_mpu_irqs[] = {
+ { .irq = INT_24XX_UART3_IRQ, },
+};
+
+static struct omap_hwmod_dma_info uart3_sdma_reqs[] = {
+ { .name = "rx", .dma_req = OMAP24XX_DMA_UART3_RX, },
+ { .name = "tx", .dma_req = OMAP24XX_DMA_UART3_TX, },
+};
+
+static struct omap_hwmod_ocp_if *omap2430_uart3_slaves[] = {
+ &omap2_l4_core__uart3,
+};
+
+static struct omap_hwmod omap2430_uart3_hwmod = {
+ .name = "uart3",
+ .mpu_irqs = uart3_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(uart3_mpu_irqs),
+ .sdma_reqs = uart3_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(uart3_sdma_reqs),
+ .main_clk = "uart3_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 2,
+ .module_bit = OMAP24XX_EN_UART3_SHIFT,
+ .idlest_reg_id = 2,
+ .idlest_idle_bit = OMAP24XX_EN_UART3_SHIFT,
+ },
+ },
+ .slaves = omap2430_uart3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_uart3_slaves),
+ .class = &uart_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
static __initdata struct omap_hwmod *omap2430_hwmods[] = {
&omap2430_l3_main_hwmod,
&omap2430_l4_core_hwmod,
&omap2430_l4_wkup_hwmod,
&omap2430_mpu_hwmod,
&omap2430_iva_hwmod,
+ &omap2430_wd_timer2_hwmod,
+ &omap2430_uart1_hwmod,
+ &omap2430_uart2_hwmod,
+ &omap2430_uart3_hwmod,
NULL,
};
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 5d8eb58ba5e3..cb97ecf0a3f6 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -17,10 +17,12 @@
#include <mach/irqs.h>
#include <plat/cpu.h>
#include <plat/dma.h>
+#include <plat/serial.h>
#include "omap_hwmod_common_data.h"
#include "prm-regbits-34xx.h"
+#include "cm-regbits-34xx.h"
/*
* OMAP3xxx hardware module integration data
@@ -36,6 +38,7 @@ static struct omap_hwmod omap3xxx_iva_hwmod;
static struct omap_hwmod omap3xxx_l3_main_hwmod;
static struct omap_hwmod omap3xxx_l4_core_hwmod;
static struct omap_hwmod omap3xxx_l4_per_hwmod;
+static struct omap_hwmod omap3xxx_wd_timer2_hwmod;
/* L3 -> L4_CORE interface */
static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_core = {
@@ -82,6 +85,10 @@ static struct omap_hwmod omap3xxx_l3_main_hwmod = {
};
static struct omap_hwmod omap3xxx_l4_wkup_hwmod;
+static struct omap_hwmod omap3xxx_uart1_hwmod;
+static struct omap_hwmod omap3xxx_uart2_hwmod;
+static struct omap_hwmod omap3xxx_uart3_hwmod;
+static struct omap_hwmod omap3xxx_uart4_hwmod;
/* L4_CORE -> L4_WKUP interface */
static struct omap_hwmod_ocp_if omap3xxx_l4_core__l4_wkup = {
@@ -90,6 +97,78 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__l4_wkup = {
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
+/* L4 CORE -> UART1 interface */
+static struct omap_hwmod_addr_space omap3xxx_uart1_addr_space[] = {
+ {
+ .pa_start = OMAP3_UART1_BASE,
+ .pa_end = OMAP3_UART1_BASE + SZ_8K - 1,
+ .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3_l4_core__uart1 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_uart1_hwmod,
+ .clk = "uart1_ick",
+ .addr = omap3xxx_uart1_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_uart1_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 CORE -> UART2 interface */
+static struct omap_hwmod_addr_space omap3xxx_uart2_addr_space[] = {
+ {
+ .pa_start = OMAP3_UART2_BASE,
+ .pa_end = OMAP3_UART2_BASE + SZ_1K - 1,
+ .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3_l4_core__uart2 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_uart2_hwmod,
+ .clk = "uart2_ick",
+ .addr = omap3xxx_uart2_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_uart2_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 PER -> UART3 interface */
+static struct omap_hwmod_addr_space omap3xxx_uart3_addr_space[] = {
+ {
+ .pa_start = OMAP3_UART3_BASE,
+ .pa_end = OMAP3_UART3_BASE + SZ_1K - 1,
+ .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3_l4_per__uart3 = {
+ .master = &omap3xxx_l4_per_hwmod,
+ .slave = &omap3xxx_uart3_hwmod,
+ .clk = "uart3_ick",
+ .addr = omap3xxx_uart3_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_uart3_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 PER -> UART4 interface */
+static struct omap_hwmod_addr_space omap3xxx_uart4_addr_space[] = {
+ {
+ .pa_start = OMAP3_UART4_BASE,
+ .pa_end = OMAP3_UART4_BASE + SZ_1K - 1,
+ .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3_l4_per__uart4 = {
+ .master = &omap3xxx_l4_per_hwmod,
+ .slave = &omap3xxx_uart4_hwmod,
+ .clk = "uart4_ick",
+ .addr = omap3xxx_uart4_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_uart4_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
/* Slave interfaces on the L4_CORE interconnect */
static struct omap_hwmod_ocp_if *omap3xxx_l4_core_slaves[] = {
&omap3xxx_l3_main__l4_core,
@@ -98,6 +177,8 @@ static struct omap_hwmod_ocp_if *omap3xxx_l4_core_slaves[] = {
/* Master interfaces on the L4_CORE interconnect */
static struct omap_hwmod_ocp_if *omap3xxx_l4_core_masters[] = {
&omap3xxx_l4_core__l4_wkup,
+ &omap3_l4_core__uart1,
+ &omap3_l4_core__uart2,
};
/* L4 CORE */
@@ -119,6 +200,8 @@ static struct omap_hwmod_ocp_if *omap3xxx_l4_per_slaves[] = {
/* Master interfaces on the L4_PER interconnect */
static struct omap_hwmod_ocp_if *omap3xxx_l4_per_masters[] = {
+ &omap3_l4_per__uart3,
+ &omap3_l4_per__uart4,
};
/* L4 PER */
@@ -197,6 +280,235 @@ static struct omap_hwmod omap3xxx_iva_hwmod = {
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
};
+/* l4_wkup -> wd_timer2 */
+static struct omap_hwmod_addr_space omap3xxx_wd_timer2_addrs[] = {
+ {
+ .pa_start = 0x48314000,
+ .pa_end = 0x4831407f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_wkup__wd_timer2 = {
+ .master = &omap3xxx_l4_wkup_hwmod,
+ .slave = &omap3xxx_wd_timer2_hwmod,
+ .clk = "wdt2_ick",
+ .addr = omap3xxx_wd_timer2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_wd_timer2_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/*
+ * 'wd_timer' class
+ * 32-bit watchdog upward counter that generates a pulse on the reset pin on
+ * overflow condition
+ */
+
+static struct omap_hwmod_class_sysconfig omap3xxx_wd_timer_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3xxx_wd_timer_hwmod_class = {
+ .name = "wd_timer",
+ .sysc = &omap3xxx_wd_timer_sysc,
+};
+
+/* wd_timer2 */
+static struct omap_hwmod_ocp_if *omap3xxx_wd_timer2_slaves[] = {
+ &omap3xxx_l4_wkup__wd_timer2,
+};
+
+static struct omap_hwmod omap3xxx_wd_timer2_hwmod = {
+ .name = "wd_timer2",
+ .class = &omap3xxx_wd_timer_hwmod_class,
+ .main_clk = "wdt2_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_WDT2_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_WDT2_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_wd_timer2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_wd_timer2_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* UART common */
+
+static struct omap_hwmod_class_sysconfig uart_sysc = {
+ .rev_offs = 0x50,
+ .sysc_offs = 0x54,
+ .syss_offs = 0x58,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class uart_class = {
+ .name = "uart",
+ .sysc = &uart_sysc,
+};
+
+/* UART1 */
+
+static struct omap_hwmod_irq_info uart1_mpu_irqs[] = {
+ { .irq = INT_24XX_UART1_IRQ, },
+};
+
+static struct omap_hwmod_dma_info uart1_sdma_reqs[] = {
+ { .name = "tx", .dma_req = OMAP24XX_DMA_UART1_TX, },
+ { .name = "rx", .dma_req = OMAP24XX_DMA_UART1_RX, },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_uart1_slaves[] = {
+ &omap3_l4_core__uart1,
+};
+
+static struct omap_hwmod omap3xxx_uart1_hwmod = {
+ .name = "uart1",
+ .mpu_irqs = uart1_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(uart1_mpu_irqs),
+ .sdma_reqs = uart1_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(uart1_sdma_reqs),
+ .main_clk = "uart1_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_UART1_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_EN_UART1_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_uart1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_uart1_slaves),
+ .class = &uart_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* UART2 */
+
+static struct omap_hwmod_irq_info uart2_mpu_irqs[] = {
+ { .irq = INT_24XX_UART2_IRQ, },
+};
+
+static struct omap_hwmod_dma_info uart2_sdma_reqs[] = {
+ { .name = "tx", .dma_req = OMAP24XX_DMA_UART2_TX, },
+ { .name = "rx", .dma_req = OMAP24XX_DMA_UART2_RX, },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_uart2_slaves[] = {
+ &omap3_l4_core__uart2,
+};
+
+static struct omap_hwmod omap3xxx_uart2_hwmod = {
+ .name = "uart2",
+ .mpu_irqs = uart2_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(uart2_mpu_irqs),
+ .sdma_reqs = uart2_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(uart2_sdma_reqs),
+ .main_clk = "uart2_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_UART2_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_EN_UART2_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_uart2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_uart2_slaves),
+ .class = &uart_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* UART3 */
+
+static struct omap_hwmod_irq_info uart3_mpu_irqs[] = {
+ { .irq = INT_24XX_UART3_IRQ, },
+};
+
+static struct omap_hwmod_dma_info uart3_sdma_reqs[] = {
+ { .name = "tx", .dma_req = OMAP24XX_DMA_UART3_TX, },
+ { .name = "rx", .dma_req = OMAP24XX_DMA_UART3_RX, },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_uart3_slaves[] = {
+ &omap3_l4_per__uart3,
+};
+
+static struct omap_hwmod omap3xxx_uart3_hwmod = {
+ .name = "uart3",
+ .mpu_irqs = uart3_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(uart3_mpu_irqs),
+ .sdma_reqs = uart3_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(uart3_sdma_reqs),
+ .main_clk = "uart3_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = OMAP3430_PER_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_UART3_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_EN_UART3_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_uart3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_uart3_slaves),
+ .class = &uart_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* UART4 */
+
+static struct omap_hwmod_irq_info uart4_mpu_irqs[] = {
+ { .irq = INT_36XX_UART4_IRQ, },
+};
+
+static struct omap_hwmod_dma_info uart4_sdma_reqs[] = {
+ { .name = "rx", .dma_req = OMAP36XX_DMA_UART4_RX, },
+ { .name = "tx", .dma_req = OMAP36XX_DMA_UART4_TX, },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_uart4_slaves[] = {
+ &omap3_l4_per__uart4,
+};
+
+static struct omap_hwmod omap3xxx_uart4_hwmod = {
+ .name = "uart4",
+ .mpu_irqs = uart4_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(uart4_mpu_irqs),
+ .sdma_reqs = uart4_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(uart4_sdma_reqs),
+ .main_clk = "uart4_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = OMAP3430_PER_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3630_EN_UART4_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3630_EN_UART4_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_uart4_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_uart4_slaves),
+ .class = &uart_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3630ES1),
+};
+
static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
&omap3xxx_l3_main_hwmod,
&omap3xxx_l4_core_hwmod,
@@ -204,6 +516,11 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
&omap3xxx_l4_wkup_hwmod,
&omap3xxx_mpu_hwmod,
&omap3xxx_iva_hwmod,
+ &omap3xxx_wd_timer2_hwmod,
+ &omap3xxx_uart1_hwmod,
+ &omap3xxx_uart2_hwmod,
+ &omap3xxx_uart3_hwmod,
+ &omap3xxx_uart4_hwmod,
NULL,
};
@@ -211,5 +528,3 @@ int __init omap3xxx_hwmod_init(void)
{
return omap_hwmod_init(omap3xxx_hwmods);
}
-
-
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
new file mode 100644
index 000000000000..7274db4de487
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -0,0 +1,850 @@
+/*
+ * Hardware modules present on the OMAP44xx chips
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ * Copyright (C) 2009-2010 Nokia Corporation
+ *
+ * Paul Walmsley
+ * Benoit Cousson
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * 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/io.h>
+
+#include <plat/omap_hwmod.h>
+#include <plat/cpu.h>
+
+#include "omap_hwmod_common_data.h"
+
+#include "cm.h"
+#include "prm-regbits-44xx.h"
+
+/* Base offset for all OMAP4 interrupts external to MPUSS */
+#define OMAP44XX_IRQ_GIC_START 32
+
+/* Base offset for all OMAP4 dma requests */
+#define OMAP44XX_DMA_REQ_START 1
+
+/* Backward references (IPs with Bus Master capability) */
+static struct omap_hwmod omap44xx_dmm_hwmod;
+static struct omap_hwmod omap44xx_emif_fw_hwmod;
+static struct omap_hwmod omap44xx_l3_instr_hwmod;
+static struct omap_hwmod omap44xx_l3_main_1_hwmod;
+static struct omap_hwmod omap44xx_l3_main_2_hwmod;
+static struct omap_hwmod omap44xx_l3_main_3_hwmod;
+static struct omap_hwmod omap44xx_l4_abe_hwmod;
+static struct omap_hwmod omap44xx_l4_cfg_hwmod;
+static struct omap_hwmod omap44xx_l4_per_hwmod;
+static struct omap_hwmod omap44xx_l4_wkup_hwmod;
+static struct omap_hwmod omap44xx_mpu_hwmod;
+static struct omap_hwmod omap44xx_mpu_private_hwmod;
+
+/*
+ * Interconnects omap_hwmod structures
+ * hwmods that compose the global OMAP interconnect
+ */
+
+/*
+ * 'dmm' class
+ * instance(s): dmm
+ */
+static struct omap_hwmod_class omap44xx_dmm_hwmod_class = {
+ .name = "dmm",
+};
+
+/* dmm interface data */
+/* l3_main_1 -> dmm */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_1__dmm = {
+ .master = &omap44xx_l3_main_1_hwmod,
+ .slave = &omap44xx_dmm_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mpu -> dmm */
+static struct omap_hwmod_ocp_if omap44xx_mpu__dmm = {
+ .master = &omap44xx_mpu_hwmod,
+ .slave = &omap44xx_dmm_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dmm slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_dmm_slaves[] = {
+ &omap44xx_l3_main_1__dmm,
+ &omap44xx_mpu__dmm,
+};
+
+static struct omap_hwmod_irq_info omap44xx_dmm_irqs[] = {
+ { .irq = 113 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod omap44xx_dmm_hwmod = {
+ .name = "dmm",
+ .class = &omap44xx_dmm_hwmod_class,
+ .slaves = omap44xx_dmm_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_dmm_slaves),
+ .mpu_irqs = omap44xx_dmm_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dmm_irqs),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'emif_fw' class
+ * instance(s): emif_fw
+ */
+static struct omap_hwmod_class omap44xx_emif_fw_hwmod_class = {
+ .name = "emif_fw",
+};
+
+/* emif_fw interface data */
+/* dmm -> emif_fw */
+static struct omap_hwmod_ocp_if omap44xx_dmm__emif_fw = {
+ .master = &omap44xx_dmm_hwmod,
+ .slave = &omap44xx_emif_fw_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> emif_fw */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__emif_fw = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_emif_fw_hwmod,
+ .clk = "l4_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* emif_fw slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_emif_fw_slaves[] = {
+ &omap44xx_dmm__emif_fw,
+ &omap44xx_l4_cfg__emif_fw,
+};
+
+static struct omap_hwmod omap44xx_emif_fw_hwmod = {
+ .name = "emif_fw",
+ .class = &omap44xx_emif_fw_hwmod_class,
+ .slaves = omap44xx_emif_fw_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_emif_fw_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'l3' class
+ * instance(s): l3_instr, l3_main_1, l3_main_2, l3_main_3
+ */
+static struct omap_hwmod_class omap44xx_l3_hwmod_class = {
+ .name = "l3",
+};
+
+/* l3_instr interface data */
+/* l3_main_3 -> l3_instr */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_3__l3_instr = {
+ .master = &omap44xx_l3_main_3_hwmod,
+ .slave = &omap44xx_l3_instr_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_instr slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_l3_instr_slaves[] = {
+ &omap44xx_l3_main_3__l3_instr,
+};
+
+static struct omap_hwmod omap44xx_l3_instr_hwmod = {
+ .name = "l3_instr",
+ .class = &omap44xx_l3_hwmod_class,
+ .slaves = omap44xx_l3_instr_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_l3_instr_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* l3_main_2 -> l3_main_1 */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__l3_main_1 = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_l3_main_1_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> l3_main_1 */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l3_main_1 = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_l3_main_1_hwmod,
+ .clk = "l4_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mpu -> l3_main_1 */
+static struct omap_hwmod_ocp_if omap44xx_mpu__l3_main_1 = {
+ .master = &omap44xx_mpu_hwmod,
+ .slave = &omap44xx_l3_main_1_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_1 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_l3_main_1_slaves[] = {
+ &omap44xx_l3_main_2__l3_main_1,
+ &omap44xx_l4_cfg__l3_main_1,
+ &omap44xx_mpu__l3_main_1,
+};
+
+static struct omap_hwmod omap44xx_l3_main_1_hwmod = {
+ .name = "l3_main_1",
+ .class = &omap44xx_l3_hwmod_class,
+ .slaves = omap44xx_l3_main_1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_l3_main_1_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* l3_main_2 interface data */
+/* l3_main_1 -> l3_main_2 */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l3_main_2 = {
+ .master = &omap44xx_l3_main_1_hwmod,
+ .slave = &omap44xx_l3_main_2_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> l3_main_2 */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l3_main_2 = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_l3_main_2_hwmod,
+ .clk = "l4_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_2 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_l3_main_2_slaves[] = {
+ &omap44xx_l3_main_1__l3_main_2,
+ &omap44xx_l4_cfg__l3_main_2,
+};
+
+static struct omap_hwmod omap44xx_l3_main_2_hwmod = {
+ .name = "l3_main_2",
+ .class = &omap44xx_l3_hwmod_class,
+ .slaves = omap44xx_l3_main_2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_l3_main_2_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* l3_main_3 interface data */
+/* l3_main_1 -> l3_main_3 */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l3_main_3 = {
+ .master = &omap44xx_l3_main_1_hwmod,
+ .slave = &omap44xx_l3_main_3_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_2 -> l3_main_3 */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__l3_main_3 = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_l3_main_3_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> l3_main_3 */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l3_main_3 = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_l3_main_3_hwmod,
+ .clk = "l4_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_3 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_l3_main_3_slaves[] = {
+ &omap44xx_l3_main_1__l3_main_3,
+ &omap44xx_l3_main_2__l3_main_3,
+ &omap44xx_l4_cfg__l3_main_3,
+};
+
+static struct omap_hwmod omap44xx_l3_main_3_hwmod = {
+ .name = "l3_main_3",
+ .class = &omap44xx_l3_hwmod_class,
+ .slaves = omap44xx_l3_main_3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_l3_main_3_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'l4' class
+ * instance(s): l4_abe, l4_cfg, l4_per, l4_wkup
+ */
+static struct omap_hwmod_class omap44xx_l4_hwmod_class = {
+ .name = "l4",
+};
+
+/* l4_abe interface data */
+/* l3_main_1 -> l4_abe */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l4_abe = {
+ .master = &omap44xx_l3_main_1_hwmod,
+ .slave = &omap44xx_l4_abe_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mpu -> l4_abe */
+static struct omap_hwmod_ocp_if omap44xx_mpu__l4_abe = {
+ .master = &omap44xx_mpu_hwmod,
+ .slave = &omap44xx_l4_abe_hwmod,
+ .clk = "ocp_abe_iclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_abe slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_l4_abe_slaves[] = {
+ &omap44xx_l3_main_1__l4_abe,
+ &omap44xx_mpu__l4_abe,
+};
+
+static struct omap_hwmod omap44xx_l4_abe_hwmod = {
+ .name = "l4_abe",
+ .class = &omap44xx_l4_hwmod_class,
+ .slaves = omap44xx_l4_abe_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_l4_abe_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* l4_cfg interface data */
+/* l3_main_1 -> l4_cfg */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l4_cfg = {
+ .master = &omap44xx_l3_main_1_hwmod,
+ .slave = &omap44xx_l4_cfg_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_l4_cfg_slaves[] = {
+ &omap44xx_l3_main_1__l4_cfg,
+};
+
+static struct omap_hwmod omap44xx_l4_cfg_hwmod = {
+ .name = "l4_cfg",
+ .class = &omap44xx_l4_hwmod_class,
+ .slaves = omap44xx_l4_cfg_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_l4_cfg_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* l4_per interface data */
+/* l3_main_2 -> l4_per */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__l4_per = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_l4_per_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_l4_per_slaves[] = {
+ &omap44xx_l3_main_2__l4_per,
+};
+
+static struct omap_hwmod omap44xx_l4_per_hwmod = {
+ .name = "l4_per",
+ .class = &omap44xx_l4_hwmod_class,
+ .slaves = omap44xx_l4_per_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_l4_per_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* l4_wkup interface data */
+/* l4_cfg -> l4_wkup */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l4_wkup = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_l4_wkup_hwmod,
+ .clk = "l4_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_l4_wkup_slaves[] = {
+ &omap44xx_l4_cfg__l4_wkup,
+};
+
+static struct omap_hwmod omap44xx_l4_wkup_hwmod = {
+ .name = "l4_wkup",
+ .class = &omap44xx_l4_hwmod_class,
+ .slaves = omap44xx_l4_wkup_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_l4_wkup_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'mpu_bus' class
+ * instance(s): mpu_private
+ */
+static struct omap_hwmod_class omap44xx_mpu_bus_hwmod_class = {
+ .name = "mpu_bus",
+};
+
+/* mpu_private interface data */
+/* mpu -> mpu_private */
+static struct omap_hwmod_ocp_if omap44xx_mpu__mpu_private = {
+ .master = &omap44xx_mpu_hwmod,
+ .slave = &omap44xx_mpu_private_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mpu_private slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_mpu_private_slaves[] = {
+ &omap44xx_mpu__mpu_private,
+};
+
+static struct omap_hwmod omap44xx_mpu_private_hwmod = {
+ .name = "mpu_private",
+ .class = &omap44xx_mpu_bus_hwmod_class,
+ .slaves = omap44xx_mpu_private_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_mpu_private_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'mpu' class
+ * mpu sub-system
+ */
+
+static struct omap_hwmod_class omap44xx_mpu_hwmod_class = {
+ .name = "mpu",
+};
+
+/* mpu */
+static struct omap_hwmod_irq_info omap44xx_mpu_irqs[] = {
+ { .name = "pl310", .irq = 0 + OMAP44XX_IRQ_GIC_START },
+ { .name = "cti0", .irq = 1 + OMAP44XX_IRQ_GIC_START },
+ { .name = "cti1", .irq = 2 + OMAP44XX_IRQ_GIC_START },
+};
+
+/* mpu master ports */
+static struct omap_hwmod_ocp_if *omap44xx_mpu_masters[] = {
+ &omap44xx_mpu__l3_main_1,
+ &omap44xx_mpu__l4_abe,
+ &omap44xx_mpu__dmm,
+};
+
+static struct omap_hwmod omap44xx_mpu_hwmod = {
+ .name = "mpu",
+ .class = &omap44xx_mpu_hwmod_class,
+ .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
+ .mpu_irqs = omap44xx_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mpu_irqs),
+ .main_clk = "dpll_mpu_m2_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_MPU_MPU_CLKCTRL,
+ },
+ },
+ .masters = omap44xx_mpu_masters,
+ .masters_cnt = ARRAY_SIZE(omap44xx_mpu_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'wd_timer' class
+ * 32-bit watchdog upward counter that generates a pulse on the reset pin on
+ * overflow condition
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_wd_timer_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE |
+ SYSC_HAS_SOFTRESET),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+/*
+ * 'uart' class
+ * universal asynchronous receiver/transmitter (uart)
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_uart_sysc = {
+ .rev_offs = 0x0050,
+ .sysc_offs = 0x0054,
+ .syss_offs = 0x0058,
+ .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_wd_timer_hwmod_class = {
+ .name = "wd_timer",
+ .sysc = &omap44xx_wd_timer_sysc,
+};
+
+/* wd_timer2 */
+static struct omap_hwmod omap44xx_wd_timer2_hwmod;
+static struct omap_hwmod_irq_info omap44xx_wd_timer2_irqs[] = {
+ { .irq = 80 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_wd_timer2_addrs[] = {
+ {
+ .pa_start = 0x4a314000,
+ .pa_end = 0x4a31407f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_class omap44xx_uart_hwmod_class = {
+ .name = "uart",
+ .sysc = &omap44xx_uart_sysc,
+};
+
+/* uart1 */
+static struct omap_hwmod omap44xx_uart1_hwmod;
+static struct omap_hwmod_irq_info omap44xx_uart1_irqs[] = {
+ { .irq = 72 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_uart1_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 48 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx", .dma_req = 49 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_uart1_addrs[] = {
+ {
+ .pa_start = 0x4806a000,
+ .pa_end = 0x4806a0ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> uart1 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__uart1 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_uart1_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_uart1_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_uart1_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* uart1 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_uart1_slaves[] = {
+ &omap44xx_l4_per__uart1,
+};
+
+static struct omap_hwmod omap44xx_uart1_hwmod = {
+ .name = "uart1",
+ .class = &omap44xx_uart_hwmod_class,
+ .mpu_irqs = omap44xx_uart1_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_uart1_irqs),
+ .sdma_reqs = omap44xx_uart1_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_uart1_sdma_reqs),
+ .main_clk = "uart1_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_UART1_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_uart1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_uart1_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* uart2 */
+static struct omap_hwmod omap44xx_uart2_hwmod;
+static struct omap_hwmod_irq_info omap44xx_uart2_irqs[] = {
+ { .irq = 73 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_uart2_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 50 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx", .dma_req = 51 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_uart2_addrs[] = {
+ {
+ .pa_start = 0x4806c000,
+ .pa_end = 0x4806c0ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_wkup -> wd_timer2 */
+static struct omap_hwmod_ocp_if omap44xx_l4_wkup__wd_timer2 = {
+ .master = &omap44xx_l4_wkup_hwmod,
+ .slave = &omap44xx_wd_timer2_hwmod,
+ .clk = "l4_wkup_clk_mux_ck",
+ .addr = omap44xx_wd_timer2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_wd_timer2_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* wd_timer2 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_wd_timer2_slaves[] = {
+ &omap44xx_l4_wkup__wd_timer2,
+};
+
+static struct omap_hwmod omap44xx_wd_timer2_hwmod = {
+ .name = "wd_timer2",
+ .class = &omap44xx_wd_timer_hwmod_class,
+ .mpu_irqs = omap44xx_wd_timer2_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_wd_timer2_irqs),
+ .main_clk = "wd_timer2_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_WKUP_WDT2_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_wd_timer2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_wd_timer2_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* wd_timer3 */
+static struct omap_hwmod omap44xx_wd_timer3_hwmod;
+static struct omap_hwmod_irq_info omap44xx_wd_timer3_irqs[] = {
+ { .irq = 36 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_wd_timer3_addrs[] = {
+ {
+ .pa_start = 0x40130000,
+ .pa_end = 0x4013007f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> uart2 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__uart2 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_uart2_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_uart2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_uart2_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* uart2 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_uart2_slaves[] = {
+ &omap44xx_l4_per__uart2,
+};
+
+static struct omap_hwmod omap44xx_uart2_hwmod = {
+ .name = "uart2",
+ .class = &omap44xx_uart_hwmod_class,
+ .mpu_irqs = omap44xx_uart2_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_uart2_irqs),
+ .sdma_reqs = omap44xx_uart2_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_uart2_sdma_reqs),
+ .main_clk = "uart2_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_UART2_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_uart2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_uart2_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* uart3 */
+static struct omap_hwmod omap44xx_uart3_hwmod;
+static struct omap_hwmod_irq_info omap44xx_uart3_irqs[] = {
+ { .irq = 74 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_uart3_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 52 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx", .dma_req = 53 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_uart3_addrs[] = {
+ {
+ .pa_start = 0x48020000,
+ .pa_end = 0x480200ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_abe -> wd_timer3 */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__wd_timer3 = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_wd_timer3_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_wd_timer3_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_wd_timer3_addrs),
+ .user = OCP_USER_MPU,
+};
+
+/* l4_abe -> wd_timer3 (dma) */
+static struct omap_hwmod_addr_space omap44xx_wd_timer3_dma_addrs[] = {
+ {
+ .pa_start = 0x49030000,
+ .pa_end = 0x4903007f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> uart3 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__uart3 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_uart3_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_uart3_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_uart3_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* uart3 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_uart3_slaves[] = {
+ &omap44xx_l4_per__uart3,
+};
+
+static struct omap_hwmod omap44xx_uart3_hwmod = {
+ .name = "uart3",
+ .class = &omap44xx_uart_hwmod_class,
+ .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
+ .mpu_irqs = omap44xx_uart3_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_uart3_irqs),
+ .sdma_reqs = omap44xx_uart3_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_uart3_sdma_reqs),
+ .main_clk = "uart3_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_UART3_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_uart3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_uart3_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* uart4 */
+static struct omap_hwmod omap44xx_uart4_hwmod;
+static struct omap_hwmod_irq_info omap44xx_uart4_irqs[] = {
+ { .irq = 70 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_uart4_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 54 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx", .dma_req = 55 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_uart4_addrs[] = {
+ {
+ .pa_start = 0x4806e000,
+ .pa_end = 0x4806e0ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__wd_timer3_dma = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_wd_timer3_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_wd_timer3_dma_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_wd_timer3_dma_addrs),
+ .user = OCP_USER_SDMA,
+};
+
+/* wd_timer3 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_wd_timer3_slaves[] = {
+ &omap44xx_l4_abe__wd_timer3,
+ &omap44xx_l4_abe__wd_timer3_dma,
+};
+
+static struct omap_hwmod omap44xx_wd_timer3_hwmod = {
+ .name = "wd_timer3",
+ .class = &omap44xx_wd_timer_hwmod_class,
+ .mpu_irqs = omap44xx_wd_timer3_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_wd_timer3_irqs),
+ .main_clk = "wd_timer3_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM1_ABE_WDT3_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_wd_timer3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_wd_timer3_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* l4_per -> uart4 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__uart4 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_uart4_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_uart4_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_uart4_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* uart4 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_uart4_slaves[] = {
+ &omap44xx_l4_per__uart4,
+};
+
+static struct omap_hwmod omap44xx_uart4_hwmod = {
+ .name = "uart4",
+ .class = &omap44xx_uart_hwmod_class,
+ .mpu_irqs = omap44xx_uart4_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_uart4_irqs),
+ .sdma_reqs = omap44xx_uart4_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_uart4_sdma_reqs),
+ .main_clk = "uart4_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_UART4_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_uart4_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_uart4_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
+ /* dmm class */
+ &omap44xx_dmm_hwmod,
+ /* emif_fw class */
+ &omap44xx_emif_fw_hwmod,
+ /* l3 class */
+ &omap44xx_l3_instr_hwmod,
+ &omap44xx_l3_main_1_hwmod,
+ &omap44xx_l3_main_2_hwmod,
+ &omap44xx_l3_main_3_hwmod,
+ /* l4 class */
+ &omap44xx_l4_abe_hwmod,
+ &omap44xx_l4_cfg_hwmod,
+ &omap44xx_l4_per_hwmod,
+ &omap44xx_l4_wkup_hwmod,
+ /* mpu_bus class */
+ &omap44xx_mpu_private_hwmod,
+
+ /* mpu class */
+ &omap44xx_mpu_hwmod,
+ /* wd_timer class */
+ &omap44xx_wd_timer2_hwmod,
+ &omap44xx_wd_timer3_hwmod,
+
+ /* uart class */
+ &omap44xx_uart1_hwmod,
+ &omap44xx_uart2_hwmod,
+ &omap44xx_uart3_hwmod,
+ &omap44xx_uart4_hwmod,
+ NULL,
+};
+
+int __init omap44xx_hwmod_init(void)
+{
+ return omap_hwmod_init(omap44xx_hwmods);
+}
+
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index 723b44e252fd..5e81517a7af2 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -31,12 +31,17 @@
#include <plat/board.h>
#include <plat/powerdomain.h>
#include <plat/clockdomain.h>
+#include <plat/dmtimer.h>
#include "prm.h"
#include "cm.h"
#include "pm.h"
int omap2_pm_debug;
+u32 enable_off_mode;
+u32 sleep_while_idle;
+u32 wakeup_timer_seconds;
+u32 wakeup_timer_milliseconds;
#define DUMP_PRM_MOD_REG(mod, reg) \
regs[reg_count].name = #mod "." #reg; \
@@ -162,7 +167,7 @@ void omap2_pm_dump(int mode, int resume, unsigned int us)
static void pm_dbg_regset_store(u32 *ptr);
-struct dentry *pm_dbg_dir;
+static struct dentry *pm_dbg_dir;
static int pm_dbg_init_done;
@@ -349,6 +354,23 @@ void pm_dbg_update_time(struct powerdomain *pwrdm, int prev)
pwrdm->timer = t;
}
+void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds)
+{
+ u32 tick_rate, cycles;
+
+ if (!seconds && !milliseconds)
+ return;
+
+ tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup));
+ cycles = tick_rate * seconds + tick_rate * milliseconds / 1000;
+ omap_dm_timer_stop(gptimer_wakeup);
+ omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles);
+
+ pr_info("PM: Resume timer in %u.%03u secs"
+ " (%d ticks at %d ticks/sec.)\n",
+ seconds, milliseconds, cycles, tick_rate);
+}
+
static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user)
{
struct seq_file *s = (struct seq_file *)user;
@@ -494,8 +516,10 @@ int pm_dbg_regset_init(int reg_set)
static int pwrdm_suspend_get(void *data, u64 *val)
{
- int ret;
- ret = omap3_pm_get_suspend_state((struct powerdomain *)data);
+ int ret = -EINVAL;
+
+ if (cpu_is_omap34xx())
+ ret = omap3_pm_get_suspend_state((struct powerdomain *)data);
*val = ret;
if (ret >= 0)
@@ -505,7 +529,10 @@ static int pwrdm_suspend_get(void *data, u64 *val)
static int pwrdm_suspend_set(void *data, u64 val)
{
- return omap3_pm_set_suspend_state((struct powerdomain *)data, (int)val);
+ if (cpu_is_omap34xx())
+ return omap3_pm_set_suspend_state(
+ (struct powerdomain *)data, (int)val);
+ return -EINVAL;
}
DEFINE_SIMPLE_ATTRIBUTE(pwrdm_suspend_fops, pwrdm_suspend_get,
@@ -553,8 +580,10 @@ static int option_set(void *data, u64 val)
*option = val;
- if (option == &enable_off_mode)
- omap3_pm_off_mode_enable(val);
+ if (option == &enable_off_mode) {
+ if (cpu_is_omap34xx())
+ omap3_pm_off_mode_enable(val);
+ }
return 0;
}
@@ -609,6 +638,9 @@ static int __init pm_dbg_init(void)
&sleep_while_idle, &pm_dbg_option_fops);
(void) debugfs_create_file("wakeup_timer_seconds", S_IRUGO | S_IWUGO, d,
&wakeup_timer_seconds, &pm_dbg_option_fops);
+ (void) debugfs_create_file("wakeup_timer_milliseconds",
+ S_IRUGO | S_IWUGO, d, &wakeup_timer_milliseconds,
+ &pm_dbg_option_fops);
pm_dbg_init_done = 1;
return 0;
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 68f9f2e95891..59ca03b0e691 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -18,11 +18,15 @@
#include <plat/omap_device.h>
#include <plat/common.h>
+#include <plat/powerdomain.h>
+#include <plat/clockdomain.h>
+
static struct omap_device_pm_latency *pm_lats;
static struct device *mpu_dev;
-static struct device *dsp_dev;
+static struct device *iva_dev;
static struct device *l3_dev;
+static struct device *dsp_dev;
struct device *omap2_get_mpuss_device(void)
{
@@ -30,10 +34,10 @@ struct device *omap2_get_mpuss_device(void)
return mpu_dev;
}
-struct device *omap2_get_dsp_device(void)
+struct device *omap2_get_iva_device(void)
{
- WARN_ON_ONCE(!dsp_dev);
- return dsp_dev;
+ WARN_ON_ONCE(!iva_dev);
+ return iva_dev;
}
struct device *omap2_get_l3_device(void)
@@ -42,6 +46,13 @@ struct device *omap2_get_l3_device(void)
return l3_dev;
}
+struct device *omap4_get_dsp_device(void)
+{
+ WARN_ON_ONCE(!dsp_dev);
+ return dsp_dev;
+}
+EXPORT_SYMBOL(omap4_get_dsp_device);
+
/* static int _init_omap_device(struct omap_hwmod *oh, void *user) */
static int _init_omap_device(char *name, struct device **new_dev)
{
@@ -69,8 +80,60 @@ static int _init_omap_device(char *name, struct device **new_dev)
static void omap2_init_processor_devices(void)
{
_init_omap_device("mpu", &mpu_dev);
- _init_omap_device("iva", &dsp_dev);
- _init_omap_device("l3_main", &l3_dev);
+ _init_omap_device("iva", &iva_dev);
+ if (cpu_is_omap44xx()) {
+ _init_omap_device("l3_main_1", &l3_dev);
+ _init_omap_device("dsp", &dsp_dev);
+ } else {
+ _init_omap_device("l3_main", &l3_dev);
+ }
+}
+
+/*
+ * This sets pwrdm state (other than mpu & core. Currently only ON &
+ * RET are supported. Function is assuming that clkdm doesn't have
+ * hw_sup mode enabled.
+ */
+int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
+{
+ u32 cur_state;
+ int sleep_switch = 0;
+ int ret = 0;
+
+ if (pwrdm == NULL || IS_ERR(pwrdm))
+ return -EINVAL;
+
+ while (!(pwrdm->pwrsts & (1 << state))) {
+ if (state == PWRDM_POWER_OFF)
+ return ret;
+ state--;
+ }
+
+ cur_state = pwrdm_read_next_pwrst(pwrdm);
+ if (cur_state == state)
+ return ret;
+
+ if (pwrdm_read_pwrst(pwrdm) < PWRDM_POWER_ON) {
+ omap2_clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
+ sleep_switch = 1;
+ pwrdm_wait_transition(pwrdm);
+ }
+
+ ret = pwrdm_set_next_pwrst(pwrdm, state);
+ if (ret) {
+ printk(KERN_ERR "Unable to set state of powerdomain: %s\n",
+ pwrdm->name);
+ goto err;
+ }
+
+ if (sleep_switch) {
+ omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
+ pwrdm_wait_transition(pwrdm);
+ pwrdm_state_switch(pwrdm);
+ }
+
+err:
+ return ret;
}
static int __init omap2_common_pm_init(void)
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 3de6ece23fc8..0d75bfd1fdbe 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -13,14 +13,11 @@
#include <plat/powerdomain.h>
-extern u32 enable_off_mode;
-extern u32 sleep_while_idle;
-
extern void *omap3_secure_ram_storage;
extern void omap3_pm_off_mode_enable(int);
extern void omap_sram_idle(void);
extern int omap3_can_sleep(void);
-extern int set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
+extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
extern int omap3_idle_init(void);
struct cpuidle_params {
@@ -48,10 +45,16 @@ extern struct omap_dm_timer *gptimer_wakeup;
#ifdef CONFIG_PM_DEBUG
extern void omap2_pm_dump(int mode, int resume, unsigned int us);
+extern void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds);
extern int omap2_pm_debug;
+extern u32 enable_off_mode;
+extern u32 sleep_while_idle;
#else
#define omap2_pm_dump(mode, resume, us) do {} while (0);
+#define omap2_pm_wakeup_on_timer(seconds, milliseconds) do {} while (0);
#define omap2_pm_debug 0
+#define enable_off_mode 0
+#define sleep_while_idle 0
#endif
#if defined(CONFIG_CPU_IDLE)
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index 6aeedeacdad8..a40457d81927 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -38,7 +38,6 @@
#include <mach/irqs.h>
#include <plat/clock.h>
#include <plat/sram.h>
-#include <plat/control.h>
#include <plat/dma.h>
#include <plat/board.h>
@@ -48,6 +47,7 @@
#include "cm-regbits-24xx.h"
#include "sdrc.h"
#include "pm.h"
+#include "control.h"
#include <plat/powerdomain.h>
#include <plat/clockdomain.h>
@@ -245,6 +245,8 @@ static int omap2_can_sleep(void)
{
if (omap2_fclks_active())
return 0;
+ if (!omap_uart_can_sleep())
+ return 0;
if (osc_ck->usecount > 1)
return 0;
if (omap_dma_running())
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 7b03426c72a3..75c0cd13ad8e 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -32,13 +32,11 @@
#include <plat/sram.h>
#include <plat/clockdomain.h>
#include <plat/powerdomain.h>
-#include <plat/control.h>
#include <plat/serial.h>
#include <plat/sdrc.h>
#include <plat/prcm.h>
#include <plat/gpmc.h>
#include <plat/dma.h>
-#include <plat/dmtimer.h>
#include <asm/tlbflush.h>
@@ -49,16 +47,12 @@
#include "prm.h"
#include "pm.h"
#include "sdrc.h"
+#include "control.h"
/* Scratchpad offsets */
-#define OMAP343X_TABLE_ADDRESS_OFFSET 0x31
-#define OMAP343X_TABLE_VALUE_OFFSET 0x30
-#define OMAP343X_CONTROL_REG_VALUE_OFFSET 0x32
-
-u32 enable_off_mode;
-u32 sleep_while_idle;
-u32 wakeup_timer_seconds;
-u32 wakeup_timer_milliseconds;
+#define OMAP343X_TABLE_ADDRESS_OFFSET 0xc4
+#define OMAP343X_TABLE_VALUE_OFFSET 0xc0
+#define OMAP343X_CONTROL_REG_VALUE_OFFSET 0xc8
struct power_state {
struct powerdomain *pwrdm;
@@ -316,7 +310,7 @@ static void restore_control_register(u32 val)
/* Function to restore the table entry that was modified for enabling MMU */
static void restore_table_entry(void)
{
- u32 *scratchpad_address;
+ void __iomem *scratchpad_address;
u32 previous_value, control_reg_value;
u32 *address;
@@ -351,7 +345,6 @@ void omap_sram_idle(void)
int core_next_state = PWRDM_POWER_ON;
int core_prev_state, per_prev_state;
u32 sdrc_pwr = 0;
- int per_state_modified = 0;
if (!_omap_sram_idle)
return;
@@ -385,9 +378,9 @@ void omap_sram_idle(void)
/* Enable IO-PAD and IO-CHAIN wakeups */
per_next_state = pwrdm_read_next_pwrst(per_pwrdm);
core_next_state = pwrdm_read_next_pwrst(core_pwrdm);
- if (omap3_has_io_wakeup() && \
- (per_next_state < PWRDM_POWER_ON ||
- core_next_state < PWRDM_POWER_ON)) {
+ if (omap3_has_io_wakeup() &&
+ (per_next_state < PWRDM_POWER_ON ||
+ core_next_state < PWRDM_POWER_ON)) {
prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN);
omap3_enable_io_chain();
}
@@ -395,20 +388,12 @@ void omap_sram_idle(void)
/* PER */
if (per_next_state < PWRDM_POWER_ON) {
omap_uart_prepare_idle(2);
+ omap_uart_prepare_idle(3);
omap2_gpio_prepare_for_idle(per_next_state);
- if (per_next_state == PWRDM_POWER_OFF) {
- if (core_next_state == PWRDM_POWER_ON) {
- per_next_state = PWRDM_POWER_RET;
- pwrdm_set_next_pwrst(per_pwrdm, per_next_state);
- per_state_modified = 1;
- } else
+ if (per_next_state == PWRDM_POWER_OFF)
omap3_per_save_context();
- }
}
- if (pwrdm_read_pwrst(cam_pwrdm) == PWRDM_POWER_ON)
- omap2_clkdm_deny_idle(mpu_pwrdm->pwrdm_clkdms[0]);
-
/* CORE */
if (core_next_state < PWRDM_POWER_ON) {
omap_uart_prepare_idle(0);
@@ -475,8 +460,7 @@ void omap_sram_idle(void)
if (per_prev_state == PWRDM_POWER_OFF)
omap3_per_restore_context();
omap_uart_resume_idle(2);
- if (per_state_modified)
- pwrdm_set_next_pwrst(per_pwrdm, PWRDM_POWER_OFF);
+ omap_uart_resume_idle(3);
}
/* Disable IO-PAD and IO-CHAIN wakeup */
@@ -501,51 +485,6 @@ int omap3_can_sleep(void)
return 1;
}
-/* This sets pwrdm state (other than mpu & core. Currently only ON &
- * RET are supported. Function is assuming that clkdm doesn't have
- * hw_sup mode enabled. */
-int set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
-{
- u32 cur_state;
- int sleep_switch = 0;
- int ret = 0;
-
- if (pwrdm == NULL || IS_ERR(pwrdm))
- return -EINVAL;
-
- while (!(pwrdm->pwrsts & (1 << state))) {
- if (state == PWRDM_POWER_OFF)
- return ret;
- state--;
- }
-
- cur_state = pwrdm_read_next_pwrst(pwrdm);
- if (cur_state == state)
- return ret;
-
- if (pwrdm_read_pwrst(pwrdm) < PWRDM_POWER_ON) {
- omap2_clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
- sleep_switch = 1;
- pwrdm_wait_transition(pwrdm);
- }
-
- ret = pwrdm_set_next_pwrst(pwrdm, state);
- if (ret) {
- printk(KERN_ERR "Unable to set state of powerdomain: %s\n",
- pwrdm->name);
- goto err;
- }
-
- if (sleep_switch) {
- omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
- pwrdm_wait_transition(pwrdm);
- pwrdm_state_switch(pwrdm);
- }
-
-err:
- return ret;
-}
-
static void omap3_pm_idle(void)
{
local_irq_disable();
@@ -567,23 +506,6 @@ out:
#ifdef CONFIG_SUSPEND
static suspend_state_t suspend_state;
-static void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds)
-{
- u32 tick_rate, cycles;
-
- if (!seconds && !milliseconds)
- return;
-
- tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup));
- cycles = tick_rate * seconds + tick_rate * milliseconds / 1000;
- omap_dm_timer_stop(gptimer_wakeup);
- omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles);
-
- pr_info("PM: Resume timer in %u.%03u secs"
- " (%d ticks at %d ticks/sec.)\n",
- seconds, milliseconds, cycles, tick_rate);
-}
-
static int omap3_pm_prepare(void)
{
disable_hlt();
@@ -604,7 +526,7 @@ static int omap3_pm_suspend(void)
pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm);
/* Set ones wanted by suspend */
list_for_each_entry(pwrst, &pwrst_list, node) {
- if (set_pwrdm_state(pwrst->pwrdm, pwrst->next_state))
+ if (omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state))
goto restore;
if (pwrdm_clear_all_prev_pwrst(pwrst->pwrdm))
goto restore;
@@ -625,7 +547,7 @@ restore:
pwrst->pwrdm->name, pwrst->next_state);
ret = -1;
}
- set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state);
+ omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state);
}
if (ret)
printk(KERN_ERR "Could not enter target state in pm_suspend\n");
@@ -756,6 +678,14 @@ static void __init omap3_d2d_idle(void)
static void __init prcm_setup_regs(void)
{
+ u32 omap3630_auto_uart4_mask = cpu_is_omap3630() ?
+ OMAP3630_AUTO_UART4_MASK : 0;
+ u32 omap3630_en_uart4_mask = cpu_is_omap3630() ?
+ OMAP3630_EN_UART4_MASK : 0;
+ u32 omap3630_grpsel_uart4_mask = cpu_is_omap3630() ?
+ OMAP3630_GRPSEL_UART4_MASK : 0;
+
+
/* XXX Reset all wkdeps. This should be done when initializing
* powerdomains */
prm_write_mod_reg(0, OMAP3430_IVA2_MOD, PM_WKDEP);
@@ -842,6 +772,7 @@ static void __init prcm_setup_regs(void)
CM_AUTOIDLE);
cm_write_mod_reg(
+ omap3630_auto_uart4_mask |
OMAP3430_AUTO_GPIO6_MASK |
OMAP3430_AUTO_GPIO5_MASK |
OMAP3430_AUTO_GPIO4_MASK |
@@ -918,14 +849,16 @@ static void __init prcm_setup_regs(void)
OMAP3430_DSS_MOD, PM_WKEN);
/* Enable wakeups in PER */
- prm_write_mod_reg(OMAP3430_EN_GPIO2_MASK | OMAP3430_EN_GPIO3_MASK |
+ prm_write_mod_reg(omap3630_en_uart4_mask |
+ OMAP3430_EN_GPIO2_MASK | OMAP3430_EN_GPIO3_MASK |
OMAP3430_EN_GPIO4_MASK | OMAP3430_EN_GPIO5_MASK |
OMAP3430_EN_GPIO6_MASK | OMAP3430_EN_UART3_MASK |
OMAP3430_EN_MCBSP2_MASK | OMAP3430_EN_MCBSP3_MASK |
OMAP3430_EN_MCBSP4_MASK,
OMAP3430_PER_MOD, PM_WKEN);
/* and allow them to wake up MPU */
- prm_write_mod_reg(OMAP3430_GRPSEL_GPIO2_MASK |
+ prm_write_mod_reg(omap3630_grpsel_uart4_mask |
+ OMAP3430_GRPSEL_GPIO2_MASK |
OMAP3430_GRPSEL_GPIO3_MASK |
OMAP3430_GRPSEL_GPIO4_MASK |
OMAP3430_GRPSEL_GPIO5_MASK |
@@ -974,7 +907,7 @@ void omap3_pm_off_mode_enable(int enable)
list_for_each_entry(pwrst, &pwrst_list, node) {
pwrst->next_state = state;
- set_pwrdm_state(pwrst->pwrdm, state);
+ omap_set_pwrdm_state(pwrst->pwrdm, state);
}
}
@@ -1019,7 +952,7 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
if (pwrdm_has_hdwr_sar(pwrdm))
pwrdm_enable_hdwr_sar(pwrdm);
- return set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
+ return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
}
/*
@@ -1029,9 +962,6 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
*/
static int __init clkdms_setup(struct clockdomain *clkdm, void *unused)
{
- clkdm_clear_all_wkdeps(clkdm);
- clkdm_clear_all_sleepdeps(clkdm);
-
if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
omap2_clkdm_allow_idle(clkdm);
else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
diff --git a/arch/arm/mach-omap2/pm_bus.c b/arch/arm/mach-omap2/pm_bus.c
new file mode 100644
index 000000000000..784989f8f2f5
--- /dev/null
+++ b/arch/arm/mach-omap2/pm_bus.c
@@ -0,0 +1,85 @@
+/*
+ * Runtime PM support code for OMAP
+ *
+ * Author: Kevin Hilman, Deep Root Systems, LLC
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+
+#include <plat/omap_device.h>
+#include <plat/omap-pm.h>
+
+#ifdef CONFIG_PM_RUNTIME
+int omap_pm_runtime_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ int r, ret = 0;
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ ret = pm_generic_runtime_suspend(dev);
+
+ if (!ret && dev->parent == &omap_device_parent) {
+ r = omap_device_idle(pdev);
+ WARN_ON(r);
+ }
+
+ return ret;
+};
+
+int omap_pm_runtime_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ int r;
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ if (dev->parent == &omap_device_parent) {
+ r = omap_device_enable(pdev);
+ WARN_ON(r);
+ }
+
+ return pm_generic_runtime_resume(dev);
+};
+#else
+#define omap_pm_runtime_suspend NULL
+#define omap_pm_runtime_resume NULL
+#endif /* CONFIG_PM_RUNTIME */
+
+static int __init omap_pm_runtime_init(void)
+{
+ const struct dev_pm_ops *pm;
+ struct dev_pm_ops *omap_pm;
+
+ pm = platform_bus_get_pm_ops();
+ if (!pm) {
+ pr_err("%s: unable to get dev_pm_ops from platform_bus\n",
+ __func__);
+ return -ENODEV;
+ }
+
+ omap_pm = kmemdup(pm, sizeof(struct dev_pm_ops), GFP_KERNEL);
+ if (!omap_pm) {
+ pr_err("%s: unable to alloc memory for new dev_pm_ops\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ omap_pm->runtime_suspend = omap_pm_runtime_suspend;
+ omap_pm->runtime_resume = omap_pm_runtime_resume;
+
+ platform_bus_set_pm_ops(omap_pm);
+
+ return 0;
+}
+core_initcall(omap_pm_runtime_init);
diff --git a/arch/arm/mach-omap2/powerdomains44xx.h b/arch/arm/mach-omap2/powerdomains44xx.h
index c7219513472a..9c01b55d6102 100644
--- a/arch/arm/mach-omap2/powerdomains44xx.h
+++ b/arch/arm/mach-omap2/powerdomains44xx.h
@@ -98,7 +98,7 @@ static struct powerdomain dss_44xx_pwrdm = {
.prcm_offs = OMAP4430_PRM_DSS_MOD,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_OFF_RET_ON,
- .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ .pwrsts_logic_ret = PWRSTS_OFF,
.banks = 1,
.pwrsts_mem_ret = {
[0] = PWRDM_POWER_OFF, /* dss_mem */
diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h
index 995b7edbf18d..298a22a754e2 100644
--- a/arch/arm/mach-omap2/prcm-common.h
+++ b/arch/arm/mach-omap2/prcm-common.h
@@ -382,6 +382,9 @@
#define OMAP3430_EN_MPU_SHIFT 1
/* CM_FCLKEN_PER, CM_ICLKEN_PER, PM_WKEN_PER shared bits */
+
+#define OMAP3630_EN_UART4_MASK (1 << 18)
+#define OMAP3630_EN_UART4_SHIFT 18
#define OMAP3430_EN_GPIO6_MASK (1 << 17)
#define OMAP3430_EN_GPIO6_SHIFT 17
#define OMAP3430_EN_GPIO5_MASK (1 << 16)
@@ -422,6 +425,8 @@
#define OMAP3430_EN_MCBSP2_SHIFT 0
/* CM_IDLEST_PER, PM_WKST_PER shared bits */
+#define OMAP3630_ST_UART4_SHIFT 18
+#define OMAP3630_ST_UART4_MASK (1 << 18)
#define OMAP3430_ST_GPIO6_SHIFT 17
#define OMAP3430_ST_GPIO6_MASK (1 << 17)
#define OMAP3430_ST_GPIO5_SHIFT 16
diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c
index c20137497c92..a51846e3a6fa 100644
--- a/arch/arm/mach-omap2/prcm.c
+++ b/arch/arm/mach-omap2/prcm.c
@@ -26,13 +26,14 @@
#include <plat/common.h>
#include <plat/prcm.h>
#include <plat/irqs.h>
-#include <plat/control.h>
#include "clock.h"
#include "clock2xxx.h"
#include "cm.h"
#include "prm.h"
#include "prm-regbits-24xx.h"
+#include "prm-regbits-44xx.h"
+#include "control.h"
static void __iomem *prm_base;
static void __iomem *cm_base;
@@ -118,7 +119,7 @@ struct omap3_prcm_regs {
u32 wkup_pm_wken;
};
-struct omap3_prcm_regs prcm_context;
+static struct omap3_prcm_regs prcm_context;
u32 omap_prcm_get_reset_sources(void)
{
@@ -161,8 +162,8 @@ void omap_prcm_arch_reset(char mode, const char *cmd)
prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, prcm_offs,
OMAP2_RM_RSTCTRL);
if (cpu_is_omap44xx())
- prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, prcm_offs,
- OMAP4_RM_RSTCTRL);
+ prm_set_mod_reg_bits(OMAP4430_RST_GLOBAL_WARM_SW_MASK,
+ prcm_offs, OMAP4_RM_RSTCTRL);
}
static inline u32 __omap_prcm_read(void __iomem *base, s16 module, u16 reg)
@@ -215,6 +216,30 @@ u32 prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
return v;
}
+/* Read a PRM register, AND it, and shift the result down to bit 0 */
+u32 omap4_prm_read_bits_shift(void __iomem *reg, u32 mask)
+{
+ u32 v;
+
+ v = __raw_readl(reg);
+ v &= mask;
+ v >>= __ffs(mask);
+
+ return v;
+}
+
+/* Read-modify-write a register in a PRM module. Caller must lock */
+u32 omap4_prm_rmw_reg_bits(u32 mask, u32 bits, void __iomem *reg)
+{
+ u32 v;
+
+ v = __raw_readl(reg);
+ v &= ~mask;
+ v |= bits;
+ __raw_writel(v, reg);
+
+ return v;
+}
/* Read a register in a CM module */
u32 cm_read_mod_reg(s16 module, u16 idx)
{
diff --git a/arch/arm/mach-omap2/prm-regbits-34xx.h b/arch/arm/mach-omap2/prm-regbits-34xx.h
index 7fd6023edf96..9e63cb743a97 100644
--- a/arch/arm/mach-omap2/prm-regbits-34xx.h
+++ b/arch/arm/mach-omap2/prm-regbits-34xx.h
@@ -122,6 +122,7 @@
#define OMAP3430_MEMRETSTATE_MASK (1 << 8)
/* PM_MPUGRPSEL_PER, PM_IVA2GRPSEL_PER shared bits */
+#define OMAP3630_GRPSEL_UART4_MASK (1 << 18)
#define OMAP3430_GRPSEL_GPIO6_MASK (1 << 17)
#define OMAP3430_GRPSEL_GPIO5_MASK (1 << 16)
#define OMAP3430_GRPSEL_GPIO4_MASK (1 << 15)
diff --git a/arch/arm/mach-omap2/prm-regbits-44xx.h b/arch/arm/mach-omap2/prm-regbits-44xx.h
index 597be4a2b9ff..25b19b610177 100644
--- a/arch/arm/mach-omap2/prm-regbits-44xx.h
+++ b/arch/arm/mach-omap2/prm-regbits-44xx.h
@@ -1,8 +1,8 @@
/*
* OMAP44xx Power Management register bits
*
- * Copyright (C) 2009 Texas Instruments, Inc.
- * Copyright (C) 2009 Nokia Corporation
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ * Copyright (C) 2009-2010 Nokia Corporation
*
* Paul Walmsley (paul@pwsan.com)
* Rajendra Nayak (rnayak@ti.com)
@@ -30,587 +30,611 @@
* PRM_LDO_SRAM_MPU_SETUP
*/
#define OMAP4430_ABBOFF_ACT_EXPORT_SHIFT 1
-#define OMAP4430_ABBOFF_ACT_EXPORT_MASK BITFIELD(1, 1)
+#define OMAP4430_ABBOFF_ACT_EXPORT_MASK (1 << 1)
/*
* Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
* PRM_LDO_SRAM_MPU_SETUP
*/
#define OMAP4430_ABBOFF_SLEEP_EXPORT_SHIFT 2
-#define OMAP4430_ABBOFF_SLEEP_EXPORT_MASK BITFIELD(2, 2)
+#define OMAP4430_ABBOFF_SLEEP_EXPORT_MASK (1 << 2)
/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
#define OMAP4430_ABB_IVA_DONE_EN_SHIFT 31
-#define OMAP4430_ABB_IVA_DONE_EN_MASK BITFIELD(31, 31)
+#define OMAP4430_ABB_IVA_DONE_EN_MASK (1 << 31)
/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
#define OMAP4430_ABB_IVA_DONE_ST_SHIFT 31
-#define OMAP4430_ABB_IVA_DONE_ST_MASK BITFIELD(31, 31)
+#define OMAP4430_ABB_IVA_DONE_ST_MASK (1 << 31)
/* Used by PRM_IRQENABLE_MPU_2 */
#define OMAP4430_ABB_MPU_DONE_EN_SHIFT 7
-#define OMAP4430_ABB_MPU_DONE_EN_MASK BITFIELD(7, 7)
+#define OMAP4430_ABB_MPU_DONE_EN_MASK (1 << 7)
/* Used by PRM_IRQSTATUS_MPU_2 */
#define OMAP4430_ABB_MPU_DONE_ST_SHIFT 7
-#define OMAP4430_ABB_MPU_DONE_ST_MASK BITFIELD(7, 7)
+#define OMAP4430_ABB_MPU_DONE_ST_MASK (1 << 7)
/* Used by PRM_LDO_ABB_IVA_SETUP, PRM_LDO_ABB_MPU_SETUP */
#define OMAP4430_ACTIVE_FBB_SEL_SHIFT 2
-#define OMAP4430_ACTIVE_FBB_SEL_MASK BITFIELD(2, 2)
+#define OMAP4430_ACTIVE_FBB_SEL_MASK (1 << 2)
/* Used by PRM_LDO_ABB_IVA_SETUP, PRM_LDO_ABB_MPU_SETUP */
#define OMAP4430_ACTIVE_RBB_SEL_SHIFT 1
-#define OMAP4430_ACTIVE_RBB_SEL_MASK BITFIELD(1, 1)
+#define OMAP4430_ACTIVE_RBB_SEL_MASK (1 << 1)
/* Used by PM_ABE_PWRSTCTRL */
#define OMAP4430_AESSMEM_ONSTATE_SHIFT 16
-#define OMAP4430_AESSMEM_ONSTATE_MASK BITFIELD(16, 17)
+#define OMAP4430_AESSMEM_ONSTATE_MASK (0x3 << 16)
/* Used by PM_ABE_PWRSTCTRL */
#define OMAP4430_AESSMEM_RETSTATE_SHIFT 8
-#define OMAP4430_AESSMEM_RETSTATE_MASK BITFIELD(8, 8)
+#define OMAP4430_AESSMEM_RETSTATE_MASK (1 << 8)
/* Used by PM_ABE_PWRSTST */
#define OMAP4430_AESSMEM_STATEST_SHIFT 4
-#define OMAP4430_AESSMEM_STATEST_MASK BITFIELD(4, 5)
+#define OMAP4430_AESSMEM_STATEST_MASK (0x3 << 4)
/*
* Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
* PRM_LDO_SRAM_MPU_SETUP
*/
#define OMAP4430_AIPOFF_SHIFT 8
-#define OMAP4430_AIPOFF_MASK BITFIELD(8, 8)
+#define OMAP4430_AIPOFF_MASK (1 << 8)
/* Used by PRM_VOLTCTRL */
#define OMAP4430_AUTO_CTRL_VDD_CORE_L_SHIFT 0
-#define OMAP4430_AUTO_CTRL_VDD_CORE_L_MASK BITFIELD(0, 1)
+#define OMAP4430_AUTO_CTRL_VDD_CORE_L_MASK (0x3 << 0)
/* Used by PRM_VOLTCTRL */
#define OMAP4430_AUTO_CTRL_VDD_IVA_L_SHIFT 4
-#define OMAP4430_AUTO_CTRL_VDD_IVA_L_MASK BITFIELD(4, 5)
+#define OMAP4430_AUTO_CTRL_VDD_IVA_L_MASK (0x3 << 4)
/* Used by PRM_VOLTCTRL */
#define OMAP4430_AUTO_CTRL_VDD_MPU_L_SHIFT 2
-#define OMAP4430_AUTO_CTRL_VDD_MPU_L_MASK BITFIELD(2, 3)
+#define OMAP4430_AUTO_CTRL_VDD_MPU_L_MASK (0x3 << 2)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_BYPS_RA_ERR_SHIFT 25
+#define OMAP4430_BYPS_RA_ERR_MASK (1 << 25)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_BYPS_SA_ERR_SHIFT 24
+#define OMAP4430_BYPS_SA_ERR_MASK (1 << 24)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_BYPS_TIMEOUT_ERR_SHIFT 26
+#define OMAP4430_BYPS_TIMEOUT_ERR_MASK (1 << 26)
+
+/* Used by PRM_RSTST */
+#define OMAP4430_C2C_RST_SHIFT 10
+#define OMAP4430_C2C_RST_MASK (1 << 10)
/* Used by PM_CAM_PWRSTCTRL */
#define OMAP4430_CAM_MEM_ONSTATE_SHIFT 16
-#define OMAP4430_CAM_MEM_ONSTATE_MASK BITFIELD(16, 17)
+#define OMAP4430_CAM_MEM_ONSTATE_MASK (0x3 << 16)
/* Used by PM_CAM_PWRSTST */
#define OMAP4430_CAM_MEM_STATEST_SHIFT 4
-#define OMAP4430_CAM_MEM_STATEST_MASK BITFIELD(4, 5)
+#define OMAP4430_CAM_MEM_STATEST_MASK (0x3 << 4)
/* Used by PRM_CLKREQCTRL */
#define OMAP4430_CLKREQ_COND_SHIFT 0
-#define OMAP4430_CLKREQ_COND_MASK BITFIELD(0, 2)
+#define OMAP4430_CLKREQ_COND_MASK (0x7 << 0)
/* Used by PRM_VC_VAL_SMPS_RA_CMD */
#define OMAP4430_CMDRA_VDD_CORE_L_SHIFT 0
-#define OMAP4430_CMDRA_VDD_CORE_L_MASK BITFIELD(0, 7)
+#define OMAP4430_CMDRA_VDD_CORE_L_MASK (0xff << 0)
/* Used by PRM_VC_VAL_SMPS_RA_CMD */
#define OMAP4430_CMDRA_VDD_IVA_L_SHIFT 8
-#define OMAP4430_CMDRA_VDD_IVA_L_MASK BITFIELD(8, 15)
+#define OMAP4430_CMDRA_VDD_IVA_L_MASK (0xff << 8)
/* Used by PRM_VC_VAL_SMPS_RA_CMD */
#define OMAP4430_CMDRA_VDD_MPU_L_SHIFT 16
-#define OMAP4430_CMDRA_VDD_MPU_L_MASK BITFIELD(16, 23)
+#define OMAP4430_CMDRA_VDD_MPU_L_MASK (0xff << 16)
/* Used by PRM_VC_CFG_CHANNEL */
#define OMAP4430_CMD_VDD_CORE_L_SHIFT 4
-#define OMAP4430_CMD_VDD_CORE_L_MASK BITFIELD(4, 4)
+#define OMAP4430_CMD_VDD_CORE_L_MASK (1 << 4)
/* Used by PRM_VC_CFG_CHANNEL */
#define OMAP4430_CMD_VDD_IVA_L_SHIFT 12
-#define OMAP4430_CMD_VDD_IVA_L_MASK BITFIELD(12, 12)
+#define OMAP4430_CMD_VDD_IVA_L_MASK (1 << 12)
/* Used by PRM_VC_CFG_CHANNEL */
#define OMAP4430_CMD_VDD_MPU_L_SHIFT 17
-#define OMAP4430_CMD_VDD_MPU_L_MASK BITFIELD(17, 17)
+#define OMAP4430_CMD_VDD_MPU_L_MASK (1 << 17)
/* Used by PM_CORE_PWRSTCTRL */
#define OMAP4430_CORE_OCMRAM_ONSTATE_SHIFT 18
-#define OMAP4430_CORE_OCMRAM_ONSTATE_MASK BITFIELD(18, 19)
+#define OMAP4430_CORE_OCMRAM_ONSTATE_MASK (0x3 << 18)
/* Used by PM_CORE_PWRSTCTRL */
#define OMAP4430_CORE_OCMRAM_RETSTATE_SHIFT 9
-#define OMAP4430_CORE_OCMRAM_RETSTATE_MASK BITFIELD(9, 9)
+#define OMAP4430_CORE_OCMRAM_RETSTATE_MASK (1 << 9)
/* Used by PM_CORE_PWRSTST */
#define OMAP4430_CORE_OCMRAM_STATEST_SHIFT 6
-#define OMAP4430_CORE_OCMRAM_STATEST_MASK BITFIELD(6, 7)
+#define OMAP4430_CORE_OCMRAM_STATEST_MASK (0x3 << 6)
/* Used by PM_CORE_PWRSTCTRL */
#define OMAP4430_CORE_OTHER_BANK_ONSTATE_SHIFT 16
-#define OMAP4430_CORE_OTHER_BANK_ONSTATE_MASK BITFIELD(16, 17)
+#define OMAP4430_CORE_OTHER_BANK_ONSTATE_MASK (0x3 << 16)
/* Used by PM_CORE_PWRSTCTRL */
#define OMAP4430_CORE_OTHER_BANK_RETSTATE_SHIFT 8
-#define OMAP4430_CORE_OTHER_BANK_RETSTATE_MASK BITFIELD(8, 8)
+#define OMAP4430_CORE_OTHER_BANK_RETSTATE_MASK (1 << 8)
/* Used by PM_CORE_PWRSTST */
#define OMAP4430_CORE_OTHER_BANK_STATEST_SHIFT 4
-#define OMAP4430_CORE_OTHER_BANK_STATEST_MASK BITFIELD(4, 5)
+#define OMAP4430_CORE_OTHER_BANK_STATEST_MASK (0x3 << 4)
+
+/* Used by REVISION_PRM */
+#define OMAP4430_CUSTOM_SHIFT 6
+#define OMAP4430_CUSTOM_MASK (0x3 << 6)
/* Used by PRM_VC_VAL_BYPASS */
#define OMAP4430_DATA_SHIFT 16
-#define OMAP4430_DATA_MASK BITFIELD(16, 23)
+#define OMAP4430_DATA_MASK (0xff << 16)
/* Used by PRM_DEVICE_OFF_CTRL */
#define OMAP4430_DEVICE_OFF_ENABLE_SHIFT 0
-#define OMAP4430_DEVICE_OFF_ENABLE_MASK BITFIELD(0, 0)
+#define OMAP4430_DEVICE_OFF_ENABLE_MASK (1 << 0)
/* Used by PRM_VC_CFG_I2C_MODE */
#define OMAP4430_DFILTEREN_SHIFT 6
-#define OMAP4430_DFILTEREN_MASK BITFIELD(6, 6)
+#define OMAP4430_DFILTEREN_MASK (1 << 6)
-/* Used by PRM_IRQENABLE_MPU, PRM_IRQENABLE_TESLA */
+/*
+ * Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
+ * PRM_LDO_SRAM_MPU_SETUP, PRM_SRAM_WKUP_SETUP
+ */
+#define OMAP4430_DISABLE_RTA_EXPORT_SHIFT 0
+#define OMAP4430_DISABLE_RTA_EXPORT_MASK (1 << 0)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU, PRM_IRQENABLE_TESLA */
#define OMAP4430_DPLL_ABE_RECAL_EN_SHIFT 4
-#define OMAP4430_DPLL_ABE_RECAL_EN_MASK BITFIELD(4, 4)
+#define OMAP4430_DPLL_ABE_RECAL_EN_MASK (1 << 4)
-/* Used by PRM_IRQSTATUS_MPU, PRM_IRQSTATUS_TESLA */
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU, PRM_IRQSTATUS_TESLA */
#define OMAP4430_DPLL_ABE_RECAL_ST_SHIFT 4
-#define OMAP4430_DPLL_ABE_RECAL_ST_MASK BITFIELD(4, 4)
+#define OMAP4430_DPLL_ABE_RECAL_ST_MASK (1 << 4)
/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
#define OMAP4430_DPLL_CORE_RECAL_EN_SHIFT 0
-#define OMAP4430_DPLL_CORE_RECAL_EN_MASK BITFIELD(0, 0)
+#define OMAP4430_DPLL_CORE_RECAL_EN_MASK (1 << 0)
/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
#define OMAP4430_DPLL_CORE_RECAL_ST_SHIFT 0
-#define OMAP4430_DPLL_CORE_RECAL_ST_MASK BITFIELD(0, 0)
+#define OMAP4430_DPLL_CORE_RECAL_ST_MASK (1 << 0)
/* Used by PRM_IRQENABLE_MPU */
#define OMAP4430_DPLL_DDRPHY_RECAL_EN_SHIFT 6
-#define OMAP4430_DPLL_DDRPHY_RECAL_EN_MASK BITFIELD(6, 6)
+#define OMAP4430_DPLL_DDRPHY_RECAL_EN_MASK (1 << 6)
/* Used by PRM_IRQSTATUS_MPU */
#define OMAP4430_DPLL_DDRPHY_RECAL_ST_SHIFT 6
-#define OMAP4430_DPLL_DDRPHY_RECAL_ST_MASK BITFIELD(6, 6)
+#define OMAP4430_DPLL_DDRPHY_RECAL_ST_MASK (1 << 6)
/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU, PRM_IRQENABLE_TESLA */
#define OMAP4430_DPLL_IVA_RECAL_EN_SHIFT 2
-#define OMAP4430_DPLL_IVA_RECAL_EN_MASK BITFIELD(2, 2)
+#define OMAP4430_DPLL_IVA_RECAL_EN_MASK (1 << 2)
/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU, PRM_IRQSTATUS_TESLA */
#define OMAP4430_DPLL_IVA_RECAL_ST_SHIFT 2
-#define OMAP4430_DPLL_IVA_RECAL_ST_MASK BITFIELD(2, 2)
+#define OMAP4430_DPLL_IVA_RECAL_ST_MASK (1 << 2)
/* Used by PRM_IRQENABLE_MPU */
#define OMAP4430_DPLL_MPU_RECAL_EN_SHIFT 1
-#define OMAP4430_DPLL_MPU_RECAL_EN_MASK BITFIELD(1, 1)
+#define OMAP4430_DPLL_MPU_RECAL_EN_MASK (1 << 1)
/* Used by PRM_IRQSTATUS_MPU */
#define OMAP4430_DPLL_MPU_RECAL_ST_SHIFT 1
-#define OMAP4430_DPLL_MPU_RECAL_ST_MASK BITFIELD(1, 1)
+#define OMAP4430_DPLL_MPU_RECAL_ST_MASK (1 << 1)
/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
#define OMAP4430_DPLL_PER_RECAL_EN_SHIFT 3
-#define OMAP4430_DPLL_PER_RECAL_EN_MASK BITFIELD(3, 3)
+#define OMAP4430_DPLL_PER_RECAL_EN_MASK (1 << 3)
/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
#define OMAP4430_DPLL_PER_RECAL_ST_SHIFT 3
-#define OMAP4430_DPLL_PER_RECAL_ST_MASK BITFIELD(3, 3)
+#define OMAP4430_DPLL_PER_RECAL_ST_MASK (1 << 3)
/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
#define OMAP4430_DPLL_UNIPRO_RECAL_EN_SHIFT 7
-#define OMAP4430_DPLL_UNIPRO_RECAL_EN_MASK BITFIELD(7, 7)
+#define OMAP4430_DPLL_UNIPRO_RECAL_EN_MASK (1 << 7)
/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
#define OMAP4430_DPLL_UNIPRO_RECAL_ST_SHIFT 7
-#define OMAP4430_DPLL_UNIPRO_RECAL_ST_MASK BITFIELD(7, 7)
-
-/* Used by PRM_IRQENABLE_MPU */
-#define OMAP4430_DPLL_USB_RECAL_EN_SHIFT 5
-#define OMAP4430_DPLL_USB_RECAL_EN_MASK BITFIELD(5, 5)
-
-/* Used by PRM_IRQSTATUS_MPU */
-#define OMAP4430_DPLL_USB_RECAL_ST_SHIFT 5
-#define OMAP4430_DPLL_USB_RECAL_ST_MASK BITFIELD(5, 5)
+#define OMAP4430_DPLL_UNIPRO_RECAL_ST_MASK (1 << 7)
/* Used by PM_DSS_PWRSTCTRL */
#define OMAP4430_DSS_MEM_ONSTATE_SHIFT 16
-#define OMAP4430_DSS_MEM_ONSTATE_MASK BITFIELD(16, 17)
+#define OMAP4430_DSS_MEM_ONSTATE_MASK (0x3 << 16)
/* Used by PM_DSS_PWRSTCTRL */
#define OMAP4430_DSS_MEM_RETSTATE_SHIFT 8
-#define OMAP4430_DSS_MEM_RETSTATE_MASK BITFIELD(8, 8)
+#define OMAP4430_DSS_MEM_RETSTATE_MASK (1 << 8)
/* Used by PM_DSS_PWRSTST */
#define OMAP4430_DSS_MEM_STATEST_SHIFT 4
-#define OMAP4430_DSS_MEM_STATEST_MASK BITFIELD(4, 5)
+#define OMAP4430_DSS_MEM_STATEST_MASK (0x3 << 4)
/* Used by PM_CORE_PWRSTCTRL */
#define OMAP4430_DUCATI_L2RAM_ONSTATE_SHIFT 20
-#define OMAP4430_DUCATI_L2RAM_ONSTATE_MASK BITFIELD(20, 21)
+#define OMAP4430_DUCATI_L2RAM_ONSTATE_MASK (0x3 << 20)
/* Used by PM_CORE_PWRSTCTRL */
#define OMAP4430_DUCATI_L2RAM_RETSTATE_SHIFT 10
-#define OMAP4430_DUCATI_L2RAM_RETSTATE_MASK BITFIELD(10, 10)
+#define OMAP4430_DUCATI_L2RAM_RETSTATE_MASK (1 << 10)
/* Used by PM_CORE_PWRSTST */
#define OMAP4430_DUCATI_L2RAM_STATEST_SHIFT 8
-#define OMAP4430_DUCATI_L2RAM_STATEST_MASK BITFIELD(8, 9)
+#define OMAP4430_DUCATI_L2RAM_STATEST_MASK (0x3 << 8)
/* Used by PM_CORE_PWRSTCTRL */
#define OMAP4430_DUCATI_UNICACHE_ONSTATE_SHIFT 22
-#define OMAP4430_DUCATI_UNICACHE_ONSTATE_MASK BITFIELD(22, 23)
+#define OMAP4430_DUCATI_UNICACHE_ONSTATE_MASK (0x3 << 22)
/* Used by PM_CORE_PWRSTCTRL */
#define OMAP4430_DUCATI_UNICACHE_RETSTATE_SHIFT 11
-#define OMAP4430_DUCATI_UNICACHE_RETSTATE_MASK BITFIELD(11, 11)
+#define OMAP4430_DUCATI_UNICACHE_RETSTATE_MASK (1 << 11)
/* Used by PM_CORE_PWRSTST */
#define OMAP4430_DUCATI_UNICACHE_STATEST_SHIFT 10
-#define OMAP4430_DUCATI_UNICACHE_STATEST_MASK BITFIELD(10, 11)
+#define OMAP4430_DUCATI_UNICACHE_STATEST_MASK (0x3 << 10)
/* Used by RM_MPU_RSTST */
#define OMAP4430_EMULATION_RST_SHIFT 0
-#define OMAP4430_EMULATION_RST_MASK BITFIELD(0, 0)
+#define OMAP4430_EMULATION_RST_MASK (1 << 0)
/* Used by RM_DUCATI_RSTST */
#define OMAP4430_EMULATION_RST1ST_SHIFT 3
-#define OMAP4430_EMULATION_RST1ST_MASK BITFIELD(3, 3)
+#define OMAP4430_EMULATION_RST1ST_MASK (1 << 3)
/* Used by RM_DUCATI_RSTST */
#define OMAP4430_EMULATION_RST2ST_SHIFT 4
-#define OMAP4430_EMULATION_RST2ST_MASK BITFIELD(4, 4)
+#define OMAP4430_EMULATION_RST2ST_MASK (1 << 4)
/* Used by RM_IVAHD_RSTST */
#define OMAP4430_EMULATION_SEQ1_RST1ST_SHIFT 3
-#define OMAP4430_EMULATION_SEQ1_RST1ST_MASK BITFIELD(3, 3)
+#define OMAP4430_EMULATION_SEQ1_RST1ST_MASK (1 << 3)
/* Used by RM_IVAHD_RSTST */
#define OMAP4430_EMULATION_SEQ2_RST2ST_SHIFT 4
-#define OMAP4430_EMULATION_SEQ2_RST2ST_MASK BITFIELD(4, 4)
+#define OMAP4430_EMULATION_SEQ2_RST2ST_MASK (1 << 4)
/* Used by PM_EMU_PWRSTCTRL */
#define OMAP4430_EMU_BANK_ONSTATE_SHIFT 16
-#define OMAP4430_EMU_BANK_ONSTATE_MASK BITFIELD(16, 17)
+#define OMAP4430_EMU_BANK_ONSTATE_MASK (0x3 << 16)
/* Used by PM_EMU_PWRSTST */
#define OMAP4430_EMU_BANK_STATEST_SHIFT 4
-#define OMAP4430_EMU_BANK_STATEST_MASK BITFIELD(4, 5)
-
-/*
- * Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
- * PRM_LDO_SRAM_MPU_SETUP, PRM_SRAM_WKUP_SETUP
- */
-#define OMAP4430_ENABLE_RTA_EXPORT_SHIFT 0
-#define OMAP4430_ENABLE_RTA_EXPORT_MASK BITFIELD(0, 0)
+#define OMAP4430_EMU_BANK_STATEST_MASK (0x3 << 4)
/*
* Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
* PRM_LDO_SRAM_MPU_SETUP
*/
-#define OMAP4430_ENFUNC1_SHIFT 3
-#define OMAP4430_ENFUNC1_MASK BITFIELD(3, 3)
+#define OMAP4430_ENFUNC1_EXPORT_SHIFT 3
+#define OMAP4430_ENFUNC1_EXPORT_MASK (1 << 3)
/*
* Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
* PRM_LDO_SRAM_MPU_SETUP
*/
-#define OMAP4430_ENFUNC3_SHIFT 5
-#define OMAP4430_ENFUNC3_MASK BITFIELD(5, 5)
+#define OMAP4430_ENFUNC3_EXPORT_SHIFT 5
+#define OMAP4430_ENFUNC3_EXPORT_MASK (1 << 5)
/*
* Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
* PRM_LDO_SRAM_MPU_SETUP
*/
#define OMAP4430_ENFUNC4_SHIFT 6
-#define OMAP4430_ENFUNC4_MASK BITFIELD(6, 6)
+#define OMAP4430_ENFUNC4_MASK (1 << 6)
/*
* Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
* PRM_LDO_SRAM_MPU_SETUP
*/
#define OMAP4430_ENFUNC5_SHIFT 7
-#define OMAP4430_ENFUNC5_MASK BITFIELD(7, 7)
+#define OMAP4430_ENFUNC5_MASK (1 << 7)
/* Used by PRM_VP_CORE_CONFIG, PRM_VP_IVA_CONFIG, PRM_VP_MPU_CONFIG */
#define OMAP4430_ERRORGAIN_SHIFT 16
-#define OMAP4430_ERRORGAIN_MASK BITFIELD(16, 23)
+#define OMAP4430_ERRORGAIN_MASK (0xff << 16)
/* Used by PRM_VP_CORE_CONFIG, PRM_VP_IVA_CONFIG, PRM_VP_MPU_CONFIG */
#define OMAP4430_ERROROFFSET_SHIFT 24
-#define OMAP4430_ERROROFFSET_MASK BITFIELD(24, 31)
+#define OMAP4430_ERROROFFSET_MASK (0xff << 24)
/* Used by PRM_RSTST */
#define OMAP4430_EXTERNAL_WARM_RST_SHIFT 5
-#define OMAP4430_EXTERNAL_WARM_RST_MASK BITFIELD(5, 5)
+#define OMAP4430_EXTERNAL_WARM_RST_MASK (1 << 5)
/* Used by PRM_VP_CORE_CONFIG, PRM_VP_IVA_CONFIG, PRM_VP_MPU_CONFIG */
#define OMAP4430_FORCEUPDATE_SHIFT 1
-#define OMAP4430_FORCEUPDATE_MASK BITFIELD(1, 1)
+#define OMAP4430_FORCEUPDATE_MASK (1 << 1)
/* Used by PRM_VP_CORE_VOLTAGE, PRM_VP_IVA_VOLTAGE, PRM_VP_MPU_VOLTAGE */
#define OMAP4430_FORCEUPDATEWAIT_SHIFT 8
-#define OMAP4430_FORCEUPDATEWAIT_MASK BITFIELD(8, 31)
+#define OMAP4430_FORCEUPDATEWAIT_MASK (0xffffff << 8)
/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_TESLA */
#define OMAP4430_FORCEWKUP_EN_SHIFT 10
-#define OMAP4430_FORCEWKUP_EN_MASK BITFIELD(10, 10)
+#define OMAP4430_FORCEWKUP_EN_MASK (1 << 10)
/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_TESLA */
#define OMAP4430_FORCEWKUP_ST_SHIFT 10
-#define OMAP4430_FORCEWKUP_ST_MASK BITFIELD(10, 10)
+#define OMAP4430_FORCEWKUP_ST_MASK (1 << 10)
+
+/* Used by REVISION_PRM */
+#define OMAP4430_FUNC_SHIFT 16
+#define OMAP4430_FUNC_MASK (0xfff << 16)
/* Used by PM_GFX_PWRSTCTRL */
#define OMAP4430_GFX_MEM_ONSTATE_SHIFT 16
-#define OMAP4430_GFX_MEM_ONSTATE_MASK BITFIELD(16, 17)
+#define OMAP4430_GFX_MEM_ONSTATE_MASK (0x3 << 16)
/* Used by PM_GFX_PWRSTST */
#define OMAP4430_GFX_MEM_STATEST_SHIFT 4
-#define OMAP4430_GFX_MEM_STATEST_MASK BITFIELD(4, 5)
+#define OMAP4430_GFX_MEM_STATEST_MASK (0x3 << 4)
/* Used by PRM_RSTST */
#define OMAP4430_GLOBAL_COLD_RST_SHIFT 0
-#define OMAP4430_GLOBAL_COLD_RST_MASK BITFIELD(0, 0)
+#define OMAP4430_GLOBAL_COLD_RST_MASK (1 << 0)
/* Used by PRM_RSTST */
#define OMAP4430_GLOBAL_WARM_SW_RST_SHIFT 1
-#define OMAP4430_GLOBAL_WARM_SW_RST_MASK BITFIELD(1, 1)
+#define OMAP4430_GLOBAL_WARM_SW_RST_MASK (1 << 1)
/* Used by PRM_IO_PMCTRL */
#define OMAP4430_GLOBAL_WUEN_SHIFT 16
-#define OMAP4430_GLOBAL_WUEN_MASK BITFIELD(16, 16)
+#define OMAP4430_GLOBAL_WUEN_MASK (1 << 16)
/* Used by PRM_VC_CFG_I2C_MODE */
#define OMAP4430_HSMCODE_SHIFT 0
-#define OMAP4430_HSMCODE_MASK BITFIELD(0, 2)
+#define OMAP4430_HSMCODE_MASK (0x7 << 0)
/* Used by PRM_VC_CFG_I2C_MODE */
#define OMAP4430_HSMODEEN_SHIFT 3
-#define OMAP4430_HSMODEEN_MASK BITFIELD(3, 3)
+#define OMAP4430_HSMODEEN_MASK (1 << 3)
/* Used by PRM_VC_CFG_I2C_CLK */
#define OMAP4430_HSSCLH_SHIFT 16
-#define OMAP4430_HSSCLH_MASK BITFIELD(16, 23)
+#define OMAP4430_HSSCLH_MASK (0xff << 16)
/* Used by PRM_VC_CFG_I2C_CLK */
#define OMAP4430_HSSCLL_SHIFT 24
-#define OMAP4430_HSSCLL_MASK BITFIELD(24, 31)
+#define OMAP4430_HSSCLL_MASK (0xff << 24)
/* Used by PM_IVAHD_PWRSTCTRL */
#define OMAP4430_HWA_MEM_ONSTATE_SHIFT 16
-#define OMAP4430_HWA_MEM_ONSTATE_MASK BITFIELD(16, 17)
+#define OMAP4430_HWA_MEM_ONSTATE_MASK (0x3 << 16)
/* Used by PM_IVAHD_PWRSTCTRL */
#define OMAP4430_HWA_MEM_RETSTATE_SHIFT 8
-#define OMAP4430_HWA_MEM_RETSTATE_MASK BITFIELD(8, 8)
+#define OMAP4430_HWA_MEM_RETSTATE_MASK (1 << 8)
/* Used by PM_IVAHD_PWRSTST */
#define OMAP4430_HWA_MEM_STATEST_SHIFT 4
-#define OMAP4430_HWA_MEM_STATEST_MASK BITFIELD(4, 5)
+#define OMAP4430_HWA_MEM_STATEST_MASK (0x3 << 4)
/* Used by RM_MPU_RSTST */
#define OMAP4430_ICECRUSHER_MPU_RST_SHIFT 1
-#define OMAP4430_ICECRUSHER_MPU_RST_MASK BITFIELD(1, 1)
+#define OMAP4430_ICECRUSHER_MPU_RST_MASK (1 << 1)
/* Used by RM_DUCATI_RSTST */
#define OMAP4430_ICECRUSHER_RST1ST_SHIFT 5
-#define OMAP4430_ICECRUSHER_RST1ST_MASK BITFIELD(5, 5)
+#define OMAP4430_ICECRUSHER_RST1ST_MASK (1 << 5)
/* Used by RM_DUCATI_RSTST */
#define OMAP4430_ICECRUSHER_RST2ST_SHIFT 6
-#define OMAP4430_ICECRUSHER_RST2ST_MASK BITFIELD(6, 6)
+#define OMAP4430_ICECRUSHER_RST2ST_MASK (1 << 6)
/* Used by RM_IVAHD_RSTST */
#define OMAP4430_ICECRUSHER_SEQ1_RST1ST_SHIFT 5
-#define OMAP4430_ICECRUSHER_SEQ1_RST1ST_MASK BITFIELD(5, 5)
+#define OMAP4430_ICECRUSHER_SEQ1_RST1ST_MASK (1 << 5)
/* Used by RM_IVAHD_RSTST */
#define OMAP4430_ICECRUSHER_SEQ2_RST2ST_SHIFT 6
-#define OMAP4430_ICECRUSHER_SEQ2_RST2ST_MASK BITFIELD(6, 6)
+#define OMAP4430_ICECRUSHER_SEQ2_RST2ST_MASK (1 << 6)
/* Used by PRM_RSTST */
#define OMAP4430_ICEPICK_RST_SHIFT 9
-#define OMAP4430_ICEPICK_RST_MASK BITFIELD(9, 9)
+#define OMAP4430_ICEPICK_RST_MASK (1 << 9)
/* Used by PRM_VP_CORE_CONFIG, PRM_VP_IVA_CONFIG, PRM_VP_MPU_CONFIG */
#define OMAP4430_INITVDD_SHIFT 2
-#define OMAP4430_INITVDD_MASK BITFIELD(2, 2)
+#define OMAP4430_INITVDD_MASK (1 << 2)
/* Used by PRM_VP_CORE_CONFIG, PRM_VP_IVA_CONFIG, PRM_VP_MPU_CONFIG */
#define OMAP4430_INITVOLTAGE_SHIFT 8
-#define OMAP4430_INITVOLTAGE_MASK BITFIELD(8, 15)
+#define OMAP4430_INITVOLTAGE_MASK (0xff << 8)
/*
- * Used by PM_EMU_PWRSTST, PM_CORE_PWRSTST, PM_CAM_PWRSTST, PM_L3INIT_PWRSTST,
- * PM_ABE_PWRSTST, PM_GFX_PWRSTST, PM_MPU_PWRSTST, PM_CEFUSE_PWRSTST,
- * PM_DSS_PWRSTST, PM_L4PER_PWRSTST, PM_TESLA_PWRSTST, PM_IVAHD_PWRSTST
+ * Used by PM_ABE_PWRSTST, PM_CAM_PWRSTST, PM_CEFUSE_PWRSTST, PM_CORE_PWRSTST,
+ * PM_DSS_PWRSTST, PM_EMU_PWRSTST, PM_GFX_PWRSTST, PM_IVAHD_PWRSTST,
+ * PM_L3INIT_PWRSTST, PM_L4PER_PWRSTST, PM_MPU_PWRSTST, PM_TESLA_PWRSTST
*/
#define OMAP4430_INTRANSITION_SHIFT 20
-#define OMAP4430_INTRANSITION_MASK BITFIELD(20, 20)
+#define OMAP4430_INTRANSITION_MASK (1 << 20)
/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
#define OMAP4430_IO_EN_SHIFT 9
-#define OMAP4430_IO_EN_MASK BITFIELD(9, 9)
+#define OMAP4430_IO_EN_MASK (1 << 9)
/* Used by PRM_IO_PMCTRL */
#define OMAP4430_IO_ON_STATUS_SHIFT 5
-#define OMAP4430_IO_ON_STATUS_MASK BITFIELD(5, 5)
+#define OMAP4430_IO_ON_STATUS_MASK (1 << 5)
/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
#define OMAP4430_IO_ST_SHIFT 9
-#define OMAP4430_IO_ST_MASK BITFIELD(9, 9)
+#define OMAP4430_IO_ST_MASK (1 << 9)
/* Used by PRM_IO_PMCTRL */
#define OMAP4430_ISOCLK_OVERRIDE_SHIFT 0
-#define OMAP4430_ISOCLK_OVERRIDE_MASK BITFIELD(0, 0)
+#define OMAP4430_ISOCLK_OVERRIDE_MASK (1 << 0)
/* Used by PRM_IO_PMCTRL */
#define OMAP4430_ISOCLK_STATUS_SHIFT 1
-#define OMAP4430_ISOCLK_STATUS_MASK BITFIELD(1, 1)
+#define OMAP4430_ISOCLK_STATUS_MASK (1 << 1)
/* Used by PRM_IO_PMCTRL */
#define OMAP4430_ISOOVR_EXTEND_SHIFT 4
-#define OMAP4430_ISOOVR_EXTEND_MASK BITFIELD(4, 4)
+#define OMAP4430_ISOOVR_EXTEND_MASK (1 << 4)
/* Used by PRM_IO_COUNT */
#define OMAP4430_ISO_2_ON_TIME_SHIFT 0
-#define OMAP4430_ISO_2_ON_TIME_MASK BITFIELD(0, 7)
+#define OMAP4430_ISO_2_ON_TIME_MASK (0xff << 0)
/* Used by PM_L3INIT_PWRSTCTRL */
#define OMAP4430_L3INIT_BANK1_ONSTATE_SHIFT 16
-#define OMAP4430_L3INIT_BANK1_ONSTATE_MASK BITFIELD(16, 17)
+#define OMAP4430_L3INIT_BANK1_ONSTATE_MASK (0x3 << 16)
/* Used by PM_L3INIT_PWRSTCTRL */
#define OMAP4430_L3INIT_BANK1_RETSTATE_SHIFT 8
-#define OMAP4430_L3INIT_BANK1_RETSTATE_MASK BITFIELD(8, 8)
+#define OMAP4430_L3INIT_BANK1_RETSTATE_MASK (1 << 8)
/* Used by PM_L3INIT_PWRSTST */
#define OMAP4430_L3INIT_BANK1_STATEST_SHIFT 4
-#define OMAP4430_L3INIT_BANK1_STATEST_MASK BITFIELD(4, 5)
+#define OMAP4430_L3INIT_BANK1_STATEST_MASK (0x3 << 4)
+
+/*
+ * Used by PM_ABE_PWRSTST, PM_CORE_PWRSTST, PM_IVAHD_PWRSTST,
+ * PM_L3INIT_PWRSTST, PM_L4PER_PWRSTST, PM_MPU_PWRSTST, PM_TESLA_PWRSTST
+ */
+#define OMAP4430_LASTPOWERSTATEENTERED_SHIFT 24
+#define OMAP4430_LASTPOWERSTATEENTERED_MASK (0x3 << 24)
/*
- * Used by PM_CORE_PWRSTCTRL, PM_L3INIT_PWRSTCTRL, PM_ABE_PWRSTCTRL,
- * PM_MPU_PWRSTCTRL, PM_DSS_PWRSTCTRL, PM_L4PER_PWRSTCTRL, PM_TESLA_PWRSTCTRL,
- * PM_IVAHD_PWRSTCTRL
+ * Used by PM_ABE_PWRSTCTRL, PM_CORE_PWRSTCTRL, PM_DSS_PWRSTCTRL,
+ * PM_IVAHD_PWRSTCTRL, PM_L3INIT_PWRSTCTRL, PM_L4PER_PWRSTCTRL,
+ * PM_MPU_PWRSTCTRL, PM_TESLA_PWRSTCTRL
*/
#define OMAP4430_LOGICRETSTATE_SHIFT 2
-#define OMAP4430_LOGICRETSTATE_MASK BITFIELD(2, 2)
+#define OMAP4430_LOGICRETSTATE_MASK (1 << 2)
/*
- * Used by PM_EMU_PWRSTST, PM_CORE_PWRSTST, PM_CAM_PWRSTST, PM_L3INIT_PWRSTST,
- * PM_ABE_PWRSTST, PM_GFX_PWRSTST, PM_MPU_PWRSTST, PM_CEFUSE_PWRSTST,
- * PM_DSS_PWRSTST, PM_L4PER_PWRSTST, PM_TESLA_PWRSTST, PM_IVAHD_PWRSTST
+ * Used by PM_ABE_PWRSTST, PM_CAM_PWRSTST, PM_CEFUSE_PWRSTST, PM_CORE_PWRSTST,
+ * PM_DSS_PWRSTST, PM_EMU_PWRSTST, PM_GFX_PWRSTST, PM_IVAHD_PWRSTST,
+ * PM_L3INIT_PWRSTST, PM_L4PER_PWRSTST, PM_MPU_PWRSTST, PM_TESLA_PWRSTST
*/
#define OMAP4430_LOGICSTATEST_SHIFT 2
-#define OMAP4430_LOGICSTATEST_MASK BITFIELD(2, 2)
+#define OMAP4430_LOGICSTATEST_MASK (1 << 2)
/*
- * Used by RM_WKUP_GPIO1_CONTEXT, RM_WKUP_KEYBOARD_CONTEXT,
- * RM_WKUP_L4WKUP_CONTEXT, RM_WKUP_RTC_CONTEXT, RM_WKUP_SARRAM_CONTEXT,
- * RM_WKUP_SYNCTIMER_CONTEXT, RM_WKUP_TIMER12_CONTEXT, RM_WKUP_TIMER1_CONTEXT,
- * RM_WKUP_USIM_CONTEXT, RM_WKUP_WDT1_CONTEXT, RM_WKUP_WDT2_CONTEXT,
- * RM_EMU_DEBUGSS_CONTEXT, RM_D2D_SAD2D_CONTEXT, RM_D2D_SAD2D_FW_CONTEXT,
- * RM_DUCATI_DUCATI_CONTEXT, RM_L3INSTR_L3_3_CONTEXT,
- * RM_L3INSTR_L3_INSTR_CONTEXT, RM_L3INSTR_OCP_WP1_CONTEXT,
- * RM_L3_1_L3_1_CONTEXT, RM_L3_2_L3_2_CONTEXT, RM_L3_2_OCMC_RAM_CONTEXT,
- * RM_L4CFG_L4_CFG_CONTEXT, RM_L4CFG_SAR_ROM_CONTEXT, RM_MEMIF_DLL_CONTEXT,
- * RM_MEMIF_DLL_H_CONTEXT, RM_MEMIF_DMM_CONTEXT, RM_MEMIF_EMIF_FW_CONTEXT,
- * RM_CAM_FDIF_CONTEXT, RM_CAM_ISS_CONTEXT, RM_L3INIT_CCPTX_CONTEXT,
- * RM_L3INIT_EMAC_CONTEXT, RM_L3INIT_P1500_CONTEXT, RM_L3INIT_PCIESS_CONTEXT,
- * RM_L3INIT_SATA_CONTEXT, RM_L3INIT_TPPSS_CONTEXT, RM_L3INIT_UNIPRO1_CONTEXT,
- * RM_L3INIT_USBPHYOCP2SCP_CONTEXT, RM_L3INIT_XHPI_CONTEXT,
- * RM_ABE_AESS_CONTEXT, RM_ABE_DMIC_CONTEXT, RM_ABE_MCASP_CONTEXT,
+ * Used by RM_ABE_AESS_CONTEXT, RM_ABE_DMIC_CONTEXT, RM_ABE_MCASP_CONTEXT,
* RM_ABE_MCBSP1_CONTEXT, RM_ABE_MCBSP2_CONTEXT, RM_ABE_MCBSP3_CONTEXT,
* RM_ABE_PDM_CONTEXT, RM_ABE_SLIMBUS_CONTEXT, RM_ABE_TIMER5_CONTEXT,
* RM_ABE_TIMER6_CONTEXT, RM_ABE_TIMER7_CONTEXT, RM_ABE_TIMER8_CONTEXT,
- * RM_ABE_WDT3_CONTEXT, RM_GFX_GFX_CONTEXT, RM_MPU_MPU_CONTEXT,
- * RM_CEFUSE_CEFUSE_CONTEXT, RM_ALWON_MDMINTC_CONTEXT,
- * RM_ALWON_SR_CORE_CONTEXT, RM_ALWON_SR_IVA_CONTEXT, RM_ALWON_SR_MPU_CONTEXT,
- * RM_DSS_DEISS_CONTEXT, RM_DSS_DSS_CONTEXT, RM_L4PER_ADC_CONTEXT,
- * RM_L4PER_DMTIMER10_CONTEXT, RM_L4PER_DMTIMER11_CONTEXT,
- * RM_L4PER_DMTIMER2_CONTEXT, RM_L4PER_DMTIMER3_CONTEXT,
- * RM_L4PER_DMTIMER4_CONTEXT, RM_L4PER_DMTIMER9_CONTEXT, RM_L4PER_ELM_CONTEXT,
- * RM_L4PER_HDQ1W_CONTEXT, RM_L4PER_HECC1_CONTEXT, RM_L4PER_HECC2_CONTEXT,
- * RM_L4PER_I2C2_CONTEXT, RM_L4PER_I2C3_CONTEXT, RM_L4PER_I2C4_CONTEXT,
- * RM_L4PER_I2C5_CONTEXT, RM_L4PER_L4_PER_CONTEXT, RM_L4PER_MCASP2_CONTEXT,
- * RM_L4PER_MCASP3_CONTEXT, RM_L4PER_MCBSP4_CONTEXT, RM_L4PER_MCSPI1_CONTEXT,
- * RM_L4PER_MCSPI2_CONTEXT, RM_L4PER_MCSPI3_CONTEXT, RM_L4PER_MCSPI4_CONTEXT,
- * RM_L4PER_MGATE_CONTEXT, RM_L4PER_MMCSD3_CONTEXT, RM_L4PER_MMCSD4_CONTEXT,
- * RM_L4PER_MMCSD5_CONTEXT, RM_L4PER_MSPROHG_CONTEXT,
- * RM_L4PER_SLIMBUS2_CONTEXT, RM_L4SEC_PKAEIP29_CONTEXT,
- * RM_TESLA_TESLA_CONTEXT, RM_IVAHD_IVAHD_CONTEXT, RM_IVAHD_SL2_CONTEXT
+ * RM_ABE_WDT3_CONTEXT, RM_ALWON_MDMINTC_CONTEXT, RM_ALWON_SR_CORE_CONTEXT,
+ * RM_ALWON_SR_IVA_CONTEXT, RM_ALWON_SR_MPU_CONTEXT, RM_CAM_FDIF_CONTEXT,
+ * RM_CAM_ISS_CONTEXT, RM_CEFUSE_CEFUSE_CONTEXT, RM_D2D_SAD2D_CONTEXT,
+ * RM_D2D_SAD2D_FW_CONTEXT, RM_DSS_DEISS_CONTEXT, RM_DSS_DSS_CONTEXT,
+ * RM_DUCATI_DUCATI_CONTEXT, RM_EMU_DEBUGSS_CONTEXT, RM_GFX_GFX_CONTEXT,
+ * RM_IVAHD_IVAHD_CONTEXT, RM_IVAHD_SL2_CONTEXT, RM_L3INIT_CCPTX_CONTEXT,
+ * RM_L3INIT_EMAC_CONTEXT, RM_L3INIT_P1500_CONTEXT, RM_L3INIT_PCIESS_CONTEXT,
+ * RM_L3INIT_SATA_CONTEXT, RM_L3INIT_TPPSS_CONTEXT, RM_L3INIT_UNIPRO1_CONTEXT,
+ * RM_L3INIT_USBPHYOCP2SCP_CONTEXT, RM_L3INIT_XHPI_CONTEXT,
+ * RM_L3INSTR_L3_3_CONTEXT, RM_L3INSTR_L3_INSTR_CONTEXT,
+ * RM_L3INSTR_OCP_WP1_CONTEXT, RM_L3_1_L3_1_CONTEXT, RM_L3_2_L3_2_CONTEXT,
+ * RM_L3_2_OCMC_RAM_CONTEXT, RM_L4CFG_L4_CFG_CONTEXT, RM_L4CFG_SAR_ROM_CONTEXT,
+ * RM_L4PER_ADC_CONTEXT, RM_L4PER_DMTIMER10_CONTEXT,
+ * RM_L4PER_DMTIMER11_CONTEXT, RM_L4PER_DMTIMER2_CONTEXT,
+ * RM_L4PER_DMTIMER3_CONTEXT, RM_L4PER_DMTIMER4_CONTEXT,
+ * RM_L4PER_DMTIMER9_CONTEXT, RM_L4PER_ELM_CONTEXT, RM_L4PER_HDQ1W_CONTEXT,
+ * RM_L4PER_HECC1_CONTEXT, RM_L4PER_HECC2_CONTEXT, RM_L4PER_I2C2_CONTEXT,
+ * RM_L4PER_I2C3_CONTEXT, RM_L4PER_I2C4_CONTEXT, RM_L4PER_I2C5_CONTEXT,
+ * RM_L4PER_L4_PER_CONTEXT, RM_L4PER_MCASP2_CONTEXT, RM_L4PER_MCASP3_CONTEXT,
+ * RM_L4PER_MCBSP4_CONTEXT, RM_L4PER_MCSPI1_CONTEXT, RM_L4PER_MCSPI2_CONTEXT,
+ * RM_L4PER_MCSPI3_CONTEXT, RM_L4PER_MCSPI4_CONTEXT, RM_L4PER_MGATE_CONTEXT,
+ * RM_L4PER_MMCSD3_CONTEXT, RM_L4PER_MMCSD4_CONTEXT, RM_L4PER_MMCSD5_CONTEXT,
+ * RM_L4PER_MSPROHG_CONTEXT, RM_L4PER_SLIMBUS2_CONTEXT,
+ * RM_L4SEC_PKAEIP29_CONTEXT, RM_MEMIF_DLL_CONTEXT, RM_MEMIF_DLL_H_CONTEXT,
+ * RM_MEMIF_DMM_CONTEXT, RM_MEMIF_EMIF_1_CONTEXT, RM_MEMIF_EMIF_2_CONTEXT,
+ * RM_MEMIF_EMIF_FW_CONTEXT, RM_MPU_MPU_CONTEXT, RM_TESLA_TESLA_CONTEXT,
+ * RM_WKUP_GPIO1_CONTEXT, RM_WKUP_KEYBOARD_CONTEXT, RM_WKUP_L4WKUP_CONTEXT,
+ * RM_WKUP_RTC_CONTEXT, RM_WKUP_SARRAM_CONTEXT, RM_WKUP_SYNCTIMER_CONTEXT,
+ * RM_WKUP_TIMER12_CONTEXT, RM_WKUP_TIMER1_CONTEXT, RM_WKUP_USIM_CONTEXT,
+ * RM_WKUP_WDT1_CONTEXT, RM_WKUP_WDT2_CONTEXT
*/
#define OMAP4430_LOSTCONTEXT_DFF_SHIFT 0
-#define OMAP4430_LOSTCONTEXT_DFF_MASK BITFIELD(0, 0)
+#define OMAP4430_LOSTCONTEXT_DFF_MASK (1 << 0)
/*
* Used by RM_D2D_MODEM_ICR_CONTEXT, RM_D2D_SAD2D_CONTEXT,
- * RM_D2D_SAD2D_FW_CONTEXT, RM_DUCATI_DUCATI_CONTEXT, RM_L3INSTR_L3_3_CONTEXT,
+ * RM_D2D_SAD2D_FW_CONTEXT, RM_DSS_DSS_CONTEXT, RM_DUCATI_DUCATI_CONTEXT,
+ * RM_L3INIT_HSI_CONTEXT, RM_L3INIT_MMC1_CONTEXT, RM_L3INIT_MMC2_CONTEXT,
+ * RM_L3INIT_MMC6_CONTEXT, RM_L3INIT_USB_HOST_CONTEXT,
+ * RM_L3INIT_USB_HOST_FS_CONTEXT, RM_L3INIT_USB_OTG_CONTEXT,
+ * RM_L3INIT_USB_TLL_CONTEXT, RM_L3INSTR_L3_3_CONTEXT,
* RM_L3INSTR_OCP_WP1_CONTEXT, RM_L3_1_L3_1_CONTEXT, RM_L3_2_GPMC_CONTEXT,
* RM_L3_2_L3_2_CONTEXT, RM_L4CFG_HW_SEM_CONTEXT, RM_L4CFG_L4_CFG_CONTEXT,
- * RM_L4CFG_MAILBOX_CONTEXT, RM_MEMIF_DMM_CONTEXT, RM_MEMIF_EMIF_1_CONTEXT,
- * RM_MEMIF_EMIF_2_CONTEXT, RM_MEMIF_EMIF_FW_CONTEXT, RM_MEMIF_EMIF_H1_CONTEXT,
- * RM_MEMIF_EMIF_H2_CONTEXT, RM_SDMA_SDMA_CONTEXT, RM_L3INIT_HSI_CONTEXT,
- * RM_L3INIT_MMC1_CONTEXT, RM_L3INIT_MMC2_CONTEXT, RM_L3INIT_MMC6_CONTEXT,
- * RM_L3INIT_USB_HOST_CONTEXT, RM_L3INIT_USB_HOST_FS_CONTEXT,
- * RM_L3INIT_USB_OTG_CONTEXT, RM_L3INIT_USB_TLL_CONTEXT, RM_DSS_DSS_CONTEXT,
- * RM_L4PER_GPIO2_CONTEXT, RM_L4PER_GPIO3_CONTEXT, RM_L4PER_GPIO4_CONTEXT,
- * RM_L4PER_GPIO5_CONTEXT, RM_L4PER_GPIO6_CONTEXT, RM_L4PER_I2C1_CONTEXT,
- * RM_L4PER_L4_PER_CONTEXT, RM_L4PER_UART1_CONTEXT, RM_L4PER_UART2_CONTEXT,
- * RM_L4PER_UART3_CONTEXT, RM_L4PER_UART4_CONTEXT, RM_L4SEC_AES1_CONTEXT,
- * RM_L4SEC_AES2_CONTEXT, RM_L4SEC_CRYPTODMA_CONTEXT, RM_L4SEC_DES3DES_CONTEXT,
- * RM_L4SEC_RNG_CONTEXT, RM_L4SEC_SHA2MD51_CONTEXT, RM_TESLA_TESLA_CONTEXT
+ * RM_L4CFG_MAILBOX_CONTEXT, RM_L4PER_GPIO2_CONTEXT, RM_L4PER_GPIO3_CONTEXT,
+ * RM_L4PER_GPIO4_CONTEXT, RM_L4PER_GPIO5_CONTEXT, RM_L4PER_GPIO6_CONTEXT,
+ * RM_L4PER_I2C1_CONTEXT, RM_L4PER_L4_PER_CONTEXT, RM_L4PER_UART1_CONTEXT,
+ * RM_L4PER_UART2_CONTEXT, RM_L4PER_UART3_CONTEXT, RM_L4PER_UART4_CONTEXT,
+ * RM_L4SEC_AES1_CONTEXT, RM_L4SEC_AES2_CONTEXT, RM_L4SEC_CRYPTODMA_CONTEXT,
+ * RM_L4SEC_DES3DES_CONTEXT, RM_L4SEC_RNG_CONTEXT, RM_L4SEC_SHA2MD51_CONTEXT,
+ * RM_MEMIF_DMM_CONTEXT, RM_MEMIF_EMIF_1_CONTEXT, RM_MEMIF_EMIF_2_CONTEXT,
+ * RM_MEMIF_EMIF_FW_CONTEXT, RM_MEMIF_EMIF_H1_CONTEXT,
+ * RM_MEMIF_EMIF_H2_CONTEXT, RM_SDMA_SDMA_CONTEXT, RM_TESLA_TESLA_CONTEXT
*/
#define OMAP4430_LOSTCONTEXT_RFF_SHIFT 1
-#define OMAP4430_LOSTCONTEXT_RFF_MASK BITFIELD(1, 1)
+#define OMAP4430_LOSTCONTEXT_RFF_MASK (1 << 1)
/* Used by RM_ABE_AESS_CONTEXT */
#define OMAP4430_LOSTMEM_AESSMEM_SHIFT 8
-#define OMAP4430_LOSTMEM_AESSMEM_MASK BITFIELD(8, 8)
+#define OMAP4430_LOSTMEM_AESSMEM_MASK (1 << 8)
/* Used by RM_CAM_FDIF_CONTEXT, RM_CAM_ISS_CONTEXT */
#define OMAP4430_LOSTMEM_CAM_MEM_SHIFT 8
-#define OMAP4430_LOSTMEM_CAM_MEM_MASK BITFIELD(8, 8)
+#define OMAP4430_LOSTMEM_CAM_MEM_MASK (1 << 8)
/* Used by RM_L3INSTR_OCP_WP1_CONTEXT */
#define OMAP4430_LOSTMEM_CORE_NRET_BANK_SHIFT 8
-#define OMAP4430_LOSTMEM_CORE_NRET_BANK_MASK BITFIELD(8, 8)
+#define OMAP4430_LOSTMEM_CORE_NRET_BANK_MASK (1 << 8)
/* Renamed from LOSTMEM_CORE_NRET_BANK Used by RM_MEMIF_DMM_CONTEXT */
#define OMAP4430_LOSTMEM_CORE_NRET_BANK_9_9_SHIFT 9
-#define OMAP4430_LOSTMEM_CORE_NRET_BANK_9_9_MASK BITFIELD(9, 9)
+#define OMAP4430_LOSTMEM_CORE_NRET_BANK_9_9_MASK (1 << 9)
/* Used by RM_L3_2_OCMC_RAM_CONTEXT */
#define OMAP4430_LOSTMEM_CORE_OCMRAM_SHIFT 8
-#define OMAP4430_LOSTMEM_CORE_OCMRAM_MASK BITFIELD(8, 8)
+#define OMAP4430_LOSTMEM_CORE_OCMRAM_MASK (1 << 8)
/*
* Used by RM_D2D_MODEM_ICR_CONTEXT, RM_MEMIF_DMM_CONTEXT,
* RM_SDMA_SDMA_CONTEXT
*/
#define OMAP4430_LOSTMEM_CORE_OTHER_BANK_SHIFT 8
-#define OMAP4430_LOSTMEM_CORE_OTHER_BANK_MASK BITFIELD(8, 8)
+#define OMAP4430_LOSTMEM_CORE_OTHER_BANK_MASK (1 << 8)
/* Used by RM_DSS_DEISS_CONTEXT, RM_DSS_DSS_CONTEXT */
#define OMAP4430_LOSTMEM_DSS_MEM_SHIFT 8
-#define OMAP4430_LOSTMEM_DSS_MEM_MASK BITFIELD(8, 8)
+#define OMAP4430_LOSTMEM_DSS_MEM_MASK (1 << 8)
/* Used by RM_DUCATI_DUCATI_CONTEXT */
#define OMAP4430_LOSTMEM_DUCATI_L2RAM_SHIFT 9
-#define OMAP4430_LOSTMEM_DUCATI_L2RAM_MASK BITFIELD(9, 9)
+#define OMAP4430_LOSTMEM_DUCATI_L2RAM_MASK (1 << 9)
/* Used by RM_DUCATI_DUCATI_CONTEXT */
#define OMAP4430_LOSTMEM_DUCATI_UNICACHE_SHIFT 8
-#define OMAP4430_LOSTMEM_DUCATI_UNICACHE_MASK BITFIELD(8, 8)
+#define OMAP4430_LOSTMEM_DUCATI_UNICACHE_MASK (1 << 8)
/* Used by RM_EMU_DEBUGSS_CONTEXT */
#define OMAP4430_LOSTMEM_EMU_BANK_SHIFT 8
-#define OMAP4430_LOSTMEM_EMU_BANK_MASK BITFIELD(8, 8)
+#define OMAP4430_LOSTMEM_EMU_BANK_MASK (1 << 8)
/* Used by RM_GFX_GFX_CONTEXT */
#define OMAP4430_LOSTMEM_GFX_MEM_SHIFT 8
-#define OMAP4430_LOSTMEM_GFX_MEM_MASK BITFIELD(8, 8)
+#define OMAP4430_LOSTMEM_GFX_MEM_MASK (1 << 8)
/* Used by RM_IVAHD_IVAHD_CONTEXT */
#define OMAP4430_LOSTMEM_HWA_MEM_SHIFT 10
-#define OMAP4430_LOSTMEM_HWA_MEM_MASK BITFIELD(10, 10)
+#define OMAP4430_LOSTMEM_HWA_MEM_MASK (1 << 10)
/*
* Used by RM_L3INIT_CCPTX_CONTEXT, RM_L3INIT_EMAC_CONTEXT,
@@ -620,19 +644,19 @@
* RM_L3INIT_USB_OTG_CONTEXT, RM_L3INIT_XHPI_CONTEXT
*/
#define OMAP4430_LOSTMEM_L3INIT_BANK1_SHIFT 8
-#define OMAP4430_LOSTMEM_L3INIT_BANK1_MASK BITFIELD(8, 8)
+#define OMAP4430_LOSTMEM_L3INIT_BANK1_MASK (1 << 8)
/* Used by RM_MPU_MPU_CONTEXT */
#define OMAP4430_LOSTMEM_MPU_L1_SHIFT 8
-#define OMAP4430_LOSTMEM_MPU_L1_MASK BITFIELD(8, 8)
+#define OMAP4430_LOSTMEM_MPU_L1_MASK (1 << 8)
/* Used by RM_MPU_MPU_CONTEXT */
#define OMAP4430_LOSTMEM_MPU_L2_SHIFT 9
-#define OMAP4430_LOSTMEM_MPU_L2_MASK BITFIELD(9, 9)
+#define OMAP4430_LOSTMEM_MPU_L2_MASK (1 << 9)
/* Used by RM_MPU_MPU_CONTEXT */
#define OMAP4430_LOSTMEM_MPU_RAM_SHIFT 10
-#define OMAP4430_LOSTMEM_MPU_RAM_MASK BITFIELD(10, 10)
+#define OMAP4430_LOSTMEM_MPU_RAM_MASK (1 << 10)
/*
* Used by RM_L4PER_HECC1_CONTEXT, RM_L4PER_HECC2_CONTEXT,
@@ -640,14 +664,14 @@
* RM_L4PER_MMCSD5_CONTEXT, RM_L4PER_SLIMBUS2_CONTEXT, RM_L4SEC_PKAEIP29_CONTEXT
*/
#define OMAP4430_LOSTMEM_NONRETAINED_BANK_SHIFT 8
-#define OMAP4430_LOSTMEM_NONRETAINED_BANK_MASK BITFIELD(8, 8)
+#define OMAP4430_LOSTMEM_NONRETAINED_BANK_MASK (1 << 8)
/*
* Used by RM_ABE_DMIC_CONTEXT, RM_ABE_MCBSP1_CONTEXT, RM_ABE_MCBSP2_CONTEXT,
* RM_ABE_MCBSP3_CONTEXT, RM_ABE_PDM_CONTEXT, RM_ABE_SLIMBUS_CONTEXT
*/
#define OMAP4430_LOSTMEM_PERIHPMEM_SHIFT 8
-#define OMAP4430_LOSTMEM_PERIHPMEM_MASK BITFIELD(8, 8)
+#define OMAP4430_LOSTMEM_PERIHPMEM_MASK (1 << 8)
/*
* Used by RM_L4PER_MSPROHG_CONTEXT, RM_L4PER_UART1_CONTEXT,
@@ -655,245 +679,237 @@
* RM_L4SEC_CRYPTODMA_CONTEXT
*/
#define OMAP4430_LOSTMEM_RETAINED_BANK_SHIFT 8
-#define OMAP4430_LOSTMEM_RETAINED_BANK_MASK BITFIELD(8, 8)
+#define OMAP4430_LOSTMEM_RETAINED_BANK_MASK (1 << 8)
/* Used by RM_IVAHD_SL2_CONTEXT */
#define OMAP4430_LOSTMEM_SL2_MEM_SHIFT 8
-#define OMAP4430_LOSTMEM_SL2_MEM_MASK BITFIELD(8, 8)
+#define OMAP4430_LOSTMEM_SL2_MEM_MASK (1 << 8)
/* Used by RM_IVAHD_IVAHD_CONTEXT */
#define OMAP4430_LOSTMEM_TCM1_MEM_SHIFT 8
-#define OMAP4430_LOSTMEM_TCM1_MEM_MASK BITFIELD(8, 8)
+#define OMAP4430_LOSTMEM_TCM1_MEM_MASK (1 << 8)
/* Used by RM_IVAHD_IVAHD_CONTEXT */
#define OMAP4430_LOSTMEM_TCM2_MEM_SHIFT 9
-#define OMAP4430_LOSTMEM_TCM2_MEM_MASK BITFIELD(9, 9)
+#define OMAP4430_LOSTMEM_TCM2_MEM_MASK (1 << 9)
/* Used by RM_TESLA_TESLA_CONTEXT */
#define OMAP4430_LOSTMEM_TESLA_EDMA_SHIFT 10
-#define OMAP4430_LOSTMEM_TESLA_EDMA_MASK BITFIELD(10, 10)
+#define OMAP4430_LOSTMEM_TESLA_EDMA_MASK (1 << 10)
/* Used by RM_TESLA_TESLA_CONTEXT */
#define OMAP4430_LOSTMEM_TESLA_L1_SHIFT 8
-#define OMAP4430_LOSTMEM_TESLA_L1_MASK BITFIELD(8, 8)
+#define OMAP4430_LOSTMEM_TESLA_L1_MASK (1 << 8)
/* Used by RM_TESLA_TESLA_CONTEXT */
#define OMAP4430_LOSTMEM_TESLA_L2_SHIFT 9
-#define OMAP4430_LOSTMEM_TESLA_L2_MASK BITFIELD(9, 9)
+#define OMAP4430_LOSTMEM_TESLA_L2_MASK (1 << 9)
/* Used by RM_WKUP_SARRAM_CONTEXT */
#define OMAP4430_LOSTMEM_WKUP_BANK_SHIFT 8
-#define OMAP4430_LOSTMEM_WKUP_BANK_MASK BITFIELD(8, 8)
+#define OMAP4430_LOSTMEM_WKUP_BANK_MASK (1 << 8)
/*
- * Used by PM_CORE_PWRSTCTRL, PM_CAM_PWRSTCTRL, PM_L3INIT_PWRSTCTRL,
- * PM_ABE_PWRSTCTRL, PM_GFX_PWRSTCTRL, PM_MPU_PWRSTCTRL, PM_CEFUSE_PWRSTCTRL,
- * PM_DSS_PWRSTCTRL, PM_L4PER_PWRSTCTRL, PM_TESLA_PWRSTCTRL, PM_IVAHD_PWRSTCTRL
+ * Used by PM_ABE_PWRSTCTRL, PM_CAM_PWRSTCTRL, PM_CEFUSE_PWRSTCTRL,
+ * PM_CORE_PWRSTCTRL, PM_DSS_PWRSTCTRL, PM_GFX_PWRSTCTRL, PM_IVAHD_PWRSTCTRL,
+ * PM_L3INIT_PWRSTCTRL, PM_L4PER_PWRSTCTRL, PM_MPU_PWRSTCTRL, PM_TESLA_PWRSTCTRL
*/
#define OMAP4430_LOWPOWERSTATECHANGE_SHIFT 4
-#define OMAP4430_LOWPOWERSTATECHANGE_MASK BITFIELD(4, 4)
-
-/* Used by PM_CORE_PWRSTCTRL */
-#define OMAP4430_MEMORYCHANGE_SHIFT 3
-#define OMAP4430_MEMORYCHANGE_MASK BITFIELD(3, 3)
+#define OMAP4430_LOWPOWERSTATECHANGE_MASK (1 << 4)
/* Used by PRM_MODEM_IF_CTRL */
#define OMAP4430_MODEM_READY_SHIFT 1
-#define OMAP4430_MODEM_READY_MASK BITFIELD(1, 1)
+#define OMAP4430_MODEM_READY_MASK (1 << 1)
/* Used by PRM_MODEM_IF_CTRL */
#define OMAP4430_MODEM_SHUTDOWN_IRQ_SHIFT 9
-#define OMAP4430_MODEM_SHUTDOWN_IRQ_MASK BITFIELD(9, 9)
+#define OMAP4430_MODEM_SHUTDOWN_IRQ_MASK (1 << 9)
/* Used by PRM_MODEM_IF_CTRL */
#define OMAP4430_MODEM_SLEEP_ST_SHIFT 16
-#define OMAP4430_MODEM_SLEEP_ST_MASK BITFIELD(16, 16)
+#define OMAP4430_MODEM_SLEEP_ST_MASK (1 << 16)
/* Used by PRM_MODEM_IF_CTRL */
#define OMAP4430_MODEM_WAKE_IRQ_SHIFT 8
-#define OMAP4430_MODEM_WAKE_IRQ_MASK BITFIELD(8, 8)
+#define OMAP4430_MODEM_WAKE_IRQ_MASK (1 << 8)
/* Used by PM_MPU_PWRSTCTRL */
#define OMAP4430_MPU_L1_ONSTATE_SHIFT 16
-#define OMAP4430_MPU_L1_ONSTATE_MASK BITFIELD(16, 17)
+#define OMAP4430_MPU_L1_ONSTATE_MASK (0x3 << 16)
/* Used by PM_MPU_PWRSTCTRL */
#define OMAP4430_MPU_L1_RETSTATE_SHIFT 8
-#define OMAP4430_MPU_L1_RETSTATE_MASK BITFIELD(8, 8)
+#define OMAP4430_MPU_L1_RETSTATE_MASK (1 << 8)
/* Used by PM_MPU_PWRSTST */
#define OMAP4430_MPU_L1_STATEST_SHIFT 4
-#define OMAP4430_MPU_L1_STATEST_MASK BITFIELD(4, 5)
+#define OMAP4430_MPU_L1_STATEST_MASK (0x3 << 4)
/* Used by PM_MPU_PWRSTCTRL */
#define OMAP4430_MPU_L2_ONSTATE_SHIFT 18
-#define OMAP4430_MPU_L2_ONSTATE_MASK BITFIELD(18, 19)
+#define OMAP4430_MPU_L2_ONSTATE_MASK (0x3 << 18)
/* Used by PM_MPU_PWRSTCTRL */
#define OMAP4430_MPU_L2_RETSTATE_SHIFT 9
-#define OMAP4430_MPU_L2_RETSTATE_MASK BITFIELD(9, 9)
+#define OMAP4430_MPU_L2_RETSTATE_MASK (1 << 9)
/* Used by PM_MPU_PWRSTST */
#define OMAP4430_MPU_L2_STATEST_SHIFT 6
-#define OMAP4430_MPU_L2_STATEST_MASK BITFIELD(6, 7)
+#define OMAP4430_MPU_L2_STATEST_MASK (0x3 << 6)
/* Used by PM_MPU_PWRSTCTRL */
#define OMAP4430_MPU_RAM_ONSTATE_SHIFT 20
-#define OMAP4430_MPU_RAM_ONSTATE_MASK BITFIELD(20, 21)
+#define OMAP4430_MPU_RAM_ONSTATE_MASK (0x3 << 20)
/* Used by PM_MPU_PWRSTCTRL */
#define OMAP4430_MPU_RAM_RETSTATE_SHIFT 10
-#define OMAP4430_MPU_RAM_RETSTATE_MASK BITFIELD(10, 10)
+#define OMAP4430_MPU_RAM_RETSTATE_MASK (1 << 10)
/* Used by PM_MPU_PWRSTST */
#define OMAP4430_MPU_RAM_STATEST_SHIFT 8
-#define OMAP4430_MPU_RAM_STATEST_MASK BITFIELD(8, 9)
+#define OMAP4430_MPU_RAM_STATEST_MASK (0x3 << 8)
/* Used by PRM_RSTST */
#define OMAP4430_MPU_SECURITY_VIOL_RST_SHIFT 2
-#define OMAP4430_MPU_SECURITY_VIOL_RST_MASK BITFIELD(2, 2)
+#define OMAP4430_MPU_SECURITY_VIOL_RST_MASK (1 << 2)
/* Used by PRM_RSTST */
#define OMAP4430_MPU_WDT_RST_SHIFT 3
-#define OMAP4430_MPU_WDT_RST_MASK BITFIELD(3, 3)
+#define OMAP4430_MPU_WDT_RST_MASK (1 << 3)
/* Used by PM_L4PER_PWRSTCTRL */
#define OMAP4430_NONRETAINED_BANK_ONSTATE_SHIFT 18
-#define OMAP4430_NONRETAINED_BANK_ONSTATE_MASK BITFIELD(18, 19)
+#define OMAP4430_NONRETAINED_BANK_ONSTATE_MASK (0x3 << 18)
/* Used by PM_L4PER_PWRSTCTRL */
#define OMAP4430_NONRETAINED_BANK_RETSTATE_SHIFT 9
-#define OMAP4430_NONRETAINED_BANK_RETSTATE_MASK BITFIELD(9, 9)
+#define OMAP4430_NONRETAINED_BANK_RETSTATE_MASK (1 << 9)
/* Used by PM_L4PER_PWRSTST */
#define OMAP4430_NONRETAINED_BANK_STATEST_SHIFT 6
-#define OMAP4430_NONRETAINED_BANK_STATEST_MASK BITFIELD(6, 7)
+#define OMAP4430_NONRETAINED_BANK_STATEST_MASK (0x3 << 6)
/* Used by PM_CORE_PWRSTCTRL */
#define OMAP4430_OCP_NRET_BANK_ONSTATE_SHIFT 24
-#define OMAP4430_OCP_NRET_BANK_ONSTATE_MASK BITFIELD(24, 25)
+#define OMAP4430_OCP_NRET_BANK_ONSTATE_MASK (0x3 << 24)
/* Used by PM_CORE_PWRSTCTRL */
#define OMAP4430_OCP_NRET_BANK_RETSTATE_SHIFT 12
-#define OMAP4430_OCP_NRET_BANK_RETSTATE_MASK BITFIELD(12, 12)
+#define OMAP4430_OCP_NRET_BANK_RETSTATE_MASK (1 << 12)
/* Used by PM_CORE_PWRSTST */
#define OMAP4430_OCP_NRET_BANK_STATEST_SHIFT 12
-#define OMAP4430_OCP_NRET_BANK_STATEST_MASK BITFIELD(12, 13)
+#define OMAP4430_OCP_NRET_BANK_STATEST_MASK (0x3 << 12)
/*
* Used by PRM_VC_VAL_CMD_VDD_CORE_L, PRM_VC_VAL_CMD_VDD_IVA_L,
* PRM_VC_VAL_CMD_VDD_MPU_L
*/
#define OMAP4430_OFF_SHIFT 0
-#define OMAP4430_OFF_MASK BITFIELD(0, 7)
-
-/* Used by PRM_LDO_BANDGAP_CTRL */
-#define OMAP4430_OFF_ENABLE_SHIFT 0
-#define OMAP4430_OFF_ENABLE_MASK BITFIELD(0, 0)
+#define OMAP4430_OFF_MASK (0xff << 0)
/*
* Used by PRM_VC_VAL_CMD_VDD_CORE_L, PRM_VC_VAL_CMD_VDD_IVA_L,
* PRM_VC_VAL_CMD_VDD_MPU_L
*/
#define OMAP4430_ON_SHIFT 24
-#define OMAP4430_ON_MASK BITFIELD(24, 31)
+#define OMAP4430_ON_MASK (0xff << 24)
/*
* Used by PRM_VC_VAL_CMD_VDD_CORE_L, PRM_VC_VAL_CMD_VDD_IVA_L,
* PRM_VC_VAL_CMD_VDD_MPU_L
*/
#define OMAP4430_ONLP_SHIFT 16
-#define OMAP4430_ONLP_MASK BITFIELD(16, 23)
+#define OMAP4430_ONLP_MASK (0xff << 16)
/* Used by PRM_LDO_ABB_IVA_CTRL, PRM_LDO_ABB_MPU_CTRL */
#define OMAP4430_OPP_CHANGE_SHIFT 2
-#define OMAP4430_OPP_CHANGE_MASK BITFIELD(2, 2)
+#define OMAP4430_OPP_CHANGE_MASK (1 << 2)
/* Used by PRM_LDO_ABB_IVA_CTRL, PRM_LDO_ABB_MPU_CTRL */
#define OMAP4430_OPP_SEL_SHIFT 0
-#define OMAP4430_OPP_SEL_MASK BITFIELD(0, 1)
+#define OMAP4430_OPP_SEL_MASK (0x3 << 0)
/* Used by PRM_SRAM_COUNT */
#define OMAP4430_PCHARGECNT_VALUE_SHIFT 0
-#define OMAP4430_PCHARGECNT_VALUE_MASK BITFIELD(0, 5)
+#define OMAP4430_PCHARGECNT_VALUE_MASK (0x3f << 0)
/* Used by PRM_PSCON_COUNT */
#define OMAP4430_PCHARGE_TIME_SHIFT 0
-#define OMAP4430_PCHARGE_TIME_MASK BITFIELD(0, 7)
+#define OMAP4430_PCHARGE_TIME_MASK (0xff << 0)
/* Used by PM_ABE_PWRSTCTRL */
#define OMAP4430_PERIPHMEM_ONSTATE_SHIFT 20
-#define OMAP4430_PERIPHMEM_ONSTATE_MASK BITFIELD(20, 21)
+#define OMAP4430_PERIPHMEM_ONSTATE_MASK (0x3 << 20)
/* Used by PM_ABE_PWRSTCTRL */
#define OMAP4430_PERIPHMEM_RETSTATE_SHIFT 10
-#define OMAP4430_PERIPHMEM_RETSTATE_MASK BITFIELD(10, 10)
+#define OMAP4430_PERIPHMEM_RETSTATE_MASK (1 << 10)
/* Used by PM_ABE_PWRSTST */
#define OMAP4430_PERIPHMEM_STATEST_SHIFT 8
-#define OMAP4430_PERIPHMEM_STATEST_MASK BITFIELD(8, 9)
+#define OMAP4430_PERIPHMEM_STATEST_MASK (0x3 << 8)
/* Used by PRM_PHASE1_CNDP */
#define OMAP4430_PHASE1_CNDP_SHIFT 0
-#define OMAP4430_PHASE1_CNDP_MASK BITFIELD(0, 31)
+#define OMAP4430_PHASE1_CNDP_MASK (0xffffffff << 0)
/* Used by PRM_PHASE2A_CNDP */
#define OMAP4430_PHASE2A_CNDP_SHIFT 0
-#define OMAP4430_PHASE2A_CNDP_MASK BITFIELD(0, 31)
+#define OMAP4430_PHASE2A_CNDP_MASK (0xffffffff << 0)
/* Used by PRM_PHASE2B_CNDP */
#define OMAP4430_PHASE2B_CNDP_SHIFT 0
-#define OMAP4430_PHASE2B_CNDP_MASK BITFIELD(0, 31)
+#define OMAP4430_PHASE2B_CNDP_MASK (0xffffffff << 0)
/* Used by PRM_PSCON_COUNT */
#define OMAP4430_PONOUT_2_PGOODIN_TIME_SHIFT 8
-#define OMAP4430_PONOUT_2_PGOODIN_TIME_MASK BITFIELD(8, 15)
+#define OMAP4430_PONOUT_2_PGOODIN_TIME_MASK (0xff << 8)
/*
- * Used by PM_EMU_PWRSTCTRL, PM_CORE_PWRSTCTRL, PM_CAM_PWRSTCTRL,
- * PM_L3INIT_PWRSTCTRL, PM_ABE_PWRSTCTRL, PM_GFX_PWRSTCTRL, PM_MPU_PWRSTCTRL,
- * PM_CEFUSE_PWRSTCTRL, PM_DSS_PWRSTCTRL, PM_L4PER_PWRSTCTRL,
- * PM_TESLA_PWRSTCTRL, PM_IVAHD_PWRSTCTRL
+ * Used by PM_ABE_PWRSTCTRL, PM_CAM_PWRSTCTRL, PM_CEFUSE_PWRSTCTRL,
+ * PM_CORE_PWRSTCTRL, PM_DSS_PWRSTCTRL, PM_EMU_PWRSTCTRL, PM_GFX_PWRSTCTRL,
+ * PM_IVAHD_PWRSTCTRL, PM_L3INIT_PWRSTCTRL, PM_L4PER_PWRSTCTRL,
+ * PM_MPU_PWRSTCTRL, PM_TESLA_PWRSTCTRL
*/
#define OMAP4430_POWERSTATE_SHIFT 0
-#define OMAP4430_POWERSTATE_MASK BITFIELD(0, 1)
+#define OMAP4430_POWERSTATE_MASK (0x3 << 0)
/*
- * Used by PM_EMU_PWRSTST, PM_CORE_PWRSTST, PM_CAM_PWRSTST, PM_L3INIT_PWRSTST,
- * PM_ABE_PWRSTST, PM_GFX_PWRSTST, PM_MPU_PWRSTST, PM_CEFUSE_PWRSTST,
- * PM_DSS_PWRSTST, PM_L4PER_PWRSTST, PM_TESLA_PWRSTST, PM_IVAHD_PWRSTST
+ * Used by PM_ABE_PWRSTST, PM_CAM_PWRSTST, PM_CEFUSE_PWRSTST, PM_CORE_PWRSTST,
+ * PM_DSS_PWRSTST, PM_EMU_PWRSTST, PM_GFX_PWRSTST, PM_IVAHD_PWRSTST,
+ * PM_L3INIT_PWRSTST, PM_L4PER_PWRSTST, PM_MPU_PWRSTST, PM_TESLA_PWRSTST
*/
#define OMAP4430_POWERSTATEST_SHIFT 0
-#define OMAP4430_POWERSTATEST_MASK BITFIELD(0, 1)
+#define OMAP4430_POWERSTATEST_MASK (0x3 << 0)
/* Used by PRM_PWRREQCTRL */
#define OMAP4430_PWRREQ_COND_SHIFT 0
-#define OMAP4430_PWRREQ_COND_MASK BITFIELD(0, 1)
+#define OMAP4430_PWRREQ_COND_MASK (0x3 << 0)
/* Used by PRM_VC_CFG_CHANNEL */
#define OMAP4430_RACEN_VDD_CORE_L_SHIFT 3
-#define OMAP4430_RACEN_VDD_CORE_L_MASK BITFIELD(3, 3)
+#define OMAP4430_RACEN_VDD_CORE_L_MASK (1 << 3)
/* Used by PRM_VC_CFG_CHANNEL */
#define OMAP4430_RACEN_VDD_IVA_L_SHIFT 11
-#define OMAP4430_RACEN_VDD_IVA_L_MASK BITFIELD(11, 11)
+#define OMAP4430_RACEN_VDD_IVA_L_MASK (1 << 11)
/* Used by PRM_VC_CFG_CHANNEL */
#define OMAP4430_RACEN_VDD_MPU_L_SHIFT 20
-#define OMAP4430_RACEN_VDD_MPU_L_MASK BITFIELD(20, 20)
+#define OMAP4430_RACEN_VDD_MPU_L_MASK (1 << 20)
/* Used by PRM_VC_CFG_CHANNEL */
#define OMAP4430_RAC_VDD_CORE_L_SHIFT 2
-#define OMAP4430_RAC_VDD_CORE_L_MASK BITFIELD(2, 2)
+#define OMAP4430_RAC_VDD_CORE_L_MASK (1 << 2)
/* Used by PRM_VC_CFG_CHANNEL */
#define OMAP4430_RAC_VDD_IVA_L_SHIFT 10
-#define OMAP4430_RAC_VDD_IVA_L_MASK BITFIELD(10, 10)
+#define OMAP4430_RAC_VDD_IVA_L_MASK (1 << 10)
/* Used by PRM_VC_CFG_CHANNEL */
#define OMAP4430_RAC_VDD_MPU_L_SHIFT 19
-#define OMAP4430_RAC_VDD_MPU_L_MASK BITFIELD(19, 19)
+#define OMAP4430_RAC_VDD_MPU_L_MASK (1 << 19)
/*
* Used by PRM_VOLTSETUP_CORE_OFF, PRM_VOLTSETUP_CORE_RET_SLEEP,
@@ -901,7 +917,7 @@
* PRM_VOLTSETUP_MPU_RET_SLEEP
*/
#define OMAP4430_RAMP_DOWN_COUNT_SHIFT 16
-#define OMAP4430_RAMP_DOWN_COUNT_MASK BITFIELD(16, 21)
+#define OMAP4430_RAMP_DOWN_COUNT_MASK (0x3f << 16)
/*
* Used by PRM_VOLTSETUP_CORE_OFF, PRM_VOLTSETUP_CORE_RET_SLEEP,
@@ -909,7 +925,7 @@
* PRM_VOLTSETUP_MPU_RET_SLEEP
*/
#define OMAP4430_RAMP_DOWN_PRESCAL_SHIFT 24
-#define OMAP4430_RAMP_DOWN_PRESCAL_MASK BITFIELD(24, 25)
+#define OMAP4430_RAMP_DOWN_PRESCAL_MASK (0x3 << 24)
/*
* Used by PRM_VOLTSETUP_CORE_OFF, PRM_VOLTSETUP_CORE_RET_SLEEP,
@@ -917,7 +933,7 @@
* PRM_VOLTSETUP_MPU_RET_SLEEP
*/
#define OMAP4430_RAMP_UP_COUNT_SHIFT 0
-#define OMAP4430_RAMP_UP_COUNT_MASK BITFIELD(0, 5)
+#define OMAP4430_RAMP_UP_COUNT_MASK (0x3f << 0)
/*
* Used by PRM_VOLTSETUP_CORE_OFF, PRM_VOLTSETUP_CORE_RET_SLEEP,
@@ -925,1281 +941,1381 @@
* PRM_VOLTSETUP_MPU_RET_SLEEP
*/
#define OMAP4430_RAMP_UP_PRESCAL_SHIFT 8
-#define OMAP4430_RAMP_UP_PRESCAL_MASK BITFIELD(8, 9)
+#define OMAP4430_RAMP_UP_PRESCAL_MASK (0x3 << 8)
/* Used by PRM_VC_CFG_CHANNEL */
#define OMAP4430_RAV_VDD_CORE_L_SHIFT 1
-#define OMAP4430_RAV_VDD_CORE_L_MASK BITFIELD(1, 1)
+#define OMAP4430_RAV_VDD_CORE_L_MASK (1 << 1)
/* Used by PRM_VC_CFG_CHANNEL */
#define OMAP4430_RAV_VDD_IVA_L_SHIFT 9
-#define OMAP4430_RAV_VDD_IVA_L_MASK BITFIELD(9, 9)
+#define OMAP4430_RAV_VDD_IVA_L_MASK (1 << 9)
/* Used by PRM_VC_CFG_CHANNEL */
#define OMAP4430_RAV_VDD_MPU_L_SHIFT 18
-#define OMAP4430_RAV_VDD_MPU_L_MASK BITFIELD(18, 18)
+#define OMAP4430_RAV_VDD_MPU_L_MASK (1 << 18)
/* Used by PRM_VC_VAL_BYPASS */
#define OMAP4430_REGADDR_SHIFT 8
-#define OMAP4430_REGADDR_MASK BITFIELD(8, 15)
+#define OMAP4430_REGADDR_MASK (0xff << 8)
/*
* Used by PRM_VC_VAL_CMD_VDD_CORE_L, PRM_VC_VAL_CMD_VDD_IVA_L,
* PRM_VC_VAL_CMD_VDD_MPU_L
*/
#define OMAP4430_RET_SHIFT 8
-#define OMAP4430_RET_MASK BITFIELD(8, 15)
+#define OMAP4430_RET_MASK (0xff << 8)
/* Used by PM_L4PER_PWRSTCTRL */
#define OMAP4430_RETAINED_BANK_ONSTATE_SHIFT 16
-#define OMAP4430_RETAINED_BANK_ONSTATE_MASK BITFIELD(16, 17)
+#define OMAP4430_RETAINED_BANK_ONSTATE_MASK (0x3 << 16)
/* Used by PM_L4PER_PWRSTCTRL */
#define OMAP4430_RETAINED_BANK_RETSTATE_SHIFT 8
-#define OMAP4430_RETAINED_BANK_RETSTATE_MASK BITFIELD(8, 8)
+#define OMAP4430_RETAINED_BANK_RETSTATE_MASK (1 << 8)
/* Used by PM_L4PER_PWRSTST */
#define OMAP4430_RETAINED_BANK_STATEST_SHIFT 4
-#define OMAP4430_RETAINED_BANK_STATEST_MASK BITFIELD(4, 5)
+#define OMAP4430_RETAINED_BANK_STATEST_MASK (0x3 << 4)
/*
* Used by PRM_LDO_SRAM_CORE_CTRL, PRM_LDO_SRAM_IVA_CTRL,
* PRM_LDO_SRAM_MPU_CTRL
*/
#define OMAP4430_RETMODE_ENABLE_SHIFT 0
-#define OMAP4430_RETMODE_ENABLE_MASK BITFIELD(0, 0)
+#define OMAP4430_RETMODE_ENABLE_MASK (1 << 0)
-/* Used by REVISION_PRM */
-#define OMAP4430_REV_SHIFT 0
-#define OMAP4430_REV_MASK BITFIELD(0, 7)
-
-/* Used by RM_DUCATI_RSTCTRL, RM_TESLA_RSTCTRL, RM_IVAHD_RSTCTRL */
+/* Used by RM_DUCATI_RSTCTRL, RM_IVAHD_RSTCTRL, RM_TESLA_RSTCTRL */
#define OMAP4430_RST1_SHIFT 0
-#define OMAP4430_RST1_MASK BITFIELD(0, 0)
+#define OMAP4430_RST1_MASK (1 << 0)
-/* Used by RM_DUCATI_RSTST, RM_TESLA_RSTST, RM_IVAHD_RSTST */
+/* Used by RM_DUCATI_RSTST, RM_IVAHD_RSTST, RM_TESLA_RSTST */
#define OMAP4430_RST1ST_SHIFT 0
-#define OMAP4430_RST1ST_MASK BITFIELD(0, 0)
+#define OMAP4430_RST1ST_MASK (1 << 0)
-/* Used by RM_DUCATI_RSTCTRL, RM_TESLA_RSTCTRL, RM_IVAHD_RSTCTRL */
+/* Used by RM_DUCATI_RSTCTRL, RM_IVAHD_RSTCTRL, RM_TESLA_RSTCTRL */
#define OMAP4430_RST2_SHIFT 1
-#define OMAP4430_RST2_MASK BITFIELD(1, 1)
+#define OMAP4430_RST2_MASK (1 << 1)
-/* Used by RM_DUCATI_RSTST, RM_TESLA_RSTST, RM_IVAHD_RSTST */
+/* Used by RM_DUCATI_RSTST, RM_IVAHD_RSTST, RM_TESLA_RSTST */
#define OMAP4430_RST2ST_SHIFT 1
-#define OMAP4430_RST2ST_MASK BITFIELD(1, 1)
+#define OMAP4430_RST2ST_MASK (1 << 1)
/* Used by RM_DUCATI_RSTCTRL, RM_IVAHD_RSTCTRL */
#define OMAP4430_RST3_SHIFT 2
-#define OMAP4430_RST3_MASK BITFIELD(2, 2)
+#define OMAP4430_RST3_MASK (1 << 2)
/* Used by RM_DUCATI_RSTST, RM_IVAHD_RSTST */
#define OMAP4430_RST3ST_SHIFT 2
-#define OMAP4430_RST3ST_MASK BITFIELD(2, 2)
+#define OMAP4430_RST3ST_MASK (1 << 2)
/* Used by PRM_RSTTIME */
#define OMAP4430_RSTTIME1_SHIFT 0
-#define OMAP4430_RSTTIME1_MASK BITFIELD(0, 9)
+#define OMAP4430_RSTTIME1_MASK (0x3ff << 0)
/* Used by PRM_RSTTIME */
#define OMAP4430_RSTTIME2_SHIFT 10
-#define OMAP4430_RSTTIME2_MASK BITFIELD(10, 14)
+#define OMAP4430_RSTTIME2_MASK (0x1f << 10)
/* Used by PRM_RSTCTRL */
#define OMAP4430_RST_GLOBAL_COLD_SW_SHIFT 1
-#define OMAP4430_RST_GLOBAL_COLD_SW_MASK BITFIELD(1, 1)
+#define OMAP4430_RST_GLOBAL_COLD_SW_MASK (1 << 1)
/* Used by PRM_RSTCTRL */
#define OMAP4430_RST_GLOBAL_WARM_SW_SHIFT 0
-#define OMAP4430_RST_GLOBAL_WARM_SW_MASK BITFIELD(0, 0)
+#define OMAP4430_RST_GLOBAL_WARM_SW_MASK (1 << 0)
+
+/* Used by REVISION_PRM */
+#define OMAP4430_R_RTL_SHIFT 11
+#define OMAP4430_R_RTL_MASK (0x1f << 11)
/* Used by PRM_VC_CFG_CHANNEL */
#define OMAP4430_SA_VDD_CORE_L_SHIFT 0
-#define OMAP4430_SA_VDD_CORE_L_MASK BITFIELD(0, 0)
+#define OMAP4430_SA_VDD_CORE_L_MASK (1 << 0)
/* Renamed from SA_VDD_CORE_L Used by PRM_VC_SMPS_SA */
#define OMAP4430_SA_VDD_CORE_L_0_6_SHIFT 0
-#define OMAP4430_SA_VDD_CORE_L_0_6_MASK BITFIELD(0, 6)
+#define OMAP4430_SA_VDD_CORE_L_0_6_MASK (0x7f << 0)
/* Used by PRM_VC_CFG_CHANNEL */
#define OMAP4430_SA_VDD_IVA_L_SHIFT 8
-#define OMAP4430_SA_VDD_IVA_L_MASK BITFIELD(8, 8)
+#define OMAP4430_SA_VDD_IVA_L_MASK (1 << 8)
/* Renamed from SA_VDD_IVA_L Used by PRM_VC_SMPS_SA */
#define OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_SHIFT 8
-#define OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_MASK BITFIELD(8, 14)
+#define OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_MASK (0x7f << 8)
/* Used by PRM_VC_CFG_CHANNEL */
#define OMAP4430_SA_VDD_MPU_L_SHIFT 16
-#define OMAP4430_SA_VDD_MPU_L_MASK BITFIELD(16, 16)
+#define OMAP4430_SA_VDD_MPU_L_MASK (1 << 16)
/* Renamed from SA_VDD_MPU_L Used by PRM_VC_SMPS_SA */
#define OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_SHIFT 16
-#define OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_MASK BITFIELD(16, 22)
+#define OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_MASK (0x7f << 16)
+
+/* Used by REVISION_PRM */
+#define OMAP4430_SCHEME_SHIFT 30
+#define OMAP4430_SCHEME_MASK (0x3 << 30)
/* Used by PRM_VC_CFG_I2C_CLK */
#define OMAP4430_SCLH_SHIFT 0
-#define OMAP4430_SCLH_MASK BITFIELD(0, 7)
+#define OMAP4430_SCLH_MASK (0xff << 0)
/* Used by PRM_VC_CFG_I2C_CLK */
#define OMAP4430_SCLL_SHIFT 8
-#define OMAP4430_SCLL_MASK BITFIELD(8, 15)
+#define OMAP4430_SCLL_MASK (0xff << 8)
/* Used by PRM_RSTST */
#define OMAP4430_SECURE_WDT_RST_SHIFT 4
-#define OMAP4430_SECURE_WDT_RST_MASK BITFIELD(4, 4)
+#define OMAP4430_SECURE_WDT_RST_MASK (1 << 4)
/* Used by PM_IVAHD_PWRSTCTRL */
#define OMAP4430_SL2_MEM_ONSTATE_SHIFT 18
-#define OMAP4430_SL2_MEM_ONSTATE_MASK BITFIELD(18, 19)
+#define OMAP4430_SL2_MEM_ONSTATE_MASK (0x3 << 18)
/* Used by PM_IVAHD_PWRSTCTRL */
#define OMAP4430_SL2_MEM_RETSTATE_SHIFT 9
-#define OMAP4430_SL2_MEM_RETSTATE_MASK BITFIELD(9, 9)
+#define OMAP4430_SL2_MEM_RETSTATE_MASK (1 << 9)
/* Used by PM_IVAHD_PWRSTST */
#define OMAP4430_SL2_MEM_STATEST_SHIFT 6
-#define OMAP4430_SL2_MEM_STATEST_MASK BITFIELD(6, 7)
+#define OMAP4430_SL2_MEM_STATEST_MASK (0x3 << 6)
/* Used by PRM_VC_VAL_BYPASS */
#define OMAP4430_SLAVEADDR_SHIFT 0
-#define OMAP4430_SLAVEADDR_MASK BITFIELD(0, 6)
+#define OMAP4430_SLAVEADDR_MASK (0x7f << 0)
/* Used by PRM_LDO_ABB_IVA_SETUP, PRM_LDO_ABB_MPU_SETUP */
#define OMAP4430_SLEEP_RBB_SEL_SHIFT 3
-#define OMAP4430_SLEEP_RBB_SEL_MASK BITFIELD(3, 3)
+#define OMAP4430_SLEEP_RBB_SEL_MASK (1 << 3)
/* Used by PRM_SRAM_COUNT */
#define OMAP4430_SLPCNT_VALUE_SHIFT 16
-#define OMAP4430_SLPCNT_VALUE_MASK BITFIELD(16, 23)
+#define OMAP4430_SLPCNT_VALUE_MASK (0xff << 16)
/* Used by PRM_VP_CORE_VSTEPMAX, PRM_VP_IVA_VSTEPMAX, PRM_VP_MPU_VSTEPMAX */
#define OMAP4430_SMPSWAITTIMEMAX_SHIFT 8
-#define OMAP4430_SMPSWAITTIMEMAX_MASK BITFIELD(8, 23)
+#define OMAP4430_SMPSWAITTIMEMAX_MASK (0xffff << 8)
/* Used by PRM_VP_CORE_VSTEPMIN, PRM_VP_IVA_VSTEPMIN, PRM_VP_MPU_VSTEPMIN */
#define OMAP4430_SMPSWAITTIMEMIN_SHIFT 8
-#define OMAP4430_SMPSWAITTIMEMIN_MASK BITFIELD(8, 23)
+#define OMAP4430_SMPSWAITTIMEMIN_MASK (0xffff << 8)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_SMPS_RA_ERR_CORE_SHIFT 1
+#define OMAP4430_SMPS_RA_ERR_CORE_MASK (1 << 1)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_SMPS_RA_ERR_IVA_SHIFT 9
+#define OMAP4430_SMPS_RA_ERR_IVA_MASK (1 << 9)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_SMPS_RA_ERR_MPU_SHIFT 17
+#define OMAP4430_SMPS_RA_ERR_MPU_MASK (1 << 17)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_SMPS_SA_ERR_CORE_SHIFT 0
+#define OMAP4430_SMPS_SA_ERR_CORE_MASK (1 << 0)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_SMPS_SA_ERR_IVA_SHIFT 8
+#define OMAP4430_SMPS_SA_ERR_IVA_MASK (1 << 8)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_SMPS_SA_ERR_MPU_SHIFT 16
+#define OMAP4430_SMPS_SA_ERR_MPU_MASK (1 << 16)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_SMPS_TIMEOUT_ERR_CORE_SHIFT 2
+#define OMAP4430_SMPS_TIMEOUT_ERR_CORE_MASK (1 << 2)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_SMPS_TIMEOUT_ERR_IVA_SHIFT 10
+#define OMAP4430_SMPS_TIMEOUT_ERR_IVA_MASK (1 << 10)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_SMPS_TIMEOUT_ERR_MPU_SHIFT 18
+#define OMAP4430_SMPS_TIMEOUT_ERR_MPU_MASK (1 << 18)
/* Used by PRM_LDO_ABB_IVA_SETUP, PRM_LDO_ABB_MPU_SETUP */
#define OMAP4430_SR2EN_SHIFT 0
-#define OMAP4430_SR2EN_MASK BITFIELD(0, 0)
+#define OMAP4430_SR2EN_MASK (1 << 0)
/* Used by PRM_LDO_ABB_IVA_CTRL, PRM_LDO_ABB_MPU_CTRL */
#define OMAP4430_SR2_IN_TRANSITION_SHIFT 6
-#define OMAP4430_SR2_IN_TRANSITION_MASK BITFIELD(6, 6)
+#define OMAP4430_SR2_IN_TRANSITION_MASK (1 << 6)
/* Used by PRM_LDO_ABB_IVA_CTRL, PRM_LDO_ABB_MPU_CTRL */
#define OMAP4430_SR2_STATUS_SHIFT 3
-#define OMAP4430_SR2_STATUS_MASK BITFIELD(3, 4)
+#define OMAP4430_SR2_STATUS_MASK (0x3 << 3)
/* Used by PRM_LDO_ABB_IVA_SETUP, PRM_LDO_ABB_MPU_SETUP */
#define OMAP4430_SR2_WTCNT_VALUE_SHIFT 8
-#define OMAP4430_SR2_WTCNT_VALUE_MASK BITFIELD(8, 15)
+#define OMAP4430_SR2_WTCNT_VALUE_MASK (0xff << 8)
/*
* Used by PRM_LDO_SRAM_CORE_CTRL, PRM_LDO_SRAM_IVA_CTRL,
* PRM_LDO_SRAM_MPU_CTRL
*/
#define OMAP4430_SRAMLDO_STATUS_SHIFT 8
-#define OMAP4430_SRAMLDO_STATUS_MASK BITFIELD(8, 8)
+#define OMAP4430_SRAMLDO_STATUS_MASK (1 << 8)
/*
* Used by PRM_LDO_SRAM_CORE_CTRL, PRM_LDO_SRAM_IVA_CTRL,
* PRM_LDO_SRAM_MPU_CTRL
*/
#define OMAP4430_SRAM_IN_TRANSITION_SHIFT 9
-#define OMAP4430_SRAM_IN_TRANSITION_MASK BITFIELD(9, 9)
+#define OMAP4430_SRAM_IN_TRANSITION_MASK (1 << 9)
/* Used by PRM_VC_CFG_I2C_MODE */
#define OMAP4430_SRMODEEN_SHIFT 4
-#define OMAP4430_SRMODEEN_MASK BITFIELD(4, 4)
+#define OMAP4430_SRMODEEN_MASK (1 << 4)
/* Used by PRM_VOLTSETUP_WARMRESET */
#define OMAP4430_STABLE_COUNT_SHIFT 0
-#define OMAP4430_STABLE_COUNT_MASK BITFIELD(0, 5)
+#define OMAP4430_STABLE_COUNT_MASK (0x3f << 0)
/* Used by PRM_VOLTSETUP_WARMRESET */
#define OMAP4430_STABLE_PRESCAL_SHIFT 8
-#define OMAP4430_STABLE_PRESCAL_MASK BITFIELD(8, 9)
+#define OMAP4430_STABLE_PRESCAL_MASK (0x3 << 8)
+
+/* Used by PRM_LDO_BANDGAP_SETUP */
+#define OMAP4430_STARTUP_COUNT_SHIFT 0
+#define OMAP4430_STARTUP_COUNT_MASK (0xff << 0)
+
+/* Renamed from STARTUP_COUNT Used by PRM_SRAM_COUNT */
+#define OMAP4430_STARTUP_COUNT_24_31_SHIFT 24
+#define OMAP4430_STARTUP_COUNT_24_31_MASK (0xff << 24)
/* Used by PM_IVAHD_PWRSTCTRL */
#define OMAP4430_TCM1_MEM_ONSTATE_SHIFT 20
-#define OMAP4430_TCM1_MEM_ONSTATE_MASK BITFIELD(20, 21)
+#define OMAP4430_TCM1_MEM_ONSTATE_MASK (0x3 << 20)
/* Used by PM_IVAHD_PWRSTCTRL */
#define OMAP4430_TCM1_MEM_RETSTATE_SHIFT 10
-#define OMAP4430_TCM1_MEM_RETSTATE_MASK BITFIELD(10, 10)
+#define OMAP4430_TCM1_MEM_RETSTATE_MASK (1 << 10)
/* Used by PM_IVAHD_PWRSTST */
#define OMAP4430_TCM1_MEM_STATEST_SHIFT 8
-#define OMAP4430_TCM1_MEM_STATEST_MASK BITFIELD(8, 9)
+#define OMAP4430_TCM1_MEM_STATEST_MASK (0x3 << 8)
/* Used by PM_IVAHD_PWRSTCTRL */
#define OMAP4430_TCM2_MEM_ONSTATE_SHIFT 22
-#define OMAP4430_TCM2_MEM_ONSTATE_MASK BITFIELD(22, 23)
+#define OMAP4430_TCM2_MEM_ONSTATE_MASK (0x3 << 22)
/* Used by PM_IVAHD_PWRSTCTRL */
#define OMAP4430_TCM2_MEM_RETSTATE_SHIFT 11
-#define OMAP4430_TCM2_MEM_RETSTATE_MASK BITFIELD(11, 11)
+#define OMAP4430_TCM2_MEM_RETSTATE_MASK (1 << 11)
/* Used by PM_IVAHD_PWRSTST */
#define OMAP4430_TCM2_MEM_STATEST_SHIFT 10
-#define OMAP4430_TCM2_MEM_STATEST_MASK BITFIELD(10, 11)
+#define OMAP4430_TCM2_MEM_STATEST_MASK (0x3 << 10)
/* Used by RM_TESLA_RSTST */
#define OMAP4430_TESLASS_EMU_RSTST_SHIFT 2
-#define OMAP4430_TESLASS_EMU_RSTST_MASK BITFIELD(2, 2)
+#define OMAP4430_TESLASS_EMU_RSTST_MASK (1 << 2)
/* Used by RM_TESLA_RSTST */
#define OMAP4430_TESLA_DSP_EMU_REQ_RSTST_SHIFT 3
-#define OMAP4430_TESLA_DSP_EMU_REQ_RSTST_MASK BITFIELD(3, 3)
+#define OMAP4430_TESLA_DSP_EMU_REQ_RSTST_MASK (1 << 3)
/* Used by PM_TESLA_PWRSTCTRL */
#define OMAP4430_TESLA_EDMA_ONSTATE_SHIFT 20
-#define OMAP4430_TESLA_EDMA_ONSTATE_MASK BITFIELD(20, 21)
+#define OMAP4430_TESLA_EDMA_ONSTATE_MASK (0x3 << 20)
/* Used by PM_TESLA_PWRSTCTRL */
#define OMAP4430_TESLA_EDMA_RETSTATE_SHIFT 10
-#define OMAP4430_TESLA_EDMA_RETSTATE_MASK BITFIELD(10, 10)
+#define OMAP4430_TESLA_EDMA_RETSTATE_MASK (1 << 10)
/* Used by PM_TESLA_PWRSTST */
#define OMAP4430_TESLA_EDMA_STATEST_SHIFT 8
-#define OMAP4430_TESLA_EDMA_STATEST_MASK BITFIELD(8, 9)
+#define OMAP4430_TESLA_EDMA_STATEST_MASK (0x3 << 8)
/* Used by PM_TESLA_PWRSTCTRL */
#define OMAP4430_TESLA_L1_ONSTATE_SHIFT 16
-#define OMAP4430_TESLA_L1_ONSTATE_MASK BITFIELD(16, 17)
+#define OMAP4430_TESLA_L1_ONSTATE_MASK (0x3 << 16)
/* Used by PM_TESLA_PWRSTCTRL */
#define OMAP4430_TESLA_L1_RETSTATE_SHIFT 8
-#define OMAP4430_TESLA_L1_RETSTATE_MASK BITFIELD(8, 8)
+#define OMAP4430_TESLA_L1_RETSTATE_MASK (1 << 8)
/* Used by PM_TESLA_PWRSTST */
#define OMAP4430_TESLA_L1_STATEST_SHIFT 4
-#define OMAP4430_TESLA_L1_STATEST_MASK BITFIELD(4, 5)
+#define OMAP4430_TESLA_L1_STATEST_MASK (0x3 << 4)
/* Used by PM_TESLA_PWRSTCTRL */
#define OMAP4430_TESLA_L2_ONSTATE_SHIFT 18
-#define OMAP4430_TESLA_L2_ONSTATE_MASK BITFIELD(18, 19)
+#define OMAP4430_TESLA_L2_ONSTATE_MASK (0x3 << 18)
/* Used by PM_TESLA_PWRSTCTRL */
#define OMAP4430_TESLA_L2_RETSTATE_SHIFT 9
-#define OMAP4430_TESLA_L2_RETSTATE_MASK BITFIELD(9, 9)
+#define OMAP4430_TESLA_L2_RETSTATE_MASK (1 << 9)
/* Used by PM_TESLA_PWRSTST */
#define OMAP4430_TESLA_L2_STATEST_SHIFT 6
-#define OMAP4430_TESLA_L2_STATEST_MASK BITFIELD(6, 7)
+#define OMAP4430_TESLA_L2_STATEST_MASK (0x3 << 6)
/* Used by PRM_VP_CORE_VLIMITTO, PRM_VP_IVA_VLIMITTO, PRM_VP_MPU_VLIMITTO */
#define OMAP4430_TIMEOUT_SHIFT 0
-#define OMAP4430_TIMEOUT_MASK BITFIELD(0, 15)
+#define OMAP4430_TIMEOUT_MASK (0xffff << 0)
/* Used by PRM_VP_CORE_CONFIG, PRM_VP_IVA_CONFIG, PRM_VP_MPU_CONFIG */
#define OMAP4430_TIMEOUTEN_SHIFT 3
-#define OMAP4430_TIMEOUTEN_MASK BITFIELD(3, 3)
+#define OMAP4430_TIMEOUTEN_MASK (1 << 3)
/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
#define OMAP4430_TRANSITION_EN_SHIFT 8
-#define OMAP4430_TRANSITION_EN_MASK BITFIELD(8, 8)
+#define OMAP4430_TRANSITION_EN_MASK (1 << 8)
/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
#define OMAP4430_TRANSITION_ST_SHIFT 8
-#define OMAP4430_TRANSITION_ST_MASK BITFIELD(8, 8)
+#define OMAP4430_TRANSITION_ST_MASK (1 << 8)
/* Used by PRM_VC_VAL_BYPASS */
#define OMAP4430_VALID_SHIFT 24
-#define OMAP4430_VALID_MASK BITFIELD(24, 24)
+#define OMAP4430_VALID_MASK (1 << 24)
/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
#define OMAP4430_VC_BYPASSACK_EN_SHIFT 14
-#define OMAP4430_VC_BYPASSACK_EN_MASK BITFIELD(14, 14)
+#define OMAP4430_VC_BYPASSACK_EN_MASK (1 << 14)
/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
#define OMAP4430_VC_BYPASSACK_ST_SHIFT 14
-#define OMAP4430_VC_BYPASSACK_ST_MASK BITFIELD(14, 14)
+#define OMAP4430_VC_BYPASSACK_ST_MASK (1 << 14)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VC_CORE_VPACK_EN_SHIFT 22
+#define OMAP4430_VC_CORE_VPACK_EN_MASK (1 << 22)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VC_CORE_VPACK_ST_SHIFT 22
+#define OMAP4430_VC_CORE_VPACK_ST_MASK (1 << 22)
/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
#define OMAP4430_VC_IVA_VPACK_EN_SHIFT 30
-#define OMAP4430_VC_IVA_VPACK_EN_MASK BITFIELD(30, 30)
+#define OMAP4430_VC_IVA_VPACK_EN_MASK (1 << 30)
/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
#define OMAP4430_VC_IVA_VPACK_ST_SHIFT 30
-#define OMAP4430_VC_IVA_VPACK_ST_MASK BITFIELD(30, 30)
+#define OMAP4430_VC_IVA_VPACK_ST_MASK (1 << 30)
/* Used by PRM_IRQENABLE_MPU_2 */
#define OMAP4430_VC_MPU_VPACK_EN_SHIFT 6
-#define OMAP4430_VC_MPU_VPACK_EN_MASK BITFIELD(6, 6)
+#define OMAP4430_VC_MPU_VPACK_EN_MASK (1 << 6)
/* Used by PRM_IRQSTATUS_MPU_2 */
#define OMAP4430_VC_MPU_VPACK_ST_SHIFT 6
-#define OMAP4430_VC_MPU_VPACK_ST_MASK BITFIELD(6, 6)
+#define OMAP4430_VC_MPU_VPACK_ST_MASK (1 << 6)
/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
#define OMAP4430_VC_RAERR_EN_SHIFT 12
-#define OMAP4430_VC_RAERR_EN_MASK BITFIELD(12, 12)
+#define OMAP4430_VC_RAERR_EN_MASK (1 << 12)
/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
#define OMAP4430_VC_RAERR_ST_SHIFT 12
-#define OMAP4430_VC_RAERR_ST_MASK BITFIELD(12, 12)
+#define OMAP4430_VC_RAERR_ST_MASK (1 << 12)
/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
#define OMAP4430_VC_SAERR_EN_SHIFT 11
-#define OMAP4430_VC_SAERR_EN_MASK BITFIELD(11, 11)
+#define OMAP4430_VC_SAERR_EN_MASK (1 << 11)
/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
#define OMAP4430_VC_SAERR_ST_SHIFT 11
-#define OMAP4430_VC_SAERR_ST_MASK BITFIELD(11, 11)
+#define OMAP4430_VC_SAERR_ST_MASK (1 << 11)
/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
#define OMAP4430_VC_TOERR_EN_SHIFT 13
-#define OMAP4430_VC_TOERR_EN_MASK BITFIELD(13, 13)
+#define OMAP4430_VC_TOERR_EN_MASK (1 << 13)
/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
#define OMAP4430_VC_TOERR_ST_SHIFT 13
-#define OMAP4430_VC_TOERR_ST_MASK BITFIELD(13, 13)
+#define OMAP4430_VC_TOERR_ST_MASK (1 << 13)
/* Used by PRM_VP_CORE_VLIMITTO, PRM_VP_IVA_VLIMITTO, PRM_VP_MPU_VLIMITTO */
#define OMAP4430_VDDMAX_SHIFT 24
-#define OMAP4430_VDDMAX_MASK BITFIELD(24, 31)
+#define OMAP4430_VDDMAX_MASK (0xff << 24)
/* Used by PRM_VP_CORE_VLIMITTO, PRM_VP_IVA_VLIMITTO, PRM_VP_MPU_VLIMITTO */
#define OMAP4430_VDDMIN_SHIFT 16
-#define OMAP4430_VDDMIN_MASK BITFIELD(16, 23)
+#define OMAP4430_VDDMIN_MASK (0xff << 16)
/* Used by PRM_VOLTCTRL */
#define OMAP4430_VDD_CORE_I2C_DISABLE_SHIFT 12
-#define OMAP4430_VDD_CORE_I2C_DISABLE_MASK BITFIELD(12, 12)
+#define OMAP4430_VDD_CORE_I2C_DISABLE_MASK (1 << 12)
/* Used by PRM_RSTST */
#define OMAP4430_VDD_CORE_VOLT_MGR_RST_SHIFT 8
-#define OMAP4430_VDD_CORE_VOLT_MGR_RST_MASK BITFIELD(8, 8)
+#define OMAP4430_VDD_CORE_VOLT_MGR_RST_MASK (1 << 8)
/* Used by PRM_VOLTCTRL */
#define OMAP4430_VDD_IVA_I2C_DISABLE_SHIFT 14
-#define OMAP4430_VDD_IVA_I2C_DISABLE_MASK BITFIELD(14, 14)
+#define OMAP4430_VDD_IVA_I2C_DISABLE_MASK (1 << 14)
/* Used by PRM_VOLTCTRL */
#define OMAP4430_VDD_IVA_PRESENCE_SHIFT 9
-#define OMAP4430_VDD_IVA_PRESENCE_MASK BITFIELD(9, 9)
+#define OMAP4430_VDD_IVA_PRESENCE_MASK (1 << 9)
/* Used by PRM_RSTST */
#define OMAP4430_VDD_IVA_VOLT_MGR_RST_SHIFT 7
-#define OMAP4430_VDD_IVA_VOLT_MGR_RST_MASK BITFIELD(7, 7)
+#define OMAP4430_VDD_IVA_VOLT_MGR_RST_MASK (1 << 7)
/* Used by PRM_VOLTCTRL */
#define OMAP4430_VDD_MPU_I2C_DISABLE_SHIFT 13
-#define OMAP4430_VDD_MPU_I2C_DISABLE_MASK BITFIELD(13, 13)
+#define OMAP4430_VDD_MPU_I2C_DISABLE_MASK (1 << 13)
/* Used by PRM_VOLTCTRL */
#define OMAP4430_VDD_MPU_PRESENCE_SHIFT 8
-#define OMAP4430_VDD_MPU_PRESENCE_MASK BITFIELD(8, 8)
+#define OMAP4430_VDD_MPU_PRESENCE_MASK (1 << 8)
/* Used by PRM_RSTST */
#define OMAP4430_VDD_MPU_VOLT_MGR_RST_SHIFT 6
-#define OMAP4430_VDD_MPU_VOLT_MGR_RST_MASK BITFIELD(6, 6)
+#define OMAP4430_VDD_MPU_VOLT_MGR_RST_MASK (1 << 6)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_VFSM_RA_ERR_CORE_SHIFT 4
+#define OMAP4430_VFSM_RA_ERR_CORE_MASK (1 << 4)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_VFSM_RA_ERR_IVA_SHIFT 12
+#define OMAP4430_VFSM_RA_ERR_IVA_MASK (1 << 12)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_VFSM_RA_ERR_MPU_SHIFT 20
+#define OMAP4430_VFSM_RA_ERR_MPU_MASK (1 << 20)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_VFSM_SA_ERR_CORE_SHIFT 3
+#define OMAP4430_VFSM_SA_ERR_CORE_MASK (1 << 3)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_VFSM_SA_ERR_IVA_SHIFT 11
+#define OMAP4430_VFSM_SA_ERR_IVA_MASK (1 << 11)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_VFSM_SA_ERR_MPU_SHIFT 19
+#define OMAP4430_VFSM_SA_ERR_MPU_MASK (1 << 19)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_VFSM_TIMEOUT_ERR_CORE_SHIFT 5
+#define OMAP4430_VFSM_TIMEOUT_ERR_CORE_MASK (1 << 5)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_VFSM_TIMEOUT_ERR_IVA_SHIFT 13
+#define OMAP4430_VFSM_TIMEOUT_ERR_IVA_MASK (1 << 13)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_VFSM_TIMEOUT_ERR_MPU_SHIFT 21
+#define OMAP4430_VFSM_TIMEOUT_ERR_MPU_MASK (1 << 21)
/* Used by PRM_VC_VAL_SMPS_RA_VOL */
#define OMAP4430_VOLRA_VDD_CORE_L_SHIFT 0
-#define OMAP4430_VOLRA_VDD_CORE_L_MASK BITFIELD(0, 7)
+#define OMAP4430_VOLRA_VDD_CORE_L_MASK (0xff << 0)
/* Used by PRM_VC_VAL_SMPS_RA_VOL */
#define OMAP4430_VOLRA_VDD_IVA_L_SHIFT 8
-#define OMAP4430_VOLRA_VDD_IVA_L_MASK BITFIELD(8, 15)
+#define OMAP4430_VOLRA_VDD_IVA_L_MASK (0xff << 8)
/* Used by PRM_VC_VAL_SMPS_RA_VOL */
#define OMAP4430_VOLRA_VDD_MPU_L_SHIFT 16
-#define OMAP4430_VOLRA_VDD_MPU_L_MASK BITFIELD(16, 23)
+#define OMAP4430_VOLRA_VDD_MPU_L_MASK (0xff << 16)
/* Used by PRM_VP_CORE_CONFIG, PRM_VP_IVA_CONFIG, PRM_VP_MPU_CONFIG */
#define OMAP4430_VPENABLE_SHIFT 0
-#define OMAP4430_VPENABLE_MASK BITFIELD(0, 0)
+#define OMAP4430_VPENABLE_MASK (1 << 0)
/* Used by PRM_VP_CORE_STATUS, PRM_VP_IVA_STATUS, PRM_VP_MPU_STATUS */
#define OMAP4430_VPINIDLE_SHIFT 0
-#define OMAP4430_VPINIDLE_MASK BITFIELD(0, 0)
+#define OMAP4430_VPINIDLE_MASK (1 << 0)
/* Used by PRM_VP_CORE_VOLTAGE, PRM_VP_IVA_VOLTAGE, PRM_VP_MPU_VOLTAGE */
#define OMAP4430_VPVOLTAGE_SHIFT 0
-#define OMAP4430_VPVOLTAGE_MASK BITFIELD(0, 7)
+#define OMAP4430_VPVOLTAGE_MASK (0xff << 0)
/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
#define OMAP4430_VP_CORE_EQVALUE_EN_SHIFT 20
-#define OMAP4430_VP_CORE_EQVALUE_EN_MASK BITFIELD(20, 20)
+#define OMAP4430_VP_CORE_EQVALUE_EN_MASK (1 << 20)
/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
#define OMAP4430_VP_CORE_EQVALUE_ST_SHIFT 20
-#define OMAP4430_VP_CORE_EQVALUE_ST_MASK BITFIELD(20, 20)
+#define OMAP4430_VP_CORE_EQVALUE_ST_MASK (1 << 20)
/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
#define OMAP4430_VP_CORE_MAXVDD_EN_SHIFT 18
-#define OMAP4430_VP_CORE_MAXVDD_EN_MASK BITFIELD(18, 18)
+#define OMAP4430_VP_CORE_MAXVDD_EN_MASK (1 << 18)
/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
#define OMAP4430_VP_CORE_MAXVDD_ST_SHIFT 18
-#define OMAP4430_VP_CORE_MAXVDD_ST_MASK BITFIELD(18, 18)
+#define OMAP4430_VP_CORE_MAXVDD_ST_MASK (1 << 18)
/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
#define OMAP4430_VP_CORE_MINVDD_EN_SHIFT 17
-#define OMAP4430_VP_CORE_MINVDD_EN_MASK BITFIELD(17, 17)
+#define OMAP4430_VP_CORE_MINVDD_EN_MASK (1 << 17)
/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
#define OMAP4430_VP_CORE_MINVDD_ST_SHIFT 17
-#define OMAP4430_VP_CORE_MINVDD_ST_MASK BITFIELD(17, 17)
+#define OMAP4430_VP_CORE_MINVDD_ST_MASK (1 << 17)
/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
#define OMAP4430_VP_CORE_NOSMPSACK_EN_SHIFT 19
-#define OMAP4430_VP_CORE_NOSMPSACK_EN_MASK BITFIELD(19, 19)
+#define OMAP4430_VP_CORE_NOSMPSACK_EN_MASK (1 << 19)
/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
#define OMAP4430_VP_CORE_NOSMPSACK_ST_SHIFT 19
-#define OMAP4430_VP_CORE_NOSMPSACK_ST_MASK BITFIELD(19, 19)
+#define OMAP4430_VP_CORE_NOSMPSACK_ST_MASK (1 << 19)
/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
#define OMAP4430_VP_CORE_OPPCHANGEDONE_EN_SHIFT 16
-#define OMAP4430_VP_CORE_OPPCHANGEDONE_EN_MASK BITFIELD(16, 16)
+#define OMAP4430_VP_CORE_OPPCHANGEDONE_EN_MASK (1 << 16)
/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
#define OMAP4430_VP_CORE_OPPCHANGEDONE_ST_SHIFT 16
-#define OMAP4430_VP_CORE_OPPCHANGEDONE_ST_MASK BITFIELD(16, 16)
+#define OMAP4430_VP_CORE_OPPCHANGEDONE_ST_MASK (1 << 16)
/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
#define OMAP4430_VP_CORE_TRANXDONE_EN_SHIFT 21
-#define OMAP4430_VP_CORE_TRANXDONE_EN_MASK BITFIELD(21, 21)
+#define OMAP4430_VP_CORE_TRANXDONE_EN_MASK (1 << 21)
/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
#define OMAP4430_VP_CORE_TRANXDONE_ST_SHIFT 21
-#define OMAP4430_VP_CORE_TRANXDONE_ST_MASK BITFIELD(21, 21)
+#define OMAP4430_VP_CORE_TRANXDONE_ST_MASK (1 << 21)
/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
#define OMAP4430_VP_IVA_EQVALUE_EN_SHIFT 28
-#define OMAP4430_VP_IVA_EQVALUE_EN_MASK BITFIELD(28, 28)
+#define OMAP4430_VP_IVA_EQVALUE_EN_MASK (1 << 28)
/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
#define OMAP4430_VP_IVA_EQVALUE_ST_SHIFT 28
-#define OMAP4430_VP_IVA_EQVALUE_ST_MASK BITFIELD(28, 28)
+#define OMAP4430_VP_IVA_EQVALUE_ST_MASK (1 << 28)
/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
#define OMAP4430_VP_IVA_MAXVDD_EN_SHIFT 26
-#define OMAP4430_VP_IVA_MAXVDD_EN_MASK BITFIELD(26, 26)
+#define OMAP4430_VP_IVA_MAXVDD_EN_MASK (1 << 26)
/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
#define OMAP4430_VP_IVA_MAXVDD_ST_SHIFT 26
-#define OMAP4430_VP_IVA_MAXVDD_ST_MASK BITFIELD(26, 26)
+#define OMAP4430_VP_IVA_MAXVDD_ST_MASK (1 << 26)
/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
#define OMAP4430_VP_IVA_MINVDD_EN_SHIFT 25
-#define OMAP4430_VP_IVA_MINVDD_EN_MASK BITFIELD(25, 25)
+#define OMAP4430_VP_IVA_MINVDD_EN_MASK (1 << 25)
/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
#define OMAP4430_VP_IVA_MINVDD_ST_SHIFT 25
-#define OMAP4430_VP_IVA_MINVDD_ST_MASK BITFIELD(25, 25)
+#define OMAP4430_VP_IVA_MINVDD_ST_MASK (1 << 25)
/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
#define OMAP4430_VP_IVA_NOSMPSACK_EN_SHIFT 27
-#define OMAP4430_VP_IVA_NOSMPSACK_EN_MASK BITFIELD(27, 27)
+#define OMAP4430_VP_IVA_NOSMPSACK_EN_MASK (1 << 27)
/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
#define OMAP4430_VP_IVA_NOSMPSACK_ST_SHIFT 27
-#define OMAP4430_VP_IVA_NOSMPSACK_ST_MASK BITFIELD(27, 27)
+#define OMAP4430_VP_IVA_NOSMPSACK_ST_MASK (1 << 27)
/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
#define OMAP4430_VP_IVA_OPPCHANGEDONE_EN_SHIFT 24
-#define OMAP4430_VP_IVA_OPPCHANGEDONE_EN_MASK BITFIELD(24, 24)
+#define OMAP4430_VP_IVA_OPPCHANGEDONE_EN_MASK (1 << 24)
/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
#define OMAP4430_VP_IVA_OPPCHANGEDONE_ST_SHIFT 24
-#define OMAP4430_VP_IVA_OPPCHANGEDONE_ST_MASK BITFIELD(24, 24)
+#define OMAP4430_VP_IVA_OPPCHANGEDONE_ST_MASK (1 << 24)
/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
#define OMAP4430_VP_IVA_TRANXDONE_EN_SHIFT 29
-#define OMAP4430_VP_IVA_TRANXDONE_EN_MASK BITFIELD(29, 29)
+#define OMAP4430_VP_IVA_TRANXDONE_EN_MASK (1 << 29)
/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
#define OMAP4430_VP_IVA_TRANXDONE_ST_SHIFT 29
-#define OMAP4430_VP_IVA_TRANXDONE_ST_MASK BITFIELD(29, 29)
+#define OMAP4430_VP_IVA_TRANXDONE_ST_MASK (1 << 29)
/* Used by PRM_IRQENABLE_MPU_2 */
#define OMAP4430_VP_MPU_EQVALUE_EN_SHIFT 4
-#define OMAP4430_VP_MPU_EQVALUE_EN_MASK BITFIELD(4, 4)
+#define OMAP4430_VP_MPU_EQVALUE_EN_MASK (1 << 4)
/* Used by PRM_IRQSTATUS_MPU_2 */
#define OMAP4430_VP_MPU_EQVALUE_ST_SHIFT 4
-#define OMAP4430_VP_MPU_EQVALUE_ST_MASK BITFIELD(4, 4)
+#define OMAP4430_VP_MPU_EQVALUE_ST_MASK (1 << 4)
/* Used by PRM_IRQENABLE_MPU_2 */
#define OMAP4430_VP_MPU_MAXVDD_EN_SHIFT 2
-#define OMAP4430_VP_MPU_MAXVDD_EN_MASK BITFIELD(2, 2)
+#define OMAP4430_VP_MPU_MAXVDD_EN_MASK (1 << 2)
/* Used by PRM_IRQSTATUS_MPU_2 */
#define OMAP4430_VP_MPU_MAXVDD_ST_SHIFT 2
-#define OMAP4430_VP_MPU_MAXVDD_ST_MASK BITFIELD(2, 2)
+#define OMAP4430_VP_MPU_MAXVDD_ST_MASK (1 << 2)
/* Used by PRM_IRQENABLE_MPU_2 */
#define OMAP4430_VP_MPU_MINVDD_EN_SHIFT 1
-#define OMAP4430_VP_MPU_MINVDD_EN_MASK BITFIELD(1, 1)
+#define OMAP4430_VP_MPU_MINVDD_EN_MASK (1 << 1)
/* Used by PRM_IRQSTATUS_MPU_2 */
#define OMAP4430_VP_MPU_MINVDD_ST_SHIFT 1
-#define OMAP4430_VP_MPU_MINVDD_ST_MASK BITFIELD(1, 1)
+#define OMAP4430_VP_MPU_MINVDD_ST_MASK (1 << 1)
/* Used by PRM_IRQENABLE_MPU_2 */
#define OMAP4430_VP_MPU_NOSMPSACK_EN_SHIFT 3
-#define OMAP4430_VP_MPU_NOSMPSACK_EN_MASK BITFIELD(3, 3)
+#define OMAP4430_VP_MPU_NOSMPSACK_EN_MASK (1 << 3)
/* Used by PRM_IRQSTATUS_MPU_2 */
#define OMAP4430_VP_MPU_NOSMPSACK_ST_SHIFT 3
-#define OMAP4430_VP_MPU_NOSMPSACK_ST_MASK BITFIELD(3, 3)
+#define OMAP4430_VP_MPU_NOSMPSACK_ST_MASK (1 << 3)
/* Used by PRM_IRQENABLE_MPU_2 */
#define OMAP4430_VP_MPU_OPPCHANGEDONE_EN_SHIFT 0
-#define OMAP4430_VP_MPU_OPPCHANGEDONE_EN_MASK BITFIELD(0, 0)
+#define OMAP4430_VP_MPU_OPPCHANGEDONE_EN_MASK (1 << 0)
/* Used by PRM_IRQSTATUS_MPU_2 */
#define OMAP4430_VP_MPU_OPPCHANGEDONE_ST_SHIFT 0
-#define OMAP4430_VP_MPU_OPPCHANGEDONE_ST_MASK BITFIELD(0, 0)
+#define OMAP4430_VP_MPU_OPPCHANGEDONE_ST_MASK (1 << 0)
/* Used by PRM_IRQENABLE_MPU_2 */
#define OMAP4430_VP_MPU_TRANXDONE_EN_SHIFT 5
-#define OMAP4430_VP_MPU_TRANXDONE_EN_MASK BITFIELD(5, 5)
+#define OMAP4430_VP_MPU_TRANXDONE_EN_MASK (1 << 5)
/* Used by PRM_IRQSTATUS_MPU_2 */
#define OMAP4430_VP_MPU_TRANXDONE_ST_SHIFT 5
-#define OMAP4430_VP_MPU_TRANXDONE_ST_MASK BITFIELD(5, 5)
+#define OMAP4430_VP_MPU_TRANXDONE_ST_MASK (1 << 5)
/* Used by PRM_SRAM_COUNT */
#define OMAP4430_VSETUPCNT_VALUE_SHIFT 8
-#define OMAP4430_VSETUPCNT_VALUE_MASK BITFIELD(8, 15)
+#define OMAP4430_VSETUPCNT_VALUE_MASK (0xff << 8)
/* Used by PRM_VP_CORE_VSTEPMAX, PRM_VP_IVA_VSTEPMAX, PRM_VP_MPU_VSTEPMAX */
#define OMAP4430_VSTEPMAX_SHIFT 0
-#define OMAP4430_VSTEPMAX_MASK BITFIELD(0, 7)
+#define OMAP4430_VSTEPMAX_MASK (0xff << 0)
/* Used by PRM_VP_CORE_VSTEPMIN, PRM_VP_IVA_VSTEPMIN, PRM_VP_MPU_VSTEPMIN */
#define OMAP4430_VSTEPMIN_SHIFT 0
-#define OMAP4430_VSTEPMIN_MASK BITFIELD(0, 7)
+#define OMAP4430_VSTEPMIN_MASK (0xff << 0)
/* Used by PRM_MODEM_IF_CTRL */
#define OMAP4430_WAKE_MODEM_SHIFT 0
-#define OMAP4430_WAKE_MODEM_MASK BITFIELD(0, 0)
+#define OMAP4430_WAKE_MODEM_MASK (1 << 0)
/* Used by PM_DSS_DSS_WKDEP */
#define OMAP4430_WKUPDEP_DISPC_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_DISPC_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_DISPC_DUCATI_MASK (1 << 1)
/* Used by PM_DSS_DSS_WKDEP */
#define OMAP4430_WKUPDEP_DISPC_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_DISPC_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_DISPC_MPU_MASK (1 << 0)
/* Used by PM_DSS_DSS_WKDEP */
#define OMAP4430_WKUPDEP_DISPC_SDMA_SHIFT 3
-#define OMAP4430_WKUPDEP_DISPC_SDMA_MASK BITFIELD(3, 3)
+#define OMAP4430_WKUPDEP_DISPC_SDMA_MASK (1 << 3)
/* Used by PM_DSS_DSS_WKDEP */
#define OMAP4430_WKUPDEP_DISPC_TESLA_SHIFT 2
-#define OMAP4430_WKUPDEP_DISPC_TESLA_MASK BITFIELD(2, 2)
+#define OMAP4430_WKUPDEP_DISPC_TESLA_MASK (1 << 2)
/* Used by PM_ABE_DMIC_WKDEP */
#define OMAP4430_WKUPDEP_DMIC_DMA_SDMA_SHIFT 7
-#define OMAP4430_WKUPDEP_DMIC_DMA_SDMA_MASK BITFIELD(7, 7)
+#define OMAP4430_WKUPDEP_DMIC_DMA_SDMA_MASK (1 << 7)
/* Used by PM_ABE_DMIC_WKDEP */
#define OMAP4430_WKUPDEP_DMIC_DMA_TESLA_SHIFT 6
-#define OMAP4430_WKUPDEP_DMIC_DMA_TESLA_MASK BITFIELD(6, 6)
+#define OMAP4430_WKUPDEP_DMIC_DMA_TESLA_MASK (1 << 6)
/* Used by PM_ABE_DMIC_WKDEP */
#define OMAP4430_WKUPDEP_DMIC_IRQ_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_DMIC_IRQ_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_DMIC_IRQ_MPU_MASK (1 << 0)
/* Used by PM_ABE_DMIC_WKDEP */
#define OMAP4430_WKUPDEP_DMIC_IRQ_TESLA_SHIFT 2
-#define OMAP4430_WKUPDEP_DMIC_IRQ_TESLA_MASK BITFIELD(2, 2)
+#define OMAP4430_WKUPDEP_DMIC_IRQ_TESLA_MASK (1 << 2)
/* Used by PM_L4PER_DMTIMER10_WKDEP */
#define OMAP4430_WKUPDEP_DMTIMER10_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_DMTIMER10_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_DMTIMER10_MPU_MASK (1 << 0)
/* Used by PM_L4PER_DMTIMER11_WKDEP */
#define OMAP4430_WKUPDEP_DMTIMER11_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_DMTIMER11_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_DMTIMER11_DUCATI_MASK (1 << 1)
/* Used by PM_L4PER_DMTIMER11_WKDEP */
#define OMAP4430_WKUPDEP_DMTIMER11_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_DMTIMER11_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_DMTIMER11_MPU_MASK (1 << 0)
/* Used by PM_L4PER_DMTIMER2_WKDEP */
#define OMAP4430_WKUPDEP_DMTIMER2_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_DMTIMER2_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_DMTIMER2_MPU_MASK (1 << 0)
/* Used by PM_L4PER_DMTIMER3_WKDEP */
#define OMAP4430_WKUPDEP_DMTIMER3_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_DMTIMER3_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_DMTIMER3_DUCATI_MASK (1 << 1)
/* Used by PM_L4PER_DMTIMER3_WKDEP */
#define OMAP4430_WKUPDEP_DMTIMER3_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_DMTIMER3_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_DMTIMER3_MPU_MASK (1 << 0)
/* Used by PM_L4PER_DMTIMER4_WKDEP */
#define OMAP4430_WKUPDEP_DMTIMER4_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_DMTIMER4_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_DMTIMER4_DUCATI_MASK (1 << 1)
/* Used by PM_L4PER_DMTIMER4_WKDEP */
#define OMAP4430_WKUPDEP_DMTIMER4_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_DMTIMER4_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_DMTIMER4_MPU_MASK (1 << 0)
/* Used by PM_L4PER_DMTIMER9_WKDEP */
#define OMAP4430_WKUPDEP_DMTIMER9_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_DMTIMER9_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_DMTIMER9_DUCATI_MASK (1 << 1)
/* Used by PM_L4PER_DMTIMER9_WKDEP */
#define OMAP4430_WKUPDEP_DMTIMER9_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_DMTIMER9_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_DMTIMER9_MPU_MASK (1 << 0)
/* Used by PM_DSS_DSS_WKDEP */
#define OMAP4430_WKUPDEP_DSI1_DUCATI_SHIFT 5
-#define OMAP4430_WKUPDEP_DSI1_DUCATI_MASK BITFIELD(5, 5)
+#define OMAP4430_WKUPDEP_DSI1_DUCATI_MASK (1 << 5)
/* Used by PM_DSS_DSS_WKDEP */
#define OMAP4430_WKUPDEP_DSI1_MPU_SHIFT 4
-#define OMAP4430_WKUPDEP_DSI1_MPU_MASK BITFIELD(4, 4)
+#define OMAP4430_WKUPDEP_DSI1_MPU_MASK (1 << 4)
/* Used by PM_DSS_DSS_WKDEP */
#define OMAP4430_WKUPDEP_DSI1_SDMA_SHIFT 7
-#define OMAP4430_WKUPDEP_DSI1_SDMA_MASK BITFIELD(7, 7)
+#define OMAP4430_WKUPDEP_DSI1_SDMA_MASK (1 << 7)
/* Used by PM_DSS_DSS_WKDEP */
#define OMAP4430_WKUPDEP_DSI1_TESLA_SHIFT 6
-#define OMAP4430_WKUPDEP_DSI1_TESLA_MASK BITFIELD(6, 6)
+#define OMAP4430_WKUPDEP_DSI1_TESLA_MASK (1 << 6)
/* Used by PM_DSS_DSS_WKDEP */
#define OMAP4430_WKUPDEP_DSI2_DUCATI_SHIFT 9
-#define OMAP4430_WKUPDEP_DSI2_DUCATI_MASK BITFIELD(9, 9)
+#define OMAP4430_WKUPDEP_DSI2_DUCATI_MASK (1 << 9)
/* Used by PM_DSS_DSS_WKDEP */
#define OMAP4430_WKUPDEP_DSI2_MPU_SHIFT 8
-#define OMAP4430_WKUPDEP_DSI2_MPU_MASK BITFIELD(8, 8)
+#define OMAP4430_WKUPDEP_DSI2_MPU_MASK (1 << 8)
/* Used by PM_DSS_DSS_WKDEP */
#define OMAP4430_WKUPDEP_DSI2_SDMA_SHIFT 11
-#define OMAP4430_WKUPDEP_DSI2_SDMA_MASK BITFIELD(11, 11)
+#define OMAP4430_WKUPDEP_DSI2_SDMA_MASK (1 << 11)
/* Used by PM_DSS_DSS_WKDEP */
#define OMAP4430_WKUPDEP_DSI2_TESLA_SHIFT 10
-#define OMAP4430_WKUPDEP_DSI2_TESLA_MASK BITFIELD(10, 10)
+#define OMAP4430_WKUPDEP_DSI2_TESLA_MASK (1 << 10)
/* Used by PM_WKUP_GPIO1_WKDEP */
#define OMAP4430_WKUPDEP_GPIO1_IRQ1_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_GPIO1_IRQ1_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_GPIO1_IRQ1_DUCATI_MASK (1 << 1)
/* Used by PM_WKUP_GPIO1_WKDEP */
#define OMAP4430_WKUPDEP_GPIO1_IRQ1_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_GPIO1_IRQ1_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_GPIO1_IRQ1_MPU_MASK (1 << 0)
/* Used by PM_WKUP_GPIO1_WKDEP */
#define OMAP4430_WKUPDEP_GPIO1_IRQ2_TESLA_SHIFT 6
-#define OMAP4430_WKUPDEP_GPIO1_IRQ2_TESLA_MASK BITFIELD(6, 6)
+#define OMAP4430_WKUPDEP_GPIO1_IRQ2_TESLA_MASK (1 << 6)
/* Used by PM_L4PER_GPIO2_WKDEP */
#define OMAP4430_WKUPDEP_GPIO2_IRQ1_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_GPIO2_IRQ1_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_GPIO2_IRQ1_DUCATI_MASK (1 << 1)
/* Used by PM_L4PER_GPIO2_WKDEP */
#define OMAP4430_WKUPDEP_GPIO2_IRQ1_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_GPIO2_IRQ1_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_GPIO2_IRQ1_MPU_MASK (1 << 0)
/* Used by PM_L4PER_GPIO2_WKDEP */
#define OMAP4430_WKUPDEP_GPIO2_IRQ2_TESLA_SHIFT 6
-#define OMAP4430_WKUPDEP_GPIO2_IRQ2_TESLA_MASK BITFIELD(6, 6)
+#define OMAP4430_WKUPDEP_GPIO2_IRQ2_TESLA_MASK (1 << 6)
/* Used by PM_L4PER_GPIO3_WKDEP */
#define OMAP4430_WKUPDEP_GPIO3_IRQ1_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_GPIO3_IRQ1_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_GPIO3_IRQ1_MPU_MASK (1 << 0)
/* Used by PM_L4PER_GPIO3_WKDEP */
#define OMAP4430_WKUPDEP_GPIO3_IRQ2_TESLA_SHIFT 6
-#define OMAP4430_WKUPDEP_GPIO3_IRQ2_TESLA_MASK BITFIELD(6, 6)
+#define OMAP4430_WKUPDEP_GPIO3_IRQ2_TESLA_MASK (1 << 6)
/* Used by PM_L4PER_GPIO4_WKDEP */
#define OMAP4430_WKUPDEP_GPIO4_IRQ1_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_GPIO4_IRQ1_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_GPIO4_IRQ1_MPU_MASK (1 << 0)
/* Used by PM_L4PER_GPIO4_WKDEP */
#define OMAP4430_WKUPDEP_GPIO4_IRQ2_TESLA_SHIFT 6
-#define OMAP4430_WKUPDEP_GPIO4_IRQ2_TESLA_MASK BITFIELD(6, 6)
+#define OMAP4430_WKUPDEP_GPIO4_IRQ2_TESLA_MASK (1 << 6)
/* Used by PM_L4PER_GPIO5_WKDEP */
#define OMAP4430_WKUPDEP_GPIO5_IRQ1_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_GPIO5_IRQ1_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_GPIO5_IRQ1_MPU_MASK (1 << 0)
/* Used by PM_L4PER_GPIO5_WKDEP */
#define OMAP4430_WKUPDEP_GPIO5_IRQ2_TESLA_SHIFT 6
-#define OMAP4430_WKUPDEP_GPIO5_IRQ2_TESLA_MASK BITFIELD(6, 6)
+#define OMAP4430_WKUPDEP_GPIO5_IRQ2_TESLA_MASK (1 << 6)
/* Used by PM_L4PER_GPIO6_WKDEP */
#define OMAP4430_WKUPDEP_GPIO6_IRQ1_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_GPIO6_IRQ1_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_GPIO6_IRQ1_MPU_MASK (1 << 0)
/* Used by PM_L4PER_GPIO6_WKDEP */
#define OMAP4430_WKUPDEP_GPIO6_IRQ2_TESLA_SHIFT 6
-#define OMAP4430_WKUPDEP_GPIO6_IRQ2_TESLA_MASK BITFIELD(6, 6)
+#define OMAP4430_WKUPDEP_GPIO6_IRQ2_TESLA_MASK (1 << 6)
/* Used by PM_DSS_DSS_WKDEP */
#define OMAP4430_WKUPDEP_HDMIDMA_SDMA_SHIFT 19
-#define OMAP4430_WKUPDEP_HDMIDMA_SDMA_MASK BITFIELD(19, 19)
+#define OMAP4430_WKUPDEP_HDMIDMA_SDMA_MASK (1 << 19)
/* Used by PM_DSS_DSS_WKDEP */
#define OMAP4430_WKUPDEP_HDMIIRQ_DUCATI_SHIFT 13
-#define OMAP4430_WKUPDEP_HDMIIRQ_DUCATI_MASK BITFIELD(13, 13)
+#define OMAP4430_WKUPDEP_HDMIIRQ_DUCATI_MASK (1 << 13)
/* Used by PM_DSS_DSS_WKDEP */
#define OMAP4430_WKUPDEP_HDMIIRQ_MPU_SHIFT 12
-#define OMAP4430_WKUPDEP_HDMIIRQ_MPU_MASK BITFIELD(12, 12)
+#define OMAP4430_WKUPDEP_HDMIIRQ_MPU_MASK (1 << 12)
/* Used by PM_DSS_DSS_WKDEP */
#define OMAP4430_WKUPDEP_HDMIIRQ_TESLA_SHIFT 14
-#define OMAP4430_WKUPDEP_HDMIIRQ_TESLA_MASK BITFIELD(14, 14)
+#define OMAP4430_WKUPDEP_HDMIIRQ_TESLA_MASK (1 << 14)
/* Used by PM_L4PER_HECC1_WKDEP */
#define OMAP4430_WKUPDEP_HECC1_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_HECC1_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_HECC1_MPU_MASK (1 << 0)
/* Used by PM_L4PER_HECC2_WKDEP */
#define OMAP4430_WKUPDEP_HECC2_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_HECC2_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_HECC2_MPU_MASK (1 << 0)
/* Used by PM_L3INIT_HSI_WKDEP */
#define OMAP4430_WKUPDEP_HSI_DSP_TESLA_SHIFT 6
-#define OMAP4430_WKUPDEP_HSI_DSP_TESLA_MASK BITFIELD(6, 6)
+#define OMAP4430_WKUPDEP_HSI_DSP_TESLA_MASK (1 << 6)
/* Used by PM_L3INIT_HSI_WKDEP */
#define OMAP4430_WKUPDEP_HSI_MCU_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_HSI_MCU_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_HSI_MCU_DUCATI_MASK (1 << 1)
/* Used by PM_L3INIT_HSI_WKDEP */
#define OMAP4430_WKUPDEP_HSI_MCU_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_HSI_MCU_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_HSI_MCU_MPU_MASK (1 << 0)
/* Used by PM_L4PER_I2C1_WKDEP */
#define OMAP4430_WKUPDEP_I2C1_DMA_SDMA_SHIFT 7
-#define OMAP4430_WKUPDEP_I2C1_DMA_SDMA_MASK BITFIELD(7, 7)
+#define OMAP4430_WKUPDEP_I2C1_DMA_SDMA_MASK (1 << 7)
/* Used by PM_L4PER_I2C1_WKDEP */
#define OMAP4430_WKUPDEP_I2C1_IRQ_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_I2C1_IRQ_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_I2C1_IRQ_DUCATI_MASK (1 << 1)
/* Used by PM_L4PER_I2C1_WKDEP */
#define OMAP4430_WKUPDEP_I2C1_IRQ_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_I2C1_IRQ_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_I2C1_IRQ_MPU_MASK (1 << 0)
/* Used by PM_L4PER_I2C2_WKDEP */
#define OMAP4430_WKUPDEP_I2C2_DMA_SDMA_SHIFT 7
-#define OMAP4430_WKUPDEP_I2C2_DMA_SDMA_MASK BITFIELD(7, 7)
+#define OMAP4430_WKUPDEP_I2C2_DMA_SDMA_MASK (1 << 7)
/* Used by PM_L4PER_I2C2_WKDEP */
#define OMAP4430_WKUPDEP_I2C2_IRQ_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_I2C2_IRQ_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_I2C2_IRQ_DUCATI_MASK (1 << 1)
/* Used by PM_L4PER_I2C2_WKDEP */
#define OMAP4430_WKUPDEP_I2C2_IRQ_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_I2C2_IRQ_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_I2C2_IRQ_MPU_MASK (1 << 0)
/* Used by PM_L4PER_I2C3_WKDEP */
#define OMAP4430_WKUPDEP_I2C3_DMA_SDMA_SHIFT 7
-#define OMAP4430_WKUPDEP_I2C3_DMA_SDMA_MASK BITFIELD(7, 7)
+#define OMAP4430_WKUPDEP_I2C3_DMA_SDMA_MASK (1 << 7)
/* Used by PM_L4PER_I2C3_WKDEP */
#define OMAP4430_WKUPDEP_I2C3_IRQ_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_I2C3_IRQ_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_I2C3_IRQ_DUCATI_MASK (1 << 1)
/* Used by PM_L4PER_I2C3_WKDEP */
#define OMAP4430_WKUPDEP_I2C3_IRQ_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_I2C3_IRQ_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_I2C3_IRQ_MPU_MASK (1 << 0)
/* Used by PM_L4PER_I2C4_WKDEP */
#define OMAP4430_WKUPDEP_I2C4_DMA_SDMA_SHIFT 7
-#define OMAP4430_WKUPDEP_I2C4_DMA_SDMA_MASK BITFIELD(7, 7)
+#define OMAP4430_WKUPDEP_I2C4_DMA_SDMA_MASK (1 << 7)
/* Used by PM_L4PER_I2C4_WKDEP */
#define OMAP4430_WKUPDEP_I2C4_IRQ_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_I2C4_IRQ_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_I2C4_IRQ_DUCATI_MASK (1 << 1)
/* Used by PM_L4PER_I2C4_WKDEP */
#define OMAP4430_WKUPDEP_I2C4_IRQ_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_I2C4_IRQ_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_I2C4_IRQ_MPU_MASK (1 << 0)
/* Used by PM_L4PER_I2C5_WKDEP */
#define OMAP4430_WKUPDEP_I2C5_DMA_SDMA_SHIFT 7
-#define OMAP4430_WKUPDEP_I2C5_DMA_SDMA_MASK BITFIELD(7, 7)
+#define OMAP4430_WKUPDEP_I2C5_DMA_SDMA_MASK (1 << 7)
/* Used by PM_L4PER_I2C5_WKDEP */
#define OMAP4430_WKUPDEP_I2C5_IRQ_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_I2C5_IRQ_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_I2C5_IRQ_MPU_MASK (1 << 0)
/* Used by PM_WKUP_KEYBOARD_WKDEP */
#define OMAP4430_WKUPDEP_KEYBOARD_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_KEYBOARD_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_KEYBOARD_MPU_MASK (1 << 0)
/* Used by PM_ABE_MCASP_WKDEP */
#define OMAP4430_WKUPDEP_MCASP1_DMA_SDMA_SHIFT 7
-#define OMAP4430_WKUPDEP_MCASP1_DMA_SDMA_MASK BITFIELD(7, 7)
+#define OMAP4430_WKUPDEP_MCASP1_DMA_SDMA_MASK (1 << 7)
/* Used by PM_ABE_MCASP_WKDEP */
#define OMAP4430_WKUPDEP_MCASP1_DMA_TESLA_SHIFT 6
-#define OMAP4430_WKUPDEP_MCASP1_DMA_TESLA_MASK BITFIELD(6, 6)
+#define OMAP4430_WKUPDEP_MCASP1_DMA_TESLA_MASK (1 << 6)
/* Used by PM_ABE_MCASP_WKDEP */
#define OMAP4430_WKUPDEP_MCASP1_IRQ_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_MCASP1_IRQ_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_MCASP1_IRQ_MPU_MASK (1 << 0)
/* Used by PM_ABE_MCASP_WKDEP */
#define OMAP4430_WKUPDEP_MCASP1_IRQ_TESLA_SHIFT 2
-#define OMAP4430_WKUPDEP_MCASP1_IRQ_TESLA_MASK BITFIELD(2, 2)
+#define OMAP4430_WKUPDEP_MCASP1_IRQ_TESLA_MASK (1 << 2)
/* Used by PM_L4PER_MCASP2_WKDEP */
#define OMAP4430_WKUPDEP_MCASP2_DMA_SDMA_SHIFT 7
-#define OMAP4430_WKUPDEP_MCASP2_DMA_SDMA_MASK BITFIELD(7, 7)
+#define OMAP4430_WKUPDEP_MCASP2_DMA_SDMA_MASK (1 << 7)
/* Used by PM_L4PER_MCASP2_WKDEP */
#define OMAP4430_WKUPDEP_MCASP2_DMA_TESLA_SHIFT 6
-#define OMAP4430_WKUPDEP_MCASP2_DMA_TESLA_MASK BITFIELD(6, 6)
+#define OMAP4430_WKUPDEP_MCASP2_DMA_TESLA_MASK (1 << 6)
/* Used by PM_L4PER_MCASP2_WKDEP */
#define OMAP4430_WKUPDEP_MCASP2_IRQ_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_MCASP2_IRQ_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_MCASP2_IRQ_MPU_MASK (1 << 0)
/* Used by PM_L4PER_MCASP2_WKDEP */
#define OMAP4430_WKUPDEP_MCASP2_IRQ_TESLA_SHIFT 2
-#define OMAP4430_WKUPDEP_MCASP2_IRQ_TESLA_MASK BITFIELD(2, 2)
+#define OMAP4430_WKUPDEP_MCASP2_IRQ_TESLA_MASK (1 << 2)
/* Used by PM_L4PER_MCASP3_WKDEP */
#define OMAP4430_WKUPDEP_MCASP3_DMA_SDMA_SHIFT 7
-#define OMAP4430_WKUPDEP_MCASP3_DMA_SDMA_MASK BITFIELD(7, 7)
+#define OMAP4430_WKUPDEP_MCASP3_DMA_SDMA_MASK (1 << 7)
/* Used by PM_L4PER_MCASP3_WKDEP */
#define OMAP4430_WKUPDEP_MCASP3_DMA_TESLA_SHIFT 6
-#define OMAP4430_WKUPDEP_MCASP3_DMA_TESLA_MASK BITFIELD(6, 6)
+#define OMAP4430_WKUPDEP_MCASP3_DMA_TESLA_MASK (1 << 6)
/* Used by PM_L4PER_MCASP3_WKDEP */
#define OMAP4430_WKUPDEP_MCASP3_IRQ_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_MCASP3_IRQ_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_MCASP3_IRQ_MPU_MASK (1 << 0)
/* Used by PM_L4PER_MCASP3_WKDEP */
#define OMAP4430_WKUPDEP_MCASP3_IRQ_TESLA_SHIFT 2
-#define OMAP4430_WKUPDEP_MCASP3_IRQ_TESLA_MASK BITFIELD(2, 2)
+#define OMAP4430_WKUPDEP_MCASP3_IRQ_TESLA_MASK (1 << 2)
/* Used by PM_ABE_MCBSP1_WKDEP */
#define OMAP4430_WKUPDEP_MCBSP1_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_MCBSP1_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_MCBSP1_MPU_MASK (1 << 0)
/* Used by PM_ABE_MCBSP1_WKDEP */
#define OMAP4430_WKUPDEP_MCBSP1_SDMA_SHIFT 3
-#define OMAP4430_WKUPDEP_MCBSP1_SDMA_MASK BITFIELD(3, 3)
+#define OMAP4430_WKUPDEP_MCBSP1_SDMA_MASK (1 << 3)
/* Used by PM_ABE_MCBSP1_WKDEP */
#define OMAP4430_WKUPDEP_MCBSP1_TESLA_SHIFT 2
-#define OMAP4430_WKUPDEP_MCBSP1_TESLA_MASK BITFIELD(2, 2)
+#define OMAP4430_WKUPDEP_MCBSP1_TESLA_MASK (1 << 2)
/* Used by PM_ABE_MCBSP2_WKDEP */
#define OMAP4430_WKUPDEP_MCBSP2_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_MCBSP2_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_MCBSP2_MPU_MASK (1 << 0)
/* Used by PM_ABE_MCBSP2_WKDEP */
#define OMAP4430_WKUPDEP_MCBSP2_SDMA_SHIFT 3
-#define OMAP4430_WKUPDEP_MCBSP2_SDMA_MASK BITFIELD(3, 3)
+#define OMAP4430_WKUPDEP_MCBSP2_SDMA_MASK (1 << 3)
/* Used by PM_ABE_MCBSP2_WKDEP */
#define OMAP4430_WKUPDEP_MCBSP2_TESLA_SHIFT 2
-#define OMAP4430_WKUPDEP_MCBSP2_TESLA_MASK BITFIELD(2, 2)
+#define OMAP4430_WKUPDEP_MCBSP2_TESLA_MASK (1 << 2)
/* Used by PM_ABE_MCBSP3_WKDEP */
#define OMAP4430_WKUPDEP_MCBSP3_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_MCBSP3_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_MCBSP3_MPU_MASK (1 << 0)
/* Used by PM_ABE_MCBSP3_WKDEP */
#define OMAP4430_WKUPDEP_MCBSP3_SDMA_SHIFT 3
-#define OMAP4430_WKUPDEP_MCBSP3_SDMA_MASK BITFIELD(3, 3)
+#define OMAP4430_WKUPDEP_MCBSP3_SDMA_MASK (1 << 3)
/* Used by PM_ABE_MCBSP3_WKDEP */
#define OMAP4430_WKUPDEP_MCBSP3_TESLA_SHIFT 2
-#define OMAP4430_WKUPDEP_MCBSP3_TESLA_MASK BITFIELD(2, 2)
+#define OMAP4430_WKUPDEP_MCBSP3_TESLA_MASK (1 << 2)
/* Used by PM_L4PER_MCBSP4_WKDEP */
#define OMAP4430_WKUPDEP_MCBSP4_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_MCBSP4_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_MCBSP4_MPU_MASK (1 << 0)
/* Used by PM_L4PER_MCBSP4_WKDEP */
#define OMAP4430_WKUPDEP_MCBSP4_SDMA_SHIFT 3
-#define OMAP4430_WKUPDEP_MCBSP4_SDMA_MASK BITFIELD(3, 3)
+#define OMAP4430_WKUPDEP_MCBSP4_SDMA_MASK (1 << 3)
/* Used by PM_L4PER_MCBSP4_WKDEP */
#define OMAP4430_WKUPDEP_MCBSP4_TESLA_SHIFT 2
-#define OMAP4430_WKUPDEP_MCBSP4_TESLA_MASK BITFIELD(2, 2)
+#define OMAP4430_WKUPDEP_MCBSP4_TESLA_MASK (1 << 2)
/* Used by PM_L4PER_MCSPI1_WKDEP */
#define OMAP4430_WKUPDEP_MCSPI1_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_MCSPI1_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_MCSPI1_DUCATI_MASK (1 << 1)
/* Used by PM_L4PER_MCSPI1_WKDEP */
#define OMAP4430_WKUPDEP_MCSPI1_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_MCSPI1_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_MCSPI1_MPU_MASK (1 << 0)
/* Used by PM_L4PER_MCSPI1_WKDEP */
#define OMAP4430_WKUPDEP_MCSPI1_SDMA_SHIFT 3
-#define OMAP4430_WKUPDEP_MCSPI1_SDMA_MASK BITFIELD(3, 3)
+#define OMAP4430_WKUPDEP_MCSPI1_SDMA_MASK (1 << 3)
/* Used by PM_L4PER_MCSPI1_WKDEP */
#define OMAP4430_WKUPDEP_MCSPI1_TESLA_SHIFT 2
-#define OMAP4430_WKUPDEP_MCSPI1_TESLA_MASK BITFIELD(2, 2)
+#define OMAP4430_WKUPDEP_MCSPI1_TESLA_MASK (1 << 2)
/* Used by PM_L4PER_MCSPI2_WKDEP */
#define OMAP4430_WKUPDEP_MCSPI2_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_MCSPI2_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_MCSPI2_DUCATI_MASK (1 << 1)
/* Used by PM_L4PER_MCSPI2_WKDEP */
#define OMAP4430_WKUPDEP_MCSPI2_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_MCSPI2_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_MCSPI2_MPU_MASK (1 << 0)
/* Used by PM_L4PER_MCSPI2_WKDEP */
#define OMAP4430_WKUPDEP_MCSPI2_SDMA_SHIFT 3
-#define OMAP4430_WKUPDEP_MCSPI2_SDMA_MASK BITFIELD(3, 3)
+#define OMAP4430_WKUPDEP_MCSPI2_SDMA_MASK (1 << 3)
/* Used by PM_L4PER_MCSPI3_WKDEP */
#define OMAP4430_WKUPDEP_MCSPI3_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_MCSPI3_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_MCSPI3_MPU_MASK (1 << 0)
/* Used by PM_L4PER_MCSPI3_WKDEP */
#define OMAP4430_WKUPDEP_MCSPI3_SDMA_SHIFT 3
-#define OMAP4430_WKUPDEP_MCSPI3_SDMA_MASK BITFIELD(3, 3)
+#define OMAP4430_WKUPDEP_MCSPI3_SDMA_MASK (1 << 3)
/* Used by PM_L4PER_MCSPI4_WKDEP */
#define OMAP4430_WKUPDEP_MCSPI4_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_MCSPI4_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_MCSPI4_MPU_MASK (1 << 0)
/* Used by PM_L4PER_MCSPI4_WKDEP */
#define OMAP4430_WKUPDEP_MCSPI4_SDMA_SHIFT 3
-#define OMAP4430_WKUPDEP_MCSPI4_SDMA_MASK BITFIELD(3, 3)
+#define OMAP4430_WKUPDEP_MCSPI4_SDMA_MASK (1 << 3)
/* Used by PM_L3INIT_MMC1_WKDEP */
#define OMAP4430_WKUPDEP_MMC1_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_MMC1_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_MMC1_DUCATI_MASK (1 << 1)
/* Used by PM_L3INIT_MMC1_WKDEP */
#define OMAP4430_WKUPDEP_MMC1_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_MMC1_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_MMC1_MPU_MASK (1 << 0)
/* Used by PM_L3INIT_MMC1_WKDEP */
#define OMAP4430_WKUPDEP_MMC1_SDMA_SHIFT 3
-#define OMAP4430_WKUPDEP_MMC1_SDMA_MASK BITFIELD(3, 3)
+#define OMAP4430_WKUPDEP_MMC1_SDMA_MASK (1 << 3)
/* Used by PM_L3INIT_MMC1_WKDEP */
#define OMAP4430_WKUPDEP_MMC1_TESLA_SHIFT 2
-#define OMAP4430_WKUPDEP_MMC1_TESLA_MASK BITFIELD(2, 2)
+#define OMAP4430_WKUPDEP_MMC1_TESLA_MASK (1 << 2)
/* Used by PM_L3INIT_MMC2_WKDEP */
#define OMAP4430_WKUPDEP_MMC2_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_MMC2_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_MMC2_DUCATI_MASK (1 << 1)
/* Used by PM_L3INIT_MMC2_WKDEP */
#define OMAP4430_WKUPDEP_MMC2_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_MMC2_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_MMC2_MPU_MASK (1 << 0)
/* Used by PM_L3INIT_MMC2_WKDEP */
#define OMAP4430_WKUPDEP_MMC2_SDMA_SHIFT 3
-#define OMAP4430_WKUPDEP_MMC2_SDMA_MASK BITFIELD(3, 3)
+#define OMAP4430_WKUPDEP_MMC2_SDMA_MASK (1 << 3)
/* Used by PM_L3INIT_MMC2_WKDEP */
#define OMAP4430_WKUPDEP_MMC2_TESLA_SHIFT 2
-#define OMAP4430_WKUPDEP_MMC2_TESLA_MASK BITFIELD(2, 2)
+#define OMAP4430_WKUPDEP_MMC2_TESLA_MASK (1 << 2)
/* Used by PM_L3INIT_MMC6_WKDEP */
#define OMAP4430_WKUPDEP_MMC6_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_MMC6_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_MMC6_DUCATI_MASK (1 << 1)
/* Used by PM_L3INIT_MMC6_WKDEP */
#define OMAP4430_WKUPDEP_MMC6_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_MMC6_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_MMC6_MPU_MASK (1 << 0)
/* Used by PM_L3INIT_MMC6_WKDEP */
#define OMAP4430_WKUPDEP_MMC6_TESLA_SHIFT 2
-#define OMAP4430_WKUPDEP_MMC6_TESLA_MASK BITFIELD(2, 2)
+#define OMAP4430_WKUPDEP_MMC6_TESLA_MASK (1 << 2)
/* Used by PM_L4PER_MMCSD3_WKDEP */
#define OMAP4430_WKUPDEP_MMCSD3_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_MMCSD3_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_MMCSD3_DUCATI_MASK (1 << 1)
/* Used by PM_L4PER_MMCSD3_WKDEP */
#define OMAP4430_WKUPDEP_MMCSD3_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_MMCSD3_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_MMCSD3_MPU_MASK (1 << 0)
/* Used by PM_L4PER_MMCSD3_WKDEP */
#define OMAP4430_WKUPDEP_MMCSD3_SDMA_SHIFT 3
-#define OMAP4430_WKUPDEP_MMCSD3_SDMA_MASK BITFIELD(3, 3)
+#define OMAP4430_WKUPDEP_MMCSD3_SDMA_MASK (1 << 3)
/* Used by PM_L4PER_MMCSD4_WKDEP */
#define OMAP4430_WKUPDEP_MMCSD4_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_MMCSD4_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_MMCSD4_DUCATI_MASK (1 << 1)
/* Used by PM_L4PER_MMCSD4_WKDEP */
#define OMAP4430_WKUPDEP_MMCSD4_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_MMCSD4_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_MMCSD4_MPU_MASK (1 << 0)
/* Used by PM_L4PER_MMCSD4_WKDEP */
#define OMAP4430_WKUPDEP_MMCSD4_SDMA_SHIFT 3
-#define OMAP4430_WKUPDEP_MMCSD4_SDMA_MASK BITFIELD(3, 3)
+#define OMAP4430_WKUPDEP_MMCSD4_SDMA_MASK (1 << 3)
/* Used by PM_L4PER_MMCSD5_WKDEP */
#define OMAP4430_WKUPDEP_MMCSD5_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_MMCSD5_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_MMCSD5_DUCATI_MASK (1 << 1)
/* Used by PM_L4PER_MMCSD5_WKDEP */
#define OMAP4430_WKUPDEP_MMCSD5_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_MMCSD5_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_MMCSD5_MPU_MASK (1 << 0)
/* Used by PM_L4PER_MMCSD5_WKDEP */
#define OMAP4430_WKUPDEP_MMCSD5_SDMA_SHIFT 3
-#define OMAP4430_WKUPDEP_MMCSD5_SDMA_MASK BITFIELD(3, 3)
+#define OMAP4430_WKUPDEP_MMCSD5_SDMA_MASK (1 << 3)
/* Used by PM_L3INIT_PCIESS_WKDEP */
#define OMAP4430_WKUPDEP_PCIESS_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_PCIESS_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_PCIESS_MPU_MASK (1 << 0)
/* Used by PM_L3INIT_PCIESS_WKDEP */
#define OMAP4430_WKUPDEP_PCIESS_TESLA_SHIFT 2
-#define OMAP4430_WKUPDEP_PCIESS_TESLA_MASK BITFIELD(2, 2)
+#define OMAP4430_WKUPDEP_PCIESS_TESLA_MASK (1 << 2)
/* Used by PM_ABE_PDM_WKDEP */
#define OMAP4430_WKUPDEP_PDM_DMA_SDMA_SHIFT 7
-#define OMAP4430_WKUPDEP_PDM_DMA_SDMA_MASK BITFIELD(7, 7)
+#define OMAP4430_WKUPDEP_PDM_DMA_SDMA_MASK (1 << 7)
/* Used by PM_ABE_PDM_WKDEP */
#define OMAP4430_WKUPDEP_PDM_DMA_TESLA_SHIFT 6
-#define OMAP4430_WKUPDEP_PDM_DMA_TESLA_MASK BITFIELD(6, 6)
+#define OMAP4430_WKUPDEP_PDM_DMA_TESLA_MASK (1 << 6)
/* Used by PM_ABE_PDM_WKDEP */
#define OMAP4430_WKUPDEP_PDM_IRQ_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_PDM_IRQ_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_PDM_IRQ_MPU_MASK (1 << 0)
/* Used by PM_ABE_PDM_WKDEP */
#define OMAP4430_WKUPDEP_PDM_IRQ_TESLA_SHIFT 2
-#define OMAP4430_WKUPDEP_PDM_IRQ_TESLA_MASK BITFIELD(2, 2)
+#define OMAP4430_WKUPDEP_PDM_IRQ_TESLA_MASK (1 << 2)
/* Used by PM_WKUP_RTC_WKDEP */
#define OMAP4430_WKUPDEP_RTC_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_RTC_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_RTC_MPU_MASK (1 << 0)
/* Used by PM_L3INIT_SATA_WKDEP */
#define OMAP4430_WKUPDEP_SATA_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_SATA_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_SATA_MPU_MASK (1 << 0)
/* Used by PM_L3INIT_SATA_WKDEP */
#define OMAP4430_WKUPDEP_SATA_TESLA_SHIFT 2
-#define OMAP4430_WKUPDEP_SATA_TESLA_MASK BITFIELD(2, 2)
+#define OMAP4430_WKUPDEP_SATA_TESLA_MASK (1 << 2)
/* Used by PM_ABE_SLIMBUS_WKDEP */
#define OMAP4430_WKUPDEP_SLIMBUS1_DMA_SDMA_SHIFT 7
-#define OMAP4430_WKUPDEP_SLIMBUS1_DMA_SDMA_MASK BITFIELD(7, 7)
+#define OMAP4430_WKUPDEP_SLIMBUS1_DMA_SDMA_MASK (1 << 7)
/* Used by PM_ABE_SLIMBUS_WKDEP */
#define OMAP4430_WKUPDEP_SLIMBUS1_DMA_TESLA_SHIFT 6
-#define OMAP4430_WKUPDEP_SLIMBUS1_DMA_TESLA_MASK BITFIELD(6, 6)
+#define OMAP4430_WKUPDEP_SLIMBUS1_DMA_TESLA_MASK (1 << 6)
/* Used by PM_ABE_SLIMBUS_WKDEP */
#define OMAP4430_WKUPDEP_SLIMBUS1_IRQ_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_SLIMBUS1_IRQ_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_SLIMBUS1_IRQ_MPU_MASK (1 << 0)
/* Used by PM_ABE_SLIMBUS_WKDEP */
#define OMAP4430_WKUPDEP_SLIMBUS1_IRQ_TESLA_SHIFT 2
-#define OMAP4430_WKUPDEP_SLIMBUS1_IRQ_TESLA_MASK BITFIELD(2, 2)
+#define OMAP4430_WKUPDEP_SLIMBUS1_IRQ_TESLA_MASK (1 << 2)
/* Used by PM_L4PER_SLIMBUS2_WKDEP */
#define OMAP4430_WKUPDEP_SLIMBUS2_DMA_SDMA_SHIFT 7
-#define OMAP4430_WKUPDEP_SLIMBUS2_DMA_SDMA_MASK BITFIELD(7, 7)
+#define OMAP4430_WKUPDEP_SLIMBUS2_DMA_SDMA_MASK (1 << 7)
/* Used by PM_L4PER_SLIMBUS2_WKDEP */
#define OMAP4430_WKUPDEP_SLIMBUS2_DMA_TESLA_SHIFT 6
-#define OMAP4430_WKUPDEP_SLIMBUS2_DMA_TESLA_MASK BITFIELD(6, 6)
+#define OMAP4430_WKUPDEP_SLIMBUS2_DMA_TESLA_MASK (1 << 6)
/* Used by PM_L4PER_SLIMBUS2_WKDEP */
#define OMAP4430_WKUPDEP_SLIMBUS2_IRQ_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_SLIMBUS2_IRQ_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_SLIMBUS2_IRQ_MPU_MASK (1 << 0)
/* Used by PM_L4PER_SLIMBUS2_WKDEP */
#define OMAP4430_WKUPDEP_SLIMBUS2_IRQ_TESLA_SHIFT 2
-#define OMAP4430_WKUPDEP_SLIMBUS2_IRQ_TESLA_MASK BITFIELD(2, 2)
+#define OMAP4430_WKUPDEP_SLIMBUS2_IRQ_TESLA_MASK (1 << 2)
/* Used by PM_ALWON_SR_CORE_WKDEP */
#define OMAP4430_WKUPDEP_SR_CORE_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_SR_CORE_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_SR_CORE_DUCATI_MASK (1 << 1)
/* Used by PM_ALWON_SR_CORE_WKDEP */
#define OMAP4430_WKUPDEP_SR_CORE_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_SR_CORE_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_SR_CORE_MPU_MASK (1 << 0)
/* Used by PM_ALWON_SR_IVA_WKDEP */
#define OMAP4430_WKUPDEP_SR_IVA_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_SR_IVA_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_SR_IVA_DUCATI_MASK (1 << 1)
/* Used by PM_ALWON_SR_IVA_WKDEP */
#define OMAP4430_WKUPDEP_SR_IVA_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_SR_IVA_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_SR_IVA_MPU_MASK (1 << 0)
/* Used by PM_ALWON_SR_MPU_WKDEP */
#define OMAP4430_WKUPDEP_SR_MPU_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_SR_MPU_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_SR_MPU_MPU_MASK (1 << 0)
/* Used by PM_WKUP_TIMER12_WKDEP */
#define OMAP4430_WKUPDEP_TIMER12_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_TIMER12_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_TIMER12_MPU_MASK (1 << 0)
/* Used by PM_WKUP_TIMER1_WKDEP */
#define OMAP4430_WKUPDEP_TIMER1_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_TIMER1_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_TIMER1_MPU_MASK (1 << 0)
/* Used by PM_ABE_TIMER5_WKDEP */
#define OMAP4430_WKUPDEP_TIMER5_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_TIMER5_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_TIMER5_MPU_MASK (1 << 0)
/* Used by PM_ABE_TIMER5_WKDEP */
#define OMAP4430_WKUPDEP_TIMER5_TESLA_SHIFT 2
-#define OMAP4430_WKUPDEP_TIMER5_TESLA_MASK BITFIELD(2, 2)
+#define OMAP4430_WKUPDEP_TIMER5_TESLA_MASK (1 << 2)
/* Used by PM_ABE_TIMER6_WKDEP */
#define OMAP4430_WKUPDEP_TIMER6_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_TIMER6_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_TIMER6_MPU_MASK (1 << 0)
/* Used by PM_ABE_TIMER6_WKDEP */
#define OMAP4430_WKUPDEP_TIMER6_TESLA_SHIFT 2
-#define OMAP4430_WKUPDEP_TIMER6_TESLA_MASK BITFIELD(2, 2)
+#define OMAP4430_WKUPDEP_TIMER6_TESLA_MASK (1 << 2)
/* Used by PM_ABE_TIMER7_WKDEP */
#define OMAP4430_WKUPDEP_TIMER7_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_TIMER7_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_TIMER7_MPU_MASK (1 << 0)
/* Used by PM_ABE_TIMER7_WKDEP */
#define OMAP4430_WKUPDEP_TIMER7_TESLA_SHIFT 2
-#define OMAP4430_WKUPDEP_TIMER7_TESLA_MASK BITFIELD(2, 2)
+#define OMAP4430_WKUPDEP_TIMER7_TESLA_MASK (1 << 2)
/* Used by PM_ABE_TIMER8_WKDEP */
#define OMAP4430_WKUPDEP_TIMER8_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_TIMER8_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_TIMER8_MPU_MASK (1 << 0)
/* Used by PM_ABE_TIMER8_WKDEP */
#define OMAP4430_WKUPDEP_TIMER8_TESLA_SHIFT 2
-#define OMAP4430_WKUPDEP_TIMER8_TESLA_MASK BITFIELD(2, 2)
+#define OMAP4430_WKUPDEP_TIMER8_TESLA_MASK (1 << 2)
/* Used by PM_L4PER_UART1_WKDEP */
#define OMAP4430_WKUPDEP_UART1_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_UART1_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_UART1_MPU_MASK (1 << 0)
/* Used by PM_L4PER_UART1_WKDEP */
#define OMAP4430_WKUPDEP_UART1_SDMA_SHIFT 3
-#define OMAP4430_WKUPDEP_UART1_SDMA_MASK BITFIELD(3, 3)
+#define OMAP4430_WKUPDEP_UART1_SDMA_MASK (1 << 3)
/* Used by PM_L4PER_UART2_WKDEP */
#define OMAP4430_WKUPDEP_UART2_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_UART2_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_UART2_MPU_MASK (1 << 0)
/* Used by PM_L4PER_UART2_WKDEP */
#define OMAP4430_WKUPDEP_UART2_SDMA_SHIFT 3
-#define OMAP4430_WKUPDEP_UART2_SDMA_MASK BITFIELD(3, 3)
+#define OMAP4430_WKUPDEP_UART2_SDMA_MASK (1 << 3)
/* Used by PM_L4PER_UART3_WKDEP */
#define OMAP4430_WKUPDEP_UART3_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_UART3_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_UART3_DUCATI_MASK (1 << 1)
/* Used by PM_L4PER_UART3_WKDEP */
#define OMAP4430_WKUPDEP_UART3_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_UART3_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_UART3_MPU_MASK (1 << 0)
/* Used by PM_L4PER_UART3_WKDEP */
#define OMAP4430_WKUPDEP_UART3_SDMA_SHIFT 3
-#define OMAP4430_WKUPDEP_UART3_SDMA_MASK BITFIELD(3, 3)
+#define OMAP4430_WKUPDEP_UART3_SDMA_MASK (1 << 3)
/* Used by PM_L4PER_UART3_WKDEP */
#define OMAP4430_WKUPDEP_UART3_TESLA_SHIFT 2
-#define OMAP4430_WKUPDEP_UART3_TESLA_MASK BITFIELD(2, 2)
+#define OMAP4430_WKUPDEP_UART3_TESLA_MASK (1 << 2)
/* Used by PM_L4PER_UART4_WKDEP */
#define OMAP4430_WKUPDEP_UART4_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_UART4_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_UART4_MPU_MASK (1 << 0)
/* Used by PM_L4PER_UART4_WKDEP */
#define OMAP4430_WKUPDEP_UART4_SDMA_SHIFT 3
-#define OMAP4430_WKUPDEP_UART4_SDMA_MASK BITFIELD(3, 3)
+#define OMAP4430_WKUPDEP_UART4_SDMA_MASK (1 << 3)
/* Used by PM_L3INIT_UNIPRO1_WKDEP */
#define OMAP4430_WKUPDEP_UNIPRO1_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_UNIPRO1_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_UNIPRO1_DUCATI_MASK (1 << 1)
/* Used by PM_L3INIT_UNIPRO1_WKDEP */
#define OMAP4430_WKUPDEP_UNIPRO1_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_UNIPRO1_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_UNIPRO1_MPU_MASK (1 << 0)
/* Used by PM_L3INIT_USB_HOST_WKDEP */
#define OMAP4430_WKUPDEP_USB_HOST_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_USB_HOST_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_USB_HOST_DUCATI_MASK (1 << 1)
/* Used by PM_L3INIT_USB_HOST_FS_WKDEP */
#define OMAP4430_WKUPDEP_USB_HOST_FS_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_USB_HOST_FS_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_USB_HOST_FS_DUCATI_MASK (1 << 1)
/* Used by PM_L3INIT_USB_HOST_FS_WKDEP */
#define OMAP4430_WKUPDEP_USB_HOST_FS_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_USB_HOST_FS_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_USB_HOST_FS_MPU_MASK (1 << 0)
/* Used by PM_L3INIT_USB_HOST_WKDEP */
#define OMAP4430_WKUPDEP_USB_HOST_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_USB_HOST_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_USB_HOST_MPU_MASK (1 << 0)
/* Used by PM_L3INIT_USB_OTG_WKDEP */
#define OMAP4430_WKUPDEP_USB_OTG_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_USB_OTG_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_USB_OTG_DUCATI_MASK (1 << 1)
/* Used by PM_L3INIT_USB_OTG_WKDEP */
#define OMAP4430_WKUPDEP_USB_OTG_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_USB_OTG_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_USB_OTG_MPU_MASK (1 << 0)
/* Used by PM_L3INIT_USB_TLL_WKDEP */
#define OMAP4430_WKUPDEP_USB_TLL_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_USB_TLL_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_USB_TLL_DUCATI_MASK (1 << 1)
/* Used by PM_L3INIT_USB_TLL_WKDEP */
#define OMAP4430_WKUPDEP_USB_TLL_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_USB_TLL_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_USB_TLL_MPU_MASK (1 << 0)
/* Used by PM_WKUP_USIM_WKDEP */
#define OMAP4430_WKUPDEP_USIM_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_USIM_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_USIM_MPU_MASK (1 << 0)
/* Used by PM_WKUP_USIM_WKDEP */
#define OMAP4430_WKUPDEP_USIM_SDMA_SHIFT 3
-#define OMAP4430_WKUPDEP_USIM_SDMA_MASK BITFIELD(3, 3)
+#define OMAP4430_WKUPDEP_USIM_SDMA_MASK (1 << 3)
/* Used by PM_WKUP_WDT2_WKDEP */
#define OMAP4430_WKUPDEP_WDT2_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_WDT2_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_WDT2_DUCATI_MASK (1 << 1)
/* Used by PM_WKUP_WDT2_WKDEP */
#define OMAP4430_WKUPDEP_WDT2_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_WDT2_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_WDT2_MPU_MASK (1 << 0)
/* Used by PM_ABE_WDT3_WKDEP */
#define OMAP4430_WKUPDEP_WDT3_MPU_SHIFT 0
-#define OMAP4430_WKUPDEP_WDT3_MPU_MASK BITFIELD(0, 0)
+#define OMAP4430_WKUPDEP_WDT3_MPU_MASK (1 << 0)
/* Used by PM_L3INIT_HSI_WKDEP */
#define OMAP4430_WKUPDEP_WGM_HSI_WAKE_MPU_SHIFT 8
-#define OMAP4430_WKUPDEP_WGM_HSI_WAKE_MPU_MASK BITFIELD(8, 8)
+#define OMAP4430_WKUPDEP_WGM_HSI_WAKE_MPU_MASK (1 << 8)
/* Used by PM_L3INIT_XHPI_WKDEP */
#define OMAP4430_WKUPDEP_XHPI_DUCATI_SHIFT 1
-#define OMAP4430_WKUPDEP_XHPI_DUCATI_MASK BITFIELD(1, 1)
+#define OMAP4430_WKUPDEP_XHPI_DUCATI_MASK (1 << 1)
/* Used by PRM_IO_PMCTRL */
#define OMAP4430_WUCLK_CTRL_SHIFT 8
-#define OMAP4430_WUCLK_CTRL_MASK BITFIELD(8, 8)
+#define OMAP4430_WUCLK_CTRL_MASK (1 << 8)
/* Used by PRM_IO_PMCTRL */
#define OMAP4430_WUCLK_STATUS_SHIFT 9
-#define OMAP4430_WUCLK_STATUS_MASK BITFIELD(9, 9)
+#define OMAP4430_WUCLK_STATUS_MASK (1 << 9)
+
+/* Used by REVISION_PRM */
+#define OMAP4430_X_MAJOR_SHIFT 8
+#define OMAP4430_X_MAJOR_MASK (0x7 << 8)
+
+/* Used by REVISION_PRM */
+#define OMAP4430_Y_MINOR_SHIFT 0
+#define OMAP4430_Y_MINOR_MASK (0x3f << 0)
#endif
diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h
index 588873b9303a..7be040b2fdab 100644
--- a/arch/arm/mach-omap2/prm.h
+++ b/arch/arm/mach-omap2/prm.h
@@ -5,7 +5,7 @@
* OMAP2/3 Power/Reset Management (PRM) register definitions
*
* Copyright (C) 2007-2009 Texas Instruments, Inc.
- * Copyright (C) 2009 Nokia Corporation
+ * Copyright (C) 2010 Nokia Corporation
*
* Written by Paul Walmsley
*
@@ -246,6 +246,15 @@ static inline u32 prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
return prm_rmw_mod_reg_bits(bits, 0x0, module, idx);
}
+/* These omap2_ PRM functions apply to both OMAP2 and 3 */
+int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift);
+int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift);
+int omap2_prm_deassert_hardreset(s16 prm_mod, u8 shift);
+
+int omap4_prm_is_hardreset_asserted(void __iomem *rstctrl_reg, u8 shift);
+int omap4_prm_assert_hardreset(void __iomem *rstctrl_reg, u8 shift);
+int omap4_prm_deassert_hardreset(void __iomem *rstctrl_reg, u8 shift);
+
#endif
/*
@@ -398,4 +407,11 @@ static inline u32 prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
#define OMAP_POWERSTATE_MASK (0x3 << 0)
+/*
+ * MAX_MODULE_HARDRESET_WAIT: Maximum microseconds to wait for an OMAP
+ * submodule to exit hardreset
+ */
+#define MAX_MODULE_HARDRESET_WAIT 10000
+
+
#endif
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
new file mode 100644
index 000000000000..421771eee450
--- /dev/null
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
@@ -0,0 +1,110 @@
+/*
+ * OMAP2/3 PRM module functions
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ * Benoît Cousson
+ * Paul Walmsley
+ *
+ * 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/delay.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+
+#include <plat/common.h>
+#include <plat/cpu.h>
+#include <plat/prcm.h>
+
+#include "prm.h"
+#include "prm-regbits-24xx.h"
+#include "prm-regbits-34xx.h"
+
+/**
+ * omap2_prm_is_hardreset_asserted - read the HW reset line state of
+ * submodules contained in the hwmod module
+ * @prm_mod: PRM submodule base (e.g. CORE_MOD)
+ * @shift: register bit shift corresponding to the reset line to check
+ *
+ * Returns 1 if the (sub)module hardreset line is currently asserted,
+ * 0 if the (sub)module hardreset line is not currently asserted, or
+ * -EINVAL if called while running on a non-OMAP2/3 chip.
+ */
+int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift)
+{
+ if (!(cpu_is_omap24xx() || cpu_is_omap34xx()))
+ return -EINVAL;
+
+ return prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTCTRL,
+ (1 << shift));
+}
+
+/**
+ * omap2_prm_assert_hardreset - assert the HW reset line of a submodule
+ * @prm_mod: PRM submodule base (e.g. CORE_MOD)
+ * @shift: register bit shift corresponding to the reset line to assert
+ *
+ * Some IPs like dsp or iva contain processors that require an HW
+ * reset line to be asserted / deasserted in order to fully enable the
+ * IP. These modules may have multiple hard-reset lines that reset
+ * different 'submodules' inside the IP block. This function will
+ * place the submodule into reset. Returns 0 upon success or -EINVAL
+ * upon an argument error.
+ */
+int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift)
+{
+ u32 mask;
+
+ if (!(cpu_is_omap24xx() || cpu_is_omap34xx()))
+ return -EINVAL;
+
+ mask = 1 << shift;
+ prm_rmw_mod_reg_bits(mask, mask, prm_mod, OMAP2_RM_RSTCTRL);
+
+ return 0;
+}
+
+/**
+ * omap2_prm_deassert_hardreset - deassert a submodule hardreset line and wait
+ * @prm_mod: PRM submodule base (e.g. CORE_MOD)
+ * @shift: register bit shift corresponding to the reset line to deassert
+ *
+ * Some IPs like dsp or iva contain processors that require an HW
+ * reset line to be asserted / deasserted in order to fully enable the
+ * IP. These modules may have multiple hard-reset lines that reset
+ * different 'submodules' inside the IP block. This function will
+ * take the submodule out of reset and wait until the PRCM indicates
+ * that the reset has completed before returning. Returns 0 upon success or
+ * -EINVAL upon an argument error, -EEXIST if the submodule was already out
+ * of reset, or -EBUSY if the submodule did not exit reset promptly.
+ */
+int omap2_prm_deassert_hardreset(s16 prm_mod, u8 shift)
+{
+ u32 mask;
+ int c;
+
+ if (!(cpu_is_omap24xx() || cpu_is_omap34xx()))
+ return -EINVAL;
+
+ mask = 1 << shift;
+
+ /* Check the current status to avoid de-asserting the line twice */
+ if (prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTCTRL, mask) == 0)
+ return -EEXIST;
+
+ /* Clear the reset status by writing 1 to the status bit */
+ prm_rmw_mod_reg_bits(0xffffffff, mask, prm_mod, OMAP2_RM_RSTST);
+ /* de-assert the reset control line */
+ prm_rmw_mod_reg_bits(mask, 0, prm_mod, OMAP2_RM_RSTCTRL);
+ /* wait the status to be set */
+ omap_test_timeout(prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTST,
+ mask),
+ MAX_MODULE_HARDRESET_WAIT, c);
+
+ return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
+}
+
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
new file mode 100644
index 000000000000..a1ff918d9bed
--- /dev/null
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -0,0 +1,116 @@
+/*
+ * OMAP4 PRM module functions
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ * Benoît Cousson
+ * Paul Walmsley
+ *
+ * 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/delay.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+
+#include <plat/common.h>
+#include <plat/cpu.h>
+#include <plat/prcm.h>
+
+#include "prm.h"
+#include "prm-regbits-44xx.h"
+
+/*
+ * Address offset (in bytes) between the reset control and the reset
+ * status registers: 4 bytes on OMAP4
+ */
+#define OMAP4_RST_CTRL_ST_OFFSET 4
+
+/**
+ * omap4_prm_is_hardreset_asserted - read the HW reset line state of
+ * submodules contained in the hwmod module
+ * @rstctrl_reg: RM_RSTCTRL register address for this module
+ * @shift: register bit shift corresponding to the reset line to check
+ *
+ * Returns 1 if the (sub)module hardreset line is currently asserted,
+ * 0 if the (sub)module hardreset line is not currently asserted, or
+ * -EINVAL upon parameter error.
+ */
+int omap4_prm_is_hardreset_asserted(void __iomem *rstctrl_reg, u8 shift)
+{
+ if (!cpu_is_omap44xx() || !rstctrl_reg)
+ return -EINVAL;
+
+ return omap4_prm_read_bits_shift(rstctrl_reg, (1 << shift));
+}
+
+/**
+ * omap4_prm_assert_hardreset - assert the HW reset line of a submodule
+ * @rstctrl_reg: RM_RSTCTRL register address for this module
+ * @shift: register bit shift corresponding to the reset line to assert
+ *
+ * Some IPs like dsp, ipu or iva contain processors that require an HW
+ * reset line to be asserted / deasserted in order to fully enable the
+ * IP. These modules may have multiple hard-reset lines that reset
+ * different 'submodules' inside the IP block. This function will
+ * place the submodule into reset. Returns 0 upon success or -EINVAL
+ * upon an argument error.
+ */
+int omap4_prm_assert_hardreset(void __iomem *rstctrl_reg, u8 shift)
+{
+ u32 mask;
+
+ if (!cpu_is_omap44xx() || !rstctrl_reg)
+ return -EINVAL;
+
+ mask = 1 << shift;
+ omap4_prm_rmw_reg_bits(mask, mask, rstctrl_reg);
+
+ return 0;
+}
+
+/**
+ * omap4_prm_deassert_hardreset - deassert a submodule hardreset line and wait
+ * @rstctrl_reg: RM_RSTCTRL register address for this module
+ * @shift: register bit shift corresponding to the reset line to deassert
+ *
+ * Some IPs like dsp, ipu or iva contain processors that require an HW
+ * reset line to be asserted / deasserted in order to fully enable the
+ * IP. These modules may have multiple hard-reset lines that reset
+ * different 'submodules' inside the IP block. This function will
+ * take the submodule out of reset and wait until the PRCM indicates
+ * that the reset has completed before returning. Returns 0 upon success or
+ * -EINVAL upon an argument error, -EEXIST if the submodule was already out
+ * of reset, or -EBUSY if the submodule did not exit reset promptly.
+ */
+int omap4_prm_deassert_hardreset(void __iomem *rstctrl_reg, u8 shift)
+{
+ u32 mask;
+ void __iomem *rstst_reg;
+ int c;
+
+ if (!cpu_is_omap44xx() || !rstctrl_reg)
+ return -EINVAL;
+
+ rstst_reg = rstctrl_reg + OMAP4_RST_CTRL_ST_OFFSET;
+
+ mask = 1 << shift;
+
+ /* Check the current status to avoid de-asserting the line twice */
+ if (omap4_prm_read_bits_shift(rstctrl_reg, mask) == 0)
+ return -EEXIST;
+
+ /* Clear the reset status by writing 1 to the status bit */
+ omap4_prm_rmw_reg_bits(0xffffffff, mask, rstst_reg);
+ /* de-assert the reset control line */
+ omap4_prm_rmw_reg_bits(mask, 0, rstctrl_reg);
+ /* wait the status to be set */
+ omap_test_timeout(omap4_prm_read_bits_shift(rstst_reg, mask),
+ MAX_MODULE_HARDRESET_WAIT, c);
+
+ return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
+}
+
diff --git a/arch/arm/mach-omap2/prm44xx.h b/arch/arm/mach-omap2/prm44xx.h
index fe8ef26431e5..59839dbabd84 100644
--- a/arch/arm/mach-omap2/prm44xx.h
+++ b/arch/arm/mach-omap2/prm44xx.h
@@ -44,14 +44,12 @@
#define OMAP4430_PRM_IRQSTATUS_TESLA OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0030)
#define OMAP4_PRM_IRQENABLE_TESLA_OFFSET 0x0038
#define OMAP4430_PRM_IRQENABLE_TESLA OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0038)
-#define OMAP4_PRM_PRM_PROFILING_CLKCTRL_OFFSET 0x0040
-#define OMAP4430_PRM_PRM_PROFILING_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0040)
+#define OMAP4_CM_PRM_PROFILING_CLKCTRL_OFFSET 0x0040
+#define OMAP4430_CM_PRM_PROFILING_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0040)
/* PRM.CKGEN_PRM register offsets */
#define OMAP4_CM_ABE_DSS_SYS_CLKSEL_OFFSET 0x0000
#define OMAP4430_CM_ABE_DSS_SYS_CLKSEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CKGEN_MOD, 0x0000)
-#define OMAP4_CM_DPLL_SYS_REF_CLKSEL_OFFSET 0x0004
-#define OMAP4430_CM_DPLL_SYS_REF_CLKSEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CKGEN_MOD, 0x0004)
#define OMAP4_CM_L4_WKUP_CLKSEL_OFFSET 0x0008
#define OMAP4430_CM_L4_WKUP_CLKSEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CKGEN_MOD, 0x0008)
#define OMAP4_CM_ABE_PLL_REF_CLKSEL_OFFSET 0x000c
@@ -686,8 +684,8 @@
#define OMAP4430_PRM_LDO_ABB_IVA_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00d8)
#define OMAP4_PRM_LDO_ABB_IVA_CTRL_OFFSET 0x00dc
#define OMAP4430_PRM_LDO_ABB_IVA_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00dc)
-#define OMAP4_PRM_LDO_BANDGAP_CTRL_OFFSET 0x00e0
-#define OMAP4430_PRM_LDO_BANDGAP_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00e0)
+#define OMAP4_PRM_LDO_BANDGAP_SETUP_OFFSET 0x00e0
+#define OMAP4430_PRM_LDO_BANDGAP_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00e0)
#define OMAP4_PRM_DEVICE_OFF_CTRL_OFFSET 0x00e4
#define OMAP4430_PRM_DEVICE_OFF_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00e4)
#define OMAP4_PRM_PHASE1_CNDP_OFFSET 0x00e8
@@ -698,6 +696,8 @@
#define OMAP4430_PRM_PHASE2B_CNDP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00f0)
#define OMAP4_PRM_MODEM_IF_CTRL_OFFSET 0x00f4
#define OMAP4430_PRM_MODEM_IF_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00f4)
+#define OMAP4_PRM_VC_ERRST_OFFSET 0x00f8
+#define OMAP4430_PRM_VC_ERRST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00f8)
/*
* PRCM_MPU
@@ -715,6 +715,8 @@
/* PRCM_MPU.DEVICE_PRM register offsets */
#define OMAP4_PRCM_MPU_PRM_RSTST_OFFSET 0x0000
#define OMAP4430_PRCM_MPU_PRM_RSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_DEVICE_PRM_MOD, 0x0000)
+#define OMAP4_PRCM_MPU_PRM_PSCON_COUNT_OFFSET 0x0004
+#define OMAP4430_PRCM_MPU_PRM_PSCON_COUNT OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_DEVICE_PRM_MOD, 0x0004)
/* PRCM_MPU.CPU0 register offsets */
#define OMAP4_PM_CPU0_PWRSTCTRL_OFFSET 0x0000
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 566e991ede81..becf0e38ef7e 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -19,20 +19,31 @@
*/
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/serial_8250.h>
#include <linux/serial_reg.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/serial_8250.h>
+#include <linux/pm_runtime.h>
+
+#ifdef CONFIG_SERIAL_OMAP
+#include <plat/omap-serial.h>
+#endif
#include <plat/common.h>
#include <plat/board.h>
#include <plat/clock.h>
-#include <plat/control.h>
+#include <plat/dma.h>
+#include <plat/omap_hwmod.h>
+#include <plat/omap_device.h>
#include "prm.h"
#include "pm.h"
+#include "cm.h"
#include "prm-regbits-34xx.h"
+#include "control.h"
#define UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV 0x52
#define UART_OMAP_WER 0x17 /* Wake-up enable register */
@@ -48,6 +59,8 @@
*/
#define DEFAULT_TIMEOUT 0
+#define MAX_UART_HWMOD_NAME_LEN 16
+
struct omap_uart_state {
int num;
int can_sleep;
@@ -58,14 +71,21 @@ struct omap_uart_state {
void __iomem *wk_en;
u32 wk_mask;
u32 padconf;
+ u32 dma_enabled;
struct clk *ick;
struct clk *fck;
int clocked;
- struct plat_serial8250_port *p;
+ int irq;
+ int regshift;
+ int irqflags;
+ void __iomem *membase;
+ resource_size_t mapbase;
+
struct list_head node;
- struct platform_device pdev;
+ struct omap_hwmod *oh;
+ struct platform_device *pdev;
u32 errata;
#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
@@ -83,75 +103,47 @@ struct omap_uart_state {
};
static LIST_HEAD(uart_list);
+static u8 num_uarts;
-static struct plat_serial8250_port serial_platform_data0[] = {
- {
- .irq = 72,
- .flags = UPF_BOOT_AUTOCONF,
- .iotype = UPIO_MEM,
- .regshift = 2,
- .uartclk = OMAP24XX_BASE_BAUD * 16,
- }, {
- .flags = 0
- }
-};
+/*
+ * Since these idle/enable hooks are used in the idle path itself
+ * which has interrupts disabled, use the non-locking versions of
+ * the hwmod enable/disable functions.
+ */
+static int uart_idle_hwmod(struct omap_device *od)
+{
+ _omap_hwmod_idle(od->hwmods[0]);
-static struct plat_serial8250_port serial_platform_data1[] = {
- {
- .irq = 73,
- .flags = UPF_BOOT_AUTOCONF,
- .iotype = UPIO_MEM,
- .regshift = 2,
- .uartclk = OMAP24XX_BASE_BAUD * 16,
- }, {
- .flags = 0
- }
-};
+ return 0;
+}
-static struct plat_serial8250_port serial_platform_data2[] = {
- {
- .irq = 74,
- .flags = UPF_BOOT_AUTOCONF,
- .iotype = UPIO_MEM,
- .regshift = 2,
- .uartclk = OMAP24XX_BASE_BAUD * 16,
- }, {
- .flags = 0
- }
-};
+static int uart_enable_hwmod(struct omap_device *od)
+{
+ _omap_hwmod_enable(od->hwmods[0]);
-static struct plat_serial8250_port serial_platform_data3[] = {
+ return 0;
+}
+
+static struct omap_device_pm_latency omap_uart_latency[] = {
{
- .irq = 70,
- .flags = UPF_BOOT_AUTOCONF,
- .iotype = UPIO_MEM,
- .regshift = 2,
- .uartclk = OMAP24XX_BASE_BAUD * 16,
- }, {
- .flags = 0
- }
+ .deactivate_func = uart_idle_hwmod,
+ .activate_func = uart_enable_hwmod,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ },
};
-void __init omap2_set_globals_uart(struct omap_globals *omap2_globals)
-{
- serial_platform_data0[0].mapbase = omap2_globals->uart1_phys;
- serial_platform_data1[0].mapbase = omap2_globals->uart2_phys;
- serial_platform_data2[0].mapbase = omap2_globals->uart3_phys;
- serial_platform_data3[0].mapbase = omap2_globals->uart4_phys;
-}
-
static inline unsigned int __serial_read_reg(struct uart_port *up,
- int offset)
+ int offset)
{
offset <<= up->regshift;
return (unsigned int)__raw_readb(up->membase + offset);
}
-static inline unsigned int serial_read_reg(struct plat_serial8250_port *up,
+static inline unsigned int serial_read_reg(struct omap_uart_state *uart,
int offset)
{
- offset <<= up->regshift;
- return (unsigned int)__raw_readb(up->membase + offset);
+ offset <<= uart->regshift;
+ return (unsigned int)__raw_readb(uart->membase + offset);
}
static inline void __serial_write_reg(struct uart_port *up, int offset,
@@ -161,11 +153,11 @@ static inline void __serial_write_reg(struct uart_port *up, int offset,
__raw_writeb(value, up->membase + offset);
}
-static inline void serial_write_reg(struct plat_serial8250_port *p, int offset,
+static inline void serial_write_reg(struct omap_uart_state *uart, int offset,
int value)
{
- offset <<= p->regshift;
- __raw_writeb(value, p->membase + offset);
+ offset <<= uart->regshift;
+ __raw_writeb(value, uart->membase + offset);
}
/*
@@ -173,14 +165,12 @@ static inline void serial_write_reg(struct plat_serial8250_port *p, int offset,
* properly. Note that the TX watermark initialization may not be needed
* once the 8250.c watermark handling code is merged.
*/
+
static inline void __init omap_uart_reset(struct omap_uart_state *uart)
{
- struct plat_serial8250_port *p = uart->p;
-
- serial_write_reg(p, UART_OMAP_MDR1, 0x07);
- serial_write_reg(p, UART_OMAP_SCR, 0x08);
- serial_write_reg(p, UART_OMAP_MDR1, 0x00);
- serial_write_reg(p, UART_OMAP_SYSC, (0x02 << 3) | (1 << 2) | (1 << 0));
+ serial_write_reg(uart, UART_OMAP_MDR1, 0x07);
+ serial_write_reg(uart, UART_OMAP_SCR, 0x08);
+ serial_write_reg(uart, UART_OMAP_MDR1, 0x00);
}
#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3)
@@ -197,24 +187,23 @@ static inline void __init omap_uart_reset(struct omap_uart_state *uart)
static void omap_uart_mdr1_errataset(struct omap_uart_state *uart, u8 mdr1_val,
u8 fcr_val)
{
- struct plat_serial8250_port *p = uart->p;
u8 timeout = 255;
- serial_write_reg(p, UART_OMAP_MDR1, mdr1_val);
+ serial_write_reg(uart, UART_OMAP_MDR1, mdr1_val);
udelay(2);
- serial_write_reg(p, UART_FCR, fcr_val | UART_FCR_CLEAR_XMIT |
+ serial_write_reg(uart, UART_FCR, fcr_val | UART_FCR_CLEAR_XMIT |
UART_FCR_CLEAR_RCVR);
/*
* Wait for FIFO to empty: when empty, RX_FIFO_E bit is 0 and
* TX_FIFO_E bit is 1.
*/
- while (UART_LSR_THRE != (serial_read_reg(p, UART_LSR) &
+ while (UART_LSR_THRE != (serial_read_reg(uart, UART_LSR) &
(UART_LSR_THRE | UART_LSR_DR))) {
timeout--;
if (!timeout) {
/* Should *never* happen. we warn and carry on */
- dev_crit(&uart->pdev.dev, "Errata i202: timedout %x\n",
- serial_read_reg(p, UART_LSR));
+ dev_crit(&uart->pdev->dev, "Errata i202: timedout %x\n",
+ serial_read_reg(uart, UART_LSR));
break;
}
udelay(1);
@@ -224,23 +213,22 @@ static void omap_uart_mdr1_errataset(struct omap_uart_state *uart, u8 mdr1_val,
static void omap_uart_save_context(struct omap_uart_state *uart)
{
u16 lcr = 0;
- struct plat_serial8250_port *p = uart->p;
if (!enable_off_mode)
return;
- lcr = serial_read_reg(p, UART_LCR);
- serial_write_reg(p, UART_LCR, 0xBF);
- uart->dll = serial_read_reg(p, UART_DLL);
- uart->dlh = serial_read_reg(p, UART_DLM);
- serial_write_reg(p, UART_LCR, lcr);
- uart->ier = serial_read_reg(p, UART_IER);
- uart->sysc = serial_read_reg(p, UART_OMAP_SYSC);
- uart->scr = serial_read_reg(p, UART_OMAP_SCR);
- uart->wer = serial_read_reg(p, UART_OMAP_WER);
- serial_write_reg(p, UART_LCR, 0x80);
- uart->mcr = serial_read_reg(p, UART_MCR);
- serial_write_reg(p, UART_LCR, lcr);
+ lcr = serial_read_reg(uart, UART_LCR);
+ serial_write_reg(uart, UART_LCR, 0xBF);
+ uart->dll = serial_read_reg(uart, UART_DLL);
+ uart->dlh = serial_read_reg(uart, UART_DLM);
+ serial_write_reg(uart, UART_LCR, lcr);
+ uart->ier = serial_read_reg(uart, UART_IER);
+ uart->sysc = serial_read_reg(uart, UART_OMAP_SYSC);
+ uart->scr = serial_read_reg(uart, UART_OMAP_SCR);
+ uart->wer = serial_read_reg(uart, UART_OMAP_WER);
+ serial_write_reg(uart, UART_LCR, 0x80);
+ uart->mcr = serial_read_reg(uart, UART_MCR);
+ serial_write_reg(uart, UART_LCR, lcr);
uart->context_valid = 1;
}
@@ -248,7 +236,6 @@ static void omap_uart_save_context(struct omap_uart_state *uart)
static void omap_uart_restore_context(struct omap_uart_state *uart)
{
u16 efr = 0;
- struct plat_serial8250_port *p = uart->p;
if (!enable_off_mode)
return;
@@ -261,29 +248,30 @@ static void omap_uart_restore_context(struct omap_uart_state *uart)
if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS)
omap_uart_mdr1_errataset(uart, 0x07, 0xA0);
else
- serial_write_reg(p, UART_OMAP_MDR1, 0x7);
- serial_write_reg(p, UART_LCR, 0xBF); /* Config B mode */
- efr = serial_read_reg(p, UART_EFR);
- serial_write_reg(p, UART_EFR, UART_EFR_ECB);
- serial_write_reg(p, UART_LCR, 0x0); /* Operational mode */
- serial_write_reg(p, UART_IER, 0x0);
- serial_write_reg(p, UART_LCR, 0xBF); /* Config B mode */
- serial_write_reg(p, UART_DLL, uart->dll);
- serial_write_reg(p, UART_DLM, uart->dlh);
- serial_write_reg(p, UART_LCR, 0x0); /* Operational mode */
- serial_write_reg(p, UART_IER, uart->ier);
- serial_write_reg(p, UART_LCR, 0x80);
- serial_write_reg(p, UART_MCR, uart->mcr);
- serial_write_reg(p, UART_LCR, 0xBF); /* Config B mode */
- serial_write_reg(p, UART_EFR, efr);
- serial_write_reg(p, UART_LCR, UART_LCR_WLEN8);
- serial_write_reg(p, UART_OMAP_SCR, uart->scr);
- serial_write_reg(p, UART_OMAP_WER, uart->wer);
- serial_write_reg(p, UART_OMAP_SYSC, uart->sysc);
+ serial_write_reg(uart, UART_OMAP_MDR1, 0x7);
+ serial_write_reg(uart, UART_LCR, 0xBF); /* Config B mode */
+ efr = serial_read_reg(uart, UART_EFR);
+ serial_write_reg(uart, UART_EFR, UART_EFR_ECB);
+ serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */
+ serial_write_reg(uart, UART_IER, 0x0);
+ serial_write_reg(uart, UART_LCR, 0xBF); /* Config B mode */
+ serial_write_reg(uart, UART_DLL, uart->dll);
+ serial_write_reg(uart, UART_DLM, uart->dlh);
+ serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */
+ serial_write_reg(uart, UART_IER, uart->ier);
+ serial_write_reg(uart, UART_LCR, 0x80);
+ serial_write_reg(uart, UART_MCR, uart->mcr);
+ serial_write_reg(uart, UART_LCR, 0xBF); /* Config B mode */
+ serial_write_reg(uart, UART_EFR, efr);
+ serial_write_reg(uart, UART_LCR, UART_LCR_WLEN8);
+ serial_write_reg(uart, UART_OMAP_SCR, uart->scr);
+ serial_write_reg(uart, UART_OMAP_WER, uart->wer);
+ serial_write_reg(uart, UART_OMAP_SYSC, uart->sysc);
if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS)
omap_uart_mdr1_errataset(uart, 0x00, 0xA1);
else
- serial_write_reg(p, UART_OMAP_MDR1, 0x00); /* UART 16x mode */
+ /* UART 16x mode */
+ serial_write_reg(uart, UART_OMAP_MDR1, 0x00);
}
#else
static inline void omap_uart_save_context(struct omap_uart_state *uart) {}
@@ -295,8 +283,7 @@ static inline void omap_uart_enable_clocks(struct omap_uart_state *uart)
if (uart->clocked)
return;
- clk_enable(uart->ick);
- clk_enable(uart->fck);
+ omap_device_enable(uart->pdev);
uart->clocked = 1;
omap_uart_restore_context(uart);
}
@@ -310,8 +297,7 @@ static inline void omap_uart_disable_clocks(struct omap_uart_state *uart)
omap_uart_save_context(uart);
uart->clocked = 0;
- clk_disable(uart->ick);
- clk_disable(uart->fck);
+ omap_device_idle(uart->pdev);
}
static void omap_uart_enable_wakeup(struct omap_uart_state *uart)
@@ -349,18 +335,24 @@ static void omap_uart_disable_wakeup(struct omap_uart_state *uart)
}
static void omap_uart_smart_idle_enable(struct omap_uart_state *uart,
- int enable)
+ int enable)
{
- struct plat_serial8250_port *p = uart->p;
- u16 sysc;
+ u8 idlemode;
- sysc = serial_read_reg(p, UART_OMAP_SYSC) & 0x7;
- if (enable)
- sysc |= 0x2 << 3;
- else
- sysc |= 0x1 << 3;
+ if (enable) {
+ /**
+ * Errata 2.15: [UART]:Cannot Acknowledge Idle Requests
+ * in Smartidle Mode When Configured for DMA Operations.
+ */
+ if (uart->dma_enabled)
+ idlemode = HWMOD_IDLEMODE_FORCE;
+ else
+ idlemode = HWMOD_IDLEMODE_SMART;
+ } else {
+ idlemode = HWMOD_IDLEMODE_NO;
+ }
- serial_write_reg(p, UART_OMAP_SYSC, sysc);
+ omap_hwmod_set_slave_idlemode(uart->oh, idlemode);
}
static void omap_uart_block_sleep(struct omap_uart_state *uart)
@@ -377,7 +369,7 @@ static void omap_uart_block_sleep(struct omap_uart_state *uart)
static void omap_uart_allow_sleep(struct omap_uart_state *uart)
{
- if (device_may_wakeup(&uart->pdev.dev))
+ if (device_may_wakeup(&uart->pdev->dev))
omap_uart_enable_wakeup(uart);
else
omap_uart_disable_wakeup(uart);
@@ -472,6 +464,7 @@ int omap_uart_can_sleep(void)
* UART will not idle or sleep for its timeout period.
*
**/
+/* static int first_interrupt; */
static irqreturn_t omap_uart_interrupt(int irq, void *dev_id)
{
struct omap_uart_state *uart = dev_id;
@@ -483,7 +476,6 @@ static irqreturn_t omap_uart_interrupt(int irq, void *dev_id)
static void omap_uart_idle_init(struct omap_uart_state *uart)
{
- struct plat_serial8250_port *p = uart->p;
int ret;
uart->can_sleep = 0;
@@ -495,7 +487,7 @@ static void omap_uart_idle_init(struct omap_uart_state *uart)
omap_uart_smart_idle_enable(uart, 0);
if (cpu_is_omap34xx()) {
- u32 mod = (uart->num == 2) ? OMAP3430_PER_MOD : CORE_MOD;
+ u32 mod = (uart->num > 1) ? OMAP3430_PER_MOD : CORE_MOD;
u32 wk_mask = 0;
u32 padconf = 0;
@@ -514,19 +506,17 @@ static void omap_uart_idle_init(struct omap_uart_state *uart)
wk_mask = OMAP3430_ST_UART3_MASK;
padconf = 0x19e;
break;
+ case 3:
+ wk_mask = OMAP3630_ST_UART4_MASK;
+ padconf = 0x0d2;
+ break;
}
uart->wk_mask = wk_mask;
uart->padconf = padconf;
} else if (cpu_is_omap24xx()) {
u32 wk_mask = 0;
+ u32 wk_en = PM_WKEN1, wk_st = PM_WKST1;
- if (cpu_is_omap2430()) {
- uart->wk_en = OMAP2430_PRM_REGADDR(CORE_MOD, PM_WKEN1);
- uart->wk_st = OMAP2430_PRM_REGADDR(CORE_MOD, PM_WKST1);
- } else if (cpu_is_omap2420()) {
- uart->wk_en = OMAP2420_PRM_REGADDR(CORE_MOD, PM_WKEN1);
- uart->wk_st = OMAP2420_PRM_REGADDR(CORE_MOD, PM_WKST1);
- }
switch (uart->num) {
case 0:
wk_mask = OMAP24XX_ST_UART1_MASK;
@@ -535,10 +525,19 @@ static void omap_uart_idle_init(struct omap_uart_state *uart)
wk_mask = OMAP24XX_ST_UART2_MASK;
break;
case 2:
+ wk_en = OMAP24XX_PM_WKEN2;
+ wk_st = OMAP24XX_PM_WKST2;
wk_mask = OMAP24XX_ST_UART3_MASK;
break;
}
uart->wk_mask = wk_mask;
+ if (cpu_is_omap2430()) {
+ uart->wk_en = OMAP2430_PRM_REGADDR(CORE_MOD, wk_en);
+ uart->wk_st = OMAP2430_PRM_REGADDR(CORE_MOD, wk_st);
+ } else if (cpu_is_omap2420()) {
+ uart->wk_en = OMAP2420_PRM_REGADDR(CORE_MOD, wk_en);
+ uart->wk_st = OMAP2420_PRM_REGADDR(CORE_MOD, wk_st);
+ }
} else {
uart->wk_en = NULL;
uart->wk_st = NULL;
@@ -546,9 +545,9 @@ static void omap_uart_idle_init(struct omap_uart_state *uart)
uart->padconf = 0;
}
- p->irqflags |= IRQF_SHARED;
- ret = request_irq(p->irq, omap_uart_interrupt, IRQF_SHARED,
- "serial idle", (void *)uart);
+ uart->irqflags |= IRQF_SHARED;
+ ret = request_threaded_irq(uart->irq, NULL, omap_uart_interrupt,
+ IRQF_SHARED, "serial idle", (void *)uart);
WARN_ON(ret);
}
@@ -558,11 +557,17 @@ void omap_uart_enable_irqs(int enable)
struct omap_uart_state *uart;
list_for_each_entry(uart, &uart_list, node) {
- if (enable)
- ret = request_irq(uart->p->irq, omap_uart_interrupt,
- IRQF_SHARED, "serial idle", (void *)uart);
- else
- free_irq(uart->p->irq, (void *)uart);
+ if (enable) {
+ pm_runtime_put_sync(&uart->pdev->dev);
+ ret = request_threaded_irq(uart->irq, NULL,
+ omap_uart_interrupt,
+ IRQF_SHARED,
+ "serial idle",
+ (void *)uart);
+ } else {
+ pm_runtime_get_noresume(&uart->pdev->dev);
+ free_irq(uart->irq, (void *)uart);
+ }
}
}
@@ -570,10 +575,9 @@ static ssize_t sleep_timeout_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- struct platform_device *pdev = container_of(dev,
- struct platform_device, dev);
- struct omap_uart_state *uart = container_of(pdev,
- struct omap_uart_state, pdev);
+ struct platform_device *pdev = to_platform_device(dev);
+ struct omap_device *odev = to_omap_device(pdev);
+ struct omap_uart_state *uart = odev->hwmods[0]->dev_attr;
return sprintf(buf, "%u\n", uart->timeout / HZ);
}
@@ -582,10 +586,9 @@ static ssize_t sleep_timeout_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t n)
{
- struct platform_device *pdev = container_of(dev,
- struct platform_device, dev);
- struct omap_uart_state *uart = container_of(pdev,
- struct omap_uart_state, pdev);
+ struct platform_device *pdev = to_platform_device(dev);
+ struct omap_device *odev = to_omap_device(pdev);
+ struct omap_uart_state *uart = odev->hwmods[0]->dev_attr;
unsigned int value;
if (sscanf(buf, "%u", &value) != 1) {
@@ -608,48 +611,15 @@ static DEVICE_ATTR(sleep_timeout, 0644, sleep_timeout_show,
#define DEV_CREATE_FILE(dev, attr) WARN_ON(device_create_file(dev, attr))
#else
static inline void omap_uart_idle_init(struct omap_uart_state *uart) {}
+static void omap_uart_block_sleep(struct omap_uart_state *uart)
+{
+ /* Needed to enable UART clocks when built without CONFIG_PM */
+ omap_uart_enable_clocks(uart);
+}
#define DEV_CREATE_FILE(dev, attr)
#endif /* CONFIG_PM */
-static struct omap_uart_state omap_uart[] = {
- {
- .pdev = {
- .name = "serial8250",
- .id = PLAT8250_DEV_PLATFORM,
- .dev = {
- .platform_data = serial_platform_data0,
- },
- },
- }, {
- .pdev = {
- .name = "serial8250",
- .id = PLAT8250_DEV_PLATFORM1,
- .dev = {
- .platform_data = serial_platform_data1,
- },
- },
- }, {
- .pdev = {
- .name = "serial8250",
- .id = PLAT8250_DEV_PLATFORM2,
- .dev = {
- .platform_data = serial_platform_data2,
- },
- },
- },
-#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
- {
- .pdev = {
- .name = "serial8250",
- .id = 3,
- .dev = {
- .platform_data = serial_platform_data3,
- },
- },
- },
-#endif
-};
-
+#ifndef CONFIG_SERIAL_OMAP
/*
* Override the default 8250 read handler: mem_serial_in()
* Empty RX fifo read causes an abort on omap3630 and omap4
@@ -682,71 +652,44 @@ static void serial_out_override(struct uart_port *up, int offset, int value)
}
__serial_write_reg(up, offset, value);
}
+#endif
+
void __init omap_serial_early_init(void)
{
- int i, nr_ports;
- char name[16];
+ int i = 0;
- if (!(cpu_is_omap3630() || cpu_is_omap4430()))
- nr_ports = 3;
- else
- nr_ports = ARRAY_SIZE(omap_uart);
+ do {
+ char oh_name[MAX_UART_HWMOD_NAME_LEN];
+ struct omap_hwmod *oh;
+ struct omap_uart_state *uart;
- /*
- * Make sure the serial ports are muxed on at this point.
- * You have to mux them off in device drivers later on
- * if not needed.
- */
+ snprintf(oh_name, MAX_UART_HWMOD_NAME_LEN,
+ "uart%d", i + 1);
+ oh = omap_hwmod_lookup(oh_name);
+ if (!oh)
+ break;
- for (i = 0; i < nr_ports; i++) {
- struct omap_uart_state *uart = &omap_uart[i];
- struct platform_device *pdev = &uart->pdev;
- struct device *dev = &pdev->dev;
- struct plat_serial8250_port *p = dev->platform_data;
+ uart = kzalloc(sizeof(struct omap_uart_state), GFP_KERNEL);
+ if (WARN_ON(!uart))
+ return;
+
+ uart->oh = oh;
+ uart->num = i++;
+ list_add_tail(&uart->node, &uart_list);
+ num_uarts++;
- /* Don't map zero-based physical address */
- if (p->mapbase == 0) {
- dev_warn(dev, "no physical address for uart#%d,"
- " so skipping early_init...\n", i);
- continue;
- }
/*
- * Module 4KB + L4 interconnect 4KB
- * Static mapping, never released
+ * NOTE: omap_hwmod_init() has not yet been called,
+ * so no hwmod functions will work yet.
*/
- p->membase = ioremap(p->mapbase, SZ_8K);
- if (!p->membase) {
- dev_err(dev, "ioremap failed for uart%i\n", i + 1);
- continue;
- }
-
- sprintf(name, "uart%d_ick", i + 1);
- uart->ick = clk_get(NULL, name);
- if (IS_ERR(uart->ick)) {
- dev_err(dev, "Could not get uart%d_ick\n", i + 1);
- uart->ick = NULL;
- }
- sprintf(name, "uart%d_fck", i+1);
- uart->fck = clk_get(NULL, name);
- if (IS_ERR(uart->fck)) {
- dev_err(dev, "Could not get uart%d_fck\n", i + 1);
- uart->fck = NULL;
- }
-
- /* FIXME: Remove this once the clkdev is ready */
- if (!cpu_is_omap44xx()) {
- if (!uart->ick || !uart->fck)
- continue;
- }
-
- uart->num = i;
- p->private_data = uart;
- uart->p = p;
-
- if (cpu_is_omap44xx())
- p->irq += 32;
- }
+ /*
+ * During UART early init, device need to be probed
+ * to determine SoC specific init before omap_device
+ * is ready. Therefore, don't allow idle here
+ */
+ uart->oh->flags |= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET;
+ } while (1);
}
/**
@@ -763,53 +706,135 @@ void __init omap_serial_early_init(void)
void __init omap_serial_init_port(int port)
{
struct omap_uart_state *uart;
- struct platform_device *pdev;
- struct device *dev;
-
- BUG_ON(port < 0);
- BUG_ON(port >= ARRAY_SIZE(omap_uart));
-
- uart = &omap_uart[port];
- pdev = &uart->pdev;
- dev = &pdev->dev;
+ struct omap_hwmod *oh;
+ struct omap_device *od;
+ void *pdata = NULL;
+ u32 pdata_size = 0;
+ char *name;
+#ifndef CONFIG_SERIAL_OMAP
+ struct plat_serial8250_port ports[2] = {
+ {},
+ {.flags = 0},
+ };
+ struct plat_serial8250_port *p = &ports[0];
+#else
+ struct omap_uart_port_info omap_up;
+#endif
- /* Don't proceed if there's no clocks available */
- if (unlikely(!uart->ick || !uart->fck)) {
- WARN(1, "%s: can't init uart%d, no clocks available\n",
- kobject_name(&dev->kobj), port);
+ if (WARN_ON(port < 0))
+ return;
+ if (WARN_ON(port >= num_uarts))
return;
- }
-
- omap_uart_enable_clocks(uart);
-
- omap_uart_reset(uart);
- omap_uart_idle_init(uart);
- list_add_tail(&uart->node, &uart_list);
+ list_for_each_entry(uart, &uart_list, node)
+ if (port == uart->num)
+ break;
- if (WARN_ON(platform_device_register(pdev)))
- return;
+ oh = uart->oh;
+ uart->dma_enabled = 0;
+#ifndef CONFIG_SERIAL_OMAP
+ name = "serial8250";
- if ((cpu_is_omap34xx() && uart->padconf) ||
- (uart->wk_en && uart->wk_mask)) {
- device_init_wakeup(dev, true);
- DEV_CREATE_FILE(dev, &dev_attr_sleep_timeout);
- }
+ /*
+ * !! 8250 driver does not use standard IORESOURCE* It
+ * has it's own custom pdata that can be taken from
+ * the hwmod resource data. But, this needs to be
+ * done after the build.
+ *
+ * ?? does it have to be done before the register ??
+ * YES, because platform_device_data_add() copies
+ * pdata, it does not use a pointer.
+ */
+ p->flags = UPF_BOOT_AUTOCONF;
+ p->iotype = UPIO_MEM;
+ p->regshift = 2;
+ p->uartclk = OMAP24XX_BASE_BAUD * 16;
+ p->irq = oh->mpu_irqs[0].irq;
+ p->mapbase = oh->slaves[0]->addr->pa_start;
+ p->membase = omap_hwmod_get_mpu_rt_va(oh);
+ p->irqflags = IRQF_SHARED;
+ p->private_data = uart;
/*
* omap44xx: Never read empty UART fifo
* omap3xxx: Never read empty UART fifo on UARTs
* with IP rev >=0x52
*/
+ uart->regshift = p->regshift;
+ uart->membase = p->membase;
if (cpu_is_omap44xx())
uart->errata |= UART_ERRATA_FIFO_FULL_ABORT;
- else if ((serial_read_reg(uart->p, UART_OMAP_MVER) & 0xFF)
+ else if ((serial_read_reg(uart, UART_OMAP_MVER) & 0xFF)
>= UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV)
uart->errata |= UART_ERRATA_FIFO_FULL_ABORT;
if (uart->errata & UART_ERRATA_FIFO_FULL_ABORT) {
- uart->p->serial_in = serial_in_override;
- uart->p->serial_out = serial_out_override;
+ p->serial_in = serial_in_override;
+ p->serial_out = serial_out_override;
+ }
+
+ pdata = &ports[0];
+ pdata_size = 2 * sizeof(struct plat_serial8250_port);
+#else
+
+ name = DRIVER_NAME;
+
+ omap_up.dma_enabled = uart->dma_enabled;
+ omap_up.uartclk = OMAP24XX_BASE_BAUD * 16;
+ omap_up.mapbase = oh->slaves[0]->addr->pa_start;
+ omap_up.membase = omap_hwmod_get_mpu_rt_va(oh);
+ omap_up.irqflags = IRQF_SHARED;
+ omap_up.flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
+
+ pdata = &omap_up;
+ pdata_size = sizeof(struct omap_uart_port_info);
+#endif
+
+ if (WARN_ON(!oh))
+ return;
+
+ od = omap_device_build(name, uart->num, oh, pdata, pdata_size,
+ omap_uart_latency,
+ ARRAY_SIZE(omap_uart_latency), false);
+ WARN(IS_ERR(od), "Could not build omap_device for %s: %s.\n",
+ name, oh->name);
+
+ uart->irq = oh->mpu_irqs[0].irq;
+ uart->regshift = 2;
+ uart->mapbase = oh->slaves[0]->addr->pa_start;
+ uart->membase = omap_hwmod_get_mpu_rt_va(oh);
+ uart->pdev = &od->pdev;
+
+ oh->dev_attr = uart;
+
+ /*
+ * Because of early UART probing, UART did not get idled
+ * on init. Now that omap_device is ready, ensure full idle
+ * before doing omap_device_enable().
+ */
+ omap_hwmod_idle(uart->oh);
+
+ omap_device_enable(uart->pdev);
+ omap_uart_idle_init(uart);
+ omap_uart_reset(uart);
+ omap_hwmod_enable_wakeup(uart->oh);
+ omap_device_idle(uart->pdev);
+
+ /*
+ * Need to block sleep long enough for interrupt driven
+ * driver to start. Console driver is in polling mode
+ * so device needs to be kept enabled while polling driver
+ * is in use.
+ */
+ if (uart->timeout)
+ uart->timeout = (30 * HZ);
+ omap_uart_block_sleep(uart);
+ uart->timeout = DEFAULT_TIMEOUT;
+
+ if ((cpu_is_omap34xx() && uart->padconf) ||
+ (uart->wk_en && uart->wk_mask)) {
+ device_init_wakeup(&od->pdev.dev, true);
+ DEV_CREATE_FILE(&od->pdev.dev, &dev_attr_sleep_timeout);
}
/* Enable the MDR1 errata for OMAP3 */
@@ -826,13 +851,8 @@ void __init omap_serial_init_port(int port)
*/
void __init omap_serial_init(void)
{
- int i, nr_ports;
-
- if (!(cpu_is_omap3630() || cpu_is_omap4430()))
- nr_ports = 3;
- else
- nr_ports = ARRAY_SIZE(omap_uart);
+ struct omap_uart_state *uart;
- for (i = 0; i < nr_ports; i++)
- omap_serial_init_port(i);
+ list_for_each_entry(uart, &uart_list, node)
+ omap_serial_init_port(uart->num);
}
diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
index ba53191ae4c5..2fb205a7f285 100644
--- a/arch/arm/mach-omap2/sleep34xx.S
+++ b/arch/arm/mach-omap2/sleep34xx.S
@@ -27,11 +27,11 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <mach/io.h>
-#include <plat/control.h>
#include "cm.h"
#include "prm.h"
#include "sdrc.h"
+#include "control.h"
#define SDRC_SCRATCHPAD_SEM_V 0xfa00291c
diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S
index de99ba2a57ab..3637274af5be 100644
--- a/arch/arm/mach-omap2/sram34xx.S
+++ b/arch/arm/mach-omap2/sram34xx.S
@@ -129,8 +129,11 @@ ENTRY(omap3_sram_configure_core_dpll)
ldr r4, [sp, #80]
str r4, omap_sdrc_mr_1_val
skip_cs1_params:
+ mrc p15, 0, r8, c1, c0, 0 @ read ctrl register
+ bic r10, r8, #0x800 @ clear Z-bit, disable branch prediction
+ mcr p15, 0, r10, c1, c0, 0 @ write ctrl register
dsb @ flush buffered writes to interconnect
-
+ isb @ prevent speculative exec past here
cmp r3, #1 @ if increasing SDRC clk rate,
bleq configure_sdrc @ program the SDRC regs early (for RFR)
cmp r1, #SDRC_UNLOCK_DLL @ set the intended DLL state
@@ -148,6 +151,7 @@ skip_cs1_params:
beq return_to_sdram @ return to SDRAM code, otherwise,
bl configure_sdrc @ reprogram SDRC regs now
return_to_sdram:
+ mcr p15, 0, r8, c1, c0, 0 @ restore ctrl register
isb @ prevent speculative exec past here
mov r0, #0 @ return value
ldmfd sp!, {r1-r12, pc} @ restore regs and return
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
index 74fbed8491f2..e13c29eecf2b 100644
--- a/arch/arm/mach-omap2/timer-gp.c
+++ b/arch/arm/mach-omap2/timer-gp.c
@@ -40,6 +40,8 @@
#include <plat/dmtimer.h>
#include <asm/localtimer.h>
+#include "timer-gp.h"
+
/* MAX_GPTIMER_ID: number of GPTIMERs on the chip */
#define MAX_GPTIMER_ID 12
@@ -228,8 +230,10 @@ static void __init omap2_gp_clocksource_init(void)
static void __init omap2_gp_timer_init(void)
{
#ifdef CONFIG_LOCAL_TIMERS
- twd_base = ioremap(OMAP44XX_LOCAL_TWD_BASE, SZ_256);
- BUG_ON(!twd_base);
+ if (cpu_is_omap44xx()) {
+ twd_base = ioremap(OMAP44XX_LOCAL_TWD_BASE, SZ_256);
+ BUG_ON(!twd_base);
+ }
#endif
omap_dm_timer_init();
diff --git a/arch/arm/plat-omap/include/plat/timer-gp.h b/arch/arm/mach-omap2/timer-gp.h
index c88d346b59d9..5c1072c6783b 100644
--- a/arch/arm/plat-omap/include/plat/timer-gp.h
+++ b/arch/arm/mach-omap2/timer-gp.h
@@ -11,7 +11,6 @@
#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_TIMER_GP_H
#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_TIMER_GP_H
-int __init omap2_gp_clockevent_set_gptimer(u8 id);
+extern int __init omap2_gp_clockevent_set_gptimer(u8 id);
#endif
-
diff --git a/arch/arm/mach-omap2/usb-fs.c b/arch/arm/mach-omap2/usb-fs.c
index a216d88b04b5..1481078763b8 100644
--- a/arch/arm/mach-omap2/usb-fs.c
+++ b/arch/arm/mach-omap2/usb-fs.c
@@ -29,18 +29,18 @@
#include <asm/irq.h>
-#include <plat/control.h>
#include <plat/usb.h>
#include <plat/board.h>
+#include "control.h"
+#include "mux.h"
+
#define INT_USB_IRQ_GEN INT_24XX_USB_IRQ_GEN
#define INT_USB_IRQ_NISO INT_24XX_USB_IRQ_NISO
#define INT_USB_IRQ_ISO INT_24XX_USB_IRQ_ISO
#define INT_USB_IRQ_HGEN INT_24XX_USB_IRQ_HGEN
#define INT_USB_IRQ_OTG INT_24XX_USB_IRQ_OTG
-#include "mux.h"
-
#if defined(CONFIG_ARCH_OMAP2)
#ifdef CONFIG_USB_GADGET_OMAP
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 6d845446ce26..aaa1166df964 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 491a27a92735..2fd5a8b35757 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..ed0dbfdb22ed 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>
@@ -1015,7 +1015,6 @@ static struct soc_camera_link iclink = {
.power = em_x270_sensor_power,
.board_info = &em_x270_i2c_cam_info[0],
.i2c_adapter_id = 0,
- .module_name = "mt9m111",
};
static struct platform_device em_x270_camera = {
@@ -1301,8 +1300,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 +1308,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..142c711f4cda 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
@@ -753,7 +755,6 @@ static struct soc_camera_link a780_iclink = {
.flags = SOCAM_SENSOR_INVERT_PCLK,
.i2c_adapter_id = 0,
.board_info = &a780_camera_i2c_board_info,
- .module_name = "mt9m111",
.power = a780_camera_power,
.reset = a780_camera_reset,
};
@@ -796,10 +797,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 +862,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 +927,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,
@@ -1025,7 +1023,6 @@ static struct soc_camera_link a910_iclink = {
.bus_id = 0,
.i2c_adapter_id = 0,
.board_info = &a910_camera_i2c_board_info,
- .module_name = "mt9m111",
.power = a910_camera_power,
.reset = a910_camera_reset,
};
@@ -1120,10 +1117,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 +1182,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 +1221,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..f5fb915e1315 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>
@@ -711,7 +711,6 @@ static struct soc_camera_link iclink = {
.bus_id = 0, /* Match id in pxa27x_device_camera in device.c */
.board_info = &mioa701_i2c_devices[0],
.i2c_adapter_id = 0,
- .module_name = "mt9m111",
};
struct i2c_pxa_platform_data i2c_pdata = {
@@ -819,8 +818,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/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c
index f56ae1008759..f33647a8e0b7 100644
--- a/arch/arm/mach-pxa/pcm990-baseboard.c
+++ b/arch/arm/mach-pxa/pcm990-baseboard.c
@@ -453,7 +453,6 @@ static struct soc_camera_link iclink[] = {
.query_bus_param = pcm990_camera_query_bus_param,
.set_bus_param = pcm990_camera_set_bus_param,
.free_bus = pcm990_camera_free_bus,
- .module_name = "mt9v022",
}, {
.bus_id = 0, /* Must match with the camera ID */
.board_info = &pcm990_camera_i2c[1],
@@ -461,7 +460,6 @@ static struct soc_camera_link iclink[] = {
.query_bus_param = pcm990_camera_query_bus_param,
.set_bus_param = pcm990_camera_set_bus_param,
.free_bus = pcm990_camera_free_bus,
- .module_name = "mt9m001",
},
};
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 90974e6fae6a..d1c747cdacf8 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 5ba9d99a1bf6..702f7a68e87d 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"
@@ -422,10 +422,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/h1940-bluetooth.c b/arch/arm/mach-s3c2410/h1940-bluetooth.c
index 8cdeb14af592..8aa2f1902a94 100644
--- a/arch/arm/mach-s3c2410/h1940-bluetooth.c
+++ b/arch/arm/mach-s3c2410/h1940-bluetooth.c
@@ -30,7 +30,7 @@ static void h1940bt_enable(int on)
{
if (on) {
/* Power on the chip */
- h1940_latch_control(0, H1940_LATCH_BLUETOOTH_POWER);
+ gpio_set_value(H1940_LATCH_BLUETOOTH_POWER, 1);
/* Reset the chip */
mdelay(10);
@@ -43,7 +43,7 @@ static void h1940bt_enable(int on)
mdelay(10);
gpio_set_value(S3C2410_GPH(1), 0);
mdelay(10);
- h1940_latch_control(H1940_LATCH_BLUETOOTH_POWER, 0);
+ gpio_set_value(H1940_LATCH_BLUETOOTH_POWER, 0);
}
}
@@ -64,7 +64,14 @@ static int __devinit h1940bt_probe(struct platform_device *pdev)
ret = gpio_request(S3C2410_GPH(1), dev_name(&pdev->dev));
if (ret) {
- dev_err(&pdev->dev, "could not get GPH1\n");\
+ dev_err(&pdev->dev, "could not get GPH1\n");
+ return ret;
+ }
+
+ ret = gpio_request(H1940_LATCH_BLUETOOTH_POWER, dev_name(&pdev->dev));
+ if (ret) {
+ gpio_free(S3C2410_GPH(1));
+ dev_err(&pdev->dev, "could not get BT_POWER\n");
return ret;
}
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/include/mach/gpio.h b/arch/arm/mach-s3c2410/include/mach/gpio.h
index b649bf2ccd5c..f7f6b07df30e 100644
--- a/arch/arm/mach-s3c2410/include/mach/gpio.h
+++ b/arch/arm/mach-s3c2410/include/mach/gpio.h
@@ -22,6 +22,8 @@
#ifdef CONFIG_CPU_S3C244X
#define ARCH_NR_GPIOS (32 * 9 + CONFIG_S3C24XX_GPIO_EXTRA)
+#elif defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416)
+#define ARCH_NR_GPIOS (32 * 12 + CONFIG_S3C24XX_GPIO_EXTRA)
#else
#define ARCH_NR_GPIOS (256 + CONFIG_S3C24XX_GPIO_EXTRA)
#endif
@@ -30,8 +32,10 @@
#include <mach/gpio-nrs.h>
#include <mach/gpio-fns.h>
-#ifdef CONFIG_CPU_S3C24XX
-#define S3C_GPIO_END (S3C2410_GPIO_BANKJ + 32)
+#ifdef CONFIG_CPU_S3C244X
+#define S3C_GPIO_END (S3C2410_GPJ(0) + 32)
+#elif defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416)
+#define S3C_GPIO_END (S3C2410_GPM(0) + 32)
#else
-#define S3C_GPIO_END (S3C2410_GPIO_BANKH + 32)
+#define S3C_GPIO_END (S3C2410_GPH(0) + 32)
#endif
diff --git a/arch/arm/mach-s3c2410/include/mach/h1940-latch.h b/arch/arm/mach-s3c2410/include/mach/h1940-latch.h
index d8a832729a8a..97e42bfce81e 100644
--- a/arch/arm/mach-s3c2410/include/mach/h1940-latch.h
+++ b/arch/arm/mach-s3c2410/include/mach/h1940-latch.h
@@ -14,51 +14,30 @@
#ifndef __ASM_ARCH_H1940_LATCH_H
#define __ASM_ARCH_H1940_LATCH_H
+#include <mach/gpio.h>
-#ifndef __ASSEMBLY__
-#define H1940_LATCH ((void __force __iomem *)0xF8000000)
-#else
-#define H1940_LATCH 0xF8000000
-#endif
-
-#define H1940_PA_LATCH (S3C2410_CS2)
+#define H1940_LATCH_GPIO(x) (S3C_GPIO_END + (x))
/* SD layer latch */
-#define H1940_LATCH_SDQ1 (1<<16)
-#define H1940_LATCH_LCD_P1 (1<<17)
-#define H1940_LATCH_LCD_P2 (1<<18)
-#define H1940_LATCH_LCD_P3 (1<<19)
-#define H1940_LATCH_MAX1698_nSHUTDOWN (1<<20) /* LCD backlight */
-#define H1940_LATCH_LED_RED (1<<21)
-#define H1940_LATCH_SDQ7 (1<<22)
-#define H1940_LATCH_USB_DP (1<<23)
+#define H1940_LATCH_LCD_P0 H1940_LATCH_GPIO(0)
+#define H1940_LATCH_LCD_P1 H1940_LATCH_GPIO(1)
+#define H1940_LATCH_LCD_P2 H1940_LATCH_GPIO(2)
+#define H1940_LATCH_LCD_P3 H1940_LATCH_GPIO(3)
+#define H1940_LATCH_MAX1698_nSHUTDOWN H1940_LATCH_GPIO(4)
+#define H1940_LATCH_LED_RED H1940_LATCH_GPIO(5)
+#define H1940_LATCH_SDQ7 H1940_LATCH_GPIO(6)
+#define H1940_LATCH_USB_DP H1940_LATCH_GPIO(7)
/* CPU layer latch */
-#define H1940_LATCH_UDA_POWER (1<<24)
-#define H1940_LATCH_AUDIO_POWER (1<<25)
-#define H1940_LATCH_SM803_ENABLE (1<<26)
-#define H1940_LATCH_LCD_P4 (1<<27)
-#define H1940_LATCH_CPUQ5 (1<<28) /* untraced */
-#define H1940_LATCH_BLUETOOTH_POWER (1<<29) /* active high */
-#define H1940_LATCH_LED_GREEN (1<<30)
-#define H1940_LATCH_LED_FLASH (1<<31)
-
-/* default settings */
-
-#define H1940_LATCH_DEFAULT \
- H1940_LATCH_LCD_P4 | \
- H1940_LATCH_SM803_ENABLE | \
- H1940_LATCH_SDQ1 | \
- H1940_LATCH_LCD_P1 | \
- H1940_LATCH_LCD_P2 | \
- H1940_LATCH_LCD_P3 | \
- H1940_LATCH_MAX1698_nSHUTDOWN | \
- H1940_LATCH_CPUQ5
-
-/* control functions */
-
-extern void h1940_latch_control(unsigned int clear, unsigned int set);
+#define H1940_LATCH_UDA_POWER H1940_LATCH_GPIO(8)
+#define H1940_LATCH_AUDIO_POWER H1940_LATCH_GPIO(9)
+#define H1940_LATCH_SM803_ENABLE H1940_LATCH_GPIO(10)
+#define H1940_LATCH_LCD_P4 H1940_LATCH_GPIO(11)
+#define H1940_LATCH_SD_POWER H1940_LATCH_GPIO(12)
+#define H1940_LATCH_BLUETOOTH_POWER H1940_LATCH_GPIO(13)
+#define H1940_LATCH_LED_GREEN H1940_LATCH_GPIO(14)
+#define H1940_LATCH_LED_FLASH H1940_LATCH_GPIO(15)
#endif /* __ASM_ARCH_H1940_LATCH_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
index 08ab9dfb6ae6..101aeea22310 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
@@ -118,6 +118,8 @@
#define S3C2443_SCLKCON_UARTCLK (1<<8)
#define S3C2443_SCLKCON_USBHOST (1<<1)
+#define S3C2443_PWRCFG_SLEEP (1<<15)
+
#include <asm/div64.h>
static inline unsigned int
diff --git a/arch/arm/mach-s3c2410/include/mach/vmalloc.h b/arch/arm/mach-s3c2410/include/mach/vmalloc.h
index 54297eb0bf5e..7a311e8dddba 100644
--- a/arch/arm/mach-s3c2410/include/mach/vmalloc.h
+++ b/arch/arm/mach-s3c2410/include/mach/vmalloc.h
@@ -15,6 +15,6 @@
#ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H
-#define VMALLOC_END 0xE0000000UL
+#define VMALLOC_END 0xF6000000UL
#endif /* __ASM_ARCH_VMALLOC_H */
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..d7ada8c7e41f 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -24,6 +24,7 @@
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/pwm_backlight.h>
+#include <linux/i2c.h>
#include <video/platform_lcd.h>
#include <linux/mmc/host.h>
@@ -59,6 +60,14 @@
#include <plat/mci.h>
#include <plat/ts.h>
+#include <sound/uda1380.h>
+
+#define H1940_LATCH ((void __force __iomem *)0xF8000000)
+
+#define H1940_PA_LATCH S3C2410_CS2
+
+#define H1940_LATCH_BIT(x) (1 << ((x) + 16 - S3C_GPIO_END))
+
static struct map_desc h1940_iodesc[] __initdata = {
[0] = {
.virtual = (unsigned long)H1940_LATCH,
@@ -100,9 +109,9 @@ static struct s3c2410_uartcfg h1940_uartcfgs[] __initdata = {
/* Board control latch control */
-static unsigned int latch_state = H1940_LATCH_DEFAULT;
+static unsigned int latch_state;
-void h1940_latch_control(unsigned int clear, unsigned int set)
+static void h1940_latch_control(unsigned int clear, unsigned int set)
{
unsigned long flags;
@@ -116,7 +125,42 @@ void h1940_latch_control(unsigned int clear, unsigned int set)
local_irq_restore(flags);
}
-EXPORT_SYMBOL_GPL(h1940_latch_control);
+static inline int h1940_gpiolib_to_latch(int offset)
+{
+ return 1 << (offset + 16);
+}
+
+static void h1940_gpiolib_latch_set(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ int latch_bit = h1940_gpiolib_to_latch(offset);
+
+ h1940_latch_control(value ? 0 : latch_bit,
+ value ? latch_bit : 0);
+}
+
+static int h1940_gpiolib_latch_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ h1940_gpiolib_latch_set(chip, offset, value);
+ return 0;
+}
+
+static int h1940_gpiolib_latch_get(struct gpio_chip *chip,
+ unsigned offset)
+{
+ return (latch_state >> (offset + 16)) & 1;
+}
+
+struct gpio_chip h1940_latch_gpiochip = {
+ .base = H1940_LATCH_GPIO(0),
+ .owner = THIS_MODULE,
+ .label = "H1940_LATCH",
+ .ngpio = 16,
+ .direction_output = h1940_gpiolib_latch_output,
+ .set = h1940_gpiolib_latch_set,
+ .get = h1940_gpiolib_latch_get,
+};
static void h1940_udc_pullup(enum s3c2410_udc_cmd_e cmd)
{
@@ -125,10 +169,10 @@ static void h1940_udc_pullup(enum s3c2410_udc_cmd_e cmd)
switch (cmd)
{
case S3C2410_UDC_P_ENABLE :
- h1940_latch_control(0, H1940_LATCH_USB_DP);
+ gpio_set_value(H1940_LATCH_USB_DP, 1);
break;
case S3C2410_UDC_P_DISABLE :
- h1940_latch_control(H1940_LATCH_USB_DP, 0);
+ gpio_set_value(H1940_LATCH_USB_DP, 0);
break;
case S3C2410_UDC_P_RESET :
break;
@@ -199,10 +243,25 @@ static struct platform_device h1940_device_bluetooth = {
.id = -1,
};
+static void h1940_set_mmc_power(unsigned char power_mode, unsigned short vdd)
+{
+ switch (power_mode) {
+ case MMC_POWER_OFF:
+ gpio_set_value(H1940_LATCH_SD_POWER, 0);
+ break;
+ case MMC_POWER_UP:
+ case MMC_POWER_ON:
+ gpio_set_value(H1940_LATCH_SD_POWER, 1);
+ break;
+ default:
+ break;
+ };
+}
+
static struct s3c24xx_mci_pdata h1940_mmc_cfg __initdata = {
.gpio_detect = S3C2410_GPF(5),
.gpio_wprotect = S3C2410_GPH(8),
- .set_power = NULL,
+ .set_power = h1940_set_mmc_power,
.ocr_avail = MMC_VDD_32_33,
};
@@ -213,15 +272,32 @@ static int h1940_backlight_init(struct device *dev)
gpio_direction_output(S3C2410_GPB(0), 0);
s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE);
s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
+ gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 1);
return 0;
}
+static int h1940_backlight_notify(struct device *dev, int brightness)
+{
+ if (!brightness) {
+ gpio_direction_output(S3C2410_GPB(0), 1);
+ gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 0);
+ } else {
+ gpio_direction_output(S3C2410_GPB(0), 0);
+ s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
+ gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 1);
+ }
+ return brightness;
+}
+
static void h1940_backlight_exit(struct device *dev)
{
gpio_direction_output(S3C2410_GPB(0), 1);
+ gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 0);
}
+
static struct platform_pwm_backlight_data backlight_data = {
.pwm_id = 0,
.max_brightness = 100,
@@ -229,6 +305,7 @@ static struct platform_pwm_backlight_data backlight_data = {
/* tcnt = 0x31 */
.pwm_period_ns = 36296,
.init = h1940_backlight_init,
+ .notify = h1940_backlight_notify,
.exit = h1940_backlight_exit,
};
@@ -247,19 +324,37 @@ static void h1940_lcd_power_set(struct plat_lcd_data *pd,
int value;
if (!power) {
- /* set to 3ec */
- gpio_direction_output(S3C2410_GPC(0), 0);
+ gpio_set_value(S3C2410_GPC(0), 0);
/* wait for 3ac */
do {
value = gpio_get_value(S3C2410_GPC(6));
} while (value);
- /* set to 38c */
- gpio_direction_output(S3C2410_GPC(5), 0);
+
+ gpio_set_value(H1940_LATCH_LCD_P2, 0);
+ gpio_set_value(H1940_LATCH_LCD_P3, 0);
+ gpio_set_value(H1940_LATCH_LCD_P4, 0);
+
+ gpio_direction_output(S3C2410_GPC(1), 0);
+ gpio_direction_output(S3C2410_GPC(4), 0);
+
+ gpio_set_value(H1940_LATCH_LCD_P1, 0);
+ gpio_set_value(H1940_LATCH_LCD_P0, 0);
+
+ gpio_set_value(S3C2410_GPC(5), 0);
+
} else {
- /* Set to 3ac */
- gpio_direction_output(S3C2410_GPC(5), 1);
- /* Set to 3ad */
- gpio_direction_output(S3C2410_GPC(0), 1);
+ gpio_set_value(H1940_LATCH_LCD_P0, 1);
+ gpio_set_value(H1940_LATCH_LCD_P1, 1);
+
+ s3c_gpio_cfgpin(S3C2410_GPC(1), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(S3C2410_GPC(4), S3C_GPIO_SFN(2));
+
+ gpio_set_value(S3C2410_GPC(5), 1);
+ gpio_set_value(S3C2410_GPC(0), 1);
+
+ gpio_set_value(H1940_LATCH_LCD_P3, 1);
+ gpio_set_value(H1940_LATCH_LCD_P2, 1);
+ gpio_set_value(H1940_LATCH_LCD_P4, 1);
}
}
@@ -273,12 +368,26 @@ static struct platform_device h1940_lcd_powerdev = {
.dev.platform_data = &h1940_lcd_power_data,
};
+static struct uda1380_platform_data uda1380_info = {
+ .gpio_power = H1940_LATCH_UDA_POWER,
+ .gpio_reset = S3C2410_GPA(12),
+ .dac_clk = UDA1380_DAC_CLK_SYSCLK,
+};
+
+static struct i2c_board_info h1940_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("uda1380", 0x1a),
+ .platform_data = &uda1380_info,
+ },
+};
+
static struct platform_device *h1940_devices[] __initdata = {
&s3c_device_ohci,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
+ &s3c_device_pcm,
&s3c_device_usbgadget,
&h1940_device_leds,
&h1940_device_bluetooth,
@@ -303,6 +412,10 @@ static void __init h1940_map_io(void)
memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 1024);
#endif
s3c_pm_init();
+
+ /* Add latch gpio chip, set latch initial value */
+ h1940_latch_control(0, 0);
+ WARN_ON(gpiochip_add(&h1940_latch_gpiochip));
}
/* H1940 and RX3715 need to reserve this for suspend */
@@ -340,18 +453,42 @@ static void __init h1940_init(void)
writel(tmp, S3C2410_UPLLCON);
gpio_request(S3C2410_GPC(0), "LCD power");
+ gpio_request(S3C2410_GPC(1), "LCD power");
+ gpio_request(S3C2410_GPC(4), "LCD power");
gpio_request(S3C2410_GPC(5), "LCD power");
gpio_request(S3C2410_GPC(6), "LCD power");
-
+ gpio_request(H1940_LATCH_LCD_P0, "LCD power");
+ gpio_request(H1940_LATCH_LCD_P1, "LCD power");
+ gpio_request(H1940_LATCH_LCD_P2, "LCD power");
+ gpio_request(H1940_LATCH_LCD_P3, "LCD power");
+ gpio_request(H1940_LATCH_LCD_P4, "LCD power");
+ gpio_request(H1940_LATCH_MAX1698_nSHUTDOWN, "LCD power");
+ gpio_direction_output(S3C2410_GPC(0), 0);
+ gpio_direction_output(S3C2410_GPC(1), 0);
+ gpio_direction_output(S3C2410_GPC(4), 0);
+ gpio_direction_output(S3C2410_GPC(5), 0);
gpio_direction_input(S3C2410_GPC(6));
+ gpio_direction_output(H1940_LATCH_LCD_P0, 0);
+ gpio_direction_output(H1940_LATCH_LCD_P1, 0);
+ gpio_direction_output(H1940_LATCH_LCD_P2, 0);
+ gpio_direction_output(H1940_LATCH_LCD_P3, 0);
+ gpio_direction_output(H1940_LATCH_LCD_P4, 0);
+ gpio_direction_output(H1940_LATCH_MAX1698_nSHUTDOWN, 0);
+
+ gpio_request(H1940_LATCH_USB_DP, "USB pullup");
+ gpio_direction_output(H1940_LATCH_USB_DP, 0);
+
+ gpio_request(H1940_LATCH_SD_POWER, "SD power");
+ gpio_direction_output(H1940_LATCH_SD_POWER, 0);
platform_add_devices(h1940_devices, ARRAY_SIZE(h1940_devices));
+
+ i2c_register_board_info(0, h1940_i2c_devices,
+ ARRAY_SIZE(h1940_i2c_devices));
}
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-s3c2412/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c
index bef39f77729d..4c6df51ddf33 100644
--- a/arch/arm/mach-s3c2412/s3c2412.c
+++ b/arch/arm/mach-s3c2412/s3c2412.c
@@ -51,6 +51,7 @@
#include <plat/clock.h>
#include <plat/pm.h>
#include <plat/pll.h>
+#include <plat/nand-core.h>
#ifndef CONFIG_CPU_S3C2412_ONLY
void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO;
@@ -92,7 +93,7 @@ void __init s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no)
/* rename devices that are s3c2412/s3c2413 specific */
s3c_device_sdi.name = "s3c2412-sdi";
s3c_device_lcd.name = "s3c2412-lcd";
- s3c_device_nand.name = "s3c2412-nand";
+ s3c_nand_setname("s3c2412-nand");
/* alter IRQ of SDI controller */
diff --git a/arch/arm/mach-s3c2416/Kconfig b/arch/arm/mach-s3c2416/Kconfig
index 657e4fe17f39..87b9c9f003bd 100644
--- a/arch/arm/mach-s3c2416/Kconfig
+++ b/arch/arm/mach-s3c2416/Kconfig
@@ -25,6 +25,11 @@ config S3C2416_DMA
help
Internal config node for S3C2416 DMA support
+config S3C2416_PM
+ bool
+ help
+ Internal config node to apply S3C2416 power management
+
menu "S3C2416 Machines"
config MACH_SMDK2416
@@ -33,6 +38,7 @@ config MACH_SMDK2416
select S3C_DEV_FB
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
+ select S3C2416_PM if PM
help
Say Y here if you are using an SMDK2416
diff --git a/arch/arm/mach-s3c2416/Makefile b/arch/arm/mach-s3c2416/Makefile
index 6c12c7bf40ad..ef038d62ffdb 100644
--- a/arch/arm/mach-s3c2416/Makefile
+++ b/arch/arm/mach-s3c2416/Makefile
@@ -11,7 +11,7 @@ obj- :=
obj-$(CONFIG_CPU_S3C2416) += s3c2416.o clock.o
obj-$(CONFIG_CPU_S3C2416) += irq.o
-
+obj-$(CONFIG_S3C2416_PM) += pm.o
#obj-$(CONFIG_S3C2416_DMA) += dma.o
# Machine support
diff --git a/arch/arm/mach-s3c2416/irq.c b/arch/arm/mach-s3c2416/irq.c
index 89f521d59d06..084d121f368c 100644
--- a/arch/arm/mach-s3c2416/irq.c
+++ b/arch/arm/mach-s3c2416/irq.c
@@ -243,6 +243,8 @@ static int __init s3c2416_irq_add(struct sys_device *sysdev)
static struct sysdev_driver s3c2416_irq_driver = {
.add = s3c2416_irq_add,
+ .suspend = s3c24xx_irq_suspend,
+ .resume = s3c24xx_irq_resume,
};
static int __init s3c2416_irq_init(void)
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-s3c2416/pm.c b/arch/arm/mach-s3c2416/pm.c
new file mode 100644
index 000000000000..4a04205b04d5
--- /dev/null
+++ b/arch/arm/mach-s3c2416/pm.c
@@ -0,0 +1,84 @@
+/* linux/arch/arm/mach-s3c2416/pm.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S3C2416 - PM support (Based on Ben Dooks' S3C2412 PM 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/sysdev.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+
+#include <mach/regs-power.h>
+#include <mach/regs-s3c2443-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+extern void s3c2412_sleep_enter(void);
+
+static void s3c2416_cpu_suspend(void)
+{
+ flush_cache_all();
+
+ /* enable wakeup sources regardless of battery state */
+ __raw_writel(S3C2443_PWRCFG_SLEEP, S3C2443_PWRCFG);
+
+ /* set the mode as sleep, 2BED represents "Go to BED" */
+ __raw_writel(0x2BED, S3C2443_PWRMODE);
+
+ s3c2412_sleep_enter();
+}
+
+static void s3c2416_pm_prepare(void)
+{
+ /*
+ * write the magic value u-boot uses to check for resume into
+ * the INFORM0 register, and ensure INFORM1 is set to the
+ * correct address to resume from.
+ */
+ __raw_writel(0x2BED, S3C2412_INFORM0);
+ __raw_writel(virt_to_phys(s3c_cpu_resume), S3C2412_INFORM1);
+}
+
+static int s3c2416_pm_add(struct sys_device *sysdev)
+{
+ pm_cpu_prep = s3c2416_pm_prepare;
+ pm_cpu_sleep = s3c2416_cpu_suspend;
+
+ return 0;
+}
+
+static int s3c2416_pm_suspend(struct sys_device *dev, pm_message_t state)
+{
+ return 0;
+}
+
+static int s3c2416_pm_resume(struct sys_device *dev)
+{
+ /* unset the return-from-sleep amd inform flags */
+ __raw_writel(0x0, S3C2443_PWRMODE);
+ __raw_writel(0x0, S3C2412_INFORM0);
+ __raw_writel(0x0, S3C2412_INFORM1);
+
+ return 0;
+}
+
+static struct sysdev_driver s3c2416_pm_driver = {
+ .add = s3c2416_pm_add,
+ .suspend = s3c2416_pm_suspend,
+ .resume = s3c2416_pm_resume,
+};
+
+static __init int s3c2416_pm_init(void)
+{
+ return sysdev_driver_register(&s3c2416_sysclass, &s3c2416_pm_driver);
+}
+
+arch_initcall(s3c2416_pm_init);
diff --git a/arch/arm/mach-s3c2416/s3c2416.c b/arch/arm/mach-s3c2416/s3c2416.c
index bc30245e133b..63f39cdc0972 100644
--- a/arch/arm/mach-s3c2416/s3c2416.c
+++ b/arch/arm/mach-s3c2416/s3c2416.c
@@ -56,6 +56,7 @@
#include <plat/iic-core.h>
#include <plat/fb-core.h>
+#include <plat/nand-core.h>
static struct map_desc s3c2416_iodesc[] __initdata = {
IODESC_ENT(WATCHDOG),
@@ -100,7 +101,7 @@ void __init s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no)
{
s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
- s3c_device_nand.name = "s3c2416-nand";
+ s3c_nand_setname("s3c2412-nand");
}
/* s3c2416_map_io
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig
index cd8e7de388f0..ff024a6c0f85 100644
--- a/arch/arm/mach-s3c2440/Kconfig
+++ b/arch/arm/mach-s3c2440/Kconfig
@@ -4,7 +4,6 @@
config CPU_S3C2440
bool
- depends on ARCH_S3C2410
select CPU_ARM920T
select S3C_GPIO_PULL_UP
select S3C2410_CLOCK
@@ -18,7 +17,6 @@ config CPU_S3C2440
config CPU_S3C2442
bool
- depends on ARCH_S3C2410
select CPU_ARM920T
select S3C2410_CLOCK
select S3C2410_GPIO
@@ -30,7 +28,7 @@ config CPU_S3C2442
config CPU_S3C244X
bool
- depends on ARCH_S3C2410 && (CPU_S3C2440 || CPU_S3C2442)
+ depends on CPU_S3C2440 || CPU_S3C2442
help
Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems.
@@ -72,7 +70,7 @@ config S3C2440_PLL_16934400
config S3C2440_DMA
bool
- depends on ARCH_S3C2410 && CPU_S3C24405B
+ depends on CPU_S3C2440
help
Support for S3C2440 specific DMA code5A
@@ -181,7 +179,6 @@ config MACH_MINI2440
select CPU_S3C2440
select EEPROM_AT24
select LEDS_TRIGGER_BACKLIGHT
- select SND_S3C24XX_SOC_S3C24XX_UDA134X
select S3C_DEV_NAND
select S3C_DEV_USB_HOST
help
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..e0622bbb6dfa 100644
--- a/arch/arm/mach-s3c2440/mach-rx1950.c
+++ b/arch/arm/mach-s3c2440/mach-rx1950.c
@@ -25,8 +25,12 @@
#include <linux/input.h>
#include <linux/gpio_keys.h>
#include <linux/sysdev.h>
+#include <linux/pda_power.h>
#include <linux/pwm_backlight.h>
#include <linux/pwm.h>
+#include <linux/s3c_adc_battery.h>
+#include <linux/leds.h>
+#include <linux/i2c.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
@@ -55,6 +59,8 @@
#include <plat/irq.h>
#include <plat/ts.h>
+#include <sound/uda1380.h>
+
#define LCD_PWM_PERIOD 192960
#define LCD_PWM_DUTY 127353
@@ -127,6 +133,193 @@ static struct s3c2410fb_display rx1950_display = {
};
+static int power_supply_init(struct device *dev)
+{
+ return gpio_request(S3C2410_GPF(2), "cable plugged");
+}
+
+static int rx1950_is_ac_online(void)
+{
+ return !gpio_get_value(S3C2410_GPF(2));
+}
+
+static void power_supply_exit(struct device *dev)
+{
+ gpio_free(S3C2410_GPF(2));
+}
+
+static char *rx1950_supplicants[] = {
+ "main-battery"
+};
+
+static struct pda_power_pdata power_supply_info = {
+ .init = power_supply_init,
+ .is_ac_online = rx1950_is_ac_online,
+ .exit = power_supply_exit,
+ .supplied_to = rx1950_supplicants,
+ .num_supplicants = ARRAY_SIZE(rx1950_supplicants),
+};
+
+static struct resource power_supply_resources[] = {
+ [0] = {
+ .name = "ac",
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE |
+ IORESOURCE_IRQ_HIGHEDGE,
+ .start = IRQ_EINT2,
+ .end = IRQ_EINT2,
+ },
+};
+
+static struct platform_device power_supply = {
+ .name = "pda-power",
+ .id = -1,
+ .dev = {
+ .platform_data =
+ &power_supply_info,
+ },
+ .resource = power_supply_resources,
+ .num_resources = ARRAY_SIZE(power_supply_resources),
+};
+
+static const struct s3c_adc_bat_thresh bat_lut_noac[] = {
+ { .volt = 4100, .cur = 156, .level = 100},
+ { .volt = 4050, .cur = 156, .level = 95},
+ { .volt = 4025, .cur = 141, .level = 90},
+ { .volt = 3995, .cur = 144, .level = 85},
+ { .volt = 3957, .cur = 162, .level = 80},
+ { .volt = 3931, .cur = 147, .level = 75},
+ { .volt = 3902, .cur = 147, .level = 70},
+ { .volt = 3863, .cur = 153, .level = 65},
+ { .volt = 3838, .cur = 150, .level = 60},
+ { .volt = 3800, .cur = 153, .level = 55},
+ { .volt = 3765, .cur = 153, .level = 50},
+ { .volt = 3748, .cur = 172, .level = 45},
+ { .volt = 3740, .cur = 153, .level = 40},
+ { .volt = 3714, .cur = 175, .level = 35},
+ { .volt = 3710, .cur = 156, .level = 30},
+ { .volt = 3963, .cur = 156, .level = 25},
+ { .volt = 3672, .cur = 178, .level = 20},
+ { .volt = 3651, .cur = 178, .level = 15},
+ { .volt = 3629, .cur = 178, .level = 10},
+ { .volt = 3612, .cur = 162, .level = 5},
+ { .volt = 3605, .cur = 162, .level = 0},
+};
+
+static const struct s3c_adc_bat_thresh bat_lut_acin[] = {
+ { .volt = 4200, .cur = 0, .level = 100},
+ { .volt = 4190, .cur = 0, .level = 99},
+ { .volt = 4178, .cur = 0, .level = 95},
+ { .volt = 4110, .cur = 0, .level = 70},
+ { .volt = 4076, .cur = 0, .level = 65},
+ { .volt = 4046, .cur = 0, .level = 60},
+ { .volt = 4021, .cur = 0, .level = 55},
+ { .volt = 3999, .cur = 0, .level = 50},
+ { .volt = 3982, .cur = 0, .level = 45},
+ { .volt = 3965, .cur = 0, .level = 40},
+ { .volt = 3957, .cur = 0, .level = 35},
+ { .volt = 3948, .cur = 0, .level = 30},
+ { .volt = 3936, .cur = 0, .level = 25},
+ { .volt = 3927, .cur = 0, .level = 20},
+ { .volt = 3906, .cur = 0, .level = 15},
+ { .volt = 3880, .cur = 0, .level = 10},
+ { .volt = 3829, .cur = 0, .level = 5},
+ { .volt = 3820, .cur = 0, .level = 0},
+};
+
+int rx1950_bat_init(void)
+{
+ int ret;
+
+ ret = gpio_request(S3C2410_GPJ(2), "rx1950-charger-enable-1");
+ if (ret)
+ goto err_gpio1;
+ ret = gpio_request(S3C2410_GPJ(3), "rx1950-charger-enable-2");
+ if (ret)
+ goto err_gpio2;
+
+ return 0;
+
+err_gpio2:
+ gpio_free(S3C2410_GPJ(2));
+err_gpio1:
+ return ret;
+}
+
+void rx1950_bat_exit(void)
+{
+ gpio_free(S3C2410_GPJ(2));
+ gpio_free(S3C2410_GPJ(3));
+}
+
+void rx1950_enable_charger(void)
+{
+ gpio_direction_output(S3C2410_GPJ(2), 1);
+ gpio_direction_output(S3C2410_GPJ(3), 1);
+}
+
+void rx1950_disable_charger(void)
+{
+ gpio_direction_output(S3C2410_GPJ(2), 0);
+ gpio_direction_output(S3C2410_GPJ(3), 0);
+}
+
+static struct gpio_led rx1950_leds_desc[] = {
+ {
+ .name = "Green",
+ .default_trigger = "main-battery-charging-or-full",
+ .gpio = S3C2410_GPA(6),
+ },
+ {
+ .name = "Red",
+ .default_trigger = "main-battery-full",
+ .gpio = S3C2410_GPA(7),
+ },
+ {
+ .name = "Blue",
+ .default_trigger = "rx1950-acx-mem",
+ .gpio = S3C2410_GPA(11),
+ },
+};
+
+static struct gpio_led_platform_data rx1950_leds_pdata = {
+ .num_leds = ARRAY_SIZE(rx1950_leds_desc),
+ .leds = rx1950_leds_desc,
+};
+
+static struct platform_device rx1950_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &rx1950_leds_pdata,
+ },
+};
+
+static struct s3c_adc_bat_pdata rx1950_bat_cfg = {
+ .init = rx1950_bat_init,
+ .exit = rx1950_bat_exit,
+ .enable_charger = rx1950_enable_charger,
+ .disable_charger = rx1950_disable_charger,
+ .gpio_charge_finished = S3C2410_GPF(3),
+ .lut_noac = bat_lut_noac,
+ .lut_noac_cnt = ARRAY_SIZE(bat_lut_noac),
+ .lut_acin = bat_lut_acin,
+ .lut_acin_cnt = ARRAY_SIZE(bat_lut_acin),
+ .volt_channel = 0,
+ .current_channel = 1,
+ .volt_mult = 4235,
+ .current_mult = 2900,
+ .internal_impedance = 200,
+};
+
+static struct platform_device rx1950_battery = {
+ .name = "s3c-adc-battery",
+ .id = -1,
+ .dev = {
+ .parent = &s3c_device_adc.dev,
+ .platform_data = &rx1950_bat_cfg,
+ },
+};
+
static struct s3c2410fb_mach_info rx1950_lcd_cfg = {
.displays = &rx1950_display,
.num_displays = 1,
@@ -481,11 +674,17 @@ static struct platform_device rx1950_device_gpiokeys = {
.dev.platform_data = &rx1950_gpio_keys_data,
};
-static struct s3c2410_platform_i2c rx1950_i2c_data = {
- .flags = 0,
- .slave_addr = 0x42,
- .frequency = 400 * 1000,
- .sda_delay = S3C2410_IICLC_SDA_DELAY5 | S3C2410_IICLC_FILTER_ON,
+static struct uda1380_platform_data uda1380_info = {
+ .gpio_power = S3C2410_GPJ(0),
+ .gpio_reset = S3C2410_GPD(0),
+ .dac_clk = UDA1380_DAC_CLK_SYSCLK,
+};
+
+static struct i2c_board_info rx1950_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("uda1380", 0x1a),
+ .platform_data = &uda1380_info,
+ },
};
static struct platform_device *rx1950_devices[] __initdata = {
@@ -493,6 +692,7 @@ static struct platform_device *rx1950_devices[] __initdata = {
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
+ &s3c_device_pcm,
&s3c_device_usbgadget,
&s3c_device_rtc,
&s3c_device_nand,
@@ -503,6 +703,9 @@ static struct platform_device *rx1950_devices[] __initdata = {
&s3c_device_timer[1],
&rx1950_backlight,
&rx1950_device_gpiokeys,
+ &power_supply,
+ &rx1950_battery,
+ &rx1950_leds,
};
static struct clk *rx1950_clocks[] __initdata = {
@@ -538,7 +741,7 @@ static void __init rx1950_init_machine(void)
s3c24xx_udc_set_platdata(&rx1950_udc_cfg);
s3c24xx_ts_set_platdata(&rx1950_ts_cfg);
s3c24xx_mci_set_platdata(&rx1950_mmc_cfg);
- s3c_i2c0_set_platdata(&rx1950_i2c_data);
+ s3c_i2c0_set_platdata(NULL);
s3c_nand_set_platdata(&rx1950_nand_info);
/* Turn off suspend on both USB ports, and switch the
@@ -569,6 +772,9 @@ static void __init rx1950_init_machine(void)
WARN_ON(gpio_request(S3C2410_GPB(1), "LCD power"));
platform_add_devices(rx1950_devices, ARRAY_SIZE(rx1950_devices));
+
+ i2c_register_board_info(0, rx1950_i2c_devices,
+ ARRAY_SIZE(rx1950_i2c_devices));
}
/* H1940 and RX3715 need to reserve this for suspend */
@@ -580,8 +786,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-s3c2440/s3c244x.c b/arch/arm/mach-s3c2440/s3c244x.c
index 5e4a97e76533..90c1707b9c95 100644
--- a/arch/arm/mach-s3c2440/s3c244x.c
+++ b/arch/arm/mach-s3c2440/s3c244x.c
@@ -44,6 +44,7 @@
#include <plat/cpu.h>
#include <plat/pm.h>
#include <plat/pll.h>
+#include <plat/nand-core.h>
static struct map_desc s3c244x_iodesc[] __initdata = {
IODESC_ENT(CLKPWR),
@@ -68,7 +69,7 @@ void __init s3c244x_map_io(void)
s3c_device_sdi.name = "s3c2440-sdi";
s3c_device_i2c0.name = "s3c2440-i2c";
- s3c_device_nand.name = "s3c2440-nand";
+ s3c_nand_setname("s3c2440-nand");
s3c_device_ts.name = "s3c2440-ts";
s3c_device_usbgadget.name = "s3c2440-usbgadget";
}
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-s3c2443/s3c2443.c b/arch/arm/mach-s3c2443/s3c2443.c
index 839b6b2ced74..33d18dd1ebd5 100644
--- a/arch/arm/mach-s3c2443/s3c2443.c
+++ b/arch/arm/mach-s3c2443/s3c2443.c
@@ -36,6 +36,7 @@
#include <plat/devs.h>
#include <plat/cpu.h>
#include <plat/fb-core.h>
+#include <plat/nand-core.h>
static struct map_desc s3c2443_iodesc[] __initdata = {
IODESC_ENT(WATCHDOG),
@@ -62,7 +63,7 @@ int __init s3c2443_init(void)
s3c24xx_reset_hook = s3c2443_hard_reset;
- s3c_device_nand.name = "s3c2412-nand";
+ s3c_nand_setname("s3c2412-nand");
s3c_fb_setname("s3c2443-fb");
/* change WDT IRQ number */
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-s3c24a0/include/mach/vmalloc.h b/arch/arm/mach-s3c24a0/include/mach/vmalloc.h
index 914656820794..6480b15277f3 100644
--- a/arch/arm/mach-s3c24a0/include/mach/vmalloc.h
+++ b/arch/arm/mach-s3c24a0/include/mach/vmalloc.h
@@ -12,6 +12,6 @@
#ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H
-#define VMALLOC_END (0xe0000000UL)
+#define VMALLOC_END 0xF6000000UL
#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig
index 1e4d78af7d84..1ca7bdc6485c 100644
--- a/arch/arm/mach-s3c64xx/Kconfig
+++ b/arch/arm/mach-s3c64xx/Kconfig
@@ -98,12 +98,33 @@ config MACH_ANW6410
help
Machine support for the A&W6410
+config MACH_MINI6410
+ bool "MINI6410"
+ select CPU_S3C6410
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C64XX_SETUP_SDHCI
+ select S3C_DEV_USB_HOST
+ select S3C_DEV_NAND
+ select S3C_DEV_FB
+ select S3C64XX_SETUP_FB_24BPP
+ select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_TS
+ help
+ Machine support for the FriendlyARM MINI6410
+
config MACH_REAL6410
bool "REAL6410"
select CPU_S3C6410
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C64XX_SETUP_SDHCI
+ select S3C_DEV_FB
+ select S3C64XX_SETUP_FB_24BPP
+ select S3C_DEV_NAND
+ select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_TS
+ select S3C_DEV_USB_HOST
help
Machine support for the CoreWind REAL6410
@@ -185,6 +206,7 @@ config SMDK6410_WM1192_EV1
select REGULATOR_WM831X
select S3C24XX_GPIO_EXTRA64
select MFD_WM831X
+ select MFD_WM831X_I2C
help
The Wolfson Microelectronics 1192-EV1 is a WM831x based PMIC
daughtercard for the Samsung SMDK6410 reference platform.
diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile
index 90221a2e0c55..4657363f0674 100644
--- a/arch/arm/mach-s3c64xx/Makefile
+++ b/arch/arm/mach-s3c64xx/Makefile
@@ -53,6 +53,7 @@ obj-$(CONFIG_MACH_ANW6410) += mach-anw6410.o
obj-$(CONFIG_MACH_SMDK6400) += mach-smdk6400.o
obj-$(CONFIG_MACH_SMDK6410) += mach-smdk6410.o
obj-$(CONFIG_MACH_REAL6410) += mach-real6410.o
+obj-$(CONFIG_MACH_MINI6410) += mach-mini6410.o
obj-$(CONFIG_MACH_NCP) += mach-ncp.o
obj-$(CONFIG_MACH_HMT) += mach-hmt.o
obj-$(CONFIG_MACH_SMARTQ) += mach-smartq.o
diff --git a/arch/arm/mach-s3c64xx/dev-audio.c b/arch/arm/mach-s3c64xx/dev-audio.c
index 3838335f125b..76426a32c013 100644
--- a/arch/arm/mach-s3c64xx/dev-audio.c
+++ b/arch/arm/mach-s3c64xx/dev-audio.c
@@ -22,27 +22,16 @@
#include <plat/audio.h>
#include <plat/gpio-cfg.h>
-#include <mach/gpio-bank-c.h>
-#include <mach/gpio-bank-d.h>
-#include <mach/gpio-bank-e.h>
-#include <mach/gpio-bank-h.h>
-
static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev)
{
+ unsigned int base;
+
switch (pdev->id) {
case 0:
- s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_I2S0_CLK);
- s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_I2S0_CDCLK);
- s3c_gpio_cfgpin(S3C64XX_GPD(2), S3C64XX_GPD2_I2S0_LRCLK);
- s3c_gpio_cfgpin(S3C64XX_GPD(3), S3C64XX_GPD3_I2S0_DI);
- s3c_gpio_cfgpin(S3C64XX_GPD(4), S3C64XX_GPD4_I2S0_D0);
+ base = S3C64XX_GPD(0);
break;
case 1:
- s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_I2S1_CLK);
- s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C64XX_GPE1_I2S1_CDCLK);
- s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_I2S1_LRCLK);
- s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_I2S1_DI);
- s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_I2S1_D0);
+ base = S3C64XX_GPE(0);
break;
default:
printk(KERN_DEBUG "Invalid I2S Controller number: %d\n",
@@ -50,18 +39,17 @@ static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev)
return -EINVAL;
}
+ s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(3));
+
return 0;
}
static int s3c64xx_i2sv4_cfg_gpio(struct platform_device *pdev)
{
- s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C64XX_GPC4_I2S_V40_DO0);
- s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C64XX_GPC5_I2S_V40_DO1);
- s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C64XX_GPC7_I2S_V40_DO2);
- s3c_gpio_cfgpin(S3C64XX_GPH(6), S3C64XX_GPH6_I2S_V40_BCLK);
- s3c_gpio_cfgpin(S3C64XX_GPH(7), S3C64XX_GPH7_I2S_V40_CDCLK);
- s3c_gpio_cfgpin(S3C64XX_GPH(8), S3C64XX_GPH8_I2S_V40_LRCLK);
- s3c_gpio_cfgpin(S3C64XX_GPH(9), S3C64XX_GPH9_I2S_V40_DI);
+ s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin_range(S3C64XX_GPH(6), 4, S3C_GPIO_SFN(5));
return 0;
}
@@ -170,20 +158,14 @@ EXPORT_SYMBOL(s3c64xx_device_iisv4);
static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev)
{
+ unsigned int base;
+
switch (pdev->id) {
case 0:
- s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_PCM0_SCLK);
- s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_PCM0_EXTCLK);
- s3c_gpio_cfgpin(S3C64XX_GPD(2), S3C64XX_GPD2_PCM0_FSYNC);
- s3c_gpio_cfgpin(S3C64XX_GPD(3), S3C64XX_GPD3_PCM0_SIN);
- s3c_gpio_cfgpin(S3C64XX_GPD(4), S3C64XX_GPD4_PCM0_SOUT);
+ base = S3C64XX_GPD(0);
break;
case 1:
- s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_PCM1_SCLK);
- s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C64XX_GPE1_PCM1_EXTCLK);
- s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_PCM1_FSYNC);
- s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_PCM1_SIN);
- s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_PCM1_SOUT);
+ base = S3C64XX_GPE(0);
break;
default:
printk(KERN_DEBUG "Invalid PCM Controller number: %d\n",
@@ -191,6 +173,7 @@ static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev)
return -EINVAL;
}
+ s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(2));
return 0;
}
@@ -264,24 +247,12 @@ EXPORT_SYMBOL(s3c64xx_device_pcm1);
static int s3c64xx_ac97_cfg_gpd(struct platform_device *pdev)
{
- s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_AC97_BITCLK);
- s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_AC97_nRESET);
- s3c_gpio_cfgpin(S3C64XX_GPD(2), S3C64XX_GPD2_AC97_SYNC);
- s3c_gpio_cfgpin(S3C64XX_GPD(3), S3C64XX_GPD3_AC97_SDI);
- s3c_gpio_cfgpin(S3C64XX_GPD(4), S3C64XX_GPD4_AC97_SDO);
-
- return 0;
+ return s3c_gpio_cfgpin_range(S3C64XX_GPD(0), 5, S3C_GPIO_SFN(4));
}
static int s3c64xx_ac97_cfg_gpe(struct platform_device *pdev)
{
- s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_AC97_BITCLK);
- s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C64XX_GPE1_AC97_nRESET);
- s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_AC97_SYNC);
- s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_AC97_SDI);
- s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_AC97_SDO);
-
- return 0;
+ return s3c_gpio_cfgpin_range(S3C64XX_GPE(0), 5, S3C_GPIO_SFN(4));
}
static struct resource s3c64xx_ac97_resource[] = {
diff --git a/arch/arm/mach-s3c64xx/gpiolib.c b/arch/arm/mach-s3c64xx/gpiolib.c
index 300dee4a667b..fd99a82e82c4 100644
--- a/arch/arm/mach-s3c64xx/gpiolib.c
+++ b/arch/arm/mach-s3c64xx/gpiolib.c
@@ -195,11 +195,6 @@ static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = {
.get_pull = s3c_gpio_getpull_updown,
};
-int s3c64xx_gpio2int_gpn(struct gpio_chip *chip, unsigned pin)
-{
- return IRQ_EINT(0) + pin;
-}
-
static struct s3c_gpio_chip gpio_2bit[] = {
{
.base = S3C64XX_GPF_BASE,
@@ -227,12 +222,13 @@ static struct s3c_gpio_chip gpio_2bit[] = {
},
}, {
.base = S3C64XX_GPN_BASE,
+ .irq_base = IRQ_EINT(0),
.config = &gpio_2bit_cfg_eint10,
.chip = {
.base = S3C64XX_GPN(0),
.ngpio = S3C64XX_GPIO_N_NR,
.label = "GPN",
- .to_irq = s3c64xx_gpio2int_gpn,
+ .to_irq = samsung_gpiolib_to_irq,
},
}, {
.base = S3C64XX_GPO_BASE,
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/include/mach/vmalloc.h b/arch/arm/mach-s3c64xx/include/mach/vmalloc.h
index bc0e91389864..23f75e556a30 100644
--- a/arch/arm/mach-s3c64xx/include/mach/vmalloc.h
+++ b/arch/arm/mach-s3c64xx/include/mach/vmalloc.h
@@ -15,6 +15,6 @@
#ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H
-#define VMALLOC_END 0xE0000000UL
+#define VMALLOC_END 0xF6000000UL
#endif /* __ASM_ARCH_VMALLOC_H */
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-mini6410.c b/arch/arm/mach-s3c64xx/mach-mini6410.c
new file mode 100644
index 000000000000..249c62956471
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-mini6410.c
@@ -0,0 +1,357 @@
+/* linux/arch/arm/mach-s3c64xx/mach-mini6410.c
+ *
+ * Copyright 2010 Darius Augulis <augulis.darius@gmail.com>
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * 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/interrupt.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/dm9000.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/serial_core.h>
+#include <linux/types.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/map.h>
+#include <mach/regs-fb.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-modem.h>
+#include <mach/regs-srom.h>
+#include <mach/s3c6410.h>
+
+#include <plat/adc.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/fb.h>
+#include <plat/nand.h>
+#include <plat/regs-serial.h>
+#include <plat/ts.h>
+
+#include <video/platform_lcd.h>
+
+#define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK)
+#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
+#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
+
+static struct s3c2410_uartcfg mini6410_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+};
+
+/* DM9000AEP 10/100 ethernet controller */
+
+static struct resource mini6410_dm9k_resource[] = {
+ [0] = {
+ .start = S3C64XX_PA_XM0CSN1,
+ .end = S3C64XX_PA_XM0CSN1 + 1,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = S3C64XX_PA_XM0CSN1 + 4,
+ .end = S3C64XX_PA_XM0CSN1 + 5,
+ .flags = IORESOURCE_MEM
+ },
+ [2] = {
+ .start = S3C_EINT(7),
+ .end = S3C_EINT(7),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL
+ }
+};
+
+static struct dm9000_plat_data mini6410_dm9k_pdata = {
+ .flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
+};
+
+static struct platform_device mini6410_device_eth = {
+ .name = "dm9000",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(mini6410_dm9k_resource),
+ .resource = mini6410_dm9k_resource,
+ .dev = {
+ .platform_data = &mini6410_dm9k_pdata,
+ },
+};
+
+static struct mtd_partition mini6410_nand_part[] = {
+ [0] = {
+ .name = "uboot",
+ .size = SZ_1M,
+ .offset = 0,
+ },
+ [1] = {
+ .name = "kernel",
+ .size = SZ_2M,
+ .offset = SZ_1M,
+ },
+ [2] = {
+ .name = "rootfs",
+ .size = MTDPART_SIZ_FULL,
+ .offset = SZ_1M + SZ_2M,
+ },
+};
+
+static struct s3c2410_nand_set mini6410_nand_sets[] = {
+ [0] = {
+ .name = "nand",
+ .nr_chips = 1,
+ .nr_partitions = ARRAY_SIZE(mini6410_nand_part),
+ .partitions = mini6410_nand_part,
+ },
+};
+
+static struct s3c2410_platform_nand mini6410_nand_info = {
+ .tacls = 25,
+ .twrph0 = 55,
+ .twrph1 = 40,
+ .nr_sets = ARRAY_SIZE(mini6410_nand_sets),
+ .sets = mini6410_nand_sets,
+};
+
+static struct s3c_fb_pd_win mini6410_fb_win[] = {
+ {
+ .win_mode = { /* 4.3" 480x272 */
+ .left_margin = 3,
+ .right_margin = 2,
+ .upper_margin = 1,
+ .lower_margin = 1,
+ .hsync_len = 40,
+ .vsync_len = 1,
+ .xres = 480,
+ .yres = 272,
+ },
+ .max_bpp = 32,
+ .default_bpp = 16,
+ }, {
+ .win_mode = { /* 7.0" 800x480 */
+ .left_margin = 8,
+ .right_margin = 13,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .max_bpp = 32,
+ .default_bpp = 16,
+ },
+};
+
+static struct s3c_fb_platdata mini6410_lcd_pdata __initdata = {
+ .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
+ .win[0] = &mini6410_fb_win[0],
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+};
+
+static void mini6410_lcd_power_set(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (power)
+ gpio_direction_output(S3C64XX_GPE(0), 1);
+ else
+ gpio_direction_output(S3C64XX_GPE(0), 0);
+}
+
+static struct plat_lcd_data mini6410_lcd_power_data = {
+ .set_power = mini6410_lcd_power_set,
+};
+
+static struct platform_device mini6410_lcd_powerdev = {
+ .name = "platform-lcd",
+ .dev.parent = &s3c_device_fb.dev,
+ .dev.platform_data = &mini6410_lcd_power_data,
+};
+
+static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
+ .delay = 10000,
+ .presc = 49,
+ .oversampling_shift = 2,
+};
+
+static struct platform_device *mini6410_devices[] __initdata = {
+ &mini6410_device_eth,
+ &s3c_device_hsmmc0,
+ &s3c_device_hsmmc1,
+ &s3c_device_ohci,
+ &s3c_device_nand,
+ &s3c_device_fb,
+ &mini6410_lcd_powerdev,
+ &s3c_device_adc,
+ &s3c_device_ts,
+};
+
+static void __init mini6410_map_io(void)
+{
+ u32 tmp;
+
+ s3c64xx_init_io(NULL, 0);
+ s3c24xx_init_clocks(12000000);
+ s3c24xx_init_uarts(mini6410_uartcfgs, ARRAY_SIZE(mini6410_uartcfgs));
+
+ /* set the LCD type */
+ tmp = __raw_readl(S3C64XX_SPCON);
+ tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
+ tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
+ __raw_writel(tmp, S3C64XX_SPCON);
+
+ /* remove the LCD bypass */
+ tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
+ tmp &= ~MIFPCON_LCD_BYPASS;
+ __raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
+}
+
+/*
+ * mini6410_features string
+ *
+ * 0-9 LCD configuration
+ *
+ */
+static char mini6410_features_str[12] __initdata = "0";
+
+static int __init mini6410_features_setup(char *str)
+{
+ if (str)
+ strlcpy(mini6410_features_str, str,
+ sizeof(mini6410_features_str));
+ return 1;
+}
+
+__setup("mini6410=", mini6410_features_setup);
+
+#define FEATURE_SCREEN (1 << 0)
+
+struct mini6410_features_t {
+ int done;
+ int lcd_index;
+};
+
+static void mini6410_parse_features(
+ struct mini6410_features_t *features,
+ const char *features_str)
+{
+ const char *fp = features_str;
+
+ features->done = 0;
+ features->lcd_index = 0;
+
+ while (*fp) {
+ char f = *fp++;
+
+ switch (f) {
+ case '0'...'9': /* tft screen */
+ if (features->done & FEATURE_SCREEN) {
+ printk(KERN_INFO "MINI6410: '%c' ignored, "
+ "screen type already set\n", f);
+ } else {
+ int li = f - '0';
+ if (li >= ARRAY_SIZE(mini6410_fb_win))
+ printk(KERN_INFO "MINI6410: '%c' out "
+ "of range LCD mode\n", f);
+ else {
+ features->lcd_index = li;
+ }
+ }
+ features->done |= FEATURE_SCREEN;
+ break;
+ }
+ }
+}
+
+static void __init mini6410_machine_init(void)
+{
+ u32 cs1;
+ struct mini6410_features_t features = { 0 };
+
+ printk(KERN_INFO "MINI6410: Option string mini6410=%s\n",
+ mini6410_features_str);
+
+ /* Parse the feature string */
+ mini6410_parse_features(&features, mini6410_features_str);
+
+ mini6410_lcd_pdata.win[0] = &mini6410_fb_win[features.lcd_index];
+
+ printk(KERN_INFO "MINI6410: selected LCD display is %dx%d\n",
+ mini6410_lcd_pdata.win[0]->win_mode.xres,
+ mini6410_lcd_pdata.win[0]->win_mode.yres);
+
+ s3c_nand_set_platdata(&mini6410_nand_info);
+ s3c_fb_set_platdata(&mini6410_lcd_pdata);
+ s3c24xx_ts_set_platdata(&s3c_ts_platform);
+
+ /* configure nCS1 width to 16 bits */
+
+ cs1 = __raw_readl(S3C64XX_SROM_BW) &
+ ~(S3C64XX_SROM_BW__CS_MASK << S3C64XX_SROM_BW__NCS1__SHIFT);
+ cs1 |= ((1 << S3C64XX_SROM_BW__DATAWIDTH__SHIFT) |
+ (1 << S3C64XX_SROM_BW__WAITENABLE__SHIFT) |
+ (1 << S3C64XX_SROM_BW__BYTEENABLE__SHIFT)) <<
+ S3C64XX_SROM_BW__NCS1__SHIFT;
+ __raw_writel(cs1, S3C64XX_SROM_BW);
+
+ /* set timing for nCS1 suitable for ethernet chip */
+
+ __raw_writel((0 << S3C64XX_SROM_BCX__PMC__SHIFT) |
+ (6 << S3C64XX_SROM_BCX__TACP__SHIFT) |
+ (4 << S3C64XX_SROM_BCX__TCAH__SHIFT) |
+ (1 << S3C64XX_SROM_BCX__TCOH__SHIFT) |
+ (13 << S3C64XX_SROM_BCX__TACC__SHIFT) |
+ (4 << S3C64XX_SROM_BCX__TCOS__SHIFT) |
+ (0 << S3C64XX_SROM_BCX__TACS__SHIFT), S3C64XX_SROM_BC1);
+
+ gpio_request(S3C64XX_GPF(15), "LCD power");
+ gpio_request(S3C64XX_GPE(0), "LCD power");
+
+ platform_add_devices(mini6410_devices, ARRAY_SIZE(mini6410_devices));
+}
+
+MACHINE_START(MINI6410, "MINI6410")
+ /* Maintainer: Darius Augulis <augulis.darius@gmail.com> */
+ .boot_params = S3C64XX_PA_SDRAM + 0x100,
+ .init_irq = s3c6410_init_irq,
+ .map_io = mini6410_map_io,
+ .init_machine = mini6410_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
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..f9ef9b5c5f5a 100644
--- a/arch/arm/mach-s3c64xx/mach-real6410.c
+++ b/arch/arm/mach-s3c64xx/mach-real6410.c
@@ -12,23 +12,39 @@
*
*/
-#include <linux/kernel.h>
-#include <linux/types.h>
+#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
#include <linux/list.h>
-#include <linux/init.h>
#include <linux/dm9000.h>
-#include <linux/serial_core.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/types.h>
+
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
+
#include <mach/map.h>
-#include <mach/s3c6410.h>
+#include <mach/regs-fb.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-modem.h>
#include <mach/regs-srom.h>
+#include <mach/s3c6410.h>
+
+#include <plat/adc.h>
#include <plat/cpu.h>
#include <plat/devs.h>
+#include <plat/fb.h>
+#include <plat/nand.h>
#include <plat/regs-serial.h>
+#include <plat/ts.h>
+
+#include <video/platform_lcd.h>
#define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK)
#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
@@ -99,22 +115,192 @@ static struct platform_device real6410_device_eth = {
},
};
+static struct s3c_fb_pd_win real6410_fb_win[] = {
+ {
+ .win_mode = { /* 4.3" 480x272 */
+ .left_margin = 3,
+ .right_margin = 2,
+ .upper_margin = 1,
+ .lower_margin = 1,
+ .hsync_len = 40,
+ .vsync_len = 1,
+ .xres = 480,
+ .yres = 272,
+ },
+ .max_bpp = 32,
+ .default_bpp = 16,
+ }, {
+ .win_mode = { /* 7.0" 800x480 */
+ .left_margin = 8,
+ .right_margin = 13,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .max_bpp = 32,
+ .default_bpp = 16,
+ },
+};
+
+static struct s3c_fb_platdata real6410_lcd_pdata __initdata = {
+ .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
+ .win[0] = &real6410_fb_win[0],
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+};
+
+static struct mtd_partition real6410_nand_part[] = {
+ [0] = {
+ .name = "uboot",
+ .size = SZ_1M,
+ .offset = 0,
+ },
+ [1] = {
+ .name = "kernel",
+ .size = SZ_2M,
+ .offset = SZ_1M,
+ },
+ [2] = {
+ .name = "rootfs",
+ .size = MTDPART_SIZ_FULL,
+ .offset = SZ_1M + SZ_2M,
+ },
+};
+
+static struct s3c2410_nand_set real6410_nand_sets[] = {
+ [0] = {
+ .name = "nand",
+ .nr_chips = 1,
+ .nr_partitions = ARRAY_SIZE(real6410_nand_part),
+ .partitions = real6410_nand_part,
+ },
+};
+
+static struct s3c2410_platform_nand real6410_nand_info = {
+ .tacls = 25,
+ .twrph0 = 55,
+ .twrph1 = 40,
+ .nr_sets = ARRAY_SIZE(real6410_nand_sets),
+ .sets = real6410_nand_sets,
+};
+
static struct platform_device *real6410_devices[] __initdata = {
&real6410_device_eth,
&s3c_device_hsmmc0,
&s3c_device_hsmmc1,
+ &s3c_device_fb,
+ &s3c_device_nand,
+ &s3c_device_adc,
+ &s3c_device_ts,
+ &s3c_device_ohci,
+};
+
+static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
+ .delay = 10000,
+ .presc = 49,
+ .oversampling_shift = 2,
};
static void __init real6410_map_io(void)
{
+ u32 tmp;
+
s3c64xx_init_io(NULL, 0);
s3c24xx_init_clocks(12000000);
s3c24xx_init_uarts(real6410_uartcfgs, ARRAY_SIZE(real6410_uartcfgs));
+
+ /* set the LCD type */
+ tmp = __raw_readl(S3C64XX_SPCON);
+ tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
+ tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
+ __raw_writel(tmp, S3C64XX_SPCON);
+
+ /* remove the LCD bypass */
+ tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
+ tmp &= ~MIFPCON_LCD_BYPASS;
+ __raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
+}
+
+/*
+ * real6410_features string
+ *
+ * 0-9 LCD configuration
+ *
+ */
+static char real6410_features_str[12] __initdata = "0";
+
+static int __init real6410_features_setup(char *str)
+{
+ if (str)
+ strlcpy(real6410_features_str, str,
+ sizeof(real6410_features_str));
+ return 1;
+}
+
+__setup("real6410=", real6410_features_setup);
+
+#define FEATURE_SCREEN (1 << 0)
+
+struct real6410_features_t {
+ int done;
+ int lcd_index;
+};
+
+static void real6410_parse_features(
+ struct real6410_features_t *features,
+ const char *features_str)
+{
+ const char *fp = features_str;
+
+ features->done = 0;
+ features->lcd_index = 0;
+
+ while (*fp) {
+ char f = *fp++;
+
+ switch (f) {
+ case '0'...'9': /* tft screen */
+ if (features->done & FEATURE_SCREEN) {
+ printk(KERN_INFO "REAL6410: '%c' ignored, "
+ "screen type already set\n", f);
+ } else {
+ int li = f - '0';
+ if (li >= ARRAY_SIZE(real6410_fb_win))
+ printk(KERN_INFO "REAL6410: '%c' out "
+ "of range LCD mode\n", f);
+ else {
+ features->lcd_index = li;
+ }
+ }
+ features->done |= FEATURE_SCREEN;
+ break;
+ }
+ }
}
static void __init real6410_machine_init(void)
{
u32 cs1;
+ struct real6410_features_t features = { 0 };
+
+ printk(KERN_INFO "REAL6410: Option string real6410=%s\n",
+ real6410_features_str);
+
+ /* Parse the feature string */
+ real6410_parse_features(&features, real6410_features_str);
+
+ real6410_lcd_pdata.win[0] = &real6410_fb_win[features.lcd_index];
+
+ printk(KERN_INFO "REAL6410: selected LCD display is %dx%d\n",
+ real6410_lcd_pdata.win[0]->win_mode.xres,
+ real6410_lcd_pdata.win[0]->win_mode.yres);
+
+ s3c_fb_set_platdata(&real6410_lcd_pdata);
+ s3c_nand_set_platdata(&real6410_nand_info);
+ s3c24xx_ts_set_platdata(&s3c_ts_platform);
/* configure nCS1 width to 16 bits */
@@ -136,13 +322,13 @@ static void __init real6410_machine_init(void)
(4 << S3C64XX_SROM_BCX__TCOS__SHIFT) |
(0 << S3C64XX_SROM_BCX__TACS__SHIFT), S3C64XX_SROM_BC1);
+ gpio_request(S3C64XX_GPF(15), "LCD power");
+
platform_add_devices(real6410_devices, ARRAY_SIZE(real6410_devices));
}
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 ecbddd377cb8..77488facfe4c 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -705,8 +705,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-s3c64xx/setup-fb-24bpp.c b/arch/arm/mach-s3c64xx/setup-fb-24bpp.c
index 000736877df2..8f3091182f9c 100644
--- a/arch/arm/mach-s3c64xx/setup-fb-24bpp.c
+++ b/arch/arm/mach-s3c64xx/setup-fb-24bpp.c
@@ -23,15 +23,6 @@
extern void s3c64xx_fb_gpio_setup_24bpp(void)
{
- unsigned int gpio;
-
- for (gpio = S3C64XX_GPI(0); gpio <= S3C64XX_GPI(15); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
-
- for (gpio = S3C64XX_GPJ(0); gpio <= S3C64XX_GPJ(11); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
+ s3c_gpio_cfgrange_nopull(S3C64XX_GPI(0), 16, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgrange_nopull(S3C64XX_GPJ(0), 12, S3C_GPIO_SFN(2));
}
diff --git a/arch/arm/mach-s3c64xx/setup-ide.c b/arch/arm/mach-s3c64xx/setup-ide.c
index c12c315f33bc..41b425602d88 100644
--- a/arch/arm/mach-s3c64xx/setup-ide.c
+++ b/arch/arm/mach-s3c64xx/setup-ide.c
@@ -17,11 +17,11 @@
#include <mach/map.h>
#include <mach/regs-clock.h>
#include <plat/gpio-cfg.h>
+#include <plat/ata.h>
void s3c64xx_ide_setup_gpio(void)
{
u32 reg;
- u32 gpio = 0;
reg = readl(S3C_MEM_SYS_CFG) & (~0x3f);
@@ -32,15 +32,12 @@ void s3c64xx_ide_setup_gpio(void)
s3c_gpio_cfgpin(S3C64XX_GPB(4), S3C_GPIO_SFN(4));
/* Set XhiDATA[15:0] pins as CF Data[15:0] */
- for (gpio = S3C64XX_GPK(0); gpio <= S3C64XX_GPK(15); gpio++)
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin_range(S3C64XX_GPK(0), 16, S3C_GPIO_SFN(5));
/* Set XhiADDR[2:0] pins as CF ADDR[2:0] */
- for (gpio = S3C64XX_GPL(0); gpio <= S3C64XX_GPL(2); gpio++)
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(6));
+ s3c_gpio_cfgpin_range(S3C64XX_GPL(0), 3, S3C_GPIO_SFN(6));
/* Set Xhi ctrl pins as CF ctrl pins(IORDY, IOWR, IORD, CE[0:1]) */
s3c_gpio_cfgpin(S3C64XX_GPM(5), S3C_GPIO_SFN(1));
- for (gpio = S3C64XX_GPM(0); gpio <= S3C64XX_GPM(4); gpio++)
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(6));
+ s3c_gpio_cfgpin_range(S3C64XX_GPM(0), 5, S3C_GPIO_SFN(6));
}
diff --git a/arch/arm/mach-s3c64xx/setup-keypad.c b/arch/arm/mach-s3c64xx/setup-keypad.c
index abc34e4e1a93..f8ed0d22db70 100644
--- a/arch/arm/mach-s3c64xx/setup-keypad.c
+++ b/arch/arm/mach-s3c64xx/setup-keypad.c
@@ -12,23 +12,13 @@
#include <linux/gpio.h>
#include <plat/gpio-cfg.h>
+#include <plat/keypad.h>
void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols)
{
- unsigned int gpio;
- unsigned int end;
-
/* Set all the necessary GPK pins to special-function 3: KP_ROW[x] */
- end = S3C64XX_GPK(8 + rows);
- for (gpio = S3C64XX_GPK(8); gpio < end; gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
+ s3c_gpio_cfgrange_nopull(S3C64XX_GPK(8), 8 + rows, S3C_GPIO_SFN(3));
/* Set all the necessary GPL pins to special-function 3: KP_COL[x] */
- end = S3C64XX_GPL(0 + cols);
- for (gpio = S3C64XX_GPL(0); gpio < end; gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
+ s3c_gpio_cfgrange_nopull(S3C64XX_GPL(0), cols, S3C_GPIO_SFN(3));
}
diff --git a/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c b/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c
index 322359591374..6eac071afae2 100644
--- a/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c
+++ b/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c
@@ -24,16 +24,9 @@
void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
{
struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
- unsigned int gpio;
- unsigned int end;
- end = S3C64XX_GPG(2 + width);
-
- /* Set all the necessary GPG pins to special-function 0 */
- for (gpio = S3C64XX_GPG(0); gpio < end; gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
+ /* Set all the necessary GPG pins to special-function 2 */
+ s3c_gpio_cfgrange_nopull(S3C64XX_GPG(0), 2 + width, S3C_GPIO_SFN(2));
if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP);
@@ -44,16 +37,9 @@ void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
{
struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
- unsigned int gpio;
- unsigned int end;
- end = S3C64XX_GPH(2 + width);
-
- /* Set all the necessary GPG pins to special-function 0 */
- for (gpio = S3C64XX_GPH(0); gpio < end; gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
+ /* Set all the necessary GPH pins to special-function 2 */
+ s3c_gpio_cfgrange_nopull(S3C64XX_GPH(0), 2 + width, S3C_GPIO_SFN(2));
if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP);
@@ -63,20 +49,9 @@ void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
void s3c64xx_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
{
- unsigned int gpio;
- unsigned int end;
+ /* Set all the necessary GPH pins to special-function 3 */
+ s3c_gpio_cfgrange_nopull(S3C64XX_GPH(6), width, S3C_GPIO_SFN(3));
- end = S3C64XX_GPH(6 + width);
-
- /* Set all the necessary GPH pins to special-function 1 */
- for (gpio = S3C64XX_GPH(6); gpio < end; gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
-
- /* Set all the necessary GPC pins to special-function 1 */
- for (gpio = S3C64XX_GPC(4); gpio < S3C64XX_GPC(6); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
+ /* Set all the necessary GPC pins to special-function 3 */
+ s3c_gpio_cfgrange_nopull(S3C64XX_GPC(4), 2, S3C_GPIO_SFN(3));
}
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 ec592e866054..000000000000
--- a/arch/arm/mach-s5p6440/cpu.c
+++ /dev/null
@@ -1,117 +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 <linux/sched.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-s5p6440/setup-i2c0.c b/arch/arm/mach-s5p6440/setup-i2c0.c
deleted file mode 100644
index 2c99d14f7ac7..000000000000
--- a/arch/arm/mach-s5p6440/setup-i2c0.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/* linux/arch/arm/mach-s5p6440/setup-i2c0.c
- *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * I2C0 GPIO configuration.
- *
- * Based on plat-s3c64xx/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
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.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)
-{
- 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);
-}
diff --git a/arch/arm/mach-s5p6440/setup-i2c1.c b/arch/arm/mach-s5p6440/setup-i2c1.c
deleted file mode 100644
index 9a1537f786e0..000000000000
--- a/arch/arm/mach-s5p6440/setup-i2c1.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/* linux/arch/arm/mach-s5p6440/setup-i2c1.c
- *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * I2C1 GPIO configuration.
- *
- * Based on plat-s3c64xx/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
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/gpio.h>
-
-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)
-{
- 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);
-}
diff --git a/arch/arm/mach-s5p6442/Kconfig b/arch/arm/mach-s5p6442/Kconfig
index 0fda0a5df968..33569e4007c4 100644
--- a/arch/arm/mach-s5p6442/Kconfig
+++ b/arch/arm/mach-s5p6442/Kconfig
@@ -11,7 +11,6 @@ if ARCH_S5P6442
config CPU_S5P6442
bool
- select PLAT_S5P
select S3C_PL330_DMA
help
Enable S5P6442 CPU support
diff --git a/arch/arm/mach-s5p6442/clock.c b/arch/arm/mach-s5p6442/clock.c
index dcd20f17212a..16d6e7e61b50 100644
--- a/arch/arm/mach-s5p6442/clock.c
+++ b/arch/arm/mach-s5p6442/clock.c
@@ -192,6 +192,11 @@ static struct clk clk_pclkd1 = {
.parent = &clk_hclkd1,
};
+int s5p6442_clk_ip0_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_IP0, clk, enable);
+}
+
int s5p6442_clk_ip3_ctrl(struct clk *clk, int enable)
{
return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable);
@@ -335,6 +340,16 @@ void __init_or_cpufreq s5p6442_setup_clocks(void)
clk_pclkd1.rate = pclkd1;
}
+static struct clk init_clocks_disable[] = {
+ {
+ .name = "pdma",
+ .id = -1,
+ .parent = &clk_pclkd1,
+ .enable = s5p6442_clk_ip0_ctrl,
+ .ctrlbit = (1 << 3),
+ },
+};
+
static struct clk init_clocks[] = {
{
.name = "systimer",
@@ -393,10 +408,23 @@ static struct clk *clks[] __initdata = {
void __init s5p6442_register_clocks(void)
{
+ struct clk *clkptr;
+ int i, ret;
+
s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
+ clkptr = init_clocks_disable;
+ for (i = 0; i < ARRAY_SIZE(init_clocks_disable); i++, clkptr++) {
+ ret = s3c24xx_register_clock(clkptr);
+ if (ret < 0) {
+ printk(KERN_ERR "Fail to register clock %s (%d)\n",
+ clkptr->name, ret);
+ } else
+ (clkptr->enable)(clkptr, 0);
+ }
+
s3c_pwmclk_init();
}
diff --git a/arch/arm/mach-s5p6442/cpu.c b/arch/arm/mach-s5p6442/cpu.c
index 70ac681af72b..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
@@ -48,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,
}
};
@@ -63,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/dev-audio.c b/arch/arm/mach-s5p6442/dev-audio.c
index 7a4e34720b7b..3462197ff352 100644
--- a/arch/arm/mach-s5p6442/dev-audio.c
+++ b/arch/arm/mach-s5p6442/dev-audio.c
@@ -21,22 +21,16 @@
static int s5p6442_cfg_i2s(struct platform_device *pdev)
{
+ unsigned int base;
+
/* configure GPIO for i2s port */
switch (pdev->id) {
case 1:
- s3c_gpio_cfgpin(S5P6442_GPC1(0), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5P6442_GPC1(1), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5P6442_GPC1(2), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5P6442_GPC1(3), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5P6442_GPC1(4), S3C_GPIO_SFN(2));
+ base = S5P6442_GPC1(0);
break;
case -1:
- s3c_gpio_cfgpin(S5P6442_GPC0(0), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5P6442_GPC0(1), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5P6442_GPC0(2), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5P6442_GPC0(3), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5P6442_GPC0(4), S3C_GPIO_SFN(2));
+ base = S5P6442_GPC0(0);
break;
default:
@@ -44,6 +38,7 @@ static int s5p6442_cfg_i2s(struct platform_device *pdev)
return -EINVAL;
}
+ s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(2));
return 0;
}
@@ -111,21 +106,15 @@ struct platform_device s5p6442_device_iis1 = {
static int s5p6442_pcm_cfg_gpio(struct platform_device *pdev)
{
+ unsigned int base;
+
switch (pdev->id) {
case 0:
- s3c_gpio_cfgpin(S5P6442_GPC0(0), S3C_GPIO_SFN(3));
- s3c_gpio_cfgpin(S5P6442_GPC0(1), S3C_GPIO_SFN(3));
- s3c_gpio_cfgpin(S5P6442_GPC0(2), S3C_GPIO_SFN(3));
- s3c_gpio_cfgpin(S5P6442_GPC0(3), S3C_GPIO_SFN(3));
- s3c_gpio_cfgpin(S5P6442_GPC0(4), S3C_GPIO_SFN(3));
+ base = S5P6442_GPC0(0);
break;
case 1:
- s3c_gpio_cfgpin(S5P6442_GPC1(0), S3C_GPIO_SFN(3));
- s3c_gpio_cfgpin(S5P6442_GPC1(1), S3C_GPIO_SFN(3));
- s3c_gpio_cfgpin(S5P6442_GPC1(2), S3C_GPIO_SFN(3));
- s3c_gpio_cfgpin(S5P6442_GPC1(3), S3C_GPIO_SFN(3));
- s3c_gpio_cfgpin(S5P6442_GPC1(4), S3C_GPIO_SFN(3));
+ base = S5P6442_GPC1(0);
break;
default:
@@ -133,6 +122,7 @@ static int s5p6442_pcm_cfg_gpio(struct platform_device *pdev)
return -EINVAL;
}
+ s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(3));
return 0;
}
diff --git a/arch/arm/mach-s5p6442/dev-spi.c b/arch/arm/mach-s5p6442/dev-spi.c
index e894651a88bd..cce8c2470709 100644
--- a/arch/arm/mach-s5p6442/dev-spi.c
+++ b/arch/arm/mach-s5p6442/dev-spi.c
@@ -38,11 +38,9 @@ static int s5p6442_spi_cfg_gpio(struct platform_device *pdev)
switch (pdev->id) {
case 0:
s3c_gpio_cfgpin(S5P6442_GPB(0), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5P6442_GPB(2), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5P6442_GPB(3), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5P6442_GPB(0), S3C_GPIO_PULL_UP);
- s3c_gpio_setpull(S5P6442_GPB(2), S3C_GPIO_PULL_UP);
- s3c_gpio_setpull(S5P6442_GPB(3), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgall_range(S5P6442_GPB(2), 2,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
break;
default:
diff --git a/arch/arm/mach-s5p6442/dma.c b/arch/arm/mach-s5p6442/dma.c
index ad4f8704b93d..7dfb13654f8a 100644
--- a/arch/arm/mach-s5p6442/dma.c
+++ b/arch/arm/mach-s5p6442/dma.c
@@ -82,7 +82,7 @@ static struct s3c_pl330_platdata s5p6442_pdma_pdata = {
static struct platform_device s5p6442_device_pdma = {
.name = "s3c-pl330",
- .id = 1,
+ .id = -1,
.num_resources = ARRAY_SIZE(s5p6442_pdma_resource),
.resource = s5p6442_pdma_resource,
.dev = {
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/include/mach/regs-clock.h b/arch/arm/mach-s5p6442/include/mach/regs-clock.h
index d8360b5d4ece..00828a336991 100644
--- a/arch/arm/mach-s5p6442/include/mach/regs-clock.h
+++ b/arch/arm/mach-s5p6442/include/mach/regs-clock.h
@@ -46,6 +46,7 @@
#define S5P_CLK_DIV5 S5P_CLKREG(0x314)
#define S5P_CLK_DIV6 S5P_CLKREG(0x318)
+#define S5P_CLKGATE_IP0 S5P_CLKREG(0x460)
#define S5P_CLKGATE_IP3 S5P_CLKREG(0x46C)
/* CLK_OUT */
diff --git a/arch/arm/mach-s5p6442/include/mach/vmalloc.h b/arch/arm/mach-s5p6442/include/mach/vmalloc.h
index f5c83f02c18e..4aa55e55ac47 100644
--- a/arch/arm/mach-s5p6442/include/mach/vmalloc.h
+++ b/arch/arm/mach-s5p6442/include/mach/vmalloc.h
@@ -12,6 +12,6 @@
#ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H
-#define VMALLOC_END 0xE0000000UL
+#define VMALLOC_END 0xF6000000UL
#endif /* __ASM_ARCH_VMALLOC_H */
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..164d2783d381
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/Kconfig
@@ -0,0 +1,55 @@
+# 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 S3C_PL330_DMA
+ help
+ Enable S5P6440 CPU support
+
+config CPU_S5P6450
+ bool
+ 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..e4883dc1c8d7
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c
@@ -0,0 +1,629 @@
+/* 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);
+
+ printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
+ clk->rate, rate);
+
+ clk->rate = rate;
+
+ return 0;
+}
+
+static struct clk_ops s5p6440_epll_ops = {
+ .get_rate = s5p_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 = "pdma",
+ .id = -1,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 12),
+ }, {
+ .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 = "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 = s5p_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..7dbf3c968f53
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c
@@ -0,0 +1,658 @@
+/* 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);
+
+ printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
+ clk->rate, rate);
+
+ clk->rate = rate;
+
+ return 0;
+}
+
+static struct clk_ops s5p6450_epll_ops = {
+ .get_rate = s5p_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 = "pdma",
+ .id = -1,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 12),
+ }, {
+ .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 = "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 = s5p_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..b52c6e2f37a6
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/clock.c
@@ -0,0 +1,235 @@
+/* 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)},
+};
+
+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..396bacc0a39a
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/dev-audio.c
@@ -0,0 +1,152 @@
+/* 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_range(S5P6440_GPR(4), 5, S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin_range(S5P6440_GPR(13), 2, 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_range(S5P6450_GPR(4), 5, S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin_range(S5P6450_GPR(13), 2, 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_range(S5P6440_GPR(6), 3, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin_range(S5P6440_GPR(13), 2, 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..e78ee18c76e3
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/dev-spi.c
@@ -0,0 +1,222 @@
+/* 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)
+{
+ unsigned int base;
+
+ switch (pdev->id) {
+ case 0:
+ base = S5P6440_GPC(0);
+ break;
+
+ case 1:
+ base = S5P6440_GPC(4);
+ break;
+
+ default:
+ dev_err(&pdev->dev, "Invalid SPI Controller number!");
+ return -EINVAL;
+ }
+
+ s3c_gpio_cfgall_range(base, 3,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+
+ return 0;
+}
+
+static int s5p6450_spi_cfg_gpio(struct platform_device *pdev)
+{
+ unsigned int base;
+
+ switch (pdev->id) {
+ case 0:
+ base = S5P6450_GPC(0);
+ break;
+
+ case 1:
+ base = S5P6450_GPC(4);
+ break;
+
+ default:
+ dev_err(&pdev->dev, "Invalid SPI Controller number!");
+ return -EINVAL;
+ }
+
+ s3c_gpio_cfgall_range(base, 3,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+
+ 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..d7ad944b3475 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 = -1,
+ .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..a133f22fa155
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/regs-clock.h
@@ -0,0 +1,65 @@
+/* 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)
+
+#define S5P_EPLL_CON S5P64X0_EPLL_CON
+
+#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..38dcc71a03cc 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>
*
@@ -12,6 +15,6 @@
#ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H
-#define VMALLOC_END 0xE0000000UL
+#define VMALLOC_END 0xF6000000UL
#endif /* __ASM_ARCH_VMALLOC_H */
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-s5p64x0/setup-i2c0.c b/arch/arm/mach-s5p64x0/setup-i2c0.c
new file mode 100644
index 000000000000..46b463917c54
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/setup-i2c0.c
@@ -0,0 +1,38 @@
+/* linux/arch/arm/mach-s5p64x0/setup-i2c0.c
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * I2C0 GPIO configuration.
+ *
+ * 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
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/gpio.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <plat/gpio-cfg.h>
+#include <plat/iic.h>
+
+#include <mach/i2c.h>
+
+void s5p6440_i2c0_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgall_range(S5P6440_GPB(5), 2,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+}
+
+void s5p6450_i2c0_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgall_range(S5P6450_GPB(5), 2,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+}
+
+void s3c_i2c0_cfg_gpio(struct platform_device *dev) { }
diff --git a/arch/arm/mach-s5p64x0/setup-i2c1.c b/arch/arm/mach-s5p64x0/setup-i2c1.c
new file mode 100644
index 000000000000..6ad3b986021c
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/setup-i2c1.c
@@ -0,0 +1,38 @@
+/* linux/arch/arm/mach-s5p64xx/setup-i2c1.c
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * I2C1 GPIO configuration.
+ *
+ * Based on plat-s3c64xx/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
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/gpio.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <plat/gpio-cfg.h>
+#include <plat/iic.h>
+
+#include <mach/i2c.h>
+
+void s5p6440_i2c1_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgall_range(S5P6440_GPR(9), 2,
+ S3C_GPIO_SFN(6), S3C_GPIO_PULL_UP);
+}
+
+void s5p6450_i2c1_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgall_range(S5P6450_GPR(9), 2,
+ S3C_GPIO_SFN(6), S3C_GPIO_PULL_UP);
+}
+
+void s3c_i2c1_cfg_gpio(struct platform_device *dev) { }
diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig
index 77ae4bfb74ba..b8fbf2fcba6f 100644
--- a/arch/arm/mach-s5pc100/Kconfig
+++ b/arch/arm/mach-s5pc100/Kconfig
@@ -9,7 +9,6 @@ if ARCH_S5PC100
config CPU_S5PC100
bool
- select PLAT_S5P
select S5P_EXT_INT
select S3C_PL330_DMA
help
diff --git a/arch/arm/mach-s5pc100/Makefile b/arch/arm/mach-s5pc100/Makefile
index a021ed1fb4b6..eecab57d2e5d 100644
--- a/arch/arm/mach-s5pc100/Makefile
+++ b/arch/arm/mach-s5pc100/Makefile
@@ -11,7 +11,7 @@ obj- :=
# Core support for S5PC100 system
-obj-$(CONFIG_CPU_S5PC100) += cpu.o init.o clock.o gpiolib.o irq-gpio.o
+obj-$(CONFIG_CPU_S5PC100) += cpu.o init.o clock.o gpiolib.o
obj-$(CONFIG_CPU_S5PC100) += setup-i2c0.o
obj-$(CONFIG_CPU_S5PC100) += dma.o
diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach-s5pc100/clock.c
index 084abd13b0a5..2d4a761a5163 100644
--- a/arch/arm/mach-s5pc100/clock.c
+++ b/arch/arm/mach-s5pc100/clock.c
@@ -273,24 +273,6 @@ static struct clksrc_clk clk_div_hdmi = {
.reg_div = { .reg = S5P_CLK_DIV3, .shift = 28, .size = 4 },
};
-static int s5pc100_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 s5pc100_epll_get_rate(struct clk *clk)
-{
- return clk->rate;
-}
-
static u32 epll_div[][4] = {
{ 32750000, 131, 3, 4 },
{ 32768000, 131, 3, 4 },
@@ -341,13 +323,16 @@ static int s5pc100_epll_set_rate(struct clk *clk, unsigned long rate)
__raw_writel(epll_con, S5P_EPLL_CON);
+ printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
+ clk->rate, rate);
+
clk->rate = rate;
return 0;
}
static struct clk_ops s5pc100_epll_ops = {
- .get_rate = s5pc100_epll_get_rate,
+ .get_rate = s5p_epll_get_rate,
.set_rate = s5pc100_epll_set_rate,
};
@@ -691,55 +676,55 @@ static struct clk init_clocks_disable[] = {
}, {
.name = "iis",
.id = 0,
- .parent = &clk_div_d1_bus.clk,
+ .parent = &clk_div_pclkd1.clk,
.enable = s5pc100_d1_5_ctrl,
.ctrlbit = (1 << 0),
}, {
.name = "iis",
.id = 1,
- .parent = &clk_div_d1_bus.clk,
+ .parent = &clk_div_pclkd1.clk,
.enable = s5pc100_d1_5_ctrl,
.ctrlbit = (1 << 1),
}, {
.name = "iis",
.id = 2,
- .parent = &clk_div_d1_bus.clk,
+ .parent = &clk_div_pclkd1.clk,
.enable = s5pc100_d1_5_ctrl,
.ctrlbit = (1 << 2),
}, {
.name = "ac97",
.id = -1,
- .parent = &clk_div_d1_bus.clk,
+ .parent = &clk_div_pclkd1.clk,
.enable = s5pc100_d1_5_ctrl,
.ctrlbit = (1 << 3),
}, {
.name = "pcm",
.id = 0,
- .parent = &clk_div_d1_bus.clk,
+ .parent = &clk_div_pclkd1.clk,
.enable = s5pc100_d1_5_ctrl,
.ctrlbit = (1 << 4),
}, {
.name = "pcm",
.id = 1,
- .parent = &clk_div_d1_bus.clk,
+ .parent = &clk_div_pclkd1.clk,
.enable = s5pc100_d1_5_ctrl,
.ctrlbit = (1 << 5),
}, {
.name = "spdif",
.id = -1,
- .parent = &clk_div_d1_bus.clk,
+ .parent = &clk_div_pclkd1.clk,
.enable = s5pc100_d1_5_ctrl,
.ctrlbit = (1 << 6),
}, {
.name = "adc",
.id = -1,
- .parent = &clk_div_d1_bus.clk,
+ .parent = &clk_div_pclkd1.clk,
.enable = s5pc100_d1_5_ctrl,
.ctrlbit = (1 << 7),
}, {
.name = "keypad",
.id = -1,
- .parent = &clk_div_d1_bus.clk,
+ .parent = &clk_div_pclkd1.clk,
.enable = s5pc100_d1_5_ctrl,
.ctrlbit = (1 << 8),
}, {
@@ -848,6 +833,18 @@ struct clksrc_sources clk_src_group3 = {
.nr_sources = ARRAY_SIZE(clk_src_group3_list),
};
+static struct clksrc_clk clk_sclk_audio0 = {
+ .clk = {
+ .name = "sclk_audio",
+ .id = 0,
+ .ctrlbit = (1 << 8),
+ .enable = s5pc100_sclk1_ctrl,
+ },
+ .sources = &clk_src_group3,
+ .reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 3 },
+ .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 },
+};
+
static struct clk *clk_src_group4_list[] = {
[0] = &clk_mout_epll.clk,
[1] = &clk_div_mpll.clk,
@@ -862,6 +859,18 @@ struct clksrc_sources clk_src_group4 = {
.nr_sources = ARRAY_SIZE(clk_src_group4_list),
};
+static struct clksrc_clk clk_sclk_audio1 = {
+ .clk = {
+ .name = "sclk_audio",
+ .id = 1,
+ .ctrlbit = (1 << 9),
+ .enable = s5pc100_sclk1_ctrl,
+ },
+ .sources = &clk_src_group4,
+ .reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 3 },
+ .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
+};
+
static struct clk *clk_src_group5_list[] = {
[0] = &clk_mout_epll.clk,
[1] = &clk_div_mpll.clk,
@@ -875,6 +884,18 @@ struct clksrc_sources clk_src_group5 = {
.nr_sources = ARRAY_SIZE(clk_src_group5_list),
};
+static struct clksrc_clk clk_sclk_audio2 = {
+ .clk = {
+ .name = "sclk_audio",
+ .id = 2,
+ .ctrlbit = (1 << 10),
+ .enable = s5pc100_sclk1_ctrl,
+ },
+ .sources = &clk_src_group5,
+ .reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 3 },
+ .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
+};
+
static struct clk *clk_src_group6_list[] = {
[0] = &s5p_clk_27m,
[1] = &clk_vclk54m,
@@ -944,6 +965,64 @@ struct clksrc_sources clk_src_pwi = {
.nr_sources = ARRAY_SIZE(clk_src_pwi_list),
};
+static struct clk *clk_sclk_spdif_list[] = {
+ [0] = &clk_sclk_audio0.clk,
+ [1] = &clk_sclk_audio1.clk,
+ [2] = &clk_sclk_audio2.clk,
+};
+
+struct clksrc_sources clk_src_sclk_spdif = {
+ .sources = clk_sclk_spdif_list,
+ .nr_sources = ARRAY_SIZE(clk_sclk_spdif_list),
+};
+
+static int s5pc100_spdif_set_rate(struct clk *clk, unsigned long rate)
+{
+ struct clk *pclk;
+ int ret;
+
+ pclk = clk_get_parent(clk);
+ if (IS_ERR(pclk))
+ return -EINVAL;
+
+ ret = pclk->ops->set_rate(pclk, rate);
+ clk_put(pclk);
+
+ return ret;
+}
+
+static unsigned long s5pc100_spdif_get_rate(struct clk *clk)
+{
+ struct clk *pclk;
+ int rate;
+
+ pclk = clk_get_parent(clk);
+ if (IS_ERR(pclk))
+ return -EINVAL;
+
+ rate = pclk->ops->get_rate(clk);
+ clk_put(pclk);
+
+ return rate;
+}
+
+static struct clk_ops s5pc100_sclk_spdif_ops = {
+ .set_rate = s5pc100_spdif_set_rate,
+ .get_rate = s5pc100_spdif_get_rate,
+};
+
+static struct clksrc_clk clk_sclk_spdif = {
+ .clk = {
+ .name = "sclk_spdif",
+ .id = -1,
+ .ctrlbit = (1 << 11),
+ .enable = s5pc100_sclk1_ctrl,
+ .ops = &s5pc100_sclk_spdif_ops,
+ },
+ .sources = &clk_src_sclk_spdif,
+ .reg_src = { .reg = S5P_CLK_SRC3, .shift = 24, .size = 2 },
+};
+
static struct clksrc_clk clksrcs[] = {
{
.clk = {
@@ -1001,39 +1080,6 @@ static struct clksrc_clk clksrcs[] = {
.reg_src = { .reg = S5P_CLK_SRC2, .shift = 28, .size = 2 },
}, {
.clk = {
- .name = "sclk_audio",
- .id = 0,
- .ctrlbit = (1 << 8),
- .enable = s5pc100_sclk1_ctrl,
-
- },
- .sources = &clk_src_group3,
- .reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 3 },
- .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_audio",
- .id = 1,
- .ctrlbit = (1 << 9),
- .enable = s5pc100_sclk1_ctrl,
-
- },
- .sources = &clk_src_group4,
- .reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 3 },
- .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_audio",
- .id = 2,
- .ctrlbit = (1 << 10),
- .enable = s5pc100_sclk1_ctrl,
-
- },
- .sources = &clk_src_group5,
- .reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 3 },
- .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
- }, {
- .clk = {
.name = "sclk_lcd",
.id = -1,
.ctrlbit = (1 << 0),
@@ -1179,6 +1225,10 @@ static struct clksrc_clk *sysclks[] = {
&clk_div_pclkd1,
&clk_div_cam,
&clk_div_hdmi,
+ &clk_sclk_audio0,
+ &clk_sclk_audio1,
+ &clk_sclk_audio2,
+ &clk_sclk_spdif,
};
void __init_or_cpufreq s5pc100_setup_clocks(void)
@@ -1196,7 +1246,7 @@ void __init_or_cpufreq s5pc100_setup_clocks(void)
unsigned int ptr;
/* Set S5PC100 functions for clk_fout_epll */
- clk_fout_epll.enable = s5pc100_epll_enable;
+ clk_fout_epll.enable = s5p_epll_enable;
clk_fout_epll.ops = &s5pc100_epll_ops;
printk(KERN_DEBUG "%s: registering clocks\n", __func__);
diff --git a/arch/arm/mach-s5pc100/cpu.c b/arch/arm/mach-s5pc100/cpu.c
index cd1afbce83e2..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>
*
@@ -57,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/dev-audio.c b/arch/arm/mach-s5pc100/dev-audio.c
index a699ed6acc23..564e195ec493 100644
--- a/arch/arm/mach-s5pc100/dev-audio.c
+++ b/arch/arm/mach-s5pc100/dev-audio.c
@@ -24,19 +24,11 @@ static int s5pc100_cfg_i2s(struct platform_device *pdev)
/* configure GPIO for i2s port */
switch (pdev->id) {
case 1:
- s3c_gpio_cfgpin(S5PC100_GPC(0), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5PC100_GPC(1), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5PC100_GPC(2), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5PC100_GPC(3), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5PC100_GPC(4), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin_range(S5PC100_GPC(0), 5, S3C_GPIO_SFN(2));
break;
case 2:
- s3c_gpio_cfgpin(S5PC100_GPG3(0), S3C_GPIO_SFN(4));
- s3c_gpio_cfgpin(S5PC100_GPG3(1), S3C_GPIO_SFN(4));
- s3c_gpio_cfgpin(S5PC100_GPG3(2), S3C_GPIO_SFN(4));
- s3c_gpio_cfgpin(S5PC100_GPG3(3), S3C_GPIO_SFN(4));
- s3c_gpio_cfgpin(S5PC100_GPG3(4), S3C_GPIO_SFN(4));
+ s3c_gpio_cfgpin_range(S5PC100_GPG3(0), 5, S3C_GPIO_SFN(4));
break;
case -1: /* Dedicated pins */
@@ -144,19 +136,11 @@ static int s5pc100_pcm_cfg_gpio(struct platform_device *pdev)
{
switch (pdev->id) {
case 0:
- s3c_gpio_cfgpin(S5PC100_GPG3(0), S3C_GPIO_SFN(5));
- s3c_gpio_cfgpin(S5PC100_GPG3(1), S3C_GPIO_SFN(5));
- s3c_gpio_cfgpin(S5PC100_GPG3(2), S3C_GPIO_SFN(5));
- s3c_gpio_cfgpin(S5PC100_GPG3(3), S3C_GPIO_SFN(5));
- s3c_gpio_cfgpin(S5PC100_GPG3(4), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin_range(S5PC100_GPG3(0), 5, S3C_GPIO_SFN(5));
break;
case 1:
- s3c_gpio_cfgpin(S5PC100_GPC(0), S3C_GPIO_SFN(3));
- s3c_gpio_cfgpin(S5PC100_GPC(1), S3C_GPIO_SFN(3));
- s3c_gpio_cfgpin(S5PC100_GPC(2), S3C_GPIO_SFN(3));
- s3c_gpio_cfgpin(S5PC100_GPC(3), S3C_GPIO_SFN(3));
- s3c_gpio_cfgpin(S5PC100_GPC(4), S3C_GPIO_SFN(3));
+ s3c_gpio_cfgpin_range(S5PC100_GPC(0), 5, S3C_GPIO_SFN(3));
break;
default:
@@ -231,13 +215,7 @@ struct platform_device s5pc100_device_pcm1 = {
static int s5pc100_ac97_cfg_gpio(struct platform_device *pdev)
{
- s3c_gpio_cfgpin(S5PC100_GPC(0), S3C_GPIO_SFN(4));
- s3c_gpio_cfgpin(S5PC100_GPC(1), S3C_GPIO_SFN(4));
- s3c_gpio_cfgpin(S5PC100_GPC(2), S3C_GPIO_SFN(4));
- s3c_gpio_cfgpin(S5PC100_GPC(3), S3C_GPIO_SFN(4));
- s3c_gpio_cfgpin(S5PC100_GPC(4), S3C_GPIO_SFN(4));
-
- return 0;
+ return s3c_gpio_cfgpin_range(S5PC100_GPC(0), 5, S3C_GPIO_SFN(4));
}
static struct resource s5pc100_ac97_resource[] = {
@@ -285,3 +263,57 @@ struct platform_device s5pc100_device_ac97 = {
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
+
+/* S/PDIF Controller platform_device */
+static int s5pc100_spdif_cfg_gpd(struct platform_device *pdev)
+{
+ s3c_gpio_cfgpin_range(S5PC100_GPD(5), 2, S3C_GPIO_SFN(3));
+
+ return 0;
+}
+
+static int s5pc100_spdif_cfg_gpg3(struct platform_device *pdev)
+{
+ s3c_gpio_cfgpin_range(S5PC100_GPG3(5), 2, S3C_GPIO_SFN(3));
+
+ return 0;
+}
+
+static struct resource s5pc100_spdif_resource[] = {
+ [0] = {
+ .start = S5PC100_PA_SPDIF,
+ .end = S5PC100_PA_SPDIF + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_SPDIF,
+ .end = DMACH_SPDIF,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct s3c_audio_pdata s5p_spdif_pdata = {
+ .cfg_gpio = s5pc100_spdif_cfg_gpd,
+};
+
+static u64 s5pc100_spdif_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s5pc100_device_spdif = {
+ .name = "samsung-spdif",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5pc100_spdif_resource),
+ .resource = s5pc100_spdif_resource,
+ .dev = {
+ .platform_data = &s5p_spdif_pdata,
+ .dma_mask = &s5pc100_spdif_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init s5pc100_spdif_setup_gpio(int gpio)
+{
+ if (gpio == S5PC100_SPDIF_GPD)
+ s5p_spdif_pdata.cfg_gpio = s5pc100_spdif_cfg_gpd;
+ else
+ s5p_spdif_pdata.cfg_gpio = s5pc100_spdif_cfg_gpg3;
+}
diff --git a/arch/arm/mach-s5pc100/dev-spi.c b/arch/arm/mach-s5pc100/dev-spi.c
index a0ef7c302c16..57b19794d9bb 100644
--- a/arch/arm/mach-s5pc100/dev-spi.c
+++ b/arch/arm/mach-s5pc100/dev-spi.c
@@ -38,30 +38,20 @@ static int s5pc100_spi_cfg_gpio(struct platform_device *pdev)
{
switch (pdev->id) {
case 0:
- s3c_gpio_cfgpin(S5PC100_GPB(0), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5PC100_GPB(1), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5PC100_GPB(2), S3C_GPIO_SFN(2));
- s3c_gpio_setpull(S5PC100_GPB(0), S3C_GPIO_PULL_UP);
- s3c_gpio_setpull(S5PC100_GPB(1), S3C_GPIO_PULL_UP);
- s3c_gpio_setpull(S5PC100_GPB(2), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgall_range(S5PC100_GPB(0), 3,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
break;
case 1:
- s3c_gpio_cfgpin(S5PC100_GPB(4), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5PC100_GPB(5), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5PC100_GPB(6), S3C_GPIO_SFN(2));
- s3c_gpio_setpull(S5PC100_GPB(4), S3C_GPIO_PULL_UP);
- s3c_gpio_setpull(S5PC100_GPB(5), S3C_GPIO_PULL_UP);
- s3c_gpio_setpull(S5PC100_GPB(6), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgall_range(S5PC100_GPB(4), 3,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
break;
case 2:
s3c_gpio_cfgpin(S5PC100_GPG3(0), S3C_GPIO_SFN(3));
- s3c_gpio_cfgpin(S5PC100_GPG3(2), S3C_GPIO_SFN(3));
- s3c_gpio_cfgpin(S5PC100_GPG3(3), S3C_GPIO_SFN(3));
s3c_gpio_setpull(S5PC100_GPG3(0), S3C_GPIO_PULL_UP);
- s3c_gpio_setpull(S5PC100_GPG3(2), S3C_GPIO_PULL_UP);
- s3c_gpio_setpull(S5PC100_GPG3(3), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgall_range(S5PC100_GPB(2), 2,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
break;
default:
diff --git a/arch/arm/mach-s5pc100/dma.c b/arch/arm/mach-s5pc100/dma.c
index 0f5517571e2c..bf4cd0fb97c6 100644
--- a/arch/arm/mach-s5pc100/dma.c
+++ b/arch/arm/mach-s5pc100/dma.c
@@ -81,7 +81,7 @@ static struct s3c_pl330_platdata s5pc100_pdma0_pdata = {
static struct platform_device s5pc100_device_pdma0 = {
.name = "s3c-pl330",
- .id = 1,
+ .id = 0,
.num_resources = ARRAY_SIZE(s5pc100_pdma0_resource),
.resource = s5pc100_pdma0_resource,
.dev = {
@@ -143,7 +143,7 @@ static struct s3c_pl330_platdata s5pc100_pdma1_pdata = {
static struct platform_device s5pc100_device_pdma1 = {
.name = "s3c-pl330",
- .id = 2,
+ .id = 1,
.num_resources = ARRAY_SIZE(s5pc100_pdma1_resource),
.resource = s5pc100_pdma1_resource,
.dev = {
diff --git a/arch/arm/mach-s5pc100/gpiolib.c b/arch/arm/mach-s5pc100/gpiolib.c
index 0fab7f2cd8bf..20856eb7dd51 100644
--- a/arch/arm/mach-s5pc100/gpiolib.c
+++ b/arch/arm/mach-s5pc100/gpiolib.c
@@ -1,5 +1,7 @@
-/*
- * arch/arm/plat-s5pc100/gpiolib.c
+/* linux/arch/arm/mach-s5pc100/gpiolib.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
*
* Copyright 2009 Samsung Electronics Co
* Kyungmin Park <kyungmin.park@samsung.com>
@@ -61,30 +63,6 @@
* L3 8 4Bit None
*/
-static int s5pc100_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
-{
- return S3C_IRQ_GPIO(chip->base + offset);
-}
-
-static int s5pc100_gpiolib_to_eint(struct gpio_chip *chip, unsigned int offset)
-{
- int base;
-
- base = chip->base - S5PC100_GPH0(0);
- if (base == 0)
- return IRQ_EINT(offset);
- base = chip->base - S5PC100_GPH1(0);
- if (base == 0)
- return IRQ_EINT(8 + offset);
- base = chip->base - S5PC100_GPH2(0);
- if (base == 0)
- return IRQ_EINT(16 + offset);
- base = chip->base - S5PC100_GPH3(0);
- if (base == 0)
- return IRQ_EINT(24 + offset);
- return -EINVAL;
-}
-
static struct s3c_gpio_cfg gpio_cfg = {
.set_config = s3c_gpio_setcfg_s3c64xx_4bit,
.set_pull = s3c_gpio_setpull_updown,
@@ -104,209 +82,150 @@ static struct s3c_gpio_cfg gpio_cfg_noint = {
.get_pull = s3c_gpio_getpull_updown,
};
+/*
+ * GPIO bank's base address given the index of the bank in the
+ * list of all gpio banks.
+ */
+#define S5PC100_BANK_BASE(bank_nr) (S5P_VA_GPIO + ((bank_nr) * 0x20))
+
+/*
+ * Following are the gpio banks in S5PC100.
+ *
+ * The 'config' member when left to NULL, is initialized to the default
+ * structure gpio_cfg in the init function below.
+ *
+ * The 'base' member is also initialized in the init function below.
+ * Note: The initialization of 'base' member of s3c_gpio_chip structure
+ * uses the above macro and depends on the banks being listed in order here.
+ */
static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
{
- .base = S5PC100_GPA0_BASE,
- .config = &gpio_cfg,
.chip = {
.base = S5PC100_GPA0(0),
.ngpio = S5PC100_GPIO_A0_NR,
.label = "GPA0",
},
}, {
- .base = S5PC100_GPA1_BASE,
- .config = &gpio_cfg,
.chip = {
.base = S5PC100_GPA1(0),
.ngpio = S5PC100_GPIO_A1_NR,
.label = "GPA1",
},
}, {
- .base = S5PC100_GPB_BASE,
- .config = &gpio_cfg,
.chip = {
.base = S5PC100_GPB(0),
.ngpio = S5PC100_GPIO_B_NR,
.label = "GPB",
},
}, {
- .base = S5PC100_GPC_BASE,
- .config = &gpio_cfg,
.chip = {
.base = S5PC100_GPC(0),
.ngpio = S5PC100_GPIO_C_NR,
.label = "GPC",
},
}, {
- .base = S5PC100_GPD_BASE,
- .config = &gpio_cfg,
.chip = {
.base = S5PC100_GPD(0),
.ngpio = S5PC100_GPIO_D_NR,
.label = "GPD",
},
}, {
- .base = S5PC100_GPE0_BASE,
- .config = &gpio_cfg,
.chip = {
.base = S5PC100_GPE0(0),
.ngpio = S5PC100_GPIO_E0_NR,
.label = "GPE0",
},
}, {
- .base = S5PC100_GPE1_BASE,
- .config = &gpio_cfg,
.chip = {
.base = S5PC100_GPE1(0),
.ngpio = S5PC100_GPIO_E1_NR,
.label = "GPE1",
},
}, {
- .base = S5PC100_GPF0_BASE,
- .config = &gpio_cfg,
.chip = {
.base = S5PC100_GPF0(0),
.ngpio = S5PC100_GPIO_F0_NR,
.label = "GPF0",
},
}, {
- .base = S5PC100_GPF1_BASE,
- .config = &gpio_cfg,
.chip = {
.base = S5PC100_GPF1(0),
.ngpio = S5PC100_GPIO_F1_NR,
.label = "GPF1",
},
}, {
- .base = S5PC100_GPF2_BASE,
- .config = &gpio_cfg,
.chip = {
.base = S5PC100_GPF2(0),
.ngpio = S5PC100_GPIO_F2_NR,
.label = "GPF2",
},
}, {
- .base = S5PC100_GPF3_BASE,
- .config = &gpio_cfg,
.chip = {
.base = S5PC100_GPF3(0),
.ngpio = S5PC100_GPIO_F3_NR,
.label = "GPF3",
},
}, {
- .base = S5PC100_GPG0_BASE,
- .config = &gpio_cfg,
.chip = {
.base = S5PC100_GPG0(0),
.ngpio = S5PC100_GPIO_G0_NR,
.label = "GPG0",
},
}, {
- .base = S5PC100_GPG1_BASE,
- .config = &gpio_cfg,
.chip = {
.base = S5PC100_GPG1(0),
.ngpio = S5PC100_GPIO_G1_NR,
.label = "GPG1",
},
}, {
- .base = S5PC100_GPG2_BASE,
- .config = &gpio_cfg,
.chip = {
.base = S5PC100_GPG2(0),
.ngpio = S5PC100_GPIO_G2_NR,
.label = "GPG2",
},
}, {
- .base = S5PC100_GPG3_BASE,
- .config = &gpio_cfg,
.chip = {
.base = S5PC100_GPG3(0),
.ngpio = S5PC100_GPIO_G3_NR,
.label = "GPG3",
},
}, {
- .base = S5PC100_GPH0_BASE,
- .config = &gpio_cfg_eint,
- .chip = {
- .base = S5PC100_GPH0(0),
- .ngpio = S5PC100_GPIO_H0_NR,
- .label = "GPH0",
- },
- }, {
- .base = S5PC100_GPH1_BASE,
- .config = &gpio_cfg_eint,
- .chip = {
- .base = S5PC100_GPH1(0),
- .ngpio = S5PC100_GPIO_H1_NR,
- .label = "GPH1",
- },
- }, {
- .base = S5PC100_GPH2_BASE,
- .config = &gpio_cfg_eint,
- .chip = {
- .base = S5PC100_GPH2(0),
- .ngpio = S5PC100_GPIO_H2_NR,
- .label = "GPH2",
- },
- }, {
- .base = S5PC100_GPH3_BASE,
- .config = &gpio_cfg_eint,
- .chip = {
- .base = S5PC100_GPH3(0),
- .ngpio = S5PC100_GPIO_H3_NR,
- .label = "GPH3",
- },
- }, {
- .base = S5PC100_GPI_BASE,
- .config = &gpio_cfg,
.chip = {
.base = S5PC100_GPI(0),
.ngpio = S5PC100_GPIO_I_NR,
.label = "GPI",
},
}, {
- .base = S5PC100_GPJ0_BASE,
- .config = &gpio_cfg,
.chip = {
.base = S5PC100_GPJ0(0),
.ngpio = S5PC100_GPIO_J0_NR,
.label = "GPJ0",
},
}, {
- .base = S5PC100_GPJ1_BASE,
- .config = &gpio_cfg,
.chip = {
.base = S5PC100_GPJ1(0),
.ngpio = S5PC100_GPIO_J1_NR,
.label = "GPJ1",
},
}, {
- .base = S5PC100_GPJ2_BASE,
- .config = &gpio_cfg,
.chip = {
.base = S5PC100_GPJ2(0),
.ngpio = S5PC100_GPIO_J2_NR,
.label = "GPJ2",
},
}, {
- .base = S5PC100_GPJ3_BASE,
- .config = &gpio_cfg,
.chip = {
.base = S5PC100_GPJ3(0),
.ngpio = S5PC100_GPIO_J3_NR,
.label = "GPJ3",
},
}, {
- .base = S5PC100_GPJ4_BASE,
- .config = &gpio_cfg,
.chip = {
.base = S5PC100_GPJ4(0),
.ngpio = S5PC100_GPIO_J4_NR,
.label = "GPJ4",
},
}, {
- .base = S5PC100_GPK0_BASE,
.config = &gpio_cfg_noint,
.chip = {
.base = S5PC100_GPK0(0),
@@ -314,7 +233,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
.label = "GPK0",
},
}, {
- .base = S5PC100_GPK1_BASE,
.config = &gpio_cfg_noint,
.chip = {
.base = S5PC100_GPK1(0),
@@ -322,7 +240,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
.label = "GPK1",
},
}, {
- .base = S5PC100_GPK2_BASE,
.config = &gpio_cfg_noint,
.chip = {
.base = S5PC100_GPK2(0),
@@ -330,7 +247,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
.label = "GPK2",
},
}, {
- .base = S5PC100_GPK3_BASE,
.config = &gpio_cfg_noint,
.chip = {
.base = S5PC100_GPK3(0),
@@ -338,7 +254,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
.label = "GPK3",
},
}, {
- .base = S5PC100_GPL0_BASE,
.config = &gpio_cfg_noint,
.chip = {
.base = S5PC100_GPL0(0),
@@ -346,7 +261,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
.label = "GPL0",
},
}, {
- .base = S5PC100_GPL1_BASE,
.config = &gpio_cfg_noint,
.chip = {
.base = S5PC100_GPL1(0),
@@ -354,7 +268,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
.label = "GPL1",
},
}, {
- .base = S5PC100_GPL2_BASE,
.config = &gpio_cfg_noint,
.chip = {
.base = S5PC100_GPL2(0),
@@ -362,7 +275,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
.label = "GPL2",
},
}, {
- .base = S5PC100_GPL3_BASE,
.config = &gpio_cfg_noint,
.chip = {
.base = S5PC100_GPL3(0),
@@ -370,56 +282,72 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
.label = "GPL3",
},
}, {
- .base = S5PC100_GPL4_BASE,
.config = &gpio_cfg_noint,
.chip = {
.base = S5PC100_GPL4(0),
.ngpio = S5PC100_GPIO_L4_NR,
.label = "GPL4",
},
+ }, {
+ .base = (S5P_VA_GPIO + 0xC00),
+ .config = &gpio_cfg_eint,
+ .irq_base = IRQ_EINT(0),
+ .chip = {
+ .base = S5PC100_GPH0(0),
+ .ngpio = S5PC100_GPIO_H0_NR,
+ .label = "GPH0",
+ .to_irq = samsung_gpiolib_to_irq,
+ },
+ }, {
+ .base = (S5P_VA_GPIO + 0xC20),
+ .config = &gpio_cfg_eint,
+ .irq_base = IRQ_EINT(8),
+ .chip = {
+ .base = S5PC100_GPH1(0),
+ .ngpio = S5PC100_GPIO_H1_NR,
+ .label = "GPH1",
+ .to_irq = samsung_gpiolib_to_irq,
+ },
+ }, {
+ .base = (S5P_VA_GPIO + 0xC40),
+ .config = &gpio_cfg_eint,
+ .irq_base = IRQ_EINT(16),
+ .chip = {
+ .base = S5PC100_GPH2(0),
+ .ngpio = S5PC100_GPIO_H2_NR,
+ .label = "GPH2",
+ .to_irq = samsung_gpiolib_to_irq,
+ },
+ }, {
+ .base = (S5P_VA_GPIO + 0xC60),
+ .config = &gpio_cfg_eint,
+ .irq_base = IRQ_EINT(24),
+ .chip = {
+ .base = S5PC100_GPH3(0),
+ .ngpio = S5PC100_GPIO_H3_NR,
+ .label = "GPH3",
+ .to_irq = samsung_gpiolib_to_irq,
+ },
},
};
-/* FIXME move from irq-gpio.c */
-extern struct irq_chip s5pc100_gpioint;
-extern void s5pc100_irq_gpioint_handler(unsigned int irq, struct irq_desc *desc);
-
-static __init void s5pc100_gpiolib_link(struct s3c_gpio_chip *chip)
+static __init int s5pc100_gpiolib_init(void)
{
- /* Interrupt */
- if (chip->config == &gpio_cfg) {
- int i, irq;
-
- chip->chip.to_irq = s5pc100_gpiolib_to_irq;
+ struct s3c_gpio_chip *chip = s5pc100_gpio_chips;
+ int nr_chips = ARRAY_SIZE(s5pc100_gpio_chips);
+ int gpioint_group = 0;
+ int i;
- for (i = 0; i < chip->chip.ngpio; i++) {
- irq = S3C_IRQ_GPIO_BASE + chip->chip.base + i;
- set_irq_chip(irq, &s5pc100_gpioint);
- set_irq_data(irq, &chip->chip);
- set_irq_handler(irq, handle_level_irq);
- set_irq_flags(irq, IRQF_VALID);
+ for (i = 0; i < nr_chips; i++, chip++) {
+ if (chip->config == NULL) {
+ chip->config = &gpio_cfg;
+ chip->group = gpioint_group++;
}
- } else if (chip->config == &gpio_cfg_eint) {
- chip->chip.to_irq = s5pc100_gpiolib_to_eint;
+ if (chip->base == NULL)
+ chip->base = S5PC100_BANK_BASE(i);
}
-}
-
-static __init int s5pc100_gpiolib_init(void)
-{
- struct s3c_gpio_chip *chip;
- int nr_chips;
-
- chip = s5pc100_gpio_chips;
- nr_chips = ARRAY_SIZE(s5pc100_gpio_chips);
-
- for (; nr_chips > 0; nr_chips--, chip++)
- s5pc100_gpiolib_link(chip);
-
- samsung_gpiolib_add_4bit_chips(s5pc100_gpio_chips,
- ARRAY_SIZE(s5pc100_gpio_chips));
- /* Interrupt */
- set_irq_chained_handler(IRQ_GPIOINT, s5pc100_irq_gpioint_handler);
+ samsung_gpiolib_add_4bit_chips(s5pc100_gpio_chips, nr_chips);
return 0;
}
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/gpio.h b/arch/arm/mach-s5pc100/include/mach/gpio.h
index 71ae1f52df1d..29a8a12d9b4f 100644
--- a/arch/arm/mach-s5pc100/include/mach/gpio.h
+++ b/arch/arm/mach-s5pc100/include/mach/gpio.h
@@ -146,13 +146,6 @@ enum s5p_gpio_number {
/* define the number of gpios we need to the one after the MP04() range */
#define ARCH_NR_GPIOS (S5PC100_GPIO_END + 1)
-#define EINT_MODE S3C_GPIO_SFN(0x2)
-
-#define EINT_GPIO_0(x) S5PC100_GPH0(x)
-#define EINT_GPIO_1(x) S5PC100_GPH1(x)
-#define EINT_GPIO_2(x) S5PC100_GPH2(x)
-#define EINT_GPIO_3(x) S5PC100_GPH3(x)
-
#include <asm-generic/gpio.h>
#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/irqs.h b/arch/arm/mach-s5pc100/include/mach/irqs.h
index 06513e647242..d2eb4757381f 100644
--- a/arch/arm/mach-s5pc100/include/mach/irqs.h
+++ b/arch/arm/mach-s5pc100/include/mach/irqs.h
@@ -48,8 +48,8 @@
#define IRQ_SPI1 S5P_IRQ_VIC1(16)
#define IRQ_SPI2 S5P_IRQ_VIC1(17)
#define IRQ_IRDA S5P_IRQ_VIC1(18)
-#define IRQ_CAN0 S5P_IRQ_VIC1(19)
-#define IRQ_CAN1 S5P_IRQ_VIC1(20)
+#define IRQ_IIC2 S5P_IRQ_VIC1(19)
+#define IRQ_IIC3 S5P_IRQ_VIC1(20)
#define IRQ_HSIRX S5P_IRQ_VIC1(21)
#define IRQ_HSITX S5P_IRQ_VIC1(22)
#define IRQ_UHOST S5P_IRQ_VIC1(23)
@@ -100,11 +100,12 @@
#define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0))
#define S5P_EINT_BASE2 (IRQ_VIC_END + 1)
-#define S3C_IRQ_GPIO_BASE (IRQ_EINT(31) + 1)
-#define S3C_IRQ_GPIO(x) (S3C_IRQ_GPIO_BASE + (x))
+/* GPIO interrupt */
+#define S5P_GPIOINT_BASE (IRQ_EINT(31) + 1)
+#define S5P_GPIOINT_GROUP_MAXNR 21
-/* Until MP04 Groups -> 40 (exactly 39) Groups * 8 ~= 320 GPIOs */
-#define NR_IRQS (S3C_IRQ_GPIO(320) + 1)
+/* Set the default NR_IRQS */
+#define NR_IRQS (IRQ_EINT(31) + S5P_GPIOINT_COUNT + 1)
/* Compatibility */
#define IRQ_LCD_FIFO IRQ_LCD0
diff --git a/arch/arm/mach-s5pc100/include/mach/map.h b/arch/arm/mach-s5pc100/include/mach/map.h
index 01b9134feff0..32e9cab5c864 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)
@@ -113,6 +110,8 @@
#define S5PC100_PA_PCM0 0xF2400000
#define S5PC100_PA_PCM1 0xF2500000
+#define S5PC100_PA_SPDIF 0xF2600000
+
#define S5PC100_PA_TSADC (0xF3000000)
/* KEYPAD */
diff --git a/arch/arm/mach-s5pc100/include/mach/regs-gpio.h b/arch/arm/mach-s5pc100/include/mach/regs-gpio.h
index dd6295e1251d..0bf73209ec7b 100644
--- a/arch/arm/mach-s5pc100/include/mach/regs-gpio.h
+++ b/arch/arm/mach-s5pc100/include/mach/regs-gpio.h
@@ -11,43 +11,6 @@
#include <mach/map.h>
-/* S5PC100 */
-#define S5PC100_GPIO_BASE S5P_VA_GPIO
-#define S5PC100_GPA0_BASE (S5PC100_GPIO_BASE + 0x0000)
-#define S5PC100_GPA1_BASE (S5PC100_GPIO_BASE + 0x0020)
-#define S5PC100_GPB_BASE (S5PC100_GPIO_BASE + 0x0040)
-#define S5PC100_GPC_BASE (S5PC100_GPIO_BASE + 0x0060)
-#define S5PC100_GPD_BASE (S5PC100_GPIO_BASE + 0x0080)
-#define S5PC100_GPE0_BASE (S5PC100_GPIO_BASE + 0x00A0)
-#define S5PC100_GPE1_BASE (S5PC100_GPIO_BASE + 0x00C0)
-#define S5PC100_GPF0_BASE (S5PC100_GPIO_BASE + 0x00E0)
-#define S5PC100_GPF1_BASE (S5PC100_GPIO_BASE + 0x0100)
-#define S5PC100_GPF2_BASE (S5PC100_GPIO_BASE + 0x0120)
-#define S5PC100_GPF3_BASE (S5PC100_GPIO_BASE + 0x0140)
-#define S5PC100_GPG0_BASE (S5PC100_GPIO_BASE + 0x0160)
-#define S5PC100_GPG1_BASE (S5PC100_GPIO_BASE + 0x0180)
-#define S5PC100_GPG2_BASE (S5PC100_GPIO_BASE + 0x01A0)
-#define S5PC100_GPG3_BASE (S5PC100_GPIO_BASE + 0x01C0)
-#define S5PC100_GPH0_BASE (S5PC100_GPIO_BASE + 0x0C00)
-#define S5PC100_GPH1_BASE (S5PC100_GPIO_BASE + 0x0C20)
-#define S5PC100_GPH2_BASE (S5PC100_GPIO_BASE + 0x0C40)
-#define S5PC100_GPH3_BASE (S5PC100_GPIO_BASE + 0x0C60)
-#define S5PC100_GPI_BASE (S5PC100_GPIO_BASE + 0x01E0)
-#define S5PC100_GPJ0_BASE (S5PC100_GPIO_BASE + 0x0200)
-#define S5PC100_GPJ1_BASE (S5PC100_GPIO_BASE + 0x0220)
-#define S5PC100_GPJ2_BASE (S5PC100_GPIO_BASE + 0x0240)
-#define S5PC100_GPJ3_BASE (S5PC100_GPIO_BASE + 0x0260)
-#define S5PC100_GPJ4_BASE (S5PC100_GPIO_BASE + 0x0280)
-#define S5PC100_GPK0_BASE (S5PC100_GPIO_BASE + 0x02A0)
-#define S5PC100_GPK1_BASE (S5PC100_GPIO_BASE + 0x02C0)
-#define S5PC100_GPK2_BASE (S5PC100_GPIO_BASE + 0x02E0)
-#define S5PC100_GPK3_BASE (S5PC100_GPIO_BASE + 0x0300)
-#define S5PC100_GPL0_BASE (S5PC100_GPIO_BASE + 0x0320)
-#define S5PC100_GPL1_BASE (S5PC100_GPIO_BASE + 0x0340)
-#define S5PC100_GPL2_BASE (S5PC100_GPIO_BASE + 0x0360)
-#define S5PC100_GPL3_BASE (S5PC100_GPIO_BASE + 0x0380)
-#define S5PC100_GPL4_BASE (S5PC100_GPIO_BASE + 0x03A0)
-
#define S5PC100EINT30CON (S5P_VA_GPIO + 0xE00)
#define S5P_EINT_CON(x) (S5PC100EINT30CON + ((x) * 0x4))
@@ -64,12 +27,12 @@
#define eint_irq_to_bit(irq) (1 << (EINT_OFFSET(irq) & 0x7))
-/* values for S5P_EXTINT0 */
-#define S5P_EXTINT_LOWLEV (0x00)
-#define S5P_EXTINT_HILEV (0x01)
-#define S5P_EXTINT_FALLEDGE (0x02)
-#define S5P_EXTINT_RISEEDGE (0x03)
-#define S5P_EXTINT_BOTHEDGE (0x04)
+#define EINT_MODE S3C_GPIO_SFN(0x2)
+
+#define EINT_GPIO_0(x) S5PC100_GPH0(x)
+#define EINT_GPIO_1(x) S5PC100_GPH1(x)
+#define EINT_GPIO_2(x) S5PC100_GPH2(x)
+#define EINT_GPIO_3(x) S5PC100_GPH3(x)
#endif /* __ASM_MACH_S5PC100_REGS_GPIO_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/vmalloc.h b/arch/arm/mach-s5pc100/include/mach/vmalloc.h
index be9df79903ed..44c8e5726d9d 100644
--- a/arch/arm/mach-s5pc100/include/mach/vmalloc.h
+++ b/arch/arm/mach-s5pc100/include/mach/vmalloc.h
@@ -12,6 +12,6 @@
#ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H
-#define VMALLOC_END (0xe0000000UL)
+#define VMALLOC_END 0xF6000000UL
#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-s5pc100/irq-gpio.c b/arch/arm/mach-s5pc100/irq-gpio.c
deleted file mode 100644
index 2bf86c18bc73..000000000000
--- a/arch/arm/mach-s5pc100/irq-gpio.c
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * arch/arm/mach-s5pc100/irq-gpio.c
- *
- * Copyright (C) 2009 Samsung Electronics
- *
- * S5PC100 - Interrupt handling for IRQ_GPIO${group}(x)
- *
- * 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/interrupt.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-
-#include <mach/map.h>
-#include <plat/gpio-cfg.h>
-
-#define S5P_GPIOREG(x) (S5P_VA_GPIO + (x))
-
-#define CON_OFFSET 0x700
-#define MASK_OFFSET 0x900
-#define PEND_OFFSET 0xA00
-#define CON_OFFSET_2 0xE00
-#define MASK_OFFSET_2 0xF00
-#define PEND_OFFSET_2 0xF40
-
-#define GPIOINT_LEVEL_LOW 0x0
-#define GPIOINT_LEVEL_HIGH 0x1
-#define GPIOINT_EDGE_FALLING 0x2
-#define GPIOINT_EDGE_RISING 0x3
-#define GPIOINT_EDGE_BOTH 0x4
-
-static int group_to_con_offset(int group)
-{
- return group << 2;
-}
-
-static int group_to_mask_offset(int group)
-{
- return group << 2;
-}
-
-static int group_to_pend_offset(int group)
-{
- return group << 2;
-}
-
-static int s5pc100_get_start(unsigned int group)
-{
- switch (group) {
- case 0: return S5PC100_GPIO_A0_START;
- case 1: return S5PC100_GPIO_A1_START;
- case 2: return S5PC100_GPIO_B_START;
- case 3: return S5PC100_GPIO_C_START;
- case 4: return S5PC100_GPIO_D_START;
- case 5: return S5PC100_GPIO_E0_START;
- case 6: return S5PC100_GPIO_E1_START;
- case 7: return S5PC100_GPIO_F0_START;
- case 8: return S5PC100_GPIO_F1_START;
- case 9: return S5PC100_GPIO_F2_START;
- case 10: return S5PC100_GPIO_F3_START;
- case 11: return S5PC100_GPIO_G0_START;
- case 12: return S5PC100_GPIO_G1_START;
- case 13: return S5PC100_GPIO_G2_START;
- case 14: return S5PC100_GPIO_G3_START;
- case 15: return S5PC100_GPIO_I_START;
- case 16: return S5PC100_GPIO_J0_START;
- case 17: return S5PC100_GPIO_J1_START;
- case 18: return S5PC100_GPIO_J2_START;
- case 19: return S5PC100_GPIO_J3_START;
- case 20: return S5PC100_GPIO_J4_START;
- default:
- BUG();
- }
-
- return -EINVAL;
-}
-
-static int s5pc100_get_group(unsigned int irq)
-{
- irq -= S3C_IRQ_GPIO(0);
-
- switch (irq) {
- case S5PC100_GPIO_A0_START ... S5PC100_GPIO_A1_START - 1:
- return 0;
- case S5PC100_GPIO_A1_START ... S5PC100_GPIO_B_START - 1:
- return 1;
- case S5PC100_GPIO_B_START ... S5PC100_GPIO_C_START - 1:
- return 2;
- case S5PC100_GPIO_C_START ... S5PC100_GPIO_D_START - 1:
- return 3;
- case S5PC100_GPIO_D_START ... S5PC100_GPIO_E0_START - 1:
- return 4;
- case S5PC100_GPIO_E0_START ... S5PC100_GPIO_E1_START - 1:
- return 5;
- case S5PC100_GPIO_E1_START ... S5PC100_GPIO_F0_START - 1:
- return 6;
- case S5PC100_GPIO_F0_START ... S5PC100_GPIO_F1_START - 1:
- return 7;
- case S5PC100_GPIO_F1_START ... S5PC100_GPIO_F2_START - 1:
- return 8;
- case S5PC100_GPIO_F2_START ... S5PC100_GPIO_F3_START - 1:
- return 9;
- case S5PC100_GPIO_F3_START ... S5PC100_GPIO_G0_START - 1:
- return 10;
- case S5PC100_GPIO_G0_START ... S5PC100_GPIO_G1_START - 1:
- return 11;
- case S5PC100_GPIO_G1_START ... S5PC100_GPIO_G2_START - 1:
- return 12;
- case S5PC100_GPIO_G2_START ... S5PC100_GPIO_G3_START - 1:
- return 13;
- case S5PC100_GPIO_G3_START ... S5PC100_GPIO_H0_START - 1:
- return 14;
- case S5PC100_GPIO_I_START ... S5PC100_GPIO_J0_START - 1:
- return 15;
- case S5PC100_GPIO_J0_START ... S5PC100_GPIO_J1_START - 1:
- return 16;
- case S5PC100_GPIO_J1_START ... S5PC100_GPIO_J2_START - 1:
- return 17;
- case S5PC100_GPIO_J2_START ... S5PC100_GPIO_J3_START - 1:
- return 18;
- case S5PC100_GPIO_J3_START ... S5PC100_GPIO_J4_START - 1:
- return 19;
- case S5PC100_GPIO_J4_START ... S5PC100_GPIO_K0_START - 1:
- return 20;
- default:
- BUG();
- }
-
- return -EINVAL;
-}
-
-static int s5pc100_get_offset(unsigned int irq)
-{
- struct gpio_chip *chip = get_irq_data(irq);
- return irq - S3C_IRQ_GPIO(chip->base);
-}
-
-static void s5pc100_gpioint_ack(unsigned int irq)
-{
- int group, offset, pend_offset;
- unsigned int value;
-
- group = s5pc100_get_group(irq);
- offset = s5pc100_get_offset(irq);
- pend_offset = group_to_pend_offset(group);
-
- value = __raw_readl(S5P_GPIOREG(PEND_OFFSET) + pend_offset);
- value |= 1 << offset;
- __raw_writel(value, S5P_GPIOREG(PEND_OFFSET) + pend_offset);
-}
-
-static void s5pc100_gpioint_mask(unsigned int irq)
-{
- int group, offset, mask_offset;
- unsigned int value;
-
- group = s5pc100_get_group(irq);
- offset = s5pc100_get_offset(irq);
- mask_offset = group_to_mask_offset(group);
-
- value = __raw_readl(S5P_GPIOREG(MASK_OFFSET) + mask_offset);
- value |= 1 << offset;
- __raw_writel(value, S5P_GPIOREG(MASK_OFFSET) + mask_offset);
-}
-
-static void s5pc100_gpioint_unmask(unsigned int irq)
-{
- int group, offset, mask_offset;
- unsigned int value;
-
- group = s5pc100_get_group(irq);
- offset = s5pc100_get_offset(irq);
- mask_offset = group_to_mask_offset(group);
-
- value = __raw_readl(S5P_GPIOREG(MASK_OFFSET) + mask_offset);
- value &= ~(1 << offset);
- __raw_writel(value, S5P_GPIOREG(MASK_OFFSET) + mask_offset);
-}
-
-static void s5pc100_gpioint_mask_ack(unsigned int irq)
-{
- s5pc100_gpioint_mask(irq);
- s5pc100_gpioint_ack(irq);
-}
-
-static int s5pc100_gpioint_set_type(unsigned int irq, unsigned int type)
-{
- int group, offset, con_offset;
- unsigned int value;
-
- group = s5pc100_get_group(irq);
- offset = s5pc100_get_offset(irq);
- con_offset = group_to_con_offset(group);
-
- switch (type) {
- case IRQ_TYPE_NONE:
- printk(KERN_WARNING "No irq type\n");
- return -EINVAL;
- case IRQ_TYPE_EDGE_RISING:
- type = GPIOINT_EDGE_RISING;
- break;
- case IRQ_TYPE_EDGE_FALLING:
- type = GPIOINT_EDGE_FALLING;
- break;
- case IRQ_TYPE_EDGE_BOTH:
- type = GPIOINT_EDGE_BOTH;
- break;
- case IRQ_TYPE_LEVEL_HIGH:
- type = GPIOINT_LEVEL_HIGH;
- break;
- case IRQ_TYPE_LEVEL_LOW:
- type = GPIOINT_LEVEL_LOW;
- break;
- default:
- BUG();
- }
-
-
- value = __raw_readl(S5P_GPIOREG(CON_OFFSET) + con_offset);
- value &= ~(0xf << (offset * 0x4));
- value |= (type << (offset * 0x4));
- __raw_writel(value, S5P_GPIOREG(CON_OFFSET) + con_offset);
-
- return 0;
-}
-
-struct irq_chip s5pc100_gpioint = {
- .name = "GPIO",
- .ack = s5pc100_gpioint_ack,
- .mask = s5pc100_gpioint_mask,
- .mask_ack = s5pc100_gpioint_mask_ack,
- .unmask = s5pc100_gpioint_unmask,
- .set_type = s5pc100_gpioint_set_type,
-};
-
-void s5pc100_irq_gpioint_handler(unsigned int irq, struct irq_desc *desc)
-{
- int group, offset, pend_offset, mask_offset;
- int real_irq, group_end;
- unsigned int pend, mask;
-
- group_end = 21;
-
- for (group = 0; group < group_end; group++) {
- pend_offset = group_to_pend_offset(group);
- pend = __raw_readl(S5P_GPIOREG(PEND_OFFSET) + pend_offset);
- if (!pend)
- continue;
-
- mask_offset = group_to_mask_offset(group);
- mask = __raw_readl(S5P_GPIOREG(MASK_OFFSET) + mask_offset);
- pend &= ~mask;
-
- for (offset = 0; offset < 8; offset++) {
- if (pend & (1 << offset)) {
- real_irq = s5pc100_get_start(group) + offset;
- generic_handle_irq(S3C_IRQ_GPIO(real_irq));
- }
- }
- }
-}
diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c
index 020c3f98f81f..18b405d514d6 100644
--- a/arch/arm/mach-s5pc100/mach-smdkc100.c
+++ b/arch/arm/mach-s5pc100/mach-smdkc100.c
@@ -47,6 +47,7 @@
#include <plat/adc.h>
#include <plat/keypad.h>
#include <plat/ts.h>
+#include <plat/audio.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDKC100_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -196,6 +197,7 @@ static struct platform_device *smdkc100_devices[] __initdata = {
&s5p_device_fimc0,
&s5p_device_fimc1,
&s5p_device_fimc2,
+ &s5pc100_device_spdif,
};
static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
@@ -226,6 +228,8 @@ static void __init smdkc100_machine_init(void)
samsung_keypad_set_platdata(&smdkc100_keypad_data);
+ s5pc100_spdif_setup_gpio(S5PC100_SPDIF_GPD);
+
/* LCD init */
gpio_request(S5PC100_GPD(0), "GPD");
gpio_request(S5PC100_GPH0(6), "GPH0");
@@ -235,8 +239,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-s5pc100/setup-fb-24bpp.c b/arch/arm/mach-s5pc100/setup-fb-24bpp.c
index 6eba6cb8e2f4..d31c0f3fe222 100644
--- a/arch/arm/mach-s5pc100/setup-fb-24bpp.c
+++ b/arch/arm/mach-s5pc100/setup-fb-24bpp.c
@@ -22,27 +22,15 @@
#define DISR_OFFSET 0x7008
-void s5pc100_fb_gpio_setup_24bpp(void)
+static void s5pc100_fb_setgpios(unsigned int base, unsigned int nr)
{
- unsigned int gpio = 0;
-
- for (gpio = S5PC100_GPF0(0); gpio <= S5PC100_GPF0(7); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
-
- for (gpio = S5PC100_GPF1(0); gpio <= S5PC100_GPF1(7); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
-
- for (gpio = S5PC100_GPF2(0); gpio <= S5PC100_GPF2(7); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
+ s3c_gpio_cfgrange_nopull(base, nr, S3C_GPIO_SFN(2));
+}
- for (gpio = S5PC100_GPF3(0); gpio <= S5PC100_GPF3(3); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
+void s5pc100_fb_gpio_setup_24bpp(void)
+{
+ s5pc100_fb_setgpios(S5PC100_GPF0(0), 8);
+ s5pc100_fb_setgpios(S5PC100_GPF1(0), 8);
+ s5pc100_fb_setgpios(S5PC100_GPF2(0), 8);
+ s5pc100_fb_setgpios(S5PC100_GPF3(0), 4);
}
diff --git a/arch/arm/mach-s5pc100/setup-i2c0.c b/arch/arm/mach-s5pc100/setup-i2c0.c
index dd3174e6ecc5..eaef7a3bda49 100644
--- a/arch/arm/mach-s5pc100/setup-i2c0.c
+++ b/arch/arm/mach-s5pc100/setup-i2c0.c
@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */
void s3c_i2c0_cfg_gpio(struct platform_device *dev)
{
- s3c_gpio_cfgpin(S5PC100_GPD(3), S3C_GPIO_SFN(2));
- s3c_gpio_setpull(S5PC100_GPD(3), S3C_GPIO_PULL_UP);
- s3c_gpio_cfgpin(S5PC100_GPD(4), S3C_GPIO_SFN(2));
- s3c_gpio_setpull(S5PC100_GPD(4), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgall_range(S5PC100_GPD(3), 2,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
}
diff --git a/arch/arm/mach-s5pc100/setup-i2c1.c b/arch/arm/mach-s5pc100/setup-i2c1.c
index d1fec26b69ee..aaff74a90dee 100644
--- a/arch/arm/mach-s5pc100/setup-i2c1.c
+++ b/arch/arm/mach-s5pc100/setup-i2c1.c
@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */
void s3c_i2c1_cfg_gpio(struct platform_device *dev)
{
- s3c_gpio_cfgpin(S5PC100_GPD(5), S3C_GPIO_SFN(2));
- s3c_gpio_setpull(S5PC100_GPD(5), S3C_GPIO_PULL_UP);
- s3c_gpio_cfgpin(S5PC100_GPD(6), S3C_GPIO_SFN(2));
- s3c_gpio_setpull(S5PC100_GPD(6), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgall_range(S5PC100_GPD(5), 2,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
}
diff --git a/arch/arm/mach-s5pc100/setup-ide.c b/arch/arm/mach-s5pc100/setup-ide.c
index 83575671fb59..223aae044466 100644
--- a/arch/arm/mach-s5pc100/setup-ide.c
+++ b/arch/arm/mach-s5pc100/setup-ide.c
@@ -17,52 +17,39 @@
#include <mach/regs-clock.h>
#include <plat/gpio-cfg.h>
+static void s5pc100_ide_cfg_gpios(unsigned int base, unsigned int nr)
+{
+ s3c_gpio_cfgrange_nopull(base, nr, S3C_GPIO_SFN(4));
+
+ for (; nr > 0; nr--, base++)
+ s5p_gpio_set_drvstr(base, S5P_GPIO_DRVSTR_LV4);
+}
+
void s5pc100_ide_setup_gpio(void)
{
u32 reg;
- u32 gpio = 0;
/* Independent CF interface, CF chip select configuration */
reg = readl(S5PC100_MEM_SYS_CFG) & (~0x3f);
writel(reg | MEM_SYS_CFG_EBI_FIX_PRI_CFCON, S5PC100_MEM_SYS_CFG);
/* CF_Add[0 - 2], CF_IORDY, CF_INTRQ, CF_DMARQ, CF_DMARST, CF_DMACK */
- for (gpio = S5PC100_GPJ0(0); gpio <= S5PC100_GPJ0(7); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
- }
+ s5pc100_ide_cfg_gpios(S5PC100_GPJ0(0), 8);
/*CF_Data[0 - 7] */
- for (gpio = S5PC100_GPJ2(0); gpio <= S5PC100_GPJ2(7); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
- }
+ s5pc100_ide_cfg_gpios(S5PC100_GPJ2(0), 8);
/* CF_Data[8 - 15] */
- for (gpio = S5PC100_GPJ3(0); gpio <= S5PC100_GPJ3(7); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
- }
+ s5pc100_ide_cfg_gpios(S5PC100_GPJ3(0), 8);
/* CF_CS0, CF_CS1, CF_IORD, CF_IOWR */
- for (gpio = S5PC100_GPJ4(0); gpio <= S5PC100_GPJ4(3); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
- }
+ s5pc100_ide_cfg_gpios(S5PC100_GPJ4(0), 4);
/* EBI_OE, EBI_WE */
- for (gpio = S5PC100_GPK0(6); gpio <= S5PC100_GPK0(7); gpio++)
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0));
+ s3c_gpio_cfgpin_range(S5PC100_GPK0(6), 2, S3C_GPIO_SFN(0));
/* CF_OE, CF_WE */
- for (gpio = S5PC100_GPK1(6); gpio <= S5PC100_GPK1(7); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
+ s3c_gpio_cfgrange_nopull(S5PC100_GPK1(6), 8, S3C_GPIO_SFN(2));
/* CF_CD */
s3c_gpio_cfgpin(S5PC100_GPK3(5), S3C_GPIO_SFN(2));
diff --git a/arch/arm/mach-s5pc100/setup-keypad.c b/arch/arm/mach-s5pc100/setup-keypad.c
index d0837a72a58e..ada377f0c206 100644
--- a/arch/arm/mach-s5pc100/setup-keypad.c
+++ b/arch/arm/mach-s5pc100/setup-keypad.c
@@ -15,20 +15,9 @@
void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols)
{
- unsigned int gpio;
- unsigned int end;
-
/* Set all the necessary GPH3 pins to special-function 3: KP_ROW[x] */
- end = S5PC100_GPH3(rows);
- for (gpio = S5PC100_GPH3(0); gpio < end; gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
+ s3c_gpio_cfgrange_nopull(S5PC100_GPH3(0), rows, S3C_GPIO_SFN(3));
/* Set all the necessary GPH2 pins to special-function 3: KP_COL[x] */
- end = S5PC100_GPH2(cols);
- for (gpio = S5PC100_GPH2(0); gpio < end; gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
+ s3c_gpio_cfgrange_nopull(S5PC100_GPH2(0), cols, S3C_GPIO_SFN(3));
}
diff --git a/arch/arm/mach-s5pc100/setup-sdhci-gpio.c b/arch/arm/mach-s5pc100/setup-sdhci-gpio.c
index dc7208c639ea..03c02d04c68c 100644
--- a/arch/arm/mach-s5pc100/setup-sdhci-gpio.c
+++ b/arch/arm/mach-s5pc100/setup-sdhci-gpio.c
@@ -25,8 +25,6 @@
void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
{
struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
- unsigned int gpio;
- unsigned int end;
unsigned int num;
num = width;
@@ -34,20 +32,11 @@ void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
if (width == 8)
num = width - 2;
- end = S5PC100_GPG0(2 + num);
-
/* Set all the necessary GPG0/GPG1 pins to special-function 0 */
- for (gpio = S5PC100_GPG0(0); gpio < end; gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
+ s3c_gpio_cfgrange_nopull(S5PC100_GPG0(0), 2 + num, S3C_GPIO_SFN(2));
- if (width == 8) {
- for (gpio = S5PC100_GPG1(0); gpio <= S5PC100_GPG1(1); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
- }
+ if (width == 8)
+ s3c_gpio_cfgrange_nopull(S5PC100_GPG1(0), 2, S3C_GPIO_SFN(2));
if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
s3c_gpio_setpull(S5PC100_GPG1(2), S3C_GPIO_PULL_UP);
@@ -58,16 +47,9 @@ void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
{
struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
- unsigned int gpio;
- unsigned int end;
-
- end = S5PC100_GPG2(2 + width);
/* Set all the necessary GPG2 pins to special-function 2 */
- for (gpio = S5PC100_GPG2(0); gpio < end; gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
+ s3c_gpio_cfgrange_nopull(S5PC100_GPG2(0), 2 + width, S3C_GPIO_SFN(2));
if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
s3c_gpio_setpull(S5PC100_GPG2(6), S3C_GPIO_PULL_UP);
@@ -78,16 +60,9 @@ void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
void s5pc100_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
{
struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
- unsigned int gpio;
- unsigned int end;
-
- end = S5PC100_GPG3(2 + width);
/* Set all the necessary GPG3 pins to special-function 2 */
- for (gpio = S5PC100_GPG3(0); gpio < end; gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
+ s3c_gpio_cfgrange_nopull(S5PC100_GPG3(0), 2 + width, S3C_GPIO_SFN(2));
if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
s3c_gpio_setpull(S5PC100_GPG3(6), S3C_GPIO_PULL_UP);
diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index d3a38955c741..862f239a0fdb 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -11,9 +11,9 @@ if ARCH_S5PV210
config CPU_S5PV210
bool
- select PLAT_S5P
select S3C_PL330_DMA
select S5P_EXT_INT
+ select S5PV210_PM if PM
help
Enable S5PV210 CPU support
@@ -53,17 +53,11 @@ 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
bool "Aquila"
select CPU_S5PV210
- select ARCH_SPARSEMEM_ENABLE
select S3C_DEV_FB
select S5P_DEV_FIMC0
select S5P_DEV_FIMC1
@@ -71,7 +65,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
@@ -80,7 +74,7 @@ config MACH_AQUILA
config MACH_GONI
bool "GONI"
select CPU_S5PV210
- select ARCH_SPARSEMEM_ENABLE
+ select S5P_GPIO_INT
select S3C_DEV_FB
select S5P_DEV_FIMC0
select S5P_DEV_FIMC1
@@ -88,8 +82,15 @@ config MACH_GONI
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_HSMMC2
- select S5PC110_DEV_ONENAND
+ select S3C_DEV_I2C1
+ select S3C_DEV_I2C2
+ select S3C_DEV_USB_HSOTG
+ select S5P_DEV_ONENAND
+ select SAMSUNG_DEV_KEYPAD
select S5PV210_SETUP_FB_24BPP
+ select S5PV210_SETUP_I2C1
+ select S5PV210_SETUP_I2C2
+ select S5PV210_SETUP_KEYPAD
select S5PV210_SETUP_SDHCI
help
Machine support for Samsung GONI board
@@ -98,7 +99,6 @@ config MACH_GONI
config MACH_SMDKC110
bool "SMDKC110"
select CPU_S5PV210
- select ARCH_SPARSEMEM_ENABLE
select S3C_DEV_I2C1
select S3C_DEV_I2C2
select S3C_DEV_RTC
@@ -118,7 +118,6 @@ menu "S5PV210 Machines"
config MACH_SMDKV210
bool "SMDKV210"
select CPU_S5PV210
- select ARCH_SPARSEMEM_ENABLE
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_HSMMC2
@@ -139,6 +138,29 @@ config MACH_SMDKV210
help
Machine support for Samsung SMDKV210
+config MACH_TORBRECK
+ bool "Torbreck"
+ select CPU_S5PV210
+ select ARCH_SPARSEMEM_ENABLE
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_HSMMC2
+ select S3C_DEV_HSMMC3
+ select S3C_DEV_I2C1
+ select S3C_DEV_I2C2
+ select S3C_DEV_RTC
+ select S3C_DEV_WDT
+ select S5PV210_SETUP_I2C1
+ select S5PV210_SETUP_I2C2
+ select S5PV210_SETUP_SDHCI
+ help
+ Machine support for aESOP Torbreck
+
endmenu
+config S5PV210_PM
+ bool
+ help
+ Power Management code common to S5PV210
+
endif
diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile
index 05048c5aa4c6..ff1a0db57a2f 100644
--- a/arch/arm/mach-s5pv210/Makefile
+++ b/arch/arm/mach-s5pv210/Makefile
@@ -14,6 +14,8 @@ obj- :=
obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o dma.o gpiolib.o
obj-$(CONFIG_CPU_S5PV210) += setup-i2c0.o
+obj-$(CONFIG_S5PV210_PM) += pm.o sleep.o
+obj-$(CONFIG_CPU_FREQ) += cpufreq.o
# machine support
@@ -21,12 +23,12 @@ obj-$(CONFIG_MACH_AQUILA) += mach-aquila.o
obj-$(CONFIG_MACH_SMDKV210) += mach-smdkv210.o
obj-$(CONFIG_MACH_SMDKC110) += mach-smdkc110.o
obj-$(CONFIG_MACH_GONI) += mach-goni.o
+obj-$(CONFIG_MACH_TORBRECK) += mach-torbreck.o
# device support
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 d562670e1b0b..019c3a69b0e4 100644
--- a/arch/arm/mach-s5pv210/clock.c
+++ b/arch/arm/mach-s5pv210/clock.c
@@ -31,6 +31,8 @@
#include <plat/clock-clksrc.h>
#include <plat/s5pv210.h>
+static unsigned long xtal;
+
static struct clksrc_clk clk_mout_apll = {
.clk = {
.name = "mout_apll",
@@ -259,6 +261,36 @@ static struct clksrc_clk clk_sclk_vpll = {
.reg_src = { .reg = S5P_CLK_SRC0, .shift = 12, .size = 1 },
};
+static struct clk *clkset_moutdmc0src_list[] = {
+ [0] = &clk_sclk_a2m.clk,
+ [1] = &clk_mout_mpll.clk,
+ [2] = NULL,
+ [3] = NULL,
+};
+
+static struct clksrc_sources clkset_moutdmc0src = {
+ .sources = clkset_moutdmc0src_list,
+ .nr_sources = ARRAY_SIZE(clkset_moutdmc0src_list),
+};
+
+static struct clksrc_clk clk_mout_dmc0 = {
+ .clk = {
+ .name = "mout_dmc0",
+ .id = -1,
+ },
+ .sources = &clkset_moutdmc0src,
+ .reg_src = { .reg = S5P_CLK_SRC6, .shift = 24, .size = 2 },
+};
+
+static struct clksrc_clk clk_sclk_dmc0 = {
+ .clk = {
+ .name = "sclk_dmc0",
+ .id = -1,
+ .parent = &clk_mout_dmc0.clk,
+ },
+ .reg_div = { .reg = S5P_CLK_DIV6, .shift = 28, .size = 4 },
+};
+
static unsigned long s5pv210_clk_imem_get_rate(struct clk *clk)
{
return clk_get_rate(clk->parent) / 2;
@@ -268,8 +300,29 @@ static struct clk_ops clk_hclk_imem_ops = {
.get_rate = s5pv210_clk_imem_get_rate,
};
+static unsigned long s5pv210_clk_fout_apll_get_rate(struct clk *clk)
+{
+ return s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
+}
+
+static struct clk_ops clk_fout_apll_ops = {
+ .get_rate = s5pv210_clk_fout_apll_get_rate,
+};
+
static struct clk init_clocks_disable[] = {
{
+ .name = "pdma",
+ .id = 0,
+ .parent = &clk_hclk_psys.clk,
+ .enable = s5pv210_clk_ip0_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "pdma",
+ .id = 1,
+ .parent = &clk_hclk_psys.clk,
+ .enable = s5pv210_clk_ip0_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
.name = "rot",
.id = -1,
.parent = &clk_hclk_dsys.clk,
@@ -431,6 +484,12 @@ static struct clk init_clocks_disable[] = {
.parent = &clk_p,
.enable = s5pv210_clk_ip3_ctrl,
.ctrlbit = (1 << 6),
+ }, {
+ .name = "spdif",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1 << 0),
},
};
@@ -660,6 +719,53 @@ static struct clksrc_sources clkset_sclk_spdif = {
.nr_sources = ARRAY_SIZE(clkset_sclk_spdif_list),
};
+static int s5pv210_spdif_set_rate(struct clk *clk, unsigned long rate)
+{
+ struct clk *pclk;
+ int ret;
+
+ pclk = clk_get_parent(clk);
+ if (IS_ERR(pclk))
+ return -EINVAL;
+
+ ret = pclk->ops->set_rate(pclk, rate);
+ clk_put(pclk);
+
+ return ret;
+}
+
+static unsigned long s5pv210_spdif_get_rate(struct clk *clk)
+{
+ struct clk *pclk;
+ int rate;
+
+ pclk = clk_get_parent(clk);
+ if (IS_ERR(pclk))
+ return -EINVAL;
+
+ rate = pclk->ops->get_rate(clk);
+ clk_put(pclk);
+
+ return rate;
+}
+
+static struct clk_ops s5pv210_sclk_spdif_ops = {
+ .set_rate = s5pv210_spdif_set_rate,
+ .get_rate = s5pv210_spdif_get_rate,
+};
+
+static struct clksrc_clk clk_sclk_spdif = {
+ .clk = {
+ .name = "sclk_spdif",
+ .id = -1,
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 27),
+ .ops = &s5pv210_sclk_spdif_ops,
+ },
+ .sources = &clkset_sclk_spdif,
+ .reg_src = { .reg = S5P_CLK_SRC6, .shift = 12, .size = 2 },
+};
+
static struct clk *clkset_group2_list[] = {
[0] = &clk_ext_xtal_mux,
[1] = &clk_xusbxti,
@@ -744,15 +850,6 @@ static struct clksrc_clk clksrcs[] = {
.sources = &clkset_sclk_mixer,
.reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 1 },
}, {
- .clk = {
- .name = "sclk_spdif",
- .id = -1,
- .enable = s5pv210_clk_mask0_ctrl,
- .ctrlbit = (1 << 27),
- },
- .sources = &clkset_sclk_spdif,
- .reg_src = { .reg = S5P_CLK_SRC6, .shift = 12, .size = 2 },
- }, {
.clk = {
.name = "sclk_fimc",
.id = 0,
@@ -953,12 +1050,93 @@ static struct clksrc_clk *sysclks[] = {
&clk_sclk_dac,
&clk_sclk_pixel,
&clk_sclk_hdmi,
+ &clk_mout_dmc0,
+ &clk_sclk_dmc0,
+ &clk_sclk_audio0,
+ &clk_sclk_audio1,
+ &clk_sclk_audio2,
+ &clk_sclk_spdif,
+};
+
+static u32 epll_div[][6] = {
+ { 48000000, 0, 48, 3, 3, 0 },
+ { 96000000, 0, 48, 3, 2, 0 },
+ { 144000000, 1, 72, 3, 2, 0 },
+ { 192000000, 0, 48, 3, 1, 0 },
+ { 288000000, 1, 72, 3, 1, 0 },
+ { 32750000, 1, 65, 3, 4, 35127 },
+ { 32768000, 1, 65, 3, 4, 35127 },
+ { 45158400, 0, 45, 3, 3, 10355 },
+ { 45000000, 0, 45, 3, 3, 10355 },
+ { 45158000, 0, 45, 3, 3, 10355 },
+ { 49125000, 0, 49, 3, 3, 9961 },
+ { 49152000, 0, 49, 3, 3, 9961 },
+ { 67737600, 1, 67, 3, 3, 48366 },
+ { 67738000, 1, 67, 3, 3, 48366 },
+ { 73800000, 1, 73, 3, 3, 47710 },
+ { 73728000, 1, 73, 3, 3, 47710 },
+ { 36000000, 1, 32, 3, 4, 0 },
+ { 60000000, 1, 60, 3, 3, 0 },
+ { 72000000, 1, 72, 3, 3, 0 },
+ { 80000000, 1, 80, 3, 3, 0 },
+ { 84000000, 0, 42, 3, 2, 0 },
+ { 50000000, 0, 50, 3, 3, 0 },
+};
+
+static int s5pv210_epll_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int epll_con, epll_con_k;
+ unsigned int i;
+
+ /* Return if nothing changed */
+ if (clk->rate == rate)
+ return 0;
+
+ epll_con = __raw_readl(S5P_EPLL_CON);
+ epll_con_k = __raw_readl(S5P_EPLL_CON1);
+
+ epll_con_k &= ~PLL46XX_KDIV_MASK;
+ epll_con &= ~(1 << 27 |
+ PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT |
+ PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT |
+ PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
+
+ for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
+ if (epll_div[i][0] == rate) {
+ epll_con_k |= epll_div[i][5] << 0;
+ epll_con |= (epll_div[i][1] << 27 |
+ epll_div[i][2] << PLL46XX_MDIV_SHIFT |
+ epll_div[i][3] << PLL46XX_PDIV_SHIFT |
+ epll_div[i][4] << PLL46XX_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_CON1);
+
+ printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
+ clk->rate, rate);
+
+ clk->rate = rate;
+
+ return 0;
+}
+
+static struct clk_ops s5pv210_epll_ops = {
+ .set_rate = s5pv210_epll_set_rate,
+ .get_rate = s5p_epll_get_rate,
};
void __init_or_cpufreq s5pv210_setup_clocks(void)
{
struct clk *xtal_clk;
- unsigned long xtal;
unsigned long vpllsrc;
unsigned long armclk;
unsigned long hclk_msys;
@@ -974,6 +1152,10 @@ void __init_or_cpufreq s5pv210_setup_clocks(void)
unsigned int ptr;
u32 clkdiv0, clkdiv1;
+ /* Set functions for clk_fout_epll */
+ clk_fout_epll.enable = s5p_epll_enable;
+ clk_fout_epll.ops = &s5pv210_epll_ops;
+
printk(KERN_DEBUG "%s: registering clocks\n", __func__);
clkdiv0 = __raw_readl(S5P_CLK_DIV0);
@@ -992,11 +1174,12 @@ void __init_or_cpufreq s5pv210_setup_clocks(void)
apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502);
- epll = s5p_get_pll45xx(xtal, __raw_readl(S5P_EPLL_CON), pll_4500);
+ epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON),
+ __raw_readl(S5P_EPLL_CON1), pll_4600);
vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
vpll = s5p_get_pll45xx(vpllsrc, __raw_readl(S5P_VPLL_CON), pll_4502);
- clk_fout_apll.rate = apll;
+ clk_fout_apll.ops = &clk_fout_apll_ops;
clk_fout_mpll.rate = mpll;
clk_fout_epll.rate = epll;
clk_fout_vpll.rate = vpll;
diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c
index 245b82b53df4..8eb480e201b0 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
@@ -51,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,
@@ -61,10 +76,30 @@ 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,
.type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_DMC0,
+ .pfn = __phys_to_pfn(S5PV210_PA_DMC0),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_DMC1,
+ .pfn = __phys_to_pfn(S5PV210_PA_DMC1),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_USB_HSPHY,
+ .pfn =__phys_to_pfn(S5PV210_PA_HSPHY),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
}
};
diff --git a/arch/arm/mach-s5pv210/cpufreq.c b/arch/arm/mach-s5pv210/cpufreq.c
new file mode 100644
index 000000000000..a6f22920a2c2
--- /dev/null
+++ b/arch/arm/mach-s5pv210/cpufreq.c
@@ -0,0 +1,484 @@
+/* linux/arch/arm/mach-s5pv210/cpufreq.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * CPU frequency scaling for S5PC110/S5PV210
+ *
+ * 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/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/cpufreq.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+
+static struct clk *cpu_clk;
+static struct clk *dmc0_clk;
+static struct clk *dmc1_clk;
+static struct cpufreq_freqs freqs;
+
+/* APLL M,P,S values for 1G/800Mhz */
+#define APLL_VAL_1000 ((1 << 31) | (125 << 16) | (3 << 8) | 1)
+#define APLL_VAL_800 ((1 << 31) | (100 << 16) | (3 << 8) | 1)
+
+/*
+ * DRAM configurations to calculate refresh counter for changing
+ * frequency of memory.
+ */
+struct dram_conf {
+ unsigned long freq; /* HZ */
+ unsigned long refresh; /* DRAM refresh counter * 1000 */
+};
+
+/* DRAM configuration (DMC0 and DMC1) */
+static struct dram_conf s5pv210_dram_conf[2];
+
+enum perf_level {
+ L0, L1, L2, L3, L4,
+};
+
+enum s5pv210_mem_type {
+ LPDDR = 0x1,
+ LPDDR2 = 0x2,
+ DDR2 = 0x4,
+};
+
+enum s5pv210_dmc_port {
+ DMC0 = 0,
+ DMC1,
+};
+
+static struct cpufreq_frequency_table s5pv210_freq_table[] = {
+ {L0, 1000*1000},
+ {L1, 800*1000},
+ {L2, 400*1000},
+ {L3, 200*1000},
+ {L4, 100*1000},
+ {0, CPUFREQ_TABLE_END},
+};
+
+static u32 clkdiv_val[5][11] = {
+ /*
+ * Clock divider value for following
+ * { APLL, A2M, HCLK_MSYS, PCLK_MSYS,
+ * HCLK_DSYS, PCLK_DSYS, HCLK_PSYS, PCLK_PSYS,
+ * ONEDRAM, MFC, G3D }
+ */
+
+ /* L0 : [1000/200/100][166/83][133/66][200/200] */
+ {0, 4, 4, 1, 3, 1, 4, 1, 3, 0, 0},
+
+ /* L1 : [800/200/100][166/83][133/66][200/200] */
+ {0, 3, 3, 1, 3, 1, 4, 1, 3, 0, 0},
+
+ /* L2 : [400/200/100][166/83][133/66][200/200] */
+ {1, 3, 1, 1, 3, 1, 4, 1, 3, 0, 0},
+
+ /* L3 : [200/200/100][166/83][133/66][200/200] */
+ {3, 3, 1, 1, 3, 1, 4, 1, 3, 0, 0},
+
+ /* L4 : [100/100/100][83/83][66/66][100/100] */
+ {7, 7, 0, 0, 7, 0, 9, 0, 7, 0, 0},
+};
+
+/*
+ * This function set DRAM refresh counter
+ * accoriding to operating frequency of DRAM
+ * ch: DMC port number 0 or 1
+ * freq: Operating frequency of DRAM(KHz)
+ */
+static void s5pv210_set_refresh(enum s5pv210_dmc_port ch, unsigned long freq)
+{
+ unsigned long tmp, tmp1;
+ void __iomem *reg = NULL;
+
+ if (ch == DMC0)
+ reg = (S5P_VA_DMC0 + 0x30);
+ else if (ch == DMC1)
+ reg = (S5P_VA_DMC1 + 0x30);
+ else
+ printk(KERN_ERR "Cannot find DMC port\n");
+
+ /* Find current DRAM frequency */
+ tmp = s5pv210_dram_conf[ch].freq;
+
+ do_div(tmp, freq);
+
+ tmp1 = s5pv210_dram_conf[ch].refresh;
+
+ do_div(tmp1, tmp);
+
+ __raw_writel(tmp1, reg);
+}
+
+int s5pv210_verify_speed(struct cpufreq_policy *policy)
+{
+ if (policy->cpu)
+ return -EINVAL;
+
+ return cpufreq_frequency_table_verify(policy, s5pv210_freq_table);
+}
+
+unsigned int s5pv210_getspeed(unsigned int cpu)
+{
+ if (cpu)
+ return 0;
+
+ return clk_get_rate(cpu_clk) / 1000;
+}
+
+static int s5pv210_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ unsigned long reg;
+ unsigned int index, priv_index;
+ unsigned int pll_changing = 0;
+ unsigned int bus_speed_changing = 0;
+
+ freqs.old = s5pv210_getspeed(0);
+
+ if (cpufreq_frequency_table_target(policy, s5pv210_freq_table,
+ target_freq, relation, &index))
+ return -EINVAL;
+
+ freqs.new = s5pv210_freq_table[index].frequency;
+ freqs.cpu = 0;
+
+ if (freqs.new == freqs.old)
+ return 0;
+
+ /* Finding current running level index */
+ if (cpufreq_frequency_table_target(policy, s5pv210_freq_table,
+ freqs.old, relation, &priv_index))
+ return -EINVAL;
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ if (freqs.new > freqs.old) {
+ /* Voltage up: will be implemented */
+ }
+
+ /* Check if there need to change PLL */
+ if ((index == L0) || (priv_index == L0))
+ pll_changing = 1;
+
+ /* Check if there need to change System bus clock */
+ if ((index == L4) || (priv_index == L4))
+ bus_speed_changing = 1;
+
+ if (bus_speed_changing) {
+ /*
+ * Reconfigure DRAM refresh counter value for minimum
+ * temporary clock while changing divider.
+ * expected clock is 83Mhz : 7.8usec/(1/83Mhz) = 0x287
+ */
+ if (pll_changing)
+ s5pv210_set_refresh(DMC1, 83000);
+ else
+ s5pv210_set_refresh(DMC1, 100000);
+
+ s5pv210_set_refresh(DMC0, 83000);
+ }
+
+ /*
+ * APLL should be changed in this level
+ * APLL -> MPLL(for stable transition) -> APLL
+ * Some clock source's clock API are not prepared.
+ * Do not use clock API in below code.
+ */
+ if (pll_changing) {
+ /*
+ * 1. Temporary Change divider for MFC and G3D
+ * SCLKA2M(200/1=200)->(200/4=50)Mhz
+ */
+ reg = __raw_readl(S5P_CLK_DIV2);
+ reg &= ~(S5P_CLKDIV2_G3D_MASK | S5P_CLKDIV2_MFC_MASK);
+ reg |= (3 << S5P_CLKDIV2_G3D_SHIFT) |
+ (3 << S5P_CLKDIV2_MFC_SHIFT);
+ __raw_writel(reg, S5P_CLK_DIV2);
+
+ /* For MFC, G3D dividing */
+ do {
+ reg = __raw_readl(S5P_CLKDIV_STAT0);
+ } while (reg & ((1 << 16) | (1 << 17)));
+
+ /*
+ * 2. Change SCLKA2M(200Mhz)to SCLKMPLL in MFC_MUX, G3D MUX
+ * (200/4=50)->(667/4=166)Mhz
+ */
+ reg = __raw_readl(S5P_CLK_SRC2);
+ reg &= ~(S5P_CLKSRC2_G3D_MASK | S5P_CLKSRC2_MFC_MASK);
+ reg |= (1 << S5P_CLKSRC2_G3D_SHIFT) |
+ (1 << S5P_CLKSRC2_MFC_SHIFT);
+ __raw_writel(reg, S5P_CLK_SRC2);
+
+ do {
+ reg = __raw_readl(S5P_CLKMUX_STAT1);
+ } while (reg & ((1 << 7) | (1 << 3)));
+
+ /*
+ * 3. DMC1 refresh count for 133Mhz if (index == L4) is
+ * true refresh counter is already programed in upper
+ * code. 0x287@83Mhz
+ */
+ if (!bus_speed_changing)
+ s5pv210_set_refresh(DMC1, 133000);
+
+ /* 4. SCLKAPLL -> SCLKMPLL */
+ reg = __raw_readl(S5P_CLK_SRC0);
+ reg &= ~(S5P_CLKSRC0_MUX200_MASK);
+ reg |= (0x1 << S5P_CLKSRC0_MUX200_SHIFT);
+ __raw_writel(reg, S5P_CLK_SRC0);
+
+ do {
+ reg = __raw_readl(S5P_CLKMUX_STAT0);
+ } while (reg & (0x1 << 18));
+
+ }
+
+ /* Change divider */
+ reg = __raw_readl(S5P_CLK_DIV0);
+
+ reg &= ~(S5P_CLKDIV0_APLL_MASK | S5P_CLKDIV0_A2M_MASK |
+ S5P_CLKDIV0_HCLK200_MASK | S5P_CLKDIV0_PCLK100_MASK |
+ S5P_CLKDIV0_HCLK166_MASK | S5P_CLKDIV0_PCLK83_MASK |
+ S5P_CLKDIV0_HCLK133_MASK | S5P_CLKDIV0_PCLK66_MASK);
+
+ reg |= ((clkdiv_val[index][0] << S5P_CLKDIV0_APLL_SHIFT) |
+ (clkdiv_val[index][1] << S5P_CLKDIV0_A2M_SHIFT) |
+ (clkdiv_val[index][2] << S5P_CLKDIV0_HCLK200_SHIFT) |
+ (clkdiv_val[index][3] << S5P_CLKDIV0_PCLK100_SHIFT) |
+ (clkdiv_val[index][4] << S5P_CLKDIV0_HCLK166_SHIFT) |
+ (clkdiv_val[index][5] << S5P_CLKDIV0_PCLK83_SHIFT) |
+ (clkdiv_val[index][6] << S5P_CLKDIV0_HCLK133_SHIFT) |
+ (clkdiv_val[index][7] << S5P_CLKDIV0_PCLK66_SHIFT));
+
+ __raw_writel(reg, S5P_CLK_DIV0);
+
+ do {
+ reg = __raw_readl(S5P_CLKDIV_STAT0);
+ } while (reg & 0xff);
+
+ /* ARM MCS value changed */
+ reg = __raw_readl(S5P_ARM_MCS_CON);
+ reg &= ~0x3;
+ if (index >= L3)
+ reg |= 0x3;
+ else
+ reg |= 0x1;
+
+ __raw_writel(reg, S5P_ARM_MCS_CON);
+
+ if (pll_changing) {
+ /* 5. Set Lock time = 30us*24Mhz = 0x2cf */
+ __raw_writel(0x2cf, S5P_APLL_LOCK);
+
+ /*
+ * 6. Turn on APLL
+ * 6-1. Set PMS values
+ * 6-2. Wait untile the PLL is locked
+ */
+ if (index == L0)
+ __raw_writel(APLL_VAL_1000, S5P_APLL_CON);
+ else
+ __raw_writel(APLL_VAL_800, S5P_APLL_CON);
+
+ do {
+ reg = __raw_readl(S5P_APLL_CON);
+ } while (!(reg & (0x1 << 29)));
+
+ /*
+ * 7. Change souce clock from SCLKMPLL(667Mhz)
+ * to SCLKA2M(200Mhz) in MFC_MUX and G3D MUX
+ * (667/4=166)->(200/4=50)Mhz
+ */
+ reg = __raw_readl(S5P_CLK_SRC2);
+ reg &= ~(S5P_CLKSRC2_G3D_MASK | S5P_CLKSRC2_MFC_MASK);
+ reg |= (0 << S5P_CLKSRC2_G3D_SHIFT) |
+ (0 << S5P_CLKSRC2_MFC_SHIFT);
+ __raw_writel(reg, S5P_CLK_SRC2);
+
+ do {
+ reg = __raw_readl(S5P_CLKMUX_STAT1);
+ } while (reg & ((1 << 7) | (1 << 3)));
+
+ /*
+ * 8. Change divider for MFC and G3D
+ * (200/4=50)->(200/1=200)Mhz
+ */
+ reg = __raw_readl(S5P_CLK_DIV2);
+ reg &= ~(S5P_CLKDIV2_G3D_MASK | S5P_CLKDIV2_MFC_MASK);
+ reg |= (clkdiv_val[index][10] << S5P_CLKDIV2_G3D_SHIFT) |
+ (clkdiv_val[index][9] << S5P_CLKDIV2_MFC_SHIFT);
+ __raw_writel(reg, S5P_CLK_DIV2);
+
+ /* For MFC, G3D dividing */
+ do {
+ reg = __raw_readl(S5P_CLKDIV_STAT0);
+ } while (reg & ((1 << 16) | (1 << 17)));
+
+ /* 9. Change MPLL to APLL in MSYS_MUX */
+ reg = __raw_readl(S5P_CLK_SRC0);
+ reg &= ~(S5P_CLKSRC0_MUX200_MASK);
+ reg |= (0x0 << S5P_CLKSRC0_MUX200_SHIFT);
+ __raw_writel(reg, S5P_CLK_SRC0);
+
+ do {
+ reg = __raw_readl(S5P_CLKMUX_STAT0);
+ } while (reg & (0x1 << 18));
+
+ /*
+ * 10. DMC1 refresh counter
+ * L4 : DMC1 = 100Mhz 7.8us/(1/100) = 0x30c
+ * Others : DMC1 = 200Mhz 7.8us/(1/200) = 0x618
+ */
+ if (!bus_speed_changing)
+ s5pv210_set_refresh(DMC1, 200000);
+ }
+
+ /*
+ * L4 level need to change memory bus speed, hence onedram clock divier
+ * and memory refresh parameter should be changed
+ */
+ if (bus_speed_changing) {
+ reg = __raw_readl(S5P_CLK_DIV6);
+ reg &= ~S5P_CLKDIV6_ONEDRAM_MASK;
+ reg |= (clkdiv_val[index][8] << S5P_CLKDIV6_ONEDRAM_SHIFT);
+ __raw_writel(reg, S5P_CLK_DIV6);
+
+ do {
+ reg = __raw_readl(S5P_CLKDIV_STAT1);
+ } while (reg & (1 << 15));
+
+ /* Reconfigure DRAM refresh counter value */
+ if (index != L4) {
+ /*
+ * DMC0 : 166Mhz
+ * DMC1 : 200Mhz
+ */
+ s5pv210_set_refresh(DMC0, 166000);
+ s5pv210_set_refresh(DMC1, 200000);
+ } else {
+ /*
+ * DMC0 : 83Mhz
+ * DMC1 : 100Mhz
+ */
+ s5pv210_set_refresh(DMC0, 83000);
+ s5pv210_set_refresh(DMC1, 100000);
+ }
+ }
+
+ if (freqs.new < freqs.old) {
+ /* Voltage down: will be implemented */
+ }
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ printk(KERN_DEBUG "Perf changed[L%d]\n", index);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int s5pv210_cpufreq_suspend(struct cpufreq_policy *policy,
+ pm_message_t pmsg)
+{
+ return 0;
+}
+
+static int s5pv210_cpufreq_resume(struct cpufreq_policy *policy)
+{
+ return 0;
+}
+#endif
+
+static int check_mem_type(void __iomem *dmc_reg)
+{
+ unsigned long val;
+
+ val = __raw_readl(dmc_reg + 0x4);
+ val = (val & (0xf << 8));
+
+ return val >> 8;
+}
+
+static int __init s5pv210_cpu_init(struct cpufreq_policy *policy)
+{
+ unsigned long mem_type;
+
+ cpu_clk = clk_get(NULL, "armclk");
+ if (IS_ERR(cpu_clk))
+ return PTR_ERR(cpu_clk);
+
+ dmc0_clk = clk_get(NULL, "sclk_dmc0");
+ if (IS_ERR(dmc0_clk)) {
+ clk_put(cpu_clk);
+ return PTR_ERR(dmc0_clk);
+ }
+
+ dmc1_clk = clk_get(NULL, "hclk_msys");
+ if (IS_ERR(dmc1_clk)) {
+ clk_put(dmc0_clk);
+ clk_put(cpu_clk);
+ return PTR_ERR(dmc1_clk);
+ }
+
+ if (policy->cpu != 0)
+ return -EINVAL;
+
+ /*
+ * check_mem_type : This driver only support LPDDR & LPDDR2.
+ * other memory type is not supported.
+ */
+ mem_type = check_mem_type(S5P_VA_DMC0);
+
+ if ((mem_type != LPDDR) && (mem_type != LPDDR2)) {
+ printk(KERN_ERR "CPUFreq doesn't support this memory type\n");
+ return -EINVAL;
+ }
+
+ /* Find current refresh counter and frequency each DMC */
+ s5pv210_dram_conf[0].refresh = (__raw_readl(S5P_VA_DMC0 + 0x30) * 1000);
+ s5pv210_dram_conf[0].freq = clk_get_rate(dmc0_clk);
+
+ s5pv210_dram_conf[1].refresh = (__raw_readl(S5P_VA_DMC1 + 0x30) * 1000);
+ s5pv210_dram_conf[1].freq = clk_get_rate(dmc1_clk);
+
+ policy->cur = policy->min = policy->max = s5pv210_getspeed(0);
+
+ cpufreq_frequency_table_get_attr(s5pv210_freq_table, policy->cpu);
+
+ policy->cpuinfo.transition_latency = 40000;
+
+ return cpufreq_frequency_table_cpuinfo(policy, s5pv210_freq_table);
+}
+
+static struct cpufreq_driver s5pv210_driver = {
+ .flags = CPUFREQ_STICKY,
+ .verify = s5pv210_verify_speed,
+ .target = s5pv210_target,
+ .get = s5pv210_getspeed,
+ .init = s5pv210_cpu_init,
+ .name = "s5pv210",
+#ifdef CONFIG_PM
+ .suspend = s5pv210_cpufreq_suspend,
+ .resume = s5pv210_cpufreq_resume,
+#endif
+};
+
+static int __init s5pv210_cpufreq_init(void)
+{
+ return cpufreq_register_driver(&s5pv210_driver);
+}
+
+late_initcall(s5pv210_cpufreq_init);
diff --git a/arch/arm/mach-s5pv210/dev-audio.c b/arch/arm/mach-s5pv210/dev-audio.c
index 21dc6cf955c3..1303fcb12b51 100644
--- a/arch/arm/mach-s5pv210/dev-audio.c
+++ b/arch/arm/mach-s5pv210/dev-audio.c
@@ -24,29 +24,15 @@ static int s5pv210_cfg_i2s(struct platform_device *pdev)
/* configure GPIO for i2s port */
switch (pdev->id) {
case 1:
- s3c_gpio_cfgpin(S5PV210_GPC0(0), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5PV210_GPC0(1), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5PV210_GPC0(2), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5PV210_GPC0(3), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5PV210_GPC0(4), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(2));
break;
case 2:
- s3c_gpio_cfgpin(S5PV210_GPC1(0), S3C_GPIO_SFN(4));
- s3c_gpio_cfgpin(S5PV210_GPC1(1), S3C_GPIO_SFN(4));
- s3c_gpio_cfgpin(S5PV210_GPC1(2), S3C_GPIO_SFN(4));
- s3c_gpio_cfgpin(S5PV210_GPC1(3), S3C_GPIO_SFN(4));
- s3c_gpio_cfgpin(S5PV210_GPC1(4), S3C_GPIO_SFN(4));
+ s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 5, S3C_GPIO_SFN(4));
break;
case -1:
- s3c_gpio_cfgpin(S5PV210_GPI(0), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5PV210_GPI(1), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5PV210_GPI(2), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5PV210_GPI(3), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5PV210_GPI(4), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5PV210_GPI(5), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5PV210_GPI(6), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin_range(S5PV210_GPI(0), 7, S3C_GPIO_SFN(2));
break;
default:
@@ -151,25 +137,13 @@ static int s5pv210_pcm_cfg_gpio(struct platform_device *pdev)
{
switch (pdev->id) {
case 0:
- s3c_gpio_cfgpin(S5PV210_GPI(0), S3C_GPIO_SFN(3));
- s3c_gpio_cfgpin(S5PV210_GPI(1), S3C_GPIO_SFN(3));
- s3c_gpio_cfgpin(S5PV210_GPI(2), S3C_GPIO_SFN(3));
- s3c_gpio_cfgpin(S5PV210_GPI(3), S3C_GPIO_SFN(3));
- s3c_gpio_cfgpin(S5PV210_GPI(4), S3C_GPIO_SFN(3));
+ s3c_gpio_cfgpin_range(S5PV210_GPI(0), 5, S3C_GPIO_SFN(3));
break;
case 1:
- s3c_gpio_cfgpin(S5PV210_GPC0(0), S3C_GPIO_SFN(3));
- s3c_gpio_cfgpin(S5PV210_GPC0(1), S3C_GPIO_SFN(3));
- s3c_gpio_cfgpin(S5PV210_GPC0(2), S3C_GPIO_SFN(3));
- s3c_gpio_cfgpin(S5PV210_GPC0(3), S3C_GPIO_SFN(3));
- s3c_gpio_cfgpin(S5PV210_GPC0(4), S3C_GPIO_SFN(3));
+ s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(3));
break;
case 2:
- s3c_gpio_cfgpin(S5PV210_GPC1(0), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5PV210_GPC1(1), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5PV210_GPC1(2), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5PV210_GPC1(3), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5PV210_GPC1(4), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 5, S3C_GPIO_SFN(2));
break;
default:
printk(KERN_DEBUG "Invalid PCM Controller number!");
@@ -271,13 +245,7 @@ struct platform_device s5pv210_device_pcm2 = {
static int s5pv210_ac97_cfg_gpio(struct platform_device *pdev)
{
- s3c_gpio_cfgpin(S5PV210_GPC0(0), S3C_GPIO_SFN(4));
- s3c_gpio_cfgpin(S5PV210_GPC0(1), S3C_GPIO_SFN(4));
- s3c_gpio_cfgpin(S5PV210_GPC0(2), S3C_GPIO_SFN(4));
- s3c_gpio_cfgpin(S5PV210_GPC0(3), S3C_GPIO_SFN(4));
- s3c_gpio_cfgpin(S5PV210_GPC0(4), S3C_GPIO_SFN(4));
-
- return 0;
+ return s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(4));
}
static struct resource s5pv210_ac97_resource[] = {
@@ -325,3 +293,43 @@ struct platform_device s5pv210_device_ac97 = {
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
+
+/* S/PDIF Controller platform_device */
+
+static int s5pv210_spdif_cfg_gpio(struct platform_device *pdev)
+{
+ s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 2, S3C_GPIO_SFN(3));
+
+ return 0;
+}
+
+static struct resource s5pv210_spdif_resource[] = {
+ [0] = {
+ .start = S5PV210_PA_SPDIF,
+ .end = S5PV210_PA_SPDIF + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_SPDIF,
+ .end = DMACH_SPDIF,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct s3c_audio_pdata samsung_spdif_pdata = {
+ .cfg_gpio = s5pv210_spdif_cfg_gpio,
+};
+
+static u64 s5pv210_spdif_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s5pv210_device_spdif = {
+ .name = "samsung-spdif",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5pv210_spdif_resource),
+ .resource = s5pv210_spdif_resource,
+ .dev = {
+ .platform_data = &samsung_spdif_pdata,
+ .dma_mask = &s5pv210_spdif_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
diff --git a/arch/arm/mach-s5pv210/dev-spi.c b/arch/arm/mach-s5pv210/dev-spi.c
index 826cdbc43e20..e3249a47e3b1 100644
--- a/arch/arm/mach-s5pv210/dev-spi.c
+++ b/arch/arm/mach-s5pv210/dev-spi.c
@@ -35,23 +35,15 @@ static char *spi_src_clks[] = {
*/
static int s5pv210_spi_cfg_gpio(struct platform_device *pdev)
{
+ unsigned int base;
+
switch (pdev->id) {
case 0:
- s3c_gpio_cfgpin(S5PV210_GPB(0), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5PV210_GPB(1), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5PV210_GPB(2), S3C_GPIO_SFN(2));
- s3c_gpio_setpull(S5PV210_GPB(0), S3C_GPIO_PULL_UP);
- s3c_gpio_setpull(S5PV210_GPB(1), S3C_GPIO_PULL_UP);
- s3c_gpio_setpull(S5PV210_GPB(2), S3C_GPIO_PULL_UP);
+ base = S5PV210_GPB(0);
break;
case 1:
- s3c_gpio_cfgpin(S5PV210_GPB(4), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5PV210_GPB(5), S3C_GPIO_SFN(2));
- s3c_gpio_cfgpin(S5PV210_GPB(6), S3C_GPIO_SFN(2));
- s3c_gpio_setpull(S5PV210_GPB(4), S3C_GPIO_PULL_UP);
- s3c_gpio_setpull(S5PV210_GPB(5), S3C_GPIO_PULL_UP);
- s3c_gpio_setpull(S5PV210_GPB(6), S3C_GPIO_PULL_UP);
+ base = S5PV210_GPB(4);
break;
default:
@@ -59,6 +51,9 @@ static int s5pv210_spi_cfg_gpio(struct platform_device *pdev)
return -EINVAL;
}
+ s3c_gpio_cfgall_range(base, 3,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+
return 0;
}
diff --git a/arch/arm/mach-s5pv210/dma.c b/arch/arm/mach-s5pv210/dma.c
index 778ad5fe231a..497d3439a142 100644
--- a/arch/arm/mach-s5pv210/dma.c
+++ b/arch/arm/mach-s5pv210/dma.c
@@ -82,7 +82,7 @@ static struct s3c_pl330_platdata s5pv210_pdma0_pdata = {
static struct platform_device s5pv210_device_pdma0 = {
.name = "s3c-pl330",
- .id = 1,
+ .id = 0,
.num_resources = ARRAY_SIZE(s5pv210_pdma0_resource),
.resource = s5pv210_pdma0_resource,
.dev = {
@@ -144,7 +144,7 @@ static struct s3c_pl330_platdata s5pv210_pdma1_pdata = {
static struct platform_device s5pv210_device_pdma1 = {
.name = "s3c-pl330",
- .id = 2,
+ .id = 1,
.num_resources = ARRAY_SIZE(s5pv210_pdma1_resource),
.resource = s5pv210_pdma1_resource,
.dev = {
diff --git a/arch/arm/mach-s5pv210/gpiolib.c b/arch/arm/mach-s5pv210/gpiolib.c
index 0d459112d039..ab673effd767 100644
--- a/arch/arm/mach-s5pv210/gpiolib.c
+++ b/arch/arm/mach-s5pv210/gpiolib.c
@@ -150,6 +150,7 @@ static struct s3c_gpio_chip s5pv210_gpio_4bit[] = {
.label = "GPG3",
},
}, {
+ .config = &gpio_cfg_noint,
.chip = {
.base = S5PV210_GPI(0),
.ngpio = S5PV210_GPIO_I_NR,
@@ -223,34 +224,42 @@ static struct s3c_gpio_chip s5pv210_gpio_4bit[] = {
}, {
.base = (S5P_VA_GPIO + 0xC00),
.config = &gpio_cfg_noint,
+ .irq_base = IRQ_EINT(0),
.chip = {
.base = S5PV210_GPH0(0),
.ngpio = S5PV210_GPIO_H0_NR,
.label = "GPH0",
+ .to_irq = samsung_gpiolib_to_irq,
},
}, {
.base = (S5P_VA_GPIO + 0xC20),
.config = &gpio_cfg_noint,
+ .irq_base = IRQ_EINT(8),
.chip = {
.base = S5PV210_GPH1(0),
.ngpio = S5PV210_GPIO_H1_NR,
.label = "GPH1",
+ .to_irq = samsung_gpiolib_to_irq,
},
}, {
.base = (S5P_VA_GPIO + 0xC40),
.config = &gpio_cfg_noint,
+ .irq_base = IRQ_EINT(16),
.chip = {
.base = S5PV210_GPH2(0),
.ngpio = S5PV210_GPIO_H2_NR,
.label = "GPH2",
+ .to_irq = samsung_gpiolib_to_irq,
},
}, {
.base = (S5P_VA_GPIO + 0xC60),
.config = &gpio_cfg_noint,
+ .irq_base = IRQ_EINT(24),
.chip = {
.base = S5PV210_GPH3(0),
.ngpio = S5PV210_GPIO_H3_NR,
.label = "GPH3",
+ .to_irq = samsung_gpiolib_to_irq,
},
},
};
@@ -259,11 +268,14 @@ static __init int s5pv210_gpiolib_init(void)
{
struct s3c_gpio_chip *chip = s5pv210_gpio_4bit;
int nr_chips = ARRAY_SIZE(s5pv210_gpio_4bit);
+ int gpioint_group = 0;
int i = 0;
for (i = 0; i < nr_chips; i++, chip++) {
- if (chip->config == NULL)
+ if (chip->config == NULL) {
chip->config = &gpio_cfg;
+ chip->group = gpioint_group++;
+ }
if (chip->base == NULL)
chip->base = S5PV210_BANK_BASE(i);
}
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/irqs.h b/arch/arm/mach-s5pv210/include/mach/irqs.h
index e1c020e5a49b..119b95fdc3ce 100644
--- a/arch/arm/mach-s5pv210/include/mach/irqs.h
+++ b/arch/arm/mach-s5pv210/include/mach/irqs.h
@@ -55,8 +55,8 @@
#define IRQ_SPI1 S5P_IRQ_VIC1(16)
#define IRQ_SPI2 S5P_IRQ_VIC1(17)
#define IRQ_IRDA S5P_IRQ_VIC1(18)
-#define IRQ_CAN0 S5P_IRQ_VIC1(19)
-#define IRQ_CAN1 S5P_IRQ_VIC1(20)
+#define IRQ_IIC2 S5P_IRQ_VIC1(19)
+#define IRQ_IIC3 S5P_IRQ_VIC1(20)
#define IRQ_HSIRX S5P_IRQ_VIC1(21)
#define IRQ_HSITX S5P_IRQ_VIC1(22)
#define IRQ_UHOST S5P_IRQ_VIC1(23)
@@ -109,7 +109,7 @@
#define IRQ_IPC S5P_IRQ_VIC3(0)
#define IRQ_HOSTIF S5P_IRQ_VIC3(1)
-#define IRQ_MMC3 S5P_IRQ_VIC3(2)
+#define IRQ_HSMMC3 S5P_IRQ_VIC3(2)
#define IRQ_CEC S5P_IRQ_VIC3(3)
#define IRQ_TSI S5P_IRQ_VIC3(4)
#define IRQ_MDNIE0 S5P_IRQ_VIC3(5)
@@ -121,8 +121,12 @@
#define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0))
#define S5P_EINT_BASE2 (IRQ_VIC_END + 1)
+/* GPIO interrupt */
+#define S5P_GPIOINT_BASE (IRQ_EINT(31) + 1)
+#define S5P_GPIOINT_GROUP_MAXNR 22
+
/* Set the default NR_IRQS */
-#define NR_IRQS (IRQ_EINT(31) + 1)
+#define NR_IRQS (IRQ_EINT(31) + S5P_GPIOINT_COUNT + 1)
/* Compatibility */
#define IRQ_LCD_FIFO IRQ_LCD0
diff --git a/arch/arm/mach-s5pv210/include/mach/map.h b/arch/arm/mach-s5pv210/include/mach/map.h
index dd4fb6bf14b5..861d7fe11fc9 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
@@ -55,6 +57,8 @@
#define S5P_SZ_UART SZ_256
+#define S3C_VA_UARTx(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET))
+
#define S5PV210_PA_SROMC (0xE8000000)
#define S5PV210_PA_CFCON (0xE8200000)
@@ -71,21 +75,20 @@
#define S5PV210_PA_HSMMC(x) (0xEB000000 + ((x) * 0x100000))
-#define S5PV210_PA_VIC0 (0xF2000000)
-#define S5P_PA_VIC0 S5PV210_PA_VIC0
+#define S5PV210_PA_HSOTG (0xEC000000)
+#define S5PV210_PA_HSPHY (0xEC100000)
+#define S5PV210_PA_VIC0 (0xF2000000)
#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
+/* S/PDIF */
+#define S5PV210_PA_SPDIF 0xE1100000
+
/* I2S */
#define S5PV210_PA_IIS0 0xEEE30000
#define S5PV210_PA_IIS1 0xE2100000
@@ -101,6 +104,9 @@
#define S5PV210_PA_ADC (0xE1700000)
+#define S5PV210_PA_DMC0 (0xF0000000)
+#define S5PV210_PA_DMC1 (0xF1400000)
+
/* compatibiltiy defines. */
#define S3C_PA_UART S5PV210_PA_UART
#define S3C_PA_HSMMC0 S5PV210_PA_HSMMC(0)
@@ -113,6 +119,7 @@
#define S3C_PA_FB S5PV210_PA_FB
#define S3C_PA_RTC S5PV210_PA_RTC
#define S3C_PA_WDT S5PV210_PA_WATCHDOG
+#define S3C_PA_USB_HSOTG S5PV210_PA_HSOTG
#define S5P_PA_FIMC0 S5PV210_PA_FIMC0
#define S5P_PA_FIMC1 S5PV210_PA_FIMC1
#define S5P_PA_FIMC2 S5PV210_PA_FIMC2
diff --git a/arch/arm/mach-s5pv210/include/mach/pm-core.h b/arch/arm/mach-s5pv210/include/mach/pm-core.h
new file mode 100644
index 000000000000..e8d394f8b057
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/pm-core.h
@@ -0,0 +1,43 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/pm-core.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/pm-core.h,
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S5PV210 - PM core support for arch/arm/plat-s5p/pm.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
+ * published by the Free Software Foundation.
+*/
+
+static inline void s3c_pm_debug_init_uart(void)
+{
+ /* nothing here yet */
+}
+
+static inline void s3c_pm_arch_prepare_irqs(void)
+{
+ __raw_writel(s3c_irqwake_intmask, S5P_WAKEUP_MASK);
+ __raw_writel(s3c_irqwake_eintmask, S5P_EINT_WAKEUP_MASK);
+}
+
+static inline void s3c_pm_arch_stop_clocks(void)
+{
+ /* nothing here yet */
+}
+
+static inline void s3c_pm_arch_show_resume_irqs(void)
+{
+ /* nothing here yet */
+}
+
+static inline void s3c_pm_arch_update_uart(void __iomem *regs,
+ struct pm_uart_save *save)
+{
+ /* nothing here yet */
+}
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-clock.h b/arch/arm/mach-s5pv210/include/mach/regs-clock.h
index 499aef737476..ebaabe021af9 100644
--- a/arch/arm/mach-s5pv210/include/mach/regs-clock.h
+++ b/arch/arm/mach-s5pv210/include/mach/regs-clock.h
@@ -25,6 +25,7 @@
#define S5P_APLL_CON S5P_CLKREG(0x100)
#define S5P_MPLL_CON S5P_CLKREG(0x108)
#define S5P_EPLL_CON S5P_CLKREG(0x110)
+#define S5P_EPLL_CON1 S5P_CLKREG(0x114)
#define S5P_VPLL_CON S5P_CLKREG(0x120)
#define S5P_CLK_SRC0 S5P_CLKREG(0x200)
@@ -67,11 +68,28 @@
#define S5P_CLKGATE_BUS1 S5P_CLKREG(0x488)
#define S5P_CLK_OUT S5P_CLKREG(0x500)
+/* DIV/MUX STATUS */
+#define S5P_CLKDIV_STAT0 S5P_CLKREG(0x1000)
+#define S5P_CLKDIV_STAT1 S5P_CLKREG(0x1004)
+#define S5P_CLKMUX_STAT0 S5P_CLKREG(0x1100)
+#define S5P_CLKMUX_STAT1 S5P_CLKREG(0x1104)
+
/* CLKSRC0 */
-#define S5P_CLKSRC0_MUX200_MASK (0x1<<16)
+#define S5P_CLKSRC0_MUX200_SHIFT (16)
+#define S5P_CLKSRC0_MUX200_MASK (0x1 << S5P_CLKSRC0_MUX200_SHIFT)
#define S5P_CLKSRC0_MUX166_MASK (0x1<<20)
#define S5P_CLKSRC0_MUX133_MASK (0x1<<24)
+/* CLKSRC2 */
+#define S5P_CLKSRC2_G3D_SHIFT (0)
+#define S5P_CLKSRC2_G3D_MASK (0x3 << S5P_CLKSRC2_G3D_SHIFT)
+#define S5P_CLKSRC2_MFC_SHIFT (4)
+#define S5P_CLKSRC2_MFC_MASK (0x3 << S5P_CLKSRC2_MFC_SHIFT)
+
+/* CLKSRC6*/
+#define S5P_CLKSRC6_ONEDRAM_SHIFT (24)
+#define S5P_CLKSRC6_ONEDRAM_MASK (0x3 << S5P_CLKSRC6_ONEDRAM_SHIFT)
+
/* CLKDIV0 */
#define S5P_CLKDIV0_APLL_SHIFT (0)
#define S5P_CLKDIV0_APLL_MASK (0x7 << S5P_CLKDIV0_APLL_SHIFT)
@@ -90,12 +108,24 @@
#define S5P_CLKDIV0_PCLK66_SHIFT (28)
#define S5P_CLKDIV0_PCLK66_MASK (0x7 << S5P_CLKDIV0_PCLK66_SHIFT)
+/* CLKDIV2 */
+#define S5P_CLKDIV2_G3D_SHIFT (0)
+#define S5P_CLKDIV2_G3D_MASK (0xF << S5P_CLKDIV2_G3D_SHIFT)
+#define S5P_CLKDIV2_MFC_SHIFT (4)
+#define S5P_CLKDIV2_MFC_MASK (0xF << S5P_CLKDIV2_MFC_SHIFT)
+
+/* CLKDIV6 */
+#define S5P_CLKDIV6_ONEDRAM_SHIFT (28)
+#define S5P_CLKDIV6_ONEDRAM_MASK (0xF << S5P_CLKDIV6_ONEDRAM_SHIFT)
+
#define S5P_SWRESET S5P_CLKREG(0x2000)
+#define S5P_ARM_MCS_CON S5P_CLKREG(0x6100)
+
/* Registers related to power management */
#define S5P_PWR_CFG S5P_CLKREG(0xC000)
#define S5P_EINT_WAKEUP_MASK S5P_CLKREG(0xC004)
-#define S5P_WAKEUP_MASK S5P_CLKREG(0xC008)
+#define S5P_WAKEUP_MASK S5P_CLKREG(0xC008)
#define S5P_PWR_MODE S5P_CLKREG(0xC00C)
#define S5P_NORMAL_CFG S5P_CLKREG(0xC010)
#define S5P_IDLE_CFG S5P_CLKREG(0xC020)
@@ -159,8 +189,11 @@
#define S5P_SLEEP_CFG_USBOSC_EN (1 << 1)
/* OTHERS Resgister */
+#define S5P_OTHERS_RET_IO (1 << 31)
+#define S5P_OTHERS_RET_CF (1 << 30)
+#define S5P_OTHERS_RET_MMC (1 << 29)
+#define S5P_OTHERS_RET_UART (1 << 28)
#define S5P_OTHERS_USB_SIG_MASK (1 << 16)
-#define S5P_OTHERS_MIPI_DPHY_EN (1 << 28)
/* MIPI */
#define S5P_MIPI_DPHY_EN (3)
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-gpio.h b/arch/arm/mach-s5pv210/include/mach/regs-gpio.h
index 49e029b4978a..de0c89976078 100644
--- a/arch/arm/mach-s5pv210/include/mach/regs-gpio.h
+++ b/arch/arm/mach-s5pv210/include/mach/regs-gpio.h
@@ -31,13 +31,6 @@
#define eint_irq_to_bit(irq) (1 << (EINT_OFFSET(irq) & 0x7))
-/* values for S5P_EXTINT0 */
-#define S5P_EXTINT_LOWLEV (0x00)
-#define S5P_EXTINT_HILEV (0x01)
-#define S5P_EXTINT_FALLEDGE (0x02)
-#define S5P_EXTINT_RISEEDGE (0x03)
-#define S5P_EXTINT_BOTHEDGE (0x04)
-
#define EINT_MODE S3C_GPIO_SFN(0xf)
#define EINT_GPIO_0(x) S5PV210_GPH0(x)
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-sys.h b/arch/arm/mach-s5pv210/include/mach/regs-sys.h
new file mode 100644
index 000000000000..26691d39d0f4
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/regs-sys.h
@@ -0,0 +1,19 @@
+/* arch/arm/mach-s5pv210/include/mach/regs-sys.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - System registers 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.
+*/
+
+#define S5PV210_USB_PHY_CON (S3C_VA_SYS + 0xE80C)
+#define S5PV210_USB_PHY0_EN (1 << 0)
+#define S5PV210_USB_PHY1_EN (1 << 1)
+
+/* compatibility defines for s3c-hsotg driver */
+#define S3C64XX_OTHERS S5PV210_USB_PHY_CON
+#define S3C64XX_OTHERS_USBMASK S5PV210_USB_PHY0_EN
diff --git a/arch/arm/mach-s5pv210/include/mach/vmalloc.h b/arch/arm/mach-s5pv210/include/mach/vmalloc.h
index df9a28808323..a6c659d68a5d 100644
--- a/arch/arm/mach-s5pv210/include/mach/vmalloc.h
+++ b/arch/arm/mach-s5pv210/include/mach/vmalloc.h
@@ -17,6 +17,6 @@
#ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H __FILE__
-#define VMALLOC_END (0xE0000000UL)
+#define VMALLOC_END 0xF6000000UL
#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c
index 0dda8012d6b2..28677caf3613 100644
--- a/arch/arm/mach-s5pv210/mach-aquila.c
+++ b/arch/arm/mach-s5pv210/mach-aquila.c
@@ -16,6 +16,8 @@
#include <linux/i2c.h>
#include <linux/i2c-gpio.h>
#include <linux/mfd/max8998.h>
+#include <linux/mfd/wm8994/pdata.h>
+#include <linux/regulator/fixed.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <linux/gpio.h>
@@ -379,6 +381,119 @@ static struct max8998_platform_data aquila_max8998_pdata = {
};
#endif
+static struct regulator_consumer_supply wm8994_fixed_voltage0_supplies[] = {
+ {
+ .dev_name = "5-001a",
+ .supply = "DBVDD",
+ }, {
+ .dev_name = "5-001a",
+ .supply = "AVDD2",
+ }, {
+ .dev_name = "5-001a",
+ .supply = "CPVDD",
+ },
+};
+
+static struct regulator_consumer_supply wm8994_fixed_voltage1_supplies[] = {
+ {
+ .dev_name = "5-001a",
+ .supply = "SPKVDD1",
+ }, {
+ .dev_name = "5-001a",
+ .supply = "SPKVDD2",
+ },
+};
+
+static struct regulator_init_data wm8994_fixed_voltage0_init_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage0_supplies),
+ .consumer_supplies = wm8994_fixed_voltage0_supplies,
+};
+
+static struct regulator_init_data wm8994_fixed_voltage1_init_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage1_supplies),
+ .consumer_supplies = wm8994_fixed_voltage1_supplies,
+};
+
+static struct fixed_voltage_config wm8994_fixed_voltage0_config = {
+ .supply_name = "VCC_1.8V_PDA",
+ .microvolts = 1800000,
+ .gpio = -EINVAL,
+ .init_data = &wm8994_fixed_voltage0_init_data,
+};
+
+static struct fixed_voltage_config wm8994_fixed_voltage1_config = {
+ .supply_name = "V_BAT",
+ .microvolts = 3700000,
+ .gpio = -EINVAL,
+ .init_data = &wm8994_fixed_voltage1_init_data,
+};
+
+static struct platform_device wm8994_fixed_voltage0 = {
+ .name = "reg-fixed-voltage",
+ .id = 0,
+ .dev = {
+ .platform_data = &wm8994_fixed_voltage0_config,
+ },
+};
+
+static struct platform_device wm8994_fixed_voltage1 = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &wm8994_fixed_voltage1_config,
+ },
+};
+
+static struct regulator_consumer_supply wm8994_avdd1_supply = {
+ .dev_name = "5-001a",
+ .supply = "AVDD1",
+};
+
+static struct regulator_consumer_supply wm8994_dcvdd_supply = {
+ .dev_name = "5-001a",
+ .supply = "DCVDD",
+};
+
+static struct regulator_init_data wm8994_ldo1_data = {
+ .constraints = {
+ .name = "AVDD1_3.0V",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &wm8994_avdd1_supply,
+};
+
+static struct regulator_init_data wm8994_ldo2_data = {
+ .constraints = {
+ .name = "DCVDD_1.0V",
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &wm8994_dcvdd_supply,
+};
+
+static struct wm8994_pdata wm8994_platform_data = {
+ /* configure gpio1 function: 0x0001(Logic level input/output) */
+ .gpio_defaults[0] = 0x0001,
+ /* configure gpio3/4/5/7 function for AIF2 voice */
+ .gpio_defaults[2] = 0x8100,
+ .gpio_defaults[3] = 0x8100,
+ .gpio_defaults[4] = 0x8100,
+ .gpio_defaults[6] = 0x0100,
+ /* configure gpio8/9/10/11 function for AIF3 BT */
+ .gpio_defaults[7] = 0x8100,
+ .gpio_defaults[8] = 0x0100,
+ .gpio_defaults[9] = 0x0100,
+ .gpio_defaults[10] = 0x0100,
+ .ldo[0] = { S5PV210_MP03(6), NULL, &wm8994_ldo1_data }, /* XM0FRNB_2 */
+ .ldo[1] = { 0, NULL, &wm8994_ldo2_data },
+};
+
/* GPIO I2C PMIC */
#define AP_I2C_GPIO_PMIC_BUS_4 4
static struct i2c_gpio_platform_data aquila_i2c_gpio_pmic_data = {
@@ -404,6 +519,29 @@ static struct i2c_board_info i2c_gpio_pmic_devs[] __initdata = {
#endif
};
+/* GPIO I2C AP 1.8V */
+#define AP_I2C_GPIO_BUS_5 5
+static struct i2c_gpio_platform_data aquila_i2c_gpio5_data = {
+ .sda_pin = S5PV210_MP05(3), /* XM0ADDR_11 */
+ .scl_pin = S5PV210_MP05(2), /* XM0ADDR_10 */
+};
+
+static struct platform_device aquila_i2c_gpio5 = {
+ .name = "i2c-gpio",
+ .id = AP_I2C_GPIO_BUS_5,
+ .dev = {
+ .platform_data = &aquila_i2c_gpio5_data,
+ },
+};
+
+static struct i2c_board_info i2c_gpio5_devs[] __initdata = {
+ {
+ /* CS/ADDR = low 0x34 (FYI: high = 0x36) */
+ I2C_BOARD_INFO("wm8994", 0x1a),
+ .platform_data = &wm8994_platform_data,
+ },
+};
+
/* PMIC Power button */
static struct gpio_keys_button aquila_gpio_keys_table[] = {
{
@@ -475,17 +613,43 @@ static void aquila_setup_sdhci(void)
static struct platform_device *aquila_devices[] __initdata = {
&aquila_i2c_gpio_pmic,
+ &aquila_i2c_gpio5,
&aquila_device_gpiokeys,
&s3c_device_fb,
- &s5pc110_device_onenand,
+ &s5p_device_onenand,
&s3c_device_hsmmc0,
&s3c_device_hsmmc1,
&s3c_device_hsmmc2,
&s5p_device_fimc0,
&s5p_device_fimc1,
&s5p_device_fimc2,
+ &s5pv210_device_iis0,
+ &wm8994_fixed_voltage0,
+ &wm8994_fixed_voltage1,
};
+static void __init aquila_sound_init(void)
+{
+ unsigned int gpio;
+
+ /* CODEC_XTAL_EN
+ *
+ * The Aquila board have a oscillator which provide main clock
+ * to WM8994 codec. The oscillator provide 24MHz clock to WM8994
+ * clock. Set gpio setting of "CODEC_XTAL_EN" to enable a oscillator.
+ * */
+ gpio = S5PV210_GPH3(2); /* XEINT_26 */
+ gpio_request(gpio, "CODEC_XTAL_EN");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+
+ /* Ths main clock of WM8994 codec uses the output of CLKOUT pin.
+ * The CLKOUT[9:8] set to 0x3(XUSBXTI) of 0xE010E000(OTHERS)
+ * because it needs 24MHz clock to operate WM8994 codec.
+ */
+ __raw_writel(__raw_readl(S5P_OTHERS) | (0x3 << 8), S5P_OTHERS);
+}
+
static void __init aquila_map_io(void)
{
s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -506,6 +670,11 @@ static void __init aquila_machine_init(void)
s3c_fimc_setname(1, "s5p-fimc");
s3c_fimc_setname(2, "s5p-fimc");
+ /* SOUND */
+ aquila_sound_init();
+ i2c_register_board_info(AP_I2C_GPIO_BUS_5, i2c_gpio5_devs,
+ ARRAY_SIZE(i2c_gpio5_devs));
+
/* FB */
s3c_fb_set_platdata(&aquila_lcd_pdata);
@@ -516,8 +685,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..b1dcf964a768 100644
--- a/arch/arm/mach-s5pv210/mach-goni.c
+++ b/arch/arm/mach-s5pv210/mach-goni.c
@@ -15,7 +15,13 @@
#include <linux/fb.h>
#include <linux/i2c.h>
#include <linux/i2c-gpio.h>
+#include <linux/i2c/qt602240_ts.h>
#include <linux/mfd/max8998.h>
+#include <linux/mfd/wm8994/pdata.h>
+#include <linux/regulator/fixed.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/lcd.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <linux/gpio.h>
@@ -35,7 +41,10 @@
#include <plat/devs.h>
#include <plat/cpu.h>
#include <plat/fb.h>
+#include <plat/iic.h>
+#include <plat/keypad.h>
#include <plat/sdhci.h>
+#include <plat/clock.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define GONI_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -87,13 +96,12 @@ static struct s3c2410_uartcfg goni_uartcfgs[] __initdata = {
/* Frame Buffer */
static struct s3c_fb_pd_win goni_fb_win0 = {
.win_mode = {
- .pixclock = 1000000000000ULL / ((16+16+2+480)*(28+3+2+800)*55),
.left_margin = 16,
.right_margin = 16,
- .upper_margin = 3,
+ .upper_margin = 2,
.lower_margin = 28,
.hsync_len = 2,
- .vsync_len = 2,
+ .vsync_len = 1,
.xres = 480,
.yres = 800,
.refresh = 55,
@@ -111,9 +119,160 @@ static struct s3c_fb_platdata goni_lcd_pdata __initdata = {
.setup_gpio = s5pv210_fb_gpio_setup_24bpp,
};
+static int lcd_power_on(struct lcd_device *ld, int enable)
+{
+ return 1;
+}
+
+static int reset_lcd(struct lcd_device *ld)
+{
+ static unsigned int first = 1;
+ int reset_gpio = -1;
+
+ reset_gpio = S5PV210_MP05(5);
+
+ if (first) {
+ gpio_request(reset_gpio, "MLCD_RST");
+ first = 0;
+ }
+
+ gpio_direction_output(reset_gpio, 1);
+ return 1;
+}
+
+static struct lcd_platform_data goni_lcd_platform_data = {
+ .reset = reset_lcd,
+ .power_on = lcd_power_on,
+ .lcd_enabled = 0,
+ .reset_delay = 120, /* 120ms */
+ .power_on_delay = 25, /* 25ms */
+ .power_off_delay = 200, /* 200ms */
+};
+
+#define LCD_BUS_NUM 3
+static struct spi_board_info spi_board_info[] __initdata = {
+ {
+ .modalias = "s6e63m0",
+ .platform_data = &goni_lcd_platform_data,
+ .max_speed_hz = 1200000,
+ .bus_num = LCD_BUS_NUM,
+ .chip_select = 0,
+ .mode = SPI_MODE_3,
+ .controller_data = (void *)S5PV210_MP01(1), /* DISPLAY_CS */
+ },
+};
+
+static struct spi_gpio_platform_data lcd_spi_gpio_data = {
+ .sck = S5PV210_MP04(1), /* DISPLAY_CLK */
+ .mosi = S5PV210_MP04(3), /* DISPLAY_SI */
+ .miso = SPI_GPIO_NO_MISO,
+ .num_chipselect = 1,
+};
+
+static struct platform_device goni_spi_gpio = {
+ .name = "spi_gpio",
+ .id = LCD_BUS_NUM,
+ .dev = {
+ .parent = &s3c_device_fb.dev,
+ .platform_data = &lcd_spi_gpio_data,
+ },
+};
+
+/* KEYPAD */
+static uint32_t keymap[] __initdata = {
+ /* KEY(row, col, keycode) */
+ KEY(0, 1, KEY_MENU), /* Send */
+ KEY(0, 2, KEY_BACK), /* End */
+ KEY(1, 1, KEY_CONFIG), /* Half shot */
+ KEY(1, 2, KEY_VOLUMEUP),
+ KEY(2, 1, KEY_CAMERA), /* Full shot */
+ KEY(2, 2, KEY_VOLUMEDOWN),
+};
+
+static struct matrix_keymap_data keymap_data __initdata = {
+ .keymap = keymap,
+ .keymap_size = ARRAY_SIZE(keymap),
+};
+
+static struct samsung_keypad_platdata keypad_data __initdata = {
+ .keymap_data = &keymap_data,
+ .rows = 3,
+ .cols = 3,
+};
+
+/* Radio */
+static struct i2c_board_info i2c1_devs[] __initdata = {
+ {
+ I2C_BOARD_INFO("si470x", 0x10),
+ },
+};
+
+static void __init goni_radio_init(void)
+{
+ int gpio;
+
+ gpio = S5PV210_GPJ2(4); /* XMSMDATA_4 */
+ gpio_request(gpio, "FM_INT");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+ i2c1_devs[0].irq = gpio_to_irq(gpio);
+
+ gpio = S5PV210_GPJ2(5); /* XMSMDATA_5 */
+ gpio_request(gpio, "FM_RST");
+ gpio_direction_output(gpio, 1);
+}
+
+/* TSP */
+static struct qt602240_platform_data qt602240_platform_data = {
+ .x_line = 17,
+ .y_line = 11,
+ .x_size = 800,
+ .y_size = 480,
+ .blen = 0x21,
+ .threshold = 0x28,
+ .voltage = 2800000, /* 2.8V */
+ .orient = QT602240_DIAGONAL,
+};
+
+static struct s3c2410_platform_i2c i2c2_data __initdata = {
+ .flags = 0,
+ .bus_num = 2,
+ .slave_addr = 0x10,
+ .frequency = 400 * 1000,
+ .sda_delay = 100,
+};
+
+static struct i2c_board_info i2c2_devs[] __initdata = {
+ {
+ I2C_BOARD_INFO("qt602240_ts", 0x4a),
+ .platform_data = &qt602240_platform_data,
+ },
+};
+
+static void __init goni_tsp_init(void)
+{
+ int gpio;
+
+ gpio = S5PV210_GPJ1(3); /* XMSMADDR_11 */
+ gpio_request(gpio, "TSP_LDO_ON");
+ gpio_direction_output(gpio, 1);
+ gpio_export(gpio, 0);
+
+ gpio = S5PV210_GPJ0(5); /* XMSMADDR_5 */
+ gpio_request(gpio, "TSP_INT");
+
+ s5p_register_gpio_interrupt(gpio);
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ i2c2_devs[0].irq = gpio_to_irq(gpio);
+}
+
/* MAX8998 regulators */
#if defined(CONFIG_REGULATOR_MAX8998) || defined(CONFIG_REGULATOR_MAX8998_MODULE)
+static struct regulator_consumer_supply goni_ldo5_consumers[] = {
+ REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"),
+};
+
static struct regulator_init_data goni_ldo2_data = {
.constraints = {
.name = "VALIVE_1.1V",
@@ -153,6 +312,8 @@ static struct regulator_init_data goni_ldo5_data = {
.max_uV = 2800000,
.apply_uV = 1,
},
+ .num_consumer_supplies = ARRAY_SIZE(goni_ldo5_consumers),
+ .consumer_supplies = goni_ldo5_consumers,
};
static struct regulator_init_data goni_ldo6_data = {
@@ -360,6 +521,119 @@ static struct max8998_platform_data goni_max8998_pdata = {
};
#endif
+static struct regulator_consumer_supply wm8994_fixed_voltage0_supplies[] = {
+ {
+ .dev_name = "5-001a",
+ .supply = "DBVDD",
+ }, {
+ .dev_name = "5-001a",
+ .supply = "AVDD2",
+ }, {
+ .dev_name = "5-001a",
+ .supply = "CPVDD",
+ },
+};
+
+static struct regulator_consumer_supply wm8994_fixed_voltage1_supplies[] = {
+ {
+ .dev_name = "5-001a",
+ .supply = "SPKVDD1",
+ }, {
+ .dev_name = "5-001a",
+ .supply = "SPKVDD2",
+ },
+};
+
+static struct regulator_init_data wm8994_fixed_voltage0_init_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage0_supplies),
+ .consumer_supplies = wm8994_fixed_voltage0_supplies,
+};
+
+static struct regulator_init_data wm8994_fixed_voltage1_init_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage1_supplies),
+ .consumer_supplies = wm8994_fixed_voltage1_supplies,
+};
+
+static struct fixed_voltage_config wm8994_fixed_voltage0_config = {
+ .supply_name = "VCC_1.8V_PDA",
+ .microvolts = 1800000,
+ .gpio = -EINVAL,
+ .init_data = &wm8994_fixed_voltage0_init_data,
+};
+
+static struct fixed_voltage_config wm8994_fixed_voltage1_config = {
+ .supply_name = "V_BAT",
+ .microvolts = 3700000,
+ .gpio = -EINVAL,
+ .init_data = &wm8994_fixed_voltage1_init_data,
+};
+
+static struct platform_device wm8994_fixed_voltage0 = {
+ .name = "reg-fixed-voltage",
+ .id = 0,
+ .dev = {
+ .platform_data = &wm8994_fixed_voltage0_config,
+ },
+};
+
+static struct platform_device wm8994_fixed_voltage1 = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &wm8994_fixed_voltage1_config,
+ },
+};
+
+static struct regulator_consumer_supply wm8994_avdd1_supply = {
+ .dev_name = "5-001a",
+ .supply = "AVDD1",
+};
+
+static struct regulator_consumer_supply wm8994_dcvdd_supply = {
+ .dev_name = "5-001a",
+ .supply = "DCVDD",
+};
+
+static struct regulator_init_data wm8994_ldo1_data = {
+ .constraints = {
+ .name = "AVDD1_3.0V",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &wm8994_avdd1_supply,
+};
+
+static struct regulator_init_data wm8994_ldo2_data = {
+ .constraints = {
+ .name = "DCVDD_1.0V",
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &wm8994_dcvdd_supply,
+};
+
+static struct wm8994_pdata wm8994_platform_data = {
+ /* configure gpio1 function: 0x0001(Logic level input/output) */
+ .gpio_defaults[0] = 0x0001,
+ /* configure gpio3/4/5/7 function for AIF2 voice */
+ .gpio_defaults[2] = 0x8100,
+ .gpio_defaults[3] = 0x8100,
+ .gpio_defaults[4] = 0x8100,
+ .gpio_defaults[6] = 0x0100,
+ /* configure gpio8/9/10/11 function for AIF3 BT */
+ .gpio_defaults[7] = 0x8100,
+ .gpio_defaults[8] = 0x0100,
+ .gpio_defaults[9] = 0x0100,
+ .gpio_defaults[10] = 0x0100,
+ .ldo[0] = { S5PV210_MP03(6), NULL, &wm8994_ldo1_data }, /* XM0FRNB_2 */
+ .ldo[1] = { 0, NULL, &wm8994_ldo2_data },
+};
+
/* GPIO I2C PMIC */
#define AP_I2C_GPIO_PMIC_BUS_4 4
static struct i2c_gpio_platform_data goni_i2c_gpio_pmic_data = {
@@ -385,6 +659,29 @@ static struct i2c_board_info i2c_gpio_pmic_devs[] __initdata = {
#endif
};
+/* GPIO I2C AP 1.8V */
+#define AP_I2C_GPIO_BUS_5 5
+static struct i2c_gpio_platform_data goni_i2c_gpio5_data = {
+ .sda_pin = S5PV210_MP05(3), /* XM0ADDR_11 */
+ .scl_pin = S5PV210_MP05(2), /* XM0ADDR_10 */
+};
+
+static struct platform_device goni_i2c_gpio5 = {
+ .name = "i2c-gpio",
+ .id = AP_I2C_GPIO_BUS_5,
+ .dev = {
+ .platform_data = &goni_i2c_gpio5_data,
+ },
+};
+
+static struct i2c_board_info i2c_gpio5_devs[] __initdata = {
+ {
+ /* CS/ADDR = low 0x34 (FYI: high = 0x36) */
+ I2C_BOARD_INFO("wm8994", 0x1a),
+ .platform_data = &wm8994_platform_data,
+ },
+};
+
/* PMIC Power button */
static struct gpio_keys_button goni_gpio_keys_table[] = {
{
@@ -444,11 +741,37 @@ static struct s3c_sdhci_platdata goni_hsmmc2_data __initdata = {
.ext_cd_gpio_invert = 1,
};
+static struct regulator_consumer_supply mmc2_supplies[] = {
+ REGULATOR_SUPPLY("vmmc", "s3c-sdhci.2"),
+};
+
+static struct regulator_init_data mmc2_fixed_voltage_init_data = {
+ .constraints = {
+ .name = "V_TF_2.8V",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(mmc2_supplies),
+ .consumer_supplies = mmc2_supplies,
+};
+
+static struct fixed_voltage_config mmc2_fixed_voltage_config = {
+ .supply_name = "EXT_FLASH_EN",
+ .microvolts = 2800000,
+ .gpio = GONI_EXT_FLASH_EN,
+ .enable_high = true,
+ .init_data = &mmc2_fixed_voltage_init_data,
+};
+
+static struct platform_device mmc2_fixed_voltage = {
+ .name = "reg-fixed-voltage",
+ .id = 2,
+ .dev = {
+ .platform_data = &mmc2_fixed_voltage_config,
+ },
+};
+
static void goni_setup_sdhci(void)
{
- gpio_request(GONI_EXT_FLASH_EN, "FLASH_EN");
- gpio_direction_output(GONI_EXT_FLASH_EN, 1);
-
s3c_sdhci0_set_platdata(&goni_hsmmc0_data);
s3c_sdhci1_set_platdata(&goni_hsmmc1_data);
s3c_sdhci2_set_platdata(&goni_hsmmc2_data);
@@ -456,8 +779,11 @@ static void goni_setup_sdhci(void)
static struct platform_device *goni_devices[] __initdata = {
&s3c_device_fb,
- &s5pc110_device_onenand,
+ &s5p_device_onenand,
+ &goni_spi_gpio,
&goni_i2c_gpio_pmic,
+ &goni_i2c_gpio5,
+ &mmc2_fixed_voltage,
&goni_device_gpiokeys,
&s5p_device_fimc0,
&s5p_device_fimc1,
@@ -465,8 +791,24 @@ static struct platform_device *goni_devices[] __initdata = {
&s3c_device_hsmmc0,
&s3c_device_hsmmc1,
&s3c_device_hsmmc2,
+ &s5pv210_device_iis0,
+ &s3c_device_usb_hsotg,
+ &samsung_device_keypad,
+ &s3c_device_i2c1,
+ &s3c_device_i2c2,
+ &wm8994_fixed_voltage0,
+ &wm8994_fixed_voltage1,
};
+static void __init goni_sound_init(void)
+{
+ /* Ths main clock of WM8994 codec uses the output of CLKOUT pin.
+ * The CLKOUT[9:8] set to 0x3(XUSBXTI) of 0xE010E000(OTHERS)
+ * because it needs 24MHz clock to operate WM8994 codec.
+ */
+ __raw_writel(__raw_readl(S5P_OTHERS) | (0x3 << 8), S5P_OTHERS);
+}
+
static void __init goni_map_io(void)
{
s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -476,6 +818,20 @@ static void __init goni_map_io(void)
static void __init goni_machine_init(void)
{
+ /* Radio: call before I2C 1 registeration */
+ goni_radio_init();
+
+ /* I2C1 */
+ s3c_i2c1_set_platdata(NULL);
+ i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
+
+ /* TSP: call before I2C 2 registeration */
+ goni_tsp_init();
+
+ /* I2C2 */
+ s3c_i2c2_set_platdata(&i2c2_data);
+ i2c_register_board_info(2, i2c2_devs, ARRAY_SIZE(i2c2_devs));
+
/* PMIC */
goni_pmic_init();
i2c_register_board_info(AP_I2C_GPIO_PMIC_BUS_4, i2c_gpio_pmic_devs,
@@ -483,16 +839,27 @@ static void __init goni_machine_init(void)
/* SDHCI */
goni_setup_sdhci();
+ /* SOUND */
+ goni_sound_init();
+ i2c_register_board_info(AP_I2C_GPIO_BUS_5, i2c_gpio5_devs,
+ ARRAY_SIZE(i2c_gpio5_devs));
+
/* FB */
s3c_fb_set_platdata(&goni_lcd_pdata);
+ /* SPI */
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+
+ /* KEYPAD */
+ samsung_keypad_set_platdata(&keypad_data);
+
+ clk_xusbxti.rate = 24000000;
+
platform_add_devices(goni_devices, ARRAY_SIZE(goni_devices));
}
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..0ad7924fe62e 100644
--- a/arch/arm/mach-s5pv210/mach-smdkc110.c
+++ b/arch/arm/mach-s5pv210/mach-smdkc110.c
@@ -28,6 +28,7 @@
#include <plat/cpu.h>
#include <plat/ata.h>
#include <plat/iic.h>
+#include <plat/pm.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDKC110_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -81,6 +82,7 @@ static struct s3c_ide_platdata smdkc110_ide_pdata __initdata = {
static struct platform_device *smdkc110_devices[] __initdata = {
&s5pv210_device_iis0,
&s5pv210_device_ac97,
+ &s5pv210_device_spdif,
&s3c_device_cfcon,
&s3c_device_i2c0,
&s3c_device_i2c1,
@@ -110,6 +112,8 @@ static void __init smdkc110_map_io(void)
static void __init smdkc110_machine_init(void)
{
+ s3c_pm_init();
+
s3c_i2c0_set_platdata(NULL);
s3c_i2c1_set_platdata(NULL);
s3c_i2c2_set_platdata(NULL);
@@ -127,8 +131,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..bcd7a5d53401 100644
--- a/arch/arm/mach-s5pv210/mach-smdkv210.c
+++ b/arch/arm/mach-s5pv210/mach-smdkv210.c
@@ -31,6 +31,7 @@
#include <plat/ata.h>
#include <plat/iic.h>
#include <plat/keypad.h>
+#include <plat/pm.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDKV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -103,6 +104,7 @@ static struct samsung_keypad_platdata smdkv210_keypad_data __initdata = {
static struct platform_device *smdkv210_devices[] __initdata = {
&s5pv210_device_iis0,
&s5pv210_device_ac97,
+ &s5pv210_device_spdif,
&s3c_device_adc,
&s3c_device_cfcon,
&s3c_device_hsmmc0,
@@ -145,6 +147,8 @@ static void __init smdkv210_map_io(void)
static void __init smdkv210_machine_init(void)
{
+ s3c_pm_init();
+
samsung_keypad_set_platdata(&smdkv210_keypad_data);
s3c24xx_ts_set_platdata(&s3c_ts_platform);
@@ -165,8 +169,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-s5pv210/mach-torbreck.c b/arch/arm/mach-s5pv210/mach-torbreck.c
new file mode 100644
index 000000000000..043c938806b0
--- /dev/null
+++ b/arch/arm/mach-s5pv210/mach-torbreck.c
@@ -0,0 +1,131 @@
+/* linux/arch/arm/mach-s5pv210/mach-torbreck.c
+ *
+ * Copyright (c) 2010 aESOP Community
+ * http://www.aesop.or.kr/
+ *
+ * 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/i2c.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+
+#include <plat/regs-serial.h>
+#include <plat/s5pv210.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/iic.h>
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define TORBRECK_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define TORBRECK_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define TORBRECK_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S5PV210_UFCON_TXTRIG4 | \
+ S5PV210_UFCON_RXTRIG4)
+
+static struct s3c2410_uartcfg torbreck_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = TORBRECK_UCON_DEFAULT,
+ .ulcon = TORBRECK_ULCON_DEFAULT,
+ .ufcon = TORBRECK_UFCON_DEFAULT,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = TORBRECK_UCON_DEFAULT,
+ .ulcon = TORBRECK_ULCON_DEFAULT,
+ .ufcon = TORBRECK_UFCON_DEFAULT,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = TORBRECK_UCON_DEFAULT,
+ .ulcon = TORBRECK_ULCON_DEFAULT,
+ .ufcon = TORBRECK_UFCON_DEFAULT,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = TORBRECK_UCON_DEFAULT,
+ .ulcon = TORBRECK_ULCON_DEFAULT,
+ .ufcon = TORBRECK_UFCON_DEFAULT,
+ },
+};
+
+static struct platform_device *torbreck_devices[] __initdata = {
+ &s5pv210_device_iis0,
+ &s3c_device_cfcon,
+ &s3c_device_hsmmc0,
+ &s3c_device_hsmmc1,
+ &s3c_device_hsmmc2,
+ &s3c_device_hsmmc3,
+ &s3c_device_i2c0,
+ &s3c_device_i2c1,
+ &s3c_device_i2c2,
+ &s3c_device_rtc,
+ &s3c_device_wdt,
+};
+
+static struct i2c_board_info torbreck_i2c_devs0[] __initdata = {
+ /* To Be Updated */
+};
+
+static struct i2c_board_info torbreck_i2c_devs1[] __initdata = {
+ /* To Be Updated */
+};
+
+static struct i2c_board_info torbreck_i2c_devs2[] __initdata = {
+ /* To Be Updated */
+};
+
+static void __init torbreck_map_io(void)
+{
+ s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+ s3c24xx_init_clocks(24000000);
+ s3c24xx_init_uarts(torbreck_uartcfgs, ARRAY_SIZE(torbreck_uartcfgs));
+}
+
+static void __init torbreck_machine_init(void)
+{
+ s3c_i2c0_set_platdata(NULL);
+ s3c_i2c1_set_platdata(NULL);
+ s3c_i2c2_set_platdata(NULL);
+ i2c_register_board_info(0, torbreck_i2c_devs0,
+ ARRAY_SIZE(torbreck_i2c_devs0));
+ i2c_register_board_info(1, torbreck_i2c_devs1,
+ ARRAY_SIZE(torbreck_i2c_devs1));
+ i2c_register_board_info(2, torbreck_i2c_devs2,
+ ARRAY_SIZE(torbreck_i2c_devs2));
+
+ platform_add_devices(torbreck_devices, ARRAY_SIZE(torbreck_devices));
+}
+
+MACHINE_START(TORBRECK, "TORBRECK")
+ /* Maintainer: Hyunchul Ko <ghcstop@gmail.com> */
+ .boot_params = S5P_PA_SDRAM + 0x100,
+ .init_irq = s5pv210_init_irq,
+ .map_io = torbreck_map_io,
+ .init_machine = torbreck_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s5pv210/pm.c b/arch/arm/mach-s5pv210/pm.c
new file mode 100644
index 000000000000..549d7924fd4c
--- /dev/null
+++ b/arch/arm/mach-s5pv210/pm.c
@@ -0,0 +1,166 @@
+/* linux/arch/arm/mach-s5pv210/pm.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5PV210 - Power Management support
+ *
+ * Based on arch/arm/mach-s3c2410/pm.c
+ * Copyright (c) 2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * 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/suspend.h>
+#include <linux/io.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/regs-timer.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-clock.h>
+
+static struct sleep_save s5pv210_core_save[] = {
+ /* Clock source */
+ SAVE_ITEM(S5P_CLK_SRC0),
+ SAVE_ITEM(S5P_CLK_SRC1),
+ SAVE_ITEM(S5P_CLK_SRC2),
+ SAVE_ITEM(S5P_CLK_SRC3),
+ SAVE_ITEM(S5P_CLK_SRC4),
+ SAVE_ITEM(S5P_CLK_SRC5),
+ SAVE_ITEM(S5P_CLK_SRC6),
+
+ /* Clock source Mask */
+ SAVE_ITEM(S5P_CLK_SRC_MASK0),
+ SAVE_ITEM(S5P_CLK_SRC_MASK1),
+
+ /* Clock Divider */
+ SAVE_ITEM(S5P_CLK_DIV0),
+ SAVE_ITEM(S5P_CLK_DIV1),
+ SAVE_ITEM(S5P_CLK_DIV2),
+ SAVE_ITEM(S5P_CLK_DIV3),
+ SAVE_ITEM(S5P_CLK_DIV4),
+ SAVE_ITEM(S5P_CLK_DIV5),
+ SAVE_ITEM(S5P_CLK_DIV6),
+ SAVE_ITEM(S5P_CLK_DIV7),
+
+ /* Clock Main Gate */
+ SAVE_ITEM(S5P_CLKGATE_MAIN0),
+ SAVE_ITEM(S5P_CLKGATE_MAIN1),
+ SAVE_ITEM(S5P_CLKGATE_MAIN2),
+
+ /* Clock source Peri Gate */
+ SAVE_ITEM(S5P_CLKGATE_PERI0),
+ SAVE_ITEM(S5P_CLKGATE_PERI1),
+
+ /* Clock source SCLK Gate */
+ SAVE_ITEM(S5P_CLKGATE_SCLK0),
+ SAVE_ITEM(S5P_CLKGATE_SCLK1),
+
+ /* Clock IP Clock gate */
+ SAVE_ITEM(S5P_CLKGATE_IP0),
+ SAVE_ITEM(S5P_CLKGATE_IP1),
+ SAVE_ITEM(S5P_CLKGATE_IP2),
+ SAVE_ITEM(S5P_CLKGATE_IP3),
+ SAVE_ITEM(S5P_CLKGATE_IP4),
+
+ /* Clock Blcok and Bus gate */
+ SAVE_ITEM(S5P_CLKGATE_BLOCK),
+ SAVE_ITEM(S5P_CLKGATE_BUS0),
+
+ /* Clock ETC */
+ SAVE_ITEM(S5P_CLK_OUT),
+ SAVE_ITEM(S5P_MDNIE_SEL),
+
+ /* PWM Register */
+ SAVE_ITEM(S3C2410_TCFG0),
+ SAVE_ITEM(S3C2410_TCFG1),
+ SAVE_ITEM(S3C64XX_TINT_CSTAT),
+ SAVE_ITEM(S3C2410_TCON),
+ SAVE_ITEM(S3C2410_TCNTB(0)),
+ SAVE_ITEM(S3C2410_TCMPB(0)),
+ SAVE_ITEM(S3C2410_TCNTO(0)),
+};
+
+void s5pv210_cpu_suspend(void)
+{
+ unsigned long tmp;
+
+ /* issue the standby signal into the pm unit. Note, we
+ * issue a write-buffer drain just in case */
+
+ tmp = 0;
+
+ asm("b 1f\n\t"
+ ".align 5\n\t"
+ "1:\n\t"
+ "mcr p15, 0, %0, c7, c10, 5\n\t"
+ "mcr p15, 0, %0, c7, c10, 4\n\t"
+ "wfi" : : "r" (tmp));
+
+ /* we should never get past here */
+ panic("sleep resumed to originator?");
+}
+
+static void s5pv210_pm_prepare(void)
+{
+ unsigned int tmp;
+
+ /* ensure at least INFORM0 has the resume address */
+ __raw_writel(virt_to_phys(s3c_cpu_resume), S5P_INFORM0);
+
+ tmp = __raw_readl(S5P_SLEEP_CFG);
+ tmp &= ~(S5P_SLEEP_CFG_OSC_EN | S5P_SLEEP_CFG_USBOSC_EN);
+ __raw_writel(tmp, S5P_SLEEP_CFG);
+
+ /* WFI for SLEEP mode configuration by SYSCON */
+ tmp = __raw_readl(S5P_PWR_CFG);
+ tmp &= S5P_CFG_WFI_CLEAN;
+ tmp |= S5P_CFG_WFI_SLEEP;
+ __raw_writel(tmp, S5P_PWR_CFG);
+
+ /* SYSCON interrupt handling disable */
+ tmp = __raw_readl(S5P_OTHERS);
+ tmp |= S5P_OTHER_SYSC_INTOFF;
+ __raw_writel(tmp, S5P_OTHERS);
+
+ s3c_pm_do_save(s5pv210_core_save, ARRAY_SIZE(s5pv210_core_save));
+}
+
+static int s5pv210_pm_add(struct sys_device *sysdev)
+{
+ pm_cpu_prep = s5pv210_pm_prepare;
+ pm_cpu_sleep = s5pv210_cpu_suspend;
+
+ return 0;
+}
+
+static int s5pv210_pm_resume(struct sys_device *dev)
+{
+ u32 tmp;
+
+ tmp = __raw_readl(S5P_OTHERS);
+ tmp |= (S5P_OTHERS_RET_IO | S5P_OTHERS_RET_CF |\
+ S5P_OTHERS_RET_MMC | S5P_OTHERS_RET_UART);
+ __raw_writel(tmp , S5P_OTHERS);
+
+ s3c_pm_do_restore_core(s5pv210_core_save, ARRAY_SIZE(s5pv210_core_save));
+
+ return 0;
+}
+
+static struct sysdev_driver s5pv210_pm_driver = {
+ .add = s5pv210_pm_add,
+ .resume = s5pv210_pm_resume,
+};
+
+static __init int s5pv210_pm_drvinit(void)
+{
+ return sysdev_driver_register(&s5pv210_sysclass, &s5pv210_pm_driver);
+}
+arch_initcall(s5pv210_pm_drvinit);
diff --git a/arch/arm/mach-s5pv210/setup-fb-24bpp.c b/arch/arm/mach-s5pv210/setup-fb-24bpp.c
index 928cf1f125fa..e932ebfac56d 100644
--- a/arch/arm/mach-s5pv210/setup-fb-24bpp.c
+++ b/arch/arm/mach-s5pv210/setup-fb-24bpp.c
@@ -21,33 +21,21 @@
#include <mach/regs-clock.h>
#include <plat/gpio-cfg.h>
-void s5pv210_fb_gpio_setup_24bpp(void)
+static void s5pv210_fb_cfg_gpios(unsigned int base, unsigned int nr)
{
- unsigned int gpio = 0;
-
- for (gpio = S5PV210_GPF0(0); gpio <= S5PV210_GPF0(7); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
- }
+ s3c_gpio_cfgrange_nopull(base, nr, S3C_GPIO_SFN(2));
- for (gpio = S5PV210_GPF1(0); gpio <= S5PV210_GPF1(7); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
- }
+ for (; nr > 0; nr--, base++)
+ s5p_gpio_set_drvstr(base, S5P_GPIO_DRVSTR_LV4);
+}
- for (gpio = S5PV210_GPF2(0); gpio <= S5PV210_GPF2(7); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
- }
- for (gpio = S5PV210_GPF3(0); gpio <= S5PV210_GPF3(3); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
- }
+void s5pv210_fb_gpio_setup_24bpp(void)
+{
+ s5pv210_fb_cfg_gpios(S5PV210_GPF0(0), 8);
+ s5pv210_fb_cfg_gpios(S5PV210_GPF1(0), 8);
+ s5pv210_fb_cfg_gpios(S5PV210_GPF2(0), 8);
+ s5pv210_fb_cfg_gpios(S5PV210_GPF3(0), 4);
/* Set DISPLAY_CONTROL register for Display path selection.
*
diff --git a/arch/arm/mach-s5pv210/setup-i2c0.c b/arch/arm/mach-s5pv210/setup-i2c0.c
index d38f7cb7e662..0f1cc3a1c1e8 100644
--- a/arch/arm/mach-s5pv210/setup-i2c0.c
+++ b/arch/arm/mach-s5pv210/setup-i2c0.c
@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */
void s3c_i2c0_cfg_gpio(struct platform_device *dev)
{
- s3c_gpio_cfgpin(S5PV210_GPD1(0), S3C_GPIO_SFN(2));
- s3c_gpio_setpull(S5PV210_GPD1(0), S3C_GPIO_PULL_UP);
- s3c_gpio_cfgpin(S5PV210_GPD1(1), S3C_GPIO_SFN(2));
- s3c_gpio_setpull(S5PV210_GPD1(1), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgall_range(S5PV210_GPD1(0), 2,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
}
diff --git a/arch/arm/mach-s5pv210/setup-i2c1.c b/arch/arm/mach-s5pv210/setup-i2c1.c
index 148bb7857d89..f61365a34c56 100644
--- a/arch/arm/mach-s5pv210/setup-i2c1.c
+++ b/arch/arm/mach-s5pv210/setup-i2c1.c
@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */
void s3c_i2c1_cfg_gpio(struct platform_device *dev)
{
- s3c_gpio_cfgpin(S5PV210_GPD1(2), S3C_GPIO_SFN(2));
- s3c_gpio_setpull(S5PV210_GPD1(2), S3C_GPIO_PULL_UP);
- s3c_gpio_cfgpin(S5PV210_GPD1(3), S3C_GPIO_SFN(2));
- s3c_gpio_setpull(S5PV210_GPD1(3), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgall_range(S5PV210_GPD1(2), 2,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
}
diff --git a/arch/arm/mach-s5pv210/setup-i2c2.c b/arch/arm/mach-s5pv210/setup-i2c2.c
index 2396cb8c373e..2f91b5cefbc6 100644
--- a/arch/arm/mach-s5pv210/setup-i2c2.c
+++ b/arch/arm/mach-s5pv210/setup-i2c2.c
@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */
void s3c_i2c2_cfg_gpio(struct platform_device *dev)
{
- s3c_gpio_cfgpin(S5PV210_GPD1(4), S3C_GPIO_SFN(2));
- s3c_gpio_setpull(S5PV210_GPD1(4), S3C_GPIO_PULL_UP);
- s3c_gpio_cfgpin(S5PV210_GPD1(5), S3C_GPIO_SFN(2));
- s3c_gpio_setpull(S5PV210_GPD1(5), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgall_range(S5PV210_GPD1(4), 2,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
}
diff --git a/arch/arm/mach-s5pv210/setup-ide.c b/arch/arm/mach-s5pv210/setup-ide.c
index b558b1cc8d60..ea123d546bd2 100644
--- a/arch/arm/mach-s5pv210/setup-ide.c
+++ b/arch/arm/mach-s5pv210/setup-ide.c
@@ -15,36 +15,25 @@
#include <plat/gpio-cfg.h>
+static void s5pv210_ide_cfg_gpios(unsigned int base, unsigned int nr)
+{
+ s3c_gpio_cfgrange_nopull(base, nr, S3C_GPIO_SFN(4));
+
+ for (; nr > 0; nr--, base++)
+ s5p_gpio_set_drvstr(base, S5P_GPIO_DRVSTR_LV4);
+}
+
void s5pv210_ide_setup_gpio(void)
{
- unsigned int gpio = 0;
-
- for (gpio = S5PV210_GPJ0(0); gpio <= S5PV210_GPJ0(7); gpio++) {
- /* CF_Add[0 - 2], CF_IORDY, CF_INTRQ, CF_DMARQ, CF_DMARST,
- CF_DMACK */
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
- }
-
- for (gpio = S5PV210_GPJ2(0); gpio <= S5PV210_GPJ2(7); gpio++) {
- /*CF_Data[0 - 7] */
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
- }
-
- for (gpio = S5PV210_GPJ3(0); gpio <= S5PV210_GPJ3(7); gpio++) {
- /* CF_Data[8 - 15] */
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
- }
-
- for (gpio = S5PV210_GPJ4(0); gpio <= S5PV210_GPJ4(3); gpio++) {
- /* CF_CS0, CF_CS1, CF_IORD, CF_IOWR */
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
- }
+ /* CF_Add[0 - 2], CF_IORDY, CF_INTRQ, CF_DMARQ, CF_DMARST, CF_DMACK */
+ s5pv210_ide_cfg_gpios(S5PV210_GPJ0(0), 8);
+
+ /* CF_Data[0 - 7] */
+ s5pv210_ide_cfg_gpios(S5PV210_GPJ2(0), 8);
+
+ /* CF_Data[8 - 15] */
+ s5pv210_ide_cfg_gpios(S5PV210_GPJ3(0), 8);
+
+ /* CF_CS0, CF_CS1, CF_IORD, CF_IOWR */
+ s5pv210_ide_cfg_gpios(S5PV210_GPJ4(0), 4);
}
diff --git a/arch/arm/mach-s5pv210/setup-keypad.c b/arch/arm/mach-s5pv210/setup-keypad.c
index 37b2790aafc3..c56420a52f48 100644
--- a/arch/arm/mach-s5pv210/setup-keypad.c
+++ b/arch/arm/mach-s5pv210/setup-keypad.c
@@ -16,19 +16,9 @@
void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols)
{
- unsigned int gpio, end;
-
/* Set all the necessary GPH3 pins to special-function 3: KP_ROW[x] */
- end = S5PV210_GPH3(rows);
- for (gpio = S5PV210_GPH3(0); gpio < end; gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
+ s3c_gpio_cfgrange_nopull(S5PV210_GPH3(0), rows, S3C_GPIO_SFN(3));
/* Set all the necessary GPH2 pins to special-function 3: KP_COL[x] */
- end = S5PV210_GPH2(cols);
- for (gpio = S5PV210_GPH2(0); gpio < end; gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
+ s3c_gpio_cfgrange_nopull(S5PV210_GPH2(0), cols, S3C_GPIO_SFN(3));
}
diff --git a/arch/arm/mach-s5pv210/setup-sdhci-gpio.c b/arch/arm/mach-s5pv210/setup-sdhci-gpio.c
index b18587b1ec58..746777d56df9 100644
--- a/arch/arm/mach-s5pv210/setup-sdhci-gpio.c
+++ b/arch/arm/mach-s5pv210/setup-sdhci-gpio.c
@@ -26,26 +26,17 @@
void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
{
struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
- unsigned int gpio;
/* Set all the necessary GPG0/GPG1 pins to special-function 2 */
- for (gpio = S5PV210_GPG0(0); gpio < S5PV210_GPG0(2); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
+ s3c_gpio_cfgrange_nopull(S5PV210_GPG0(0), 2, S3C_GPIO_SFN(2));
+
switch (width) {
case 8:
/* GPG1[3:6] special-funtion 3 */
- for (gpio = S5PV210_GPG1(3); gpio <= S5PV210_GPG1(6); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
+ s3c_gpio_cfgrange_nopull(S5PV210_GPG1(3), 4, S3C_GPIO_SFN(3));
case 4:
/* GPG0[3:6] special-funtion 2 */
- for (gpio = S5PV210_GPG0(3); gpio <= S5PV210_GPG0(6); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
+ s3c_gpio_cfgrange_nopull(S5PV210_GPG0(3), 4, S3C_GPIO_SFN(2));
default:
break;
}
@@ -59,19 +50,12 @@ void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
{
struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
- unsigned int gpio;
/* Set all the necessary GPG1[0:1] pins to special-function 2 */
- for (gpio = S5PV210_GPG1(0); gpio < S5PV210_GPG1(2); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
+ s3c_gpio_cfgrange_nopull(S5PV210_GPG1(0), 2, S3C_GPIO_SFN(2));
/* Data pin GPG1[3:6] to special-function 2 */
- for (gpio = S5PV210_GPG1(3); gpio <= S5PV210_GPG1(6); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
+ s3c_gpio_cfgrange_nopull(S5PV210_GPG1(3), 4, S3C_GPIO_SFN(2));
if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
s3c_gpio_setpull(S5PV210_GPG1(2), S3C_GPIO_PULL_UP);
@@ -82,27 +66,17 @@ void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
{
struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
- unsigned int gpio;
/* Set all the necessary GPG2[0:1] pins to special-function 2 */
- for (gpio = S5PV210_GPG2(0); gpio < S5PV210_GPG2(2); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
+ s3c_gpio_cfgrange_nopull(S5PV210_GPG2(0), 2, S3C_GPIO_SFN(2));
switch (width) {
case 8:
/* Data pin GPG3[3:6] to special-function 3 */
- for (gpio = S5PV210_GPG3(3); gpio <= S5PV210_GPG3(6); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
+ s3c_gpio_cfgrange_nopull(S5PV210_GPG3(3), 4, S3C_GPIO_SFN(3));
case 4:
/* Data pin GPG2[3:6] to special-function 2 */
- for (gpio = S5PV210_GPG2(3); gpio <= S5PV210_GPG2(6); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
+ s3c_gpio_cfgrange_nopull(S5PV210_GPG2(3), 4, S3C_GPIO_SFN(2));
default:
break;
}
@@ -116,19 +90,12 @@ void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width)
{
struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
- unsigned int gpio;
- /* Set all the necessary GPG3[0:2] pins to special-function 2 */
- for (gpio = S5PV210_GPG3(0); gpio < S5PV210_GPG3(2); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
+ /* Set all the necessary GPG3[0:1] pins to special-function 2 */
+ s3c_gpio_cfgrange_nopull(S5PV210_GPG3(0), 2, S3C_GPIO_SFN(2));
/* Data pin GPG3[3:6] to special-function 2 */
- for (gpio = S5PV210_GPG3(3); gpio <= S5PV210_GPG3(6); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- }
+ s3c_gpio_cfgrange_nopull(S5PV210_GPG3(3), 4, S3C_GPIO_SFN(2));
if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
s3c_gpio_setpull(S5PV210_GPG3(2), S3C_GPIO_PULL_UP);
diff --git a/arch/arm/mach-s5pv210/sleep.S b/arch/arm/mach-s5pv210/sleep.S
new file mode 100644
index 000000000000..d4d222b716b4
--- /dev/null
+++ b/arch/arm/mach-s5pv210/sleep.S
@@ -0,0 +1,170 @@
+/* linux/arch/arm/plat-s5p/sleep.S
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5PV210 power Manager (Suspend-To-RAM) support
+ * Based on S3C2410 sleep code by:
+ * Ben Dooks, (c) 2004 Simtec Electronics
+ *
+ * Based on PXA/SA1100 sleep code by:
+ * Nicolas Pitre, (c) 2002 Monta Vista Software Inc
+ * Cliff Brake, (c) 2001
+ *
+ * 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/linkage.h>
+#include <asm/assembler.h>
+#include <asm/memory.h>
+
+ .text
+
+ /* s3c_cpu_save
+ *
+ * entry:
+ * r0 = save address (virtual addr of s3c_sleep_save_phys)
+ */
+
+ENTRY(s3c_cpu_save)
+
+ stmfd sp!, { r3 - r12, lr }
+
+ mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mrc p15, 0, r5, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r6, c2, c0, 0 @ Translation Table BASE0
+ mrc p15, 0, r7, c2, c0, 1 @ Translation Table BASE1
+ mrc p15, 0, r8, c2, c0, 2 @ Translation Table Control
+ mrc p15, 0, r9, c1, c0, 0 @ Control register
+ mrc p15, 0, r10, c1, c0, 1 @ Auxiliary control register
+ mrc p15, 0, r11, c1, c0, 2 @ Co-processor access controls
+ mrc p15, 0, r12, c10, c2, 0 @ Read PRRR
+ mrc p15, 0, r3, c10, c2, 1 @ READ NMRR
+
+ stmia r0, { r3 - r13 }
+
+ bl s3c_pm_cb_flushcache
+
+ ldr r0, =pm_cpu_sleep
+ ldr r0, [ r0 ]
+ mov pc, r0
+
+resume_with_mmu:
+ /*
+ * After MMU is turned on, restore the previous MMU table.
+ */
+ ldr r9 , =(PAGE_OFFSET - PHYS_OFFSET)
+ add r4, r4, r9
+ str r12, [r4]
+
+ ldmfd sp!, { r3 - r12, pc }
+
+ .ltorg
+
+ .data
+
+ .global s3c_sleep_save_phys
+s3c_sleep_save_phys:
+ .word 0
+
+ /* sleep magic, to allow the bootloader to check for an valid
+ * image to resume to. Must be the first word before the
+ * s3c_cpu_resume entry.
+ */
+
+ .word 0x2bedf00d
+
+ /* s3c_cpu_resume
+ *
+ * resume code entry for bootloader to call
+ *
+ * we must put this code here in the data segment as we have no
+ * other way of restoring the stack pointer after sleep, and we
+ * must not write to the code segment (code is read-only)
+ */
+
+ENTRY(s3c_cpu_resume)
+ mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
+ msr cpsr_c, r0
+
+ mov r1, #0
+ mcr p15, 0, r1, c8, c7, 0 @ invalidate TLBs
+ mcr p15, 0, r1, c7, c5, 0 @ invalidate I Cache
+
+ ldr r0, s3c_sleep_save_phys @ address of restore block
+ ldmia r0, { r3 - r13 }
+
+ mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mcr p15, 0, r5, c3, c0, 0 @ Domain ID
+
+ mcr p15, 0, r8, c2, c0, 2 @ Translation Table Control
+ mcr p15, 0, r7, c2, c0, 1 @ Translation Table BASE1
+ mcr p15, 0, r6, c2, c0, 0 @ Translation Table BASE0
+
+ mcr p15, 0, r10, c1, c0, 1 @ Auxiliary control register
+
+ mov r0, #0
+ mcr p15, 0, r0, c8, c7, 0 @ Invalidate I & D TLB
+
+ mov r0, #0 @ restore copro access
+ mcr p15, 0, r11, c1, c0, 2 @ Co-processor access
+ mcr p15, 0, r0, c7, c5, 4
+
+ mcr p15, 0, r12, c10, c2, 0 @ write PRRR
+ mcr p15, 0, r3, c10, c2, 1 @ write NMRR
+
+ /*
+ * In Cortex-A8, when MMU is turned on, the pipeline is flushed.
+ * And there are no valid entries in the MMU table at this point.
+ * So before turning on the MMU, the MMU entry for the DRAM address
+ * range is added. After the MMU is turned on, the other entries
+ * in the MMU table will be restored.
+ */
+
+ /* r6 = Translation Table BASE0 */
+ mov r4, r6
+ mov r4, r4, LSR #14
+ mov r4, r4, LSL #14
+
+ /* Load address for adding to MMU table list */
+ ldr r11, =0xE010F000 @ INFORM0 reg.
+ ldr r10, [r11, #0]
+ mov r10, r10, LSR #18
+ bic r10, r10, #0x3
+ orr r4, r4, r10
+
+ /* Calculate MMU table entry */
+ mov r10, r10, LSL #18
+ ldr r5, =0x40E
+ orr r10, r10, r5
+
+ /* Back up originally data */
+ ldr r12, [r4]
+
+ /* Add calculated MMU table entry into MMU table list */
+ str r10, [r4]
+
+ ldr r2, =resume_with_mmu
+ mcr p15, 0, r9, c1, c0, 0 @ turn on MMU, etc
+
+ nop
+ nop
+ nop
+ nop
+ nop @ second-to-last before mmu
+
+ mov pc, r2 @ go back to virtual address
+
+ .ltorg
diff --git a/arch/arm/mach-s5pv310/Kconfig b/arch/arm/mach-s5pv310/Kconfig
index 331b5bd97aba..1150b360f38c 100644
--- a/arch/arm/mach-s5pv310/Kconfig
+++ b/arch/arm/mach-s5pv310/Kconfig
@@ -11,7 +11,6 @@ if ARCH_S5PV310
config CPU_S5PV310
bool
- select PLAT_S5P
help
Enable S5PV310 CPU support
@@ -25,21 +24,105 @@ config S5PV310_SETUP_I2C2
help
Common setup code for i2c bus 2.
+config S5PV310_SETUP_I2C3
+ bool
+ help
+ Common setup code for i2c bus 3.
+
+config S5PV310_SETUP_I2C4
+ bool
+ help
+ Common setup code for i2c bus 4.
+
+config S5PV310_SETUP_I2C5
+ bool
+ help
+ Common setup code for i2c bus 5.
+
+config S5PV310_SETUP_I2C6
+ bool
+ help
+ Common setup code for i2c bus 6.
+
+config S5PV310_SETUP_I2C7
+ bool
+ help
+ Common setup code for i2c bus 7.
+
+config S5PV310_SETUP_SDHCI
+ bool
+ select S5PV310_SETUP_SDHCI_GPIO
+ help
+ Internal helper functions for S5PV310 based SDHCI systems.
+
+config S5PV310_SETUP_SDHCI_GPIO
+ bool
+ help
+ Common setup code for SDHCI gpio.
+
# machine support
-config MACH_SMDKV310
- bool "SMDKV310"
+menu "S5PC210 Machines"
+
+config MACH_SMDKC210
+ bool "SMDKC210"
select CPU_S5PV310
- select ARCH_SPARSEMEM_ENABLE
+ select S3C_DEV_RTC
+ select S3C_DEV_WDT
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_HSMMC2
+ select S3C_DEV_HSMMC3
+ select S5PV310_SETUP_SDHCI
help
- Machine support for Samsung SMDKV310
+ Machine support for Samsung SMDKC210
+ S5PC210(MCP) is one of package option of S5PV310
config MACH_UNIVERSAL_C210
bool "Mobile UNIVERSAL_C210 Board"
select CPU_S5PV310
- select ARCH_SPARSEMEM_ENABLE
+ select S5P_DEV_ONENAND
+ select S3C_DEV_I2C1
+ select S5PV310_SETUP_I2C1
help
Machine support for Samsung Mobile Universal S5PC210 Reference
Board. S5PC210(MCP) is one of package option of S5PV310
+endmenu
+
+menu "S5PV310 Machines"
+
+config MACH_SMDKV310
+ bool "SMDKV310"
+ select CPU_S5PV310
+ select S3C_DEV_RTC
+ select S3C_DEV_WDT
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_HSMMC2
+ select S3C_DEV_HSMMC3
+ select S5PV310_SETUP_SDHCI
+ help
+ Machine support for Samsung SMDKV310
+
+endmenu
+
+comment "Configuration for HSMMC bus width"
+
+menu "Use 8-bit bus width"
+
+config S5PV310_SDHCI_CH0_8BIT
+ bool "Channel 0 with 8-bit bus"
+ help
+ Support HSMMC Channel 0 8-bit bus.
+ If selected, Channel 1 is disabled.
+
+config S5PV310_SDHCI_CH2_8BIT
+ bool "Channel 2 with 8-bit bus"
+ help
+ Support HSMMC Channel 2 8-bit bus.
+ If selected, Channel 3 is disabled.
+
+endmenu
+
endif
diff --git a/arch/arm/mach-s5pv310/Makefile b/arch/arm/mach-s5pv310/Makefile
index d5b51c72340f..84afc64e7c01 100644
--- a/arch/arm/mach-s5pv310/Makefile
+++ b/arch/arm/mach-s5pv310/Makefile
@@ -13,7 +13,7 @@ obj- :=
# Core support for S5PV310 system
obj-$(CONFIG_CPU_S5PV310) += cpu.o init.o clock.o irq-combiner.o
-obj-$(CONFIG_CPU_S5PV310) += setup-i2c0.o time.o
+obj-$(CONFIG_CPU_S5PV310) += setup-i2c0.o time.o gpiolib.o irq-eint.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
@@ -21,6 +21,7 @@ obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
# machine support
+obj-$(CONFIG_MACH_SMDKC210) += mach-smdkc210.o
obj-$(CONFIG_MACH_SMDKV310) += mach-smdkv310.o
obj-$(CONFIG_MACH_UNIVERSAL_C210) += mach-universal_c210.o
@@ -28,3 +29,10 @@ obj-$(CONFIG_MACH_UNIVERSAL_C210) += mach-universal_c210.o
obj-$(CONFIG_S5PV310_SETUP_I2C1) += setup-i2c1.o
obj-$(CONFIG_S5PV310_SETUP_I2C2) += setup-i2c2.o
+obj-$(CONFIG_S5PV310_SETUP_I2C3) += setup-i2c3.o
+obj-$(CONFIG_S5PV310_SETUP_I2C4) += setup-i2c4.o
+obj-$(CONFIG_S5PV310_SETUP_I2C5) += setup-i2c5.o
+obj-$(CONFIG_S5PV310_SETUP_I2C6) += setup-i2c6.o
+obj-$(CONFIG_S5PV310_SETUP_I2C7) += setup-i2c7.o
+obj-$(CONFIG_S5PV310_SETUP_SDHCI) += setup-sdhci.o
+obj-$(CONFIG_S5PV310_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
diff --git a/arch/arm/mach-s5pv310/clock.c b/arch/arm/mach-s5pv310/clock.c
index 26a0f03df8ea..58c9d33f36fe 100644
--- a/arch/arm/mach-s5pv310/clock.c
+++ b/arch/arm/mach-s5pv310/clock.c
@@ -30,16 +30,92 @@ static struct clk clk_sclk_hdmi27m = {
.rate = 27000000,
};
+static struct clk clk_sclk_hdmiphy = {
+ .name = "sclk_hdmiphy",
+ .id = -1,
+};
+
+static struct clk clk_sclk_usbphy0 = {
+ .name = "sclk_usbphy0",
+ .id = -1,
+ .rate = 27000000,
+};
+
+static struct clk clk_sclk_usbphy1 = {
+ .name = "sclk_usbphy1",
+ .id = -1,
+};
+
+static int s5pv310_clksrc_mask_top_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKSRC_MASK_TOP, clk, enable);
+}
+
+static int s5pv310_clksrc_mask_cam_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKSRC_MASK_CAM, clk, enable);
+}
+
+static int s5pv310_clksrc_mask_lcd0_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKSRC_MASK_LCD0, clk, enable);
+}
+
+static int s5pv310_clksrc_mask_lcd1_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKSRC_MASK_LCD1, clk, enable);
+}
+
+static int s5pv310_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKSRC_MASK_FSYS, clk, enable);
+}
+
static int s5pv310_clksrc_mask_peril0_ctrl(struct clk *clk, int enable)
{
return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL0, clk, enable);
}
+static int s5pv310_clksrc_mask_peril1_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL1, clk, enable);
+}
+
+static int s5pv310_clk_ip_cam_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_IP_CAM, clk, enable);
+}
+
+static int s5pv310_clk_ip_image_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_IP_IMAGE, clk, enable);
+}
+
+static int s5pv310_clk_ip_lcd0_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_IP_LCD0, clk, enable);
+}
+
+static int s5pv310_clk_ip_lcd1_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_IP_LCD1, clk, enable);
+}
+
+static int s5pv310_clk_ip_fsys_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_IP_FSYS, clk, enable);
+}
+
static int s5pv310_clk_ip_peril_ctrl(struct clk *clk, int enable)
{
return s5p_gatectrl(S5P_CLKGATE_IP_PERIL, clk, enable);
}
+static int s5pv310_clk_ip_perir_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_IP_PERIR, clk, enable);
+}
+
/* Core list of CMU_CPU side */
static struct clksrc_clk clk_mout_apll = {
@@ -79,7 +155,7 @@ static struct clksrc_clk clk_mout_mpll = {
};
static struct clk *clkset_moutcore_list[] = {
- [0] = &clk_sclk_apll.clk,
+ [0] = &clk_mout_apll.clk,
[1] = &clk_mout_mpll.clk,
};
@@ -150,24 +226,6 @@ static struct clksrc_clk clk_periphclk = {
.reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 12, .size = 3 },
};
-static struct clksrc_clk clk_atclk = {
- .clk = {
- .name = "atclk",
- .id = -1,
- .parent = &clk_moutcore.clk,
- },
- .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 16, .size = 3 },
-};
-
-static struct clksrc_clk clk_pclk_dbg = {
- .clk = {
- .name = "pclk_dbg",
- .id = -1,
- .parent = &clk_atclk.clk,
- },
- .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 20, .size = 3 },
-};
-
/* Core list of CMU_CORE side */
static struct clk *clkset_corebus_list[] = {
@@ -241,7 +299,7 @@ static struct clk *clkset_aclk_top_list[] = {
[1] = &clk_sclk_apll.clk,
};
-static struct clksrc_sources clkset_aclk_200 = {
+static struct clksrc_sources clkset_aclk = {
.sources = clkset_aclk_top_list,
.nr_sources = ARRAY_SIZE(clkset_aclk_top_list),
};
@@ -251,52 +309,37 @@ static struct clksrc_clk clk_aclk_200 = {
.name = "aclk_200",
.id = -1,
},
- .sources = &clkset_aclk_200,
+ .sources = &clkset_aclk,
.reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 12, .size = 1 },
.reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 0, .size = 3 },
};
-static struct clksrc_sources clkset_aclk_100 = {
- .sources = clkset_aclk_top_list,
- .nr_sources = ARRAY_SIZE(clkset_aclk_top_list),
-};
-
static struct clksrc_clk clk_aclk_100 = {
.clk = {
.name = "aclk_100",
.id = -1,
},
- .sources = &clkset_aclk_100,
+ .sources = &clkset_aclk,
.reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 16, .size = 1 },
.reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 4, .size = 4 },
};
-static struct clksrc_sources clkset_aclk_160 = {
- .sources = clkset_aclk_top_list,
- .nr_sources = ARRAY_SIZE(clkset_aclk_top_list),
-};
-
static struct clksrc_clk clk_aclk_160 = {
.clk = {
.name = "aclk_160",
.id = -1,
},
- .sources = &clkset_aclk_160,
+ .sources = &clkset_aclk,
.reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 20, .size = 1 },
.reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 8, .size = 3 },
};
-static struct clksrc_sources clkset_aclk_133 = {
- .sources = clkset_aclk_top_list,
- .nr_sources = ARRAY_SIZE(clkset_aclk_top_list),
-};
-
static struct clksrc_clk clk_aclk_133 = {
.clk = {
.name = "aclk_133",
.id = -1,
},
- .sources = &clkset_aclk_133,
+ .sources = &clkset_aclk,
.reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 24, .size = 1 },
.reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 12, .size = 3 },
};
@@ -315,6 +358,8 @@ static struct clksrc_clk clk_vpllsrc = {
.clk = {
.name = "vpll_src",
.id = -1,
+ .enable = s5pv310_clksrc_mask_top_ctrl,
+ .ctrlbit = (1 << 0),
},
.sources = &clkset_vpllsrc,
.reg_src = { .reg = S5P_CLKSRC_TOP1, .shift = 0, .size = 1 },
@@ -346,7 +391,175 @@ static struct clk init_clocks_disable[] = {
.parent = &clk_aclk_100.clk,
.enable = s5pv310_clk_ip_peril_ctrl,
.ctrlbit = (1<<24),
- }
+ }, {
+ .name = "csis",
+ .id = 0,
+ .enable = s5pv310_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "csis",
+ .id = 1,
+ .enable = s5pv310_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 5),
+ }, {
+ .name = "fimc",
+ .id = 0,
+ .enable = s5pv310_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "fimc",
+ .id = 1,
+ .enable = s5pv310_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "fimc",
+ .id = 2,
+ .enable = s5pv310_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "fimc",
+ .id = 3,
+ .enable = s5pv310_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "fimd",
+ .id = 0,
+ .enable = s5pv310_clk_ip_lcd0_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "fimd",
+ .id = 1,
+ .enable = s5pv310_clk_ip_lcd1_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "hsmmc",
+ .id = 0,
+ .parent = &clk_aclk_133.clk,
+ .enable = s5pv310_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 5),
+ }, {
+ .name = "hsmmc",
+ .id = 1,
+ .parent = &clk_aclk_133.clk,
+ .enable = s5pv310_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 6),
+ }, {
+ .name = "hsmmc",
+ .id = 2,
+ .parent = &clk_aclk_133.clk,
+ .enable = s5pv310_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = "hsmmc",
+ .id = 3,
+ .parent = &clk_aclk_133.clk,
+ .enable = s5pv310_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 8),
+ }, {
+ .name = "hsmmc",
+ .id = 4,
+ .parent = &clk_aclk_133.clk,
+ .enable = s5pv310_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 9),
+ }, {
+ .name = "sata",
+ .id = -1,
+ .enable = s5pv310_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 10),
+ }, {
+ .name = "adc",
+ .id = -1,
+ .enable = s5pv310_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 15),
+ }, {
+ .name = "rtc",
+ .id = -1,
+ .enable = s5pv310_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 15),
+ }, {
+ .name = "watchdog",
+ .id = -1,
+ .enable = s5pv310_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 14),
+ }, {
+ .name = "usbhost",
+ .id = -1,
+ .enable = s5pv310_clk_ip_fsys_ctrl ,
+ .ctrlbit = (1 << 12),
+ }, {
+ .name = "otg",
+ .id = -1,
+ .enable = s5pv310_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 13),
+ }, {
+ .name = "spi",
+ .id = 0,
+ .enable = s5pv310_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 16),
+ }, {
+ .name = "spi",
+ .id = 1,
+ .enable = s5pv310_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 17),
+ }, {
+ .name = "spi",
+ .id = 2,
+ .enable = s5pv310_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 18),
+ }, {
+ .name = "fimg2d",
+ .id = -1,
+ .enable = s5pv310_clk_ip_image_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "i2c",
+ .id = 0,
+ .parent = &clk_aclk_100.clk,
+ .enable = s5pv310_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 6),
+ }, {
+ .name = "i2c",
+ .id = 1,
+ .parent = &clk_aclk_100.clk,
+ .enable = s5pv310_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = "i2c",
+ .id = 2,
+ .parent = &clk_aclk_100.clk,
+ .enable = s5pv310_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 8),
+ }, {
+ .name = "i2c",
+ .id = 3,
+ .parent = &clk_aclk_100.clk,
+ .enable = s5pv310_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 9),
+ }, {
+ .name = "i2c",
+ .id = 4,
+ .parent = &clk_aclk_100.clk,
+ .enable = s5pv310_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 10),
+ }, {
+ .name = "i2c",
+ .id = 5,
+ .parent = &clk_aclk_100.clk,
+ .enable = s5pv310_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 11),
+ }, {
+ .name = "i2c",
+ .id = 6,
+ .parent = &clk_aclk_100.clk,
+ .enable = s5pv310_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 12),
+ }, {
+ .name = "i2c",
+ .id = 7,
+ .parent = &clk_aclk_100.clk,
+ .enable = s5pv310_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 13),
+ },
};
static struct clk init_clocks[] = {
@@ -387,6 +600,9 @@ static struct clk *clkset_group_list[] = {
[0] = &clk_ext_xtal_mux,
[1] = &clk_xusbxti,
[2] = &clk_sclk_hdmi27m,
+ [3] = &clk_sclk_usbphy0,
+ [4] = &clk_sclk_usbphy1,
+ [5] = &clk_sclk_hdmiphy,
[6] = &clk_mout_mpll.clk,
[7] = &clk_mout_epll.clk,
[8] = &clk_sclk_vpll.clk,
@@ -397,6 +613,104 @@ static struct clksrc_sources clkset_group = {
.nr_sources = ARRAY_SIZE(clkset_group_list),
};
+static struct clk *clkset_mout_g2d0_list[] = {
+ [0] = &clk_mout_mpll.clk,
+ [1] = &clk_sclk_apll.clk,
+};
+
+static struct clksrc_sources clkset_mout_g2d0 = {
+ .sources = clkset_mout_g2d0_list,
+ .nr_sources = ARRAY_SIZE(clkset_mout_g2d0_list),
+};
+
+static struct clksrc_clk clk_mout_g2d0 = {
+ .clk = {
+ .name = "mout_g2d0",
+ .id = -1,
+ },
+ .sources = &clkset_mout_g2d0,
+ .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 0, .size = 1 },
+};
+
+static struct clk *clkset_mout_g2d1_list[] = {
+ [0] = &clk_mout_epll.clk,
+ [1] = &clk_sclk_vpll.clk,
+};
+
+static struct clksrc_sources clkset_mout_g2d1 = {
+ .sources = clkset_mout_g2d1_list,
+ .nr_sources = ARRAY_SIZE(clkset_mout_g2d1_list),
+};
+
+static struct clksrc_clk clk_mout_g2d1 = {
+ .clk = {
+ .name = "mout_g2d1",
+ .id = -1,
+ },
+ .sources = &clkset_mout_g2d1,
+ .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 4, .size = 1 },
+};
+
+static struct clk *clkset_mout_g2d_list[] = {
+ [0] = &clk_mout_g2d0.clk,
+ [1] = &clk_mout_g2d1.clk,
+};
+
+static struct clksrc_sources clkset_mout_g2d = {
+ .sources = clkset_mout_g2d_list,
+ .nr_sources = ARRAY_SIZE(clkset_mout_g2d_list),
+};
+
+static struct clksrc_clk clk_dout_mmc0 = {
+ .clk = {
+ .name = "dout_mmc0",
+ .id = -1,
+ },
+ .sources = &clkset_group,
+ .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 0, .size = 4 },
+ .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk clk_dout_mmc1 = {
+ .clk = {
+ .name = "dout_mmc1",
+ .id = -1,
+ },
+ .sources = &clkset_group,
+ .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 4, .size = 4 },
+ .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk clk_dout_mmc2 = {
+ .clk = {
+ .name = "dout_mmc2",
+ .id = -1,
+ },
+ .sources = &clkset_group,
+ .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 8, .size = 4 },
+ .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk clk_dout_mmc3 = {
+ .clk = {
+ .name = "dout_mmc3",
+ .id = -1,
+ },
+ .sources = &clkset_group,
+ .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 12, .size = 4 },
+ .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk clk_dout_mmc4 = {
+ .clk = {
+ .name = "dout_mmc4",
+ .id = -1,
+ },
+ .sources = &clkset_group,
+ .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 16, .size = 4 },
+ .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 0, .size = 4 },
+};
+
static struct clksrc_clk clksrcs[] = {
{
.clk = {
@@ -448,7 +762,200 @@ static struct clksrc_clk clksrcs[] = {
.sources = &clkset_group,
.reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 24, .size = 4 },
.reg_div = { .reg = S5P_CLKDIV_PERIL3, .shift = 0, .size = 4 },
- },
+ }, {
+ .clk = {
+ .name = "sclk_csis",
+ .id = 0,
+ .enable = s5pv310_clksrc_mask_cam_ctrl,
+ .ctrlbit = (1 << 24),
+ },
+ .sources = &clkset_group,
+ .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 24, .size = 4 },
+ .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 24, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_csis",
+ .id = 1,
+ .enable = s5pv310_clksrc_mask_cam_ctrl,
+ .ctrlbit = (1 << 28),
+ },
+ .sources = &clkset_group,
+ .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 28, .size = 4 },
+ .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 28, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_cam",
+ .id = 0,
+ .enable = s5pv310_clksrc_mask_cam_ctrl,
+ .ctrlbit = (1 << 16),
+ },
+ .sources = &clkset_group,
+ .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 16, .size = 4 },
+ .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 16, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_cam",
+ .id = 1,
+ .enable = s5pv310_clksrc_mask_cam_ctrl,
+ .ctrlbit = (1 << 20),
+ },
+ .sources = &clkset_group,
+ .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 20, .size = 4 },
+ .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 20, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimc",
+ .id = 0,
+ .enable = s5pv310_clksrc_mask_cam_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .sources = &clkset_group,
+ .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 0, .size = 4 },
+ .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimc",
+ .id = 1,
+ .enable = s5pv310_clksrc_mask_cam_ctrl,
+ .ctrlbit = (1 << 4),
+ },
+ .sources = &clkset_group,
+ .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 4, .size = 4 },
+ .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 4, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimc",
+ .id = 2,
+ .enable = s5pv310_clksrc_mask_cam_ctrl,
+ .ctrlbit = (1 << 8),
+ },
+ .sources = &clkset_group,
+ .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 8, .size = 4 },
+ .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 8, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimc",
+ .id = 3,
+ .enable = s5pv310_clksrc_mask_cam_ctrl,
+ .ctrlbit = (1 << 12),
+ },
+ .sources = &clkset_group,
+ .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 12, .size = 4 },
+ .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 12, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimd",
+ .id = 0,
+ .enable = s5pv310_clksrc_mask_lcd0_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .sources = &clkset_group,
+ .reg_src = { .reg = S5P_CLKSRC_LCD0, .shift = 0, .size = 4 },
+ .reg_div = { .reg = S5P_CLKDIV_LCD0, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimd",
+ .id = 1,
+ .enable = s5pv310_clksrc_mask_lcd1_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .sources = &clkset_group,
+ .reg_src = { .reg = S5P_CLKSRC_LCD1, .shift = 0, .size = 4 },
+ .reg_div = { .reg = S5P_CLKDIV_LCD1, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_sata",
+ .id = -1,
+ .enable = s5pv310_clksrc_mask_fsys_ctrl,
+ .ctrlbit = (1 << 24),
+ },
+ .sources = &clkset_mout_corebus,
+ .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 24, .size = 1 },
+ .reg_div = { .reg = S5P_CLKDIV_FSYS0, .shift = 20, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_spi",
+ .id = 0,
+ .enable = s5pv310_clksrc_mask_peril1_ctrl,
+ .ctrlbit = (1 << 16),
+ },
+ .sources = &clkset_group,
+ .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 16, .size = 4 },
+ .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_spi",
+ .id = 1,
+ .enable = s5pv310_clksrc_mask_peril1_ctrl,
+ .ctrlbit = (1 << 20),
+ },
+ .sources = &clkset_group,
+ .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 20, .size = 4 },
+ .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 16, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_spi",
+ .id = 2,
+ .enable = s5pv310_clksrc_mask_peril1_ctrl,
+ .ctrlbit = (1 << 24),
+ },
+ .sources = &clkset_group,
+ .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 24, .size = 4 },
+ .reg_div = { .reg = S5P_CLKDIV_PERIL2, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimg2d",
+ .id = -1,
+ },
+ .sources = &clkset_mout_g2d,
+ .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 8, .size = 1 },
+ .reg_div = { .reg = S5P_CLKDIV_IMAGE, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .id = 0,
+ .parent = &clk_dout_mmc0.clk,
+ .enable = s5pv310_clksrc_mask_fsys_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 8, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .id = 1,
+ .parent = &clk_dout_mmc1.clk,
+ .enable = s5pv310_clksrc_mask_fsys_ctrl,
+ .ctrlbit = (1 << 4),
+ },
+ .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 24, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .id = 2,
+ .parent = &clk_dout_mmc2.clk,
+ .enable = s5pv310_clksrc_mask_fsys_ctrl,
+ .ctrlbit = (1 << 8),
+ },
+ .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 8, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .id = 3,
+ .parent = &clk_dout_mmc3.clk,
+ .enable = s5pv310_clksrc_mask_fsys_ctrl,
+ .ctrlbit = (1 << 12),
+ },
+ .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 24, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .id = 4,
+ .parent = &clk_dout_mmc4.clk,
+ .enable = s5pv310_clksrc_mask_fsys_ctrl,
+ .ctrlbit = (1 << 16),
+ },
+ .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 8, .size = 8 },
+ }
};
/* Clock initialization code */
@@ -464,8 +971,6 @@ static struct clksrc_clk *sysclks[] = {
&clk_aclk_cores,
&clk_aclk_corem1,
&clk_periphclk,
- &clk_atclk,
- &clk_pclk_dbg,
&clk_mout_corebus,
&clk_sclk_dmc,
&clk_aclk_cored,
@@ -478,6 +983,11 @@ static struct clksrc_clk *sysclks[] = {
&clk_aclk_100,
&clk_aclk_160,
&clk_aclk_133,
+ &clk_dout_mmc0,
+ &clk_dout_mmc1,
+ &clk_dout_mmc2,
+ &clk_dout_mmc3,
+ &clk_dout_mmc4,
};
void __init_or_cpufreq s5pv310_setup_clocks(void)
@@ -490,15 +1000,11 @@ void __init_or_cpufreq s5pv310_setup_clocks(void)
unsigned long vpllsrc;
unsigned long xtal;
unsigned long armclk;
- unsigned long aclk_corem0;
- unsigned long aclk_cores;
- unsigned long aclk_corem1;
- unsigned long periphclk;
unsigned long sclk_dmc;
- unsigned long aclk_cored;
- unsigned long aclk_corep;
- unsigned long aclk_acp;
- unsigned long pclk_acp;
+ unsigned long aclk_200;
+ unsigned long aclk_100;
+ unsigned long aclk_160;
+ unsigned long aclk_133;
unsigned int ptr;
printk(KERN_DEBUG "%s: registering clocks\n", __func__);
@@ -529,26 +1035,21 @@ void __init_or_cpufreq s5pv310_setup_clocks(void)
apll, mpll, epll, vpll);
armclk = clk_get_rate(&clk_armclk.clk);
- aclk_corem0 = clk_get_rate(&clk_aclk_corem0.clk);
- aclk_cores = clk_get_rate(&clk_aclk_cores.clk);
- aclk_corem1 = clk_get_rate(&clk_aclk_corem1.clk);
- periphclk = clk_get_rate(&clk_periphclk.clk);
sclk_dmc = clk_get_rate(&clk_sclk_dmc.clk);
- aclk_cored = clk_get_rate(&clk_aclk_cored.clk);
- aclk_corep = clk_get_rate(&clk_aclk_corep.clk);
- aclk_acp = clk_get_rate(&clk_aclk_acp.clk);
- pclk_acp = clk_get_rate(&clk_pclk_acp.clk);
-
- printk(KERN_INFO "S5PV310: ARMCLK=%ld, COREM0=%ld, CORES=%ld\n"
- "COREM1=%ld, PERI=%ld, DMC=%ld, CORED=%ld\n"
- "COREP=%ld, ACLK_ACP=%ld, PCLK_ACP=%ld",
- armclk, aclk_corem0, aclk_cores, aclk_corem1,
- periphclk, sclk_dmc, aclk_cored, aclk_corep,
- aclk_acp, pclk_acp);
+
+ aclk_200 = clk_get_rate(&clk_aclk_200.clk);
+ aclk_100 = clk_get_rate(&clk_aclk_100.clk);
+ aclk_160 = clk_get_rate(&clk_aclk_160.clk);
+ aclk_133 = clk_get_rate(&clk_aclk_133.clk);
+
+ printk(KERN_INFO "S5PV310: ARMCLK=%ld, DMC=%ld, ACLK200=%ld\n"
+ "ACLK100=%ld, ACLK160=%ld, ACLK133=%ld\n",
+ armclk, sclk_dmc, aclk_200,
+ aclk_100, aclk_160, aclk_133);
clk_f.rate = armclk;
clk_h.rate = sclk_dmc;
- clk_p.rate = periphclk;
+ clk_p.rate = aclk_100;
for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
s3c_set_clksrc(&clksrcs[ptr], true);
diff --git a/arch/arm/mach-s5pv310/cpu.c b/arch/arm/mach-s5pv310/cpu.c
index e5b261a99ab2..82ce4aa6d61a 100644
--- a/arch/arm/mach-s5pv310/cpu.c
+++ b/arch/arm/mach-s5pv310/cpu.c
@@ -15,10 +15,12 @@
#include <asm/mach/irq.h>
#include <asm/proc-fns.h>
+#include <asm/hardware/cache-l2x0.h>
#include <plat/cpu.h>
#include <plat/clock.h>
#include <plat/s5pv310.h>
+#include <plat/sdhci.h>
#include <mach/regs-irq.h>
@@ -31,9 +33,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 +48,39 @@ 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_GPIO1,
+ .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)S5P_VA_GPIO2,
+ .pfn = __phys_to_pfn(S5PV310_PA_GPIO2),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_GPIO3,
+ .pfn = __phys_to_pfn(S5PV310_PA_GPIO3),
+ .length = SZ_256,
+ .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(S5PV310_PA_SROMC),
+ .length = SZ_4K,
.type = MT_DEVICE,
},
};
@@ -73,6 +100,12 @@ static void s5pv310_idle(void)
void __init s5pv310_map_io(void)
{
iotable_init(s5pv310_iodesc, ARRAY_SIZE(s5pv310_iodesc));
+
+ /* initialize device information early */
+ s5pv310_default_sdhci0();
+ s5pv310_default_sdhci1();
+ s5pv310_default_sdhci2();
+ s5pv310_default_sdhci3();
}
void __init s5pv310_init_clocks(int xtal)
@@ -121,6 +154,28 @@ static int __init s5pv310_core_init(void)
core_initcall(s5pv310_core_init);
+#ifdef CONFIG_CACHE_L2X0
+static int __init s5pv310_l2x0_cache_init(void)
+{
+ /* TAG, Data Latency Control: 2cycle */
+ __raw_writel(0x110, S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL);
+ __raw_writel(0x110, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL);
+
+ /* L2X0 Prefetch Control */
+ __raw_writel(0x30000007, S5P_VA_L2CC + L2X0_PREFETCH_CTRL);
+
+ /* L2X0 Power Control */
+ __raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN,
+ S5P_VA_L2CC + L2X0_POWER_CTRL);
+
+ l2x0_init(S5P_VA_L2CC, 0x7C070001, 0xC200ffff);
+
+ return 0;
+}
+
+early_initcall(s5pv310_l2x0_cache_init);
+#endif
+
int __init s5pv310_init(void)
{
printk(KERN_INFO "S5PV310: Initializing architecture\n");
diff --git a/arch/arm/mach-s5pv310/gpiolib.c b/arch/arm/mach-s5pv310/gpiolib.c
new file mode 100644
index 000000000000..55217b8923ec
--- /dev/null
+++ b/arch/arm/mach-s5pv310/gpiolib.c
@@ -0,0 +1,304 @@
+/* linux/arch/arm/mach-s5pv310/gpiolib.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5PV310 - 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>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <mach/map.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
+static struct s3c_gpio_cfg gpio_cfg = {
+ .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
+ .set_pull = s3c_gpio_setpull_updown,
+ .get_pull = s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_cfg_noint = {
+ .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
+ .set_pull = s3c_gpio_setpull_updown,
+ .get_pull = s3c_gpio_getpull_updown,
+};
+
+/*
+ * Following are the gpio banks in v310.
+ *
+ * The 'config' member when left to NULL, is initialized to the default
+ * structure gpio_cfg in the init function below.
+ *
+ * The 'base' member is also initialized in the init function below.
+ * Note: The initialization of 'base' member of s3c_gpio_chip structure
+ * uses the above macro and depends on the banks being listed in order here.
+ */
+static struct s3c_gpio_chip s5pv310_gpio_part1_4bit[] = {
+ {
+ .chip = {
+ .base = S5PV310_GPA0(0),
+ .ngpio = S5PV310_GPIO_A0_NR,
+ .label = "GPA0",
+ },
+ }, {
+ .chip = {
+ .base = S5PV310_GPA1(0),
+ .ngpio = S5PV310_GPIO_A1_NR,
+ .label = "GPA1",
+ },
+ }, {
+ .chip = {
+ .base = S5PV310_GPB(0),
+ .ngpio = S5PV310_GPIO_B_NR,
+ .label = "GPB",
+ },
+ }, {
+ .chip = {
+ .base = S5PV310_GPC0(0),
+ .ngpio = S5PV310_GPIO_C0_NR,
+ .label = "GPC0",
+ },
+ }, {
+ .chip = {
+ .base = S5PV310_GPC1(0),
+ .ngpio = S5PV310_GPIO_C1_NR,
+ .label = "GPC1",
+ },
+ }, {
+ .chip = {
+ .base = S5PV310_GPD0(0),
+ .ngpio = S5PV310_GPIO_D0_NR,
+ .label = "GPD0",
+ },
+ }, {
+ .chip = {
+ .base = S5PV310_GPD1(0),
+ .ngpio = S5PV310_GPIO_D1_NR,
+ .label = "GPD1",
+ },
+ }, {
+ .chip = {
+ .base = S5PV310_GPE0(0),
+ .ngpio = S5PV310_GPIO_E0_NR,
+ .label = "GPE0",
+ },
+ }, {
+ .chip = {
+ .base = S5PV310_GPE1(0),
+ .ngpio = S5PV310_GPIO_E1_NR,
+ .label = "GPE1",
+ },
+ }, {
+ .chip = {
+ .base = S5PV310_GPE2(0),
+ .ngpio = S5PV310_GPIO_E2_NR,
+ .label = "GPE2",
+ },
+ }, {
+ .chip = {
+ .base = S5PV310_GPE3(0),
+ .ngpio = S5PV310_GPIO_E3_NR,
+ .label = "GPE3",
+ },
+ }, {
+ .chip = {
+ .base = S5PV310_GPE4(0),
+ .ngpio = S5PV310_GPIO_E4_NR,
+ .label = "GPE4",
+ },
+ }, {
+ .chip = {
+ .base = S5PV310_GPF0(0),
+ .ngpio = S5PV310_GPIO_F0_NR,
+ .label = "GPF0",
+ },
+ }, {
+ .chip = {
+ .base = S5PV310_GPF1(0),
+ .ngpio = S5PV310_GPIO_F1_NR,
+ .label = "GPF1",
+ },
+ }, {
+ .chip = {
+ .base = S5PV310_GPF2(0),
+ .ngpio = S5PV310_GPIO_F2_NR,
+ .label = "GPF2",
+ },
+ }, {
+ .chip = {
+ .base = S5PV310_GPF3(0),
+ .ngpio = S5PV310_GPIO_F3_NR,
+ .label = "GPF3",
+ },
+ },
+};
+
+static struct s3c_gpio_chip s5pv310_gpio_part2_4bit[] = {
+ {
+ .chip = {
+ .base = S5PV310_GPJ0(0),
+ .ngpio = S5PV310_GPIO_J0_NR,
+ .label = "GPJ0",
+ },
+ }, {
+ .chip = {
+ .base = S5PV310_GPJ1(0),
+ .ngpio = S5PV310_GPIO_J1_NR,
+ .label = "GPJ1",
+ },
+ }, {
+ .chip = {
+ .base = S5PV310_GPK0(0),
+ .ngpio = S5PV310_GPIO_K0_NR,
+ .label = "GPK0",
+ },
+ }, {
+ .chip = {
+ .base = S5PV310_GPK1(0),
+ .ngpio = S5PV310_GPIO_K1_NR,
+ .label = "GPK1",
+ },
+ }, {
+ .chip = {
+ .base = S5PV310_GPK2(0),
+ .ngpio = S5PV310_GPIO_K2_NR,
+ .label = "GPK2",
+ },
+ }, {
+ .chip = {
+ .base = S5PV310_GPK3(0),
+ .ngpio = S5PV310_GPIO_K3_NR,
+ .label = "GPK3",
+ },
+ }, {
+ .chip = {
+ .base = S5PV310_GPL0(0),
+ .ngpio = S5PV310_GPIO_L0_NR,
+ .label = "GPL0",
+ },
+ }, {
+ .chip = {
+ .base = S5PV310_GPL1(0),
+ .ngpio = S5PV310_GPIO_L1_NR,
+ .label = "GPL1",
+ },
+ }, {
+ .chip = {
+ .base = S5PV310_GPL2(0),
+ .ngpio = S5PV310_GPIO_L2_NR,
+ .label = "GPL2",
+ },
+ }, {
+ .base = (S5P_VA_GPIO2 + 0xC00),
+ .config = &gpio_cfg_noint,
+ .irq_base = IRQ_EINT(0),
+ .chip = {
+ .base = S5PV310_GPX0(0),
+ .ngpio = S5PV310_GPIO_X0_NR,
+ .label = "GPX0",
+ .to_irq = samsung_gpiolib_to_irq,
+ },
+ }, {
+ .base = (S5P_VA_GPIO2 + 0xC20),
+ .config = &gpio_cfg_noint,
+ .irq_base = IRQ_EINT(8),
+ .chip = {
+ .base = S5PV310_GPX1(0),
+ .ngpio = S5PV310_GPIO_X1_NR,
+ .label = "GPX1",
+ .to_irq = samsung_gpiolib_to_irq,
+ },
+ }, {
+ .base = (S5P_VA_GPIO2 + 0xC40),
+ .config = &gpio_cfg_noint,
+ .irq_base = IRQ_EINT(16),
+ .chip = {
+ .base = S5PV310_GPX2(0),
+ .ngpio = S5PV310_GPIO_X2_NR,
+ .label = "GPX2",
+ .to_irq = samsung_gpiolib_to_irq,
+ },
+ }, {
+ .base = (S5P_VA_GPIO2 + 0xC60),
+ .config = &gpio_cfg_noint,
+ .irq_base = IRQ_EINT(24),
+ .chip = {
+ .base = S5PV310_GPX3(0),
+ .ngpio = S5PV310_GPIO_X3_NR,
+ .label = "GPX3",
+ .to_irq = samsung_gpiolib_to_irq,
+ },
+ },
+};
+
+static struct s3c_gpio_chip s5pv310_gpio_part3_4bit[] = {
+ {
+ .chip = {
+ .base = S5PV310_GPZ(0),
+ .ngpio = S5PV310_GPIO_Z_NR,
+ .label = "GPZ",
+ },
+ },
+};
+
+static __init int s5pv310_gpiolib_init(void)
+{
+ struct s3c_gpio_chip *chip;
+ int i;
+ int nr_chips;
+
+ /* GPIO part 1 */
+
+ chip = s5pv310_gpio_part1_4bit;
+ nr_chips = ARRAY_SIZE(s5pv310_gpio_part1_4bit);
+
+ for (i = 0; i < nr_chips; i++, chip++) {
+ if (chip->config == NULL)
+ chip->config = &gpio_cfg;
+ if (chip->base == NULL)
+ chip->base = S5P_VA_GPIO1 + (i) * 0x20;
+ }
+
+ samsung_gpiolib_add_4bit_chips(s5pv310_gpio_part1_4bit, nr_chips);
+
+ /* GPIO part 2 */
+
+ chip = s5pv310_gpio_part2_4bit;
+ nr_chips = ARRAY_SIZE(s5pv310_gpio_part2_4bit);
+
+ for (i = 0; i < nr_chips; i++, chip++) {
+ if (chip->config == NULL)
+ chip->config = &gpio_cfg;
+ if (chip->base == NULL)
+ chip->base = S5P_VA_GPIO2 + (i) * 0x20;
+ }
+
+ samsung_gpiolib_add_4bit_chips(s5pv310_gpio_part2_4bit, nr_chips);
+
+ /* GPIO part 3 */
+
+ chip = s5pv310_gpio_part3_4bit;
+ nr_chips = ARRAY_SIZE(s5pv310_gpio_part3_4bit);
+
+ for (i = 0; i < nr_chips; i++, chip++) {
+ if (chip->config == NULL)
+ chip->config = &gpio_cfg;
+ if (chip->base == NULL)
+ chip->base = S5P_VA_GPIO3 + (i) * 0x20;
+ }
+
+ samsung_gpiolib_add_4bit_chips(s5pv310_gpio_part3_4bit, nr_chips);
+
+ return 0;
+}
+core_initcall(s5pv310_gpiolib_init);
diff --git a/arch/arm/mach-s5pv310/hotplug.c b/arch/arm/mach-s5pv310/hotplug.c
new file mode 100644
index 000000000000..03652c3605f6
--- /dev/null
+++ b/arch/arm/mach-s5pv310/hotplug.c
@@ -0,0 +1,144 @@
+/* linux arch/arm/mach-s5pv310/hotplug.c
+ *
+ * Cloned from linux/arch/arm/mach-realview/hotplug.c
+ *
+ * Copyright (C) 2002 ARM Ltd.
+ * 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.
+*/
+
+#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 cpu_enter_lowpower(void)
+{
+ unsigned int v;
+
+ flush_cache_all();
+ asm volatile(
+ " mcr p15, 0, %1, c7, c5, 0\n"
+ " mcr p15, 0, %1, c7, c10, 4\n"
+ /*
+ * Turn off coherency
+ */
+ " mrc p15, 0, %0, c1, c0, 1\n"
+ " bic %0, %0, #0x20\n"
+ " mcr p15, 0, %0, c1, c0, 1\n"
+ " mrc p15, 0, %0, c1, c0, 0\n"
+ " bic %0, %0, #0x04\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ : "=&r" (v)
+ : "r" (0)
+ : "cc");
+}
+
+static inline void cpu_leave_lowpower(void)
+{
+ unsigned int v;
+
+ asm volatile(
+ "mrc p15, 0, %0, c1, c0, 0\n"
+ " orr %0, %0, #0x04\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ " mrc p15, 0, %0, c1, c0, 1\n"
+ " orr %0, %0, #0x20\n"
+ " mcr p15, 0, %0, c1, c0, 1\n"
+ : "=&r" (v)
+ :
+ : "cc");
+}
+
+static inline void platform_do_lowpower(unsigned int cpu)
+{
+ /*
+ * there is no power-control hardware on this platform, so all
+ * we can do is put the core into WFI; this is safe as the calling
+ * code will have already disabled interrupts
+ */
+ for (;;) {
+ /*
+ * here's the WFI
+ */
+ asm(".word 0xe320f003\n"
+ :
+ :
+ : "memory", "cc");
+
+ if (pen_release == cpu) {
+ /*
+ * OK, proper wakeup, we're done
+ */
+ break;
+ }
+
+ /*
+ * getting here, means that we have come out of WFI without
+ * having been woken up - this shouldn't happen
+ *
+ * The trouble is, letting people know about this is not really
+ * possible, since we are currently running incoherently, and
+ * therefore cannot safely call printk() or anything else
+ */
+#ifdef DEBUG
+ printk(KERN_WARN "CPU%u: spurious wakeup call\n", cpu);
+#endif
+ }
+}
+
+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);
+
+ /*
+ * we're ready for shutdown now, so do it
+ */
+ cpu_enter_lowpower();
+ platform_do_lowpower(cpu);
+
+ /*
+ * bring this CPU back into the world of cache
+ * coherency, and then restore interrupts
+ */
+ cpu_leave_lowpower();
+}
+
+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-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..99e7dad8a85a 100644
--- a/arch/arm/mach-s5pv310/include/mach/irqs.h
+++ b/arch/arm/mach-s5pv310/include/mach/irqs.h
@@ -3,7 +3,7 @@
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
- * S5PV210 - IRQ definitions
+ * S5PV310 - 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
@@ -60,6 +60,9 @@
#define IRQ_TIMER3_VIC COMBINER_IRQ(22, 3)
#define IRQ_TIMER4_VIC COMBINER_IRQ(22, 4)
+#define IRQ_RTC_ALARM COMBINER_IRQ(23, 0)
+#define IRQ_RTC_TIC COMBINER_IRQ(23, 1)
+
#define IRQ_UART0 COMBINER_IRQ(26, 0)
#define IRQ_UART1 COMBINER_IRQ(26, 1)
#define IRQ_UART2 COMBINER_IRQ(26, 2)
@@ -67,11 +70,46 @@
#define IRQ_UART4 COMBINER_IRQ(26, 4)
#define IRQ_IIC COMBINER_IRQ(27, 0)
+#define IRQ_IIC1 COMBINER_IRQ(27, 1)
+#define IRQ_IIC2 COMBINER_IRQ(27, 2)
+#define IRQ_IIC3 COMBINER_IRQ(27, 3)
+#define IRQ_IIC4 COMBINER_IRQ(27, 4)
+#define IRQ_IIC5 COMBINER_IRQ(27, 5)
+#define IRQ_IIC6 COMBINER_IRQ(27, 6)
+#define IRQ_IIC7 COMBINER_IRQ(27, 7)
-/* Set the default NR_IRQS */
+#define IRQ_HSMMC0 COMBINER_IRQ(29, 0)
+#define IRQ_HSMMC1 COMBINER_IRQ(29, 1)
+#define IRQ_HSMMC2 COMBINER_IRQ(29, 2)
+#define IRQ_HSMMC3 COMBINER_IRQ(29, 3)
+
+#define IRQ_ONENAND_AUDI COMBINER_IRQ(34, 0)
+
+#define IRQ_EINT4 COMBINER_IRQ(37, 0)
+#define IRQ_EINT5 COMBINER_IRQ(37, 1)
+#define IRQ_EINT6 COMBINER_IRQ(37, 2)
+#define IRQ_EINT7 COMBINER_IRQ(37, 3)
+#define IRQ_EINT8 COMBINER_IRQ(38, 0)
+
+#define IRQ_EINT9 COMBINER_IRQ(38, 1)
+#define IRQ_EINT10 COMBINER_IRQ(38, 2)
+#define IRQ_EINT11 COMBINER_IRQ(38, 3)
+#define IRQ_EINT12 COMBINER_IRQ(38, 4)
+#define IRQ_EINT13 COMBINER_IRQ(38, 5)
+#define IRQ_EINT14 COMBINER_IRQ(38, 6)
+#define IRQ_EINT15 COMBINER_IRQ(38, 7)
-#define NR_IRQS COMBINER_IRQ(MAX_COMBINER_NR, 0)
+#define IRQ_EINT16_31 COMBINER_IRQ(39, 0)
+
+#define MAX_COMBINER_NR 40
+
+#define S5P_IRQ_EINT_BASE COMBINER_IRQ(MAX_COMBINER_NR, 0)
+
+#define S5P_EINT_BASE1 (S5P_IRQ_EINT_BASE + 0)
+#define S5P_EINT_BASE2 (S5P_IRQ_EINT_BASE + 16)
+
+/* Set the default NR_IRQS */
-#define MAX_COMBINER_NR 39
+#define NR_IRQS (S5P_IRQ_EINT_BASE + 32)
#endif /* __ASM_ARCH_IRQS_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/map.h b/arch/arm/mach-s5pv310/include/mach/map.h
index 213e1101a3b3..7acf4e77e92e 100644
--- a/arch/arm/mach-s5pv310/include/mach/map.h
+++ b/arch/arm/mach-s5pv310/include/mach/map.h
@@ -25,15 +25,24 @@
#define S5PV310_PA_SYSRAM (0x02025000)
+#define S5PV310_PA_SROM_BANK(x) (0x04000000 + ((x) * 0x01000000))
+
+#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
-#define S5PV310_PA_SYSCON (0x10020000)
+#define S5PV310_PA_SYSCON (0x10010000)
#define S5P_PA_SYSCON S5PV310_PA_SYSCON
#define S5PV310_PA_CMU (0x10030000)
#define S5PV310_PA_WATCHDOG (0x10060000)
+#define S5PV310_PA_RTC (0x10070000)
#define S5PV310_PA_COMBINER (0x10448000)
@@ -46,10 +55,11 @@
#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))
+#define S5PV310_PA_SROMC (0x12570000)
+
#define S5PV310_PA_UART (0x13800000)
#define S5P_PA_UART(x) (S5PV310_PA_UART + ((x) * S3C_UART_OFFSET))
@@ -61,7 +71,7 @@
#define S5P_SZ_UART SZ_256
-#define S5PV310_PA_IIC0 (0x13860000)
+#define S5PV310_PA_IIC(x) (0x13860000 + ((x) * 0x10000))
#define S5PV310_PA_TIMER (0x139D0000)
#define S5P_PA_TIMER S5PV310_PA_TIMER
@@ -75,7 +85,15 @@
#define S3C_PA_HSMMC1 S5PV310_PA_HSMMC(1)
#define S3C_PA_HSMMC2 S5PV310_PA_HSMMC(2)
#define S3C_PA_HSMMC3 S5PV310_PA_HSMMC(3)
-#define S3C_PA_IIC S5PV310_PA_IIC0
+#define S3C_PA_IIC S5PV310_PA_IIC(0)
+#define S3C_PA_IIC1 S5PV310_PA_IIC(1)
+#define S3C_PA_IIC2 S5PV310_PA_IIC(2)
+#define S3C_PA_IIC3 S5PV310_PA_IIC(3)
+#define S3C_PA_IIC4 S5PV310_PA_IIC(4)
+#define S3C_PA_IIC5 S5PV310_PA_IIC(5)
+#define S3C_PA_IIC6 S5PV310_PA_IIC(6)
+#define S3C_PA_IIC7 S5PV310_PA_IIC(7)
+#define S3C_PA_RTC S5PV310_PA_RTC
#define S3C_PA_WDT S5PV310_PA_WATCHDOG
#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/regs-clock.h b/arch/arm/mach-s5pv310/include/mach/regs-clock.h
index 4013553cd9be..f1028cad9788 100644
--- a/arch/arm/mach-s5pv310/include/mach/regs-clock.h
+++ b/arch/arm/mach-s5pv310/include/mach/regs-clock.h
@@ -26,11 +26,23 @@
#define S5P_CLKSRC_TOP0 S5P_CLKREG(0x0C210)
#define S5P_CLKSRC_TOP1 S5P_CLKREG(0x0C214)
-
+#define S5P_CLKSRC_CAM S5P_CLKREG(0x0C220)
+#define S5P_CLKSRC_IMAGE S5P_CLKREG(0x0C230)
+#define S5P_CLKSRC_LCD0 S5P_CLKREG(0x0C234)
+#define S5P_CLKSRC_LCD1 S5P_CLKREG(0x0C238)
+#define S5P_CLKSRC_FSYS S5P_CLKREG(0x0C240)
#define S5P_CLKSRC_PERIL0 S5P_CLKREG(0x0C250)
+#define S5P_CLKSRC_PERIL1 S5P_CLKREG(0x0C254)
#define S5P_CLKDIV_TOP S5P_CLKREG(0x0C510)
-
+#define S5P_CLKDIV_CAM S5P_CLKREG(0x0C520)
+#define S5P_CLKDIV_IMAGE S5P_CLKREG(0x0C530)
+#define S5P_CLKDIV_LCD0 S5P_CLKREG(0x0C534)
+#define S5P_CLKDIV_LCD1 S5P_CLKREG(0x0C538)
+#define S5P_CLKDIV_FSYS0 S5P_CLKREG(0x0C540)
+#define S5P_CLKDIV_FSYS1 S5P_CLKREG(0x0C544)
+#define S5P_CLKDIV_FSYS2 S5P_CLKREG(0x0C548)
+#define S5P_CLKDIV_FSYS3 S5P_CLKREG(0x0C54C)
#define S5P_CLKDIV_PERIL0 S5P_CLKREG(0x0C550)
#define S5P_CLKDIV_PERIL1 S5P_CLKREG(0x0C554)
#define S5P_CLKDIV_PERIL2 S5P_CLKREG(0x0C558)
@@ -38,9 +50,21 @@
#define S5P_CLKDIV_PERIL4 S5P_CLKREG(0x0C560)
#define S5P_CLKDIV_PERIL5 S5P_CLKREG(0x0C564)
+#define S5P_CLKSRC_MASK_TOP S5P_CLKREG(0x0C310)
+#define S5P_CLKSRC_MASK_CAM S5P_CLKREG(0x0C320)
+#define S5P_CLKSRC_MASK_LCD0 S5P_CLKREG(0x0C334)
+#define S5P_CLKSRC_MASK_LCD1 S5P_CLKREG(0x0C338)
+#define S5P_CLKSRC_MASK_FSYS S5P_CLKREG(0x0C340)
#define S5P_CLKSRC_MASK_PERIL0 S5P_CLKREG(0x0C350)
+#define S5P_CLKSRC_MASK_PERIL1 S5P_CLKREG(0x0C354)
+#define S5P_CLKGATE_IP_CAM S5P_CLKREG(0x0C920)
+#define S5P_CLKGATE_IP_IMAGE S5P_CLKREG(0x0C930)
+#define S5P_CLKGATE_IP_LCD0 S5P_CLKREG(0x0C934)
+#define S5P_CLKGATE_IP_LCD1 S5P_CLKREG(0x0C938)
+#define S5P_CLKGATE_IP_FSYS S5P_CLKREG(0x0C940)
#define S5P_CLKGATE_IP_PERIL S5P_CLKREG(0x0C950)
+#define S5P_CLKGATE_IP_PERIR S5P_CLKREG(0x0C960)
#define S5P_CLKSRC_CORE S5P_CLKREG(0x10200)
#define S5P_CLKDIV_CORE0 S5P_CLKREG(0x10500)
@@ -60,4 +84,8 @@
#define S5P_CLKGATE_SCLKCPU S5P_CLKREG(0x14800)
+/* Compatibility defines */
+
+#define S5P_EPLL_CON S5P_EPLL_CON0
+
#endif /* __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/regs-gpio.h b/arch/arm/mach-s5pv310/include/mach/regs-gpio.h
new file mode 100644
index 000000000000..82e9e0c9d452
--- /dev/null
+++ b/arch/arm/mach-s5pv310/include/mach/regs-gpio.h
@@ -0,0 +1,42 @@
+/* linux/arch/arm/mach-s5pv310/include/mach/regs-gpio.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5PV310 - GPIO (including EINT) 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>
+#include <mach/irqs.h>
+
+#define S5PV310_EINT40CON (S5P_VA_GPIO2 + 0xE00)
+#define S5P_EINT_CON(x) (S5PV310_EINT40CON + ((x) * 0x4))
+
+#define S5PV310_EINT40FLTCON0 (S5P_VA_GPIO2 + 0xE80)
+#define S5P_EINT_FLTCON(x) (S5PV310_EINT40FLTCON0 + ((x) * 0x4))
+
+#define S5PV310_EINT40MASK (S5P_VA_GPIO2 + 0xF00)
+#define S5P_EINT_MASK(x) (S5PV310_EINT40MASK + ((x) * 0x4))
+
+#define S5PV310_EINT40PEND (S5P_VA_GPIO2 + 0xF40)
+#define S5P_EINT_PEND(x) (S5PV310_EINT40PEND + ((x) * 0x4))
+
+#define EINT_REG_NR(x) (EINT_OFFSET(x) >> 3)
+
+#define eint_irq_to_bit(irq) (1 << (EINT_OFFSET(irq) & 0x7))
+
+#define EINT_MODE S3C_GPIO_SFN(0xf)
+
+#define EINT_GPIO_0(x) S5PV310_GPX0(x)
+#define EINT_GPIO_1(x) S5PV310_GPX1(x)
+#define EINT_GPIO_2(x) S5PV310_GPX2(x)
+#define EINT_GPIO_3(x) S5PV310_GPX3(x)
+
+#endif /* __ASM_ARCH_REGS_GPIO_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/regs-srom.h b/arch/arm/mach-s5pv310/include/mach/regs-srom.h
new file mode 100644
index 000000000000..1898b3e10550
--- /dev/null
+++ b/arch/arm/mach-s5pv310/include/mach/regs-srom.h
@@ -0,0 +1,50 @@
+/* linux/arch/arm/mach-s5pv310/include/mach/regs-srom.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5PV310 - SROMC 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_SROM_H
+#define __ASM_ARCH_REGS_SROM_H __FILE__
+
+#include <mach/map.h>
+
+#define S5PV310_SROMREG(x) (S5P_VA_SROMC + (x))
+
+#define S5PV310_SROM_BW S5PV310_SROMREG(0x0)
+#define S5PV310_SROM_BC0 S5PV310_SROMREG(0x4)
+#define S5PV310_SROM_BC1 S5PV310_SROMREG(0x8)
+#define S5PV310_SROM_BC2 S5PV310_SROMREG(0xc)
+#define S5PV310_SROM_BC3 S5PV310_SROMREG(0x10)
+
+/* one register BW holds 4 x 4-bit packed settings for NCS0 - NCS3 */
+
+#define S5PV310_SROM_BW__DATAWIDTH__SHIFT 0
+#define S5PV310_SROM_BW__ADDRMODE__SHIFT 1
+#define S5PV310_SROM_BW__WAITENABLE__SHIFT 2
+#define S5PV310_SROM_BW__BYTEENABLE__SHIFT 3
+
+#define S5PV310_SROM_BW__CS_MASK 0xf
+
+#define S5PV310_SROM_BW__NCS0__SHIFT 0
+#define S5PV310_SROM_BW__NCS1__SHIFT 4
+#define S5PV310_SROM_BW__NCS2__SHIFT 8
+#define S5PV310_SROM_BW__NCS3__SHIFT 12
+
+/* applies to same to BCS0 - BCS3 */
+
+#define S5PV310_SROM_BCX__PMC__SHIFT 0
+#define S5PV310_SROM_BCX__TACP__SHIFT 4
+#define S5PV310_SROM_BCX__TCAH__SHIFT 8
+#define S5PV310_SROM_BCX__TCOH__SHIFT 12
+#define S5PV310_SROM_BCX__TACC__SHIFT 16
+#define S5PV310_SROM_BCX__TCOS__SHIFT 24
+#define S5PV310_SROM_BCX__TACS__SHIFT 28
+
+#endif /* __ASM_ARCH_REGS_SROM_H */
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/include/mach/vmalloc.h b/arch/arm/mach-s5pv310/include/mach/vmalloc.h
index 256f221edf3a..65759fb97581 100644
--- a/arch/arm/mach-s5pv310/include/mach/vmalloc.h
+++ b/arch/arm/mach-s5pv310/include/mach/vmalloc.h
@@ -17,6 +17,6 @@
#ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H __FILE__
-#define VMALLOC_END (0xF0000000UL)
+#define VMALLOC_END 0xF6000000UL
#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-s5pv310/irq-combiner.c b/arch/arm/mach-s5pv310/irq-combiner.c
index 0f7052164f23..c3f88c3faf6c 100644
--- a/arch/arm/mach-s5pv310/irq-combiner.c
+++ b/arch/arm/mach-s5pv310/irq-combiner.c
@@ -66,11 +66,7 @@ static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
if (status == 0)
goto out;
- for (combiner_irq = 0; combiner_irq < 32; combiner_irq++) {
- if (status & 0x1)
- break;
- status >>= 1;
- }
+ combiner_irq = __ffs(status);
cascade_irq = combiner_irq + (chip_data->irq_offset & ~31);
if (unlikely(cascade_irq >= NR_IRQS))
diff --git a/arch/arm/mach-s5pv310/irq-eint.c b/arch/arm/mach-s5pv310/irq-eint.c
new file mode 100644
index 000000000000..5877503e92c3
--- /dev/null
+++ b/arch/arm/mach-s5pv310/irq-eint.c
@@ -0,0 +1,228 @@
+/* linux/arch/arm/mach-s5pv310/irq-eint.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5PV310 - IRQ EINT 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/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/gpio.h>
+
+#include <plat/pm.h>
+#include <plat/cpu.h>
+#include <plat/gpio-cfg.h>
+
+#include <mach/regs-gpio.h>
+
+static DEFINE_SPINLOCK(eint_lock);
+
+static unsigned int eint0_15_data[16];
+
+static unsigned int s5pv310_get_irq_nr(unsigned int number)
+{
+ u32 ret = 0;
+
+ switch (number) {
+ case 0 ... 3:
+ ret = (number + IRQ_EINT0);
+ break;
+ case 4 ... 7:
+ ret = (number + (IRQ_EINT4 - 4));
+ break;
+ case 8 ... 15:
+ ret = (number + (IRQ_EINT8 - 8));
+ break;
+ default:
+ printk(KERN_ERR "number available : %d\n", number);
+ }
+
+ return ret;
+}
+
+static inline void s5pv310_irq_eint_mask(unsigned int irq)
+{
+ u32 mask;
+
+ spin_lock(&eint_lock);
+ mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(irq)));
+ mask |= eint_irq_to_bit(irq);
+ __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(irq)));
+ spin_unlock(&eint_lock);
+}
+
+static void s5pv310_irq_eint_unmask(unsigned int irq)
+{
+ u32 mask;
+
+ spin_lock(&eint_lock);
+ mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(irq)));
+ mask &= ~(eint_irq_to_bit(irq));
+ __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(irq)));
+ spin_unlock(&eint_lock);
+}
+
+static inline void s5pv310_irq_eint_ack(unsigned int irq)
+{
+ __raw_writel(eint_irq_to_bit(irq), S5P_EINT_PEND(EINT_REG_NR(irq)));
+}
+
+static void s5pv310_irq_eint_maskack(unsigned int irq)
+{
+ s5pv310_irq_eint_mask(irq);
+ s5pv310_irq_eint_ack(irq);
+}
+
+static int s5pv310_irq_eint_set_type(unsigned int irq, unsigned int type)
+{
+ int offs = EINT_OFFSET(irq);
+ int shift;
+ u32 ctrl, mask;
+ u32 newvalue = 0;
+
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ newvalue = S5P_IRQ_TYPE_EDGE_RISING;
+ break;
+
+ case IRQ_TYPE_EDGE_FALLING:
+ newvalue = S5P_IRQ_TYPE_EDGE_FALLING;
+ break;
+
+ case IRQ_TYPE_EDGE_BOTH:
+ newvalue = S5P_IRQ_TYPE_EDGE_BOTH;
+ break;
+
+ case IRQ_TYPE_LEVEL_LOW:
+ newvalue = S5P_IRQ_TYPE_LEVEL_LOW;
+ break;
+
+ case IRQ_TYPE_LEVEL_HIGH:
+ newvalue = S5P_IRQ_TYPE_LEVEL_HIGH;
+ break;
+
+ default:
+ printk(KERN_ERR "No such irq type %d", type);
+ return -EINVAL;
+ }
+
+ shift = (offs & 0x7) * 4;
+ mask = 0x7 << shift;
+
+ spin_lock(&eint_lock);
+ ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(irq)));
+ ctrl &= ~mask;
+ ctrl |= newvalue << shift;
+ __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(irq)));
+ spin_unlock(&eint_lock);
+
+ switch (offs) {
+ case 0 ... 7:
+ s3c_gpio_cfgpin(EINT_GPIO_0(offs & 0x7), EINT_MODE);
+ break;
+ case 8 ... 15:
+ s3c_gpio_cfgpin(EINT_GPIO_1(offs & 0x7), EINT_MODE);
+ break;
+ case 16 ... 23:
+ s3c_gpio_cfgpin(EINT_GPIO_2(offs & 0x7), EINT_MODE);
+ break;
+ case 24 ... 31:
+ s3c_gpio_cfgpin(EINT_GPIO_3(offs & 0x7), EINT_MODE);
+ break;
+ default:
+ printk(KERN_ERR "No such irq number %d", offs);
+ }
+
+ return 0;
+}
+
+static struct irq_chip s5pv310_irq_eint = {
+ .name = "s5pv310-eint",
+ .mask = s5pv310_irq_eint_mask,
+ .unmask = s5pv310_irq_eint_unmask,
+ .mask_ack = s5pv310_irq_eint_maskack,
+ .ack = s5pv310_irq_eint_ack,
+ .set_type = s5pv310_irq_eint_set_type,
+#ifdef CONFIG_PM
+ .set_wake = s3c_irqext_wake,
+#endif
+};
+
+/* s5pv310_irq_demux_eint
+ *
+ * This function demuxes the IRQ from from EINTs 16 to 31.
+ * It is designed to be inlined into the specific handler
+ * s5p_irq_demux_eintX_Y.
+ *
+ * Each EINT pend/mask registers handle eight of them.
+ */
+static inline void s5pv310_irq_demux_eint(unsigned int start)
+{
+ unsigned int irq;
+
+ u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start)));
+ u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start)));
+
+ status &= ~mask;
+ status &= 0xff;
+
+ while (status) {
+ irq = fls(status) - 1;
+ generic_handle_irq(irq + start);
+ status &= ~(1 << irq);
+ }
+}
+
+static void s5pv310_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
+{
+ s5pv310_irq_demux_eint(IRQ_EINT(16));
+ s5pv310_irq_demux_eint(IRQ_EINT(24));
+}
+
+static void s5pv310_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
+{
+ u32 *irq_data = get_irq_data(irq);
+ struct irq_chip *chip = get_irq_chip(irq);
+
+ chip->mask(irq);
+
+ if (chip->ack)
+ chip->ack(irq);
+
+ generic_handle_irq(*irq_data);
+
+ chip->unmask(irq);
+}
+
+int __init s5pv310_init_irq_eint(void)
+{
+ int irq;
+
+ for (irq = 0 ; irq <= 31 ; irq++) {
+ set_irq_chip(IRQ_EINT(irq), &s5pv310_irq_eint);
+ set_irq_handler(IRQ_EINT(irq), handle_level_irq);
+ set_irq_flags(IRQ_EINT(irq), IRQF_VALID);
+ }
+
+ set_irq_chained_handler(IRQ_EINT16_31, s5pv310_irq_demux_eint16_31);
+
+ for (irq = 0 ; irq <= 15 ; irq++) {
+ eint0_15_data[irq] = IRQ_EINT(irq);
+
+ set_irq_data(s5pv310_get_irq_nr(irq), &eint0_15_data[irq]);
+ set_irq_chained_handler(s5pv310_get_irq_nr(irq),
+ s5pv310_irq_eint0_15);
+ }
+
+ return 0;
+}
+
+arch_initcall(s5pv310_init_irq_eint);
diff --git a/arch/arm/mach-s5pv310/mach-smdkc210.c b/arch/arm/mach-s5pv310/mach-smdkc210.c
new file mode 100644
index 000000000000..2b8d4fc52d7c
--- /dev/null
+++ b/arch/arm/mach-s5pv310/mach-smdkc210.c
@@ -0,0 +1,202 @@
+/* linux/arch/arm/mach-s5pv310/mach-smdkc210.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/serial_core.h>
+#include <linux/gpio.h>
+#include <linux/mmc/host.h>
+#include <linux/platform_device.h>
+#include <linux/smsc911x.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <plat/s5pv310.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/sdhci.h>
+
+#include <mach/map.h>
+#include <mach/regs-srom.h>
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define SMDKC210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define SMDKC210_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define SMDKC210_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S5PV210_UFCON_TXTRIG4 | \
+ S5PV210_UFCON_RXTRIG4)
+
+static struct s3c2410_uartcfg smdkc210_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = SMDKC210_UCON_DEFAULT,
+ .ulcon = SMDKC210_ULCON_DEFAULT,
+ .ufcon = SMDKC210_UFCON_DEFAULT,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = SMDKC210_UCON_DEFAULT,
+ .ulcon = SMDKC210_ULCON_DEFAULT,
+ .ufcon = SMDKC210_UFCON_DEFAULT,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = SMDKC210_UCON_DEFAULT,
+ .ulcon = SMDKC210_ULCON_DEFAULT,
+ .ufcon = SMDKC210_UFCON_DEFAULT,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = SMDKC210_UCON_DEFAULT,
+ .ulcon = SMDKC210_ULCON_DEFAULT,
+ .ufcon = SMDKC210_UFCON_DEFAULT,
+ },
+};
+
+static struct s3c_sdhci_platdata smdkc210_hsmmc0_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_GPIO,
+ .ext_cd_gpio = S5PV310_GPK0(2),
+ .ext_cd_gpio_invert = 1,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+#ifdef CONFIG_S5PV310_SDHCI_CH0_8BIT
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA,
+#endif
+};
+
+static struct s3c_sdhci_platdata smdkc210_hsmmc1_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_GPIO,
+ .ext_cd_gpio = S5PV310_GPK0(2),
+ .ext_cd_gpio_invert = 1,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+
+static struct s3c_sdhci_platdata smdkc210_hsmmc2_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_GPIO,
+ .ext_cd_gpio = S5PV310_GPK2(2),
+ .ext_cd_gpio_invert = 1,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+#ifdef CONFIG_S5PV310_SDHCI_CH2_8BIT
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA,
+#endif
+};
+
+static struct s3c_sdhci_platdata smdkc210_hsmmc3_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_GPIO,
+ .ext_cd_gpio = S5PV310_GPK2(2),
+ .ext_cd_gpio_invert = 1,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+
+static struct resource smdkc210_smsc911x_resources[] = {
+ [0] = {
+ .start = S5PV310_PA_SROM_BANK(1),
+ .end = S5PV310_PA_SROM_BANK(1) + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_EINT(5),
+ .end = IRQ_EINT(5),
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+ },
+};
+
+static struct smsc911x_platform_config smsc9215_config = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+ .flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .mac = {0x00, 0x80, 0x00, 0x23, 0x45, 0x67},
+};
+
+static struct platform_device smdkc210_smsc911x = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smdkc210_smsc911x_resources),
+ .resource = smdkc210_smsc911x_resources,
+ .dev = {
+ .platform_data = &smsc9215_config,
+ },
+};
+
+static struct platform_device *smdkc210_devices[] __initdata = {
+ &s3c_device_hsmmc0,
+ &s3c_device_hsmmc1,
+ &s3c_device_hsmmc2,
+ &s3c_device_hsmmc3,
+ &s3c_device_rtc,
+ &s3c_device_wdt,
+ &smdkc210_smsc911x,
+};
+
+static void __init smdkc210_smsc911x_init(void)
+{
+ u32 cs1;
+
+ /* configure nCS1 width to 16 bits */
+ cs1 = __raw_readl(S5PV310_SROM_BW) &
+ ~(S5PV310_SROM_BW__CS_MASK <<
+ S5PV310_SROM_BW__NCS1__SHIFT);
+ cs1 |= ((1 << S5PV310_SROM_BW__DATAWIDTH__SHIFT) |
+ (1 << S5PV310_SROM_BW__WAITENABLE__SHIFT) |
+ (1 << S5PV310_SROM_BW__BYTEENABLE__SHIFT)) <<
+ S5PV310_SROM_BW__NCS1__SHIFT;
+ __raw_writel(cs1, S5PV310_SROM_BW);
+
+ /* set timing for nCS1 suitable for ethernet chip */
+ __raw_writel((0x1 << S5PV310_SROM_BCX__PMC__SHIFT) |
+ (0x9 << S5PV310_SROM_BCX__TACP__SHIFT) |
+ (0xc << S5PV310_SROM_BCX__TCAH__SHIFT) |
+ (0x1 << S5PV310_SROM_BCX__TCOH__SHIFT) |
+ (0x6 << S5PV310_SROM_BCX__TACC__SHIFT) |
+ (0x1 << S5PV310_SROM_BCX__TCOS__SHIFT) |
+ (0x1 << S5PV310_SROM_BCX__TACS__SHIFT), S5PV310_SROM_BC1);
+}
+
+static void __init smdkc210_map_io(void)
+{
+ s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+ s3c24xx_init_clocks(24000000);
+ s3c24xx_init_uarts(smdkc210_uartcfgs, ARRAY_SIZE(smdkc210_uartcfgs));
+}
+
+static void __init smdkc210_machine_init(void)
+{
+ smdkc210_smsc911x_init();
+
+ s3c_sdhci0_set_platdata(&smdkc210_hsmmc0_pdata);
+ s3c_sdhci1_set_platdata(&smdkc210_hsmmc1_pdata);
+ s3c_sdhci2_set_platdata(&smdkc210_hsmmc2_pdata);
+ s3c_sdhci3_set_platdata(&smdkc210_hsmmc3_pdata);
+
+ platform_add_devices(smdkc210_devices, ARRAY_SIZE(smdkc210_devices));
+}
+
+MACHINE_START(SMDKC210, "SMDKC210")
+ /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+ .boot_params = S5P_PA_SDRAM + 0x100,
+ .init_irq = s5pv310_init_irq,
+ .map_io = smdkc210_map_io,
+ .init_machine = smdkc210_machine_init,
+ .timer = &s5pv310_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s5pv310/mach-smdkv310.c b/arch/arm/mach-s5pv310/mach-smdkv310.c
index 0d6ab77709d2..35826d66632c 100644
--- a/arch/arm/mach-s5pv310/mach-smdkv310.c
+++ b/arch/arm/mach-s5pv310/mach-smdkv310.c
@@ -9,16 +9,23 @@
*/
#include <linux/serial_core.h>
+#include <linux/gpio.h>
+#include <linux/mmc/host.h>
+#include <linux/platform_device.h>
+#include <linux/smsc911x.h>
+#include <linux/io.h>
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
-#include <asm/hardware/cache-l2x0.h>
#include <plat/regs-serial.h>
#include <plat/s5pv310.h>
#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/sdhci.h>
#include <mach/map.h>
+#include <mach/regs-srom.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDKV310_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -65,6 +72,107 @@ static struct s3c2410_uartcfg smdkv310_uartcfgs[] __initdata = {
},
};
+static struct s3c_sdhci_platdata smdkv310_hsmmc0_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_GPIO,
+ .ext_cd_gpio = S5PV310_GPK0(2),
+ .ext_cd_gpio_invert = 1,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+#ifdef CONFIG_S5PV310_SDHCI_CH0_8BIT
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA,
+#endif
+};
+
+static struct s3c_sdhci_platdata smdkv310_hsmmc1_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_GPIO,
+ .ext_cd_gpio = S5PV310_GPK0(2),
+ .ext_cd_gpio_invert = 1,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+
+static struct s3c_sdhci_platdata smdkv310_hsmmc2_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_GPIO,
+ .ext_cd_gpio = S5PV310_GPK2(2),
+ .ext_cd_gpio_invert = 1,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+#ifdef CONFIG_S5PV310_SDHCI_CH2_8BIT
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA,
+#endif
+};
+
+static struct s3c_sdhci_platdata smdkv310_hsmmc3_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_GPIO,
+ .ext_cd_gpio = S5PV310_GPK2(2),
+ .ext_cd_gpio_invert = 1,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+
+static struct resource smdkv310_smsc911x_resources[] = {
+ [0] = {
+ .start = S5PV310_PA_SROM_BANK(1),
+ .end = S5PV310_PA_SROM_BANK(1) + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_EINT(5),
+ .end = IRQ_EINT(5),
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+ },
+};
+
+static struct smsc911x_platform_config smsc9215_config = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+ .flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .mac = {0x00, 0x80, 0x00, 0x23, 0x45, 0x67},
+};
+
+static struct platform_device smdkv310_smsc911x = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smdkv310_smsc911x_resources),
+ .resource = smdkv310_smsc911x_resources,
+ .dev = {
+ .platform_data = &smsc9215_config,
+ },
+};
+
+static struct platform_device *smdkv310_devices[] __initdata = {
+ &s3c_device_hsmmc0,
+ &s3c_device_hsmmc1,
+ &s3c_device_hsmmc2,
+ &s3c_device_hsmmc3,
+ &s3c_device_rtc,
+ &s3c_device_wdt,
+ &smdkv310_smsc911x,
+};
+
+static void __init smdkv310_smsc911x_init(void)
+{
+ u32 cs1;
+
+ /* configure nCS1 width to 16 bits */
+ cs1 = __raw_readl(S5PV310_SROM_BW) &
+ ~(S5PV310_SROM_BW__CS_MASK <<
+ S5PV310_SROM_BW__NCS1__SHIFT);
+ cs1 |= ((1 << S5PV310_SROM_BW__DATAWIDTH__SHIFT) |
+ (1 << S5PV310_SROM_BW__WAITENABLE__SHIFT) |
+ (1 << S5PV310_SROM_BW__BYTEENABLE__SHIFT)) <<
+ S5PV310_SROM_BW__NCS1__SHIFT;
+ __raw_writel(cs1, S5PV310_SROM_BW);
+
+ /* set timing for nCS1 suitable for ethernet chip */
+ __raw_writel((0x1 << S5PV310_SROM_BCX__PMC__SHIFT) |
+ (0x9 << S5PV310_SROM_BCX__TACP__SHIFT) |
+ (0xc << S5PV310_SROM_BCX__TCAH__SHIFT) |
+ (0x1 << S5PV310_SROM_BCX__TCOH__SHIFT) |
+ (0x6 << S5PV310_SROM_BCX__TACC__SHIFT) |
+ (0x1 << S5PV310_SROM_BCX__TCOS__SHIFT) |
+ (0x1 << S5PV310_SROM_BCX__TACS__SHIFT), S5PV310_SROM_BC1);
+}
+
static void __init smdkv310_map_io(void)
{
s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -74,16 +182,19 @@ static void __init smdkv310_map_io(void)
static void __init smdkv310_machine_init(void)
{
-#ifdef CONFIG_CACHE_L2X0
- l2x0_init(S5P_VA_L2CC, 1 << 28, 0xffffffff);
-#endif
+ smdkv310_smsc911x_init();
+
+ s3c_sdhci0_set_platdata(&smdkv310_hsmmc0_pdata);
+ s3c_sdhci1_set_platdata(&smdkv310_hsmmc1_pdata);
+ s3c_sdhci2_set_platdata(&smdkv310_hsmmc2_pdata);
+ s3c_sdhci3_set_platdata(&smdkv310_hsmmc3_pdata);
+
+ platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices));
}
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..16d8fc00cafd 100644
--- a/arch/arm/mach-s5pv310/mach-universal_c210.c
+++ b/arch/arm/mach-s5pv310/mach-universal_c210.c
@@ -7,15 +7,20 @@
* published by the Free Software Foundation.
*/
+#include <linux/platform_device.h>
#include <linux/serial_core.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/gpio_keys.h>
+#include <linux/gpio.h>
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
-#include <asm/hardware/cache-l2x0.h>
#include <plat/regs-serial.h>
#include <plat/s5pv310.h>
#include <plat/cpu.h>
+#include <plat/devs.h>
#include <mach/map.h>
@@ -60,6 +65,72 @@ static struct s3c2410_uartcfg universal_uartcfgs[] __initdata = {
},
};
+static struct gpio_keys_button universal_gpio_keys_tables[] = {
+ {
+ .code = KEY_VOLUMEUP,
+ .gpio = S5PV310_GPX2(0), /* XEINT16 */
+ .desc = "gpio-keys: KEY_VOLUMEUP",
+ .type = EV_KEY,
+ .active_low = 1,
+ .debounce_interval = 1,
+ }, {
+ .code = KEY_VOLUMEDOWN,
+ .gpio = S5PV310_GPX2(1), /* XEINT17 */
+ .desc = "gpio-keys: KEY_VOLUMEDOWN",
+ .type = EV_KEY,
+ .active_low = 1,
+ .debounce_interval = 1,
+ }, {
+ .code = KEY_CONFIG,
+ .gpio = S5PV310_GPX2(2), /* XEINT18 */
+ .desc = "gpio-keys: KEY_CONFIG",
+ .type = EV_KEY,
+ .active_low = 1,
+ .debounce_interval = 1,
+ }, {
+ .code = KEY_CAMERA,
+ .gpio = S5PV310_GPX2(3), /* XEINT19 */
+ .desc = "gpio-keys: KEY_CAMERA",
+ .type = EV_KEY,
+ .active_low = 1,
+ .debounce_interval = 1,
+ }, {
+ .code = KEY_OK,
+ .gpio = S5PV310_GPX3(5), /* XEINT29 */
+ .desc = "gpio-keys: KEY_OK",
+ .type = EV_KEY,
+ .active_low = 1,
+ .debounce_interval = 1,
+ },
+};
+
+static struct gpio_keys_platform_data universal_gpio_keys_data = {
+ .buttons = universal_gpio_keys_tables,
+ .nbuttons = ARRAY_SIZE(universal_gpio_keys_tables),
+};
+
+static struct platform_device universal_gpio_keys = {
+ .name = "gpio-keys",
+ .dev = {
+ .platform_data = &universal_gpio_keys_data,
+ },
+};
+
+/* I2C0 */
+static struct i2c_board_info i2c0_devs[] __initdata = {
+ /* Camera, To be updated */
+};
+
+/* I2C1 */
+static struct i2c_board_info i2c1_devs[] __initdata = {
+ /* Gyro, To be updated */
+};
+
+static struct platform_device *universal_devices[] __initdata = {
+ &universal_gpio_keys,
+ &s5p_device_onenand,
+};
+
static void __init universal_map_io(void)
{
s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -69,15 +140,15 @@ static void __init universal_map_io(void)
static void __init universal_machine_init(void)
{
-#ifdef CONFIG_CACHE_L2X0
- l2x0_init(S5P_VA_L2CC, 1 << 28, 0xffffffff);
-#endif
+ i2c_register_board_info(0, i2c0_devs, ARRAY_SIZE(i2c0_devs));
+ i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
+
+ /* Last */
+ platform_add_devices(universal_devices, ARRAY_SIZE(universal_devices));
}
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-s5pv310/setup-i2c0.c b/arch/arm/mach-s5pv310/setup-i2c0.c
index 436712807383..f47f8f3152ec 100644
--- a/arch/arm/mach-s5pv310/setup-i2c0.c
+++ b/arch/arm/mach-s5pv310/setup-i2c0.c
@@ -21,8 +21,6 @@ struct platform_device; /* don't need the contents */
void s3c_i2c0_cfg_gpio(struct platform_device *dev)
{
- s3c_gpio_cfgpin(S5PV310_GPD1(0), S3C_GPIO_SFN(2));
- s3c_gpio_setpull(S5PV310_GPD1(0), S3C_GPIO_PULL_UP);
- s3c_gpio_cfgpin(S5PV310_GPD1(1), S3C_GPIO_SFN(2));
- s3c_gpio_setpull(S5PV310_GPD1(1), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgall_range(S5PV310_GPD1(0), 2,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
}
diff --git a/arch/arm/mach-s5pv310/setup-i2c1.c b/arch/arm/mach-s5pv310/setup-i2c1.c
index 1ecd5bc35b5a..9d07e4e2f14c 100644
--- a/arch/arm/mach-s5pv310/setup-i2c1.c
+++ b/arch/arm/mach-s5pv310/setup-i2c1.c
@@ -18,8 +18,6 @@ struct platform_device; /* don't need the contents */
void s3c_i2c1_cfg_gpio(struct platform_device *dev)
{
- s3c_gpio_cfgpin(S5PV310_GPD1(2), S3C_GPIO_SFN(2));
- s3c_gpio_setpull(S5PV310_GPD1(2), S3C_GPIO_PULL_UP);
- s3c_gpio_cfgpin(S5PV310_GPD1(3), S3C_GPIO_SFN(2));
- s3c_gpio_setpull(S5PV310_GPD1(3), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgall_range(S5PV310_GPD1(2), 2,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
}
diff --git a/arch/arm/mach-s5pv310/setup-i2c2.c b/arch/arm/mach-s5pv310/setup-i2c2.c
index 4c0d8def660a..4163b1233daf 100644
--- a/arch/arm/mach-s5pv310/setup-i2c2.c
+++ b/arch/arm/mach-s5pv310/setup-i2c2.c
@@ -18,8 +18,6 @@ struct platform_device; /* don't need the contents */
void s3c_i2c2_cfg_gpio(struct platform_device *dev)
{
- s3c_gpio_cfgpin(S5PV310_GPA0(6), S3C_GPIO_SFN(3));
- s3c_gpio_setpull(S5PV310_GPA0(6), S3C_GPIO_PULL_UP);
- s3c_gpio_cfgpin(S5PV310_GPA0(7), S3C_GPIO_SFN(3));
- s3c_gpio_setpull(S5PV310_GPA0(7), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgall_range(S5PV310_GPA0(6), 2,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
}
diff --git a/arch/arm/mach-s5pv310/setup-i2c3.c b/arch/arm/mach-s5pv310/setup-i2c3.c
new file mode 100644
index 000000000000..180f153d2a20
--- /dev/null
+++ b/arch/arm/mach-s5pv310/setup-i2c3.c
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-s5pv310/setup-i2c3.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *
+ * I2C3 GPIO 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.
+*/
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c3_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgall_range(S5PV310_GPA1(2), 2,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-s5pv310/setup-i2c4.c b/arch/arm/mach-s5pv310/setup-i2c4.c
new file mode 100644
index 000000000000..909e8dfc5316
--- /dev/null
+++ b/arch/arm/mach-s5pv310/setup-i2c4.c
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-s5pv310/setup-i2c4.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *
+ * I2C4 GPIO 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.
+*/
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c4_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgall_range(S5PV310_GPB(2), 2,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-s5pv310/setup-i2c5.c b/arch/arm/mach-s5pv310/setup-i2c5.c
new file mode 100644
index 000000000000..5d0fa4ac0283
--- /dev/null
+++ b/arch/arm/mach-s5pv310/setup-i2c5.c
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-s5pv310/setup-i2c5.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *
+ * I2C5 GPIO 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.
+*/
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c5_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgall_range(S5PV310_GPB(6), 2,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-s5pv310/setup-i2c6.c b/arch/arm/mach-s5pv310/setup-i2c6.c
new file mode 100644
index 000000000000..34aafab92ac4
--- /dev/null
+++ b/arch/arm/mach-s5pv310/setup-i2c6.c
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-s5pv310/setup-i2c6.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *
+ * I2C6 GPIO 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.
+*/
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c6_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgall_range(S5PV310_GPC1(3), 2,
+ S3C_GPIO_SFN(4), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-s5pv310/setup-i2c7.c b/arch/arm/mach-s5pv310/setup-i2c7.c
new file mode 100644
index 000000000000..9b25b8d18920
--- /dev/null
+++ b/arch/arm/mach-s5pv310/setup-i2c7.c
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-s5pv310/setup-i2c7.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *
+ * I2C7 GPIO 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.
+*/
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c7_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgall_range(S5PV310_GPD0(2), 2,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-s5pv310/setup-sdhci-gpio.c b/arch/arm/mach-s5pv310/setup-sdhci-gpio.c
new file mode 100644
index 000000000000..86d38cc49135
--- /dev/null
+++ b/arch/arm/mach-s5pv310/setup-sdhci-gpio.c
@@ -0,0 +1,152 @@
+/* linux/arch/arm/mach-s5pv310/setup-sdhci-gpio.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV310 - Helper functions for setting up SDHCI device(s) GPIO (HSMMC)
+ *
+ * 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/platform_device.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/regs-sdhci.h>
+#include <plat/sdhci.h>
+
+void s5pv310_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
+{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+ unsigned int gpio;
+
+ /* Set all the necessary GPK0[0:1] pins to special-function 2 */
+ for (gpio = S5PV310_GPK0(0); gpio < S5PV310_GPK0(2); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+
+ switch (width) {
+ case 8:
+ for (gpio = S5PV310_GPK1(3); gpio <= S5PV310_GPK1(6); gpio++) {
+ /* Data pin GPK1[3:6] to special-funtion 3 */
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+ case 4:
+ for (gpio = S5PV310_GPK0(3); gpio <= S5PV310_GPK0(6); gpio++) {
+ /* Data pin GPK0[3:6] to special-funtion 2 */
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+ default:
+ break;
+ }
+
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_cfgpin(S5PV310_GPK0(2), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(S5PV310_GPK0(2), S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+}
+
+void s5pv310_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
+{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+ unsigned int gpio;
+
+ /* Set all the necessary GPK1[0:1] pins to special-function 2 */
+ for (gpio = S5PV310_GPK1(0); gpio < S5PV310_GPK1(2); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+
+ for (gpio = S5PV310_GPK1(3); gpio <= S5PV310_GPK1(6); gpio++) {
+ /* Data pin GPK1[3:6] to special-function 2 */
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_cfgpin(S5PV310_GPK1(2), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(S5PV310_GPK1(2), S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+}
+
+void s5pv310_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
+{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+ unsigned int gpio;
+
+ /* Set all the necessary GPK2[0:1] pins to special-function 2 */
+ for (gpio = S5PV310_GPK2(0); gpio < S5PV310_GPK2(2); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+
+ switch (width) {
+ case 8:
+ for (gpio = S5PV310_GPK3(3); gpio <= S5PV310_GPK3(6); gpio++) {
+ /* Data pin GPK3[3:6] to special-function 3 */
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+ case 4:
+ for (gpio = S5PV310_GPK2(3); gpio <= S5PV310_GPK2(6); gpio++) {
+ /* Data pin GPK2[3:6] to special-function 2 */
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+ default:
+ break;
+ }
+
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_cfgpin(S5PV310_GPK2(2), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(S5PV310_GPK2(2), S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+}
+
+void s5pv310_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width)
+{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+ unsigned int gpio;
+
+ /* Set all the necessary GPK3[0:1] pins to special-function 2 */
+ for (gpio = S5PV310_GPK3(0); gpio < S5PV310_GPK3(2); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+
+ for (gpio = S5PV310_GPK3(3); gpio <= S5PV310_GPK3(6); gpio++) {
+ /* Data pin GPK3[3:6] to special-function 2 */
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_cfgpin(S5PV310_GPK3(2), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(S5PV310_GPK3(2), S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+}
diff --git a/arch/arm/mach-s5pv310/setup-sdhci.c b/arch/arm/mach-s5pv310/setup-sdhci.c
new file mode 100644
index 000000000000..db8358fc4662
--- /dev/null
+++ b/arch/arm/mach-s5pv310/setup-sdhci.c
@@ -0,0 +1,69 @@
+/* linux/arch/arm/mach-s5pv310/setup-sdhci.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV310 - Helper functions for settign up SDHCI device(s) (HSMMC)
+ *
+ * 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/platform_device.h>
+#include <linux/io.h>
+
+#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
+
+#include <plat/regs-sdhci.h>
+
+/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
+
+char *s5pv310_hsmmc_clksrcs[4] = {
+ [0] = NULL,
+ [1] = NULL,
+ [2] = "sclk_mmc", /* mmc_bus */
+ [3] = NULL,
+};
+
+void s5pv310_setup_sdhci_cfg_card(struct platform_device *dev, void __iomem *r,
+ struct mmc_ios *ios, struct mmc_card *card)
+{
+ u32 ctrl2, ctrl3;
+
+ /* don't need to alter anything acording to card-type */
+
+ ctrl2 = readl(r + S3C_SDHCI_CONTROL2);
+
+ /* select base clock source to HCLK */
+
+ ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
+
+ /*
+ * clear async mode, enable conflict mask, rx feedback ctrl, SD
+ * clk hold and no use debounce count
+ */
+
+ ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
+ S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
+ S3C_SDHCI_CTRL2_ENFBCLKRX |
+ S3C_SDHCI_CTRL2_DFCNT_NONE |
+ S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
+
+ /* Tx and Rx feedback clock delay control */
+
+ if (ios->clock < 25 * 1000000)
+ ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
+ S3C_SDHCI_CTRL3_FCSEL2 |
+ S3C_SDHCI_CTRL3_FCSEL1 |
+ S3C_SDHCI_CTRL3_FCSEL0);
+ else
+ ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
+
+ writel(ctrl2, r + S3C_SDHCI_CONTROL2);
+ writel(ctrl3, r + S3C_SDHCI_CONTROL3);
+}
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..96f7dc103b59 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:
@@ -184,16 +184,15 @@ static int sa1100_target(struct cpufreq_policy *policy,
{
unsigned int cur = sa11x0_getspeed(0);
unsigned int new_ppcr;
-
struct cpufreq_freqs freqs;
+
+ new_ppcr = sa11x0_freq_to_ppcr(target_freq);
switch(relation){
case CPUFREQ_RELATION_L:
- new_ppcr = sa11x0_freq_to_ppcr(target_freq);
if (sa11x0_ppcr_to_freq(new_ppcr) > policy->max)
new_ppcr--;
break;
case CPUFREQ_RELATION_H:
- new_ppcr = sa11x0_freq_to_ppcr(target_freq);
if ((sa11x0_ppcr_to_freq(new_ppcr) > target_freq) &&
(sa11x0_ppcr_to_freq(new_ppcr - 1) >= policy->min))
new_ppcr--;
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..46ca4d4abf91 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -30,7 +30,6 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
-#include <linux/mmc/host.h>
#include <linux/mmc/sh_mmcif.h>
#include <linux/i2c.h>
#include <linux/i2c/tsc2007.h>
@@ -44,6 +43,10 @@
#include <linux/input/sh_keysc.h>
#include <linux/usb/r8a66597.h>
+#include <media/sh_mobile_ceu.h>
+#include <media/sh_mobile_csi2.h>
+#include <media/soc_camera.h>
+
#include <sound/sh_fsi.h>
#include <video/sh_mobile_hdmi.h>
@@ -235,10 +238,22 @@ static struct platform_device smc911x_device = {
},
};
+/*
+ * The card detect pin of the top SD/MMC slot (CN7) is active low and is
+ * connected to GPIO A22 of SH7372 (GPIO_PORT41).
+ */
+static int slot_cn7_get_cd(struct platform_device *pdev)
+{
+ if (gpio_is_valid(GPIO_PORT41))
+ return !gpio_get_value(GPIO_PORT41);
+ else
+ return -ENXIO;
+}
+
/* SH_MMCIF */
static struct resource sh_mmcif_resources[] = {
[0] = {
- .name = "SH_MMCIF",
+ .name = "MMCIF",
.start = 0xE6BD0000,
.end = 0xE6BD00FF,
.flags = IORESOURCE_MEM,
@@ -261,6 +276,7 @@ static struct sh_mmcif_plat_data sh_mmcif_plat = {
.caps = MMC_CAP_4_BIT_DATA |
MMC_CAP_8_BIT_DATA |
MMC_CAP_NEEDS_POLL,
+ .get_cd = slot_cn7_get_cd,
};
static struct platform_device sh_mmcif_device = {
@@ -310,6 +326,8 @@ static struct sh_mobile_sdhi_info sdhi1_info = {
.dma_slave_rx = SHDMA_SLAVE_SDHI1_RX,
.tmio_ocr_mask = MMC_VDD_165_195,
.tmio_flags = TMIO_MMC_WRPROTECT_DISABLE,
+ .tmio_caps = MMC_CAP_NEEDS_POLL,
+ .get_cd = slot_cn7_get_cd,
};
static struct resource sdhi1_resources[] = {
@@ -375,10 +393,40 @@ static struct platform_device usb1_host_device = {
.resource = usb1_host_resources,
};
+const static struct fb_videomode ap4evb_lcdc_modes[] = {
+ {
+#ifdef CONFIG_AP4EVB_QHD
+ .name = "R63302(QHD)",
+ .xres = 544,
+ .yres = 961,
+ .left_margin = 72,
+ .right_margin = 600,
+ .hsync_len = 16,
+ .upper_margin = 8,
+ .lower_margin = 8,
+ .vsync_len = 2,
+ .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
+#else
+ .name = "WVGA Panel",
+ .xres = 800,
+ .yres = 480,
+ .left_margin = 220,
+ .right_margin = 110,
+ .hsync_len = 70,
+ .upper_margin = 20,
+ .lower_margin = 5,
+ .vsync_len = 5,
+ .sync = 0,
+#endif
+ },
+};
+
static struct sh_mobile_lcdc_info lcdc_info = {
.ch[0] = {
.chan = LCDC_CHAN_MAINLCD,
.bpp = 16,
+ .lcd_cfg = ap4evb_lcdc_modes,
+ .num_cfg = ARRAY_SIZE(ap4evb_lcdc_modes),
}
};
@@ -517,27 +565,6 @@ static struct platform_device *qhd_devices[] __initdata = {
/* FSI */
#define IRQ_FSI evt2irq(0x1840)
-#define FSIACKCR 0xE6150018
-static void fsiackcr_init(struct clk *clk)
-{
- u32 status = __raw_readl(clk->enable_reg);
-
- /* use external clock */
- status &= ~0x000000ff;
- status |= 0x00000080;
- __raw_writel(status, clk->enable_reg);
-}
-
-static struct clk_ops fsiackcr_clk_ops = {
- .init = fsiackcr_init,
-};
-
-static struct clk fsiackcr_clk = {
- .ops = &fsiackcr_clk_ops,
- .enable_reg = (void __iomem *)FSIACKCR,
- .rate = 0, /* unknown */
-};
-
static struct sh_fsi_platform_info fsi_info = {
.porta_flags = SH_FSI_BRS_INV |
SH_FSI_OUT_SLAVE_MODE |
@@ -577,26 +604,6 @@ static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info = {
.interface_type = RGB24,
.clock_divider = 1,
.flags = LCDC_FLAGS_DWPOL,
- .lcd_cfg = {
- .name = "HDMI",
- /* So far only 720p is supported */
- .xres = 1280,
- .yres = 720,
- /*
- * If left and right margins are not multiples of 8,
- * LDHAJR will be adjusted accordingly by the LCDC
- * driver. Until we start using EDID, these values
- * might have to be adjusted for different monitors.
- */
- .left_margin = 200,
- .right_margin = 88,
- .hsync_len = 48,
- .upper_margin = 20,
- .lower_margin = 5,
- .vsync_len = 5,
- .pixclock = 13468,
- .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
- },
}
};
@@ -608,7 +615,7 @@ static struct resource lcdc1_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = intcs_evt2irq(0x17a0),
+ .start = intcs_evt2irq(0x1780),
.flags = IORESOURCE_IRQ,
},
};
@@ -689,6 +696,95 @@ static struct platform_device leds_device = {
},
};
+static struct i2c_board_info imx074_info = {
+ I2C_BOARD_INFO("imx074", 0x1a),
+};
+
+struct soc_camera_link imx074_link = {
+ .bus_id = 0,
+ .board_info = &imx074_info,
+ .i2c_adapter_id = 0,
+ .module_name = "imx074",
+};
+
+static struct platform_device ap4evb_camera = {
+ .name = "soc-camera-pdrv",
+ .id = 0,
+ .dev = {
+ .platform_data = &imx074_link,
+ },
+};
+
+static struct sh_csi2_client_config csi2_clients[] = {
+ {
+ .phy = SH_CSI2_PHY_MAIN,
+ .lanes = 3,
+ .channel = 0,
+ .pdev = &ap4evb_camera,
+ },
+};
+
+static struct sh_csi2_pdata csi2_info = {
+ .type = SH_CSI2C,
+ .clients = csi2_clients,
+ .num_clients = ARRAY_SIZE(csi2_clients),
+ .flags = SH_CSI2_ECC | SH_CSI2_CRC,
+};
+
+static struct resource csi2_resources[] = {
+ [0] = {
+ .name = "CSI2",
+ .start = 0xffc90000,
+ .end = 0xffc90fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = intcs_evt2irq(0x17a0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device csi2_device = {
+ .name = "sh-mobile-csi2",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(csi2_resources),
+ .resource = csi2_resources,
+ .dev = {
+ .platform_data = &csi2_info,
+ },
+};
+
+static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
+ .flags = SH_CEU_FLAG_USE_8BIT_BUS,
+ .csi2_dev = &csi2_device.dev,
+};
+
+static struct resource ceu_resources[] = {
+ [0] = {
+ .name = "CEU",
+ .start = 0xfe910000,
+ .end = 0xfe91009f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = intcs_evt2irq(0x880),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ /* place holder for contiguous memory */
+ },
+};
+
+static struct platform_device ceu_device = {
+ .name = "sh_mobile_ceu",
+ .id = 0, /* "ceu0" clock */
+ .num_resources = ARRAY_SIZE(ceu_resources),
+ .resource = ceu_resources,
+ .dev = {
+ .platform_data = &sh_mobile_ceu_info,
+ },
+};
+
static struct platform_device *ap4evb_devices[] __initdata = {
&leds_device,
&nor_flash_device,
@@ -701,6 +797,9 @@ static struct platform_device *ap4evb_devices[] __initdata = {
&lcdc1_device,
&lcdc_device,
&hdmi_device,
+ &csi2_device,
+ &ceu_device,
+ &ap4evb_camera,
};
static int __init hdmi_init_pm_clock(void)
@@ -715,22 +814,22 @@ static int __init hdmi_init_pm_clock(void)
goto out;
}
- ret = clk_set_parent(&pllc2_clk, &dv_clki_div2_clk);
+ ret = clk_set_parent(&sh7372_pllc2_clk, &sh7372_dv_clki_div2_clk);
if (ret < 0) {
- pr_err("Cannot set PLLC2 parent: %d, %d users\n", ret, pllc2_clk.usecount);
+ pr_err("Cannot set PLLC2 parent: %d, %d users\n", ret, sh7372_pllc2_clk.usecount);
goto out;
}
- pr_debug("PLLC2 initial frequency %lu\n", clk_get_rate(&pllc2_clk));
+ pr_debug("PLLC2 initial frequency %lu\n", clk_get_rate(&sh7372_pllc2_clk));
- rate = clk_round_rate(&pllc2_clk, 594000000);
+ rate = clk_round_rate(&sh7372_pllc2_clk, 594000000);
if (rate < 0) {
pr_err("Cannot get suitable rate: %ld\n", rate);
ret = rate;
goto out;
}
- ret = clk_set_rate(&pllc2_clk, rate);
+ ret = clk_set_rate(&sh7372_pllc2_clk, rate);
if (ret < 0) {
pr_err("Cannot set rate %ld: %d\n", rate, ret);
goto out;
@@ -738,7 +837,7 @@ static int __init hdmi_init_pm_clock(void)
pr_debug("PLLC2 set frequency %lu\n", rate);
- ret = clk_set_parent(hdmi_ick, &pllc2_clk);
+ ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk);
if (ret < 0) {
pr_err("Cannot set HDMI parent: %d\n", ret);
goto out;
@@ -752,11 +851,51 @@ out:
device_initcall(hdmi_init_pm_clock);
+#define FSIACK_DUMMY_RATE 48000
+static int __init fsi_init_pm_clock(void)
+{
+ struct clk *fsia_ick;
+ int ret;
+
+ /*
+ * FSIACK is connected to AK4642,
+ * and the rate is depend on playing sound rate.
+ * So, set dummy rate (= 48k) here
+ */
+ ret = clk_set_rate(&sh7372_fsiack_clk, FSIACK_DUMMY_RATE);
+ if (ret < 0) {
+ pr_err("Cannot set FSIACK dummy rate: %d\n", ret);
+ return ret;
+ }
+
+ fsia_ick = clk_get(&fsi_device.dev, "icka");
+ if (IS_ERR(fsia_ick)) {
+ ret = PTR_ERR(fsia_ick);
+ pr_err("Cannot get FSI ICK: %d\n", ret);
+ return ret;
+ }
+
+ ret = clk_set_parent(fsia_ick, &sh7372_fsiack_clk);
+ if (ret < 0) {
+ pr_err("Cannot set FSI-A parent: %d\n", ret);
+ goto out;
+ }
+
+ ret = clk_set_rate(fsia_ick, FSIACK_DUMMY_RATE);
+ if (ret < 0)
+ pr_err("Cannot set FSI-A rate: %d\n", ret);
+
+out:
+ clk_put(fsia_ick);
+
+ return ret;
+}
+device_initcall(fsi_init_pm_clock);
+
/*
* FIXME !!
*
* gpio_no_direction
- * gpio_pull_up
* are quick_hack.
*
* current gpio frame work doesn't have
@@ -768,49 +907,37 @@ static void __init gpio_no_direction(u32 addr)
__raw_writeb(0x00, addr);
}
-static void __init gpio_pull_up(u32 addr)
-{
- u8 data = __raw_readb(addr);
-
- data &= 0x0F;
- data |= 0xC0;
- __raw_writeb(data, addr);
-}
-
/* TouchScreen */
+#ifdef CONFIG_AP4EVB_QHD
+# define GPIO_TSC_IRQ GPIO_FN_IRQ28_123
+# define GPIO_TSC_PORT GPIO_PORT123
+#else /* WVGA */
+# define GPIO_TSC_IRQ GPIO_FN_IRQ7_40
+# define GPIO_TSC_PORT GPIO_PORT40
+#endif
+
#define IRQ28 evt2irq(0x3380) /* IRQ28A */
#define IRQ7 evt2irq(0x02e0) /* IRQ7A */
static int ts_get_pendown_state(void)
{
- int val1, val2;
+ int val;
- gpio_free(GPIO_FN_IRQ28_123);
- gpio_free(GPIO_FN_IRQ7_40);
+ gpio_free(GPIO_TSC_IRQ);
- gpio_request(GPIO_PORT123, NULL);
- gpio_request(GPIO_PORT40, NULL);
+ gpio_request(GPIO_TSC_PORT, NULL);
- gpio_direction_input(GPIO_PORT123);
- gpio_direction_input(GPIO_PORT40);
+ gpio_direction_input(GPIO_TSC_PORT);
- val1 = gpio_get_value(GPIO_PORT123);
- val2 = gpio_get_value(GPIO_PORT40);
+ val = gpio_get_value(GPIO_TSC_PORT);
- gpio_request(GPIO_FN_IRQ28_123, NULL); /* for QHD */
- gpio_request(GPIO_FN_IRQ7_40, NULL); /* for WVGA */
+ gpio_request(GPIO_TSC_IRQ, NULL);
- return val1 ^ val2;
+ return !val;
}
-#define PORT40CR 0xE6051028
-#define PORT123CR 0xE605007B
static int ts_init(void)
{
- gpio_request(GPIO_FN_IRQ28_123, NULL); /* for QHD */
- gpio_request(GPIO_FN_IRQ7_40, NULL); /* for WVGA */
-
- gpio_pull_up(PORT40CR);
- gpio_pull_up(PORT123CR);
+ gpio_request(GPIO_TSC_IRQ, NULL);
return 0;
}
@@ -948,6 +1075,10 @@ static void __init ap4evb_init(void)
gpio_no_direction(GPIO_PORT9CR); /* FSIAOBT needs no direction */
gpio_no_direction(GPIO_PORT10CR); /* FSIAOLR needs no direction */
+ /* card detect pin for MMC slot (CN7) */
+ gpio_request(GPIO_PORT41, NULL);
+ gpio_direction_input(GPIO_PORT41);
+
/* set SPU2 clock to 119.6 MHz */
clk = clk_get(NULL, "spu_clk");
if (!IS_ERR(clk)) {
@@ -955,14 +1086,6 @@ static void __init ap4evb_init(void)
clk_put(clk);
}
- /* change parent of FSI A */
- clk = clk_get(NULL, "fsia_clk");
- if (!IS_ERR(clk)) {
- clk_register(&fsiackcr_clk);
- clk_set_parent(clk, &fsiackcr_clk);
- clk_put(clk);
- }
-
/*
* set irq priority, to avoid sound chopping
* when NFS rootfs is used
@@ -977,8 +1100,10 @@ static void __init ap4evb_init(void)
ARRAY_SIZE(i2c1_devices));
#ifdef CONFIG_AP4EVB_QHD
+
/*
- * QHD
+ * For QHD Panel (MIPI-DSI, CONFIG_AP4EVB_QHD=y) and
+ * IRQ28 for Touch Panel, set dip switches S3, S43 as OFF, ON.
*/
/* enable KEYSC */
@@ -1004,17 +1129,6 @@ static void __init ap4evb_init(void)
lcdc_info.ch[0].interface_type = RGB24;
lcdc_info.ch[0].clock_divider = 1;
lcdc_info.ch[0].flags = LCDC_FLAGS_DWPOL;
- lcdc_info.ch[0].lcd_cfg.name = "R63302(QHD)";
- lcdc_info.ch[0].lcd_cfg.xres = 544;
- lcdc_info.ch[0].lcd_cfg.yres = 961;
- lcdc_info.ch[0].lcd_cfg.left_margin = 72;
- lcdc_info.ch[0].lcd_cfg.right_margin = 600;
- lcdc_info.ch[0].lcd_cfg.hsync_len = 16;
- lcdc_info.ch[0].lcd_cfg.upper_margin = 8;
- lcdc_info.ch[0].lcd_cfg.lower_margin = 8;
- lcdc_info.ch[0].lcd_cfg.vsync_len = 2;
- lcdc_info.ch[0].lcd_cfg.sync = FB_SYNC_VERT_HIGH_ACT |
- FB_SYNC_HOR_HIGH_ACT;
lcdc_info.ch[0].lcd_size_cfg.width = 44;
lcdc_info.ch[0].lcd_size_cfg.height = 79;
@@ -1022,8 +1136,10 @@ static void __init ap4evb_init(void)
#else
/*
- * WVGA
+ * For WVGA Panel (18-bit RGB, CONFIG_AP4EVB_WVGA=y) and
+ * IRQ7 for Touch Panel, set dip switches S3, S43 to ON, OFF.
*/
+
gpio_request(GPIO_FN_LCDD17, NULL);
gpio_request(GPIO_FN_LCDD16, NULL);
gpio_request(GPIO_FN_LCDD15, NULL);
@@ -1055,16 +1171,6 @@ static void __init ap4evb_init(void)
lcdc_info.ch[0].interface_type = RGB18;
lcdc_info.ch[0].clock_divider = 2;
lcdc_info.ch[0].flags = 0;
- lcdc_info.ch[0].lcd_cfg.name = "WVGA Panel";
- lcdc_info.ch[0].lcd_cfg.xres = 800;
- lcdc_info.ch[0].lcd_cfg.yres = 480;
- lcdc_info.ch[0].lcd_cfg.left_margin = 220;
- lcdc_info.ch[0].lcd_cfg.right_margin = 110;
- lcdc_info.ch[0].lcd_cfg.hsync_len = 70;
- lcdc_info.ch[0].lcd_cfg.upper_margin = 20;
- lcdc_info.ch[0].lcd_cfg.lower_margin = 5;
- lcdc_info.ch[0].lcd_cfg.vsync_len = 5;
- lcdc_info.ch[0].lcd_cfg.sync = 0;
lcdc_info.ch[0].lcd_size_cfg.width = 152;
lcdc_info.ch[0].lcd_size_cfg.height = 91;
@@ -1075,6 +1181,23 @@ static void __init ap4evb_init(void)
i2c_register_board_info(0, &tsc_device, 1);
#endif /* CONFIG_AP4EVB_QHD */
+ /* CEU */
+
+ /*
+ * TODO: reserve memory for V4L2 DMA buffers, when a suitable API
+ * becomes available
+ */
+
+ /* MIPI-CSI stuff */
+ gpio_request(GPIO_FN_VIO_CKO, NULL);
+
+ clk = clk_get(NULL, "vck1_clk");
+ if (!IS_ERR(clk)) {
+ clk_set_rate(clk, clk_round_rate(clk, 13000000));
+ clk_enable(clk);
+ clk_put(clk);
+ }
+
sh7372_add_standard_devices();
/* HDMI */
@@ -1097,7 +1220,7 @@ static void __init ap4evb_timer_init(void)
shmobile_timer.init();
/* External clock source */
- clk_set_rate(&dv_clki_clk, 27000000);
+ clk_set_rate(&sh7372_dv_clki_clk, 27000000);
}
static struct sys_timer ap4evb_timer = {
@@ -1105,8 +1228,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-shmobile/clock-sh7367.c b/arch/arm/mach-shmobile/clock-sh7367.c
index b6454c9f2abb..9f78729098f2 100644
--- a/arch/arm/mach-shmobile/clock-sh7367.c
+++ b/arch/arm/mach-shmobile/clock-sh7367.c
@@ -321,7 +321,7 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[SYMSTP001]), /* SCIFA3 */
CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[SYMSTP000]), /* SCIFA4 */
CLKDEV_DEV_ID("sh_siu", &mstp_clks[SYMSTP231]), /* SIU */
- CLKDEV_CON_ID("cmt1", &mstp_clks[SYMSTP229]), /* CMT10 */
+ CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[SYMSTP229]), /* CMT10 */
CLKDEV_DEV_ID("sh_irda", &mstp_clks[SYMSTP225]), /* IRDA */
CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[SYMSTP223]), /* IIC1 */
CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[SYMSTP222]), /* USBHS */
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c
index 759468992ad2..8565aefa21fd 100644
--- a/arch/arm/mach-shmobile/clock-sh7372.c
+++ b/arch/arm/mach-shmobile/clock-sh7372.c
@@ -51,7 +51,7 @@
#define SMSTPCR4 0xe6150140
/* Platforms must set frequency on their DV_CLKI pin */
-struct clk dv_clki_clk = {
+struct clk sh7372_dv_clki_clk = {
};
/* Fixed 32 KHz root clock from EXTALR pin */
@@ -86,9 +86,9 @@ static struct clk_ops div2_clk_ops = {
};
/* Divide dv_clki by two */
-struct clk dv_clki_div2_clk = {
+struct clk sh7372_dv_clki_div2_clk = {
.ops = &div2_clk_ops,
- .parent = &dv_clki_clk,
+ .parent = &sh7372_dv_clki_clk,
};
/* Divide extal1 by two */
@@ -150,7 +150,7 @@ static struct clk pllc1_div2_clk = {
static struct clk *pllc2_parent[] = {
[0] = &extal1_div2_clk,
[1] = &extal2_div2_clk,
- [2] = &dv_clki_div2_clk,
+ [2] = &sh7372_dv_clki_div2_clk,
};
/* Only multipliers 20 * 2 to 46 * 2 are valid, last entry for CPUFREQ_TABLE_END */
@@ -284,7 +284,7 @@ static struct clk_ops pllc2_clk_ops = {
.set_parent = pllc2_set_parent,
};
-struct clk pllc2_clk = {
+struct clk sh7372_pllc2_clk = {
.ops = &pllc2_clk_ops,
.parent = &extal1_div2_clk,
.freq_table = pllc2_freq_table,
@@ -292,19 +292,28 @@ struct clk pllc2_clk = {
.parent_num = ARRAY_SIZE(pllc2_parent),
};
+/* External input clock (pin name: FSIACK/FSIBCK ) */
+struct clk sh7372_fsiack_clk = {
+};
+
+struct clk sh7372_fsibck_clk = {
+};
+
static struct clk *main_clks[] = {
- &dv_clki_clk,
+ &sh7372_dv_clki_clk,
&r_clk,
&sh7372_extal1_clk,
&sh7372_extal2_clk,
- &dv_clki_div2_clk,
+ &sh7372_dv_clki_div2_clk,
&extal1_div2_clk,
&extal2_div2_clk,
&extal2_div4_clk,
&pllc0_clk,
&pllc1_clk,
&pllc1_div2_clk,
- &pllc2_clk,
+ &sh7372_pllc2_clk,
+ &sh7372_fsiack_clk,
+ &sh7372_fsibck_clk,
};
static void div4_kick(struct clk *clk)
@@ -357,7 +366,7 @@ static struct clk div4_clks[DIV4_NR] = {
};
enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO,
- DIV6_FSIA, DIV6_FSIB, DIV6_SUB, DIV6_SPU,
+ DIV6_SUB, DIV6_SPU,
DIV6_VOU, DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
DIV6_NR };
@@ -367,8 +376,6 @@ static struct clk div6_clks[DIV6_NR] = {
[DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0),
[DIV6_FMSI] = SH_CLK_DIV6(&pllc1_div2_clk, FMSICKCR, 0),
[DIV6_FMSO] = SH_CLK_DIV6(&pllc1_div2_clk, FMSOCKCR, 0),
- [DIV6_FSIA] = SH_CLK_DIV6(&pllc1_div2_clk, FSIACKCR, 0),
- [DIV6_FSIB] = SH_CLK_DIV6(&pllc1_div2_clk, FSIBCKCR, 0),
[DIV6_SUB] = SH_CLK_DIV6(&sh7372_extal2_clk, SUBCKCR, 0),
[DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0),
[DIV6_VOU] = SH_CLK_DIV6(&pllc1_div2_clk, VOUCKCR, 0),
@@ -377,24 +384,42 @@ static struct clk div6_clks[DIV6_NR] = {
[DIV6_DSI1P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI1PCKCR, 0),
};
-enum { DIV6_HDMI, DIV6_REPARENT_NR };
+enum { DIV6_HDMI, DIV6_FSIA, DIV6_FSIB, DIV6_REPARENT_NR };
/* Indices are important - they are the actual src selecting values */
static struct clk *hdmi_parent[] = {
[0] = &pllc1_div2_clk,
- [1] = &pllc2_clk,
- [2] = &dv_clki_clk,
+ [1] = &sh7372_pllc2_clk,
+ [2] = &sh7372_dv_clki_clk,
[3] = NULL, /* pllc2_div4 not implemented yet */
};
+static struct clk *fsiackcr_parent[] = {
+ [0] = &pllc1_div2_clk,
+ [1] = &sh7372_pllc2_clk,
+ [2] = &sh7372_fsiack_clk, /* external input for FSI A */
+ [3] = NULL, /* setting prohibited */
+};
+
+static struct clk *fsibckcr_parent[] = {
+ [0] = &pllc1_div2_clk,
+ [1] = &sh7372_pllc2_clk,
+ [2] = &sh7372_fsibck_clk, /* external input for FSI B */
+ [3] = NULL, /* setting prohibited */
+};
+
static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
[DIV6_HDMI] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, HDMICKCR, 0,
hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2),
+ [DIV6_FSIA] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIACKCR, 0,
+ fsiackcr_parent, ARRAY_SIZE(fsiackcr_parent), 6, 2),
+ [DIV6_FSIB] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIBCKCR, 0,
+ fsibckcr_parent, ARRAY_SIZE(fsibckcr_parent), 6, 2),
};
enum { MSTP001,
MSTP131, MSTP130,
- MSTP129, MSTP128, MSTP127, MSTP126,
+ MSTP129, MSTP128, MSTP127, MSTP126, MSTP125,
MSTP118, MSTP117, MSTP116,
MSTP106, MSTP101, MSTP100,
MSTP223,
@@ -414,6 +439,7 @@ static struct clk mstp_clks[MSTP_NR] = {
[MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */
[MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU */
[MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2 */
+ [MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
[MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */
[MSTP117] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */
[MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
@@ -429,7 +455,7 @@ static struct clk mstp_clks[MSTP_NR] = {
[MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
[MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
[MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
- [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSIA */
+ [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSI2 */
[MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
[MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */
[MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
@@ -445,10 +471,11 @@ static struct clk mstp_clks[MSTP_NR] = {
#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk }
+#define CLKDEV_ICK_ID(_cid, _did, _clk) { .con_id = _cid, .dev_id = _did, .clk = _clk }
static struct clk_lookup lookups[] = {
/* main clocks */
- CLKDEV_CON_ID("dv_clki_div2_clk", &dv_clki_div2_clk),
+ CLKDEV_CON_ID("dv_clki_div2_clk", &sh7372_dv_clki_div2_clk),
CLKDEV_CON_ID("r_clk", &r_clk),
CLKDEV_CON_ID("extal1", &sh7372_extal1_clk),
CLKDEV_CON_ID("extal2", &sh7372_extal2_clk),
@@ -458,7 +485,7 @@ static struct clk_lookup lookups[] = {
CLKDEV_CON_ID("pllc0_clk", &pllc0_clk),
CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
- CLKDEV_CON_ID("pllc2_clk", &pllc2_clk),
+ CLKDEV_CON_ID("pllc2_clk", &sh7372_pllc2_clk),
/* DIV4 clocks */
CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
@@ -483,8 +510,8 @@ static struct clk_lookup lookups[] = {
CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]),
CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]),
- CLKDEV_CON_ID("fsia_clk", &div6_clks[DIV6_FSIA]),
- CLKDEV_CON_ID("fsib_clk", &div6_clks[DIV6_FSIB]),
+ CLKDEV_CON_ID("fsia_clk", &div6_reparent_clks[DIV6_FSIA]),
+ CLKDEV_CON_ID("fsib_clk", &div6_reparent_clks[DIV6_FSIB]),
CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]),
@@ -501,6 +528,8 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */
CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU */
CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2 */
+ CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */
+ CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */
CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */
CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */
CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */
@@ -516,7 +545,7 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
- CLKDEV_CON_ID("cmt1", &mstp_clks[MSTP329]), /* CMT10 */
+ CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */
CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP323]), /* USB0 */
@@ -531,7 +560,10 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */
CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */
CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
- {.con_id = "ick", .dev_id = "sh-mobile-hdmi", .clk = &div6_reparent_clks[DIV6_HDMI]},
+
+ CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]),
+ CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]),
+ CLKDEV_ICK_ID("ickb", "sh_fsi2", &div6_reparent_clks[DIV6_FSIB]),
};
void __init sh7372_clock_init(void)
@@ -548,7 +580,7 @@ void __init sh7372_clock_init(void)
ret = sh_clk_div6_register(div6_clks, DIV6_NR);
if (!ret)
- ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_NR);
+ ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_REPARENT_NR);
if (!ret)
ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
diff --git a/arch/arm/mach-shmobile/clock-sh7377.c b/arch/arm/mach-shmobile/clock-sh7377.c
index e007c28cf0a8..f91395aeb9ab 100644
--- a/arch/arm/mach-shmobile/clock-sh7377.c
+++ b/arch/arm/mach-shmobile/clock-sh7377.c
@@ -333,7 +333,7 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
- CLKDEV_CON_ID("cmt1", &mstp_clks[MSTP329]), /* CMT10 */
+ CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
CLKDEV_DEV_ID("sh_irda", &mstp_clks[MSTP325]), /* IRDA */
CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USBHS */
diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h
index 33e9700ded7e..147775a94bce 100644
--- a/arch/arm/mach-shmobile/include/mach/sh7372.h
+++ b/arch/arm/mach-shmobile/include/mach/sh7372.h
@@ -457,8 +457,12 @@ enum {
SHDMA_SLAVE_SDHI2_TX,
};
-extern struct clk dv_clki_clk;
-extern struct clk dv_clki_div2_clk;
-extern struct clk pllc2_clk;
+extern struct clk sh7372_extal1_clk;
+extern struct clk sh7372_extal2_clk;
+extern struct clk sh7372_dv_clki_clk;
+extern struct clk sh7372_dv_clki_div2_clk;
+extern struct clk sh7372_pllc2_clk;
+extern struct clk sh7372_fsiack_clk;
+extern struct clk sh7372_fsibck_clk;
#endif /* __ASM_SH7372_H__ */
diff --git a/arch/arm/mach-shmobile/intc-sh7372.c b/arch/arm/mach-shmobile/intc-sh7372.c
index e3551b56cd03..4cd3cae38e72 100644
--- a/arch/arm/mach-shmobile/intc-sh7372.c
+++ b/arch/arm/mach-shmobile/intc-sh7372.c
@@ -369,9 +369,13 @@ enum {
INTCS,
/* interrupt sources INTCS */
+
+ /* IRQ0S - IRQ31S */
VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3,
RTDMAC_1_DEI0, RTDMAC_1_DEI1, RTDMAC_1_DEI2, RTDMAC_1_DEI3,
CEU, BEU_BEU0, BEU_BEU1, BEU_BEU2,
+ /* MFI */
+ /* BBIF2 */
VPU,
TSIF1,
_3DG_SGX530,
@@ -379,13 +383,17 @@ enum {
IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2,
IPMMU_IPMMUR, IPMMU_IPMMUR2,
RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR,
+ /* KEYSC */
+ /* TTI20 */
MSIOF,
IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0,
TMU_TUNI0, TMU_TUNI1, TMU_TUNI2,
CMT0,
TSIF0,
+ /* CMT2 */
LMB,
CTI,
+ /* RWDT0 */
ICB,
JPU_JPEG,
LCDC,
@@ -397,11 +405,17 @@ enum {
CSIRX,
DSITX_DSITX0,
DSITX_DSITX1,
+ /* SPU2 */
+ /* FSI */
+ /* FMSI */
+ /* HDMI */
TMU1_TUNI0, TMU1_TUNI1, TMU1_TUNI2,
CMT4,
DSITX1_DSITX1_0,
DSITX1_DSITX1_1,
+ /* MFIS2 */
CPORTS2R,
+ /* CEC */
JPU6E,
/* interrupt groups INTCS */
@@ -410,12 +424,15 @@ enum {
};
static struct intc_vect intcs_vectors[] = {
+ /* IRQ0S - IRQ31S */
INTCS_VECT(VEU_VEU0, 0x700), INTCS_VECT(VEU_VEU1, 0x720),
INTCS_VECT(VEU_VEU2, 0x740), INTCS_VECT(VEU_VEU3, 0x760),
INTCS_VECT(RTDMAC_1_DEI0, 0x800), INTCS_VECT(RTDMAC_1_DEI1, 0x820),
INTCS_VECT(RTDMAC_1_DEI2, 0x840), INTCS_VECT(RTDMAC_1_DEI3, 0x860),
INTCS_VECT(CEU, 0x880), INTCS_VECT(BEU_BEU0, 0x8a0),
INTCS_VECT(BEU_BEU1, 0x8c0), INTCS_VECT(BEU_BEU2, 0x8e0),
+ /* MFI */
+ /* BBIF2 */
INTCS_VECT(VPU, 0x980),
INTCS_VECT(TSIF1, 0x9a0),
INTCS_VECT(_3DG_SGX530, 0x9e0),
@@ -425,14 +442,19 @@ static struct intc_vect intcs_vectors[] = {
INTCS_VECT(IPMMU_IPMMUR, 0xb00), INTCS_VECT(IPMMU_IPMMUR2, 0xb20),
INTCS_VECT(RTDMAC_2_DEI4, 0xb80), INTCS_VECT(RTDMAC_2_DEI5, 0xba0),
INTCS_VECT(RTDMAC_2_DADERR, 0xbc0),
+ /* KEYSC */
+ /* TTI20 */
+ INTCS_VECT(MSIOF, 0x0d20),
INTCS_VECT(IIC0_ALI0, 0xe00), INTCS_VECT(IIC0_TACKI0, 0xe20),
INTCS_VECT(IIC0_WAITI0, 0xe40), INTCS_VECT(IIC0_DTEI0, 0xe60),
INTCS_VECT(TMU_TUNI0, 0xe80), INTCS_VECT(TMU_TUNI1, 0xea0),
INTCS_VECT(TMU_TUNI2, 0xec0),
INTCS_VECT(CMT0, 0xf00),
INTCS_VECT(TSIF0, 0xf20),
+ /* CMT2 */
INTCS_VECT(LMB, 0xf60),
INTCS_VECT(CTI, 0x400),
+ /* RWDT0 */
INTCS_VECT(ICB, 0x480),
INTCS_VECT(JPU_JPEG, 0x560),
INTCS_VECT(LCDC, 0x580),
@@ -446,12 +468,18 @@ static struct intc_vect intcs_vectors[] = {
INTCS_VECT(CSIRX, 0x17a0),
INTCS_VECT(DSITX_DSITX0, 0x17c0),
INTCS_VECT(DSITX_DSITX1, 0x17e0),
+ /* SPU2 */
+ /* FSI */
+ /* FMSI */
+ /* HDMI */
INTCS_VECT(TMU1_TUNI0, 0x1900), INTCS_VECT(TMU1_TUNI1, 0x1920),
INTCS_VECT(TMU1_TUNI2, 0x1940),
INTCS_VECT(CMT4, 0x1980),
INTCS_VECT(DSITX1_DSITX1_0, 0x19a0),
INTCS_VECT(DSITX1_DSITX1_1, 0x19c0),
+ /* MFIS2 */
INTCS_VECT(CPORTS2R, 0x1a20),
+ /* CEC */
INTCS_VECT(JPU6E, 0x1a80),
INTC_VECT(INTCS, 0xf80),
diff --git a/arch/arm/mach-shmobile/pfc-sh7372.c b/arch/arm/mach-shmobile/pfc-sh7372.c
index ec420353f8e3..9c265dae138a 100644
--- a/arch/arm/mach-shmobile/pfc-sh7372.c
+++ b/arch/arm/mach-shmobile/pfc-sh7372.c
@@ -166,12 +166,12 @@ enum {
MSIOF2_TSYNC_MARK, MSIOF2_TSCK_MARK, MSIOF2_RXD_MARK,
MSIOF2_TXD_MARK,
- /* MSIOF3 */
+ /* BBIF1 */
BBIF1_RXD_MARK, BBIF1_TSYNC_MARK, BBIF1_TSCK_MARK,
BBIF1_TXD_MARK, BBIF1_RSCK_MARK, BBIF1_RSYNC_MARK,
BBIF1_FLOW_MARK, BB_RX_FLOW_N_MARK,
- /* MSIOF4 */
+ /* BBIF2 */
BBIF2_TSCK1_MARK, BBIF2_TSYNC1_MARK,
BBIF2_TXD1_MARK, BBIF2_RXD_MARK,
@@ -976,12 +976,12 @@ static struct pinmux_gpio pinmux_gpios[] = {
GPIO_FN(MSIOF2_TSYNC), GPIO_FN(MSIOF2_TSCK), GPIO_FN(MSIOF2_RXD),
GPIO_FN(MSIOF2_TXD),
- /* MSIOF3 */
+ /* BBIF1 */
GPIO_FN(BBIF1_RXD), GPIO_FN(BBIF1_TSYNC), GPIO_FN(BBIF1_TSCK),
GPIO_FN(BBIF1_TXD), GPIO_FN(BBIF1_RSCK), GPIO_FN(BBIF1_RSYNC),
GPIO_FN(BBIF1_FLOW), GPIO_FN(BB_RX_FLOW_N),
- /* MSIOF4 */
+ /* BBIF2 */
GPIO_FN(BBIF2_TSCK1), GPIO_FN(BBIF2_TSYNC1),
GPIO_FN(BBIF2_TXD1), GPIO_FN(BBIF2_RXD),
diff --git a/arch/arm/mach-shmobile/setup-sh7367.c b/arch/arm/mach-shmobile/setup-sh7367.c
index 3148c11a550e..003008c18360 100644
--- a/arch/arm/mach-shmobile/setup-sh7367.c
+++ b/arch/arm/mach-shmobile/setup-sh7367.c
@@ -154,7 +154,6 @@ static struct sh_timer_config cmt10_platform_data = {
.name = "CMT10",
.channel_offset = 0x10,
.timer_bit = 0,
- .clk = "r_clk",
.clockevent_rating = 125,
.clocksource_rating = 125,
};
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c
index e26686c9d0b6..564a6d0be473 100644
--- a/arch/arm/mach-shmobile/setup-sh7372.c
+++ b/arch/arm/mach-shmobile/setup-sh7372.c
@@ -158,7 +158,6 @@ static struct sh_timer_config cmt10_platform_data = {
.name = "CMT10",
.channel_offset = 0x10,
.timer_bit = 0,
- .clk = "cmt1",
.clockevent_rating = 125,
.clocksource_rating = 125,
};
@@ -186,6 +185,67 @@ static struct platform_device cmt10_device = {
.num_resources = ARRAY_SIZE(cmt10_resources),
};
+/* TMU */
+static struct sh_timer_config tmu00_platform_data = {
+ .name = "TMU00",
+ .channel_offset = 0x4,
+ .timer_bit = 0,
+ .clockevent_rating = 200,
+};
+
+static struct resource tmu00_resources[] = {
+ [0] = {
+ .name = "TMU00",
+ .start = 0xfff60008,
+ .end = 0xfff60013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = intcs_evt2irq(0xe80), /* TMU_TUNI0 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu00_device = {
+ .name = "sh_tmu",
+ .id = 0,
+ .dev = {
+ .platform_data = &tmu00_platform_data,
+ },
+ .resource = tmu00_resources,
+ .num_resources = ARRAY_SIZE(tmu00_resources),
+};
+
+static struct sh_timer_config tmu01_platform_data = {
+ .name = "TMU01",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clocksource_rating = 200,
+};
+
+static struct resource tmu01_resources[] = {
+ [0] = {
+ .name = "TMU01",
+ .start = 0xfff60014,
+ .end = 0xfff6001f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = intcs_evt2irq(0xea0), /* TMU_TUNI1 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu01_device = {
+ .name = "sh_tmu",
+ .id = 1,
+ .dev = {
+ .platform_data = &tmu01_platform_data,
+ },
+ .resource = tmu01_resources,
+ .num_resources = ARRAY_SIZE(tmu01_resources),
+};
+
/* I2C */
static struct resource iic0_resources[] = {
[0] = {
@@ -419,14 +479,14 @@ static struct resource sh7372_dmae0_resources[] = {
},
{
/* DMA error IRQ */
- .start = 246,
- .end = 246,
+ .start = evt2irq(0x20c0),
+ .end = evt2irq(0x20c0),
.flags = IORESOURCE_IRQ,
},
{
/* IRQ for channels 0-5 */
- .start = 240,
- .end = 245,
+ .start = evt2irq(0x2000),
+ .end = evt2irq(0x20a0),
.flags = IORESOURCE_IRQ,
},
};
@@ -447,14 +507,14 @@ static struct resource sh7372_dmae1_resources[] = {
},
{
/* DMA error IRQ */
- .start = 254,
- .end = 254,
+ .start = evt2irq(0x21c0),
+ .end = evt2irq(0x21c0),
.flags = IORESOURCE_IRQ,
},
{
/* IRQ for channels 0-5 */
- .start = 248,
- .end = 253,
+ .start = evt2irq(0x2100),
+ .end = evt2irq(0x21a0),
.flags = IORESOURCE_IRQ,
},
};
@@ -475,14 +535,14 @@ static struct resource sh7372_dmae2_resources[] = {
},
{
/* DMA error IRQ */
- .start = 262,
- .end = 262,
+ .start = evt2irq(0x22c0),
+ .end = evt2irq(0x22c0),
.flags = IORESOURCE_IRQ,
},
{
/* IRQ for channels 0-5 */
- .start = 256,
- .end = 261,
+ .start = evt2irq(0x2200),
+ .end = evt2irq(0x22a0),
.flags = IORESOURCE_IRQ,
},
};
@@ -526,6 +586,11 @@ static struct platform_device *sh7372_early_devices[] __initdata = {
&scif5_device,
&scif6_device,
&cmt10_device,
+ &tmu00_device,
+ &tmu01_device,
+};
+
+static struct platform_device *sh7372_late_devices[] __initdata = {
&iic0_device,
&iic1_device,
&dma0_device,
@@ -537,6 +602,9 @@ void __init sh7372_add_standard_devices(void)
{
platform_add_devices(sh7372_early_devices,
ARRAY_SIZE(sh7372_early_devices));
+
+ platform_add_devices(sh7372_late_devices,
+ ARRAY_SIZE(sh7372_late_devices));
}
void __init sh7372_add_early_devices(void)
diff --git a/arch/arm/mach-shmobile/setup-sh7377.c b/arch/arm/mach-shmobile/setup-sh7377.c
index bb4adf17dbf4..575dbd6c2f1d 100644
--- a/arch/arm/mach-shmobile/setup-sh7377.c
+++ b/arch/arm/mach-shmobile/setup-sh7377.c
@@ -172,7 +172,6 @@ static struct sh_timer_config cmt10_platform_data = {
.name = "CMT10",
.channel_offset = 0x10,
.timer_bit = 0,
- .clk = "r_clk",
.clockevent_rating = 125,
.clocksource_rating = 125,
};
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/Kconfig b/arch/arm/mach-tegra/Kconfig
index a57713c1954a..acd9552f8ada 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -16,6 +16,10 @@ config ARCH_TEGRA_2x_SOC
endchoice
+config TEGRA_PCI
+ bool "PCI Express support"
+ select PCI
+
comment "Tegra board type"
config MACH_HARMONY
@@ -47,4 +51,11 @@ config TEGRA_DEBUG_UARTE
endchoice
+config TEGRA_SYSTEM_DMA
+ bool "Enable system DMA driver for NVIDIA Tegra SoCs"
+ default y
+ help
+ Adds system DMA functionality for NVIDIA Tegra SoCs, used by
+ several Tegra device drivers
+
endif
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 51e9370eed99..cdbc68e4c0ca 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -1,14 +1,21 @@
obj-y += common.o
obj-y += io.o
-obj-y += irq.o
+obj-y += irq.o legacy_irq.o
obj-y += clock.o
obj-y += timer.o
obj-y += gpio.o
obj-y += pinmux.o
+obj-y += fuse.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clock.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o
+obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_dvfs.o
+obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pinmux-t2-tables.o
obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
+obj-$(CONFIG_TEGRA_SYSTEM_DMA) += dma.o
+obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o
+obj-$(CONFIG_TEGRA_PCI) += pcie.o
obj-${CONFIG_MACH_HARMONY} += board-harmony.o
obj-${CONFIG_MACH_HARMONY} += board-harmony-pinmux.o
+obj-${CONFIG_MACH_HARMONY} += board-harmony-pcie.o
diff --git a/arch/arm/mach-tegra/board-harmony-pcie.c b/arch/arm/mach-tegra/board-harmony-pcie.c
new file mode 100644
index 000000000000..f7e7d4514b6a
--- /dev/null
+++ b/arch/arm/mach-tegra/board-harmony-pcie.c
@@ -0,0 +1,57 @@
+/*
+ * arch/arm/mach-tegra/board-harmony-pcie.c
+ *
+ * Copyright (C) 2010 CompuLab, Ltd.
+ * Mike Rapoport <mike@compulab.co.il>
+ *
+ * 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 <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/err.h>
+#include <linux/regulator/consumer.h>
+
+#include <asm/mach-types.h>
+
+#include <mach/pinmux.h>
+#include "board.h"
+
+#ifdef CONFIG_TEGRA_PCI
+
+static int __init harmony_pcie_init(void)
+{
+ int err;
+
+ if (!machine_is_harmony())
+ return 0;
+
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_GPV, TEGRA_TRI_NORMAL);
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXA, TEGRA_TRI_NORMAL);
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXK, TEGRA_TRI_NORMAL);
+
+ err = tegra_pcie_init(true, true);
+ if (err)
+ goto err_pcie;
+
+ return 0;
+
+err_pcie:
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_GPV, TEGRA_TRI_TRISTATE);
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXA, TEGRA_TRI_TRISTATE);
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXK, TEGRA_TRI_TRISTATE);
+
+ return err;
+}
+
+subsys_initcall(harmony_pcie_init);
+
+#endif
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/board.h b/arch/arm/mach-tegra/board.h
index 3d06354136f2..0de565ca37c5 100644
--- a/arch/arm/mach-tegra/board.h
+++ b/arch/arm/mach-tegra/board.h
@@ -27,6 +27,7 @@ void __init tegra_common_init(void);
void __init tegra_map_common_io(void);
void __init tegra_init_irq(void);
void __init tegra_init_clock(void);
+int __init tegra_pcie_init(bool init_port0, bool init_port1);
extern struct sys_timer tegra_timer;
#endif
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
index 03ad578349b9..ae19f95585be 100644
--- a/arch/arm/mach-tegra/clock.c
+++ b/arch/arm/mach-tegra/clock.c
@@ -24,13 +24,80 @@
#include <linux/debugfs.h>
#include <linux/slab.h>
#include <linux/seq_file.h>
+#include <linux/regulator/consumer.h>
#include <asm/clkdev.h>
#include "clock.h"
+#include "board.h"
+#include "fuse.h"
static LIST_HEAD(clocks);
static DEFINE_SPINLOCK(clock_lock);
+static DEFINE_MUTEX(dvfs_lock);
+
+static int clk_is_dvfs(struct clk *c)
+{
+ return (c->dvfs != NULL);
+};
+
+static int dvfs_set_rate(struct dvfs *d, unsigned long rate)
+{
+ struct dvfs_table *t;
+
+ if (d->table == NULL)
+ return -ENODEV;
+
+ for (t = d->table; t->rate != 0; t++) {
+ if (rate <= t->rate) {
+ if (!d->reg)
+ return 0;
+
+ return regulator_set_voltage(d->reg,
+ t->millivolts * 1000,
+ d->max_millivolts * 1000);
+ }
+ }
+
+ return -EINVAL;
+}
+
+static void dvfs_init(struct clk *c)
+{
+ int process_id;
+ int i;
+ struct dvfs_table *table;
+
+ process_id = c->dvfs->cpu ? tegra_core_process_id() :
+ tegra_cpu_process_id();
+
+ for (i = 0; i < c->dvfs->process_id_table_length; i++)
+ if (process_id == c->dvfs->process_id_table[i].process_id)
+ c->dvfs->table = c->dvfs->process_id_table[i].table;
+
+ if (c->dvfs->table == NULL) {
+ pr_err("Failed to find dvfs table for clock %s process %d\n",
+ c->name, process_id);
+ return;
+ }
+
+ c->dvfs->max_millivolts = 0;
+ for (table = c->dvfs->table; table->rate != 0; table++)
+ if (c->dvfs->max_millivolts < table->millivolts)
+ c->dvfs->max_millivolts = table->millivolts;
+
+ c->dvfs->reg = regulator_get(NULL, c->dvfs->reg_id);
+
+ if (IS_ERR(c->dvfs->reg)) {
+ pr_err("Failed to get regulator %s for clock %s\n",
+ c->dvfs->reg_id, c->name);
+ c->dvfs->reg = NULL;
+ return;
+ }
+
+ if (c->refcnt > 0)
+ dvfs_set_rate(c->dvfs, c->rate);
+}
struct clk *tegra_get_clock_by_name(const char *name)
{
@@ -48,14 +115,31 @@ struct clk *tegra_get_clock_by_name(const char *name)
return ret;
}
+static void clk_recalculate_rate(struct clk *c)
+{
+ u64 rate;
+
+ if (!c->parent)
+ return;
+
+ rate = c->parent->rate;
+
+ if (c->mul != 0 && c->div != 0) {
+ rate = rate * c->mul;
+ do_div(rate, c->div);
+ }
+
+ if (rate > c->max_rate)
+ pr_warn("clocks: Set clock %s to rate %llu, max is %lu\n",
+ c->name, rate, c->max_rate);
+
+ c->rate = rate;
+}
+
int clk_reparent(struct clk *c, struct clk *parent)
{
pr_debug("%s: %s\n", __func__, c->name);
- if (c->refcnt && c->parent)
- clk_disable_locked(c->parent);
c->parent = parent;
- if (c->refcnt && c->parent)
- clk_enable_locked(c->parent);
list_del(&c->sibling);
list_add_tail(&c->sibling, &parent->children);
return 0;
@@ -67,8 +151,7 @@ static void propagate_rate(struct clk *c)
pr_debug("%s: %s\n", __func__, c->name);
list_for_each_entry(clkp, &c->children, sibling) {
pr_debug(" %s\n", clkp->name);
- if (clkp->ops->recalculate_rate)
- clkp->ops->recalculate_rate(clkp);
+ clk_recalculate_rate(clkp);
propagate_rate(clkp);
}
}
@@ -77,6 +160,8 @@ void clk_init(struct clk *c)
{
unsigned long flags;
+ pr_debug("%s: %s\n", __func__, c->name);
+
spin_lock_irqsave(&clock_lock, flags);
INIT_LIST_HEAD(&c->children);
@@ -85,6 +170,8 @@ void clk_init(struct clk *c)
if (c->ops && c->ops->init)
c->ops->init(c);
+ clk_recalculate_rate(c);
+
list_add(&c->node, &clocks);
if (c->parent)
@@ -122,13 +209,38 @@ int clk_enable_locked(struct clk *c)
return 0;
}
+int clk_enable_cansleep(struct clk *c)
+{
+ int ret;
+ unsigned long flags;
+
+ mutex_lock(&dvfs_lock);
+
+ if (clk_is_dvfs(c) && c->refcnt > 0)
+ dvfs_set_rate(c->dvfs, c->rate);
+
+ spin_lock_irqsave(&clock_lock, flags);
+ ret = clk_enable_locked(c);
+ spin_unlock_irqrestore(&clock_lock, flags);
+
+ mutex_unlock(&dvfs_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_enable_cansleep);
+
int clk_enable(struct clk *c)
{
int ret;
unsigned long flags;
+
+ if (clk_is_dvfs(c))
+ BUG();
+
spin_lock_irqsave(&clock_lock, flags);
ret = clk_enable_locked(c);
spin_unlock_irqrestore(&clock_lock, flags);
+
return ret;
}
EXPORT_SYMBOL(clk_enable);
@@ -152,9 +264,30 @@ void clk_disable_locked(struct clk *c)
c->refcnt--;
}
+void clk_disable_cansleep(struct clk *c)
+{
+ unsigned long flags;
+
+ mutex_lock(&dvfs_lock);
+
+ spin_lock_irqsave(&clock_lock, flags);
+ clk_disable_locked(c);
+ spin_unlock_irqrestore(&clock_lock, flags);
+
+ if (clk_is_dvfs(c) && c->refcnt == 0)
+ dvfs_set_rate(c->dvfs, c->rate);
+
+ mutex_unlock(&dvfs_lock);
+}
+EXPORT_SYMBOL(clk_disable_cansleep);
+
void clk_disable(struct clk *c)
{
unsigned long flags;
+
+ if (clk_is_dvfs(c))
+ BUG();
+
spin_lock_irqsave(&clock_lock, flags);
clk_disable_locked(c);
spin_unlock_irqrestore(&clock_lock, flags);
@@ -175,6 +308,8 @@ int clk_set_parent_locked(struct clk *c, struct clk *parent)
if (ret)
return ret;
+ clk_recalculate_rate(c);
+
propagate_rate(c);
return 0;
@@ -197,22 +332,69 @@ struct clk *clk_get_parent(struct clk *c)
}
EXPORT_SYMBOL(clk_get_parent);
-int clk_set_rate(struct clk *c, unsigned long rate)
+int clk_set_rate_locked(struct clk *c, unsigned long rate)
+{
+ int ret;
+
+ if (rate > c->max_rate)
+ rate = c->max_rate;
+
+ if (!c->ops || !c->ops->set_rate)
+ return -ENOSYS;
+
+ ret = c->ops->set_rate(c, rate);
+
+ if (ret)
+ return ret;
+
+ clk_recalculate_rate(c);
+
+ propagate_rate(c);
+
+ return 0;
+}
+
+int clk_set_rate_cansleep(struct clk *c, unsigned long rate)
{
int ret = 0;
unsigned long flags;
+ pr_debug("%s: %s\n", __func__, c->name);
+
+ mutex_lock(&dvfs_lock);
+
+ if (rate > c->rate)
+ ret = dvfs_set_rate(c->dvfs, rate);
+ if (ret)
+ goto out;
+
spin_lock_irqsave(&clock_lock, flags);
+ ret = clk_set_rate_locked(c, rate);
+ spin_unlock_irqrestore(&clock_lock, flags);
- pr_debug("%s: %s\n", __func__, c->name);
+ if (ret)
+ goto out;
- if (c->ops && c->ops->set_rate)
- ret = c->ops->set_rate(c, rate);
- else
- ret = -ENOSYS;
+ ret = dvfs_set_rate(c->dvfs, rate);
- propagate_rate(c);
+out:
+ mutex_unlock(&dvfs_lock);
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_rate_cansleep);
+
+int clk_set_rate(struct clk *c, unsigned long rate)
+{
+ int ret = 0;
+ unsigned long flags;
+
+ pr_debug("%s: %s\n", __func__, c->name);
+
+ if (clk_is_dvfs(c))
+ BUG();
+ spin_lock_irqsave(&clock_lock, flags);
+ ret = clk_set_rate_locked(c, rate);
spin_unlock_irqrestore(&clock_lock, flags);
return ret;
@@ -235,6 +417,20 @@ unsigned long clk_get_rate(struct clk *c)
}
EXPORT_SYMBOL(clk_get_rate);
+long clk_round_rate(struct clk *c, unsigned long rate)
+{
+ pr_debug("%s: %s\n", __func__, c->name);
+
+ if (!c->ops || !c->ops->round_rate)
+ return -ENOSYS;
+
+ if (rate > c->max_rate)
+ rate = c->max_rate;
+
+ return c->ops->round_rate(c, rate);
+}
+EXPORT_SYMBOL(clk_round_rate);
+
static int tegra_clk_init_one_from_table(struct tegra_clk_init_table *table)
{
struct clk *c;
@@ -308,13 +504,28 @@ void tegra_periph_reset_assert(struct clk *c)
}
EXPORT_SYMBOL(tegra_periph_reset_assert);
-int __init tegra_init_clock(void)
+void __init tegra_init_clock(void)
{
tegra2_init_clocks();
+}
+
+int __init tegra_init_dvfs(void)
+{
+ struct clk *c, *safe;
+
+ mutex_lock(&dvfs_lock);
+
+ list_for_each_entry_safe(c, safe, &clocks, node)
+ if (c->dvfs)
+ dvfs_init(c);
+
+ mutex_unlock(&dvfs_lock);
return 0;
}
+late_initcall(tegra_init_dvfs);
+
#ifdef CONFIG_DEBUG_FS
static struct dentry *clk_debugfs_root;
@@ -324,7 +535,7 @@ static void clock_tree_show_one(struct seq_file *s, struct clk *c, int level)
struct clk *child;
struct clk *safe;
const char *state = "uninit";
- char div[5] = {0};
+ char div[8] = {0};
if (c->state == ON)
state = "on";
@@ -332,16 +543,26 @@ static void clock_tree_show_one(struct seq_file *s, struct clk *c, int level)
state = "off";
if (c->mul != 0 && c->div != 0) {
- BUG_ON(c->mul > 2);
- if (c->mul > c->div)
- snprintf(div, sizeof(div), "x%d", c->mul / c->div);
- else
+ if (c->mul > c->div) {
+ int mul = c->mul / c->div;
+ int mul2 = (c->mul * 10 / c->div) % 10;
+ int mul3 = (c->mul * 10) % c->div;
+ if (mul2 == 0 && mul3 == 0)
+ snprintf(div, sizeof(div), "x%d", mul);
+ else if (mul3 == 0)
+ snprintf(div, sizeof(div), "x%d.%d", mul, mul2);
+ else
+ snprintf(div, sizeof(div), "x%d.%d..", mul, mul2);
+ } else {
snprintf(div, sizeof(div), "%d%s", c->div / c->mul,
(c->div % c->mul) ? ".5" : "");
+ }
}
- seq_printf(s, "%*s%-*s %-6s %-3d %-5s %-10lu\n",
- level * 3 + 1, c->set ? "" : "*",
+ seq_printf(s, "%*s%c%c%-*s %-6s %-3d %-8s %-10lu\n",
+ level * 3 + 1, "",
+ c->rate > c->max_rate ? '!' : ' ',
+ !c->set ? '*' : ' ',
30 - level * 3, c->name,
state, c->refcnt, div, c->rate);
list_for_each_entry_safe(child, safe, &c->children, sibling) {
@@ -353,8 +574,8 @@ static int clock_tree_show(struct seq_file *s, void *data)
{
struct clk *c;
unsigned long flags;
- seq_printf(s, " clock state ref div rate \n");
- seq_printf(s, "-----------------------------------------------------------\n");
+ seq_printf(s, " clock state ref div rate\n");
+ seq_printf(s, "--------------------------------------------------------------\n");
spin_lock_irqsave(&clock_lock, flags);
list_for_each_entry(c, &clocks, node)
if (c->parent == NULL)
diff --git a/arch/arm/mach-tegra/clock.h b/arch/arm/mach-tegra/clock.h
index af7c70e2a3ba..94fd859770f1 100644
--- a/arch/arm/mach-tegra/clock.h
+++ b/arch/arm/mach-tegra/clock.h
@@ -27,18 +27,43 @@
#define DIV_U71 (1 << 1)
#define DIV_U71_FIXED (1 << 2)
#define DIV_2 (1 << 3)
-#define PLL_FIXED (1 << 4)
-#define PLL_HAS_CPCON (1 << 5)
-#define MUX (1 << 6)
-#define PLLD (1 << 7)
-#define PERIPH_NO_RESET (1 << 8)
-#define PERIPH_NO_ENB (1 << 9)
-#define PERIPH_EMC_ENB (1 << 10)
-#define PERIPH_MANUAL_RESET (1 << 11)
-#define PLL_ALT_MISC_REG (1 << 12)
+#define DIV_U16 (1 << 4)
+#define PLL_FIXED (1 << 5)
+#define PLL_HAS_CPCON (1 << 6)
+#define MUX (1 << 7)
+#define PLLD (1 << 8)
+#define PERIPH_NO_RESET (1 << 9)
+#define PERIPH_NO_ENB (1 << 10)
+#define PERIPH_EMC_ENB (1 << 11)
+#define PERIPH_MANUAL_RESET (1 << 12)
+#define PLL_ALT_MISC_REG (1 << 13)
+#define PLLU (1 << 14)
#define ENABLE_ON_INIT (1 << 28)
struct clk;
+struct regulator;
+
+struct dvfs_table {
+ unsigned long rate;
+ int millivolts;
+};
+
+struct dvfs_process_id_table {
+ int process_id;
+ struct dvfs_table *table;
+};
+
+
+struct dvfs {
+ struct regulator *reg;
+ struct dvfs_table *table;
+ int max_millivolts;
+
+ int process_id_table_length;
+ const char *reg_id;
+ bool cpu;
+ struct dvfs_process_id_table process_id_table[];
+};
struct clk_mux_sel {
struct clk *input;
@@ -58,12 +83,9 @@ struct clk_ops {
void (*init)(struct clk *);
int (*enable)(struct clk *);
void (*disable)(struct clk *);
- void (*recalc)(struct clk *);
int (*set_parent)(struct clk *, struct clk *);
int (*set_rate)(struct clk *, unsigned long);
- unsigned long (*get_rate)(struct clk *);
long (*round_rate)(struct clk *, unsigned long);
- unsigned long (*recalculate_rate)(struct clk *);
};
enum clk_state {
@@ -85,6 +107,7 @@ struct clk {
struct clk *parent;
struct clk_lookup lookup;
unsigned long rate;
+ unsigned long max_rate;
u32 flags;
u32 refcnt;
const char *name;
@@ -103,10 +126,6 @@ struct clk {
unsigned long cf_max;
unsigned long vco_min;
unsigned long vco_max;
- u32 m;
- u32 n;
- u32 p;
- u32 cpcon;
const struct clk_pll_table *pll_table;
/* DIV */
@@ -117,6 +136,12 @@ struct clk {
const struct clk_mux_sel *inputs;
u32 sel;
u32 reg_mask;
+
+ /* Virtual cpu clock */
+ struct clk *main;
+ struct clk *backup;
+
+ struct dvfs *dvfs;
};
@@ -141,6 +166,7 @@ unsigned long clk_measure_input_freq(void);
void clk_disable_locked(struct clk *c);
int clk_enable_locked(struct clk *c);
int clk_set_parent_locked(struct clk *c, struct clk *parent);
+int clk_set_rate_locked(struct clk *c, unsigned long rate);
int clk_reparent(struct clk *c, struct clk *parent);
void tegra_clk_init_from_table(struct tegra_clk_init_table *table);
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
index 039a514b61ef..7c91e2b9d643 100644
--- a/arch/arm/mach-tegra/common.c
+++ b/arch/arm/mach-tegra/common.c
@@ -19,13 +19,17 @@
#include <linux/init.h>
#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
#include <asm/hardware/cache-l2x0.h>
#include <mach/iomap.h>
+#include <mach/dma.h>
#include "board.h"
#include "clock.h"
+#include "fuse.h"
static __initdata struct tegra_clk_init_table common_clk_init_table[] = {
/* name parent rate enabled */
@@ -35,8 +39,8 @@ static __initdata struct tegra_clk_init_table common_clk_init_table[] = {
{ "pll_p_out2", "pll_p", 48000000, true },
{ "pll_p_out3", "pll_p", 72000000, true },
{ "pll_p_out4", "pll_p", 108000000, true },
- { "sys", "pll_p_out4", 108000000, true },
- { "hclk", "sys", 108000000, true },
+ { "sclk", "pll_p_out4", 108000000, true },
+ { "hclk", "sclk", 108000000, true },
{ "pclk", "hclk", 54000000, true },
{ NULL, NULL, 0, 0},
};
@@ -51,11 +55,16 @@ void __init tegra_init_cache(void)
l2x0_init(p, 0x6C080001, 0x8200c3fe);
#endif
+
}
void __init tegra_common_init(void)
{
+ tegra_init_fuse();
tegra_init_clock();
tegra_clk_init_from_table(common_clk_init_table);
tegra_init_cache();
+#ifdef CONFIG_TEGRA_SYSTEM_DMA
+ tegra_dma_init();
+#endif
}
diff --git a/arch/arm/mach-tegra/cpu-tegra.c b/arch/arm/mach-tegra/cpu-tegra.c
new file mode 100644
index 000000000000..fea5719c7072
--- /dev/null
+++ b/arch/arm/mach-tegra/cpu-tegra.c
@@ -0,0 +1,185 @@
+/*
+ * arch/arm/mach-tegra/cpu-tegra.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ * Based on arch/arm/plat-omap/cpu-omap.c, (C) 2005 Nokia Corporation
+ *
+ * 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 <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/cpufreq.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+
+#include <mach/hardware.h>
+#include <mach/clk.h>
+
+/* Frequency table index must be sequential starting at 0 */
+static struct cpufreq_frequency_table freq_table[] = {
+ { 0, 312000 },
+ { 1, 456000 },
+ { 2, 608000 },
+ { 3, 760000 },
+ { 4, 816000 },
+ { 5, 912000 },
+ { 6, 1000000 },
+ { 7, CPUFREQ_TABLE_END },
+};
+
+#define NUM_CPUS 2
+
+static struct clk *cpu_clk;
+
+static unsigned long target_cpu_speed[NUM_CPUS];
+
+int tegra_verify_speed(struct cpufreq_policy *policy)
+{
+ return cpufreq_frequency_table_verify(policy, freq_table);
+}
+
+unsigned int tegra_getspeed(unsigned int cpu)
+{
+ unsigned long rate;
+
+ if (cpu >= NUM_CPUS)
+ return 0;
+
+ rate = clk_get_rate(cpu_clk) / 1000;
+ return rate;
+}
+
+static int tegra_update_cpu_speed(void)
+{
+ int i;
+ unsigned long rate = 0;
+ int ret = 0;
+ struct cpufreq_freqs freqs;
+
+ for_each_online_cpu(i)
+ rate = max(rate, target_cpu_speed[i]);
+
+ freqs.old = tegra_getspeed(0);
+ freqs.new = rate;
+
+ if (freqs.old == freqs.new)
+ return ret;
+
+ for_each_online_cpu(freqs.cpu)
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+#ifdef CONFIG_CPU_FREQ_DEBUG
+ printk(KERN_DEBUG "cpufreq-tegra: transition: %u --> %u\n",
+ freqs.old, freqs.new);
+#endif
+
+ ret = clk_set_rate_cansleep(cpu_clk, freqs.new * 1000);
+ if (ret) {
+ pr_err("cpu-tegra: Failed to set cpu frequency to %d kHz\n",
+ freqs.new);
+ return ret;
+ }
+
+ for_each_online_cpu(freqs.cpu)
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ return 0;
+}
+
+static int tegra_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ int idx;
+ unsigned int freq;
+
+ cpufreq_frequency_table_target(policy, freq_table, target_freq,
+ relation, &idx);
+
+ freq = freq_table[idx].frequency;
+
+ target_cpu_speed[policy->cpu] = freq;
+
+ return tegra_update_cpu_speed();
+}
+
+static int tegra_cpu_init(struct cpufreq_policy *policy)
+{
+ if (policy->cpu >= NUM_CPUS)
+ return -EINVAL;
+
+ cpu_clk = clk_get_sys(NULL, "cpu");
+ if (IS_ERR(cpu_clk))
+ return PTR_ERR(cpu_clk);
+
+ cpufreq_frequency_table_cpuinfo(policy, freq_table);
+ cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
+ policy->cur = tegra_getspeed(policy->cpu);
+ target_cpu_speed[policy->cpu] = policy->cur;
+
+ /* FIXME: what's the actual transition time? */
+ policy->cpuinfo.transition_latency = 300 * 1000;
+
+ policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
+ cpumask_copy(policy->related_cpus, cpu_possible_mask);
+
+ return 0;
+}
+
+static int tegra_cpu_exit(struct cpufreq_policy *policy)
+{
+ cpufreq_frequency_table_cpuinfo(policy, freq_table);
+ clk_put(cpu_clk);
+ return 0;
+}
+
+static struct freq_attr *tegra_cpufreq_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
+static struct cpufreq_driver tegra_cpufreq_driver = {
+ .verify = tegra_verify_speed,
+ .target = tegra_target,
+ .get = tegra_getspeed,
+ .init = tegra_cpu_init,
+ .exit = tegra_cpu_exit,
+ .name = "tegra",
+ .attr = tegra_cpufreq_attr,
+};
+
+static int __init tegra_cpufreq_init(void)
+{
+ return cpufreq_register_driver(&tegra_cpufreq_driver);
+}
+
+static void __exit tegra_cpufreq_exit(void)
+{
+ cpufreq_unregister_driver(&tegra_cpufreq_driver);
+}
+
+
+MODULE_AUTHOR("Colin Cross <ccross@android.com>");
+MODULE_DESCRIPTION("cpufreq driver for Nvidia Tegra2");
+MODULE_LICENSE("GPL");
+module_init(tegra_cpufreq_init);
+module_exit(tegra_cpufreq_exit);
diff --git a/arch/arm/mach-tegra/dma.c b/arch/arm/mach-tegra/dma.c
new file mode 100644
index 000000000000..edda6ec5e925
--- /dev/null
+++ b/arch/arm/mach-tegra/dma.c
@@ -0,0 +1,752 @@
+/*
+ * arch/arm/mach-tegra/dma.c
+ *
+ * System DMA driver for NVIDIA Tegra SoCs
+ *
+ * Copyright (c) 2008-2009, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/err.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <mach/dma.h>
+#include <mach/irqs.h>
+#include <mach/iomap.h>
+
+#define APB_DMA_GEN 0x000
+#define GEN_ENABLE (1<<31)
+
+#define APB_DMA_CNTRL 0x010
+
+#define APB_DMA_IRQ_MASK 0x01c
+
+#define APB_DMA_IRQ_MASK_SET 0x020
+
+#define APB_DMA_CHAN_CSR 0x000
+#define CSR_ENB (1<<31)
+#define CSR_IE_EOC (1<<30)
+#define CSR_HOLD (1<<29)
+#define CSR_DIR (1<<28)
+#define CSR_ONCE (1<<27)
+#define CSR_FLOW (1<<21)
+#define CSR_REQ_SEL_SHIFT 16
+#define CSR_REQ_SEL_MASK (0x1F<<CSR_REQ_SEL_SHIFT)
+#define CSR_REQ_SEL_INVALID (31<<CSR_REQ_SEL_SHIFT)
+#define CSR_WCOUNT_SHIFT 2
+#define CSR_WCOUNT_MASK 0xFFFC
+
+#define APB_DMA_CHAN_STA 0x004
+#define STA_BUSY (1<<31)
+#define STA_ISE_EOC (1<<30)
+#define STA_HALT (1<<29)
+#define STA_PING_PONG (1<<28)
+#define STA_COUNT_SHIFT 2
+#define STA_COUNT_MASK 0xFFFC
+
+#define APB_DMA_CHAN_AHB_PTR 0x010
+
+#define APB_DMA_CHAN_AHB_SEQ 0x014
+#define AHB_SEQ_INTR_ENB (1<<31)
+#define AHB_SEQ_BUS_WIDTH_SHIFT 28
+#define AHB_SEQ_BUS_WIDTH_MASK (0x7<<AHB_SEQ_BUS_WIDTH_SHIFT)
+#define AHB_SEQ_BUS_WIDTH_8 (0<<AHB_SEQ_BUS_WIDTH_SHIFT)
+#define AHB_SEQ_BUS_WIDTH_16 (1<<AHB_SEQ_BUS_WIDTH_SHIFT)
+#define AHB_SEQ_BUS_WIDTH_32 (2<<AHB_SEQ_BUS_WIDTH_SHIFT)
+#define AHB_SEQ_BUS_WIDTH_64 (3<<AHB_SEQ_BUS_WIDTH_SHIFT)
+#define AHB_SEQ_BUS_WIDTH_128 (4<<AHB_SEQ_BUS_WIDTH_SHIFT)
+#define AHB_SEQ_DATA_SWAP (1<<27)
+#define AHB_SEQ_BURST_MASK (0x7<<24)
+#define AHB_SEQ_BURST_1 (4<<24)
+#define AHB_SEQ_BURST_4 (5<<24)
+#define AHB_SEQ_BURST_8 (6<<24)
+#define AHB_SEQ_DBL_BUF (1<<19)
+#define AHB_SEQ_WRAP_SHIFT 16
+#define AHB_SEQ_WRAP_MASK (0x7<<AHB_SEQ_WRAP_SHIFT)
+
+#define APB_DMA_CHAN_APB_PTR 0x018
+
+#define APB_DMA_CHAN_APB_SEQ 0x01c
+#define APB_SEQ_BUS_WIDTH_SHIFT 28
+#define APB_SEQ_BUS_WIDTH_MASK (0x7<<APB_SEQ_BUS_WIDTH_SHIFT)
+#define APB_SEQ_BUS_WIDTH_8 (0<<APB_SEQ_BUS_WIDTH_SHIFT)
+#define APB_SEQ_BUS_WIDTH_16 (1<<APB_SEQ_BUS_WIDTH_SHIFT)
+#define APB_SEQ_BUS_WIDTH_32 (2<<APB_SEQ_BUS_WIDTH_SHIFT)
+#define APB_SEQ_BUS_WIDTH_64 (3<<APB_SEQ_BUS_WIDTH_SHIFT)
+#define APB_SEQ_BUS_WIDTH_128 (4<<APB_SEQ_BUS_WIDTH_SHIFT)
+#define APB_SEQ_DATA_SWAP (1<<27)
+#define APB_SEQ_WRAP_SHIFT 16
+#define APB_SEQ_WRAP_MASK (0x7<<APB_SEQ_WRAP_SHIFT)
+
+#define TEGRA_SYSTEM_DMA_CH_NR 16
+#define TEGRA_SYSTEM_DMA_AVP_CH_NUM 4
+#define TEGRA_SYSTEM_DMA_CH_MIN 0
+#define TEGRA_SYSTEM_DMA_CH_MAX \
+ (TEGRA_SYSTEM_DMA_CH_NR - TEGRA_SYSTEM_DMA_AVP_CH_NUM - 1)
+
+#define NV_DMA_MAX_TRASFER_SIZE 0x10000
+
+const unsigned int ahb_addr_wrap_table[8] = {
+ 0, 32, 64, 128, 256, 512, 1024, 2048
+};
+
+const unsigned int apb_addr_wrap_table[8] = {0, 1, 2, 4, 8, 16, 32, 64};
+
+const unsigned int bus_width_table[5] = {8, 16, 32, 64, 128};
+
+#define TEGRA_DMA_NAME_SIZE 16
+struct tegra_dma_channel {
+ struct list_head list;
+ int id;
+ spinlock_t lock;
+ char name[TEGRA_DMA_NAME_SIZE];
+ void __iomem *addr;
+ int mode;
+ int irq;
+
+ /* Register shadow */
+ u32 csr;
+ u32 ahb_seq;
+ u32 ahb_ptr;
+ u32 apb_seq;
+ u32 apb_ptr;
+};
+
+#define NV_DMA_MAX_CHANNELS 32
+
+static DECLARE_BITMAP(channel_usage, NV_DMA_MAX_CHANNELS);
+static struct tegra_dma_channel dma_channels[NV_DMA_MAX_CHANNELS];
+
+static void tegra_dma_update_hw(struct tegra_dma_channel *ch,
+ struct tegra_dma_req *req);
+static void tegra_dma_update_hw_partial(struct tegra_dma_channel *ch,
+ struct tegra_dma_req *req);
+static void tegra_dma_init_hw(struct tegra_dma_channel *ch);
+static void tegra_dma_stop(struct tegra_dma_channel *ch);
+
+void tegra_dma_flush(struct tegra_dma_channel *ch)
+{
+}
+EXPORT_SYMBOL(tegra_dma_flush);
+
+void tegra_dma_dequeue(struct tegra_dma_channel *ch)
+{
+ struct tegra_dma_req *req;
+
+ req = list_entry(ch->list.next, typeof(*req), node);
+
+ tegra_dma_dequeue_req(ch, req);
+ return;
+}
+
+void tegra_dma_stop(struct tegra_dma_channel *ch)
+{
+ unsigned int csr;
+ unsigned int status;
+
+ csr = ch->csr;
+ csr &= ~CSR_IE_EOC;
+ writel(csr, ch->addr + APB_DMA_CHAN_CSR);
+
+ csr &= ~CSR_ENB;
+ writel(csr, ch->addr + APB_DMA_CHAN_CSR);
+
+ status = readl(ch->addr + APB_DMA_CHAN_STA);
+ if (status & STA_ISE_EOC)
+ writel(status, ch->addr + APB_DMA_CHAN_STA);
+}
+
+int tegra_dma_cancel(struct tegra_dma_channel *ch)
+{
+ unsigned int csr;
+ unsigned long irq_flags;
+
+ spin_lock_irqsave(&ch->lock, irq_flags);
+ while (!list_empty(&ch->list))
+ list_del(ch->list.next);
+
+ csr = ch->csr;
+ csr &= ~CSR_REQ_SEL_MASK;
+ csr |= CSR_REQ_SEL_INVALID;
+
+ /* Set the enable as that is not shadowed */
+ csr |= CSR_ENB;
+ writel(csr, ch->addr + APB_DMA_CHAN_CSR);
+
+ tegra_dma_stop(ch);
+
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+ return 0;
+}
+
+int tegra_dma_dequeue_req(struct tegra_dma_channel *ch,
+ struct tegra_dma_req *_req)
+{
+ unsigned int csr;
+ unsigned int status;
+ struct tegra_dma_req *req = NULL;
+ int found = 0;
+ unsigned long irq_flags;
+ int to_transfer;
+ int req_transfer_count;
+
+ spin_lock_irqsave(&ch->lock, irq_flags);
+ list_for_each_entry(req, &ch->list, node) {
+ if (req == _req) {
+ list_del(&req->node);
+ found = 1;
+ break;
+ }
+ }
+ if (!found) {
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+ return 0;
+ }
+
+ /* STOP the DMA and get the transfer count.
+ * Getting the transfer count is tricky.
+ * - Change the source selector to invalid to stop the DMA from
+ * FIFO to memory.
+ * - Read the status register to know the number of pending
+ * bytes to be transfered.
+ * - Finally stop or program the DMA to the next buffer in the
+ * list.
+ */
+ csr = ch->csr;
+ csr &= ~CSR_REQ_SEL_MASK;
+ csr |= CSR_REQ_SEL_INVALID;
+
+ /* Set the enable as that is not shadowed */
+ csr |= CSR_ENB;
+ writel(csr, ch->addr + APB_DMA_CHAN_CSR);
+
+ /* Get the transfer count */
+ status = readl(ch->addr + APB_DMA_CHAN_STA);
+ to_transfer = (status & STA_COUNT_MASK) >> STA_COUNT_SHIFT;
+ req_transfer_count = (ch->csr & CSR_WCOUNT_MASK) >> CSR_WCOUNT_SHIFT;
+ req_transfer_count += 1;
+ to_transfer += 1;
+
+ req->bytes_transferred = req_transfer_count;
+
+ if (status & STA_BUSY)
+ req->bytes_transferred -= to_transfer;
+
+ /* In continous transfer mode, DMA only tracks the count of the
+ * half DMA buffer. So, if the DMA already finished half the DMA
+ * then add the half buffer to the completed count.
+ *
+ * FIXME: There can be a race here. What if the req to
+ * dequue happens at the same time as the DMA just moved to
+ * the new buffer and SW didn't yet received the interrupt?
+ */
+ if (ch->mode & TEGRA_DMA_MODE_CONTINOUS)
+ if (req->buffer_status == TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL)
+ req->bytes_transferred += req_transfer_count;
+
+ req->bytes_transferred *= 4;
+
+ tegra_dma_stop(ch);
+ if (!list_empty(&ch->list)) {
+ /* if the list is not empty, queue the next request */
+ struct tegra_dma_req *next_req;
+ next_req = list_entry(ch->list.next,
+ typeof(*next_req), node);
+ tegra_dma_update_hw(ch, next_req);
+ }
+ req->status = -TEGRA_DMA_REQ_ERROR_ABORTED;
+
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+
+ /* Callback should be called without any lock */
+ req->complete(req);
+ return 0;
+}
+EXPORT_SYMBOL(tegra_dma_dequeue_req);
+
+bool tegra_dma_is_empty(struct tegra_dma_channel *ch)
+{
+ unsigned long irq_flags;
+ bool is_empty;
+
+ spin_lock_irqsave(&ch->lock, irq_flags);
+ if (list_empty(&ch->list))
+ is_empty = true;
+ else
+ is_empty = false;
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+ return is_empty;
+}
+EXPORT_SYMBOL(tegra_dma_is_empty);
+
+bool tegra_dma_is_req_inflight(struct tegra_dma_channel *ch,
+ struct tegra_dma_req *_req)
+{
+ unsigned long irq_flags;
+ struct tegra_dma_req *req;
+
+ spin_lock_irqsave(&ch->lock, irq_flags);
+ list_for_each_entry(req, &ch->list, node) {
+ if (req == _req) {
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+ return true;
+ }
+ }
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+ return false;
+}
+EXPORT_SYMBOL(tegra_dma_is_req_inflight);
+
+int tegra_dma_enqueue_req(struct tegra_dma_channel *ch,
+ struct tegra_dma_req *req)
+{
+ unsigned long irq_flags;
+ int start_dma = 0;
+
+ if (req->size > NV_DMA_MAX_TRASFER_SIZE ||
+ req->source_addr & 0x3 || req->dest_addr & 0x3) {
+ pr_err("Invalid DMA request for channel %d\n", ch->id);
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&ch->lock, irq_flags);
+
+ req->bytes_transferred = 0;
+ req->status = 0;
+ req->buffer_status = 0;
+ if (list_empty(&ch->list))
+ start_dma = 1;
+
+ list_add_tail(&req->node, &ch->list);
+
+ if (start_dma)
+ tegra_dma_update_hw(ch, req);
+
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(tegra_dma_enqueue_req);
+
+struct tegra_dma_channel *tegra_dma_allocate_channel(int mode)
+{
+ int channel;
+ struct tegra_dma_channel *ch;
+
+ /* first channel is the shared channel */
+ if (mode & TEGRA_DMA_SHARED) {
+ channel = TEGRA_SYSTEM_DMA_CH_MIN;
+ } else {
+ channel = find_first_zero_bit(channel_usage,
+ ARRAY_SIZE(dma_channels));
+ if (channel >= ARRAY_SIZE(dma_channels))
+ return NULL;
+ }
+ __set_bit(channel, channel_usage);
+ ch = &dma_channels[channel];
+ ch->mode = mode;
+ return ch;
+}
+EXPORT_SYMBOL(tegra_dma_allocate_channel);
+
+void tegra_dma_free_channel(struct tegra_dma_channel *ch)
+{
+ if (ch->mode & TEGRA_DMA_SHARED)
+ return;
+ tegra_dma_cancel(ch);
+ __clear_bit(ch->id, channel_usage);
+}
+EXPORT_SYMBOL(tegra_dma_free_channel);
+
+static void tegra_dma_update_hw_partial(struct tegra_dma_channel *ch,
+ struct tegra_dma_req *req)
+{
+ if (req->to_memory) {
+ ch->apb_ptr = req->source_addr;
+ ch->ahb_ptr = req->dest_addr;
+ } else {
+ ch->apb_ptr = req->dest_addr;
+ ch->ahb_ptr = req->source_addr;
+ }
+ writel(ch->apb_ptr, ch->addr + APB_DMA_CHAN_APB_PTR);
+ writel(ch->ahb_ptr, ch->addr + APB_DMA_CHAN_AHB_PTR);
+
+ req->status = TEGRA_DMA_REQ_INFLIGHT;
+ return;
+}
+
+static void tegra_dma_update_hw(struct tegra_dma_channel *ch,
+ struct tegra_dma_req *req)
+{
+ int ahb_addr_wrap;
+ int apb_addr_wrap;
+ int ahb_bus_width;
+ int apb_bus_width;
+ int index;
+ unsigned long csr;
+
+
+ ch->csr |= CSR_FLOW;
+ ch->csr &= ~CSR_REQ_SEL_MASK;
+ ch->csr |= req->req_sel << CSR_REQ_SEL_SHIFT;
+ ch->ahb_seq &= ~AHB_SEQ_BURST_MASK;
+ ch->ahb_seq |= AHB_SEQ_BURST_1;
+
+ /* One shot mode is always single buffered,
+ * continuous mode is always double buffered
+ * */
+ if (ch->mode & TEGRA_DMA_MODE_ONESHOT) {
+ ch->csr |= CSR_ONCE;
+ ch->ahb_seq &= ~AHB_SEQ_DBL_BUF;
+ ch->csr &= ~CSR_WCOUNT_MASK;
+ ch->csr |= ((req->size>>2) - 1) << CSR_WCOUNT_SHIFT;
+ } else {
+ ch->csr &= ~CSR_ONCE;
+ ch->ahb_seq |= AHB_SEQ_DBL_BUF;
+
+ /* In double buffered mode, we set the size to half the
+ * requested size and interrupt when half the buffer
+ * is full */
+ ch->csr &= ~CSR_WCOUNT_MASK;
+ ch->csr |= ((req->size>>3) - 1) << CSR_WCOUNT_SHIFT;
+ }
+
+ if (req->to_memory) {
+ ch->csr &= ~CSR_DIR;
+ ch->apb_ptr = req->source_addr;
+ ch->ahb_ptr = req->dest_addr;
+
+ apb_addr_wrap = req->source_wrap;
+ ahb_addr_wrap = req->dest_wrap;
+ apb_bus_width = req->source_bus_width;
+ ahb_bus_width = req->dest_bus_width;
+
+ } else {
+ ch->csr |= CSR_DIR;
+ ch->apb_ptr = req->dest_addr;
+ ch->ahb_ptr = req->source_addr;
+
+ apb_addr_wrap = req->dest_wrap;
+ ahb_addr_wrap = req->source_wrap;
+ apb_bus_width = req->dest_bus_width;
+ ahb_bus_width = req->source_bus_width;
+ }
+
+ apb_addr_wrap >>= 2;
+ ahb_addr_wrap >>= 2;
+
+ /* set address wrap for APB size */
+ index = 0;
+ do {
+ if (apb_addr_wrap_table[index] == apb_addr_wrap)
+ break;
+ index++;
+ } while (index < ARRAY_SIZE(apb_addr_wrap_table));
+ BUG_ON(index == ARRAY_SIZE(apb_addr_wrap_table));
+ ch->apb_seq &= ~APB_SEQ_WRAP_MASK;
+ ch->apb_seq |= index << APB_SEQ_WRAP_SHIFT;
+
+ /* set address wrap for AHB size */
+ index = 0;
+ do {
+ if (ahb_addr_wrap_table[index] == ahb_addr_wrap)
+ break;
+ index++;
+ } while (index < ARRAY_SIZE(ahb_addr_wrap_table));
+ BUG_ON(index == ARRAY_SIZE(ahb_addr_wrap_table));
+ ch->ahb_seq &= ~AHB_SEQ_WRAP_MASK;
+ ch->ahb_seq |= index << AHB_SEQ_WRAP_SHIFT;
+
+ for (index = 0; index < ARRAY_SIZE(bus_width_table); index++) {
+ if (bus_width_table[index] == ahb_bus_width)
+ break;
+ }
+ BUG_ON(index == ARRAY_SIZE(bus_width_table));
+ ch->ahb_seq &= ~AHB_SEQ_BUS_WIDTH_MASK;
+ ch->ahb_seq |= index << AHB_SEQ_BUS_WIDTH_SHIFT;
+
+ for (index = 0; index < ARRAY_SIZE(bus_width_table); index++) {
+ if (bus_width_table[index] == apb_bus_width)
+ break;
+ }
+ BUG_ON(index == ARRAY_SIZE(bus_width_table));
+ ch->apb_seq &= ~APB_SEQ_BUS_WIDTH_MASK;
+ ch->apb_seq |= index << APB_SEQ_BUS_WIDTH_SHIFT;
+
+ ch->csr |= CSR_IE_EOC;
+
+ /* update hw registers with the shadow */
+ writel(ch->csr, ch->addr + APB_DMA_CHAN_CSR);
+ writel(ch->apb_seq, ch->addr + APB_DMA_CHAN_APB_SEQ);
+ writel(ch->apb_ptr, ch->addr + APB_DMA_CHAN_APB_PTR);
+ writel(ch->ahb_seq, ch->addr + APB_DMA_CHAN_AHB_SEQ);
+ writel(ch->ahb_ptr, ch->addr + APB_DMA_CHAN_AHB_PTR);
+
+ csr = ch->csr | CSR_ENB;
+ writel(csr, ch->addr + APB_DMA_CHAN_CSR);
+
+ req->status = TEGRA_DMA_REQ_INFLIGHT;
+}
+
+static void tegra_dma_init_hw(struct tegra_dma_channel *ch)
+{
+ /* One shot with an interrupt to CPU after transfer */
+ ch->csr = CSR_ONCE | CSR_IE_EOC;
+ ch->ahb_seq = AHB_SEQ_BUS_WIDTH_32 | AHB_SEQ_INTR_ENB;
+ ch->apb_seq = APB_SEQ_BUS_WIDTH_32 | 1 << APB_SEQ_WRAP_SHIFT;
+}
+
+static void handle_oneshot_dma(struct tegra_dma_channel *ch)
+{
+ struct tegra_dma_req *req;
+
+ spin_lock(&ch->lock);
+ if (list_empty(&ch->list)) {
+ spin_unlock(&ch->lock);
+ return;
+ }
+
+ req = list_entry(ch->list.next, typeof(*req), node);
+ if (req) {
+ int bytes_transferred;
+
+ bytes_transferred =
+ (ch->csr & CSR_WCOUNT_MASK) >> CSR_WCOUNT_SHIFT;
+ bytes_transferred += 1;
+ bytes_transferred <<= 2;
+
+ list_del(&req->node);
+ req->bytes_transferred = bytes_transferred;
+ req->status = TEGRA_DMA_REQ_SUCCESS;
+
+ spin_unlock(&ch->lock);
+ /* Callback should be called without any lock */
+ pr_debug("%s: transferred %d bytes\n", __func__,
+ req->bytes_transferred);
+ req->complete(req);
+ spin_lock(&ch->lock);
+ }
+
+ if (!list_empty(&ch->list)) {
+ req = list_entry(ch->list.next, typeof(*req), node);
+ /* the complete function we just called may have enqueued
+ another req, in which case dma has already started */
+ if (req->status != TEGRA_DMA_REQ_INFLIGHT)
+ tegra_dma_update_hw(ch, req);
+ }
+ spin_unlock(&ch->lock);
+}
+
+static void handle_continuous_dma(struct tegra_dma_channel *ch)
+{
+ struct tegra_dma_req *req;
+
+ spin_lock(&ch->lock);
+ if (list_empty(&ch->list)) {
+ spin_unlock(&ch->lock);
+ return;
+ }
+
+ req = list_entry(ch->list.next, typeof(*req), node);
+ if (req) {
+ if (req->buffer_status == TEGRA_DMA_REQ_BUF_STATUS_EMPTY) {
+ /* Load the next request into the hardware, if available
+ * */
+ if (!list_is_last(&req->node, &ch->list)) {
+ struct tegra_dma_req *next_req;
+
+ next_req = list_entry(req->node.next,
+ typeof(*next_req), node);
+ tegra_dma_update_hw_partial(ch, next_req);
+ }
+ req->buffer_status = TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL;
+ req->status = TEGRA_DMA_REQ_SUCCESS;
+ /* DMA lock is NOT held when callback is called */
+ spin_unlock(&ch->lock);
+ if (likely(req->threshold))
+ req->threshold(req);
+ return;
+
+ } else if (req->buffer_status ==
+ TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL) {
+ /* Callback when the buffer is completely full (i.e on
+ * the second interrupt */
+ int bytes_transferred;
+
+ bytes_transferred =
+ (ch->csr & CSR_WCOUNT_MASK) >> CSR_WCOUNT_SHIFT;
+ bytes_transferred += 1;
+ bytes_transferred <<= 3;
+
+ req->buffer_status = TEGRA_DMA_REQ_BUF_STATUS_FULL;
+ req->bytes_transferred = bytes_transferred;
+ req->status = TEGRA_DMA_REQ_SUCCESS;
+ list_del(&req->node);
+
+ /* DMA lock is NOT held when callbak is called */
+ spin_unlock(&ch->lock);
+ req->complete(req);
+ return;
+
+ } else {
+ BUG();
+ }
+ }
+ spin_unlock(&ch->lock);
+}
+
+static irqreturn_t dma_isr(int irq, void *data)
+{
+ struct tegra_dma_channel *ch = data;
+ unsigned long status;
+
+ status = readl(ch->addr + APB_DMA_CHAN_STA);
+ if (status & STA_ISE_EOC)
+ writel(status, ch->addr + APB_DMA_CHAN_STA);
+ else {
+ pr_warning("Got a spurious ISR for DMA channel %d\n", ch->id);
+ return IRQ_HANDLED;
+ }
+ return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t dma_thread_fn(int irq, void *data)
+{
+ struct tegra_dma_channel *ch = data;
+
+ if (ch->mode & TEGRA_DMA_MODE_ONESHOT)
+ handle_oneshot_dma(ch);
+ else
+ handle_continuous_dma(ch);
+
+
+ return IRQ_HANDLED;
+}
+
+int __init tegra_dma_init(void)
+{
+ int ret = 0;
+ int i;
+ unsigned int irq;
+ void __iomem *addr;
+
+ addr = IO_ADDRESS(TEGRA_APB_DMA_BASE);
+ writel(GEN_ENABLE, addr + APB_DMA_GEN);
+ writel(0, addr + APB_DMA_CNTRL);
+ writel(0xFFFFFFFFul >> (31 - TEGRA_SYSTEM_DMA_CH_MAX),
+ addr + APB_DMA_IRQ_MASK_SET);
+
+ memset(channel_usage, 0, sizeof(channel_usage));
+ memset(dma_channels, 0, sizeof(dma_channels));
+
+ /* Reserve all the channels we are not supposed to touch */
+ for (i = 0; i < TEGRA_SYSTEM_DMA_CH_MIN; i++)
+ __set_bit(i, channel_usage);
+
+ for (i = TEGRA_SYSTEM_DMA_CH_MIN; i <= TEGRA_SYSTEM_DMA_CH_MAX; i++) {
+ struct tegra_dma_channel *ch = &dma_channels[i];
+
+ __clear_bit(i, channel_usage);
+
+ ch->id = i;
+ snprintf(ch->name, TEGRA_DMA_NAME_SIZE, "dma_channel_%d", i);
+
+ ch->addr = IO_ADDRESS(TEGRA_APB_DMA_CH0_BASE +
+ TEGRA_APB_DMA_CH0_SIZE * i);
+
+ spin_lock_init(&ch->lock);
+ INIT_LIST_HEAD(&ch->list);
+ tegra_dma_init_hw(ch);
+
+ irq = INT_APB_DMA_CH0 + i;
+ ret = request_threaded_irq(irq, dma_isr, dma_thread_fn, 0,
+ dma_channels[i].name, ch);
+ if (ret) {
+ pr_err("Failed to register IRQ %d for DMA %d\n",
+ irq, i);
+ goto fail;
+ }
+ ch->irq = irq;
+ }
+ /* mark the shared channel allocated */
+ __set_bit(TEGRA_SYSTEM_DMA_CH_MIN, channel_usage);
+
+ for (i = TEGRA_SYSTEM_DMA_CH_MAX+1; i < NV_DMA_MAX_CHANNELS; i++)
+ __set_bit(i, channel_usage);
+
+ return ret;
+fail:
+ writel(0, addr + APB_DMA_GEN);
+ for (i = TEGRA_SYSTEM_DMA_CH_MIN; i <= TEGRA_SYSTEM_DMA_CH_MAX; i++) {
+ struct tegra_dma_channel *ch = &dma_channels[i];
+ if (ch->irq)
+ free_irq(ch->irq, ch);
+ }
+ return ret;
+}
+
+#ifdef CONFIG_PM
+static u32 apb_dma[5*TEGRA_SYSTEM_DMA_CH_NR + 3];
+
+void tegra_dma_suspend(void)
+{
+ void __iomem *addr = IO_ADDRESS(TEGRA_APB_DMA_BASE);
+ u32 *ctx = apb_dma;
+ int i;
+
+ *ctx++ = readl(addr + APB_DMA_GEN);
+ *ctx++ = readl(addr + APB_DMA_CNTRL);
+ *ctx++ = readl(addr + APB_DMA_IRQ_MASK);
+
+ for (i = 0; i < TEGRA_SYSTEM_DMA_CH_NR; i++) {
+ addr = IO_ADDRESS(TEGRA_APB_DMA_CH0_BASE +
+ TEGRA_APB_DMA_CH0_SIZE * i);
+
+ *ctx++ = readl(addr + APB_DMA_CHAN_CSR);
+ *ctx++ = readl(addr + APB_DMA_CHAN_AHB_PTR);
+ *ctx++ = readl(addr + APB_DMA_CHAN_AHB_SEQ);
+ *ctx++ = readl(addr + APB_DMA_CHAN_APB_PTR);
+ *ctx++ = readl(addr + APB_DMA_CHAN_APB_SEQ);
+ }
+}
+
+void tegra_dma_resume(void)
+{
+ void __iomem *addr = IO_ADDRESS(TEGRA_APB_DMA_BASE);
+ u32 *ctx = apb_dma;
+ int i;
+
+ writel(*ctx++, addr + APB_DMA_GEN);
+ writel(*ctx++, addr + APB_DMA_CNTRL);
+ writel(*ctx++, addr + APB_DMA_IRQ_MASK);
+
+ for (i = 0; i < TEGRA_SYSTEM_DMA_CH_NR; i++) {
+ addr = IO_ADDRESS(TEGRA_APB_DMA_CH0_BASE +
+ TEGRA_APB_DMA_CH0_SIZE * i);
+
+ writel(*ctx++, addr + APB_DMA_CHAN_CSR);
+ writel(*ctx++, addr + APB_DMA_CHAN_AHB_PTR);
+ writel(*ctx++, addr + APB_DMA_CHAN_AHB_SEQ);
+ writel(*ctx++, addr + APB_DMA_CHAN_APB_PTR);
+ writel(*ctx++, addr + APB_DMA_CHAN_APB_SEQ);
+ }
+}
+
+#endif
diff --git a/arch/arm/mach-tegra/fuse.c b/arch/arm/mach-tegra/fuse.c
new file mode 100644
index 000000000000..1fa26d9a1a68
--- /dev/null
+++ b/arch/arm/mach-tegra/fuse.c
@@ -0,0 +1,84 @@
+/*
+ * arch/arm/mach-tegra/fuse.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@android.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 <linux/kernel.h>
+#include <linux/io.h>
+
+#include <mach/iomap.h>
+
+#include "fuse.h"
+
+#define FUSE_UID_LOW 0x108
+#define FUSE_UID_HIGH 0x10c
+#define FUSE_SKU_INFO 0x110
+#define FUSE_SPARE_BIT 0x200
+
+static inline u32 fuse_readl(unsigned long offset)
+{
+ return readl(IO_TO_VIRT(TEGRA_FUSE_BASE + offset));
+}
+
+static inline void fuse_writel(u32 value, unsigned long offset)
+{
+ writel(value, IO_TO_VIRT(TEGRA_FUSE_BASE + offset));
+}
+
+void tegra_init_fuse(void)
+{
+ u32 reg = readl(IO_TO_VIRT(TEGRA_CLK_RESET_BASE + 0x48));
+ reg |= 1 << 28;
+ writel(reg, IO_TO_VIRT(TEGRA_CLK_RESET_BASE + 0x48));
+
+ pr_info("Tegra SKU: %d CPU Process: %d Core Process: %d\n",
+ tegra_sku_id(), tegra_cpu_process_id(),
+ tegra_core_process_id());
+}
+
+unsigned long long tegra_chip_uid(void)
+{
+ unsigned long long lo, hi;
+
+ lo = fuse_readl(FUSE_UID_LOW);
+ hi = fuse_readl(FUSE_UID_HIGH);
+ return (hi << 32ull) | lo;
+}
+
+int tegra_sku_id(void)
+{
+ int sku_id;
+ u32 reg = fuse_readl(FUSE_SKU_INFO);
+ sku_id = reg & 0xFF;
+ return sku_id;
+}
+
+int tegra_cpu_process_id(void)
+{
+ int cpu_process_id;
+ u32 reg = fuse_readl(FUSE_SPARE_BIT);
+ cpu_process_id = (reg >> 6) & 3;
+ return cpu_process_id;
+}
+
+int tegra_core_process_id(void)
+{
+ int core_process_id;
+ u32 reg = fuse_readl(FUSE_SPARE_BIT);
+ core_process_id = (reg >> 12) & 3;
+ return core_process_id;
+}
diff --git a/arch/arm/mach-tegra/fuse.h b/arch/arm/mach-tegra/fuse.h
new file mode 100644
index 000000000000..584b2e27dbda
--- /dev/null
+++ b/arch/arm/mach-tegra/fuse.h
@@ -0,0 +1,24 @@
+/*
+ * arch/arm/mach-tegra/fuse.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@android.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.
+ *
+ */
+
+unsigned long long tegra_chip_uid(void);
+int tegra_sku_id(void);
+int tegra_cpu_process_id(void);
+int tegra_core_process_id(void);
+void tegra_init_fuse(void);
diff --git a/arch/arm/mach-tegra/gpio.c b/arch/arm/mach-tegra/gpio.c
index fe78fba25f3c..0775265e69f5 100644
--- a/arch/arm/mach-tegra/gpio.c
+++ b/arch/arm/mach-tegra/gpio.c
@@ -19,6 +19,7 @@
#include <linux/init.h>
#include <linux/irq.h>
+#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/gpio.h>
@@ -60,6 +61,13 @@ struct tegra_gpio_bank {
int bank;
int irq;
spinlock_t lvl_lock[4];
+#ifdef CONFIG_PM
+ u32 cnf[4];
+ u32 out[4];
+ u32 oe[4];
+ u32 int_enb[4];
+ u32 int_lvl[4];
+#endif
};
@@ -131,7 +139,7 @@ static struct gpio_chip tegra_gpio_chip = {
.direction_output = tegra_gpio_direction_output,
.set = tegra_gpio_set,
.base = 0,
- .ngpio = ARCH_NR_GPIOS,
+ .ngpio = TEGRA_NR_GPIOS,
};
static void tegra_gpio_irq_ack(unsigned int irq)
@@ -244,6 +252,76 @@ static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
}
+#ifdef CONFIG_PM
+void tegra_gpio_resume(void)
+{
+ unsigned long flags;
+ int b, p, i;
+
+ local_irq_save(flags);
+
+ for (b = 0; b < ARRAY_SIZE(tegra_gpio_banks); b++) {
+ struct tegra_gpio_bank *bank = &tegra_gpio_banks[b];
+
+ for (p = 0; p < ARRAY_SIZE(bank->oe); p++) {
+ unsigned int gpio = (b<<5) | (p<<3);
+ __raw_writel(bank->cnf[p], GPIO_CNF(gpio));
+ __raw_writel(bank->out[p], GPIO_OUT(gpio));
+ __raw_writel(bank->oe[p], GPIO_OE(gpio));
+ __raw_writel(bank->int_lvl[p], GPIO_INT_LVL(gpio));
+ __raw_writel(bank->int_enb[p], GPIO_INT_ENB(gpio));
+ }
+ }
+
+ local_irq_restore(flags);
+
+ for (i = INT_GPIO_BASE; i < (INT_GPIO_BASE + TEGRA_NR_GPIOS); i++) {
+ struct irq_desc *desc = irq_to_desc(i);
+ if (!desc || (desc->status & IRQ_WAKEUP))
+ continue;
+ enable_irq(i);
+ }
+}
+
+void tegra_gpio_suspend(void)
+{
+ unsigned long flags;
+ int b, p, i;
+
+ for (i = INT_GPIO_BASE; i < (INT_GPIO_BASE + TEGRA_NR_GPIOS); i++) {
+ struct irq_desc *desc = irq_to_desc(i);
+ if (!desc)
+ continue;
+ if (desc->status & IRQ_WAKEUP) {
+ int gpio = i - INT_GPIO_BASE;
+ pr_debug("gpio %d.%d is wakeup\n", gpio/8, gpio&7);
+ continue;
+ }
+ disable_irq(i);
+ }
+
+ local_irq_save(flags);
+ for (b = 0; b < ARRAY_SIZE(tegra_gpio_banks); b++) {
+ struct tegra_gpio_bank *bank = &tegra_gpio_banks[b];
+
+ for (p = 0; p < ARRAY_SIZE(bank->oe); p++) {
+ unsigned int gpio = (b<<5) | (p<<3);
+ bank->cnf[p] = __raw_readl(GPIO_CNF(gpio));
+ bank->out[p] = __raw_readl(GPIO_OUT(gpio));
+ bank->oe[p] = __raw_readl(GPIO_OE(gpio));
+ bank->int_enb[p] = __raw_readl(GPIO_INT_ENB(gpio));
+ bank->int_lvl[p] = __raw_readl(GPIO_INT_LVL(gpio));
+ }
+ }
+ local_irq_restore(flags);
+}
+
+static int tegra_gpio_wake_enable(unsigned int irq, unsigned int enable)
+{
+ struct tegra_gpio_bank *bank = get_irq_chip_data(irq);
+ return set_irq_wake(bank->irq, enable);
+}
+#endif
static struct irq_chip tegra_gpio_irq_chip = {
.name = "GPIO",
@@ -251,6 +329,9 @@ static struct irq_chip tegra_gpio_irq_chip = {
.mask = tegra_gpio_irq_mask,
.unmask = tegra_gpio_irq_unmask,
.set_type = tegra_gpio_irq_set_type,
+#ifdef CONFIG_PM
+ .set_wake = tegra_gpio_wake_enable,
+#endif
};
@@ -274,7 +355,7 @@ static int __init tegra_gpio_init(void)
gpiochip_add(&tegra_gpio_chip);
- for (i = INT_GPIO_BASE; i < (INT_GPIO_BASE + ARCH_NR_GPIOS); i++) {
+ for (i = INT_GPIO_BASE; i < (INT_GPIO_BASE + TEGRA_NR_GPIOS); i++) {
bank = &tegra_gpio_banks[GPIO_BANK(irq_to_gpio(i))];
lockdep_set_class(&irq_desc[i].lock, &gpio_lock_class);
@@ -312,15 +393,16 @@ static int dbg_gpio_show(struct seq_file *s, void *unused)
for (i = 0; i < 7; i++) {
for (j = 0; j < 4; j++) {
int gpio = tegra_gpio_compose(i, j, 0);
- seq_printf(s, "%d:%d %02x %02x %02x %02x %02x %02x %06x\n",
- i, j,
- __raw_readl(GPIO_CNF(gpio)),
- __raw_readl(GPIO_OE(gpio)),
- __raw_readl(GPIO_OUT(gpio)),
- __raw_readl(GPIO_IN(gpio)),
- __raw_readl(GPIO_INT_STA(gpio)),
- __raw_readl(GPIO_INT_ENB(gpio)),
- __raw_readl(GPIO_INT_LVL(gpio)));
+ seq_printf(s,
+ "%d:%d %02x %02x %02x %02x %02x %02x %06x\n",
+ i, j,
+ __raw_readl(GPIO_CNF(gpio)),
+ __raw_readl(GPIO_OE(gpio)),
+ __raw_readl(GPIO_OUT(gpio)),
+ __raw_readl(GPIO_IN(gpio)),
+ __raw_readl(GPIO_INT_STA(gpio)),
+ __raw_readl(GPIO_INT_ENB(gpio)),
+ __raw_readl(GPIO_INT_LVL(gpio)));
}
}
return 0;
diff --git a/arch/arm/mach-tegra/include/mach/clk.h b/arch/arm/mach-tegra/include/mach/clk.h
index 2896f25ebfb5..d7723955dac7 100644
--- a/arch/arm/mach-tegra/include/mach/clk.h
+++ b/arch/arm/mach-tegra/include/mach/clk.h
@@ -23,4 +23,9 @@
void tegra_periph_reset_deassert(struct clk *c);
void tegra_periph_reset_assert(struct clk *c);
+int clk_enable_cansleep(struct clk *clk);
+void clk_disable_cansleep(struct clk *clk);
+int clk_set_rate_cansleep(struct clk *clk, unsigned long rate);
+int clk_set_parent_cansleep(struct clk *clk, struct clk *parent);
+
#endif
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/dma.h b/arch/arm/mach-tegra/include/mach/dma.h
new file mode 100644
index 000000000000..39011bd9a925
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/dma.h
@@ -0,0 +1,155 @@
+/*
+ * arch/arm/mach-tegra/include/mach/dma.h
+ *
+ * Copyright (c) 2008-2009, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_TEGRA_DMA_H
+#define __MACH_TEGRA_DMA_H
+
+#include <linux/list.h>
+
+#if defined(CONFIG_TEGRA_SYSTEM_DMA)
+
+struct tegra_dma_req;
+struct tegra_dma_channel;
+
+#define TEGRA_DMA_REQ_SEL_CNTR 0
+#define TEGRA_DMA_REQ_SEL_I2S_2 1
+#define TEGRA_DMA_REQ_SEL_I2S_1 2
+#define TEGRA_DMA_REQ_SEL_SPD_I 3
+#define TEGRA_DMA_REQ_SEL_UI_I 4
+#define TEGRA_DMA_REQ_SEL_MIPI 5
+#define TEGRA_DMA_REQ_SEL_I2S2_2 6
+#define TEGRA_DMA_REQ_SEL_I2S2_1 7
+#define TEGRA_DMA_REQ_SEL_UARTA 8
+#define TEGRA_DMA_REQ_SEL_UARTB 9
+#define TEGRA_DMA_REQ_SEL_UARTC 10
+#define TEGRA_DMA_REQ_SEL_SPI 11
+#define TEGRA_DMA_REQ_SEL_AC97 12
+#define TEGRA_DMA_REQ_SEL_ACMODEM 13
+#define TEGRA_DMA_REQ_SEL_SL4B 14
+#define TEGRA_DMA_REQ_SEL_SL2B1 15
+#define TEGRA_DMA_REQ_SEL_SL2B2 16
+#define TEGRA_DMA_REQ_SEL_SL2B3 17
+#define TEGRA_DMA_REQ_SEL_SL2B4 18
+#define TEGRA_DMA_REQ_SEL_UARTD 19
+#define TEGRA_DMA_REQ_SEL_UARTE 20
+#define TEGRA_DMA_REQ_SEL_I2C 21
+#define TEGRA_DMA_REQ_SEL_I2C2 22
+#define TEGRA_DMA_REQ_SEL_I2C3 23
+#define TEGRA_DMA_REQ_SEL_DVC_I2C 24
+#define TEGRA_DMA_REQ_SEL_OWR 25
+#define TEGRA_DMA_REQ_SEL_INVALID 31
+
+enum tegra_dma_mode {
+ TEGRA_DMA_SHARED = 1,
+ TEGRA_DMA_MODE_CONTINOUS = 2,
+ TEGRA_DMA_MODE_ONESHOT = 4,
+};
+
+enum tegra_dma_req_error {
+ TEGRA_DMA_REQ_SUCCESS = 0,
+ TEGRA_DMA_REQ_ERROR_ABORTED,
+ TEGRA_DMA_REQ_INFLIGHT,
+};
+
+enum tegra_dma_req_buff_status {
+ TEGRA_DMA_REQ_BUF_STATUS_EMPTY = 0,
+ TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL,
+ TEGRA_DMA_REQ_BUF_STATUS_FULL,
+};
+
+struct tegra_dma_req {
+ struct list_head node;
+ unsigned int modid;
+ int instance;
+
+ /* Called when the req is complete and from the DMA ISR context.
+ * When this is called the req structure is no longer queued by
+ * the DMA channel.
+ *
+ * State of the DMA depends on the number of req it has. If there are
+ * no DMA requests queued up, then it will STOP the DMA. It there are
+ * more requests in the DMA, then it will queue the next request.
+ */
+ void (*complete)(struct tegra_dma_req *req);
+
+ /* This is a called from the DMA ISR context when the DMA is still in
+ * progress and is actively filling same buffer.
+ *
+ * In case of continous mode receive, this threshold is 1/2 the buffer
+ * size. In other cases, this will not even be called as there is no
+ * hardware support for it.
+ *
+ * In the case of continous mode receive, if there is next req already
+ * queued, DMA programs the HW to use that req when this req is
+ * completed. If there is no "next req" queued, then DMA ISR doesn't do
+ * anything before calling this callback.
+ *
+ * This is mainly used by the cases, where the clients has queued
+ * only one req and want to get some sort of DMA threshold
+ * callback to program the next buffer.
+ *
+ */
+ void (*threshold)(struct tegra_dma_req *req);
+
+ /* 1 to copy to memory.
+ * 0 to copy from the memory to device FIFO */
+ int to_memory;
+
+ void *virt_addr;
+
+ unsigned long source_addr;
+ unsigned long dest_addr;
+ unsigned long dest_wrap;
+ unsigned long source_wrap;
+ unsigned long source_bus_width;
+ unsigned long dest_bus_width;
+ unsigned long req_sel;
+ unsigned int size;
+
+ /* Updated by the DMA driver on the conpletion of the request. */
+ int bytes_transferred;
+ int status;
+
+ /* DMA completion tracking information */
+ int buffer_status;
+
+ /* Client specific data */
+ void *dev;
+};
+
+int tegra_dma_enqueue_req(struct tegra_dma_channel *ch,
+ struct tegra_dma_req *req);
+int tegra_dma_dequeue_req(struct tegra_dma_channel *ch,
+ struct tegra_dma_req *req);
+void tegra_dma_dequeue(struct tegra_dma_channel *ch);
+void tegra_dma_flush(struct tegra_dma_channel *ch);
+
+bool tegra_dma_is_req_inflight(struct tegra_dma_channel *ch,
+ struct tegra_dma_req *req);
+bool tegra_dma_is_empty(struct tegra_dma_channel *ch);
+
+struct tegra_dma_channel *tegra_dma_allocate_channel(int mode);
+void tegra_dma_free_channel(struct tegra_dma_channel *ch);
+
+int __init tegra_dma_init(void);
+
+#endif
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/gpio.h b/arch/arm/mach-tegra/include/mach/gpio.h
index 540e822e50f7..e31f486d69a2 100644
--- a/arch/arm/mach-tegra/include/mach/gpio.h
+++ b/arch/arm/mach-tegra/include/mach/gpio.h
@@ -22,7 +22,7 @@
#include <mach/irqs.h>
-#define ARCH_NR_GPIOS INT_GPIO_NR
+#define TEGRA_NR_GPIOS INT_GPIO_NR
#include <asm-generic/gpio.h>
@@ -35,7 +35,7 @@
static inline int gpio_to_irq(unsigned int gpio)
{
- if (gpio < ARCH_NR_GPIOS)
+ if (gpio < TEGRA_NR_GPIOS)
return INT_GPIO_BASE + gpio;
return -EINVAL;
}
diff --git a/arch/arm/mach-tegra/include/mach/hardware.h b/arch/arm/mach-tegra/include/mach/hardware.h
index 6014edf60d93..56e43b3a5b97 100644
--- a/arch/arm/mach-tegra/include/mach/hardware.h
+++ b/arch/arm/mach-tegra/include/mach/hardware.h
@@ -21,4 +21,8 @@
#ifndef __MACH_TEGRA_HARDWARE_H
#define __MACH_TEGRA_HARDWARE_H
+#define PCIBIOS_MIN_IO 0x1000
+#define PCIBIOS_MIN_MEM 0
+#define pcibios_assign_all_busses() 1
+
#endif
diff --git a/arch/arm/mach-tegra/include/mach/io.h b/arch/arm/mach-tegra/include/mach/io.h
index 35edfc32ffc9..f0981b1ac59e 100644
--- a/arch/arm/mach-tegra/include/mach/io.h
+++ b/arch/arm/mach-tegra/include/mach/io.h
@@ -21,7 +21,7 @@
#ifndef __MACH_TEGRA_IO_H
#define __MACH_TEGRA_IO_H
-#define IO_SPACE_LIMIT 0xffffffff
+#define IO_SPACE_LIMIT 0xffff
/* On TEGRA, many peripherals are very closely packed in
* two 256MB io windows (that actually only use about 64KB
@@ -33,6 +33,10 @@
*
*/
+#define IO_IRAM_PHYS 0x40000000
+#define IO_IRAM_VIRT 0xFE400000
+#define IO_IRAM_SIZE SZ_256K
+
#define IO_CPU_PHYS 0x50040000
#define IO_CPU_VIRT 0xFE000000
#define IO_CPU_SIZE SZ_16K
@@ -55,6 +59,8 @@
IO_TO_VIRT_XLATE((n), IO_APB_PHYS, IO_APB_VIRT) : \
IO_TO_VIRT_BETWEEN((n), IO_CPU_PHYS, IO_CPU_SIZE) ? \
IO_TO_VIRT_XLATE((n), IO_CPU_PHYS, IO_CPU_VIRT) : \
+ IO_TO_VIRT_BETWEEN((n), IO_IRAM_PHYS, IO_IRAM_SIZE) ? \
+ IO_TO_VIRT_XLATE((n), IO_IRAM_PHYS, IO_IRAM_VIRT) : \
0)
#ifndef __ASSEMBLER__
@@ -67,10 +73,20 @@ void tegra_iounmap(volatile void __iomem *addr);
#define IO_ADDRESS(n) ((void __iomem *) IO_TO_VIRT(n))
+#ifdef CONFIG_TEGRA_PCI
+extern void __iomem *tegra_pcie_io_base;
+
+static inline void __iomem *__io(unsigned long addr)
+{
+ return tegra_pcie_io_base + (addr & IO_SPACE_LIMIT);
+}
+#else
static inline void __iomem *__io(unsigned long addr)
{
return (void __iomem *)addr;
}
+#endif
+
#define __io(a) __io(a)
#define __mem_pci(a) (a)
diff --git a/arch/arm/mach-tegra/include/mach/iomap.h b/arch/arm/mach-tegra/include/mach/iomap.h
index 1741f7dd7a9b..44a4f4bcf91f 100644
--- a/arch/arm/mach-tegra/include/mach/iomap.h
+++ b/arch/arm/mach-tegra/include/mach/iomap.h
@@ -23,9 +23,15 @@
#include <asm/sizes.h>
+#define TEGRA_IRAM_BASE 0x40000000
+#define TEGRA_IRAM_SIZE SZ_256K
+
#define TEGRA_ARM_PERIF_BASE 0x50040000
#define TEGRA_ARM_PERIF_SIZE SZ_8K
+#define TEGRA_ARM_PL310_BASE 0x50043000
+#define TEGRA_ARM_PL310_SIZE SZ_4K
+
#define TEGRA_ARM_INT_DIST_BASE 0x50041000
#define TEGRA_ARM_INT_DIST_SIZE SZ_4K
@@ -68,7 +74,22 @@
#define TEGRA_FLOW_CTRL_BASE 0x60007000
#define TEGRA_FLOW_CTRL_SIZE 20
-#define TEGRA_STATMON_BASE 0x6000C4000
+#define TEGRA_AHB_DMA_BASE 0x60008000
+#define TEGRA_AHB_DMA_SIZE SZ_4K
+
+#define TEGRA_AHB_DMA_CH0_BASE 0x60009000
+#define TEGRA_AHB_DMA_CH0_SIZE 32
+
+#define TEGRA_APB_DMA_BASE 0x6000A000
+#define TEGRA_APB_DMA_SIZE SZ_4K
+
+#define TEGRA_APB_DMA_CH0_BASE 0x6000B000
+#define TEGRA_APB_DMA_CH0_SIZE 32
+
+#define TEGRA_AHB_GIZMO_BASE 0x6000C004
+#define TEGRA_AHB_GIZMO_SIZE 0x10C
+
+#define TEGRA_STATMON_BASE 0x6000C400
#define TEGRA_STATMON_SIZE SZ_1K
#define TEGRA_GPIO_BASE 0x6000D000
@@ -137,7 +158,7 @@
#define TEGRA_I2C3_BASE 0x7000C500
#define TEGRA_I2C3_SIZE SZ_256
-#define TEGRA_OWR_BASE 0x7000D000
+#define TEGRA_OWR_BASE 0x7000C600
#define TEGRA_OWR_SIZE 80
#define TEGRA_DVC_BASE 0x7000D000
@@ -182,12 +203,12 @@
#define TEGRA_USB_BASE 0xC5000000
#define TEGRA_USB_SIZE SZ_16K
-#define TEGRA_USB1_BASE 0xC5004000
-#define TEGRA_USB1_SIZE SZ_16K
-
-#define TEGRA_USB2_BASE 0xC5008000
+#define TEGRA_USB2_BASE 0xC5004000
#define TEGRA_USB2_SIZE SZ_16K
+#define TEGRA_USB3_BASE 0xC5008000
+#define TEGRA_USB3_SIZE SZ_16K
+
#define TEGRA_SDMMC1_BASE 0xC8000000
#define TEGRA_SDMMC1_SIZE SZ_512
diff --git a/arch/arm/mach-tegra/include/mach/irqs.h b/arch/arm/mach-tegra/include/mach/irqs.h
index 20f640edaa0d..71bbf3422953 100644
--- a/arch/arm/mach-tegra/include/mach/irqs.h
+++ b/arch/arm/mach-tegra/include/mach/irqs.h
@@ -25,6 +25,7 @@
#define IRQ_LOCALTIMER 29
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
/* Primary Interrupt Controller */
#define INT_PRI_BASE (INT_GIC_BASE + 32)
#define INT_TMR1 (INT_PRI_BASE + 0)
@@ -169,5 +170,6 @@
#define INT_GPIO_NR (28 * 8)
#define NR_IRQS (INT_GPIO_BASE + INT_GPIO_NR)
+#endif
#endif
diff --git a/arch/arm/mach-tegra/include/mach/legacy_irq.h b/arch/arm/mach-tegra/include/mach/legacy_irq.h
new file mode 100644
index 000000000000..db1eb3dd04c8
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/legacy_irq.h
@@ -0,0 +1,31 @@
+/*
+ * arch/arm/mach-tegra/include/mach/legacy_irq.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ * Author: Colin Cross <ccross@android.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.
+ *
+ */
+
+#ifndef _ARCH_ARM_MACH_TEGRA_LEGARY_IRQ_H
+#define _ARCH_ARM_MACH_TEGRA_LEGARY_IRQ_H
+
+void tegra_legacy_mask_irq(unsigned int irq);
+void tegra_legacy_unmask_irq(unsigned int irq);
+void tegra_legacy_select_fiq(unsigned int irq, bool fiq);
+void tegra_legacy_force_irq_set(unsigned int irq);
+void tegra_legacy_force_irq_clr(unsigned int irq);
+int tegra_legacy_force_irq_status(unsigned int irq);
+void tegra_legacy_select_fiq(unsigned int irq, bool fiq);
+unsigned long tegra_legacy_vfiq(int nr);
+unsigned long tegra_legacy_class(int nr);
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/pinmux-t2.h b/arch/arm/mach-tegra/include/mach/pinmux-t2.h
new file mode 100644
index 000000000000..e5b9d740f973
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/pinmux-t2.h
@@ -0,0 +1,174 @@
+/*
+ * linux/arch/arm/mach-tegra/include/mach/pinmux-t2.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * 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 __MACH_TEGRA_PINMUX_T2_H
+#define __MACH_TEGRA_PINMUX_T2_H
+
+enum tegra_pingroup {
+ TEGRA_PINGROUP_ATA = 0,
+ TEGRA_PINGROUP_ATB,
+ TEGRA_PINGROUP_ATC,
+ TEGRA_PINGROUP_ATD,
+ TEGRA_PINGROUP_ATE,
+ TEGRA_PINGROUP_CDEV1,
+ TEGRA_PINGROUP_CDEV2,
+ TEGRA_PINGROUP_CRTP,
+ TEGRA_PINGROUP_CSUS,
+ TEGRA_PINGROUP_DAP1,
+ TEGRA_PINGROUP_DAP2,
+ TEGRA_PINGROUP_DAP3,
+ TEGRA_PINGROUP_DAP4,
+ TEGRA_PINGROUP_DDC,
+ TEGRA_PINGROUP_DTA,
+ TEGRA_PINGROUP_DTB,
+ TEGRA_PINGROUP_DTC,
+ TEGRA_PINGROUP_DTD,
+ TEGRA_PINGROUP_DTE,
+ TEGRA_PINGROUP_DTF,
+ TEGRA_PINGROUP_GMA,
+ TEGRA_PINGROUP_GMB,
+ TEGRA_PINGROUP_GMC,
+ TEGRA_PINGROUP_GMD,
+ TEGRA_PINGROUP_GME,
+ TEGRA_PINGROUP_GPU,
+ TEGRA_PINGROUP_GPU7,
+ TEGRA_PINGROUP_GPV,
+ TEGRA_PINGROUP_HDINT,
+ TEGRA_PINGROUP_I2CP,
+ TEGRA_PINGROUP_IRRX,
+ TEGRA_PINGROUP_IRTX,
+ TEGRA_PINGROUP_KBCA,
+ TEGRA_PINGROUP_KBCB,
+ TEGRA_PINGROUP_KBCC,
+ TEGRA_PINGROUP_KBCD,
+ TEGRA_PINGROUP_KBCE,
+ TEGRA_PINGROUP_KBCF,
+ TEGRA_PINGROUP_LCSN,
+ TEGRA_PINGROUP_LD0,
+ TEGRA_PINGROUP_LD1,
+ TEGRA_PINGROUP_LD10,
+ TEGRA_PINGROUP_LD11,
+ TEGRA_PINGROUP_LD12,
+ TEGRA_PINGROUP_LD13,
+ TEGRA_PINGROUP_LD14,
+ TEGRA_PINGROUP_LD15,
+ TEGRA_PINGROUP_LD16,
+ TEGRA_PINGROUP_LD17,
+ TEGRA_PINGROUP_LD2,
+ TEGRA_PINGROUP_LD3,
+ TEGRA_PINGROUP_LD4,
+ TEGRA_PINGROUP_LD5,
+ TEGRA_PINGROUP_LD6,
+ TEGRA_PINGROUP_LD7,
+ TEGRA_PINGROUP_LD8,
+ TEGRA_PINGROUP_LD9,
+ TEGRA_PINGROUP_LDC,
+ TEGRA_PINGROUP_LDI,
+ TEGRA_PINGROUP_LHP0,
+ TEGRA_PINGROUP_LHP1,
+ TEGRA_PINGROUP_LHP2,
+ TEGRA_PINGROUP_LHS,
+ TEGRA_PINGROUP_LM0,
+ TEGRA_PINGROUP_LM1,
+ TEGRA_PINGROUP_LPP,
+ TEGRA_PINGROUP_LPW0,
+ TEGRA_PINGROUP_LPW1,
+ TEGRA_PINGROUP_LPW2,
+ TEGRA_PINGROUP_LSC0,
+ TEGRA_PINGROUP_LSC1,
+ TEGRA_PINGROUP_LSCK,
+ TEGRA_PINGROUP_LSDA,
+ TEGRA_PINGROUP_LSDI,
+ TEGRA_PINGROUP_LSPI,
+ TEGRA_PINGROUP_LVP0,
+ TEGRA_PINGROUP_LVP1,
+ TEGRA_PINGROUP_LVS,
+ TEGRA_PINGROUP_OWC,
+ TEGRA_PINGROUP_PMC,
+ TEGRA_PINGROUP_PTA,
+ TEGRA_PINGROUP_RM,
+ TEGRA_PINGROUP_SDB,
+ TEGRA_PINGROUP_SDC,
+ TEGRA_PINGROUP_SDD,
+ TEGRA_PINGROUP_SDIO1,
+ TEGRA_PINGROUP_SLXA,
+ TEGRA_PINGROUP_SLXC,
+ TEGRA_PINGROUP_SLXD,
+ TEGRA_PINGROUP_SLXK,
+ TEGRA_PINGROUP_SPDI,
+ TEGRA_PINGROUP_SPDO,
+ TEGRA_PINGROUP_SPIA,
+ TEGRA_PINGROUP_SPIB,
+ TEGRA_PINGROUP_SPIC,
+ TEGRA_PINGROUP_SPID,
+ TEGRA_PINGROUP_SPIE,
+ TEGRA_PINGROUP_SPIF,
+ TEGRA_PINGROUP_SPIG,
+ TEGRA_PINGROUP_SPIH,
+ TEGRA_PINGROUP_UAA,
+ TEGRA_PINGROUP_UAB,
+ TEGRA_PINGROUP_UAC,
+ TEGRA_PINGROUP_UAD,
+ TEGRA_PINGROUP_UCA,
+ TEGRA_PINGROUP_UCB,
+ TEGRA_PINGROUP_UDA,
+ /* these pin groups only have pullup and pull down control */
+ TEGRA_PINGROUP_CK32,
+ TEGRA_PINGROUP_DDRC,
+ TEGRA_PINGROUP_PMCA,
+ TEGRA_PINGROUP_PMCB,
+ TEGRA_PINGROUP_PMCC,
+ TEGRA_PINGROUP_PMCD,
+ TEGRA_PINGROUP_PMCE,
+ TEGRA_PINGROUP_XM2C,
+ TEGRA_PINGROUP_XM2D,
+ TEGRA_MAX_PINGROUP,
+};
+
+enum tegra_drive_pingroup {
+ TEGRA_DRIVE_PINGROUP_AO1 = 0,
+ TEGRA_DRIVE_PINGROUP_AO2,
+ TEGRA_DRIVE_PINGROUP_AT1,
+ TEGRA_DRIVE_PINGROUP_AT2,
+ TEGRA_DRIVE_PINGROUP_CDEV1,
+ TEGRA_DRIVE_PINGROUP_CDEV2,
+ TEGRA_DRIVE_PINGROUP_CSUS,
+ TEGRA_DRIVE_PINGROUP_DAP1,
+ TEGRA_DRIVE_PINGROUP_DAP2,
+ TEGRA_DRIVE_PINGROUP_DAP3,
+ TEGRA_DRIVE_PINGROUP_DAP4,
+ TEGRA_DRIVE_PINGROUP_DBG,
+ TEGRA_DRIVE_PINGROUP_LCD1,
+ TEGRA_DRIVE_PINGROUP_LCD2,
+ TEGRA_DRIVE_PINGROUP_SDMMC2,
+ TEGRA_DRIVE_PINGROUP_SDMMC3,
+ TEGRA_DRIVE_PINGROUP_SPI,
+ TEGRA_DRIVE_PINGROUP_UAA,
+ TEGRA_DRIVE_PINGROUP_UAB,
+ TEGRA_DRIVE_PINGROUP_UART2,
+ TEGRA_DRIVE_PINGROUP_UART3,
+ TEGRA_DRIVE_PINGROUP_VI1,
+ TEGRA_DRIVE_PINGROUP_VI2,
+ TEGRA_DRIVE_PINGROUP_XM2A,
+ TEGRA_DRIVE_PINGROUP_XM2C,
+ TEGRA_DRIVE_PINGROUP_XM2D,
+ TEGRA_DRIVE_PINGROUP_XM2CLK,
+ TEGRA_DRIVE_PINGROUP_MEMCOMP,
+ TEGRA_MAX_DRIVE_PINGROUP,
+};
+
+#endif
+
diff --git a/arch/arm/mach-tegra/include/mach/pinmux.h b/arch/arm/mach-tegra/include/mach/pinmux.h
index 41c8ce5b7c27..defd8775defa 100644
--- a/arch/arm/mach-tegra/include/mach/pinmux.h
+++ b/arch/arm/mach-tegra/include/mach/pinmux.h
@@ -17,126 +17,11 @@
#ifndef __MACH_TEGRA_PINMUX_H
#define __MACH_TEGRA_PINMUX_H
-enum tegra_pingroup {
- TEGRA_PINGROUP_ATA = 0,
- TEGRA_PINGROUP_ATB,
- TEGRA_PINGROUP_ATC,
- TEGRA_PINGROUP_ATD,
- TEGRA_PINGROUP_ATE,
- TEGRA_PINGROUP_CDEV1,
- TEGRA_PINGROUP_CDEV2,
- TEGRA_PINGROUP_CRTP,
- TEGRA_PINGROUP_CSUS,
- TEGRA_PINGROUP_DAP1,
- TEGRA_PINGROUP_DAP2,
- TEGRA_PINGROUP_DAP3,
- TEGRA_PINGROUP_DAP4,
- TEGRA_PINGROUP_DDC,
- TEGRA_PINGROUP_DTA,
- TEGRA_PINGROUP_DTB,
- TEGRA_PINGROUP_DTC,
- TEGRA_PINGROUP_DTD,
- TEGRA_PINGROUP_DTE,
- TEGRA_PINGROUP_DTF,
- TEGRA_PINGROUP_GMA,
- TEGRA_PINGROUP_GMB,
- TEGRA_PINGROUP_GMC,
- TEGRA_PINGROUP_GMD,
- TEGRA_PINGROUP_GME,
- TEGRA_PINGROUP_GPU,
- TEGRA_PINGROUP_GPU7,
- TEGRA_PINGROUP_GPV,
- TEGRA_PINGROUP_HDINT,
- TEGRA_PINGROUP_I2CP,
- TEGRA_PINGROUP_IRRX,
- TEGRA_PINGROUP_IRTX,
- TEGRA_PINGROUP_KBCA,
- TEGRA_PINGROUP_KBCB,
- TEGRA_PINGROUP_KBCC,
- TEGRA_PINGROUP_KBCD,
- TEGRA_PINGROUP_KBCE,
- TEGRA_PINGROUP_KBCF,
- TEGRA_PINGROUP_LCSN,
- TEGRA_PINGROUP_LD0,
- TEGRA_PINGROUP_LD1,
- TEGRA_PINGROUP_LD10,
- TEGRA_PINGROUP_LD11,
- TEGRA_PINGROUP_LD12,
- TEGRA_PINGROUP_LD13,
- TEGRA_PINGROUP_LD14,
- TEGRA_PINGROUP_LD15,
- TEGRA_PINGROUP_LD16,
- TEGRA_PINGROUP_LD17,
- TEGRA_PINGROUP_LD2,
- TEGRA_PINGROUP_LD3,
- TEGRA_PINGROUP_LD4,
- TEGRA_PINGROUP_LD5,
- TEGRA_PINGROUP_LD6,
- TEGRA_PINGROUP_LD7,
- TEGRA_PINGROUP_LD8,
- TEGRA_PINGROUP_LD9,
- TEGRA_PINGROUP_LDC,
- TEGRA_PINGROUP_LDI,
- TEGRA_PINGROUP_LHP0,
- TEGRA_PINGROUP_LHP1,
- TEGRA_PINGROUP_LHP2,
- TEGRA_PINGROUP_LHS,
- TEGRA_PINGROUP_LM0,
- TEGRA_PINGROUP_LM1,
- TEGRA_PINGROUP_LPP,
- TEGRA_PINGROUP_LPW0,
- TEGRA_PINGROUP_LPW1,
- TEGRA_PINGROUP_LPW2,
- TEGRA_PINGROUP_LSC0,
- TEGRA_PINGROUP_LSC1,
- TEGRA_PINGROUP_LSCK,
- TEGRA_PINGROUP_LSDA,
- TEGRA_PINGROUP_LSDI,
- TEGRA_PINGROUP_LSPI,
- TEGRA_PINGROUP_LVP0,
- TEGRA_PINGROUP_LVP1,
- TEGRA_PINGROUP_LVS,
- TEGRA_PINGROUP_OWC,
- TEGRA_PINGROUP_PMC,
- TEGRA_PINGROUP_PTA,
- TEGRA_PINGROUP_RM,
- TEGRA_PINGROUP_SDB,
- TEGRA_PINGROUP_SDC,
- TEGRA_PINGROUP_SDD,
- TEGRA_PINGROUP_SDIO1,
- TEGRA_PINGROUP_SLXA,
- TEGRA_PINGROUP_SLXC,
- TEGRA_PINGROUP_SLXD,
- TEGRA_PINGROUP_SLXK,
- TEGRA_PINGROUP_SPDI,
- TEGRA_PINGROUP_SPDO,
- TEGRA_PINGROUP_SPIA,
- TEGRA_PINGROUP_SPIB,
- TEGRA_PINGROUP_SPIC,
- TEGRA_PINGROUP_SPID,
- TEGRA_PINGROUP_SPIE,
- TEGRA_PINGROUP_SPIF,
- TEGRA_PINGROUP_SPIG,
- TEGRA_PINGROUP_SPIH,
- TEGRA_PINGROUP_UAA,
- TEGRA_PINGROUP_UAB,
- TEGRA_PINGROUP_UAC,
- TEGRA_PINGROUP_UAD,
- TEGRA_PINGROUP_UCA,
- TEGRA_PINGROUP_UCB,
- TEGRA_PINGROUP_UDA,
- /* these pin groups only have pullup and pull down control */
- TEGRA_PINGROUP_CK32,
- TEGRA_PINGROUP_DDRC,
- TEGRA_PINGROUP_PMCA,
- TEGRA_PINGROUP_PMCB,
- TEGRA_PINGROUP_PMCC,
- TEGRA_PINGROUP_PMCD,
- TEGRA_PINGROUP_PMCE,
- TEGRA_PINGROUP_XM2C,
- TEGRA_PINGROUP_XM2D,
- TEGRA_MAX_PINGROUP,
-};
+#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
+#include "pinmux-t2.h"
+#else
+#error "Undefined Tegra architecture"
+#endif
enum tegra_mux_func {
TEGRA_MUX_RSVD = 0x8000,
@@ -205,6 +90,7 @@ enum tegra_mux_func {
TEGRA_MUX_VI,
TEGRA_MUX_VI_SENSOR_CLK,
TEGRA_MUX_XIO,
+ TEGRA_MUX_SAFE,
TEGRA_MAX_MUX,
};
@@ -219,6 +105,18 @@ enum tegra_tristate {
TEGRA_TRI_TRISTATE = 1,
};
+enum tegra_vddio {
+ TEGRA_VDDIO_BB = 0,
+ TEGRA_VDDIO_LCD,
+ TEGRA_VDDIO_VI,
+ TEGRA_VDDIO_UART,
+ TEGRA_VDDIO_DDR,
+ TEGRA_VDDIO_NAND,
+ TEGRA_VDDIO_SYS,
+ TEGRA_VDDIO_AUDIO,
+ TEGRA_VDDIO_SD,
+};
+
struct tegra_pingroup_config {
enum tegra_pingroup pingroup;
enum tegra_mux_func func;
@@ -270,38 +168,6 @@ enum tegra_pull_strength {
TEGRA_MAX_PULL,
};
-enum tegra_drive_pingroup {
- TEGRA_DRIVE_PINGROUP_AO1 = 0,
- TEGRA_DRIVE_PINGROUP_AO2,
- TEGRA_DRIVE_PINGROUP_AT1,
- TEGRA_DRIVE_PINGROUP_AT2,
- TEGRA_DRIVE_PINGROUP_CDEV1,
- TEGRA_DRIVE_PINGROUP_CDEV2,
- TEGRA_DRIVE_PINGROUP_CSUS,
- TEGRA_DRIVE_PINGROUP_DAP1,
- TEGRA_DRIVE_PINGROUP_DAP2,
- TEGRA_DRIVE_PINGROUP_DAP3,
- TEGRA_DRIVE_PINGROUP_DAP4,
- TEGRA_DRIVE_PINGROUP_DBG,
- TEGRA_DRIVE_PINGROUP_LCD1,
- TEGRA_DRIVE_PINGROUP_LCD2,
- TEGRA_DRIVE_PINGROUP_SDMMC2,
- TEGRA_DRIVE_PINGROUP_SDMMC3,
- TEGRA_DRIVE_PINGROUP_SPI,
- TEGRA_DRIVE_PINGROUP_UAA,
- TEGRA_DRIVE_PINGROUP_UAB,
- TEGRA_DRIVE_PINGROUP_UART2,
- TEGRA_DRIVE_PINGROUP_UART3,
- TEGRA_DRIVE_PINGROUP_VI1,
- TEGRA_DRIVE_PINGROUP_VI2,
- TEGRA_DRIVE_PINGROUP_XM2A,
- TEGRA_DRIVE_PINGROUP_XM2C,
- TEGRA_DRIVE_PINGROUP_XM2D,
- TEGRA_DRIVE_PINGROUP_XM2CLK,
- TEGRA_DRIVE_PINGROUP_MEMCOMP,
- TEGRA_MAX_DRIVE_PINGROUP,
-};
-
enum tegra_drive {
TEGRA_DRIVE_DIV_8 = 0,
TEGRA_DRIVE_DIV_4,
@@ -331,18 +197,44 @@ struct tegra_drive_pingroup_config {
enum tegra_slew slew_falling;
};
-int tegra_pinmux_set_func(enum tegra_pingroup pg, enum tegra_mux_func func);
-int tegra_pinmux_set_tristate(enum tegra_pingroup pg, enum tegra_tristate tristate);
-int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg, enum tegra_pullupdown pupd);
+struct tegra_drive_pingroup_desc {
+ const char *name;
+ s16 reg;
+};
+
+struct tegra_pingroup_desc {
+ const char *name;
+ int funcs[4];
+ int func_safe;
+ int vddio;
+ s16 tri_reg; /* offset into the TRISTATE_REG_* register bank */
+ s16 mux_reg; /* offset into the PIN_MUX_CTL_* register bank */
+ s16 pupd_reg; /* offset into the PULL_UPDOWN_REG_* register bank */
+ s8 tri_bit; /* offset into the TRISTATE_REG_* register bit */
+ s8 mux_bit; /* offset into the PIN_MUX_CTL_* register bit */
+ s8 pupd_bit; /* offset into the PULL_UPDOWN_REG_* register bit */
+};
+
+extern const struct tegra_pingroup_desc tegra_soc_pingroups[];
+extern const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[];
-void tegra_pinmux_config_pingroup(enum tegra_pingroup pingroup,
- enum tegra_mux_func func, enum tegra_pullupdown pupd,
+int tegra_pinmux_set_tristate(enum tegra_pingroup pg,
enum tegra_tristate tristate);
+int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg,
+ enum tegra_pullupdown pupd);
-void tegra_pinmux_config_table(struct tegra_pingroup_config *config, int len);
+void tegra_pinmux_config_table(const struct tegra_pingroup_config *config,
+ int len);
void tegra_drive_pinmux_config_table(struct tegra_drive_pingroup_config *config,
int len);
-
+void tegra_pinmux_set_safe_pinmux_table(const struct tegra_pingroup_config *config,
+ int len);
+void tegra_pinmux_config_pinmux_table(const struct tegra_pingroup_config *config,
+ int len);
+void tegra_pinmux_config_tristate_table(const struct tegra_pingroup_config *config,
+ int len, enum tegra_tristate tristate);
+void tegra_pinmux_config_pullupdown_table(const struct tegra_pingroup_config *config,
+ int len, enum tegra_pullupdown pupd);
#endif
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-tegra/io.c b/arch/arm/mach-tegra/io.c
index 9fe2c5c683d4..31848a9592f8 100644
--- a/arch/arm/mach-tegra/io.c
+++ b/arch/arm/mach-tegra/io.c
@@ -49,6 +49,12 @@ static struct map_desc tegra_io_desc[] __initdata = {
.length = IO_CPU_SIZE,
.type = MT_DEVICE,
},
+ {
+ .virtual = IO_IRAM_VIRT,
+ .pfn = __phys_to_pfn(IO_IRAM_PHYS),
+ .length = IO_IRAM_SIZE,
+ .type = MT_DEVICE,
+ },
};
void __init tegra_map_common_io(void)
diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
index 1fdbe708d43d..50a8dfb9a0cf 100644
--- a/arch/arm/mach-tegra/irq.c
+++ b/arch/arm/mach-tegra/irq.c
@@ -4,6 +4,8 @@
* Author:
* Colin Cross <ccross@google.com>
*
+ * Copyright (C) 2010, NVIDIA Corporation
+ *
* 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.
@@ -27,8 +29,143 @@
#include "board.h"
+#define INT_SYS_NR (INT_GPIO_BASE - INT_PRI_BASE)
+#define INT_SYS_SZ (INT_SEC_BASE - INT_PRI_BASE)
+#define PPI_NR ((INT_SYS_NR+INT_SYS_SZ-1)/INT_SYS_SZ)
+
+#define APBDMA_IRQ_STA_CPU 0x14
+#define APBDMA_IRQ_MASK_SET 0x20
+#define APBDMA_IRQ_MASK_CLR 0x24
+
+#define ICTLR_CPU_IER 0x20
+#define ICTLR_CPU_IER_SET 0x24
+#define ICTLR_CPU_IER_CLR 0x28
+#define ICTLR_CPU_IEP_CLASS 0x2c
+#define ICTLR_COP_IER 0x30
+#define ICTLR_COP_IER_SET 0x34
+#define ICTLR_COP_IER_CLR 0x38
+#define ICTLR_COP_IEP_CLASS 0x3c
+
+static void (*gic_mask_irq)(unsigned int irq);
+static void (*gic_unmask_irq)(unsigned int irq);
+
+#define irq_to_ictlr(irq) (((irq)-32) >> 5)
+static void __iomem *tegra_ictlr_base = IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE);
+#define ictlr_to_virt(ictlr) (tegra_ictlr_base + (ictlr)*0x100)
+
+static void tegra_mask(unsigned int irq)
+{
+ void __iomem *addr = ictlr_to_virt(irq_to_ictlr(irq));
+ gic_mask_irq(irq);
+ writel(1<<(irq&31), addr+ICTLR_CPU_IER_CLR);
+}
+
+static void tegra_unmask(unsigned int irq)
+{
+ void __iomem *addr = ictlr_to_virt(irq_to_ictlr(irq));
+ gic_unmask_irq(irq);
+ writel(1<<(irq&31), addr+ICTLR_CPU_IER_SET);
+}
+
+#ifdef CONFIG_PM
+
+static int tegra_set_wake(unsigned int irq, unsigned int on)
+{
+ return 0;
+}
+#endif
+
+static struct irq_chip tegra_irq = {
+ .name = "PPI",
+ .mask = tegra_mask,
+ .unmask = tegra_unmask,
+#ifdef CONFIG_PM
+ .set_wake = tegra_set_wake,
+#endif
+};
+
void __init tegra_init_irq(void)
{
+ struct irq_chip *gic;
+ unsigned int i;
+
+ for (i = 0; i < PPI_NR; i++) {
+ writel(~0, ictlr_to_virt(i) + ICTLR_CPU_IER_CLR);
+ writel(0, ictlr_to_virt(i) + ICTLR_CPU_IEP_CLASS);
+ }
+
gic_dist_init(0, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE), 29);
gic_cpu_init(0, IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100));
+
+ gic = get_irq_chip(29);
+ gic_unmask_irq = gic->unmask;
+ gic_mask_irq = gic->mask;
+ tegra_irq.ack = gic->ack;
+#ifdef CONFIG_SMP
+ tegra_irq.set_affinity = gic->set_affinity;
+#endif
+
+ for (i = INT_PRI_BASE; i < INT_GPIO_BASE; i++) {
+ set_irq_chip(i, &tegra_irq);
+ set_irq_handler(i, handle_level_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+}
+
+#ifdef CONFIG_PM
+static u32 cop_ier[PPI_NR];
+static u32 cpu_ier[PPI_NR];
+static u32 cpu_iep[PPI_NR];
+
+void tegra_irq_suspend(void)
+{
+ unsigned long flags;
+ int i;
+
+ for (i = INT_PRI_BASE; i < INT_GPIO_BASE; i++) {
+ struct irq_desc *desc = irq_to_desc(i);
+ if (!desc)
+ continue;
+ if (desc->status & IRQ_WAKEUP) {
+ pr_debug("irq %d is wakeup\n", i);
+ continue;
+ }
+ disable_irq(i);
+ }
+
+ local_irq_save(flags);
+ for (i = 0; i < PPI_NR; i++) {
+ void __iomem *ictlr = ictlr_to_virt(i);
+ cpu_ier[i] = readl(ictlr + ICTLR_CPU_IER);
+ cpu_iep[i] = readl(ictlr + ICTLR_CPU_IEP_CLASS);
+ cop_ier[i] = readl(ictlr + ICTLR_COP_IER);
+ writel(~0, ictlr + ICTLR_COP_IER_CLR);
+ }
+ local_irq_restore(flags);
+}
+
+void tegra_irq_resume(void)
+{
+ unsigned long flags;
+ int i;
+
+ local_irq_save(flags);
+ for (i = 0; i < PPI_NR; i++) {
+ void __iomem *ictlr = ictlr_to_virt(i);
+ writel(cpu_iep[i], ictlr + ICTLR_CPU_IEP_CLASS);
+ writel(~0ul, ictlr + ICTLR_CPU_IER_CLR);
+ writel(cpu_ier[i], ictlr + ICTLR_CPU_IER_SET);
+ writel(0, ictlr + ICTLR_COP_IEP_CLASS);
+ writel(~0ul, ictlr + ICTLR_COP_IER_CLR);
+ writel(cop_ier[i], ictlr + ICTLR_COP_IER_SET);
+ }
+ local_irq_restore(flags);
+
+ for (i = INT_PRI_BASE; i < INT_GPIO_BASE; i++) {
+ struct irq_desc *desc = irq_to_desc(i);
+ if (!desc || (desc->status & IRQ_WAKEUP))
+ continue;
+ enable_irq(i);
+ }
}
+#endif
diff --git a/arch/arm/mach-tegra/legacy_irq.c b/arch/arm/mach-tegra/legacy_irq.c
new file mode 100644
index 000000000000..7cc8601c19ff
--- /dev/null
+++ b/arch/arm/mach-tegra/legacy_irq.c
@@ -0,0 +1,114 @@
+/*
+ * arch/arm/mach-tegra/legacy_irq.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ * Author: Colin Cross <ccross@android.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 <linux/io.h>
+#include <linux/kernel.h>
+#include <mach/iomap.h>
+#include <mach/legacy_irq.h>
+
+#define ICTLR_CPU_IER 0x20
+#define ICTLR_CPU_IER_SET 0x24
+#define ICTLR_CPU_IER_CLR 0x28
+#define ICTLR_CPU_IEP_CLASS 0x2C
+#define ICTLR_CPU_IEP_VFIQ 0x08
+#define ICTLR_CPU_IEP_FIR 0x14
+#define ICTLR_CPU_IEP_FIR_SET 0x18
+#define ICTLR_CPU_IEP_FIR_CLR 0x1c
+
+static void __iomem *ictlr_reg_base[] = {
+ IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE),
+ IO_ADDRESS(TEGRA_SECONDARY_ICTLR_BASE),
+ IO_ADDRESS(TEGRA_TERTIARY_ICTLR_BASE),
+ IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE),
+};
+
+/* When going into deep sleep, the CPU is powered down, taking the GIC with it
+ In order to wake, the wake interrupts need to be enabled in the legacy
+ interrupt controller. */
+void tegra_legacy_unmask_irq(unsigned int irq)
+{
+ void __iomem *base;
+ pr_debug("%s: %d\n", __func__, irq);
+
+ irq -= 32;
+ base = ictlr_reg_base[irq>>5];
+ writel(1 << (irq & 31), base + ICTLR_CPU_IER_SET);
+}
+
+void tegra_legacy_mask_irq(unsigned int irq)
+{
+ void __iomem *base;
+ pr_debug("%s: %d\n", __func__, irq);
+
+ irq -= 32;
+ base = ictlr_reg_base[irq>>5];
+ writel(1 << (irq & 31), base + ICTLR_CPU_IER_CLR);
+}
+
+void tegra_legacy_force_irq_set(unsigned int irq)
+{
+ void __iomem *base;
+ pr_debug("%s: %d\n", __func__, irq);
+
+ irq -= 32;
+ base = ictlr_reg_base[irq>>5];
+ writel(1 << (irq & 31), base + ICTLR_CPU_IEP_FIR_SET);
+}
+
+void tegra_legacy_force_irq_clr(unsigned int irq)
+{
+ void __iomem *base;
+ pr_debug("%s: %d\n", __func__, irq);
+
+ irq -= 32;
+ base = ictlr_reg_base[irq>>5];
+ writel(1 << (irq & 31), base + ICTLR_CPU_IEP_FIR_CLR);
+}
+
+int tegra_legacy_force_irq_status(unsigned int irq)
+{
+ void __iomem *base;
+ pr_debug("%s: %d\n", __func__, irq);
+
+ irq -= 32;
+ base = ictlr_reg_base[irq>>5];
+ return !!(readl(base + ICTLR_CPU_IEP_FIR) & (1 << (irq & 31)));
+}
+
+void tegra_legacy_select_fiq(unsigned int irq, bool fiq)
+{
+ void __iomem *base;
+ pr_debug("%s: %d\n", __func__, irq);
+
+ irq -= 32;
+ base = ictlr_reg_base[irq>>5];
+ writel(fiq << (irq & 31), base + ICTLR_CPU_IEP_CLASS);
+}
+
+unsigned long tegra_legacy_vfiq(int nr)
+{
+ void __iomem *base;
+ base = ictlr_reg_base[nr];
+ return readl(base + ICTLR_CPU_IEP_VFIQ);
+}
+
+unsigned long tegra_legacy_class(int nr)
+{
+ void __iomem *base;
+ base = ictlr_reg_base[nr];
+ return readl(base + ICTLR_CPU_IEP_CLASS);
+}
diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c
new file mode 100644
index 000000000000..53f5fa37014a
--- /dev/null
+++ b/arch/arm/mach-tegra/pcie.c
@@ -0,0 +1,915 @@
+/*
+ * arch/arm/mach-tegra/pci.c
+ *
+ * PCIe host controller driver for TEGRA(2) SOCs
+ *
+ * Copyright (c) 2010, CompuLab, Ltd.
+ * Author: Mike Rapoport <mike@compulab.co.il>
+ *
+ * Based on NVIDIA PCIe driver
+ * Copyright (c) 2008-2009, NVIDIA Corporation.
+ *
+ * Bits taken from arch/arm/mach-dove/pcie.c
+ *
+ * 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/pci.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+
+#include <asm/sizes.h>
+#include <asm/mach/pci.h>
+
+#include <mach/pinmux.h>
+#include <mach/iomap.h>
+#include <mach/clk.h>
+
+/* register definitions */
+#define AFI_OFFSET 0x3800
+#define PADS_OFFSET 0x3000
+#define RP0_OFFSET 0x0000
+#define RP1_OFFSET 0x1000
+
+#define AFI_AXI_BAR0_SZ 0x00
+#define AFI_AXI_BAR1_SZ 0x04
+#define AFI_AXI_BAR2_SZ 0x08
+#define AFI_AXI_BAR3_SZ 0x0c
+#define AFI_AXI_BAR4_SZ 0x10
+#define AFI_AXI_BAR5_SZ 0x14
+
+#define AFI_AXI_BAR0_START 0x18
+#define AFI_AXI_BAR1_START 0x1c
+#define AFI_AXI_BAR2_START 0x20
+#define AFI_AXI_BAR3_START 0x24
+#define AFI_AXI_BAR4_START 0x28
+#define AFI_AXI_BAR5_START 0x2c
+
+#define AFI_FPCI_BAR0 0x30
+#define AFI_FPCI_BAR1 0x34
+#define AFI_FPCI_BAR2 0x38
+#define AFI_FPCI_BAR3 0x3c
+#define AFI_FPCI_BAR4 0x40
+#define AFI_FPCI_BAR5 0x44
+
+#define AFI_CACHE_BAR0_SZ 0x48
+#define AFI_CACHE_BAR0_ST 0x4c
+#define AFI_CACHE_BAR1_SZ 0x50
+#define AFI_CACHE_BAR1_ST 0x54
+
+#define AFI_MSI_BAR_SZ 0x60
+#define AFI_MSI_FPCI_BAR_ST 0x64
+#define AFI_MSI_AXI_BAR_ST 0x68
+
+#define AFI_CONFIGURATION 0xac
+#define AFI_CONFIGURATION_EN_FPCI (1 << 0)
+
+#define AFI_FPCI_ERROR_MASKS 0xb0
+
+#define AFI_INTR_MASK 0xb4
+#define AFI_INTR_MASK_INT_MASK (1 << 0)
+#define AFI_INTR_MASK_MSI_MASK (1 << 8)
+
+#define AFI_INTR_CODE 0xb8
+#define AFI_INTR_CODE_MASK 0xf
+#define AFI_INTR_MASTER_ABORT 4
+#define AFI_INTR_LEGACY 6
+
+#define AFI_INTR_SIGNATURE 0xbc
+#define AFI_SM_INTR_ENABLE 0xc4
+
+#define AFI_AFI_INTR_ENABLE 0xc8
+#define AFI_INTR_EN_INI_SLVERR (1 << 0)
+#define AFI_INTR_EN_INI_DECERR (1 << 1)
+#define AFI_INTR_EN_TGT_SLVERR (1 << 2)
+#define AFI_INTR_EN_TGT_DECERR (1 << 3)
+#define AFI_INTR_EN_TGT_WRERR (1 << 4)
+#define AFI_INTR_EN_DFPCI_DECERR (1 << 5)
+#define AFI_INTR_EN_AXI_DECERR (1 << 6)
+#define AFI_INTR_EN_FPCI_TIMEOUT (1 << 7)
+
+#define AFI_PCIE_CONFIG 0x0f8
+#define AFI_PCIE_CONFIG_PCIEC0_DISABLE_DEVICE (1 << 1)
+#define AFI_PCIE_CONFIG_PCIEC1_DISABLE_DEVICE (1 << 2)
+#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK (0xf << 20)
+#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_SINGLE (0x0 << 20)
+#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL (0x1 << 20)
+
+#define AFI_FUSE 0x104
+#define AFI_FUSE_PCIE_T0_GEN2_DIS (1 << 2)
+
+#define AFI_PEX0_CTRL 0x110
+#define AFI_PEX1_CTRL 0x118
+#define AFI_PEX_CTRL_RST (1 << 0)
+#define AFI_PEX_CTRL_REFCLK_EN (1 << 3)
+
+#define RP_VEND_XP 0x00000F00
+#define RP_VEND_XP_DL_UP (1 << 30)
+
+#define RP_LINK_CONTROL_STATUS 0x00000090
+#define RP_LINK_CONTROL_STATUS_LINKSTAT_MASK 0x3fff0000
+
+#define PADS_CTL_SEL 0x0000009C
+
+#define PADS_CTL 0x000000A0
+#define PADS_CTL_IDDQ_1L (1 << 0)
+#define PADS_CTL_TX_DATA_EN_1L (1 << 6)
+#define PADS_CTL_RX_DATA_EN_1L (1 << 10)
+
+#define PADS_PLL_CTL 0x000000B8
+#define PADS_PLL_CTL_RST_B4SM (1 << 1)
+#define PADS_PLL_CTL_LOCKDET (1 << 8)
+#define PADS_PLL_CTL_REFCLK_MASK (0x3 << 16)
+#define PADS_PLL_CTL_REFCLK_INTERNAL_CML (0 << 16)
+#define PADS_PLL_CTL_REFCLK_INTERNAL_CMOS (1 << 16)
+#define PADS_PLL_CTL_REFCLK_EXTERNAL (2 << 16)
+#define PADS_PLL_CTL_TXCLKREF_MASK (0x1 << 20)
+#define PADS_PLL_CTL_TXCLKREF_DIV10 (0 << 20)
+#define PADS_PLL_CTL_TXCLKREF_DIV5 (1 << 20)
+
+/* PMC access is required for PCIE xclk (un)clamping */
+#define PMC_SCRATCH42 0x144
+#define PMC_SCRATCH42_PCX_CLAMP (1 << 0)
+
+static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
+
+#define pmc_writel(value, reg) \
+ __raw_writel(value, (u32)reg_pmc_base + (reg))
+#define pmc_readl(reg) \
+ __raw_readl((u32)reg_pmc_base + (reg))
+
+/*
+ * Tegra2 defines 1GB in the AXI address map for PCIe.
+ *
+ * That address space is split into different regions, with sizes and
+ * offsets as follows:
+ *
+ * 0x80000000 - 0x80003fff - PCI controller registers
+ * 0x80004000 - 0x80103fff - PCI configuration space
+ * 0x80104000 - 0x80203fff - PCI extended configuration space
+ * 0x80203fff - 0x803fffff - unused
+ * 0x80400000 - 0x8040ffff - downstream IO
+ * 0x80410000 - 0x8fffffff - unused
+ * 0x90000000 - 0x9fffffff - non-prefetchable memory
+ * 0xa0000000 - 0xbfffffff - prefetchable memory
+ */
+#define TEGRA_PCIE_BASE 0x80000000
+
+#define PCIE_REGS_SZ SZ_16K
+#define PCIE_CFG_OFF PCIE_REGS_SZ
+#define PCIE_CFG_SZ SZ_1M
+#define PCIE_EXT_CFG_OFF (PCIE_CFG_SZ + PCIE_CFG_OFF)
+#define PCIE_EXT_CFG_SZ SZ_1M
+#define PCIE_IOMAP_SZ (PCIE_REGS_SZ + PCIE_CFG_SZ + PCIE_EXT_CFG_SZ)
+
+#define MMIO_BASE (TEGRA_PCIE_BASE + SZ_4M)
+#define MMIO_SIZE SZ_64K
+#define MEM_BASE_0 (TEGRA_PCIE_BASE + SZ_256M)
+#define MEM_SIZE_0 SZ_128M
+#define MEM_BASE_1 (MEM_BASE_0 + MEM_SIZE_0)
+#define MEM_SIZE_1 SZ_128M
+#define PREFETCH_MEM_BASE_0 (MEM_BASE_1 + MEM_SIZE_1)
+#define PREFETCH_MEM_SIZE_0 SZ_128M
+#define PREFETCH_MEM_BASE_1 (PREFETCH_MEM_BASE_0 + PREFETCH_MEM_SIZE_0)
+#define PREFETCH_MEM_SIZE_1 SZ_128M
+
+#define PCIE_CONF_BUS(b) ((b) << 16)
+#define PCIE_CONF_DEV(d) ((d) << 11)
+#define PCIE_CONF_FUNC(f) ((f) << 8)
+#define PCIE_CONF_REG(r) \
+ (((r) & ~0x3) | (((r) < 256) ? PCIE_CFG_OFF : PCIE_EXT_CFG_OFF))
+
+struct tegra_pcie_port {
+ int index;
+ u8 root_bus_nr;
+ void __iomem *base;
+
+ bool link_up;
+
+ char io_space_name[16];
+ char mem_space_name[16];
+ char prefetch_space_name[20];
+ struct resource res[3];
+};
+
+struct tegra_pcie_info {
+ struct tegra_pcie_port port[2];
+ int num_ports;
+
+ void __iomem *regs;
+ struct resource res_mmio;
+
+ struct clk *pex_clk;
+ struct clk *afi_clk;
+ struct clk *pcie_xclk;
+ struct clk *pll_e;
+};
+
+static struct tegra_pcie_info tegra_pcie = {
+ .res_mmio = {
+ .name = "PCI IO",
+ .start = MMIO_BASE,
+ .end = MMIO_BASE + MMIO_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+void __iomem *tegra_pcie_io_base;
+EXPORT_SYMBOL(tegra_pcie_io_base);
+
+static inline void afi_writel(u32 value, unsigned long offset)
+{
+ writel(value, offset + AFI_OFFSET + tegra_pcie.regs);
+}
+
+static inline u32 afi_readl(unsigned long offset)
+{
+ return readl(offset + AFI_OFFSET + tegra_pcie.regs);
+}
+
+static inline void pads_writel(u32 value, unsigned long offset)
+{
+ writel(value, offset + PADS_OFFSET + tegra_pcie.regs);
+}
+
+static inline u32 pads_readl(unsigned long offset)
+{
+ return readl(offset + PADS_OFFSET + tegra_pcie.regs);
+}
+
+static struct tegra_pcie_port *bus_to_port(int bus)
+{
+ int i;
+
+ for (i = tegra_pcie.num_ports - 1; i >= 0; i--) {
+ int rbus = tegra_pcie.port[i].root_bus_nr;
+ if (rbus != -1 && rbus == bus)
+ break;
+ }
+
+ return i >= 0 ? tegra_pcie.port + i : NULL;
+}
+
+static int tegra_pcie_read_conf(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *val)
+{
+ struct tegra_pcie_port *pp = bus_to_port(bus->number);
+ void __iomem *addr;
+
+ if (pp) {
+ if (devfn != 0) {
+ *val = 0xffffffff;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ addr = pp->base + (where & ~0x3);
+ } else {
+ addr = tegra_pcie.regs + (PCIE_CONF_BUS(bus->number) +
+ PCIE_CONF_DEV(PCI_SLOT(devfn)) +
+ PCIE_CONF_FUNC(PCI_FUNC(devfn)) +
+ PCIE_CONF_REG(where));
+ }
+
+ *val = readl(addr);
+
+ if (size == 1)
+ *val = (*val >> (8 * (where & 3))) & 0xff;
+ else if (size == 2)
+ *val = (*val >> (8 * (where & 3))) & 0xffff;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int tegra_pcie_write_conf(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ struct tegra_pcie_port *pp = bus_to_port(bus->number);
+ void __iomem *addr;
+
+ u32 mask;
+ u32 tmp;
+
+ if (pp) {
+ if (devfn != 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ addr = pp->base + (where & ~0x3);
+ } else {
+ addr = tegra_pcie.regs + (PCIE_CONF_BUS(bus->number) +
+ PCIE_CONF_DEV(PCI_SLOT(devfn)) +
+ PCIE_CONF_FUNC(PCI_FUNC(devfn)) +
+ PCIE_CONF_REG(where));
+ }
+
+ if (size == 4) {
+ writel(val, addr);
+ return PCIBIOS_SUCCESSFUL;
+ }
+
+ if (size == 2)
+ mask = ~(0xffff << ((where & 0x3) * 8));
+ else if (size == 1)
+ mask = ~(0xff << ((where & 0x3) * 8));
+ else
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ tmp = readl(addr) & mask;
+ tmp |= val << ((where & 0x3) * 8);
+ writel(tmp, addr);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops tegra_pcie_ops = {
+ .read = tegra_pcie_read_conf,
+ .write = tegra_pcie_write_conf,
+};
+
+static void __devinit tegra_pcie_fixup_bridge(struct pci_dev *dev)
+{
+ u16 reg;
+
+ if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) {
+ pci_read_config_word(dev, PCI_COMMAND, &reg);
+ reg |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER | PCI_COMMAND_SERR);
+ pci_write_config_word(dev, PCI_COMMAND, reg);
+ }
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_fixup_bridge);
+
+/* Tegra PCIE root complex wrongly reports device class */
+static void __devinit tegra_pcie_fixup_class(struct pci_dev *dev)
+{
+ dev->class = PCI_CLASS_BRIDGE_PCI << 8;
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0bf0, tegra_pcie_fixup_class);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_fixup_class);
+
+/* Tegra PCIE requires relaxed ordering */
+static void __devinit tegra_pcie_relax_enable(struct pci_dev *dev)
+{
+ u16 val16;
+ int pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+
+ if (pos <= 0) {
+ dev_err(&dev->dev, "skipping relaxed ordering fixup\n");
+ return;
+ }
+
+ pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &val16);
+ val16 |= PCI_EXP_DEVCTL_RELAX_EN;
+ pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, val16);
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable);
+
+static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
+{
+ struct tegra_pcie_port *pp;
+
+ if (nr >= tegra_pcie.num_ports)
+ return 0;
+
+ pp = tegra_pcie.port + nr;
+ pp->root_bus_nr = sys->busnr;
+
+ /*
+ * IORESOURCE_IO
+ */
+ snprintf(pp->io_space_name, sizeof(pp->io_space_name),
+ "PCIe %d I/O", pp->index);
+ pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0;
+ pp->res[0].name = pp->io_space_name;
+ if (pp->index == 0) {
+ pp->res[0].start = PCIBIOS_MIN_IO;
+ pp->res[0].end = pp->res[0].start + SZ_32K - 1;
+ } else {
+ pp->res[0].start = PCIBIOS_MIN_IO + SZ_32K;
+ pp->res[0].end = IO_SPACE_LIMIT;
+ }
+ pp->res[0].flags = IORESOURCE_IO;
+ if (request_resource(&ioport_resource, &pp->res[0]))
+ panic("Request PCIe IO resource failed\n");
+ sys->resource[0] = &pp->res[0];
+
+ /*
+ * IORESOURCE_MEM
+ */
+ snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
+ "PCIe %d MEM", pp->index);
+ pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
+ pp->res[1].name = pp->mem_space_name;
+ if (pp->index == 0) {
+ pp->res[1].start = MEM_BASE_0;
+ pp->res[1].end = pp->res[1].start + MEM_SIZE_0 - 1;
+ } else {
+ pp->res[1].start = MEM_BASE_1;
+ pp->res[1].end = pp->res[1].start + MEM_SIZE_1 - 1;
+ }
+ pp->res[1].flags = IORESOURCE_MEM;
+ if (request_resource(&iomem_resource, &pp->res[1]))
+ panic("Request PCIe Memory resource failed\n");
+ sys->resource[1] = &pp->res[1];
+
+ /*
+ * IORESOURCE_MEM | IORESOURCE_PREFETCH
+ */
+ snprintf(pp->prefetch_space_name, sizeof(pp->prefetch_space_name),
+ "PCIe %d PREFETCH MEM", pp->index);
+ pp->prefetch_space_name[sizeof(pp->prefetch_space_name) - 1] = 0;
+ pp->res[2].name = pp->prefetch_space_name;
+ if (pp->index == 0) {
+ pp->res[2].start = PREFETCH_MEM_BASE_0;
+ pp->res[2].end = pp->res[2].start + PREFETCH_MEM_SIZE_0 - 1;
+ } else {
+ pp->res[2].start = PREFETCH_MEM_BASE_1;
+ pp->res[2].end = pp->res[2].start + PREFETCH_MEM_SIZE_1 - 1;
+ }
+ pp->res[2].flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
+ if (request_resource(&iomem_resource, &pp->res[2]))
+ panic("Request PCIe Prefetch Memory resource failed\n");
+ sys->resource[2] = &pp->res[2];
+
+ return 1;
+}
+
+static int tegra_pcie_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return INT_PCIE_INTR;
+}
+
+static struct pci_bus __init *tegra_pcie_scan_bus(int nr,
+ struct pci_sys_data *sys)
+{
+ struct tegra_pcie_port *pp;
+
+ if (nr >= tegra_pcie.num_ports)
+ return 0;
+
+ pp = tegra_pcie.port + nr;
+ pp->root_bus_nr = sys->busnr;
+
+ return pci_scan_bus(sys->busnr, &tegra_pcie_ops, sys);
+}
+
+static struct hw_pci tegra_pcie_hw __initdata = {
+ .nr_controllers = 2,
+ .setup = tegra_pcie_setup,
+ .scan = tegra_pcie_scan_bus,
+ .swizzle = pci_std_swizzle,
+ .map_irq = tegra_pcie_map_irq,
+};
+
+
+static irqreturn_t tegra_pcie_isr(int irq, void *arg)
+{
+ const char *err_msg[] = {
+ "Unknown",
+ "AXI slave error",
+ "AXI decode error",
+ "Target abort",
+ "Master abort",
+ "Invalid write",
+ "Response decoding error",
+ "AXI response decoding error",
+ "Transcation timeout",
+ };
+
+ u32 code, signature;
+
+ code = afi_readl(AFI_INTR_CODE) & AFI_INTR_CODE_MASK;
+ signature = afi_readl(AFI_INTR_SIGNATURE);
+ afi_writel(0, AFI_INTR_CODE);
+
+ if (code == AFI_INTR_LEGACY)
+ return IRQ_NONE;
+
+ if (code >= ARRAY_SIZE(err_msg))
+ code = 0;
+
+ /*
+ * do not pollute kernel log with master abort reports since they
+ * happen a lot during enumeration
+ */
+ if (code == AFI_INTR_MASTER_ABORT)
+ pr_debug("PCIE: %s, signature: %08x\n", err_msg[code], signature);
+ else
+ pr_err("PCIE: %s, signature: %08x\n", err_msg[code], signature);
+
+ return IRQ_HANDLED;
+}
+
+static void tegra_pcie_setup_translations(void)
+{
+ u32 fpci_bar;
+ u32 size;
+ u32 axi_address;
+
+ /* Bar 0: config Bar */
+ fpci_bar = ((u32)0xfdff << 16);
+ size = PCIE_CFG_SZ;
+ axi_address = TEGRA_PCIE_BASE + PCIE_CFG_OFF;
+ afi_writel(axi_address, AFI_AXI_BAR0_START);
+ afi_writel(size >> 12, AFI_AXI_BAR0_SZ);
+ afi_writel(fpci_bar, AFI_FPCI_BAR0);
+
+ /* Bar 1: extended config Bar */
+ fpci_bar = ((u32)0xfe1 << 20);
+ size = PCIE_EXT_CFG_SZ;
+ axi_address = TEGRA_PCIE_BASE + PCIE_EXT_CFG_OFF;
+ afi_writel(axi_address, AFI_AXI_BAR1_START);
+ afi_writel(size >> 12, AFI_AXI_BAR1_SZ);
+ afi_writel(fpci_bar, AFI_FPCI_BAR1);
+
+ /* Bar 2: downstream IO bar */
+ fpci_bar = ((__u32)0xfdfc << 16);
+ size = MMIO_SIZE;
+ axi_address = MMIO_BASE;
+ afi_writel(axi_address, AFI_AXI_BAR2_START);
+ afi_writel(size >> 12, AFI_AXI_BAR2_SZ);
+ afi_writel(fpci_bar, AFI_FPCI_BAR2);
+
+ /* Bar 3: prefetchable memory BAR */
+ fpci_bar = (((PREFETCH_MEM_BASE_0 >> 12) & 0x0fffffff) << 4) | 0x1;
+ size = PREFETCH_MEM_SIZE_0 + PREFETCH_MEM_SIZE_1;
+ axi_address = PREFETCH_MEM_BASE_0;
+ afi_writel(axi_address, AFI_AXI_BAR3_START);
+ afi_writel(size >> 12, AFI_AXI_BAR3_SZ);
+ afi_writel(fpci_bar, AFI_FPCI_BAR3);
+
+ /* Bar 4: non prefetchable memory BAR */
+ fpci_bar = (((MEM_BASE_0 >> 12) & 0x0FFFFFFF) << 4) | 0x1;
+ size = MEM_SIZE_0 + MEM_SIZE_1;
+ axi_address = MEM_BASE_0;
+ afi_writel(axi_address, AFI_AXI_BAR4_START);
+ afi_writel(size >> 12, AFI_AXI_BAR4_SZ);
+ afi_writel(fpci_bar, AFI_FPCI_BAR4);
+
+ /* Bar 5: NULL out the remaining BAR as it is not used */
+ fpci_bar = 0;
+ size = 0;
+ axi_address = 0;
+ afi_writel(axi_address, AFI_AXI_BAR5_START);
+ afi_writel(size >> 12, AFI_AXI_BAR5_SZ);
+ afi_writel(fpci_bar, AFI_FPCI_BAR5);
+
+ /* map all upstream transactions as uncached */
+ afi_writel(PHYS_OFFSET, AFI_CACHE_BAR0_ST);
+ afi_writel(0, AFI_CACHE_BAR0_SZ);
+ afi_writel(0, AFI_CACHE_BAR1_ST);
+ afi_writel(0, AFI_CACHE_BAR1_SZ);
+
+ /* No MSI */
+ afi_writel(0, AFI_MSI_FPCI_BAR_ST);
+ afi_writel(0, AFI_MSI_BAR_SZ);
+ afi_writel(0, AFI_MSI_AXI_BAR_ST);
+ afi_writel(0, AFI_MSI_BAR_SZ);
+}
+
+static void tegra_pcie_enable_controller(void)
+{
+ u32 val, reg;
+ int i;
+
+ /* Enable slot clock and pulse the reset signals */
+ for (i = 0, reg = AFI_PEX0_CTRL; i < 2; i++, reg += 0x8) {
+ val = afi_readl(reg) | AFI_PEX_CTRL_REFCLK_EN;
+ afi_writel(val, reg);
+ val &= ~AFI_PEX_CTRL_RST;
+ afi_writel(val, reg);
+
+ val = afi_readl(reg) | AFI_PEX_CTRL_RST;
+ afi_writel(val, reg);
+ }
+
+ /* Enable dual controller and both ports */
+ val = afi_readl(AFI_PCIE_CONFIG);
+ val &= ~(AFI_PCIE_CONFIG_PCIEC0_DISABLE_DEVICE |
+ AFI_PCIE_CONFIG_PCIEC1_DISABLE_DEVICE |
+ AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK);
+ val |= AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL;
+ afi_writel(val, AFI_PCIE_CONFIG);
+
+ val = afi_readl(AFI_FUSE) & ~AFI_FUSE_PCIE_T0_GEN2_DIS;
+ afi_writel(val, AFI_FUSE);
+
+ /* Initialze internal PHY, enable up to 16 PCIE lanes */
+ pads_writel(0x0, PADS_CTL_SEL);
+
+ /* override IDDQ to 1 on all 4 lanes */
+ val = pads_readl(PADS_CTL) | PADS_CTL_IDDQ_1L;
+ pads_writel(val, PADS_CTL);
+
+ /*
+ * set up PHY PLL inputs select PLLE output as refclock,
+ * set TX ref sel to div10 (not div5)
+ */
+ val = pads_readl(PADS_PLL_CTL);
+ val &= ~(PADS_PLL_CTL_REFCLK_MASK | PADS_PLL_CTL_TXCLKREF_MASK);
+ val |= (PADS_PLL_CTL_REFCLK_INTERNAL_CML | PADS_PLL_CTL_TXCLKREF_DIV10);
+ pads_writel(val, PADS_PLL_CTL);
+
+ /* take PLL out of reset */
+ val = pads_readl(PADS_PLL_CTL) | PADS_PLL_CTL_RST_B4SM;
+ pads_writel(val, PADS_PLL_CTL);
+
+ /*
+ * Hack, set the clock voltage to the DEFAULT provided by hw folks.
+ * This doesn't exist in the documentation
+ */
+ pads_writel(0xfa5cfa5c, 0xc8);
+
+ /* Wait for the PLL to lock */
+ do {
+ val = pads_readl(PADS_PLL_CTL);
+ } while (!(val & PADS_PLL_CTL_LOCKDET));
+
+ /* turn off IDDQ override */
+ val = pads_readl(PADS_CTL) & ~PADS_CTL_IDDQ_1L;
+ pads_writel(val, PADS_CTL);
+
+ /* enable TX/RX data */
+ val = pads_readl(PADS_CTL);
+ val |= (PADS_CTL_TX_DATA_EN_1L | PADS_CTL_RX_DATA_EN_1L);
+ pads_writel(val, PADS_CTL);
+
+ /* Take the PCIe interface module out of reset */
+ tegra_periph_reset_deassert(tegra_pcie.pcie_xclk);
+
+ /* Finally enable PCIe */
+ val = afi_readl(AFI_CONFIGURATION) | AFI_CONFIGURATION_EN_FPCI;
+ afi_writel(val, AFI_CONFIGURATION);
+
+ val = (AFI_INTR_EN_INI_SLVERR | AFI_INTR_EN_INI_DECERR |
+ AFI_INTR_EN_TGT_SLVERR | AFI_INTR_EN_TGT_DECERR |
+ AFI_INTR_EN_TGT_WRERR | AFI_INTR_EN_DFPCI_DECERR);
+ afi_writel(val, AFI_AFI_INTR_ENABLE);
+ afi_writel(0xffffffff, AFI_SM_INTR_ENABLE);
+
+ /* FIXME: No MSI for now, only INT */
+ afi_writel(AFI_INTR_MASK_INT_MASK, AFI_INTR_MASK);
+
+ /* Disable all execptions */
+ afi_writel(0, AFI_FPCI_ERROR_MASKS);
+
+ return;
+}
+
+static void tegra_pcie_xclk_clamp(bool clamp)
+{
+ u32 reg;
+
+ reg = pmc_readl(PMC_SCRATCH42) & ~PMC_SCRATCH42_PCX_CLAMP;
+
+ if (clamp)
+ reg |= PMC_SCRATCH42_PCX_CLAMP;
+
+ pmc_writel(reg, PMC_SCRATCH42);
+}
+
+static int tegra_pcie_power_on(void)
+{
+ tegra_pcie_xclk_clamp(true);
+ tegra_periph_reset_assert(tegra_pcie.pcie_xclk);
+ tegra_pcie_xclk_clamp(false);
+
+ clk_enable(tegra_pcie.afi_clk);
+ clk_enable(tegra_pcie.pex_clk);
+ return clk_enable(tegra_pcie.pll_e);
+}
+
+static void tegra_pcie_power_off(void)
+{
+ tegra_periph_reset_assert(tegra_pcie.pcie_xclk);
+ tegra_periph_reset_assert(tegra_pcie.afi_clk);
+ tegra_periph_reset_assert(tegra_pcie.pex_clk);
+
+ tegra_pcie_xclk_clamp(true);
+}
+
+static int tegra_pcie_clocks_get(void)
+{
+ int err;
+
+ tegra_pcie.pex_clk = clk_get(NULL, "pex");
+ if (IS_ERR(tegra_pcie.pex_clk))
+ return PTR_ERR(tegra_pcie.pex_clk);
+
+ tegra_pcie.afi_clk = clk_get(NULL, "afi");
+ if (IS_ERR(tegra_pcie.afi_clk)) {
+ err = PTR_ERR(tegra_pcie.afi_clk);
+ goto err_afi_clk;
+ }
+
+ tegra_pcie.pcie_xclk = clk_get(NULL, "pcie_xclk");
+ if (IS_ERR(tegra_pcie.pcie_xclk)) {
+ err = PTR_ERR(tegra_pcie.pcie_xclk);
+ goto err_pcie_xclk;
+ }
+
+ tegra_pcie.pll_e = clk_get_sys(NULL, "pll_e");
+ if (IS_ERR(tegra_pcie.pll_e)) {
+ err = PTR_ERR(tegra_pcie.pll_e);
+ goto err_pll_e;
+ }
+
+ return 0;
+
+err_pll_e:
+ clk_put(tegra_pcie.pcie_xclk);
+err_pcie_xclk:
+ clk_put(tegra_pcie.afi_clk);
+err_afi_clk:
+ clk_put(tegra_pcie.pex_clk);
+
+ return err;
+}
+
+static void tegra_pcie_clocks_put(void)
+{
+ clk_put(tegra_pcie.pll_e);
+ clk_put(tegra_pcie.pcie_xclk);
+ clk_put(tegra_pcie.afi_clk);
+ clk_put(tegra_pcie.pex_clk);
+}
+
+static int __init tegra_pcie_get_resources(void)
+{
+ struct resource *res_mmio = &tegra_pcie.res_mmio;
+ int err;
+
+ err = tegra_pcie_clocks_get();
+ if (err) {
+ pr_err("PCIE: failed to get clocks: %d\n", err);
+ return err;
+ }
+
+ err = tegra_pcie_power_on();
+ if (err) {
+ pr_err("PCIE: failed to power up: %d\n", err);
+ goto err_pwr_on;
+ }
+
+ tegra_pcie.regs = ioremap_nocache(TEGRA_PCIE_BASE, PCIE_IOMAP_SZ);
+ if (tegra_pcie.regs == NULL) {
+ pr_err("PCIE: Failed to map PCI/AFI registers\n");
+ err = -ENOMEM;
+ goto err_map_reg;
+ }
+
+ err = request_resource(&iomem_resource, res_mmio);
+ if (err) {
+ pr_err("PCIE: Failed to request resources: %d\n", err);
+ goto err_req_io;
+ }
+
+ tegra_pcie_io_base = ioremap_nocache(res_mmio->start,
+ resource_size(res_mmio));
+ if (tegra_pcie_io_base == NULL) {
+ pr_err("PCIE: Failed to map IO\n");
+ err = -ENOMEM;
+ goto err_map_io;
+ }
+
+ err = request_irq(INT_PCIE_INTR, tegra_pcie_isr,
+ IRQF_SHARED, "PCIE", &tegra_pcie);
+ if (err) {
+ pr_err("PCIE: Failed to register IRQ: %d\n", err);
+ goto err_irq;
+ }
+ set_irq_flags(INT_PCIE_INTR, IRQF_VALID);
+
+ return 0;
+
+err_irq:
+ iounmap(tegra_pcie_io_base);
+err_map_io:
+ release_resource(&tegra_pcie.res_mmio);
+err_req_io:
+ iounmap(tegra_pcie.regs);
+err_map_reg:
+ tegra_pcie_power_off();
+err_pwr_on:
+ tegra_pcie_clocks_put();
+
+ return err;
+}
+
+/*
+ * FIXME: If there are no PCIe cards attached, then calling this function
+ * can result in the increase of the bootup time as there are big timeout
+ * loops.
+ */
+#define TEGRA_PCIE_LINKUP_TIMEOUT 200 /* up to 1.2 seconds */
+static bool tegra_pcie_check_link(struct tegra_pcie_port *pp, int idx,
+ u32 reset_reg)
+{
+ u32 reg;
+ int retries = 3;
+ int timeout;
+
+ do {
+ timeout = TEGRA_PCIE_LINKUP_TIMEOUT;
+ while (timeout) {
+ reg = readl(pp->base + RP_VEND_XP);
+
+ if (reg & RP_VEND_XP_DL_UP)
+ break;
+
+ mdelay(1);
+ timeout--;
+ }
+
+ if (!timeout) {
+ pr_err("PCIE: port %d: link down, retrying\n", idx);
+ goto retry;
+ }
+
+ timeout = TEGRA_PCIE_LINKUP_TIMEOUT;
+ while (timeout) {
+ reg = readl(pp->base + RP_LINK_CONTROL_STATUS);
+
+ if (reg & 0x20000000)
+ return true;
+
+ mdelay(1);
+ timeout--;
+ }
+
+retry:
+ /* Pulse the PEX reset */
+ reg = afi_readl(reset_reg) | AFI_PEX_CTRL_RST;
+ afi_writel(reg, reset_reg);
+ mdelay(1);
+ reg = afi_readl(reset_reg) & ~AFI_PEX_CTRL_RST;
+ afi_writel(reg, reset_reg);
+
+ retries--;
+ } while (retries);
+
+ return false;
+}
+
+static void __init tegra_pcie_add_port(int index, u32 offset, u32 reset_reg)
+{
+ struct tegra_pcie_port *pp;
+
+ pp = tegra_pcie.port + tegra_pcie.num_ports;
+
+ pp->index = -1;
+ pp->base = tegra_pcie.regs + offset;
+ pp->link_up = tegra_pcie_check_link(pp, index, reset_reg);
+
+ if (!pp->link_up) {
+ pp->base = NULL;
+ printk(KERN_INFO "PCIE: port %d: link down, ignoring\n", index);
+ return;
+ }
+
+ tegra_pcie.num_ports++;
+ pp->index = index;
+ pp->root_bus_nr = -1;
+ memset(pp->res, 0, sizeof(pp->res));
+}
+
+int __init tegra_pcie_init(bool init_port0, bool init_port1)
+{
+ int err;
+
+ if (!(init_port0 || init_port1))
+ return -ENODEV;
+
+ err = tegra_pcie_get_resources();
+ if (err)
+ return err;
+
+ tegra_pcie_enable_controller();
+
+ /* setup the AFI address translations */
+ tegra_pcie_setup_translations();
+
+ if (init_port0)
+ tegra_pcie_add_port(0, RP0_OFFSET, AFI_PEX0_CTRL);
+
+ if (init_port1)
+ tegra_pcie_add_port(1, RP1_OFFSET, AFI_PEX1_CTRL);
+
+ pci_common_init(&tegra_pcie_hw);
+
+ return 0;
+}
diff --git a/arch/arm/mach-tegra/pinmux-t2-tables.c b/arch/arm/mach-tegra/pinmux-t2-tables.c
new file mode 100644
index 000000000000..a6ea34e782dc
--- /dev/null
+++ b/arch/arm/mach-tegra/pinmux-t2-tables.c
@@ -0,0 +1,260 @@
+/*
+ * linux/arch/arm/mach-tegra/pinmux-t2-tables.c
+ *
+ * Common pinmux configurations for Tegra 2 SoCs
+ *
+ * Copyright (C) 2010 NVIDIA Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <mach/iomap.h>
+#include <mach/pinmux.h>
+
+#define DRIVE_PINGROUP(pg_name, r) \
+ [TEGRA_DRIVE_PINGROUP_ ## pg_name] = { \
+ .name = #pg_name, \
+ .reg = r \
+ }
+
+const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE_PINGROUP] = {
+ DRIVE_PINGROUP(AO1, 0x868),
+ DRIVE_PINGROUP(AO2, 0x86c),
+ DRIVE_PINGROUP(AT1, 0x870),
+ DRIVE_PINGROUP(AT2, 0x874),
+ DRIVE_PINGROUP(CDEV1, 0x878),
+ DRIVE_PINGROUP(CDEV2, 0x87c),
+ DRIVE_PINGROUP(CSUS, 0x880),
+ DRIVE_PINGROUP(DAP1, 0x884),
+ DRIVE_PINGROUP(DAP2, 0x888),
+ DRIVE_PINGROUP(DAP3, 0x88c),
+ DRIVE_PINGROUP(DAP4, 0x890),
+ DRIVE_PINGROUP(DBG, 0x894),
+ DRIVE_PINGROUP(LCD1, 0x898),
+ DRIVE_PINGROUP(LCD2, 0x89c),
+ DRIVE_PINGROUP(SDMMC2, 0x8a0),
+ DRIVE_PINGROUP(SDMMC3, 0x8a4),
+ DRIVE_PINGROUP(SPI, 0x8a8),
+ DRIVE_PINGROUP(UAA, 0x8ac),
+ DRIVE_PINGROUP(UAB, 0x8b0),
+ DRIVE_PINGROUP(UART2, 0x8b4),
+ DRIVE_PINGROUP(UART3, 0x8b8),
+ DRIVE_PINGROUP(VI1, 0x8bc),
+ DRIVE_PINGROUP(VI2, 0x8c0),
+ DRIVE_PINGROUP(XM2A, 0x8c4),
+ DRIVE_PINGROUP(XM2C, 0x8c8),
+ DRIVE_PINGROUP(XM2D, 0x8cc),
+ DRIVE_PINGROUP(XM2CLK, 0x8d0),
+ DRIVE_PINGROUP(MEMCOMP, 0x8d4),
+};
+
+#define PINGROUP(pg_name, vdd, f0, f1, f2, f3, f_safe, \
+ tri_r, tri_b, mux_r, mux_b, pupd_r, pupd_b) \
+ [TEGRA_PINGROUP_ ## pg_name] = { \
+ .name = #pg_name, \
+ .vddio = TEGRA_VDDIO_ ## vdd, \
+ .funcs = { \
+ TEGRA_MUX_ ## f0, \
+ TEGRA_MUX_ ## f1, \
+ TEGRA_MUX_ ## f2, \
+ TEGRA_MUX_ ## f3, \
+ }, \
+ .func_safe = TEGRA_MUX_ ## f_safe, \
+ .tri_reg = tri_r, \
+ .tri_bit = tri_b, \
+ .mux_reg = mux_r, \
+ .mux_bit = mux_b, \
+ .pupd_reg = pupd_r, \
+ .pupd_bit = pupd_b, \
+ }
+
+const struct tegra_pingroup_desc tegra_soc_pingroups[TEGRA_MAX_PINGROUP] = {
+ PINGROUP(ATA, NAND, IDE, NAND, GMI, RSVD, IDE, 0x14, 0, 0x80, 24, 0xA0, 0),
+ PINGROUP(ATB, NAND, IDE, NAND, GMI, SDIO4, IDE, 0x14, 1, 0x80, 16, 0xA0, 2),
+ PINGROUP(ATC, NAND, IDE, NAND, GMI, SDIO4, IDE, 0x14, 2, 0x80, 22, 0xA0, 4),
+ PINGROUP(ATD, NAND, IDE, NAND, GMI, SDIO4, IDE, 0x14, 3, 0x80, 20, 0xA0, 6),
+ PINGROUP(ATE, NAND, IDE, NAND, GMI, RSVD, IDE, 0x18, 25, 0x80, 12, 0xA0, 8),
+ PINGROUP(CDEV1, AUDIO, OSC, PLLA_OUT, PLLM_OUT1, AUDIO_SYNC, OSC, 0x14, 4, 0x88, 2, 0xA8, 0),
+ PINGROUP(CDEV2, AUDIO, OSC, AHB_CLK, APB_CLK, PLLP_OUT4, OSC, 0x14, 5, 0x88, 4, 0xA8, 2),
+ PINGROUP(CRTP, LCD, CRT, RSVD, RSVD, RSVD, RSVD, 0x20, 14, 0x98, 20, 0xA4, 24),
+ PINGROUP(CSUS, VI, PLLC_OUT1, PLLP_OUT2, PLLP_OUT3, VI_SENSOR_CLK, PLLC_OUT1, 0x14, 6, 0x88, 6, 0xAC, 24),
+ PINGROUP(DAP1, AUDIO, DAP1, RSVD, GMI, SDIO2, DAP1, 0x14, 7, 0x88, 20, 0xA0, 10),
+ PINGROUP(DAP2, AUDIO, DAP2, TWC, RSVD, GMI, DAP2, 0x14, 8, 0x88, 22, 0xA0, 12),
+ PINGROUP(DAP3, BB, DAP3, RSVD, RSVD, RSVD, DAP3, 0x14, 9, 0x88, 24, 0xA0, 14),
+ PINGROUP(DAP4, UART, DAP4, RSVD, GMI, RSVD, DAP4, 0x14, 10, 0x88, 26, 0xA0, 16),
+ PINGROUP(DDC, LCD, I2C2, RSVD, RSVD, RSVD, RSVD4, 0x18, 31, 0x88, 0, 0xB0, 28),
+ PINGROUP(DTA, VI, RSVD, SDIO2, VI, RSVD, RSVD4, 0x14, 11, 0x84, 20, 0xA0, 18),
+ PINGROUP(DTB, VI, RSVD, RSVD, VI, SPI1, RSVD1, 0x14, 12, 0x84, 22, 0xA0, 20),
+ PINGROUP(DTC, VI, RSVD, RSVD, VI, RSVD, RSVD1, 0x14, 13, 0x84, 26, 0xA0, 22),
+ PINGROUP(DTD, VI, RSVD, SDIO2, VI, RSVD, RSVD1, 0x14, 14, 0x84, 28, 0xA0, 24),
+ PINGROUP(DTE, VI, RSVD, RSVD, VI, SPI1, RSVD1, 0x14, 15, 0x84, 30, 0xA0, 26),
+ PINGROUP(DTF, VI, I2C3, RSVD, VI, RSVD, RSVD4, 0x20, 12, 0x98, 30, 0xA0, 28),
+ PINGROUP(GMA, NAND, UARTE, SPI3, GMI, SDIO4, SPI3, 0x14, 28, 0x84, 0, 0xB0, 20),
+ PINGROUP(GMB, NAND, IDE, NAND, GMI, GMI_INT, GMI, 0x18, 29, 0x88, 28, 0xB0, 22),
+ PINGROUP(GMC, NAND, UARTD, SPI4, GMI, SFLASH, SPI4, 0x14, 29, 0x84, 2, 0xB0, 24),
+ PINGROUP(GMD, NAND, RSVD, NAND, GMI, SFLASH, GMI, 0x18, 30, 0x88, 30, 0xB0, 26),
+ PINGROUP(GME, NAND, RSVD, DAP5, GMI, SDIO4, GMI, 0x18, 0, 0x8C, 0, 0xA8, 24),
+ PINGROUP(GPU, UART, PWM, UARTA, GMI, RSVD, RSVD4, 0x14, 16, 0x8C, 4, 0xA4, 20),
+ PINGROUP(GPU7, SYS, RTCK, RSVD, RSVD, RSVD, RTCK, 0x20, 11, 0x98, 28, 0xA4, 6),
+ PINGROUP(GPV, SD, PCIE, RSVD, RSVD, RSVD, PCIE, 0x14, 17, 0x8C, 2, 0xA0, 30),
+ PINGROUP(HDINT, LCD, HDMI, RSVD, RSVD, RSVD, HDMI, 0x1C, 23, 0x84, 4, 0xAC, 22),
+ PINGROUP(I2CP, SYS, I2C, RSVD, RSVD, RSVD, RSVD4, 0x14, 18, 0x88, 8, 0xA4, 2),
+ PINGROUP(IRRX, UART, UARTA, UARTB, GMI, SPI4, UARTB, 0x14, 20, 0x88, 18, 0xA8, 22),
+ PINGROUP(IRTX, UART, UARTA, UARTB, GMI, SPI4, UARTB, 0x14, 19, 0x88, 16, 0xA8, 20),
+ PINGROUP(KBCA, SYS, KBC, NAND, SDIO2, EMC_TEST0_DLL, KBC, 0x14, 22, 0x88, 10, 0xA4, 8),
+ PINGROUP(KBCB, SYS, KBC, NAND, SDIO2, MIO, KBC, 0x14, 21, 0x88, 12, 0xA4, 10),
+ PINGROUP(KBCC, SYS, KBC, NAND, TRACE, EMC_TEST1_DLL, KBC, 0x18, 26, 0x88, 14, 0xA4, 12),
+ PINGROUP(KBCD, SYS, KBC, NAND, SDIO2, MIO, KBC, 0x20, 10, 0x98, 26, 0xA4, 14),
+ PINGROUP(KBCE, SYS, KBC, NAND, OWR, RSVD, KBC, 0x14, 26, 0x80, 28, 0xB0, 2),
+ PINGROUP(KBCF, SYS, KBC, NAND, TRACE, MIO, KBC, 0x14, 27, 0x80, 26, 0xB0, 0),
+ PINGROUP(LCSN, LCD, DISPLAYA, DISPLAYB, SPI3, RSVD, RSVD4, 0x1C, 31, 0x90, 12, 0xAC, 20),
+ PINGROUP(LD0, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 0, 0x94, 0, 0xAC, 12),
+ PINGROUP(LD1, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 1, 0x94, 2, 0xAC, 12),
+ PINGROUP(LD10, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 10, 0x94, 20, 0xAC, 12),
+ PINGROUP(LD11, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 11, 0x94, 22, 0xAC, 12),
+ PINGROUP(LD12, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 12, 0x94, 24, 0xAC, 12),
+ PINGROUP(LD13, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 13, 0x94, 26, 0xAC, 12),
+ PINGROUP(LD14, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 14, 0x94, 28, 0xAC, 12),
+ PINGROUP(LD15, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 15, 0x94, 30, 0xAC, 12),
+ PINGROUP(LD16, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 16, 0x98, 0, 0xAC, 12),
+ PINGROUP(LD17, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x1C, 17, 0x98, 2, 0xAC, 12),
+ PINGROUP(LD2, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 2, 0x94, 4, 0xAC, 12),
+ PINGROUP(LD3, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 3, 0x94, 6, 0xAC, 12),
+ PINGROUP(LD4, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 4, 0x94, 8, 0xAC, 12),
+ PINGROUP(LD5, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 5, 0x94, 10, 0xAC, 12),
+ PINGROUP(LD6, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 6, 0x94, 12, 0xAC, 12),
+ PINGROUP(LD7, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 7, 0x94, 14, 0xAC, 12),
+ PINGROUP(LD8, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 8, 0x94, 16, 0xAC, 12),
+ PINGROUP(LD9, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 9, 0x94, 18, 0xAC, 12),
+ PINGROUP(LDC, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x1C, 30, 0x90, 14, 0xAC, 20),
+ PINGROUP(LDI, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x20, 6, 0x98, 16, 0xAC, 18),
+ PINGROUP(LHP0, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x1C, 18, 0x98, 10, 0xAC, 16),
+ PINGROUP(LHP1, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x1C, 19, 0x98, 4, 0xAC, 14),
+ PINGROUP(LHP2, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x1C, 20, 0x98, 6, 0xAC, 14),
+ PINGROUP(LHS, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x20, 7, 0x90, 22, 0xAC, 22),
+ PINGROUP(LM0, LCD, DISPLAYA, DISPLAYB, SPI3, RSVD, RSVD4, 0x1C, 24, 0x90, 26, 0xAC, 22),
+ PINGROUP(LM1, LCD, DISPLAYA, DISPLAYB, RSVD, CRT, RSVD3, 0x1C, 25, 0x90, 28, 0xAC, 22),
+ PINGROUP(LPP, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x20, 8, 0x98, 14, 0xAC, 18),
+ PINGROUP(LPW0, LCD, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x20, 3, 0x90, 0, 0xAC, 20),
+ PINGROUP(LPW1, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x20, 4, 0x90, 2, 0xAC, 20),
+ PINGROUP(LPW2, LCD, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x20, 5, 0x90, 4, 0xAC, 20),
+ PINGROUP(LSC0, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 27, 0x90, 18, 0xAC, 22),
+ PINGROUP(LSC1, LCD, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x1C, 28, 0x90, 20, 0xAC, 20),
+ PINGROUP(LSCK, LCD, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x1C, 29, 0x90, 16, 0xAC, 20),
+ PINGROUP(LSDA, LCD, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x20, 1, 0x90, 8, 0xAC, 20),
+ PINGROUP(LSDI, LCD, DISPLAYA, DISPLAYB, SPI3, RSVD, DISPLAYA, 0x20, 2, 0x90, 6, 0xAC, 20),
+ PINGROUP(LSPI, LCD, DISPLAYA, DISPLAYB, XIO, HDMI, DISPLAYA, 0x20, 0, 0x90, 10, 0xAC, 22),
+ PINGROUP(LVP0, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x1C, 21, 0x90, 30, 0xAC, 22),
+ PINGROUP(LVP1, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x1C, 22, 0x98, 8, 0xAC, 16),
+ PINGROUP(LVS, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 26, 0x90, 24, 0xAC, 22),
+ PINGROUP(OWC, SYS, OWR, RSVD, RSVD, RSVD, OWR, 0x14, 31, 0x84, 8, 0xB0, 30),
+ PINGROUP(PMC, SYS, PWR_ON, PWR_INTR, RSVD, RSVD, PWR_ON, 0x14, 23, 0x98, 18, -1, -1),
+ PINGROUP(PTA, NAND, I2C2, HDMI, GMI, RSVD, RSVD4, 0x14, 24, 0x98, 22, 0xA4, 4),
+ PINGROUP(RM, UART, I2C, RSVD, RSVD, RSVD, RSVD4, 0x14, 25, 0x80, 14, 0xA4, 0),
+ PINGROUP(SDB, SD, UARTA, PWM, SDIO3, SPI2, PWM, 0x20, 15, 0x8C, 10, -1, -1),
+ PINGROUP(SDC, SD, PWM, TWC, SDIO3, SPI3, TWC, 0x18, 1, 0x8C, 12, 0xAC, 28),
+ PINGROUP(SDD, SD, UARTA, PWM, SDIO3, SPI3, PWM, 0x18, 2, 0x8C, 14, 0xAC, 30),
+ PINGROUP(SDIO1, BB, SDIO1, RSVD, UARTE, UARTA, RSVD2, 0x14, 30, 0x80, 30, 0xB0, 18),
+ PINGROUP(SLXA, SD, PCIE, SPI4, SDIO3, SPI2, PCIE, 0x18, 3, 0x84, 6, 0xA4, 22),
+ PINGROUP(SLXC, SD, SPDIF, SPI4, SDIO3, SPI2, SPI4, 0x18, 5, 0x84, 10, 0xA4, 26),
+ PINGROUP(SLXD, SD, SPDIF, SPI4, SDIO3, SPI2, SPI4, 0x18, 6, 0x84, 12, 0xA4, 28),
+ PINGROUP(SLXK, SD, PCIE, SPI4, SDIO3, SPI2, PCIE, 0x18, 7, 0x84, 14, 0xA4, 30),
+ PINGROUP(SPDI, AUDIO, SPDIF, RSVD, I2C, SDIO2, RSVD2, 0x18, 8, 0x8C, 8, 0xA4, 16),
+ PINGROUP(SPDO, AUDIO, SPDIF, RSVD, I2C, SDIO2, RSVD2, 0x18, 9, 0x8C, 6, 0xA4, 18),
+ PINGROUP(SPIA, AUDIO, SPI1, SPI2, SPI3, GMI, GMI, 0x18, 10, 0x8C, 30, 0xA8, 4),
+ PINGROUP(SPIB, AUDIO, SPI1, SPI2, SPI3, GMI, GMI, 0x18, 11, 0x8C, 28, 0xA8, 6),
+ PINGROUP(SPIC, AUDIO, SPI1, SPI2, SPI3, GMI, GMI, 0x18, 12, 0x8C, 26, 0xA8, 8),
+ PINGROUP(SPID, AUDIO, SPI2, SPI1, SPI2_ALT, GMI, GMI, 0x18, 13, 0x8C, 24, 0xA8, 10),
+ PINGROUP(SPIE, AUDIO, SPI2, SPI1, SPI2_ALT, GMI, GMI, 0x18, 14, 0x8C, 22, 0xA8, 12),
+ PINGROUP(SPIF, AUDIO, SPI3, SPI1, SPI2, RSVD, RSVD4, 0x18, 15, 0x8C, 20, 0xA8, 14),
+ PINGROUP(SPIG, AUDIO, SPI3, SPI2, SPI2_ALT, I2C, SPI2_ALT, 0x18, 16, 0x8C, 18, 0xA8, 16),
+ PINGROUP(SPIH, AUDIO, SPI3, SPI2, SPI2_ALT, I2C, SPI2_ALT, 0x18, 17, 0x8C, 16, 0xA8, 18),
+ PINGROUP(UAA, BB, SPI3, MIPI_HS, UARTA, ULPI, MIPI_HS, 0x18, 18, 0x80, 0, 0xAC, 0),
+ PINGROUP(UAB, BB, SPI2, MIPI_HS, UARTA, ULPI, MIPI_HS, 0x18, 19, 0x80, 2, 0xAC, 2),
+ PINGROUP(UAC, BB, OWR, RSVD, RSVD, RSVD, RSVD4, 0x18, 20, 0x80, 4, 0xAC, 4),
+ PINGROUP(UAD, UART, IRDA, SPDIF, UARTA, SPI4, SPDIF, 0x18, 21, 0x80, 6, 0xAC, 6),
+ PINGROUP(UCA, UART, UARTC, RSVD, GMI, RSVD, RSVD4, 0x18, 22, 0x84, 16, 0xAC, 8),
+ PINGROUP(UCB, UART, UARTC, PWM, GMI, RSVD, RSVD4, 0x18, 23, 0x84, 18, 0xAC, 10),
+ PINGROUP(UDA, BB, SPI1, RSVD, UARTD, ULPI, RSVD2, 0x20, 13, 0x80, 8, 0xB0, 16),
+ /* these pin groups only have pullup and pull down control */
+ PINGROUP(CK32, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xB0, 14),
+ PINGROUP(DDRC, DDR, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xAC, 26),
+ PINGROUP(PMCA, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xB0, 4),
+ PINGROUP(PMCB, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xB0, 6),
+ PINGROUP(PMCC, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xB0, 8),
+ PINGROUP(PMCD, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xB0, 10),
+ PINGROUP(PMCE, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xB0, 12),
+ PINGROUP(XM2C, DDR, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xA8, 30),
+ PINGROUP(XM2D, DDR, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xA8, 28),
+};
+
+#ifdef CONFIG_PM
+#define TRISTATE_REG_A 0x14
+#define TRISTATE_REG_NUM 4
+#define PIN_MUX_CTL_REG_A 0x80
+#define PIN_MUX_CTL_REG_NUM 8
+#define PULLUPDOWN_REG_A 0xa0
+#define PULLUPDOWN_REG_NUM 5
+
+static u32 pinmux_reg[TRISTATE_REG_NUM + PIN_MUX_CTL_REG_NUM +
+ PULLUPDOWN_REG_NUM];
+
+static inline unsigned long pg_readl(unsigned long offset)
+{
+ return readl(IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset));
+}
+
+static inline void pg_writel(unsigned long value, unsigned long offset)
+{
+ writel(value, IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset));
+}
+
+void tegra_pinmux_suspend(void)
+{
+ unsigned int i;
+ u32 *ctx = pinmux_reg;
+
+ for (i = 0; i < TRISTATE_REG_NUM; i++)
+ *ctx++ = pg_readl(TRISTATE_REG_A + i*4);
+
+ for (i = 0; i < PIN_MUX_CTL_REG_NUM; i++)
+ *ctx++ = pg_readl(PIN_MUX_CTL_REG_A + i*4);
+
+ for (i = 0; i < PULLUPDOWN_REG_NUM; i++)
+ *ctx++ = pg_readl(PULLUPDOWN_REG_A + i*4);
+}
+
+void tegra_pinmux_resume(void)
+{
+ unsigned int i;
+ u32 *ctx = pinmux_reg;
+
+ for (i = 0; i < PIN_MUX_CTL_REG_NUM; i++)
+ pg_writel(*ctx++, PIN_MUX_CTL_REG_A + i*4);
+
+ for (i = 0; i < PULLUPDOWN_REG_NUM; i++)
+ pg_writel(*ctx++, PULLUPDOWN_REG_A + i*4);
+
+ for (i = 0; i < TRISTATE_REG_NUM; i++)
+ pg_writel(*ctx++, TRISTATE_REG_A + i*4);
+}
+#endif
diff --git a/arch/arm/mach-tegra/pinmux.c b/arch/arm/mach-tegra/pinmux.c
index 13ae10237e84..f80d507671bc 100644
--- a/arch/arm/mach-tegra/pinmux.c
+++ b/arch/arm/mach-tegra/pinmux.c
@@ -14,7 +14,8 @@
*
*/
-
+#include <linux/init.h>
+#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/spinlock.h>
@@ -23,21 +24,6 @@
#include <mach/iomap.h>
#include <mach/pinmux.h>
-
-#define TEGRA_TRI_STATE(x) (0x14 + (4 * (x)))
-#define TEGRA_PP_MUX_CTL(x) (0x80 + (4 * (x)))
-#define TEGRA_PP_PU_PD(x) (0xa0 + (4 * (x)))
-
-#define REG_A 0
-#define REG_B 1
-#define REG_C 2
-#define REG_D 3
-#define REG_E 4
-#define REG_F 5
-#define REG_G 6
-
-#define REG_N -1
-
#define HSM_EN(reg) (((reg) >> 2) & 0x1)
#define SCHMT_EN(reg) (((reg) >> 3) & 0x1)
#define LPMD(reg) (((reg) >> 4) & 0x3)
@@ -46,154 +32,8 @@
#define SLWR(reg) (((reg) >> 28) & 0x3)
#define SLWF(reg) (((reg) >> 30) & 0x3)
-struct tegra_pingroup_desc {
- const char *name;
- int funcs[4];
- s8 tri_reg; /* offset into the TRISTATE_REG_* register bank */
- s8 tri_bit; /* offset into the TRISTATE_REG_* register bit */
- s8 mux_reg; /* offset into the PIN_MUX_CTL_* register bank */
- s8 mux_bit; /* offset into the PIN_MUX_CTL_* register bit */
- s8 pupd_reg; /* offset into the PULL_UPDOWN_REG_* register bank */
- s8 pupd_bit; /* offset into the PULL_UPDOWN_REG_* register bit */
-};
-
-#define PINGROUP(pg_name, f0, f1, f2, f3, \
- tri_r, tri_b, mux_r, mux_b, pupd_r, pupd_b) \
- [TEGRA_PINGROUP_ ## pg_name] = { \
- .name = #pg_name, \
- .funcs = { \
- TEGRA_MUX_ ## f0, \
- TEGRA_MUX_ ## f1, \
- TEGRA_MUX_ ## f2, \
- TEGRA_MUX_ ## f3, \
- }, \
- .tri_reg = REG_ ## tri_r, \
- .tri_bit = tri_b, \
- .mux_reg = REG_ ## mux_r, \
- .mux_bit = mux_b, \
- .pupd_reg = REG_ ## pupd_r, \
- .pupd_bit = pupd_b, \
- }
-
-static const struct tegra_pingroup_desc pingroups[TEGRA_MAX_PINGROUP] = {
- PINGROUP(ATA, IDE, NAND, GMI, RSVD, A, 0, A, 24, A, 0),
- PINGROUP(ATB, IDE, NAND, GMI, SDIO4, A, 1, A, 16, A, 2),
- PINGROUP(ATC, IDE, NAND, GMI, SDIO4, A, 2, A, 22, A, 4),
- PINGROUP(ATD, IDE, NAND, GMI, SDIO4, A, 3, A, 20, A, 6),
- PINGROUP(ATE, IDE, NAND, GMI, RSVD, B, 25, A, 12, A, 8),
- PINGROUP(CDEV1, OSC, PLLA_OUT, PLLM_OUT1, AUDIO_SYNC, A, 4, C, 2, C, 0),
- PINGROUP(CDEV2, OSC, AHB_CLK, APB_CLK, PLLP_OUT4, A, 5, C, 4, C, 2),
- PINGROUP(CRTP, CRT, RSVD, RSVD, RSVD, D, 14, G, 20, B, 24),
- PINGROUP(CSUS, PLLC_OUT1, PLLP_OUT2, PLLP_OUT3, VI_SENSOR_CLK, A, 6, C, 6, D, 24),
- PINGROUP(DAP1, DAP1, RSVD, GMI, SDIO2, A, 7, C, 20, A, 10),
- PINGROUP(DAP2, DAP2, TWC, RSVD, GMI, A, 8, C, 22, A, 12),
- PINGROUP(DAP3, DAP3, RSVD, RSVD, RSVD, A, 9, C, 24, A, 14),
- PINGROUP(DAP4, DAP4, RSVD, GMI, RSVD, A, 10, C, 26, A, 16),
- PINGROUP(DDC, I2C2, RSVD, RSVD, RSVD, B, 31, C, 0, E, 28),
- PINGROUP(DTA, RSVD, SDIO2, VI, RSVD, A, 11, B, 20, A, 18),
- PINGROUP(DTB, RSVD, RSVD, VI, SPI1, A, 12, B, 22, A, 20),
- PINGROUP(DTC, RSVD, RSVD, VI, RSVD, A, 13, B, 26, A, 22),
- PINGROUP(DTD, RSVD, SDIO2, VI, RSVD, A, 14, B, 28, A, 24),
- PINGROUP(DTE, RSVD, RSVD, VI, SPI1, A, 15, B, 30, A, 26),
- PINGROUP(DTF, I2C3, RSVD, VI, RSVD, D, 12, G, 30, A, 28),
- PINGROUP(GMA, UARTE, SPI3, GMI, SDIO4, A, 28, B, 0, E, 20),
- PINGROUP(GMB, IDE, NAND, GMI, GMI_INT, B, 29, C, 28, E, 22),
- PINGROUP(GMC, UARTD, SPI4, GMI, SFLASH, A, 29, B, 2, E, 24),
- PINGROUP(GMD, RSVD, NAND, GMI, SFLASH, B, 30, C, 30, E, 26),
- PINGROUP(GME, RSVD, DAP5, GMI, SDIO4, B, 0, D, 0, C, 24),
- PINGROUP(GPU, PWM, UARTA, GMI, RSVD, A, 16, D, 4, B, 20),
- PINGROUP(GPU7, RTCK, RSVD, RSVD, RSVD, D, 11, G, 28, B, 6),
- PINGROUP(GPV, PCIE, RSVD, RSVD, RSVD, A, 17, D, 2, A, 30),
- PINGROUP(HDINT, HDMI, RSVD, RSVD, RSVD, C, 23, B, 4, D, 22),
- PINGROUP(I2CP, I2C, RSVD, RSVD, RSVD, A, 18, C, 8, B, 2),
- PINGROUP(IRRX, UARTA, UARTB, GMI, SPI4, A, 20, C, 18, C, 22),
- PINGROUP(IRTX, UARTA, UARTB, GMI, SPI4, A, 19, C, 16, C, 20),
- PINGROUP(KBCA, KBC, NAND, SDIO2, EMC_TEST0_DLL, A, 22, C, 10, B, 8),
- PINGROUP(KBCB, KBC, NAND, SDIO2, MIO, A, 21, C, 12, B, 10),
- PINGROUP(KBCC, KBC, NAND, TRACE, EMC_TEST1_DLL, B, 26, C, 14, B, 12),
- PINGROUP(KBCD, KBC, NAND, SDIO2, MIO, D, 10, G, 26, B, 14),
- PINGROUP(KBCE, KBC, NAND, OWR, RSVD, A, 26, A, 28, E, 2),
- PINGROUP(KBCF, KBC, NAND, TRACE, MIO, A, 27, A, 26, E, 0),
- PINGROUP(LCSN, DISPLAYA, DISPLAYB, SPI3, RSVD, C, 31, E, 12, D, 20),
- PINGROUP(LD0, DISPLAYA, DISPLAYB, XIO, RSVD, C, 0, F, 0, D, 12),
- PINGROUP(LD1, DISPLAYA, DISPLAYB, XIO, RSVD, C, 1, F, 2, D, 12),
- PINGROUP(LD10, DISPLAYA, DISPLAYB, XIO, RSVD, C, 10, F, 20, D, 12),
- PINGROUP(LD11, DISPLAYA, DISPLAYB, XIO, RSVD, C, 11, F, 22, D, 12),
- PINGROUP(LD12, DISPLAYA, DISPLAYB, XIO, RSVD, C, 12, F, 24, D, 12),
- PINGROUP(LD13, DISPLAYA, DISPLAYB, XIO, RSVD, C, 13, F, 26, D, 12),
- PINGROUP(LD14, DISPLAYA, DISPLAYB, XIO, RSVD, C, 14, F, 28, D, 12),
- PINGROUP(LD15, DISPLAYA, DISPLAYB, XIO, RSVD, C, 15, F, 30, D, 12),
- PINGROUP(LD16, DISPLAYA, DISPLAYB, XIO, RSVD, C, 16, G, 0, D, 12),
- PINGROUP(LD17, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 17, G, 2, D, 12),
- PINGROUP(LD2, DISPLAYA, DISPLAYB, XIO, RSVD, C, 2, F, 4, D, 12),
- PINGROUP(LD3, DISPLAYA, DISPLAYB, XIO, RSVD, C, 3, F, 6, D, 12),
- PINGROUP(LD4, DISPLAYA, DISPLAYB, XIO, RSVD, C, 4, F, 8, D, 12),
- PINGROUP(LD5, DISPLAYA, DISPLAYB, XIO, RSVD, C, 5, F, 10, D, 12),
- PINGROUP(LD6, DISPLAYA, DISPLAYB, XIO, RSVD, C, 6, F, 12, D, 12),
- PINGROUP(LD7, DISPLAYA, DISPLAYB, XIO, RSVD, C, 7, F, 14, D, 12),
- PINGROUP(LD8, DISPLAYA, DISPLAYB, XIO, RSVD, C, 8, F, 16, D, 12),
- PINGROUP(LD9, DISPLAYA, DISPLAYB, XIO, RSVD, C, 9, F, 18, D, 12),
- PINGROUP(LDC, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 30, E, 14, D, 20),
- PINGROUP(LDI, DISPLAYA, DISPLAYB, RSVD, RSVD, D, 6, G, 16, D, 18),
- PINGROUP(LHP0, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 18, G, 10, D, 16),
- PINGROUP(LHP1, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 19, G, 4, D, 14),
- PINGROUP(LHP2, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 20, G, 6, D, 14),
- PINGROUP(LHS, DISPLAYA, DISPLAYB, XIO, RSVD, D, 7, E, 22, D, 22),
- PINGROUP(LM0, DISPLAYA, DISPLAYB, SPI3, RSVD, C, 24, E, 26, D, 22),
- PINGROUP(LM1, DISPLAYA, DISPLAYB, RSVD, CRT, C, 25, E, 28, D, 22),
- PINGROUP(LPP, DISPLAYA, DISPLAYB, RSVD, RSVD, D, 8, G, 14, D, 18),
- PINGROUP(LPW0, DISPLAYA, DISPLAYB, SPI3, HDMI, D, 3, E, 0, D, 20),
- PINGROUP(LPW1, DISPLAYA, DISPLAYB, RSVD, RSVD, D, 4, E, 2, D, 20),
- PINGROUP(LPW2, DISPLAYA, DISPLAYB, SPI3, HDMI, D, 5, E, 4, D, 20),
- PINGROUP(LSC0, DISPLAYA, DISPLAYB, XIO, RSVD, C, 27, E, 18, D, 22),
- PINGROUP(LSC1, DISPLAYA, DISPLAYB, SPI3, HDMI, C, 28, E, 20, D, 20),
- PINGROUP(LSCK, DISPLAYA, DISPLAYB, SPI3, HDMI, C, 29, E, 16, D, 20),
- PINGROUP(LSDA, DISPLAYA, DISPLAYB, SPI3, HDMI, D, 1, E, 8, D, 20),
- PINGROUP(LSDI, DISPLAYA, DISPLAYB, SPI3, RSVD, D, 2, E, 6, D, 20),
- PINGROUP(LSPI, DISPLAYA, DISPLAYB, XIO, HDMI, D, 0, E, 10, D, 22),
- PINGROUP(LVP0, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 21, E, 30, D, 22),
- PINGROUP(LVP1, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 22, G, 8, D, 16),
- PINGROUP(LVS, DISPLAYA, DISPLAYB, XIO, RSVD, C, 26, E, 24, D, 22),
- PINGROUP(OWC, OWR, RSVD, RSVD, RSVD, A, 31, B, 8, E, 30),
- PINGROUP(PMC, PWR_ON, PWR_INTR, RSVD, RSVD, A, 23, G, 18, N, -1),
- PINGROUP(PTA, I2C2, HDMI, GMI, RSVD, A, 24, G, 22, B, 4),
- PINGROUP(RM, I2C, RSVD, RSVD, RSVD, A, 25, A, 14, B, 0),
- PINGROUP(SDB, UARTA, PWM, SDIO3, SPI2, D, 15, D, 10, N, -1),
- PINGROUP(SDC, PWM, TWC, SDIO3, SPI3, B, 1, D, 12, D, 28),
- PINGROUP(SDD, UARTA, PWM, SDIO3, SPI3, B, 2, D, 14, D, 30),
- PINGROUP(SDIO1, SDIO1, RSVD, UARTE, UARTA, A, 30, A, 30, E, 18),
- PINGROUP(SLXA, PCIE, SPI4, SDIO3, SPI2, B, 3, B, 6, B, 22),
- PINGROUP(SLXC, SPDIF, SPI4, SDIO3, SPI2, B, 5, B, 10, B, 26),
- PINGROUP(SLXD, SPDIF, SPI4, SDIO3, SPI2, B, 6, B, 12, B, 28),
- PINGROUP(SLXK, PCIE, SPI4, SDIO3, SPI2, B, 7, B, 14, B, 30),
- PINGROUP(SPDI, SPDIF, RSVD, I2C, SDIO2, B, 8, D, 8, B, 16),
- PINGROUP(SPDO, SPDIF, RSVD, I2C, SDIO2, B, 9, D, 6, B, 18),
- PINGROUP(SPIA, SPI1, SPI2, SPI3, GMI, B, 10, D, 30, C, 4),
- PINGROUP(SPIB, SPI1, SPI2, SPI3, GMI, B, 11, D, 28, C, 6),
- PINGROUP(SPIC, SPI1, SPI2, SPI3, GMI, B, 12, D, 26, C, 8),
- PINGROUP(SPID, SPI2, SPI1, SPI2_ALT, GMI, B, 13, D, 24, C, 10),
- PINGROUP(SPIE, SPI2, SPI1, SPI2_ALT, GMI, B, 14, D, 22, C, 12),
- PINGROUP(SPIF, SPI3, SPI1, SPI2, RSVD, B, 15, D, 20, C, 14),
- PINGROUP(SPIG, SPI3, SPI2, SPI2_ALT, I2C, B, 16, D, 18, C, 16),
- PINGROUP(SPIH, SPI3, SPI2, SPI2_ALT, I2C, B, 17, D, 16, C, 18),
- PINGROUP(UAA, SPI3, MIPI_HS, UARTA, ULPI, B, 18, A, 0, D, 0),
- PINGROUP(UAB, SPI2, MIPI_HS, UARTA, ULPI, B, 19, A, 2, D, 2),
- PINGROUP(UAC, OWR, RSVD, RSVD, RSVD, B, 20, A, 4, D, 4),
- PINGROUP(UAD, IRDA, SPDIF, UARTA, SPI4, B, 21, A, 6, D, 6),
- PINGROUP(UCA, UARTC, RSVD, GMI, RSVD, B, 22, B, 16, D, 8),
- PINGROUP(UCB, UARTC, PWM, GMI, RSVD, B, 23, B, 18, D, 10),
- PINGROUP(UDA, SPI1, RSVD, UARTD, ULPI, D, 13, A, 8, E, 16),
- /* these pin groups only have pullup and pull down control */
- PINGROUP(CK32, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 14),
- PINGROUP(DDRC, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, D, 26),
- PINGROUP(PMCA, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 4),
- PINGROUP(PMCB, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 6),
- PINGROUP(PMCC, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 8),
- PINGROUP(PMCD, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 10),
- PINGROUP(PMCE, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 12),
- PINGROUP(XM2C, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, C, 30),
- PINGROUP(XM2D, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, C, 28),
-};
+static const struct tegra_pingroup_desc *const pingroups = tegra_soc_pingroups;
+static const struct tegra_drive_pingroup_desc *const drive_pingroups = tegra_soc_drive_pingroups;
static char *tegra_mux_names[TEGRA_MAX_MUX] = {
[TEGRA_MUX_AHB_CLK] = "AHB_CLK",
@@ -256,48 +96,7 @@ static char *tegra_mux_names[TEGRA_MAX_MUX] = {
[TEGRA_MUX_VI] = "VI",
[TEGRA_MUX_VI_SENSOR_CLK] = "VI_SENSOR_CLK",
[TEGRA_MUX_XIO] = "XIO",
-};
-
-struct tegra_drive_pingroup_desc {
- const char *name;
- s16 reg;
-};
-
-#define DRIVE_PINGROUP(pg_name, r) \
- [TEGRA_DRIVE_PINGROUP_ ## pg_name] = { \
- .name = #pg_name, \
- .reg = r \
- }
-
-static const struct tegra_drive_pingroup_desc drive_pingroups[TEGRA_MAX_PINGROUP] = {
- DRIVE_PINGROUP(AO1, 0x868),
- DRIVE_PINGROUP(AO2, 0x86c),
- DRIVE_PINGROUP(AT1, 0x870),
- DRIVE_PINGROUP(AT2, 0x874),
- DRIVE_PINGROUP(CDEV1, 0x878),
- DRIVE_PINGROUP(CDEV2, 0x87c),
- DRIVE_PINGROUP(CSUS, 0x880),
- DRIVE_PINGROUP(DAP1, 0x884),
- DRIVE_PINGROUP(DAP2, 0x888),
- DRIVE_PINGROUP(DAP3, 0x88c),
- DRIVE_PINGROUP(DAP4, 0x890),
- DRIVE_PINGROUP(DBG, 0x894),
- DRIVE_PINGROUP(LCD1, 0x898),
- DRIVE_PINGROUP(LCD2, 0x89c),
- DRIVE_PINGROUP(SDMMC2, 0x8a0),
- DRIVE_PINGROUP(SDMMC3, 0x8a4),
- DRIVE_PINGROUP(SPI, 0x8a8),
- DRIVE_PINGROUP(UAA, 0x8ac),
- DRIVE_PINGROUP(UAB, 0x8b0),
- DRIVE_PINGROUP(UART2, 0x8b4),
- DRIVE_PINGROUP(UART3, 0x8b8),
- DRIVE_PINGROUP(VI1, 0x8bc),
- DRIVE_PINGROUP(VI2, 0x8c0),
- DRIVE_PINGROUP(XM2A, 0x8c4),
- DRIVE_PINGROUP(XM2C, 0x8c8),
- DRIVE_PINGROUP(XM2D, 0x8cc),
- DRIVE_PINGROUP(XM2CLK, 0x8d0),
- DRIVE_PINGROUP(MEMCOMP, 0x8d4),
+ [TEGRA_MUX_SAFE] = "<safe>",
};
static const char *tegra_drive_names[TEGRA_MAX_DRIVE] = {
@@ -381,22 +180,27 @@ static inline void pg_writel(unsigned long value, unsigned long offset)
writel(value, IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset));
}
-int tegra_pinmux_set_func(enum tegra_pingroup pg, enum tegra_mux_func func)
+static int tegra_pinmux_set_func(const struct tegra_pingroup_config *config)
{
int mux = -1;
int i;
unsigned long reg;
unsigned long flags;
+ enum tegra_pingroup pg = config->pingroup;
+ enum tegra_mux_func func = config->func;
if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
return -ERANGE;
- if (pingroups[pg].mux_reg == REG_N)
+ if (pingroups[pg].mux_reg < 0)
return -EINVAL;
if (func < 0)
return -ERANGE;
+ if (func == TEGRA_MUX_SAFE)
+ func = pingroups[pg].func_safe;
+
if (func & TEGRA_MUX_RSVD) {
mux = func & 0x3;
} else {
@@ -413,10 +217,10 @@ int tegra_pinmux_set_func(enum tegra_pingroup pg, enum tegra_mux_func func)
spin_lock_irqsave(&mux_lock, flags);
- reg = pg_readl(TEGRA_PP_MUX_CTL(pingroups[pg].mux_reg));
+ reg = pg_readl(pingroups[pg].mux_reg);
reg &= ~(0x3 << pingroups[pg].mux_bit);
reg |= mux << pingroups[pg].mux_bit;
- pg_writel(reg, TEGRA_PP_MUX_CTL(pingroups[pg].mux_reg));
+ pg_writel(reg, pingroups[pg].mux_reg);
spin_unlock_irqrestore(&mux_lock, flags);
@@ -432,16 +236,16 @@ int tegra_pinmux_set_tristate(enum tegra_pingroup pg,
if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
return -ERANGE;
- if (pingroups[pg].tri_reg == REG_N)
+ if (pingroups[pg].tri_reg < 0)
return -EINVAL;
spin_lock_irqsave(&mux_lock, flags);
- reg = pg_readl(TEGRA_TRI_STATE(pingroups[pg].tri_reg));
+ reg = pg_readl(pingroups[pg].tri_reg);
reg &= ~(0x1 << pingroups[pg].tri_bit);
if (tristate)
reg |= 1 << pingroups[pg].tri_bit;
- pg_writel(reg, TEGRA_TRI_STATE(pingroups[pg].tri_reg));
+ pg_writel(reg, pingroups[pg].tri_reg);
spin_unlock_irqrestore(&mux_lock, flags);
@@ -457,7 +261,7 @@ int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg,
if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
return -ERANGE;
- if (pingroups[pg].pupd_reg == REG_N)
+ if (pingroups[pg].pupd_reg < 0)
return -EINVAL;
if (pupd != TEGRA_PUPD_NORMAL &&
@@ -468,38 +272,39 @@ int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg,
spin_lock_irqsave(&mux_lock, flags);
- reg = pg_readl(TEGRA_PP_PU_PD(pingroups[pg].pupd_reg));
+ reg = pg_readl(pingroups[pg].pupd_reg);
reg &= ~(0x3 << pingroups[pg].pupd_bit);
reg |= pupd << pingroups[pg].pupd_bit;
- pg_writel(reg, TEGRA_PP_PU_PD(pingroups[pg].pupd_reg));
+ pg_writel(reg, pingroups[pg].pupd_reg);
spin_unlock_irqrestore(&mux_lock, flags);
return 0;
}
-void tegra_pinmux_config_pingroup(enum tegra_pingroup pingroup,
- enum tegra_mux_func func,
- enum tegra_pullupdown pupd,
- enum tegra_tristate tristate)
+static void tegra_pinmux_config_pingroup(const struct tegra_pingroup_config *config)
{
+ enum tegra_pingroup pingroup = config->pingroup;
+ enum tegra_mux_func func = config->func;
+ enum tegra_pullupdown pupd = config->pupd;
+ enum tegra_tristate tristate = config->tristate;
int err;
- if (pingroups[pingroup].mux_reg != REG_N) {
- err = tegra_pinmux_set_func(pingroup, func);
+ if (pingroups[pingroup].mux_reg >= 0) {
+ err = tegra_pinmux_set_func(config);
if (err < 0)
pr_err("pinmux: can't set pingroup %s func to %s: %d\n",
pingroup_name(pingroup), func_name(func), err);
}
- if (pingroups[pingroup].pupd_reg != REG_N) {
+ if (pingroups[pingroup].pupd_reg >= 0) {
err = tegra_pinmux_set_pullupdown(pingroup, pupd);
if (err < 0)
pr_err("pinmux: can't set pingroup %s pullupdown to %s: %d\n",
pingroup_name(pingroup), pupd_name(pupd), err);
}
- if (pingroups[pingroup].tri_reg != REG_N) {
+ if (pingroups[pingroup].tri_reg >= 0) {
err = tegra_pinmux_set_tristate(pingroup, tristate);
if (err < 0)
pr_err("pinmux: can't set pingroup %s tristate to %s: %d\n",
@@ -507,17 +312,12 @@ void tegra_pinmux_config_pingroup(enum tegra_pingroup pingroup,
}
}
-
-
-void tegra_pinmux_config_table(struct tegra_pingroup_config *config, int len)
+void tegra_pinmux_config_table(const struct tegra_pingroup_config *config, int len)
{
int i;
for (i = 0; i < len; i++)
- tegra_pinmux_config_pingroup(config[i].pingroup,
- config[i].func,
- config[i].pupd,
- config[i].tristate);
+ tegra_pinmux_config_pingroup(&config[i]);
}
static const char *drive_pinmux_name(enum tegra_drive_pingroup pg)
@@ -784,6 +584,86 @@ void tegra_drive_pinmux_config_table(struct tegra_drive_pingroup_config *config,
config[i].slew_falling);
}
+void tegra_pinmux_set_safe_pinmux_table(const struct tegra_pingroup_config *config,
+ int len)
+{
+ int i;
+ struct tegra_pingroup_config c;
+
+ for (i = 0; i < len; i++) {
+ int err;
+ c = config[i];
+ if (c.pingroup < 0 || c.pingroup >= TEGRA_MAX_PINGROUP) {
+ WARN_ON(1);
+ continue;
+ }
+ c.func = pingroups[c.pingroup].func_safe;
+ err = tegra_pinmux_set_func(&c);
+ if (err < 0)
+ pr_err("%s: tegra_pinmux_set_func returned %d setting "
+ "%s to %s\n", __func__, err,
+ pingroup_name(c.pingroup), func_name(c.func));
+ }
+}
+
+void tegra_pinmux_config_pinmux_table(const struct tegra_pingroup_config *config,
+ int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ int err;
+ if (config[i].pingroup < 0 ||
+ config[i].pingroup >= TEGRA_MAX_PINGROUP) {
+ WARN_ON(1);
+ continue;
+ }
+ err = tegra_pinmux_set_func(&config[i]);
+ if (err < 0)
+ pr_err("%s: tegra_pinmux_set_func returned %d setting "
+ "%s to %s\n", __func__, err,
+ pingroup_name(config[i].pingroup),
+ func_name(config[i].func));
+ }
+}
+
+void tegra_pinmux_config_tristate_table(const struct tegra_pingroup_config *config,
+ int len, enum tegra_tristate tristate)
+{
+ int i;
+ int err;
+ enum tegra_pingroup pingroup;
+
+ for (i = 0; i < len; i++) {
+ pingroup = config[i].pingroup;
+ if (pingroups[pingroup].tri_reg >= 0) {
+ err = tegra_pinmux_set_tristate(pingroup, tristate);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s tristate"
+ " to %s: %d\n", pingroup_name(pingroup),
+ tri_name(tristate), err);
+ }
+ }
+}
+
+void tegra_pinmux_config_pullupdown_table(const struct tegra_pingroup_config *config,
+ int len, enum tegra_pullupdown pupd)
+{
+ int i;
+ int err;
+ enum tegra_pingroup pingroup;
+
+ for (i = 0; i < len; i++) {
+ pingroup = config[i].pingroup;
+ if (pingroups[pingroup].pupd_reg >= 0) {
+ err = tegra_pinmux_set_pullupdown(pingroup, pupd);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s pullupdown"
+ " to %s: %d\n", pingroup_name(pingroup),
+ pupd_name(pupd), err);
+ }
+ }
+}
#ifdef CONFIG_DEBUG_FS
@@ -812,11 +692,11 @@ static int dbg_pinmux_show(struct seq_file *s, void *unused)
len = strlen(pingroups[i].name);
dbg_pad_field(s, 5 - len);
- if (pingroups[i].mux_reg == REG_N) {
+ if (pingroups[i].mux_reg < 0) {
seq_printf(s, "TEGRA_MUX_NONE");
len = strlen("NONE");
} else {
- mux = (pg_readl(TEGRA_PP_MUX_CTL(pingroups[i].mux_reg)) >>
+ mux = (pg_readl(pingroups[i].mux_reg) >>
pingroups[i].mux_bit) & 0x3;
if (pingroups[i].funcs[mux] == TEGRA_MUX_RSVD) {
seq_printf(s, "TEGRA_MUX_RSVD%1lu", mux+1);
@@ -829,21 +709,21 @@ static int dbg_pinmux_show(struct seq_file *s, void *unused)
}
dbg_pad_field(s, 13-len);
- if (pingroups[i].mux_reg == REG_N) {
+ if (pingroups[i].pupd_reg < 0) {
seq_printf(s, "TEGRA_PUPD_NORMAL");
len = strlen("NORMAL");
} else {
- pupd = (pg_readl(TEGRA_PP_PU_PD(pingroups[i].pupd_reg)) >>
+ pupd = (pg_readl(pingroups[i].pupd_reg) >>
pingroups[i].pupd_bit) & 0x3;
seq_printf(s, "TEGRA_PUPD_%s", pupd_name(pupd));
len = strlen(pupd_name(pupd));
}
dbg_pad_field(s, 9 - len);
- if (pingroups[i].tri_reg == REG_N) {
+ if (pingroups[i].tri_reg < 0) {
seq_printf(s, "TEGRA_TRI_NORMAL");
} else {
- tri = (pg_readl(TEGRA_TRI_STATE(pingroups[i].tri_reg)) >>
+ tri = (pg_readl(pingroups[i].tri_reg) >>
pingroups[i].tri_bit) & 0x1;
seq_printf(s, "TEGRA_TRI_%s", tri_name(tri));
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
index 426163231fff..ae3b308e22a4 100644
--- a/arch/arm/mach-tegra/tegra2_clocks.c
+++ b/arch/arm/mach-tegra/tegra2_clocks.c
@@ -30,14 +30,21 @@
#include <mach/iomap.h>
#include "clock.h"
+#include "fuse.h"
+#include "tegra2_dvfs.h"
#define RST_DEVICES 0x004
#define RST_DEVICES_SET 0x300
#define RST_DEVICES_CLR 0x304
+#define RST_DEVICES_NUM 3
#define CLK_OUT_ENB 0x010
#define CLK_OUT_ENB_SET 0x320
#define CLK_OUT_ENB_CLR 0x324
+#define CLK_OUT_ENB_NUM 3
+
+#define CLK_MASK_ARM 0x44
+#define MISC_CLK_ENB 0x48
#define OSC_CTRL 0x50
#define OSC_CTRL_OSC_FREQ_MASK (3<<30)
@@ -45,6 +52,7 @@
#define OSC_CTRL_OSC_FREQ_19_2MHZ (1<<30)
#define OSC_CTRL_OSC_FREQ_12MHZ (2<<30)
#define OSC_CTRL_OSC_FREQ_26MHZ (3<<30)
+#define OSC_CTRL_MASK 0x3f2
#define OSC_FREQ_DET 0x58
#define OSC_FREQ_DET_TRIG (1<<31)
@@ -53,10 +61,17 @@
#define OSC_FREQ_DET_BUSY (1<<31)
#define OSC_FREQ_DET_CNT_MASK 0xFFFF
+#define PERIPH_CLK_SOURCE_I2S1 0x100
+#define PERIPH_CLK_SOURCE_EMC 0x19c
+#define PERIPH_CLK_SOURCE_OSC 0x1fc
+#define PERIPH_CLK_SOURCE_NUM \
+ ((PERIPH_CLK_SOURCE_OSC - PERIPH_CLK_SOURCE_I2S1) / 4)
+
#define PERIPH_CLK_SOURCE_MASK (3<<30)
#define PERIPH_CLK_SOURCE_SHIFT 30
#define PERIPH_CLK_SOURCE_ENABLE (1<<28)
-#define PERIPH_CLK_SOURCE_DIV_MASK 0xFF
+#define PERIPH_CLK_SOURCE_DIVU71_MASK 0xFF
+#define PERIPH_CLK_SOURCE_DIVU16_MASK 0xFFFF
#define PERIPH_CLK_SOURCE_DIV_SHIFT 0
#define PLL_BASE 0x0
@@ -79,8 +94,9 @@
#define PLL_OUT_RESET_DISABLE (1<<0)
#define PLL_MISC(c) (((c)->flags & PLL_ALT_MISC_REG) ? 0x4 : 0xc)
+#define PLL_MISC_LOCK_ENABLE(c) (((c)->flags & PLLU) ? (1<<22) : (1<<18))
+
#define PLL_MISC_DCCON_SHIFT 20
-#define PLL_MISC_LOCK_ENABLE (1<<18)
#define PLL_MISC_CPCON_SHIFT 8
#define PLL_MISC_CPCON_MASK (0xF<<PLL_MISC_CPCON_SHIFT)
#define PLL_MISC_LFCON_SHIFT 4
@@ -88,10 +104,14 @@
#define PLL_MISC_VCOCON_SHIFT 0
#define PLL_MISC_VCOCON_MASK (0xF<<PLL_MISC_VCOCON_SHIFT)
+#define PLLU_BASE_POST_DIV (1<<20)
+
#define PLLD_MISC_CLKENABLE (1<<30)
#define PLLD_MISC_DIV_RST (1<<23)
#define PLLD_MISC_DCCON_SHIFT 12
+#define PLLE_MISC_READY (1 << 15)
+
#define PERIPH_CLK_TO_ENB_REG(c) ((c->clk_num / 32) * 4)
#define PERIPH_CLK_TO_ENB_SET_REG(c) ((c->clk_num / 32) * 8)
#define PERIPH_CLK_TO_ENB_BIT(c) (1 << (c->clk_num % 32))
@@ -143,30 +163,37 @@ unsigned long clk_measure_input_freq(void)
}
}
-static int clk_div71_get_divider(struct clk *c, unsigned long rate)
+static int clk_div71_get_divider(unsigned long parent_rate, unsigned long rate)
{
- unsigned long divider_u71;
+ s64 divider_u71 = parent_rate * 2;
+ divider_u71 += rate - 1;
+ do_div(divider_u71, rate);
- divider_u71 = DIV_ROUND_UP(c->rate * 2, rate);
+ if (divider_u71 - 2 < 0)
+ return 0;
- if (divider_u71 - 2 > 255 || divider_u71 - 2 < 0)
+ if (divider_u71 - 2 > 255)
return -EINVAL;
return divider_u71 - 2;
}
-static unsigned long tegra2_clk_recalculate_rate(struct clk *c)
+static int clk_div16_get_divider(unsigned long parent_rate, unsigned long rate)
{
- unsigned long rate;
- rate = c->parent->rate;
+ s64 divider_u16;
- if (c->mul != 0 && c->div != 0)
- c->rate = rate * c->mul / c->div;
- else
- c->rate = rate;
- return c->rate;
-}
+ divider_u16 = parent_rate;
+ divider_u16 += rate - 1;
+ do_div(divider_u16, rate);
+
+ if (divider_u16 - 1 < 0)
+ return 0;
+ if (divider_u16 - 1 > 255)
+ return -EINVAL;
+
+ return divider_u16 - 1;
+}
/* clk_m functions */
static unsigned long tegra2_clk_m_autodetect_rate(struct clk *c)
@@ -244,7 +271,6 @@ static void tegra2_super_clk_init(struct clk *c)
}
BUG_ON(sel->input == NULL);
c->parent = sel->input;
- tegra2_clk_recalculate_rate(c);
}
static int tegra2_super_clk_enable(struct clk *c)
@@ -266,6 +292,7 @@ static int tegra2_super_clk_set_parent(struct clk *c, struct clk *p)
u32 val;
const struct clk_mux_sel *sel;
int shift;
+
val = clk_readl(c->reg + SUPER_CLK_MUX);;
BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
@@ -273,11 +300,18 @@ static int tegra2_super_clk_set_parent(struct clk *c, struct clk *p)
SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
for (sel = c->inputs; sel->input != NULL; sel++) {
if (sel->input == p) {
- clk_reparent(c, p);
val &= ~(SUPER_SOURCE_MASK << shift);
val |= sel->value << shift;
+
+ if (c->refcnt)
+ clk_enable_locked(p);
+
clk_writel(val, c->reg);
- c->rate = c->parent->rate;
+
+ if (c->refcnt && c->parent)
+ clk_disable_locked(c->parent);
+
+ clk_reparent(c, p);
return 0;
}
}
@@ -289,7 +323,61 @@ static struct clk_ops tegra_super_ops = {
.enable = tegra2_super_clk_enable,
.disable = tegra2_super_clk_disable,
.set_parent = tegra2_super_clk_set_parent,
- .recalculate_rate = tegra2_clk_recalculate_rate,
+};
+
+/* virtual cpu clock functions */
+/* some clocks can not be stopped (cpu, memory bus) while the SoC is running.
+ To change the frequency of these clocks, the parent pll may need to be
+ reprogrammed, so the clock must be moved off the pll, the pll reprogrammed,
+ and then the clock moved back to the pll. To hide this sequence, a virtual
+ clock handles it.
+ */
+static void tegra2_cpu_clk_init(struct clk *c)
+{
+}
+
+static int tegra2_cpu_clk_enable(struct clk *c)
+{
+ return 0;
+}
+
+static void tegra2_cpu_clk_disable(struct clk *c)
+{
+ pr_debug("%s on clock %s\n", __func__, c->name);
+
+ /* oops - don't disable the CPU clock! */
+ BUG();
+}
+
+static int tegra2_cpu_clk_set_rate(struct clk *c, unsigned long rate)
+{
+ int ret;
+ ret = clk_set_parent_locked(c->parent, c->backup);
+ if (ret) {
+ pr_err("Failed to switch cpu to clock %s\n", c->backup->name);
+ return ret;
+ }
+
+ ret = clk_set_rate_locked(c->main, rate);
+ if (ret) {
+ pr_err("Failed to change cpu pll to %lu\n", rate);
+ return ret;
+ }
+
+ ret = clk_set_parent_locked(c->parent, c->main);
+ if (ret) {
+ pr_err("Failed to switch cpu to clock %s\n", c->main->name);
+ return ret;
+ }
+
+ return 0;
+}
+
+static struct clk_ops tegra_cpu_ops = {
+ .init = tegra2_cpu_clk_init,
+ .enable = tegra2_cpu_clk_enable,
+ .disable = tegra2_cpu_clk_disable,
+ .set_rate = tegra2_cpu_clk_set_rate,
};
/* bus clock functions */
@@ -299,7 +387,6 @@ static void tegra2_bus_clk_init(struct clk *c)
c->state = ((val >> c->reg_shift) & BUS_CLK_DISABLE) ? OFF : ON;
c->div = ((val >> c->reg_shift) & BUS_CLK_DIV_MASK) + 1;
c->mul = 1;
- tegra2_clk_recalculate_rate(c);
}
static int tegra2_bus_clk_enable(struct clk *c)
@@ -340,27 +427,15 @@ static struct clk_ops tegra_bus_ops = {
.enable = tegra2_bus_clk_enable,
.disable = tegra2_bus_clk_disable,
.set_rate = tegra2_bus_clk_set_rate,
- .recalculate_rate = tegra2_clk_recalculate_rate,
};
/* PLL Functions */
-static unsigned long tegra2_pll_clk_recalculate_rate(struct clk *c)
-{
- u64 rate;
- rate = c->parent->rate;
- rate *= c->n;
- do_div(rate, c->m);
- if (c->p == 2)
- rate >>= 1;
- c->rate = rate;
- return c->rate;
-}
-
static int tegra2_pll_clk_wait_for_lock(struct clk *c)
{
ktime_t before;
before = ktime_get();
+
while (!(clk_readl(c->reg + PLL_BASE) & PLL_BASE_LOCK)) {
if (ktime_us_delta(ktime_get(), before) > 5000) {
pr_err("Timed out waiting for lock bit on pll %s",
@@ -380,24 +455,19 @@ static void tegra2_pll_clk_init(struct clk *c)
if (c->flags & PLL_FIXED && !(val & PLL_BASE_OVERRIDE)) {
pr_warning("Clock %s has unknown fixed frequency\n", c->name);
- c->n = 1;
- c->m = 0;
- c->p = 1;
+ c->mul = 1;
+ c->div = 1;
} else if (val & PLL_BASE_BYPASS) {
- c->n = 1;
- c->m = 1;
- c->p = 1;
+ c->mul = 1;
+ c->div = 1;
} else {
- c->n = (val & PLL_BASE_DIVN_MASK) >> PLL_BASE_DIVN_SHIFT;
- c->m = (val & PLL_BASE_DIVM_MASK) >> PLL_BASE_DIVM_SHIFT;
- c->p = (val & PLL_BASE_DIVP_MASK) ? 2 : 1;
+ c->mul = (val & PLL_BASE_DIVN_MASK) >> PLL_BASE_DIVN_SHIFT;
+ c->div = (val & PLL_BASE_DIVM_MASK) >> PLL_BASE_DIVM_SHIFT;
+ if (c->flags & PLLU)
+ c->div *= (val & PLLU_BASE_POST_DIV) ? 1 : 2;
+ else
+ c->div *= (val & PLL_BASE_DIVP_MASK) ? 2 : 1;
}
-
- val = clk_readl(c->reg + PLL_MISC(c));
- if (c->flags & PLL_HAS_CPCON)
- c->cpcon = (val & PLL_MISC_CPCON_MASK) >> PLL_MISC_CPCON_SHIFT;
-
- tegra2_pll_clk_recalculate_rate(c);
}
static int tegra2_pll_clk_enable(struct clk *c)
@@ -411,7 +481,7 @@ static int tegra2_pll_clk_enable(struct clk *c)
clk_writel(val, c->reg + PLL_BASE);
val = clk_readl(c->reg + PLL_MISC(c));
- val |= PLL_MISC_LOCK_ENABLE;
+ val |= PLL_MISC_LOCK_ENABLE(c);
clk_writel(val, c->reg + PLL_MISC(c));
tegra2_pll_clk_wait_for_lock(c);
@@ -441,33 +511,36 @@ static int tegra2_pll_clk_set_rate(struct clk *c, unsigned long rate)
input_rate = c->parent->rate;
for (sel = c->pll_table; sel->input_rate != 0; sel++) {
if (sel->input_rate == input_rate && sel->output_rate == rate) {
- c->n = sel->n;
- c->m = sel->m;
- c->p = sel->p;
- c->cpcon = sel->cpcon;
+ c->mul = sel->n;
+ c->div = sel->m * sel->p;
val = clk_readl(c->reg + PLL_BASE);
if (c->flags & PLL_FIXED)
val |= PLL_BASE_OVERRIDE;
val &= ~(PLL_BASE_DIVP_MASK | PLL_BASE_DIVN_MASK |
PLL_BASE_DIVM_MASK);
- val |= (c->m << PLL_BASE_DIVM_SHIFT) |
- (c->n << PLL_BASE_DIVN_SHIFT);
- BUG_ON(c->p > 2);
- if (c->p == 2)
- val |= 1 << PLL_BASE_DIVP_SHIFT;
+ val |= (sel->m << PLL_BASE_DIVM_SHIFT) |
+ (sel->n << PLL_BASE_DIVN_SHIFT);
+ BUG_ON(sel->p < 1 || sel->p > 2);
+ if (c->flags & PLLU) {
+ if (sel->p == 1)
+ val |= PLLU_BASE_POST_DIV;
+ } else {
+ if (sel->p == 2)
+ val |= 1 << PLL_BASE_DIVP_SHIFT;
+ }
clk_writel(val, c->reg + PLL_BASE);
if (c->flags & PLL_HAS_CPCON) {
- val = c->cpcon << PLL_MISC_CPCON_SHIFT;
- val |= PLL_MISC_LOCK_ENABLE;
+ val = clk_readl(c->reg + PLL_MISC(c));
+ val &= ~PLL_MISC_CPCON_MASK;
+ val |= sel->cpcon << PLL_MISC_CPCON_SHIFT;
clk_writel(val, c->reg + PLL_MISC(c));
}
if (c->state == ON)
tegra2_pll_clk_enable(c);
- c->rate = rate;
return 0;
}
}
@@ -479,7 +552,46 @@ static struct clk_ops tegra_pll_ops = {
.enable = tegra2_pll_clk_enable,
.disable = tegra2_pll_clk_disable,
.set_rate = tegra2_pll_clk_set_rate,
- .recalculate_rate = tegra2_pll_clk_recalculate_rate,
+};
+
+static void tegra2_pllx_clk_init(struct clk *c)
+{
+ tegra2_pll_clk_init(c);
+
+ if (tegra_sku_id() == 7)
+ c->max_rate = 750000000;
+}
+
+static struct clk_ops tegra_pllx_ops = {
+ .init = tegra2_pllx_clk_init,
+ .enable = tegra2_pll_clk_enable,
+ .disable = tegra2_pll_clk_disable,
+ .set_rate = tegra2_pll_clk_set_rate,
+};
+
+static int tegra2_plle_clk_enable(struct clk *c)
+{
+ u32 val;
+
+ pr_debug("%s on clock %s\n", __func__, c->name);
+
+ mdelay(1);
+
+ val = clk_readl(c->reg + PLL_BASE);
+ if (!(val & PLLE_MISC_READY))
+ return -EBUSY;
+
+ val = clk_readl(c->reg + PLL_BASE);
+ val |= PLL_BASE_ENABLE | PLL_BASE_BYPASS;
+ clk_writel(val, c->reg + PLL_BASE);
+
+ return 0;
+}
+
+static struct clk_ops tegra_plle_ops = {
+ .init = tegra2_pll_clk_init,
+ .enable = tegra2_plle_clk_enable,
+ .set_rate = tegra2_pll_clk_set_rate,
};
/* Clock divider ops */
@@ -503,8 +615,6 @@ static void tegra2_pll_div_clk_init(struct clk *c)
c->div = 1;
c->mul = 1;
}
-
- tegra2_clk_recalculate_rate(c);
}
static int tegra2_pll_div_clk_enable(struct clk *c)
@@ -565,7 +675,7 @@ static int tegra2_pll_div_clk_set_rate(struct clk *c, unsigned long rate)
int divider_u71;
pr_debug("%s: %s %lu\n", __func__, c->name, rate);
if (c->flags & DIV_U71) {
- divider_u71 = clk_div71_get_divider(c->parent, rate);
+ divider_u71 = clk_div71_get_divider(c->parent->rate, rate);
if (divider_u71 >= 0) {
val = clk_readl(c->reg);
new_val = val >> c->reg_shift;
@@ -580,25 +690,37 @@ static int tegra2_pll_div_clk_set_rate(struct clk *c, unsigned long rate)
clk_writel(val, c->reg);
c->div = divider_u71 + 2;
c->mul = 2;
- tegra2_clk_recalculate_rate(c);
return 0;
}
} else if (c->flags & DIV_2) {
- if (c->parent->rate == rate * 2) {
- c->rate = rate;
+ if (c->parent->rate == rate * 2)
return 0;
- }
}
return -EINVAL;
}
+static long tegra2_pll_div_clk_round_rate(struct clk *c, unsigned long rate)
+{
+ int divider;
+ pr_debug("%s: %s %lu\n", __func__, c->name, rate);
+
+ if (c->flags & DIV_U71) {
+ divider = clk_div71_get_divider(c->parent->rate, rate);
+ if (divider < 0)
+ return divider;
+ return c->parent->rate * 2 / (divider + 2);
+ } else if (c->flags & DIV_2) {
+ return c->parent->rate / 2;
+ }
+ return -EINVAL;
+}
static struct clk_ops tegra_pll_div_ops = {
.init = tegra2_pll_div_clk_init,
.enable = tegra2_pll_div_clk_enable,
.disable = tegra2_pll_div_clk_disable,
.set_rate = tegra2_pll_div_clk_set_rate,
- .recalculate_rate = tegra2_clk_recalculate_rate,
+ .round_rate = tegra2_pll_div_clk_round_rate,
};
/* Periph clk ops */
@@ -621,9 +743,13 @@ static void tegra2_periph_clk_init(struct clk *c)
}
if (c->flags & DIV_U71) {
- u32 divu71 = val & PERIPH_CLK_SOURCE_DIV_MASK;
+ u32 divu71 = val & PERIPH_CLK_SOURCE_DIVU71_MASK;
c->div = divu71 + 2;
c->mul = 2;
+ } else if (c->flags & DIV_U16) {
+ u32 divu16 = val & PERIPH_CLK_SOURCE_DIVU16_MASK;
+ c->div = divu16 + 1;
+ c->mul = 1;
} else {
c->div = 1;
c->mul = 1;
@@ -637,7 +763,6 @@ static void tegra2_periph_clk_init(struct clk *c)
if (clk_readl(RST_DEVICES + PERIPH_CLK_TO_ENB_REG(c)) &
PERIPH_CLK_TO_ENB_BIT(c))
c->state = OFF;
- tegra2_clk_recalculate_rate(c);
}
static int tegra2_periph_clk_enable(struct clk *c)
@@ -692,12 +817,19 @@ static int tegra2_periph_clk_set_parent(struct clk *c, struct clk *p)
pr_debug("%s: %s %s\n", __func__, c->name, p->name);
for (sel = c->inputs; sel->input != NULL; sel++) {
if (sel->input == p) {
- clk_reparent(c, p);
val = clk_readl(c->reg);
val &= ~PERIPH_CLK_SOURCE_MASK;
val |= (sel->value) << PERIPH_CLK_SOURCE_SHIFT;
+
+ if (c->refcnt)
+ clk_enable_locked(p);
+
clk_writel(val, c->reg);
- c->rate = c->parent->rate;
+
+ if (c->refcnt && c->parent)
+ clk_disable_locked(c->parent);
+
+ clk_reparent(c, p);
return 0;
}
}
@@ -708,20 +840,55 @@ static int tegra2_periph_clk_set_parent(struct clk *c, struct clk *p)
static int tegra2_periph_clk_set_rate(struct clk *c, unsigned long rate)
{
u32 val;
- int divider_u71;
+ int divider;
pr_debug("%s: %lu\n", __func__, rate);
if (c->flags & DIV_U71) {
- divider_u71 = clk_div71_get_divider(c->parent, rate);
- if (divider_u71 >= 0) {
+ divider = clk_div71_get_divider(c->parent->rate, rate);
+ if (divider >= 0) {
val = clk_readl(c->reg);
- val &= ~PERIPH_CLK_SOURCE_DIV_MASK;
- val |= divider_u71;
+ val &= ~PERIPH_CLK_SOURCE_DIVU71_MASK;
+ val |= divider;
clk_writel(val, c->reg);
- c->div = divider_u71 + 2;
+ c->div = divider + 2;
c->mul = 2;
- tegra2_clk_recalculate_rate(c);
return 0;
}
+ } else if (c->flags & DIV_U16) {
+ divider = clk_div16_get_divider(c->parent->rate, rate);
+ if (divider >= 0) {
+ val = clk_readl(c->reg);
+ val &= ~PERIPH_CLK_SOURCE_DIVU16_MASK;
+ val |= divider;
+ clk_writel(val, c->reg);
+ c->div = divider + 1;
+ c->mul = 1;
+ return 0;
+ }
+ } else if (c->parent->rate <= rate) {
+ c->div = 1;
+ c->mul = 1;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static long tegra2_periph_clk_round_rate(struct clk *c,
+ unsigned long rate)
+{
+ int divider;
+ pr_debug("%s: %s %lu\n", __func__, c->name, rate);
+
+ if (c->flags & DIV_U71) {
+ divider = clk_div71_get_divider(c->parent->rate, rate);
+ if (divider < 0)
+ return divider;
+
+ return c->parent->rate * 2 / (divider + 2);
+ } else if (c->flags & DIV_U16) {
+ divider = clk_div16_get_divider(c->parent->rate, rate);
+ if (divider < 0)
+ return divider;
+ return c->parent->rate / (divider + 1);
}
return -EINVAL;
}
@@ -732,7 +899,7 @@ static struct clk_ops tegra_periph_clk_ops = {
.disable = &tegra2_periph_clk_disable,
.set_parent = &tegra2_periph_clk_set_parent,
.set_rate = &tegra2_periph_clk_set_rate,
- .recalculate_rate = &tegra2_clk_recalculate_rate,
+ .round_rate = &tegra2_periph_clk_round_rate,
};
/* Clock doubler ops */
@@ -744,21 +911,108 @@ static void tegra2_clk_double_init(struct clk *c)
if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
PERIPH_CLK_TO_ENB_BIT(c)))
c->state = OFF;
- tegra2_clk_recalculate_rate(c);
};
+static int tegra2_clk_double_set_rate(struct clk *c, unsigned long rate)
+{
+ if (rate != 2 * c->parent->rate)
+ return -EINVAL;
+ c->mul = 2;
+ c->div = 1;
+ return 0;
+}
+
static struct clk_ops tegra_clk_double_ops = {
.init = &tegra2_clk_double_init,
.enable = &tegra2_periph_clk_enable,
.disable = &tegra2_periph_clk_disable,
- .recalculate_rate = &tegra2_clk_recalculate_rate,
+ .set_rate = &tegra2_clk_double_set_rate,
+};
+
+static void tegra2_audio_sync_clk_init(struct clk *c)
+{
+ int source;
+ const struct clk_mux_sel *sel;
+ u32 val = clk_readl(c->reg);
+ c->state = (val & (1<<4)) ? OFF : ON;
+ source = val & 0xf;
+ for (sel = c->inputs; sel->input != NULL; sel++)
+ if (sel->value == source)
+ break;
+ BUG_ON(sel->input == NULL);
+ c->parent = sel->input;
+}
+
+static int tegra2_audio_sync_clk_enable(struct clk *c)
+{
+ clk_writel(0, c->reg);
+ return 0;
+}
+
+static void tegra2_audio_sync_clk_disable(struct clk *c)
+{
+ clk_writel(1, c->reg);
+}
+
+static int tegra2_audio_sync_clk_set_parent(struct clk *c, struct clk *p)
+{
+ u32 val;
+ const struct clk_mux_sel *sel;
+ for (sel = c->inputs; sel->input != NULL; sel++) {
+ if (sel->input == p) {
+ val = clk_readl(c->reg);
+ val &= ~0xf;
+ val |= sel->value;
+
+ if (c->refcnt)
+ clk_enable_locked(p);
+
+ clk_writel(val, c->reg);
+
+ if (c->refcnt && c->parent)
+ clk_disable_locked(c->parent);
+
+ clk_reparent(c, p);
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int tegra2_audio_sync_clk_set_rate(struct clk *c, unsigned long rate)
+{
+ unsigned long parent_rate;
+ if (!c->parent) {
+ pr_err("%s: clock has no parent\n", __func__);
+ return -EINVAL;
+ }
+ parent_rate = c->parent->rate;
+ if (rate != parent_rate) {
+ pr_err("%s: %s/%ld differs from parent %s/%ld\n",
+ __func__,
+ c->name, rate,
+ c->parent->name, parent_rate);
+ return -EINVAL;
+ }
+ c->rate = parent_rate;
+ return 0;
+}
+
+static struct clk_ops tegra_audio_sync_clk_ops = {
+ .init = tegra2_audio_sync_clk_init,
+ .enable = tegra2_audio_sync_clk_enable,
+ .disable = tegra2_audio_sync_clk_disable,
+ .set_rate = tegra2_audio_sync_clk_set_rate,
+ .set_parent = tegra2_audio_sync_clk_set_parent,
};
/* Clock definitions */
static struct clk tegra_clk_32k = {
.name = "clk_32k",
- .rate = 32678,
+ .rate = 32768,
.ops = NULL,
+ .max_rate = 32768,
};
static struct clk_pll_table tegra_pll_s_table[] = {
@@ -782,6 +1036,7 @@ static struct clk tegra_pll_s = {
.vco_min = 12000000,
.vco_max = 26000000,
.pll_table = tegra_pll_s_table,
+ .max_rate = 26000000,
};
static struct clk_mux_sel tegra_clk_m_sel[] = {
@@ -797,6 +1052,7 @@ static struct clk tegra_clk_m = {
.reg = 0x1fc,
.reg_mask = (1<<28),
.reg_shift = 28,
+ .max_rate = 26000000,
};
static struct clk_pll_table tegra_pll_c_table[] = {
@@ -816,6 +1072,7 @@ static struct clk tegra_pll_c = {
.vco_min = 20000000,
.vco_max = 1400000000,
.pll_table = tegra_pll_c_table,
+ .max_rate = 600000000,
};
static struct clk tegra_pll_c_out1 = {
@@ -825,9 +1082,18 @@ static struct clk tegra_pll_c_out1 = {
.parent = &tegra_pll_c,
.reg = 0x84,
.reg_shift = 0,
+ .max_rate = 600000000,
};
static struct clk_pll_table tegra_pll_m_table[] = {
+ { 12000000, 666000000, 666, 12, 1, 8},
+ { 13000000, 666000000, 666, 13, 1, 8},
+ { 19200000, 666000000, 555, 16, 1, 8},
+ { 26000000, 666000000, 666, 26, 1, 8},
+ { 12000000, 600000000, 600, 12, 1, 8},
+ { 13000000, 600000000, 600, 13, 1, 8},
+ { 19200000, 600000000, 375, 12, 1, 6},
+ { 26000000, 600000000, 600, 26, 1, 8},
{ 0, 0, 0, 0, 0, 0 },
};
@@ -844,6 +1110,7 @@ static struct clk tegra_pll_m = {
.vco_min = 20000000,
.vco_max = 1200000000,
.pll_table = tegra_pll_m_table,
+ .max_rate = 800000000,
};
static struct clk tegra_pll_m_out1 = {
@@ -853,6 +1120,7 @@ static struct clk tegra_pll_m_out1 = {
.parent = &tegra_pll_m,
.reg = 0x94,
.reg_shift = 0,
+ .max_rate = 600000000,
};
static struct clk_pll_table tegra_pll_p_table[] = {
@@ -880,6 +1148,7 @@ static struct clk tegra_pll_p = {
.vco_min = 20000000,
.vco_max = 1400000000,
.pll_table = tegra_pll_p_table,
+ .max_rate = 432000000,
};
static struct clk tegra_pll_p_out1 = {
@@ -889,6 +1158,7 @@ static struct clk tegra_pll_p_out1 = {
.parent = &tegra_pll_p,
.reg = 0xa4,
.reg_shift = 0,
+ .max_rate = 432000000,
};
static struct clk tegra_pll_p_out2 = {
@@ -898,6 +1168,7 @@ static struct clk tegra_pll_p_out2 = {
.parent = &tegra_pll_p,
.reg = 0xa4,
.reg_shift = 16,
+ .max_rate = 432000000,
};
static struct clk tegra_pll_p_out3 = {
@@ -907,6 +1178,7 @@ static struct clk tegra_pll_p_out3 = {
.parent = &tegra_pll_p,
.reg = 0xa8,
.reg_shift = 0,
+ .max_rate = 432000000,
};
static struct clk tegra_pll_p_out4 = {
@@ -916,6 +1188,7 @@ static struct clk tegra_pll_p_out4 = {
.parent = &tegra_pll_p,
.reg = 0xa8,
.reg_shift = 16,
+ .max_rate = 432000000,
};
static struct clk_pll_table tegra_pll_a_table[] = {
@@ -923,6 +1196,7 @@ static struct clk_pll_table tegra_pll_a_table[] = {
{ 28800000, 73728000, 64, 25, 1, 1},
{ 28800000, 11289600, 49, 25, 1, 1},
{ 28800000, 12288000, 64, 25, 1, 1},
+ { 28800000, 24000000, 5, 6, 1, 1},
{ 0, 0, 0, 0, 0, 0 },
};
@@ -939,6 +1213,7 @@ static struct clk tegra_pll_a = {
.vco_min = 20000000,
.vco_max = 1400000000,
.pll_table = tegra_pll_a_table,
+ .max_rate = 56448000,
};
static struct clk tegra_pll_a_out0 = {
@@ -948,6 +1223,7 @@ static struct clk tegra_pll_a_out0 = {
.parent = &tegra_pll_a,
.reg = 0xb4,
.reg_shift = 0,
+ .max_rate = 56448000,
};
static struct clk_pll_table tegra_pll_d_table[] = {
@@ -971,6 +1247,7 @@ static struct clk tegra_pll_d = {
.vco_min = 40000000,
.vco_max = 1000000000,
.pll_table = tegra_pll_d_table,
+ .max_rate = 1000000000,
};
static struct clk tegra_pll_d_out0 = {
@@ -978,19 +1255,20 @@ static struct clk tegra_pll_d_out0 = {
.ops = &tegra_pll_div_ops,
.flags = DIV_2 | PLLD,
.parent = &tegra_pll_d,
+ .max_rate = 500000000,
};
static struct clk_pll_table tegra_pll_u_table[] = {
- { 12000000, 480000000, 960, 12, 1, 0},
- { 13000000, 480000000, 960, 13, 1, 0},
- { 19200000, 480000000, 200, 4, 1, 0},
- { 26000000, 480000000, 960, 26, 1, 0},
+ { 12000000, 480000000, 960, 12, 2, 0},
+ { 13000000, 480000000, 960, 13, 2, 0},
+ { 19200000, 480000000, 200, 4, 2, 0},
+ { 26000000, 480000000, 960, 26, 2, 0},
{ 0, 0, 0, 0, 0, 0 },
};
static struct clk tegra_pll_u = {
.name = "pll_u",
- .flags = 0,
+ .flags = PLLU,
.ops = &tegra_pll_ops,
.reg = 0xc0,
.input_min = 2000000,
@@ -1001,24 +1279,59 @@ static struct clk tegra_pll_u = {
.vco_min = 480000000,
.vco_max = 960000000,
.pll_table = tegra_pll_u_table,
+ .max_rate = 480000000,
};
static struct clk_pll_table tegra_pll_x_table[] = {
+ /* 1 GHz */
{ 12000000, 1000000000, 1000, 12, 1, 12},
{ 13000000, 1000000000, 1000, 13, 1, 12},
{ 19200000, 1000000000, 625, 12, 1, 8},
{ 26000000, 1000000000, 1000, 26, 1, 12},
- { 12000000, 750000000, 750, 12, 1, 12},
- { 13000000, 750000000, 750, 13, 1, 12},
- { 19200000, 750000000, 625, 16, 1, 8},
- { 26000000, 750000000, 750, 26, 1, 12},
+
+ /* 912 MHz */
+ { 12000000, 912000000, 912, 12, 1, 12},
+ { 13000000, 912000000, 912, 13, 1, 12},
+ { 19200000, 912000000, 760, 16, 1, 8},
+ { 26000000, 912000000, 912, 26, 1, 12},
+
+ /* 816 MHz */
+ { 12000000, 816000000, 816, 12, 1, 12},
+ { 13000000, 816000000, 816, 13, 1, 12},
+ { 19200000, 816000000, 680, 16, 1, 8},
+ { 26000000, 816000000, 816, 26, 1, 12},
+
+ /* 760 MHz */
+ { 12000000, 760000000, 760, 12, 1, 12},
+ { 13000000, 760000000, 760, 13, 1, 12},
+ { 19200000, 760000000, 950, 24, 1, 8},
+ { 26000000, 760000000, 760, 26, 1, 12},
+
+ /* 608 MHz */
+ { 12000000, 608000000, 760, 12, 1, 12},
+ { 13000000, 608000000, 760, 13, 1, 12},
+ { 19200000, 608000000, 380, 12, 1, 8},
+ { 26000000, 608000000, 760, 26, 1, 12},
+
+ /* 456 MHz */
+ { 12000000, 456000000, 456, 12, 1, 12},
+ { 13000000, 456000000, 456, 13, 1, 12},
+ { 19200000, 456000000, 380, 16, 1, 8},
+ { 26000000, 456000000, 456, 26, 1, 12},
+
+ /* 312 MHz */
+ { 12000000, 312000000, 312, 12, 1, 12},
+ { 13000000, 312000000, 312, 13, 1, 12},
+ { 19200000, 312000000, 260, 16, 1, 8},
+ { 26000000, 312000000, 312, 26, 1, 12},
+
{ 0, 0, 0, 0, 0, 0 },
};
static struct clk tegra_pll_x = {
.name = "pll_x",
.flags = PLL_HAS_CPCON | PLL_ALT_MISC_REG,
- .ops = &tegra_pll_ops,
+ .ops = &tegra_pllx_ops,
.reg = 0xe0,
.input_min = 2000000,
.input_max = 31000000,
@@ -1028,6 +1341,24 @@ static struct clk tegra_pll_x = {
.vco_min = 20000000,
.vco_max = 1200000000,
.pll_table = tegra_pll_x_table,
+ .max_rate = 1000000000,
+};
+
+static struct clk_pll_table tegra_pll_e_table[] = {
+ { 12000000, 100000000, 200, 24, 1, 0 },
+ { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_e = {
+ .name = "pll_e",
+ .flags = PLL_ALT_MISC_REG,
+ .ops = &tegra_plle_ops,
+ .input_min = 12000000,
+ .input_max = 12000000,
+ .max_rate = 100000000,
+ .parent = &tegra_clk_m,
+ .reg = 0xe8,
+ .pll_table = tegra_pll_e_table,
};
static struct clk tegra_clk_d = {
@@ -1038,19 +1369,77 @@ static struct clk tegra_clk_d = {
.reg = 0x34,
.reg_shift = 12,
.parent = &tegra_clk_m,
+ .max_rate = 52000000,
+};
+
+/* initialized before peripheral clocks */
+static struct clk_mux_sel mux_audio_sync_clk[8+1];
+static const struct audio_sources {
+ const char *name;
+ int value;
+} mux_audio_sync_clk_sources[] = {
+ { .name = "spdif_in", .value = 0 },
+ { .name = "i2s1", .value = 1 },
+ { .name = "i2s2", .value = 2 },
+ { .name = "pll_a_out0", .value = 4 },
+#if 0 /* FIXME: not implemented */
+ { .name = "ac97", .value = 3 },
+ { .name = "ext_audio_clk2", .value = 5 },
+ { .name = "ext_audio_clk1", .value = 6 },
+ { .name = "ext_vimclk", .value = 7 },
+#endif
+ { 0, 0 }
+};
+
+static struct clk tegra_clk_audio = {
+ .name = "audio",
+ .inputs = mux_audio_sync_clk,
+ .reg = 0x38,
+ .max_rate = 24000000,
+ .ops = &tegra_audio_sync_clk_ops
};
-/* FIXME: need tegra_audio
static struct clk tegra_clk_audio_2x = {
- .name = "clk_d",
+ .name = "audio_2x",
.flags = PERIPH_NO_RESET,
+ .max_rate = 48000000,
.ops = &tegra_clk_double_ops,
.clk_num = 89,
.reg = 0x34,
.reg_shift = 8,
- .parent = &tegra_audio,
+ .parent = &tegra_clk_audio,
+};
+
+struct clk_lookup tegra_audio_clk_lookups[] = {
+ { .con_id = "audio", .clk = &tegra_clk_audio },
+ { .con_id = "audio_2x", .clk = &tegra_clk_audio_2x }
+};
+
+/* This is called after peripheral clocks are initialized, as the
+ * audio_sync clock depends on some of the peripheral clocks.
+ */
+
+static void init_audio_sync_clock_mux(void)
+{
+ int i;
+ struct clk_mux_sel *sel = mux_audio_sync_clk;
+ const struct audio_sources *src = mux_audio_sync_clk_sources;
+ struct clk_lookup *lookup;
+
+ for (i = 0; src->name; i++, sel++, src++) {
+ sel->input = tegra_get_clock_by_name(src->name);
+ if (!sel->input)
+ pr_err("%s: could not find clk %s\n", __func__,
+ src->name);
+ sel->value = src->value;
+ }
+
+ lookup = tegra_audio_clk_lookups;
+ for (i = 0; i < ARRAY_SIZE(tegra_audio_clk_lookups); i++, lookup++) {
+ clk_init(lookup->clk);
+ clkdev_add(lookup);
+ }
}
-*/
static struct clk_mux_sel mux_cclk[] = {
{ .input = &tegra_clk_m, .value = 0},
@@ -1077,27 +1466,40 @@ static struct clk_mux_sel mux_sclk[] = {
{ 0, 0},
};
-static struct clk tegra_clk_cpu = {
- .name = "cpu",
+static struct clk tegra_clk_cclk = {
+ .name = "cclk",
.inputs = mux_cclk,
.reg = 0x20,
.ops = &tegra_super_ops,
+ .max_rate = 1000000000,
};
-static struct clk tegra_clk_sys = {
- .name = "sys",
+static struct clk tegra_clk_sclk = {
+ .name = "sclk",
.inputs = mux_sclk,
.reg = 0x28,
.ops = &tegra_super_ops,
+ .max_rate = 600000000,
+};
+
+static struct clk tegra_clk_virtual_cpu = {
+ .name = "cpu",
+ .parent = &tegra_clk_cclk,
+ .main = &tegra_pll_x,
+ .backup = &tegra_clk_m,
+ .ops = &tegra_cpu_ops,
+ .max_rate = 1000000000,
+ .dvfs = &tegra_dvfs_virtual_cpu_dvfs,
};
static struct clk tegra_clk_hclk = {
.name = "hclk",
.flags = DIV_BUS,
- .parent = &tegra_clk_sys,
+ .parent = &tegra_clk_sclk,
.reg = 0x30,
.reg_shift = 4,
.ops = &tegra_bus_ops,
+ .max_rate = 240000000,
};
static struct clk tegra_clk_pclk = {
@@ -1107,6 +1509,7 @@ static struct clk tegra_clk_pclk = {
.reg = 0x30,
.reg_shift = 0,
.ops = &tegra_bus_ops,
+ .max_rate = 108000000,
};
static struct clk_mux_sel mux_pllm_pllc_pllp_plla[] = {
@@ -1133,10 +1536,9 @@ static struct clk_mux_sel mux_pllp_pllc_pllm_clkm[] = {
{ 0, 0},
};
-static struct clk_mux_sel mux_plla_audio_pllp_clkm[] = {
- {.input = &tegra_pll_a, .value = 0},
- /* FIXME: no mux defined for tegra_audio
- {.input = &tegra_audio, .value = 1},*/
+static struct clk_mux_sel mux_pllaout0_audio2x_pllp_clkm[] = {
+ {.input = &tegra_pll_a_out0, .value = 0},
+ {.input = &tegra_clk_audio_2x, .value = 1},
{.input = &tegra_pll_p, .value = 2},
{.input = &tegra_clk_m, .value = 3},
{ 0, 0},
@@ -1153,8 +1555,7 @@ static struct clk_mux_sel mux_pllp_plld_pllc_clkm[] = {
static struct clk_mux_sel mux_pllp_pllc_audio_clkm_clk32[] = {
{.input = &tegra_pll_p, .value = 0},
{.input = &tegra_pll_c, .value = 1},
- /* FIXME: no mux defined for tegra_audio
- {.input = &tegra_audio, .value = 2},*/
+ {.input = &tegra_clk_audio, .value = 2},
{.input = &tegra_clk_m, .value = 3},
{.input = &tegra_clk_32k, .value = 4},
{ 0, 0},
@@ -1187,7 +1588,7 @@ static struct clk_mux_sel mux_clk_32k[] = {
{ 0, 0},
};
-#define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, _inputs, _flags) \
+#define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, _max, _inputs, _flags) \
{ \
.name = _name, \
.lookup = { \
@@ -1199,72 +1600,79 @@ static struct clk_mux_sel mux_clk_32k[] = {
.reg = _reg, \
.inputs = _inputs, \
.flags = _flags, \
+ .max_rate = _max, \
}
struct clk tegra_periph_clks[] = {
- PERIPH_CLK("rtc", "rtc-tegra", NULL, 4, 0, mux_clk_32k, PERIPH_NO_RESET),
- PERIPH_CLK("timer", "timer", NULL, 5, 0, mux_clk_m, 0),
- PERIPH_CLK("i2s1", "i2s.0", NULL, 11, 0x100, mux_plla_audio_pllp_clkm, MUX | DIV_U71),
- PERIPH_CLK("i2s2", "i2s.1", NULL, 18, 0x104, mux_plla_audio_pllp_clkm, MUX | DIV_U71),
+ PERIPH_CLK("rtc", "rtc-tegra", NULL, 4, 0, 32768, mux_clk_32k, PERIPH_NO_RESET),
+ PERIPH_CLK("timer", "timer", NULL, 5, 0, 26000000, mux_clk_m, 0),
+ PERIPH_CLK("i2s1", "i2s.0", NULL, 11, 0x100, 26000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71),
+ PERIPH_CLK("i2s2", "i2s.1", NULL, 18, 0x104, 26000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71),
/* FIXME: spdif has 2 clocks but 1 enable */
- PERIPH_CLK("spdif_out", "spdif_out", NULL, 10, 0x108, mux_plla_audio_pllp_clkm, MUX | DIV_U71),
- PERIPH_CLK("spdif_in", "spdif_in", NULL, 10, 0x10c, mux_pllp_pllc_pllm, MUX | DIV_U71),
- PERIPH_CLK("pwm", "pwm", NULL, 17, 0x110, mux_pllp_pllc_audio_clkm_clk32, MUX | DIV_U71),
- PERIPH_CLK("spi", "spi", NULL, 43, 0x114, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
- PERIPH_CLK("xio", "xio", NULL, 45, 0x120, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
- PERIPH_CLK("twc", "twc", NULL, 16, 0x12c, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
- PERIPH_CLK("sbc1", "spi_tegra.0", NULL, 41, 0x134, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
- PERIPH_CLK("sbc2", "spi_tegra.1", NULL, 44, 0x118, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
- PERIPH_CLK("sbc3", "spi_tegra.2", NULL, 46, 0x11c, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
- PERIPH_CLK("sbc4", "spi_tegra.3", NULL, 68, 0x1b4, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
- PERIPH_CLK("ide", "ide", NULL, 25, 0x144, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
- PERIPH_CLK("ndflash", "tegra_nand", NULL, 13, 0x160, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("spdif_out", "spdif_out", NULL, 10, 0x108, 100000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71),
+ PERIPH_CLK("spdif_in", "spdif_in", NULL, 10, 0x10c, 100000000, mux_pllp_pllc_pllm, MUX | DIV_U71),
+ PERIPH_CLK("pwm", "pwm", NULL, 17, 0x110, 432000000, mux_pllp_pllc_audio_clkm_clk32, MUX | DIV_U71),
+ PERIPH_CLK("spi", "spi", NULL, 43, 0x114, 40000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("xio", "xio", NULL, 45, 0x120, 150000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("twc", "twc", NULL, 16, 0x12c, 150000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("sbc1", "spi_tegra.0", NULL, 41, 0x134, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("sbc2", "spi_tegra.1", NULL, 44, 0x118, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("sbc3", "spi_tegra.2", NULL, 46, 0x11c, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("sbc4", "spi_tegra.3", NULL, 68, 0x1b4, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("ide", "ide", NULL, 25, 0x144, 100000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* requires min voltage */
+ PERIPH_CLK("ndflash", "tegra_nand", NULL, 13, 0x160, 164000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
/* FIXME: vfir shares an enable with uartb */
- PERIPH_CLK("vfir", "vfir", NULL, 7, 0x168, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
- PERIPH_CLK("sdmmc1", "sdhci-tegra.0", NULL, 14, 0x150, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
- PERIPH_CLK("sdmmc2", "sdhci-tegra.1", NULL, 9, 0x154, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
- PERIPH_CLK("sdmmc3", "sdhci-tegra.2", NULL, 69, 0x1bc, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
- PERIPH_CLK("sdmmc4", "sdhci-tegra.3", NULL, 15, 0x160, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
- PERIPH_CLK("vde", "vde", NULL, 61, 0x1c8, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
- PERIPH_CLK("csite", "csite", NULL, 73, 0x1d4, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("vfir", "vfir", NULL, 7, 0x168, 72000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("sdmmc1", "sdhci-tegra.0", NULL, 14, 0x150, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
+ PERIPH_CLK("sdmmc2", "sdhci-tegra.1", NULL, 9, 0x154, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
+ PERIPH_CLK("sdmmc3", "sdhci-tegra.2", NULL, 69, 0x1bc, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
+ PERIPH_CLK("sdmmc4", "sdhci-tegra.3", NULL, 15, 0x160, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
+ PERIPH_CLK("vde", "vde", NULL, 61, 0x1c8, 250000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage and process_id */
+ PERIPH_CLK("csite", "csite", NULL, 73, 0x1d4, 144000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* max rate ??? */
/* FIXME: what is la? */
- PERIPH_CLK("la", "la", NULL, 76, 0x1f8, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
- PERIPH_CLK("owr", "owr", NULL, 71, 0x1cc, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
- PERIPH_CLK("nor", "nor", NULL, 42, 0x1d0, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
- PERIPH_CLK("mipi", "mipi", NULL, 50, 0x174, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
- PERIPH_CLK("i2c1", "tegra-i2c.0", NULL, 12, 0x124, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
- PERIPH_CLK("i2c2", "tegra-i2c.1", NULL, 54, 0x198, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
- PERIPH_CLK("i2c3", "tegra-i2c.2", NULL, 67, 0x1b8, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
- PERIPH_CLK("dvc", "tegra-i2c.3", NULL, 47, 0x128, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
- PERIPH_CLK("i2c1_i2c", "tegra-i2c.0", "i2c", 0, 0, mux_pllp_out3, 0),
- PERIPH_CLK("i2c2_i2c", "tegra-i2c.1", "i2c", 0, 0, mux_pllp_out3, 0),
- PERIPH_CLK("i2c3_i2c", "tegra-i2c.2", "i2c", 0, 0, mux_pllp_out3, 0),
- PERIPH_CLK("dvc_i2c", "tegra-i2c.3", "i2c", 0, 0, mux_pllp_out3, 0),
- PERIPH_CLK("uarta", "uart.0", NULL, 6, 0x178, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
- PERIPH_CLK("uartb", "uart.1", NULL, 7, 0x17c, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
- PERIPH_CLK("uartc", "uart.2", NULL, 55, 0x1a0, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
- PERIPH_CLK("uartd", "uart.3", NULL, 65, 0x1c0, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
- PERIPH_CLK("uarte", "uart.4", NULL, 66, 0x1c4, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
- PERIPH_CLK("3d", "3d", NULL, 24, 0x158, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_MANUAL_RESET),
- PERIPH_CLK("2d", "2d", NULL, 21, 0x15c, mux_pllm_pllc_pllp_plla, MUX | DIV_U71),
+ PERIPH_CLK("la", "la", NULL, 76, 0x1f8, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("owr", "tegra_w1", NULL, 71, 0x1cc, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("nor", "nor", NULL, 42, 0x1d0, 92000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* requires min voltage */
+ PERIPH_CLK("mipi", "mipi", NULL, 50, 0x174, 60000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
+ PERIPH_CLK("i2c1", "tegra-i2c.0", NULL, 12, 0x124, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16),
+ PERIPH_CLK("i2c2", "tegra-i2c.1", NULL, 54, 0x198, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16),
+ PERIPH_CLK("i2c3", "tegra-i2c.2", NULL, 67, 0x1b8, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16),
+ PERIPH_CLK("dvc", "tegra-i2c.3", NULL, 47, 0x128, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16),
+ PERIPH_CLK("i2c1_i2c", "tegra-i2c.0", "i2c", 0, 0, 72000000, mux_pllp_out3, 0),
+ PERIPH_CLK("i2c2_i2c", "tegra-i2c.1", "i2c", 0, 0, 72000000, mux_pllp_out3, 0),
+ PERIPH_CLK("i2c3_i2c", "tegra-i2c.2", "i2c", 0, 0, 72000000, mux_pllp_out3, 0),
+ PERIPH_CLK("dvc_i2c", "tegra-i2c.3", "i2c", 0, 0, 72000000, mux_pllp_out3, 0),
+ PERIPH_CLK("uarta", "uart.0", NULL, 6, 0x178, 216000000, mux_pllp_pllc_pllm_clkm, MUX),
+ PERIPH_CLK("uartb", "uart.1", NULL, 7, 0x17c, 216000000, mux_pllp_pllc_pllm_clkm, MUX),
+ PERIPH_CLK("uartc", "uart.2", NULL, 55, 0x1a0, 216000000, mux_pllp_pllc_pllm_clkm, MUX),
+ PERIPH_CLK("uartd", "uart.3", NULL, 65, 0x1c0, 216000000, mux_pllp_pllc_pllm_clkm, MUX),
+ PERIPH_CLK("uarte", "uart.4", NULL, 66, 0x1c4, 216000000, mux_pllp_pllc_pllm_clkm, MUX),
+ PERIPH_CLK("3d", "3d", NULL, 24, 0x158, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_MANUAL_RESET), /* scales with voltage and process_id */
+ PERIPH_CLK("2d", "2d", NULL, 21, 0x15c, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
/* FIXME: vi and vi_sensor share an enable */
- PERIPH_CLK("vi", "vi", NULL, 20, 0x148, mux_pllm_pllc_pllp_plla, MUX | DIV_U71),
- PERIPH_CLK("vi_sensor", "vi_sensor", NULL, 20, 0x1a8, mux_pllm_pllc_pllp_plla, MUX | DIV_U71),
- PERIPH_CLK("epp", "epp", NULL, 19, 0x16c, mux_pllm_pllc_pllp_plla, MUX | DIV_U71),
- PERIPH_CLK("mpe", "mpe", NULL, 60, 0x170, mux_pllm_pllc_pllp_plla, MUX | DIV_U71),
- PERIPH_CLK("host1x", "host1x", NULL, 28, 0x180, mux_pllm_pllc_pllp_plla, MUX | DIV_U71),
+ PERIPH_CLK("vi", "vi", NULL, 20, 0x148, 150000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
+ PERIPH_CLK("vi_sensor", "vi_sensor", NULL, 20, 0x1a8, 150000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_NO_RESET), /* scales with voltage and process_id */
+ PERIPH_CLK("epp", "epp", NULL, 19, 0x16c, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
+ PERIPH_CLK("mpe", "mpe", NULL, 60, 0x170, 250000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
+ PERIPH_CLK("host1x", "host1x", NULL, 28, 0x180, 166000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
/* FIXME: cve and tvo share an enable */
- PERIPH_CLK("cve", "cve", NULL, 49, 0x140, mux_pllp_plld_pllc_clkm, MUX | DIV_U71),
- PERIPH_CLK("tvo", "tvo", NULL, 49, 0x188, mux_pllp_plld_pllc_clkm, MUX | DIV_U71),
- PERIPH_CLK("hdmi", "hdmi", NULL, 51, 0x18c, mux_pllp_plld_pllc_clkm, MUX | DIV_U71),
- PERIPH_CLK("tvdac", "tvdac", NULL, 53, 0x194, mux_pllp_plld_pllc_clkm, MUX | DIV_U71),
- PERIPH_CLK("disp1", "tegrafb.0", NULL, 27, 0x138, mux_pllp_plld_pllc_clkm, MUX | DIV_U71),
- PERIPH_CLK("disp2", "tegrafb.1", NULL, 26, 0x13c, mux_pllp_plld_pllc_clkm, MUX | DIV_U71),
- PERIPH_CLK("usbd", "fsl-tegra-udc", NULL, 22, 0, mux_clk_m, 0),
- PERIPH_CLK("usb2", "usb.1", NULL, 58, 0, mux_clk_m, 0),
- PERIPH_CLK("usb3", "usb.2", NULL, 59, 0, mux_clk_m, 0),
- PERIPH_CLK("emc", "emc", NULL, 57, 0x19c, mux_pllm_pllc_pllp_clkm, MUX | DIV_U71 | PERIPH_EMC_ENB),
- PERIPH_CLK("dsi", "dsi", NULL, 48, 0, mux_plld, 0),
+ PERIPH_CLK("cve", "cve", NULL, 49, 0x140, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
+ PERIPH_CLK("tvo", "tvo", NULL, 49, 0x188, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
+ PERIPH_CLK("hdmi", "hdmi", NULL, 51, 0x18c, 148500000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
+ PERIPH_CLK("tvdac", "tvdac", NULL, 53, 0x194, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
+ PERIPH_CLK("disp1", "tegrafb.0", NULL, 27, 0x138, 190000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* scales with voltage and process_id */
+ PERIPH_CLK("disp2", "tegrafb.1", NULL, 26, 0x13c, 190000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* scales with voltage and process_id */
+ PERIPH_CLK("usbd", "fsl-tegra-udc", NULL, 22, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
+ PERIPH_CLK("usb2", "tegra-ehci.1", NULL, 58, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
+ PERIPH_CLK("usb3", "tegra-ehci.2", NULL, 59, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
+ PERIPH_CLK("emc", "emc", NULL, 57, 0x19c, 800000000, mux_pllm_pllc_pllp_clkm, MUX | DIV_U71 | PERIPH_EMC_ENB),
+ PERIPH_CLK("dsi", "dsi", NULL, 48, 0, 500000000, mux_plld, 0), /* scales with voltage */
+ PERIPH_CLK("csi", "csi", NULL, 52, 0, 72000000, mux_pllp_out3, 0),
+ PERIPH_CLK("isp", "isp", NULL, 23, 0, 150000000, mux_clk_m, 0), /* same frequency as VI */
+ PERIPH_CLK("csus", "csus", NULL, 92, 0, 150000000, mux_clk_m, PERIPH_NO_RESET),
+ PERIPH_CLK("pex", NULL, "pex", 70, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET),
+ PERIPH_CLK("afi", NULL, "afi", 72, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET),
+ PERIPH_CLK("pcie_xclk", NULL, "pcie_xclk", 74, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET),
};
#define CLK_DUPLICATE(_name, _dev, _con) \
@@ -1286,6 +1694,9 @@ struct clk_duplicate tegra_clk_duplicates[] = {
CLK_DUPLICATE("uartc", "tegra_uart.2", NULL),
CLK_DUPLICATE("uartd", "tegra_uart.3", NULL),
CLK_DUPLICATE("uarte", "tegra_uart.4", NULL),
+ CLK_DUPLICATE("host1x", "tegrafb.0", "host1x"),
+ CLK_DUPLICATE("host1x", "tegrafb.1", "host1x"),
+ CLK_DUPLICATE("usbd", "tegra-ehci.0", NULL),
};
#define CLK(dev, con, ck) \
@@ -1315,11 +1726,13 @@ struct clk_lookup tegra_clk_lookups[] = {
CLK(NULL, "pll_d_out0", &tegra_pll_d_out0),
CLK(NULL, "pll_u", &tegra_pll_u),
CLK(NULL, "pll_x", &tegra_pll_x),
- CLK(NULL, "cpu", &tegra_clk_cpu),
- CLK(NULL, "sys", &tegra_clk_sys),
+ CLK(NULL, "pll_e", &tegra_pll_e),
+ CLK(NULL, "cclk", &tegra_clk_cclk),
+ CLK(NULL, "sclk", &tegra_clk_sclk),
CLK(NULL, "hclk", &tegra_clk_hclk),
CLK(NULL, "pclk", &tegra_clk_pclk),
CLK(NULL, "clk_d", &tegra_clk_d),
+ CLK(NULL, "cpu", &tegra_clk_virtual_cpu),
};
void __init tegra2_init_clocks(void)
@@ -1356,4 +1769,75 @@ void __init tegra2_init_clocks(void)
cd->name);
}
}
+
+ init_audio_sync_clock_mux();
+}
+
+#ifdef CONFIG_PM
+static u32 clk_rst_suspend[RST_DEVICES_NUM + CLK_OUT_ENB_NUM +
+ PERIPH_CLK_SOURCE_NUM + 3];
+
+void tegra_clk_suspend(void)
+{
+ unsigned long off, i;
+ u32 *ctx = clk_rst_suspend;
+
+ *ctx++ = clk_readl(OSC_CTRL) & OSC_CTRL_MASK;
+
+ for (off = PERIPH_CLK_SOURCE_I2S1; off <= PERIPH_CLK_SOURCE_OSC;
+ off += 4) {
+ if (off == PERIPH_CLK_SOURCE_EMC)
+ continue;
+ *ctx++ = clk_readl(off);
+ }
+
+ off = RST_DEVICES;
+ for (i = 0; i < RST_DEVICES_NUM; i++, off += 4)
+ *ctx++ = clk_readl(off);
+
+ off = CLK_OUT_ENB;
+ for (i = 0; i < CLK_OUT_ENB_NUM; i++, off += 4)
+ *ctx++ = clk_readl(off);
+
+ *ctx++ = clk_readl(MISC_CLK_ENB);
+ *ctx++ = clk_readl(CLK_MASK_ARM);
+}
+
+void tegra_clk_resume(void)
+{
+ unsigned long off, i;
+ const u32 *ctx = clk_rst_suspend;
+ u32 val;
+
+ val = clk_readl(OSC_CTRL) & ~OSC_CTRL_MASK;
+ val |= *ctx++;
+ clk_writel(val, OSC_CTRL);
+
+ /* enable all clocks before configuring clock sources */
+ clk_writel(0xbffffff9ul, CLK_OUT_ENB);
+ clk_writel(0xfefffff7ul, CLK_OUT_ENB + 4);
+ clk_writel(0x77f01bfful, CLK_OUT_ENB + 8);
+ wmb();
+
+ for (off = PERIPH_CLK_SOURCE_I2S1; off <= PERIPH_CLK_SOURCE_OSC;
+ off += 4) {
+ if (off == PERIPH_CLK_SOURCE_EMC)
+ continue;
+ clk_writel(*ctx++, off);
+ }
+ wmb();
+
+ off = RST_DEVICES;
+ for (i = 0; i < RST_DEVICES_NUM; i++, off += 4)
+ clk_writel(*ctx++, off);
+ wmb();
+
+ off = CLK_OUT_ENB;
+ for (i = 0; i < CLK_OUT_ENB_NUM; i++, off += 4)
+ clk_writel(*ctx++, off);
+ wmb();
+
+ clk_writel(*ctx++, MISC_CLK_ENB);
+ clk_writel(*ctx++, CLK_MASK_ARM);
}
+#endif
diff --git a/arch/arm/mach-tegra/tegra2_dvfs.c b/arch/arm/mach-tegra/tegra2_dvfs.c
new file mode 100644
index 000000000000..5529c238dd77
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra2_dvfs.c
@@ -0,0 +1,86 @@
+/*
+ * arch/arm/mach-tegra/tegra2_dvfs.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@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 <linux/kernel.h>
+
+#include "clock.h"
+#include "tegra2_dvfs.h"
+
+static struct dvfs_table virtual_cpu_process_0[] = {
+ {314000000, 750},
+ {456000000, 825},
+ {608000000, 900},
+ {760000000, 975},
+ {817000000, 1000},
+ {912000000, 1050},
+ {1000000000, 1100},
+ {0, 0},
+};
+
+static struct dvfs_table virtual_cpu_process_1[] = {
+ {314000000, 750},
+ {456000000, 825},
+ {618000000, 900},
+ {770000000, 975},
+ {827000000, 1000},
+ {922000000, 1050},
+ {1000000000, 1100},
+ {0, 0},
+};
+
+static struct dvfs_table virtual_cpu_process_2[] = {
+ {494000000, 750},
+ {675000000, 825},
+ {817000000, 875},
+ {922000000, 925},
+ {1000000000, 975},
+ {0, 0},
+};
+
+static struct dvfs_table virtual_cpu_process_3[] = {
+ {730000000, 750},
+ {760000000, 775},
+ {845000000, 800},
+ {1000000000, 875},
+ {0, 0},
+};
+
+struct dvfs tegra_dvfs_virtual_cpu_dvfs = {
+ .reg_id = "vdd_cpu",
+ .process_id_table = {
+ {
+ .process_id = 0,
+ .table = virtual_cpu_process_0,
+ },
+ {
+ .process_id = 1,
+ .table = virtual_cpu_process_1,
+ },
+ {
+ .process_id = 2,
+ .table = virtual_cpu_process_2,
+ },
+ {
+ .process_id = 3,
+ .table = virtual_cpu_process_3,
+ },
+ },
+ .process_id_table_length = 4,
+ .cpu = 1,
+};
diff --git a/arch/arm/mach-tegra/tegra2_dvfs.h b/arch/arm/mach-tegra/tegra2_dvfs.h
new file mode 100644
index 000000000000..f8c1adba96a6
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra2_dvfs.h
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/mach-tegra/tegra2_dvfs.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@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.
+ *
+ */
+
+extern struct dvfs tegra_dvfs_virtual_cpu_dvfs;
diff --git a/arch/arm/mach-tegra/timer.c b/arch/arm/mach-tegra/timer.c
index 2f420210d406..9057d6fd1d31 100644
--- a/arch/arm/mach-tegra/timer.c
+++ b/arch/arm/mach-tegra/timer.c
@@ -28,7 +28,6 @@
#include <linux/cnt32_to_63.h>
#include <asm/mach/time.h>
-#include <asm/mach/time.h>
#include <asm/localtimer.h>
#include <mach/iomap.h>
diff --git a/arch/arm/mach-u300/clock.c b/arch/arm/mach-u300/clock.c
index 60acf9e708ae..7458fc6df5c6 100644
--- a/arch/arm/mach-u300/clock.c
+++ b/arch/arm/mach-u300/clock.c
@@ -66,7 +66,7 @@ static DEFINE_SPINLOCK(syscon_resetreg_lock);
* AMBA bus
* |
* +- CPU
- * +- NANDIF NAND Flash interface
+ * +- FSMC NANDIF NAND Flash interface
* +- SEMI Shared Memory interface
* +- ISP Image Signal Processor (U335 only)
* +- CDS (U335 only)
@@ -726,7 +726,7 @@ static struct clk cpu_clk = {
};
static struct clk nandif_clk = {
- .name = "NANDIF",
+ .name = "FSMC",
.parent = &amba_clk,
.hw_ctrld = false,
.reset = true,
@@ -1259,7 +1259,7 @@ static struct clk_lookup lookups[] = {
/* Connected directly to the AMBA bus */
DEF_LOOKUP("amba", &amba_clk),
DEF_LOOKUP("cpu", &cpu_clk),
- DEF_LOOKUP("fsmc", &nandif_clk),
+ DEF_LOOKUP("fsmc-nand", &nandif_clk),
DEF_LOOKUP("semi", &semi_clk),
#ifdef CONFIG_MACH_U300_BS335
DEF_LOOKUP("isp", &isp_clk),
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c
index ea41c236be0f..aa53ee22438f 100644
--- a/arch/arm/mach-u300/core.c
+++ b/arch/arm/mach-u300/core.c
@@ -21,7 +21,8 @@
#include <linux/gpio.h>
#include <linux/clk.h>
#include <linux/err.h>
-#include <mach/coh901318.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/fsmc.h>
#include <asm/types.h>
#include <asm/setup.h>
@@ -30,6 +31,7 @@
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
+#include <mach/coh901318.h>
#include <mach/hardware.h>
#include <mach/syscon.h>
#include <mach/dma_channels.h>
@@ -285,6 +287,13 @@ static struct resource rtc_resources[] = {
*/
static struct resource fsmc_resources[] = {
{
+ .name = "nand_data",
+ .start = U300_NAND_CS0_PHYS_BASE,
+ .end = U300_NAND_CS0_PHYS_BASE + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "fsmc_regs",
.start = U300_NAND_IF_PHYS_BASE,
.end = U300_NAND_IF_PHYS_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
@@ -1429,11 +1438,39 @@ static struct platform_device rtc_device = {
.resource = rtc_resources,
};
-static struct platform_device fsmc_device = {
- .name = "nandif",
+static struct mtd_partition u300_partitions[] = {
+ {
+ .name = "bootrecords",
+ .offset = 0,
+ .size = SZ_128K,
+ },
+ {
+ .name = "free",
+ .offset = SZ_128K,
+ .size = 8064 * SZ_1K,
+ },
+ {
+ .name = "platform",
+ .offset = 8192 * SZ_1K,
+ .size = 253952 * SZ_1K,
+ },
+};
+
+static struct fsmc_nand_platform_data nand_platform_data = {
+ .partitions = u300_partitions,
+ .nr_partitions = ARRAY_SIZE(u300_partitions),
+ .options = NAND_SKIP_BBTSCAN,
+ .width = FSMC_NAND_BW8,
+};
+
+static struct platform_device nand_device = {
+ .name = "fsmc-nand",
.id = -1,
- .num_resources = ARRAY_SIZE(fsmc_resources),
.resource = fsmc_resources,
+ .num_resources = ARRAY_SIZE(fsmc_resources),
+ .dev = {
+ .platform_data = &nand_platform_data,
+ },
};
static struct platform_device ave_device = {
@@ -1465,7 +1502,7 @@ static struct platform_device *platform_devs[] __initdata = {
&keypad_device,
&rtc_device,
&gpio_device,
- &fsmc_device,
+ &nand_device,
&wdog_device,
&ave_device
};
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/include/mach/u300-regs.h b/arch/arm/mach-u300/include/mach/u300-regs.h
index 56721a0cd2af..8b85df4c8d8f 100644
--- a/arch/arm/mach-u300/include/mach/u300-regs.h
+++ b/arch/arm/mach-u300/include/mach/u300-regs.h
@@ -20,11 +20,9 @@
/* NAND Flash CS0 */
#define U300_NAND_CS0_PHYS_BASE 0x80000000
-#define U300_NAND_CS0_VIRT_BASE 0xff040000
/* NFIF */
#define U300_NAND_IF_PHYS_BASE 0x9f800000
-#define U300_NAND_IF_VIRT_BASE 0xff030000
/* AHB Peripherals */
#define U300_AHB_PER_PHYS_BASE 0xa0000000
diff --git a/arch/arm/mach-u300/spi.c b/arch/arm/mach-u300/spi.c
index f0e887bea30e..00869def5420 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_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/cpu.c b/arch/arm/mach-ux500/cpu.c
index e0fd747e447a..73fb1a551ec6 100644
--- a/arch/arm/mach-ux500/cpu.c
+++ b/arch/arm/mach-ux500/cpu.c
@@ -10,6 +10,7 @@
#include <linux/io.h>
#include <linux/clk.h>
+#include <asm/cacheflush.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/hardware/gic.h>
#include <asm/mach/map.h>
@@ -71,6 +72,46 @@ void __init ux500_init_irq(void)
}
#ifdef CONFIG_CACHE_L2X0
+static inline void ux500_cache_wait(void __iomem *reg, unsigned long mask)
+{
+ /* wait for the operation to complete */
+ while (readl(reg) & mask)
+ ;
+}
+
+static inline void ux500_cache_sync(void)
+{
+ void __iomem *base = __io_address(UX500_L2CC_BASE);
+ writel(0, base + L2X0_CACHE_SYNC);
+ ux500_cache_wait(base + L2X0_CACHE_SYNC, 1);
+}
+
+/*
+ * The L2 cache cannot be turned off in the non-secure world.
+ * Dummy until a secure service is in place.
+ */
+static void ux500_l2x0_disable(void)
+{
+}
+
+/*
+ * This is only called when doing a kexec, just after turning off the L2
+ * and L1 cache, and it is surrounded by a spinlock in the generic version.
+ * However, we're not really turning off the L2 cache right now and the
+ * PL310 does not support exclusive accesses (used to implement the spinlock).
+ * So, the invalidation needs to be done without the spinlock.
+ */
+static void ux500_l2x0_inv_all(void)
+{
+ void __iomem *l2x0_base = __io_address(UX500_L2CC_BASE);
+ uint32_t l2x0_way_mask = (1<<16) - 1; /* Bitmask of active ways */
+
+ /* invalidate all ways */
+ writel(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
+ ux500_cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
+ ux500_cache_sync();
+}
+
static int ux500_l2x0_init(void)
{
void __iomem *l2x0_base;
@@ -80,6 +121,10 @@ static int ux500_l2x0_init(void)
/* 64KB way size, 8 way associativity, force WA */
l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff);
+ /* Override invalidate function */
+ outer_cache.disable = ux500_l2x0_disable;
+ outer_cache.inv_all = ux500_l2x0_inv_all;
+
return 0;
}
early_initcall(ux500_l2x0_init);
diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c
index 9280d2561111..4a94be3304b9 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,
@@ -132,35 +208,25 @@ static struct resource dma40_resources[] = {
/* Default configuration for physcial memcpy */
struct stedma40_chan_cfg dma40_memcpy_conf_phy = {
- .channel_type = (STEDMA40_CHANNEL_IN_PHY_MODE |
- STEDMA40_LOW_PRIORITY_CHANNEL |
- STEDMA40_PCHAN_BASIC_MODE),
+ .mode = STEDMA40_MODE_PHYSICAL,
.dir = STEDMA40_MEM_TO_MEM,
- .src_info.endianess = STEDMA40_LITTLE_ENDIAN,
.src_info.data_width = STEDMA40_BYTE_WIDTH,
.src_info.psize = STEDMA40_PSIZE_PHY_1,
.src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
- .dst_info.endianess = STEDMA40_LITTLE_ENDIAN,
.dst_info.data_width = STEDMA40_BYTE_WIDTH,
.dst_info.psize = STEDMA40_PSIZE_PHY_1,
.dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
};
/* Default configuration for logical memcpy */
struct stedma40_chan_cfg dma40_memcpy_conf_log = {
- .channel_type = (STEDMA40_CHANNEL_IN_LOG_MODE |
- STEDMA40_LOW_PRIORITY_CHANNEL |
- STEDMA40_LCHAN_SRC_LOG_DST_LOG |
- STEDMA40_NO_TIM_FOR_LINK),
.dir = STEDMA40_MEM_TO_MEM,
- .src_info.endianess = STEDMA40_LITTLE_ENDIAN,
.src_info.data_width = STEDMA40_BYTE_WIDTH,
.src_info.psize = STEDMA40_PSIZE_LOG_1,
.src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
- .dst_info.endianess = STEDMA40_LITTLE_ENDIAN,
.dst_info.data_width = STEDMA40_BYTE_WIDTH,
.dst_info.psize = STEDMA40_PSIZE_LOG_1,
.dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
@@ -170,30 +236,29 @@ 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,
.memcpy_len = ARRAY_SIZE(dma40_memcpy_event),
.memcpy_conf_phy = &dma40_memcpy_conf_phy,
.memcpy_conf_log = &dma40_memcpy_conf_log,
- .llis_per_log = 8,
.disabled_channels = {-1},
};
@@ -216,3 +281,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 71fb17349520..c2e405a9e025 100644
--- a/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -245,8 +245,6 @@ static void __init 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-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/Kconfig b/arch/arm/mm/Kconfig
index a0a2928ae4dd..4414a01e1e8a 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -779,6 +779,14 @@ config CACHE_L2X0
help
This option enables the L2x0 PrimeCell.
+config CACHE_PL310
+ bool
+ depends on CACHE_L2X0
+ default y if CPU_V7 && !CPU_V6
+ help
+ This option enables optimisations for the PL310 cache
+ controller.
+
config CACHE_TAUROS2
bool "Enable the Tauros2 L2 cache controller"
depends on (ARCH_DOVE || ARCH_MMP)
diff --git a/arch/arm/mm/cache-fa.S b/arch/arm/mm/cache-fa.S
index 7148e53e6078..1fa6f71470de 100644
--- a/arch/arm/mm/cache-fa.S
+++ b/arch/arm/mm/cache-fa.S
@@ -38,6 +38,17 @@
#define CACHE_DLIMIT (CACHE_DSIZE * 2)
/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(fa_flush_icache_all)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mov pc, lr
+ENDPROC(fa_flush_icache_all)
+
+/*
* flush_user_cache_all()
*
* Clean and invalidate all cache entries in a particular address
@@ -233,6 +244,7 @@ ENDPROC(fa_dma_unmap_area)
.type fa_cache_fns, #object
ENTRY(fa_cache_fns)
+ .long fa_flush_icache_all
.long fa_flush_kern_cache_all
.long fa_flush_user_cache_all
.long fa_flush_user_cache_range
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 9982eb385c0f..170c9bb95866 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -28,14 +28,24 @@
static void __iomem *l2x0_base;
static DEFINE_SPINLOCK(l2x0_lock);
static uint32_t l2x0_way_mask; /* Bitmask of active ways */
+static uint32_t l2x0_size;
-static inline void cache_wait(void __iomem *reg, unsigned long mask)
+static inline void cache_wait_way(void __iomem *reg, unsigned long mask)
{
- /* wait for the operation to complete */
+ /* wait for cache operation by line or way to complete */
while (readl_relaxed(reg) & mask)
;
}
+#ifdef CONFIG_CACHE_PL310
+static inline void cache_wait(void __iomem *reg, unsigned long mask)
+{
+ /* cache operations by line are atomic on PL310 */
+}
+#else
+#define cache_wait cache_wait_way
+#endif
+
static inline void cache_sync(void)
{
void __iomem *base = l2x0_base;
@@ -103,14 +113,40 @@ static void l2x0_cache_sync(void)
spin_unlock_irqrestore(&l2x0_lock, flags);
}
-static inline void l2x0_inv_all(void)
+static void l2x0_flush_all(void)
+{
+ unsigned long flags;
+
+ /* clean all ways */
+ spin_lock_irqsave(&l2x0_lock, flags);
+ writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_INV_WAY);
+ cache_wait_way(l2x0_base + L2X0_CLEAN_INV_WAY, l2x0_way_mask);
+ cache_sync();
+ spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
+static void l2x0_clean_all(void)
+{
+ unsigned long flags;
+
+ /* clean all ways */
+ spin_lock_irqsave(&l2x0_lock, flags);
+ writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_WAY);
+ cache_wait_way(l2x0_base + L2X0_CLEAN_WAY, l2x0_way_mask);
+ cache_sync();
+ spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
+static void l2x0_inv_all(void)
{
unsigned long flags;
/* invalidate all ways */
spin_lock_irqsave(&l2x0_lock, flags);
+ /* Invalidating when L2 is enabled is a nono */
+ BUG_ON(readl(l2x0_base + L2X0_CTRL) & 1);
writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
- cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
+ cache_wait_way(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
cache_sync();
spin_unlock_irqrestore(&l2x0_lock, flags);
}
@@ -159,6 +195,11 @@ static void l2x0_clean_range(unsigned long start, unsigned long end)
void __iomem *base = l2x0_base;
unsigned long flags;
+ if ((end - start) >= l2x0_size) {
+ l2x0_clean_all();
+ return;
+ }
+
spin_lock_irqsave(&l2x0_lock, flags);
start &= ~(CACHE_LINE_SIZE - 1);
while (start < end) {
@@ -184,6 +225,11 @@ static void l2x0_flush_range(unsigned long start, unsigned long end)
void __iomem *base = l2x0_base;
unsigned long flags;
+ if ((end - start) >= l2x0_size) {
+ l2x0_flush_all();
+ return;
+ }
+
spin_lock_irqsave(&l2x0_lock, flags);
start &= ~(CACHE_LINE_SIZE - 1);
while (start < end) {
@@ -206,10 +252,20 @@ static void l2x0_flush_range(unsigned long start, unsigned long end)
spin_unlock_irqrestore(&l2x0_lock, flags);
}
+static void l2x0_disable(void)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&l2x0_lock, flags);
+ writel(0, l2x0_base + L2X0_CTRL);
+ spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
{
__u32 aux;
__u32 cache_id;
+ __u32 way_size = 0;
int ways;
const char *type;
@@ -244,6 +300,13 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
l2x0_way_mask = (1 << ways) - 1;
/*
+ * L2 cache Size = Way size * Number of ways
+ */
+ way_size = (aux & L2X0_AUX_CTRL_WAY_SIZE_MASK) >> 17;
+ way_size = 1 << (way_size + 3);
+ l2x0_size = ways * way_size * SZ_1K;
+
+ /*
* Check if l2x0 controller is already enabled.
* If you are booting from non-secure mode
* accessing the below registers will fault.
@@ -263,8 +326,11 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
outer_cache.clean_range = l2x0_clean_range;
outer_cache.flush_range = l2x0_flush_range;
outer_cache.sync = l2x0_cache_sync;
+ outer_cache.flush_all = l2x0_flush_all;
+ outer_cache.inv_all = l2x0_inv_all;
+ outer_cache.disable = l2x0_disable;
printk(KERN_INFO "%s cache controller enabled\n", type);
- printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x\n",
- ways, cache_id, aux);
+ printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n",
+ ways, cache_id, aux, l2x0_size);
}
diff --git a/arch/arm/mm/cache-v3.S b/arch/arm/mm/cache-v3.S
index c2ff3c599fee..2e2bc406a18d 100644
--- a/arch/arm/mm/cache-v3.S
+++ b/arch/arm/mm/cache-v3.S
@@ -13,6 +13,15 @@
#include "proc-macros.S"
/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(v3_flush_icache_all)
+ mov pc, lr
+ENDPROC(v3_flush_icache_all)
+
+/*
* flush_user_cache_all()
*
* Invalidate all cache entries in a particular address
@@ -122,6 +131,7 @@ ENDPROC(v3_dma_map_area)
.type v3_cache_fns, #object
ENTRY(v3_cache_fns)
+ .long v3_flush_icache_all
.long v3_flush_kern_cache_all
.long v3_flush_user_cache_all
.long v3_flush_user_cache_range
diff --git a/arch/arm/mm/cache-v4.S b/arch/arm/mm/cache-v4.S
index 4810f7e3e813..a8fefb523f19 100644
--- a/arch/arm/mm/cache-v4.S
+++ b/arch/arm/mm/cache-v4.S
@@ -13,6 +13,15 @@
#include "proc-macros.S"
/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(v4_flush_icache_all)
+ mov pc, lr
+ENDPROC(v4_flush_icache_all)
+
+/*
* flush_user_cache_all()
*
* Invalidate all cache entries in a particular address
@@ -134,6 +143,7 @@ ENDPROC(v4_dma_map_area)
.type v4_cache_fns, #object
ENTRY(v4_cache_fns)
+ .long v4_flush_icache_all
.long v4_flush_kern_cache_all
.long v4_flush_user_cache_all
.long v4_flush_user_cache_range
diff --git a/arch/arm/mm/cache-v4wb.S b/arch/arm/mm/cache-v4wb.S
index df8368afa102..d3644db467b7 100644
--- a/arch/arm/mm/cache-v4wb.S
+++ b/arch/arm/mm/cache-v4wb.S
@@ -51,6 +51,17 @@ flush_base:
.text
/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(v4wb_flush_icache_all)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mov pc, lr
+ENDPROC(v4wb_flush_icache_all)
+
+/*
* flush_user_cache_all()
*
* Clean and invalidate all cache entries in a particular address
@@ -244,6 +255,7 @@ ENDPROC(v4wb_dma_unmap_area)
.type v4wb_cache_fns, #object
ENTRY(v4wb_cache_fns)
+ .long v4wb_flush_icache_all
.long v4wb_flush_kern_cache_all
.long v4wb_flush_user_cache_all
.long v4wb_flush_user_cache_range
diff --git a/arch/arm/mm/cache-v4wt.S b/arch/arm/mm/cache-v4wt.S
index 45c70312f43b..49c2b66cf3dd 100644
--- a/arch/arm/mm/cache-v4wt.S
+++ b/arch/arm/mm/cache-v4wt.S
@@ -41,6 +41,17 @@
#define CACHE_DLIMIT 16384
/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(v4wt_flush_icache_all)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mov pc, lr
+ENDPROC(v4wt_flush_icache_all)
+
+/*
* flush_user_cache_all()
*
* Invalidate all cache entries in a particular address
@@ -188,6 +199,7 @@ ENDPROC(v4wt_dma_map_area)
.type v4wt_cache_fns, #object
ENTRY(v4wt_cache_fns)
+ .long v4wt_flush_icache_all
.long v4wt_flush_kern_cache_all
.long v4wt_flush_user_cache_all
.long v4wt_flush_user_cache_range
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..83e59f870426 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.
@@ -65,6 +66,30 @@ static int do_adjust_pte(struct vm_area_struct *vma, unsigned long address,
return ret;
}
+#if USE_SPLIT_PTLOCKS
+/*
+ * If we are using split PTE locks, then we need to take the page
+ * lock here. Otherwise we are using shared mm->page_table_lock
+ * which is already locked, thus cannot take it.
+ */
+static inline void do_pte_lock(spinlock_t *ptl)
+{
+ /*
+ * Use nested version here to indicate that we are already
+ * holding one similar spinlock.
+ */
+ spin_lock_nested(ptl, SINGLE_DEPTH_NESTING);
+}
+
+static inline void do_pte_unlock(spinlock_t *ptl)
+{
+ spin_unlock(ptl);
+}
+#else /* !USE_SPLIT_PTLOCKS */
+static inline void do_pte_lock(spinlock_t *ptl) {}
+static inline void do_pte_unlock(spinlock_t *ptl) {}
+#endif /* USE_SPLIT_PTLOCKS */
+
static int adjust_pte(struct vm_area_struct *vma, unsigned long address,
unsigned long pfn)
{
@@ -88,13 +113,13 @@ static int adjust_pte(struct vm_area_struct *vma, unsigned long address,
* open-code the spin-locking.
*/
ptl = pte_lockptr(vma->vm_mm, pmd);
- pte = pte_offset_map_nested(pmd, address);
- spin_lock(ptl);
+ pte = pte_offset_map(pmd, address);
+ do_pte_lock(ptl);
ret = do_adjust_pte(vma, address, pfn, pte);
- spin_unlock(ptl);
- pte_unmap_nested(pte);
+ do_pte_unlock(ptl);
+ pte_unmap(pte);
return ret;
}
@@ -141,7 +166,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 +193,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 +202,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/highmem.c b/arch/arm/mm/highmem.c
index 1fbdb55bfd1b..c435fd9e1da9 100644
--- a/arch/arm/mm/highmem.c
+++ b/arch/arm/mm/highmem.c
@@ -36,18 +36,17 @@ void kunmap(struct page *page)
}
EXPORT_SYMBOL(kunmap);
-void *kmap_atomic(struct page *page, enum km_type type)
+void *__kmap_atomic(struct page *page)
{
unsigned int idx;
unsigned long vaddr;
void *kmap;
+ int type;
pagefault_disable();
if (!PageHighMem(page))
return page_address(page);
- debug_kmap_atomic(type);
-
#ifdef CONFIG_DEBUG_HIGHMEM
/*
* There is no cache coherency issue when non VIVT, so force the
@@ -61,6 +60,8 @@ void *kmap_atomic(struct page *page, enum km_type type)
if (kmap)
return kmap;
+ type = kmap_atomic_idx_push();
+
idx = type + KM_TYPE_NR * smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
#ifdef CONFIG_DEBUG_HIGHMEM
@@ -80,14 +81,17 @@ void *kmap_atomic(struct page *page, enum km_type type)
return (void *)vaddr;
}
-EXPORT_SYMBOL(kmap_atomic);
+EXPORT_SYMBOL(__kmap_atomic);
-void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type)
+void __kunmap_atomic(void *kvaddr)
{
unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
- unsigned int idx = type + KM_TYPE_NR * smp_processor_id();
+ int idx, type;
if (kvaddr >= (void *)FIXADDR_START) {
+ type = kmap_atomic_idx();
+ idx = type + KM_TYPE_NR * smp_processor_id();
+
if (cache_is_vivt())
__cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
#ifdef CONFIG_DEBUG_HIGHMEM
@@ -97,21 +101,23 @@ void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type)
#else
(void) idx; /* to kill a warning */
#endif
+ kmap_atomic_idx_pop();
} else if (vaddr >= PKMAP_ADDR(0) && vaddr < PKMAP_ADDR(LAST_PKMAP)) {
/* this address was obtained through kmap_high_get() */
kunmap_high(pte_page(pkmap_page_table[PKMAP_NR(vaddr)]));
}
pagefault_enable();
}
-EXPORT_SYMBOL(kunmap_atomic_notypecheck);
+EXPORT_SYMBOL(__kunmap_atomic);
-void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
+void *kmap_atomic_pfn(unsigned long pfn)
{
- unsigned int idx;
unsigned long vaddr;
+ int idx, type;
pagefault_disable();
+ type = kmap_atomic_idx_push();
idx = type + KM_TYPE_NR * smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
#ifdef CONFIG_DEBUG_HIGHMEM
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 7185b00650fe..5164069ced42 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -18,6 +18,7 @@
#include <linux/highmem.h>
#include <linux/gfp.h>
#include <linux/memblock.h>
+#include <linux/sort.h>
#include <asm/mach-types.h>
#include <asm/sections.h>
@@ -121,9 +122,10 @@ void show_mem(void)
printk("%d pages swap cached\n", cached);
}
-static void __init find_limits(struct meminfo *mi,
- unsigned long *min, unsigned long *max_low, unsigned long *max_high)
+static void __init find_limits(unsigned long *min, unsigned long *max_low,
+ unsigned long *max_high)
{
+ struct meminfo *mi = &meminfo;
int i;
*min = -1UL;
@@ -147,13 +149,13 @@ 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)
+static void __init arm_bootmem_init(unsigned long start_pfn,
+ unsigned long end_pfn)
{
+ struct memblock_region *reg;
unsigned int boot_pages;
phys_addr_t bitmap;
pg_data_t *pgdat;
- int i;
/*
* Allocate the bootmem bitmap page. This must be in a region
@@ -171,30 +173,39 @@ static void __init arm_bootmem_init(struct meminfo *mi,
pgdat = NODE_DATA(0);
init_bootmem_node(pgdat, __phys_to_pfn(bitmap), start_pfn, end_pfn);
- for_each_bank(i, mi) {
- struct membank *bank = &mi->bank[i];
- if (!bank->highmem)
- free_bootmem(bank_phys_start(bank), bank_phys_size(bank));
+ /* Free the lowmem regions from memblock into bootmem. */
+ for_each_memblock(memory, reg) {
+ unsigned long start = memblock_region_memory_base_pfn(reg);
+ unsigned long end = memblock_region_memory_end_pfn(reg);
+
+ if (end >= end_pfn)
+ end = end_pfn;
+ if (start >= end)
+ break;
+
+ free_bootmem(__pfn_to_phys(start), (end - start) << PAGE_SHIFT);
}
- /*
- * 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)
- reserve_bootmem_node(pgdat, __pfn_to_phys(start),
- memblock_size_bytes(&memblock.reserved, i),
- BOOTMEM_DEFAULT);
+ /* Reserve the lowmem memblock reserved regions in bootmem. */
+ for_each_memblock(reserved, reg) {
+ unsigned long start = memblock_region_reserved_base_pfn(reg);
+ unsigned long end = memblock_region_reserved_end_pfn(reg);
+
+ if (end >= end_pfn)
+ end = end_pfn;
+ if (start >= end)
+ break;
+
+ reserve_bootmem(__pfn_to_phys(start),
+ (end - start) << PAGE_SHIFT, BOOTMEM_DEFAULT);
}
}
-static void __init arm_bootmem_free(struct meminfo *mi, unsigned long min,
- unsigned long max_low, unsigned long max_high)
+static void __init arm_bootmem_free(unsigned long min, unsigned long max_low,
+ unsigned long max_high)
{
unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES];
- int i;
+ struct memblock_region *reg;
/*
* initialise the zones.
@@ -216,13 +227,20 @@ static void __init arm_bootmem_free(struct meminfo *mi, unsigned long min,
* holes = node_size - sum(bank_sizes)
*/
memcpy(zhole_size, zone_size, sizeof(zhole_size));
- for_each_bank(i, mi) {
- int idx = 0;
+ for_each_memblock(memory, reg) {
+ unsigned long start = memblock_region_memory_base_pfn(reg);
+ unsigned long end = memblock_region_memory_end_pfn(reg);
+
+ if (start < max_low) {
+ unsigned long low_end = min(end, max_low);
+ zhole_size[0] -= low_end - start;
+ }
#ifdef CONFIG_HIGHMEM
- if (mi->bank[i].highmem)
- idx = ZONE_HIGHMEM;
+ if (end > max_low) {
+ unsigned long high_start = max(start, max_low);
+ zhole_size[ZONE_HIGHMEM] -= end - high_start;
+ }
#endif
- zhole_size[idx] -= bank_pfn_size(&mi->bank[i]);
}
/*
@@ -237,20 +255,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,24 +265,34 @@ 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
+static int __init meminfo_cmp(const void *_a, const void *_b)
+{
+ const struct membank *a = _a, *b = _b;
+ long cmp = bank_pfn_start(a) - bank_pfn_start(b);
+ return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
+}
+
void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc)
{
int i;
+ sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
+
memblock_init();
for (i = 0; i < mi->nr_banks; i++)
memblock_add(mi->bank[i].start, mi->bank[i].size);
/* 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
@@ -303,14 +318,13 @@ void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc)
void __init bootmem_init(void)
{
- struct meminfo *mi = &meminfo;
unsigned long min, max_low, max_high;
max_low = max_high = 0;
- find_limits(mi, &min, &max_low, &max_high);
+ find_limits(&min, &max_low, &max_high);
- arm_bootmem_init(mi, min, max_low);
+ arm_bootmem_init(min, max_low);
/*
* Sparsemem tries to allocate bootmem in memory_present(),
@@ -328,7 +342,7 @@ void __init bootmem_init(void)
* the sparse mem_map arrays initialized by sparse_init()
* for memmap_init_zone(), otherwise all PFNs are invalid.
*/
- arm_bootmem_free(mi, min, max_low, max_high);
+ arm_bootmem_free(min, max_low, max_high);
high_memory = __va((max_low << PAGE_SHIFT) - 1) + 1;
@@ -422,6 +436,56 @@ static void __init free_unused_memmap(struct meminfo *mi)
}
}
+static void __init free_highpages(void)
+{
+#ifdef CONFIG_HIGHMEM
+ unsigned long max_low = max_low_pfn + PHYS_PFN_OFFSET;
+ struct memblock_region *mem, *res;
+
+ /* set highmem page free */
+ for_each_memblock(memory, mem) {
+ unsigned long start = memblock_region_memory_base_pfn(mem);
+ unsigned long end = memblock_region_memory_end_pfn(mem);
+
+ /* Ignore complete lowmem entries */
+ if (end <= max_low)
+ continue;
+
+ /* Truncate partial highmem entries */
+ if (start < max_low)
+ start = max_low;
+
+ /* Find and exclude any reserved regions */
+ for_each_memblock(reserved, res) {
+ unsigned long res_start, res_end;
+
+ res_start = memblock_region_reserved_base_pfn(res);
+ res_end = memblock_region_reserved_end_pfn(res);
+
+ if (res_end < start)
+ continue;
+ if (res_start < start)
+ res_start = start;
+ if (res_start > end)
+ res_start = end;
+ if (res_end > end)
+ res_end = end;
+ if (res_start != start)
+ totalhigh_pages += free_area(start, res_start,
+ NULL);
+ start = res_end;
+ if (start == end)
+ break;
+ }
+
+ /* And now free anything which remains */
+ if (start < end)
+ totalhigh_pages += free_area(start, end, NULL);
+ }
+ totalram_pages += totalhigh_pages;
+#endif
+}
+
/*
* mem_init() marks the free areas in the mem_map and tells us how much
* memory is free. This is done after various parts of the system have
@@ -430,6 +494,7 @@ static void __init free_unused_memmap(struct meminfo *mi)
void __init mem_init(void)
{
unsigned long reserved_pages, free_pages;
+ struct memblock_region *reg;
int i;
#ifdef CONFIG_HAVE_TCM
/* These pointers are filled in on TCM detection */
@@ -450,16 +515,7 @@ void __init mem_init(void)
__phys_to_pfn(__pa(swapper_pg_dir)), NULL);
#endif
-#ifdef CONFIG_HIGHMEM
- /* set highmem page free */
- for_each_bank (i, &meminfo) {
- unsigned long start = bank_pfn_start(&meminfo.bank[i]);
- unsigned long end = bank_pfn_end(&meminfo.bank[i]);
- if (start >= max_low_pfn + PHYS_PFN_OFFSET)
- totalhigh_pages += free_area(start, end, NULL);
- }
- totalram_pages += totalhigh_pages;
-#endif
+ free_highpages();
reserved_pages = free_pages = 0;
@@ -489,9 +545,11 @@ void __init mem_init(void)
*/
printk(KERN_INFO "Memory:");
num_physpages = 0;
- for (i = 0; i < meminfo.nr_banks; i++) {
- num_physpages += bank_pfn_size(&meminfo.bank[i]);
- printk(" %ldMB", bank_phys_size(&meminfo.bank[i]) >> 20);
+ for_each_memblock(memory, reg) {
+ unsigned long pages = memblock_region_memory_end_pfn(reg) -
+ memblock_region_memory_base_pfn(reg);
+ num_physpages += pages;
+ printk(" %ldMB", pages >> (20 - PAGE_SHIFT));
}
printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT));
@@ -545,7 +603,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/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 e8ed9dc461fe..72ad3e1f56cf 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -14,7 +14,6 @@
#include <linux/mman.h>
#include <linux/nodemask.h>
#include <linux/memblock.h>
-#include <linux/sort.h>
#include <linux/fs.h>
#include <asm/cputype.h>
@@ -265,17 +264,17 @@ static struct mem_type mem_types[] = {
.domain = DOMAIN_KERNEL,
},
[MT_MEMORY_DTCM] = {
- .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG |
- L_PTE_DIRTY | L_PTE_WRITE,
- .prot_l1 = PMD_TYPE_TABLE,
- .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,
- .domain = DOMAIN_KERNEL,
+ .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+ L_PTE_WRITE,
+ .prot_l1 = PMD_TYPE_TABLE,
+ .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,
+ .domain = DOMAIN_KERNEL,
},
[MT_MEMORY_ITCM] = {
.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,
- .domain = DOMAIN_IO,
+ .domain = DOMAIN_KERNEL,
},
};
@@ -310,9 +309,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 +404,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 +432,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;
+ }
}
/*
@@ -747,13 +744,14 @@ static int __init early_vmalloc(char *arg)
}
early_param("vmalloc", early_vmalloc);
-phys_addr_t lowmem_end_addr;
+static phys_addr_t lowmem_limit __initdata = 0;
static void __init sanity_check_meminfo(void)
{
int i, j, highmem = 0;
- lowmem_end_addr = __pa(vmalloc_min - 1) + 1;
+ lowmem_limit = __pa(vmalloc_min - 1) + 1;
+ memblock_set_current_limit(lowmem_limit);
for (i = 0, j = 0; i < meminfo.nr_banks; i++) {
struct membank *bank = &meminfo.bank[j];
@@ -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",
@@ -856,6 +852,7 @@ static void __init sanity_check_meminfo(void)
static inline void prepare_page_table(void)
{
unsigned long addr;
+ phys_addr_t end;
/*
* Clear out all the mappings below the kernel image.
@@ -871,10 +868,17 @@ static inline void prepare_page_table(void)
pmd_clear(pmd_off_k(addr));
/*
+ * Find the end of the first block of lowmem.
+ */
+ end = memblock.memory.regions[0].base + memblock.memory.regions[0].size;
+ if (end >= lowmem_limit)
+ end = lowmem_limit;
+
+ /*
* Clear out all the kernel space mappings, except for the first
* memory bank, up to the end of the vmalloc region.
*/
- for (addr = __phys_to_virt(bank_phys_end(&meminfo.bank[0]));
+ for (addr = __phys_to_virt(end);
addr < VMALLOC_END; addr += PGDIR_SIZE)
pmd_clear(pmd_off_k(addr));
}
@@ -991,37 +995,28 @@ static void __init kmap_init(void)
#endif
}
-static inline void map_memory_bank(struct membank *bank)
-{
- struct map_desc map;
-
- map.pfn = bank_pfn_start(bank);
- map.virtual = __phys_to_virt(bank_phys_start(bank));
- map.length = bank_phys_size(bank);
- map.type = MT_MEMORY;
-
- create_mapping(&map);
-}
-
static void __init map_lowmem(void)
{
- struct meminfo *mi = &meminfo;
- int i;
+ struct memblock_region *reg;
/* Map all the lowmem memory banks. */
- for (i = 0; i < mi->nr_banks; i++) {
- struct membank *bank = &mi->bank[i];
+ for_each_memblock(memory, reg) {
+ phys_addr_t start = reg->base;
+ phys_addr_t end = start + reg->size;
+ struct map_desc map;
+
+ if (end > lowmem_limit)
+ end = lowmem_limit;
+ if (start >= end)
+ break;
- if (!bank->highmem)
- map_memory_bank(bank);
- }
-}
+ map.pfn = __phys_to_pfn(start);
+ map.virtual = __phys_to_virt(start);
+ map.length = end - start;
+ map.type = MT_MEMORY;
-static int __init meminfo_cmp(const void *_a, const void *_b)
-{
- const struct membank *a = _a, *b = _b;
- long cmp = bank_pfn_start(a) - bank_pfn_start(b);
- return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
+ create_mapping(&map);
+ }
}
/*
@@ -1032,8 +1027,6 @@ void __init paging_init(struct machine_desc *mdesc)
{
void *zero_page;
- sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
-
build_mem_type_table();
sanity_check_meminfo();
prepare_page_table();
diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c
index be5f58e153bf..69bbfc6645a6 100644
--- a/arch/arm/mm/pgd.c
+++ b/arch/arm/mm/pgd.c
@@ -57,9 +57,9 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
goto no_pte;
init_pmd = pmd_offset(init_pgd, 0);
- init_pte = pte_offset_map_nested(init_pmd, 0);
+ init_pte = pte_offset_map(init_pmd, 0);
set_pte_ext(new_pte, *init_pte, 0);
- pte_unmap_nested(init_pte);
+ pte_unmap(init_pte);
pte_unmap(new_pte);
}
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
index 203a4e944d9e..bcf748d9f4e2 100644
--- a/arch/arm/mm/proc-arm1020.S
+++ b/arch/arm/mm/proc-arm1020.S
@@ -119,6 +119,20 @@ ENTRY(cpu_arm1020_do_idle)
/* ================================= CACHE ================================ */
.align 5
+
+/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm1020_flush_icache_all)
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+#endif
+ mov pc, lr
+ENDPROC(arm1020_flush_icache_all)
+
/*
* flush_user_cache_all()
*
@@ -351,6 +365,7 @@ ENTRY(arm1020_dma_unmap_area)
ENDPROC(arm1020_dma_unmap_area)
ENTRY(arm1020_cache_fns)
+ .long arm1020_flush_icache_all
.long arm1020_flush_kern_cache_all
.long arm1020_flush_user_cache_all
.long arm1020_flush_user_cache_range
@@ -430,7 +445,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..ab7ec26657ea 100644
--- a/arch/arm/mm/proc-arm1020e.S
+++ b/arch/arm/mm/proc-arm1020e.S
@@ -119,6 +119,20 @@ ENTRY(cpu_arm1020e_do_idle)
/* ================================= CACHE ================================ */
.align 5
+
+/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm1020e_flush_icache_all)
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+#endif
+ mov pc, lr
+ENDPROC(arm1020e_flush_icache_all)
+
/*
* flush_user_cache_all()
*
@@ -337,6 +351,7 @@ ENTRY(arm1020e_dma_unmap_area)
ENDPROC(arm1020e_dma_unmap_area)
ENTRY(arm1020e_cache_fns)
+ .long arm1020e_flush_icache_all
.long arm1020e_flush_kern_cache_all
.long arm1020e_flush_user_cache_all
.long arm1020e_flush_user_cache_range
@@ -412,7 +427,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..831c5e54e22f 100644
--- a/arch/arm/mm/proc-arm1022.S
+++ b/arch/arm/mm/proc-arm1022.S
@@ -108,6 +108,20 @@ ENTRY(cpu_arm1022_do_idle)
/* ================================= CACHE ================================ */
.align 5
+
+/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm1022_flush_icache_all)
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+#endif
+ mov pc, lr
+ENDPROC(arm1022_flush_icache_all)
+
/*
* flush_user_cache_all()
*
@@ -326,6 +340,7 @@ ENTRY(arm1022_dma_unmap_area)
ENDPROC(arm1022_dma_unmap_area)
ENTRY(arm1022_cache_fns)
+ .long arm1022_flush_icache_all
.long arm1022_flush_kern_cache_all
.long arm1022_flush_user_cache_all
.long arm1022_flush_user_cache_range
@@ -394,7 +409,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..e3f7e9a166bf 100644
--- a/arch/arm/mm/proc-arm1026.S
+++ b/arch/arm/mm/proc-arm1026.S
@@ -108,6 +108,20 @@ ENTRY(cpu_arm1026_do_idle)
/* ================================= CACHE ================================ */
.align 5
+
+/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm1026_flush_icache_all)
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+#endif
+ mov pc, lr
+ENDPROC(arm1026_flush_icache_all)
+
/*
* flush_user_cache_all()
*
@@ -320,6 +334,7 @@ ENTRY(arm1026_dma_unmap_area)
ENDPROC(arm1026_dma_unmap_area)
ENTRY(arm1026_cache_fns)
+ .long arm1026_flush_icache_all
.long arm1026_flush_kern_cache_all
.long arm1026_flush_user_cache_all
.long arm1026_flush_user_cache_range
@@ -384,7 +399,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..6109f278a904 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -110,6 +110,17 @@ ENTRY(cpu_arm920_do_idle)
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm920_flush_icache_all)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mov pc, lr
+ENDPROC(arm920_flush_icache_all)
+
+/*
* flush_user_cache_all()
*
* Invalidate all cache entries in a particular address
@@ -305,6 +316,7 @@ ENTRY(arm920_dma_unmap_area)
ENDPROC(arm920_dma_unmap_area)
ENTRY(arm920_cache_fns)
+ .long arm920_flush_icache_all
.long arm920_flush_kern_cache_all
.long arm920_flush_user_cache_all
.long arm920_flush_user_cache_range
@@ -375,7 +387,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..bb2f0f46a5e6 100644
--- a/arch/arm/mm/proc-arm922.S
+++ b/arch/arm/mm/proc-arm922.S
@@ -112,6 +112,17 @@ ENTRY(cpu_arm922_do_idle)
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm922_flush_icache_all)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mov pc, lr
+ENDPROC(arm922_flush_icache_all)
+
+/*
* flush_user_cache_all()
*
* Clean and invalidate all cache entries in a particular
@@ -307,6 +318,7 @@ ENTRY(arm922_dma_unmap_area)
ENDPROC(arm922_dma_unmap_area)
ENTRY(arm922_cache_fns)
+ .long arm922_flush_icache_all
.long arm922_flush_kern_cache_all
.long arm922_flush_user_cache_all
.long arm922_flush_user_cache_range
@@ -379,7 +391,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..c13e01accfe2 100644
--- a/arch/arm/mm/proc-arm925.S
+++ b/arch/arm/mm/proc-arm925.S
@@ -145,6 +145,17 @@ ENTRY(cpu_arm925_do_idle)
mov pc, lr
/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm925_flush_icache_all)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mov pc, lr
+ENDPROC(arm925_flush_icache_all)
+
+/*
* flush_user_cache_all()
*
* Clean and invalidate all cache entries in a particular
@@ -362,6 +373,7 @@ ENTRY(arm925_dma_unmap_area)
ENDPROC(arm925_dma_unmap_area)
ENTRY(arm925_cache_fns)
+ .long arm925_flush_icache_all
.long arm925_flush_kern_cache_all
.long arm925_flush_user_cache_all
.long arm925_flush_user_cache_range
@@ -428,7 +440,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..42eb4315740b 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -111,6 +111,17 @@ ENTRY(cpu_arm926_do_idle)
mov pc, lr
/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm926_flush_icache_all)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mov pc, lr
+ENDPROC(arm926_flush_icache_all)
+
+/*
* flush_user_cache_all()
*
* Clean and invalidate all cache entries in a particular
@@ -325,6 +336,7 @@ ENTRY(arm926_dma_unmap_area)
ENDPROC(arm926_dma_unmap_area)
ENTRY(arm926_cache_fns)
+ .long arm926_flush_icache_all
.long arm926_flush_kern_cache_all
.long arm926_flush_user_cache_all
.long arm926_flush_user_cache_range
@@ -389,7 +401,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..7b11cdb9935f 100644
--- a/arch/arm/mm/proc-arm940.S
+++ b/arch/arm/mm/proc-arm940.S
@@ -68,6 +68,17 @@ ENTRY(cpu_arm940_do_idle)
mov pc, lr
/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm940_flush_icache_all)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mov pc, lr
+ENDPROC(arm940_flush_icache_all)
+
+/*
* flush_user_cache_all()
*/
ENTRY(arm940_flush_user_cache_all)
@@ -254,6 +265,7 @@ ENTRY(arm940_dma_unmap_area)
ENDPROC(arm940_dma_unmap_area)
ENTRY(arm940_cache_fns)
+ .long arm940_flush_icache_all
.long arm940_flush_kern_cache_all
.long arm940_flush_user_cache_all
.long arm940_flush_user_cache_range
@@ -264,7 +276,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..1a5bbf080342 100644
--- a/arch/arm/mm/proc-arm946.S
+++ b/arch/arm/mm/proc-arm946.S
@@ -75,6 +75,17 @@ ENTRY(cpu_arm946_do_idle)
mov pc, lr
/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm946_flush_icache_all)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mov pc, lr
+ENDPROC(arm946_flush_icache_all)
+
+/*
* flush_user_cache_all()
*/
ENTRY(arm946_flush_user_cache_all)
@@ -296,6 +307,7 @@ ENTRY(arm946_dma_unmap_area)
ENDPROC(arm946_dma_unmap_area)
ENTRY(arm946_cache_fns)
+ .long arm946_flush_icache_all
.long arm946_flush_kern_cache_all
.long arm946_flush_user_cache_all
.long arm946_flush_user_cache_range
@@ -317,7 +329,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..b4597edbff97 100644
--- a/arch/arm/mm/proc-feroceon.S
+++ b/arch/arm/mm/proc-feroceon.S
@@ -124,6 +124,17 @@ ENTRY(cpu_feroceon_do_idle)
mov pc, lr
/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(feroceon_flush_icache_all)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mov pc, lr
+ENDPROC(feroceon_flush_icache_all)
+
+/*
* flush_user_cache_all()
*
* Clean and invalidate all cache entries in a particular
@@ -401,6 +412,7 @@ ENTRY(feroceon_dma_unmap_area)
ENDPROC(feroceon_dma_unmap_area)
ENTRY(feroceon_cache_fns)
+ .long feroceon_flush_icache_all
.long feroceon_flush_kern_cache_all
.long feroceon_flush_user_cache_all
.long feroceon_flush_user_cache_range
@@ -412,6 +424,7 @@ ENTRY(feroceon_cache_fns)
.long feroceon_dma_flush_range
ENTRY(feroceon_range_cache_fns)
+ .long feroceon_flush_icache_all
.long feroceon_flush_kern_cache_all
.long feroceon_flush_user_cache_all
.long feroceon_flush_user_cache_range
@@ -494,7 +507,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 197f21bed5e9..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
@@ -270,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
@@ -332,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
@@ -345,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"
@@ -362,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
+ 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 | \
@@ -388,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..ec26355cb7c2 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -141,6 +141,17 @@ ENTRY(cpu_xsc3_do_idle)
/* ================================= CACHE ================================ */
/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(xsc3_flush_icache_all)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mov pc, lr
+ENDPROC(xsc3_flush_icache_all)
+
+/*
* flush_user_cache_all()
*
* Invalidate all cache entries in a particular address
@@ -325,6 +336,7 @@ ENTRY(xsc3_dma_unmap_area)
ENDPROC(xsc3_dma_unmap_area)
ENTRY(xsc3_cache_fns)
+ .long xsc3_flush_icache_all
.long xsc3_flush_kern_cache_all
.long xsc3_flush_user_cache_all
.long xsc3_flush_user_cache_range
@@ -404,7 +416,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..523408c0bb38 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -181,6 +181,17 @@ ENTRY(cpu_xscale_do_idle)
/* ================================= CACHE ================================ */
/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(xscale_flush_icache_all)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mov pc, lr
+ENDPROC(xscale_flush_icache_all)
+
+/*
* flush_user_cache_all()
*
* Invalidate all cache entries in a particular address
@@ -397,6 +408,7 @@ ENTRY(xscale_dma_unmap_area)
ENDPROC(xscale_dma_unmap_area)
ENTRY(xscale_cache_fns)
+ .long xscale_flush_icache_all
.long xscale_flush_kern_cache_all
.long xscale_flush_user_cache_all
.long xscale_flush_user_cache_range
@@ -506,7 +518,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 72e09eb642dd..8aa974491dfc 100644
--- a/arch/arm/oprofile/common.c
+++ b/arch/arm/oprofile/common.c
@@ -25,139 +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)
+char *op_name_from_perf_id(void)
{
- 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) {
- perf_event_release_kernel(pevent);
- pr_warning("oprofile: failed to enable event %d "
- "on CPU %d\n", event, cpu);
- ret = -EBUSY;
- } else {
- perf_events[cpu][event] = pevent;
- }
-
- return ret;
-}
+ enum arm_perf_pmu_ids id = armpmu_get_pmu_id();
-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)
-{
- int cpu, event;
-
- 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";
@@ -176,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;
@@ -350,74 +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);
- counter_config = NULL;
- 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) {
- 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);
- exit_driverfs();
- }
+ oprofile_perf_exit();
}
#else
int __init oprofile_arch_init(struct oprofile_operations *ops)
@@ -425,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..372670952789 100644
--- a/arch/arm/plat-mxc/Makefile
+++ b/arch/arm/plat-mxc/Makefile
@@ -10,12 +10,15 @@ 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
+obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o
ifdef CONFIG_SND_IMX_SOC
obj-y += ssi-fiq.o
obj-y += ssi-fiq-ksym.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/cpufreq.c b/arch/arm/plat-mxc/cpufreq.c
new file mode 100644
index 000000000000..039538e68793
--- /dev/null
+++ b/arch/arm/plat-mxc/cpufreq.c
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2010 Freescale Semiconductor, 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
+ */
+
+/*
+ * A driver for the Freescale Semiconductor i.MXC CPUfreq module.
+ * The CPUFREQ driver is for controling CPU frequency. It allows you to change
+ * the CPU clock speed on the fly.
+ */
+
+#include <linux/cpufreq.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <mach/hardware.h>
+#include <mach/clock.h>
+
+#define CLK32_FREQ 32768
+#define NANOSECOND (1000 * 1000 * 1000)
+
+struct cpu_op *(*get_cpu_op)(int *op);
+
+static int cpu_freq_khz_min;
+static int cpu_freq_khz_max;
+
+static struct clk *cpu_clk;
+static struct cpufreq_frequency_table *imx_freq_table;
+
+static int cpu_op_nr;
+static struct cpu_op *cpu_op_tbl;
+
+static int set_cpu_freq(int freq)
+{
+ int ret = 0;
+ int org_cpu_rate;
+
+ org_cpu_rate = clk_get_rate(cpu_clk);
+ if (org_cpu_rate == freq)
+ return ret;
+
+ ret = clk_set_rate(cpu_clk, freq);
+ if (ret != 0) {
+ printk(KERN_DEBUG "cannot set CPU clock rate\n");
+ return ret;
+ }
+
+ return ret;
+}
+
+static int mxc_verify_speed(struct cpufreq_policy *policy)
+{
+ if (policy->cpu != 0)
+ return -EINVAL;
+
+ return cpufreq_frequency_table_verify(policy, imx_freq_table);
+}
+
+static unsigned int mxc_get_speed(unsigned int cpu)
+{
+ if (cpu)
+ return 0;
+
+ return clk_get_rate(cpu_clk) / 1000;
+}
+
+static int mxc_set_target(struct cpufreq_policy *policy,
+ unsigned int target_freq, unsigned int relation)
+{
+ struct cpufreq_freqs freqs;
+ int freq_Hz;
+ int ret = 0;
+ unsigned int index;
+
+ cpufreq_frequency_table_target(policy, imx_freq_table,
+ target_freq, relation, &index);
+ freq_Hz = imx_freq_table[index].frequency * 1000;
+
+ freqs.old = clk_get_rate(cpu_clk) / 1000;
+ freqs.new = freq_Hz / 1000;
+ freqs.cpu = 0;
+ freqs.flags = 0;
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ ret = set_cpu_freq(freq_Hz);
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ return ret;
+}
+
+static int __init mxc_cpufreq_init(struct cpufreq_policy *policy)
+{
+ int ret;
+ int i;
+
+ printk(KERN_INFO "i.MXC CPU frequency driver\n");
+
+ if (policy->cpu != 0)
+ return -EINVAL;
+
+ if (!get_cpu_op)
+ return -EINVAL;
+
+ cpu_clk = clk_get(NULL, "cpu_clk");
+ if (IS_ERR(cpu_clk)) {
+ printk(KERN_ERR "%s: failed to get cpu clock\n", __func__);
+ return PTR_ERR(cpu_clk);
+ }
+
+ cpu_op_tbl = get_cpu_op(&cpu_op_nr);
+
+ cpu_freq_khz_min = cpu_op_tbl[0].cpu_rate / 1000;
+ cpu_freq_khz_max = cpu_op_tbl[0].cpu_rate / 1000;
+
+ imx_freq_table = kmalloc(
+ sizeof(struct cpufreq_frequency_table) * (cpu_op_nr + 1),
+ GFP_KERNEL);
+ if (!imx_freq_table) {
+ ret = -ENOMEM;
+ goto err1;
+ }
+
+ for (i = 0; i < cpu_op_nr; i++) {
+ imx_freq_table[i].index = i;
+ imx_freq_table[i].frequency = cpu_op_tbl[i].cpu_rate / 1000;
+
+ if ((cpu_op_tbl[i].cpu_rate / 1000) < cpu_freq_khz_min)
+ cpu_freq_khz_min = cpu_op_tbl[i].cpu_rate / 1000;
+
+ if ((cpu_op_tbl[i].cpu_rate / 1000) > cpu_freq_khz_max)
+ cpu_freq_khz_max = cpu_op_tbl[i].cpu_rate / 1000;
+ }
+
+ imx_freq_table[i].index = i;
+ imx_freq_table[i].frequency = CPUFREQ_TABLE_END;
+
+ policy->cur = clk_get_rate(cpu_clk) / 1000;
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+ policy->min = policy->cpuinfo.min_freq = cpu_freq_khz_min;
+ policy->max = policy->cpuinfo.max_freq = cpu_freq_khz_max;
+
+ /* Manual states, that PLL stabilizes in two CLK32 periods */
+ policy->cpuinfo.transition_latency = 2 * NANOSECOND / CLK32_FREQ;
+
+ ret = cpufreq_frequency_table_cpuinfo(policy, imx_freq_table);
+
+ if (ret < 0) {
+ printk(KERN_ERR "%s: failed to register i.MXC CPUfreq \
+ with error code %d\n", __func__, ret);
+ goto err;
+ }
+
+ cpufreq_frequency_table_get_attr(imx_freq_table, policy->cpu);
+ return 0;
+err:
+ kfree(imx_freq_table);
+err1:
+ clk_put(cpu_clk);
+ return ret;
+}
+
+static int mxc_cpufreq_exit(struct cpufreq_policy *policy)
+{
+ cpufreq_frequency_table_put_attr(policy->cpu);
+
+ set_cpu_freq(cpu_freq_khz_max * 1000);
+ clk_put(cpu_clk);
+ kfree(imx_freq_table);
+ return 0;
+}
+
+static struct cpufreq_driver mxc_driver = {
+ .flags = CPUFREQ_STICKY,
+ .verify = mxc_verify_speed,
+ .target = mxc_set_target,
+ .get = mxc_get_speed,
+ .init = mxc_cpufreq_init,
+ .exit = mxc_cpufreq_exit,
+ .name = "imx",
+};
+
+static int __devinit mxc_cpufreq_driver_init(void)
+{
+ return cpufreq_register_driver(&mxc_driver);
+}
+
+static void mxc_cpufreq_driver_exit(void)
+{
+ cpufreq_unregister_driver(&mxc_driver);
+}
+
+module_init(mxc_cpufreq_driver_init);
+module_exit(mxc_cpufreq_driver_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor Inc. Yong Shen <yong.shen@linaro.org>");
+MODULE_DESCRIPTION("CPUfreq driver for i.MX");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-mxc/devices/Kconfig b/arch/arm/plat-mxc/devices/Kconfig
index 9ab784b776f9..9aa6f3ea9012 100644
--- a/arch/arm/plat-mxc/devices/Kconfig
+++ b/arch/arm/plat-mxc/devices/Kconfig
@@ -1,10 +1,24 @@
+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
+ select HAVE_CAN_FLEXCAN if CAN
bool
+config IMX_HAVE_PLATFORM_GPIO_KEYS
+ bool
+ default y if ARCH_MX51
+
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..45aefeb283ba 100644
--- a/arch/arm/plat-mxc/devices/Makefile
+++ b/arch/arm/plat-mxc/devices/Makefile
@@ -1,8 +1,10 @@
-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-$(CONFIG_IMX_HAVE_PLATFORM_GPIO_KEYS) += platform-gpio_keys.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-gpio_keys.c b/arch/arm/plat-mxc/devices/platform-gpio_keys.c
new file mode 100644
index 000000000000..1c53a532ea0e
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-gpio_keys.c
@@ -0,0 +1,27 @@
+/*
+ * 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 <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+struct platform_device *__init imx_add_gpio_keys(
+ const struct gpio_keys_platform_data *pdata)
+{
+ return imx_add_platform_device("gpio-keys", -1, NULL,
+ 0, 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..9c3e36232b5b 100644
--- a/arch/arm/plat-mxc/gpio.c
+++ b/arch/arm/plat-mxc/gpio.c
@@ -20,6 +20,7 @@
*/
#include <linux/init.h>
+#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/gpio.h>
@@ -201,11 +202,42 @@ static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc)
}
}
+/*
+ * Set interrupt number "irq" in the GPIO as a wake-up source.
+ * While system is running, all registered GPIO interrupts need to have
+ * wake-up enabled. When system is suspended, only selected GPIO interrupts
+ * need to have wake-up enabled.
+ * @param irq interrupt source number
+ * @param enable enable as wake-up if equal to non-zero
+ * @return This function returns 0 on success.
+ */
+static int gpio_set_wake_irq(u32 irq, u32 enable)
+{
+ u32 gpio = irq_to_gpio(irq);
+ u32 gpio_idx = gpio & 0x1F;
+ struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32];
+
+ if (enable) {
+ if (port->irq_high && (gpio_idx >= 16))
+ enable_irq_wake(port->irq_high);
+ else
+ enable_irq_wake(port->irq);
+ } else {
+ if (port->irq_high && (gpio_idx >= 16))
+ disable_irq_wake(port->irq_high);
+ else
+ disable_irq_wake(port->irq);
+ }
+
+ return 0;
+}
+
static struct irq_chip gpio_irq_chip = {
.ack = gpio_ack_irq,
.mask = gpio_mask_irq,
.unmask = gpio_unmask_irq,
.set_type = gpio_set_irq_type,
+ .set_wake = gpio_set_wake_irq,
};
static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
@@ -235,7 +267,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..8c6896fd1e5f 100644
--- a/arch/arm/plat-mxc/include/mach/devices-common.h
+++ b/arch/arm/plat-mxc/include/mach/devices-common.h
@@ -14,47 +14,109 @@ 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 <linux/gpio_keys.h>
+struct platform_device *__init imx_add_gpio_keys(
+ const struct gpio_keys_platform_data *pdata);
#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/dma.h b/arch/arm/plat-mxc/include/mach/dma.h
new file mode 100644
index 000000000000..ef7751546f5f
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/dma.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2004-2009 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_DMA_H__
+#define __ASM_ARCH_MXC_DMA_H__
+
+#include <linux/scatterlist.h>
+#include <linux/device.h>
+#include <linux/dmaengine.h>
+
+/*
+ * This enumerates peripheral types. Used for SDMA.
+ */
+enum sdma_peripheral_type {
+ IMX_DMATYPE_SSI, /* MCU domain SSI */
+ IMX_DMATYPE_SSI_SP, /* Shared SSI */
+ IMX_DMATYPE_MMC, /* MMC */
+ IMX_DMATYPE_SDHC, /* SDHC */
+ IMX_DMATYPE_UART, /* MCU domain UART */
+ IMX_DMATYPE_UART_SP, /* Shared UART */
+ IMX_DMATYPE_FIRI, /* FIRI */
+ IMX_DMATYPE_CSPI, /* MCU domain CSPI */
+ IMX_DMATYPE_CSPI_SP, /* Shared CSPI */
+ IMX_DMATYPE_SIM, /* SIM */
+ IMX_DMATYPE_ATA, /* ATA */
+ IMX_DMATYPE_CCM, /* CCM */
+ IMX_DMATYPE_EXT, /* External peripheral */
+ IMX_DMATYPE_MSHC, /* Memory Stick Host Controller */
+ IMX_DMATYPE_MSHC_SP, /* Shared Memory Stick Host Controller */
+ IMX_DMATYPE_DSP, /* DSP */
+ IMX_DMATYPE_MEMORY, /* Memory */
+ IMX_DMATYPE_FIFO_MEMORY,/* FIFO type Memory */
+ IMX_DMATYPE_SPDIF, /* SPDIF */
+ IMX_DMATYPE_IPU_MEMORY, /* IPU Memory */
+ IMX_DMATYPE_ASRC, /* ASRC */
+ IMX_DMATYPE_ESAI, /* ESAI */
+};
+
+enum imx_dma_prio {
+ DMA_PRIO_HIGH = 0,
+ DMA_PRIO_MEDIUM = 1,
+ DMA_PRIO_LOW = 2
+};
+
+struct imx_dma_data {
+ int dma_request; /* DMA request line */
+ enum sdma_peripheral_type peripheral_type;
+ int priority;
+};
+
+static inline int imx_dma_is_ipu(struct dma_chan *chan)
+{
+ return !strcmp(dev_name(chan->device->dev), "ipu-core");
+}
+
+static inline int imx_dma_is_general_purpose(struct dma_chan *chan)
+{
+ return !strcmp(dev_name(chan->device->dev), "imx-sdma") ||
+ !strcmp(dev_name(chan->device->dev), "imx-dma");
+}
+
+#endif
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..d7a41e9a2605 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx51.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx51.h
@@ -45,6 +45,20 @@ 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_GPIO_PAD_CTRL_2 (PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | \
+ PAD_CTL_PUS_100K_UP)
+#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 +120,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 +146,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 +219,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 +280,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 +338,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..61cfe827498b 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 */
@@ -231,7 +240,6 @@ static inline void mx31_setup_weimcs(size_t cs,
#define MPEG4_ENC_BASE_ADDR MX31_MPEG4_ENC_BASE_ADDR
#define MXC_INT_MPEG4_ENCODER MX31_INT_MPEG4_ENCODER
#define MXC_INT_FIRI MX31_INT_FIRI
-#define MXC_INT_MMC_SDHC1 MX31_INT_MMC_SDHC1
#define MXC_INT_MBX MX31_INT_MBX
#define MXC_INT_CSPI3 MX31_INT_CSPI3
#define MXC_INT_SIM2 MX31_INT_SIM2
diff --git a/arch/arm/plat-mxc/include/mach/mx35.h b/arch/arm/plat-mxc/include/mach/mx35.h
index af3038c12e39..6267cff6035d 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,30 +179,24 @@
#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
/* these should go away */
#define MXC_FEC_BASE_ADDR MX35_FEC_BASE_ADDR
#define MXC_INT_OWIRE MX35_INT_OWIRE
-#define MXC_INT_MMC_SDHC2 MX35_INT_MMC_SDHC2
-#define MXC_INT_MMC_SDHC3 MX35_INT_MMC_SDHC3
#define MXC_INT_GPU2D MX35_INT_GPU2D
#define MXC_INT_ASRC MX35_INT_ASRC
#define MXC_INT_USBHS MX35_INT_USBHS
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/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
index a790bf212972..a42c7207082d 100644
--- a/arch/arm/plat-mxc/include/mach/mxc.h
+++ b/arch/arm/plat-mxc/include/mach/mxc.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2007, 2010 Freescale Semiconductor, Inc. All Rights Reserved.
* Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
*
* This program is free software; you can redistribute it and/or
@@ -20,6 +20,8 @@
#ifndef __ASM_ARCH_MXC_H__
#define __ASM_ARCH_MXC_H__
+#include <linux/types.h>
+
#ifndef __ASM_ARCH_MXC_HARDWARE_H__
#error "Do not include directly."
#endif
@@ -133,6 +135,15 @@ extern unsigned int __mxc_cpu_type;
# define cpu_is_mxc91231() (0)
#endif
+#ifndef __ASSEMBLY__
+
+struct cpu_op {
+ u32 cpu_rate;
+};
+
+extern struct cpu_op *(*get_cpu_op)(int *op);
+#endif
+
#if defined(CONFIG_ARCH_MX3) || defined(CONFIG_ARCH_MX2)
/* These are deprecated, use mx[23][157]_setup_weimcs instead. */
#define CSCR_U(n) (IO_ADDRESS(WEIM_BASE_ADDR + n * 0x10))
diff --git a/arch/arm/plat-mxc/include/mach/sdma.h b/arch/arm/plat-mxc/include/mach/sdma.h
new file mode 100644
index 000000000000..9be112227ac4
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/sdma.h
@@ -0,0 +1,17 @@
+#ifndef __MACH_MXC_SDMA_H__
+#define __MACH_MXC_SDMA_H__
+
+/**
+ * struct sdma_platform_data - platform specific data for SDMA engine
+ *
+ * @sdma_version The version of this SDMA engine
+ * @cpu_name used to generate the firmware name
+ * @to_version CPU Tape out version
+ */
+struct sdma_platform_data {
+ int sdma_version;
+ char *cpu_name;
+ int to_version;
+};
+
+#endif /* __MACH_MXC_SDMA_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-nomadik/include/plat/ste_dma40.h b/arch/arm/plat-nomadik/include/plat/ste_dma40.h
index 5fbde4b8dc12..74b62f10d07f 100644
--- a/arch/arm/plat-nomadik/include/plat/ste_dma40.h
+++ b/arch/arm/plat-nomadik/include/plat/ste_dma40.h
@@ -1,10 +1,8 @@
/*
- * arch/arm/plat-nomadik/include/plat/ste_dma40.h
- *
- * Copyright (C) ST-Ericsson 2007-2010
+ * Copyright (C) ST-Ericsson SA 2007-2010
+ * Author: Per Forlin <per.forlin@stericsson.com> for ST-Ericsson
+ * Author: Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson
* License terms: GNU General Public License (GPL) version 2
- * Author: Per Friden <per.friden@stericsson.com>
- * Author: Jonas Aaberg <jonas.aberg@stericsson.com>
*/
@@ -14,43 +12,25 @@
#include <linux/dmaengine.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
-#include <linux/dmaengine.h>
/* dev types for memcpy */
#define STEDMA40_DEV_DST_MEMORY (-1)
#define STEDMA40_DEV_SRC_MEMORY (-1)
-/*
- * Description of bitfields of channel_type variable is available in
- * the info structure.
- */
+enum stedma40_mode {
+ STEDMA40_MODE_LOGICAL = 0,
+ STEDMA40_MODE_PHYSICAL,
+ STEDMA40_MODE_OPERATION,
+};
-/* Priority */
-#define STEDMA40_INFO_PRIO_TYPE_POS 2
-#define STEDMA40_HIGH_PRIORITY_CHANNEL (0x1 << STEDMA40_INFO_PRIO_TYPE_POS)
-#define STEDMA40_LOW_PRIORITY_CHANNEL (0x2 << STEDMA40_INFO_PRIO_TYPE_POS)
-
-/* Mode */
-#define STEDMA40_INFO_CH_MODE_TYPE_POS 6
-#define STEDMA40_CHANNEL_IN_PHY_MODE (0x1 << STEDMA40_INFO_CH_MODE_TYPE_POS)
-#define STEDMA40_CHANNEL_IN_LOG_MODE (0x2 << STEDMA40_INFO_CH_MODE_TYPE_POS)
-#define STEDMA40_CHANNEL_IN_OPER_MODE (0x3 << STEDMA40_INFO_CH_MODE_TYPE_POS)
-
-/* Mode options */
-#define STEDMA40_INFO_CH_MODE_OPT_POS 8
-#define STEDMA40_PCHAN_BASIC_MODE (0x1 << STEDMA40_INFO_CH_MODE_OPT_POS)
-#define STEDMA40_PCHAN_MODULO_MODE (0x2 << STEDMA40_INFO_CH_MODE_OPT_POS)
-#define STEDMA40_PCHAN_DOUBLE_DST_MODE (0x3 << STEDMA40_INFO_CH_MODE_OPT_POS)
-#define STEDMA40_LCHAN_SRC_PHY_DST_LOG (0x1 << STEDMA40_INFO_CH_MODE_OPT_POS)
-#define STEDMA40_LCHAN_SRC_LOG_DST_PHS (0x2 << STEDMA40_INFO_CH_MODE_OPT_POS)
-#define STEDMA40_LCHAN_SRC_LOG_DST_LOG (0x3 << STEDMA40_INFO_CH_MODE_OPT_POS)
-
-/* Interrupt */
-#define STEDMA40_INFO_TIM_POS 10
-#define STEDMA40_NO_TIM_FOR_LINK (0x0 << STEDMA40_INFO_TIM_POS)
-#define STEDMA40_TIM_FOR_LINK (0x1 << STEDMA40_INFO_TIM_POS)
-
-/* End of channel_type configuration */
+enum stedma40_mode_opt {
+ STEDMA40_PCHAN_BASIC_MODE = 0,
+ STEDMA40_LCHAN_SRC_LOG_DST_LOG = 0,
+ STEDMA40_PCHAN_MODULO_MODE,
+ STEDMA40_PCHAN_DOUBLE_DST_MODE,
+ STEDMA40_LCHAN_SRC_PHY_DST_LOG,
+ STEDMA40_LCHAN_SRC_LOG_DST_PHY,
+};
#define STEDMA40_ESIZE_8_BIT 0x0
#define STEDMA40_ESIZE_16_BIT 0x1
@@ -73,16 +53,14 @@
#define STEDMA40_PSIZE_LOG_8 STEDMA40_PSIZE_PHY_8
#define STEDMA40_PSIZE_LOG_16 STEDMA40_PSIZE_PHY_16
+/* Maximum number of possible physical channels */
+#define STEDMA40_MAX_PHYS 32
+
enum stedma40_flow_ctrl {
STEDMA40_NO_FLOW_CTRL,
STEDMA40_FLOW_CTRL,
};
-enum stedma40_endianess {
- STEDMA40_LITTLE_ENDIAN,
- STEDMA40_BIG_ENDIAN
-};
-
enum stedma40_periph_data_width {
STEDMA40_BYTE_WIDTH = STEDMA40_ESIZE_8_BIT,
STEDMA40_HALFWORD_WIDTH = STEDMA40_ESIZE_16_BIT,
@@ -90,15 +68,8 @@ enum stedma40_periph_data_width {
STEDMA40_DOUBLEWORD_WIDTH = STEDMA40_ESIZE_64_BIT
};
-struct stedma40_half_channel_info {
- enum stedma40_endianess endianess;
- enum stedma40_periph_data_width data_width;
- int psize;
- enum stedma40_flow_ctrl flow_ctrl;
-};
-
enum stedma40_xfer_dir {
- STEDMA40_MEM_TO_MEM,
+ STEDMA40_MEM_TO_MEM = 1,
STEDMA40_MEM_TO_PERIPH,
STEDMA40_PERIPH_TO_MEM,
STEDMA40_PERIPH_TO_PERIPH
@@ -106,18 +77,31 @@ enum stedma40_xfer_dir {
/**
+ * struct stedma40_chan_cfg - dst/src channel configuration
+ *
+ * @big_endian: true if the src/dst should be read as big endian
+ * @data_width: Data width of the src/dst hardware
+ * @p_size: Burst size
+ * @flow_ctrl: Flow control on/off.
+ */
+struct stedma40_half_channel_info {
+ bool big_endian;
+ enum stedma40_periph_data_width data_width;
+ int psize;
+ enum stedma40_flow_ctrl flow_ctrl;
+};
+
+/**
* struct stedma40_chan_cfg - Structure to be filled by client drivers.
*
* @dir: MEM 2 MEM, PERIPH 2 MEM , MEM 2 PERIPH, PERIPH 2 PERIPH
- * @channel_type: priority, mode, mode options and interrupt configuration.
+ * @high_priority: true if high-priority
+ * @mode: channel mode: physical, logical, or operation
+ * @mode_opt: options for the chosen channel mode
* @src_dev_type: Src device type
* @dst_dev_type: Dst device type
* @src_info: Parameters for dst half channel
* @dst_info: Parameters for dst half channel
- * @pre_transfer_data: Data to be passed on to the pre_transfer() function.
- * @pre_transfer: Callback used if needed before preparation of transfer.
- * Only called if device is set. size of bytes to transfer
- * (in case of multiple element transfer size is size of the first element).
*
*
* This structure has to be filled by the client drivers.
@@ -126,15 +110,13 @@ enum stedma40_xfer_dir {
*/
struct stedma40_chan_cfg {
enum stedma40_xfer_dir dir;
- unsigned int channel_type;
+ bool high_priority;
+ enum stedma40_mode mode;
+ enum stedma40_mode_opt mode_opt;
int src_dev_type;
int dst_dev_type;
struct stedma40_half_channel_info src_info;
struct stedma40_half_channel_info dst_info;
- void *pre_transfer_data;
- int (*pre_transfer) (struct dma_chan *chan,
- void *data,
- int size);
};
/**
@@ -147,7 +129,6 @@ struct stedma40_chan_cfg {
* @memcpy_len: length of memcpy
* @memcpy_conf_phy: default configuration of physical channel memcpy
* @memcpy_conf_log: default configuration of logical channel memcpy
- * @llis_per_log: number of max linked list items per logical channel
* @disabled_channels: A vector, ending with -1, that marks physical channels
* that are for different reasons not available for the driver.
*/
@@ -159,23 +140,10 @@ struct stedma40_platform_data {
u32 memcpy_len;
struct stedma40_chan_cfg *memcpy_conf_phy;
struct stedma40_chan_cfg *memcpy_conf_log;
- unsigned int llis_per_log;
- int disabled_channels[8];
+ int disabled_channels[STEDMA40_MAX_PHYS];
};
-/**
- * setdma40_set_psize() - Used for changing the package size of an
- * already configured dma channel.
- *
- * @chan: dmaengine handle
- * @src_psize: new package side for src. (STEDMA40_PSIZE*)
- * @src_psize: new package side for dst. (STEDMA40_PSIZE*)
- *
- * returns 0 on ok, otherwise negative error number.
- */
-int stedma40_set_psize(struct dma_chan *chan,
- int src_psize,
- int dst_psize);
+#ifdef CONFIG_STE_DMA40
/**
* stedma40_filter() - Provides stedma40_chan_cfg to the
@@ -238,4 +206,21 @@ dma_async_tx_descriptor *stedma40_slave_mem(struct dma_chan *chan,
direction, flags);
}
+#else
+static inline bool stedma40_filter(struct dma_chan *chan, void *data)
+{
+ return false;
+}
+
+static inline struct
+dma_async_tx_descriptor *stedma40_slave_mem(struct dma_chan *chan,
+ dma_addr_t addr,
+ unsigned int size,
+ enum dma_data_direction direction,
+ unsigned long flags)
+{
+ return NULL;
+}
+#endif
+
#endif
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index a92cb499313f..92c5bb7909f5 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -19,7 +19,7 @@ config ARCH_OMAP2PLUS
bool "TI OMAP2/3/4"
select COMMON_CLKDEV
help
- "Systems based on omap24xx, omap34xx or omap44xx"
+ "Systems based on OMAP2, OMAP3 or OMAP4"
endchoice
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 9405831b746a..a4a12859fdd5 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -4,7 +4,7 @@
# Common support
obj-y := common.o sram.o clock.o devices.o dma.o mux.o gpio.o \
- usb.o fb.o io.o
+ usb.o fb.o io.o counter_32k.o
obj-m :=
obj-n :=
obj- :=
@@ -31,4 +31,4 @@ obj-y += $(i2c-omap-m) $(i2c-omap-y)
# OMAP mailbox framework
obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox.o
-obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o \ No newline at end of file
+obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index 7190cbd92620..fc62fb5fc20b 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -60,7 +60,7 @@ void clk_disable(struct clk *clk)
spin_lock_irqsave(&clockfw_lock, flags);
if (clk->usecount == 0) {
- printk(KERN_ERR "Trying disable clock %s with 0 usecount\n",
+ pr_err("Trying disable clock %s with 0 usecount\n",
clk->name);
WARN_ON(1);
goto out;
@@ -397,6 +397,7 @@ static int __init clk_disable_unused(void)
struct clk *ck;
unsigned long flags;
+ pr_info("clock: disabling unused clocks to save power\n");
list_for_each_entry(ck, &clocks, node) {
if (ck->ops == &clkops_null)
continue;
@@ -418,7 +419,7 @@ late_initcall(clk_disable_unused);
int __init clk_init(struct clk_functions * custom_clocks)
{
if (!custom_clocks) {
- printk(KERN_ERR "No custom clock functions registered\n");
+ pr_err("No custom clock functions registered\n");
BUG();
}
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index 3008e7104487..f04731820301 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -11,38 +11,16 @@
* 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/init.h>
-#include <linux/delay.h>
-#include <linux/console.h>
-#include <linux/serial.h>
-#include <linux/tty.h>
-#include <linux/serial_8250.h>
-#include <linux/serial_reg.h>
-#include <linux/clk.h>
#include <linux/io.h>
#include <linux/omapfb.h>
-#include <mach/hardware.h>
-#include <asm/system.h>
-#include <asm/pgtable.h>
-#include <asm/mach/map.h>
-#include <asm/setup.h>
-
#include <plat/common.h>
#include <plat/board.h>
-#include <plat/control.h>
-#include <plat/mux.h>
-#include <plat/fpga.h>
-#include <plat/serial.h>
#include <plat/vram.h>
+#include <plat/dsp.h>
-#include <plat/clock.h>
-
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-# include "../mach-omap2/sdrc.h"
-#endif
#define NO_LENGTH_CHECK 0xffffffff
@@ -87,271 +65,5 @@ void __init omap_reserve(void)
{
omapfb_reserve_sdram_memblock();
omap_vram_reserve_sdram_memblock();
+ omap_dsp_reserve_sdram_memblock();
}
-
-/*
- * 32KHz clocksource ... always available, on pretty most chips except
- * OMAP 730 and 1510. Other timers could be used as clocksources, with
- * higher resolution in free-running counter modes (e.g. 12 MHz xtal),
- * but systems won't necessarily want to spend resources that way.
- */
-
-#define OMAP16XX_TIMER_32K_SYNCHRONIZED 0xfffbc410
-
-#if !(defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP15XX))
-
-#include <linux/clocksource.h>
-
-/*
- * offset_32k holds the init time counter value. It is then subtracted
- * from every counter read to achieve a counter that counts time from the
- * kernel boot (needed for sched_clock()).
- */
-static u32 offset_32k __read_mostly;
-
-#ifdef CONFIG_ARCH_OMAP16XX
-static cycle_t omap16xx_32k_read(struct clocksource *cs)
-{
- return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED) - offset_32k;
-}
-#else
-#define omap16xx_32k_read NULL
-#endif
-
-#ifdef CONFIG_ARCH_OMAP2420
-static cycle_t omap2420_32k_read(struct clocksource *cs)
-{
- return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10) - offset_32k;
-}
-#else
-#define omap2420_32k_read NULL
-#endif
-
-#ifdef CONFIG_ARCH_OMAP2430
-static cycle_t omap2430_32k_read(struct clocksource *cs)
-{
- return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10) - offset_32k;
-}
-#else
-#define omap2430_32k_read NULL
-#endif
-
-#ifdef CONFIG_ARCH_OMAP3
-static cycle_t omap34xx_32k_read(struct clocksource *cs)
-{
- return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10) - offset_32k;
-}
-#else
-#define omap34xx_32k_read NULL
-#endif
-
-#ifdef CONFIG_ARCH_OMAP4
-static cycle_t omap44xx_32k_read(struct clocksource *cs)
-{
- return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10) - offset_32k;
-}
-#else
-#define omap44xx_32k_read NULL
-#endif
-
-/*
- * Kernel assumes that sched_clock can be called early but may not have
- * things ready yet.
- */
-static cycle_t omap_32k_read_dummy(struct clocksource *cs)
-{
- return 0;
-}
-
-static struct clocksource clocksource_32k = {
- .name = "32k_counter",
- .rating = 250,
- .read = omap_32k_read_dummy,
- .mask = CLOCKSOURCE_MASK(32),
- .shift = 10,
- .flags = CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-/*
- * Returns current time from boot in nsecs. It's OK for this to wrap
- * around for now, as it's just a relative time stamp.
- */
-unsigned long long sched_clock(void)
-{
- return clocksource_cyc2ns(clocksource_32k.read(&clocksource_32k),
- clocksource_32k.mult, clocksource_32k.shift);
-}
-
-/**
- * read_persistent_clock - Return time from a persistent clock.
- *
- * Reads the time from a source which isn't disabled during PM, the
- * 32k sync timer. Convert the cycles elapsed since last read into
- * nsecs and adds to a monotonically increasing timespec.
- */
-static struct timespec persistent_ts;
-static cycles_t cycles, last_cycles;
-void read_persistent_clock(struct timespec *ts)
-{
- unsigned long long nsecs;
- cycles_t delta;
- struct timespec *tsp = &persistent_ts;
-
- last_cycles = cycles;
- cycles = clocksource_32k.read(&clocksource_32k);
- delta = cycles - last_cycles;
-
- nsecs = clocksource_cyc2ns(delta,
- clocksource_32k.mult, clocksource_32k.shift);
-
- timespec_add_ns(tsp, nsecs);
- *ts = *tsp;
-}
-
-static int __init omap_init_clocksource_32k(void)
-{
- static char err[] __initdata = KERN_ERR
- "%s: can't register clocksource!\n";
-
- if (cpu_is_omap16xx() || cpu_class_is_omap2()) {
- struct clk *sync_32k_ick;
-
- if (cpu_is_omap16xx())
- clocksource_32k.read = omap16xx_32k_read;
- else if (cpu_is_omap2420())
- clocksource_32k.read = omap2420_32k_read;
- else if (cpu_is_omap2430())
- clocksource_32k.read = omap2430_32k_read;
- else if (cpu_is_omap34xx())
- clocksource_32k.read = omap34xx_32k_read;
- else if (cpu_is_omap44xx())
- clocksource_32k.read = omap44xx_32k_read;
- else
- return -ENODEV;
-
- sync_32k_ick = clk_get(NULL, "omap_32ksync_ick");
- if (sync_32k_ick)
- clk_enable(sync_32k_ick);
-
- clocksource_32k.mult = clocksource_hz2mult(32768,
- clocksource_32k.shift);
-
- offset_32k = clocksource_32k.read(&clocksource_32k);
-
- if (clocksource_register(&clocksource_32k))
- printk(err, clocksource_32k.name);
- }
- return 0;
-}
-arch_initcall(omap_init_clocksource_32k);
-
-#endif /* !(defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP15XX)) */
-
-/* Global address base setup code */
-
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-
-static void __init __omap2_set_globals(struct omap_globals *omap2_globals)
-{
- omap2_set_globals_tap(omap2_globals);
- omap2_set_globals_sdrc(omap2_globals);
- omap2_set_globals_control(omap2_globals);
- omap2_set_globals_prcm(omap2_globals);
- omap2_set_globals_uart(omap2_globals);
-}
-
-#endif
-
-#if defined(CONFIG_ARCH_OMAP2420)
-
-static struct omap_globals omap242x_globals = {
- .class = OMAP242X_CLASS,
- .tap = OMAP2_L4_IO_ADDRESS(0x48014000),
- .sdrc = OMAP2420_SDRC_BASE,
- .sms = OMAP2420_SMS_BASE,
- .ctrl = OMAP2420_CTRL_BASE,
- .prm = OMAP2420_PRM_BASE,
- .cm = OMAP2420_CM_BASE,
- .uart1_phys = OMAP2_UART1_BASE,
- .uart2_phys = OMAP2_UART2_BASE,
- .uart3_phys = OMAP2_UART3_BASE,
-};
-
-void __init omap2_set_globals_242x(void)
-{
- __omap2_set_globals(&omap242x_globals);
-}
-#endif
-
-#if defined(CONFIG_ARCH_OMAP2430)
-
-static struct omap_globals omap243x_globals = {
- .class = OMAP243X_CLASS,
- .tap = OMAP2_L4_IO_ADDRESS(0x4900a000),
- .sdrc = OMAP243X_SDRC_BASE,
- .sms = OMAP243X_SMS_BASE,
- .ctrl = OMAP243X_CTRL_BASE,
- .prm = OMAP2430_PRM_BASE,
- .cm = OMAP2430_CM_BASE,
- .uart1_phys = OMAP2_UART1_BASE,
- .uart2_phys = OMAP2_UART2_BASE,
- .uart3_phys = OMAP2_UART3_BASE,
-};
-
-void __init omap2_set_globals_243x(void)
-{
- __omap2_set_globals(&omap243x_globals);
-}
-#endif
-
-#if defined(CONFIG_ARCH_OMAP3)
-
-static struct omap_globals omap3_globals = {
- .class = OMAP343X_CLASS,
- .tap = OMAP2_L4_IO_ADDRESS(0x4830A000),
- .sdrc = OMAP343X_SDRC_BASE,
- .sms = OMAP343X_SMS_BASE,
- .ctrl = OMAP343X_CTRL_BASE,
- .prm = OMAP3430_PRM_BASE,
- .cm = OMAP3430_CM_BASE,
- .uart1_phys = OMAP3_UART1_BASE,
- .uart2_phys = OMAP3_UART2_BASE,
- .uart3_phys = OMAP3_UART3_BASE,
- .uart4_phys = OMAP3_UART4_BASE, /* Only on 3630 */
-};
-
-void __init omap2_set_globals_3xxx(void)
-{
- __omap2_set_globals(&omap3_globals);
-}
-
-void __init omap3_map_io(void)
-{
- omap2_set_globals_3xxx();
- omap34xx_map_common_io();
-}
-#endif
-
-#if defined(CONFIG_ARCH_OMAP4)
-static struct omap_globals omap4_globals = {
- .class = OMAP443X_CLASS,
- .tap = OMAP2_L4_IO_ADDRESS(OMAP443X_SCM_BASE),
- .ctrl = OMAP443X_CTRL_BASE,
- .prm = OMAP4430_PRM_BASE,
- .cm = OMAP4430_CM_BASE,
- .cm2 = OMAP4430_CM2_BASE,
- .uart1_phys = OMAP4_UART1_BASE,
- .uart2_phys = OMAP4_UART2_BASE,
- .uart3_phys = OMAP4_UART3_BASE,
- .uart4_phys = OMAP4_UART4_BASE,
-};
-
-void __init omap2_set_globals_443x(void)
-{
- omap2_set_globals_tap(&omap4_globals);
- omap2_set_globals_control(&omap4_globals);
- omap2_set_globals_prcm(&omap4_globals);
- omap2_set_globals_uart(&omap4_globals);
-}
-#endif
-
diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c
new file mode 100644
index 000000000000..155fe43a672b
--- /dev/null
+++ b/arch/arm/plat-omap/counter_32k.c
@@ -0,0 +1,183 @@
+/*
+ * OMAP 32ksynctimer/counter_32k-related code
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Copyright (C) 2010 Nokia Corporation
+ * Tony Lindgren <tony@atomide.com>
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.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.
+ *
+ * NOTE: This timer is not the same timer as the old OMAP1 MPU timer.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/common.h>
+#include <plat/board.h>
+
+#include <plat/clock.h>
+
+
+/*
+ * 32KHz clocksource ... always available, on pretty most chips except
+ * OMAP 730 and 1510. Other timers could be used as clocksources, with
+ * higher resolution in free-running counter modes (e.g. 12 MHz xtal),
+ * but systems won't necessarily want to spend resources that way.
+ */
+
+#define OMAP16XX_TIMER_32K_SYNCHRONIZED 0xfffbc410
+
+#if !(defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP15XX))
+
+#include <linux/clocksource.h>
+
+/*
+ * offset_32k holds the init time counter value. It is then subtracted
+ * from every counter read to achieve a counter that counts time from the
+ * kernel boot (needed for sched_clock()).
+ */
+static u32 offset_32k __read_mostly;
+
+#ifdef CONFIG_ARCH_OMAP16XX
+static cycle_t omap16xx_32k_read(struct clocksource *cs)
+{
+ return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED) - offset_32k;
+}
+#else
+#define omap16xx_32k_read NULL
+#endif
+
+#ifdef CONFIG_ARCH_OMAP2420
+static cycle_t omap2420_32k_read(struct clocksource *cs)
+{
+ return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10) - offset_32k;
+}
+#else
+#define omap2420_32k_read NULL
+#endif
+
+#ifdef CONFIG_ARCH_OMAP2430
+static cycle_t omap2430_32k_read(struct clocksource *cs)
+{
+ return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10) - offset_32k;
+}
+#else
+#define omap2430_32k_read NULL
+#endif
+
+#ifdef CONFIG_ARCH_OMAP3
+static cycle_t omap34xx_32k_read(struct clocksource *cs)
+{
+ return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10) - offset_32k;
+}
+#else
+#define omap34xx_32k_read NULL
+#endif
+
+#ifdef CONFIG_ARCH_OMAP4
+static cycle_t omap44xx_32k_read(struct clocksource *cs)
+{
+ return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10) - offset_32k;
+}
+#else
+#define omap44xx_32k_read NULL
+#endif
+
+/*
+ * Kernel assumes that sched_clock can be called early but may not have
+ * things ready yet.
+ */
+static cycle_t omap_32k_read_dummy(struct clocksource *cs)
+{
+ return 0;
+}
+
+static struct clocksource clocksource_32k = {
+ .name = "32k_counter",
+ .rating = 250,
+ .read = omap_32k_read_dummy,
+ .mask = CLOCKSOURCE_MASK(32),
+ .shift = 10,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+/*
+ * Returns current time from boot in nsecs. It's OK for this to wrap
+ * around for now, as it's just a relative time stamp.
+ */
+unsigned long long sched_clock(void)
+{
+ return clocksource_cyc2ns(clocksource_32k.read(&clocksource_32k),
+ clocksource_32k.mult, clocksource_32k.shift);
+}
+
+/**
+ * read_persistent_clock - Return time from a persistent clock.
+ *
+ * Reads the time from a source which isn't disabled during PM, the
+ * 32k sync timer. Convert the cycles elapsed since last read into
+ * nsecs and adds to a monotonically increasing timespec.
+ */
+static struct timespec persistent_ts;
+static cycles_t cycles, last_cycles;
+void read_persistent_clock(struct timespec *ts)
+{
+ unsigned long long nsecs;
+ cycles_t delta;
+ struct timespec *tsp = &persistent_ts;
+
+ last_cycles = cycles;
+ cycles = clocksource_32k.read(&clocksource_32k);
+ delta = cycles - last_cycles;
+
+ nsecs = clocksource_cyc2ns(delta,
+ clocksource_32k.mult, clocksource_32k.shift);
+
+ timespec_add_ns(tsp, nsecs);
+ *ts = *tsp;
+}
+
+static int __init omap_init_clocksource_32k(void)
+{
+ static char err[] __initdata = KERN_ERR
+ "%s: can't register clocksource!\n";
+
+ if (cpu_is_omap16xx() || cpu_class_is_omap2()) {
+ struct clk *sync_32k_ick;
+
+ if (cpu_is_omap16xx())
+ clocksource_32k.read = omap16xx_32k_read;
+ else if (cpu_is_omap2420())
+ clocksource_32k.read = omap2420_32k_read;
+ else if (cpu_is_omap2430())
+ clocksource_32k.read = omap2430_32k_read;
+ else if (cpu_is_omap34xx())
+ clocksource_32k.read = omap34xx_32k_read;
+ else if (cpu_is_omap44xx())
+ clocksource_32k.read = omap44xx_32k_read;
+ else
+ return -ENODEV;
+
+ sync_32k_ick = clk_get(NULL, "omap_32ksync_ick");
+ if (sync_32k_ick)
+ clk_enable(sync_32k_ick);
+
+ clocksource_32k.mult = clocksource_hz2mult(32768,
+ clocksource_32k.shift);
+
+ offset_32k = clocksource_32k.read(&clocksource_32k);
+
+ if (clocksource_register(&clocksource_32k))
+ printk(err, clocksource_32k.name);
+ }
+ return 0;
+}
+arch_initcall(omap_init_clocksource_32k);
+
+#endif /* !(defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP15XX)) */
+
diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
index 6d3d33360056..11c54ec8d47f 100644
--- a/arch/arm/plat-omap/cpu-omap.c
+++ b/arch/arm/plat-omap/cpu-omap.c
@@ -40,7 +40,7 @@ static struct clk *mpu_clk;
/* TODO: Add support for SDRAM timing changes */
-int omap_verify_speed(struct cpufreq_policy *policy)
+static int omap_verify_speed(struct cpufreq_policy *policy)
{
if (freq_table)
return cpufreq_frequency_table_verify(policy, freq_table);
@@ -58,7 +58,7 @@ int omap_verify_speed(struct cpufreq_policy *policy)
return 0;
}
-unsigned int omap_getspeed(unsigned int cpu)
+static unsigned int omap_getspeed(unsigned int cpu)
{
unsigned long rate;
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index d1920be7833b..6f42a18b8aa4 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -15,13 +15,13 @@
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/slab.h>
+#include <linux/memblock.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/map.h>
#include <plat/tc.h>
-#include <plat/control.h>
#include <plat/board.h>
#include <plat/mmc.h>
#include <mach/gpio.h>
@@ -272,6 +272,35 @@ static void omap_init_wdt(void)
static inline void omap_init_wdt(void) {}
#endif
+#if defined(CONFIG_TIDSPBRIDGE) || defined(CONFIG_TIDSPBRIDGE_MODULE)
+
+static phys_addr_t omap_dsp_phys_mempool_base;
+
+void __init omap_dsp_reserve_sdram_memblock(void)
+{
+ phys_addr_t size = CONFIG_TIDSPBRIDGE_MEMPOOL_SIZE;
+ phys_addr_t paddr;
+
+ if (!size)
+ return;
+
+ paddr = __memblock_alloc_base(size, SZ_1M, MEMBLOCK_REAL_LIMIT);
+ if (!paddr) {
+ pr_err("%s: failed to reserve %x bytes\n",
+ __func__, size);
+ return;
+ }
+
+ omap_dsp_phys_mempool_base = paddr;
+}
+
+phys_addr_t omap_dsp_get_mempool_base(void)
+{
+ return omap_dsp_phys_mempool_base;
+}
+EXPORT_SYMBOL(omap_dsp_get_mempool_base);
+#endif
+
/*
* This gets called after board-specific INIT_MACHINE, and initializes most
* on-chip peripherals accessible on this board (except for few like USB):
@@ -300,7 +329,6 @@ static int __init omap_init_devices(void)
omap_init_rng();
omap_init_mcpdm();
omap_init_uwire();
- omap_init_wdt();
return 0;
}
arch_initcall(omap_init_devices);
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index ec7eddf9e525..f5c5b8da9a87 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -30,6 +30,7 @@
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/slab.h>
+#include <linux/delay.h>
#include <asm/system.h>
#include <mach/hardware.h>
@@ -996,11 +997,17 @@ void omap_start_dma(int lch)
l = dma_read(CCR(lch));
/*
- * Errata: On ES2.0 BUFFERING disable must be set.
- * This will always fail on ES1.0
+ * Errata: Inter Frame DMA buffering issue (All OMAP2420 and
+ * OMAP2430ES1.0): DMA will wrongly buffer elements if packing and
+ * bursting is enabled. This might result in data gets stalled in
+ * FIFO at the end of the block.
+ * Workaround: DMA channels must have BUFFERING_DISABLED bit set to
+ * guarantee no data will stay in the DMA FIFO in case inter frame
+ * buffering occurs.
*/
- if (cpu_is_omap24xx())
- l |= OMAP_DMA_CCR_EN;
+ if (cpu_is_omap2420() ||
+ (cpu_is_omap2430() && (omap_type() == OMAP2430_REV_ES1_0)))
+ l |= OMAP_DMA_CCR_BUFFERING_DISABLE;
l |= OMAP_DMA_CCR_EN;
dma_write(l, CCR(lch));
@@ -1018,8 +1025,39 @@ void omap_stop_dma(int lch)
dma_write(0, CICR(lch));
l = dma_read(CCR(lch));
- l &= ~OMAP_DMA_CCR_EN;
- dma_write(l, CCR(lch));
+ /* OMAP3 Errata i541: sDMA FIFO draining does not finish */
+ if (cpu_is_omap34xx() && (l & OMAP_DMA_CCR_SEL_SRC_DST_SYNC)) {
+ int i = 0;
+ u32 sys_cf;
+
+ /* Configure No-Standby */
+ l = dma_read(OCP_SYSCONFIG);
+ sys_cf = l;
+ l &= ~DMA_SYSCONFIG_MIDLEMODE_MASK;
+ l |= DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_NO_IDLE);
+ dma_write(l , OCP_SYSCONFIG);
+
+ l = dma_read(CCR(lch));
+ l &= ~OMAP_DMA_CCR_EN;
+ dma_write(l, CCR(lch));
+
+ /* Wait for sDMA FIFO drain */
+ l = dma_read(CCR(lch));
+ while (i < 100 && (l & (OMAP_DMA_CCR_RD_ACTIVE |
+ OMAP_DMA_CCR_WR_ACTIVE))) {
+ udelay(5);
+ i++;
+ l = dma_read(CCR(lch));
+ }
+ if (i >= 100)
+ printk(KERN_ERR "DMA drain did not complete on "
+ "lch %d\n", lch);
+ /* Restore OCP_SYSCONFIG */
+ dma_write(sys_cf, OCP_SYSCONFIG);
+ } else {
+ l &= ~OMAP_DMA_CCR_EN;
+ dma_write(l, CCR(lch));
+ }
if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
int next_lch, cur_lch = lch;
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 44bafdab2dce..1d706cf63ca0 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -581,7 +581,7 @@ int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
* When the functional clock disappears, too quick writes seem
* to cause an abort. XXX Is this still necessary?
*/
- __delay(150000);
+ __delay(300000);
return ret;
}
diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c
index 0054b9501a53..c9e5d7298c40 100644
--- a/arch/arm/plat-omap/fb.c
+++ b/arch/arm/plat-omap/fb.c
@@ -36,6 +36,8 @@
#include <plat/board.h>
#include <plat/sram.h>
+#include "fb.h"
+
#if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE)
static struct omapfb_platform_data omapfb_config;
@@ -94,7 +96,7 @@ static int fbmem_region_reserved(unsigned long start, size_t size)
* Get the region_idx`th region from board config/ATAG and convert it to
* our internal format.
*/
-static int get_fbmem_region(int region_idx, struct omapfb_mem_region *rg)
+static int __init get_fbmem_region(int region_idx, struct omapfb_mem_region *rg)
{
const struct omap_fbmem_config *conf;
u32 paddr;
@@ -126,7 +128,7 @@ static int set_fbmem_region_type(struct omapfb_mem_region *rg, int mem_type,
* type = 0 && paddr = 0, a default don't care case maps to
* the SDRAM type.
*/
- if (rg->type || (!rg->type && !rg->paddr))
+ if (rg->type || !rg->paddr)
return 0;
if (ranges_overlap(rg->paddr, rg->size, mem_start, mem_size)) {
rg->type = mem_type;
@@ -173,11 +175,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)
@@ -262,7 +260,7 @@ void __init omapfb_reserve_sdram_memblock(void)
* this point, since the driver built as a module would have problem with
* freeing / reallocating the regions.
*/
-unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
+unsigned long __init omapfb_reserve_sram(unsigned long sram_pstart,
unsigned long sram_vstart,
unsigned long sram_size,
unsigned long pstart_avail,
@@ -336,7 +334,7 @@ void omapfb_set_ctrl_platform_data(void *data)
omapfb_config.ctrl_platform_data = data;
}
-static inline int omap_init_fb(void)
+static int __init omap_init_fb(void)
{
const struct omap_lcd_config *conf;
@@ -381,7 +379,7 @@ void omapfb_set_platform_data(struct omapfb_platform_data *data)
omapfb_config = *data;
}
-static inline int omap_init_fb(void)
+static int __init omap_init_fb(void)
{
return platform_device_register(&omap_fb_device);
}
@@ -392,7 +390,7 @@ void omapfb_reserve_sdram_memblock(void)
{
}
-unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
+unsigned long __init omapfb_reserve_sram(unsigned long sram_pstart,
unsigned long sram_vstart,
unsigned long sram_size,
unsigned long start_avail,
@@ -411,7 +409,7 @@ void omapfb_reserve_sdram_memblock(void)
{
}
-unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
+unsigned long __init omapfb_reserve_sram(unsigned long sram_pstart,
unsigned long sram_vstart,
unsigned long sram_size,
unsigned long start_avail,
diff --git a/arch/arm/plat-omap/fb.h b/arch/arm/plat-omap/fb.h
new file mode 100644
index 000000000000..d765d0bd8520
--- /dev/null
+++ b/arch/arm/plat-omap/fb.h
@@ -0,0 +1,10 @@
+#ifndef __PLAT_OMAP_FB_H__
+#define __PLAT_OMAP_FB_H__
+
+extern unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
+ unsigned long sram_vstart,
+ unsigned long sram_size,
+ unsigned long pstart_avail,
+ unsigned long size_avail);
+
+#endif /* __PLAT_OMAP_FB_H__ */
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 7951eefe1a0e..c05c653d1674 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -2084,9 +2084,10 @@ void omap2_gpio_prepare_for_idle(int power_state)
for (i = min; i < gpio_bank_count; i++) {
struct gpio_bank *bank = &gpio_bank[i];
- u32 l1, l2;
+ u32 l1 = 0, l2 = 0;
+ int j;
- if (bank->dbck_enable_mask)
+ for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
clk_disable(bank->dbck);
if (power_state > PWRDM_POWER_OFF)
@@ -2151,9 +2152,10 @@ void omap2_gpio_resume_after_idle(void)
min = 1;
for (i = min; i < gpio_bank_count; i++) {
struct gpio_bank *bank = &gpio_bank[i];
- u32 l, gen, gen0, gen1;
+ u32 l = 0, gen, gen0, gen1;
+ int j;
- if (bank->dbck_enable_mask)
+ for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
clk_enable(bank->dbck);
if (!workaround_enabled)
diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h
index 9776b41ad76f..a9d69a09920d 100644
--- a/arch/arm/plat-omap/include/plat/common.h
+++ b/arch/arm/plat-omap/include/plat/common.h
@@ -47,6 +47,7 @@ struct omap_globals {
unsigned long sdrc; /* SDRAM Controller */
unsigned long sms; /* SDRAM Memory Scheduler */
unsigned long ctrl; /* System Control Module */
+ unsigned long ctrl_pad; /* PAD Control Module */
unsigned long prm; /* Power and Reset Management */
unsigned long cm; /* Clock Management */
unsigned long cm2;
@@ -66,7 +67,6 @@ void omap2_set_globals_tap(struct omap_globals *);
void omap2_set_globals_sdrc(struct omap_globals *);
void omap2_set_globals_control(struct omap_globals *);
void omap2_set_globals_prcm(struct omap_globals *);
-void omap2_set_globals_uart(struct omap_globals *);
void omap3_map_io(void);
@@ -91,7 +91,8 @@ void omap3_map_io(void);
})
extern struct device *omap2_get_mpuss_device(void);
-extern struct device *omap2_get_dsp_device(void);
+extern struct device *omap2_get_iva_device(void);
extern struct device *omap2_get_l3_device(void);
+extern struct device *omap4_get_dsp_device(void);
#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */
diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h
index 2e2ae530fced..3fd8b4055727 100644
--- a/arch/arm/plat-omap/include/plat/cpu.h
+++ b/arch/arm/plat-omap/include/plat/cpu.h
@@ -68,10 +68,9 @@ unsigned int omap_rev(void);
#define OMAP_REVBITS_00 0x00
#define OMAP_REVBITS_01 0x01
#define OMAP_REVBITS_02 0x02
-#define OMAP_REVBITS_10 0x10
-#define OMAP_REVBITS_20 0x20
-#define OMAP_REVBITS_30 0x30
-#define OMAP_REVBITS_40 0x40
+#define OMAP_REVBITS_03 0x03
+#define OMAP_REVBITS_04 0x04
+#define OMAP_REVBITS_05 0x05
/*
* Get the CPU revision for OMAP devices
@@ -363,23 +362,24 @@ IS_OMAP_TYPE(3517, 0x3517)
/* Various silicon revisions for omap2 */
#define OMAP242X_CLASS 0x24200024
-#define OMAP2420_REV_ES1_0 0x24200024
-#define OMAP2420_REV_ES2_0 0x24201024
+#define OMAP2420_REV_ES1_0 OMAP242X_CLASS
+#define OMAP2420_REV_ES2_0 (OMAP242X_CLASS | (OMAP_REVBITS_01 << 8))
#define OMAP243X_CLASS 0x24300024
-#define OMAP2430_REV_ES1_0 0x24300024
+#define OMAP2430_REV_ES1_0 OMAP243X_CLASS
#define OMAP343X_CLASS 0x34300034
-#define OMAP3430_REV_ES1_0 0x34300034
-#define OMAP3430_REV_ES2_0 0x34301034
-#define OMAP3430_REV_ES2_1 0x34302034
-#define OMAP3430_REV_ES3_0 0x34303034
-#define OMAP3430_REV_ES3_1 0x34304034
-#define OMAP3430_REV_ES3_1_2 0x34305034
-
-#define OMAP3630_REV_ES1_0 0x36300034
-#define OMAP3630_REV_ES1_1 0x36300134
-#define OMAP3630_REV_ES1_2 0x36300234
+#define OMAP3430_REV_ES1_0 OMAP343X_CLASS
+#define OMAP3430_REV_ES2_0 (OMAP343X_CLASS | (OMAP_REVBITS_01 << 8))
+#define OMAP3430_REV_ES2_1 (OMAP343X_CLASS | (OMAP_REVBITS_02 << 8))
+#define OMAP3430_REV_ES3_0 (OMAP343X_CLASS | (OMAP_REVBITS_03 << 8))
+#define OMAP3430_REV_ES3_1 (OMAP343X_CLASS | (OMAP_REVBITS_04 << 8))
+#define OMAP3430_REV_ES3_1_2 (OMAP343X_CLASS | (OMAP_REVBITS_05 << 8))
+
+#define OMAP363X_CLASS 0x36300034
+#define OMAP3630_REV_ES1_0 OMAP363X_CLASS
+#define OMAP3630_REV_ES1_1 (OMAP363X_CLASS | (OMAP_REVBITS_01 << 8))
+#define OMAP3630_REV_ES1_2 (OMAP363X_CLASS | (OMAP_REVBITS_02 << 8))
#define OMAP35XX_CLASS 0x35000034
#define OMAP3503_REV(v) (OMAP35XX_CLASS | (0x3503 << 16) | (v << 8))
@@ -390,7 +390,8 @@ IS_OMAP_TYPE(3517, 0x3517)
#define OMAP3517_REV(v) (OMAP35XX_CLASS | (0x3517 << 16) | (v << 8))
#define OMAP443X_CLASS 0x44300044
-#define OMAP4430_REV_ES1_0 0x44300044
+#define OMAP4430_REV_ES1_0 OMAP443X_CLASS
+#define OMAP4430_REV_ES2_0 0x44301044
/*
* omap_chip bits
@@ -417,10 +418,12 @@ IS_OMAP_TYPE(3517, 0x3517)
#define CHIP_IS_OMAP4430ES1 (1 << 8)
#define CHIP_IS_OMAP3630ES1_1 (1 << 9)
#define CHIP_IS_OMAP3630ES1_2 (1 << 10)
+#define CHIP_IS_OMAP4430ES2 (1 << 11)
#define CHIP_IS_OMAP24XX (CHIP_IS_OMAP2420 | CHIP_IS_OMAP2430)
-#define CHIP_IS_OMAP4430 (CHIP_IS_OMAP4430ES1)
+#define CHIP_IS_OMAP4430 (CHIP_IS_OMAP4430ES1 | \
+ CHIP_IS_OMAP4430ES2)
/*
* "GE" here represents "greater than or equal to" in terms of ES
diff --git a/arch/arm/plat-omap/include/plat/display.h b/arch/arm/plat-omap/include/plat/display.h
index 8bd15bdb4132..c915a661f1f5 100644
--- a/arch/arm/plat-omap/include/plat/display.h
+++ b/arch/arm/plat-omap/include/plat/display.h
@@ -81,37 +81,6 @@ enum omap_color_mode {
OMAP_DSS_COLOR_ARGB32 = 1 << 11, /* ARGB32 */
OMAP_DSS_COLOR_RGBA32 = 1 << 12, /* RGBA32 */
OMAP_DSS_COLOR_RGBX32 = 1 << 13, /* RGBx32 */
-
- OMAP_DSS_COLOR_GFX_OMAP2 =
- OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 |
- OMAP_DSS_COLOR_CLUT4 | OMAP_DSS_COLOR_CLUT8 |
- OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_RGB16 |
- OMAP_DSS_COLOR_RGB24U | OMAP_DSS_COLOR_RGB24P,
-
- OMAP_DSS_COLOR_VID_OMAP2 =
- OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U |
- OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_YUV2 |
- OMAP_DSS_COLOR_UYVY,
-
- OMAP_DSS_COLOR_GFX_OMAP3 =
- OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 |
- OMAP_DSS_COLOR_CLUT4 | OMAP_DSS_COLOR_CLUT8 |
- OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_ARGB16 |
- OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U |
- OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_ARGB32 |
- OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32,
-
- OMAP_DSS_COLOR_VID1_OMAP3 =
- OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_RGB16 |
- OMAP_DSS_COLOR_RGB24U | OMAP_DSS_COLOR_RGB24P |
- OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_UYVY,
-
- OMAP_DSS_COLOR_VID2_OMAP3 =
- OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_ARGB16 |
- OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U |
- OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_YUV2 |
- OMAP_DSS_COLOR_UYVY | OMAP_DSS_COLOR_ARGB32 |
- OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32,
};
enum omap_lcd_display_type {
diff --git a/arch/arm/plat-omap/include/plat/dma.h b/arch/arm/plat-omap/include/plat/dma.h
index af3a03941add..0cce4ca83aa0 100644
--- a/arch/arm/plat-omap/include/plat/dma.h
+++ b/arch/arm/plat-omap/include/plat/dma.h
@@ -319,6 +319,8 @@
#define OMAP34XX_DMA_USIM_TX 79 /* S_DMA_78 */
#define OMAP34XX_DMA_USIM_RX 80 /* S_DMA_79 */
+#define OMAP36XX_DMA_UART4_TX 81 /* S_DMA_80 */
+#define OMAP36XX_DMA_UART4_RX 82 /* S_DMA_81 */
/*----------------------------------------------------------------------------*/
#define OMAP1_DMA_TOUT_IRQ (1 << 0)
@@ -335,6 +337,10 @@
#define OMAP2_DMA_MISALIGNED_ERR_IRQ (1 << 11)
#define OMAP_DMA_CCR_EN (1 << 7)
+#define OMAP_DMA_CCR_RD_ACTIVE (1 << 9)
+#define OMAP_DMA_CCR_WR_ACTIVE (1 << 10)
+#define OMAP_DMA_CCR_SEL_SRC_DST_SYNC (1 << 24)
+#define OMAP_DMA_CCR_BUFFERING_DISABLE (1 << 25)
#define OMAP_DMA_DATA_TYPE_S8 0x00
#define OMAP_DMA_DATA_TYPE_S16 0x01
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index 20f1054c0a80..dfa3aff9761b 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -45,6 +45,8 @@
#define OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE 0x02
struct omap_dm_timer;
+extern struct omap_dm_timer *gptimer_wakeup;
+extern struct sys_timer omap_timer;
struct clk;
int omap_dm_timer_init(void);
diff --git a/arch/arm/plat-omap/include/plat/dsp.h b/arch/arm/plat-omap/include/plat/dsp.h
new file mode 100644
index 000000000000..9c604b390f9f
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/dsp.h
@@ -0,0 +1,31 @@
+#ifndef __OMAP_DSP_H__
+#define __OMAP_DSP_H__
+
+#include <linux/types.h>
+
+struct omap_dsp_platform_data {
+ void (*dsp_set_min_opp) (u8 opp_id);
+ u8 (*dsp_get_opp) (void);
+ void (*cpu_set_freq) (unsigned long f);
+ unsigned long (*cpu_get_freq) (void);
+ unsigned long mpu_speed[6];
+
+ /* functions to write and read PRCM registers */
+ void (*dsp_prm_write)(u32, s16 , u16);
+ u32 (*dsp_prm_read)(s16 , u16);
+ u32 (*dsp_prm_rmw_bits)(u32, u32, s16, s16);
+ void (*dsp_cm_write)(u32, s16 , u16);
+ u32 (*dsp_cm_read)(s16 , u16);
+ u32 (*dsp_cm_rmw_bits)(u32, u32, s16, s16);
+
+ phys_addr_t phys_mempool_base;
+ phys_addr_t phys_mempool_size;
+};
+
+#if defined(CONFIG_TIDSPBRIDGE) || defined(CONFIG_TIDSPBRIDGE_MODULE)
+extern void omap_dsp_reserve_sdram_memblock(void);
+#else
+static inline void omap_dsp_reserve_sdram_memblock(void) { }
+#endif
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/gpmc-smsc911x.h b/arch/arm/plat-omap/include/plat/gpmc-smsc911x.h
new file mode 100644
index 000000000000..872de0bf1e6b
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/gpmc-smsc911x.h
@@ -0,0 +1,35 @@
+/*
+ * arch/arm/plat-omap/include/plat/gpmc-smsc911x.h
+ *
+ * Copyright (C) 2009 Li-Pro.Net
+ * Stephan Linz <linz@li-pro.net>
+ *
+ * Modified from arch/arm/plat-omap/include/plat/gpmc-smc91x.h
+ *
+ * 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_OMAP_GPMC_SMSC911X_H__
+
+struct omap_smsc911x_platform_data {
+ int cs;
+ int gpio_irq;
+ int gpio_reset;
+ u32 flags;
+};
+
+#if defined(CONFIG_SMSC911X) || \
+ defined(CONFIG_SMSC911X_MODULE)
+
+extern void gpmc_smsc911x_init(struct omap_smsc911x_platform_data *d);
+
+#else
+
+static inline void gpmc_smsc911x_init(struct omap_smsc911x_platform_data *d)
+{
+}
+
+#endif
+#endif
diff --git a/arch/arm/plat-omap/include/plat/i2c.h b/arch/arm/plat-omap/include/plat/i2c.h
index 87f6bf2ea4fa..36a0befd6168 100644
--- a/arch/arm/plat-omap/include/plat/i2c.h
+++ b/arch/arm/plat-omap/include/plat/i2c.h
@@ -18,6 +18,8 @@
* 02110-1301 USA
*
*/
+#ifndef __ASM__ARCH_OMAP_I2C_H
+#define __ASM__ARCH_OMAP_I2C_H
#include <linux/i2c.h>
@@ -36,3 +38,5 @@ static inline int omap_register_i2c_bus(int bus_id, u32 clkrate,
void __init omap1_i2c_mux_pins(int bus_id);
void __init omap2_i2c_mux_pins(int bus_id);
+
+#endif /* __ASM__ARCH_OMAP_I2C_H */
diff --git a/arch/arm/plat-omap/include/plat/irqs.h b/arch/arm/plat-omap/include/plat/irqs.h
index c01d9f08a198..65e20a686713 100644
--- a/arch/arm/plat-omap/include/plat/irqs.h
+++ b/arch/arm/plat-omap/include/plat/irqs.h
@@ -345,6 +345,8 @@
#define INT_34XX_MMC3_IRQ 94
#define INT_34XX_GPT12_IRQ 95
+#define INT_36XX_UART4_IRQ 80
+
#define INT_35XX_HECC0_IRQ 24
#define INT_35XX_HECC1_IRQ 28
#define INT_35XX_EMAC_C0_RXTHRESH_IRQ 67
diff --git a/arch/arm/plat-omap/include/plat/mcbsp.h b/arch/arm/plat-omap/include/plat/mcbsp.h
index 5b20103e68eb..b87d83ccd545 100644
--- a/arch/arm/plat-omap/include/plat/mcbsp.h
+++ b/arch/arm/plat-omap/include/plat/mcbsp.h
@@ -319,6 +319,18 @@ static struct platform_device omap_mcbsp##port_nr = { \
#define RFSREN 0x0002
#define RSYNCERREN 0x0001
+/* CLKR signal muxing options */
+#define CLKR_SRC_CLKR 0
+#define CLKR_SRC_CLKX 1
+
+/* FSR signal muxing options */
+#define FSR_SRC_FSR 0
+#define FSR_SRC_FSX 1
+
+/* McBSP functional clock sources */
+#define MCBSP_CLKS_PRCM_SRC 0
+#define MCBSP_CLKS_PAD_SRC 1
+
/* we don't do multichannel for now */
struct omap_mcbsp_reg_cfg {
u16 spcr2;
@@ -405,6 +417,7 @@ struct omap_mcbsp_spi_cfg {
struct omap_mcbsp_ops {
void (*request)(unsigned int);
void (*free)(unsigned int);
+ int (*set_clks_src)(u8, u8);
};
struct omap_mcbsp_platform_data {
@@ -471,6 +484,9 @@ struct omap_mcbsp {
extern struct omap_mcbsp **mcbsp_ptr;
extern int omap_mcbsp_count, omap_mcbsp_cache_size;
+#define omap_mcbsp_check_valid_id(id) (id < omap_mcbsp_count)
+#define id_to_mcbsp_ptr(id) mcbsp_ptr[id];
+
int omap_mcbsp_init(void);
void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
int size);
@@ -509,6 +525,8 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word);
int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word);
+/* McBSP functional clock source changing function */
+extern int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id);
/* SPI specific API */
void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * spi_cfg);
@@ -517,6 +535,10 @@ int omap_mcbsp_pollread(unsigned int id, u16 * buf);
int omap_mcbsp_pollwrite(unsigned int id, u16 buf);
int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type);
+/* McBSP signal muxing API */
+void omap2_mcbsp1_mux_clkr_src(u8 mux);
+void omap2_mcbsp1_mux_fsr_src(u8 mux);
+
#ifdef CONFIG_ARCH_OMAP3
/* Sidetone specific API */
int omap_st_set_chgain(unsigned int id, int channel, s16 chgain);
diff --git a/arch/arm/plat-omap/include/plat/mmc.h b/arch/arm/plat-omap/include/plat/mmc.h
index 9b89ec601ee2..f57f36abb07e 100644
--- a/arch/arm/plat-omap/include/plat/mmc.h
+++ b/arch/arm/plat-omap/include/plat/mmc.h
@@ -71,12 +71,17 @@ struct omap_mmc_platform_data {
u64 dma_mask;
+ /* Register offset deviation */
+ u16 reg_offset;
+
struct omap_mmc_slot_data {
- /* 4 wire signaling is optional, and is used for SD/SDIO/HSMMC;
- * 8 wire signaling is also optional, and is used with HSMMC
+ /*
+ * 4/8 wires and any additional host capabilities
+ * need to OR'd all capabilities (ref. linux/mmc/host.h)
*/
- u8 wires;
+ u8 wires; /* Used for the MMC driver on omap1 and 2420 */
+ u32 caps; /* Used for the MMC driver on 2430 and later */
/*
* nomux means "standard" muxing is wrong on this board, and
@@ -104,6 +109,7 @@ struct omap_mmc_platform_data {
/* we can put the features above into this variable */
#define HSMMC_HAS_PBIAS (1 << 0)
+#define HSMMC_HAS_UPDATED_RESET (1 << 1)
unsigned features;
int switch_pin; /* gpio (card detect) */
diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h
new file mode 100644
index 000000000000..c8dae02f0704
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/omap-serial.h
@@ -0,0 +1,128 @@
+/*
+ * Driver for OMAP-UART controller.
+ * Based on drivers/serial/8250.c
+ *
+ * Copyright (C) 2010 Texas Instruments.
+ *
+ * Authors:
+ * Govindraj R <govindraj.raja@ti.com>
+ * Thara Gopinath <thara@ti.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.
+ */
+
+#ifndef __OMAP_SERIAL_H__
+#define __OMAP_SERIAL_H__
+
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+
+#include <plat/mux.h>
+
+#define DRIVER_NAME "omap-hsuart"
+
+/*
+ * Use tty device name as ttyO, [O -> OMAP]
+ * in bootargs we specify as console=ttyO0 if uart1
+ * is used as console uart.
+ */
+#define OMAP_SERIAL_NAME "ttyO"
+
+#define OMAP_MDR1_DISABLE 0x07
+#define OMAP_MDR1_MODE13X 0x03
+#define OMAP_MDR1_MODE16X 0x00
+#define OMAP_MODE13X_SPEED 230400
+
+/*
+ * LCR = 0XBF: Switch to Configuration Mode B.
+ * In configuration mode b allow access
+ * to EFR,DLL,DLH.
+ * Reference OMAP TRM Chapter 17
+ * Section: 1.4.3 Mode Selection
+ */
+#define OMAP_UART_LCR_CONF_MDB 0XBF
+
+/* WER = 0x7F
+ * Enable module level wakeup in WER reg
+ */
+#define OMAP_UART_WER_MOD_WKUP 0X7F
+
+/* Enable XON/XOFF flow control on output */
+#define OMAP_UART_SW_TX 0x04
+
+/* Enable XON/XOFF flow control on input */
+#define OMAP_UART_SW_RX 0x04
+
+#define OMAP_UART_SYSC_RESET 0X07
+#define OMAP_UART_TCR_TRIG 0X0F
+#define OMAP_UART_SW_CLR 0XF0
+#define OMAP_UART_FIFO_CLR 0X06
+
+#define OMAP_UART_DMA_CH_FREE -1
+
+#define RX_TIMEOUT (3 * HZ)
+#define OMAP_MAX_HSUART_PORTS 4
+
+#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
+
+struct omap_uart_port_info {
+ bool dma_enabled; /* To specify DMA Mode */
+ unsigned int uartclk; /* UART clock rate */
+ void __iomem *membase; /* ioremap cookie or NULL */
+ resource_size_t mapbase; /* resource base */
+ unsigned long irqflags; /* request_irq flags */
+ upf_t flags; /* UPF_* flags */
+};
+
+struct uart_omap_dma {
+ u8 uart_dma_tx;
+ u8 uart_dma_rx;
+ int rx_dma_channel;
+ int tx_dma_channel;
+ dma_addr_t rx_buf_dma_phys;
+ dma_addr_t tx_buf_dma_phys;
+ unsigned int uart_base;
+ /*
+ * Buffer for rx dma.It is not required for tx because the buffer
+ * comes from port structure.
+ */
+ unsigned char *rx_buf;
+ unsigned int prev_rx_dma_pos;
+ int tx_buf_size;
+ int tx_dma_used;
+ int rx_dma_used;
+ spinlock_t tx_lock;
+ spinlock_t rx_lock;
+ /* timer to poll activity on rx dma */
+ struct timer_list rx_timer;
+ int rx_buf_size;
+ int rx_timeout;
+};
+
+struct uart_omap_port {
+ struct uart_port port;
+ struct uart_omap_dma uart_dma;
+ struct platform_device *pdev;
+
+ unsigned char ier;
+ unsigned char lcr;
+ unsigned char mcr;
+ unsigned char fcr;
+ unsigned char efr;
+
+ int use_dma;
+ /*
+ * Some bits in registers are cleared on a read, so they must
+ * be saved whenever the register is read but the bits will not
+ * be immediately processed.
+ */
+ unsigned int lsr_break_flag;
+ unsigned char msr_saved_flags;
+ char name[20];
+ unsigned long port_activity;
+};
+
+#endif /* __OMAP_SERIAL_H__ */
diff --git a/arch/arm/plat-omap/include/plat/omap24xx.h b/arch/arm/plat-omap/include/plat/omap24xx.h
index 7055672a8c68..92df9e27cc5c 100644
--- a/arch/arm/plat-omap/include/plat/omap24xx.h
+++ b/arch/arm/plat-omap/include/plat/omap24xx.h
@@ -40,7 +40,7 @@
#define OMAP24XX_IC_BASE (L4_24XX_BASE + 0xfe000)
#define OMAP24XX_IVA_INTC_BASE 0x40000000
-#define OMAP2420_CTRL_BASE L4_24XX_BASE
+#define OMAP242X_CTRL_BASE L4_24XX_BASE
#define OMAP2420_32KSYNCT_BASE (L4_24XX_BASE + 0x4000)
#define OMAP2420_PRCM_BASE (L4_24XX_BASE + 0x8000)
#define OMAP2420_CM_BASE (L4_24XX_BASE + 0x8000)
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/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
index 25cd9ac3b095..28e2d1a78433 100644
--- a/arch/arm/plat-omap/include/plat/omap_device.h
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -36,6 +36,8 @@
#include <plat/omap_hwmod.h>
+extern struct device omap_device_parent;
+
/* omap_device._state values */
#define OMAP_DEVICE_STATE_UNKNOWN 0
#define OMAP_DEVICE_STATE_ENABLED 1
@@ -62,7 +64,6 @@
*
*/
struct omap_device {
- u32 magic;
struct platform_device pdev;
struct omap_hwmod **hwmods;
struct omap_device_pm_latency *pm_lats;
@@ -82,7 +83,6 @@ int omap_device_shutdown(struct platform_device *pdev);
/* Core code interface */
-bool omap_device_is_valid(struct omap_device *od);
int omap_device_count_resources(struct omap_device *od);
int omap_device_fill_resources(struct omap_device *od, struct resource *res);
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index a4e508dfaba2..7eaa8edf3b14 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -14,19 +14,16 @@
*
* These headers and macros are used to define OMAP on-chip module
* data and their integration with other OMAP modules and Linux.
- *
- * References:
- * - OMAP2420 Multimedia Processor Silicon Revision 2.1.1, 2.2 (SWPU064)
- * - OMAP2430 Multimedia Device POP Silicon Revision 2.1 (SWPU090)
- * - OMAP34xx Multimedia Device Silicon Revision 3.1 (SWPU108)
- * - OMAP4430 Multimedia Device Silicon Revision 1.0 (SWPU140)
- * - Open Core Protocol Specification 2.2
+ * Copious documentation and references can also be found in the
+ * omap_hwmod code, in arch/arm/mach-omap2/omap_hwmod.c (as of this
+ * writing).
*
* To do:
* - add interconnect error log structures
* - add pinmuxing
* - init_conn_id_bit (CONNID_BIT_VECTOR)
* - implement default hwmod SMS/SDRC flags?
+ * - remove unused fields
*
*/
#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD_H
@@ -35,6 +32,7 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/ioport.h>
+#include <linux/mutex.h>
#include <plat/cpu.h>
struct omap_device;
@@ -96,7 +94,7 @@ struct omap_hwmod_irq_info {
/**
* struct omap_hwmod_dma_info - DMA channels used by the hwmod
* @name: name of the DMA channel (module local name)
- * @dma_ch: DMA channel ID
+ * @dma_req: DMA request ID
*
* @name should be something short, e.g., "tx" or "rx". It is for use
* by platform_get_resource_byname(). It is defined locally to the
@@ -104,7 +102,20 @@ struct omap_hwmod_irq_info {
*/
struct omap_hwmod_dma_info {
const char *name;
- u16 dma_ch;
+ u16 dma_req;
+};
+
+/**
+ * struct omap_hwmod_rst_info - IPs reset lines use by hwmod
+ * @name: name of the reset line (module local name)
+ * @rst_shift: Offset of the reset bit
+ *
+ * @name should be something short, e.g., "cpu0" or "rst". It is defined
+ * locally to the hwmod.
+ */
+struct omap_hwmod_rst_info {
+ const char *name;
+ u8 rst_shift;
};
/**
@@ -237,8 +248,9 @@ struct omap_hwmod_ocp_if {
#define SYSC_HAS_CLOCKACTIVITY (1 << 4)
#define SYSC_HAS_SIDLEMODE (1 << 5)
#define SYSC_HAS_MIDLEMODE (1 << 6)
-#define SYSS_MISSING (1 << 7)
+#define SYSS_HAS_RESET_STATUS (1 << 7)
#define SYSC_NO_CACHE (1 << 8) /* XXX SW flag, belongs elsewhere */
+#define SYSC_HAS_RESET_STATUS (1 << 9)
/* omap_hwmod_sysconfig.clockact flags */
#define CLOCKACT_TEST_BOTH 0x0
@@ -327,10 +339,12 @@ struct omap_hwmod_omap2_prcm {
/**
* struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data
* @clkctrl_reg: PRCM address of the clock control register
+ * @rstctrl_reg: adress of the XXX_RSTCTRL register located in the PRM
* @submodule_wkdep_bit: bit shift of the WKDEP range
*/
struct omap_hwmod_omap4_prcm {
void __iomem *clkctrl_reg;
+ void __iomem *rstctrl_reg;
u8 submodule_wkdep_bit;
};
@@ -352,6 +366,11 @@ struct omap_hwmod_omap4_prcm {
* HWMOD_SET_DEFAULT_CLOCKACT: program CLOCKACTIVITY bits at startup
* HWMOD_NO_IDLEST : this module does not have idle status - this is the case
* only for few initiator modules on OMAP2 & 3.
+ * HWMOD_CONTROL_OPT_CLKS_IN_RESET: Enable all optional clocks during reset.
+ * This is needed for devices like DSS that require optional clocks enabled
+ * in order to complete the reset. Optional clocks will be disabled
+ * again after the reset.
+ * HWMOD_16BIT_REG: Module has 16bit registers
*/
#define HWMOD_SWSUP_SIDLE (1 << 0)
#define HWMOD_SWSUP_MSTANDBY (1 << 1)
@@ -360,6 +379,8 @@ struct omap_hwmod_omap4_prcm {
#define HWMOD_NO_OCP_AUTOIDLE (1 << 4)
#define HWMOD_SET_DEFAULT_CLOCKACT (1 << 5)
#define HWMOD_NO_IDLEST (1 << 6)
+#define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7)
+#define HWMOD_16BIT_REG (1 << 8)
/*
* omap_hwmod._int_flags definitions
@@ -410,7 +431,7 @@ struct omap_hwmod_class {
* @class: struct omap_hwmod_class * to the class of this hwmod
* @od: struct omap_device currently associated with this hwmod (internal use)
* @mpu_irqs: ptr to an array of MPU IRQs (see also mpu_irqs_cnt)
- * @sdma_chs: ptr to an array of SDMA channel IDs (see also sdma_chs_cnt)
+ * @sdma_reqs: ptr to an array of System DMA request IDs (see sdma_reqs_cnt)
* @prcm: PRCM data pertaining to this hwmod
* @main_clk: main clock: OMAP clock name
* @_clk: pointer to the main struct clk (filled in at runtime)
@@ -424,7 +445,7 @@ struct omap_hwmod_class {
* @msuspendmux_reg_id: CONTROL_MSUSPENDMUX register ID (1-6)
* @msuspendmux_shift: CONTROL_MSUSPENDMUX register bit shift
* @mpu_irqs_cnt: number of @mpu_irqs
- * @sdma_chs_cnt: number of @sdma_chs
+ * @sdma_reqs_cnt: number of @sdma_reqs
* @opt_clks_cnt: number of @opt_clks
* @master_cnt: number of @master entries
* @slaves_cnt: number of @slave entries
@@ -433,6 +454,7 @@ struct omap_hwmod_class {
* @_state: internal-use hwmod state
* @flags: hwmod flags (documented below)
* @omap_chip: OMAP chips this hwmod is present on
+ * @_mutex: mutex serializing operations on this hwmod
* @node: list node for hwmod list (internal use)
*
* @main_clk refers to this module's "main clock," which for our
@@ -448,7 +470,8 @@ struct omap_hwmod {
struct omap_hwmod_class *class;
struct omap_device *od;
struct omap_hwmod_irq_info *mpu_irqs;
- struct omap_hwmod_dma_info *sdma_chs;
+ struct omap_hwmod_dma_info *sdma_reqs;
+ struct omap_hwmod_rst_info *rst_lines;
union {
struct omap_hwmod_omap2_prcm omap2;
struct omap_hwmod_omap4_prcm omap4;
@@ -461,6 +484,7 @@ struct omap_hwmod {
void *dev_attr;
u32 _sysc_cache;
void __iomem *_mpu_rt_va;
+ struct mutex _mutex;
struct list_head node;
u16 flags;
u8 _mpu_port_index;
@@ -468,7 +492,8 @@ struct omap_hwmod {
u8 msuspendmux_shift;
u8 response_lat;
u8 mpu_irqs_cnt;
- u8 sdma_chs_cnt;
+ u8 sdma_reqs_cnt;
+ u8 rst_lines_cnt;
u8 opt_clks_cnt;
u8 masters_cnt;
u8 slaves_cnt;
@@ -492,6 +517,10 @@ int omap_hwmod_idle(struct omap_hwmod *oh);
int _omap_hwmod_idle(struct omap_hwmod *oh);
int omap_hwmod_shutdown(struct omap_hwmod *oh);
+int omap_hwmod_assert_hardreset(struct omap_hwmod *oh, const char *name);
+int omap_hwmod_deassert_hardreset(struct omap_hwmod *oh, const char *name);
+int omap_hwmod_read_hardreset(struct omap_hwmod *oh, const char *name);
+
int omap_hwmod_enable_clocks(struct omap_hwmod *oh);
int omap_hwmod_disable_clocks(struct omap_hwmod *oh);
@@ -500,8 +529,8 @@ int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode);
int omap_hwmod_reset(struct omap_hwmod *oh);
void omap_hwmod_ocp_barrier(struct omap_hwmod *oh);
-void omap_hwmod_writel(u32 v, struct omap_hwmod *oh, u16 reg_offs);
-u32 omap_hwmod_readl(struct omap_hwmod *oh, u16 reg_offs);
+void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs);
+u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs);
int omap_hwmod_count_resources(struct omap_hwmod *oh);
int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res);
@@ -534,5 +563,6 @@ int omap_hwmod_for_each_by_class(const char *classname,
extern int omap2420_hwmod_init(void);
extern int omap2430_hwmod_init(void);
extern int omap3xxx_hwmod_init(void);
+extern int omap44xx_hwmod_init(void);
#endif
diff --git a/arch/arm/plat-omap/include/plat/powerdomain.h b/arch/arm/plat-omap/include/plat/powerdomain.h
index fb6ec74fe39e..9ca420dcd2f8 100644
--- a/arch/arm/plat-omap/include/plat/powerdomain.h
+++ b/arch/arm/plat-omap/include/plat/powerdomain.h
@@ -32,6 +32,7 @@
/* Powerdomain allowable state bitfields */
#define PWRSTS_ON (1 << PWRDM_POWER_ON)
+#define PWRSTS_OFF (1 << PWRDM_POWER_OFF)
#define PWRSTS_OFF_ON ((1 << PWRDM_POWER_OFF) | \
(1 << PWRDM_POWER_ON))
@@ -161,5 +162,6 @@ int pwrdm_state_switch(struct powerdomain *pwrdm);
int pwrdm_clkdm_state_switch(struct clockdomain *clkdm);
int pwrdm_pre_transition(void);
int pwrdm_post_transition(void);
+int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm);
#endif
diff --git a/arch/arm/plat-omap/include/plat/prcm.h b/arch/arm/plat-omap/include/plat/prcm.h
index 9fbd91419cd1..ab77442e42ab 100644
--- a/arch/arm/plat-omap/include/plat/prcm.h
+++ b/arch/arm/plat-omap/include/plat/prcm.h
@@ -38,6 +38,8 @@ u32 prm_read_mod_reg(s16 module, u16 idx);
void prm_write_mod_reg(u32 val, s16 module, u16 idx);
u32 prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
u32 prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask);
+u32 omap4_prm_read_bits_shift(void __iomem *reg, u32 mask);
+u32 omap4_prm_rmw_reg_bits(u32 mask, u32 bits, void __iomem *reg);
u32 cm_read_mod_reg(s16 module, u16 idx);
void cm_write_mod_reg(u32 val, s16 module, u16 idx);
u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
diff --git a/arch/arm/plat-omap/include/plat/sdrc.h b/arch/arm/plat-omap/include/plat/sdrc.h
index 7b76f50564ba..efd87c8dda69 100644
--- a/arch/arm/plat-omap/include/plat/sdrc.h
+++ b/arch/arm/plat-omap/include/plat/sdrc.h
@@ -147,6 +147,7 @@ struct memory_timings {
};
extern void omap2xxx_sdrc_init_params(u32 force_lock_to_unlock_mode);
+struct omap_sdrc_params *rx51_get_sdram_timings(void);
u32 omap2xxx_sdrc_dll_is_unlocked(void);
u32 omap2xxx_sdrc_reprogram(u32 level, u32 force);
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/sram.h b/arch/arm/plat-omap/include/plat/sram.h
index 16a1b458d53c..5905100b29a1 100644
--- a/arch/arm/plat-omap/include/plat/sram.h
+++ b/arch/arm/plat-omap/include/plat/sram.h
@@ -11,7 +11,6 @@
#ifndef __ARCH_ARM_OMAP_SRAM_H
#define __ARCH_ARM_OMAP_SRAM_H
-extern int __init omap_sram_init(void);
extern void * omap_sram_push(void * start, unsigned long size);
extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl);
diff --git a/arch/arm/plat-omap/include/plat/uncompress.h b/arch/arm/plat-omap/include/plat/uncompress.h
index ddf723be48dc..9036e374e0ac 100644
--- a/arch/arm/plat-omap/include/plat/uncompress.h
+++ b/arch/arm/plat-omap/include/plat/uncompress.h
@@ -139,10 +139,14 @@ static inline void __arch_decomp_setup(unsigned long arch_id)
DEBUG_LL_OMAP2(1, omap3evm);
DEBUG_LL_OMAP3(1, omap_3430sdp);
DEBUG_LL_OMAP3(1, omap_3630sdp);
+ DEBUG_LL_OMAP3(1, omap3530_lv_som);
+ DEBUG_LL_OMAP3(1, omap3_torpedo);
/* omap3 based boards using UART3 */
DEBUG_LL_OMAP3(3, cm_t35);
+ DEBUG_LL_OMAP3(3, cm_t3517);
DEBUG_LL_OMAP3(3, igep0020);
+ DEBUG_LL_OMAP3(3, igep0030);
DEBUG_LL_OMAP3(3, nokia_rx51);
DEBUG_LL_OMAP3(3, omap3517evm);
DEBUG_LL_OMAP3(3, omap3_beagle);
@@ -153,6 +157,7 @@ static inline void __arch_decomp_setup(unsigned long arch_id)
/* omap4 based boards using UART3 */
DEBUG_LL_OMAP4(3, omap_4430sdp);
+ DEBUG_LL_OMAP4(3, omap4_panda);
/* zoom2/3 external uart */
DEBUG_LL_ZOOM(omap_zoom2);
diff --git a/arch/arm/plat-omap/include/plat/usb.h b/arch/arm/plat-omap/include/plat/usb.h
index 2a9427c8cc48..59c7fe731f28 100644
--- a/arch/arm/plat-omap/include/plat/usb.h
+++ b/arch/arm/plat-omap/include/plat/usb.h
@@ -105,7 +105,7 @@ static inline void omap1_usb_init(struct omap_usb_config *pdata)
#if defined(CONFIG_ARCH_OMAP_OTG) || defined(CONFIG_ARCH_OMAP_OTG_MODULE)
void omap2_usbfs_init(struct omap_usb_config *pdata);
#else
-static inline omap2_usbfs_init(struct omap_usb_config *pdata)
+static inline void omap2_usbfs_init(struct omap_usb_config *pdata)
{
}
#endif
@@ -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/include/plat/vrfb.h b/arch/arm/plat-omap/include/plat/vrfb.h
index d8a03ced3b10..3792bdea2f6d 100644
--- a/arch/arm/plat-omap/include/plat/vrfb.h
+++ b/arch/arm/plat-omap/include/plat/vrfb.h
@@ -35,6 +35,7 @@ struct vrfb {
bool yuv_mode;
};
+#ifdef CONFIG_OMAP2_VRFB
extern int omap_vrfb_request_ctx(struct vrfb *vrfb);
extern void omap_vrfb_release_ctx(struct vrfb *vrfb);
extern void omap_vrfb_adjust_size(u16 *width, u16 *height,
@@ -47,4 +48,19 @@ extern void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr,
extern int omap_vrfb_map_angle(struct vrfb *vrfb, u16 height, u8 rot);
extern void omap_vrfb_restore_context(void);
+#else
+static inline int omap_vrfb_request_ctx(struct vrfb *vrfb) { return 0; }
+static inline void omap_vrfb_release_ctx(struct vrfb *vrfb) {}
+static inline void omap_vrfb_adjust_size(u16 *width, u16 *height,
+ u8 bytespp) {}
+static inline u32 omap_vrfb_min_phys_size(u16 width, u16 height, u8 bytespp)
+ { return 0; }
+static inline u16 omap_vrfb_max_height(u32 phys_size, u16 width, u8 bytespp)
+ { return 0; }
+static inline void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr,
+ u16 width, u16 height, unsigned bytespp, bool yuv_mode) {}
+static inline int omap_vrfb_map_angle(struct vrfb *vrfb, u16 height, u8 rot)
+ { return 0; }
+static inline void omap_vrfb_restore_context(void) {}
+#endif
#endif /* __VRFB_H */
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/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index 0c8612fd8312..eac4b978e9fd 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -33,7 +33,7 @@
struct omap_mcbsp **mcbsp_ptr;
int omap_mcbsp_count, omap_mcbsp_cache_size;
-void omap_mcbsp_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
+static void omap_mcbsp_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
{
if (cpu_class_is_omap1()) {
((u16 *)mcbsp->reg_cache)[reg / sizeof(u16)] = (u16)val;
@@ -47,7 +47,7 @@ void omap_mcbsp_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
}
}
-int omap_mcbsp_read(struct omap_mcbsp *mcbsp, u16 reg, bool from_cache)
+static int omap_mcbsp_read(struct omap_mcbsp *mcbsp, u16 reg, bool from_cache)
{
if (cpu_class_is_omap1()) {
return !from_cache ? __raw_readw(mcbsp->io_base + reg) :
@@ -62,12 +62,12 @@ int omap_mcbsp_read(struct omap_mcbsp *mcbsp, u16 reg, bool from_cache)
}
#ifdef CONFIG_ARCH_OMAP3
-void omap_mcbsp_st_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
+static void omap_mcbsp_st_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
{
__raw_writel(val, mcbsp->st_data->io_base_st + reg);
}
-int omap_mcbsp_st_read(struct omap_mcbsp *mcbsp, u16 reg)
+static int omap_mcbsp_st_read(struct omap_mcbsp *mcbsp, u16 reg)
{
return __raw_readl(mcbsp->st_data->io_base_st + reg);
}
@@ -80,9 +80,6 @@ int omap_mcbsp_st_read(struct omap_mcbsp *mcbsp, u16 reg)
#define MCBSP_READ_CACHE(mcbsp, reg) \
omap_mcbsp_read(mcbsp, OMAP_MCBSP_REG_##reg, 1)
-#define omap_mcbsp_check_valid_id(id) (id < omap_mcbsp_count)
-#define id_to_mcbsp_ptr(id) mcbsp_ptr[id];
-
#define MCBSP_ST_READ(mcbsp, reg) \
omap_mcbsp_st_read(mcbsp, OMAP_ST_REG_##reg)
#define MCBSP_ST_WRITE(mcbsp, reg, val) \
@@ -878,7 +875,7 @@ EXPORT_SYMBOL(omap_mcbsp_free);
void omap_mcbsp_start(unsigned int id, int tx, int rx)
{
struct omap_mcbsp *mcbsp;
- int idle;
+ int enable_srg = 0;
u16 w;
if (!omap_mcbsp_check_valid_id(id)) {
@@ -893,10 +890,13 @@ void omap_mcbsp_start(unsigned int id, int tx, int rx)
mcbsp->rx_word_length = (MCBSP_READ_CACHE(mcbsp, RCR1) >> 5) & 0x7;
mcbsp->tx_word_length = (MCBSP_READ_CACHE(mcbsp, XCR1) >> 5) & 0x7;
- idle = !((MCBSP_READ_CACHE(mcbsp, SPCR2) |
- MCBSP_READ_CACHE(mcbsp, SPCR1)) & 1);
+ /* Only enable SRG, if McBSP is master */
+ w = MCBSP_READ_CACHE(mcbsp, PCR0);
+ if (w & (FSXM | FSRM | CLKXM | CLKRM))
+ enable_srg = !((MCBSP_READ_CACHE(mcbsp, SPCR2) |
+ MCBSP_READ_CACHE(mcbsp, SPCR1)) & 1);
- if (idle) {
+ if (enable_srg) {
/* Start the sample generator */
w = MCBSP_READ_CACHE(mcbsp, SPCR2);
MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 6));
@@ -919,7 +919,7 @@ void omap_mcbsp_start(unsigned int id, int tx, int rx)
*/
udelay(500);
- if (idle) {
+ if (enable_srg) {
/* Start frame sync */
w = MCBSP_READ_CACHE(mcbsp, SPCR2);
MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 7));
@@ -1645,7 +1645,7 @@ static const struct attribute_group sidetone_attr_group = {
.attrs = (struct attribute **)sidetone_attrs,
};
-int __devinit omap_st_add(struct omap_mcbsp *mcbsp)
+static int __devinit omap_st_add(struct omap_mcbsp *mcbsp)
{
struct omap_mcbsp_platform_data *pdata = mcbsp->pdata;
struct omap_mcbsp_st_data *st_data;
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index d2b160942ccc..abe933cd8f09 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -82,6 +82,7 @@
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/io.h>
+#include <linux/clk.h>
#include <plat/omap_device.h>
#include <plat/omap_hwmod.h>
@@ -90,12 +91,6 @@
#define USE_WAKEUP_LAT 0
#define IGNORE_WAKEUP_LAT 1
-/*
- * OMAP_DEVICE_MAGIC: used to determine whether a struct omap_device
- * obtained via container_of() is in fact a struct omap_device
- */
-#define OMAP_DEVICE_MAGIC 0xf00dcafe
-
/* Private functions */
/**
@@ -243,6 +238,44 @@ static inline struct omap_device *_find_by_pdev(struct platform_device *pdev)
return container_of(pdev, struct omap_device, pdev);
}
+/**
+ * _add_optional_clock_alias - Add clock alias for hwmod optional clocks
+ * @od: struct omap_device *od
+ *
+ * For every optional clock present per hwmod per omap_device, this function
+ * adds an entry in the clocks list of the form <dev-id=dev_name, con-id=role>
+ * if an entry is already present in it with the form <dev-id=NULL, con-id=role>
+ *
+ * The function is called from inside omap_device_build_ss(), after
+ * omap_device_register.
+ *
+ * This allows drivers to get a pointer to its optional clocks based on its role
+ * by calling clk_get(<dev*>, <role>).
+ *
+ * No return value.
+ */
+static void _add_optional_clock_alias(struct omap_device *od,
+ struct omap_hwmod *oh)
+{
+ int i;
+
+ for (i = 0; i < oh->opt_clks_cnt; i++) {
+ struct omap_hwmod_opt_clk *oc;
+ int r;
+
+ oc = &oh->opt_clks[i];
+
+ if (!oc->_clk)
+ continue;
+
+ r = clk_add_alias(oc->role, dev_name(&od->pdev.dev),
+ (char *)oc->clk, &od->pdev.dev);
+ if (r)
+ pr_err("omap_device: %s: clk_add_alias for %s failed\n",
+ dev_name(&od->pdev.dev), oc->role);
+ }
+}
+
/* Public functions for use by core code */
@@ -257,12 +290,11 @@ static inline struct omap_device *_find_by_pdev(struct platform_device *pdev)
*/
int omap_device_count_resources(struct omap_device *od)
{
- struct omap_hwmod *oh;
int c = 0;
int i;
- for (i = 0, oh = *od->hwmods; i < od->hwmods_cnt; i++, oh++)
- c += omap_hwmod_count_resources(oh);
+ for (i = 0; i < od->hwmods_cnt; i++)
+ c += omap_hwmod_count_resources(od->hwmods[i]);
pr_debug("omap_device: %s: counted %d total resources across %d "
"hwmods\n", od->pdev.name, c, od->hwmods_cnt);
@@ -289,12 +321,11 @@ int omap_device_count_resources(struct omap_device *od)
*/
int omap_device_fill_resources(struct omap_device *od, struct resource *res)
{
- struct omap_hwmod *oh;
int c = 0;
int i, r;
- for (i = 0, oh = *od->hwmods; i < od->hwmods_cnt; i++, oh++) {
- r = omap_hwmod_fill_resources(oh, res);
+ for (i = 0; i < od->hwmods_cnt; i++) {
+ r = omap_hwmod_fill_resources(od->hwmods[i], res);
res += r;
c += r;
}
@@ -414,15 +445,15 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
od->pm_lats = pm_lats;
od->pm_lats_cnt = pm_lats_cnt;
- od->magic = OMAP_DEVICE_MAGIC;
-
if (is_early_device)
ret = omap_early_device_register(od);
else
ret = omap_device_register(od);
- for (i = 0; i < oh_cnt; i++)
+ for (i = 0; i < oh_cnt; i++) {
hwmods[i]->od = od;
+ _add_optional_clock_alias(od, hwmods[i]);
+ }
if (ret)
goto odbs_exit4;
@@ -473,6 +504,7 @@ int omap_device_register(struct omap_device *od)
{
pr_debug("omap_device: %s: registering\n", od->pdev.name);
+ od->pdev.dev.parent = &omap_device_parent;
return platform_device_register(&od->pdev);
}
@@ -566,7 +598,6 @@ int omap_device_shutdown(struct platform_device *pdev)
{
int ret, i;
struct omap_device *od;
- struct omap_hwmod *oh;
od = _find_by_pdev(pdev);
@@ -579,8 +610,8 @@ int omap_device_shutdown(struct platform_device *pdev)
ret = _omap_device_deactivate(od, IGNORE_WAKEUP_LAT);
- for (i = 0, oh = *od->hwmods; i < od->hwmods_cnt; i++, oh++)
- omap_hwmod_shutdown(oh);
+ for (i = 0; i < od->hwmods_cnt; i++)
+ omap_hwmod_shutdown(od->hwmods[i]);
od->_state = OMAP_DEVICE_STATE_SHUTDOWN;
@@ -627,18 +658,6 @@ int omap_device_align_pm_lat(struct platform_device *pdev,
}
/**
- * omap_device_is_valid - Check if pointer is a valid omap_device
- * @od: struct omap_device *
- *
- * Return whether struct omap_device pointer @od points to a valid
- * omap_device.
- */
-bool omap_device_is_valid(struct omap_device *od)
-{
- return (od && od->magic == OMAP_DEVICE_MAGIC);
-}
-
-/**
* omap_device_get_pwrdm - return the powerdomain * associated with @od
* @od: struct omap_device *
*
@@ -692,11 +711,10 @@ void __iomem *omap_device_get_rt_va(struct omap_device *od)
*/
int omap_device_enable_hwmods(struct omap_device *od)
{
- struct omap_hwmod *oh;
int i;
- for (i = 0, oh = *od->hwmods; i < od->hwmods_cnt; i++, oh++)
- omap_hwmod_enable(oh);
+ for (i = 0; i < od->hwmods_cnt; i++)
+ omap_hwmod_enable(od->hwmods[i]);
/* XXX pass along return value here? */
return 0;
@@ -710,11 +728,10 @@ int omap_device_enable_hwmods(struct omap_device *od)
*/
int omap_device_idle_hwmods(struct omap_device *od)
{
- struct omap_hwmod *oh;
int i;
- for (i = 0, oh = *od->hwmods; i < od->hwmods_cnt; i++, oh++)
- omap_hwmod_idle(oh);
+ for (i = 0; i < od->hwmods_cnt; i++)
+ omap_hwmod_idle(od->hwmods[i]);
/* XXX pass along return value here? */
return 0;
@@ -729,11 +746,10 @@ int omap_device_idle_hwmods(struct omap_device *od)
*/
int omap_device_disable_clocks(struct omap_device *od)
{
- struct omap_hwmod *oh;
int i;
- for (i = 0, oh = *od->hwmods; i < od->hwmods_cnt; i++, oh++)
- omap_hwmod_disable_clocks(oh);
+ for (i = 0; i < od->hwmods_cnt; i++)
+ omap_hwmod_disable_clocks(od->hwmods[i]);
/* XXX pass along return value here? */
return 0;
@@ -748,12 +764,22 @@ int omap_device_disable_clocks(struct omap_device *od)
*/
int omap_device_enable_clocks(struct omap_device *od)
{
- struct omap_hwmod *oh;
int i;
- for (i = 0, oh = *od->hwmods; i < od->hwmods_cnt; i++, oh++)
- omap_hwmod_enable_clocks(oh);
+ for (i = 0; i < od->hwmods_cnt; i++)
+ omap_hwmod_enable_clocks(od->hwmods[i]);
/* XXX pass along return value here? */
return 0;
}
+
+struct device omap_device_parent = {
+ .init_name = "omap",
+ .parent = &platform_bus,
+};
+
+static int __init omap_device_init(void)
+{
+ return device_register(&omap_device_parent);
+}
+core_initcall(omap_device_init);
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index 10b3b4c63372..e2c8eebe6b3a 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -19,6 +19,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
+#include <linux/omapfb.h>
#include <asm/tlb.h>
#include <asm/cacheflush.h>
@@ -30,8 +31,8 @@
#include <plat/cpu.h>
#include <plat/vram.h>
-#include <plat/control.h>
-
+#include "sram.h"
+#include "fb.h"
#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
# include "../mach-omap2/prm.h"
# include "../mach-omap2/cm.h"
@@ -53,7 +54,7 @@
#define OMAP4_SRAM_PUB_PA (OMAP4_SRAM_PA + 0x4000)
#define OMAP4_SRAM_PUB_VA (OMAP4_SRAM_VA + 0x4000)
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+#if defined(CONFIG_ARCH_OMAP2PLUS)
#define SRAM_BOOTLOADER_SZ 0x00
#else
#define SRAM_BOOTLOADER_SZ 0x80
@@ -68,7 +69,6 @@
#define OMAP34XX_VA_WRITEPERM0 OMAP2_L3_IO_ADDRESS(0x68012858)
#define OMAP34XX_VA_ADDR_MATCH2 OMAP2_L3_IO_ADDRESS(0x68012880)
#define OMAP34XX_VA_SMS_RG_ATT0 OMAP2_L3_IO_ADDRESS(0x6C000048)
-#define OMAP34XX_VA_CONTROL_STAT OMAP2_L4_IO_ADDRESS(0x480022F0)
#define GP_DEVICE 0x300
@@ -79,12 +79,6 @@ static unsigned long omap_sram_base;
static unsigned long omap_sram_size;
static unsigned long omap_sram_ceil;
-extern unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
- unsigned long sram_vstart,
- unsigned long sram_size,
- unsigned long pstart_avail,
- unsigned long size_avail);
-
/*
* Depending on the target RAMFS firewall setup, the public usable amount of
* SRAM varies. The default accessible size for all device types is 2k. A GP
@@ -93,16 +87,7 @@ extern unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
*/
static int is_sram_locked(void)
{
- int type = 0;
-
- if (cpu_is_omap44xx())
- /* Not yet supported */
- return 0;
-
- if (cpu_is_omap242x())
- type = omap_rev() & OMAP2_DEVICETYPE_MASK;
-
- if (type == GP_DEVICE) {
+ if (OMAP2_DEVICE_TYPE_GP == omap_type()) {
/* RAMFW: R/W access to all initiators for all qualifier sets */
if (cpu_is_omap242x()) {
__raw_writel(0xFF, OMAP24XX_VA_REQINFOPERM0); /* all q-vects */
@@ -127,7 +112,7 @@ static int is_sram_locked(void)
* to secure SRAM will hang the system. Also the SRAM is not
* yet mapped at this point.
*/
-void __init omap_detect_sram(void)
+static void __init omap_detect_sram(void)
{
unsigned long reserved;
@@ -213,7 +198,7 @@ static struct map_desc omap_sram_io_desc[] __initdata = {
/*
* Note that we cannot use ioremap for SRAM, as clock init needs SRAM early.
*/
-void __init omap_map_sram(void)
+static void __init omap_map_sram(void)
{
unsigned long base;
@@ -330,7 +315,7 @@ u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass)
#endif
#ifdef CONFIG_ARCH_OMAP2420
-int __init omap242x_sram_init(void)
+static int __init omap242x_sram_init(void)
{
_omap2_sram_ddr_init = omap_sram_push(omap242x_sram_ddr_init,
omap242x_sram_ddr_init_sz);
@@ -351,7 +336,7 @@ static inline int omap242x_sram_init(void)
#endif
#ifdef CONFIG_ARCH_OMAP2430
-int __init omap243x_sram_init(void)
+static int __init omap243x_sram_init(void)
{
_omap2_sram_ddr_init = omap_sram_push(omap243x_sram_ddr_init,
omap243x_sram_ddr_init_sz);
@@ -407,7 +392,7 @@ void omap3_sram_restore_context(void)
}
#endif /* CONFIG_PM */
-int __init omap34xx_sram_init(void)
+static int __init omap34xx_sram_init(void)
{
_omap3_sram_configure_core_dpll =
omap_sram_push(omap3_sram_configure_core_dpll,
@@ -423,7 +408,7 @@ static inline int omap34xx_sram_init(void)
#endif
#ifdef CONFIG_ARCH_OMAP4
-int __init omap44xx_sram_init(void)
+static int __init omap44xx_sram_init(void)
{
printk(KERN_ERR "FIXME: %s not implemented\n", __func__);
diff --git a/arch/arm/plat-omap/sram.h b/arch/arm/plat-omap/sram.h
new file mode 100644
index 000000000000..29b43ef97f20
--- /dev/null
+++ b/arch/arm/plat-omap/sram.h
@@ -0,0 +1,6 @@
+#ifndef __PLAT_OMAP_SRAM_H__
+#define __PLAT_OMAP_SRAM_H__
+
+extern int __init omap_sram_init(void);
+
+#endif /* __PLAT_OMAP_SRAM_H__ */
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-pxa/include/plat/pxa3xx_nand.h b/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h
index 3478eae32d8a..01a8448e471c 100644
--- a/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h
+++ b/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h
@@ -30,15 +30,15 @@ struct pxa3xx_nand_cmdset {
};
struct pxa3xx_nand_flash {
- const struct pxa3xx_nand_timing *timing; /* NAND Flash timing */
- const struct pxa3xx_nand_cmdset *cmdset;
-
- uint32_t page_per_block;/* Pages per block (PG_PER_BLK) */
- uint32_t page_size; /* Page size in bytes (PAGE_SZ) */
- uint32_t flash_width; /* Width of Flash memory (DWIDTH_M) */
- uint32_t dfc_width; /* Width of flash controller(DWIDTH_C) */
- uint32_t num_blocks; /* Number of physical blocks in Flash */
- uint32_t chip_id;
+ uint32_t chip_id;
+ unsigned int page_per_block; /* Pages per block (PG_PER_BLK) */
+ unsigned int page_size; /* Page size in bytes (PAGE_SZ) */
+ unsigned int flash_width; /* Width of Flash memory (DWIDTH_M) */
+ unsigned int dfc_width; /* Width of flash controller(DWIDTH_C) */
+ unsigned int num_blocks; /* Number of physical blocks in Flash */
+
+ struct pxa3xx_nand_cmdset *cmdset; /* NAND command set */
+ struct pxa3xx_nand_timing *timing; /* NAND Flash timing */
};
struct pxa3xx_nand_platform_data {
diff --git a/arch/arm/plat-pxa/include/plat/sdhci.h b/arch/arm/plat-pxa/include/plat/sdhci.h
new file mode 100644
index 000000000000..e49c5b6fc4e2
--- /dev/null
+++ b/arch/arm/plat-pxa/include/plat/sdhci.h
@@ -0,0 +1,32 @@
+/* linux/arch/arm/plat-pxa/include/plat/sdhci.h
+ *
+ * Copyright 2010 Marvell
+ * Zhangfei Gao <zhangfei.gao@marvell.com>
+ *
+ * PXA Platform - SDHCI platform data 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 __PLAT_PXA_SDHCI_H
+#define __PLAT_PXA_SDHCI_H
+
+/* pxa specific flag */
+/* Require clock free running */
+#define PXA_FLAG_DISABLE_CLOCK_GATING (1<<0)
+
+/*
+ * struct pxa_sdhci_platdata() - Platform device data for PXA SDHCI
+ * @max_speed: the maximum speed supported
+ * @quirks: quirks of specific device
+ * @flags: flags for platform requirement
+ */
+struct sdhci_pxa_platdata {
+ unsigned int max_speed;
+ unsigned int quirks;
+ unsigned int flags;
+};
+
+#endif /* __PLAT_PXA_SDHCI_H */
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig
index 984bf66826d2..5a27b1b538f2 100644
--- a/arch/arm/plat-s3c24xx/Kconfig
+++ b/arch/arm/plat-s3c24xx/Kconfig
@@ -69,6 +69,7 @@ config S3C24XX_GPIO_EXTRA
int
default 128 if S3C24XX_GPIO_EXTRA128
default 64 if S3C24XX_GPIO_EXTRA64
+ default 16 if ARCH_H1940
default 0
config S3C24XX_GPIO_EXTRA64
diff --git a/arch/arm/plat-s3c24xx/common-smdk.c b/arch/arm/plat-s3c24xx/common-smdk.c
index 7b44d0c592b5..bcc43f346272 100644
--- a/arch/arm/plat-s3c24xx/common-smdk.c
+++ b/arch/arm/plat-s3c24xx/common-smdk.c
@@ -147,7 +147,7 @@ static struct mtd_partition smdk_default_nand_part[] = {
[7] = {
.name = "S3C2410 flash partition 7",
.offset = SZ_1M * 48,
- .size = SZ_16M,
+ .size = MTDPART_SIZ_FULL,
}
};
diff --git a/arch/arm/plat-s3c24xx/gpiolib.c b/arch/arm/plat-s3c24xx/gpiolib.c
index 4c0896f2572d..24c6f5a30596 100644
--- a/arch/arm/plat-s3c24xx/gpiolib.c
+++ b/arch/arm/plat-s3c24xx/gpiolib.c
@@ -74,11 +74,6 @@ static int s3c24xx_gpiolib_bankf_toirq(struct gpio_chip *chip, unsigned offset)
return -EINVAL;
}
-static int s3c24xx_gpiolib_bankg_toirq(struct gpio_chip *chip, unsigned offset)
-{
- return IRQ_EINT8 + offset;
-}
-
static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = {
.set_config = s3c_gpio_setcfg_s3c24xx_a,
.get_config = s3c_gpio_getcfg_s3c24xx_a,
@@ -87,6 +82,8 @@ static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = {
struct s3c_gpio_cfg s3c24xx_gpiocfg_default = {
.set_config = s3c_gpio_setcfg_s3c24xx,
.get_config = s3c_gpio_getcfg_s3c24xx,
+ .set_pull = s3c_gpio_setpull_1up,
+ .get_pull = s3c_gpio_getpull_1up,
};
struct s3c_gpio_chip s3c24xx_gpios[] = {
@@ -157,12 +154,13 @@ struct s3c_gpio_chip s3c24xx_gpios[] = {
[6] = {
.base = S3C2410_GPGCON,
.pm = __gpio_pm(&s3c_gpio_pm_2bit),
+ .irq_base = IRQ_EINT8,
.chip = {
.base = S3C2410_GPG(0),
.owner = THIS_MODULE,
.label = "GPIOG",
.ngpio = 16,
- .to_irq = s3c24xx_gpiolib_bankg_toirq,
+ .to_irq = samsung_gpiolib_to_irq,
},
}, {
.base = S3C2410_GPHCON,
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
index c6a855db2fb6..65dbfa8e0a86 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,12 @@ 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_GPIO_INT
+ bool
+ help
+ Common code for the GPIO interrupts (other than external interrupts.)
config S5P_DEV_FIMC0
bool
@@ -46,3 +51,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..de65238a7aef 100644
--- a/arch/arm/plat-s5p/Makefile
+++ b/arch/arm/plat-s5p/Makefile
@@ -18,9 +18,13 @@ obj-y += cpu.o
obj-y += clock.o
obj-y += irq.o
obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o
+obj-$(CONFIG_S5P_GPIO_INT) += irq-gpioint.o
+obj-$(CONFIG_PM) += pm.o
+obj-$(CONFIG_PM) += irq-pm.o
# devices
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..8d081d968c58 100644
--- a/arch/arm/plat-s5p/clock.c
+++ b/arch/arm/plat-s5p/clock.c
@@ -21,6 +21,8 @@
#include <linux/io.h>
#include <asm/div64.h>
+#include <mach/regs-clock.h>
+
#include <plat/clock.h>
#include <plat/clock-clksrc.h>
#include <plat/s5p-clock.h>
@@ -74,19 +76,18 @@ struct clk clk_fout_epll = {
.ctrlbit = (1 << 31),
};
-/* VPLL clock output */
-struct clk clk_fout_vpll = {
- .name = "fout_vpll",
+/* DPLL clock output */
+struct clk clk_fout_dpll = {
+ .name = "fout_dpll",
.id = -1,
.ctrlbit = (1 << 31),
};
-/* ARM clock */
-struct clk clk_arm = {
- .name = "armclk",
+/* VPLL clock output */
+struct clk clk_fout_vpll = {
+ .name = "fout_vpll",
.id = -1,
- .rate = 0,
- .ctrlbit = 0,
+ .ctrlbit = (1 << 31),
};
/* Possible clock sources for APLL Mux */
@@ -122,6 +123,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,
@@ -138,6 +150,24 @@ int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable)
return 0;
}
+int s5p_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;
+}
+
+unsigned long s5p_epll_get_rate(struct clk *clk)
+{
+ return clk->rate;
+}
+
static struct clk *s5p_clks[] __initdata = {
&clk_ext_xtal_mux,
&clk_48m,
@@ -145,8 +175,8 @@ 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,
&clk_xusbxti,
};
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/irqs.h b/arch/arm/plat-s5p/include/plat/irqs.h
index 3fb3a3a17465..ba9121c60a2a 100644
--- a/arch/arm/plat-s5p/include/plat/irqs.h
+++ b/arch/arm/plat-s5p/include/plat/irqs.h
@@ -94,4 +94,22 @@
((irq) - S5P_EINT_BASE1) : \
((irq) + 16 - S5P_EINT_BASE2))
+#define IRQ_EINT_BIT(x) EINT_OFFSET(x)
+
+/* Typically only a few gpio chips require gpio interrupt support.
+ To avoid memory waste irq descriptors are allocated only for
+ S5P_GPIOINT_GROUP_COUNT chips, each with total number of
+ S5P_GPIOINT_GROUP_SIZE pins/irqs. Each GPIOINT group can be assiged
+ to any gpio chip with the s5p_register_gpio_interrupt() function */
+#define S5P_GPIOINT_GROUP_COUNT 4
+#define S5P_GPIOINT_GROUP_SIZE 8
+#define S5P_GPIOINT_COUNT (S5P_GPIOINT_GROUP_COUNT * S5P_GPIOINT_GROUP_SIZE)
+
+/* IRQ types common for all s5p platforms */
+#define S5P_IRQ_TYPE_LEVEL_LOW (0x00)
+#define S5P_IRQ_TYPE_LEVEL_HIGH (0x01)
+#define S5P_IRQ_TYPE_EDGE_FALLING (0x02)
+#define S5P_IRQ_TYPE_EDGE_RISING (0x03)
+#define S5P_IRQ_TYPE_EDGE_BOTH (0x04)
+
#endif /* __ASM_PLAT_S5P_IRQS_H */
diff --git a/arch/arm/plat-s5p/include/plat/map-s5p.h b/arch/arm/plat-s5p/include/plat/map-s5p.h
index c4ff88bf6477..fef353d44513 100644
--- a/arch/arm/plat-s5p/include/plat/map-s5p.h
+++ b/arch/arm/plat-s5p/include/plat/map-s5p.h
@@ -13,24 +13,38 @@
#ifndef __ASM_PLAT_MAP_S5P_H
#define __ASM_PLAT_MAP_S5P_H __FILE__
-#define S5P_VA_CHIPID S3C_ADDR(0x00700000)
-#define S5P_VA_GPIO S3C_ADDR(0x00500000)
-#define S5P_VA_SYSTIMER S3C_ADDR(0x01200000)
-#define S5P_VA_SROMC S3C_ADDR(0x01100000)
-#define S5P_VA_SYSRAM S3C_ADDR(0x01180000)
-
-#define S5P_VA_COMBINER_BASE S3C_ADDR(0x00600000)
+#define S5P_VA_CHIPID S3C_ADDR(0x02000000)
+#define S5P_VA_CMU S3C_ADDR(0x02100000)
+#define S5P_VA_GPIO S3C_ADDR(0x02200000)
+#define S5P_VA_GPIO1 S5P_VA_GPIO
+#define S5P_VA_GPIO2 S3C_ADDR(0x02240000)
+#define S5P_VA_GPIO3 S3C_ADDR(0x02280000)
+
+#define S5P_VA_SYSRAM S3C_ADDR(0x02400000)
+#define S5P_VA_DMC0 S3C_ADDR(0x02440000)
+#define S5P_VA_DMC1 S3C_ADDR(0x02480000)
+#define S5P_VA_SROMC S3C_ADDR(0x024C0000)
+
+#define S5P_VA_SYSTIMER S3C_ADDR(0x02500000)
+#define S5P_VA_L2CC S3C_ADDR(0x02600000)
+
+#define S5P_VA_COMBINER_BASE S3C_ADDR(0x02700000)
#define S5P_VA_COMBINER(x) (S5P_VA_COMBINER_BASE + ((x) >> 2) * 0x10)
-#define S5P_VA_COREPERI_BASE S3C_ADDR(0x00800000)
+#define S5P_VA_COREPERI_BASE S3C_ADDR(0x02800000)
#define S5P_VA_COREPERI(x) (S5P_VA_COREPERI_BASE + (x))
#define S5P_VA_SCU S5P_VA_COREPERI(0x0)
#define S5P_VA_GIC_CPU S5P_VA_COREPERI(0x100)
#define S5P_VA_TWD S5P_VA_COREPERI(0x600)
#define S5P_VA_GIC_DIST S5P_VA_COREPERI(0x1000)
-#define S5P_VA_L2CC S3C_ADDR(0x00900000)
-#define S5P_VA_CMU S3C_ADDR(0x00920000)
+#define S3C_VA_USB_HSPHY S3C_ADDR(0x02900000)
+
+#define VA_VIC(x) (S3C_VA_IRQ + ((x) * 0x10000))
+#define VA_VIC0 VA_VIC(0)
+#define VA_VIC1 VA_VIC(1)
+#define VA_VIC2 VA_VIC(2)
+#define VA_VIC3 VA_VIC(3)
#define S5P_VA_UART(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET))
#define S5P_VA_UART0 S5P_VA_UART(0)
@@ -42,10 +56,4 @@
#define S3C_UART_OFFSET (0x400)
#endif
-#define VA_VIC(x) (S3C_VA_IRQ + ((x) * 0x10000))
-#define VA_VIC0 VA_VIC(0)
-#define VA_VIC1 VA_VIC(1)
-#define VA_VIC2 VA_VIC(2)
-#define VA_VIC3 VA_VIC(3)
-
#endif /* __ASM_PLAT_MAP_S5P_H */
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..2b6dcff8ab2b 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,12 @@ 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);
+/* Common EPLL operations for S5P platform */
+extern int s5p_epll_enable(struct clk *clk, int enable);
+extern unsigned long s5p_epll_get_rate(struct clk *clk);
+
#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-s5p/irq-eint.c b/arch/arm/plat-s5p/irq-eint.c
index f36cd3327025..752f1a645f9d 100644
--- a/arch/arm/plat-s5p/irq-eint.c
+++ b/arch/arm/plat-s5p/irq-eint.c
@@ -67,23 +67,23 @@ static int s5p_irq_eint_set_type(unsigned int irq, unsigned int type)
switch (type) {
case IRQ_TYPE_EDGE_RISING:
- newvalue = S5P_EXTINT_RISEEDGE;
+ newvalue = S5P_IRQ_TYPE_EDGE_RISING;
break;
case IRQ_TYPE_EDGE_FALLING:
- newvalue = S5P_EXTINT_FALLEDGE;
+ newvalue = S5P_IRQ_TYPE_EDGE_FALLING;
break;
case IRQ_TYPE_EDGE_BOTH:
- newvalue = S5P_EXTINT_BOTHEDGE;
+ newvalue = S5P_IRQ_TYPE_EDGE_BOTH;
break;
case IRQ_TYPE_LEVEL_LOW:
- newvalue = S5P_EXTINT_LOWLEV;
+ newvalue = S5P_IRQ_TYPE_LEVEL_LOW;
break;
case IRQ_TYPE_LEVEL_HIGH:
- newvalue = S5P_EXTINT_HILEV;
+ newvalue = S5P_IRQ_TYPE_LEVEL_HIGH;
break;
default:
diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-gpioint.c
new file mode 100644
index 000000000000..0e5dc8cbf5e3
--- /dev/null
+++ b/arch/arm/plat-s5p/irq-gpioint.c
@@ -0,0 +1,237 @@
+/* linux/arch/arm/plat-s5p/irq-gpioint.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * Author: Kyungmin Park <kyungmin.park@samsung.com>
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
+ * Author: Marek Szyprowski <m.szyprowski@samsung.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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <mach/map.h>
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+
+#define S5P_GPIOREG(x) (S5P_VA_GPIO + (x))
+
+#define GPIOINT_CON_OFFSET 0x700
+#define GPIOINT_MASK_OFFSET 0x900
+#define GPIOINT_PEND_OFFSET 0xA00
+
+static struct s3c_gpio_chip *irq_chips[S5P_GPIOINT_GROUP_MAXNR];
+
+static int s5p_gpioint_get_group(unsigned int irq)
+{
+ struct gpio_chip *chip = get_irq_data(irq);
+ struct s3c_gpio_chip *s3c_chip = container_of(chip,
+ struct s3c_gpio_chip, chip);
+ int group;
+
+ for (group = 0; group < S5P_GPIOINT_GROUP_MAXNR; group++)
+ if (s3c_chip == irq_chips[group])
+ break;
+
+ return group;
+}
+
+static int s5p_gpioint_get_offset(unsigned int irq)
+{
+ struct gpio_chip *chip = get_irq_data(irq);
+ struct s3c_gpio_chip *s3c_chip = container_of(chip,
+ struct s3c_gpio_chip, chip);
+
+ return irq - s3c_chip->irq_base;
+}
+
+static void s5p_gpioint_ack(unsigned int irq)
+{
+ int group, offset, pend_offset;
+ unsigned int value;
+
+ group = s5p_gpioint_get_group(irq);
+ offset = s5p_gpioint_get_offset(irq);
+ pend_offset = group << 2;
+
+ value = __raw_readl(S5P_GPIOREG(GPIOINT_PEND_OFFSET) + pend_offset);
+ value |= 1 << offset;
+ __raw_writel(value, S5P_GPIOREG(GPIOINT_PEND_OFFSET) + pend_offset);
+}
+
+static void s5p_gpioint_mask(unsigned int irq)
+{
+ int group, offset, mask_offset;
+ unsigned int value;
+
+ group = s5p_gpioint_get_group(irq);
+ offset = s5p_gpioint_get_offset(irq);
+ mask_offset = group << 2;
+
+ value = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
+ value |= 1 << offset;
+ __raw_writel(value, S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
+}
+
+static void s5p_gpioint_unmask(unsigned int irq)
+{
+ int group, offset, mask_offset;
+ unsigned int value;
+
+ group = s5p_gpioint_get_group(irq);
+ offset = s5p_gpioint_get_offset(irq);
+ mask_offset = group << 2;
+
+ value = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
+ value &= ~(1 << offset);
+ __raw_writel(value, S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
+}
+
+static void s5p_gpioint_mask_ack(unsigned int irq)
+{
+ s5p_gpioint_mask(irq);
+ s5p_gpioint_ack(irq);
+}
+
+static int s5p_gpioint_set_type(unsigned int irq, unsigned int type)
+{
+ int group, offset, con_offset;
+ unsigned int value;
+
+ group = s5p_gpioint_get_group(irq);
+ offset = s5p_gpioint_get_offset(irq);
+ con_offset = group << 2;
+
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ type = S5P_IRQ_TYPE_EDGE_RISING;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ type = S5P_IRQ_TYPE_EDGE_FALLING;
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ type = S5P_IRQ_TYPE_EDGE_BOTH;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ type = S5P_IRQ_TYPE_LEVEL_HIGH;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ type = S5P_IRQ_TYPE_LEVEL_LOW;
+ break;
+ case IRQ_TYPE_NONE:
+ default:
+ printk(KERN_WARNING "No irq type\n");
+ return -EINVAL;
+ }
+
+ value = __raw_readl(S5P_GPIOREG(GPIOINT_CON_OFFSET) + con_offset);
+ value &= ~(0x7 << (offset * 0x4));
+ value |= (type << (offset * 0x4));
+ __raw_writel(value, S5P_GPIOREG(GPIOINT_CON_OFFSET) + con_offset);
+
+ return 0;
+}
+
+struct irq_chip s5p_gpioint = {
+ .name = "s5p_gpioint",
+ .ack = s5p_gpioint_ack,
+ .mask = s5p_gpioint_mask,
+ .mask_ack = s5p_gpioint_mask_ack,
+ .unmask = s5p_gpioint_unmask,
+ .set_type = s5p_gpioint_set_type,
+};
+
+static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
+{
+ int group, offset, pend_offset, mask_offset;
+ int real_irq;
+ unsigned int pend, mask;
+
+ for (group = 0; group < S5P_GPIOINT_GROUP_MAXNR; group++) {
+ pend_offset = group << 2;
+ pend = __raw_readl(S5P_GPIOREG(GPIOINT_PEND_OFFSET) +
+ pend_offset);
+ if (!pend)
+ continue;
+
+ mask_offset = group << 2;
+ mask = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) +
+ mask_offset);
+ pend &= ~mask;
+
+ for (offset = 0; offset < 8; offset++) {
+ if (pend & (1 << offset)) {
+ struct s3c_gpio_chip *chip = irq_chips[group];
+ if (chip) {
+ real_irq = chip->irq_base + offset;
+ generic_handle_irq(real_irq);
+ }
+ }
+ }
+ }
+}
+
+static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
+{
+ static int used_gpioint_groups = 0;
+ static bool handler_registered = 0;
+ int irq, group = chip->group;
+ int i;
+
+ if (used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT)
+ return -ENOMEM;
+
+ chip->irq_base = S5P_GPIOINT_BASE +
+ used_gpioint_groups * S5P_GPIOINT_GROUP_SIZE;
+ used_gpioint_groups++;
+
+ if (!handler_registered) {
+ set_irq_chained_handler(IRQ_GPIOINT, s5p_gpioint_handler);
+ handler_registered = 1;
+ }
+
+ irq_chips[group] = chip;
+ for (i = 0; i < chip->chip.ngpio; i++) {
+ irq = chip->irq_base + i;
+ set_irq_chip(irq, &s5p_gpioint);
+ set_irq_data(irq, &chip->chip);
+ set_irq_handler(irq, handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+ return 0;
+}
+
+int __init s5p_register_gpio_interrupt(int pin)
+{
+ struct s3c_gpio_chip *my_chip = s3c_gpiolib_getchip(pin);
+ int offset, group;
+ int ret;
+
+ if (!my_chip)
+ return -EINVAL;
+
+ offset = pin - my_chip->chip.base;
+ group = my_chip->group;
+
+ /* check if the group has been already registered */
+ if (my_chip->irq_base)
+ return my_chip->irq_base + offset;
+
+ /* register gpio group */
+ ret = s5p_gpioint_add(my_chip);
+ if (ret == 0) {
+ my_chip->chip.to_irq = samsung_gpiolib_to_irq;
+ printk(KERN_INFO "Registered interrupt support for gpio group %d.\n",
+ group);
+ return my_chip->irq_base + offset;
+ }
+ return ret;
+}
diff --git a/arch/arm/plat-s5p/irq-pm.c b/arch/arm/plat-s5p/irq-pm.c
new file mode 100644
index 000000000000..dc33b9ecda45
--- /dev/null
+++ b/arch/arm/plat-s5p/irq-pm.c
@@ -0,0 +1,93 @@
+/* linux/arch/arm/plat-s5p/irq-pm.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Based on arch/arm/plat-s3c24xx/irq-pm.c,
+ * Copyright (c) 2003,2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * 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/interrupt.h>
+#include <linux/sysdev.h>
+
+#include <plat/cpu.h>
+#include <plat/irqs.h>
+#include <plat/pm.h>
+#include <mach/map.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/regs-irq.h>
+
+/* state for IRQs over sleep */
+
+/* default is to allow for EINT0..EINT31, and IRQ_RTC_TIC, IRQ_RTC_ALARM,
+ * as wakeup sources
+ *
+ * set bit to 1 in allow bitfield to enable the wakeup settings on it
+*/
+
+unsigned long s3c_irqwake_intallow = 0x00000006L;
+unsigned long s3c_irqwake_eintallow = 0xffffffffL;
+
+int s3c_irq_wake(unsigned int irqno, unsigned int state)
+{
+ unsigned long irqbit;
+
+ switch (irqno) {
+ case IRQ_RTC_TIC:
+ case IRQ_RTC_ALARM:
+ irqbit = 1 << (irqno + 1 - IRQ_RTC_ALARM);
+ if (!state)
+ s3c_irqwake_intmask |= irqbit;
+ else
+ s3c_irqwake_intmask &= ~irqbit;
+ break;
+ default:
+ return -ENOENT;
+ }
+ return 0;
+}
+
+static struct sleep_save eint_save[] = {
+ SAVE_ITEM(S5P_EINT_CON(0)),
+ SAVE_ITEM(S5P_EINT_CON(1)),
+ SAVE_ITEM(S5P_EINT_CON(2)),
+ SAVE_ITEM(S5P_EINT_CON(3)),
+
+ SAVE_ITEM(S5P_EINT_FLTCON(0)),
+ SAVE_ITEM(S5P_EINT_FLTCON(1)),
+ SAVE_ITEM(S5P_EINT_FLTCON(2)),
+ SAVE_ITEM(S5P_EINT_FLTCON(3)),
+ SAVE_ITEM(S5P_EINT_FLTCON(4)),
+ SAVE_ITEM(S5P_EINT_FLTCON(5)),
+ SAVE_ITEM(S5P_EINT_FLTCON(6)),
+ SAVE_ITEM(S5P_EINT_FLTCON(7)),
+
+ SAVE_ITEM(S5P_EINT_MASK(0)),
+ SAVE_ITEM(S5P_EINT_MASK(1)),
+ SAVE_ITEM(S5P_EINT_MASK(2)),
+ SAVE_ITEM(S5P_EINT_MASK(3)),
+};
+
+int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state)
+{
+ s3c_pm_do_save(eint_save, ARRAY_SIZE(eint_save));
+
+ return 0;
+}
+
+int s3c24xx_irq_resume(struct sys_device *dev)
+{
+ s3c_pm_do_restore(eint_save, ARRAY_SIZE(eint_save));
+
+ return 0;
+}
+
diff --git a/arch/arm/plat-s5p/pm.c b/arch/arm/plat-s5p/pm.c
new file mode 100644
index 000000000000..d592b6304b48
--- /dev/null
+++ b/arch/arm/plat-s5p/pm.c
@@ -0,0 +1,52 @@
+/* linux/arch/arm/plat-s5p/pm.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P Power Manager (Suspend-To-RAM) support
+ *
+ * Based on arch/arm/plat-s3c24xx/pm.c
+ * Copyright (c) 2004,2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * 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/suspend.h>
+#include <plat/pm.h>
+
+#define PFX "s5p pm: "
+
+/* s3c_pm_check_resume_pin
+ *
+ * check to see if the pin is configured correctly for sleep mode, and
+ * make any necessary adjustments if it is not
+*/
+
+static void s3c_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs)
+{
+ /* nothing here yet */
+}
+
+/* s3c_pm_configure_extint
+ *
+ * configure all external interrupt pins
+*/
+
+void s3c_pm_configure_extint(void)
+{
+ /* nothing here yet */
+}
+
+void s3c_pm_restore_core(void)
+{
+ /* nothing here yet */
+}
+
+void s3c_pm_save_core(void)
+{
+ /* nothing here yet */
+}
+
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 7c0bde781167..dcd6eff4ee53 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -180,6 +180,31 @@ config S3C_DEV_I2C2
help
Compile in platform device definitions for I2C channel 2
+config S3C_DEV_I2C3
+ bool
+ help
+ Compile in platform device definition for I2C controller 3
+
+config S3C_DEV_I2C4
+ bool
+ help
+ Compile in platform device definition for I2C controller 4
+
+config S3C_DEV_I2C5
+ bool
+ help
+ Compile in platform device definition for I2C controller 5
+
+config S3C_DEV_I2C6
+ bool
+ help
+ Compile in platform device definition for I2C controller 6
+
+config S3C_DEV_I2C7
+ bool
+ help
+ Compile in platform device definition for I2C controller 7
+
config S3C_DEV_FB
bool
help
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index 4d8ff923207a..afcce474af8e 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -40,6 +40,11 @@ obj-$(CONFIG_S3C_DEV_HWMON) += dev-hwmon.o
obj-y += dev-i2c0.o
obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o
obj-$(CONFIG_S3C_DEV_I2C2) += dev-i2c2.o
+obj-$(CONFIG_S3C_DEV_I2C3) += dev-i2c3.o
+obj-$(CONFIG_S3C_DEV_I2C4) += dev-i2c4.o
+obj-$(CONFIG_S3C_DEV_I2C5) += dev-i2c5.o
+obj-$(CONFIG_S3C_DEV_I2C6) += dev-i2c6.o
+obj-$(CONFIG_S3C_DEV_I2C7) += dev-i2c7.o
obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o
obj-y += dev-uart.o
obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o
diff --git a/arch/arm/plat-samsung/dev-hsmmc.c b/arch/arm/plat-samsung/dev-hsmmc.c
index 9d2be0941410..db7a65c7f127 100644
--- a/arch/arm/plat-samsung/dev-hsmmc.c
+++ b/arch/arm/plat-samsung/dev-hsmmc.c
@@ -41,6 +41,7 @@ struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata = {
.max_width = 4,
.host_caps = (MMC_CAP_4_BIT_DATA |
MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+ .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
};
struct platform_device s3c_device_hsmmc0 = {
@@ -59,17 +60,20 @@ void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd)
{
struct s3c_sdhci_platdata *set = &s3c_hsmmc0_def_platdata;
- set->max_width = pd->max_width;
set->cd_type = pd->cd_type;
set->ext_cd_init = pd->ext_cd_init;
set->ext_cd_cleanup = pd->ext_cd_cleanup;
set->ext_cd_gpio = pd->ext_cd_gpio;
set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
+ if (pd->max_width)
+ set->max_width = pd->max_width;
if (pd->cfg_gpio)
set->cfg_gpio = pd->cfg_gpio;
if (pd->cfg_card)
set->cfg_card = pd->cfg_card;
if (pd->host_caps)
- set->host_caps = pd->host_caps;
+ set->host_caps |= pd->host_caps;
+ if (pd->clk_type)
+ set->clk_type = pd->clk_type;
}
diff --git a/arch/arm/plat-samsung/dev-hsmmc1.c b/arch/arm/plat-samsung/dev-hsmmc1.c
index a6c8295840af..2497321f08d7 100644
--- a/arch/arm/plat-samsung/dev-hsmmc1.c
+++ b/arch/arm/plat-samsung/dev-hsmmc1.c
@@ -41,6 +41,7 @@ struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata = {
.max_width = 4,
.host_caps = (MMC_CAP_4_BIT_DATA |
MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+ .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
};
struct platform_device s3c_device_hsmmc1 = {
@@ -59,17 +60,20 @@ void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd)
{
struct s3c_sdhci_platdata *set = &s3c_hsmmc1_def_platdata;
- set->max_width = pd->max_width;
set->cd_type = pd->cd_type;
set->ext_cd_init = pd->ext_cd_init;
set->ext_cd_cleanup = pd->ext_cd_cleanup;
set->ext_cd_gpio = pd->ext_cd_gpio;
set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
+ if (pd->max_width)
+ set->max_width = pd->max_width;
if (pd->cfg_gpio)
set->cfg_gpio = pd->cfg_gpio;
if (pd->cfg_card)
set->cfg_card = pd->cfg_card;
if (pd->host_caps)
- set->host_caps = pd->host_caps;
+ set->host_caps |= pd->host_caps;
+ if (pd->clk_type)
+ set->clk_type = pd->clk_type;
}
diff --git a/arch/arm/plat-samsung/dev-hsmmc2.c b/arch/arm/plat-samsung/dev-hsmmc2.c
index cb0d7143381a..f60aedba417c 100644
--- a/arch/arm/plat-samsung/dev-hsmmc2.c
+++ b/arch/arm/plat-samsung/dev-hsmmc2.c
@@ -42,6 +42,7 @@ struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata = {
.max_width = 4,
.host_caps = (MMC_CAP_4_BIT_DATA |
MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+ .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
};
struct platform_device s3c_device_hsmmc2 = {
@@ -60,17 +61,20 @@ void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
{
struct s3c_sdhci_platdata *set = &s3c_hsmmc2_def_platdata;
- set->max_width = pd->max_width;
set->cd_type = pd->cd_type;
set->ext_cd_init = pd->ext_cd_init;
set->ext_cd_cleanup = pd->ext_cd_cleanup;
set->ext_cd_gpio = pd->ext_cd_gpio;
set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
+ if (pd->max_width)
+ set->max_width = pd->max_width;
if (pd->cfg_gpio)
set->cfg_gpio = pd->cfg_gpio;
if (pd->cfg_card)
set->cfg_card = pd->cfg_card;
if (pd->host_caps)
- set->host_caps = pd->host_caps;
+ set->host_caps |= pd->host_caps;
+ if (pd->clk_type)
+ set->clk_type = pd->clk_type;
}
diff --git a/arch/arm/plat-samsung/dev-hsmmc3.c b/arch/arm/plat-samsung/dev-hsmmc3.c
index 85aaf0f2842f..ede776f20e62 100644
--- a/arch/arm/plat-samsung/dev-hsmmc3.c
+++ b/arch/arm/plat-samsung/dev-hsmmc3.c
@@ -33,8 +33,8 @@ static struct resource s3c_hsmmc3_resource[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = IRQ_MMC3,
- .end = IRQ_MMC3,
+ .start = IRQ_HSMMC3,
+ .end = IRQ_HSMMC3,
.flags = IORESOURCE_IRQ,
}
};
@@ -45,6 +45,7 @@ struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata = {
.max_width = 4,
.host_caps = (MMC_CAP_4_BIT_DATA |
MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+ .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
};
struct platform_device s3c_device_hsmmc3 = {
@@ -63,15 +64,20 @@ void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd)
{
struct s3c_sdhci_platdata *set = &s3c_hsmmc3_def_platdata;
- set->max_width = pd->max_width;
set->cd_type = pd->cd_type;
set->ext_cd_init = pd->ext_cd_init;
set->ext_cd_cleanup = pd->ext_cd_cleanup;
set->ext_cd_gpio = pd->ext_cd_gpio;
set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
+ if (pd->max_width)
+ set->max_width = pd->max_width;
if (pd->cfg_gpio)
set->cfg_gpio = pd->cfg_gpio;
if (pd->cfg_card)
set->cfg_card = pd->cfg_card;
+ if (pd->host_caps)
+ set->host_caps |= pd->host_caps;
+ if (pd->clk_type)
+ set->clk_type = pd->clk_type;
}
diff --git a/arch/arm/plat-samsung/dev-i2c2.c b/arch/arm/plat-samsung/dev-i2c2.c
index 07036dee09e7..ff4ba69b6830 100644
--- a/arch/arm/plat-samsung/dev-i2c2.c
+++ b/arch/arm/plat-samsung/dev-i2c2.c
@@ -32,8 +32,8 @@ static struct resource s3c_i2c_resource[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = IRQ_CAN0,
- .end = IRQ_CAN0,
+ .start = IRQ_IIC2,
+ .end = IRQ_IIC2,
.flags = IORESOURCE_IRQ,
},
};
diff --git a/arch/arm/plat-samsung/dev-i2c3.c b/arch/arm/plat-samsung/dev-i2c3.c
new file mode 100644
index 000000000000..8586a10014b7
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c3.c
@@ -0,0 +1,68 @@
+/* linux/arch/arm/plat-samsung/dev-i2c3.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P series device definition for i2c device 3
+ *
+ * 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/gfp.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/regs-iic.h>
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_i2c_resource[] = {
+ [0] = {
+ .start = S3C_PA_IIC3,
+ .end = S3C_PA_IIC3 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IIC3,
+ .end = IRQ_IIC3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_i2c3 = {
+ .name = "s3c2440-i2c",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(s3c_i2c_resource),
+ .resource = s3c_i2c_resource,
+};
+
+static struct s3c2410_platform_i2c default_i2c_data3 __initdata = {
+ .flags = 0,
+ .bus_num = 3,
+ .slave_addr = 0x10,
+ .frequency = 100*1000,
+ .sda_delay = 100,
+};
+
+void __init s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+ struct s3c2410_platform_i2c *npd;
+
+ if (!pd)
+ pd = &default_i2c_data3;
+
+ npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c3_cfg_gpio;
+
+ s3c_device_i2c3.dev.platform_data = npd;
+}
diff --git a/arch/arm/plat-samsung/dev-i2c4.c b/arch/arm/plat-samsung/dev-i2c4.c
new file mode 100644
index 000000000000..df2159e2daa6
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c4.c
@@ -0,0 +1,68 @@
+/* linux/arch/arm/plat-samsung/dev-i2c4.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P series device definition for i2c device 3
+ *
+ * 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/gfp.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/regs-iic.h>
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_i2c_resource[] = {
+ [0] = {
+ .start = S3C_PA_IIC4,
+ .end = S3C_PA_IIC4 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IIC4,
+ .end = IRQ_IIC4,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_i2c4 = {
+ .name = "s3c2440-i2c",
+ .id = 4,
+ .num_resources = ARRAY_SIZE(s3c_i2c_resource),
+ .resource = s3c_i2c_resource,
+};
+
+static struct s3c2410_platform_i2c default_i2c_data4 __initdata = {
+ .flags = 0,
+ .bus_num = 4,
+ .slave_addr = 0x10,
+ .frequency = 100*1000,
+ .sda_delay = 100,
+};
+
+void __init s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+ struct s3c2410_platform_i2c *npd;
+
+ if (!pd)
+ pd = &default_i2c_data4;
+
+ npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c4_cfg_gpio;
+
+ s3c_device_i2c4.dev.platform_data = npd;
+}
diff --git a/arch/arm/plat-samsung/dev-i2c5.c b/arch/arm/plat-samsung/dev-i2c5.c
new file mode 100644
index 000000000000..0499c2c3877b
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c5.c
@@ -0,0 +1,68 @@
+/* linux/arch/arm/plat-samsung/dev-i2c3.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P series device definition for i2c device 3
+ *
+ * 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/gfp.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/regs-iic.h>
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_i2c_resource[] = {
+ [0] = {
+ .start = S3C_PA_IIC5,
+ .end = S3C_PA_IIC5 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IIC5,
+ .end = IRQ_IIC5,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_i2c5 = {
+ .name = "s3c2440-i2c",
+ .id = 5,
+ .num_resources = ARRAY_SIZE(s3c_i2c_resource),
+ .resource = s3c_i2c_resource,
+};
+
+static struct s3c2410_platform_i2c default_i2c_data5 __initdata = {
+ .flags = 0,
+ .bus_num = 5,
+ .slave_addr = 0x10,
+ .frequency = 100*1000,
+ .sda_delay = 100,
+};
+
+void __init s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+ struct s3c2410_platform_i2c *npd;
+
+ if (!pd)
+ pd = &default_i2c_data5;
+
+ npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c5_cfg_gpio;
+
+ s3c_device_i2c5.dev.platform_data = npd;
+}
diff --git a/arch/arm/plat-samsung/dev-i2c6.c b/arch/arm/plat-samsung/dev-i2c6.c
new file mode 100644
index 000000000000..4083108908a8
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c6.c
@@ -0,0 +1,68 @@
+/* linux/arch/arm/plat-samsung/dev-i2c6.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P series device definition for i2c device 6
+ *
+ * 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/gfp.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/regs-iic.h>
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_i2c_resource[] = {
+ [0] = {
+ .start = S3C_PA_IIC6,
+ .end = S3C_PA_IIC6 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IIC6,
+ .end = IRQ_IIC6,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_i2c6 = {
+ .name = "s3c2440-i2c",
+ .id = 6,
+ .num_resources = ARRAY_SIZE(s3c_i2c_resource),
+ .resource = s3c_i2c_resource,
+};
+
+static struct s3c2410_platform_i2c default_i2c_data6 __initdata = {
+ .flags = 0,
+ .bus_num = 6,
+ .slave_addr = 0x10,
+ .frequency = 100*1000,
+ .sda_delay = 100,
+};
+
+void __init s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+ struct s3c2410_platform_i2c *npd;
+
+ if (!pd)
+ pd = &default_i2c_data6;
+
+ npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c6_cfg_gpio;
+
+ s3c_device_i2c6.dev.platform_data = npd;
+}
diff --git a/arch/arm/plat-samsung/dev-i2c7.c b/arch/arm/plat-samsung/dev-i2c7.c
new file mode 100644
index 000000000000..1182451d7dce
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c7.c
@@ -0,0 +1,68 @@
+/* linux/arch/arm/plat-samsung/dev-i2c7.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P series device definition for i2c device 7
+ *
+ * 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/gfp.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/regs-iic.h>
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_i2c_resource[] = {
+ [0] = {
+ .start = S3C_PA_IIC7,
+ .end = S3C_PA_IIC7 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IIC7,
+ .end = IRQ_IIC7,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_i2c7 = {
+ .name = "s3c2440-i2c",
+ .id = 7,
+ .num_resources = ARRAY_SIZE(s3c_i2c_resource),
+ .resource = s3c_i2c_resource,
+};
+
+static struct s3c2410_platform_i2c default_i2c_data7 __initdata = {
+ .flags = 0,
+ .bus_num = 7,
+ .slave_addr = 0x10,
+ .frequency = 100*1000,
+ .sda_delay = 100,
+};
+
+void __init s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+ struct s3c2410_platform_i2c *npd;
+
+ if (!pd)
+ pd = &default_i2c_data7;
+
+ npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c7_cfg_gpio;
+
+ s3c_device_i2c7.dev.platform_data = npd;
+}
diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c
index e3d41eaed1ff..b732b773b9af 100644
--- a/arch/arm/plat-samsung/gpio-config.c
+++ b/arch/arm/plat-samsung/gpio-config.c
@@ -41,6 +41,37 @@ int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
}
EXPORT_SYMBOL(s3c_gpio_cfgpin);
+int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
+ unsigned int cfg)
+{
+ int ret;
+
+ for (; nr > 0; nr--, start++) {
+ ret = s3c_gpio_cfgpin(start, cfg);
+ if (ret != 0)
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range);
+
+int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
+ unsigned int cfg, s3c_gpio_pull_t pull)
+{
+ int ret;
+
+ for (; nr > 0; nr--, start++) {
+ s3c_gpio_setpull(start, pull);
+ ret = s3c_gpio_cfgpin(start, cfg);
+ if (ret != 0)
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range);
+
unsigned s3c_gpio_getcfg(unsigned int pin)
{
struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
@@ -80,6 +111,25 @@ int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
}
EXPORT_SYMBOL(s3c_gpio_setpull);
+s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ unsigned long flags;
+ int offset;
+ u32 pup = 0;
+
+ if (chip) {
+ offset = pin - chip->chip.base;
+
+ s3c_gpio_lock(chip, flags);
+ pup = s3c_gpio_do_getpull(chip, offset);
+ s3c_gpio_unlock(chip, flags);
+ }
+
+ return (__force s3c_gpio_pull_t)pup;
+}
+EXPORT_SYMBOL(s3c_gpio_getpull);
+
#ifdef CONFIG_S3C_GPIO_CFG_S3C24XX
int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
unsigned int off, unsigned int cfg)
diff --git a/arch/arm/plat-samsung/gpio.c b/arch/arm/plat-samsung/gpio.c
index b83a83351cea..7743c4b8b2fb 100644
--- a/arch/arm/plat-samsung/gpio.c
+++ b/arch/arm/plat-samsung/gpio.c
@@ -157,3 +157,11 @@ __init void s3c_gpiolib_add(struct s3c_gpio_chip *chip)
if (ret >= 0)
s3c_gpiolib_track(chip);
}
+
+int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
+{
+ struct s3c_gpio_chip *s3c_chip = container_of(chip,
+ struct s3c_gpio_chip, chip);
+
+ return s3c_chip->irq_base + offset;
+}
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/audio.h b/arch/arm/plat-samsung/include/plat/audio.h
index e32f9edfd4b7..7712ff6336f4 100644
--- a/arch/arm/plat-samsung/include/plat/audio.h
+++ b/arch/arm/plat-samsung/include/plat/audio.h
@@ -16,6 +16,15 @@
#define S3C64XX_AC97_GPE 1
extern void s3c64xx_ac97_setup_gpio(int);
+/*
+ * The machine init code calls s5p*_spdif_setup_gpio with
+ * one of these defines in order to select appropriate bank
+ * of GPIO for S/PDIF pins
+ */
+#define S5PC100_SPDIF_GPD 0
+#define S5PC100_SPDIF_GPG3 1
+extern void s5pc100_spdif_setup_gpio(int);
+
/**
* struct s3c_audio_pdata - common platform data for audio device drivers
* @cfg_gpio: Callback function to setup mux'ed pins in I2S/PCM/AC97 mode
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 a9fecd615de4..2d82a6cb1444 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -48,6 +48,11 @@ extern struct platform_device s3c_device_wdt;
extern struct platform_device s3c_device_i2c0;
extern struct platform_device s3c_device_i2c1;
extern struct platform_device s3c_device_i2c2;
+extern struct platform_device s3c_device_i2c3;
+extern struct platform_device s3c_device_i2c4;
+extern struct platform_device s3c_device_i2c5;
+extern struct platform_device s3c_device_i2c6;
+extern struct platform_device s3c_device_i2c7;
extern struct platform_device s3c_device_rtc;
extern struct platform_device s3c_device_adc;
extern struct platform_device s3c_device_sdi;
@@ -69,13 +74,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;
@@ -87,6 +94,7 @@ extern struct platform_device s5pv210_device_pcm2;
extern struct platform_device s5pv210_device_iis0;
extern struct platform_device s5pv210_device_iis1;
extern struct platform_device s5pv210_device_iis2;
+extern struct platform_device s5pv210_device_spdif;
extern struct platform_device s5p6442_device_pcm0;
extern struct platform_device s5p6442_device_pcm1;
@@ -97,12 +105,16 @@ 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;
extern struct platform_device s5pc100_device_iis0;
extern struct platform_device s5pc100_device_iis1;
extern struct platform_device s5pc100_device_iis2;
+extern struct platform_device s5pc100_device_spdif;
extern struct platform_device samsung_device_keypad;
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
index 3e21c75feefa..8fd65d8b5863 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
@@ -42,6 +42,12 @@ static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip,
return (chip->config->set_pull)(chip, off, pull);
}
+static inline s3c_gpio_pull_t s3c_gpio_do_getpull(struct s3c_gpio_chip *chip,
+ unsigned int off)
+{
+ return chip->config->get_pull(chip, off);
+}
+
/**
* s3c_gpio_setcfg_s3c24xx - S3C24XX style GPIO configuration.
* @chip: The gpio chip that is being configured.
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg.h b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
index 1c6b92947c5d..e4b5cf126fa9 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-cfg.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
@@ -108,6 +108,19 @@ extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to);
*/
extern unsigned s3c_gpio_getcfg(unsigned int pin);
+/**
+ * s3c_gpio_cfgpin_range() - Change the GPIO function for configuring pin range
+ * @start: The pin number to start at
+ * @nr: The number of pins to configure from @start.
+ * @cfg: The configuration for the pin's function
+ *
+ * Call s3c_gpio_cfgpin() for the @nr pins starting at @start.
+ *
+ * @sa s3c_gpio_cfgpin.
+ */
+extern int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
+ unsigned int cfg);
+
/* Define values for the pull-{up,down} available for each gpio pin.
*
* These values control the state of the weak pull-{up,down} resistors
@@ -140,6 +153,31 @@ extern int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull);
*/
extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin);
+/* configure `all` aspects of an gpio */
+
+/**
+ * s3c_gpio_cfgall_range() - configure range of gpio functtion and pull.
+ * @start: The gpio number to start at.
+ * @nr: The number of gpio to configure from @start.
+ * @cfg: The configuration to use
+ * @pull: The pull setting to use.
+ *
+ * Run s3c_gpio_cfgpin() and s3c_gpio_setpull() over the gpio range starting
+ * @gpio and running for @size.
+ *
+ * @sa s3c_gpio_cfgpin
+ * @sa s3c_gpio_setpull
+ * @sa s3c_gpio_cfgpin_range
+ */
+extern int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
+ unsigned int cfg, s3c_gpio_pull_t pull);
+
+static inline int s3c_gpio_cfgrange_nopull(unsigned int pin, unsigned int size,
+ unsigned int cfg)
+{
+ return s3c_gpio_cfgall_range(pin, size, cfg, S3C_GPIO_PULL_NONE);
+}
+
/* Define values for the drvstr available for each gpio pin.
*
* These values control the value of the output signal driver strength,
@@ -169,4 +207,22 @@ extern s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin);
*/
extern int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr);
+/**
+ * s5p_register_gpio_interrupt() - register interrupt support for a gpio group
+ * @pin: The pin number from the group to be registered
+ *
+ * This function registers gpio interrupt support for the group that the
+ * specified pin belongs to.
+ *
+ * The total number of gpio pins is quite large ob s5p series. Registering
+ * irq support for all of them would be a resource waste. Because of that the
+ * interrupt support for standard gpio pins is registered dynamically.
+ *
+ * It will return the irq number of the interrupt that has been registered
+ * or -ENOMEM if no more gpio interrupts can be registered. It is allowed
+ * to call this function more than once for the same gpio group (the group
+ * will be registered only once).
+ */
+extern int s5p_register_gpio_interrupt(int pin);
+
#endif /* __PLAT_GPIO_CFG_H */
diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h
index e358c7da8480..13a22b8861ef 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-core.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-core.h
@@ -43,6 +43,8 @@ struct s3c_gpio_cfg;
* struct s3c_gpio_chip - wrapper for specific implementation of gpio
* @chip: The chip structure to be exported via gpiolib.
* @base: The base pointer to the gpio configuration registers.
+ * @group: The group register number for gpio interrupt support.
+ * @irq_base: The base irq number.
* @config: special function and pull-resistor control information.
* @lock: Lock for exclusive access to this gpio bank.
* @pm_save: Save information for suspend/resume support.
@@ -63,6 +65,8 @@ struct s3c_gpio_chip {
struct s3c_gpio_cfg *config;
struct s3c_gpio_pm *pm;
void __iomem *base;
+ int irq_base;
+ int group;
spinlock_t lock;
#ifdef CONFIG_PM
u32 pm_save[4];
@@ -118,6 +122,17 @@ extern void samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip,
extern void samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip);
extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip);
+
+/**
+ * samsung_gpiolib_to_irq - convert gpio pin to irq number
+ * @chip: The gpio chip that the pin belongs to.
+ * @offset: The offset of the pin in the chip.
+ *
+ * This helper returns the irq number calculated from the chip->irq_base and
+ * the provided offset.
+ */
+extern int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset);
+
/* exported for core SoC support to change */
extern struct s3c_gpio_cfg s3c24xx_gpiocfg_default;
diff --git a/arch/arm/plat-samsung/include/plat/iic.h b/arch/arm/plat-samsung/include/plat/iic.h
index 133308bf595d..1543da8f85c1 100644
--- a/arch/arm/plat-samsung/include/plat/iic.h
+++ b/arch/arm/plat-samsung/include/plat/iic.h
@@ -55,10 +55,20 @@ struct s3c2410_platform_i2c {
extern void s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *i2c);
extern void s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *i2c);
extern void s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *i2c);
+extern void s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *i2c);
+extern void s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *i2c);
+extern void s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *i2c);
+extern void s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *i2c);
+extern void s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *i2c);
/* defined by architecture to configure gpio */
extern void s3c_i2c0_cfg_gpio(struct platform_device *dev);
extern void s3c_i2c1_cfg_gpio(struct platform_device *dev);
extern void s3c_i2c2_cfg_gpio(struct platform_device *dev);
+extern void s3c_i2c3_cfg_gpio(struct platform_device *dev);
+extern void s3c_i2c4_cfg_gpio(struct platform_device *dev);
+extern void s3c_i2c5_cfg_gpio(struct platform_device *dev);
+extern void s3c_i2c6_cfg_gpio(struct platform_device *dev);
+extern void s3c_i2c7_cfg_gpio(struct platform_device *dev);
#endif /* __ASM_ARCH_IIC_H */
diff --git a/arch/arm/plat-samsung/include/plat/map-base.h b/arch/arm/plat-samsung/include/plat/map-base.h
index 250be311c85b..3ffac4d2e4f0 100644
--- a/arch/arm/plat-samsung/include/plat/map-base.h
+++ b/arch/arm/plat-samsung/include/plat/map-base.h
@@ -14,7 +14,7 @@
#ifndef __ASM_PLAT_MAP_H
#define __ASM_PLAT_MAP_H __FILE__
-/* Fit all our registers in at 0xF4000000 upwards, trying to use as
+/* Fit all our registers in at 0xF6000000 upwards, trying to use as
* little of the VA space as possible so vmalloc and friends have a
* better chance of getting memory.
*
@@ -22,7 +22,7 @@
* an single MOVS instruction (ie, only 8 bits of set data)
*/
-#define S3C_ADDR_BASE (0xF4000000)
+#define S3C_ADDR_BASE 0xF6000000
#ifndef __ASSEMBLY__
#define S3C_ADDR(x) ((void __iomem __force *)S3C_ADDR_BASE + (x))
diff --git a/arch/arm/plat-samsung/include/plat/nand-core.h b/arch/arm/plat-samsung/include/plat/nand-core.h
new file mode 100644
index 000000000000..6de20789a95e
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/nand-core.h
@@ -0,0 +1,28 @@
+/* arch/arm/plat-samsung/include/plat/nand-core.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S3C - Nand Controller core functions
+ *
+ * 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_NAND_CORE_H
+#define __ASM_ARCH_NAND_CORE_H __FILE__
+
+/* These functions are only for use with the core support code, such as
+ * the cpu specific initialisation code
+ */
+
+/* re-define device name depending on support. */
+static inline void s3c_nand_setname(char *name)
+{
+#ifdef CONFIG_S3C_DEV_NAND
+ s3c_device_nand.name = name;
+#endif
+}
+
+#endif /* __ASM_ARCH_NAND_CORE_H */
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-samsung/include/plat/sdhci.h b/arch/arm/plat-samsung/include/plat/sdhci.h
index 30844c263d03..85853f8c4c5d 100644
--- a/arch/arm/plat-samsung/include/plat/sdhci.h
+++ b/arch/arm/plat-samsung/include/plat/sdhci.h
@@ -28,11 +28,17 @@ enum cd_types {
S3C_SDHCI_CD_PERMANENT, /* no CD line, card permanently wired to host */
};
+enum clk_types {
+ S3C_SDHCI_CLK_DIV_INTERNAL, /* use mmc internal clock divider */
+ S3C_SDHCI_CLK_DIV_EXTERNAL, /* use external clock divider */
+};
+
/**
* struct s3c_sdhci_platdata() - Platform device data for Samsung SDHCI
* @max_width: The maximum number of data bits supported.
* @host_caps: Standard MMC host capabilities bit field.
* @cd_type: Type of Card Detection method (see cd_types enum above)
+ * @clk_type: Type of clock divider method (see clk_types enum above)
* @ext_cd_init: Initialize external card detect subsystem. Called on
* sdhci-s3c driver probe when cd_type == S3C_SDHCI_CD_EXTERNAL.
* notify_func argument is a callback to the sdhci-s3c driver
@@ -59,6 +65,7 @@ struct s3c_sdhci_platdata {
unsigned int max_width;
unsigned int host_caps;
enum cd_types cd_type;
+ enum clk_types clk_type;
char **clocks; /* set of clock sources */
@@ -110,6 +117,10 @@ extern void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
extern void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
extern void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
extern void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *, int w);
+extern void s5pv310_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
+extern void s5pv310_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
+extern void s5pv310_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
+extern void s5pv310_setup_sdhci3_cfg_gpio(struct platform_device *, int w);
/* S3C64XX SDHCI setup */
@@ -288,4 +299,57 @@ static inline void s5pv210_default_sdhci3(void) { }
#endif /* CONFIG_S5PV210_SETUP_SDHCI */
+/* S5PV310 SDHCI setup */
+#ifdef CONFIG_S5PV310_SETUP_SDHCI
+extern char *s5pv310_hsmmc_clksrcs[4];
+
+extern void s5pv310_setup_sdhci_cfg_card(struct platform_device *dev,
+ void __iomem *r,
+ struct mmc_ios *ios,
+ struct mmc_card *card);
+
+static inline void s5pv310_default_sdhci0(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC
+ s3c_hsmmc0_def_platdata.clocks = s5pv310_hsmmc_clksrcs;
+ s3c_hsmmc0_def_platdata.cfg_gpio = s5pv310_setup_sdhci0_cfg_gpio;
+ s3c_hsmmc0_def_platdata.cfg_card = s5pv310_setup_sdhci_cfg_card;
+#endif
+}
+
+static inline void s5pv310_default_sdhci1(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ s3c_hsmmc1_def_platdata.clocks = s5pv310_hsmmc_clksrcs;
+ s3c_hsmmc1_def_platdata.cfg_gpio = s5pv310_setup_sdhci1_cfg_gpio;
+ s3c_hsmmc1_def_platdata.cfg_card = s5pv310_setup_sdhci_cfg_card;
+#endif
+}
+
+static inline void s5pv310_default_sdhci2(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ s3c_hsmmc2_def_platdata.clocks = s5pv310_hsmmc_clksrcs;
+ s3c_hsmmc2_def_platdata.cfg_gpio = s5pv310_setup_sdhci2_cfg_gpio;
+ s3c_hsmmc2_def_platdata.cfg_card = s5pv310_setup_sdhci_cfg_card;
+#endif
+}
+
+static inline void s5pv310_default_sdhci3(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ s3c_hsmmc3_def_platdata.clocks = s5pv310_hsmmc_clksrcs;
+ s3c_hsmmc3_def_platdata.cfg_gpio = s5pv310_setup_sdhci3_cfg_gpio;
+ s3c_hsmmc3_def_platdata.cfg_card = s5pv310_setup_sdhci_cfg_card;
+#endif
+}
+
+#else
+static inline void s5pv310_default_sdhci0(void) { }
+static inline void s5pv310_default_sdhci1(void) { }
+static inline void s5pv310_default_sdhci2(void) { }
+static inline void s5pv310_default_sdhci3(void) { }
+
+#endif /* CONFIG_S5PV310_SETUP_SDHCI */
+
#endif /* __PLAT_S3C_SDHCI_H */
diff --git a/arch/arm/plat-samsung/pm-gpio.c b/arch/arm/plat-samsung/pm-gpio.c
index 7df03f87fbfa..96528200eb79 100644
--- a/arch/arm/plat-samsung/pm-gpio.c
+++ b/arch/arm/plat-samsung/pm-gpio.c
@@ -192,7 +192,7 @@ struct s3c_gpio_pm s3c_gpio_pm_2bit = {
.resume = s3c_gpio_pm_2bit_resume,
};
-#ifdef CONFIG_ARCH_S3C64XX
+#if defined(CONFIG_ARCH_S3C64XX) || defined(CONFIG_PLAT_S5P)
static void s3c_gpio_pm_4bit_save(struct s3c_gpio_chip *chip)
{
chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON);
@@ -302,7 +302,7 @@ struct s3c_gpio_pm s3c_gpio_pm_4bit = {
.save = s3c_gpio_pm_4bit_save,
.resume = s3c_gpio_pm_4bit_resume,
};
-#endif /* CONFIG_ARCH_S3C64XX */
+#endif /* CONFIG_ARCH_S3C64XX || CONFIG_PLAT_S5P */
/**
* s3c_pm_save_gpio() - save gpio chip data for suspend
diff --git a/arch/arm/plat-samsung/s3c-pl330.c b/arch/arm/plat-samsung/s3c-pl330.c
index a91305a60aed..b4ff8d74ac40 100644
--- a/arch/arm/plat-samsung/s3c-pl330.c
+++ b/arch/arm/plat-samsung/s3c-pl330.c
@@ -15,6 +15,8 @@
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
#include <asm/hardware/pl330.h>
@@ -27,6 +29,7 @@
* @node: To attach to the global list of DMACs.
* @pi: PL330 configuration info for the DMAC.
* @kmcache: Pool to quickly allocate xfers for all channels in the dmac.
+ * @clk: Pointer of DMAC operation clock.
*/
struct s3c_pl330_dmac {
unsigned busy_chan;
@@ -34,6 +37,7 @@ struct s3c_pl330_dmac {
struct list_head node;
struct pl330_info *pi;
struct kmem_cache *kmcache;
+ struct clk *clk;
};
/**
@@ -1072,16 +1076,25 @@ static int pl330_probe(struct platform_device *pdev)
if (ret)
goto probe_err4;
- ret = pl330_add(pl330_info);
- if (ret)
- goto probe_err5;
-
/* Allocate a new DMAC */
s3c_pl330_dmac = kmalloc(sizeof(*s3c_pl330_dmac), GFP_KERNEL);
if (!s3c_pl330_dmac) {
ret = -ENOMEM;
+ goto probe_err5;
+ }
+
+ /* Get operation clock and enable it */
+ s3c_pl330_dmac->clk = clk_get(&pdev->dev, "pdma");
+ if (IS_ERR(s3c_pl330_dmac->clk)) {
+ dev_err(&pdev->dev, "Cannot get operation clock.\n");
+ ret = -EINVAL;
goto probe_err6;
}
+ clk_enable(s3c_pl330_dmac->clk);
+
+ ret = pl330_add(pl330_info);
+ if (ret)
+ goto probe_err7;
/* Hook the info */
s3c_pl330_dmac->pi = pl330_info;
@@ -1094,7 +1107,7 @@ static int pl330_probe(struct platform_device *pdev)
if (!s3c_pl330_dmac->kmcache) {
ret = -ENOMEM;
- goto probe_err7;
+ goto probe_err8;
}
/* Get the list of peripherals */
@@ -1120,10 +1133,13 @@ static int pl330_probe(struct platform_device *pdev)
return 0;
+probe_err8:
+ pl330_del(pl330_info);
probe_err7:
- kfree(s3c_pl330_dmac);
+ clk_disable(s3c_pl330_dmac->clk);
+ clk_put(s3c_pl330_dmac->clk);
probe_err6:
- pl330_del(pl330_info);
+ kfree(s3c_pl330_dmac);
probe_err5:
free_irq(irq, pl330_info);
probe_err4:
@@ -1188,6 +1204,10 @@ static int pl330_remove(struct platform_device *pdev)
}
}
+ /* Disable operation clock */
+ clk_disable(dmac->clk);
+ clk_put(dmac->clk);
+
/* Remove the DMAC */
list_del(&dmac->node);
kfree(dmac);
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..313b13073c54 100644
--- a/arch/avr32/Kconfig
+++ b/arch/avr32/Kconfig
@@ -1,10 +1,3 @@
-#
-# For a description of the syntax of this configuration file,
-# see Documentation/kbuild/kconfig-language.txt.
-#
-
-mainmenu "Linux Kernel Configuration"
-
config AVR32
def_bool y
# With EMBEDDED=n, we get lots of stuff automatically selected
@@ -90,6 +83,7 @@ config PLATFORM_AT32AP
select ARCH_REQUIRE_GPIOLIB
select GENERIC_ALLOCATOR
select HAVE_FB_ATMEL
+ select HAVE_NET_MACB
#
# CPU types
@@ -145,7 +139,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/include/asm/pgtable.h b/arch/avr32/include/asm/pgtable.h
index a9ae30c41e74..6fbfea61f7bb 100644
--- a/arch/avr32/include/asm/pgtable.h
+++ b/arch/avr32/include/asm/pgtable.h
@@ -319,9 +319,7 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
#define pte_offset_kernel(dir, address) \
((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(address))
#define pte_offset_map(dir, address) pte_offset_kernel(dir, address)
-#define pte_offset_map_nested(dir, address) pte_offset_kernel(dir, address)
#define pte_unmap(pte) do { } while (0)
-#define pte_unmap_nested(pte) do { } while (0)
struct vm_area_struct;
extern void update_mmu_cache(struct vm_area_struct * vma,
diff --git a/arch/avr32/kernel/ptrace.c b/arch/avr32/kernel/ptrace.c
index 5e73c25f8f85..4aedcab7cd4b 100644
--- a/arch/avr32/kernel/ptrace.c
+++ b/arch/avr32/kernel/ptrace.c
@@ -146,9 +146,11 @@ static int ptrace_setregs(struct task_struct *tsk, const void __user *uregs)
return ret;
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int ret;
+ void __user *datap = (void __user *) data;
switch (request) {
/* Read the word at location addr in the child process */
@@ -158,8 +160,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
case PTRACE_PEEKUSR:
- ret = ptrace_read_user(child, addr,
- (unsigned long __user *)data);
+ ret = ptrace_read_user(child, addr, datap);
break;
/* Write the word in data at location addr */
@@ -173,11 +174,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
case PTRACE_GETREGS:
- ret = ptrace_getregs(child, (void __user *)data);
+ ret = ptrace_getregs(child, datap);
break;
case PTRACE_SETREGS:
- ret = ptrace_setregs(child, (const void __user *)data);
+ ret = ptrace_setregs(child, datap);
break;
default:
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index 5a3152b75cdb..0a221d48152d 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -1,10 +1,3 @@
-#
-# For a description of the syntax of this configuration file,
-# see Documentation/kbuild/kconfig-language.txt.
-#
-
-mainmenu "Blackfin Kernel Configuration"
-
config SYMBOL_PREFIX
string
default "_"
@@ -300,7 +293,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 +349,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 +419,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 +457,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 +921,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/Kconfig.debug b/arch/blackfin/Kconfig.debug
index d1825cb24768..acb83799a215 100644
--- a/arch/blackfin/Kconfig.debug
+++ b/arch/blackfin/Kconfig.debug
@@ -102,17 +102,6 @@ config DEBUG_DOUBLEFAULT_RESET
endchoice
-config DEBUG_ICACHE_CHECK
- bool "Check Instruction cache coherency"
- depends on DEBUG_KERNEL
- depends on DEBUG_HWERR
- help
- Say Y here if you are getting weird unexplained errors. This will
- ensure that icache is what SDRAM says it should be by doing a
- byte wise comparison between SDRAM and instruction cache. This
- also relocates the irq_panic() function to L1 memory, (which is
- un-cached).
-
config DEBUG_HUNT_FOR_ZERO
bool "Catch NULL pointer reads/writes"
default y
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/BF518F-EZBRD_defconfig b/arch/blackfin/configs/BF518F-EZBRD_defconfig
index 46fac1bf0605..c0b988ee30df 100644
--- a/arch/blackfin/configs/BF518F-EZBRD_defconfig
+++ b/arch/blackfin/configs/BF518F-EZBRD_defconfig
@@ -35,6 +35,7 @@ CONFIG_C_CDPRIO=y
CONFIG_BANK_3=0x99B2
CONFIG_BINFMT_FLAT=y
CONFIG_BINFMT_ZFLAT=y
+CONFIG_PM=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
@@ -114,7 +115,6 @@ 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_CRC_CCITT=m
diff --git a/arch/blackfin/configs/BF526-EZBRD_defconfig b/arch/blackfin/configs/BF526-EZBRD_defconfig
index 80240806cf9e..864af5b68874 100644
--- a/arch/blackfin/configs/BF526-EZBRD_defconfig
+++ b/arch/blackfin/configs/BF526-EZBRD_defconfig
@@ -40,6 +40,7 @@ CONFIG_C_CDPRIO=y
CONFIG_BANK_3=0x99B2
CONFIG_BINFMT_FLAT=y
CONFIG_BINFMT_ZFLAT=y
+CONFIG_PM=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
@@ -152,7 +153,6 @@ 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_CRC_CCITT=m
diff --git a/arch/blackfin/configs/BF527-AD7160-EVAL_defconfig b/arch/blackfin/configs/BF527-AD7160-EVAL_defconfig
new file mode 100644
index 000000000000..7b6a3370dbe2
--- /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_MMAP_ALLOW_UNINITIALIZED=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_CRC_CCITT=m
diff --git a/arch/blackfin/configs/BF527-EZKIT-V2_defconfig b/arch/blackfin/configs/BF527-EZKIT-V2_defconfig
index 4a9125558fcf..4faa6b46a352 100644
--- a/arch/blackfin/configs/BF527-EZKIT-V2_defconfig
+++ b/arch/blackfin/configs/BF527-EZKIT-V2_defconfig
@@ -20,6 +20,7 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_LBDAF is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
CONFIG_PREEMPT_VOLUNTARY=y
CONFIG_BF527=y
CONFIG_BF_REV_0_2=y
@@ -38,6 +39,7 @@ CONFIG_C_CDPRIO=y
CONFIG_BANK_3=0x99B2
CONFIG_BINFMT_FLAT=y
CONFIG_BINFMT_ZFLAT=y
+CONFIG_PM=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
@@ -181,6 +183,5 @@ 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
diff --git a/arch/blackfin/configs/BF527-EZKIT_defconfig b/arch/blackfin/configs/BF527-EZKIT_defconfig
index 8ccf3cec7534..9d893eb68243 100644
--- a/arch/blackfin/configs/BF527-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF527-EZKIT_defconfig
@@ -20,6 +20,7 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_LBDAF is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
CONFIG_PREEMPT_VOLUNTARY=y
CONFIG_BF527=y
CONFIG_BF_REV_0_1=y
@@ -37,6 +38,7 @@ CONFIG_C_CDPRIO=y
CONFIG_BANK_3=0x99B2
CONFIG_BINFMT_FLAT=y
CONFIG_BINFMT_ZFLAT=y
+CONFIG_PM=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
@@ -173,6 +175,5 @@ 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
diff --git a/arch/blackfin/configs/BF527-TLL6527M_defconfig b/arch/blackfin/configs/BF527-TLL6527M_defconfig
new file mode 100644
index 000000000000..97a2767c80f8
--- /dev/null
+++ b/arch/blackfin/configs/BF527-TLL6527M_defconfig
@@ -0,0 +1,179 @@
+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_CRYPTO=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRC7=m
diff --git a/arch/blackfin/configs/BF533-EZKIT_defconfig b/arch/blackfin/configs/BF533-EZKIT_defconfig
index c40e0f1c7eac..f84774360c5b 100644
--- a/arch/blackfin/configs/BF533-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF533-EZKIT_defconfig
@@ -20,6 +20,7 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_LBDAF is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
CONFIG_PREEMPT_VOLUNTARY=y
CONFIG_BFIN533_EZKIT=y
CONFIG_TIMER0=11
@@ -107,6 +108,5 @@ 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
diff --git a/arch/blackfin/configs/BF533-STAMP_defconfig b/arch/blackfin/configs/BF533-STAMP_defconfig
index aa8c1d7453ba..0e7262c04cc2 100644
--- a/arch/blackfin/configs/BF533-STAMP_defconfig
+++ b/arch/blackfin/configs/BF533-STAMP_defconfig
@@ -20,6 +20,7 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_LBDAF is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
CONFIG_PREEMPT_VOLUNTARY=y
CONFIG_TIMER0=11
CONFIG_HIGH_RES_TIMERS=y
@@ -121,6 +122,5 @@ 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
diff --git a/arch/blackfin/configs/BF537-STAMP_defconfig b/arch/blackfin/configs/BF537-STAMP_defconfig
index f245c0b427e4..4d14a002e7bd 100644
--- a/arch/blackfin/configs/BF537-STAMP_defconfig
+++ b/arch/blackfin/configs/BF537-STAMP_defconfig
@@ -20,9 +20,9 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_LBDAF is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
CONFIG_PREEMPT_VOLUNTARY=y
CONFIG_BF537=y
-CONFIG_IRQ_ERROR=11
CONFIG_HIGH_RES_TIMERS=y
CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
CONFIG_BFIN_GPTIMERS=m
@@ -133,6 +133,5 @@ 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
diff --git a/arch/blackfin/configs/BF538-EZKIT_defconfig b/arch/blackfin/configs/BF538-EZKIT_defconfig
index 74a330cca9b4..fbee9d776f56 100644
--- a/arch/blackfin/configs/BF538-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF538-EZKIT_defconfig
@@ -20,6 +20,7 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_LBDAF is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
CONFIG_PREEMPT_VOLUNTARY=y
CONFIG_BF538=y
CONFIG_IRQ_TIMER0=12
@@ -31,6 +32,7 @@ CONFIG_C_CDPRIO=y
CONFIG_BANK_3=0x99B2
CONFIG_BINFMT_FLAT=y
CONFIG_BINFMT_ZFLAT=y
+CONFIG_PM=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
@@ -129,6 +131,5 @@ 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
diff --git a/arch/blackfin/configs/BF548-EZKIT_defconfig b/arch/blackfin/configs/BF548-EZKIT_defconfig
index 29373cbba227..05dd11db2f7d 100644
--- a/arch/blackfin/configs/BF548-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF548-EZKIT_defconfig
@@ -40,6 +40,7 @@ CONFIG_EBIU_MODEVAL=0x1
CONFIG_EBIU_FCTLVAL=0x6
CONFIG_BINFMT_FLAT=y
CONFIG_BINFMT_ZFLAT=y
+CONFIG_PM=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
@@ -62,7 +63,7 @@ CONFIG_IRCOMM=m
CONFIG_IRTTY_SIR=m
CONFIG_BFIN_SIR=m
CONFIG_BFIN_SIR3=y
-CONFIG_LIB80211=m
+# CONFIG_WIRELESS is not set
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_FW_LOADER=m
CONFIG_MTD=y
@@ -92,6 +93,7 @@ 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=m
# CONFIG_INPUT_MOUSEDEV is not set
CONFIG_INPUT_EVDEV=m
diff --git a/arch/blackfin/configs/BF561-ACVILON_defconfig b/arch/blackfin/configs/BF561-ACVILON_defconfig
index 1f12034f5610..bcb14d1c5664 100644
--- a/arch/blackfin/configs/BF561-ACVILON_defconfig
+++ b/arch/blackfin/configs/BF561-ACVILON_defconfig
@@ -14,6 +14,7 @@ CONFIG_EMBEDDED=y
# 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
@@ -44,6 +45,7 @@ CONFIG_IP_PNP=y
CONFIG_SYN_COOKIES=y
# CONFIG_INET_LRO is not set
# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
# CONFIG_FW_LOADER is not set
CONFIG_MTD=y
@@ -71,6 +73,7 @@ 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 is not set
# CONFIG_SERIO is not set
# CONFIG_VT is not set
@@ -147,5 +150,4 @@ CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_MMRS=y
# CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
CONFIG_CPLB_INFO=y
-CONFIG_SECURITY=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/blackfin/configs/BF561-EZKIT_defconfig b/arch/blackfin/configs/BF561-EZKIT_defconfig
index 8913d997fa47..843aaa54a9e3 100644
--- a/arch/blackfin/configs/BF561-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF561-EZKIT_defconfig
@@ -35,6 +35,7 @@ CONFIG_C_CDPRIO=y
CONFIG_BANK_3=0xAAC2
CONFIG_BINFMT_FLAT=y
CONFIG_BINFMT_ZFLAT=y
+CONFIG_PM=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
diff --git a/arch/blackfin/configs/BlackStamp_defconfig b/arch/blackfin/configs/BlackStamp_defconfig
index 0242917b69c9..dae7adf3b2a2 100644
--- a/arch/blackfin/configs/BlackStamp_defconfig
+++ b/arch/blackfin/configs/BlackStamp_defconfig
@@ -40,6 +40,7 @@ CONFIG_INET=y
CONFIG_IP_PNP=y
# CONFIG_INET_LRO is not set
# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
# CONFIG_FW_LOADER is not set
CONFIG_MTD=y
@@ -63,6 +64,7 @@ CONFIG_NET_ETHERNET=y
CONFIG_SMC91X=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=m
# CONFIG_INPUT_KEYBOARD is not set
@@ -104,5 +106,4 @@ CONFIG_DEBUG_MMRS=y
# 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/CM-BF527_defconfig b/arch/blackfin/configs/CM-BF527_defconfig
index 0512fef3d55a..f3414244bfed 100644
--- a/arch/blackfin/configs/CM-BF527_defconfig
+++ b/arch/blackfin/configs/CM-BF527_defconfig
@@ -50,6 +50,7 @@ CONFIG_IP_PNP=y
# 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_FW_LOADER is not set
CONFIG_MTD=y
@@ -70,9 +71,9 @@ CONFIG_BLK_DEV_SD=y
CONFIG_NETDEVICES=y
CONFIG_NET_ETHERNET=y
CONFIG_BFIN_MAC=y
-CONFIG_BFIN_MAC_RMII=y
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
# CONFIG_INPUT is not set
# CONFIG_SERIO is not set
# CONFIG_VT is not set
@@ -124,7 +125,6 @@ CONFIG_DEBUG_FS=y
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
CONFIG_EARLY_PRINTK=y
-CONFIG_SECURITY=y
CONFIG_CRYPTO=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRC_CCITT=m
diff --git a/arch/blackfin/configs/CM-BF533_defconfig b/arch/blackfin/configs/CM-BF533_defconfig
index 05e09be8b4c5..8c7e08f173d4 100644
--- a/arch/blackfin/configs/CM-BF533_defconfig
+++ b/arch/blackfin/configs/CM-BF533_defconfig
@@ -33,6 +33,7 @@ CONFIG_BINFMT_SHARED_FLAT=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
+# CONFIG_WIRELESS is not set
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_MTD=y
CONFIG_MTD_PARTITIONS=y
@@ -47,6 +48,7 @@ CONFIG_MTD_PHYSMAP=y
CONFIG_NETDEVICES=y
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
# CONFIG_INPUT is not set
# CONFIG_SERIO is not set
# CONFIG_VT is not set
@@ -72,7 +74,6 @@ CONFIG_DEBUG_MMRS=y
# CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
CONFIG_EARLY_PRINTK=y
CONFIG_CPLB_INFO=y
-CONFIG_SECURITY=y
CONFIG_CRC_CCITT=y
CONFIG_CRC_ITU_T=y
CONFIG_CRC7=y
diff --git a/arch/blackfin/configs/CM-BF537E_defconfig b/arch/blackfin/configs/CM-BF537E_defconfig
index d2eb5325b9c3..bd3cb766d078 100644
--- a/arch/blackfin/configs/CM-BF537E_defconfig
+++ b/arch/blackfin/configs/CM-BF537E_defconfig
@@ -48,6 +48,7 @@ CONFIG_IP_PNP=y
# 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_MTD=y
CONFIG_MTD_CMDLINE_PARTS=y
@@ -65,6 +66,7 @@ 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 is not set
# CONFIG_SERIO is not set
# CONFIG_VT is not set
@@ -99,7 +101,6 @@ CONFIG_DEBUG_MMRS=y
# CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
CONFIG_EARLY_PRINTK=y
CONFIG_CPLB_INFO=y
-CONFIG_SECURITY=y
CONFIG_CRYPTO=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRC_CCITT=m
diff --git a/arch/blackfin/configs/CM-BF537U_defconfig b/arch/blackfin/configs/CM-BF537U_defconfig
index 9d52c443eb09..82224f37c04e 100644
--- a/arch/blackfin/configs/CM-BF537U_defconfig
+++ b/arch/blackfin/configs/CM-BF537U_defconfig
@@ -44,6 +44,7 @@ CONFIG_INET=y
# CONFIG_INET_XFRM_MODE_BEET 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_MTD=y
CONFIG_MTD_CMDLINE_PARTS=y
@@ -59,6 +60,7 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_NETDEVICES=y
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
# CONFIG_INPUT is not set
# CONFIG_SERIO is not set
# CONFIG_VT is not set
@@ -90,7 +92,6 @@ CONFIG_DEBUG_MMRS=y
# CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
CONFIG_EARLY_PRINTK=y
CONFIG_CPLB_INFO=y
-CONFIG_SECURITY=y
CONFIG_CRC_CCITT=m
CONFIG_CRC_ITU_T=y
CONFIG_CRC7=y
diff --git a/arch/blackfin/configs/CM-BF548_defconfig b/arch/blackfin/configs/CM-BF548_defconfig
index 9de13cf2cdda..433598c6e773 100644
--- a/arch/blackfin/configs/CM-BF548_defconfig
+++ b/arch/blackfin/configs/CM-BF548_defconfig
@@ -49,6 +49,7 @@ CONFIG_INET_XFRM_MODE_BEET=m
# 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_FW_LOADER is not set
CONFIG_MTD=y
@@ -71,6 +72,7 @@ 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_MOUSEDEV is not set
CONFIG_INPUT_EVDEV=m
CONFIG_INPUT_EVBUG=m
@@ -167,7 +169,6 @@ CONFIG_DEBUG_FS=y
# CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
CONFIG_EARLY_PRINTK=y
CONFIG_CPLB_INFO=y
-CONFIG_SECURITY=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_HW is not set
CONFIG_CRC_CCITT=m
diff --git a/arch/blackfin/configs/CM-BF561_defconfig b/arch/blackfin/configs/CM-BF561_defconfig
index 238353a53bf0..ded7d845cb39 100644
--- a/arch/blackfin/configs/CM-BF561_defconfig
+++ b/arch/blackfin/configs/CM-BF561_defconfig
@@ -48,6 +48,7 @@ CONFIG_INET=y
# 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_MTD=y
CONFIG_MTD_PARTITIONS=y
@@ -67,6 +68,7 @@ CONFIG_MII=y
CONFIG_SMSC911X=m
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
# CONFIG_INPUT is not set
# CONFIG_SERIO is not set
# CONFIG_VT is not set
@@ -99,7 +101,6 @@ CONFIG_DEBUG_MMRS=y
# CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
CONFIG_EARLY_PRINTK=y
CONFIG_CPLB_INFO=y
-CONFIG_SECURITY=y
CONFIG_CRC_CCITT=m
CONFIG_CRC_ITU_T=y
CONFIG_CRC7=y
diff --git a/arch/blackfin/configs/H8606_defconfig b/arch/blackfin/configs/H8606_defconfig
index 0cb524e8947f..700fb701c121 100644
--- a/arch/blackfin/configs/H8606_defconfig
+++ b/arch/blackfin/configs/H8606_defconfig
@@ -33,6 +33,7 @@ CONFIG_IRLAN=m
CONFIG_IRCOMM=m
CONFIG_IRDA_CACHE_LAST_LSAP=y
CONFIG_IRTTY_SIR=m
+# CONFIG_WIRELESS is not set
# CONFIG_FW_LOADER is not set
CONFIG_MTD=y
CONFIG_MTD_PARTITIONS=y
@@ -50,6 +51,7 @@ CONFIG_NET_ETHERNET=y
CONFIG_DM9000=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_KEYBOARD_ATKBD is not set
@@ -84,4 +86,3 @@ CONFIG_NFS_V3=y
CONFIG_NLS=m
# CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
CONFIG_CPLB_INFO=y
-CONFIG_SECURITY=y
diff --git a/arch/blackfin/configs/IP0X_defconfig b/arch/blackfin/configs/IP0X_defconfig
index 2a3411ef19fd..b40156d217e3 100644
--- a/arch/blackfin/configs/IP0X_defconfig
+++ b/arch/blackfin/configs/IP0X_defconfig
@@ -41,6 +41,7 @@ CONFIG_IP_NF_IPTABLES=y
CONFIG_IP_NF_FILTER=y
CONFIG_IP_NF_TARGET_REJECT=y
CONFIG_IP_NF_MANGLE=y
+# CONFIG_WIRELESS is not set
CONFIG_MTD=y
CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CHAR=y
@@ -60,6 +61,7 @@ CONFIG_NET_ETHERNET=y
CONFIG_DM9000=y
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
# CONFIG_INPUT is not set
# CONFIG_SERIO is not set
# CONFIG_VT is not set
@@ -89,5 +91,4 @@ CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
# CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
CONFIG_CPLB_INFO=y
-CONFIG_SECURITY=y
CONFIG_CRC_CCITT=y
diff --git a/arch/blackfin/configs/PNAV-10_defconfig b/arch/blackfin/configs/PNAV-10_defconfig
index fea303386548..be866d95ed76 100644
--- a/arch/blackfin/configs/PNAV-10_defconfig
+++ b/arch/blackfin/configs/PNAV-10_defconfig
@@ -14,6 +14,7 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_LBDAF is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
CONFIG_PREEMPT_VOLUNTARY=y
CONFIG_BF537=y
CONFIG_IRQ_TIMER0=12
@@ -107,7 +108,6 @@ CONFIG_SMB_FS=m
# CONFIG_DEBUG_HUNT_FOR_ZERO is not set
# CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
# CONFIG_ACCESS_CHECK is not set
-CONFIG_SECURITY=y
CONFIG_CRYPTO=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRC_CCITT=m
diff --git a/arch/blackfin/configs/SRV1_defconfig b/arch/blackfin/configs/SRV1_defconfig
index 9811b3186847..b64bdf759b82 100644
--- a/arch/blackfin/configs/SRV1_defconfig
+++ b/arch/blackfin/configs/SRV1_defconfig
@@ -35,6 +35,7 @@ CONFIG_IRLAN=m
CONFIG_IRCOMM=m
CONFIG_IRDA_CACHE_LAST_LSAP=y
CONFIG_IRTTY_SIR=m
+# CONFIG_WIRELESS is not set
# CONFIG_FW_LOADER is not set
CONFIG_MTD=y
CONFIG_MTD_PARTITIONS=y
@@ -51,6 +52,7 @@ CONFIG_EEPROM_AT25=m
CONFIG_NETDEVICES=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=m
# CONFIG_INPUT_KEYBOARD is not set
@@ -85,4 +87,3 @@ CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
CONFIG_CPLB_INFO=y
-CONFIG_SECURITY=y
diff --git a/arch/blackfin/configs/TCM-BF518_defconfig b/arch/blackfin/configs/TCM-BF518_defconfig
index 412bf79b9724..1bccd9a50986 100644
--- a/arch/blackfin/configs/TCM-BF518_defconfig
+++ b/arch/blackfin/configs/TCM-BF518_defconfig
@@ -128,7 +128,6 @@ 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_CRC_CCITT=m
diff --git a/arch/blackfin/configs/TCM-BF537_defconfig b/arch/blackfin/configs/TCM-BF537_defconfig
index 04bf52c4cf12..00ce899e9e5d 100644
--- a/arch/blackfin/configs/TCM-BF537_defconfig
+++ b/arch/blackfin/configs/TCM-BF537_defconfig
@@ -40,6 +40,7 @@ CONFIG_UNIX=y
CONFIG_INET=y
# CONFIG_INET_DIAG is not set
# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_MTD=y
CONFIG_MTD_CMDLINE_PARTS=y
@@ -57,6 +58,7 @@ 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 is not set
# CONFIG_SERIO is not set
# CONFIG_VT is not set
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..5392583d0253 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,28 @@
#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
+/*
+ * 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_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
+/*
+ * bfin spi registers layout
+ */
+struct bfin_spi_regs {
+ __BFP(ctl);
+ __BFP(flg);
+ __BFP(stat);
+ __BFP(tdbr);
+ __BFP(rdbr);
+ __BFP(baud);
+ __BFP(shadow);
+};
-#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
+#undef __BFP
-#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 +78,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..3be05faa2c65
--- /dev/null
+++ b/arch/blackfin/include/asm/bfin_ppi.h
@@ -0,0 +1,53 @@
+/*
+ * 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;
+};
+
+#undef __BFP
+
+#endif
diff --git a/arch/blackfin/include/asm/bfin_twi.h b/arch/blackfin/include/asm/bfin_twi.h
new file mode 100644
index 000000000000..e767d649dfc4
--- /dev/null
+++ b/arch/blackfin/include/asm/bfin_twi.h
@@ -0,0 +1,45 @@
+/*
+ * bfin_twi.h - interface to Blackfin TWIs
+ *
+ * Copyright 2005-2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __ASM_BFIN_TWI_H__
+#define __ASM_BFIN_TWI_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 twi registers layout
+ */
+struct bfin_twi_regs {
+ __BFP(clkdiv);
+ __BFP(control);
+ __BFP(slave_ctl);
+ __BFP(slave_stat);
+ __BFP(slave_addr);
+ __BFP(master_ctl);
+ __BFP(master_stat);
+ __BFP(master_addr);
+ __BFP(int_stat);
+ __BFP(int_mask);
+ __BFP(fifo_ctl);
+ __BFP(fifo_stat);
+ u32 __pad[20];
+ __BFP(xmt_data8);
+ __BFP(xmt_data16);
+ __BFP(rcv_data8);
+ __BFP(rcv_data16);
+};
+
+#undef __BFP
+
+#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..59af63c0c2be 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/entry.h b/arch/blackfin/include/asm/entry.h
index a6886f6e4819..4104d5783e2c 100644
--- a/arch/blackfin/include/asm/entry.h
+++ b/arch/blackfin/include/asm/entry.h
@@ -15,14 +15,6 @@
#define LFLUSH_I_AND_D 0x00000808
#define LSIGTRAP 5
-/* process bits for task_struct.flags */
-#define PF_TRACESYS_OFF 3
-#define PF_TRACESYS_BIT 5
-#define PF_PTRACED_OFF 3
-#define PF_PTRACED_BIT 4
-#define PF_DTRACE_OFF 1
-#define PF_DTRACE_BIT 5
-
/*
* NOTE! The single-stepping code assumes that all interrupt handlers
* start by saving SYSCFG on the stack with their first instruction.
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.c b/arch/blackfin/kernel/kgdb.c
index 08bc44ea6883..edae461b1c54 100644
--- a/arch/blackfin/kernel/kgdb.c
+++ b/arch/blackfin/kernel/kgdb.c
@@ -320,7 +320,7 @@ static void bfin_correct_hw_break(void)
}
}
-void kgdb_disable_hw_debug(struct pt_regs *regs)
+static void bfin_disable_hw_debug(struct pt_regs *regs)
{
/* Disable hardware debugging while we are in kgdb */
bfin_write_WPIACTL(0);
@@ -406,6 +406,7 @@ struct kgdb_arch arch_kgdb_ops = {
#endif
.set_hw_breakpoint = bfin_set_hw_break,
.remove_hw_breakpoint = bfin_remove_hw_break,
+ .disable_hw_break = bfin_disable_hw_debug,
.remove_all_hw_break = bfin_remove_all_hw_break,
.correct_hw_break = bfin_correct_hw_break,
};
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..75089f80855d 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.
@@ -37,12 +38,13 @@
* Get contents of register REGNO in task TASK.
*/
static inline long
-get_reg(struct task_struct *task, long regno, unsigned long __user *datap)
+get_reg(struct task_struct *task, unsigned long regno,
+ unsigned long __user *datap)
{
long tmp;
struct pt_regs *regs = task_pt_regs(task);
- if (regno & 3 || regno > PT_LAST_PSEUDO || regno < 0)
+ if (regno & 3 || regno > PT_LAST_PSEUDO)
return -EIO;
switch (regno) {
@@ -73,11 +75,11 @@ get_reg(struct task_struct *task, long regno, unsigned long __user *datap)
* Write contents of register REGNO in task TASK.
*/
static inline int
-put_reg(struct task_struct *task, long regno, unsigned long data)
+put_reg(struct task_struct *task, unsigned long regno, unsigned long data)
{
struct pt_regs *regs = task_pt_regs(task);
- if (regno & 3 || regno > PT_LAST_PSEUDO || regno < 0)
+ if (regno & 3 || regno > PT_LAST_PSEUDO)
return -EIO;
switch (regno) {
@@ -113,8 +115,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 +137,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;
}
@@ -232,7 +241,8 @@ void user_disable_single_step(struct task_struct *child)
clear_tsk_thread_flag(child, TIF_SINGLESTEP);
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int ret;
unsigned long __user *datap = (unsigned long __user *)data;
@@ -360,14 +370,14 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
return copy_regset_to_user(child, &user_bfin_native_view,
REGSET_GENERAL,
0, sizeof(struct pt_regs),
- (void __user *)data);
+ datap);
case PTRACE_SETREGS:
pr_debug("ptrace: PTRACE_SETREGS\n");
return copy_regset_from_user(child, &user_bfin_native_view,
REGSET_GENERAL,
0, sizeof(struct pt_regs),
- (const void __user *)data);
+ datap);
case_default:
default:
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..b894c8abe7ec 100644
--- a/arch/blackfin/mach-bf518/boards/ezbrd.c
+++ b/arch/blackfin/mach-bf518/boards/ezbrd.c
@@ -87,13 +87,55 @@ static struct platform_device rtc_device = {
#endif
#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+#include <linux/bfin_mac.h>
+static const unsigned short bfin_mac_peripherals[] = {
+ P_MII0_ETxD0,
+ P_MII0_ETxD1,
+ P_MII0_ETxEN,
+ P_MII0_ERxD0,
+ P_MII0_ERxD1,
+ P_MII0_TxCLK,
+ P_MII0_PHYINT,
+ P_MII0_CRS,
+ P_MII0_MDC,
+ P_MII0_MDIO,
+ 0
+};
+
+static struct bfin_phydev_platform_data bfin_phydev_data[] = {
+ {
+ .addr = 1,
+ .irq = IRQ_MAC_PHYINT,
+ },
+ {
+ .addr = 2,
+ .irq = IRQ_MAC_PHYINT,
+ },
+ {
+ .addr = 3,
+ .irq = IRQ_MAC_PHYINT,
+ },
+};
+
+static struct bfin_mii_bus_platform_data bfin_mii_bus_data = {
+ .phydev_number = 3,
+ .phydev_data = bfin_phydev_data,
+ .phy_mode = PHY_INTERFACE_MODE_MII,
+ .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,
+ .dev = {
+ .platform_data = &bfin_mii_bus,
+ }
};
#if defined(CONFIG_NET_DSA_KSZ8893M) || defined(CONFIG_NET_DSA_KSZ8893M_MODULE)
@@ -312,7 +354,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 +389,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 +567,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 +609,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 +791,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..e6ce1d7c523a 100644
--- a/arch/blackfin/mach-bf518/boards/tcm-bf518.c
+++ b/arch/blackfin/mach-bf518/boards/tcm-bf518.c
@@ -81,13 +81,35 @@ static struct platform_device rtc_device = {
#endif
#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+#include <linux/bfin_mac.h>
+static const unsigned short bfin_mac_peripherals[] = P_MII0;
+
+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_MII,
+ .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,
+ .dev = {
+ .platform_data = &bfin_mii_bus,
+ }
};
#endif
@@ -291,7 +313,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..2c31af7a320a 100644
--- a/arch/blackfin/mach-bf527/boards/cm_bf527.c
+++ b/arch/blackfin/mach-bf527/boards/cm_bf527.c
@@ -273,13 +273,35 @@ static struct platform_device dm9000_device = {
#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,
+ .dev = {
+ .platform_data = &bfin_mii_bus,
+ }
};
#endif
@@ -342,8 +364,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 +442,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..9a736a850c5c 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,
},
{
@@ -189,13 +193,35 @@ static struct platform_device rtc_device = {
#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,
+ .dev = {
+ .platform_data = &bfin_mii_bus,
+ }
};
#endif
diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c
index 87b41e994ba3..9222bc00bbd3 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,
},
{
@@ -362,13 +366,35 @@ static struct platform_device dm9000_device = {
#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,
+ .dev = {
+ .platform_data = &bfin_mii_bus,
+ }
};
#endif
@@ -431,8 +457,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 +573,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 +909,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 +955,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..9ec575729e2c
--- /dev/null
+++ b/arch/blackfin/mach-bf527/boards/tll6527m.c
@@ -0,0 +1,1008 @@
+/* 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)
+#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_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..836698c4ee54 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,
},
};
@@ -597,13 +597,35 @@ static struct platform_device bfin_sport1_uart_device = {
#endif
#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+#include <linux/bfin_mac.h>
+static const unsigned short bfin_mac_peripherals[] = P_MII0;
+
+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_MII,
+ .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,
+ .dev = {
+ .platform_data = &bfin_mii_bus,
+ }
};
#endif
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537u.c b/arch/blackfin/mach-bf537/boards/cm_bf537u.c
index d464ad5b72b2..2a85670273cb 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,
},
};
@@ -562,13 +562,35 @@ static struct platform_device bfin_sport1_uart_device = {
#endif
#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+#include <linux/bfin_mac.h>
+static const unsigned short bfin_mac_peripherals[] = P_MII0;
+
+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_MII,
+ .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,
+ .dev = {
+ .platform_data = &bfin_mii_bus,
+ }
};
#endif
diff --git a/arch/blackfin/mach-bf537/boards/minotaur.c b/arch/blackfin/mach-bf537/boards/minotaur.c
index 05d45994480e..49800518412c 100644
--- a/arch/blackfin/mach-bf537/boards/minotaur.c
+++ b/arch/blackfin/mach-bf537/boards/minotaur.c
@@ -68,13 +68,35 @@ static struct platform_device rtc_device = {
#endif
#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+#include <linux/bfin_mac.h>
+static const unsigned short bfin_mac_peripherals[] = P_MII0;
+
+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_MII,
+ .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,
+ .dev = {
+ .platform_data = &bfin_mii_bus,
+ }
};
#endif
diff --git a/arch/blackfin/mach-bf537/boards/pnav10.c b/arch/blackfin/mach-bf537/boards/pnav10.c
index 812e8f991601..b95807894e25 100644
--- a/arch/blackfin/mach-bf537/boards/pnav10.c
+++ b/arch/blackfin/mach-bf537/boards/pnav10.c
@@ -99,13 +99,35 @@ static struct platform_device smc91x_device = {
#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,
+ .dev = {
+ .platform_data = &bfin_mii_bus,
+ }
};
#endif
@@ -175,8 +197,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 +260,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..3aa344ce8e52 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,
},
};
@@ -329,13 +327,35 @@ static struct platform_device bfin_can_device = {
#endif
#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+#include <linux/bfin_mac.h>
+static const unsigned short bfin_mac_peripherals[] = P_MII0;
+
+static struct bfin_phydev_platform_data bfin_phydev_data[] = {
+ {
+ .addr = 1,
+ .irq = PHY_POLL, /* 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_MII,
+ .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,
+ .dev = {
+ .platform_data = &bfin_mii_bus,
+ }
};
#endif
@@ -418,7 +438,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 +565,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 +721,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 +911,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 +1023,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 +1074,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 +1092,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 +1121,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 +1148,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 +1268,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 +1290,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 +1308,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 +2037,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 +2165,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 +2197,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 +2256,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 +2264,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 +2369,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 +2406,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 +2415,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 +2609,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 +2666,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 +2818,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..31498add1a42 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,
},
};
@@ -564,13 +564,35 @@ static struct platform_device bfin_sport1_uart_device = {
#endif
#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+#include <linux/bfin_mac.h>
+static const unsigned short bfin_mac_peripherals[] = P_MII0;
+
+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_MII,
+ .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,
+ .dev = {
+ .platform_data = &bfin_mii_bus,
+ }
};
#endif
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/Makefile b/arch/blackfin/mach-common/Makefile
index 814cb483853b..ff299f24aba0 100644
--- a/arch/blackfin/mach-common/Makefile
+++ b/arch/blackfin/mach-common/Makefile
@@ -11,4 +11,3 @@ obj-$(CONFIG_CPU_FREQ) += cpufreq.o
obj-$(CONFIG_CPU_VOLTAGE) += dpmc.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_BFIN_KERNEL_CLOCK) += clocks-init.o
-obj-$(CONFIG_DEBUG_ICACHE_CHECK) += irqpanic.o
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/irqpanic.c b/arch/blackfin/mach-common/irqpanic.c
deleted file mode 100644
index c6496249e2bc..000000000000
--- a/arch/blackfin/mach-common/irqpanic.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * panic kernel with dump information
- *
- * Copyright 2005-2009 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/module.h>
-#include <linux/kernel_stat.h>
-#include <linux/sched.h>
-#include <asm/blackfin.h>
-
-#define L1_ICACHE_START 0xffa10000
-#define L1_ICACHE_END 0xffa13fff
-
-/*
- * irq_panic - calls panic with string setup
- */
-__attribute__ ((l1_text))
-asmlinkage void irq_panic(int reason, struct pt_regs *regs)
-{
- unsigned int cmd, tag, ca, cache_hi, cache_lo, *pa;
- unsigned short i, j, die;
- unsigned int bad[10][6];
-
- /* check entire cache for coherency
- * Since printk is in cacheable memory,
- * don't call it until you have checked everything
- */
-
- die = 0;
- i = 0;
-
- /* check icache */
-
- for (ca = L1_ICACHE_START; ca <= L1_ICACHE_END && i < 10; ca += 32) {
-
- /* Grab various address bits for the itest_cmd fields */
- cmd = (((ca & 0x3000) << 4) | /* ca[13:12] for SBNK[1:0] */
- ((ca & 0x0c00) << 16) | /* ca[11:10] for WAYSEL[1:0] */
- ((ca & 0x3f8)) | /* ca[09:03] for SET[4:0] and DW[1:0] */
- 0); /* Access Tag, Read access */
-
- SSYNC();
- bfin_write_ITEST_COMMAND(cmd);
- SSYNC();
- tag = bfin_read_ITEST_DATA0();
- SSYNC();
-
- /* if tag is marked as valid, check it */
- if (tag & 1) {
- /* The icache is arranged in 4 groups of 64-bits */
- for (j = 0; j < 32; j += 8) {
- cmd = ((((ca + j) & 0x3000) << 4) | /* ca[13:12] for SBNK[1:0] */
- (((ca + j) & 0x0c00) << 16) | /* ca[11:10] for WAYSEL[1:0] */
- (((ca + j) & 0x3f8)) | /* ca[09:03] for SET[4:0] and DW[1:0] */
- 4); /* Access Data, Read access */
-
- SSYNC();
- bfin_write_ITEST_COMMAND(cmd);
- SSYNC();
-
- cache_hi = bfin_read_ITEST_DATA1();
- cache_lo = bfin_read_ITEST_DATA0();
-
- pa = ((unsigned int *)((tag & 0xffffcc00) |
- ((ca + j) & ~(0xffffcc00))));
-
- /*
- * Debugging this, enable
- *
- * printk("addr: %08x %08x%08x | %08x%08x\n",
- * ((unsigned int *)((tag & 0xffffcc00) | ((ca+j) & ~(0xffffcc00)))),
- * cache_hi, cache_lo, *(pa+1), *pa);
- */
-
- if (cache_hi != *(pa + 1) || cache_lo != *pa) {
- /* Since icache is not working, stay out of it, by not printing */
- die = 1;
- bad[i][0] = (ca + j);
- bad[i][1] = cache_hi;
- bad[i][2] = cache_lo;
- bad[i][3] = ((tag & 0xffffcc00) |
- ((ca + j) & ~(0xffffcc00)));
- bad[i][4] = *(pa + 1);
- bad[i][5] = *(pa);
- i++;
- }
- }
- }
- }
- if (die) {
- printk(KERN_EMERG "icache coherency error\n");
- for (j = 0; j <= i; j++) {
- printk(KERN_EMERG
- "cache address : %08x cache value : %08x%08x\n",
- bad[j][0], bad[j][1], bad[j][2]);
- printk(KERN_EMERG
- "physical address: %08x SDRAM value : %08x%08x\n",
- bad[j][3], bad[j][4], bad[j][5]);
- }
- panic("icache coherency error");
- } else
- printk(KERN_EMERG "icache checked, and OK\n");
-}
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/Kconfig b/arch/cris/Kconfig
index aefe3b18a074..613e62831c55 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -1,10 +1,3 @@
-#
-# For a description of the syntax of this configuration file,
-# see the Configure script.
-#
-
-mainmenu "Linux/CRIS Kernel Configuration"
-
config MMU
bool
default y
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-v10/kernel/ptrace.c b/arch/cris/arch-v10/kernel/ptrace.c
index e70c804e9377..320065f3cbe5 100644
--- a/arch/cris/arch-v10/kernel/ptrace.c
+++ b/arch/cris/arch-v10/kernel/ptrace.c
@@ -76,9 +76,11 @@ ptrace_disable(struct task_struct *child)
* (in user space) where the result of the ptrace call is written (instead of
* being returned).
*/
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int ret;
+ unsigned int regno = addr >> 2;
unsigned long __user *datap = (unsigned long __user *)data;
switch (request) {
@@ -93,10 +95,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
unsigned long tmp;
ret = -EIO;
- if ((addr & 3) || addr < 0 || addr > PT_MAX << 2)
+ if ((addr & 3) || regno > PT_MAX)
break;
- tmp = get_reg(child, addr >> 2);
+ tmp = get_reg(child, regno);
ret = put_user(tmp, datap);
break;
}
@@ -110,19 +112,17 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
/* Write the word at location address in the USER area. */
case PTRACE_POKEUSR:
ret = -EIO;
- if ((addr & 3) || addr < 0 || addr > PT_MAX << 2)
+ if ((addr & 3) || regno > PT_MAX)
break;
- addr >>= 2;
-
- if (addr == PT_DCCR) {
+ if (regno == PT_DCCR) {
/* don't allow the tracing process to change stuff like
* interrupt enable, kernel/user bit, dma enables etc.
*/
data &= DCCR_MASK;
data |= get_reg(child, PT_DCCR) & ~DCCR_MASK;
}
- if (put_reg(child, addr, data))
+ if (put_reg(child, regno, data))
break;
ret = 0;
break;
@@ -141,7 +141,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
}
- data += sizeof(long);
+ datap++;
}
break;
@@ -165,7 +165,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
}
put_reg(child, i, tmp);
- data += sizeof(long);
+ datap++;
}
break;
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/arch-v32/kernel/ptrace.c b/arch/cris/arch-v32/kernel/ptrace.c
index f4ebd1e7d0f5..511ece94a574 100644
--- a/arch/cris/arch-v32/kernel/ptrace.c
+++ b/arch/cris/arch-v32/kernel/ptrace.c
@@ -126,9 +126,11 @@ ptrace_disable(struct task_struct *child)
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int ret;
+ unsigned int regno = addr >> 2;
unsigned long __user *datap = (unsigned long __user *)data;
switch (request) {
@@ -163,10 +165,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
unsigned long tmp;
ret = -EIO;
- if ((addr & 3) || addr < 0 || addr > PT_MAX << 2)
+ if ((addr & 3) || regno > PT_MAX)
break;
- tmp = get_reg(child, addr >> 2);
+ tmp = get_reg(child, regno);
ret = put_user(tmp, datap);
break;
}
@@ -180,19 +182,17 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
/* Write the word at location address in the USER area. */
case PTRACE_POKEUSR:
ret = -EIO;
- if ((addr & 3) || addr < 0 || addr > PT_MAX << 2)
+ if ((addr & 3) || regno > PT_MAX)
break;
- addr >>= 2;
-
- if (addr == PT_CCS) {
+ if (regno == PT_CCS) {
/* don't allow the tracing process to change stuff like
* interrupt enable, kernel/user bit, dma enables etc.
*/
data &= CCS_MASK;
data |= get_reg(child, PT_CCS) & ~CCS_MASK;
}
- if (put_reg(child, addr, data))
+ if (put_reg(child, regno, data))
break;
ret = 0;
break;
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/pgtable.h b/arch/cris/include/asm/pgtable.h
index f63d6fccbc6c..9eaae217b21b 100644
--- a/arch/cris/include/asm/pgtable.h
+++ b/arch/cris/include/asm/pgtable.h
@@ -248,10 +248,8 @@ static inline pgd_t * pgd_offset(const struct mm_struct *mm, unsigned long addre
((pte_t *) pmd_page_vaddr(*(dir)) + __pte_offset(address))
#define pte_offset_map(dir, address) \
((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address))
-#define pte_offset_map_nested(dir, address) pte_offset_map(dir, address)
#define pte_unmap(pte) do { } while (0)
-#define pte_unmap_nested(pte) do { } while (0)
#define pte_pfn(x) ((unsigned long)(__va((x).pte)) >> PAGE_SHIFT)
#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
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..f6bcb039cd6d 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -1,12 +1,9 @@
-#
-# For a description of the syntax of this configuration file,
-# see Documentation/kbuild/kconfig-language.txt.
-#
config FRV
bool
default y
select HAVE_IDE
select HAVE_ARCH_TRACEHOOK
+ select HAVE_IRQ_WORK
select HAVE_PERF_EVENTS
config ZONE_DMA
@@ -60,8 +57,6 @@ config HZ
int
default 1000
-mainmenu "Fujitsu FR-V Kernel Configuration"
-
source "init/Kconfig"
source "kernel/Kconfig.freezer"
diff --git a/arch/frv/include/asm/highmem.h b/arch/frv/include/asm/highmem.h
index cb4c317eaecc..a8d6565d415d 100644
--- a/arch/frv/include/asm/highmem.h
+++ b/arch/frv/include/asm/highmem.h
@@ -112,12 +112,11 @@ extern struct page *kmap_atomic_to_page(void *ptr);
(void *) damlr; \
})
-static inline void *kmap_atomic(struct page *page, enum km_type type)
+static inline void *kmap_atomic_primary(struct page *page, enum km_type type)
{
unsigned long paddr;
pagefault_disable();
- debug_kmap_atomic(type);
paddr = page_to_phys(page);
switch (type) {
@@ -125,14 +124,6 @@ static inline void *kmap_atomic(struct page *page, enum km_type type)
case 1: return __kmap_atomic_primary(1, paddr, 3);
case 2: return __kmap_atomic_primary(2, paddr, 4);
case 3: return __kmap_atomic_primary(3, paddr, 5);
- case 4: return __kmap_atomic_primary(4, paddr, 6);
- case 5: return __kmap_atomic_primary(5, paddr, 7);
- case 6: return __kmap_atomic_primary(6, paddr, 8);
- case 7: return __kmap_atomic_primary(7, paddr, 9);
- case 8: return __kmap_atomic_primary(8, paddr, 10);
-
- case 9 ... 9 + NR_TLB_LINES - 1:
- return __kmap_atomic_secondary(type - 9, paddr);
default:
BUG();
@@ -152,22 +143,13 @@ do { \
asm volatile("tlbpr %0,gr0,#4,#1" : : "r"(vaddr) : "memory"); \
} while(0)
-static inline void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type)
+static inline void kunmap_atomic_primary(void *kvaddr, enum km_type type)
{
switch (type) {
case 0: __kunmap_atomic_primary(0, 2); break;
case 1: __kunmap_atomic_primary(1, 3); break;
case 2: __kunmap_atomic_primary(2, 4); break;
case 3: __kunmap_atomic_primary(3, 5); break;
- case 4: __kunmap_atomic_primary(4, 6); break;
- case 5: __kunmap_atomic_primary(5, 7); break;
- case 6: __kunmap_atomic_primary(6, 8); break;
- case 7: __kunmap_atomic_primary(7, 9); break;
- case 8: __kunmap_atomic_primary(8, 10); break;
-
- case 9 ... 9 + NR_TLB_LINES - 1:
- __kunmap_atomic_secondary(type - 9, kvaddr);
- break;
default:
BUG();
@@ -175,6 +157,9 @@ static inline void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type)
pagefault_enable();
}
+void *__kmap_atomic(struct page *page);
+void __kunmap_atomic(void *kvaddr);
+
#endif /* !__ASSEMBLY__ */
#endif /* __KERNEL__ */
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/pgtable.h b/arch/frv/include/asm/pgtable.h
index c18b0d32e636..6bc241e4b4f8 100644
--- a/arch/frv/include/asm/pgtable.h
+++ b/arch/frv/include/asm/pgtable.h
@@ -451,17 +451,12 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
#if defined(CONFIG_HIGHPTE)
#define pte_offset_map(dir, address) \
- ((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE0) + pte_index(address))
-#define pte_offset_map_nested(dir, address) \
- ((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE1) + pte_index(address))
-#define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0)
-#define pte_unmap_nested(pte) kunmap_atomic((pte), KM_PTE1)
+ ((pte_t *)kmap_atomic(pmd_page(*(dir))) + pte_index(address))
+#define pte_unmap(pte) kunmap_atomic(pte)
#else
#define pte_offset_map(dir, address) \
((pte_t *)page_address(pmd_page(*(dir))) + pte_index(address))
-#define pte_offset_map_nested(dir, address) pte_offset_map((dir), (address))
#define pte_unmap(pte) do { } while (0)
-#define pte_unmap_nested(pte) do { } while (0)
#endif
/*
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/kernel/ptrace.c b/arch/frv/kernel/ptrace.c
index fac028936a04..9d68f7fac730 100644
--- a/arch/frv/kernel/ptrace.c
+++ b/arch/frv/kernel/ptrace.c
@@ -254,23 +254,26 @@ void ptrace_disable(struct task_struct *child)
user_disable_single_step(child);
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
unsigned long tmp;
int ret;
+ int regno = addr >> 2;
+ unsigned long __user *datap = (unsigned long __user *) data;
switch (request) {
/* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: {
tmp = 0;
ret = -EIO;
- if ((addr & 3) || addr < 0)
+ if (addr & 3)
break;
ret = 0;
- switch (addr >> 2) {
+ switch (regno) {
case 0 ... PT__END - 1:
- tmp = get_reg(child, addr >> 2);
+ tmp = get_reg(child, regno);
break;
case PT__END + 0:
@@ -299,23 +302,18 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
}
if (ret == 0)
- ret = put_user(tmp, (unsigned long *) data);
+ ret = put_user(tmp, datap);
break;
}
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
ret = -EIO;
- if ((addr & 3) || addr < 0)
+ if (addr & 3)
break;
- ret = 0;
- switch (addr >> 2) {
+ switch (regno) {
case 0 ... PT__END - 1:
- ret = put_reg(child, addr >> 2, data);
- break;
-
- default:
- ret = -EIO;
+ ret = put_reg(child, regno, data);
break;
}
break;
@@ -324,25 +322,25 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
return copy_regset_to_user(child, &user_frv_native_view,
REGSET_GENERAL,
0, sizeof(child->thread.user->i),
- (void __user *)data);
+ datap);
case PTRACE_SETREGS: /* Set all integer regs in the child. */
return copy_regset_from_user(child, &user_frv_native_view,
REGSET_GENERAL,
0, sizeof(child->thread.user->i),
- (const void __user *)data);
+ datap);
case PTRACE_GETFPREGS: /* Get the child FP/Media state. */
return copy_regset_to_user(child, &user_frv_native_view,
REGSET_FPMEDIA,
0, sizeof(child->thread.user->f),
- (void __user *)data);
+ datap);
case PTRACE_SETFPREGS: /* Set the child FP/Media state. */
return copy_regset_from_user(child, &user_frv_native_view,
REGSET_FPMEDIA,
0, sizeof(child->thread.user->f),
- (const void __user *)data);
+ datap);
default:
ret = ptrace_request(child, request, addr, data);
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/frv/mb93090-mb00/pci-dma.c b/arch/frv/mb93090-mb00/pci-dma.c
index 85d110b71cf7..41098a3803a2 100644
--- a/arch/frv/mb93090-mb00/pci-dma.c
+++ b/arch/frv/mb93090-mb00/pci-dma.c
@@ -61,14 +61,14 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
dampr2 = __get_DAMPR(2);
for (i = 0; i < nents; i++) {
- vaddr = kmap_atomic(sg_page(&sg[i]), __KM_CACHE);
+ vaddr = kmap_atomic_primary(sg_page(&sg[i]), __KM_CACHE);
frv_dcache_writeback((unsigned long) vaddr,
(unsigned long) vaddr + PAGE_SIZE);
}
- kunmap_atomic(vaddr, __KM_CACHE);
+ kunmap_atomic_primary(vaddr, __KM_CACHE);
if (dampr2) {
__set_DAMPR(2, dampr2);
__set_IAMPR(2, dampr2);
diff --git a/arch/frv/mm/cache-page.c b/arch/frv/mm/cache-page.c
index 0261cbe153b5..b24ade27a0f0 100644
--- a/arch/frv/mm/cache-page.c
+++ b/arch/frv/mm/cache-page.c
@@ -26,11 +26,11 @@ void flush_dcache_page(struct page *page)
dampr2 = __get_DAMPR(2);
- vaddr = kmap_atomic(page, __KM_CACHE);
+ vaddr = kmap_atomic_primary(page, __KM_CACHE);
frv_dcache_writeback((unsigned long) vaddr, (unsigned long) vaddr + PAGE_SIZE);
- kunmap_atomic(vaddr, __KM_CACHE);
+ kunmap_atomic_primary(vaddr, __KM_CACHE);
if (dampr2) {
__set_DAMPR(2, dampr2);
@@ -54,12 +54,12 @@ void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
dampr2 = __get_DAMPR(2);
- vaddr = kmap_atomic(page, __KM_CACHE);
+ vaddr = kmap_atomic_primary(page, __KM_CACHE);
start = (start & ~PAGE_MASK) | (unsigned long) vaddr;
frv_cache_wback_inv(start, start + len);
- kunmap_atomic(vaddr, __KM_CACHE);
+ kunmap_atomic_primary(vaddr, __KM_CACHE);
if (dampr2) {
__set_DAMPR(2, dampr2);
diff --git a/arch/frv/mm/highmem.c b/arch/frv/mm/highmem.c
index eadd07658075..fd7fcd4c2e33 100644
--- a/arch/frv/mm/highmem.c
+++ b/arch/frv/mm/highmem.c
@@ -36,3 +36,54 @@ struct page *kmap_atomic_to_page(void *ptr)
{
return virt_to_page(ptr);
}
+
+void *__kmap_atomic(struct page *page)
+{
+ unsigned long paddr;
+ int type;
+
+ pagefault_disable();
+ type = kmap_atomic_idx_push();
+ paddr = page_to_phys(page);
+
+ switch (type) {
+ /*
+ * The first 4 primary maps are reserved for architecture code
+ */
+ case 0: return __kmap_atomic_primary(4, paddr, 6);
+ case 1: return __kmap_atomic_primary(5, paddr, 7);
+ case 2: return __kmap_atomic_primary(6, paddr, 8);
+ case 3: return __kmap_atomic_primary(7, paddr, 9);
+ case 4: return __kmap_atomic_primary(8, paddr, 10);
+
+ case 5 ... 5 + NR_TLB_LINES - 1:
+ return __kmap_atomic_secondary(type - 5, paddr);
+
+ default:
+ BUG();
+ return NULL;
+ }
+}
+EXPORT_SYMBOL(__kmap_atomic);
+
+void __kunmap_atomic(void *kvaddr)
+{
+ int type = kmap_atomic_idx();
+ switch (type) {
+ case 0: __kunmap_atomic_primary(4, 6); break;
+ case 1: __kunmap_atomic_primary(5, 7); break;
+ case 2: __kunmap_atomic_primary(6, 8); break;
+ case 3: __kunmap_atomic_primary(7, 9); break;
+ case 4: __kunmap_atomic_primary(8, 10); break;
+
+ case 5 ... 5 + NR_TLB_LINES - 1:
+ __kunmap_atomic_secondary(type - 5, kvaddr);
+ break;
+
+ default:
+ BUG();
+ }
+ kmap_atomic_idx_pop();
+ pagefault_enable();
+}
+EXPORT_SYMBOL(__kunmap_atomic);
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
index 988b6ff34cc4..65f897d8c1e9 100644
--- a/arch/h8300/Kconfig
+++ b/arch/h8300/Kconfig
@@ -1,10 +1,3 @@
-#
-# For a description of the syntax of this configuration file,
-# see Documentation/kbuild/kconfig-language.txt.
-#
-
-mainmenu "uClinux/h8300 (w/o MMU) Kernel Configuration"
-
config H8300
bool
default y
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/ptrace.c b/arch/h8300/kernel/ptrace.c
index df114122ebdf..497fa89b5df4 100644
--- a/arch/h8300/kernel/ptrace.c
+++ b/arch/h8300/kernel/ptrace.c
@@ -50,27 +50,29 @@ void ptrace_disable(struct task_struct *child)
user_disable_single_step(child);
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int ret;
+ int regno = addr >> 2;
+ unsigned long __user *datap = (unsigned long __user *) data;
switch (request) {
/* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: {
unsigned long tmp = 0;
- if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) {
+ if ((addr & 3) || addr >= sizeof(struct user)) {
ret = -EIO;
break ;
}
ret = 0; /* Default return condition */
- addr = addr >> 2; /* temporary hack. */
- if (addr < H8300_REGS_NO)
- tmp = h8300_get_reg(child, addr);
+ if (regno < H8300_REGS_NO)
+ tmp = h8300_get_reg(child, regno);
else {
- switch(addr) {
+ switch (regno) {
case 49:
tmp = child->mm->start_code;
break ;
@@ -88,24 +90,23 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
}
}
if (!ret)
- ret = put_user(tmp,(unsigned long *) data);
+ ret = put_user(tmp, datap);
break ;
}
/* when I and D space are separate, this will have to be fixed. */
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
- if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) {
+ if ((addr & 3) || addr >= sizeof(struct user)) {
ret = -EIO;
break ;
}
- addr = addr >> 2; /* temporary hack. */
- if (addr == PT_ORIG_ER0) {
+ if (regno == PT_ORIG_ER0) {
ret = -EIO;
break ;
}
- if (addr < H8300_REGS_NO) {
- ret = h8300_put_reg(child, addr, data);
+ if (regno < H8300_REGS_NO) {
+ ret = h8300_put_reg(child, regno, data);
break ;
}
ret = -EIO;
@@ -116,11 +117,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
unsigned long tmp;
for (i = 0; i < H8300_REGS_NO; i++) {
tmp = h8300_get_reg(child, i);
- if (put_user(tmp, (unsigned long *) data)) {
+ if (put_user(tmp, datap)) {
ret = -EFAULT;
break;
}
- data += sizeof(long);
+ datap++;
}
ret = 0;
break;
@@ -130,12 +131,12 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
int i;
unsigned long tmp;
for (i = 0; i < H8300_REGS_NO; i++) {
- if (get_user(tmp, (unsigned long *) data)) {
+ if (get_user(tmp, datap)) {
ret = -EFAULT;
break;
}
h8300_put_reg(child, i, tmp);
- data += sizeof(long);
+ datap++;
}
ret = 0;
break;
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index ba22849ee3ec..e0f5b6d7f849 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -1,10 +1,3 @@
-#
-# For a description of the syntax of this configuration file,
-# see Documentation/kbuild/kconfig-language.txt.
-#
-
-mainmenu "IA-64 Linux Kernel Configuration"
-
source "init/Kconfig"
source "kernel/Kconfig.freezer"
@@ -53,6 +46,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 +58,9 @@ config NEED_SG_DMA_LENGTH
config SWIOTLB
bool
+config STACKTRACE_SUPPORT
+ def_bool y
+
config GENERIC_LOCKBREAK
def_bool n
@@ -683,8 +682,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/cputime.h b/arch/ia64/include/asm/cputime.h
index 7fa8a8594660..6073b187528a 100644
--- a/arch/ia64/include/asm/cputime.h
+++ b/arch/ia64/include/asm/cputime.h
@@ -56,10 +56,10 @@ typedef u64 cputime64_t;
#define jiffies64_to_cputime64(__jif) ((__jif) * (NSEC_PER_SEC / HZ))
/*
- * Convert cputime <-> milliseconds
+ * Convert cputime <-> microseconds
*/
-#define cputime_to_msecs(__ct) ((__ct) / NSEC_PER_MSEC)
-#define msecs_to_cputime(__msecs) ((__msecs) * NSEC_PER_MSEC)
+#define cputime_to_usecs(__ct) ((__ct) / NSEC_PER_USEC)
+#define usecs_to_cputime(__usecs) ((__usecs) * NSEC_PER_USEC)
/*
* Convert cputime <-> seconds
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/pgtable.h b/arch/ia64/include/asm/pgtable.h
index c3286f42e501..1a97af31ef17 100644
--- a/arch/ia64/include/asm/pgtable.h
+++ b/arch/ia64/include/asm/pgtable.h
@@ -406,9 +406,7 @@ pgd_offset (const struct mm_struct *mm, unsigned long address)
#define pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
#define pte_offset_kernel(dir,addr) ((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(addr))
#define pte_offset_map(dir,addr) pte_offset_kernel(dir, addr)
-#define pte_offset_map_nested(dir,addr) pte_offset_map(dir, addr)
#define pte_unmap(pte) do { } while (0)
-#define pte_unmap_nested(pte) do { } while (0)
/* atomic versions of the some PTE manipulations: */
diff --git a/arch/ia64/include/asm/siginfo.h b/arch/ia64/include/asm/siginfo.h
index 118d42979003..c8fcaa2ac48f 100644
--- a/arch/ia64/include/asm/siginfo.h
+++ b/arch/ia64/include/asm/siginfo.h
@@ -62,6 +62,7 @@ typedef struct siginfo {
int _imm; /* immediate value for "break" */
unsigned int _flags; /* see below */
unsigned long _isr; /* isr */
+ short _addr_lsb; /* lsb of faulting address */
} _sigfault;
/* SIGPOLL */
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..39e534f5a3b0 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -618,16 +618,15 @@ pfm_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
}
-static int
-pfmfs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data,
- struct vfsmount *mnt)
+static struct dentry *
+pfmfs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data)
{
- return get_sb_pseudo(fs_type, "pfm:", NULL, PFMFS_MAGIC, mnt);
+ return mount_pseudo(fs_type, "pfm:", NULL, PFMFS_MAGIC);
}
static struct file_system_type pfm_fs_type = {
.name = "pfmfs",
- .get_sb = pfmfs_get_sb,
+ .mount = pfmfs_mount,
.kill_sb = kill_anon_super,
};
@@ -1573,7 +1572,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 +1672,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 +1732,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 +1840,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 +1983,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 +4906,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/ptrace.c b/arch/ia64/kernel/ptrace.c
index 7c7909f9bc93..8848f43d819e 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -1177,7 +1177,8 @@ ptrace_disable (struct task_struct *child)
}
long
-arch_ptrace (struct task_struct *child, long request, long addr, long data)
+arch_ptrace (struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
switch (request) {
case PTRACE_PEEKTEXT:
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..5c291d65196b 100644
--- a/arch/m32r/Kconfig
+++ b/arch/m32r/Kconfig
@@ -1,10 +1,3 @@
-#
-# For a description of the syntax of this configuration file,
-# see Documentation/kbuild/kconfig-language.txt.
-#
-
-mainmenu "Linux/M32R Kernel Configuration"
-
config M32R
bool
default y
@@ -315,7 +308,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/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/pgtable.h b/arch/m32r/include/asm/pgtable.h
index e6359c566b50..8a28cfea2729 100644
--- a/arch/m32r/include/asm/pgtable.h
+++ b/arch/m32r/include/asm/pgtable.h
@@ -332,9 +332,7 @@ static inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
((pte_t *)pmd_page_vaddr(*(dir)) + pte_index(address))
#define pte_offset_map(dir, address) \
((pte_t *)page_address(pmd_page(*(dir))) + pte_index(address))
-#define pte_offset_map_nested(dir, address) pte_offset_map(dir, address)
#define pte_unmap(pte) do { } while (0)
-#define pte_unmap_nested(pte) do { } while (0)
/* Encode and de-code a swap entry */
#define __swp_type(x) (((x).val >> 2) & 0x1f)
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/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/ptrace.c b/arch/m32r/kernel/ptrace.c
index 0021ade4cba8..20743754f2b2 100644
--- a/arch/m32r/kernel/ptrace.c
+++ b/arch/m32r/kernel/ptrace.c
@@ -622,9 +622,11 @@ void ptrace_disable(struct task_struct *child)
}
long
-arch_ptrace(struct task_struct *child, long request, long addr, long data)
+arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int ret;
+ unsigned long __user *datap = (unsigned long __user *) data;
switch (request) {
/*
@@ -639,8 +641,7 @@ arch_ptrace(struct task_struct *child, long request, long addr, long data)
* read the word at location addr in the USER area.
*/
case PTRACE_PEEKUSR:
- ret = ptrace_read_user(child, addr,
- (unsigned long __user *)data);
+ ret = ptrace_read_user(child, addr, datap);
break;
/*
@@ -661,11 +662,11 @@ arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
case PTRACE_GETREGS:
- ret = ptrace_getregs(child, (void __user *)data);
+ ret = ptrace_getregs(child, datap);
break;
case PTRACE_SETREGS:
- ret = ptrace_setregs(child, (void __user *)data);
+ ret = ptrace_setregs(child, datap);
break;
default:
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..bc9271b85759 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -1,7 +1,3 @@
-#
-# For a description of the syntax of this configuration file,
-# see Documentation/kbuild/kconfig-language.txt.
-#
config M68K
bool
default y
@@ -62,8 +58,6 @@ config HZ
config ARCH_USES_GETTIMEOFFSET
def_bool y
-mainmenu "Linux/68k Kernel Configuration"
-
source "init/Kconfig"
source "kernel/Kconfig.freezer"
@@ -434,7 +428,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 +439,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..73b8c8fbed9c 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':
@@ -47,14 +50,6 @@
LFLUSH_I_AND_D = 0x00000808
-/* process bits for task_struct.ptrace */
-PT_TRACESYS_OFF = 3
-PT_TRACESYS_BIT = 1
-PT_PTRACED_OFF = 3
-PT_PTRACED_BIT = 0
-PT_DTRACE_OFF = 3
-PT_DTRACE_BIT = 2
-
#define SAVE_ALL_INT save_all_int
#define SAVE_ALL_SYS save_all_sys
#define RESTORE_ALL restore_all
diff --git a/arch/m68k/include/asm/entry_no.h b/arch/m68k/include/asm/entry_no.h
index 907ed03d792f..26be277394f9 100644
--- a/arch/m68k/include/asm/entry_no.h
+++ b/arch/m68k/include/asm/entry_no.h
@@ -28,20 +28,10 @@
* M68K COLDFIRE
*/
-#define ALLOWINT 0xf8ff
+#define ALLOWINT (~0x700)
#ifdef __ASSEMBLY__
-/* process bits for task_struct.flags */
-PF_TRACESYS_OFF = 3
-PF_TRACESYS_BIT = 5
-PF_PTRACED_OFF = 3
-PF_PTRACED_BIT = 4
-PF_DTRACE_OFF = 1
-PF_DTRACE_BIT = 5
-
-LENOSYS = 38
-
#define SWITCH_STACK_SIZE (6*4+4) /* Includes return address */
/*
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/motorola_pgtable.h b/arch/m68k/include/asm/motorola_pgtable.h
index 8e9a8a754dde..45bd3f589bf0 100644
--- a/arch/m68k/include/asm/motorola_pgtable.h
+++ b/arch/m68k/include/asm/motorola_pgtable.h
@@ -221,9 +221,7 @@ static inline pte_t *pte_offset_kernel(pmd_t *pmdp, unsigned long address)
}
#define pte_offset_map(pmdp,address) ((pte_t *)__pmd_page(*pmdp) + (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
-#define pte_offset_map_nested(pmdp, address) pte_offset_map(pmdp, address)
#define pte_unmap(pte) ((void)0)
-#define pte_unmap_nested(pte) ((void)0)
/*
* Allocate and free page tables. The xxx_kernel() versions are
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/sun3_pgtable.h b/arch/m68k/include/asm/sun3_pgtable.h
index f847ec732d62..cf5fad9b5250 100644
--- a/arch/m68k/include/asm/sun3_pgtable.h
+++ b/arch/m68k/include/asm/sun3_pgtable.h
@@ -219,9 +219,7 @@ static inline pte_t pgoff_to_pte(unsigned off)
#define pte_offset_kernel(pmd, address) ((pte_t *) __pmd_page(*pmd) + pte_index(address))
/* FIXME: should we bother with kmap() here? */
#define pte_offset_map(pmd, address) ((pte_t *)kmap(pmd_page(*pmd)) + pte_index(address))
-#define pte_offset_map_nested(pmd, address) pte_offset_map(pmd, address)
#define pte_unmap(pte) kunmap(pte)
-#define pte_unmap_nested(pte) kunmap(pte)
/* Macros to (de)construct the fake PTEs representing swap pages. */
#define __swp_type(x) ((x).val & 0x7F)
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/ptrace.c b/arch/m68k/kernel/ptrace.c
index 616e59752c29..0b252683cefb 100644
--- a/arch/m68k/kernel/ptrace.c
+++ b/arch/m68k/kernel/ptrace.c
@@ -156,55 +156,57 @@ void user_disable_single_step(struct task_struct *child)
singlestep_disable(child);
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
unsigned long tmp;
int i, ret = 0;
+ int regno = addr >> 2; /* temporary hack. */
+ unsigned long __user *datap = (unsigned long __user *) data;
switch (request) {
/* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR:
if (addr & 3)
goto out_eio;
- addr >>= 2; /* temporary hack. */
- if (addr >= 0 && addr < 19) {
- tmp = get_reg(child, addr);
- } else if (addr >= 21 && addr < 49) {
- tmp = child->thread.fp[addr - 21];
+ if (regno >= 0 && regno < 19) {
+ tmp = get_reg(child, regno);
+ } else if (regno >= 21 && regno < 49) {
+ tmp = child->thread.fp[regno - 21];
/* Convert internal fpu reg representation
* into long double format
*/
- if (FPU_IS_EMU && (addr < 45) && !(addr % 3))
+ if (FPU_IS_EMU && (regno < 45) && !(regno % 3))
tmp = ((tmp & 0xffff0000) << 15) |
((tmp & 0x0000ffff) << 16);
} else
goto out_eio;
- ret = put_user(tmp, (unsigned long *)data);
+ ret = put_user(tmp, datap);
break;
- case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
+ case PTRACE_POKEUSR:
+ /* write the word at location addr in the USER area */
if (addr & 3)
goto out_eio;
- addr >>= 2; /* temporary hack. */
- if (addr == PT_SR) {
+ if (regno == PT_SR) {
data &= SR_MASK;
data |= get_reg(child, PT_SR) & ~SR_MASK;
}
- if (addr >= 0 && addr < 19) {
- if (put_reg(child, addr, data))
+ if (regno >= 0 && regno < 19) {
+ if (put_reg(child, regno, data))
goto out_eio;
- } else if (addr >= 21 && addr < 48) {
+ } else if (regno >= 21 && regno < 48) {
/* Convert long double format
* into internal fpu reg representation
*/
- if (FPU_IS_EMU && (addr < 45) && !(addr % 3)) {
- data = (unsigned long)data << 15;
+ if (FPU_IS_EMU && (regno < 45) && !(regno % 3)) {
+ data <<= 15;
data = (data & 0xffff0000) |
((data & 0x0000ffff) >> 1);
}
- child->thread.fp[addr - 21] = data;
+ child->thread.fp[regno - 21] = data;
} else
goto out_eio;
break;
@@ -212,16 +214,16 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
case PTRACE_GETREGS: /* Get all gp regs from the child. */
for (i = 0; i < 19; i++) {
tmp = get_reg(child, i);
- ret = put_user(tmp, (unsigned long *)data);
+ ret = put_user(tmp, datap);
if (ret)
break;
- data += sizeof(long);
+ datap++;
}
break;
case PTRACE_SETREGS: /* Set all gp regs in the child. */
for (i = 0; i < 19; i++) {
- ret = get_user(tmp, (unsigned long *)data);
+ ret = get_user(tmp, datap);
if (ret)
break;
if (i == PT_SR) {
@@ -229,25 +231,24 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
tmp |= get_reg(child, PT_SR) & ~SR_MASK;
}
put_reg(child, i, tmp);
- data += sizeof(long);
+ datap++;
}
break;
case PTRACE_GETFPREGS: /* Get the child FPU state. */
- if (copy_to_user((void *)data, &child->thread.fp,
+ if (copy_to_user(datap, &child->thread.fp,
sizeof(struct user_m68kfp_struct)))
ret = -EFAULT;
break;
case PTRACE_SETFPREGS: /* Set the child FPU state. */
- if (copy_from_user(&child->thread.fp, (void *)data,
+ if (copy_from_user(&child->thread.fp, datap,
sizeof(struct user_m68kfp_struct)))
ret = -EFAULT;
break;
case PTRACE_GET_THREAD_AREA:
- ret = put_user(task_thread_info(child)->tp_value,
- (unsigned long __user *)data);
+ ret = put_user(task_thread_info(child)->tp_value, datap);
break;
default:
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 05285d08e547..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
*/
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..fa9f746cf4ae 100644
--- a/arch/m68knommu/Kconfig
+++ b/arch/m68knommu/Kconfig
@@ -1,10 +1,3 @@
-#
-# For a description of the syntax of this configuration file,
-# see Documentation/kbuild/kconfig-language.txt.
-#
-
-mainmenu "uClinux/68k (w/o MMU) Kernel Configuration"
-
config M68K
bool
default y
@@ -59,6 +52,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 +168,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 +183,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..6709fb707335 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>
@@ -111,9 +112,12 @@ void ptrace_disable(struct task_struct *child)
user_disable_single_step(child);
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int ret;
+ int regno = addr >> 2;
+ unsigned long __user *datap = (unsigned long __user *) data;
switch (request) {
/* read the word at location addr in the USER area. */
@@ -121,71 +125,48 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
unsigned long tmp;
ret = -EIO;
- if ((addr & 3) || addr < 0 ||
- addr > sizeof(struct user) - 3)
+ if ((addr & 3) || addr > sizeof(struct user) - 3)
break;
tmp = 0; /* Default return condition */
- addr = addr >> 2; /* temporary hack. */
ret = -EIO;
- if (addr < 19) {
- tmp = get_reg(child, addr);
- if (addr == PT_SR)
+ if (regno < 19) {
+ tmp = get_reg(child, regno);
+ if (regno == PT_SR)
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) {
+ } else if (regno >= 21 && regno < 49) {
+ tmp = child->thread.fp[regno - 21];
+ } else if (regno == 49) {
tmp = child->mm->start_code;
- } else if (addr == 50) {
+ } else if (regno == 50) {
tmp = child->mm->start_data;
- } else if (addr == 51) {
+ } else if (regno == 51) {
tmp = child->mm->end_code;
} else
break;
- ret = put_user(tmp,(unsigned long *) data);
+ ret = put_user(tmp, datap);
break;
}
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
ret = -EIO;
- if ((addr & 3) || addr < 0 ||
- addr > sizeof(struct user) - 3)
+ if ((addr & 3) || addr > sizeof(struct user) - 3)
break;
- addr = addr >> 2; /* temporary hack. */
-
- if (addr == PT_SR) {
+ if (regno == PT_SR) {
data &= SR_MASK;
data <<= 16;
data |= get_reg(child, PT_SR) & ~(SR_MASK << 16);
}
- if (addr < 19) {
- if (put_reg(child, addr, data))
+ if (regno < 19) {
+ if (put_reg(child, regno, data))
break;
ret = 0;
break;
}
- if (addr >= 21 && addr < 48)
+ if (regno >= 21 && regno < 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;
+ child->thread.fp[regno - 21] = data;
ret = 0;
}
break;
@@ -197,11 +178,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
tmp = get_reg(child, i);
if (i == PT_SR)
tmp >>= 16;
- if (put_user(tmp, (unsigned long *) data)) {
+ if (put_user(tmp, datap)) {
ret = -EFAULT;
break;
}
- data += sizeof(long);
+ datap++;
}
ret = 0;
break;
@@ -211,7 +192,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
int i;
unsigned long tmp;
for (i = 0; i < 19; i++) {
- if (get_user(tmp, (unsigned long *) data)) {
+ if (get_user(tmp, datap)) {
ret = -EFAULT;
break;
}
@@ -221,7 +202,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
tmp |= get_reg(child, PT_SR) & ~(SR_MASK << 16);
}
put_reg(child, i, tmp);
- data += sizeof(long);
+ datap++;
}
ret = 0;
break;
@@ -230,7 +211,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
#ifdef PTRACE_GETFPREGS
case PTRACE_GETFPREGS: { /* Get the child FPU state. */
ret = 0;
- if (copy_to_user((void *)data, &child->thread.fp,
+ if (copy_to_user(datap, &child->thread.fp,
sizeof(struct user_m68kfp_struct)))
ret = -EFAULT;
break;
@@ -240,7 +221,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
#ifdef PTRACE_SETFPREGS
case PTRACE_SETFPREGS: { /* Set the child FPU state. */
ret = 0;
- if (copy_from_user(&child->thread.fp, (void *)data,
+ if (copy_from_user(&child->thread.fp, datap,
sizeof(struct user_m68kfp_struct)))
ret = -EFAULT;
break;
@@ -248,8 +229,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
#endif
case PTRACE_GET_THREAD_AREA:
- ret = put_user(task_thread_info(child)->tp_value,
- (unsigned long __user *)data);
+ ret = put_user(task_thread_info(child)->tp_value, datap);
break;
default:
@@ -259,21 +239,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/Kconfig b/arch/microblaze/Kconfig
index 692fdfce2a23..387d5ffdfd3a 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -1,8 +1,3 @@
-# For a description of the syntax of this configuration file,
-# see Documentation/kbuild/kconfig-language.txt.
-
-mainmenu "Linux/Microblaze Kernel Configuration"
-
config MICROBLAZE
def_bool y
select HAVE_MEMBLOCK
@@ -121,6 +116,23 @@ config CMDLINE_FORCE
Set this to have arguments from the default kernel command string
override those passed by the boot loader.
+config SECCOMP
+ bool "Enable seccomp to safely compute untrusted bytecode"
+ depends on PROC_FS
+ default y
+ 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 /proc/<pid>/seccomp, it cannot be disabled
+ and the task is only allowed to execute a few safe syscalls
+ defined by each seccomp mode.
+
+ If unsure, say Y. Only embedded should say N here.
+
endmenu
menu "Advanced setup"
diff --git a/arch/microblaze/Kconfig.debug b/arch/microblaze/Kconfig.debug
index e6e5e0da28c3..e66e25c4b0b2 100644
--- a/arch/microblaze/Kconfig.debug
+++ b/arch/microblaze/Kconfig.debug
@@ -10,7 +10,7 @@ source "lib/Kconfig.debug"
config EARLY_PRINTK
bool "Early printk function for kernel"
- depends on SERIAL_UARTLITE_CONSOLE
+ depends on SERIAL_UARTLITE_CONSOLE || SERIAL_8250_CONSOLE
default n
help
This option turns on/off early printk messages to console.
diff --git a/arch/microblaze/Makefile b/arch/microblaze/Makefile
index 592c7079de88..15f1f1d1840d 100644
--- a/arch/microblaze/Makefile
+++ b/arch/microblaze/Makefile
@@ -42,11 +42,8 @@ KBUILD_CFLAGS += -ffixed-r31 $(CPUFLAGS-1) $(CPUFLAGS-2)
LDFLAGS :=
LDFLAGS_vmlinux :=
-LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
-
head-y := arch/microblaze/kernel/head.o
libs-y += arch/microblaze/lib/
-libs-y += $(LIBGCC)
core-y += arch/microblaze/kernel/
core-y += arch/microblaze/mm/
core-y += arch/microblaze/platform/
@@ -72,12 +69,16 @@ export MMU DTB
all: linux.bin
-BOOT_TARGETS = linux.bin linux.bin.gz simpleImage.%
+# With make 3.82 we cannot mix normal and wildcard targets
+BOOT_TARGETS1 = linux.bin linux.bin.gz
+BOOT_TARGETS2 = simpleImage.%
archclean:
$(Q)$(MAKE) $(clean)=$(boot)
-$(BOOT_TARGETS): vmlinux
+$(BOOT_TARGETS1): vmlinux
+ $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+$(BOOT_TARGETS2): vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
define archhelp
diff --git a/arch/microblaze/include/asm/byteorder.h b/arch/microblaze/include/asm/byteorder.h
index ce9c58732ffc..31902762a426 100644
--- a/arch/microblaze/include/asm/byteorder.h
+++ b/arch/microblaze/include/asm/byteorder.h
@@ -1,6 +1,10 @@
#ifndef _ASM_MICROBLAZE_BYTEORDER_H
#define _ASM_MICROBLAZE_BYTEORDER_H
+#ifdef __MICROBLAZEEL__
+#include <linux/byteorder/little_endian.h>
+#else
#include <linux/byteorder/big_endian.h>
+#endif
#endif /* _ASM_MICROBLAZE_BYTEORDER_H */
diff --git a/arch/microblaze/include/asm/checksum.h b/arch/microblaze/include/asm/checksum.h
index 128bf03b54b7..0185cbefdda4 100644
--- a/arch/microblaze/include/asm/checksum.h
+++ b/arch/microblaze/include/asm/checksum.h
@@ -24,8 +24,13 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
"addc %0, %0, %3\n\t"
"addc %0, %0, r0\n\t"
: "+&d" (sum)
- : "d" (saddr), "d" (daddr), "d" (len + proto));
-
+ : "d" (saddr), "d" (daddr),
+#ifdef __MICROBLAZEEL__
+ "d" ((len + proto) << 8)
+#else
+ "d" (len + proto)
+#endif
+);
return sum;
}
diff --git a/arch/microblaze/include/asm/cpuinfo.h b/arch/microblaze/include/asm/cpuinfo.h
index b4f5ca33aebf..cd257537ae54 100644
--- a/arch/microblaze/include/asm/cpuinfo.h
+++ b/arch/microblaze/include/asm/cpuinfo.h
@@ -38,6 +38,7 @@ struct cpuinfo {
u32 use_exc;
u32 ver_code;
u32 mmu;
+ u32 endian;
/* CPU caches */
u32 use_icache;
@@ -76,7 +77,6 @@ struct cpuinfo {
u32 num_rd_brk;
u32 num_wr_brk;
u32 cpu_clock_freq; /* store real freq of cpu */
- u32 freq_div_hz; /* store freq/HZ */
/* FPGA family */
u32 fpga_family_code;
@@ -97,7 +97,8 @@ void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu);
static inline unsigned int fcpu(struct device_node *cpu, char *n)
{
int *val;
- return (val = (int *) of_get_property(cpu, n, NULL)) ? *val : 0;
+ return (val = (int *) of_get_property(cpu, n, NULL)) ?
+ be32_to_cpup(val) : 0;
}
#endif /* _ASM_MICROBLAZE_CPUINFO_H */
diff --git a/arch/microblaze/include/asm/elf.h b/arch/microblaze/include/asm/elf.h
index 732caf1be741..098dfdde4b06 100644
--- a/arch/microblaze/include/asm/elf.h
+++ b/arch/microblaze/include/asm/elf.h
@@ -71,7 +71,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
#define ELF_ET_DYN_BASE (0x08000000)
-#ifdef __LITTLE_ENDIAN__
+#ifdef __MICROBLAZEEL__
#define ELF_DATA ELFDATA2LSB
#else
#define ELF_DATA ELFDATA2MSB
diff --git a/arch/microblaze/include/asm/gpio.h b/arch/microblaze/include/asm/gpio.h
index 2345ac354d9b..2b2c18be71c6 100644
--- a/arch/microblaze/include/asm/gpio.h
+++ b/arch/microblaze/include/asm/gpio.h
@@ -38,12 +38,9 @@ static inline int gpio_cansleep(unsigned int gpio)
return __gpio_cansleep(gpio);
}
-/*
- * Not implemented, yet.
- */
static inline int gpio_to_irq(unsigned int gpio)
{
- return -ENOSYS;
+ return __gpio_to_irq(gpio);
}
static inline int irq_to_gpio(unsigned int irq)
diff --git a/arch/microblaze/include/asm/io.h b/arch/microblaze/include/asm/io.h
index 00b5398d08c7..eae32220f447 100644
--- a/arch/microblaze/include/asm/io.h
+++ b/arch/microblaze/include/asm/io.h
@@ -243,6 +243,8 @@ static inline void __iomem *__ioremap(phys_addr_t address, unsigned long size,
#define out_8(a, v) __raw_writeb((v), (a))
#define in_8(a) __raw_readb(a)
+#define mmiowb()
+
#define ioport_map(port, nr) ((void __iomem *)(port))
#define ioport_unmap(addr)
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/include/asm/page.h b/arch/microblaze/include/asm/page.h
index cf377d91da71..ed9d0f6e2cdb 100644
--- a/arch/microblaze/include/asm/page.h
+++ b/arch/microblaze/include/asm/page.h
@@ -205,9 +205,6 @@ extern int page_is_ram(unsigned long pfn);
#define TOPHYS(addr) __virt_to_phys(addr)
#ifdef CONFIG_MMU
-#ifdef CONFIG_CONTIGUOUS_PAGE_ALLOC
-#define WANT_PAGE_VIRTUAL 1 /* page alloc 2 relies on this */
-#endif
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h
index 5a388eeeb28f..2232ff942ba9 100644
--- a/arch/microblaze/include/asm/pci.h
+++ b/arch/microblaze/include/asm/pci.h
@@ -165,5 +165,7 @@ extern void __init xilinx_pci_init(void);
static inline void __init xilinx_pci_init(void) { return; }
#endif
+#include <asm-generic/pci-dma-compat.h>
+
#endif /* __KERNEL__ */
#endif /* __ASM_MICROBLAZE_PCI_H */
diff --git a/arch/microblaze/include/asm/pgalloc.h b/arch/microblaze/include/asm/pgalloc.h
index c614a893f8a3..ebd35792482c 100644
--- a/arch/microblaze/include/asm/pgalloc.h
+++ b/arch/microblaze/include/asm/pgalloc.h
@@ -165,7 +165,8 @@ extern inline void pte_free(struct mm_struct *mm, struct page *ptepage)
#define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, (pte))
-#define pmd_populate(mm, pmd, pte) (pmd_val(*(pmd)) = page_address(pte))
+#define pmd_populate(mm, pmd, pte) \
+ (pmd_val(*(pmd)) = (unsigned long)page_address(pte))
#define pmd_populate_kernel(mm, pmd, pte) \
(pmd_val(*(pmd)) = (unsigned long) (pte))
diff --git a/arch/microblaze/include/asm/pgtable.h b/arch/microblaze/include/asm/pgtable.h
index ca2d92871545..cae268c22ba2 100644
--- a/arch/microblaze/include/asm/pgtable.h
+++ b/arch/microblaze/include/asm/pgtable.h
@@ -57,6 +57,13 @@ static inline int pte_file(pte_t pte) { return 0; }
#define pgprot_noncached_wc(prot) prot
+/*
+ * All 32bit addresses are effectively valid for vmalloc...
+ * Sort of meaningless for non-VM targets.
+ */
+#define VMALLOC_START 0
+#define VMALLOC_END 0xffffffff
+
#else /* CONFIG_MMU */
#include <asm-generic/4level-fixup.h>
@@ -497,12 +504,9 @@ static inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address)
#define pte_offset_kernel(dir, addr) \
((pte_t *) pmd_page_kernel(*(dir)) + pte_index(addr))
#define pte_offset_map(dir, addr) \
- ((pte_t *) kmap_atomic(pmd_page(*(dir)), KM_PTE0) + pte_index(addr))
-#define pte_offset_map_nested(dir, addr) \
- ((pte_t *) kmap_atomic(pmd_page(*(dir)), KM_PTE1) + pte_index(addr))
+ ((pte_t *) kmap_atomic(pmd_page(*(dir))) + pte_index(addr))
-#define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0)
-#define pte_unmap_nested(pte) kunmap_atomic(pte, KM_PTE1)
+#define pte_unmap(pte) kunmap_atomic(pte)
/* Encode and decode a nonlinear file mapping entry */
#define PTE_FILE_MAX_BITS 29
diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
index 101fa098f62a..bdc38312ae4a 100644
--- a/arch/microblaze/include/asm/prom.h
+++ b/arch/microblaze/include/asm/prom.h
@@ -27,6 +27,7 @@
/* Other Prototypes */
extern int early_uartlite_console(void);
+extern int early_uart16550_console(void);
#ifdef CONFIG_PCI
/*
diff --git a/arch/microblaze/include/asm/pvr.h b/arch/microblaze/include/asm/pvr.h
index 9578666e98ba..37db96a15b45 100644
--- a/arch/microblaze/include/asm/pvr.h
+++ b/arch/microblaze/include/asm/pvr.h
@@ -30,7 +30,9 @@ struct pvr_s {
#define PVR0_USE_EXC_MASK 0x04000000
#define PVR0_USE_ICACHE_MASK 0x02000000
#define PVR0_USE_DCACHE_MASK 0x01000000
-#define PVR0_USE_MMU 0x00800000 /* new */
+#define PVR0_USE_MMU 0x00800000
+#define PVR0_USE_BTC 0x00400000
+#define PVR0_ENDI 0x00200000
#define PVR0_VERSION_MASK 0x0000FF00
#define PVR0_USER1_MASK 0x000000FF
@@ -38,9 +40,9 @@ struct pvr_s {
#define PVR1_USER2_MASK 0xFFFFFFFF
/* Configuration PVR masks */
-#define PVR2_D_OPB_MASK 0x80000000
+#define PVR2_D_OPB_MASK 0x80000000 /* or AXI */
#define PVR2_D_LMB_MASK 0x40000000
-#define PVR2_I_OPB_MASK 0x20000000
+#define PVR2_I_OPB_MASK 0x20000000 /* or AXI */
#define PVR2_I_LMB_MASK 0x10000000
#define PVR2_INTERRUPT_IS_EDGE_MASK 0x08000000
#define PVR2_EDGE_IS_POSITIVE_MASK 0x04000000
@@ -63,8 +65,8 @@ struct pvr_s {
#define PVR2_OPCODE_0x0_ILL_MASK 0x00000040
#define PVR2_UNALIGNED_EXC_MASK 0x00000020
#define PVR2_ILL_OPCODE_EXC_MASK 0x00000010
-#define PVR2_IOPB_BUS_EXC_MASK 0x00000008
-#define PVR2_DOPB_BUS_EXC_MASK 0x00000004
+#define PVR2_IOPB_BUS_EXC_MASK 0x00000008 /* or AXI */
+#define PVR2_DOPB_BUS_EXC_MASK 0x00000004 /* or AXI */
#define PVR2_DIV_ZERO_EXC_MASK 0x00000002
#define PVR2_FPU_EXC_MASK 0x00000001
@@ -208,6 +210,8 @@ struct pvr_s {
#define PVR_MMU_TLB_ACCESS(pvr) (pvr.pvr[11] & PVR11_MMU_TLB_ACCESS)
#define PVR_MMU_ZONES(pvr) (pvr.pvr[11] & PVR11_MMU_ZONES)
+/* endian */
+#define PVR_ENDIAN(pvr) (pvr.pvr[0] & PVR0_ENDI)
int cpu_has_pvr(void);
void get_pvr(struct pvr_s *pvr);
diff --git a/arch/microblaze/include/asm/seccomp.h b/arch/microblaze/include/asm/seccomp.h
new file mode 100644
index 000000000000..0d912758a0d7
--- /dev/null
+++ b/arch/microblaze/include/asm/seccomp.h
@@ -0,0 +1,16 @@
+#ifndef _ASM_MICROBLAZE_SECCOMP_H
+#define _ASM_MICROBLAZE_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_sigreturn
+
+#define __NR_seccomp_read_32 __NR_read
+#define __NR_seccomp_write_32 __NR_write
+#define __NR_seccomp_exit_32 __NR_exit
+#define __NR_seccomp_sigreturn_32 __NR_sigreturn
+
+#endif /* _ASM_MICROBLAZE_SECCOMP_H */
diff --git a/arch/microblaze/include/asm/setup.h b/arch/microblaze/include/asm/setup.h
index 782b5c89248e..8f3968971e4e 100644
--- a/arch/microblaze/include/asm/setup.h
+++ b/arch/microblaze/include/asm/setup.h
@@ -25,6 +25,12 @@ void early_printk(const char *fmt, ...);
int setup_early_printk(char *opt);
void disable_early_printk(void);
+#if defined(CONFIG_EARLY_PRINTK)
+#define eprintk early_printk
+#else
+#define eprintk printk
+#endif
+
void heartbeat(void);
void setup_heartbeat(void);
diff --git a/arch/microblaze/include/asm/thread_info.h b/arch/microblaze/include/asm/thread_info.h
index 8a8e9fc6e0c0..b73da2ac21b3 100644
--- a/arch/microblaze/include/asm/thread_info.h
+++ b/arch/microblaze/include/asm/thread_info.h
@@ -127,23 +127,19 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SECCOMP 10 /* secure computing */
#define TIF_FREEZE 14 /* Freezing for suspend */
-/* FIXME change in entry.S */
-#define TIF_KERNEL_TRACE 8 /* kernel trace active */
-
/* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_POLLING_NRFLAG 16
-#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
-#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
-#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
-#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
-#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
-#define _TIF_IRET (1<<TIF_IRET)
-#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
-#define _TIF_FREEZE (1<<TIF_FREEZE)
+#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
+#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
+#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
+#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
+#define _TIF_IRET (1 << TIF_IRET)
+#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
+#define _TIF_FREEZE (1 << TIF_FREEZE)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_SECCOMP (1 << TIF_SECCOMP)
-#define _TIF_KERNEL_TRACE (1 << TIF_KERNEL_TRACE)
/* work to do in syscall trace */
#define _TIF_WORK_SYSCALL_MASK (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | \
diff --git a/arch/microblaze/include/asm/unaligned.h b/arch/microblaze/include/asm/unaligned.h
index 3658d91ac0fb..2b97cbe500e9 100644
--- a/arch/microblaze/include/asm/unaligned.h
+++ b/arch/microblaze/include/asm/unaligned.h
@@ -12,12 +12,18 @@
# ifdef __KERNEL__
-# include <linux/unaligned/be_struct.h>
+# include <linux/unaligned/be_byteshift.h>
# include <linux/unaligned/le_byteshift.h>
# include <linux/unaligned/generic.h>
-# define get_unaligned __get_unaligned_be
-# define put_unaligned __put_unaligned_be
+
+# ifdef __MICROBLAZEEL__
+# define get_unaligned __get_unaligned_le
+# define put_unaligned __put_unaligned_le
+# else
+# define get_unaligned __get_unaligned_be
+# define put_unaligned __put_unaligned_be
+# endif
# endif /* __KERNEL__ */
#endif /* _ASM_MICROBLAZE_UNALIGNED_H */
diff --git a/arch/microblaze/include/asm/unistd.h b/arch/microblaze/include/asm/unistd.h
index 2b67e92a773c..d770b00ec6b1 100644
--- a/arch/microblaze/include/asm/unistd.h
+++ b/arch/microblaze/include/asm/unistd.h
@@ -383,8 +383,11 @@
#define __NR_rt_tgsigqueueinfo 365 /* new */
#define __NR_perf_event_open 366 /* new */
#define __NR_recvmmsg 367 /* new */
+#define __NR_fanotify_init 368
+#define __NR_fanotify_mark 369
+#define __NR_prlimit64 370
-#define __NR_syscalls 368
+#define __NR_syscalls 371
#ifdef __KERNEL__
#ifndef __ASSEMBLY__
diff --git a/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c b/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c
index f72dbd66c844..f70a6047f08e 100644
--- a/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c
+++ b/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c
@@ -72,6 +72,7 @@ void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu)
CI(pvr_user2, USER2);
CI(mmu, USE_MMU);
+ CI(endian, ENDIAN);
CI(use_icache, USE_ICACHE);
CI(icache_tagbits, ICACHE_ADDR_TAG_BITS);
diff --git a/arch/microblaze/kernel/cpu/cpuinfo-static.c b/arch/microblaze/kernel/cpu/cpuinfo-static.c
index 6095aa6b5c88..b16b994ca3d2 100644
--- a/arch/microblaze/kernel/cpu/cpuinfo-static.c
+++ b/arch/microblaze/kernel/cpu/cpuinfo-static.c
@@ -119,6 +119,7 @@ void __init set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu)
ci->pvr_user2 = fcpu(cpu, "xlnx,pvr-user2");
ci->mmu = fcpu(cpu, "xlnx,use-mmu");
+ ci->endian = fcpu(cpu, "xlnx,endianness");
ci->ver_code = 0;
ci->fpga_family_code = 0;
diff --git a/arch/microblaze/kernel/cpu/cpuinfo.c b/arch/microblaze/kernel/cpu/cpuinfo.c
index 255ef880351e..87c79fa275c3 100644
--- a/arch/microblaze/kernel/cpu/cpuinfo.c
+++ b/arch/microblaze/kernel/cpu/cpuinfo.c
@@ -30,6 +30,8 @@ const struct cpu_ver_key cpu_ver_lookup[] = {
{"7.20.c", 0x0e},
{"7.20.d", 0x0f},
{"7.30.a", 0x10},
+ {"7.30.b", 0x11},
+ {"8.00.a", 0x12},
{NULL, 0},
};
diff --git a/arch/microblaze/kernel/cpu/mb.c b/arch/microblaze/kernel/cpu/mb.c
index 7086e3564281..b4048af02615 100644
--- a/arch/microblaze/kernel/cpu/mb.c
+++ b/arch/microblaze/kernel/cpu/mb.c
@@ -51,11 +51,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
count = seq_printf(m,
"CPU-Family: MicroBlaze\n"
"FPGA-Arch: %s\n"
- "CPU-Ver: %s\n"
+ "CPU-Ver: %s, %s endian\n"
"CPU-MHz: %d.%02d\n"
"BogoMips: %lu.%02lu\n",
fpga_family,
cpu_ver,
+ cpuinfo.endian ? "little" : "big",
cpuinfo.cpu_clock_freq /
1000000,
cpuinfo.cpu_clock_freq %
diff --git a/arch/microblaze/kernel/cpu/pvr.c b/arch/microblaze/kernel/cpu/pvr.c
index 9bee9382bf74..e01afa68273e 100644
--- a/arch/microblaze/kernel/cpu/pvr.c
+++ b/arch/microblaze/kernel/cpu/pvr.c
@@ -27,7 +27,7 @@
register unsigned tmp __asm__("r3"); \
tmp = 0x0; /* Prevent warning about unused */ \
__asm__ __volatile__ ( \
- ".byte 0x94,0x60,0xa0, " #pvrid "\n\t" \
+ "mfs %0, rpvr" #pvrid ";" \
: "=r" (tmp) : : "memory"); \
val = tmp; \
}
diff --git a/arch/microblaze/kernel/early_printk.c b/arch/microblaze/kernel/early_printk.c
index 7de84923ba07..c3616a080ebf 100644
--- a/arch/microblaze/kernel/early_printk.c
+++ b/arch/microblaze/kernel/early_printk.c
@@ -24,7 +24,8 @@
static u32 early_console_initialized;
static u32 base_addr;
-static void early_printk_putc(char c)
+#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
+static void early_printk_uartlite_putc(char c)
{
/*
* Limit how many times we'll spin waiting for TX FIFO status.
@@ -45,25 +46,70 @@ static void early_printk_putc(char c)
out_be32(base_addr + 4, c & 0xff);
}
-static void early_printk_write(struct console *unused,
+static void early_printk_uartlite_write(struct console *unused,
const char *s, unsigned n)
{
while (*s && n-- > 0) {
- early_printk_putc(*s);
+ early_printk_uartlite_putc(*s);
if (*s == '\n')
- early_printk_putc('\r');
+ early_printk_uartlite_putc('\r');
s++;
}
}
-static struct console early_serial_console = {
+static struct console early_serial_uartlite_console = {
.name = "earlyser",
- .write = early_printk_write,
+ .write = early_printk_uartlite_write,
.flags = CON_PRINTBUFFER,
.index = -1,
};
+#endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */
-static struct console *early_console = &early_serial_console;
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+static void early_printk_uart16550_putc(char c)
+{
+ /*
+ * Limit how many times we'll spin waiting for TX FIFO status.
+ * This will prevent lockups if the base address is incorrectly
+ * set, or any other issue on the UARTLITE.
+ * This limit is pretty arbitrary, unless we are at about 10 baud
+ * we'll never timeout on a working UART.
+ */
+
+ #define UART_LSR_TEMT 0x40 /* Transmitter empty */
+ #define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
+ #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
+
+ unsigned retries = 10000;
+
+ while (--retries &&
+ !((in_be32(base_addr + 0x14) & BOTH_EMPTY) == BOTH_EMPTY))
+ ;
+
+ if (retries)
+ out_be32(base_addr, c & 0xff);
+}
+
+static void early_printk_uart16550_write(struct console *unused,
+ const char *s, unsigned n)
+{
+ while (*s && n-- > 0) {
+ early_printk_uart16550_putc(*s);
+ if (*s == '\n')
+ early_printk_uart16550_putc('\r');
+ s++;
+ }
+}
+
+static struct console early_serial_uart16550_console = {
+ .name = "earlyser",
+ .write = early_printk_uart16550_write,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+};
+#endif /* CONFIG_SERIAL_8250_CONSOLE */
+
+static struct console *early_console;
void early_printk(const char *fmt, ...)
{
@@ -84,20 +130,43 @@ int __init setup_early_printk(char *opt)
if (early_console_initialized)
return 1;
+#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
base_addr = early_uartlite_console();
if (base_addr) {
early_console_initialized = 1;
#ifdef CONFIG_MMU
early_console_reg_tlb_alloc(base_addr);
#endif
+ early_console = &early_serial_uartlite_console;
early_printk("early_printk_console is enabled at 0x%08x\n",
base_addr);
/* register_console(early_console); */
return 0;
- } else
- return 1;
+ }
+#endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+ base_addr = early_uart16550_console();
+ base_addr &= ~3; /* clear register offset */
+ if (base_addr) {
+ early_console_initialized = 1;
+#ifdef CONFIG_MMU
+ early_console_reg_tlb_alloc(base_addr);
+#endif
+ early_console = &early_serial_uart16550_console;
+
+ early_printk("early_printk_console is enabled at 0x%08x\n",
+ base_addr);
+
+ /* register_console(early_console); */
+
+ return 0;
+ }
+#endif /* CONFIG_SERIAL_8250_CONSOLE */
+
+ return 1;
}
void __init disable_early_printk(void)
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S
index 304882e56459..819238b8a429 100644
--- a/arch/microblaze/kernel/entry.S
+++ b/arch/microblaze/kernel/entry.S
@@ -186,6 +186,8 @@
swi r13, r1, PTO+PT_R13; /* Save SDA2 */ \
swi r14, r1, PTO+PT_PC; /* PC, before IRQ/trap */ \
swi r15, r1, PTO+PT_R15; /* Save LP */ \
+ swi r16, r1, PTO+PT_R16; \
+ swi r17, r1, PTO+PT_R17; \
swi r18, r1, PTO+PT_R18; /* Save asm scratch reg */ \
swi r19, r1, PTO+PT_R19; \
swi r20, r1, PTO+PT_R20; \
@@ -220,6 +222,8 @@
lwi r13, r1, PTO+PT_R13; /* restore SDA2 */ \
lwi r14, r1, PTO+PT_PC; /* RESTORE_LINK PC, before IRQ/trap */\
lwi r15, r1, PTO+PT_R15; /* restore LP */ \
+ lwi r16, r1, PTO+PT_R16; \
+ lwi r17, r1, PTO+PT_R17; \
lwi r18, r1, PTO+PT_R18; /* restore asm scratch reg */ \
lwi r19, r1, PTO+PT_R19; \
lwi r20, r1, PTO+PT_R20; \
@@ -295,6 +299,8 @@ C_ENTRY(_user_exception):
/* addik r1, r1, -STATE_SAVE_SIZE; */
addik r1, r1, THREAD_SIZE + CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE;
SAVE_REGS
+ swi r0, r1, PTO + PT_R3
+ swi r0, r1, PTO + PT_R4
lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
swi r11, r1, PTO+PT_R1; /* Store user SP. */
@@ -458,14 +464,8 @@ C_ENTRY(sys_execve):
addik r8, r1, PTO; /* add user context as 4th arg */
C_ENTRY(sys_rt_sigreturn_wrapper):
- swi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */
- swi r4, r1, PTO+PT_R4;
- brlid r15, sys_rt_sigreturn /* Do real work */
+ brid sys_rt_sigreturn /* Do real work */
addik r5, r1, PTO; /* add user context as 1st arg */
- lwi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */
- lwi r4, r1, PTO+PT_R4;
- bri ret_from_trap /* fall through will not work here due to align */
- nop;
/*
* HW EXCEPTION rutine start
@@ -765,9 +765,7 @@ C_ENTRY(_debug_exception):
/* save all regs to pt_reg structure */
swi r0, r1, PTO+PT_R0; /* R0 must be saved too */
swi r14, r1, PTO+PT_R14 /* rewrite saved R14 value */
- swi r16, r1, PTO+PT_R16
swi r16, r1, PTO+PT_PC; /* PC and r16 are the same */
- swi r17, r1, PTO+PT_R17
/* save special purpose registers to pt_regs */
mfs r11, rear;
swi r11, r1, PTO+PT_EAR;
@@ -801,8 +799,6 @@ C_ENTRY(_debug_exception):
addik r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack. */
SAVE_REGS;
- swi r17, r1, PTO+PT_R17;
- swi r16, r1, PTO+PT_R16;
swi r16, r1, PTO+PT_PC; /* Save LP */
swi r0, r1, PTO + PT_MODE; /* Was in user-mode. */
lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
@@ -848,8 +844,6 @@ dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */
tophys(r1,r1);
/* MS: Restore all regs */
RESTORE_REGS
- lwi r17, r1, PTO+PT_R17;
- lwi r16, r1, PTO+PT_R16;
addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space */
lwi r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer */
DBTRAP_return_user: /* MS: Make global symbol for debugging */
@@ -863,7 +857,6 @@ DBTRAP_return_user: /* MS: Make global symbol for debugging */
RESTORE_REGS
lwi r14, r1, PTO+PT_R14;
lwi r16, r1, PTO+PT_PC;
- lwi r17, r1, PTO+PT_R17;
addik r1, r1, STATE_SAVE_SIZE; /* MS: Clean up stack space */
tovirt(r1,r1);
DBTRAP_return_kernel: /* MS: Make global symbol for debugging */
diff --git a/arch/microblaze/kernel/exceptions.c b/arch/microblaze/kernel/exceptions.c
index b98ee8d0c1cd..478f2943ede7 100644
--- a/arch/microblaze/kernel/exceptions.c
+++ b/arch/microblaze/kernel/exceptions.c
@@ -72,7 +72,6 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
int fsr, int addr)
{
#ifdef CONFIG_MMU
- int code;
addr = regs->pc;
#endif
@@ -86,8 +85,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
switch (type & 0x1F) {
case MICROBLAZE_ILL_OPCODE_EXCEPTION:
if (user_mode(regs)) {
- pr_debug(KERN_WARNING "Illegal opcode exception " \
- "in user mode.\n");
+ pr_debug("Illegal opcode exception in user mode\n");
_exception(SIGILL, regs, ILL_ILLOPC, addr);
return;
}
@@ -97,8 +95,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
break;
case MICROBLAZE_IBUS_EXCEPTION:
if (user_mode(regs)) {
- pr_debug(KERN_WARNING "Instruction bus error " \
- "exception in user mode.\n");
+ pr_debug("Instruction bus error exception in user mode\n");
_exception(SIGBUS, regs, BUS_ADRERR, addr);
return;
}
@@ -108,8 +105,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
break;
case MICROBLAZE_DBUS_EXCEPTION:
if (user_mode(regs)) {
- pr_debug(KERN_WARNING "Data bus error exception " \
- "in user mode.\n");
+ pr_debug("Data bus error exception in user mode\n");
_exception(SIGBUS, regs, BUS_ADRERR, addr);
return;
}
@@ -119,8 +115,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
break;
case MICROBLAZE_DIV_ZERO_EXCEPTION:
if (user_mode(regs)) {
- pr_debug(KERN_WARNING "Divide by zero exception " \
- "in user mode\n");
+ pr_debug("Divide by zero exception in user mode\n");
_exception(SIGILL, regs, FPE_INTDIV, addr);
return;
}
@@ -129,7 +124,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
die("Divide by zero exception", regs, SIGBUS);
break;
case MICROBLAZE_FPU_EXCEPTION:
- pr_debug(KERN_WARNING "FPU exception\n");
+ pr_debug("FPU exception\n");
/* IEEE FP exception */
/* I removed fsr variable and use code var for storing fsr */
if (fsr & FSR_IO)
@@ -147,14 +142,8 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
#ifdef CONFIG_MMU
case MICROBLAZE_PRIVILEGED_EXCEPTION:
- pr_debug(KERN_WARNING "Privileged exception\n");
- /* "brk r0,r0" - used as debug breakpoint - old toolchain */
- if (get_user(code, (unsigned long *)regs->pc) == 0
- && code == 0x980c0000) {
- _exception(SIGTRAP, regs, TRAP_BRKPT, addr);
- } else {
- _exception(SIGILL, regs, ILL_PRVOPC, addr);
- }
+ pr_debug("Privileged exception\n");
+ _exception(SIGILL, regs, ILL_PRVOPC, addr);
break;
#endif
default:
diff --git a/arch/microblaze/kernel/heartbeat.c b/arch/microblaze/kernel/heartbeat.c
index 522751737cfa..154756f3c694 100644
--- a/arch/microblaze/kernel/heartbeat.c
+++ b/arch/microblaze/kernel/heartbeat.c
@@ -47,11 +47,10 @@ void setup_heartbeat(void)
struct device_node *gpio = NULL;
int *prop;
int j;
- char *gpio_list[] = {
- "xlnx,xps-gpio-1.00.a",
- "xlnx,opb-gpio-1.00.a",
- NULL
- };
+ const char * const gpio_list[] = {
+ "xlnx,xps-gpio-1.00.a",
+ NULL
+ };
for (j = 0; gpio_list[j] != NULL; j++) {
gpio = of_find_compatible_node(NULL, NULL, gpio_list[j]);
@@ -60,7 +59,7 @@ void setup_heartbeat(void)
}
if (gpio) {
- base_addr = *(int *) of_get_property(gpio, "reg", NULL);
+ base_addr = be32_to_cpup(of_get_property(gpio, "reg", NULL));
base_addr = (unsigned long) ioremap(base_addr, PAGE_SIZE);
printk(KERN_NOTICE "Heartbeat GPIO at 0x%x\n", base_addr);
diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c
index 03172c1da770..d61ea33aff7c 100644
--- a/arch/microblaze/kernel/intc.c
+++ b/arch/microblaze/kernel/intc.c
@@ -126,11 +126,8 @@ void __init init_IRQ(void)
0
};
#endif
- static char *intc_list[] = {
+ const char * const intc_list[] = {
"xlnx,xps-intc-1.00.a",
- "xlnx,opb-intc-1.00.c",
- "xlnx,opb-intc-1.00.b",
- "xlnx,opb-intc-1.00.a",
NULL
};
@@ -141,12 +138,15 @@ void __init init_IRQ(void)
}
BUG_ON(!intc);
- intc_baseaddr = *(int *) of_get_property(intc, "reg", NULL);
+ intc_baseaddr = be32_to_cpup(of_get_property(intc,
+ "reg", NULL));
intc_baseaddr = (unsigned long) ioremap(intc_baseaddr, PAGE_SIZE);
- nr_irq = *(int *) of_get_property(intc, "xlnx,num-intr-inputs", NULL);
+ nr_irq = be32_to_cpup(of_get_property(intc,
+ "xlnx,num-intr-inputs", NULL));
intr_type =
- *(int *) of_get_property(intc, "xlnx,kind-of-intr", NULL);
+ be32_to_cpup(of_get_property(intc,
+ "xlnx,kind-of-intr", NULL));
if (intr_type >= (1 << (nr_irq + 1)))
printk(KERN_INFO " ERROR: Mismatch in kind-of-intr param\n");
diff --git a/arch/microblaze/kernel/kgdb.c b/arch/microblaze/kernel/kgdb.c
index bfc006b7f2d8..09a5e8286137 100644
--- a/arch/microblaze/kernel/kgdb.c
+++ b/arch/microblaze/kernel/kgdb.c
@@ -80,7 +80,7 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
void microblaze_kgdb_break(struct pt_regs *regs)
{
if (kgdb_handle_exception(1, SIGTRAP, 0, regs) != 0)
- return 0;
+ return;
/* Jump over the first arch_kgdb_breakpoint which is barrier to
* get kgdb work. The same solution is used for powerpc */
@@ -114,7 +114,6 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code,
{
char *ptr;
unsigned long address;
- int cpu = smp_processor_id();
switch (remcom_in_buffer[0]) {
case 'c':
@@ -143,5 +142,9 @@ void kgdb_arch_exit(void)
* Global data
*/
struct kgdb_arch arch_kgdb_ops = {
+#ifdef __MICROBLAZEEL__
+ .gdb_bpt_instr = {0x18, 0x00, 0x0c, 0xba}, /* brki r16, 0x18 */
+#else
.gdb_bpt_instr = {0xba, 0x0c, 0x00, 0x18}, /* brki r16, 0x18 */
+#endif
};
diff --git a/arch/microblaze/kernel/microblaze_ksyms.c b/arch/microblaze/kernel/microblaze_ksyms.c
index ff85f7718035..5cb034174005 100644
--- a/arch/microblaze/kernel/microblaze_ksyms.c
+++ b/arch/microblaze/kernel/microblaze_ksyms.c
@@ -15,37 +15,13 @@
#include <linux/syscalls.h>
#include <asm/checksum.h>
+#include <asm/cacheflush.h>
#include <linux/io.h>
#include <asm/page.h>
#include <asm/system.h>
#include <linux/ftrace.h>
#include <linux/uaccess.h>
-/*
- * libgcc functions - functions that are used internally by the
- * compiler... (prototypes are not correct though, but that
- * doesn't really matter since they're not versioned).
- */
-extern void __ashldi3(void);
-EXPORT_SYMBOL(__ashldi3);
-extern void __ashrdi3(void);
-EXPORT_SYMBOL(__ashrdi3);
-extern void __divsi3(void);
-EXPORT_SYMBOL(__divsi3);
-extern void __lshrdi3(void);
-EXPORT_SYMBOL(__lshrdi3);
-extern void __modsi3(void);
-EXPORT_SYMBOL(__modsi3);
-extern void __mulsi3(void);
-EXPORT_SYMBOL(__mulsi3);
-extern void __muldi3(void);
-EXPORT_SYMBOL(__muldi3);
-extern void __ucmpdi2(void);
-EXPORT_SYMBOL(__ucmpdi2);
-extern void __udivsi3(void);
-EXPORT_SYMBOL(__udivsi3);
-extern void __umodsi3(void);
-EXPORT_SYMBOL(__umodsi3);
extern char *_ebss;
EXPORT_SYMBOL_GPL(_ebss);
#ifdef CONFIG_FUNCTION_TRACER
@@ -63,3 +39,9 @@ EXPORT_SYMBOL(__strncpy_user);
EXPORT_SYMBOL(memcpy);
EXPORT_SYMBOL(memmove);
#endif
+
+#ifdef CONFIG_MMU
+EXPORT_SYMBOL(empty_zero_page);
+#endif
+
+EXPORT_SYMBOL(mbc);
diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
index 427b13b4740f..a105301e2b7f 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);
@@ -77,11 +72,12 @@ static int __init early_init_dt_scan_serial(unsigned long node,
/* find compatible node with uartlite */
p = of_get_flat_dt_prop(node, "compatible", &l);
if ((strncmp(p, "xlnx,xps-uartlite", 17) != 0) &&
- (strncmp(p, "xlnx,opb-uartlite", 17) != 0))
+ (strncmp(p, "xlnx,opb-uartlite", 17) != 0) &&
+ (strncmp(p, "xlnx,axi-uartlite", 17) != 0))
return 0;
addr = of_get_flat_dt_prop(node, "reg", &l);
- return *addr; /* return address */
+ return be32_to_cpup(addr); /* return address */
}
/* this function is looking for early uartlite console - Microblaze specific */
@@ -89,6 +85,40 @@ int __init early_uartlite_console(void)
{
return of_scan_flat_dt(early_init_dt_scan_serial, NULL);
}
+
+/* MS this is Microblaze specifig function */
+static int __init early_init_dt_scan_serial_full(unsigned long node,
+ const char *uname, int depth, void *data)
+{
+ unsigned long l;
+ char *p;
+ unsigned int addr;
+
+ pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
+
+/* find all serial nodes */
+ if (strncmp(uname, "serial", 6) != 0)
+ return 0;
+
+ early_init_dt_check_for_initrd(node);
+
+/* find compatible node with uartlite */
+ p = of_get_flat_dt_prop(node, "compatible", &l);
+
+ if ((strncmp(p, "xlnx,xps-uart16550", 18) != 0) &&
+ (strncmp(p, "xlnx,axi-uart16550", 18) != 0))
+ return 0;
+
+ addr = *(u32 *)of_get_flat_dt_prop(node, "reg", &l);
+ addr += *(u32 *)of_get_flat_dt_prop(node, "reg-offset", &l);
+ return be32_to_cpu(addr); /* return address */
+}
+
+/* this function is looking for early uartlite console - Microblaze specific */
+int __init early_uart16550_console(void)
+{
+ return of_scan_flat_dt(early_init_dt_scan_serial_full, NULL);
+}
#endif
void __init early_init_devtree(void *params)
diff --git a/arch/microblaze/kernel/ptrace.c b/arch/microblaze/kernel/ptrace.c
index dc03ffc8174a..05ac8cc975d5 100644
--- a/arch/microblaze/kernel/ptrace.c
+++ b/arch/microblaze/kernel/ptrace.c
@@ -73,7 +73,8 @@ static microblaze_reg_t *reg_save_addr(unsigned reg_offs,
return (microblaze_reg_t *)((char *)regs + reg_offs);
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int rval;
unsigned long val = 0;
@@ -99,7 +100,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
} else {
rval = -EIO;
}
- } else if (addr >= 0 && addr < PT_SIZE && (addr & 0x3) == 0) {
+ } else if (addr < PT_SIZE && (addr & 0x3) == 0) {
microblaze_reg_t *reg_addr = reg_save_addr(addr, child);
if (request == PTRACE_PEEKUSR)
val = *reg_addr;
diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c
index f5f768842354..bb1558e4b283 100644
--- a/arch/microblaze/kernel/setup.c
+++ b/arch/microblaze/kernel/setup.c
@@ -92,12 +92,6 @@ inline unsigned get_romfs_len(unsigned *addr)
}
#endif /* CONFIG_MTD_UCLINUX_EBSS */
-#if defined(CONFIG_EARLY_PRINTK) && defined(CONFIG_SERIAL_UARTLITE_CONSOLE)
-#define eprintk early_printk
-#else
-#define eprintk printk
-#endif
-
void __init machine_early_init(const char *cmdline, unsigned int ram,
unsigned int fdt, unsigned int msr)
{
diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S
index 03376dc814c9..e88a930fd1e3 100644
--- a/arch/microblaze/kernel/syscall_table.S
+++ b/arch/microblaze/kernel/syscall_table.S
@@ -372,3 +372,6 @@ ENTRY(sys_call_table)
.long sys_rt_tgsigqueueinfo /* 365 */
.long sys_perf_event_open
.long sys_recvmmsg
+ .long sys_fanotify_init
+ .long sys_fanotify_mark
+ .long sys_prlimit64 /* 370 */
diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c
index b1380ae93ae1..a5aa33db1df3 100644
--- a/arch/microblaze/kernel/timer.c
+++ b/arch/microblaze/kernel/timer.c
@@ -38,6 +38,9 @@ static unsigned int timer_baseaddr;
#define TIMER_BASE timer_baseaddr
#endif
+unsigned int freq_div_hz;
+unsigned int timer_clock_freq;
+
#define TCSR0 (0x00)
#define TLR0 (0x04)
#define TCR0 (0x08)
@@ -115,7 +118,7 @@ static void microblaze_timer_set_mode(enum clock_event_mode mode,
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
printk(KERN_INFO "%s: periodic\n", __func__);
- microblaze_timer0_start_periodic(cpuinfo.freq_div_hz);
+ microblaze_timer0_start_periodic(freq_div_hz);
break;
case CLOCK_EVT_MODE_ONESHOT:
printk(KERN_INFO "%s: oneshot\n", __func__);
@@ -168,7 +171,7 @@ static struct irqaction timer_irqaction = {
static __init void microblaze_clockevent_init(void)
{
clockevent_microblaze_timer.mult =
- div_sc(cpuinfo.cpu_clock_freq, NSEC_PER_SEC,
+ div_sc(timer_clock_freq, NSEC_PER_SEC,
clockevent_microblaze_timer.shift);
clockevent_microblaze_timer.max_delta_ns =
clockevent_delta2ns((u32)~0, &clockevent_microblaze_timer);
@@ -201,7 +204,7 @@ static struct cyclecounter microblaze_cc = {
int __init init_microblaze_timecounter(void)
{
- microblaze_cc.mult = div_sc(cpuinfo.cpu_clock_freq, NSEC_PER_SEC,
+ microblaze_cc.mult = div_sc(timer_clock_freq, NSEC_PER_SEC,
microblaze_cc.shift);
timecounter_init(&microblaze_tc, &microblaze_cc, sched_clock());
@@ -221,7 +224,7 @@ static struct clocksource clocksource_microblaze = {
static int __init microblaze_clocksource_init(void)
{
clocksource_microblaze.mult =
- clocksource_hz2mult(cpuinfo.cpu_clock_freq,
+ clocksource_hz2mult(timer_clock_freq,
clocksource_microblaze.shift);
if (clocksource_register(&clocksource_microblaze))
panic("failed to register clocksource");
@@ -247,6 +250,7 @@ void __init time_init(void)
u32 irq, i = 0;
u32 timer_num = 1;
struct device_node *timer = NULL;
+ const void *prop;
#ifdef CONFIG_SELFMOD_TIMER
unsigned int timer_baseaddr = 0;
int arr_func[] = {
@@ -258,12 +262,10 @@ void __init time_init(void)
0
};
#endif
- char *timer_list[] = {
- "xlnx,xps-timer-1.00.a",
- "xlnx,opb-timer-1.00.b",
- "xlnx,opb-timer-1.00.a",
- NULL
- };
+ const char * const timer_list[] = {
+ "xlnx,xps-timer-1.00.a",
+ NULL
+ };
for (i = 0; timer_list[i] != NULL; i++) {
timer = of_find_compatible_node(NULL, NULL, timer_list[i]);
@@ -272,13 +274,13 @@ void __init time_init(void)
}
BUG_ON(!timer);
- timer_baseaddr = *(int *) of_get_property(timer, "reg", NULL);
+ timer_baseaddr = be32_to_cpup(of_get_property(timer, "reg", NULL));
timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE);
- irq = *(int *) of_get_property(timer, "interrupts", NULL);
- timer_num =
- *(int *) of_get_property(timer, "xlnx,one-timer-only", NULL);
+ irq = be32_to_cpup(of_get_property(timer, "interrupts", NULL));
+ timer_num = be32_to_cpup(of_get_property(timer,
+ "xlnx,one-timer-only", NULL));
if (timer_num) {
- printk(KERN_EMERG "Please enable two timers in HW\n");
+ eprintk(KERN_EMERG "Please enable two timers in HW\n");
BUG();
}
@@ -288,7 +290,14 @@ void __init time_init(void)
printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n",
timer_list[i], timer_baseaddr, irq);
- cpuinfo.freq_div_hz = cpuinfo.cpu_clock_freq / HZ;
+ /* If there is clock-frequency property than use it */
+ prop = of_get_property(timer, "clock-frequency", NULL);
+ if (prop)
+ timer_clock_freq = be32_to_cpup(prop);
+ else
+ timer_clock_freq = cpuinfo.cpu_clock_freq;
+
+ freq_div_hz = timer_clock_freq / HZ;
setup_irq(irq, &timer_irqaction);
#ifdef CONFIG_HEART_BEAT
diff --git a/arch/microblaze/kernel/vmlinux.lds.S b/arch/microblaze/kernel/vmlinux.lds.S
index a09f2962fbec..96a88c31fe48 100644
--- a/arch/microblaze/kernel/vmlinux.lds.S
+++ b/arch/microblaze/kernel/vmlinux.lds.S
@@ -8,7 +8,6 @@
* for more details.
*/
-OUTPUT_FORMAT("elf32-microblaze", "elf32-microblaze", "elf32-microblaze")
OUTPUT_ARCH(microblaze)
ENTRY(microblaze_start)
@@ -16,7 +15,11 @@ ENTRY(microblaze_start)
#include <asm-generic/vmlinux.lds.h>
#include <asm/thread_info.h>
+#ifdef __MICROBLAZEEL__
+jiffies = jiffies_64;
+#else
jiffies = jiffies_64 + 4;
+#endif
SECTIONS {
. = CONFIG_KERNEL_START;
diff --git a/arch/microblaze/lib/Makefile b/arch/microblaze/lib/Makefile
index 4dfe47d3cd91..f1fcbff3da25 100644
--- a/arch/microblaze/lib/Makefile
+++ b/arch/microblaze/lib/Makefile
@@ -11,3 +11,13 @@ lib-y += memcpy.o memmove.o
endif
lib-y += uaccess_old.o
+
+lib-y += ashldi3.o
+lib-y += ashrdi3.o
+lib-y += divsi3.o
+lib-y += lshrdi3.o
+lib-y += modsi3.o
+lib-y += muldi3.o
+lib-y += mulsi3.o
+lib-y += udivsi3.o
+lib-y += umodsi3.o
diff --git a/arch/microblaze/lib/ashldi3.c b/arch/microblaze/lib/ashldi3.c
new file mode 100644
index 000000000000..beb80f316095
--- /dev/null
+++ b/arch/microblaze/lib/ashldi3.c
@@ -0,0 +1,29 @@
+#include <linux/module.h>
+
+#include "libgcc.h"
+
+long long __ashldi3(long long u, word_type b)
+{
+ DWunion uu, w;
+ word_type bm;
+
+ if (b == 0)
+ return u;
+
+ uu.ll = u;
+ bm = 32 - b;
+
+ if (bm <= 0) {
+ w.s.low = 0;
+ w.s.high = (unsigned int) uu.s.low << -bm;
+ } else {
+ const unsigned int carries = (unsigned int) uu.s.low >> bm;
+
+ w.s.low = (unsigned int) uu.s.low << b;
+ w.s.high = ((unsigned int) uu.s.high << b) | carries;
+ }
+
+ return w.ll;
+}
+
+EXPORT_SYMBOL(__ashldi3);
diff --git a/arch/microblaze/lib/ashrdi3.c b/arch/microblaze/lib/ashrdi3.c
new file mode 100644
index 000000000000..c884a912b660
--- /dev/null
+++ b/arch/microblaze/lib/ashrdi3.c
@@ -0,0 +1,31 @@
+#include <linux/module.h>
+
+#include "libgcc.h"
+
+long long __ashrdi3(long long u, word_type b)
+{
+ DWunion uu, w;
+ word_type bm;
+
+ if (b == 0)
+ return u;
+
+ uu.ll = u;
+ bm = 32 - b;
+
+ if (bm <= 0) {
+ /* w.s.high = 1..1 or 0..0 */
+ w.s.high =
+ uu.s.high >> 31;
+ w.s.low = uu.s.high >> -bm;
+ } else {
+ const unsigned int carries = (unsigned int) uu.s.high << bm;
+
+ w.s.high = uu.s.high >> b;
+ w.s.low = ((unsigned int) uu.s.low >> b) | carries;
+ }
+
+ return w.ll;
+}
+
+EXPORT_SYMBOL(__ashrdi3);
diff --git a/arch/microblaze/lib/divsi3.S b/arch/microblaze/lib/divsi3.S
new file mode 100644
index 000000000000..595b02d6e86b
--- /dev/null
+++ b/arch/microblaze/lib/divsi3.S
@@ -0,0 +1,73 @@
+#include <linux/linkage.h>
+
+/*
+* Divide operation for 32 bit integers.
+* Input : Dividend in Reg r5
+* Divisor in Reg r6
+* Output: Result in Reg r3
+*/
+ .text
+ .globl __divsi3
+ .type __divsi3, @function
+ .ent __divsi3
+__divsi3:
+ .frame r1, 0, r15
+
+ addik r1, r1, -16
+ swi r28, r1, 0
+ swi r29, r1, 4
+ swi r30, r1, 8
+ swi r31, r1, 12
+
+ beqi r6, div_by_zero /* div_by_zero - division error */
+ beqi r5, result_is_zero /* result is zero */
+ bgeid r5, r5_pos
+ xor r28, r5, r6 /* get the sign of the result */
+ rsubi r5, r5, 0 /* make r5 positive */
+r5_pos:
+ bgei r6, r6_pos
+ rsubi r6, r6, 0 /* make r6 positive */
+r6_pos:
+ addik r30, r0, 0 /* clear mod */
+ addik r3, r0, 0 /* clear div */
+ addik r29, r0, 32 /* initialize the loop count */
+
+ /* first part try to find the first '1' in the r5 */
+div0:
+ blti r5, div2 /* this traps r5 == 0x80000000 */
+div1:
+ add r5, r5, r5 /* left shift logical r5 */
+ bgtid r5, div1
+ addik r29, r29, -1
+div2:
+ /* left shift logical r5 get the '1' into the carry */
+ add r5, r5, r5
+ addc r30, r30, r30 /* move that bit into the mod register */
+ rsub r31, r6, r30 /* try to subtract (r30 a r6) */
+ blti r31, mod_too_small
+ /* move the r31 to mod since the result was positive */
+ or r30, r0, r31
+ addik r3, r3, 1
+mod_too_small:
+ addik r29, r29, -1
+ beqi r29, loop_end
+ add r3, r3, r3 /* shift in the '1' into div */
+ bri div2 /* div2 */
+loop_end:
+ bgei r28, return_here
+ brid return_here
+ rsubi r3, r3, 0 /* negate the result */
+div_by_zero:
+result_is_zero:
+ or r3, r0, r0 /* set result to 0 */
+return_here:
+/* restore values of csrs and that of r3 and the divisor and the dividend */
+ lwi r28, r1, 0
+ lwi r29, r1, 4
+ lwi r30, r1, 8
+ lwi r31, r1, 12
+ rtsd r15, 8
+ addik r1, r1, 16
+
+.size __divsi3, . - __divsi3
+.end __divsi3
diff --git a/arch/microblaze/lib/libgcc.h b/arch/microblaze/lib/libgcc.h
new file mode 100644
index 000000000000..05909d58e2fe
--- /dev/null
+++ b/arch/microblaze/lib/libgcc.h
@@ -0,0 +1,25 @@
+#ifndef __ASM_LIBGCC_H
+#define __ASM_LIBGCC_H
+
+#include <asm/byteorder.h>
+
+typedef int word_type __attribute__ ((mode (__word__)));
+
+#ifdef __BIG_ENDIAN
+struct DWstruct {
+ int high, low;
+};
+#elif defined(__LITTLE_ENDIAN)
+struct DWstruct {
+ int low, high;
+};
+#else
+#error I feel sick.
+#endif
+
+typedef union {
+ struct DWstruct s;
+ long long ll;
+} DWunion;
+
+#endif /* __ASM_LIBGCC_H */
diff --git a/arch/microblaze/lib/lshrdi3.c b/arch/microblaze/lib/lshrdi3.c
new file mode 100644
index 000000000000..dcf8d6810b7c
--- /dev/null
+++ b/arch/microblaze/lib/lshrdi3.c
@@ -0,0 +1,29 @@
+#include <linux/module.h>
+
+#include "libgcc.h"
+
+long long __lshrdi3(long long u, word_type b)
+{
+ DWunion uu, w;
+ word_type bm;
+
+ if (b == 0)
+ return u;
+
+ uu.ll = u;
+ bm = 32 - b;
+
+ if (bm <= 0) {
+ w.s.high = 0;
+ w.s.low = (unsigned int) uu.s.high >> -bm;
+ } else {
+ const unsigned int carries = (unsigned int) uu.s.high << bm;
+
+ w.s.high = (unsigned int) uu.s.high >> b;
+ w.s.low = ((unsigned int) uu.s.low >> b) | carries;
+ }
+
+ return w.ll;
+}
+
+EXPORT_SYMBOL(__lshrdi3);
diff --git a/arch/microblaze/lib/memcpy.c b/arch/microblaze/lib/memcpy.c
index 014bac92bdff..cc495d7d99cc 100644
--- a/arch/microblaze/lib/memcpy.c
+++ b/arch/microblaze/lib/memcpy.c
@@ -33,17 +33,24 @@
#include <asm/system.h>
#ifdef __HAVE_ARCH_MEMCPY
+#ifndef CONFIG_OPT_LIB_FUNCTION
void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
{
const char *src = v_src;
char *dst = v_dst;
-#ifndef CONFIG_OPT_LIB_FUNCTION
+
/* Simple, byte oriented memcpy. */
while (c--)
*dst++ = *src++;
return v_dst;
-#else
+}
+#else /* CONFIG_OPT_LIB_FUNCTION */
+void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
+{
+ const char *src = v_src;
+ char *dst = v_dst;
+
/* The following code tries to optimize the copy by using unsigned
* alignment. This will work fine if both source and destination are
* aligned on the same boundary. However, if they are aligned on
@@ -86,7 +93,7 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
case 0x1: /* Unaligned - Off by 1 */
/* Word align the source */
i_src = (const void *) ((unsigned)src & ~3);
-
+#ifndef __MICROBLAZEEL__
/* Load the holding buffer */
buf_hold = *i_src++ << 8;
@@ -95,7 +102,16 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
*i_dst++ = buf_hold | value >> 24;
buf_hold = value << 8;
}
+#else
+ /* Load the holding buffer */
+ buf_hold = (*i_src++ & 0xFFFFFF00) >>8;
+ for (; c >= 4; c -= 4) {
+ value = *i_src++;
+ *i_dst++ = buf_hold | ((value & 0xFF) << 24);
+ buf_hold = (value & 0xFFFFFF00) >>8;
+ }
+#endif
/* Realign the source */
src = (const void *)i_src;
src -= 3;
@@ -103,7 +119,7 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
case 0x2: /* Unaligned - Off by 2 */
/* Word align the source */
i_src = (const void *) ((unsigned)src & ~3);
-
+#ifndef __MICROBLAZEEL__
/* Load the holding buffer */
buf_hold = *i_src++ << 16;
@@ -112,7 +128,16 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
*i_dst++ = buf_hold | value >> 16;
buf_hold = value << 16;
}
+#else
+ /* Load the holding buffer */
+ buf_hold = (*i_src++ & 0xFFFF0000 )>>16;
+ for (; c >= 4; c -= 4) {
+ value = *i_src++;
+ *i_dst++ = buf_hold | ((value & 0xFFFF)<<16);
+ buf_hold = (value & 0xFFFF0000) >>16;
+ }
+#endif
/* Realign the source */
src = (const void *)i_src;
src -= 2;
@@ -120,7 +145,7 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
case 0x3: /* Unaligned - Off by 3 */
/* Word align the source */
i_src = (const void *) ((unsigned)src & ~3);
-
+#ifndef __MICROBLAZEEL__
/* Load the holding buffer */
buf_hold = *i_src++ << 24;
@@ -129,7 +154,16 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
*i_dst++ = buf_hold | value >> 8;
buf_hold = value << 24;
}
+#else
+ /* Load the holding buffer */
+ buf_hold = (*i_src++ & 0xFF000000) >> 24;
+ for (; c >= 4; c -= 4) {
+ value = *i_src++;
+ *i_dst++ = buf_hold | ((value & 0xFFFFFF) << 8);
+ buf_hold = (value & 0xFF000000) >> 24;
+ }
+#endif
/* Realign the source */
src = (const void *)i_src;
src -= 1;
@@ -150,7 +184,7 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
}
return v_dst;
-#endif
}
+#endif /* CONFIG_OPT_LIB_FUNCTION */
EXPORT_SYMBOL(memcpy);
#endif /* __HAVE_ARCH_MEMCPY */
diff --git a/arch/microblaze/lib/memmove.c b/arch/microblaze/lib/memmove.c
index 0929198c5e68..123e3616f2dd 100644
--- a/arch/microblaze/lib/memmove.c
+++ b/arch/microblaze/lib/memmove.c
@@ -31,16 +31,12 @@
#include <linux/string.h>
#ifdef __HAVE_ARCH_MEMMOVE
+#ifndef CONFIG_OPT_LIB_FUNCTION
void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
{
const char *src = v_src;
char *dst = v_dst;
-#ifdef CONFIG_OPT_LIB_FUNCTION
- const uint32_t *i_src;
- uint32_t *i_dst;
-#endif
-
if (!c)
return v_dst;
@@ -48,7 +44,6 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
if (v_dst <= v_src)
return memcpy(v_dst, v_src, c);
-#ifndef CONFIG_OPT_LIB_FUNCTION
/* copy backwards, from end to beginning */
src += c;
dst += c;
@@ -58,7 +53,22 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
*--dst = *--src;
return v_dst;
-#else
+}
+#else /* CONFIG_OPT_LIB_FUNCTION */
+void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
+{
+ const char *src = v_src;
+ char *dst = v_dst;
+ const uint32_t *i_src;
+ uint32_t *i_dst;
+
+ if (!c)
+ return v_dst;
+
+ /* Use memcpy when source is higher than dest */
+ if (v_dst <= v_src)
+ return memcpy(v_dst, v_src, c);
+
/* The following code tries to optimize the copy by using unsigned
* alignment. This will work fine if both source and destination are
* aligned on the same boundary. However, if they are aligned on
@@ -104,7 +114,7 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
case 0x1: /* Unaligned - Off by 1 */
/* Word align the source */
i_src = (const void *) (((unsigned)src + 4) & ~3);
-
+#ifndef __MICROBLAZEEL__
/* Load the holding buffer */
buf_hold = *--i_src >> 24;
@@ -113,7 +123,16 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
*--i_dst = buf_hold << 8 | value;
buf_hold = value >> 24;
}
+#else
+ /* Load the holding buffer */
+ buf_hold = (*--i_src & 0xFF) << 24;
+ for (; c >= 4; c -= 4) {
+ value = *--i_src;
+ *--i_dst = buf_hold | ((value & 0xFFFFFF00)>>8);
+ buf_hold = (value & 0xFF) << 24;
+ }
+#endif
/* Realign the source */
src = (const void *)i_src;
src += 1;
@@ -121,7 +140,7 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
case 0x2: /* Unaligned - Off by 2 */
/* Word align the source */
i_src = (const void *) (((unsigned)src + 4) & ~3);
-
+#ifndef __MICROBLAZEEL__
/* Load the holding buffer */
buf_hold = *--i_src >> 16;
@@ -130,7 +149,16 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
*--i_dst = buf_hold << 16 | value;
buf_hold = value >> 16;
}
+#else
+ /* Load the holding buffer */
+ buf_hold = (*--i_src & 0xFFFF) << 16;
+ for (; c >= 4; c -= 4) {
+ value = *--i_src;
+ *--i_dst = buf_hold | ((value & 0xFFFF0000)>>16);
+ buf_hold = (value & 0xFFFF) << 16;
+ }
+#endif
/* Realign the source */
src = (const void *)i_src;
src += 2;
@@ -138,7 +166,7 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
case 0x3: /* Unaligned - Off by 3 */
/* Word align the source */
i_src = (const void *) (((unsigned)src + 4) & ~3);
-
+#ifndef __MICROBLAZEEL__
/* Load the holding buffer */
buf_hold = *--i_src >> 8;
@@ -147,7 +175,16 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
*--i_dst = buf_hold << 24 | value;
buf_hold = value >> 8;
}
+#else
+ /* Load the holding buffer */
+ buf_hold = (*--i_src & 0xFFFFFF) << 8;
+ for (; c >= 4; c -= 4) {
+ value = *--i_src;
+ *--i_dst = buf_hold | ((value & 0xFF000000)>> 24);
+ buf_hold = (value & 0xFFFFFF) << 8;;
+ }
+#endif
/* Realign the source */
src = (const void *)i_src;
src += 3;
@@ -169,7 +206,7 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
*--dst = *--src;
}
return v_dst;
-#endif
}
+#endif /* CONFIG_OPT_LIB_FUNCTION */
EXPORT_SYMBOL(memmove);
#endif /* __HAVE_ARCH_MEMMOVE */
diff --git a/arch/microblaze/lib/memset.c b/arch/microblaze/lib/memset.c
index ecfb663e1fc1..834565d1607e 100644
--- a/arch/microblaze/lib/memset.c
+++ b/arch/microblaze/lib/memset.c
@@ -31,17 +31,30 @@
#include <linux/string.h>
#ifdef __HAVE_ARCH_MEMSET
+#ifndef CONFIG_OPT_LIB_FUNCTION
+void *memset(void *v_src, int c, __kernel_size_t n)
+{
+ char *src = v_src;
+
+ /* Truncate c to 8 bits */
+ c = (c & 0xFF);
+
+ /* Simple, byte oriented memset or the rest of count. */
+ while (n--)
+ *src++ = c;
+
+ return v_src;
+}
+#else /* CONFIG_OPT_LIB_FUNCTION */
void *memset(void *v_src, int c, __kernel_size_t n)
{
char *src = v_src;
-#ifdef CONFIG_OPT_LIB_FUNCTION
uint32_t *i_src;
uint32_t w32 = 0;
-#endif
+
/* Truncate c to 8 bits */
c = (c & 0xFF);
-#ifdef CONFIG_OPT_LIB_FUNCTION
if (unlikely(c)) {
/* Make a repeating word out of it */
w32 = c;
@@ -72,12 +85,13 @@ void *memset(void *v_src, int c, __kernel_size_t n)
src = (void *)i_src;
}
-#endif
+
/* Simple, byte oriented memset or the rest of count. */
while (n--)
*src++ = c;
return v_src;
}
+#endif /* CONFIG_OPT_LIB_FUNCTION */
EXPORT_SYMBOL(memset);
#endif /* __HAVE_ARCH_MEMSET */
diff --git a/arch/microblaze/lib/modsi3.S b/arch/microblaze/lib/modsi3.S
new file mode 100644
index 000000000000..84e0bee6e8c7
--- /dev/null
+++ b/arch/microblaze/lib/modsi3.S
@@ -0,0 +1,73 @@
+#include <linux/linkage.h>
+
+/*
+* modulo operation for 32 bit integers.
+* Input : op1 in Reg r5
+* op2 in Reg r6
+* Output: op1 mod op2 in Reg r3
+*/
+
+ .text
+ .globl __modsi3
+ .type __modsi3, @function
+ .ent __modsi3
+
+__modsi3:
+ .frame r1, 0, r15
+
+ addik r1, r1, -16
+ swi r28, r1, 0
+ swi r29, r1, 4
+ swi r30, r1, 8
+ swi r31, r1, 12
+
+ beqi r6, div_by_zero /* div_by_zero division error */
+ beqi r5, result_is_zero /* result is zero */
+ bgeid r5, r5_pos
+ /* get the sign of the result [ depends only on the first arg] */
+ add r28, r5, r0
+ rsubi r5, r5, 0 /* make r5 positive */
+r5_pos:
+ bgei r6, r6_pos
+ rsubi r6, r6, 0 /* make r6 positive */
+r6_pos:
+ addik r3, r0, 0 /* clear mod */
+ addik r30, r0, 0 /* clear div */
+ addik r29, r0, 32 /* initialize the loop count */
+/* first part try to find the first '1' in the r5 */
+div1:
+ add r5, r5, r5 /* left shift logical r5 */
+ bgeid r5, div1
+ addik r29, r29, -1
+div2:
+ /* left shift logical r5 get the '1' into the carry */
+ add r5, r5, r5
+ addc r3, r3, r3 /* move that bit into the mod register */
+ rsub r31, r6, r3 /* try to subtract (r30 a r6) */
+ blti r31, mod_too_small
+ /* move the r31 to mod since the result was positive */
+ or r3, r0, r31
+ addik r30, r30, 1
+mod_too_small:
+ addik r29, r29, -1
+ beqi r29, loop_end
+ add r30, r30, r30 /* shift in the '1' into div */
+ bri div2 /* div2 */
+loop_end:
+ bgei r28, return_here
+ brid return_here
+ rsubi r3, r3, 0 /* negate the result */
+div_by_zero:
+result_is_zero:
+ or r3, r0, r0 /* set result to 0 [both mod as well as div are 0] */
+return_here:
+/* restore values of csrs and that of r3 and the divisor and the dividend */
+ lwi r28, r1, 0
+ lwi r29, r1, 4
+ lwi r30, r1, 8
+ lwi r31, r1, 12
+ rtsd r15, 8
+ addik r1, r1, 16
+
+.size __modsi3, . - __modsi3
+.end __modsi3
diff --git a/arch/microblaze/lib/muldi3.S b/arch/microblaze/lib/muldi3.S
new file mode 100644
index 000000000000..ceeaa8c407f2
--- /dev/null
+++ b/arch/microblaze/lib/muldi3.S
@@ -0,0 +1,121 @@
+#include <linux/linkage.h>
+
+/*
+ * Multiply operation for 64 bit integers, for devices with hard multiply
+ * Input : Operand1[H] in Reg r5
+ * Operand1[L] in Reg r6
+ * Operand2[H] in Reg r7
+ * Operand2[L] in Reg r8
+ * Output: Result[H] in Reg r3
+ * Result[L] in Reg r4
+ *
+ * Explaination:
+ *
+ * Both the input numbers are divided into 16 bit number as follows
+ * op1 = A B C D
+ * op2 = E F G H
+ * result = D * H
+ * + (C * H + D * G) << 16
+ * + (B * H + C * G + D * F) << 32
+ * + (A * H + B * G + C * F + D * E) << 48
+ *
+ * Only 64 bits of the output are considered
+ */
+
+ .text
+ .globl __muldi3
+ .type __muldi3, @function
+ .ent __muldi3
+
+__muldi3:
+ addi r1, r1, -40
+
+/* Save the input operands on the caller's stack */
+ swi r5, r1, 44
+ swi r6, r1, 48
+ swi r7, r1, 52
+ swi r8, r1, 56
+
+/* Store all the callee saved registers */
+ sw r20, r1, r0
+ swi r21, r1, 4
+ swi r22, r1, 8
+ swi r23, r1, 12
+ swi r24, r1, 16
+ swi r25, r1, 20
+ swi r26, r1, 24
+ swi r27, r1, 28
+
+/* Load all the 16 bit values for A thru H */
+ lhui r20, r1, 44 /* A */
+ lhui r21, r1, 46 /* B */
+ lhui r22, r1, 48 /* C */
+ lhui r23, r1, 50 /* D */
+ lhui r24, r1, 52 /* E */
+ lhui r25, r1, 54 /* F */
+ lhui r26, r1, 56 /* G */
+ lhui r27, r1, 58 /* H */
+
+/* D * H ==> LSB of the result on stack ==> Store1 */
+ mul r9, r23, r27
+ swi r9, r1, 36 /* Pos2 and Pos3 */
+
+/* Hi (Store1) + C * H + D * G ==> Store2 ==> Pos1 and Pos2 */
+/* Store the carry generated in position 2 for Pos 3 */
+ lhui r11, r1, 36 /* Pos2 */
+ mul r9, r22, r27 /* C * H */
+ mul r10, r23, r26 /* D * G */
+ add r9, r9, r10
+ addc r12, r0, r0
+ add r9, r9, r11
+ addc r12, r12, r0 /* Store the Carry */
+ shi r9, r1, 36 /* Store Pos2 */
+ swi r9, r1, 32
+ lhui r11, r1, 32
+ shi r11, r1, 34 /* Store Pos1 */
+
+/* Hi (Store2) + B * H + C * G + D * F ==> Store3 ==> Pos0 and Pos1 */
+ mul r9, r21, r27 /* B * H */
+ mul r10, r22, r26 /* C * G */
+ mul r7, r23, r25 /* D * F */
+ add r9, r9, r11
+ add r9, r9, r10
+ add r9, r9, r7
+ swi r9, r1, 32 /* Pos0 and Pos1 */
+
+/* Hi (Store3) + A * H + B * G + C * F + D * E ==> Store3 ==> Pos0 */
+ lhui r11, r1, 32 /* Pos0 */
+ mul r9, r20, r27 /* A * H */
+ mul r10, r21, r26 /* B * G */
+ mul r7, r22, r25 /* C * F */
+ mul r8, r23, r24 /* D * E */
+ add r9, r9, r11
+ add r9, r9, r10
+ add r9, r9, r7
+ add r9, r9, r8
+ sext16 r9, r9 /* Sign extend the MSB */
+ shi r9, r1, 32
+
+/* Move results to r3 and r4 */
+ lhui r3, r1, 32
+ add r3, r3, r12
+ shi r3, r1, 32
+ lwi r3, r1, 32 /* Hi Part */
+ lwi r4, r1, 36 /* Lo Part */
+
+/* Restore Callee saved registers */
+ lw r20, r1, r0
+ lwi r21, r1, 4
+ lwi r22, r1, 8
+ lwi r23, r1, 12
+ lwi r24, r1, 16
+ lwi r25, r1, 20
+ lwi r26, r1, 24
+ lwi r27, r1, 28
+
+/* Restore Frame and return */
+ rtsd r15, 8
+ addi r1, r1, 40
+
+.size __muldi3, . - __muldi3
+.end __muldi3
diff --git a/arch/microblaze/lib/mulsi3.S b/arch/microblaze/lib/mulsi3.S
new file mode 100644
index 000000000000..90bd7b93afe6
--- /dev/null
+++ b/arch/microblaze/lib/mulsi3.S
@@ -0,0 +1,46 @@
+#include <linux/linkage.h>
+
+/*
+ * Multiply operation for 32 bit integers.
+ * Input : Operand1 in Reg r5
+ * Operand2 in Reg r6
+ * Output: Result [op1 * op2] in Reg r3
+ */
+ .text
+ .globl __mulsi3
+ .type __mulsi3, @function
+ .ent __mulsi3
+
+__mulsi3:
+ .frame r1, 0, r15
+ add r3, r0, r0
+ beqi r5, result_is_zero /* multiply by zero */
+ beqi r6, result_is_zero /* multiply by zero */
+ bgeid r5, r5_pos
+ xor r4, r5, r6 /* get the sign of the result */
+ rsubi r5, r5, 0 /* make r5 positive */
+r5_pos:
+ bgei r6, r6_pos
+ rsubi r6, r6, 0 /* make r6 positive */
+r6_pos:
+ bri l1
+l2:
+ add r5, r5, r5
+l1:
+ srl r6, r6
+ addc r7, r0, r0
+ beqi r7, l2
+ bneid r6, l2
+ add r3, r3, r5
+ blti r4, negateresult
+ rtsd r15, 8
+ nop
+negateresult:
+ rtsd r15, 8
+ rsub r3, r3, r0
+result_is_zero:
+ rtsd r15, 8
+ addi r3, r0, 0
+
+.size __mulsi3, . - __mulsi3
+.end __mulsi3
diff --git a/arch/microblaze/lib/udivsi3.S b/arch/microblaze/lib/udivsi3.S
new file mode 100644
index 000000000000..64cf57e4bb85
--- /dev/null
+++ b/arch/microblaze/lib/udivsi3.S
@@ -0,0 +1,84 @@
+#include <linux/linkage.h>
+
+/*
+* Unsigned divide operation.
+* Input : Divisor in Reg r5
+* Dividend in Reg r6
+* Output: Result in Reg r3
+*/
+
+ .text
+ .globl __udivsi3
+ .type __udivsi3, @function
+ .ent __udivsi3
+
+__udivsi3:
+
+ .frame r1, 0, r15
+
+ addik r1, r1, -12
+ swi r29, r1, 0
+ swi r30, r1, 4
+ swi r31, r1, 8
+
+ beqi r6, div_by_zero /* div_by_zero /* division error */
+ beqid r5, result_is_zero /* result is zero */
+ addik r30, r0, 0 /* clear mod */
+ addik r29, r0, 32 /* initialize the loop count */
+
+/* check if r6 and r5 are equal - if yes, return 1 */
+ rsub r18, r5, r6
+ beqid r18, return_here
+ addik r3, r0, 1
+
+/* check if (uns)r6 is greater than (uns)r5. in that case, just return 0 */
+ xor r18, r5, r6
+ bgeid r18, 16
+ add r3, r0, r0 /* we would anyways clear r3 */
+ blti r6, return_here /* r6[bit 31 = 1] hence is greater */
+ bri checkr6
+ rsub r18, r6, r5 /* microblazecmp */
+ blti r18, return_here
+
+/* if r6 [bit 31] is set, then return result as 1 */
+checkr6:
+ bgti r6, div0
+ brid return_here
+ addik r3, r0, 1
+
+/* first part try to find the first '1' in the r5 */
+div0:
+ blti r5, div2
+div1:
+ add r5, r5, r5 /* left shift logical r5 */
+ bgtid r5, div1
+ addik r29, r29, -1
+div2:
+/* left shift logical r5 get the '1' into the carry */
+ add r5, r5, r5
+ addc r30, r30, r30 /* move that bit into the mod register */
+ rsub r31, r6, r30 /* try to subtract (r30 a r6) */
+ blti r31, mod_too_small
+/* move the r31 to mod since the result was positive */
+ or r30, r0, r31
+ addik r3, r3, 1
+mod_too_small:
+ addik r29, r29, -1
+ beqi r29, loop_end
+ add r3, r3, r3 /* shift in the '1' into div */
+ bri div2 /* div2 */
+loop_end:
+ bri return_here
+div_by_zero:
+result_is_zero:
+ or r3, r0, r0 /* set result to 0 */
+return_here:
+/* restore values of csrs and that of r3 and the divisor and the dividend */
+ lwi r29, r1, 0
+ lwi r30, r1, 4
+ lwi r31, r1, 8
+ rtsd r15, 8
+ addik r1, r1, 12
+
+.size __udivsi3, . - __udivsi3
+.end __udivsi3
diff --git a/arch/microblaze/lib/umodsi3.S b/arch/microblaze/lib/umodsi3.S
new file mode 100644
index 000000000000..17d16bafae58
--- /dev/null
+++ b/arch/microblaze/lib/umodsi3.S
@@ -0,0 +1,86 @@
+#include <linux/linkage.h>
+
+/*
+ * Unsigned modulo operation for 32 bit integers.
+ * Input : op1 in Reg r5
+ * op2 in Reg r6
+ * Output: op1 mod op2 in Reg r3
+ */
+
+ .text
+ .globl __umodsi3
+ .type __umodsi3, @function
+ .ent __umodsi3
+
+__umodsi3:
+ .frame r1, 0, r15
+
+ addik r1, r1, -12
+ swi r29, r1, 0
+ swi r30, r1, 4
+ swi r31, r1, 8
+
+ beqi r6, div_by_zero /* div_by_zero - division error */
+ beqid r5, result_is_zero /* result is zero */
+ addik r3, r0, 0 /* clear div */
+ addik r30, r0, 0 /* clear mod */
+ addik r29, r0, 32 /* initialize the loop count */
+
+/* check if r6 and r5 are equal /* if yes, return 0 */
+ rsub r18, r5, r6
+ beqi r18, return_here
+
+/* check if (uns)r6 is greater than (uns)r5. in that case, just return r5 */
+ xor r18, r5, r6
+ bgeid r18, 16
+ addik r3, r5, 0
+ blti r6, return_here
+ bri $lcheckr6
+ rsub r18, r5, r6 /* microblazecmp */
+ bgti r18, return_here
+
+/* if r6 [bit 31] is set, then return result as r5-r6 */
+$lcheckr6:
+ bgtid r6, div0
+ addik r3, r0, 0
+ addik r18, r0, 0x7fffffff
+ and r5, r5, r18
+ and r6, r6, r18
+ brid return_here
+ rsub r3, r6, r5
+/* first part: try to find the first '1' in the r5 */
+div0:
+ blti r5, div2
+div1:
+ add r5, r5, r5 /* left shift logical r5 */
+ bgeid r5, div1
+ addik r29, r29, -1
+div2:
+ /* left shift logical r5 get the '1' into the carry */
+ add r5, r5, r5
+ addc r3, r3, r3 /* move that bit into the mod register */
+ rsub r31, r6, r3 /* try to subtract (r3 a r6) */
+ blti r31, mod_too_small
+ /* move the r31 to mod since the result was positive */
+ or r3, r0, r31
+ addik r30, r30, 1
+mod_too_small:
+ addik r29, r29, -1
+ beqi r29, loop_end
+ add r30, r30, r30 /* shift in the '1' into div */
+ bri div2 /* div2 */
+loop_end:
+ bri return_here
+div_by_zero:
+result_is_zero:
+ or r3, r0, r0 /* set result to 0 */
+return_here:
+/* restore values of csrs and that of r3 and the divisor and the dividend */
+ lwi r29, r1, 0
+ lwi r30, r1, 4
+ lwi r31, r1, 8
+ rtsd r15, 8
+ addik r1, r1, 12
+
+.size __umodsi3, . - __umodsi3
+.end __umodsi3
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/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index 55ef532f32be..e363615d6798 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -60,21 +60,6 @@ struct dma_map_ops *get_pci_dma_ops(void)
}
EXPORT_SYMBOL(get_pci_dma_ops);
-int pci_set_dma_mask(struct pci_dev *dev, u64 mask)
-{
- return dma_set_mask(&dev->dev, mask);
-}
-
-int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
-{
- int rc;
-
- rc = dma_set_mask(&dev->dev, mask);
- dev->dev.coherent_dma_mask = dev->dma_mask;
-
- return rc;
-}
-
struct pci_controller *pcibios_alloc_controller(struct device_node *dev)
{
struct pci_controller *phb;
@@ -1075,8 +1060,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;
-
/* Setup OF node pointer in archdata */
dev->dev.of_node = pci_device_to_OF_node(dev);
@@ -1086,8 +1069,8 @@ 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;
- sd->dma_data = (void *)PCI_DRAM_OFFSET;
+ set_dma_ops(&dev->dev, pci_dma_ops);
+ dev->dev.archdata.dma_data = (void *)PCI_DRAM_OFFSET;
/* Read default IRQs and fixup if necessary */
pci_read_irq_line(dev);
diff --git a/arch/microblaze/platform/generic/system.dts b/arch/microblaze/platform/generic/system.dts
index 2d5c41767cd0..3f85df2b73b3 100644
--- a/arch/microblaze/platform/generic/system.dts
+++ b/arch/microblaze/platform/generic/system.dts
@@ -85,6 +85,7 @@
xlnx,dynamic-bus-sizing = <0x1>;
xlnx,edge-is-positive = <0x1>;
xlnx,family = "virtex5";
+ xlnx,endianness = <0x1>;
xlnx,fpu-exception = <0x1>;
xlnx,fsl-data-size = <0x20>;
xlnx,fsl-exception = <0x0>;
@@ -218,6 +219,7 @@
#address-cells = <1>;
#size-cells = <1>;
compatible = "xlnx,compound";
+ ranges ;
ethernet@81c00000 {
compatible = "xlnx,xps-ll-temac-1.01.b", "xlnx,xps-ll-temac-1.00.a";
device_type = "network";
@@ -332,6 +334,7 @@
#address-cells = <1>;
#size-cells = <1>;
compatible = "xlnx,mpmc-4.02.a";
+ ranges ;
PIM3: sdma@84600180 {
compatible = "xlnx,ll-dma-1.00.a";
interrupt-parent = <&xps_intc_0>;
diff --git a/arch/microblaze/platform/platform.c b/arch/microblaze/platform/platform.c
index 5b89b58c5aed..b9529caa507a 100644
--- a/arch/microblaze/platform/platform.c
+++ b/arch/microblaze/platform/platform.c
@@ -17,9 +17,6 @@
static struct of_device_id xilinx_of_bus_ids[] __initdata = {
{ .compatible = "simple-bus", },
- { .compatible = "xlnx,plb-v46-1.00.a", },
- { .compatible = "xlnx,opb-v20-1.10.c", },
- { .compatible = "xlnx,opb-v20-1.10.b", },
{ .compatible = "xlnx,compound", },
{}
};
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 4c9f402295dd..67a2fa2caa49 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -4,18 +4,21 @@ config MIPS
select HAVE_GENERIC_DMA_COHERENT
select HAVE_IDE
select HAVE_OPROFILE
+ select HAVE_PERF_EVENTS
+ select PERF_USE_VMALLOC
select HAVE_ARCH_KGDB
select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_TRACE_MCOUNT_TEST
select HAVE_DYNAMIC_FTRACE
select HAVE_FTRACE_MCOUNT_RECORD
+ select HAVE_C_RECORDMCOUNT
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_KPROBES
select HAVE_KRETPROBES
select RTC_LIB if !MACH_LOONGSON
select GENERIC_ATOMIC64 if !64BIT
-
-mainmenu "Linux/MIPS Kernel Configuration"
+ select HAVE_DMA_ATTRS
+ select HAVE_DMA_API_DEBUG
menu "Machine selection"
@@ -693,6 +696,9 @@ config CAVIUM_OCTEON_REFERENCE_BOARD
select SWAP_IO_SPACE
select HW_HAS_PCI
select ARCH_SUPPORTS_MSI
+ select ZONE_DMA32
+ select USB_ARCH_HAS_OHCI
+ select USB_ARCH_HAS_EHCI
help
This option supports all of the Octeon reference boards from Cavium
Networks. It builds a kernel that dynamically determines the Octeon
@@ -1336,6 +1342,57 @@ config CPU_CAVIUM_OCTEON
can have up to 16 Mips64v2 cores and 8 integrated gigabit ethernets.
Full details can be found at http://www.caviumnetworks.com.
+config CPU_BMIPS3300
+ bool "BMIPS3300"
+ depends on SYS_HAS_CPU_BMIPS3300
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select SWAP_IO_SPACE
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select WEAK_ORDERING
+ help
+ Broadcom BMIPS3300 processors.
+
+config CPU_BMIPS4350
+ bool "BMIPS4350"
+ depends on SYS_HAS_CPU_BMIPS4350
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select SWAP_IO_SPACE
+ select SYS_SUPPORTS_SMP
+ select SYS_SUPPORTS_HOTPLUG_CPU
+ select WEAK_ORDERING
+ help
+ Broadcom BMIPS4350 ("VIPER") processors.
+
+config CPU_BMIPS4380
+ bool "BMIPS4380"
+ depends on SYS_HAS_CPU_BMIPS4380
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select SWAP_IO_SPACE
+ select SYS_SUPPORTS_SMP
+ select SYS_SUPPORTS_HOTPLUG_CPU
+ select WEAK_ORDERING
+ help
+ Broadcom BMIPS4380 processors.
+
+config CPU_BMIPS5000
+ bool "BMIPS5000"
+ depends on SYS_HAS_CPU_BMIPS5000
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select SWAP_IO_SPACE
+ select SYS_SUPPORTS_SMP
+ select SYS_SUPPORTS_HOTPLUG_CPU
+ select WEAK_ORDERING
+ help
+ Broadcom BMIPS5000 processors.
+
endchoice
if CPU_LOONGSON2F
@@ -1454,6 +1511,18 @@ config SYS_HAS_CPU_SB1
config SYS_HAS_CPU_CAVIUM_OCTEON
bool
+config SYS_HAS_CPU_BMIPS3300
+ bool
+
+config SYS_HAS_CPU_BMIPS4350
+ bool
+
+config SYS_HAS_CPU_BMIPS4380
+ bool
+
+config SYS_HAS_CPU_BMIPS5000
+ bool
+
#
# CPU may reorder R->R, R->W, W->R, W->W
# Reordering beyond LL and SC is handled in WEAK_REORDERING_BEYOND_LLSC
@@ -1930,6 +1999,14 @@ config NODES_SHIFT
default "6"
depends on NEED_MULTIPLE_NODES
+config HW_PERF_EVENTS
+ bool "Enable hardware performance counter support for perf events"
+ depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && CPU_MIPS32
+ default y
+ help
+ Enable hardware performance counter support for perf events. If
+ disabled, perf events will use software events only.
+
source "mm/Kconfig"
config SMP
@@ -2128,6 +2205,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
@@ -2196,10 +2280,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/Kconfig.debug b/arch/mips/Kconfig.debug
index 43dc27997730..f437cd1fafb8 100644
--- a/arch/mips/Kconfig.debug
+++ b/arch/mips/Kconfig.debug
@@ -67,6 +67,15 @@ config CMDLINE_OVERRIDE
Normally, you will choose 'N' here.
+config DEBUG_STACKOVERFLOW
+ bool "Check for stack overflows"
+ depends on DEBUG_KERNEL
+ help
+ This option will cause messages to be printed if free stack space
+ drops below a certain limit(2GB on MIPS). The debugging option
+ provides another way to check stack overflow happened on kernel mode
+ stack usually caused by nested interruption.
+
config DEBUG_STACK_USAGE
bool "Enable stack utilization instrumentation"
depends on DEBUG_KERNEL
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index f4a4b663ebb3..7c1102e41fe2 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -48,9 +48,6 @@ ifneq ($(SUBARCH),$(ARCH))
endif
endif
-ifndef CONFIG_FUNCTION_TRACER
-cflags-y := -ffunction-sections
-endif
ifdef CONFIG_FUNCTION_GRAPH_TRACER
ifndef KBUILD_MCOUNT_RA_ADDRESS
ifeq ($(call cc-option-yn,-mmcount-ra-address), y)
@@ -159,6 +156,7 @@ cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += $(call cc-option,-march=octeon) -Wa,--trap
ifeq (,$(findstring march=octeon, $(cflags-$(CONFIG_CPU_CAVIUM_OCTEON))))
cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += -Wa,-march=octeon
endif
+cflags-$(CONFIG_CAVIUM_CN63XXP1) += -Wa,-mfix-cn63xxp1
cflags-$(CONFIG_CPU_R4000_WORKAROUNDS) += $(call cc-option,-mfix-r4000,)
cflags-$(CONFIG_CPU_R4400_WORKAROUNDS) += $(call cc-option,-mfix-r4400,)
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/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/gpio.c b/arch/mips/ar7/gpio.c
index c32fbb57441a..425dfa5d6e12 100644
--- a/arch/mips/ar7/gpio.c
+++ b/arch/mips/ar7/gpio.c
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2007 Eugene Konev <ejka@openwrt.org>
- * Copyright (C) 2009 Florian Fainelli <florian@openwrt.org>
+ * Copyright (C) 2009-2010 Florian Fainelli <florian@openwrt.org>
*
* 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
@@ -37,6 +37,16 @@ static int ar7_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
return readl(gpio_in) & (1 << gpio);
}
+static int titan_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
+{
+ struct ar7_gpio_chip *gpch =
+ container_of(chip, struct ar7_gpio_chip, chip);
+ void __iomem *gpio_in0 = gpch->regs + TITAN_GPIO_INPUT_0;
+ void __iomem *gpio_in1 = gpch->regs + TITAN_GPIO_INPUT_1;
+
+ return readl(gpio >> 5 ? gpio_in1 : gpio_in0) & (1 << (gpio & 0x1f));
+}
+
static void ar7_gpio_set_value(struct gpio_chip *chip,
unsigned gpio, int value)
{
@@ -51,6 +61,21 @@ static void ar7_gpio_set_value(struct gpio_chip *chip,
writel(tmp, gpio_out);
}
+static void titan_gpio_set_value(struct gpio_chip *chip,
+ unsigned gpio, int value)
+{
+ struct ar7_gpio_chip *gpch =
+ container_of(chip, struct ar7_gpio_chip, chip);
+ void __iomem *gpio_out0 = gpch->regs + TITAN_GPIO_OUTPUT_0;
+ void __iomem *gpio_out1 = gpch->regs + TITAN_GPIO_OUTPUT_1;
+ unsigned tmp;
+
+ tmp = readl(gpio >> 5 ? gpio_out1 : gpio_out0) & ~(1 << (gpio & 0x1f));
+ if (value)
+ tmp |= 1 << (gpio & 0x1f);
+ writel(tmp, gpio >> 5 ? gpio_out1 : gpio_out0);
+}
+
static int ar7_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
{
struct ar7_gpio_chip *gpch =
@@ -62,6 +87,21 @@ static int ar7_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
return 0;
}
+static int titan_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
+{
+ struct ar7_gpio_chip *gpch =
+ container_of(chip, struct ar7_gpio_chip, chip);
+ void __iomem *gpio_dir0 = gpch->regs + TITAN_GPIO_DIR_0;
+ void __iomem *gpio_dir1 = gpch->regs + TITAN_GPIO_DIR_1;
+
+ if (gpio >= TITAN_GPIO_MAX)
+ return -EINVAL;
+
+ writel(readl(gpio >> 5 ? gpio_dir1 : gpio_dir0) | (1 << (gpio & 0x1f)),
+ gpio >> 5 ? gpio_dir1 : gpio_dir0);
+ return 0;
+}
+
static int ar7_gpio_direction_output(struct gpio_chip *chip,
unsigned gpio, int value)
{
@@ -75,6 +115,24 @@ static int ar7_gpio_direction_output(struct gpio_chip *chip,
return 0;
}
+static int titan_gpio_direction_output(struct gpio_chip *chip,
+ unsigned gpio, int value)
+{
+ struct ar7_gpio_chip *gpch =
+ container_of(chip, struct ar7_gpio_chip, chip);
+ void __iomem *gpio_dir0 = gpch->regs + TITAN_GPIO_DIR_0;
+ void __iomem *gpio_dir1 = gpch->regs + TITAN_GPIO_DIR_1;
+
+ if (gpio >= TITAN_GPIO_MAX)
+ return -EINVAL;
+
+ titan_gpio_set_value(chip, gpio, value);
+ writel(readl(gpio >> 5 ? gpio_dir1 : gpio_dir0) & ~(1 <<
+ (gpio & 0x1f)), gpio >> 5 ? gpio_dir1 : gpio_dir0);
+
+ return 0;
+}
+
static struct ar7_gpio_chip ar7_gpio_chip = {
.chip = {
.label = "ar7-gpio",
@@ -87,7 +145,19 @@ static struct ar7_gpio_chip ar7_gpio_chip = {
}
};
-int ar7_gpio_enable(unsigned gpio)
+static struct ar7_gpio_chip titan_gpio_chip = {
+ .chip = {
+ .label = "titan-gpio",
+ .direction_input = titan_gpio_direction_input,
+ .direction_output = titan_gpio_direction_output,
+ .set = titan_gpio_set_value,
+ .get = titan_gpio_get_value,
+ .base = 0,
+ .ngpio = TITAN_GPIO_MAX,
+ }
+};
+
+static inline int ar7_gpio_enable_ar7(unsigned gpio)
{
void __iomem *gpio_en = ar7_gpio_chip.regs + AR7_GPIO_ENABLE;
@@ -95,9 +165,26 @@ int ar7_gpio_enable(unsigned gpio)
return 0;
}
+
+static inline int ar7_gpio_enable_titan(unsigned gpio)
+{
+ void __iomem *gpio_en0 = titan_gpio_chip.regs + TITAN_GPIO_ENBL_0;
+ void __iomem *gpio_en1 = titan_gpio_chip.regs + TITAN_GPIO_ENBL_1;
+
+ writel(readl(gpio >> 5 ? gpio_en1 : gpio_en0) | (1 << (gpio & 0x1f)),
+ gpio >> 5 ? gpio_en1 : gpio_en0);
+
+ return 0;
+}
+
+int ar7_gpio_enable(unsigned gpio)
+{
+ return ar7_is_titan() ? ar7_gpio_enable_titan(gpio) :
+ ar7_gpio_enable_ar7(gpio);
+}
EXPORT_SYMBOL(ar7_gpio_enable);
-int ar7_gpio_disable(unsigned gpio)
+static inline int ar7_gpio_disable_ar7(unsigned gpio)
{
void __iomem *gpio_en = ar7_gpio_chip.regs + AR7_GPIO_ENABLE;
@@ -105,27 +192,159 @@ int ar7_gpio_disable(unsigned gpio)
return 0;
}
+
+static inline int ar7_gpio_disable_titan(unsigned gpio)
+{
+ void __iomem *gpio_en0 = titan_gpio_chip.regs + TITAN_GPIO_ENBL_0;
+ void __iomem *gpio_en1 = titan_gpio_chip.regs + TITAN_GPIO_ENBL_1;
+
+ writel(readl(gpio >> 5 ? gpio_en1 : gpio_en0) & ~(1 << (gpio & 0x1f)),
+ gpio >> 5 ? gpio_en1 : gpio_en0);
+
+ return 0;
+}
+
+int ar7_gpio_disable(unsigned gpio)
+{
+ return ar7_is_titan() ? ar7_gpio_disable_titan(gpio) :
+ ar7_gpio_disable_ar7(gpio);
+}
EXPORT_SYMBOL(ar7_gpio_disable);
-static int __init ar7_gpio_init(void)
+struct titan_gpio_cfg {
+ u32 reg;
+ u32 shift;
+ u32 func;
+};
+
+static struct titan_gpio_cfg titan_gpio_table[] = {
+ /* reg, start bit, mux value */
+ {4, 24, 1},
+ {4, 26, 1},
+ {4, 28, 1},
+ {4, 30, 1},
+ {5, 6, 1},
+ {5, 8, 1},
+ {5, 10, 1},
+ {5, 12, 1},
+ {7, 14, 3},
+ {7, 16, 3},
+ {7, 18, 3},
+ {7, 20, 3},
+ {7, 22, 3},
+ {7, 26, 3},
+ {7, 28, 3},
+ {7, 30, 3},
+ {8, 0, 3},
+ {8, 2, 3},
+ {8, 4, 3},
+ {8, 10, 3},
+ {8, 14, 3},
+ {8, 16, 3},
+ {8, 18, 3},
+ {8, 20, 3},
+ {9, 8, 3},
+ {9, 10, 3},
+ {9, 12, 3},
+ {9, 14, 3},
+ {9, 18, 3},
+ {9, 20, 3},
+ {9, 24, 3},
+ {9, 26, 3},
+ {9, 28, 3},
+ {9, 30, 3},
+ {10, 0, 3},
+ {10, 2, 3},
+ {10, 8, 3},
+ {10, 10, 3},
+ {10, 12, 3},
+ {10, 14, 3},
+ {13, 12, 3},
+ {13, 14, 3},
+ {13, 16, 3},
+ {13, 18, 3},
+ {13, 24, 3},
+ {13, 26, 3},
+ {13, 28, 3},
+ {13, 30, 3},
+ {14, 2, 3},
+ {14, 6, 3},
+ {14, 8, 3},
+ {14, 12, 3}
+};
+
+static int titan_gpio_pinsel(unsigned gpio)
+{
+ struct titan_gpio_cfg gpio_cfg;
+ u32 mux_status, pin_sel_reg, tmp;
+ void __iomem *pin_sel = (void __iomem *)KSEG1ADDR(AR7_REGS_PINSEL);
+
+ if (gpio >= ARRAY_SIZE(titan_gpio_table))
+ return -EINVAL;
+
+ gpio_cfg = titan_gpio_table[gpio];
+ pin_sel_reg = gpio_cfg.reg - 1;
+
+ mux_status = (readl(pin_sel + pin_sel_reg) >> gpio_cfg.shift) & 0x3;
+
+ /* Check the mux status */
+ if (!((mux_status == 0) || (mux_status == gpio_cfg.func)))
+ return 0;
+
+ /* Set the pin sel value */
+ tmp = readl(pin_sel + pin_sel_reg);
+ tmp |= ((gpio_cfg.func & 0x3) << gpio_cfg.shift);
+ writel(tmp, pin_sel + pin_sel_reg);
+
+ return 0;
+}
+
+/* Perform minimal Titan GPIO configuration */
+static void titan_gpio_init(void)
+{
+ unsigned i;
+
+ for (i = 44; i < 48; i++) {
+ titan_gpio_pinsel(i);
+ ar7_gpio_enable_titan(i);
+ titan_gpio_direction_input(&titan_gpio_chip.chip, i);
+ }
+}
+
+int __init ar7_gpio_init(void)
{
int ret;
+ struct ar7_gpio_chip *gpch;
+ unsigned size;
+
+ if (!ar7_is_titan()) {
+ gpch = &ar7_gpio_chip;
+ size = 0x10;
+ } else {
+ gpch = &titan_gpio_chip;
+ size = 0x1f;
+ }
- ar7_gpio_chip.regs = ioremap_nocache(AR7_REGS_GPIO,
+ gpch->regs = ioremap_nocache(AR7_REGS_GPIO,
AR7_REGS_GPIO + 0x10);
- if (!ar7_gpio_chip.regs) {
- printk(KERN_ERR "ar7-gpio: failed to ioremap regs\n");
+ if (!gpch->regs) {
+ printk(KERN_ERR "%s: failed to ioremap regs\n",
+ gpch->chip.label);
return -ENOMEM;
}
- ret = gpiochip_add(&ar7_gpio_chip.chip);
+ ret = gpiochip_add(&gpch->chip);
if (ret) {
- printk(KERN_ERR "ar7-gpio: failed to add gpiochip\n");
+ printk(KERN_ERR "%s: failed to add gpiochip\n",
+ gpch->chip.label);
return ret;
}
- printk(KERN_INFO "ar7-gpio: registered %d GPIOs\n",
- ar7_gpio_chip.chip.ngpio);
+ printk(KERN_INFO "%s: registered %d GPIOs\n",
+ gpch->chip.label, gpch->chip.ngpio);
+
+ if (ar7_is_titan())
+ titan_gpio_init();
+
return ret;
}
-arch_initcall(ar7_gpio_init);
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/ar7/platform.c b/arch/mips/ar7/platform.c
index 0da5b2b8dd88..7d2fab392327 100644
--- a/arch/mips/ar7/platform.c
+++ b/arch/mips/ar7/platform.c
@@ -357,6 +357,11 @@ static struct gpio_led default_leds[] = {
},
};
+static struct gpio_led titan_leds[] = {
+ { .name = "status", .gpio = 8, .active_low = 1, },
+ { .name = "wifi", .gpio = 13, .active_low = 1, },
+};
+
static struct gpio_led dsl502t_leds[] = {
{
.name = "status",
@@ -495,6 +500,9 @@ static void __init detect_leds(void)
} else if (strstr(prid, "DG834")) {
ar7_led_data.num_leds = ARRAY_SIZE(dg834g_leds);
ar7_led_data.leds = dg834g_leds;
+ } else if (strstr(prid, "CYWM") || strstr(prid, "CYWL")) {
+ ar7_led_data.num_leds = ARRAY_SIZE(titan_leds);
+ ar7_led_data.leds = titan_leds;
}
}
@@ -560,6 +568,51 @@ static int __init ar7_register_uarts(void)
return 0;
}
+static void __init titan_fixup_devices(void)
+{
+ /* Set vlynq0 data */
+ vlynq_low_data.reset_bit = 15;
+ vlynq_low_data.gpio_bit = 14;
+
+ /* Set vlynq1 data */
+ vlynq_high_data.reset_bit = 16;
+ vlynq_high_data.gpio_bit = 7;
+
+ /* Set vlynq0 resources */
+ vlynq_low_res[0].start = TITAN_REGS_VLYNQ0;
+ vlynq_low_res[0].end = TITAN_REGS_VLYNQ0 + 0xff;
+ vlynq_low_res[1].start = 33;
+ vlynq_low_res[1].end = 33;
+ vlynq_low_res[2].start = 0x0c000000;
+ vlynq_low_res[2].end = 0x0fffffff;
+ vlynq_low_res[3].start = 80;
+ vlynq_low_res[3].end = 111;
+
+ /* Set vlynq1 resources */
+ vlynq_high_res[0].start = TITAN_REGS_VLYNQ1;
+ vlynq_high_res[0].end = TITAN_REGS_VLYNQ1 + 0xff;
+ vlynq_high_res[1].start = 34;
+ vlynq_high_res[1].end = 34;
+ vlynq_high_res[2].start = 0x40000000;
+ vlynq_high_res[2].end = 0x43ffffff;
+ vlynq_high_res[3].start = 112;
+ vlynq_high_res[3].end = 143;
+
+ /* Set cpmac0 data */
+ cpmac_low_data.phy_mask = 0x40000000;
+
+ /* Set cpmac1 data */
+ cpmac_high_data.phy_mask = 0x80000000;
+
+ /* Set cpmac0 resources */
+ cpmac_low_res[0].start = TITAN_REGS_MAC0;
+ cpmac_low_res[0].end = TITAN_REGS_MAC0 + 0x7ff;
+
+ /* Set cpmac1 resources */
+ cpmac_high_res[0].start = TITAN_REGS_MAC1;
+ cpmac_high_res[0].end = TITAN_REGS_MAC1 + 0x7ff;
+}
+
static int __init ar7_register_devices(void)
{
void __iomem *bootcr;
@@ -574,6 +627,9 @@ static int __init ar7_register_devices(void)
if (res)
pr_warning("unable to register physmap-flash: %d\n", res);
+ if (ar7_is_titan())
+ titan_fixup_devices();
+
ar7_device_disable(vlynq_low_data.reset_bit);
res = platform_device_register(&vlynq_low);
if (res)
diff --git a/arch/mips/ar7/prom.c b/arch/mips/ar7/prom.c
index 52385790e5c1..23818d299127 100644
--- a/arch/mips/ar7/prom.c
+++ b/arch/mips/ar7/prom.c
@@ -246,6 +246,8 @@ void __init prom_init(void)
ar7_init_cmdline(fw_arg0, (char **)fw_arg1);
ar7_init_env((struct env_var *)fw_arg2);
console_config();
+
+ ar7_gpio_init();
}
#define PORT(offset) (KSEG1ADDR(AR7_REGS_UART0 + (offset * 4)))
diff --git a/arch/mips/ar7/setup.c b/arch/mips/ar7/setup.c
index 3a801d2cb6e5..f20b53e597c4 100644
--- a/arch/mips/ar7/setup.c
+++ b/arch/mips/ar7/setup.c
@@ -23,6 +23,7 @@
#include <asm/reboot.h>
#include <asm/mach-ar7/ar7.h>
#include <asm/mach-ar7/prom.h>
+#include <asm/mach-ar7/gpio.h>
static void ar7_machine_restart(char *command)
{
@@ -49,6 +50,8 @@ static void ar7_machine_power_off(void)
const char *get_system_type(void)
{
u16 chip_id = ar7_chip_id();
+ u16 titan_variant_id = titan_chip_id();
+
switch (chip_id) {
case AR7_CHIP_7100:
return "TI AR7 (TNETD7100)";
@@ -56,6 +59,17 @@ const char *get_system_type(void)
return "TI AR7 (TNETD7200)";
case AR7_CHIP_7300:
return "TI AR7 (TNETD7300)";
+ case AR7_CHIP_TITAN:
+ switch (titan_variant_id) {
+ case TITAN_CHIP_1050:
+ return "TI AR7 (TNETV1050)";
+ case TITAN_CHIP_1055:
+ return "TI AR7 (TNETV1055)";
+ case TITAN_CHIP_1056:
+ return "TI AR7 (TNETV1056)";
+ case TITAN_CHIP_1060:
+ return "TI AR7 (TNETV1060)";
+ }
default:
return "TI AR7 (unknown)";
}
diff --git a/arch/mips/bcm63xx/cpu.c b/arch/mips/bcm63xx/cpu.c
index cbb7caf86d77..7c7e4d4486ce 100644
--- a/arch/mips/bcm63xx/cpu.c
+++ b/arch/mips/bcm63xx/cpu.c
@@ -10,7 +10,9 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/cpu.h>
+#include <asm/cpu.h>
#include <asm/cpu-info.h>
+#include <asm/mipsregs.h>
#include <bcm63xx_cpu.h>
#include <bcm63xx_regs.h>
#include <bcm63xx_io.h>
@@ -296,26 +298,24 @@ void __init bcm63xx_cpu_init(void)
expected_cpu_id = 0;
switch (c->cputype) {
- /*
- * BCM6338 as the same PrId as BCM3302 see arch/mips/kernel/cpu-probe.c
- */
- case CPU_BCM3302:
- __cpu_name[cpu] = "Broadcom BCM6338";
- expected_cpu_id = BCM6338_CPU_ID;
- bcm63xx_regs_base = bcm96338_regs_base;
- bcm63xx_irqs = bcm96338_irqs;
+ case CPU_BMIPS3300:
+ if ((read_c0_prid() & 0xff00) == PRID_IMP_BMIPS3300_ALT) {
+ expected_cpu_id = BCM6348_CPU_ID;
+ bcm63xx_regs_base = bcm96348_regs_base;
+ bcm63xx_irqs = bcm96348_irqs;
+ } else {
+ __cpu_name[cpu] = "Broadcom BCM6338";
+ expected_cpu_id = BCM6338_CPU_ID;
+ bcm63xx_regs_base = bcm96338_regs_base;
+ bcm63xx_irqs = bcm96338_irqs;
+ }
break;
- case CPU_BCM6345:
+ case CPU_BMIPS32:
expected_cpu_id = BCM6345_CPU_ID;
bcm63xx_regs_base = bcm96345_regs_base;
bcm63xx_irqs = bcm96345_irqs;
break;
- case CPU_BCM6348:
- expected_cpu_id = BCM6348_CPU_ID;
- bcm63xx_regs_base = bcm96348_regs_base;
- bcm63xx_irqs = bcm96348_irqs;
- break;
- case CPU_BCM6358:
+ case CPU_BMIPS4350:
expected_cpu_id = BCM6358_CPU_ID;
bcm63xx_regs_base = bcm96358_regs_base;
bcm63xx_irqs = bcm96358_irqs;
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/cavium-octeon/Kconfig b/arch/mips/cavium-octeon/Kconfig
index 47323ca452dc..caae22858163 100644
--- a/arch/mips/cavium-octeon/Kconfig
+++ b/arch/mips/cavium-octeon/Kconfig
@@ -3,6 +3,17 @@ config CAVIUM_OCTEON_SPECIFIC_OPTIONS
depends on CPU_CAVIUM_OCTEON
default "y"
+config CAVIUM_CN63XXP1
+ bool "Enable CN63XXP1 errata worarounds"
+ depends on CAVIUM_OCTEON_SPECIFIC_OPTIONS
+ default "n"
+ help
+ The CN63XXP1 chip requires build time workarounds to
+ function reliably, select this option to enable them. These
+ workarounds will cause a slight decrease in performance on
+ non-CN63XXP1 hardware, so it is recommended to select "n"
+ unless it is known the workarounds are needed.
+
config CAVIUM_OCTEON_2ND_KERNEL
bool "Build the kernel to be used as a 2nd kernel on the same chip"
depends on CAVIUM_OCTEON_SPECIFIC_OPTIONS
@@ -87,3 +98,15 @@ config ARCH_SPARSEMEM_ENABLE
config CAVIUM_OCTEON_HELPER
def_bool y
depends on OCTEON_ETHERNET || PCI
+
+config IOMMU_HELPER
+ bool
+
+config NEED_SG_DMA_LENGTH
+ bool
+
+config SWIOTLB
+ def_bool y
+ depends on CPU_CAVIUM_OCTEON
+ select IOMMU_HELPER
+ select NEED_SG_DMA_LENGTH
diff --git a/arch/mips/cavium-octeon/csrc-octeon.c b/arch/mips/cavium-octeon/csrc-octeon.c
index b6847c8e0ddd..26bf71130bf8 100644
--- a/arch/mips/cavium-octeon/csrc-octeon.c
+++ b/arch/mips/cavium-octeon/csrc-octeon.c
@@ -4,14 +4,18 @@
* for more details.
*
* Copyright (C) 2007 by Ralf Baechle
+ * Copyright (C) 2009, 2010 Cavium Networks, Inc.
*/
#include <linux/clocksource.h>
#include <linux/init.h>
+#include <linux/smp.h>
+#include <asm/cpu-info.h>
#include <asm/time.h>
#include <asm/octeon/octeon.h>
#include <asm/octeon/cvmx-ipd-defs.h>
+#include <asm/octeon/cvmx-mio-defs.h>
/*
* Set the current core's cvmcount counter to the value of the
@@ -19,11 +23,23 @@
* on-line. This allows for a read from a local cpu register to
* access a synchronized counter.
*
+ * On CPU_CAVIUM_OCTEON2 the IPD_CLK_COUNT is scaled by rdiv/sdiv.
*/
void octeon_init_cvmcount(void)
{
unsigned long flags;
unsigned loops = 2;
+ u64 f = 0;
+ u64 rdiv = 0;
+ u64 sdiv = 0;
+ if (current_cpu_type() == CPU_CAVIUM_OCTEON2) {
+ union cvmx_mio_rst_boot rst_boot;
+ rst_boot.u64 = cvmx_read_csr(CVMX_MIO_RST_BOOT);
+ rdiv = rst_boot.s.c_mul; /* CPU clock */
+ sdiv = rst_boot.s.pnr_mul; /* I/O clock */
+ f = (0x8000000000000000ull / sdiv) * 2;
+ }
+
/* Clobber loops so GCC will not unroll the following while loop. */
asm("" : "+r" (loops));
@@ -33,8 +49,20 @@ void octeon_init_cvmcount(void)
* Loop several times so we are executing from the cache,
* which should give more deterministic timing.
*/
- while (loops--)
- write_c0_cvmcount(cvmx_read_csr(CVMX_IPD_CLK_COUNT));
+ while (loops--) {
+ u64 ipd_clk_count = cvmx_read_csr(CVMX_IPD_CLK_COUNT);
+ if (rdiv != 0) {
+ ipd_clk_count *= rdiv;
+ if (f != 0) {
+ asm("dmultu\t%[cnt],%[f]\n\t"
+ "mfhi\t%[cnt]"
+ : [cnt] "+r" (ipd_clk_count),
+ [f] "=r" (f)
+ : : "hi", "lo");
+ }
+ }
+ write_c0_cvmcount(ipd_clk_count);
+ }
local_irq_restore(flags);
}
@@ -77,7 +105,7 @@ unsigned long long notrace sched_clock(void)
void __init plat_time_init(void)
{
clocksource_mips.rating = 300;
- clocksource_set_clock(&clocksource_mips, mips_hpt_frequency);
+ clocksource_set_clock(&clocksource_mips, octeon_get_clock_rate());
clocksource_register(&clocksource_mips);
}
diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c
index d22b5a2d64f4..1abb66caaa1d 100644
--- a/arch/mips/cavium-octeon/dma-octeon.c
+++ b/arch/mips/cavium-octeon/dma-octeon.c
@@ -8,335 +8,342 @@
* Copyright (C) 2005 Ilya A. Volynets-Evenbakh <ilya@total-knowledge.com>
* swiped from i386, and cloned for MIPS by Geert, polished by Ralf.
* IP32 changes by Ilya.
- * Cavium Networks: Create new dma setup for Cavium Networks Octeon based on
- * the kernels original.
+ * Copyright (C) 2010 Cavium Networks, Inc.
*/
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/string.h>
#include <linux/dma-mapping.h>
-#include <linux/platform_device.h>
#include <linux/scatterlist.h>
+#include <linux/bootmem.h>
+#include <linux/swiotlb.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
-#include <linux/cache.h>
-#include <linux/io.h>
+#include <asm/bootinfo.h>
#include <asm/octeon/octeon.h>
+
+#ifdef CONFIG_PCI
+#include <asm/octeon/pci-octeon.h>
#include <asm/octeon/cvmx-npi-defs.h>
#include <asm/octeon/cvmx-pci-defs.h>
-#include <dma-coherence.h>
+static dma_addr_t octeon_hole_phys_to_dma(phys_addr_t paddr)
+{
+ if (paddr >= CVMX_PCIE_BAR1_PHYS_BASE && paddr < (CVMX_PCIE_BAR1_PHYS_BASE + CVMX_PCIE_BAR1_PHYS_SIZE))
+ return paddr - CVMX_PCIE_BAR1_PHYS_BASE + CVMX_PCIE_BAR1_RC_BASE;
+ else
+ return paddr;
+}
-#ifdef CONFIG_PCI
-#include <asm/octeon/pci-octeon.h>
-#endif
+static phys_addr_t octeon_hole_dma_to_phys(dma_addr_t daddr)
+{
+ if (daddr >= CVMX_PCIE_BAR1_RC_BASE)
+ return daddr + CVMX_PCIE_BAR1_PHYS_BASE - CVMX_PCIE_BAR1_RC_BASE;
+ else
+ return daddr;
+}
+
+static dma_addr_t octeon_gen1_phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+ if (paddr >= 0x410000000ull && paddr < 0x420000000ull)
+ paddr -= 0x400000000ull;
+ return octeon_hole_phys_to_dma(paddr);
+}
-#define BAR2_PCI_ADDRESS 0x8000000000ul
+static phys_addr_t octeon_gen1_dma_to_phys(struct device *dev, dma_addr_t daddr)
+{
+ daddr = octeon_hole_dma_to_phys(daddr);
-struct bar1_index_state {
- int16_t ref_count; /* Number of PCI mappings using this index */
- uint16_t address_bits; /* Upper bits of physical address. This is
- shifted 22 bits */
-};
+ if (daddr >= 0x10000000ull && daddr < 0x20000000ull)
+ daddr += 0x400000000ull;
-#ifdef CONFIG_PCI
-static DEFINE_RAW_SPINLOCK(bar1_lock);
-static struct bar1_index_state bar1_state[32];
-#endif
+ return daddr;
+}
-dma_addr_t octeon_map_dma_mem(struct device *dev, void *ptr, size_t size)
+static dma_addr_t octeon_big_phys_to_dma(struct device *dev, phys_addr_t paddr)
{
-#ifndef CONFIG_PCI
- /* Without PCI/PCIe this function can be called for Octeon internal
- devices such as USB. These devices all support 64bit addressing */
+ if (paddr >= 0x410000000ull && paddr < 0x420000000ull)
+ paddr -= 0x400000000ull;
+
+ /* Anything in the BAR1 hole or above goes via BAR2 */
+ if (paddr >= 0xf0000000ull)
+ paddr = OCTEON_BAR2_PCI_ADDRESS + paddr;
+
+ return paddr;
+}
+
+static phys_addr_t octeon_big_dma_to_phys(struct device *dev, dma_addr_t daddr)
+{
+ if (daddr >= OCTEON_BAR2_PCI_ADDRESS)
+ daddr -= OCTEON_BAR2_PCI_ADDRESS;
+
+ if (daddr >= 0x10000000ull && daddr < 0x20000000ull)
+ daddr += 0x400000000ull;
+ return daddr;
+}
+
+static dma_addr_t octeon_small_phys_to_dma(struct device *dev,
+ phys_addr_t paddr)
+{
+ if (paddr >= 0x410000000ull && paddr < 0x420000000ull)
+ paddr -= 0x400000000ull;
+
+ /* Anything not in the BAR1 range goes via BAR2 */
+ if (paddr >= octeon_bar1_pci_phys && paddr < octeon_bar1_pci_phys + 0x8000000ull)
+ paddr = paddr - octeon_bar1_pci_phys;
+ else
+ paddr = OCTEON_BAR2_PCI_ADDRESS + paddr;
+
+ return paddr;
+}
+
+static phys_addr_t octeon_small_dma_to_phys(struct device *dev,
+ dma_addr_t daddr)
+{
+ if (daddr >= OCTEON_BAR2_PCI_ADDRESS)
+ daddr -= OCTEON_BAR2_PCI_ADDRESS;
+ else
+ daddr += octeon_bar1_pci_phys;
+
+ if (daddr >= 0x10000000ull && daddr < 0x20000000ull)
+ daddr += 0x400000000ull;
+ return daddr;
+}
+
+#endif /* CONFIG_PCI */
+
+static dma_addr_t octeon_dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ dma_addr_t daddr = swiotlb_map_page(dev, page, offset, size,
+ direction, attrs);
mb();
- return virt_to_phys(ptr);
-#else
- unsigned long flags;
- uint64_t dma_mask;
- int64_t start_index;
- dma_addr_t result = -1;
- uint64_t physical = virt_to_phys(ptr);
- int64_t index;
+ return daddr;
+}
+
+static int octeon_dma_map_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction direction, struct dma_attrs *attrs)
+{
+ int r = swiotlb_map_sg_attrs(dev, sg, nents, direction, attrs);
mb();
- /*
- * Use the DMA masks to determine the allowed memory
- * region. For us it doesn't limit the actual memory, just the
- * address visible over PCI. Devices with limits need to use
- * lower indexed Bar1 entries.
- */
- if (dev) {
- dma_mask = dev->coherent_dma_mask;
- if (dev->dma_mask)
- dma_mask = *dev->dma_mask;
- } else {
- dma_mask = 0xfffffffful;
- }
+ return r;
+}
- /*
- * Platform devices, such as the internal USB, skip all
- * translation and use Octeon physical addresses directly.
- */
- if (!dev || dev->bus == &platform_bus_type)
- return physical;
+static void octeon_dma_sync_single_for_device(struct device *dev,
+ dma_addr_t dma_handle, size_t size, enum dma_data_direction direction)
+{
+ swiotlb_sync_single_for_device(dev, dma_handle, size, direction);
+ mb();
+}
- switch (octeon_dma_bar_type) {
- case OCTEON_DMA_BAR_TYPE_PCIE:
- if (unlikely(physical < (16ul << 10)))
- panic("dma_map_single: Not allowed to map first 16KB."
- " It interferes with BAR0 special area\n");
- else if ((physical + size >= (256ul << 20)) &&
- (physical < (512ul << 20)))
- panic("dma_map_single: Not allowed to map bootbus\n");
- else if ((physical + size >= 0x400000000ull) &&
- physical < 0x410000000ull)
- panic("dma_map_single: "
- "Attempt to map illegal memory address 0x%llx\n",
- physical);
- else if (physical >= 0x420000000ull)
- panic("dma_map_single: "
- "Attempt to map illegal memory address 0x%llx\n",
- physical);
- else if (physical >= CVMX_PCIE_BAR1_PHYS_BASE &&
- physical + size < (CVMX_PCIE_BAR1_PHYS_BASE + CVMX_PCIE_BAR1_PHYS_SIZE)) {
- result = physical - CVMX_PCIE_BAR1_PHYS_BASE + CVMX_PCIE_BAR1_RC_BASE;
-
- if (((result+size-1) & dma_mask) != result+size-1)
- panic("dma_map_single: Attempt to map address 0x%llx-0x%llx, which can't be accessed according to the dma mask 0x%llx\n",
- physical, physical+size-1, dma_mask);
- goto done;
- }
-
- /* The 2nd 256MB is mapped at 256<<20 instead of 0x410000000 */
- if ((physical >= 0x410000000ull) && physical < 0x420000000ull)
- result = physical - 0x400000000ull;
- else
- result = physical;
- if (((result+size-1) & dma_mask) != result+size-1)
- panic("dma_map_single: Attempt to map address "
- "0x%llx-0x%llx, which can't be accessed "
- "according to the dma mask 0x%llx\n",
- physical, physical+size-1, dma_mask);
- goto done;
+static void octeon_dma_sync_sg_for_device(struct device *dev,
+ struct scatterlist *sg, int nelems, enum dma_data_direction direction)
+{
+ swiotlb_sync_sg_for_device(dev, sg, nelems, direction);
+ mb();
+}
- case OCTEON_DMA_BAR_TYPE_BIG:
-#ifdef CONFIG_64BIT
- /* If the device supports 64bit addressing, then use BAR2 */
- if (dma_mask > BAR2_PCI_ADDRESS) {
- result = physical + BAR2_PCI_ADDRESS;
- goto done;
- }
-#endif
- if (unlikely(physical < (4ul << 10))) {
- panic("dma_map_single: Not allowed to map first 4KB. "
- "It interferes with BAR0 special area\n");
- } else if (physical < (256ul << 20)) {
- if (unlikely(physical + size > (256ul << 20)))
- panic("dma_map_single: Requested memory spans "
- "Bar0 0:256MB and bootbus\n");
- result = physical;
- goto done;
- } else if (unlikely(physical < (512ul << 20))) {
- panic("dma_map_single: Not allowed to map bootbus\n");
- } else if (physical < (2ul << 30)) {
- if (unlikely(physical + size > (2ul << 30)))
- panic("dma_map_single: Requested memory spans "
- "Bar0 512MB:2GB and BAR1\n");
- result = physical;
- goto done;
- } else if (physical < (2ul << 30) + (128 << 20)) {
- /* Fall through */
- } else if (physical <
- (4ul << 30) - (OCTEON_PCI_BAR1_HOLE_SIZE << 20)) {
- if (unlikely
- (physical + size >
- (4ul << 30) - (OCTEON_PCI_BAR1_HOLE_SIZE << 20)))
- panic("dma_map_single: Requested memory "
- "extends past Bar1 (4GB-%luMB)\n",
- OCTEON_PCI_BAR1_HOLE_SIZE);
- result = physical;
- goto done;
- } else if ((physical >= 0x410000000ull) &&
- (physical < 0x420000000ull)) {
- if (unlikely(physical + size > 0x420000000ull))
- panic("dma_map_single: Requested memory spans "
- "non existant memory\n");
- /* BAR0 fixed mapping 256MB:512MB ->
- * 16GB+256MB:16GB+512MB */
- result = physical - 0x400000000ull;
- goto done;
- } else {
- /* Continued below switch statement */
- }
- break;
+static void *octeon_dma_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t gfp)
+{
+ void *ret;
- case OCTEON_DMA_BAR_TYPE_SMALL:
-#ifdef CONFIG_64BIT
- /* If the device supports 64bit addressing, then use BAR2 */
- if (dma_mask > BAR2_PCI_ADDRESS) {
- result = physical + BAR2_PCI_ADDRESS;
- goto done;
- }
+ if (dma_alloc_from_coherent(dev, size, dma_handle, &ret))
+ return ret;
+
+ /* ignore region specifiers */
+ gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM);
+
+#ifdef CONFIG_ZONE_DMA
+ if (dev == NULL)
+ gfp |= __GFP_DMA;
+ else if (dev->coherent_dma_mask <= DMA_BIT_MASK(24))
+ gfp |= __GFP_DMA;
+ else
#endif
- /* Continued below switch statement */
- break;
+#ifdef CONFIG_ZONE_DMA32
+ if (dev->coherent_dma_mask <= DMA_BIT_MASK(32))
+ gfp |= __GFP_DMA32;
+ else
+#endif
+ ;
- default:
- panic("dma_map_single: Invalid octeon_dma_bar_type\n");
- }
+ /* Don't invoke OOM killer */
+ gfp |= __GFP_NORETRY;
- /* Don't allow mapping to span multiple Bar entries. The hardware guys
- won't guarantee that DMA across boards work */
- if (unlikely((physical >> 22) != ((physical + size - 1) >> 22)))
- panic("dma_map_single: "
- "Requested memory spans more than one Bar1 entry\n");
+ ret = swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
- if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG)
- start_index = 31;
- else if (unlikely(dma_mask < (1ul << 27)))
- start_index = (dma_mask >> 22);
- else
- start_index = 31;
-
- /* Only one processor can access the Bar register at once */
- raw_spin_lock_irqsave(&bar1_lock, flags);
-
- /* Look through Bar1 for existing mapping that will work */
- for (index = start_index; index >= 0; index--) {
- if ((bar1_state[index].address_bits == physical >> 22) &&
- (bar1_state[index].ref_count)) {
- /* An existing mapping will work, use it */
- bar1_state[index].ref_count++;
- if (unlikely(bar1_state[index].ref_count < 0))
- panic("dma_map_single: "
- "Bar1[%d] reference count overflowed\n",
- (int) index);
- result = (index << 22) | (physical & ((1 << 22) - 1));
- /* Large BAR1 is offset at 2GB */
- if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG)
- result += 2ul << 30;
- goto done_unlock;
- }
- }
+ mb();
- /* No existing mappings, look for a free entry */
- for (index = start_index; index >= 0; index--) {
- if (unlikely(bar1_state[index].ref_count == 0)) {
- union cvmx_pci_bar1_indexx bar1_index;
- /* We have a free entry, use it */
- bar1_state[index].ref_count = 1;
- bar1_state[index].address_bits = physical >> 22;
- bar1_index.u32 = 0;
- /* Address bits[35:22] sent to L2C */
- bar1_index.s.addr_idx = physical >> 22;
- /* Don't put PCI accesses in L2. */
- bar1_index.s.ca = 1;
- /* Endian Swap Mode */
- bar1_index.s.end_swp = 1;
- /* Set '1' when the selected address range is valid. */
- bar1_index.s.addr_v = 1;
- octeon_npi_write32(CVMX_NPI_PCI_BAR1_INDEXX(index),
- bar1_index.u32);
- /* An existing mapping will work, use it */
- result = (index << 22) | (physical & ((1 << 22) - 1));
- /* Large BAR1 is offset at 2GB */
- if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG)
- result += 2ul << 30;
- goto done_unlock;
- }
- }
+ return ret;
+}
- pr_err("dma_map_single: "
- "Can't find empty BAR1 index for physical mapping 0x%llx\n",
- (unsigned long long) physical);
+static void octeon_dma_free_coherent(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle)
+{
+ int order = get_order(size);
-done_unlock:
- raw_spin_unlock_irqrestore(&bar1_lock, flags);
-done:
- pr_debug("dma_map_single 0x%llx->0x%llx\n", physical, result);
- return result;
-#endif
+ if (dma_release_from_coherent(dev, order, vaddr))
+ return;
+
+ swiotlb_free_coherent(dev, size, vaddr, dma_handle);
}
-void octeon_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
+static dma_addr_t octeon_unity_phys_to_dma(struct device *dev, phys_addr_t paddr)
{
-#ifndef CONFIG_PCI
- /*
- * Without PCI/PCIe this function can be called for Octeon internal
- * devices such as USB. These devices all support 64bit addressing.
- */
- return;
-#else
- unsigned long flags;
- uint64_t index;
+ return paddr;
+}
+static phys_addr_t octeon_unity_dma_to_phys(struct device *dev, dma_addr_t daddr)
+{
+ return daddr;
+}
+
+struct octeon_dma_map_ops {
+ struct dma_map_ops dma_map_ops;
+ dma_addr_t (*phys_to_dma)(struct device *dev, phys_addr_t paddr);
+ phys_addr_t (*dma_to_phys)(struct device *dev, dma_addr_t daddr);
+};
+
+dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+ struct octeon_dma_map_ops *ops = container_of(get_dma_ops(dev),
+ struct octeon_dma_map_ops,
+ dma_map_ops);
+
+ return ops->phys_to_dma(dev, paddr);
+}
+EXPORT_SYMBOL(phys_to_dma);
+
+phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
+{
+ struct octeon_dma_map_ops *ops = container_of(get_dma_ops(dev),
+ struct octeon_dma_map_ops,
+ dma_map_ops);
+
+ return ops->dma_to_phys(dev, daddr);
+}
+EXPORT_SYMBOL(dma_to_phys);
+
+static struct octeon_dma_map_ops octeon_linear_dma_map_ops = {
+ .dma_map_ops = {
+ .alloc_coherent = octeon_dma_alloc_coherent,
+ .free_coherent = octeon_dma_free_coherent,
+ .map_page = octeon_dma_map_page,
+ .unmap_page = swiotlb_unmap_page,
+ .map_sg = octeon_dma_map_sg,
+ .unmap_sg = swiotlb_unmap_sg_attrs,
+ .sync_single_for_cpu = swiotlb_sync_single_for_cpu,
+ .sync_single_for_device = octeon_dma_sync_single_for_device,
+ .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
+ .sync_sg_for_device = octeon_dma_sync_sg_for_device,
+ .mapping_error = swiotlb_dma_mapping_error,
+ .dma_supported = swiotlb_dma_supported
+ },
+ .phys_to_dma = octeon_unity_phys_to_dma,
+ .dma_to_phys = octeon_unity_dma_to_phys
+};
+
+char *octeon_swiotlb;
+
+void __init plat_swiotlb_setup(void)
+{
+ int i;
+ phys_t max_addr;
+ phys_t addr_size;
+ size_t swiotlbsize;
+ unsigned long swiotlb_nslabs;
+
+ max_addr = 0;
+ addr_size = 0;
+
+ for (i = 0 ; i < boot_mem_map.nr_map; i++) {
+ struct boot_mem_map_entry *e = &boot_mem_map.map[i];
+ if (e->type != BOOT_MEM_RAM)
+ continue;
+
+ /* These addresses map low for PCI. */
+ if (e->addr > 0x410000000ull)
+ continue;
+
+ addr_size += e->size;
+
+ if (max_addr < e->addr + e->size)
+ max_addr = e->addr + e->size;
+
+ }
+
+ swiotlbsize = PAGE_SIZE;
+
+#ifdef CONFIG_PCI
/*
- * Platform devices, such as the internal USB, skip all
- * translation and use Octeon physical addresses directly.
+ * For OCTEON_DMA_BAR_TYPE_SMALL, size the iotlb at 1/4 memory
+ * size to a maximum of 64MB
*/
- if (dev->bus == &platform_bus_type)
- return;
+ if (OCTEON_IS_MODEL(OCTEON_CN31XX)
+ || OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2)) {
+ swiotlbsize = addr_size / 4;
+ if (swiotlbsize > 64 * (1<<20))
+ swiotlbsize = 64 * (1<<20);
+ } else if (max_addr > 0xf0000000ul) {
+ /*
+ * Otherwise only allocate a big iotlb if there is
+ * memory past the BAR1 hole.
+ */
+ swiotlbsize = 64 * (1<<20);
+ }
+#endif
+ swiotlb_nslabs = swiotlbsize >> IO_TLB_SHIFT;
+ swiotlb_nslabs = ALIGN(swiotlb_nslabs, IO_TLB_SEGSIZE);
+ swiotlbsize = swiotlb_nslabs << IO_TLB_SHIFT;
+
+ octeon_swiotlb = alloc_bootmem_low_pages(swiotlbsize);
+ swiotlb_init_with_tbl(octeon_swiotlb, swiotlb_nslabs, 1);
+
+ mips_dma_map_ops = &octeon_linear_dma_map_ops.dma_map_ops;
+}
+
+#ifdef CONFIG_PCI
+static struct octeon_dma_map_ops _octeon_pci_dma_map_ops = {
+ .dma_map_ops = {
+ .alloc_coherent = octeon_dma_alloc_coherent,
+ .free_coherent = octeon_dma_free_coherent,
+ .map_page = octeon_dma_map_page,
+ .unmap_page = swiotlb_unmap_page,
+ .map_sg = octeon_dma_map_sg,
+ .unmap_sg = swiotlb_unmap_sg_attrs,
+ .sync_single_for_cpu = swiotlb_sync_single_for_cpu,
+ .sync_single_for_device = octeon_dma_sync_single_for_device,
+ .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
+ .sync_sg_for_device = octeon_dma_sync_sg_for_device,
+ .mapping_error = swiotlb_dma_mapping_error,
+ .dma_supported = swiotlb_dma_supported
+ },
+};
+
+struct dma_map_ops *octeon_pci_dma_map_ops;
+
+void __init octeon_pci_dma_init(void)
+{
switch (octeon_dma_bar_type) {
case OCTEON_DMA_BAR_TYPE_PCIE:
- /* Nothing to do, all mappings are static */
- goto done;
-
+ _octeon_pci_dma_map_ops.phys_to_dma = octeon_gen1_phys_to_dma;
+ _octeon_pci_dma_map_ops.dma_to_phys = octeon_gen1_dma_to_phys;
+ break;
case OCTEON_DMA_BAR_TYPE_BIG:
-#ifdef CONFIG_64BIT
- /* Nothing to do for addresses using BAR2 */
- if (dma_addr >= BAR2_PCI_ADDRESS)
- goto done;
-#endif
- if (unlikely(dma_addr < (4ul << 10)))
- panic("dma_unmap_single: Unexpect DMA address 0x%llx\n",
- dma_addr);
- else if (dma_addr < (2ul << 30))
- /* Nothing to do for addresses using BAR0 */
- goto done;
- else if (dma_addr < (2ul << 30) + (128ul << 20))
- /* Need to unmap, fall through */
- index = (dma_addr - (2ul << 30)) >> 22;
- else if (dma_addr <
- (4ul << 30) - (OCTEON_PCI_BAR1_HOLE_SIZE << 20))
- goto done; /* Nothing to do for the rest of BAR1 */
- else
- panic("dma_unmap_single: Unexpect DMA address 0x%llx\n",
- dma_addr);
- /* Continued below switch statement */
+ _octeon_pci_dma_map_ops.phys_to_dma = octeon_big_phys_to_dma;
+ _octeon_pci_dma_map_ops.dma_to_phys = octeon_big_dma_to_phys;
break;
-
case OCTEON_DMA_BAR_TYPE_SMALL:
-#ifdef CONFIG_64BIT
- /* Nothing to do for addresses using BAR2 */
- if (dma_addr >= BAR2_PCI_ADDRESS)
- goto done;
-#endif
- index = dma_addr >> 22;
- /* Continued below switch statement */
+ _octeon_pci_dma_map_ops.phys_to_dma = octeon_small_phys_to_dma;
+ _octeon_pci_dma_map_ops.dma_to_phys = octeon_small_dma_to_phys;
break;
-
default:
- panic("dma_unmap_single: Invalid octeon_dma_bar_type\n");
+ BUG();
}
-
- if (unlikely(index > 31))
- panic("dma_unmap_single: "
- "Attempt to unmap an invalid address (0x%llx)\n",
- dma_addr);
-
- raw_spin_lock_irqsave(&bar1_lock, flags);
- bar1_state[index].ref_count--;
- if (bar1_state[index].ref_count == 0)
- octeon_npi_write32(CVMX_NPI_PCI_BAR1_INDEXX(index), 0);
- else if (unlikely(bar1_state[index].ref_count < 0))
- panic("dma_unmap_single: Bar1[%u] reference count < 0\n",
- (int) index);
- raw_spin_unlock_irqrestore(&bar1_lock, flags);
-done:
- pr_debug("dma_unmap_single 0x%llx\n", dma_addr);
- return;
-#endif
+ octeon_pci_dma_map_ops = &_octeon_pci_dma_map_ops.dma_map_ops;
}
+#endif /* CONFIG_PCI */
diff --git a/arch/mips/cavium-octeon/executive/cvmx-l2c.c b/arch/mips/cavium-octeon/executive/cvmx-l2c.c
index 6abe56f1e097..d38246e33ddb 100644
--- a/arch/mips/cavium-octeon/executive/cvmx-l2c.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-l2c.c
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
@@ -26,8 +26,8 @@
***********************license end**************************************/
/*
- * Implementation of the Level 2 Cache (L2C) control, measurement, and
- * debugging facilities.
+ * Implementation of the Level 2 Cache (L2C) control,
+ * measurement, and debugging facilities.
*/
#include <asm/octeon/cvmx.h>
@@ -42,13 +42,7 @@
* if multiple applications or operating systems are running, then it
* is up to the user program to coordinate between them.
*/
-static cvmx_spinlock_t cvmx_l2c_spinlock;
-
-static inline int l2_size_half(void)
-{
- uint64_t val = cvmx_read_csr(CVMX_L2D_FUS3);
- return !!(val & (1ull << 34));
-}
+cvmx_spinlock_t cvmx_l2c_spinlock;
int cvmx_l2c_get_core_way_partition(uint32_t core)
{
@@ -58,6 +52,9 @@ int cvmx_l2c_get_core_way_partition(uint32_t core)
if (core >= cvmx_octeon_num_cores())
return -1;
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX))
+ return cvmx_read_csr(CVMX_L2C_WPAR_PPX(core)) & 0xffff;
+
/*
* Use the lower two bits of the coreNumber to determine the
* bit offset of the UMSK[] field in the L2C_SPAR register.
@@ -71,17 +68,13 @@ int cvmx_l2c_get_core_way_partition(uint32_t core)
switch (core & 0xC) {
case 0x0:
- return (cvmx_read_csr(CVMX_L2C_SPAR0) & (0xFF << field)) >>
- field;
+ return (cvmx_read_csr(CVMX_L2C_SPAR0) & (0xFF << field)) >> field;
case 0x4:
- return (cvmx_read_csr(CVMX_L2C_SPAR1) & (0xFF << field)) >>
- field;
+ return (cvmx_read_csr(CVMX_L2C_SPAR1) & (0xFF << field)) >> field;
case 0x8:
- return (cvmx_read_csr(CVMX_L2C_SPAR2) & (0xFF << field)) >>
- field;
+ return (cvmx_read_csr(CVMX_L2C_SPAR2) & (0xFF << field)) >> field;
case 0xC:
- return (cvmx_read_csr(CVMX_L2C_SPAR3) & (0xFF << field)) >>
- field;
+ return (cvmx_read_csr(CVMX_L2C_SPAR3) & (0xFF << field)) >> field;
}
return 0;
}
@@ -95,48 +88,50 @@ int cvmx_l2c_set_core_way_partition(uint32_t core, uint32_t mask)
mask &= valid_mask;
- /* A UMSK setting which blocks all L2C Ways is an error. */
- if (mask == valid_mask)
+ /* A UMSK setting which blocks all L2C Ways is an error on some chips */
+ if (mask == valid_mask && !OCTEON_IS_MODEL(OCTEON_CN63XX))
return -1;
/* Validate the core number */
if (core >= cvmx_octeon_num_cores())
return -1;
- /* Check to make sure current mask & new mask don't block all ways */
- if (((mask | cvmx_l2c_get_core_way_partition(core)) & valid_mask) ==
- valid_mask)
- return -1;
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+ cvmx_write_csr(CVMX_L2C_WPAR_PPX(core), mask);
+ return 0;
+ }
- /* Use the lower two bits of core to determine the bit offset of the
+ /*
+ * Use the lower two bits of core to determine the bit offset of the
* UMSK[] field in the L2C_SPAR register.
*/
field = (core & 0x3) * 8;
- /* Assign the new mask setting to the UMSK[] field in the appropriate
+ /*
+ * Assign the new mask setting to the UMSK[] field in the appropriate
* L2C_SPAR register based on the core_num.
*
*/
switch (core & 0xC) {
case 0x0:
cvmx_write_csr(CVMX_L2C_SPAR0,
- (cvmx_read_csr(CVMX_L2C_SPAR0) &
- ~(0xFF << field)) | mask << field);
+ (cvmx_read_csr(CVMX_L2C_SPAR0) & ~(0xFF << field)) |
+ mask << field);
break;
case 0x4:
cvmx_write_csr(CVMX_L2C_SPAR1,
- (cvmx_read_csr(CVMX_L2C_SPAR1) &
- ~(0xFF << field)) | mask << field);
+ (cvmx_read_csr(CVMX_L2C_SPAR1) & ~(0xFF << field)) |
+ mask << field);
break;
case 0x8:
cvmx_write_csr(CVMX_L2C_SPAR2,
- (cvmx_read_csr(CVMX_L2C_SPAR2) &
- ~(0xFF << field)) | mask << field);
+ (cvmx_read_csr(CVMX_L2C_SPAR2) & ~(0xFF << field)) |
+ mask << field);
break;
case 0xC:
cvmx_write_csr(CVMX_L2C_SPAR3,
- (cvmx_read_csr(CVMX_L2C_SPAR3) &
- ~(0xFF << field)) | mask << field);
+ (cvmx_read_csr(CVMX_L2C_SPAR3) & ~(0xFF << field)) |
+ mask << field);
break;
}
return 0;
@@ -146,84 +141,137 @@ int cvmx_l2c_set_hw_way_partition(uint32_t mask)
{
uint32_t valid_mask;
- valid_mask = 0xff;
-
- if (OCTEON_IS_MODEL(OCTEON_CN58XX) || OCTEON_IS_MODEL(OCTEON_CN38XX)) {
- if (l2_size_half())
- valid_mask = 0xf;
- } else if (l2_size_half())
- valid_mask = 0x3;
-
+ valid_mask = (0x1 << cvmx_l2c_get_num_assoc()) - 1;
mask &= valid_mask;
- /* A UMSK setting which blocks all L2C Ways is an error. */
- if (mask == valid_mask)
- return -1;
- /* Check to make sure current mask & new mask don't block all ways */
- if (((mask | cvmx_l2c_get_hw_way_partition()) & valid_mask) ==
- valid_mask)
+ /* A UMSK setting which blocks all L2C Ways is an error on some chips */
+ if (mask == valid_mask && !OCTEON_IS_MODEL(OCTEON_CN63XX))
return -1;
- cvmx_write_csr(CVMX_L2C_SPAR4,
- (cvmx_read_csr(CVMX_L2C_SPAR4) & ~0xFF) | mask);
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX))
+ cvmx_write_csr(CVMX_L2C_WPAR_IOBX(0), mask);
+ else
+ cvmx_write_csr(CVMX_L2C_SPAR4,
+ (cvmx_read_csr(CVMX_L2C_SPAR4) & ~0xFF) | mask);
return 0;
}
int cvmx_l2c_get_hw_way_partition(void)
{
- return cvmx_read_csr(CVMX_L2C_SPAR4) & (0xFF);
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX))
+ return cvmx_read_csr(CVMX_L2C_WPAR_IOBX(0)) & 0xffff;
+ else
+ return cvmx_read_csr(CVMX_L2C_SPAR4) & (0xFF);
}
void cvmx_l2c_config_perf(uint32_t counter, enum cvmx_l2c_event event,
uint32_t clear_on_read)
{
- union cvmx_l2c_pfctl pfctl;
+ if (OCTEON_IS_MODEL(OCTEON_CN5XXX) || OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
+ union cvmx_l2c_pfctl pfctl;
- pfctl.u64 = cvmx_read_csr(CVMX_L2C_PFCTL);
+ pfctl.u64 = cvmx_read_csr(CVMX_L2C_PFCTL);
- switch (counter) {
- case 0:
- pfctl.s.cnt0sel = event;
- pfctl.s.cnt0ena = 1;
- if (!cvmx_octeon_is_pass1())
+ switch (counter) {
+ case 0:
+ pfctl.s.cnt0sel = event;
+ pfctl.s.cnt0ena = 1;
pfctl.s.cnt0rdclr = clear_on_read;
- break;
- case 1:
- pfctl.s.cnt1sel = event;
- pfctl.s.cnt1ena = 1;
- if (!cvmx_octeon_is_pass1())
+ break;
+ case 1:
+ pfctl.s.cnt1sel = event;
+ pfctl.s.cnt1ena = 1;
pfctl.s.cnt1rdclr = clear_on_read;
- break;
- case 2:
- pfctl.s.cnt2sel = event;
- pfctl.s.cnt2ena = 1;
- if (!cvmx_octeon_is_pass1())
+ break;
+ case 2:
+ pfctl.s.cnt2sel = event;
+ pfctl.s.cnt2ena = 1;
pfctl.s.cnt2rdclr = clear_on_read;
- break;
- case 3:
- default:
- pfctl.s.cnt3sel = event;
- pfctl.s.cnt3ena = 1;
- if (!cvmx_octeon_is_pass1())
+ break;
+ case 3:
+ default:
+ pfctl.s.cnt3sel = event;
+ pfctl.s.cnt3ena = 1;
pfctl.s.cnt3rdclr = clear_on_read;
- break;
- }
+ break;
+ }
- cvmx_write_csr(CVMX_L2C_PFCTL, pfctl.u64);
+ cvmx_write_csr(CVMX_L2C_PFCTL, pfctl.u64);
+ } else {
+ union cvmx_l2c_tadx_prf l2c_tadx_prf;
+ int tad;
+
+ cvmx_dprintf("L2C performance counter events are different for this chip, mapping 'event' to cvmx_l2c_tad_event_t\n");
+ if (clear_on_read)
+ cvmx_dprintf("L2C counters don't support clear on read for this chip\n");
+
+ l2c_tadx_prf.u64 = cvmx_read_csr(CVMX_L2C_TADX_PRF(0));
+
+ switch (counter) {
+ case 0:
+ l2c_tadx_prf.s.cnt0sel = event;
+ break;
+ case 1:
+ l2c_tadx_prf.s.cnt1sel = event;
+ break;
+ case 2:
+ l2c_tadx_prf.s.cnt2sel = event;
+ break;
+ default:
+ case 3:
+ l2c_tadx_prf.s.cnt3sel = event;
+ break;
+ }
+ for (tad = 0; tad < CVMX_L2C_TADS; tad++)
+ cvmx_write_csr(CVMX_L2C_TADX_PRF(tad),
+ l2c_tadx_prf.u64);
+ }
}
uint64_t cvmx_l2c_read_perf(uint32_t counter)
{
switch (counter) {
case 0:
- return cvmx_read_csr(CVMX_L2C_PFC0);
+ if (OCTEON_IS_MODEL(OCTEON_CN5XXX) || OCTEON_IS_MODEL(OCTEON_CN3XXX))
+ return cvmx_read_csr(CVMX_L2C_PFC0);
+ else {
+ uint64_t counter = 0;
+ int tad;
+ for (tad = 0; tad < CVMX_L2C_TADS; tad++)
+ counter += cvmx_read_csr(CVMX_L2C_TADX_PFC0(tad));
+ return counter;
+ }
case 1:
- return cvmx_read_csr(CVMX_L2C_PFC1);
+ if (OCTEON_IS_MODEL(OCTEON_CN5XXX) || OCTEON_IS_MODEL(OCTEON_CN3XXX))
+ return cvmx_read_csr(CVMX_L2C_PFC1);
+ else {
+ uint64_t counter = 0;
+ int tad;
+ for (tad = 0; tad < CVMX_L2C_TADS; tad++)
+ counter += cvmx_read_csr(CVMX_L2C_TADX_PFC1(tad));
+ return counter;
+ }
case 2:
- return cvmx_read_csr(CVMX_L2C_PFC2);
+ if (OCTEON_IS_MODEL(OCTEON_CN5XXX) || OCTEON_IS_MODEL(OCTEON_CN3XXX))
+ return cvmx_read_csr(CVMX_L2C_PFC2);
+ else {
+ uint64_t counter = 0;
+ int tad;
+ for (tad = 0; tad < CVMX_L2C_TADS; tad++)
+ counter += cvmx_read_csr(CVMX_L2C_TADX_PFC2(tad));
+ return counter;
+ }
case 3:
default:
- return cvmx_read_csr(CVMX_L2C_PFC3);
+ if (OCTEON_IS_MODEL(OCTEON_CN5XXX) || OCTEON_IS_MODEL(OCTEON_CN3XXX))
+ return cvmx_read_csr(CVMX_L2C_PFC3);
+ else {
+ uint64_t counter = 0;
+ int tad;
+ for (tad = 0; tad < CVMX_L2C_TADS; tad++)
+ counter += cvmx_read_csr(CVMX_L2C_TADX_PFC3(tad));
+ return counter;
+ }
}
}
@@ -240,7 +288,7 @@ static void fault_in(uint64_t addr, int len)
volatile char dummy;
/*
* Adjust addr and length so we get all cache lines even for
- * small ranges spanning two cache lines
+ * small ranges spanning two cache lines.
*/
len += addr & CVMX_CACHE_LINE_MASK;
addr &= ~CVMX_CACHE_LINE_MASK;
@@ -259,67 +307,100 @@ static void fault_in(uint64_t addr, int len)
int cvmx_l2c_lock_line(uint64_t addr)
{
- int retval = 0;
- union cvmx_l2c_dbg l2cdbg;
- union cvmx_l2c_lckbase lckbase;
- union cvmx_l2c_lckoff lckoff;
- union cvmx_l2t_err l2t_err;
- l2cdbg.u64 = 0;
- lckbase.u64 = 0;
- lckoff.u64 = 0;
-
- cvmx_spinlock_lock(&cvmx_l2c_spinlock);
-
- /* Clear l2t error bits if set */
- l2t_err.u64 = cvmx_read_csr(CVMX_L2T_ERR);
- l2t_err.s.lckerr = 1;
- l2t_err.s.lckerr2 = 1;
- cvmx_write_csr(CVMX_L2T_ERR, l2t_err.u64);
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+ int shift = CVMX_L2C_TAG_ADDR_ALIAS_SHIFT;
+ uint64_t assoc = cvmx_l2c_get_num_assoc();
+ uint64_t tag = addr >> shift;
+ uint64_t index = CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, cvmx_l2c_address_to_index(addr) << CVMX_L2C_IDX_ADDR_SHIFT);
+ uint64_t way;
+ union cvmx_l2c_tadx_tag l2c_tadx_tag;
+
+ CVMX_CACHE_LCKL2(CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, addr), 0);
+
+ /* Make sure we were able to lock the line */
+ for (way = 0; way < assoc; way++) {
+ CVMX_CACHE_LTGL2I(index | (way << shift), 0);
+ /* make sure CVMX_L2C_TADX_TAG is updated */
+ CVMX_SYNC;
+ l2c_tadx_tag.u64 = cvmx_read_csr(CVMX_L2C_TADX_TAG(0));
+ if (l2c_tadx_tag.s.valid && l2c_tadx_tag.s.tag == tag)
+ break;
+ }
- addr &= ~CVMX_CACHE_LINE_MASK;
+ /* Check if a valid line is found */
+ if (way >= assoc) {
+ /* cvmx_dprintf("ERROR: cvmx_l2c_lock_line: line not found for locking at 0x%llx address\n", (unsigned long long)addr); */
+ return -1;
+ }
- /* Set this core as debug core */
- l2cdbg.s.ppnum = cvmx_get_core_num();
- CVMX_SYNC;
- cvmx_write_csr(CVMX_L2C_DBG, l2cdbg.u64);
- cvmx_read_csr(CVMX_L2C_DBG);
-
- lckoff.s.lck_offset = 0; /* Only lock 1 line at a time */
- cvmx_write_csr(CVMX_L2C_LCKOFF, lckoff.u64);
- cvmx_read_csr(CVMX_L2C_LCKOFF);
-
- if (((union cvmx_l2c_cfg) (cvmx_read_csr(CVMX_L2C_CFG))).s.idxalias) {
- int alias_shift =
- CVMX_L2C_IDX_ADDR_SHIFT + 2 * CVMX_L2_SET_BITS - 1;
- uint64_t addr_tmp =
- addr ^ (addr & ((1 << alias_shift) - 1)) >>
- CVMX_L2_SET_BITS;
- lckbase.s.lck_base = addr_tmp >> 7;
+ /* Check if lock bit is not set */
+ if (!l2c_tadx_tag.s.lock) {
+ /* cvmx_dprintf("ERROR: cvmx_l2c_lock_line: Not able to lock at 0x%llx address\n", (unsigned long long)addr); */
+ return -1;
+ }
+ return way;
} else {
- lckbase.s.lck_base = addr >> 7;
- }
+ int retval = 0;
+ union cvmx_l2c_dbg l2cdbg;
+ union cvmx_l2c_lckbase lckbase;
+ union cvmx_l2c_lckoff lckoff;
+ union cvmx_l2t_err l2t_err;
- lckbase.s.lck_ena = 1;
- cvmx_write_csr(CVMX_L2C_LCKBASE, lckbase.u64);
- cvmx_read_csr(CVMX_L2C_LCKBASE); /* Make sure it gets there */
+ cvmx_spinlock_lock(&cvmx_l2c_spinlock);
- fault_in(addr, CVMX_CACHE_LINE_SIZE);
+ l2cdbg.u64 = 0;
+ lckbase.u64 = 0;
+ lckoff.u64 = 0;
- lckbase.s.lck_ena = 0;
- cvmx_write_csr(CVMX_L2C_LCKBASE, lckbase.u64);
- cvmx_read_csr(CVMX_L2C_LCKBASE); /* Make sure it gets there */
+ /* Clear l2t error bits if set */
+ l2t_err.u64 = cvmx_read_csr(CVMX_L2T_ERR);
+ l2t_err.s.lckerr = 1;
+ l2t_err.s.lckerr2 = 1;
+ cvmx_write_csr(CVMX_L2T_ERR, l2t_err.u64);
- /* Stop being debug core */
- cvmx_write_csr(CVMX_L2C_DBG, 0);
- cvmx_read_csr(CVMX_L2C_DBG);
+ addr &= ~CVMX_CACHE_LINE_MASK;
- l2t_err.u64 = cvmx_read_csr(CVMX_L2T_ERR);
- if (l2t_err.s.lckerr || l2t_err.s.lckerr2)
- retval = 1; /* We were unable to lock the line */
+ /* Set this core as debug core */
+ l2cdbg.s.ppnum = cvmx_get_core_num();
+ CVMX_SYNC;
+ cvmx_write_csr(CVMX_L2C_DBG, l2cdbg.u64);
+ cvmx_read_csr(CVMX_L2C_DBG);
+
+ lckoff.s.lck_offset = 0; /* Only lock 1 line at a time */
+ cvmx_write_csr(CVMX_L2C_LCKOFF, lckoff.u64);
+ cvmx_read_csr(CVMX_L2C_LCKOFF);
+
+ if (((union cvmx_l2c_cfg)(cvmx_read_csr(CVMX_L2C_CFG))).s.idxalias) {
+ int alias_shift = CVMX_L2C_IDX_ADDR_SHIFT + 2 * CVMX_L2_SET_BITS - 1;
+ uint64_t addr_tmp = addr ^ (addr & ((1 << alias_shift) - 1)) >> CVMX_L2_SET_BITS;
+ lckbase.s.lck_base = addr_tmp >> 7;
+ } else {
+ lckbase.s.lck_base = addr >> 7;
+ }
- cvmx_spinlock_unlock(&cvmx_l2c_spinlock);
+ lckbase.s.lck_ena = 1;
+ cvmx_write_csr(CVMX_L2C_LCKBASE, lckbase.u64);
+ /* Make sure it gets there */
+ cvmx_read_csr(CVMX_L2C_LCKBASE);
- return retval;
+ fault_in(addr, CVMX_CACHE_LINE_SIZE);
+
+ lckbase.s.lck_ena = 0;
+ cvmx_write_csr(CVMX_L2C_LCKBASE, lckbase.u64);
+ /* Make sure it gets there */
+ cvmx_read_csr(CVMX_L2C_LCKBASE);
+
+ /* Stop being debug core */
+ cvmx_write_csr(CVMX_L2C_DBG, 0);
+ cvmx_read_csr(CVMX_L2C_DBG);
+
+ l2t_err.u64 = cvmx_read_csr(CVMX_L2T_ERR);
+ if (l2t_err.s.lckerr || l2t_err.s.lckerr2)
+ retval = 1; /* We were unable to lock the line */
+
+ cvmx_spinlock_unlock(&cvmx_l2c_spinlock);
+ return retval;
+ }
}
int cvmx_l2c_lock_mem_region(uint64_t start, uint64_t len)
@@ -336,7 +417,6 @@ int cvmx_l2c_lock_mem_region(uint64_t start, uint64_t len)
start += CVMX_CACHE_LINE_SIZE;
len -= CVMX_CACHE_LINE_SIZE;
}
-
return retval;
}
@@ -344,80 +424,73 @@ void cvmx_l2c_flush(void)
{
uint64_t assoc, set;
uint64_t n_assoc, n_set;
- union cvmx_l2c_dbg l2cdbg;
-
- cvmx_spinlock_lock(&cvmx_l2c_spinlock);
- l2cdbg.u64 = 0;
- if (!OCTEON_IS_MODEL(OCTEON_CN30XX))
- l2cdbg.s.ppnum = cvmx_get_core_num();
- l2cdbg.s.finv = 1;
- n_set = CVMX_L2_SETS;
- n_assoc = l2_size_half() ? (CVMX_L2_ASSOC / 2) : CVMX_L2_ASSOC;
- for (set = 0; set < n_set; set++) {
- for (assoc = 0; assoc < n_assoc; assoc++) {
- l2cdbg.s.set = assoc;
- /* Enter debug mode, and make sure all other
- ** writes complete before we enter debug
- ** mode */
- CVMX_SYNCW;
- cvmx_write_csr(CVMX_L2C_DBG, l2cdbg.u64);
- cvmx_read_csr(CVMX_L2C_DBG);
-
- CVMX_PREPARE_FOR_STORE(CVMX_ADD_SEG
- (CVMX_MIPS_SPACE_XKPHYS,
- set * CVMX_CACHE_LINE_SIZE), 0);
- CVMX_SYNCW; /* Push STF out to L2 */
- /* Exit debug mode */
- CVMX_SYNC;
- cvmx_write_csr(CVMX_L2C_DBG, 0);
- cvmx_read_csr(CVMX_L2C_DBG);
+ n_set = cvmx_l2c_get_num_sets();
+ n_assoc = cvmx_l2c_get_num_assoc();
+
+ if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
+ uint64_t address;
+ /* These may look like constants, but they aren't... */
+ int assoc_shift = CVMX_L2C_TAG_ADDR_ALIAS_SHIFT;
+ int set_shift = CVMX_L2C_IDX_ADDR_SHIFT;
+ for (set = 0; set < n_set; set++) {
+ for (assoc = 0; assoc < n_assoc; assoc++) {
+ address = CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS,
+ (assoc << assoc_shift) | (set << set_shift));
+ CVMX_CACHE_WBIL2I(address, 0);
+ }
}
+ } else {
+ for (set = 0; set < n_set; set++)
+ for (assoc = 0; assoc < n_assoc; assoc++)
+ cvmx_l2c_flush_line(assoc, set);
}
-
- cvmx_spinlock_unlock(&cvmx_l2c_spinlock);
}
+
int cvmx_l2c_unlock_line(uint64_t address)
{
- int assoc;
- union cvmx_l2c_tag tag;
- union cvmx_l2c_dbg l2cdbg;
- uint32_t tag_addr;
- uint32_t index = cvmx_l2c_address_to_index(address);
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+ int assoc;
+ union cvmx_l2c_tag tag;
+ uint32_t tag_addr;
+ uint32_t index = cvmx_l2c_address_to_index(address);
+
+ tag_addr = ((address >> CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) & ((1 << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) - 1));
+
+ /*
+ * For 63XX, we can flush a line by using the physical
+ * address directly, so finding the cache line used by
+ * the address is only required to provide the proper
+ * return value for the function.
+ */
+ for (assoc = 0; assoc < CVMX_L2_ASSOC; assoc++) {
+ tag = cvmx_l2c_get_tag(assoc, index);
+
+ if (tag.s.V && (tag.s.addr == tag_addr)) {
+ CVMX_CACHE_WBIL2(CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, address), 0);
+ return tag.s.L;
+ }
+ }
+ } else {
+ int assoc;
+ union cvmx_l2c_tag tag;
+ uint32_t tag_addr;
- cvmx_spinlock_lock(&cvmx_l2c_spinlock);
- /* Compute portion of address that is stored in tag */
- tag_addr =
- ((address >> CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) &
- ((1 << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) - 1));
- for (assoc = 0; assoc < CVMX_L2_ASSOC; assoc++) {
- tag = cvmx_get_l2c_tag(assoc, index);
+ uint32_t index = cvmx_l2c_address_to_index(address);
- if (tag.s.V && (tag.s.addr == tag_addr)) {
- l2cdbg.u64 = 0;
- l2cdbg.s.ppnum = cvmx_get_core_num();
- l2cdbg.s.set = assoc;
- l2cdbg.s.finv = 1;
+ /* Compute portion of address that is stored in tag */
+ tag_addr = ((address >> CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) & ((1 << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) - 1));
+ for (assoc = 0; assoc < CVMX_L2_ASSOC; assoc++) {
+ tag = cvmx_l2c_get_tag(assoc, index);
- CVMX_SYNC;
- /* Enter debug mode */
- cvmx_write_csr(CVMX_L2C_DBG, l2cdbg.u64);
- cvmx_read_csr(CVMX_L2C_DBG);
-
- CVMX_PREPARE_FOR_STORE(CVMX_ADD_SEG
- (CVMX_MIPS_SPACE_XKPHYS,
- address), 0);
- CVMX_SYNC;
- /* Exit debug mode */
- cvmx_write_csr(CVMX_L2C_DBG, 0);
- cvmx_read_csr(CVMX_L2C_DBG);
- cvmx_spinlock_unlock(&cvmx_l2c_spinlock);
- return tag.s.L;
+ if (tag.s.V && (tag.s.addr == tag_addr)) {
+ cvmx_l2c_flush_line(assoc, index);
+ return tag.s.L;
+ }
}
}
- cvmx_spinlock_unlock(&cvmx_l2c_spinlock);
return 0;
}
@@ -445,48 +518,49 @@ union __cvmx_l2c_tag {
uint64_t u64;
struct cvmx_l2c_tag_cn50xx {
uint64_t reserved:40;
- uint64_t V:1; /* Line valid */
- uint64_t D:1; /* Line dirty */
- uint64_t L:1; /* Line locked */
- uint64_t U:1; /* Use, LRU eviction */
+ uint64_t V:1; /* Line valid */
+ uint64_t D:1; /* Line dirty */
+ uint64_t L:1; /* Line locked */
+ uint64_t U:1; /* Use, LRU eviction */
uint64_t addr:20; /* Phys mem addr (33..14) */
} cn50xx;
struct cvmx_l2c_tag_cn30xx {
uint64_t reserved:41;
- uint64_t V:1; /* Line valid */
- uint64_t D:1; /* Line dirty */
- uint64_t L:1; /* Line locked */
- uint64_t U:1; /* Use, LRU eviction */
+ uint64_t V:1; /* Line valid */
+ uint64_t D:1; /* Line dirty */
+ uint64_t L:1; /* Line locked */
+ uint64_t U:1; /* Use, LRU eviction */
uint64_t addr:19; /* Phys mem addr (33..15) */
} cn30xx;
struct cvmx_l2c_tag_cn31xx {
uint64_t reserved:42;
- uint64_t V:1; /* Line valid */
- uint64_t D:1; /* Line dirty */
- uint64_t L:1; /* Line locked */
- uint64_t U:1; /* Use, LRU eviction */
+ uint64_t V:1; /* Line valid */
+ uint64_t D:1; /* Line dirty */
+ uint64_t L:1; /* Line locked */
+ uint64_t U:1; /* Use, LRU eviction */
uint64_t addr:18; /* Phys mem addr (33..16) */
} cn31xx;
struct cvmx_l2c_tag_cn38xx {
uint64_t reserved:43;
- uint64_t V:1; /* Line valid */
- uint64_t D:1; /* Line dirty */
- uint64_t L:1; /* Line locked */
- uint64_t U:1; /* Use, LRU eviction */
+ uint64_t V:1; /* Line valid */
+ uint64_t D:1; /* Line dirty */
+ uint64_t L:1; /* Line locked */
+ uint64_t U:1; /* Use, LRU eviction */
uint64_t addr:17; /* Phys mem addr (33..17) */
} cn38xx;
struct cvmx_l2c_tag_cn58xx {
uint64_t reserved:44;
- uint64_t V:1; /* Line valid */
- uint64_t D:1; /* Line dirty */
- uint64_t L:1; /* Line locked */
- uint64_t U:1; /* Use, LRU eviction */
+ uint64_t V:1; /* Line valid */
+ uint64_t D:1; /* Line dirty */
+ uint64_t L:1; /* Line locked */
+ uint64_t U:1; /* Use, LRU eviction */
uint64_t addr:16; /* Phys mem addr (33..18) */
} cn58xx;
struct cvmx_l2c_tag_cn58xx cn56xx; /* 2048 sets */
struct cvmx_l2c_tag_cn31xx cn52xx; /* 512 sets */
};
+
/**
* @INTERNAL
* Function to read a L2C tag. This code make the current core
@@ -503,7 +577,7 @@ union __cvmx_l2c_tag {
static union __cvmx_l2c_tag __read_l2_tag(uint64_t assoc, uint64_t index)
{
- uint64_t debug_tag_addr = (((1ULL << 63) | (index << 7)) + 96);
+ uint64_t debug_tag_addr = CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, (index << 7) + 96);
uint64_t core = cvmx_get_core_num();
union __cvmx_l2c_tag tag_val;
uint64_t dbg_addr = CVMX_L2C_DBG;
@@ -512,12 +586,15 @@ static union __cvmx_l2c_tag __read_l2_tag(uint64_t assoc, uint64_t index)
union cvmx_l2c_dbg debug_val;
debug_val.u64 = 0;
/*
- * For low core count parts, the core number is always small enough
- * to stay in the correct field and not set any reserved bits.
+ * For low core count parts, the core number is always small
+ * enough to stay in the correct field and not set any
+ * reserved bits.
*/
debug_val.s.ppnum = core;
debug_val.s.l2t = 1;
debug_val.s.set = assoc;
+
+ local_irq_save(flags);
/*
* Make sure core is quiet (no prefetches, etc.) before
* entering debug mode.
@@ -526,112 +603,139 @@ static union __cvmx_l2c_tag __read_l2_tag(uint64_t assoc, uint64_t index)
/* Flush L1 to make sure debug load misses L1 */
CVMX_DCACHE_INVALIDATE;
- local_irq_save(flags);
-
/*
* The following must be done in assembly as when in debug
* mode all data loads from L2 return special debug data, not
- * normal memory contents. Also, interrupts must be
- * disabled, since if an interrupt occurs while in debug mode
- * the ISR will get debug data from all its memory reads
- * instead of the contents of memory
+ * normal memory contents. Also, interrupts must be disabled,
+ * since if an interrupt occurs while in debug mode the ISR
+ * will get debug data from all its memory * reads instead of
+ * the contents of memory.
*/
- asm volatile (".set push \n"
- " .set mips64 \n"
- " .set noreorder \n"
- /* Enter debug mode, wait for store */
- " sd %[dbg_val], 0(%[dbg_addr]) \n"
- " ld $0, 0(%[dbg_addr]) \n"
- /* Read L2C tag data */
- " ld %[tag_val], 0(%[tag_addr]) \n"
- /* Exit debug mode, wait for store */
- " sd $0, 0(%[dbg_addr]) \n"
- " ld $0, 0(%[dbg_addr]) \n"
- /* Invalidate dcache to discard debug data */
- " cache 9, 0($0) \n"
- " .set pop" :
- [tag_val] "=r"(tag_val.u64) : [dbg_addr] "r"(dbg_addr),
- [dbg_val] "r"(debug_val.u64),
- [tag_addr] "r"(debug_tag_addr) : "memory");
+ asm volatile (
+ ".set push\n\t"
+ ".set mips64\n\t"
+ ".set noreorder\n\t"
+ "sd %[dbg_val], 0(%[dbg_addr])\n\t" /* Enter debug mode, wait for store */
+ "ld $0, 0(%[dbg_addr])\n\t"
+ "ld %[tag_val], 0(%[tag_addr])\n\t" /* Read L2C tag data */
+ "sd $0, 0(%[dbg_addr])\n\t" /* Exit debug mode, wait for store */
+ "ld $0, 0(%[dbg_addr])\n\t"
+ "cache 9, 0($0)\n\t" /* Invalidate dcache to discard debug data */
+ ".set pop"
+ : [tag_val] "=r" (tag_val)
+ : [dbg_addr] "r" (dbg_addr), [dbg_val] "r" (debug_val), [tag_addr] "r" (debug_tag_addr)
+ : "memory");
local_irq_restore(flags);
- return tag_val;
+ return tag_val;
}
+
union cvmx_l2c_tag cvmx_l2c_get_tag(uint32_t association, uint32_t index)
{
- union __cvmx_l2c_tag tmp_tag;
union cvmx_l2c_tag tag;
tag.u64 = 0;
if ((int)association >= cvmx_l2c_get_num_assoc()) {
- cvmx_dprintf
- ("ERROR: cvmx_get_l2c_tag association out of range\n");
+ cvmx_dprintf("ERROR: cvmx_l2c_get_tag association out of range\n");
return tag;
}
if ((int)index >= cvmx_l2c_get_num_sets()) {
- cvmx_dprintf("ERROR: cvmx_get_l2c_tag "
- "index out of range (arg: %d, max: %d\n",
- index, cvmx_l2c_get_num_sets());
+ cvmx_dprintf("ERROR: cvmx_l2c_get_tag index out of range (arg: %d, max: %d)\n",
+ (int)index, cvmx_l2c_get_num_sets());
return tag;
}
- /* __read_l2_tag is intended for internal use only */
- tmp_tag = __read_l2_tag(association, index);
-
- /*
- * Convert all tag structure types to generic version, as it
- * can represent all models.
- */
- if (OCTEON_IS_MODEL(OCTEON_CN58XX) || OCTEON_IS_MODEL(OCTEON_CN56XX)) {
- tag.s.V = tmp_tag.cn58xx.V;
- tag.s.D = tmp_tag.cn58xx.D;
- tag.s.L = tmp_tag.cn58xx.L;
- tag.s.U = tmp_tag.cn58xx.U;
- tag.s.addr = tmp_tag.cn58xx.addr;
- } else if (OCTEON_IS_MODEL(OCTEON_CN38XX)) {
- tag.s.V = tmp_tag.cn38xx.V;
- tag.s.D = tmp_tag.cn38xx.D;
- tag.s.L = tmp_tag.cn38xx.L;
- tag.s.U = tmp_tag.cn38xx.U;
- tag.s.addr = tmp_tag.cn38xx.addr;
- } else if (OCTEON_IS_MODEL(OCTEON_CN31XX)
- || OCTEON_IS_MODEL(OCTEON_CN52XX)) {
- tag.s.V = tmp_tag.cn31xx.V;
- tag.s.D = tmp_tag.cn31xx.D;
- tag.s.L = tmp_tag.cn31xx.L;
- tag.s.U = tmp_tag.cn31xx.U;
- tag.s.addr = tmp_tag.cn31xx.addr;
- } else if (OCTEON_IS_MODEL(OCTEON_CN30XX)) {
- tag.s.V = tmp_tag.cn30xx.V;
- tag.s.D = tmp_tag.cn30xx.D;
- tag.s.L = tmp_tag.cn30xx.L;
- tag.s.U = tmp_tag.cn30xx.U;
- tag.s.addr = tmp_tag.cn30xx.addr;
- } else if (OCTEON_IS_MODEL(OCTEON_CN50XX)) {
- tag.s.V = tmp_tag.cn50xx.V;
- tag.s.D = tmp_tag.cn50xx.D;
- tag.s.L = tmp_tag.cn50xx.L;
- tag.s.U = tmp_tag.cn50xx.U;
- tag.s.addr = tmp_tag.cn50xx.addr;
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+ union cvmx_l2c_tadx_tag l2c_tadx_tag;
+ uint64_t address = CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS,
+ (association << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) |
+ (index << CVMX_L2C_IDX_ADDR_SHIFT));
+ /*
+ * Use L2 cache Index load tag cache instruction, as
+ * hardware loads the virtual tag for the L2 cache
+ * block with the contents of L2C_TAD0_TAG
+ * register.
+ */
+ CVMX_CACHE_LTGL2I(address, 0);
+ CVMX_SYNC; /* make sure CVMX_L2C_TADX_TAG is updated */
+ l2c_tadx_tag.u64 = cvmx_read_csr(CVMX_L2C_TADX_TAG(0));
+
+ tag.s.V = l2c_tadx_tag.s.valid;
+ tag.s.D = l2c_tadx_tag.s.dirty;
+ tag.s.L = l2c_tadx_tag.s.lock;
+ tag.s.U = l2c_tadx_tag.s.use;
+ tag.s.addr = l2c_tadx_tag.s.tag;
} else {
- cvmx_dprintf("Unsupported OCTEON Model in %s\n", __func__);
+ union __cvmx_l2c_tag tmp_tag;
+ /* __read_l2_tag is intended for internal use only */
+ tmp_tag = __read_l2_tag(association, index);
+
+ /*
+ * Convert all tag structure types to generic version,
+ * as it can represent all models.
+ */
+ if (OCTEON_IS_MODEL(OCTEON_CN58XX) || OCTEON_IS_MODEL(OCTEON_CN56XX)) {
+ tag.s.V = tmp_tag.cn58xx.V;
+ tag.s.D = tmp_tag.cn58xx.D;
+ tag.s.L = tmp_tag.cn58xx.L;
+ tag.s.U = tmp_tag.cn58xx.U;
+ tag.s.addr = tmp_tag.cn58xx.addr;
+ } else if (OCTEON_IS_MODEL(OCTEON_CN38XX)) {
+ tag.s.V = tmp_tag.cn38xx.V;
+ tag.s.D = tmp_tag.cn38xx.D;
+ tag.s.L = tmp_tag.cn38xx.L;
+ tag.s.U = tmp_tag.cn38xx.U;
+ tag.s.addr = tmp_tag.cn38xx.addr;
+ } else if (OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)) {
+ tag.s.V = tmp_tag.cn31xx.V;
+ tag.s.D = tmp_tag.cn31xx.D;
+ tag.s.L = tmp_tag.cn31xx.L;
+ tag.s.U = tmp_tag.cn31xx.U;
+ tag.s.addr = tmp_tag.cn31xx.addr;
+ } else if (OCTEON_IS_MODEL(OCTEON_CN30XX)) {
+ tag.s.V = tmp_tag.cn30xx.V;
+ tag.s.D = tmp_tag.cn30xx.D;
+ tag.s.L = tmp_tag.cn30xx.L;
+ tag.s.U = tmp_tag.cn30xx.U;
+ tag.s.addr = tmp_tag.cn30xx.addr;
+ } else if (OCTEON_IS_MODEL(OCTEON_CN50XX)) {
+ tag.s.V = tmp_tag.cn50xx.V;
+ tag.s.D = tmp_tag.cn50xx.D;
+ tag.s.L = tmp_tag.cn50xx.L;
+ tag.s.U = tmp_tag.cn50xx.U;
+ tag.s.addr = tmp_tag.cn50xx.addr;
+ } else {
+ cvmx_dprintf("Unsupported OCTEON Model in %s\n", __func__);
+ }
}
-
return tag;
}
uint32_t cvmx_l2c_address_to_index(uint64_t addr)
{
uint64_t idx = addr >> CVMX_L2C_IDX_ADDR_SHIFT;
- union cvmx_l2c_cfg l2c_cfg;
- l2c_cfg.u64 = cvmx_read_csr(CVMX_L2C_CFG);
+ int indxalias = 0;
- if (l2c_cfg.s.idxalias) {
- idx ^=
- ((addr & CVMX_L2C_ALIAS_MASK) >>
- CVMX_L2C_TAG_ADDR_ALIAS_SHIFT);
+ if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
+ union cvmx_l2c_ctl l2c_ctl;
+ l2c_ctl.u64 = cvmx_read_csr(CVMX_L2C_CTL);
+ indxalias = !l2c_ctl.s.disidxalias;
+ } else {
+ union cvmx_l2c_cfg l2c_cfg;
+ l2c_cfg.u64 = cvmx_read_csr(CVMX_L2C_CFG);
+ indxalias = l2c_cfg.s.idxalias;
+ }
+
+ if (indxalias) {
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+ uint32_t a_14_12 = (idx / (CVMX_L2C_MEMBANK_SELECT_SIZE/(1<<CVMX_L2C_IDX_ADDR_SHIFT))) & 0x7;
+ idx ^= idx / cvmx_l2c_get_num_sets();
+ idx ^= a_14_12;
+ } else {
+ idx ^= ((addr & CVMX_L2C_ALIAS_MASK) >> CVMX_L2C_TAG_ADDR_ALIAS_SHIFT);
+ }
}
idx &= CVMX_L2C_IDX_MASK;
return idx;
@@ -652,10 +756,9 @@ int cvmx_l2c_get_set_bits(void)
int l2_set_bits;
if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN58XX))
l2_set_bits = 11; /* 2048 sets */
- else if (OCTEON_IS_MODEL(OCTEON_CN38XX))
+ else if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN63XX))
l2_set_bits = 10; /* 1024 sets */
- else if (OCTEON_IS_MODEL(OCTEON_CN31XX)
- || OCTEON_IS_MODEL(OCTEON_CN52XX))
+ else if (OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN52XX))
l2_set_bits = 9; /* 512 sets */
else if (OCTEON_IS_MODEL(OCTEON_CN30XX))
l2_set_bits = 8; /* 256 sets */
@@ -666,7 +769,6 @@ int cvmx_l2c_get_set_bits(void)
l2_set_bits = 11; /* 2048 sets */
}
return l2_set_bits;
-
}
/* Return the number of sets in the L2 Cache */
@@ -682,8 +784,11 @@ int cvmx_l2c_get_num_assoc(void)
if (OCTEON_IS_MODEL(OCTEON_CN56XX) ||
OCTEON_IS_MODEL(OCTEON_CN52XX) ||
OCTEON_IS_MODEL(OCTEON_CN58XX) ||
- OCTEON_IS_MODEL(OCTEON_CN50XX) || OCTEON_IS_MODEL(OCTEON_CN38XX))
+ OCTEON_IS_MODEL(OCTEON_CN50XX) ||
+ OCTEON_IS_MODEL(OCTEON_CN38XX))
l2_assoc = 8;
+ else if (OCTEON_IS_MODEL(OCTEON_CN63XX))
+ l2_assoc = 16;
else if (OCTEON_IS_MODEL(OCTEON_CN31XX) ||
OCTEON_IS_MODEL(OCTEON_CN30XX))
l2_assoc = 4;
@@ -693,11 +798,42 @@ int cvmx_l2c_get_num_assoc(void)
}
/* Check to see if part of the cache is disabled */
- if (cvmx_fuse_read(265))
- l2_assoc = l2_assoc >> 2;
- else if (cvmx_fuse_read(264))
- l2_assoc = l2_assoc >> 1;
-
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+ union cvmx_mio_fus_dat3 mio_fus_dat3;
+
+ mio_fus_dat3.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT3);
+ /*
+ * cvmx_mio_fus_dat3.s.l2c_crip fuses map as follows
+ * <2> will be not used for 63xx
+ * <1> disables 1/2 ways
+ * <0> disables 1/4 ways
+ * They are cumulative, so for 63xx:
+ * <1> <0>
+ * 0 0 16-way 2MB cache
+ * 0 1 12-way 1.5MB cache
+ * 1 0 8-way 1MB cache
+ * 1 1 4-way 512KB cache
+ */
+
+ if (mio_fus_dat3.s.l2c_crip == 3)
+ l2_assoc = 4;
+ else if (mio_fus_dat3.s.l2c_crip == 2)
+ l2_assoc = 8;
+ else if (mio_fus_dat3.s.l2c_crip == 1)
+ l2_assoc = 12;
+ } else {
+ union cvmx_l2d_fus3 val;
+ val.u64 = cvmx_read_csr(CVMX_L2D_FUS3);
+ /*
+ * Using shifts here, as bit position names are
+ * different for each model but they all mean the
+ * same.
+ */
+ if ((val.u64 >> 35) & 0x1)
+ l2_assoc = l2_assoc >> 2;
+ else if ((val.u64 >> 34) & 0x1)
+ l2_assoc = l2_assoc >> 1;
+ }
return l2_assoc;
}
@@ -711,24 +847,54 @@ int cvmx_l2c_get_num_assoc(void)
*/
void cvmx_l2c_flush_line(uint32_t assoc, uint32_t index)
{
- union cvmx_l2c_dbg l2cdbg;
+ /* Check the range of the index. */
+ if (index > (uint32_t)cvmx_l2c_get_num_sets()) {
+ cvmx_dprintf("ERROR: cvmx_l2c_flush_line index out of range.\n");
+ return;
+ }
- l2cdbg.u64 = 0;
- l2cdbg.s.ppnum = cvmx_get_core_num();
- l2cdbg.s.finv = 1;
+ /* Check the range of association. */
+ if (assoc > (uint32_t)cvmx_l2c_get_num_assoc()) {
+ cvmx_dprintf("ERROR: cvmx_l2c_flush_line association out of range.\n");
+ return;
+ }
- l2cdbg.s.set = assoc;
- /*
- * Enter debug mode, and make sure all other writes complete
- * before we enter debug mode.
- */
- asm volatile ("sync" : : : "memory");
- cvmx_write_csr(CVMX_L2C_DBG, l2cdbg.u64);
- cvmx_read_csr(CVMX_L2C_DBG);
-
- CVMX_PREPARE_FOR_STORE(((1ULL << 63) + (index) * 128), 0);
- /* Exit debug mode */
- asm volatile ("sync" : : : "memory");
- cvmx_write_csr(CVMX_L2C_DBG, 0);
- cvmx_read_csr(CVMX_L2C_DBG);
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+ uint64_t address;
+ /* Create the address based on index and association.
+ * Bits<20:17> select the way of the cache block involved in
+ * the operation
+ * Bits<16:7> of the effect address select the index
+ */
+ address = CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS,
+ (assoc << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) |
+ (index << CVMX_L2C_IDX_ADDR_SHIFT));
+ CVMX_CACHE_WBIL2I(address, 0);
+ } else {
+ union cvmx_l2c_dbg l2cdbg;
+
+ l2cdbg.u64 = 0;
+ if (!OCTEON_IS_MODEL(OCTEON_CN30XX))
+ l2cdbg.s.ppnum = cvmx_get_core_num();
+ l2cdbg.s.finv = 1;
+
+ l2cdbg.s.set = assoc;
+ cvmx_spinlock_lock(&cvmx_l2c_spinlock);
+ /*
+ * Enter debug mode, and make sure all other writes
+ * complete before we enter debug mode
+ */
+ CVMX_SYNC;
+ cvmx_write_csr(CVMX_L2C_DBG, l2cdbg.u64);
+ cvmx_read_csr(CVMX_L2C_DBG);
+
+ CVMX_PREPARE_FOR_STORE(CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS,
+ index * CVMX_CACHE_LINE_SIZE),
+ 0);
+ /* Exit debug mode */
+ CVMX_SYNC;
+ cvmx_write_csr(CVMX_L2C_DBG, 0);
+ cvmx_read_csr(CVMX_L2C_DBG);
+ cvmx_spinlock_unlock(&cvmx_l2c_spinlock);
+ }
}
diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c
index 62ac30eef5e8..cecaf62aef32 100644
--- a/arch/mips/cavium-octeon/octeon-platform.c
+++ b/arch/mips/cavium-octeon/octeon-platform.c
@@ -3,13 +3,15 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 2004-2009 Cavium Networks
+ * Copyright (C) 2004-2010 Cavium Networks
* Copyright (C) 2008 Wind River Systems
*/
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/i2c.h>
+#include <linux/usb.h>
+#include <linux/dma-mapping.h>
#include <linux/module.h>
#include <linux/platform_device.h>
@@ -198,7 +200,7 @@ static int __init octeon_i2c_device_init(void)
num_ports = 1;
for (port = 0; port < num_ports; port++) {
- octeon_i2c_data[port].sys_freq = octeon_get_clock_rate();
+ octeon_i2c_data[port].sys_freq = octeon_get_io_clock_rate();
/*FIXME: should be examined. At the moment is set for 100Khz */
octeon_i2c_data[port].i2c_freq = 100000;
@@ -301,6 +303,10 @@ static int __init octeon_mgmt_device_init(void)
ret = -ENOMEM;
goto out;
}
+ /* No DMA restrictions */
+ pd->dev.coherent_dma_mask = DMA_BIT_MASK(64);
+ pd->dev.dma_mask = &pd->dev.coherent_dma_mask;
+
switch (port) {
case 0:
mgmt_port_resource.start = OCTEON_IRQ_MII0;
@@ -332,6 +338,108 @@ out:
}
device_initcall(octeon_mgmt_device_init);
+#ifdef CONFIG_USB
+
+static int __init octeon_ehci_device_init(void)
+{
+ struct platform_device *pd;
+ int ret = 0;
+
+ struct resource usb_resources[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ }, {
+ .flags = IORESOURCE_IRQ,
+ }
+ };
+
+ /* Only Octeon2 has ehci/ohci */
+ if (!OCTEON_IS_MODEL(OCTEON_CN63XX))
+ return 0;
+
+ if (octeon_is_simulation() || usb_disabled())
+ return 0; /* No USB in the simulator. */
+
+ pd = platform_device_alloc("octeon-ehci", 0);
+ if (!pd) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ usb_resources[0].start = 0x00016F0000000000ULL;
+ usb_resources[0].end = usb_resources[0].start + 0x100;
+
+ usb_resources[1].start = OCTEON_IRQ_USB0;
+ usb_resources[1].end = OCTEON_IRQ_USB0;
+
+ ret = platform_device_add_resources(pd, usb_resources,
+ ARRAY_SIZE(usb_resources));
+ if (ret)
+ goto fail;
+
+ ret = platform_device_add(pd);
+ if (ret)
+ goto fail;
+
+ return ret;
+fail:
+ platform_device_put(pd);
+out:
+ return ret;
+}
+device_initcall(octeon_ehci_device_init);
+
+static int __init octeon_ohci_device_init(void)
+{
+ struct platform_device *pd;
+ int ret = 0;
+
+ struct resource usb_resources[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ }, {
+ .flags = IORESOURCE_IRQ,
+ }
+ };
+
+ /* Only Octeon2 has ehci/ohci */
+ if (!OCTEON_IS_MODEL(OCTEON_CN63XX))
+ return 0;
+
+ if (octeon_is_simulation() || usb_disabled())
+ return 0; /* No USB in the simulator. */
+
+ pd = platform_device_alloc("octeon-ohci", 0);
+ if (!pd) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ usb_resources[0].start = 0x00016F0000000400ULL;
+ usb_resources[0].end = usb_resources[0].start + 0x100;
+
+ usb_resources[1].start = OCTEON_IRQ_USB0;
+ usb_resources[1].end = OCTEON_IRQ_USB0;
+
+ ret = platform_device_add_resources(pd, usb_resources,
+ ARRAY_SIZE(usb_resources));
+ if (ret)
+ goto fail;
+
+ ret = platform_device_add(pd);
+ if (ret)
+ goto fail;
+
+ return ret;
+fail:
+ platform_device_put(pd);
+out:
+ return ret;
+}
+device_initcall(octeon_ohci_device_init);
+
+#endif /* CONFIG_USB */
+
MODULE_AUTHOR("David Daney <ddaney@caviumnetworks.com>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Platform driver for Octeon SOC");
diff --git a/arch/mips/cavium-octeon/serial.c b/arch/mips/cavium-octeon/serial.c
index 638adab02842..057f0ae88c99 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>
@@ -65,7 +66,7 @@ static void __init octeon_uart_set_common(struct plat_serial8250_port *p)
/* Make simulator output fast*/
p->uartclk = 115200 * 16;
else
- p->uartclk = mips_hpt_frequency;
+ p->uartclk = octeon_get_io_clock_rate();
p->serial_in = octeon_serial_in;
p->serial_out = octeon_serial_out;
}
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index 69197cb6c7ea..b0c3686c96dd 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -33,6 +33,7 @@
#include <asm/octeon/octeon.h>
#include <asm/octeon/pci-octeon.h>
+#include <asm/octeon/cvmx-mio-defs.h>
#ifdef CONFIG_CAVIUM_DECODE_RSL
extern void cvmx_interrupt_rsl_decode(void);
@@ -96,12 +97,21 @@ int octeon_is_pci_host(void)
*/
uint64_t octeon_get_clock_rate(void)
{
- if (octeon_is_simulation())
- octeon_bootinfo->eclock_hz = 6000000;
- return octeon_bootinfo->eclock_hz;
+ struct cvmx_sysinfo *sysinfo = cvmx_sysinfo_get();
+
+ return sysinfo->cpu_clock_hz;
}
EXPORT_SYMBOL(octeon_get_clock_rate);
+static u64 octeon_io_clock_rate;
+
+u64 octeon_get_io_clock_rate(void)
+{
+ return octeon_io_clock_rate;
+}
+EXPORT_SYMBOL(octeon_get_io_clock_rate);
+
+
/**
* Write to the LCD display connected to the bootbus. This display
* exists on most Cavium evaluation boards. If it doesn't exist, then
@@ -346,8 +356,18 @@ void octeon_user_io_init(void)
cvmmemctl.s.wbfltime = 0;
/* R/W If set, do not put Istream in the L2 cache. */
cvmmemctl.s.istrnol2 = 0;
- /* R/W The write buffer threshold. */
- cvmmemctl.s.wbthresh = 10;
+
+ /*
+ * R/W The write buffer threshold. As per erratum Core-14752
+ * for CN63XX, a sc/scd might fail if the write buffer is
+ * full. Lowering WBTHRESH greatly lowers the chances of the
+ * write buffer ever being full and triggering the erratum.
+ */
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X))
+ cvmmemctl.s.wbthresh = 4;
+ else
+ cvmmemctl.s.wbthresh = 10;
+
/* R/W If set, CVMSEG is available for loads/stores in
* kernel/debug mode. */
#if CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0
@@ -365,14 +385,13 @@ void octeon_user_io_init(void)
* is max legal value. */
cvmmemctl.s.lmemsz = CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE;
+ write_c0_cvmmemctl(cvmmemctl.u64);
if (smp_processor_id() == 0)
pr_notice("CVMSEG size: %d cache lines (%d bytes)\n",
CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE,
CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE * 128);
- write_c0_cvmmemctl(cvmmemctl.u64);
-
/* Move the performance counter interrupts to IRQ 6 */
cvmctl = read_c0_cvmctl();
cvmctl &= ~(7 << 7);
@@ -416,6 +435,41 @@ void __init prom_init(void)
cvmx_phys_to_ptr(octeon_boot_desc_ptr->cvmx_desc_vaddr);
cvmx_bootmem_init(cvmx_phys_to_ptr(octeon_bootinfo->phy_mem_desc_addr));
+ sysinfo = cvmx_sysinfo_get();
+ memset(sysinfo, 0, sizeof(*sysinfo));
+ sysinfo->system_dram_size = octeon_bootinfo->dram_size << 20;
+ sysinfo->phy_mem_desc_ptr =
+ cvmx_phys_to_ptr(octeon_bootinfo->phy_mem_desc_addr);
+ sysinfo->core_mask = octeon_bootinfo->core_mask;
+ sysinfo->exception_base_addr = octeon_bootinfo->exception_base_addr;
+ sysinfo->cpu_clock_hz = octeon_bootinfo->eclock_hz;
+ sysinfo->dram_data_rate_hz = octeon_bootinfo->dclock_hz * 2;
+ sysinfo->board_type = octeon_bootinfo->board_type;
+ sysinfo->board_rev_major = octeon_bootinfo->board_rev_major;
+ sysinfo->board_rev_minor = octeon_bootinfo->board_rev_minor;
+ memcpy(sysinfo->mac_addr_base, octeon_bootinfo->mac_addr_base,
+ sizeof(sysinfo->mac_addr_base));
+ sysinfo->mac_addr_count = octeon_bootinfo->mac_addr_count;
+ memcpy(sysinfo->board_serial_number,
+ octeon_bootinfo->board_serial_number,
+ sizeof(sysinfo->board_serial_number));
+ sysinfo->compact_flash_common_base_addr =
+ octeon_bootinfo->compact_flash_common_base_addr;
+ sysinfo->compact_flash_attribute_base_addr =
+ octeon_bootinfo->compact_flash_attribute_base_addr;
+ sysinfo->led_display_base_addr = octeon_bootinfo->led_display_base_addr;
+ sysinfo->dfa_ref_clock_hz = octeon_bootinfo->dfa_ref_clock_hz;
+ sysinfo->bootloader_config_flags = octeon_bootinfo->config_flags;
+
+ if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
+ /* I/O clock runs at a different rate than the CPU. */
+ union cvmx_mio_rst_boot rst_boot;
+ rst_boot.u64 = cvmx_read_csr(CVMX_MIO_RST_BOOT);
+ octeon_io_clock_rate = 50000000 * rst_boot.s.pnr_mul;
+ } else {
+ octeon_io_clock_rate = sysinfo->cpu_clock_hz;
+ }
+
/*
* Only enable the LED controller if we're running on a CN38XX, CN58XX,
* or CN56XX. The CN30XX and CN31XX don't have an LED controller.
@@ -479,33 +533,6 @@ void __init prom_init(void)
}
#endif
- sysinfo = cvmx_sysinfo_get();
- memset(sysinfo, 0, sizeof(*sysinfo));
- sysinfo->system_dram_size = octeon_bootinfo->dram_size << 20;
- sysinfo->phy_mem_desc_ptr =
- cvmx_phys_to_ptr(octeon_bootinfo->phy_mem_desc_addr);
- sysinfo->core_mask = octeon_bootinfo->core_mask;
- sysinfo->exception_base_addr = octeon_bootinfo->exception_base_addr;
- sysinfo->cpu_clock_hz = octeon_bootinfo->eclock_hz;
- sysinfo->dram_data_rate_hz = octeon_bootinfo->dclock_hz * 2;
- sysinfo->board_type = octeon_bootinfo->board_type;
- sysinfo->board_rev_major = octeon_bootinfo->board_rev_major;
- sysinfo->board_rev_minor = octeon_bootinfo->board_rev_minor;
- memcpy(sysinfo->mac_addr_base, octeon_bootinfo->mac_addr_base,
- sizeof(sysinfo->mac_addr_base));
- sysinfo->mac_addr_count = octeon_bootinfo->mac_addr_count;
- memcpy(sysinfo->board_serial_number,
- octeon_bootinfo->board_serial_number,
- sizeof(sysinfo->board_serial_number));
- sysinfo->compact_flash_common_base_addr =
- octeon_bootinfo->compact_flash_common_base_addr;
- sysinfo->compact_flash_attribute_base_addr =
- octeon_bootinfo->compact_flash_attribute_base_addr;
- sysinfo->led_display_base_addr = octeon_bootinfo->led_display_base_addr;
- sysinfo->dfa_ref_clock_hz = octeon_bootinfo->dfa_ref_clock_hz;
- sysinfo->bootloader_config_flags = octeon_bootinfo->config_flags;
-
-
octeon_check_cpu_bist();
octeon_uart = octeon_get_boot_uart();
@@ -740,6 +767,31 @@ EXPORT_SYMBOL(prom_putchar);
void prom_free_prom_memory(void)
{
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X)) {
+ /* Check for presence of Core-14449 fix. */
+ u32 insn;
+ u32 *foo;
+
+ foo = &insn;
+
+ asm volatile("# before" : : : "memory");
+ prefetch(foo);
+ asm volatile(
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ "bal 1f\n\t"
+ "nop\n"
+ "1:\tlw %0,-12($31)\n\t"
+ ".set pop\n\t"
+ : "=r" (insn) : : "$31", "memory");
+
+ if ((insn >> 26) != 0x33)
+ panic("No PREF instruction at Core-14449 probe point.\n");
+
+ if (((insn >> 16) & 0x1f) != 28)
+ panic("Core-14449 WAR not in place (%04x).\n"
+ "Please build kernel with proper options (CONFIG_CAVIUM_CN63XXP1).\n", insn);
+ }
#ifdef CONFIG_CAVIUM_DECODE_RSL
cvmx_interrupt_rsl_enable();
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 47d87da379f9..4a02fe891ab6 100644
--- a/arch/mips/include/asm/atomic.h
+++ b/arch/mips/include/asm/atomic.h
@@ -64,18 +64,16 @@ static __inline__ void atomic_add(int i, atomic_t * v)
} else if (kernel_uses_llsc) {
int temp;
- __asm__ __volatile__(
- " .set mips3 \n"
- "1: ll %0, %1 # atomic_add \n"
- " addu %0, %2 \n"
- " sc %0, %1 \n"
- " beqz %0, 2f \n"
- " .subsection 2 \n"
- "2: b 1b \n"
- " .previous \n"
- " .set mips0 \n"
- : "=&r" (temp), "=m" (v->counter)
- : "Ir" (i), "m" (v->counter));
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " ll %0, %1 # atomic_add \n"
+ " addu %0, %2 \n"
+ " sc %0, %1 \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter));
+ } while (unlikely(!temp));
} else {
unsigned long flags;
@@ -109,18 +107,16 @@ static __inline__ void atomic_sub(int i, atomic_t * v)
} else if (kernel_uses_llsc) {
int temp;
- __asm__ __volatile__(
- " .set mips3 \n"
- "1: ll %0, %1 # atomic_sub \n"
- " subu %0, %2 \n"
- " sc %0, %1 \n"
- " beqz %0, 2f \n"
- " .subsection 2 \n"
- "2: b 1b \n"
- " .previous \n"
- " .set mips0 \n"
- : "=&r" (temp), "=m" (v->counter)
- : "Ir" (i), "m" (v->counter));
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " ll %0, %1 # atomic_sub \n"
+ " subu %0, %2 \n"
+ " sc %0, %1 \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter));
+ } while (unlikely(!temp));
} else {
unsigned long flags;
@@ -156,20 +152,19 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
} else if (kernel_uses_llsc) {
int temp;
- __asm__ __volatile__(
- " .set mips3 \n"
- "1: ll %1, %2 # atomic_add_return \n"
- " addu %0, %1, %3 \n"
- " sc %0, %2 \n"
- " beqz %0, 2f \n"
- " addu %0, %1, %3 \n"
- " .subsection 2 \n"
- "2: b 1b \n"
- " .previous \n"
- " .set mips0 \n"
- : "=&r" (result), "=&r" (temp), "=m" (v->counter)
- : "Ir" (i), "m" (v->counter)
- : "memory");
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " ll %1, %2 # atomic_add_return \n"
+ " addu %0, %1, %3 \n"
+ " sc %0, %2 \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter)
+ : "memory");
+ } while (unlikely(!result));
+
+ result = temp + i;
} else {
unsigned long flags;
@@ -205,23 +200,24 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
+
+ result = temp - i;
} else if (kernel_uses_llsc) {
int temp;
- __asm__ __volatile__(
- " .set mips3 \n"
- "1: ll %1, %2 # atomic_sub_return \n"
- " subu %0, %1, %3 \n"
- " sc %0, %2 \n"
- " beqz %0, 2f \n"
- " subu %0, %1, %3 \n"
- " .subsection 2 \n"
- "2: b 1b \n"
- " .previous \n"
- " .set mips0 \n"
- : "=&r" (result), "=&r" (temp), "=m" (v->counter)
- : "Ir" (i), "m" (v->counter)
- : "memory");
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " ll %1, %2 # atomic_sub_return \n"
+ " subu %0, %1, %3 \n"
+ " sc %0, %2 \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter)
+ : "memory");
+ } while (unlikely(!result));
+
+ result = temp - i;
} else {
unsigned long flags;
@@ -279,12 +275,9 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
" bltz %0, 1f \n"
" sc %0, %2 \n"
" .set noreorder \n"
- " beqz %0, 2f \n"
+ " beqz %0, 1b \n"
" subu %0, %1, %3 \n"
" .set reorder \n"
- " .subsection 2 \n"
- "2: b 1b \n"
- " .previous \n"
"1: \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
@@ -443,18 +436,16 @@ static __inline__ void atomic64_add(long i, atomic64_t * v)
} else if (kernel_uses_llsc) {
long temp;
- __asm__ __volatile__(
- " .set mips3 \n"
- "1: lld %0, %1 # atomic64_add \n"
- " daddu %0, %2 \n"
- " scd %0, %1 \n"
- " beqz %0, 2f \n"
- " .subsection 2 \n"
- "2: b 1b \n"
- " .previous \n"
- " .set mips0 \n"
- : "=&r" (temp), "=m" (v->counter)
- : "Ir" (i), "m" (v->counter));
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " lld %0, %1 # atomic64_add \n"
+ " daddu %0, %2 \n"
+ " scd %0, %1 \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter));
+ } while (unlikely(!temp));
} else {
unsigned long flags;
@@ -488,18 +479,16 @@ static __inline__ void atomic64_sub(long i, atomic64_t * v)
} else if (kernel_uses_llsc) {
long temp;
- __asm__ __volatile__(
- " .set mips3 \n"
- "1: lld %0, %1 # atomic64_sub \n"
- " dsubu %0, %2 \n"
- " scd %0, %1 \n"
- " beqz %0, 2f \n"
- " .subsection 2 \n"
- "2: b 1b \n"
- " .previous \n"
- " .set mips0 \n"
- : "=&r" (temp), "=m" (v->counter)
- : "Ir" (i), "m" (v->counter));
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " lld %0, %1 # atomic64_sub \n"
+ " dsubu %0, %2 \n"
+ " scd %0, %1 \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter));
+ } while (unlikely(!temp));
} else {
unsigned long flags;
@@ -535,20 +524,19 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
} else if (kernel_uses_llsc) {
long temp;
- __asm__ __volatile__(
- " .set mips3 \n"
- "1: lld %1, %2 # atomic64_add_return \n"
- " daddu %0, %1, %3 \n"
- " scd %0, %2 \n"
- " beqz %0, 2f \n"
- " daddu %0, %1, %3 \n"
- " .subsection 2 \n"
- "2: b 1b \n"
- " .previous \n"
- " .set mips0 \n"
- : "=&r" (result), "=&r" (temp), "=m" (v->counter)
- : "Ir" (i), "m" (v->counter)
- : "memory");
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " lld %1, %2 # atomic64_add_return \n"
+ " daddu %0, %1, %3 \n"
+ " scd %0, %2 \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter)
+ : "memory");
+ } while (unlikely(!result));
+
+ result = temp + i;
} else {
unsigned long flags;
@@ -587,20 +575,19 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
} else if (kernel_uses_llsc) {
long temp;
- __asm__ __volatile__(
- " .set mips3 \n"
- "1: lld %1, %2 # atomic64_sub_return \n"
- " dsubu %0, %1, %3 \n"
- " scd %0, %2 \n"
- " beqz %0, 2f \n"
- " dsubu %0, %1, %3 \n"
- " .subsection 2 \n"
- "2: b 1b \n"
- " .previous \n"
- " .set mips0 \n"
- : "=&r" (result), "=&r" (temp), "=m" (v->counter)
- : "Ir" (i), "m" (v->counter)
- : "memory");
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " lld %1, %2 # atomic64_sub_return \n"
+ " dsubu %0, %1, %3 \n"
+ " scd %0, %2 \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter)
+ : "memory");
+ } while (unlikely(!result));
+
+ result = temp - i;
} else {
unsigned long flags;
@@ -658,12 +645,9 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
" bltz %0, 1f \n"
" scd %0, %2 \n"
" .set noreorder \n"
- " beqz %0, 2f \n"
+ " beqz %0, 1b \n"
" dsubu %0, %1, %3 \n"
" .set reorder \n"
- " .subsection 2 \n"
- "2: b 1b \n"
- " .previous \n"
"1: \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h
index b0ce7ca2851f..50b4ef288c53 100644
--- a/arch/mips/include/asm/bitops.h
+++ b/arch/mips/include/asm/bitops.h
@@ -73,30 +73,26 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
: "ir" (1UL << bit), "m" (*m));
#ifdef CONFIG_CPU_MIPSR2
} else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
- __asm__ __volatile__(
- "1: " __LL "%0, %1 # set_bit \n"
- " " __INS "%0, %4, %2, 1 \n"
- " " __SC "%0, %1 \n"
- " beqz %0, 2f \n"
- " .subsection 2 \n"
- "2: b 1b \n"
- " .previous \n"
- : "=&r" (temp), "=m" (*m)
- : "ir" (bit), "m" (*m), "r" (~0));
+ do {
+ __asm__ __volatile__(
+ " " __LL "%0, %1 # set_bit \n"
+ " " __INS "%0, %3, %2, 1 \n"
+ " " __SC "%0, %1 \n"
+ : "=&r" (temp), "+m" (*m)
+ : "ir" (bit), "r" (~0));
+ } while (unlikely(!temp));
#endif /* CONFIG_CPU_MIPSR2 */
} else if (kernel_uses_llsc) {
- __asm__ __volatile__(
- " .set mips3 \n"
- "1: " __LL "%0, %1 # set_bit \n"
- " or %0, %2 \n"
- " " __SC "%0, %1 \n"
- " beqz %0, 2f \n"
- " .subsection 2 \n"
- "2: b 1b \n"
- " .previous \n"
- " .set mips0 \n"
- : "=&r" (temp), "=m" (*m)
- : "ir" (1UL << bit), "m" (*m));
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " " __LL "%0, %1 # set_bit \n"
+ " or %0, %2 \n"
+ " " __SC "%0, %1 \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "+m" (*m)
+ : "ir" (1UL << bit));
+ } while (unlikely(!temp));
} else {
volatile unsigned long *a = addr;
unsigned long mask;
@@ -134,34 +130,30 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
" " __SC "%0, %1 \n"
" beqzl %0, 1b \n"
" .set mips0 \n"
- : "=&r" (temp), "=m" (*m)
- : "ir" (~(1UL << bit)), "m" (*m));
+ : "=&r" (temp), "+m" (*m)
+ : "ir" (~(1UL << bit)));
#ifdef CONFIG_CPU_MIPSR2
} else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
- __asm__ __volatile__(
- "1: " __LL "%0, %1 # clear_bit \n"
- " " __INS "%0, $0, %2, 1 \n"
- " " __SC "%0, %1 \n"
- " beqz %0, 2f \n"
- " .subsection 2 \n"
- "2: b 1b \n"
- " .previous \n"
- : "=&r" (temp), "=m" (*m)
- : "ir" (bit), "m" (*m));
+ do {
+ __asm__ __volatile__(
+ " " __LL "%0, %1 # clear_bit \n"
+ " " __INS "%0, $0, %2, 1 \n"
+ " " __SC "%0, %1 \n"
+ : "=&r" (temp), "+m" (*m)
+ : "ir" (bit));
+ } while (unlikely(!temp));
#endif /* CONFIG_CPU_MIPSR2 */
} else if (kernel_uses_llsc) {
- __asm__ __volatile__(
- " .set mips3 \n"
- "1: " __LL "%0, %1 # clear_bit \n"
- " and %0, %2 \n"
- " " __SC "%0, %1 \n"
- " beqz %0, 2f \n"
- " .subsection 2 \n"
- "2: b 1b \n"
- " .previous \n"
- " .set mips0 \n"
- : "=&r" (temp), "=m" (*m)
- : "ir" (~(1UL << bit)), "m" (*m));
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " " __LL "%0, %1 # clear_bit \n"
+ " and %0, %2 \n"
+ " " __SC "%0, %1 \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "+m" (*m)
+ : "ir" (~(1UL << bit)));
+ } while (unlikely(!temp));
} else {
volatile unsigned long *a = addr;
unsigned long mask;
@@ -213,24 +205,22 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
" " __SC "%0, %1 \n"
" beqzl %0, 1b \n"
" .set mips0 \n"
- : "=&r" (temp), "=m" (*m)
- : "ir" (1UL << bit), "m" (*m));
+ : "=&r" (temp), "+m" (*m)
+ : "ir" (1UL << bit));
} else if (kernel_uses_llsc) {
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
unsigned long temp;
- __asm__ __volatile__(
- " .set mips3 \n"
- "1: " __LL "%0, %1 # change_bit \n"
- " xor %0, %2 \n"
- " " __SC "%0, %1 \n"
- " beqz %0, 2f \n"
- " .subsection 2 \n"
- "2: b 1b \n"
- " .previous \n"
- " .set mips0 \n"
- : "=&r" (temp), "=m" (*m)
- : "ir" (1UL << bit), "m" (*m));
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " " __LL "%0, %1 # change_bit \n"
+ " xor %0, %2 \n"
+ " " __SC "%0, %1 \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "+m" (*m)
+ : "ir" (1UL << bit));
+ } while (unlikely(!temp));
} else {
volatile unsigned long *a = addr;
unsigned long mask;
@@ -272,30 +262,26 @@ static inline int test_and_set_bit(unsigned long nr,
" beqzl %2, 1b \n"
" and %2, %0, %3 \n"
" .set mips0 \n"
- : "=&r" (temp), "=m" (*m), "=&r" (res)
- : "r" (1UL << bit), "m" (*m)
+ : "=&r" (temp), "+m" (*m), "=&r" (res)
+ : "r" (1UL << bit)
: "memory");
} else if (kernel_uses_llsc) {
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
unsigned long temp;
- __asm__ __volatile__(
- " .set push \n"
- " .set noreorder \n"
- " .set mips3 \n"
- "1: " __LL "%0, %1 # test_and_set_bit \n"
- " or %2, %0, %3 \n"
- " " __SC "%2, %1 \n"
- " beqz %2, 2f \n"
- " and %2, %0, %3 \n"
- " .subsection 2 \n"
- "2: b 1b \n"
- " nop \n"
- " .previous \n"
- " .set pop \n"
- : "=&r" (temp), "=m" (*m), "=&r" (res)
- : "r" (1UL << bit), "m" (*m)
- : "memory");
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " " __LL "%0, %1 # test_and_set_bit \n"
+ " or %2, %0, %3 \n"
+ " " __SC "%2, %1 \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "+m" (*m), "=&r" (res)
+ : "r" (1UL << bit)
+ : "memory");
+ } while (unlikely(!res));
+
+ res = temp & (1UL << bit);
} else {
volatile unsigned long *a = addr;
unsigned long mask;
@@ -340,30 +326,26 @@ static inline int test_and_set_bit_lock(unsigned long nr,
" beqzl %2, 1b \n"
" and %2, %0, %3 \n"
" .set mips0 \n"
- : "=&r" (temp), "=m" (*m), "=&r" (res)
- : "r" (1UL << bit), "m" (*m)
+ : "=&r" (temp), "+m" (*m), "=&r" (res)
+ : "r" (1UL << bit)
: "memory");
} else if (kernel_uses_llsc) {
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
unsigned long temp;
- __asm__ __volatile__(
- " .set push \n"
- " .set noreorder \n"
- " .set mips3 \n"
- "1: " __LL "%0, %1 # test_and_set_bit \n"
- " or %2, %0, %3 \n"
- " " __SC "%2, %1 \n"
- " beqz %2, 2f \n"
- " and %2, %0, %3 \n"
- " .subsection 2 \n"
- "2: b 1b \n"
- " nop \n"
- " .previous \n"
- " .set pop \n"
- : "=&r" (temp), "=m" (*m), "=&r" (res)
- : "r" (1UL << bit), "m" (*m)
- : "memory");
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " " __LL "%0, %1 # test_and_set_bit \n"
+ " or %2, %0, %3 \n"
+ " " __SC "%2, %1 \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "+m" (*m), "=&r" (res)
+ : "r" (1UL << bit)
+ : "memory");
+ } while (unlikely(!res));
+
+ res = temp & (1UL << bit);
} else {
volatile unsigned long *a = addr;
unsigned long mask;
@@ -410,49 +392,43 @@ static inline int test_and_clear_bit(unsigned long nr,
" beqzl %2, 1b \n"
" and %2, %0, %3 \n"
" .set mips0 \n"
- : "=&r" (temp), "=m" (*m), "=&r" (res)
- : "r" (1UL << bit), "m" (*m)
+ : "=&r" (temp), "+m" (*m), "=&r" (res)
+ : "r" (1UL << bit)
: "memory");
#ifdef CONFIG_CPU_MIPSR2
} else if (kernel_uses_llsc && __builtin_constant_p(nr)) {
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
unsigned long temp;
- __asm__ __volatile__(
- "1: " __LL "%0, %1 # test_and_clear_bit \n"
- " " __EXT "%2, %0, %3, 1 \n"
- " " __INS "%0, $0, %3, 1 \n"
- " " __SC "%0, %1 \n"
- " beqz %0, 2f \n"
- " .subsection 2 \n"
- "2: b 1b \n"
- " .previous \n"
- : "=&r" (temp), "=m" (*m), "=&r" (res)
- : "ir" (bit), "m" (*m)
- : "memory");
+ do {
+ __asm__ __volatile__(
+ " " __LL "%0, %1 # test_and_clear_bit \n"
+ " " __EXT "%2, %0, %3, 1 \n"
+ " " __INS "%0, $0, %3, 1 \n"
+ " " __SC "%0, %1 \n"
+ : "=&r" (temp), "+m" (*m), "=&r" (res)
+ : "ir" (bit)
+ : "memory");
+ } while (unlikely(!temp));
#endif
} else if (kernel_uses_llsc) {
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
unsigned long temp;
- __asm__ __volatile__(
- " .set push \n"
- " .set noreorder \n"
- " .set mips3 \n"
- "1: " __LL "%0, %1 # test_and_clear_bit \n"
- " or %2, %0, %3 \n"
- " xor %2, %3 \n"
- " " __SC "%2, %1 \n"
- " beqz %2, 2f \n"
- " and %2, %0, %3 \n"
- " .subsection 2 \n"
- "2: b 1b \n"
- " nop \n"
- " .previous \n"
- " .set pop \n"
- : "=&r" (temp), "=m" (*m), "=&r" (res)
- : "r" (1UL << bit), "m" (*m)
- : "memory");
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " " __LL "%0, %1 # test_and_clear_bit \n"
+ " or %2, %0, %3 \n"
+ " xor %2, %3 \n"
+ " " __SC "%2, %1 \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "+m" (*m), "=&r" (res)
+ : "r" (1UL << bit)
+ : "memory");
+ } while (unlikely(!res));
+
+ res = temp & (1UL << bit);
} else {
volatile unsigned long *a = addr;
unsigned long mask;
@@ -499,30 +475,26 @@ static inline int test_and_change_bit(unsigned long nr,
" beqzl %2, 1b \n"
" and %2, %0, %3 \n"
" .set mips0 \n"
- : "=&r" (temp), "=m" (*m), "=&r" (res)
- : "r" (1UL << bit), "m" (*m)
+ : "=&r" (temp), "+m" (*m), "=&r" (res)
+ : "r" (1UL << bit)
: "memory");
} else if (kernel_uses_llsc) {
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
unsigned long temp;
- __asm__ __volatile__(
- " .set push \n"
- " .set noreorder \n"
- " .set mips3 \n"
- "1: " __LL "%0, %1 # test_and_change_bit \n"
- " xor %2, %0, %3 \n"
- " " __SC "\t%2, %1 \n"
- " beqz %2, 2f \n"
- " and %2, %0, %3 \n"
- " .subsection 2 \n"
- "2: b 1b \n"
- " nop \n"
- " .previous \n"
- " .set pop \n"
- : "=&r" (temp), "=m" (*m), "=&r" (res)
- : "r" (1UL << bit), "m" (*m)
- : "memory");
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " " __LL "%0, %1 # test_and_change_bit \n"
+ " xor %2, %0, %3 \n"
+ " " __SC "\t%2, %1 \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "+m" (*m), "=&r" (res)
+ : "r" (1UL << bit)
+ : "memory");
+ } while (unlikely(!res));
+
+ res = temp & (1UL << bit);
} else {
volatile unsigned long *a = addr;
unsigned long mask;
diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h
index 15a8ef0707c6..35cd1bab69c3 100644
--- a/arch/mips/include/asm/bootinfo.h
+++ b/arch/mips/include/asm/bootinfo.h
@@ -125,4 +125,16 @@ extern unsigned long fw_arg0, fw_arg1, fw_arg2, fw_arg3;
*/
extern void plat_mem_setup(void);
+#ifdef CONFIG_SWIOTLB
+/*
+ * Optional platform hook to call swiotlb_setup().
+ */
+extern void plat_swiotlb_setup(void);
+
+#else
+
+static inline void plat_swiotlb_setup(void) {}
+
+#endif /* CONFIG_SWIOTLB */
+
#endif /* _ASM_BOOTINFO_H */
diff --git a/arch/mips/include/asm/cmpxchg.h b/arch/mips/include/asm/cmpxchg.h
index 2d28017e95d0..d8d1c2805ac7 100644
--- a/arch/mips/include/asm/cmpxchg.h
+++ b/arch/mips/include/asm/cmpxchg.h
@@ -44,12 +44,9 @@
" move $1, %z4 \n" \
" .set mips3 \n" \
" " st " $1, %1 \n" \
- " beqz $1, 3f \n" \
- "2: \n" \
- " .subsection 2 \n" \
- "3: b 1b \n" \
- " .previous \n" \
+ " beqz $1, 1b \n" \
" .set pop \n" \
+ "2: \n" \
: "=&r" (__ret), "=R" (*m) \
: "R" (*m), "Jr" (old), "Jr" (new) \
: "memory"); \
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
index b201a8f5b127..06d59dcbe243 100644
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -111,14 +111,16 @@
* These are the PRID's for when 23:16 == PRID_COMP_BROADCOM
*/
-#define PRID_IMP_BCM4710 0x4000
-#define PRID_IMP_BCM3302 0x9000
-#define PRID_IMP_BCM6338 0x9000
-#define PRID_IMP_BCM6345 0x8000
-#define PRID_IMP_BCM6348 0x9100
-#define PRID_IMP_BCM4350 0xA000
-#define PRID_REV_BCM6358 0x0010
-#define PRID_REV_BCM6368 0x0030
+#define PRID_IMP_BMIPS4KC 0x4000
+#define PRID_IMP_BMIPS32 0x8000
+#define PRID_IMP_BMIPS3300 0x9000
+#define PRID_IMP_BMIPS3300_ALT 0x9100
+#define PRID_IMP_BMIPS3300_BUG 0x0000
+#define PRID_IMP_BMIPS43XX 0xa000
+#define PRID_IMP_BMIPS5000 0x5a00
+
+#define PRID_REV_BMIPS4380_LO 0x0040
+#define PRID_REV_BMIPS4380_HI 0x006f
/*
* These are the PRID's for when 23:16 == PRID_COMP_CAVIUM
@@ -131,6 +133,7 @@
#define PRID_IMP_CAVIUM_CN56XX 0x0400
#define PRID_IMP_CAVIUM_CN50XX 0x0600
#define PRID_IMP_CAVIUM_CN52XX 0x0700
+#define PRID_IMP_CAVIUM_CN63XX 0x9000
/*
* These are the PRID's for when 23:16 == PRID_COMP_INGENIC
@@ -223,15 +226,14 @@ enum cpu_type_enum {
* MIPS32 class processors
*/
CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K,
- CPU_ALCHEMY, CPU_PR4450, CPU_BCM3302, CPU_BCM4710,
- CPU_BCM6338, CPU_BCM6345, CPU_BCM6348, CPU_BCM6358,
- CPU_JZRISC,
+ CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350,
+ CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC,
/*
* MIPS64 class processors
*/
CPU_5KC, CPU_20KC, CPU_25KF, CPU_SB1, CPU_SB1A, CPU_LOONGSON2,
- CPU_CAVIUM_OCTEON, CPU_CAVIUM_OCTEON_PLUS,
+ CPU_CAVIUM_OCTEON, CPU_CAVIUM_OCTEON_PLUS, CPU_CAVIUM_OCTEON2,
CPU_LAST
};
diff --git a/arch/mips/include/asm/device.h b/arch/mips/include/asm/device.h
index 06746c5e8099..c94fafba9e62 100644
--- a/arch/mips/include/asm/device.h
+++ b/arch/mips/include/asm/device.h
@@ -3,4 +3,17 @@
*
* This file is released under the GPLv2
*/
-#include <asm-generic/device.h>
+#ifndef _ASM_MIPS_DEVICE_H
+#define _ASM_MIPS_DEVICE_H
+
+struct dma_map_ops;
+
+struct dev_archdata {
+ /* DMA operations on that device */
+ struct dma_map_ops *dma_ops;
+};
+
+struct pdev_archdata {
+};
+
+#endif /* _ASM_MIPS_DEVICE_H*/
diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h
index 18fbf7af8e93..655f849bd08d 100644
--- a/arch/mips/include/asm/dma-mapping.h
+++ b/arch/mips/include/asm/dma-mapping.h
@@ -5,51 +5,41 @@
#include <asm/cache.h>
#include <asm-generic/dma-coherent.h>
-void *dma_alloc_noncoherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t flag);
+#include <dma-coherence.h>
-void dma_free_noncoherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle);
+extern struct dma_map_ops *mips_dma_map_ops;
-void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t flag);
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
+{
+ if (dev && dev->archdata.dma_ops)
+ return dev->archdata.dma_ops;
+ else
+ return mips_dma_map_ops;
+}
-void dma_free_coherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle);
+static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
+{
+ if (!dev->dma_mask)
+ return 0;
-extern dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
- enum dma_data_direction direction);
-extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
- size_t size, enum dma_data_direction direction);
-extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
- enum dma_data_direction direction);
-extern dma_addr_t dma_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size, enum dma_data_direction direction);
-
-static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
- size_t size, enum dma_data_direction direction)
+ return addr + size <= *dev->dma_mask;
+}
+
+static inline void dma_mark_clean(void *addr, size_t size) {}
+
+#include <asm-generic/dma-mapping-common.h>
+
+static inline int dma_supported(struct device *dev, u64 mask)
{
- dma_unmap_single(dev, dma_address, size, direction);
+ struct dma_map_ops *ops = get_dma_ops(dev);
+ return ops->dma_supported(dev, mask);
}
-extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
- int nhwentries, enum dma_data_direction direction);
-extern void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
- size_t size, enum dma_data_direction direction);
-extern void dma_sync_single_for_device(struct device *dev,
- dma_addr_t dma_handle, size_t size, enum dma_data_direction direction);
-extern void dma_sync_single_range_for_cpu(struct device *dev,
- dma_addr_t dma_handle, unsigned long offset, size_t size,
- enum dma_data_direction direction);
-extern void dma_sync_single_range_for_device(struct device *dev,
- dma_addr_t dma_handle, unsigned long offset, size_t size,
- enum dma_data_direction direction);
-extern void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
- int nelems, enum dma_data_direction direction);
-extern void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
- int nelems, enum dma_data_direction direction);
-extern int dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
-extern int dma_supported(struct device *dev, u64 mask);
+static inline int dma_mapping_error(struct device *dev, u64 mask)
+{
+ struct dma_map_ops *ops = get_dma_ops(dev);
+ return ops->mapping_error(dev, mask);
+}
static inline int
dma_set_mask(struct device *dev, u64 mask)
@@ -65,4 +55,34 @@ dma_set_mask(struct device *dev, u64 mask)
extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction direction);
+static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t gfp)
+{
+ void *ret;
+ struct dma_map_ops *ops = get_dma_ops(dev);
+
+ ret = ops->alloc_coherent(dev, size, dma_handle, gfp);
+
+ debug_dma_alloc_coherent(dev, size, *dma_handle, ret);
+
+ return ret;
+}
+
+static inline void dma_free_coherent(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle)
+{
+ struct dma_map_ops *ops = get_dma_ops(dev);
+
+ ops->free_coherent(dev, size, vaddr, dma_handle);
+
+ debug_dma_free_coherent(dev, size, vaddr, dma_handle);
+}
+
+
+void *dma_alloc_noncoherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flag);
+
+void dma_free_noncoherent(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle);
+
#endif /* _ASM_DMA_MAPPING_H */
diff --git a/arch/mips/include/asm/dma.h b/arch/mips/include/asm/dma.h
index 1353c81065d1..2d47da62d5a7 100644
--- a/arch/mips/include/asm/dma.h
+++ b/arch/mips/include/asm/dma.h
@@ -91,7 +91,10 @@
#define MAX_DMA_ADDRESS (PAGE_OFFSET + 0x01000000)
#endif
#define MAX_DMA_PFN PFN_DOWN(virt_to_phys((void *)MAX_DMA_ADDRESS))
+
+#ifndef MAX_DMA32_PFN
#define MAX_DMA32_PFN (1UL << (32 - PAGE_SHIFT))
+#endif
/* 8237 DMA controllers */
#define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */
diff --git a/arch/mips/include/asm/highmem.h b/arch/mips/include/asm/highmem.h
index 75753ca73bfd..77e644082a3b 100644
--- a/arch/mips/include/asm/highmem.h
+++ b/arch/mips/include/asm/highmem.h
@@ -45,18 +45,12 @@ extern pte_t *pkmap_page_table;
extern void * kmap_high(struct page *page);
extern void kunmap_high(struct page *page);
-extern void *__kmap(struct page *page);
-extern void __kunmap(struct page *page);
-extern void *__kmap_atomic(struct page *page, enum km_type type);
-extern void __kunmap_atomic_notypecheck(void *kvaddr, enum km_type type);
-extern void *kmap_atomic_pfn(unsigned long pfn, enum km_type type);
-extern struct page *__kmap_atomic_to_page(void *ptr);
-
-#define kmap __kmap
-#define kunmap __kunmap
-#define kmap_atomic __kmap_atomic
-#define kunmap_atomic_notypecheck __kunmap_atomic_notypecheck
-#define kmap_atomic_to_page __kmap_atomic_to_page
+extern void *kmap(struct page *page);
+extern void kunmap(struct page *page);
+extern void *__kmap_atomic(struct page *page);
+extern void __kunmap_atomic(void *kvaddr);
+extern void *kmap_atomic_pfn(unsigned long pfn);
+extern struct page *kmap_atomic_to_page(void *ptr);
#define flush_cache_kmaps() flush_cache_all()
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/local.h b/arch/mips/include/asm/local.h
index bdcdef02d147..fffc8307a80a 100644
--- a/arch/mips/include/asm/local.h
+++ b/arch/mips/include/asm/local.h
@@ -117,7 +117,7 @@ static __inline__ long local_sub_return(long i, local_t * l)
#define local_cmpxchg(l, o, n) \
((long)cmpxchg_local(&((l)->a.counter), (o), (n)))
-#define local_xchg(l, n) (xchg_local(&((l)->a.counter), (n)))
+#define local_xchg(l, n) (atomic_long_xchg((&(l)->a), (n)))
/**
* local_add_unless - add unless the number is a given value
diff --git a/arch/mips/include/asm/mach-ar7/ar7.h b/arch/mips/include/asm/mach-ar7/ar7.h
index 483ffea9ecb1..7919d76186bf 100644
--- a/arch/mips/include/asm/mach-ar7/ar7.h
+++ b/arch/mips/include/asm/mach-ar7/ar7.h
@@ -39,6 +39,7 @@
#define AR7_REGS_UART0 (AR7_REGS_BASE + 0x0e00)
#define AR7_REGS_USB (AR7_REGS_BASE + 0x1200)
#define AR7_REGS_RESET (AR7_REGS_BASE + 0x1600)
+#define AR7_REGS_PINSEL (AR7_REGS_BASE + 0x160C)
#define AR7_REGS_VLYNQ0 (AR7_REGS_BASE + 0x1800)
#define AR7_REGS_DCL (AR7_REGS_BASE + 0x1a00)
#define AR7_REGS_VLYNQ1 (AR7_REGS_BASE + 0x1c00)
@@ -50,6 +51,14 @@
#define UR8_REGS_WDT (AR7_REGS_BASE + 0x0b00)
#define UR8_REGS_UART1 (AR7_REGS_BASE + 0x0f00)
+/* Titan registers */
+#define TITAN_REGS_ESWITCH_BASE (0x08640000)
+#define TITAN_REGS_MAC0 (TITAN_REGS_ESWITCH_BASE)
+#define TITAN_REGS_MAC1 (TITAN_REGS_ESWITCH_BASE + 0x0800)
+#define TITAN_REGS_MDIO (TITAN_REGS_ESWITCH_BASE + 0x02000)
+#define TITAN_REGS_VLYNQ0 (AR7_REGS_BASE + 0x1c00)
+#define TITAN_REGS_VLYNQ1 (AR7_REGS_BASE + 0x1300)
+
#define AR7_RESET_PERIPHERAL 0x0
#define AR7_RESET_SOFTWARE 0x4
#define AR7_RESET_STATUS 0x8
@@ -59,15 +68,30 @@
#define AR7_RESET_BIT_MDIO 22
#define AR7_RESET_BIT_EPHY 26
+#define TITAN_RESET_BIT_EPHY1 28
+
/* GPIO control registers */
#define AR7_GPIO_INPUT 0x0
#define AR7_GPIO_OUTPUT 0x4
#define AR7_GPIO_DIR 0x8
#define AR7_GPIO_ENABLE 0xc
+#define TITAN_GPIO_INPUT_0 0x0
+#define TITAN_GPIO_INPUT_1 0x4
+#define TITAN_GPIO_OUTPUT_0 0x8
+#define TITAN_GPIO_OUTPUT_1 0xc
+#define TITAN_GPIO_DIR_0 0x10
+#define TITAN_GPIO_DIR_1 0x14
+#define TITAN_GPIO_ENBL_0 0x18
+#define TITAN_GPIO_ENBL_1 0x1c
#define AR7_CHIP_7100 0x18
#define AR7_CHIP_7200 0x2b
#define AR7_CHIP_7300 0x05
+#define AR7_CHIP_TITAN 0x07
+#define TITAN_CHIP_1050 0x0f
+#define TITAN_CHIP_1055 0x0e
+#define TITAN_CHIP_1056 0x0d
+#define TITAN_CHIP_1060 0x07
/* Interrupts */
#define AR7_IRQ_UART0 15
@@ -95,14 +119,29 @@ struct plat_dsl_data {
extern int ar7_cpu_clock, ar7_bus_clock, ar7_dsp_clock;
+static inline int ar7_is_titan(void)
+{
+ return (readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x24)) & 0xffff) ==
+ AR7_CHIP_TITAN;
+}
+
static inline u16 ar7_chip_id(void)
{
- return readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x14)) & 0xffff;
+ return ar7_is_titan() ? AR7_CHIP_TITAN : (readl((void *)
+ KSEG1ADDR(AR7_REGS_GPIO + 0x14)) & 0xffff);
+}
+
+static inline u16 titan_chip_id(void)
+{
+ unsigned int val = readl((void *)KSEG1ADDR(AR7_REGS_GPIO +
+ TITAN_GPIO_INPUT_1));
+ return ((val >> 12) & 0x0f);
}
static inline u8 ar7_chip_rev(void)
{
- return (readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x14)) >> 16) & 0xff;
+ return (readl((void *)KSEG1ADDR(AR7_REGS_GPIO + (ar7_is_titan() ? 0x24 :
+ 0x14))) >> 16) & 0xff;
}
struct clk {
@@ -161,4 +200,8 @@ static inline void ar7_device_off(u32 bit)
msleep(20);
}
+int __init ar7_gpio_init(void);
+
+int __init ar7_gpio_init(void);
+
#endif /* __AR7_H__ */
diff --git a/arch/mips/include/asm/mach-ar7/gpio.h b/arch/mips/include/asm/mach-ar7/gpio.h
index abc317c0372e..c177cd1eed25 100644
--- a/arch/mips/include/asm/mach-ar7/gpio.h
+++ b/arch/mips/include/asm/mach-ar7/gpio.h
@@ -22,7 +22,8 @@
#include <asm/mach-ar7/ar7.h>
#define AR7_GPIO_MAX 32
-#define NR_BUILTIN_GPIO AR7_GPIO_MAX
+#define TITAN_GPIO_MAX 51
+#define NR_BUILTIN_GPIO TITAN_GPIO_MAX
#define gpio_to_irq(gpio) -1
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h b/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h
new file mode 100644
index 000000000000..5325084d5c48
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h
@@ -0,0 +1,97 @@
+#ifndef __BCM963XX_TAG_H
+#define __BCM963XX_TAG_H
+
+#define TAGVER_LEN 4 /* Length of Tag Version */
+#define TAGLAYOUT_LEN 4 /* Length of FlashLayoutVer */
+#define SIG1_LEN 20 /* Company Signature 1 Length */
+#define SIG2_LEN 14 /* Company Signature 2 Lenght */
+#define BOARDID_LEN 16 /* Length of BoardId */
+#define ENDIANFLAG_LEN 2 /* Endian Flag Length */
+#define CHIPID_LEN 6 /* Chip Id Length */
+#define IMAGE_LEN 10 /* Length of Length Field */
+#define ADDRESS_LEN 12 /* Length of Address field */
+#define DUALFLAG_LEN 2 /* Dual Image flag Length */
+#define INACTIVEFLAG_LEN 2 /* Inactie Flag Length */
+#define RSASIG_LEN 20 /* Length of RSA Signature in tag */
+#define TAGINFO1_LEN 30 /* Length of vendor information field1 in tag */
+#define FLASHLAYOUTVER_LEN 4 /* Length of Flash Layout Version String tag */
+#define TAGINFO2_LEN 16 /* Length of vendor information field2 in tag */
+#define CRC_LEN 4 /* Length of CRC in bytes */
+#define ALTTAGINFO_LEN 54 /* Alternate length for vendor information; Pirelli */
+
+#define NUM_PIRELLI 2
+#define IMAGETAG_CRC_START 0xFFFFFFFF
+
+#define PIRELLI_BOARDS { \
+ "AGPF-S0", \
+ "DWV-S0", \
+}
+
+/*
+ * The broadcom firmware assumes the rootfs starts the image,
+ * therefore uses the rootfs start (flash_image_address)
+ * to determine where to flash the image. Since we have the kernel first
+ * we have to give it the kernel address, but the crc uses the length
+ * associated with this address (root_length), which is added to the kernel
+ * length (kernel_length) to determine the length of image to flash and thus
+ * needs to be rootfs + deadcode (jffs2 EOF marker)
+*/
+
+struct bcm_tag {
+ /* 0-3: Version of the image tag */
+ char tag_version[TAGVER_LEN];
+ /* 4-23: Company Line 1 */
+ char sig_1[SIG1_LEN];
+ /* 24-37: Company Line 2 */
+ char sig_2[SIG2_LEN];
+ /* 38-43: Chip this image is for */
+ char chip_id[CHIPID_LEN];
+ /* 44-59: Board name */
+ char board_id[BOARDID_LEN];
+ /* 60-61: Map endianness -- 1 BE 0 LE */
+ char big_endian[ENDIANFLAG_LEN];
+ /* 62-71: Total length of image */
+ char total_length[IMAGE_LEN];
+ /* 72-83: Address in memory of CFE */
+ char cfe__address[ADDRESS_LEN];
+ /* 84-93: Size of CFE */
+ char cfe_length[IMAGE_LEN];
+ /* 94-105: Address in memory of image start
+ * (kernel for OpenWRT, rootfs for stock firmware)
+ */
+ char flash_image_start[ADDRESS_LEN];
+ /* 106-115: Size of rootfs */
+ char root_length[IMAGE_LEN];
+ /* 116-127: Address in memory of kernel */
+ char kernel_address[ADDRESS_LEN];
+ /* 128-137: Size of kernel */
+ char kernel_length[IMAGE_LEN];
+ /* 138-139: Unused at the moment */
+ char dual_image[DUALFLAG_LEN];
+ /* 140-141: Unused at the moment */
+ char inactive_flag[INACTIVEFLAG_LEN];
+ /* 142-161: RSA Signature (not used; some vendors may use this) */
+ char rsa_signature[RSASIG_LEN];
+ /* 162-191: Compilation and related information (not used in OpenWrt) */
+ char information1[TAGINFO1_LEN];
+ /* 192-195: Version flash layout */
+ char flash_layout_ver[FLASHLAYOUTVER_LEN];
+ /* 196-199: kernel+rootfs CRC32 */
+ char fskernel_crc[CRC_LEN];
+ /* 200-215: Unused except on Alice Gate where is is information */
+ char information2[TAGINFO2_LEN];
+ /* 216-219: CRC32 of image less imagetag (kernel for Alice Gate) */
+ char image_crc[CRC_LEN];
+ /* 220-223: CRC32 of rootfs partition */
+ char rootfs_crc[CRC_LEN];
+ /* 224-227: CRC32 of kernel partition */
+ char kernel_crc[CRC_LEN];
+ /* 228-235: Unused at present */
+ char reserved1[8];
+ /* 236-239: CRC32 of header excluding tagVersion */
+ char header_crc[CRC_LEN];
+ /* 240-255: Unused at present */
+ char reserved2[16];
+};
+
+#endif /* __BCM63XX_TAG_H */
diff --git a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
index b952fc7215e2..0d5a42b5f47a 100644
--- a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
@@ -59,7 +59,7 @@
#define cpu_has_veic 0
#define cpu_hwrena_impl_bits 0xc0000000
-#define kernel_uses_smartmips_rixi (cpu_data[0].cputype == CPU_CAVIUM_OCTEON_PLUS)
+#define kernel_uses_smartmips_rixi (cpu_data[0].cputype != CPU_CAVIUM_OCTEON)
#define ARCH_HAS_IRQ_PER_CPU 1
#define ARCH_HAS_SPINLOCK_PREFETCH 1
@@ -81,4 +81,10 @@ static inline int octeon_has_saa(void)
return id >= 0x000d0300;
}
+/*
+ * The last 256MB are reserved for device to device mappings and the
+ * BAR1 hole.
+ */
+#define MAX_DMA32_PFN (((1ULL << 32) - (1ULL << 28)) >> PAGE_SHIFT)
+
#endif
diff --git a/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h b/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
index 17d579471ec4..be8fb4240cec 100644
--- a/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
+++ b/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
@@ -15,41 +15,40 @@
struct device;
-dma_addr_t octeon_map_dma_mem(struct device *, void *, size_t);
-void octeon_unmap_dma_mem(struct device *, dma_addr_t);
+extern void octeon_pci_dma_init(void);
static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
size_t size)
{
- return octeon_map_dma_mem(dev, addr, size);
+ BUG();
}
static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
struct page *page)
{
- return octeon_map_dma_mem(dev, page_address(page), PAGE_SIZE);
+ BUG();
}
static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
dma_addr_t dma_addr)
{
- return dma_addr;
+ BUG();
}
static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
size_t size, enum dma_data_direction direction)
{
- octeon_unmap_dma_mem(dev, dma_addr);
+ BUG();
}
static inline int plat_dma_supported(struct device *dev, u64 mask)
{
- return 1;
+ BUG();
}
static inline void plat_extra_sync_for_device(struct device *dev)
{
- mb();
+ BUG();
}
static inline int plat_device_is_coherent(struct device *dev)
@@ -60,7 +59,14 @@ static inline int plat_device_is_coherent(struct device *dev)
static inline int plat_dma_mapping_error(struct device *dev,
dma_addr_t dma_addr)
{
- return dma_addr == -1;
+ BUG();
}
+dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
+phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);
+
+struct dma_map_ops;
+extern struct dma_map_ops *octeon_pci_dma_map_ops;
+extern char *octeon_swiotlb;
+
#endif /* __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H */
diff --git a/arch/mips/include/asm/mach-ip27/dma-coherence.h b/arch/mips/include/asm/mach-ip27/dma-coherence.h
index d3d04018a858..016d0989b141 100644
--- a/arch/mips/include/asm/mach-ip27/dma-coherence.h
+++ b/arch/mips/include/asm/mach-ip27/dma-coherence.h
@@ -26,14 +26,15 @@ static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
return pa;
}
-static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
+static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
+ struct page *page)
{
dma_addr_t pa = dev_to_baddr(dev, page_to_phys(page));
return pa;
}
-static unsigned long plat_dma_addr_to_phys(struct device *dev,
+static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
dma_addr_t dma_addr)
{
return dma_addr & ~(0xffUL << 56);
diff --git a/arch/mips/include/asm/mach-ip32/dma-coherence.h b/arch/mips/include/asm/mach-ip32/dma-coherence.h
index 37855955b313..c8fb5aacf50a 100644
--- a/arch/mips/include/asm/mach-ip32/dma-coherence.h
+++ b/arch/mips/include/asm/mach-ip32/dma-coherence.h
@@ -37,7 +37,8 @@ static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
return pa;
}
-static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
+static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
+ struct page *page)
{
dma_addr_t pa;
@@ -50,7 +51,7 @@ static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
}
/* This is almost certainly wrong but it's what dma-ip32.c used to use */
-static unsigned long plat_dma_addr_to_phys(struct device *dev,
+static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
dma_addr_t dma_addr)
{
unsigned long addr = dma_addr & RAM_OFFSET_MASK;
diff --git a/arch/mips/include/asm/mach-jazz/dma-coherence.h b/arch/mips/include/asm/mach-jazz/dma-coherence.h
index f93aee59454a..302101b54acb 100644
--- a/arch/mips/include/asm/mach-jazz/dma-coherence.h
+++ b/arch/mips/include/asm/mach-jazz/dma-coherence.h
@@ -12,23 +12,24 @@
struct device;
-static dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size)
+static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size)
{
return vdma_alloc(virt_to_phys(addr), size);
}
-static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
+static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
+ struct page *page)
{
return vdma_alloc(page_to_phys(page), PAGE_SIZE);
}
-static unsigned long plat_dma_addr_to_phys(struct device *dev,
+static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
dma_addr_t dma_addr)
{
return vdma_log2phys(dma_addr);
}
-static void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
+static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
size_t size, enum dma_data_direction direction)
{
vdma_free(dma_addr);
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/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 335474c155f6..4d9870975382 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -1040,6 +1040,12 @@ do { \
#define read_c0_dtaglo() __read_32bit_c0_register($28, 2)
#define write_c0_dtaglo(val) __write_32bit_c0_register($28, 2, val)
+#define read_c0_ddatalo() __read_32bit_c0_register($28, 3)
+#define write_c0_ddatalo(val) __write_32bit_c0_register($28, 3, val)
+
+#define read_c0_staglo() __read_32bit_c0_register($28, 4)
+#define write_c0_staglo(val) __write_32bit_c0_register($28, 4, val)
+
#define read_c0_taghi() __read_32bit_c0_register($29, 0)
#define write_c0_taghi(val) __write_32bit_c0_register($29, 0, val)
@@ -1082,6 +1088,51 @@ do { \
#define read_octeon_c0_dcacheerr() __read_64bit_c0_register($27, 1)
#define write_octeon_c0_dcacheerr(val) __write_64bit_c0_register($27, 1, val)
+/* BMIPS3300 */
+#define read_c0_brcm_config_0() __read_32bit_c0_register($22, 0)
+#define write_c0_brcm_config_0(val) __write_32bit_c0_register($22, 0, val)
+
+#define read_c0_brcm_bus_pll() __read_32bit_c0_register($22, 4)
+#define write_c0_brcm_bus_pll(val) __write_32bit_c0_register($22, 4, val)
+
+#define read_c0_brcm_reset() __read_32bit_c0_register($22, 5)
+#define write_c0_brcm_reset(val) __write_32bit_c0_register($22, 5, val)
+
+/* BMIPS4380 */
+#define read_c0_brcm_cmt_intr() __read_32bit_c0_register($22, 1)
+#define write_c0_brcm_cmt_intr(val) __write_32bit_c0_register($22, 1, val)
+
+#define read_c0_brcm_cmt_ctrl() __read_32bit_c0_register($22, 2)
+#define write_c0_brcm_cmt_ctrl(val) __write_32bit_c0_register($22, 2, val)
+
+#define read_c0_brcm_cmt_local() __read_32bit_c0_register($22, 3)
+#define write_c0_brcm_cmt_local(val) __write_32bit_c0_register($22, 3, val)
+
+#define read_c0_brcm_config_1() __read_32bit_c0_register($22, 5)
+#define write_c0_brcm_config_1(val) __write_32bit_c0_register($22, 5, val)
+
+#define read_c0_brcm_cbr() __read_32bit_c0_register($22, 6)
+#define write_c0_brcm_cbr(val) __write_32bit_c0_register($22, 6, val)
+
+/* BMIPS5000 */
+#define read_c0_brcm_config() __read_32bit_c0_register($22, 0)
+#define write_c0_brcm_config(val) __write_32bit_c0_register($22, 0, val)
+
+#define read_c0_brcm_mode() __read_32bit_c0_register($22, 1)
+#define write_c0_brcm_mode(val) __write_32bit_c0_register($22, 1, val)
+
+#define read_c0_brcm_action() __read_32bit_c0_register($22, 2)
+#define write_c0_brcm_action(val) __write_32bit_c0_register($22, 2, val)
+
+#define read_c0_brcm_edsp() __read_32bit_c0_register($22, 3)
+#define write_c0_brcm_edsp(val) __write_32bit_c0_register($22, 3, val)
+
+#define read_c0_brcm_bootvec() __read_32bit_c0_register($22, 4)
+#define write_c0_brcm_bootvec(val) __write_32bit_c0_register($22, 4, val)
+
+#define read_c0_brcm_sleepcount() __read_32bit_c0_register($22, 7)
+#define write_c0_brcm_sleepcount(val) __write_32bit_c0_register($22, 7, val)
+
/*
* Macros to access the floating point coprocessor control registers
*/
diff --git a/arch/mips/include/asm/octeon/cvmx-agl-defs.h b/arch/mips/include/asm/octeon/cvmx-agl-defs.h
index ec94b9ab7be1..30d68f2365e0 100644
--- a/arch/mips/include/asm/octeon/cvmx-agl-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-agl-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
@@ -28,148 +28,80 @@
#ifndef __CVMX_AGL_DEFS_H__
#define __CVMX_AGL_DEFS_H__
-#define CVMX_AGL_GMX_BAD_REG \
- CVMX_ADD_IO_SEG(0x00011800E0000518ull)
-#define CVMX_AGL_GMX_BIST \
- CVMX_ADD_IO_SEG(0x00011800E0000400ull)
-#define CVMX_AGL_GMX_DRV_CTL \
- CVMX_ADD_IO_SEG(0x00011800E00007F0ull)
-#define CVMX_AGL_GMX_INF_MODE \
- CVMX_ADD_IO_SEG(0x00011800E00007F8ull)
-#define CVMX_AGL_GMX_PRTX_CFG(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000010ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_ADR_CAM0(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000180ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_ADR_CAM1(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000188ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_ADR_CAM2(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000190ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_ADR_CAM3(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000198ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_ADR_CAM4(offset) \
- CVMX_ADD_IO_SEG(0x00011800E00001A0ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_ADR_CAM5(offset) \
- CVMX_ADD_IO_SEG(0x00011800E00001A8ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_ADR_CAM_EN(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000108ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_ADR_CTL(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000100ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_DECISION(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000040ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_FRM_CHK(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000020ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_FRM_CTL(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000018ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_FRM_MAX(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000030ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_FRM_MIN(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000028ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_IFG(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000058ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_INT_EN(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000008ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_INT_REG(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000000ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_JABBER(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000038ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_PAUSE_DROP_TIME(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000068ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_CTL(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000050ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_OCTS(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000088ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_OCTS_CTL(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000098ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_OCTS_DMAC(offset) \
- CVMX_ADD_IO_SEG(0x00011800E00000A8ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_OCTS_DRP(offset) \
- CVMX_ADD_IO_SEG(0x00011800E00000B8ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_PKTS(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000080ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_PKTS_BAD(offset) \
- CVMX_ADD_IO_SEG(0x00011800E00000C0ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_PKTS_CTL(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000090ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_PKTS_DMAC(offset) \
- CVMX_ADD_IO_SEG(0x00011800E00000A0ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_PKTS_DRP(offset) \
- CVMX_ADD_IO_SEG(0x00011800E00000B0ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_UDD_SKP(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000048ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RX_BP_DROPX(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000420ull + (((offset) & 1) * 8))
-#define CVMX_AGL_GMX_RX_BP_OFFX(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000460ull + (((offset) & 1) * 8))
-#define CVMX_AGL_GMX_RX_BP_ONX(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000440ull + (((offset) & 1) * 8))
-#define CVMX_AGL_GMX_RX_PRT_INFO \
- CVMX_ADD_IO_SEG(0x00011800E00004E8ull)
-#define CVMX_AGL_GMX_RX_TX_STATUS \
- CVMX_ADD_IO_SEG(0x00011800E00007E8ull)
-#define CVMX_AGL_GMX_SMACX(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000230ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_STAT_BP \
- CVMX_ADD_IO_SEG(0x00011800E0000520ull)
-#define CVMX_AGL_GMX_TXX_APPEND(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000218ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_CTL(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000270ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_MIN_PKT(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000240ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_PAUSE_PKT_INTERVAL(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000248ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_PAUSE_PKT_TIME(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000238ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_PAUSE_TOGO(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000258ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_PAUSE_ZERO(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000260ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_SOFT_PAUSE(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000250ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT0(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000280ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT1(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000288ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT2(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000290ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT3(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000298ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT4(offset) \
- CVMX_ADD_IO_SEG(0x00011800E00002A0ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT5(offset) \
- CVMX_ADD_IO_SEG(0x00011800E00002A8ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT6(offset) \
- CVMX_ADD_IO_SEG(0x00011800E00002B0ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT7(offset) \
- CVMX_ADD_IO_SEG(0x00011800E00002B8ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT8(offset) \
- CVMX_ADD_IO_SEG(0x00011800E00002C0ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT9(offset) \
- CVMX_ADD_IO_SEG(0x00011800E00002C8ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STATS_CTL(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000268ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_THRESH(offset) \
- CVMX_ADD_IO_SEG(0x00011800E0000210ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TX_BP \
- CVMX_ADD_IO_SEG(0x00011800E00004D0ull)
-#define CVMX_AGL_GMX_TX_COL_ATTEMPT \
- CVMX_ADD_IO_SEG(0x00011800E0000498ull)
-#define CVMX_AGL_GMX_TX_IFG \
- CVMX_ADD_IO_SEG(0x00011800E0000488ull)
-#define CVMX_AGL_GMX_TX_INT_EN \
- CVMX_ADD_IO_SEG(0x00011800E0000508ull)
-#define CVMX_AGL_GMX_TX_INT_REG \
- CVMX_ADD_IO_SEG(0x00011800E0000500ull)
-#define CVMX_AGL_GMX_TX_JAM \
- CVMX_ADD_IO_SEG(0x00011800E0000490ull)
-#define CVMX_AGL_GMX_TX_LFSR \
- CVMX_ADD_IO_SEG(0x00011800E00004F8ull)
-#define CVMX_AGL_GMX_TX_OVR_BP \
- CVMX_ADD_IO_SEG(0x00011800E00004C8ull)
-#define CVMX_AGL_GMX_TX_PAUSE_PKT_DMAC \
- CVMX_ADD_IO_SEG(0x00011800E00004A0ull)
-#define CVMX_AGL_GMX_TX_PAUSE_PKT_TYPE \
- CVMX_ADD_IO_SEG(0x00011800E00004A8ull)
+#define CVMX_AGL_GMX_BAD_REG (CVMX_ADD_IO_SEG(0x00011800E0000518ull))
+#define CVMX_AGL_GMX_BIST (CVMX_ADD_IO_SEG(0x00011800E0000400ull))
+#define CVMX_AGL_GMX_DRV_CTL (CVMX_ADD_IO_SEG(0x00011800E00007F0ull))
+#define CVMX_AGL_GMX_INF_MODE (CVMX_ADD_IO_SEG(0x00011800E00007F8ull))
+#define CVMX_AGL_GMX_PRTX_CFG(offset) (CVMX_ADD_IO_SEG(0x00011800E0000010ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_ADR_CAM0(offset) (CVMX_ADD_IO_SEG(0x00011800E0000180ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_ADR_CAM1(offset) (CVMX_ADD_IO_SEG(0x00011800E0000188ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_ADR_CAM2(offset) (CVMX_ADD_IO_SEG(0x00011800E0000190ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_ADR_CAM3(offset) (CVMX_ADD_IO_SEG(0x00011800E0000198ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_ADR_CAM4(offset) (CVMX_ADD_IO_SEG(0x00011800E00001A0ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_ADR_CAM5(offset) (CVMX_ADD_IO_SEG(0x00011800E00001A8ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_ADR_CAM_EN(offset) (CVMX_ADD_IO_SEG(0x00011800E0000108ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_ADR_CTL(offset) (CVMX_ADD_IO_SEG(0x00011800E0000100ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_DECISION(offset) (CVMX_ADD_IO_SEG(0x00011800E0000040ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_FRM_CHK(offset) (CVMX_ADD_IO_SEG(0x00011800E0000020ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_FRM_CTL(offset) (CVMX_ADD_IO_SEG(0x00011800E0000018ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_FRM_MAX(offset) (CVMX_ADD_IO_SEG(0x00011800E0000030ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_FRM_MIN(offset) (CVMX_ADD_IO_SEG(0x00011800E0000028ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_IFG(offset) (CVMX_ADD_IO_SEG(0x00011800E0000058ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_INT_EN(offset) (CVMX_ADD_IO_SEG(0x00011800E0000008ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_INT_REG(offset) (CVMX_ADD_IO_SEG(0x00011800E0000000ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_JABBER(offset) (CVMX_ADD_IO_SEG(0x00011800E0000038ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_PAUSE_DROP_TIME(offset) (CVMX_ADD_IO_SEG(0x00011800E0000068ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_RX_INBND(offset) (CVMX_ADD_IO_SEG(0x00011800E0000060ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_CTL(offset) (CVMX_ADD_IO_SEG(0x00011800E0000050ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_OCTS(offset) (CVMX_ADD_IO_SEG(0x00011800E0000088ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_OCTS_CTL(offset) (CVMX_ADD_IO_SEG(0x00011800E0000098ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_OCTS_DMAC(offset) (CVMX_ADD_IO_SEG(0x00011800E00000A8ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_OCTS_DRP(offset) (CVMX_ADD_IO_SEG(0x00011800E00000B8ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_PKTS(offset) (CVMX_ADD_IO_SEG(0x00011800E0000080ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_PKTS_BAD(offset) (CVMX_ADD_IO_SEG(0x00011800E00000C0ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_PKTS_CTL(offset) (CVMX_ADD_IO_SEG(0x00011800E0000090ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_PKTS_DMAC(offset) (CVMX_ADD_IO_SEG(0x00011800E00000A0ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_PKTS_DRP(offset) (CVMX_ADD_IO_SEG(0x00011800E00000B0ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_UDD_SKP(offset) (CVMX_ADD_IO_SEG(0x00011800E0000048ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RX_BP_DROPX(offset) (CVMX_ADD_IO_SEG(0x00011800E0000420ull) + ((offset) & 1) * 8)
+#define CVMX_AGL_GMX_RX_BP_OFFX(offset) (CVMX_ADD_IO_SEG(0x00011800E0000460ull) + ((offset) & 1) * 8)
+#define CVMX_AGL_GMX_RX_BP_ONX(offset) (CVMX_ADD_IO_SEG(0x00011800E0000440ull) + ((offset) & 1) * 8)
+#define CVMX_AGL_GMX_RX_PRT_INFO (CVMX_ADD_IO_SEG(0x00011800E00004E8ull))
+#define CVMX_AGL_GMX_RX_TX_STATUS (CVMX_ADD_IO_SEG(0x00011800E00007E8ull))
+#define CVMX_AGL_GMX_SMACX(offset) (CVMX_ADD_IO_SEG(0x00011800E0000230ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_STAT_BP (CVMX_ADD_IO_SEG(0x00011800E0000520ull))
+#define CVMX_AGL_GMX_TXX_APPEND(offset) (CVMX_ADD_IO_SEG(0x00011800E0000218ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_CLK(offset) (CVMX_ADD_IO_SEG(0x00011800E0000208ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_CTL(offset) (CVMX_ADD_IO_SEG(0x00011800E0000270ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_MIN_PKT(offset) (CVMX_ADD_IO_SEG(0x00011800E0000240ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_PAUSE_PKT_INTERVAL(offset) (CVMX_ADD_IO_SEG(0x00011800E0000248ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_PAUSE_PKT_TIME(offset) (CVMX_ADD_IO_SEG(0x00011800E0000238ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_PAUSE_TOGO(offset) (CVMX_ADD_IO_SEG(0x00011800E0000258ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_PAUSE_ZERO(offset) (CVMX_ADD_IO_SEG(0x00011800E0000260ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_SOFT_PAUSE(offset) (CVMX_ADD_IO_SEG(0x00011800E0000250ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT0(offset) (CVMX_ADD_IO_SEG(0x00011800E0000280ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT1(offset) (CVMX_ADD_IO_SEG(0x00011800E0000288ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT2(offset) (CVMX_ADD_IO_SEG(0x00011800E0000290ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT3(offset) (CVMX_ADD_IO_SEG(0x00011800E0000298ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT4(offset) (CVMX_ADD_IO_SEG(0x00011800E00002A0ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT5(offset) (CVMX_ADD_IO_SEG(0x00011800E00002A8ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT6(offset) (CVMX_ADD_IO_SEG(0x00011800E00002B0ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT7(offset) (CVMX_ADD_IO_SEG(0x00011800E00002B8ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT8(offset) (CVMX_ADD_IO_SEG(0x00011800E00002C0ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT9(offset) (CVMX_ADD_IO_SEG(0x00011800E00002C8ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STATS_CTL(offset) (CVMX_ADD_IO_SEG(0x00011800E0000268ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_THRESH(offset) (CVMX_ADD_IO_SEG(0x00011800E0000210ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TX_BP (CVMX_ADD_IO_SEG(0x00011800E00004D0ull))
+#define CVMX_AGL_GMX_TX_COL_ATTEMPT (CVMX_ADD_IO_SEG(0x00011800E0000498ull))
+#define CVMX_AGL_GMX_TX_IFG (CVMX_ADD_IO_SEG(0x00011800E0000488ull))
+#define CVMX_AGL_GMX_TX_INT_EN (CVMX_ADD_IO_SEG(0x00011800E0000508ull))
+#define CVMX_AGL_GMX_TX_INT_REG (CVMX_ADD_IO_SEG(0x00011800E0000500ull))
+#define CVMX_AGL_GMX_TX_JAM (CVMX_ADD_IO_SEG(0x00011800E0000490ull))
+#define CVMX_AGL_GMX_TX_LFSR (CVMX_ADD_IO_SEG(0x00011800E00004F8ull))
+#define CVMX_AGL_GMX_TX_OVR_BP (CVMX_ADD_IO_SEG(0x00011800E00004C8ull))
+#define CVMX_AGL_GMX_TX_PAUSE_PKT_DMAC (CVMX_ADD_IO_SEG(0x00011800E00004A0ull))
+#define CVMX_AGL_GMX_TX_PAUSE_PKT_TYPE (CVMX_ADD_IO_SEG(0x00011800E00004A8ull))
+#define CVMX_AGL_PRTX_CTL(offset) (CVMX_ADD_IO_SEG(0x00011800E0002000ull) + ((offset) & 1) * 8)
union cvmx_agl_gmx_bad_reg {
uint64_t u64;
@@ -183,14 +115,29 @@ union cvmx_agl_gmx_bad_reg {
uint64_t ovrflw:1;
uint64_t reserved_27_31:5;
uint64_t statovr:1;
+ uint64_t reserved_24_25:2;
+ uint64_t loststat:2;
+ uint64_t reserved_4_21:18;
+ uint64_t out_ovr:2;
+ uint64_t reserved_0_1:2;
+ } s;
+ struct cvmx_agl_gmx_bad_reg_cn52xx {
+ uint64_t reserved_38_63:26;
+ uint64_t txpsh1:1;
+ uint64_t txpop1:1;
+ uint64_t ovrflw1:1;
+ uint64_t txpsh:1;
+ uint64_t txpop:1;
+ uint64_t ovrflw:1;
+ uint64_t reserved_27_31:5;
+ uint64_t statovr:1;
uint64_t reserved_23_25:3;
uint64_t loststat:1;
uint64_t reserved_4_21:18;
uint64_t out_ovr:2;
uint64_t reserved_0_1:2;
- } s;
- struct cvmx_agl_gmx_bad_reg_s cn52xx;
- struct cvmx_agl_gmx_bad_reg_s cn52xxp1;
+ } cn52xx;
+ struct cvmx_agl_gmx_bad_reg_cn52xx cn52xxp1;
struct cvmx_agl_gmx_bad_reg_cn56xx {
uint64_t reserved_35_63:29;
uint64_t txpsh:1;
@@ -205,18 +152,25 @@ union cvmx_agl_gmx_bad_reg {
uint64_t reserved_0_1:2;
} cn56xx;
struct cvmx_agl_gmx_bad_reg_cn56xx cn56xxp1;
+ struct cvmx_agl_gmx_bad_reg_s cn63xx;
+ struct cvmx_agl_gmx_bad_reg_s cn63xxp1;
};
union cvmx_agl_gmx_bist {
uint64_t u64;
struct cvmx_agl_gmx_bist_s {
+ uint64_t reserved_25_63:39;
+ uint64_t status:25;
+ } s;
+ struct cvmx_agl_gmx_bist_cn52xx {
uint64_t reserved_10_63:54;
uint64_t status:10;
- } s;
- struct cvmx_agl_gmx_bist_s cn52xx;
- struct cvmx_agl_gmx_bist_s cn52xxp1;
- struct cvmx_agl_gmx_bist_s cn56xx;
- struct cvmx_agl_gmx_bist_s cn56xxp1;
+ } cn52xx;
+ struct cvmx_agl_gmx_bist_cn52xx cn52xxp1;
+ struct cvmx_agl_gmx_bist_cn52xx cn56xx;
+ struct cvmx_agl_gmx_bist_cn52xx cn56xxp1;
+ struct cvmx_agl_gmx_bist_s cn63xx;
+ struct cvmx_agl_gmx_bist_s cn63xxp1;
};
union cvmx_agl_gmx_drv_ctl {
@@ -264,7 +218,13 @@ union cvmx_agl_gmx_inf_mode {
union cvmx_agl_gmx_prtx_cfg {
uint64_t u64;
struct cvmx_agl_gmx_prtx_cfg_s {
- uint64_t reserved_6_63:58;
+ uint64_t reserved_14_63:50;
+ uint64_t tx_idle:1;
+ uint64_t rx_idle:1;
+ uint64_t reserved_9_11:3;
+ uint64_t speed_msb:1;
+ uint64_t reserved_7_7:1;
+ uint64_t burst:1;
uint64_t tx_en:1;
uint64_t rx_en:1;
uint64_t slottime:1;
@@ -272,10 +232,20 @@ union cvmx_agl_gmx_prtx_cfg {
uint64_t speed:1;
uint64_t en:1;
} s;
- struct cvmx_agl_gmx_prtx_cfg_s cn52xx;
- struct cvmx_agl_gmx_prtx_cfg_s cn52xxp1;
- struct cvmx_agl_gmx_prtx_cfg_s cn56xx;
- struct cvmx_agl_gmx_prtx_cfg_s cn56xxp1;
+ struct cvmx_agl_gmx_prtx_cfg_cn52xx {
+ uint64_t reserved_6_63:58;
+ uint64_t tx_en:1;
+ uint64_t rx_en:1;
+ uint64_t slottime:1;
+ uint64_t duplex:1;
+ uint64_t speed:1;
+ uint64_t en:1;
+ } cn52xx;
+ struct cvmx_agl_gmx_prtx_cfg_cn52xx cn52xxp1;
+ struct cvmx_agl_gmx_prtx_cfg_cn52xx cn56xx;
+ struct cvmx_agl_gmx_prtx_cfg_cn52xx cn56xxp1;
+ struct cvmx_agl_gmx_prtx_cfg_s cn63xx;
+ struct cvmx_agl_gmx_prtx_cfg_s cn63xxp1;
};
union cvmx_agl_gmx_rxx_adr_cam0 {
@@ -287,6 +257,8 @@ union cvmx_agl_gmx_rxx_adr_cam0 {
struct cvmx_agl_gmx_rxx_adr_cam0_s cn52xxp1;
struct cvmx_agl_gmx_rxx_adr_cam0_s cn56xx;
struct cvmx_agl_gmx_rxx_adr_cam0_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam0_s cn63xx;
+ struct cvmx_agl_gmx_rxx_adr_cam0_s cn63xxp1;
};
union cvmx_agl_gmx_rxx_adr_cam1 {
@@ -298,6 +270,8 @@ union cvmx_agl_gmx_rxx_adr_cam1 {
struct cvmx_agl_gmx_rxx_adr_cam1_s cn52xxp1;
struct cvmx_agl_gmx_rxx_adr_cam1_s cn56xx;
struct cvmx_agl_gmx_rxx_adr_cam1_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam1_s cn63xx;
+ struct cvmx_agl_gmx_rxx_adr_cam1_s cn63xxp1;
};
union cvmx_agl_gmx_rxx_adr_cam2 {
@@ -309,6 +283,8 @@ union cvmx_agl_gmx_rxx_adr_cam2 {
struct cvmx_agl_gmx_rxx_adr_cam2_s cn52xxp1;
struct cvmx_agl_gmx_rxx_adr_cam2_s cn56xx;
struct cvmx_agl_gmx_rxx_adr_cam2_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam2_s cn63xx;
+ struct cvmx_agl_gmx_rxx_adr_cam2_s cn63xxp1;
};
union cvmx_agl_gmx_rxx_adr_cam3 {
@@ -320,6 +296,8 @@ union cvmx_agl_gmx_rxx_adr_cam3 {
struct cvmx_agl_gmx_rxx_adr_cam3_s cn52xxp1;
struct cvmx_agl_gmx_rxx_adr_cam3_s cn56xx;
struct cvmx_agl_gmx_rxx_adr_cam3_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam3_s cn63xx;
+ struct cvmx_agl_gmx_rxx_adr_cam3_s cn63xxp1;
};
union cvmx_agl_gmx_rxx_adr_cam4 {
@@ -331,6 +309,8 @@ union cvmx_agl_gmx_rxx_adr_cam4 {
struct cvmx_agl_gmx_rxx_adr_cam4_s cn52xxp1;
struct cvmx_agl_gmx_rxx_adr_cam4_s cn56xx;
struct cvmx_agl_gmx_rxx_adr_cam4_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam4_s cn63xx;
+ struct cvmx_agl_gmx_rxx_adr_cam4_s cn63xxp1;
};
union cvmx_agl_gmx_rxx_adr_cam5 {
@@ -342,6 +322,8 @@ union cvmx_agl_gmx_rxx_adr_cam5 {
struct cvmx_agl_gmx_rxx_adr_cam5_s cn52xxp1;
struct cvmx_agl_gmx_rxx_adr_cam5_s cn56xx;
struct cvmx_agl_gmx_rxx_adr_cam5_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam5_s cn63xx;
+ struct cvmx_agl_gmx_rxx_adr_cam5_s cn63xxp1;
};
union cvmx_agl_gmx_rxx_adr_cam_en {
@@ -354,6 +336,8 @@ union cvmx_agl_gmx_rxx_adr_cam_en {
struct cvmx_agl_gmx_rxx_adr_cam_en_s cn52xxp1;
struct cvmx_agl_gmx_rxx_adr_cam_en_s cn56xx;
struct cvmx_agl_gmx_rxx_adr_cam_en_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam_en_s cn63xx;
+ struct cvmx_agl_gmx_rxx_adr_cam_en_s cn63xxp1;
};
union cvmx_agl_gmx_rxx_adr_ctl {
@@ -368,6 +352,8 @@ union cvmx_agl_gmx_rxx_adr_ctl {
struct cvmx_agl_gmx_rxx_adr_ctl_s cn52xxp1;
struct cvmx_agl_gmx_rxx_adr_ctl_s cn56xx;
struct cvmx_agl_gmx_rxx_adr_ctl_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_adr_ctl_s cn63xx;
+ struct cvmx_agl_gmx_rxx_adr_ctl_s cn63xxp1;
};
union cvmx_agl_gmx_rxx_decision {
@@ -380,11 +366,26 @@ union cvmx_agl_gmx_rxx_decision {
struct cvmx_agl_gmx_rxx_decision_s cn52xxp1;
struct cvmx_agl_gmx_rxx_decision_s cn56xx;
struct cvmx_agl_gmx_rxx_decision_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_decision_s cn63xx;
+ struct cvmx_agl_gmx_rxx_decision_s cn63xxp1;
};
union cvmx_agl_gmx_rxx_frm_chk {
uint64_t u64;
struct cvmx_agl_gmx_rxx_frm_chk_s {
+ uint64_t reserved_10_63:54;
+ uint64_t niberr:1;
+ uint64_t skperr:1;
+ uint64_t rcverr:1;
+ uint64_t lenerr:1;
+ uint64_t alnerr:1;
+ uint64_t fcserr:1;
+ uint64_t jabber:1;
+ uint64_t maxerr:1;
+ uint64_t carext:1;
+ uint64_t minerr:1;
+ } s;
+ struct cvmx_agl_gmx_rxx_frm_chk_cn52xx {
uint64_t reserved_9_63:55;
uint64_t skperr:1;
uint64_t rcverr:1;
@@ -395,17 +396,21 @@ union cvmx_agl_gmx_rxx_frm_chk {
uint64_t maxerr:1;
uint64_t reserved_1_1:1;
uint64_t minerr:1;
- } s;
- struct cvmx_agl_gmx_rxx_frm_chk_s cn52xx;
- struct cvmx_agl_gmx_rxx_frm_chk_s cn52xxp1;
- struct cvmx_agl_gmx_rxx_frm_chk_s cn56xx;
- struct cvmx_agl_gmx_rxx_frm_chk_s cn56xxp1;
+ } cn52xx;
+ struct cvmx_agl_gmx_rxx_frm_chk_cn52xx cn52xxp1;
+ struct cvmx_agl_gmx_rxx_frm_chk_cn52xx cn56xx;
+ struct cvmx_agl_gmx_rxx_frm_chk_cn52xx cn56xxp1;
+ struct cvmx_agl_gmx_rxx_frm_chk_s cn63xx;
+ struct cvmx_agl_gmx_rxx_frm_chk_s cn63xxp1;
};
union cvmx_agl_gmx_rxx_frm_ctl {
uint64_t u64;
struct cvmx_agl_gmx_rxx_frm_ctl_s {
- uint64_t reserved_10_63:54;
+ uint64_t reserved_13_63:51;
+ uint64_t ptp_mode:1;
+ uint64_t reserved_11_11:1;
+ uint64_t null_dis:1;
uint64_t pre_align:1;
uint64_t pad_len:1;
uint64_t vlan_len:1;
@@ -417,10 +422,24 @@ union cvmx_agl_gmx_rxx_frm_ctl {
uint64_t pre_strp:1;
uint64_t pre_chk:1;
} s;
- struct cvmx_agl_gmx_rxx_frm_ctl_s cn52xx;
- struct cvmx_agl_gmx_rxx_frm_ctl_s cn52xxp1;
- struct cvmx_agl_gmx_rxx_frm_ctl_s cn56xx;
- struct cvmx_agl_gmx_rxx_frm_ctl_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_frm_ctl_cn52xx {
+ uint64_t reserved_10_63:54;
+ uint64_t pre_align:1;
+ uint64_t pad_len:1;
+ uint64_t vlan_len:1;
+ uint64_t pre_free:1;
+ uint64_t ctl_smac:1;
+ uint64_t ctl_mcst:1;
+ uint64_t ctl_bck:1;
+ uint64_t ctl_drp:1;
+ uint64_t pre_strp:1;
+ uint64_t pre_chk:1;
+ } cn52xx;
+ struct cvmx_agl_gmx_rxx_frm_ctl_cn52xx cn52xxp1;
+ struct cvmx_agl_gmx_rxx_frm_ctl_cn52xx cn56xx;
+ struct cvmx_agl_gmx_rxx_frm_ctl_cn52xx cn56xxp1;
+ struct cvmx_agl_gmx_rxx_frm_ctl_s cn63xx;
+ struct cvmx_agl_gmx_rxx_frm_ctl_s cn63xxp1;
};
union cvmx_agl_gmx_rxx_frm_max {
@@ -433,6 +452,8 @@ union cvmx_agl_gmx_rxx_frm_max {
struct cvmx_agl_gmx_rxx_frm_max_s cn52xxp1;
struct cvmx_agl_gmx_rxx_frm_max_s cn56xx;
struct cvmx_agl_gmx_rxx_frm_max_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_frm_max_s cn63xx;
+ struct cvmx_agl_gmx_rxx_frm_max_s cn63xxp1;
};
union cvmx_agl_gmx_rxx_frm_min {
@@ -445,6 +466,8 @@ union cvmx_agl_gmx_rxx_frm_min {
struct cvmx_agl_gmx_rxx_frm_min_s cn52xxp1;
struct cvmx_agl_gmx_rxx_frm_min_s cn56xx;
struct cvmx_agl_gmx_rxx_frm_min_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_frm_min_s cn63xx;
+ struct cvmx_agl_gmx_rxx_frm_min_s cn63xxp1;
};
union cvmx_agl_gmx_rxx_ifg {
@@ -457,6 +480,8 @@ union cvmx_agl_gmx_rxx_ifg {
struct cvmx_agl_gmx_rxx_ifg_s cn52xxp1;
struct cvmx_agl_gmx_rxx_ifg_s cn56xx;
struct cvmx_agl_gmx_rxx_ifg_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_ifg_s cn63xx;
+ struct cvmx_agl_gmx_rxx_ifg_s cn63xxp1;
};
union cvmx_agl_gmx_rxx_int_en {
@@ -464,6 +489,29 @@ union cvmx_agl_gmx_rxx_int_en {
struct cvmx_agl_gmx_rxx_int_en_s {
uint64_t reserved_20_63:44;
uint64_t pause_drp:1;
+ uint64_t phy_dupx:1;
+ uint64_t phy_spd:1;
+ uint64_t phy_link:1;
+ uint64_t ifgerr:1;
+ uint64_t coldet:1;
+ uint64_t falerr:1;
+ uint64_t rsverr:1;
+ uint64_t pcterr:1;
+ uint64_t ovrerr:1;
+ uint64_t niberr:1;
+ uint64_t skperr:1;
+ uint64_t rcverr:1;
+ uint64_t lenerr:1;
+ uint64_t alnerr:1;
+ uint64_t fcserr:1;
+ uint64_t jabber:1;
+ uint64_t maxerr:1;
+ uint64_t carext:1;
+ uint64_t minerr:1;
+ } s;
+ struct cvmx_agl_gmx_rxx_int_en_cn52xx {
+ uint64_t reserved_20_63:44;
+ uint64_t pause_drp:1;
uint64_t reserved_16_18:3;
uint64_t ifgerr:1;
uint64_t coldet:1;
@@ -481,11 +529,12 @@ union cvmx_agl_gmx_rxx_int_en {
uint64_t maxerr:1;
uint64_t reserved_1_1:1;
uint64_t minerr:1;
- } s;
- struct cvmx_agl_gmx_rxx_int_en_s cn52xx;
- struct cvmx_agl_gmx_rxx_int_en_s cn52xxp1;
- struct cvmx_agl_gmx_rxx_int_en_s cn56xx;
- struct cvmx_agl_gmx_rxx_int_en_s cn56xxp1;
+ } cn52xx;
+ struct cvmx_agl_gmx_rxx_int_en_cn52xx cn52xxp1;
+ struct cvmx_agl_gmx_rxx_int_en_cn52xx cn56xx;
+ struct cvmx_agl_gmx_rxx_int_en_cn52xx cn56xxp1;
+ struct cvmx_agl_gmx_rxx_int_en_s cn63xx;
+ struct cvmx_agl_gmx_rxx_int_en_s cn63xxp1;
};
union cvmx_agl_gmx_rxx_int_reg {
@@ -493,6 +542,29 @@ union cvmx_agl_gmx_rxx_int_reg {
struct cvmx_agl_gmx_rxx_int_reg_s {
uint64_t reserved_20_63:44;
uint64_t pause_drp:1;
+ uint64_t phy_dupx:1;
+ uint64_t phy_spd:1;
+ uint64_t phy_link:1;
+ uint64_t ifgerr:1;
+ uint64_t coldet:1;
+ uint64_t falerr:1;
+ uint64_t rsverr:1;
+ uint64_t pcterr:1;
+ uint64_t ovrerr:1;
+ uint64_t niberr:1;
+ uint64_t skperr:1;
+ uint64_t rcverr:1;
+ uint64_t lenerr:1;
+ uint64_t alnerr:1;
+ uint64_t fcserr:1;
+ uint64_t jabber:1;
+ uint64_t maxerr:1;
+ uint64_t carext:1;
+ uint64_t minerr:1;
+ } s;
+ struct cvmx_agl_gmx_rxx_int_reg_cn52xx {
+ uint64_t reserved_20_63:44;
+ uint64_t pause_drp:1;
uint64_t reserved_16_18:3;
uint64_t ifgerr:1;
uint64_t coldet:1;
@@ -510,11 +582,12 @@ union cvmx_agl_gmx_rxx_int_reg {
uint64_t maxerr:1;
uint64_t reserved_1_1:1;
uint64_t minerr:1;
- } s;
- struct cvmx_agl_gmx_rxx_int_reg_s cn52xx;
- struct cvmx_agl_gmx_rxx_int_reg_s cn52xxp1;
- struct cvmx_agl_gmx_rxx_int_reg_s cn56xx;
- struct cvmx_agl_gmx_rxx_int_reg_s cn56xxp1;
+ } cn52xx;
+ struct cvmx_agl_gmx_rxx_int_reg_cn52xx cn52xxp1;
+ struct cvmx_agl_gmx_rxx_int_reg_cn52xx cn56xx;
+ struct cvmx_agl_gmx_rxx_int_reg_cn52xx cn56xxp1;
+ struct cvmx_agl_gmx_rxx_int_reg_s cn63xx;
+ struct cvmx_agl_gmx_rxx_int_reg_s cn63xxp1;
};
union cvmx_agl_gmx_rxx_jabber {
@@ -527,6 +600,8 @@ union cvmx_agl_gmx_rxx_jabber {
struct cvmx_agl_gmx_rxx_jabber_s cn52xxp1;
struct cvmx_agl_gmx_rxx_jabber_s cn56xx;
struct cvmx_agl_gmx_rxx_jabber_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_jabber_s cn63xx;
+ struct cvmx_agl_gmx_rxx_jabber_s cn63xxp1;
};
union cvmx_agl_gmx_rxx_pause_drop_time {
@@ -539,6 +614,20 @@ union cvmx_agl_gmx_rxx_pause_drop_time {
struct cvmx_agl_gmx_rxx_pause_drop_time_s cn52xxp1;
struct cvmx_agl_gmx_rxx_pause_drop_time_s cn56xx;
struct cvmx_agl_gmx_rxx_pause_drop_time_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_pause_drop_time_s cn63xx;
+ struct cvmx_agl_gmx_rxx_pause_drop_time_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_rx_inbnd {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_rx_inbnd_s {
+ uint64_t reserved_4_63:60;
+ uint64_t duplex:1;
+ uint64_t speed:2;
+ uint64_t status:1;
+ } s;
+ struct cvmx_agl_gmx_rxx_rx_inbnd_s cn63xx;
+ struct cvmx_agl_gmx_rxx_rx_inbnd_s cn63xxp1;
};
union cvmx_agl_gmx_rxx_stats_ctl {
@@ -551,6 +640,8 @@ union cvmx_agl_gmx_rxx_stats_ctl {
struct cvmx_agl_gmx_rxx_stats_ctl_s cn52xxp1;
struct cvmx_agl_gmx_rxx_stats_ctl_s cn56xx;
struct cvmx_agl_gmx_rxx_stats_ctl_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_ctl_s cn63xx;
+ struct cvmx_agl_gmx_rxx_stats_ctl_s cn63xxp1;
};
union cvmx_agl_gmx_rxx_stats_octs {
@@ -563,6 +654,8 @@ union cvmx_agl_gmx_rxx_stats_octs {
struct cvmx_agl_gmx_rxx_stats_octs_s cn52xxp1;
struct cvmx_agl_gmx_rxx_stats_octs_s cn56xx;
struct cvmx_agl_gmx_rxx_stats_octs_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_octs_s cn63xx;
+ struct cvmx_agl_gmx_rxx_stats_octs_s cn63xxp1;
};
union cvmx_agl_gmx_rxx_stats_octs_ctl {
@@ -575,6 +668,8 @@ union cvmx_agl_gmx_rxx_stats_octs_ctl {
struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn52xxp1;
struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn56xx;
struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn63xx;
+ struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn63xxp1;
};
union cvmx_agl_gmx_rxx_stats_octs_dmac {
@@ -587,6 +682,8 @@ union cvmx_agl_gmx_rxx_stats_octs_dmac {
struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn52xxp1;
struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn56xx;
struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn63xx;
+ struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn63xxp1;
};
union cvmx_agl_gmx_rxx_stats_octs_drp {
@@ -599,6 +696,8 @@ union cvmx_agl_gmx_rxx_stats_octs_drp {
struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn52xxp1;
struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn56xx;
struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn63xx;
+ struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn63xxp1;
};
union cvmx_agl_gmx_rxx_stats_pkts {
@@ -611,6 +710,8 @@ union cvmx_agl_gmx_rxx_stats_pkts {
struct cvmx_agl_gmx_rxx_stats_pkts_s cn52xxp1;
struct cvmx_agl_gmx_rxx_stats_pkts_s cn56xx;
struct cvmx_agl_gmx_rxx_stats_pkts_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_pkts_s cn63xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_s cn63xxp1;
};
union cvmx_agl_gmx_rxx_stats_pkts_bad {
@@ -623,6 +724,8 @@ union cvmx_agl_gmx_rxx_stats_pkts_bad {
struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn52xxp1;
struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn56xx;
struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn63xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn63xxp1;
};
union cvmx_agl_gmx_rxx_stats_pkts_ctl {
@@ -635,6 +738,8 @@ union cvmx_agl_gmx_rxx_stats_pkts_ctl {
struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn52xxp1;
struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn56xx;
struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn63xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn63xxp1;
};
union cvmx_agl_gmx_rxx_stats_pkts_dmac {
@@ -647,6 +752,8 @@ union cvmx_agl_gmx_rxx_stats_pkts_dmac {
struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn52xxp1;
struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn56xx;
struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn63xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn63xxp1;
};
union cvmx_agl_gmx_rxx_stats_pkts_drp {
@@ -659,6 +766,8 @@ union cvmx_agl_gmx_rxx_stats_pkts_drp {
struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn52xxp1;
struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn56xx;
struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn63xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn63xxp1;
};
union cvmx_agl_gmx_rxx_udd_skp {
@@ -673,6 +782,8 @@ union cvmx_agl_gmx_rxx_udd_skp {
struct cvmx_agl_gmx_rxx_udd_skp_s cn52xxp1;
struct cvmx_agl_gmx_rxx_udd_skp_s cn56xx;
struct cvmx_agl_gmx_rxx_udd_skp_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_udd_skp_s cn63xx;
+ struct cvmx_agl_gmx_rxx_udd_skp_s cn63xxp1;
};
union cvmx_agl_gmx_rx_bp_dropx {
@@ -685,6 +796,8 @@ union cvmx_agl_gmx_rx_bp_dropx {
struct cvmx_agl_gmx_rx_bp_dropx_s cn52xxp1;
struct cvmx_agl_gmx_rx_bp_dropx_s cn56xx;
struct cvmx_agl_gmx_rx_bp_dropx_s cn56xxp1;
+ struct cvmx_agl_gmx_rx_bp_dropx_s cn63xx;
+ struct cvmx_agl_gmx_rx_bp_dropx_s cn63xxp1;
};
union cvmx_agl_gmx_rx_bp_offx {
@@ -697,6 +810,8 @@ union cvmx_agl_gmx_rx_bp_offx {
struct cvmx_agl_gmx_rx_bp_offx_s cn52xxp1;
struct cvmx_agl_gmx_rx_bp_offx_s cn56xx;
struct cvmx_agl_gmx_rx_bp_offx_s cn56xxp1;
+ struct cvmx_agl_gmx_rx_bp_offx_s cn63xx;
+ struct cvmx_agl_gmx_rx_bp_offx_s cn63xxp1;
};
union cvmx_agl_gmx_rx_bp_onx {
@@ -709,6 +824,8 @@ union cvmx_agl_gmx_rx_bp_onx {
struct cvmx_agl_gmx_rx_bp_onx_s cn52xxp1;
struct cvmx_agl_gmx_rx_bp_onx_s cn56xx;
struct cvmx_agl_gmx_rx_bp_onx_s cn56xxp1;
+ struct cvmx_agl_gmx_rx_bp_onx_s cn63xx;
+ struct cvmx_agl_gmx_rx_bp_onx_s cn63xxp1;
};
union cvmx_agl_gmx_rx_prt_info {
@@ -728,6 +845,8 @@ union cvmx_agl_gmx_rx_prt_info {
uint64_t commit:1;
} cn56xx;
struct cvmx_agl_gmx_rx_prt_info_cn56xx cn56xxp1;
+ struct cvmx_agl_gmx_rx_prt_info_s cn63xx;
+ struct cvmx_agl_gmx_rx_prt_info_s cn63xxp1;
};
union cvmx_agl_gmx_rx_tx_status {
@@ -747,6 +866,8 @@ union cvmx_agl_gmx_rx_tx_status {
uint64_t rx:1;
} cn56xx;
struct cvmx_agl_gmx_rx_tx_status_cn56xx cn56xxp1;
+ struct cvmx_agl_gmx_rx_tx_status_s cn63xx;
+ struct cvmx_agl_gmx_rx_tx_status_s cn63xxp1;
};
union cvmx_agl_gmx_smacx {
@@ -759,6 +880,8 @@ union cvmx_agl_gmx_smacx {
struct cvmx_agl_gmx_smacx_s cn52xxp1;
struct cvmx_agl_gmx_smacx_s cn56xx;
struct cvmx_agl_gmx_smacx_s cn56xxp1;
+ struct cvmx_agl_gmx_smacx_s cn63xx;
+ struct cvmx_agl_gmx_smacx_s cn63xxp1;
};
union cvmx_agl_gmx_stat_bp {
@@ -772,6 +895,8 @@ union cvmx_agl_gmx_stat_bp {
struct cvmx_agl_gmx_stat_bp_s cn52xxp1;
struct cvmx_agl_gmx_stat_bp_s cn56xx;
struct cvmx_agl_gmx_stat_bp_s cn56xxp1;
+ struct cvmx_agl_gmx_stat_bp_s cn63xx;
+ struct cvmx_agl_gmx_stat_bp_s cn63xxp1;
};
union cvmx_agl_gmx_txx_append {
@@ -787,6 +912,18 @@ union cvmx_agl_gmx_txx_append {
struct cvmx_agl_gmx_txx_append_s cn52xxp1;
struct cvmx_agl_gmx_txx_append_s cn56xx;
struct cvmx_agl_gmx_txx_append_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_append_s cn63xx;
+ struct cvmx_agl_gmx_txx_append_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_txx_clk {
+ uint64_t u64;
+ struct cvmx_agl_gmx_txx_clk_s {
+ uint64_t reserved_6_63:58;
+ uint64_t clk_cnt:6;
+ } s;
+ struct cvmx_agl_gmx_txx_clk_s cn63xx;
+ struct cvmx_agl_gmx_txx_clk_s cn63xxp1;
};
union cvmx_agl_gmx_txx_ctl {
@@ -800,6 +937,8 @@ union cvmx_agl_gmx_txx_ctl {
struct cvmx_agl_gmx_txx_ctl_s cn52xxp1;
struct cvmx_agl_gmx_txx_ctl_s cn56xx;
struct cvmx_agl_gmx_txx_ctl_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_ctl_s cn63xx;
+ struct cvmx_agl_gmx_txx_ctl_s cn63xxp1;
};
union cvmx_agl_gmx_txx_min_pkt {
@@ -812,6 +951,8 @@ union cvmx_agl_gmx_txx_min_pkt {
struct cvmx_agl_gmx_txx_min_pkt_s cn52xxp1;
struct cvmx_agl_gmx_txx_min_pkt_s cn56xx;
struct cvmx_agl_gmx_txx_min_pkt_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_min_pkt_s cn63xx;
+ struct cvmx_agl_gmx_txx_min_pkt_s cn63xxp1;
};
union cvmx_agl_gmx_txx_pause_pkt_interval {
@@ -824,6 +965,8 @@ union cvmx_agl_gmx_txx_pause_pkt_interval {
struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn52xxp1;
struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn56xx;
struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn63xx;
+ struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn63xxp1;
};
union cvmx_agl_gmx_txx_pause_pkt_time {
@@ -836,6 +979,8 @@ union cvmx_agl_gmx_txx_pause_pkt_time {
struct cvmx_agl_gmx_txx_pause_pkt_time_s cn52xxp1;
struct cvmx_agl_gmx_txx_pause_pkt_time_s cn56xx;
struct cvmx_agl_gmx_txx_pause_pkt_time_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_pause_pkt_time_s cn63xx;
+ struct cvmx_agl_gmx_txx_pause_pkt_time_s cn63xxp1;
};
union cvmx_agl_gmx_txx_pause_togo {
@@ -848,6 +993,8 @@ union cvmx_agl_gmx_txx_pause_togo {
struct cvmx_agl_gmx_txx_pause_togo_s cn52xxp1;
struct cvmx_agl_gmx_txx_pause_togo_s cn56xx;
struct cvmx_agl_gmx_txx_pause_togo_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_pause_togo_s cn63xx;
+ struct cvmx_agl_gmx_txx_pause_togo_s cn63xxp1;
};
union cvmx_agl_gmx_txx_pause_zero {
@@ -860,6 +1007,8 @@ union cvmx_agl_gmx_txx_pause_zero {
struct cvmx_agl_gmx_txx_pause_zero_s cn52xxp1;
struct cvmx_agl_gmx_txx_pause_zero_s cn56xx;
struct cvmx_agl_gmx_txx_pause_zero_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_pause_zero_s cn63xx;
+ struct cvmx_agl_gmx_txx_pause_zero_s cn63xxp1;
};
union cvmx_agl_gmx_txx_soft_pause {
@@ -872,6 +1021,8 @@ union cvmx_agl_gmx_txx_soft_pause {
struct cvmx_agl_gmx_txx_soft_pause_s cn52xxp1;
struct cvmx_agl_gmx_txx_soft_pause_s cn56xx;
struct cvmx_agl_gmx_txx_soft_pause_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_soft_pause_s cn63xx;
+ struct cvmx_agl_gmx_txx_soft_pause_s cn63xxp1;
};
union cvmx_agl_gmx_txx_stat0 {
@@ -884,6 +1035,8 @@ union cvmx_agl_gmx_txx_stat0 {
struct cvmx_agl_gmx_txx_stat0_s cn52xxp1;
struct cvmx_agl_gmx_txx_stat0_s cn56xx;
struct cvmx_agl_gmx_txx_stat0_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat0_s cn63xx;
+ struct cvmx_agl_gmx_txx_stat0_s cn63xxp1;
};
union cvmx_agl_gmx_txx_stat1 {
@@ -896,6 +1049,8 @@ union cvmx_agl_gmx_txx_stat1 {
struct cvmx_agl_gmx_txx_stat1_s cn52xxp1;
struct cvmx_agl_gmx_txx_stat1_s cn56xx;
struct cvmx_agl_gmx_txx_stat1_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat1_s cn63xx;
+ struct cvmx_agl_gmx_txx_stat1_s cn63xxp1;
};
union cvmx_agl_gmx_txx_stat2 {
@@ -908,6 +1063,8 @@ union cvmx_agl_gmx_txx_stat2 {
struct cvmx_agl_gmx_txx_stat2_s cn52xxp1;
struct cvmx_agl_gmx_txx_stat2_s cn56xx;
struct cvmx_agl_gmx_txx_stat2_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat2_s cn63xx;
+ struct cvmx_agl_gmx_txx_stat2_s cn63xxp1;
};
union cvmx_agl_gmx_txx_stat3 {
@@ -920,6 +1077,8 @@ union cvmx_agl_gmx_txx_stat3 {
struct cvmx_agl_gmx_txx_stat3_s cn52xxp1;
struct cvmx_agl_gmx_txx_stat3_s cn56xx;
struct cvmx_agl_gmx_txx_stat3_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat3_s cn63xx;
+ struct cvmx_agl_gmx_txx_stat3_s cn63xxp1;
};
union cvmx_agl_gmx_txx_stat4 {
@@ -932,6 +1091,8 @@ union cvmx_agl_gmx_txx_stat4 {
struct cvmx_agl_gmx_txx_stat4_s cn52xxp1;
struct cvmx_agl_gmx_txx_stat4_s cn56xx;
struct cvmx_agl_gmx_txx_stat4_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat4_s cn63xx;
+ struct cvmx_agl_gmx_txx_stat4_s cn63xxp1;
};
union cvmx_agl_gmx_txx_stat5 {
@@ -944,6 +1105,8 @@ union cvmx_agl_gmx_txx_stat5 {
struct cvmx_agl_gmx_txx_stat5_s cn52xxp1;
struct cvmx_agl_gmx_txx_stat5_s cn56xx;
struct cvmx_agl_gmx_txx_stat5_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat5_s cn63xx;
+ struct cvmx_agl_gmx_txx_stat5_s cn63xxp1;
};
union cvmx_agl_gmx_txx_stat6 {
@@ -956,6 +1119,8 @@ union cvmx_agl_gmx_txx_stat6 {
struct cvmx_agl_gmx_txx_stat6_s cn52xxp1;
struct cvmx_agl_gmx_txx_stat6_s cn56xx;
struct cvmx_agl_gmx_txx_stat6_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat6_s cn63xx;
+ struct cvmx_agl_gmx_txx_stat6_s cn63xxp1;
};
union cvmx_agl_gmx_txx_stat7 {
@@ -968,6 +1133,8 @@ union cvmx_agl_gmx_txx_stat7 {
struct cvmx_agl_gmx_txx_stat7_s cn52xxp1;
struct cvmx_agl_gmx_txx_stat7_s cn56xx;
struct cvmx_agl_gmx_txx_stat7_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat7_s cn63xx;
+ struct cvmx_agl_gmx_txx_stat7_s cn63xxp1;
};
union cvmx_agl_gmx_txx_stat8 {
@@ -980,6 +1147,8 @@ union cvmx_agl_gmx_txx_stat8 {
struct cvmx_agl_gmx_txx_stat8_s cn52xxp1;
struct cvmx_agl_gmx_txx_stat8_s cn56xx;
struct cvmx_agl_gmx_txx_stat8_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat8_s cn63xx;
+ struct cvmx_agl_gmx_txx_stat8_s cn63xxp1;
};
union cvmx_agl_gmx_txx_stat9 {
@@ -992,6 +1161,8 @@ union cvmx_agl_gmx_txx_stat9 {
struct cvmx_agl_gmx_txx_stat9_s cn52xxp1;
struct cvmx_agl_gmx_txx_stat9_s cn56xx;
struct cvmx_agl_gmx_txx_stat9_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat9_s cn63xx;
+ struct cvmx_agl_gmx_txx_stat9_s cn63xxp1;
};
union cvmx_agl_gmx_txx_stats_ctl {
@@ -1004,6 +1175,8 @@ union cvmx_agl_gmx_txx_stats_ctl {
struct cvmx_agl_gmx_txx_stats_ctl_s cn52xxp1;
struct cvmx_agl_gmx_txx_stats_ctl_s cn56xx;
struct cvmx_agl_gmx_txx_stats_ctl_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stats_ctl_s cn63xx;
+ struct cvmx_agl_gmx_txx_stats_ctl_s cn63xxp1;
};
union cvmx_agl_gmx_txx_thresh {
@@ -1016,6 +1189,8 @@ union cvmx_agl_gmx_txx_thresh {
struct cvmx_agl_gmx_txx_thresh_s cn52xxp1;
struct cvmx_agl_gmx_txx_thresh_s cn56xx;
struct cvmx_agl_gmx_txx_thresh_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_thresh_s cn63xx;
+ struct cvmx_agl_gmx_txx_thresh_s cn63xxp1;
};
union cvmx_agl_gmx_tx_bp {
@@ -1031,6 +1206,8 @@ union cvmx_agl_gmx_tx_bp {
uint64_t bp:1;
} cn56xx;
struct cvmx_agl_gmx_tx_bp_cn56xx cn56xxp1;
+ struct cvmx_agl_gmx_tx_bp_s cn63xx;
+ struct cvmx_agl_gmx_tx_bp_s cn63xxp1;
};
union cvmx_agl_gmx_tx_col_attempt {
@@ -1043,6 +1220,8 @@ union cvmx_agl_gmx_tx_col_attempt {
struct cvmx_agl_gmx_tx_col_attempt_s cn52xxp1;
struct cvmx_agl_gmx_tx_col_attempt_s cn56xx;
struct cvmx_agl_gmx_tx_col_attempt_s cn56xxp1;
+ struct cvmx_agl_gmx_tx_col_attempt_s cn63xx;
+ struct cvmx_agl_gmx_tx_col_attempt_s cn63xxp1;
};
union cvmx_agl_gmx_tx_ifg {
@@ -1056,12 +1235,16 @@ union cvmx_agl_gmx_tx_ifg {
struct cvmx_agl_gmx_tx_ifg_s cn52xxp1;
struct cvmx_agl_gmx_tx_ifg_s cn56xx;
struct cvmx_agl_gmx_tx_ifg_s cn56xxp1;
+ struct cvmx_agl_gmx_tx_ifg_s cn63xx;
+ struct cvmx_agl_gmx_tx_ifg_s cn63xxp1;
};
union cvmx_agl_gmx_tx_int_en {
uint64_t u64;
struct cvmx_agl_gmx_tx_int_en_s {
- uint64_t reserved_18_63:46;
+ uint64_t reserved_22_63:42;
+ uint64_t ptp_lost:2;
+ uint64_t reserved_18_19:2;
uint64_t late_col:2;
uint64_t reserved_14_15:2;
uint64_t xsdef:2;
@@ -1072,8 +1255,19 @@ union cvmx_agl_gmx_tx_int_en {
uint64_t reserved_1_1:1;
uint64_t pko_nxa:1;
} s;
- struct cvmx_agl_gmx_tx_int_en_s cn52xx;
- struct cvmx_agl_gmx_tx_int_en_s cn52xxp1;
+ struct cvmx_agl_gmx_tx_int_en_cn52xx {
+ uint64_t reserved_18_63:46;
+ uint64_t late_col:2;
+ uint64_t reserved_14_15:2;
+ uint64_t xsdef:2;
+ uint64_t reserved_10_11:2;
+ uint64_t xscol:2;
+ uint64_t reserved_4_7:4;
+ uint64_t undflw:2;
+ uint64_t reserved_1_1:1;
+ uint64_t pko_nxa:1;
+ } cn52xx;
+ struct cvmx_agl_gmx_tx_int_en_cn52xx cn52xxp1;
struct cvmx_agl_gmx_tx_int_en_cn56xx {
uint64_t reserved_17_63:47;
uint64_t late_col:1;
@@ -1087,12 +1281,16 @@ union cvmx_agl_gmx_tx_int_en {
uint64_t pko_nxa:1;
} cn56xx;
struct cvmx_agl_gmx_tx_int_en_cn56xx cn56xxp1;
+ struct cvmx_agl_gmx_tx_int_en_s cn63xx;
+ struct cvmx_agl_gmx_tx_int_en_s cn63xxp1;
};
union cvmx_agl_gmx_tx_int_reg {
uint64_t u64;
struct cvmx_agl_gmx_tx_int_reg_s {
- uint64_t reserved_18_63:46;
+ uint64_t reserved_22_63:42;
+ uint64_t ptp_lost:2;
+ uint64_t reserved_18_19:2;
uint64_t late_col:2;
uint64_t reserved_14_15:2;
uint64_t xsdef:2;
@@ -1103,8 +1301,19 @@ union cvmx_agl_gmx_tx_int_reg {
uint64_t reserved_1_1:1;
uint64_t pko_nxa:1;
} s;
- struct cvmx_agl_gmx_tx_int_reg_s cn52xx;
- struct cvmx_agl_gmx_tx_int_reg_s cn52xxp1;
+ struct cvmx_agl_gmx_tx_int_reg_cn52xx {
+ uint64_t reserved_18_63:46;
+ uint64_t late_col:2;
+ uint64_t reserved_14_15:2;
+ uint64_t xsdef:2;
+ uint64_t reserved_10_11:2;
+ uint64_t xscol:2;
+ uint64_t reserved_4_7:4;
+ uint64_t undflw:2;
+ uint64_t reserved_1_1:1;
+ uint64_t pko_nxa:1;
+ } cn52xx;
+ struct cvmx_agl_gmx_tx_int_reg_cn52xx cn52xxp1;
struct cvmx_agl_gmx_tx_int_reg_cn56xx {
uint64_t reserved_17_63:47;
uint64_t late_col:1;
@@ -1118,6 +1327,8 @@ union cvmx_agl_gmx_tx_int_reg {
uint64_t pko_nxa:1;
} cn56xx;
struct cvmx_agl_gmx_tx_int_reg_cn56xx cn56xxp1;
+ struct cvmx_agl_gmx_tx_int_reg_s cn63xx;
+ struct cvmx_agl_gmx_tx_int_reg_s cn63xxp1;
};
union cvmx_agl_gmx_tx_jam {
@@ -1130,6 +1341,8 @@ union cvmx_agl_gmx_tx_jam {
struct cvmx_agl_gmx_tx_jam_s cn52xxp1;
struct cvmx_agl_gmx_tx_jam_s cn56xx;
struct cvmx_agl_gmx_tx_jam_s cn56xxp1;
+ struct cvmx_agl_gmx_tx_jam_s cn63xx;
+ struct cvmx_agl_gmx_tx_jam_s cn63xxp1;
};
union cvmx_agl_gmx_tx_lfsr {
@@ -1142,6 +1355,8 @@ union cvmx_agl_gmx_tx_lfsr {
struct cvmx_agl_gmx_tx_lfsr_s cn52xxp1;
struct cvmx_agl_gmx_tx_lfsr_s cn56xx;
struct cvmx_agl_gmx_tx_lfsr_s cn56xxp1;
+ struct cvmx_agl_gmx_tx_lfsr_s cn63xx;
+ struct cvmx_agl_gmx_tx_lfsr_s cn63xxp1;
};
union cvmx_agl_gmx_tx_ovr_bp {
@@ -1165,6 +1380,8 @@ union cvmx_agl_gmx_tx_ovr_bp {
uint64_t ign_full:1;
} cn56xx;
struct cvmx_agl_gmx_tx_ovr_bp_cn56xx cn56xxp1;
+ struct cvmx_agl_gmx_tx_ovr_bp_s cn63xx;
+ struct cvmx_agl_gmx_tx_ovr_bp_s cn63xxp1;
};
union cvmx_agl_gmx_tx_pause_pkt_dmac {
@@ -1177,6 +1394,8 @@ union cvmx_agl_gmx_tx_pause_pkt_dmac {
struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn52xxp1;
struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn56xx;
struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn56xxp1;
+ struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn63xx;
+ struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn63xxp1;
};
union cvmx_agl_gmx_tx_pause_pkt_type {
@@ -1189,6 +1408,39 @@ union cvmx_agl_gmx_tx_pause_pkt_type {
struct cvmx_agl_gmx_tx_pause_pkt_type_s cn52xxp1;
struct cvmx_agl_gmx_tx_pause_pkt_type_s cn56xx;
struct cvmx_agl_gmx_tx_pause_pkt_type_s cn56xxp1;
+ struct cvmx_agl_gmx_tx_pause_pkt_type_s cn63xx;
+ struct cvmx_agl_gmx_tx_pause_pkt_type_s cn63xxp1;
+};
+
+union cvmx_agl_prtx_ctl {
+ uint64_t u64;
+ struct cvmx_agl_prtx_ctl_s {
+ uint64_t drv_byp:1;
+ uint64_t reserved_62_62:1;
+ uint64_t cmp_pctl:6;
+ uint64_t reserved_54_55:2;
+ uint64_t cmp_nctl:6;
+ uint64_t reserved_46_47:2;
+ uint64_t drv_pctl:6;
+ uint64_t reserved_38_39:2;
+ uint64_t drv_nctl:6;
+ uint64_t reserved_29_31:3;
+ uint64_t clk_set:5;
+ uint64_t clkrx_byp:1;
+ uint64_t reserved_21_22:2;
+ uint64_t clkrx_set:5;
+ uint64_t clktx_byp:1;
+ uint64_t reserved_13_14:2;
+ uint64_t clktx_set:5;
+ uint64_t reserved_5_7:3;
+ uint64_t dllrst:1;
+ uint64_t comp:1;
+ uint64_t enable:1;
+ uint64_t clkrst:1;
+ uint64_t mode:1;
+ } s;
+ struct cvmx_agl_prtx_ctl_s cn63xx;
+ struct cvmx_agl_prtx_ctl_s cn63xxp1;
};
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-asm.h b/arch/mips/include/asm/octeon/cvmx-asm.h
index b21d3fc1ef91..5de5de95311b 100644
--- a/arch/mips/include/asm/octeon/cvmx-asm.h
+++ b/arch/mips/include/asm/octeon/cvmx-asm.h
@@ -114,6 +114,17 @@
#define CVMX_DCACHE_INVALIDATE \
{ CVMX_SYNC; asm volatile ("cache 9, 0($0)" : : ); }
+#define CVMX_CACHE(op, address, offset) \
+ asm volatile ("cache " CVMX_TMP_STR(op) ", " CVMX_TMP_STR(offset) "(%[rbase])" \
+ : : [rbase] "d" (address) )
+/* fetch and lock the state. */
+#define CVMX_CACHE_LCKL2(address, offset) CVMX_CACHE(31, address, offset)
+/* unlock the state. */
+#define CVMX_CACHE_WBIL2(address, offset) CVMX_CACHE(23, address, offset)
+/* invalidate the cache block and clear the USED bits for the block */
+#define CVMX_CACHE_WBIL2I(address, offset) CVMX_CACHE(3, address, offset)
+/* load virtual tag and data for the L2 cache block into L2C_TAD0_TAG register */
+#define CVMX_CACHE_LTGL2I(address, offset) CVMX_CACHE(7, address, offset)
#define CVMX_POP(result, input) \
asm ("pop %[rd],%[rs]" : [rd] "=d" (result) : [rs] "d" (input))
diff --git a/arch/mips/include/asm/octeon/cvmx-ciu-defs.h b/arch/mips/include/asm/octeon/cvmx-ciu-defs.h
index f8f05b7764b7..27cead370411 100644
--- a/arch/mips/include/asm/octeon/cvmx-ciu-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-ciu-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
@@ -28,87 +28,61 @@
#ifndef __CVMX_CIU_DEFS_H__
#define __CVMX_CIU_DEFS_H__
-#define CVMX_CIU_BIST \
- CVMX_ADD_IO_SEG(0x0001070000000730ull)
-#define CVMX_CIU_DINT \
- CVMX_ADD_IO_SEG(0x0001070000000720ull)
-#define CVMX_CIU_FUSE \
- CVMX_ADD_IO_SEG(0x0001070000000728ull)
-#define CVMX_CIU_GSTOP \
- CVMX_ADD_IO_SEG(0x0001070000000710ull)
-#define CVMX_CIU_INTX_EN0(offset) \
- CVMX_ADD_IO_SEG(0x0001070000000200ull + (((offset) & 63) * 16))
-#define CVMX_CIU_INTX_EN0_W1C(offset) \
- CVMX_ADD_IO_SEG(0x0001070000002200ull + (((offset) & 63) * 16))
-#define CVMX_CIU_INTX_EN0_W1S(offset) \
- CVMX_ADD_IO_SEG(0x0001070000006200ull + (((offset) & 63) * 16))
-#define CVMX_CIU_INTX_EN1(offset) \
- CVMX_ADD_IO_SEG(0x0001070000000208ull + (((offset) & 63) * 16))
-#define CVMX_CIU_INTX_EN1_W1C(offset) \
- CVMX_ADD_IO_SEG(0x0001070000002208ull + (((offset) & 63) * 16))
-#define CVMX_CIU_INTX_EN1_W1S(offset) \
- CVMX_ADD_IO_SEG(0x0001070000006208ull + (((offset) & 63) * 16))
-#define CVMX_CIU_INTX_EN4_0(offset) \
- CVMX_ADD_IO_SEG(0x0001070000000C80ull + (((offset) & 15) * 16))
-#define CVMX_CIU_INTX_EN4_0_W1C(offset) \
- CVMX_ADD_IO_SEG(0x0001070000002C80ull + (((offset) & 15) * 16))
-#define CVMX_CIU_INTX_EN4_0_W1S(offset) \
- CVMX_ADD_IO_SEG(0x0001070000006C80ull + (((offset) & 15) * 16))
-#define CVMX_CIU_INTX_EN4_1(offset) \
- CVMX_ADD_IO_SEG(0x0001070000000C88ull + (((offset) & 15) * 16))
-#define CVMX_CIU_INTX_EN4_1_W1C(offset) \
- CVMX_ADD_IO_SEG(0x0001070000002C88ull + (((offset) & 15) * 16))
-#define CVMX_CIU_INTX_EN4_1_W1S(offset) \
- CVMX_ADD_IO_SEG(0x0001070000006C88ull + (((offset) & 15) * 16))
-#define CVMX_CIU_INTX_SUM0(offset) \
- CVMX_ADD_IO_SEG(0x0001070000000000ull + (((offset) & 63) * 8))
-#define CVMX_CIU_INTX_SUM4(offset) \
- CVMX_ADD_IO_SEG(0x0001070000000C00ull + (((offset) & 15) * 8))
-#define CVMX_CIU_INT_SUM1 \
- CVMX_ADD_IO_SEG(0x0001070000000108ull)
-#define CVMX_CIU_MBOX_CLRX(offset) \
- CVMX_ADD_IO_SEG(0x0001070000000680ull + (((offset) & 15) * 8))
-#define CVMX_CIU_MBOX_SETX(offset) \
- CVMX_ADD_IO_SEG(0x0001070000000600ull + (((offset) & 15) * 8))
-#define CVMX_CIU_NMI \
- CVMX_ADD_IO_SEG(0x0001070000000718ull)
-#define CVMX_CIU_PCI_INTA \
- CVMX_ADD_IO_SEG(0x0001070000000750ull)
-#define CVMX_CIU_PP_DBG \
- CVMX_ADD_IO_SEG(0x0001070000000708ull)
-#define CVMX_CIU_PP_POKEX(offset) \
- CVMX_ADD_IO_SEG(0x0001070000000580ull + (((offset) & 15) * 8))
-#define CVMX_CIU_PP_RST \
- CVMX_ADD_IO_SEG(0x0001070000000700ull)
-#define CVMX_CIU_QLM_DCOK \
- CVMX_ADD_IO_SEG(0x0001070000000760ull)
-#define CVMX_CIU_QLM_JTGC \
- CVMX_ADD_IO_SEG(0x0001070000000768ull)
-#define CVMX_CIU_QLM_JTGD \
- CVMX_ADD_IO_SEG(0x0001070000000770ull)
-#define CVMX_CIU_SOFT_BIST \
- CVMX_ADD_IO_SEG(0x0001070000000738ull)
-#define CVMX_CIU_SOFT_PRST \
- CVMX_ADD_IO_SEG(0x0001070000000748ull)
-#define CVMX_CIU_SOFT_PRST1 \
- CVMX_ADD_IO_SEG(0x0001070000000758ull)
-#define CVMX_CIU_SOFT_RST \
- CVMX_ADD_IO_SEG(0x0001070000000740ull)
-#define CVMX_CIU_TIMX(offset) \
- CVMX_ADD_IO_SEG(0x0001070000000480ull + (((offset) & 3) * 8))
-#define CVMX_CIU_WDOGX(offset) \
- CVMX_ADD_IO_SEG(0x0001070000000500ull + (((offset) & 15) * 8))
+#define CVMX_CIU_BIST (CVMX_ADD_IO_SEG(0x0001070000000730ull))
+#define CVMX_CIU_BLOCK_INT (CVMX_ADD_IO_SEG(0x00010700000007C0ull))
+#define CVMX_CIU_DINT (CVMX_ADD_IO_SEG(0x0001070000000720ull))
+#define CVMX_CIU_FUSE (CVMX_ADD_IO_SEG(0x0001070000000728ull))
+#define CVMX_CIU_GSTOP (CVMX_ADD_IO_SEG(0x0001070000000710ull))
+#define CVMX_CIU_INT33_SUM0 (CVMX_ADD_IO_SEG(0x0001070000000110ull))
+#define CVMX_CIU_INTX_EN0(offset) (CVMX_ADD_IO_SEG(0x0001070000000200ull) + ((offset) & 63) * 16)
+#define CVMX_CIU_INTX_EN0_W1C(offset) (CVMX_ADD_IO_SEG(0x0001070000002200ull) + ((offset) & 63) * 16)
+#define CVMX_CIU_INTX_EN0_W1S(offset) (CVMX_ADD_IO_SEG(0x0001070000006200ull) + ((offset) & 63) * 16)
+#define CVMX_CIU_INTX_EN1(offset) (CVMX_ADD_IO_SEG(0x0001070000000208ull) + ((offset) & 63) * 16)
+#define CVMX_CIU_INTX_EN1_W1C(offset) (CVMX_ADD_IO_SEG(0x0001070000002208ull) + ((offset) & 63) * 16)
+#define CVMX_CIU_INTX_EN1_W1S(offset) (CVMX_ADD_IO_SEG(0x0001070000006208ull) + ((offset) & 63) * 16)
+#define CVMX_CIU_INTX_EN4_0(offset) (CVMX_ADD_IO_SEG(0x0001070000000C80ull) + ((offset) & 15) * 16)
+#define CVMX_CIU_INTX_EN4_0_W1C(offset) (CVMX_ADD_IO_SEG(0x0001070000002C80ull) + ((offset) & 15) * 16)
+#define CVMX_CIU_INTX_EN4_0_W1S(offset) (CVMX_ADD_IO_SEG(0x0001070000006C80ull) + ((offset) & 15) * 16)
+#define CVMX_CIU_INTX_EN4_1(offset) (CVMX_ADD_IO_SEG(0x0001070000000C88ull) + ((offset) & 15) * 16)
+#define CVMX_CIU_INTX_EN4_1_W1C(offset) (CVMX_ADD_IO_SEG(0x0001070000002C88ull) + ((offset) & 15) * 16)
+#define CVMX_CIU_INTX_EN4_1_W1S(offset) (CVMX_ADD_IO_SEG(0x0001070000006C88ull) + ((offset) & 15) * 16)
+#define CVMX_CIU_INTX_SUM0(offset) (CVMX_ADD_IO_SEG(0x0001070000000000ull) + ((offset) & 63) * 8)
+#define CVMX_CIU_INTX_SUM4(offset) (CVMX_ADD_IO_SEG(0x0001070000000C00ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_INT_DBG_SEL (CVMX_ADD_IO_SEG(0x00010700000007D0ull))
+#define CVMX_CIU_INT_SUM1 (CVMX_ADD_IO_SEG(0x0001070000000108ull))
+#define CVMX_CIU_MBOX_CLRX(offset) (CVMX_ADD_IO_SEG(0x0001070000000680ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_MBOX_SETX(offset) (CVMX_ADD_IO_SEG(0x0001070000000600ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_NMI (CVMX_ADD_IO_SEG(0x0001070000000718ull))
+#define CVMX_CIU_PCI_INTA (CVMX_ADD_IO_SEG(0x0001070000000750ull))
+#define CVMX_CIU_PP_DBG (CVMX_ADD_IO_SEG(0x0001070000000708ull))
+#define CVMX_CIU_PP_POKEX(offset) (CVMX_ADD_IO_SEG(0x0001070000000580ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_PP_RST (CVMX_ADD_IO_SEG(0x0001070000000700ull))
+#define CVMX_CIU_QLM0 (CVMX_ADD_IO_SEG(0x0001070000000780ull))
+#define CVMX_CIU_QLM1 (CVMX_ADD_IO_SEG(0x0001070000000788ull))
+#define CVMX_CIU_QLM2 (CVMX_ADD_IO_SEG(0x0001070000000790ull))
+#define CVMX_CIU_QLM_DCOK (CVMX_ADD_IO_SEG(0x0001070000000760ull))
+#define CVMX_CIU_QLM_JTGC (CVMX_ADD_IO_SEG(0x0001070000000768ull))
+#define CVMX_CIU_QLM_JTGD (CVMX_ADD_IO_SEG(0x0001070000000770ull))
+#define CVMX_CIU_SOFT_BIST (CVMX_ADD_IO_SEG(0x0001070000000738ull))
+#define CVMX_CIU_SOFT_PRST (CVMX_ADD_IO_SEG(0x0001070000000748ull))
+#define CVMX_CIU_SOFT_PRST1 (CVMX_ADD_IO_SEG(0x0001070000000758ull))
+#define CVMX_CIU_SOFT_RST (CVMX_ADD_IO_SEG(0x0001070000000740ull))
+#define CVMX_CIU_TIMX(offset) (CVMX_ADD_IO_SEG(0x0001070000000480ull) + ((offset) & 3) * 8)
+#define CVMX_CIU_WDOGX(offset) (CVMX_ADD_IO_SEG(0x0001070000000500ull) + ((offset) & 15) * 8)
union cvmx_ciu_bist {
uint64_t u64;
struct cvmx_ciu_bist_s {
+ uint64_t reserved_5_63:59;
+ uint64_t bist:5;
+ } s;
+ struct cvmx_ciu_bist_cn30xx {
uint64_t reserved_4_63:60;
uint64_t bist:4;
- } s;
- struct cvmx_ciu_bist_s cn30xx;
- struct cvmx_ciu_bist_s cn31xx;
- struct cvmx_ciu_bist_s cn38xx;
- struct cvmx_ciu_bist_s cn38xxp2;
+ } cn30xx;
+ struct cvmx_ciu_bist_cn30xx cn31xx;
+ struct cvmx_ciu_bist_cn30xx cn38xx;
+ struct cvmx_ciu_bist_cn30xx cn38xxp2;
struct cvmx_ciu_bist_cn50xx {
uint64_t reserved_2_63:62;
uint64_t bist:2;
@@ -118,10 +92,57 @@ union cvmx_ciu_bist {
uint64_t bist:3;
} cn52xx;
struct cvmx_ciu_bist_cn52xx cn52xxp1;
- struct cvmx_ciu_bist_s cn56xx;
- struct cvmx_ciu_bist_s cn56xxp1;
- struct cvmx_ciu_bist_s cn58xx;
- struct cvmx_ciu_bist_s cn58xxp1;
+ struct cvmx_ciu_bist_cn30xx cn56xx;
+ struct cvmx_ciu_bist_cn30xx cn56xxp1;
+ struct cvmx_ciu_bist_cn30xx cn58xx;
+ struct cvmx_ciu_bist_cn30xx cn58xxp1;
+ struct cvmx_ciu_bist_s cn63xx;
+ struct cvmx_ciu_bist_s cn63xxp1;
+};
+
+union cvmx_ciu_block_int {
+ uint64_t u64;
+ struct cvmx_ciu_block_int_s {
+ uint64_t reserved_43_63:21;
+ uint64_t ptp:1;
+ uint64_t dpi:1;
+ uint64_t dfm:1;
+ uint64_t reserved_34_39:6;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t reserved_31_31:1;
+ uint64_t iob:1;
+ uint64_t reserved_29_29:1;
+ uint64_t agl:1;
+ uint64_t reserved_27_27:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t reserved_23_24:2;
+ uint64_t asxpcs0:1;
+ uint64_t reserved_21_21:1;
+ uint64_t pip:1;
+ uint64_t reserved_18_19:2;
+ uint64_t lmc0:1;
+ uint64_t l2c:1;
+ uint64_t reserved_15_15:1;
+ uint64_t rad:1;
+ uint64_t usb:1;
+ uint64_t pow:1;
+ uint64_t tim:1;
+ uint64_t pko:1;
+ uint64_t ipd:1;
+ uint64_t reserved_8_8:1;
+ uint64_t zip:1;
+ uint64_t dfa:1;
+ uint64_t fpa:1;
+ uint64_t key:1;
+ uint64_t sli:1;
+ uint64_t reserved_2_2:1;
+ uint64_t gmx0:1;
+ uint64_t mio:1;
+ } s;
+ struct cvmx_ciu_block_int_s cn63xx;
+ struct cvmx_ciu_block_int_s cn63xxp1;
};
union cvmx_ciu_dint {
@@ -153,6 +174,11 @@ union cvmx_ciu_dint {
struct cvmx_ciu_dint_cn56xx cn56xxp1;
struct cvmx_ciu_dint_s cn58xx;
struct cvmx_ciu_dint_s cn58xxp1;
+ struct cvmx_ciu_dint_cn63xx {
+ uint64_t reserved_6_63:58;
+ uint64_t dint:6;
+ } cn63xx;
+ struct cvmx_ciu_dint_cn63xx cn63xxp1;
};
union cvmx_ciu_fuse {
@@ -184,6 +210,11 @@ union cvmx_ciu_fuse {
struct cvmx_ciu_fuse_cn56xx cn56xxp1;
struct cvmx_ciu_fuse_s cn58xx;
struct cvmx_ciu_fuse_s cn58xxp1;
+ struct cvmx_ciu_fuse_cn63xx {
+ uint64_t reserved_6_63:58;
+ uint64_t fuse:6;
+ } cn63xx;
+ struct cvmx_ciu_fuse_cn63xx cn63xxp1;
};
union cvmx_ciu_gstop {
@@ -203,6 +234,8 @@ union cvmx_ciu_gstop {
struct cvmx_ciu_gstop_s cn56xxp1;
struct cvmx_ciu_gstop_s cn58xx;
struct cvmx_ciu_gstop_s cn58xxp1;
+ struct cvmx_ciu_gstop_s cn63xx;
+ struct cvmx_ciu_gstop_s cn63xxp1;
};
union cvmx_ciu_intx_en0 {
@@ -343,6 +376,8 @@ union cvmx_ciu_intx_en0 {
struct cvmx_ciu_intx_en0_cn56xx cn56xxp1;
struct cvmx_ciu_intx_en0_cn38xx cn58xx;
struct cvmx_ciu_intx_en0_cn38xx cn58xxp1;
+ struct cvmx_ciu_intx_en0_cn52xx cn63xx;
+ struct cvmx_ciu_intx_en0_cn52xx cn63xxp1;
};
union cvmx_ciu_intx_en0_w1c {
@@ -412,6 +447,8 @@ union cvmx_ciu_intx_en0_w1c {
uint64_t gpio:16;
uint64_t workq:16;
} cn58xx;
+ struct cvmx_ciu_intx_en0_w1c_cn52xx cn63xx;
+ struct cvmx_ciu_intx_en0_w1c_cn52xx cn63xxp1;
};
union cvmx_ciu_intx_en0_w1s {
@@ -481,12 +518,42 @@ union cvmx_ciu_intx_en0_w1s {
uint64_t gpio:16;
uint64_t workq:16;
} cn58xx;
+ struct cvmx_ciu_intx_en0_w1s_cn52xx cn63xx;
+ struct cvmx_ciu_intx_en0_w1s_cn52xx cn63xxp1;
};
union cvmx_ciu_intx_en1 {
uint64_t u64;
struct cvmx_ciu_intx_en1_s {
- uint64_t reserved_20_63:44;
+ uint64_t rst:1;
+ uint64_t reserved_57_62:6;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
uint64_t nand:1;
uint64_t mii1:1;
uint64_t usb1:1;
@@ -531,12 +598,76 @@ union cvmx_ciu_intx_en1 {
struct cvmx_ciu_intx_en1_cn56xx cn56xxp1;
struct cvmx_ciu_intx_en1_cn38xx cn58xx;
struct cvmx_ciu_intx_en1_cn38xx cn58xxp1;
+ struct cvmx_ciu_intx_en1_cn63xx {
+ uint64_t rst:1;
+ uint64_t reserved_57_62:6;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_6_17:12;
+ uint64_t wdog:6;
+ } cn63xx;
+ struct cvmx_ciu_intx_en1_cn63xx cn63xxp1;
};
union cvmx_ciu_intx_en1_w1c {
uint64_t u64;
struct cvmx_ciu_intx_en1_w1c_s {
- uint64_t reserved_20_63:44;
+ uint64_t rst:1;
+ uint64_t reserved_57_62:6;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
uint64_t nand:1;
uint64_t mii1:1;
uint64_t usb1:1;
@@ -560,12 +691,76 @@ union cvmx_ciu_intx_en1_w1c {
uint64_t reserved_16_63:48;
uint64_t wdog:16;
} cn58xx;
+ struct cvmx_ciu_intx_en1_w1c_cn63xx {
+ uint64_t rst:1;
+ uint64_t reserved_57_62:6;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_6_17:12;
+ uint64_t wdog:6;
+ } cn63xx;
+ struct cvmx_ciu_intx_en1_w1c_cn63xx cn63xxp1;
};
union cvmx_ciu_intx_en1_w1s {
uint64_t u64;
struct cvmx_ciu_intx_en1_w1s_s {
- uint64_t reserved_20_63:44;
+ uint64_t rst:1;
+ uint64_t reserved_57_62:6;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
uint64_t nand:1;
uint64_t mii1:1;
uint64_t usb1:1;
@@ -589,6 +784,42 @@ union cvmx_ciu_intx_en1_w1s {
uint64_t reserved_16_63:48;
uint64_t wdog:16;
} cn58xx;
+ struct cvmx_ciu_intx_en1_w1s_cn63xx {
+ uint64_t rst:1;
+ uint64_t reserved_57_62:6;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_6_17:12;
+ uint64_t wdog:6;
+ } cn63xx;
+ struct cvmx_ciu_intx_en1_w1s_cn63xx cn63xxp1;
};
union cvmx_ciu_intx_en4_0 {
@@ -705,6 +936,8 @@ union cvmx_ciu_intx_en4_0 {
uint64_t workq:16;
} cn58xx;
struct cvmx_ciu_intx_en4_0_cn58xx cn58xxp1;
+ struct cvmx_ciu_intx_en4_0_cn52xx cn63xx;
+ struct cvmx_ciu_intx_en4_0_cn52xx cn63xxp1;
};
union cvmx_ciu_intx_en4_0_w1c {
@@ -774,6 +1007,8 @@ union cvmx_ciu_intx_en4_0_w1c {
uint64_t gpio:16;
uint64_t workq:16;
} cn58xx;
+ struct cvmx_ciu_intx_en4_0_w1c_cn52xx cn63xx;
+ struct cvmx_ciu_intx_en4_0_w1c_cn52xx cn63xxp1;
};
union cvmx_ciu_intx_en4_0_w1s {
@@ -843,12 +1078,42 @@ union cvmx_ciu_intx_en4_0_w1s {
uint64_t gpio:16;
uint64_t workq:16;
} cn58xx;
+ struct cvmx_ciu_intx_en4_0_w1s_cn52xx cn63xx;
+ struct cvmx_ciu_intx_en4_0_w1s_cn52xx cn63xxp1;
};
union cvmx_ciu_intx_en4_1 {
uint64_t u64;
struct cvmx_ciu_intx_en4_1_s {
- uint64_t reserved_20_63:44;
+ uint64_t rst:1;
+ uint64_t reserved_57_62:6;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
uint64_t nand:1;
uint64_t mii1:1;
uint64_t usb1:1;
@@ -886,12 +1151,76 @@ union cvmx_ciu_intx_en4_1 {
uint64_t wdog:16;
} cn58xx;
struct cvmx_ciu_intx_en4_1_cn58xx cn58xxp1;
+ struct cvmx_ciu_intx_en4_1_cn63xx {
+ uint64_t rst:1;
+ uint64_t reserved_57_62:6;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_6_17:12;
+ uint64_t wdog:6;
+ } cn63xx;
+ struct cvmx_ciu_intx_en4_1_cn63xx cn63xxp1;
};
union cvmx_ciu_intx_en4_1_w1c {
uint64_t u64;
struct cvmx_ciu_intx_en4_1_w1c_s {
- uint64_t reserved_20_63:44;
+ uint64_t rst:1;
+ uint64_t reserved_57_62:6;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
uint64_t nand:1;
uint64_t mii1:1;
uint64_t usb1:1;
@@ -915,12 +1244,76 @@ union cvmx_ciu_intx_en4_1_w1c {
uint64_t reserved_16_63:48;
uint64_t wdog:16;
} cn58xx;
+ struct cvmx_ciu_intx_en4_1_w1c_cn63xx {
+ uint64_t rst:1;
+ uint64_t reserved_57_62:6;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_6_17:12;
+ uint64_t wdog:6;
+ } cn63xx;
+ struct cvmx_ciu_intx_en4_1_w1c_cn63xx cn63xxp1;
};
union cvmx_ciu_intx_en4_1_w1s {
uint64_t u64;
struct cvmx_ciu_intx_en4_1_w1s_s {
- uint64_t reserved_20_63:44;
+ uint64_t rst:1;
+ uint64_t reserved_57_62:6;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
uint64_t nand:1;
uint64_t mii1:1;
uint64_t usb1:1;
@@ -944,6 +1337,42 @@ union cvmx_ciu_intx_en4_1_w1s {
uint64_t reserved_16_63:48;
uint64_t wdog:16;
} cn58xx;
+ struct cvmx_ciu_intx_en4_1_w1s_cn63xx {
+ uint64_t rst:1;
+ uint64_t reserved_57_62:6;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_6_17:12;
+ uint64_t wdog:6;
+ } cn63xx;
+ struct cvmx_ciu_intx_en4_1_w1s_cn63xx cn63xxp1;
};
union cvmx_ciu_intx_sum0 {
@@ -1084,6 +1513,8 @@ union cvmx_ciu_intx_sum0 {
struct cvmx_ciu_intx_sum0_cn56xx cn56xxp1;
struct cvmx_ciu_intx_sum0_cn38xx cn58xx;
struct cvmx_ciu_intx_sum0_cn38xx cn58xxp1;
+ struct cvmx_ciu_intx_sum0_cn52xx cn63xx;
+ struct cvmx_ciu_intx_sum0_cn52xx cn63xxp1;
};
union cvmx_ciu_intx_sum4 {
@@ -1200,12 +1631,85 @@ union cvmx_ciu_intx_sum4 {
uint64_t workq:16;
} cn58xx;
struct cvmx_ciu_intx_sum4_cn58xx cn58xxp1;
+ struct cvmx_ciu_intx_sum4_cn52xx cn63xx;
+ struct cvmx_ciu_intx_sum4_cn52xx cn63xxp1;
+};
+
+union cvmx_ciu_int33_sum0 {
+ uint64_t u64;
+ struct cvmx_ciu_int33_sum0_s {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } s;
+ struct cvmx_ciu_int33_sum0_s cn63xx;
+ struct cvmx_ciu_int33_sum0_s cn63xxp1;
+};
+
+union cvmx_ciu_int_dbg_sel {
+ uint64_t u64;
+ struct cvmx_ciu_int_dbg_sel_s {
+ uint64_t reserved_19_63:45;
+ uint64_t sel:3;
+ uint64_t reserved_10_15:6;
+ uint64_t irq:2;
+ uint64_t reserved_3_7:5;
+ uint64_t pp:3;
+ } s;
+ struct cvmx_ciu_int_dbg_sel_s cn63xx;
};
union cvmx_ciu_int_sum1 {
uint64_t u64;
struct cvmx_ciu_int_sum1_s {
- uint64_t reserved_20_63:44;
+ uint64_t rst:1;
+ uint64_t reserved_57_62:6;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
uint64_t nand:1;
uint64_t mii1:1;
uint64_t usb1:1;
@@ -1250,6 +1754,42 @@ union cvmx_ciu_int_sum1 {
struct cvmx_ciu_int_sum1_cn56xx cn56xxp1;
struct cvmx_ciu_int_sum1_cn38xx cn58xx;
struct cvmx_ciu_int_sum1_cn38xx cn58xxp1;
+ struct cvmx_ciu_int_sum1_cn63xx {
+ uint64_t rst:1;
+ uint64_t reserved_57_62:6;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_6_17:12;
+ uint64_t wdog:6;
+ } cn63xx;
+ struct cvmx_ciu_int_sum1_cn63xx cn63xxp1;
};
union cvmx_ciu_mbox_clrx {
@@ -1269,6 +1809,8 @@ union cvmx_ciu_mbox_clrx {
struct cvmx_ciu_mbox_clrx_s cn56xxp1;
struct cvmx_ciu_mbox_clrx_s cn58xx;
struct cvmx_ciu_mbox_clrx_s cn58xxp1;
+ struct cvmx_ciu_mbox_clrx_s cn63xx;
+ struct cvmx_ciu_mbox_clrx_s cn63xxp1;
};
union cvmx_ciu_mbox_setx {
@@ -1288,6 +1830,8 @@ union cvmx_ciu_mbox_setx {
struct cvmx_ciu_mbox_setx_s cn56xxp1;
struct cvmx_ciu_mbox_setx_s cn58xx;
struct cvmx_ciu_mbox_setx_s cn58xxp1;
+ struct cvmx_ciu_mbox_setx_s cn63xx;
+ struct cvmx_ciu_mbox_setx_s cn63xxp1;
};
union cvmx_ciu_nmi {
@@ -1319,6 +1863,11 @@ union cvmx_ciu_nmi {
struct cvmx_ciu_nmi_cn56xx cn56xxp1;
struct cvmx_ciu_nmi_s cn58xx;
struct cvmx_ciu_nmi_s cn58xxp1;
+ struct cvmx_ciu_nmi_cn63xx {
+ uint64_t reserved_6_63:58;
+ uint64_t nmi:6;
+ } cn63xx;
+ struct cvmx_ciu_nmi_cn63xx cn63xxp1;
};
union cvmx_ciu_pci_inta {
@@ -1338,6 +1887,8 @@ union cvmx_ciu_pci_inta {
struct cvmx_ciu_pci_inta_s cn56xxp1;
struct cvmx_ciu_pci_inta_s cn58xx;
struct cvmx_ciu_pci_inta_s cn58xxp1;
+ struct cvmx_ciu_pci_inta_s cn63xx;
+ struct cvmx_ciu_pci_inta_s cn63xxp1;
};
union cvmx_ciu_pp_dbg {
@@ -1369,12 +1920,17 @@ union cvmx_ciu_pp_dbg {
struct cvmx_ciu_pp_dbg_cn56xx cn56xxp1;
struct cvmx_ciu_pp_dbg_s cn58xx;
struct cvmx_ciu_pp_dbg_s cn58xxp1;
+ struct cvmx_ciu_pp_dbg_cn63xx {
+ uint64_t reserved_6_63:58;
+ uint64_t ppdbg:6;
+ } cn63xx;
+ struct cvmx_ciu_pp_dbg_cn63xx cn63xxp1;
};
union cvmx_ciu_pp_pokex {
uint64_t u64;
struct cvmx_ciu_pp_pokex_s {
- uint64_t reserved_0_63:64;
+ uint64_t poke:64;
} s;
struct cvmx_ciu_pp_pokex_s cn30xx;
struct cvmx_ciu_pp_pokex_s cn31xx;
@@ -1387,6 +1943,8 @@ union cvmx_ciu_pp_pokex {
struct cvmx_ciu_pp_pokex_s cn56xxp1;
struct cvmx_ciu_pp_pokex_s cn58xx;
struct cvmx_ciu_pp_pokex_s cn58xxp1;
+ struct cvmx_ciu_pp_pokex_s cn63xx;
+ struct cvmx_ciu_pp_pokex_s cn63xxp1;
};
union cvmx_ciu_pp_rst {
@@ -1422,6 +1980,97 @@ union cvmx_ciu_pp_rst {
struct cvmx_ciu_pp_rst_cn56xx cn56xxp1;
struct cvmx_ciu_pp_rst_s cn58xx;
struct cvmx_ciu_pp_rst_s cn58xxp1;
+ struct cvmx_ciu_pp_rst_cn63xx {
+ uint64_t reserved_6_63:58;
+ uint64_t rst:5;
+ uint64_t rst0:1;
+ } cn63xx;
+ struct cvmx_ciu_pp_rst_cn63xx cn63xxp1;
+};
+
+union cvmx_ciu_qlm0 {
+ uint64_t u64;
+ struct cvmx_ciu_qlm0_s {
+ uint64_t g2bypass:1;
+ uint64_t reserved_53_62:10;
+ uint64_t g2deemph:5;
+ uint64_t reserved_45_47:3;
+ uint64_t g2margin:5;
+ uint64_t reserved_32_39:8;
+ uint64_t txbypass:1;
+ uint64_t reserved_21_30:10;
+ uint64_t txdeemph:5;
+ uint64_t reserved_13_15:3;
+ uint64_t txmargin:5;
+ uint64_t reserved_4_7:4;
+ uint64_t lane_en:4;
+ } s;
+ struct cvmx_ciu_qlm0_s cn63xx;
+ struct cvmx_ciu_qlm0_cn63xxp1 {
+ uint64_t reserved_32_63:32;
+ uint64_t txbypass:1;
+ uint64_t reserved_20_30:11;
+ uint64_t txdeemph:4;
+ uint64_t reserved_13_15:3;
+ uint64_t txmargin:5;
+ uint64_t reserved_4_7:4;
+ uint64_t lane_en:4;
+ } cn63xxp1;
+};
+
+union cvmx_ciu_qlm1 {
+ uint64_t u64;
+ struct cvmx_ciu_qlm1_s {
+ uint64_t g2bypass:1;
+ uint64_t reserved_53_62:10;
+ uint64_t g2deemph:5;
+ uint64_t reserved_45_47:3;
+ uint64_t g2margin:5;
+ uint64_t reserved_32_39:8;
+ uint64_t txbypass:1;
+ uint64_t reserved_21_30:10;
+ uint64_t txdeemph:5;
+ uint64_t reserved_13_15:3;
+ uint64_t txmargin:5;
+ uint64_t reserved_4_7:4;
+ uint64_t lane_en:4;
+ } s;
+ struct cvmx_ciu_qlm1_s cn63xx;
+ struct cvmx_ciu_qlm1_cn63xxp1 {
+ uint64_t reserved_32_63:32;
+ uint64_t txbypass:1;
+ uint64_t reserved_20_30:11;
+ uint64_t txdeemph:4;
+ uint64_t reserved_13_15:3;
+ uint64_t txmargin:5;
+ uint64_t reserved_4_7:4;
+ uint64_t lane_en:4;
+ } cn63xxp1;
+};
+
+union cvmx_ciu_qlm2 {
+ uint64_t u64;
+ struct cvmx_ciu_qlm2_s {
+ uint64_t reserved_32_63:32;
+ uint64_t txbypass:1;
+ uint64_t reserved_21_30:10;
+ uint64_t txdeemph:5;
+ uint64_t reserved_13_15:3;
+ uint64_t txmargin:5;
+ uint64_t reserved_4_7:4;
+ uint64_t lane_en:4;
+ } s;
+ struct cvmx_ciu_qlm2_s cn63xx;
+ struct cvmx_ciu_qlm2_cn63xxp1 {
+ uint64_t reserved_32_63:32;
+ uint64_t txbypass:1;
+ uint64_t reserved_20_30:11;
+ uint64_t txdeemph:4;
+ uint64_t reserved_13_15:3;
+ uint64_t txmargin:5;
+ uint64_t reserved_4_7:4;
+ uint64_t lane_en:4;
+ } cn63xxp1;
};
union cvmx_ciu_qlm_dcok {
@@ -1459,6 +2108,15 @@ union cvmx_ciu_qlm_jtgc {
struct cvmx_ciu_qlm_jtgc_cn52xx cn52xxp1;
struct cvmx_ciu_qlm_jtgc_s cn56xx;
struct cvmx_ciu_qlm_jtgc_s cn56xxp1;
+ struct cvmx_ciu_qlm_jtgc_cn63xx {
+ uint64_t reserved_11_63:53;
+ uint64_t clk_div:3;
+ uint64_t reserved_6_7:2;
+ uint64_t mux_sel:2;
+ uint64_t reserved_3_3:1;
+ uint64_t bypass:3;
+ } cn63xx;
+ struct cvmx_ciu_qlm_jtgc_cn63xx cn63xxp1;
};
union cvmx_ciu_qlm_jtgd {
@@ -1493,6 +2151,17 @@ union cvmx_ciu_qlm_jtgd {
uint64_t shft_cnt:5;
uint64_t shft_reg:32;
} cn56xxp1;
+ struct cvmx_ciu_qlm_jtgd_cn63xx {
+ uint64_t capture:1;
+ uint64_t shift:1;
+ uint64_t update:1;
+ uint64_t reserved_43_60:18;
+ uint64_t select:3;
+ uint64_t reserved_37_39:3;
+ uint64_t shft_cnt:5;
+ uint64_t shft_reg:32;
+ } cn63xx;
+ struct cvmx_ciu_qlm_jtgd_cn63xx cn63xxp1;
};
union cvmx_ciu_soft_bist {
@@ -1512,6 +2181,8 @@ union cvmx_ciu_soft_bist {
struct cvmx_ciu_soft_bist_s cn56xxp1;
struct cvmx_ciu_soft_bist_s cn58xx;
struct cvmx_ciu_soft_bist_s cn58xxp1;
+ struct cvmx_ciu_soft_bist_s cn63xx;
+ struct cvmx_ciu_soft_bist_s cn63xxp1;
};
union cvmx_ciu_soft_prst {
@@ -1536,6 +2207,8 @@ union cvmx_ciu_soft_prst {
struct cvmx_ciu_soft_prst_cn52xx cn56xxp1;
struct cvmx_ciu_soft_prst_s cn58xx;
struct cvmx_ciu_soft_prst_s cn58xxp1;
+ struct cvmx_ciu_soft_prst_cn52xx cn63xx;
+ struct cvmx_ciu_soft_prst_cn52xx cn63xxp1;
};
union cvmx_ciu_soft_prst1 {
@@ -1548,6 +2221,8 @@ union cvmx_ciu_soft_prst1 {
struct cvmx_ciu_soft_prst1_s cn52xxp1;
struct cvmx_ciu_soft_prst1_s cn56xx;
struct cvmx_ciu_soft_prst1_s cn56xxp1;
+ struct cvmx_ciu_soft_prst1_s cn63xx;
+ struct cvmx_ciu_soft_prst1_s cn63xxp1;
};
union cvmx_ciu_soft_rst {
@@ -1567,6 +2242,8 @@ union cvmx_ciu_soft_rst {
struct cvmx_ciu_soft_rst_s cn56xxp1;
struct cvmx_ciu_soft_rst_s cn58xx;
struct cvmx_ciu_soft_rst_s cn58xxp1;
+ struct cvmx_ciu_soft_rst_s cn63xx;
+ struct cvmx_ciu_soft_rst_s cn63xxp1;
};
union cvmx_ciu_timx {
@@ -1587,6 +2264,8 @@ union cvmx_ciu_timx {
struct cvmx_ciu_timx_s cn56xxp1;
struct cvmx_ciu_timx_s cn58xx;
struct cvmx_ciu_timx_s cn58xxp1;
+ struct cvmx_ciu_timx_s cn63xx;
+ struct cvmx_ciu_timx_s cn63xxp1;
};
union cvmx_ciu_wdogx {
@@ -1611,6 +2290,8 @@ union cvmx_ciu_wdogx {
struct cvmx_ciu_wdogx_s cn56xxp1;
struct cvmx_ciu_wdogx_s cn58xx;
struct cvmx_ciu_wdogx_s cn58xxp1;
+ struct cvmx_ciu_wdogx_s cn63xx;
+ struct cvmx_ciu_wdogx_s cn63xxp1;
};
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-gpio-defs.h b/arch/mips/include/asm/octeon/cvmx-gpio-defs.h
index 5fdd6ba48a05..395564e8d1f0 100644
--- a/arch/mips/include/asm/octeon/cvmx-gpio-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-gpio-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
@@ -28,29 +28,22 @@
#ifndef __CVMX_GPIO_DEFS_H__
#define __CVMX_GPIO_DEFS_H__
-#define CVMX_GPIO_BIT_CFGX(offset) \
- CVMX_ADD_IO_SEG(0x0001070000000800ull + (((offset) & 15) * 8))
-#define CVMX_GPIO_BOOT_ENA \
- CVMX_ADD_IO_SEG(0x00010700000008A8ull)
-#define CVMX_GPIO_CLK_GENX(offset) \
- CVMX_ADD_IO_SEG(0x00010700000008C0ull + (((offset) & 3) * 8))
-#define CVMX_GPIO_DBG_ENA \
- CVMX_ADD_IO_SEG(0x00010700000008A0ull)
-#define CVMX_GPIO_INT_CLR \
- CVMX_ADD_IO_SEG(0x0001070000000898ull)
-#define CVMX_GPIO_RX_DAT \
- CVMX_ADD_IO_SEG(0x0001070000000880ull)
-#define CVMX_GPIO_TX_CLR \
- CVMX_ADD_IO_SEG(0x0001070000000890ull)
-#define CVMX_GPIO_TX_SET \
- CVMX_ADD_IO_SEG(0x0001070000000888ull)
-#define CVMX_GPIO_XBIT_CFGX(offset) \
- CVMX_ADD_IO_SEG(0x0001070000000900ull + (((offset) & 31) * 8) - 8 * 16)
+#define CVMX_GPIO_BIT_CFGX(offset) (CVMX_ADD_IO_SEG(0x0001070000000800ull) + ((offset) & 15) * 8)
+#define CVMX_GPIO_BOOT_ENA (CVMX_ADD_IO_SEG(0x00010700000008A8ull))
+#define CVMX_GPIO_CLK_GENX(offset) (CVMX_ADD_IO_SEG(0x00010700000008C0ull) + ((offset) & 3) * 8)
+#define CVMX_GPIO_CLK_QLMX(offset) (CVMX_ADD_IO_SEG(0x00010700000008E0ull) + ((offset) & 1) * 8)
+#define CVMX_GPIO_DBG_ENA (CVMX_ADD_IO_SEG(0x00010700000008A0ull))
+#define CVMX_GPIO_INT_CLR (CVMX_ADD_IO_SEG(0x0001070000000898ull))
+#define CVMX_GPIO_RX_DAT (CVMX_ADD_IO_SEG(0x0001070000000880ull))
+#define CVMX_GPIO_TX_CLR (CVMX_ADD_IO_SEG(0x0001070000000890ull))
+#define CVMX_GPIO_TX_SET (CVMX_ADD_IO_SEG(0x0001070000000888ull))
+#define CVMX_GPIO_XBIT_CFGX(offset) (CVMX_ADD_IO_SEG(0x0001070000000900ull) + ((offset) & 31) * 8 - 8*16)
union cvmx_gpio_bit_cfgx {
uint64_t u64;
struct cvmx_gpio_bit_cfgx_s {
- uint64_t reserved_15_63:49;
+ uint64_t reserved_17_63:47;
+ uint64_t synce_sel:2;
uint64_t clk_gen:1;
uint64_t clk_sel:2;
uint64_t fil_sel:4;
@@ -73,12 +66,24 @@ union cvmx_gpio_bit_cfgx {
struct cvmx_gpio_bit_cfgx_cn30xx cn38xx;
struct cvmx_gpio_bit_cfgx_cn30xx cn38xxp2;
struct cvmx_gpio_bit_cfgx_cn30xx cn50xx;
- struct cvmx_gpio_bit_cfgx_s cn52xx;
- struct cvmx_gpio_bit_cfgx_s cn52xxp1;
- struct cvmx_gpio_bit_cfgx_s cn56xx;
- struct cvmx_gpio_bit_cfgx_s cn56xxp1;
+ struct cvmx_gpio_bit_cfgx_cn52xx {
+ uint64_t reserved_15_63:49;
+ uint64_t clk_gen:1;
+ uint64_t clk_sel:2;
+ uint64_t fil_sel:4;
+ uint64_t fil_cnt:4;
+ uint64_t int_type:1;
+ uint64_t int_en:1;
+ uint64_t rx_xor:1;
+ uint64_t tx_oe:1;
+ } cn52xx;
+ struct cvmx_gpio_bit_cfgx_cn52xx cn52xxp1;
+ struct cvmx_gpio_bit_cfgx_cn52xx cn56xx;
+ struct cvmx_gpio_bit_cfgx_cn52xx cn56xxp1;
struct cvmx_gpio_bit_cfgx_cn30xx cn58xx;
struct cvmx_gpio_bit_cfgx_cn30xx cn58xxp1;
+ struct cvmx_gpio_bit_cfgx_s cn63xx;
+ struct cvmx_gpio_bit_cfgx_s cn63xxp1;
};
union cvmx_gpio_boot_ena {
@@ -103,6 +108,19 @@ union cvmx_gpio_clk_genx {
struct cvmx_gpio_clk_genx_s cn52xxp1;
struct cvmx_gpio_clk_genx_s cn56xx;
struct cvmx_gpio_clk_genx_s cn56xxp1;
+ struct cvmx_gpio_clk_genx_s cn63xx;
+ struct cvmx_gpio_clk_genx_s cn63xxp1;
+};
+
+union cvmx_gpio_clk_qlmx {
+ uint64_t u64;
+ struct cvmx_gpio_clk_qlmx_s {
+ uint64_t reserved_3_63:61;
+ uint64_t div:1;
+ uint64_t lane_sel:2;
+ } s;
+ struct cvmx_gpio_clk_qlmx_s cn63xx;
+ struct cvmx_gpio_clk_qlmx_s cn63xxp1;
};
union cvmx_gpio_dbg_ena {
@@ -133,6 +151,8 @@ union cvmx_gpio_int_clr {
struct cvmx_gpio_int_clr_s cn56xxp1;
struct cvmx_gpio_int_clr_s cn58xx;
struct cvmx_gpio_int_clr_s cn58xxp1;
+ struct cvmx_gpio_int_clr_s cn63xx;
+ struct cvmx_gpio_int_clr_s cn63xxp1;
};
union cvmx_gpio_rx_dat {
@@ -155,6 +175,8 @@ union cvmx_gpio_rx_dat {
struct cvmx_gpio_rx_dat_cn38xx cn56xxp1;
struct cvmx_gpio_rx_dat_cn38xx cn58xx;
struct cvmx_gpio_rx_dat_cn38xx cn58xxp1;
+ struct cvmx_gpio_rx_dat_cn38xx cn63xx;
+ struct cvmx_gpio_rx_dat_cn38xx cn63xxp1;
};
union cvmx_gpio_tx_clr {
@@ -177,6 +199,8 @@ union cvmx_gpio_tx_clr {
struct cvmx_gpio_tx_clr_cn38xx cn56xxp1;
struct cvmx_gpio_tx_clr_cn38xx cn58xx;
struct cvmx_gpio_tx_clr_cn38xx cn58xxp1;
+ struct cvmx_gpio_tx_clr_cn38xx cn63xx;
+ struct cvmx_gpio_tx_clr_cn38xx cn63xxp1;
};
union cvmx_gpio_tx_set {
@@ -199,6 +223,8 @@ union cvmx_gpio_tx_set {
struct cvmx_gpio_tx_set_cn38xx cn56xxp1;
struct cvmx_gpio_tx_set_cn38xx cn58xx;
struct cvmx_gpio_tx_set_cn38xx cn58xxp1;
+ struct cvmx_gpio_tx_set_cn38xx cn63xx;
+ struct cvmx_gpio_tx_set_cn38xx cn63xxp1;
};
union cvmx_gpio_xbit_cfgx {
diff --git a/arch/mips/include/asm/octeon/cvmx-iob-defs.h b/arch/mips/include/asm/octeon/cvmx-iob-defs.h
index 0ee36baec500..d7d856c2483d 100644
--- a/arch/mips/include/asm/octeon/cvmx-iob-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-iob-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
@@ -28,55 +28,39 @@
#ifndef __CVMX_IOB_DEFS_H__
#define __CVMX_IOB_DEFS_H__
-#define CVMX_IOB_BIST_STATUS \
- CVMX_ADD_IO_SEG(0x00011800F00007F8ull)
-#define CVMX_IOB_CTL_STATUS \
- CVMX_ADD_IO_SEG(0x00011800F0000050ull)
-#define CVMX_IOB_DWB_PRI_CNT \
- CVMX_ADD_IO_SEG(0x00011800F0000028ull)
-#define CVMX_IOB_FAU_TIMEOUT \
- CVMX_ADD_IO_SEG(0x00011800F0000000ull)
-#define CVMX_IOB_I2C_PRI_CNT \
- CVMX_ADD_IO_SEG(0x00011800F0000010ull)
-#define CVMX_IOB_INB_CONTROL_MATCH \
- CVMX_ADD_IO_SEG(0x00011800F0000078ull)
-#define CVMX_IOB_INB_CONTROL_MATCH_ENB \
- CVMX_ADD_IO_SEG(0x00011800F0000088ull)
-#define CVMX_IOB_INB_DATA_MATCH \
- CVMX_ADD_IO_SEG(0x00011800F0000070ull)
-#define CVMX_IOB_INB_DATA_MATCH_ENB \
- CVMX_ADD_IO_SEG(0x00011800F0000080ull)
-#define CVMX_IOB_INT_ENB \
- CVMX_ADD_IO_SEG(0x00011800F0000060ull)
-#define CVMX_IOB_INT_SUM \
- CVMX_ADD_IO_SEG(0x00011800F0000058ull)
-#define CVMX_IOB_N2C_L2C_PRI_CNT \
- CVMX_ADD_IO_SEG(0x00011800F0000020ull)
-#define CVMX_IOB_N2C_RSP_PRI_CNT \
- CVMX_ADD_IO_SEG(0x00011800F0000008ull)
-#define CVMX_IOB_OUTB_COM_PRI_CNT \
- CVMX_ADD_IO_SEG(0x00011800F0000040ull)
-#define CVMX_IOB_OUTB_CONTROL_MATCH \
- CVMX_ADD_IO_SEG(0x00011800F0000098ull)
-#define CVMX_IOB_OUTB_CONTROL_MATCH_ENB \
- CVMX_ADD_IO_SEG(0x00011800F00000A8ull)
-#define CVMX_IOB_OUTB_DATA_MATCH \
- CVMX_ADD_IO_SEG(0x00011800F0000090ull)
-#define CVMX_IOB_OUTB_DATA_MATCH_ENB \
- CVMX_ADD_IO_SEG(0x00011800F00000A0ull)
-#define CVMX_IOB_OUTB_FPA_PRI_CNT \
- CVMX_ADD_IO_SEG(0x00011800F0000048ull)
-#define CVMX_IOB_OUTB_REQ_PRI_CNT \
- CVMX_ADD_IO_SEG(0x00011800F0000038ull)
-#define CVMX_IOB_P2C_REQ_PRI_CNT \
- CVMX_ADD_IO_SEG(0x00011800F0000018ull)
-#define CVMX_IOB_PKT_ERR \
- CVMX_ADD_IO_SEG(0x00011800F0000068ull)
+#define CVMX_IOB_BIST_STATUS (CVMX_ADD_IO_SEG(0x00011800F00007F8ull))
+#define CVMX_IOB_CTL_STATUS (CVMX_ADD_IO_SEG(0x00011800F0000050ull))
+#define CVMX_IOB_DWB_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000028ull))
+#define CVMX_IOB_FAU_TIMEOUT (CVMX_ADD_IO_SEG(0x00011800F0000000ull))
+#define CVMX_IOB_I2C_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000010ull))
+#define CVMX_IOB_INB_CONTROL_MATCH (CVMX_ADD_IO_SEG(0x00011800F0000078ull))
+#define CVMX_IOB_INB_CONTROL_MATCH_ENB (CVMX_ADD_IO_SEG(0x00011800F0000088ull))
+#define CVMX_IOB_INB_DATA_MATCH (CVMX_ADD_IO_SEG(0x00011800F0000070ull))
+#define CVMX_IOB_INB_DATA_MATCH_ENB (CVMX_ADD_IO_SEG(0x00011800F0000080ull))
+#define CVMX_IOB_INT_ENB (CVMX_ADD_IO_SEG(0x00011800F0000060ull))
+#define CVMX_IOB_INT_SUM (CVMX_ADD_IO_SEG(0x00011800F0000058ull))
+#define CVMX_IOB_N2C_L2C_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000020ull))
+#define CVMX_IOB_N2C_RSP_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000008ull))
+#define CVMX_IOB_OUTB_COM_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000040ull))
+#define CVMX_IOB_OUTB_CONTROL_MATCH (CVMX_ADD_IO_SEG(0x00011800F0000098ull))
+#define CVMX_IOB_OUTB_CONTROL_MATCH_ENB (CVMX_ADD_IO_SEG(0x00011800F00000A8ull))
+#define CVMX_IOB_OUTB_DATA_MATCH (CVMX_ADD_IO_SEG(0x00011800F0000090ull))
+#define CVMX_IOB_OUTB_DATA_MATCH_ENB (CVMX_ADD_IO_SEG(0x00011800F00000A0ull))
+#define CVMX_IOB_OUTB_FPA_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000048ull))
+#define CVMX_IOB_OUTB_REQ_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000038ull))
+#define CVMX_IOB_P2C_REQ_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000018ull))
+#define CVMX_IOB_PKT_ERR (CVMX_ADD_IO_SEG(0x00011800F0000068ull))
+#define CVMX_IOB_TO_CMB_CREDITS (CVMX_ADD_IO_SEG(0x00011800F00000B0ull))
union cvmx_iob_bist_status {
uint64_t u64;
struct cvmx_iob_bist_status_s {
- uint64_t reserved_18_63:46;
+ uint64_t reserved_23_63:41;
+ uint64_t xmdfif:1;
+ uint64_t xmcfif:1;
+ uint64_t iorfif:1;
+ uint64_t rsdfif:1;
+ uint64_t iocfif:1;
uint64_t icnrcb:1;
uint64_t icr0:1;
uint64_t icr1:1;
@@ -96,40 +80,81 @@ union cvmx_iob_bist_status {
uint64_t ibd:1;
uint64_t icd:1;
} s;
- struct cvmx_iob_bist_status_s cn30xx;
- struct cvmx_iob_bist_status_s cn31xx;
- struct cvmx_iob_bist_status_s cn38xx;
- struct cvmx_iob_bist_status_s cn38xxp2;
- struct cvmx_iob_bist_status_s cn50xx;
- struct cvmx_iob_bist_status_s cn52xx;
- struct cvmx_iob_bist_status_s cn52xxp1;
- struct cvmx_iob_bist_status_s cn56xx;
- struct cvmx_iob_bist_status_s cn56xxp1;
- struct cvmx_iob_bist_status_s cn58xx;
- struct cvmx_iob_bist_status_s cn58xxp1;
+ struct cvmx_iob_bist_status_cn30xx {
+ uint64_t reserved_18_63:46;
+ uint64_t icnrcb:1;
+ uint64_t icr0:1;
+ uint64_t icr1:1;
+ uint64_t icnr1:1;
+ uint64_t icnr0:1;
+ uint64_t ibdr0:1;
+ uint64_t ibdr1:1;
+ uint64_t ibr0:1;
+ uint64_t ibr1:1;
+ uint64_t icnrt:1;
+ uint64_t ibrq0:1;
+ uint64_t ibrq1:1;
+ uint64_t icrn0:1;
+ uint64_t icrn1:1;
+ uint64_t icrp0:1;
+ uint64_t icrp1:1;
+ uint64_t ibd:1;
+ uint64_t icd:1;
+ } cn30xx;
+ struct cvmx_iob_bist_status_cn30xx cn31xx;
+ struct cvmx_iob_bist_status_cn30xx cn38xx;
+ struct cvmx_iob_bist_status_cn30xx cn38xxp2;
+ struct cvmx_iob_bist_status_cn30xx cn50xx;
+ struct cvmx_iob_bist_status_cn30xx cn52xx;
+ struct cvmx_iob_bist_status_cn30xx cn52xxp1;
+ struct cvmx_iob_bist_status_cn30xx cn56xx;
+ struct cvmx_iob_bist_status_cn30xx cn56xxp1;
+ struct cvmx_iob_bist_status_cn30xx cn58xx;
+ struct cvmx_iob_bist_status_cn30xx cn58xxp1;
+ struct cvmx_iob_bist_status_s cn63xx;
+ struct cvmx_iob_bist_status_s cn63xxp1;
};
union cvmx_iob_ctl_status {
uint64_t u64;
struct cvmx_iob_ctl_status_s {
- uint64_t reserved_5_63:59;
+ uint64_t reserved_10_63:54;
+ uint64_t xmc_per:4;
+ uint64_t rr_mode:1;
uint64_t outb_mat:1;
uint64_t inb_mat:1;
uint64_t pko_enb:1;
uint64_t dwb_enb:1;
uint64_t fau_end:1;
} s;
- struct cvmx_iob_ctl_status_s cn30xx;
- struct cvmx_iob_ctl_status_s cn31xx;
- struct cvmx_iob_ctl_status_s cn38xx;
- struct cvmx_iob_ctl_status_s cn38xxp2;
- struct cvmx_iob_ctl_status_s cn50xx;
- struct cvmx_iob_ctl_status_s cn52xx;
- struct cvmx_iob_ctl_status_s cn52xxp1;
- struct cvmx_iob_ctl_status_s cn56xx;
- struct cvmx_iob_ctl_status_s cn56xxp1;
- struct cvmx_iob_ctl_status_s cn58xx;
- struct cvmx_iob_ctl_status_s cn58xxp1;
+ struct cvmx_iob_ctl_status_cn30xx {
+ uint64_t reserved_5_63:59;
+ uint64_t outb_mat:1;
+ uint64_t inb_mat:1;
+ uint64_t pko_enb:1;
+ uint64_t dwb_enb:1;
+ uint64_t fau_end:1;
+ } cn30xx;
+ struct cvmx_iob_ctl_status_cn30xx cn31xx;
+ struct cvmx_iob_ctl_status_cn30xx cn38xx;
+ struct cvmx_iob_ctl_status_cn30xx cn38xxp2;
+ struct cvmx_iob_ctl_status_cn30xx cn50xx;
+ struct cvmx_iob_ctl_status_cn52xx {
+ uint64_t reserved_6_63:58;
+ uint64_t rr_mode:1;
+ uint64_t outb_mat:1;
+ uint64_t inb_mat:1;
+ uint64_t pko_enb:1;
+ uint64_t dwb_enb:1;
+ uint64_t fau_end:1;
+ } cn52xx;
+ struct cvmx_iob_ctl_status_cn30xx cn52xxp1;
+ struct cvmx_iob_ctl_status_cn30xx cn56xx;
+ struct cvmx_iob_ctl_status_cn30xx cn56xxp1;
+ struct cvmx_iob_ctl_status_cn30xx cn58xx;
+ struct cvmx_iob_ctl_status_cn30xx cn58xxp1;
+ struct cvmx_iob_ctl_status_s cn63xx;
+ struct cvmx_iob_ctl_status_s cn63xxp1;
};
union cvmx_iob_dwb_pri_cnt {
@@ -147,6 +172,8 @@ union cvmx_iob_dwb_pri_cnt {
struct cvmx_iob_dwb_pri_cnt_s cn56xxp1;
struct cvmx_iob_dwb_pri_cnt_s cn58xx;
struct cvmx_iob_dwb_pri_cnt_s cn58xxp1;
+ struct cvmx_iob_dwb_pri_cnt_s cn63xx;
+ struct cvmx_iob_dwb_pri_cnt_s cn63xxp1;
};
union cvmx_iob_fau_timeout {
@@ -167,6 +194,8 @@ union cvmx_iob_fau_timeout {
struct cvmx_iob_fau_timeout_s cn56xxp1;
struct cvmx_iob_fau_timeout_s cn58xx;
struct cvmx_iob_fau_timeout_s cn58xxp1;
+ struct cvmx_iob_fau_timeout_s cn63xx;
+ struct cvmx_iob_fau_timeout_s cn63xxp1;
};
union cvmx_iob_i2c_pri_cnt {
@@ -184,6 +213,8 @@ union cvmx_iob_i2c_pri_cnt {
struct cvmx_iob_i2c_pri_cnt_s cn56xxp1;
struct cvmx_iob_i2c_pri_cnt_s cn58xx;
struct cvmx_iob_i2c_pri_cnt_s cn58xxp1;
+ struct cvmx_iob_i2c_pri_cnt_s cn63xx;
+ struct cvmx_iob_i2c_pri_cnt_s cn63xxp1;
};
union cvmx_iob_inb_control_match {
@@ -206,6 +237,8 @@ union cvmx_iob_inb_control_match {
struct cvmx_iob_inb_control_match_s cn56xxp1;
struct cvmx_iob_inb_control_match_s cn58xx;
struct cvmx_iob_inb_control_match_s cn58xxp1;
+ struct cvmx_iob_inb_control_match_s cn63xx;
+ struct cvmx_iob_inb_control_match_s cn63xxp1;
};
union cvmx_iob_inb_control_match_enb {
@@ -228,6 +261,8 @@ union cvmx_iob_inb_control_match_enb {
struct cvmx_iob_inb_control_match_enb_s cn56xxp1;
struct cvmx_iob_inb_control_match_enb_s cn58xx;
struct cvmx_iob_inb_control_match_enb_s cn58xxp1;
+ struct cvmx_iob_inb_control_match_enb_s cn63xx;
+ struct cvmx_iob_inb_control_match_enb_s cn63xxp1;
};
union cvmx_iob_inb_data_match {
@@ -246,6 +281,8 @@ union cvmx_iob_inb_data_match {
struct cvmx_iob_inb_data_match_s cn56xxp1;
struct cvmx_iob_inb_data_match_s cn58xx;
struct cvmx_iob_inb_data_match_s cn58xxp1;
+ struct cvmx_iob_inb_data_match_s cn63xx;
+ struct cvmx_iob_inb_data_match_s cn63xxp1;
};
union cvmx_iob_inb_data_match_enb {
@@ -264,6 +301,8 @@ union cvmx_iob_inb_data_match_enb {
struct cvmx_iob_inb_data_match_enb_s cn56xxp1;
struct cvmx_iob_inb_data_match_enb_s cn58xx;
struct cvmx_iob_inb_data_match_enb_s cn58xxp1;
+ struct cvmx_iob_inb_data_match_enb_s cn63xx;
+ struct cvmx_iob_inb_data_match_enb_s cn63xxp1;
};
union cvmx_iob_int_enb {
@@ -294,6 +333,8 @@ union cvmx_iob_int_enb {
struct cvmx_iob_int_enb_s cn56xxp1;
struct cvmx_iob_int_enb_s cn58xx;
struct cvmx_iob_int_enb_s cn58xxp1;
+ struct cvmx_iob_int_enb_s cn63xx;
+ struct cvmx_iob_int_enb_s cn63xxp1;
};
union cvmx_iob_int_sum {
@@ -324,6 +365,8 @@ union cvmx_iob_int_sum {
struct cvmx_iob_int_sum_s cn56xxp1;
struct cvmx_iob_int_sum_s cn58xx;
struct cvmx_iob_int_sum_s cn58xxp1;
+ struct cvmx_iob_int_sum_s cn63xx;
+ struct cvmx_iob_int_sum_s cn63xxp1;
};
union cvmx_iob_n2c_l2c_pri_cnt {
@@ -341,6 +384,8 @@ union cvmx_iob_n2c_l2c_pri_cnt {
struct cvmx_iob_n2c_l2c_pri_cnt_s cn56xxp1;
struct cvmx_iob_n2c_l2c_pri_cnt_s cn58xx;
struct cvmx_iob_n2c_l2c_pri_cnt_s cn58xxp1;
+ struct cvmx_iob_n2c_l2c_pri_cnt_s cn63xx;
+ struct cvmx_iob_n2c_l2c_pri_cnt_s cn63xxp1;
};
union cvmx_iob_n2c_rsp_pri_cnt {
@@ -358,6 +403,8 @@ union cvmx_iob_n2c_rsp_pri_cnt {
struct cvmx_iob_n2c_rsp_pri_cnt_s cn56xxp1;
struct cvmx_iob_n2c_rsp_pri_cnt_s cn58xx;
struct cvmx_iob_n2c_rsp_pri_cnt_s cn58xxp1;
+ struct cvmx_iob_n2c_rsp_pri_cnt_s cn63xx;
+ struct cvmx_iob_n2c_rsp_pri_cnt_s cn63xxp1;
};
union cvmx_iob_outb_com_pri_cnt {
@@ -375,6 +422,8 @@ union cvmx_iob_outb_com_pri_cnt {
struct cvmx_iob_outb_com_pri_cnt_s cn56xxp1;
struct cvmx_iob_outb_com_pri_cnt_s cn58xx;
struct cvmx_iob_outb_com_pri_cnt_s cn58xxp1;
+ struct cvmx_iob_outb_com_pri_cnt_s cn63xx;
+ struct cvmx_iob_outb_com_pri_cnt_s cn63xxp1;
};
union cvmx_iob_outb_control_match {
@@ -397,6 +446,8 @@ union cvmx_iob_outb_control_match {
struct cvmx_iob_outb_control_match_s cn56xxp1;
struct cvmx_iob_outb_control_match_s cn58xx;
struct cvmx_iob_outb_control_match_s cn58xxp1;
+ struct cvmx_iob_outb_control_match_s cn63xx;
+ struct cvmx_iob_outb_control_match_s cn63xxp1;
};
union cvmx_iob_outb_control_match_enb {
@@ -419,6 +470,8 @@ union cvmx_iob_outb_control_match_enb {
struct cvmx_iob_outb_control_match_enb_s cn56xxp1;
struct cvmx_iob_outb_control_match_enb_s cn58xx;
struct cvmx_iob_outb_control_match_enb_s cn58xxp1;
+ struct cvmx_iob_outb_control_match_enb_s cn63xx;
+ struct cvmx_iob_outb_control_match_enb_s cn63xxp1;
};
union cvmx_iob_outb_data_match {
@@ -437,6 +490,8 @@ union cvmx_iob_outb_data_match {
struct cvmx_iob_outb_data_match_s cn56xxp1;
struct cvmx_iob_outb_data_match_s cn58xx;
struct cvmx_iob_outb_data_match_s cn58xxp1;
+ struct cvmx_iob_outb_data_match_s cn63xx;
+ struct cvmx_iob_outb_data_match_s cn63xxp1;
};
union cvmx_iob_outb_data_match_enb {
@@ -455,6 +510,8 @@ union cvmx_iob_outb_data_match_enb {
struct cvmx_iob_outb_data_match_enb_s cn56xxp1;
struct cvmx_iob_outb_data_match_enb_s cn58xx;
struct cvmx_iob_outb_data_match_enb_s cn58xxp1;
+ struct cvmx_iob_outb_data_match_enb_s cn63xx;
+ struct cvmx_iob_outb_data_match_enb_s cn63xxp1;
};
union cvmx_iob_outb_fpa_pri_cnt {
@@ -472,6 +529,8 @@ union cvmx_iob_outb_fpa_pri_cnt {
struct cvmx_iob_outb_fpa_pri_cnt_s cn56xxp1;
struct cvmx_iob_outb_fpa_pri_cnt_s cn58xx;
struct cvmx_iob_outb_fpa_pri_cnt_s cn58xxp1;
+ struct cvmx_iob_outb_fpa_pri_cnt_s cn63xx;
+ struct cvmx_iob_outb_fpa_pri_cnt_s cn63xxp1;
};
union cvmx_iob_outb_req_pri_cnt {
@@ -489,6 +548,8 @@ union cvmx_iob_outb_req_pri_cnt {
struct cvmx_iob_outb_req_pri_cnt_s cn56xxp1;
struct cvmx_iob_outb_req_pri_cnt_s cn58xx;
struct cvmx_iob_outb_req_pri_cnt_s cn58xxp1;
+ struct cvmx_iob_outb_req_pri_cnt_s cn63xx;
+ struct cvmx_iob_outb_req_pri_cnt_s cn63xxp1;
};
union cvmx_iob_p2c_req_pri_cnt {
@@ -506,25 +567,46 @@ union cvmx_iob_p2c_req_pri_cnt {
struct cvmx_iob_p2c_req_pri_cnt_s cn56xxp1;
struct cvmx_iob_p2c_req_pri_cnt_s cn58xx;
struct cvmx_iob_p2c_req_pri_cnt_s cn58xxp1;
+ struct cvmx_iob_p2c_req_pri_cnt_s cn63xx;
+ struct cvmx_iob_p2c_req_pri_cnt_s cn63xxp1;
};
union cvmx_iob_pkt_err {
uint64_t u64;
struct cvmx_iob_pkt_err_s {
+ uint64_t reserved_12_63:52;
+ uint64_t vport:6;
+ uint64_t port:6;
+ } s;
+ struct cvmx_iob_pkt_err_cn30xx {
uint64_t reserved_6_63:58;
uint64_t port:6;
+ } cn30xx;
+ struct cvmx_iob_pkt_err_cn30xx cn31xx;
+ struct cvmx_iob_pkt_err_cn30xx cn38xx;
+ struct cvmx_iob_pkt_err_cn30xx cn38xxp2;
+ struct cvmx_iob_pkt_err_cn30xx cn50xx;
+ struct cvmx_iob_pkt_err_cn30xx cn52xx;
+ struct cvmx_iob_pkt_err_cn30xx cn52xxp1;
+ struct cvmx_iob_pkt_err_cn30xx cn56xx;
+ struct cvmx_iob_pkt_err_cn30xx cn56xxp1;
+ struct cvmx_iob_pkt_err_cn30xx cn58xx;
+ struct cvmx_iob_pkt_err_cn30xx cn58xxp1;
+ struct cvmx_iob_pkt_err_s cn63xx;
+ struct cvmx_iob_pkt_err_s cn63xxp1;
+};
+
+union cvmx_iob_to_cmb_credits {
+ uint64_t u64;
+ struct cvmx_iob_to_cmb_credits_s {
+ uint64_t reserved_9_63:55;
+ uint64_t pko_rd:3;
+ uint64_t ncb_rd:3;
+ uint64_t ncb_wr:3;
} s;
- struct cvmx_iob_pkt_err_s cn30xx;
- struct cvmx_iob_pkt_err_s cn31xx;
- struct cvmx_iob_pkt_err_s cn38xx;
- struct cvmx_iob_pkt_err_s cn38xxp2;
- struct cvmx_iob_pkt_err_s cn50xx;
- struct cvmx_iob_pkt_err_s cn52xx;
- struct cvmx_iob_pkt_err_s cn52xxp1;
- struct cvmx_iob_pkt_err_s cn56xx;
- struct cvmx_iob_pkt_err_s cn56xxp1;
- struct cvmx_iob_pkt_err_s cn58xx;
- struct cvmx_iob_pkt_err_s cn58xxp1;
+ struct cvmx_iob_to_cmb_credits_s cn52xx;
+ struct cvmx_iob_to_cmb_credits_s cn63xx;
+ struct cvmx_iob_to_cmb_credits_s cn63xxp1;
};
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-ipd-defs.h b/arch/mips/include/asm/octeon/cvmx-ipd-defs.h
index f8b8fc657d2c..e0a5bfe88d04 100644
--- a/arch/mips/include/asm/octeon/cvmx-ipd-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-ipd-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
@@ -28,104 +28,57 @@
#ifndef __CVMX_IPD_DEFS_H__
#define __CVMX_IPD_DEFS_H__
-#define CVMX_IPD_1ST_MBUFF_SKIP \
- CVMX_ADD_IO_SEG(0x00014F0000000000ull)
-#define CVMX_IPD_1st_NEXT_PTR_BACK \
- CVMX_ADD_IO_SEG(0x00014F0000000150ull)
-#define CVMX_IPD_2nd_NEXT_PTR_BACK \
- CVMX_ADD_IO_SEG(0x00014F0000000158ull)
-#define CVMX_IPD_BIST_STATUS \
- CVMX_ADD_IO_SEG(0x00014F00000007F8ull)
-#define CVMX_IPD_BP_PRT_RED_END \
- CVMX_ADD_IO_SEG(0x00014F0000000328ull)
-#define CVMX_IPD_CLK_COUNT \
- CVMX_ADD_IO_SEG(0x00014F0000000338ull)
-#define CVMX_IPD_CTL_STATUS \
- CVMX_ADD_IO_SEG(0x00014F0000000018ull)
-#define CVMX_IPD_INT_ENB \
- CVMX_ADD_IO_SEG(0x00014F0000000160ull)
-#define CVMX_IPD_INT_SUM \
- CVMX_ADD_IO_SEG(0x00014F0000000168ull)
-#define CVMX_IPD_NOT_1ST_MBUFF_SKIP \
- CVMX_ADD_IO_SEG(0x00014F0000000008ull)
-#define CVMX_IPD_PACKET_MBUFF_SIZE \
- CVMX_ADD_IO_SEG(0x00014F0000000010ull)
-#define CVMX_IPD_PKT_PTR_VALID \
- CVMX_ADD_IO_SEG(0x00014F0000000358ull)
-#define CVMX_IPD_PORTX_BP_PAGE_CNT(offset) \
- CVMX_ADD_IO_SEG(0x00014F0000000028ull + (((offset) & 63) * 8))
-#define CVMX_IPD_PORTX_BP_PAGE_CNT2(offset) \
- CVMX_ADD_IO_SEG(0x00014F0000000368ull + (((offset) & 63) * 8) - 8 * 36)
-#define CVMX_IPD_PORT_BP_COUNTERS2_PAIRX(offset) \
- CVMX_ADD_IO_SEG(0x00014F0000000388ull + (((offset) & 63) * 8) - 8 * 36)
-#define CVMX_IPD_PORT_BP_COUNTERS_PAIRX(offset) \
- CVMX_ADD_IO_SEG(0x00014F00000001B8ull + (((offset) & 63) * 8))
-#define CVMX_IPD_PORT_QOS_INTX(offset) \
- CVMX_ADD_IO_SEG(0x00014F0000000808ull + (((offset) & 7) * 8))
-#define CVMX_IPD_PORT_QOS_INT_ENBX(offset) \
- CVMX_ADD_IO_SEG(0x00014F0000000848ull + (((offset) & 7) * 8))
-#define CVMX_IPD_PORT_QOS_X_CNT(offset) \
- CVMX_ADD_IO_SEG(0x00014F0000000888ull + (((offset) & 511) * 8))
-#define CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL \
- CVMX_ADD_IO_SEG(0x00014F0000000348ull)
-#define CVMX_IPD_PRC_PORT_PTR_FIFO_CTL \
- CVMX_ADD_IO_SEG(0x00014F0000000350ull)
-#define CVMX_IPD_PTR_COUNT \
- CVMX_ADD_IO_SEG(0x00014F0000000320ull)
-#define CVMX_IPD_PWP_PTR_FIFO_CTL \
- CVMX_ADD_IO_SEG(0x00014F0000000340ull)
-#define CVMX_IPD_QOS0_RED_MARKS \
- CVMX_ADD_IO_SEG(0x00014F0000000178ull)
-#define CVMX_IPD_QOS1_RED_MARKS \
- CVMX_ADD_IO_SEG(0x00014F0000000180ull)
-#define CVMX_IPD_QOS2_RED_MARKS \
- CVMX_ADD_IO_SEG(0x00014F0000000188ull)
-#define CVMX_IPD_QOS3_RED_MARKS \
- CVMX_ADD_IO_SEG(0x00014F0000000190ull)
-#define CVMX_IPD_QOS4_RED_MARKS \
- CVMX_ADD_IO_SEG(0x00014F0000000198ull)
-#define CVMX_IPD_QOS5_RED_MARKS \
- CVMX_ADD_IO_SEG(0x00014F00000001A0ull)
-#define CVMX_IPD_QOS6_RED_MARKS \
- CVMX_ADD_IO_SEG(0x00014F00000001A8ull)
-#define CVMX_IPD_QOS7_RED_MARKS \
- CVMX_ADD_IO_SEG(0x00014F00000001B0ull)
-#define CVMX_IPD_QOSX_RED_MARKS(offset) \
- CVMX_ADD_IO_SEG(0x00014F0000000178ull + (((offset) & 7) * 8))
-#define CVMX_IPD_QUE0_FREE_PAGE_CNT \
- CVMX_ADD_IO_SEG(0x00014F0000000330ull)
-#define CVMX_IPD_RED_PORT_ENABLE \
- CVMX_ADD_IO_SEG(0x00014F00000002D8ull)
-#define CVMX_IPD_RED_PORT_ENABLE2 \
- CVMX_ADD_IO_SEG(0x00014F00000003A8ull)
-#define CVMX_IPD_RED_QUE0_PARAM \
- CVMX_ADD_IO_SEG(0x00014F00000002E0ull)
-#define CVMX_IPD_RED_QUE1_PARAM \
- CVMX_ADD_IO_SEG(0x00014F00000002E8ull)
-#define CVMX_IPD_RED_QUE2_PARAM \
- CVMX_ADD_IO_SEG(0x00014F00000002F0ull)
-#define CVMX_IPD_RED_QUE3_PARAM \
- CVMX_ADD_IO_SEG(0x00014F00000002F8ull)
-#define CVMX_IPD_RED_QUE4_PARAM \
- CVMX_ADD_IO_SEG(0x00014F0000000300ull)
-#define CVMX_IPD_RED_QUE5_PARAM \
- CVMX_ADD_IO_SEG(0x00014F0000000308ull)
-#define CVMX_IPD_RED_QUE6_PARAM \
- CVMX_ADD_IO_SEG(0x00014F0000000310ull)
-#define CVMX_IPD_RED_QUE7_PARAM \
- CVMX_ADD_IO_SEG(0x00014F0000000318ull)
-#define CVMX_IPD_RED_QUEX_PARAM(offset) \
- CVMX_ADD_IO_SEG(0x00014F00000002E0ull + (((offset) & 7) * 8))
-#define CVMX_IPD_SUB_PORT_BP_PAGE_CNT \
- CVMX_ADD_IO_SEG(0x00014F0000000148ull)
-#define CVMX_IPD_SUB_PORT_FCS \
- CVMX_ADD_IO_SEG(0x00014F0000000170ull)
-#define CVMX_IPD_SUB_PORT_QOS_CNT \
- CVMX_ADD_IO_SEG(0x00014F0000000800ull)
-#define CVMX_IPD_WQE_FPA_QUEUE \
- CVMX_ADD_IO_SEG(0x00014F0000000020ull)
-#define CVMX_IPD_WQE_PTR_VALID \
- CVMX_ADD_IO_SEG(0x00014F0000000360ull)
+#define CVMX_IPD_1ST_MBUFF_SKIP (CVMX_ADD_IO_SEG(0x00014F0000000000ull))
+#define CVMX_IPD_1st_NEXT_PTR_BACK (CVMX_ADD_IO_SEG(0x00014F0000000150ull))
+#define CVMX_IPD_2nd_NEXT_PTR_BACK (CVMX_ADD_IO_SEG(0x00014F0000000158ull))
+#define CVMX_IPD_BIST_STATUS (CVMX_ADD_IO_SEG(0x00014F00000007F8ull))
+#define CVMX_IPD_BP_PRT_RED_END (CVMX_ADD_IO_SEG(0x00014F0000000328ull))
+#define CVMX_IPD_CLK_COUNT (CVMX_ADD_IO_SEG(0x00014F0000000338ull))
+#define CVMX_IPD_CTL_STATUS (CVMX_ADD_IO_SEG(0x00014F0000000018ull))
+#define CVMX_IPD_INT_ENB (CVMX_ADD_IO_SEG(0x00014F0000000160ull))
+#define CVMX_IPD_INT_SUM (CVMX_ADD_IO_SEG(0x00014F0000000168ull))
+#define CVMX_IPD_NOT_1ST_MBUFF_SKIP (CVMX_ADD_IO_SEG(0x00014F0000000008ull))
+#define CVMX_IPD_PACKET_MBUFF_SIZE (CVMX_ADD_IO_SEG(0x00014F0000000010ull))
+#define CVMX_IPD_PKT_PTR_VALID (CVMX_ADD_IO_SEG(0x00014F0000000358ull))
+#define CVMX_IPD_PORTX_BP_PAGE_CNT(offset) (CVMX_ADD_IO_SEG(0x00014F0000000028ull) + ((offset) & 63) * 8)
+#define CVMX_IPD_PORTX_BP_PAGE_CNT2(offset) (CVMX_ADD_IO_SEG(0x00014F0000000368ull) + ((offset) & 63) * 8 - 8*36)
+#define CVMX_IPD_PORTX_BP_PAGE_CNT3(offset) (CVMX_ADD_IO_SEG(0x00014F00000003D0ull) + ((offset) & 63) * 8 - 8*40)
+#define CVMX_IPD_PORT_BP_COUNTERS2_PAIRX(offset) (CVMX_ADD_IO_SEG(0x00014F0000000388ull) + ((offset) & 63) * 8 - 8*36)
+#define CVMX_IPD_PORT_BP_COUNTERS3_PAIRX(offset) (CVMX_ADD_IO_SEG(0x00014F00000003B0ull) + ((offset) & 63) * 8 - 8*40)
+#define CVMX_IPD_PORT_BP_COUNTERS_PAIRX(offset) (CVMX_ADD_IO_SEG(0x00014F00000001B8ull) + ((offset) & 63) * 8)
+#define CVMX_IPD_PORT_QOS_INTX(offset) (CVMX_ADD_IO_SEG(0x00014F0000000808ull) + ((offset) & 7) * 8)
+#define CVMX_IPD_PORT_QOS_INT_ENBX(offset) (CVMX_ADD_IO_SEG(0x00014F0000000848ull) + ((offset) & 7) * 8)
+#define CVMX_IPD_PORT_QOS_X_CNT(offset) (CVMX_ADD_IO_SEG(0x00014F0000000888ull) + ((offset) & 511) * 8)
+#define CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL (CVMX_ADD_IO_SEG(0x00014F0000000348ull))
+#define CVMX_IPD_PRC_PORT_PTR_FIFO_CTL (CVMX_ADD_IO_SEG(0x00014F0000000350ull))
+#define CVMX_IPD_PTR_COUNT (CVMX_ADD_IO_SEG(0x00014F0000000320ull))
+#define CVMX_IPD_PWP_PTR_FIFO_CTL (CVMX_ADD_IO_SEG(0x00014F0000000340ull))
+#define CVMX_IPD_QOS0_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(0)
+#define CVMX_IPD_QOS1_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(1)
+#define CVMX_IPD_QOS2_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(2)
+#define CVMX_IPD_QOS3_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(3)
+#define CVMX_IPD_QOS4_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(4)
+#define CVMX_IPD_QOS5_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(5)
+#define CVMX_IPD_QOS6_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(6)
+#define CVMX_IPD_QOS7_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(7)
+#define CVMX_IPD_QOSX_RED_MARKS(offset) (CVMX_ADD_IO_SEG(0x00014F0000000178ull) + ((offset) & 7) * 8)
+#define CVMX_IPD_QUE0_FREE_PAGE_CNT (CVMX_ADD_IO_SEG(0x00014F0000000330ull))
+#define CVMX_IPD_RED_PORT_ENABLE (CVMX_ADD_IO_SEG(0x00014F00000002D8ull))
+#define CVMX_IPD_RED_PORT_ENABLE2 (CVMX_ADD_IO_SEG(0x00014F00000003A8ull))
+#define CVMX_IPD_RED_QUE0_PARAM CVMX_IPD_RED_QUEX_PARAM(0)
+#define CVMX_IPD_RED_QUE1_PARAM CVMX_IPD_RED_QUEX_PARAM(1)
+#define CVMX_IPD_RED_QUE2_PARAM CVMX_IPD_RED_QUEX_PARAM(2)
+#define CVMX_IPD_RED_QUE3_PARAM CVMX_IPD_RED_QUEX_PARAM(3)
+#define CVMX_IPD_RED_QUE4_PARAM CVMX_IPD_RED_QUEX_PARAM(4)
+#define CVMX_IPD_RED_QUE5_PARAM CVMX_IPD_RED_QUEX_PARAM(5)
+#define CVMX_IPD_RED_QUE6_PARAM CVMX_IPD_RED_QUEX_PARAM(6)
+#define CVMX_IPD_RED_QUE7_PARAM CVMX_IPD_RED_QUEX_PARAM(7)
+#define CVMX_IPD_RED_QUEX_PARAM(offset) (CVMX_ADD_IO_SEG(0x00014F00000002E0ull) + ((offset) & 7) * 8)
+#define CVMX_IPD_SUB_PORT_BP_PAGE_CNT (CVMX_ADD_IO_SEG(0x00014F0000000148ull))
+#define CVMX_IPD_SUB_PORT_FCS (CVMX_ADD_IO_SEG(0x00014F0000000170ull))
+#define CVMX_IPD_SUB_PORT_QOS_CNT (CVMX_ADD_IO_SEG(0x00014F0000000800ull))
+#define CVMX_IPD_WQE_FPA_QUEUE (CVMX_ADD_IO_SEG(0x00014F0000000020ull))
+#define CVMX_IPD_WQE_PTR_VALID (CVMX_ADD_IO_SEG(0x00014F0000000360ull))
union cvmx_ipd_1st_mbuff_skip {
uint64_t u64;
@@ -144,6 +97,8 @@ union cvmx_ipd_1st_mbuff_skip {
struct cvmx_ipd_1st_mbuff_skip_s cn56xxp1;
struct cvmx_ipd_1st_mbuff_skip_s cn58xx;
struct cvmx_ipd_1st_mbuff_skip_s cn58xxp1;
+ struct cvmx_ipd_1st_mbuff_skip_s cn63xx;
+ struct cvmx_ipd_1st_mbuff_skip_s cn63xxp1;
};
union cvmx_ipd_1st_next_ptr_back {
@@ -163,6 +118,8 @@ union cvmx_ipd_1st_next_ptr_back {
struct cvmx_ipd_1st_next_ptr_back_s cn56xxp1;
struct cvmx_ipd_1st_next_ptr_back_s cn58xx;
struct cvmx_ipd_1st_next_ptr_back_s cn58xxp1;
+ struct cvmx_ipd_1st_next_ptr_back_s cn63xx;
+ struct cvmx_ipd_1st_next_ptr_back_s cn63xxp1;
};
union cvmx_ipd_2nd_next_ptr_back {
@@ -182,6 +139,8 @@ union cvmx_ipd_2nd_next_ptr_back {
struct cvmx_ipd_2nd_next_ptr_back_s cn56xxp1;
struct cvmx_ipd_2nd_next_ptr_back_s cn58xx;
struct cvmx_ipd_2nd_next_ptr_back_s cn58xxp1;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn63xx;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn63xxp1;
};
union cvmx_ipd_bist_status {
@@ -236,13 +195,15 @@ union cvmx_ipd_bist_status {
struct cvmx_ipd_bist_status_s cn56xxp1;
struct cvmx_ipd_bist_status_cn30xx cn58xx;
struct cvmx_ipd_bist_status_cn30xx cn58xxp1;
+ struct cvmx_ipd_bist_status_s cn63xx;
+ struct cvmx_ipd_bist_status_s cn63xxp1;
};
union cvmx_ipd_bp_prt_red_end {
uint64_t u64;
struct cvmx_ipd_bp_prt_red_end_s {
- uint64_t reserved_40_63:24;
- uint64_t prt_enb:40;
+ uint64_t reserved_44_63:20;
+ uint64_t prt_enb:44;
} s;
struct cvmx_ipd_bp_prt_red_end_cn30xx {
uint64_t reserved_36_63:28;
@@ -252,12 +213,17 @@ union cvmx_ipd_bp_prt_red_end {
struct cvmx_ipd_bp_prt_red_end_cn30xx cn38xx;
struct cvmx_ipd_bp_prt_red_end_cn30xx cn38xxp2;
struct cvmx_ipd_bp_prt_red_end_cn30xx cn50xx;
- struct cvmx_ipd_bp_prt_red_end_s cn52xx;
- struct cvmx_ipd_bp_prt_red_end_s cn52xxp1;
- struct cvmx_ipd_bp_prt_red_end_s cn56xx;
- struct cvmx_ipd_bp_prt_red_end_s cn56xxp1;
+ struct cvmx_ipd_bp_prt_red_end_cn52xx {
+ uint64_t reserved_40_63:24;
+ uint64_t prt_enb:40;
+ } cn52xx;
+ struct cvmx_ipd_bp_prt_red_end_cn52xx cn52xxp1;
+ struct cvmx_ipd_bp_prt_red_end_cn52xx cn56xx;
+ struct cvmx_ipd_bp_prt_red_end_cn52xx cn56xxp1;
struct cvmx_ipd_bp_prt_red_end_cn30xx cn58xx;
struct cvmx_ipd_bp_prt_red_end_cn30xx cn58xxp1;
+ struct cvmx_ipd_bp_prt_red_end_s cn63xx;
+ struct cvmx_ipd_bp_prt_red_end_s cn63xxp1;
};
union cvmx_ipd_clk_count {
@@ -276,12 +242,17 @@ union cvmx_ipd_clk_count {
struct cvmx_ipd_clk_count_s cn56xxp1;
struct cvmx_ipd_clk_count_s cn58xx;
struct cvmx_ipd_clk_count_s cn58xxp1;
+ struct cvmx_ipd_clk_count_s cn63xx;
+ struct cvmx_ipd_clk_count_s cn63xxp1;
};
union cvmx_ipd_ctl_status {
uint64_t u64;
struct cvmx_ipd_ctl_status_s {
- uint64_t reserved_15_63:49;
+ uint64_t reserved_18_63:46;
+ uint64_t use_sop:1;
+ uint64_t rst_done:1;
+ uint64_t clken:1;
uint64_t no_wptr:1;
uint64_t pq_apkt:1;
uint64_t pq_nabuf:1;
@@ -322,11 +293,27 @@ union cvmx_ipd_ctl_status {
uint64_t opc_mode:2;
uint64_t ipd_en:1;
} cn38xxp2;
- struct cvmx_ipd_ctl_status_s cn50xx;
- struct cvmx_ipd_ctl_status_s cn52xx;
- struct cvmx_ipd_ctl_status_s cn52xxp1;
- struct cvmx_ipd_ctl_status_s cn56xx;
- struct cvmx_ipd_ctl_status_s cn56xxp1;
+ struct cvmx_ipd_ctl_status_cn50xx {
+ uint64_t reserved_15_63:49;
+ uint64_t no_wptr:1;
+ uint64_t pq_apkt:1;
+ uint64_t pq_nabuf:1;
+ uint64_t ipd_full:1;
+ uint64_t pkt_off:1;
+ uint64_t len_m8:1;
+ uint64_t reset:1;
+ uint64_t addpkt:1;
+ uint64_t naddbuf:1;
+ uint64_t pkt_lend:1;
+ uint64_t wqe_lend:1;
+ uint64_t pbp_en:1;
+ uint64_t opc_mode:2;
+ uint64_t ipd_en:1;
+ } cn50xx;
+ struct cvmx_ipd_ctl_status_cn50xx cn52xx;
+ struct cvmx_ipd_ctl_status_cn50xx cn52xxp1;
+ struct cvmx_ipd_ctl_status_cn50xx cn56xx;
+ struct cvmx_ipd_ctl_status_cn50xx cn56xxp1;
struct cvmx_ipd_ctl_status_cn58xx {
uint64_t reserved_12_63:52;
uint64_t ipd_full:1;
@@ -342,6 +329,25 @@ union cvmx_ipd_ctl_status {
uint64_t ipd_en:1;
} cn58xx;
struct cvmx_ipd_ctl_status_cn58xx cn58xxp1;
+ struct cvmx_ipd_ctl_status_s cn63xx;
+ struct cvmx_ipd_ctl_status_cn63xxp1 {
+ uint64_t reserved_16_63:48;
+ uint64_t clken:1;
+ uint64_t no_wptr:1;
+ uint64_t pq_apkt:1;
+ uint64_t pq_nabuf:1;
+ uint64_t ipd_full:1;
+ uint64_t pkt_off:1;
+ uint64_t len_m8:1;
+ uint64_t reset:1;
+ uint64_t addpkt:1;
+ uint64_t naddbuf:1;
+ uint64_t pkt_lend:1;
+ uint64_t wqe_lend:1;
+ uint64_t pbp_en:1;
+ uint64_t opc_mode:2;
+ uint64_t ipd_en:1;
+ } cn63xxp1;
};
union cvmx_ipd_int_enb {
@@ -391,6 +397,8 @@ union cvmx_ipd_int_enb {
struct cvmx_ipd_int_enb_s cn56xxp1;
struct cvmx_ipd_int_enb_cn38xx cn58xx;
struct cvmx_ipd_int_enb_cn38xx cn58xxp1;
+ struct cvmx_ipd_int_enb_s cn63xx;
+ struct cvmx_ipd_int_enb_s cn63xxp1;
};
union cvmx_ipd_int_sum {
@@ -440,6 +448,8 @@ union cvmx_ipd_int_sum {
struct cvmx_ipd_int_sum_s cn56xxp1;
struct cvmx_ipd_int_sum_cn38xx cn58xx;
struct cvmx_ipd_int_sum_cn38xx cn58xxp1;
+ struct cvmx_ipd_int_sum_s cn63xx;
+ struct cvmx_ipd_int_sum_s cn63xxp1;
};
union cvmx_ipd_not_1st_mbuff_skip {
@@ -459,6 +469,8 @@ union cvmx_ipd_not_1st_mbuff_skip {
struct cvmx_ipd_not_1st_mbuff_skip_s cn56xxp1;
struct cvmx_ipd_not_1st_mbuff_skip_s cn58xx;
struct cvmx_ipd_not_1st_mbuff_skip_s cn58xxp1;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn63xx;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn63xxp1;
};
union cvmx_ipd_packet_mbuff_size {
@@ -478,6 +490,8 @@ union cvmx_ipd_packet_mbuff_size {
struct cvmx_ipd_packet_mbuff_size_s cn56xxp1;
struct cvmx_ipd_packet_mbuff_size_s cn58xx;
struct cvmx_ipd_packet_mbuff_size_s cn58xxp1;
+ struct cvmx_ipd_packet_mbuff_size_s cn63xx;
+ struct cvmx_ipd_packet_mbuff_size_s cn63xxp1;
};
union cvmx_ipd_pkt_ptr_valid {
@@ -496,6 +510,8 @@ union cvmx_ipd_pkt_ptr_valid {
struct cvmx_ipd_pkt_ptr_valid_s cn56xxp1;
struct cvmx_ipd_pkt_ptr_valid_s cn58xx;
struct cvmx_ipd_pkt_ptr_valid_s cn58xxp1;
+ struct cvmx_ipd_pkt_ptr_valid_s cn63xx;
+ struct cvmx_ipd_pkt_ptr_valid_s cn63xxp1;
};
union cvmx_ipd_portx_bp_page_cnt {
@@ -516,6 +532,8 @@ union cvmx_ipd_portx_bp_page_cnt {
struct cvmx_ipd_portx_bp_page_cnt_s cn56xxp1;
struct cvmx_ipd_portx_bp_page_cnt_s cn58xx;
struct cvmx_ipd_portx_bp_page_cnt_s cn58xxp1;
+ struct cvmx_ipd_portx_bp_page_cnt_s cn63xx;
+ struct cvmx_ipd_portx_bp_page_cnt_s cn63xxp1;
};
union cvmx_ipd_portx_bp_page_cnt2 {
@@ -529,6 +547,19 @@ union cvmx_ipd_portx_bp_page_cnt2 {
struct cvmx_ipd_portx_bp_page_cnt2_s cn52xxp1;
struct cvmx_ipd_portx_bp_page_cnt2_s cn56xx;
struct cvmx_ipd_portx_bp_page_cnt2_s cn56xxp1;
+ struct cvmx_ipd_portx_bp_page_cnt2_s cn63xx;
+ struct cvmx_ipd_portx_bp_page_cnt2_s cn63xxp1;
+};
+
+union cvmx_ipd_portx_bp_page_cnt3 {
+ uint64_t u64;
+ struct cvmx_ipd_portx_bp_page_cnt3_s {
+ uint64_t reserved_18_63:46;
+ uint64_t bp_enb:1;
+ uint64_t page_cnt:17;
+ } s;
+ struct cvmx_ipd_portx_bp_page_cnt3_s cn63xx;
+ struct cvmx_ipd_portx_bp_page_cnt3_s cn63xxp1;
};
union cvmx_ipd_port_bp_counters2_pairx {
@@ -541,6 +572,18 @@ union cvmx_ipd_port_bp_counters2_pairx {
struct cvmx_ipd_port_bp_counters2_pairx_s cn52xxp1;
struct cvmx_ipd_port_bp_counters2_pairx_s cn56xx;
struct cvmx_ipd_port_bp_counters2_pairx_s cn56xxp1;
+ struct cvmx_ipd_port_bp_counters2_pairx_s cn63xx;
+ struct cvmx_ipd_port_bp_counters2_pairx_s cn63xxp1;
+};
+
+union cvmx_ipd_port_bp_counters3_pairx {
+ uint64_t u64;
+ struct cvmx_ipd_port_bp_counters3_pairx_s {
+ uint64_t reserved_25_63:39;
+ uint64_t cnt_val:25;
+ } s;
+ struct cvmx_ipd_port_bp_counters3_pairx_s cn63xx;
+ struct cvmx_ipd_port_bp_counters3_pairx_s cn63xxp1;
};
union cvmx_ipd_port_bp_counters_pairx {
@@ -560,6 +603,8 @@ union cvmx_ipd_port_bp_counters_pairx {
struct cvmx_ipd_port_bp_counters_pairx_s cn56xxp1;
struct cvmx_ipd_port_bp_counters_pairx_s cn58xx;
struct cvmx_ipd_port_bp_counters_pairx_s cn58xxp1;
+ struct cvmx_ipd_port_bp_counters_pairx_s cn63xx;
+ struct cvmx_ipd_port_bp_counters_pairx_s cn63xxp1;
};
union cvmx_ipd_port_qos_x_cnt {
@@ -572,6 +617,8 @@ union cvmx_ipd_port_qos_x_cnt {
struct cvmx_ipd_port_qos_x_cnt_s cn52xxp1;
struct cvmx_ipd_port_qos_x_cnt_s cn56xx;
struct cvmx_ipd_port_qos_x_cnt_s cn56xxp1;
+ struct cvmx_ipd_port_qos_x_cnt_s cn63xx;
+ struct cvmx_ipd_port_qos_x_cnt_s cn63xxp1;
};
union cvmx_ipd_port_qos_intx {
@@ -583,6 +630,8 @@ union cvmx_ipd_port_qos_intx {
struct cvmx_ipd_port_qos_intx_s cn52xxp1;
struct cvmx_ipd_port_qos_intx_s cn56xx;
struct cvmx_ipd_port_qos_intx_s cn56xxp1;
+ struct cvmx_ipd_port_qos_intx_s cn63xx;
+ struct cvmx_ipd_port_qos_intx_s cn63xxp1;
};
union cvmx_ipd_port_qos_int_enbx {
@@ -594,6 +643,8 @@ union cvmx_ipd_port_qos_int_enbx {
struct cvmx_ipd_port_qos_int_enbx_s cn52xxp1;
struct cvmx_ipd_port_qos_int_enbx_s cn56xx;
struct cvmx_ipd_port_qos_int_enbx_s cn56xxp1;
+ struct cvmx_ipd_port_qos_int_enbx_s cn63xx;
+ struct cvmx_ipd_port_qos_int_enbx_s cn63xxp1;
};
union cvmx_ipd_prc_hold_ptr_fifo_ctl {
@@ -616,6 +667,8 @@ union cvmx_ipd_prc_hold_ptr_fifo_ctl {
struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn56xxp1;
struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn58xx;
struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn58xxp1;
+ struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn63xx;
+ struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn63xxp1;
};
union cvmx_ipd_prc_port_ptr_fifo_ctl {
@@ -637,6 +690,8 @@ union cvmx_ipd_prc_port_ptr_fifo_ctl {
struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn56xxp1;
struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn58xx;
struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn58xxp1;
+ struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn63xx;
+ struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn63xxp1;
};
union cvmx_ipd_ptr_count {
@@ -660,6 +715,8 @@ union cvmx_ipd_ptr_count {
struct cvmx_ipd_ptr_count_s cn56xxp1;
struct cvmx_ipd_ptr_count_s cn58xx;
struct cvmx_ipd_ptr_count_s cn58xxp1;
+ struct cvmx_ipd_ptr_count_s cn63xx;
+ struct cvmx_ipd_ptr_count_s cn63xxp1;
};
union cvmx_ipd_pwp_ptr_fifo_ctl {
@@ -683,6 +740,8 @@ union cvmx_ipd_pwp_ptr_fifo_ctl {
struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn56xxp1;
struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn58xx;
struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn58xxp1;
+ struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn63xx;
+ struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn63xxp1;
};
union cvmx_ipd_qosx_red_marks {
@@ -702,6 +761,8 @@ union cvmx_ipd_qosx_red_marks {
struct cvmx_ipd_qosx_red_marks_s cn56xxp1;
struct cvmx_ipd_qosx_red_marks_s cn58xx;
struct cvmx_ipd_qosx_red_marks_s cn58xxp1;
+ struct cvmx_ipd_qosx_red_marks_s cn63xx;
+ struct cvmx_ipd_qosx_red_marks_s cn63xxp1;
};
union cvmx_ipd_que0_free_page_cnt {
@@ -721,6 +782,8 @@ union cvmx_ipd_que0_free_page_cnt {
struct cvmx_ipd_que0_free_page_cnt_s cn56xxp1;
struct cvmx_ipd_que0_free_page_cnt_s cn58xx;
struct cvmx_ipd_que0_free_page_cnt_s cn58xxp1;
+ struct cvmx_ipd_que0_free_page_cnt_s cn63xx;
+ struct cvmx_ipd_que0_free_page_cnt_s cn63xxp1;
};
union cvmx_ipd_red_port_enable {
@@ -741,18 +804,25 @@ union cvmx_ipd_red_port_enable {
struct cvmx_ipd_red_port_enable_s cn56xxp1;
struct cvmx_ipd_red_port_enable_s cn58xx;
struct cvmx_ipd_red_port_enable_s cn58xxp1;
+ struct cvmx_ipd_red_port_enable_s cn63xx;
+ struct cvmx_ipd_red_port_enable_s cn63xxp1;
};
union cvmx_ipd_red_port_enable2 {
uint64_t u64;
struct cvmx_ipd_red_port_enable2_s {
+ uint64_t reserved_8_63:56;
+ uint64_t prt_enb:8;
+ } s;
+ struct cvmx_ipd_red_port_enable2_cn52xx {
uint64_t reserved_4_63:60;
uint64_t prt_enb:4;
- } s;
- struct cvmx_ipd_red_port_enable2_s cn52xx;
- struct cvmx_ipd_red_port_enable2_s cn52xxp1;
- struct cvmx_ipd_red_port_enable2_s cn56xx;
- struct cvmx_ipd_red_port_enable2_s cn56xxp1;
+ } cn52xx;
+ struct cvmx_ipd_red_port_enable2_cn52xx cn52xxp1;
+ struct cvmx_ipd_red_port_enable2_cn52xx cn56xx;
+ struct cvmx_ipd_red_port_enable2_cn52xx cn56xxp1;
+ struct cvmx_ipd_red_port_enable2_s cn63xx;
+ struct cvmx_ipd_red_port_enable2_s cn63xxp1;
};
union cvmx_ipd_red_quex_param {
@@ -775,6 +845,8 @@ union cvmx_ipd_red_quex_param {
struct cvmx_ipd_red_quex_param_s cn56xxp1;
struct cvmx_ipd_red_quex_param_s cn58xx;
struct cvmx_ipd_red_quex_param_s cn58xxp1;
+ struct cvmx_ipd_red_quex_param_s cn63xx;
+ struct cvmx_ipd_red_quex_param_s cn63xxp1;
};
union cvmx_ipd_sub_port_bp_page_cnt {
@@ -795,6 +867,8 @@ union cvmx_ipd_sub_port_bp_page_cnt {
struct cvmx_ipd_sub_port_bp_page_cnt_s cn56xxp1;
struct cvmx_ipd_sub_port_bp_page_cnt_s cn58xx;
struct cvmx_ipd_sub_port_bp_page_cnt_s cn58xxp1;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn63xx;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn63xxp1;
};
union cvmx_ipd_sub_port_fcs {
@@ -822,6 +896,8 @@ union cvmx_ipd_sub_port_fcs {
struct cvmx_ipd_sub_port_fcs_s cn56xxp1;
struct cvmx_ipd_sub_port_fcs_cn38xx cn58xx;
struct cvmx_ipd_sub_port_fcs_cn38xx cn58xxp1;
+ struct cvmx_ipd_sub_port_fcs_s cn63xx;
+ struct cvmx_ipd_sub_port_fcs_s cn63xxp1;
};
union cvmx_ipd_sub_port_qos_cnt {
@@ -835,6 +911,8 @@ union cvmx_ipd_sub_port_qos_cnt {
struct cvmx_ipd_sub_port_qos_cnt_s cn52xxp1;
struct cvmx_ipd_sub_port_qos_cnt_s cn56xx;
struct cvmx_ipd_sub_port_qos_cnt_s cn56xxp1;
+ struct cvmx_ipd_sub_port_qos_cnt_s cn63xx;
+ struct cvmx_ipd_sub_port_qos_cnt_s cn63xxp1;
};
union cvmx_ipd_wqe_fpa_queue {
@@ -854,6 +932,8 @@ union cvmx_ipd_wqe_fpa_queue {
struct cvmx_ipd_wqe_fpa_queue_s cn56xxp1;
struct cvmx_ipd_wqe_fpa_queue_s cn58xx;
struct cvmx_ipd_wqe_fpa_queue_s cn58xxp1;
+ struct cvmx_ipd_wqe_fpa_queue_s cn63xx;
+ struct cvmx_ipd_wqe_fpa_queue_s cn63xxp1;
};
union cvmx_ipd_wqe_ptr_valid {
@@ -872,6 +952,8 @@ union cvmx_ipd_wqe_ptr_valid {
struct cvmx_ipd_wqe_ptr_valid_s cn56xxp1;
struct cvmx_ipd_wqe_ptr_valid_s cn58xx;
struct cvmx_ipd_wqe_ptr_valid_s cn58xxp1;
+ struct cvmx_ipd_wqe_ptr_valid_s cn63xx;
+ struct cvmx_ipd_wqe_ptr_valid_s cn63xxp1;
};
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-l2c-defs.h b/arch/mips/include/asm/octeon/cvmx-l2c-defs.h
index 337583842b51..7a50a0beb472 100644
--- a/arch/mips/include/asm/octeon/cvmx-l2c-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-l2c-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
@@ -28,70 +28,113 @@
#ifndef __CVMX_L2C_DEFS_H__
#define __CVMX_L2C_DEFS_H__
-#define CVMX_L2C_BST0 \
- CVMX_ADD_IO_SEG(0x00011800800007F8ull)
-#define CVMX_L2C_BST1 \
- CVMX_ADD_IO_SEG(0x00011800800007F0ull)
-#define CVMX_L2C_BST2 \
- CVMX_ADD_IO_SEG(0x00011800800007E8ull)
-#define CVMX_L2C_CFG \
- CVMX_ADD_IO_SEG(0x0001180080000000ull)
-#define CVMX_L2C_DBG \
- CVMX_ADD_IO_SEG(0x0001180080000030ull)
-#define CVMX_L2C_DUT \
- CVMX_ADD_IO_SEG(0x0001180080000050ull)
-#define CVMX_L2C_GRPWRR0 \
- CVMX_ADD_IO_SEG(0x00011800800000C8ull)
-#define CVMX_L2C_GRPWRR1 \
- CVMX_ADD_IO_SEG(0x00011800800000D0ull)
-#define CVMX_L2C_INT_EN \
- CVMX_ADD_IO_SEG(0x0001180080000100ull)
-#define CVMX_L2C_INT_STAT \
- CVMX_ADD_IO_SEG(0x00011800800000F8ull)
-#define CVMX_L2C_LCKBASE \
- CVMX_ADD_IO_SEG(0x0001180080000058ull)
-#define CVMX_L2C_LCKOFF \
- CVMX_ADD_IO_SEG(0x0001180080000060ull)
-#define CVMX_L2C_LFB0 \
- CVMX_ADD_IO_SEG(0x0001180080000038ull)
-#define CVMX_L2C_LFB1 \
- CVMX_ADD_IO_SEG(0x0001180080000040ull)
-#define CVMX_L2C_LFB2 \
- CVMX_ADD_IO_SEG(0x0001180080000048ull)
-#define CVMX_L2C_LFB3 \
- CVMX_ADD_IO_SEG(0x00011800800000B8ull)
-#define CVMX_L2C_OOB \
- CVMX_ADD_IO_SEG(0x00011800800000D8ull)
-#define CVMX_L2C_OOB1 \
- CVMX_ADD_IO_SEG(0x00011800800000E0ull)
-#define CVMX_L2C_OOB2 \
- CVMX_ADD_IO_SEG(0x00011800800000E8ull)
-#define CVMX_L2C_OOB3 \
- CVMX_ADD_IO_SEG(0x00011800800000F0ull)
-#define CVMX_L2C_PFC0 \
- CVMX_ADD_IO_SEG(0x0001180080000098ull)
-#define CVMX_L2C_PFC1 \
- CVMX_ADD_IO_SEG(0x00011800800000A0ull)
-#define CVMX_L2C_PFC2 \
- CVMX_ADD_IO_SEG(0x00011800800000A8ull)
-#define CVMX_L2C_PFC3 \
- CVMX_ADD_IO_SEG(0x00011800800000B0ull)
-#define CVMX_L2C_PFCTL \
- CVMX_ADD_IO_SEG(0x0001180080000090ull)
-#define CVMX_L2C_PFCX(offset) \
- CVMX_ADD_IO_SEG(0x0001180080000098ull + (((offset) & 3) * 8))
-#define CVMX_L2C_PPGRP \
- CVMX_ADD_IO_SEG(0x00011800800000C0ull)
-#define CVMX_L2C_SPAR0 \
- CVMX_ADD_IO_SEG(0x0001180080000068ull)
-#define CVMX_L2C_SPAR1 \
- CVMX_ADD_IO_SEG(0x0001180080000070ull)
-#define CVMX_L2C_SPAR2 \
- CVMX_ADD_IO_SEG(0x0001180080000078ull)
-#define CVMX_L2C_SPAR3 \
- CVMX_ADD_IO_SEG(0x0001180080000080ull)
-#define CVMX_L2C_SPAR4 \
- CVMX_ADD_IO_SEG(0x0001180080000088ull)
+#define CVMX_L2C_BIG_CTL (CVMX_ADD_IO_SEG(0x0001180080800030ull))
+#define CVMX_L2C_BST (CVMX_ADD_IO_SEG(0x00011800808007F8ull))
+#define CVMX_L2C_BST0 (CVMX_ADD_IO_SEG(0x00011800800007F8ull))
+#define CVMX_L2C_BST1 (CVMX_ADD_IO_SEG(0x00011800800007F0ull))
+#define CVMX_L2C_BST2 (CVMX_ADD_IO_SEG(0x00011800800007E8ull))
+#define CVMX_L2C_BST_MEMX(block_id) (CVMX_ADD_IO_SEG(0x0001180080C007F8ull))
+#define CVMX_L2C_BST_TDTX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007F0ull))
+#define CVMX_L2C_BST_TTGX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007F8ull))
+#define CVMX_L2C_CFG (CVMX_ADD_IO_SEG(0x0001180080000000ull))
+#define CVMX_L2C_COP0_MAPX(offset) (CVMX_ADD_IO_SEG(0x0001180080940000ull) + ((offset) & 16383) * 8)
+#define CVMX_L2C_CTL (CVMX_ADD_IO_SEG(0x0001180080800000ull))
+#define CVMX_L2C_DBG (CVMX_ADD_IO_SEG(0x0001180080000030ull))
+#define CVMX_L2C_DUT (CVMX_ADD_IO_SEG(0x0001180080000050ull))
+#define CVMX_L2C_DUT_MAPX(offset) (CVMX_ADD_IO_SEG(0x0001180080E00000ull) + ((offset) & 2047) * 8)
+#define CVMX_L2C_ERR_TDTX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007E0ull))
+#define CVMX_L2C_ERR_TTGX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007E8ull))
+#define CVMX_L2C_ERR_VBFX(block_id) (CVMX_ADD_IO_SEG(0x0001180080C007F0ull))
+#define CVMX_L2C_ERR_XMC (CVMX_ADD_IO_SEG(0x00011800808007D8ull))
+#define CVMX_L2C_GRPWRR0 (CVMX_ADD_IO_SEG(0x00011800800000C8ull))
+#define CVMX_L2C_GRPWRR1 (CVMX_ADD_IO_SEG(0x00011800800000D0ull))
+#define CVMX_L2C_INT_EN (CVMX_ADD_IO_SEG(0x0001180080000100ull))
+#define CVMX_L2C_INT_ENA (CVMX_ADD_IO_SEG(0x0001180080800020ull))
+#define CVMX_L2C_INT_REG (CVMX_ADD_IO_SEG(0x0001180080800018ull))
+#define CVMX_L2C_INT_STAT (CVMX_ADD_IO_SEG(0x00011800800000F8ull))
+#define CVMX_L2C_IOCX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800420ull))
+#define CVMX_L2C_IORX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800428ull))
+#define CVMX_L2C_LCKBASE (CVMX_ADD_IO_SEG(0x0001180080000058ull))
+#define CVMX_L2C_LCKOFF (CVMX_ADD_IO_SEG(0x0001180080000060ull))
+#define CVMX_L2C_LFB0 (CVMX_ADD_IO_SEG(0x0001180080000038ull))
+#define CVMX_L2C_LFB1 (CVMX_ADD_IO_SEG(0x0001180080000040ull))
+#define CVMX_L2C_LFB2 (CVMX_ADD_IO_SEG(0x0001180080000048ull))
+#define CVMX_L2C_LFB3 (CVMX_ADD_IO_SEG(0x00011800800000B8ull))
+#define CVMX_L2C_OOB (CVMX_ADD_IO_SEG(0x00011800800000D8ull))
+#define CVMX_L2C_OOB1 (CVMX_ADD_IO_SEG(0x00011800800000E0ull))
+#define CVMX_L2C_OOB2 (CVMX_ADD_IO_SEG(0x00011800800000E8ull))
+#define CVMX_L2C_OOB3 (CVMX_ADD_IO_SEG(0x00011800800000F0ull))
+#define CVMX_L2C_PFC0 CVMX_L2C_PFCX(0)
+#define CVMX_L2C_PFC1 CVMX_L2C_PFCX(1)
+#define CVMX_L2C_PFC2 CVMX_L2C_PFCX(2)
+#define CVMX_L2C_PFC3 CVMX_L2C_PFCX(3)
+#define CVMX_L2C_PFCTL (CVMX_ADD_IO_SEG(0x0001180080000090ull))
+#define CVMX_L2C_PFCX(offset) (CVMX_ADD_IO_SEG(0x0001180080000098ull) + ((offset) & 3) * 8)
+#define CVMX_L2C_PPGRP (CVMX_ADD_IO_SEG(0x00011800800000C0ull))
+#define CVMX_L2C_QOS_IOBX(block_id) (CVMX_ADD_IO_SEG(0x0001180080880200ull))
+#define CVMX_L2C_QOS_PPX(offset) (CVMX_ADD_IO_SEG(0x0001180080880000ull) + ((offset) & 7) * 8)
+#define CVMX_L2C_QOS_WGT (CVMX_ADD_IO_SEG(0x0001180080800008ull))
+#define CVMX_L2C_RSCX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800410ull))
+#define CVMX_L2C_RSDX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800418ull))
+#define CVMX_L2C_SPAR0 (CVMX_ADD_IO_SEG(0x0001180080000068ull))
+#define CVMX_L2C_SPAR1 (CVMX_ADD_IO_SEG(0x0001180080000070ull))
+#define CVMX_L2C_SPAR2 (CVMX_ADD_IO_SEG(0x0001180080000078ull))
+#define CVMX_L2C_SPAR3 (CVMX_ADD_IO_SEG(0x0001180080000080ull))
+#define CVMX_L2C_SPAR4 (CVMX_ADD_IO_SEG(0x0001180080000088ull))
+#define CVMX_L2C_TADX_ECC0(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00018ull))
+#define CVMX_L2C_TADX_ECC1(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00020ull))
+#define CVMX_L2C_TADX_IEN(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00000ull))
+#define CVMX_L2C_TADX_INT(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00028ull))
+#define CVMX_L2C_TADX_PFC0(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00400ull))
+#define CVMX_L2C_TADX_PFC1(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00408ull))
+#define CVMX_L2C_TADX_PFC2(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00410ull))
+#define CVMX_L2C_TADX_PFC3(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00418ull))
+#define CVMX_L2C_TADX_PRF(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00008ull))
+#define CVMX_L2C_TADX_TAG(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00010ull))
+#define CVMX_L2C_VER_ID (CVMX_ADD_IO_SEG(0x00011800808007E0ull))
+#define CVMX_L2C_VER_IOB (CVMX_ADD_IO_SEG(0x00011800808007F0ull))
+#define CVMX_L2C_VER_MSC (CVMX_ADD_IO_SEG(0x00011800808007D0ull))
+#define CVMX_L2C_VER_PP (CVMX_ADD_IO_SEG(0x00011800808007E8ull))
+#define CVMX_L2C_VIRTID_IOBX(block_id) (CVMX_ADD_IO_SEG(0x00011800808C0200ull))
+#define CVMX_L2C_VIRTID_PPX(offset) (CVMX_ADD_IO_SEG(0x00011800808C0000ull) + ((offset) & 7) * 8)
+#define CVMX_L2C_VRT_CTL (CVMX_ADD_IO_SEG(0x0001180080800010ull))
+#define CVMX_L2C_VRT_MEMX(offset) (CVMX_ADD_IO_SEG(0x0001180080900000ull) + ((offset) & 1023) * 8)
+#define CVMX_L2C_WPAR_IOBX(block_id) (CVMX_ADD_IO_SEG(0x0001180080840200ull))
+#define CVMX_L2C_WPAR_PPX(offset) (CVMX_ADD_IO_SEG(0x0001180080840000ull) + ((offset) & 7) * 8)
+#define CVMX_L2C_XMCX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800400ull))
+#define CVMX_L2C_XMC_CMD (CVMX_ADD_IO_SEG(0x0001180080800028ull))
+#define CVMX_L2C_XMDX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800408ull))
+
+union cvmx_l2c_big_ctl {
+ uint64_t u64;
+ struct cvmx_l2c_big_ctl_s {
+ uint64_t reserved_8_63:56;
+ uint64_t maxdram:4;
+ uint64_t reserved_1_3:3;
+ uint64_t disable:1;
+ } s;
+ struct cvmx_l2c_big_ctl_s cn63xx;
+};
+
+union cvmx_l2c_bst {
+ uint64_t u64;
+ struct cvmx_l2c_bst_s {
+ uint64_t reserved_38_63:26;
+ uint64_t dutfl:6;
+ uint64_t reserved_17_31:15;
+ uint64_t ioccmdfl:1;
+ uint64_t reserved_13_15:3;
+ uint64_t iocdatfl:1;
+ uint64_t reserved_9_11:3;
+ uint64_t dutresfl:1;
+ uint64_t reserved_5_7:3;
+ uint64_t vrtfl:1;
+ uint64_t reserved_1_3:3;
+ uint64_t tdffl:1;
+ } s;
+ struct cvmx_l2c_bst_s cn63xx;
+ struct cvmx_l2c_bst_s cn63xxp1;
+};
union cvmx_l2c_bst0 {
uint64_t u64;
@@ -253,6 +296,48 @@ union cvmx_l2c_bst2 {
struct cvmx_l2c_bst2_cn56xx cn58xxp1;
};
+union cvmx_l2c_bst_memx {
+ uint64_t u64;
+ struct cvmx_l2c_bst_memx_s {
+ uint64_t start_bist:1;
+ uint64_t clear_bist:1;
+ uint64_t reserved_5_61:57;
+ uint64_t rdffl:1;
+ uint64_t vbffl:4;
+ } s;
+ struct cvmx_l2c_bst_memx_s cn63xx;
+ struct cvmx_l2c_bst_memx_s cn63xxp1;
+};
+
+union cvmx_l2c_bst_tdtx {
+ uint64_t u64;
+ struct cvmx_l2c_bst_tdtx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t fbfrspfl:8;
+ uint64_t sbffl:8;
+ uint64_t fbffl:8;
+ uint64_t l2dfl:8;
+ } s;
+ struct cvmx_l2c_bst_tdtx_s cn63xx;
+ struct cvmx_l2c_bst_tdtx_cn63xxp1 {
+ uint64_t reserved_24_63:40;
+ uint64_t sbffl:8;
+ uint64_t fbffl:8;
+ uint64_t l2dfl:8;
+ } cn63xxp1;
+};
+
+union cvmx_l2c_bst_ttgx {
+ uint64_t u64;
+ struct cvmx_l2c_bst_ttgx_s {
+ uint64_t reserved_17_63:47;
+ uint64_t lrufl:1;
+ uint64_t tagfl:16;
+ } s;
+ struct cvmx_l2c_bst_ttgx_s cn63xx;
+ struct cvmx_l2c_bst_ttgx_s cn63xxp1;
+};
+
union cvmx_l2c_cfg {
uint64_t u64;
struct cvmx_l2c_cfg_s {
@@ -333,6 +418,49 @@ union cvmx_l2c_cfg {
} cn58xxp1;
};
+union cvmx_l2c_cop0_mapx {
+ uint64_t u64;
+ struct cvmx_l2c_cop0_mapx_s {
+ uint64_t data:64;
+ } s;
+ struct cvmx_l2c_cop0_mapx_s cn63xx;
+ struct cvmx_l2c_cop0_mapx_s cn63xxp1;
+};
+
+union cvmx_l2c_ctl {
+ uint64_t u64;
+ struct cvmx_l2c_ctl_s {
+ uint64_t reserved_28_63:36;
+ uint64_t disstgl2i:1;
+ uint64_t l2dfsbe:1;
+ uint64_t l2dfdbe:1;
+ uint64_t discclk:1;
+ uint64_t maxvab:4;
+ uint64_t maxlfb:4;
+ uint64_t rsp_arb_mode:1;
+ uint64_t xmc_arb_mode:1;
+ uint64_t ef_ena:1;
+ uint64_t ef_cnt:7;
+ uint64_t vab_thresh:4;
+ uint64_t disecc:1;
+ uint64_t disidxalias:1;
+ } s;
+ struct cvmx_l2c_ctl_s cn63xx;
+ struct cvmx_l2c_ctl_cn63xxp1 {
+ uint64_t reserved_25_63:39;
+ uint64_t discclk:1;
+ uint64_t maxvab:4;
+ uint64_t maxlfb:4;
+ uint64_t rsp_arb_mode:1;
+ uint64_t xmc_arb_mode:1;
+ uint64_t ef_ena:1;
+ uint64_t ef_cnt:7;
+ uint64_t vab_thresh:4;
+ uint64_t disecc:1;
+ uint64_t disidxalias:1;
+ } cn63xxp1;
+};
+
union cvmx_l2c_dbg {
uint64_t u64;
struct cvmx_l2c_dbg_s {
@@ -349,7 +477,9 @@ union cvmx_l2c_dbg {
uint64_t reserved_13_63:51;
uint64_t lfb_enum:2;
uint64_t lfb_dmp:1;
- uint64_t reserved_5_9:5;
+ uint64_t reserved_7_9:3;
+ uint64_t ppnum:1;
+ uint64_t reserved_5_5:1;
uint64_t set:2;
uint64_t finv:1;
uint64_t l2d:1;
@@ -420,6 +550,79 @@ union cvmx_l2c_dut {
struct cvmx_l2c_dut_s cn58xxp1;
};
+union cvmx_l2c_dut_mapx {
+ uint64_t u64;
+ struct cvmx_l2c_dut_mapx_s {
+ uint64_t reserved_38_63:26;
+ uint64_t tag:28;
+ uint64_t reserved_1_9:9;
+ uint64_t valid:1;
+ } s;
+ struct cvmx_l2c_dut_mapx_s cn63xx;
+ struct cvmx_l2c_dut_mapx_s cn63xxp1;
+};
+
+union cvmx_l2c_err_tdtx {
+ uint64_t u64;
+ struct cvmx_l2c_err_tdtx_s {
+ uint64_t dbe:1;
+ uint64_t sbe:1;
+ uint64_t vdbe:1;
+ uint64_t vsbe:1;
+ uint64_t syn:10;
+ uint64_t reserved_21_49:29;
+ uint64_t wayidx:17;
+ uint64_t reserved_2_3:2;
+ uint64_t type:2;
+ } s;
+ struct cvmx_l2c_err_tdtx_s cn63xx;
+ struct cvmx_l2c_err_tdtx_s cn63xxp1;
+};
+
+union cvmx_l2c_err_ttgx {
+ uint64_t u64;
+ struct cvmx_l2c_err_ttgx_s {
+ uint64_t dbe:1;
+ uint64_t sbe:1;
+ uint64_t noway:1;
+ uint64_t reserved_56_60:5;
+ uint64_t syn:6;
+ uint64_t reserved_21_49:29;
+ uint64_t wayidx:14;
+ uint64_t reserved_2_6:5;
+ uint64_t type:2;
+ } s;
+ struct cvmx_l2c_err_ttgx_s cn63xx;
+ struct cvmx_l2c_err_ttgx_s cn63xxp1;
+};
+
+union cvmx_l2c_err_vbfx {
+ uint64_t u64;
+ struct cvmx_l2c_err_vbfx_s {
+ uint64_t reserved_62_63:2;
+ uint64_t vdbe:1;
+ uint64_t vsbe:1;
+ uint64_t vsyn:10;
+ uint64_t reserved_2_49:48;
+ uint64_t type:2;
+ } s;
+ struct cvmx_l2c_err_vbfx_s cn63xx;
+ struct cvmx_l2c_err_vbfx_s cn63xxp1;
+};
+
+union cvmx_l2c_err_xmc {
+ uint64_t u64;
+ struct cvmx_l2c_err_xmc_s {
+ uint64_t cmd:6;
+ uint64_t reserved_52_57:6;
+ uint64_t sid:4;
+ uint64_t reserved_38_47:10;
+ uint64_t addr:38;
+ } s;
+ struct cvmx_l2c_err_xmc_s cn63xx;
+ struct cvmx_l2c_err_xmc_s cn63xxp1;
+};
+
union cvmx_l2c_grpwrr0 {
uint64_t u64;
struct cvmx_l2c_grpwrr0_s {
@@ -464,6 +667,60 @@ union cvmx_l2c_int_en {
struct cvmx_l2c_int_en_s cn56xxp1;
};
+union cvmx_l2c_int_ena {
+ uint64_t u64;
+ struct cvmx_l2c_int_ena_s {
+ uint64_t reserved_8_63:56;
+ uint64_t bigrd:1;
+ uint64_t bigwr:1;
+ uint64_t vrtpe:1;
+ uint64_t vrtadrng:1;
+ uint64_t vrtidrng:1;
+ uint64_t vrtwr:1;
+ uint64_t holewr:1;
+ uint64_t holerd:1;
+ } s;
+ struct cvmx_l2c_int_ena_s cn63xx;
+ struct cvmx_l2c_int_ena_cn63xxp1 {
+ uint64_t reserved_6_63:58;
+ uint64_t vrtpe:1;
+ uint64_t vrtadrng:1;
+ uint64_t vrtidrng:1;
+ uint64_t vrtwr:1;
+ uint64_t holewr:1;
+ uint64_t holerd:1;
+ } cn63xxp1;
+};
+
+union cvmx_l2c_int_reg {
+ uint64_t u64;
+ struct cvmx_l2c_int_reg_s {
+ uint64_t reserved_17_63:47;
+ uint64_t tad0:1;
+ uint64_t reserved_8_15:8;
+ uint64_t bigrd:1;
+ uint64_t bigwr:1;
+ uint64_t vrtpe:1;
+ uint64_t vrtadrng:1;
+ uint64_t vrtidrng:1;
+ uint64_t vrtwr:1;
+ uint64_t holewr:1;
+ uint64_t holerd:1;
+ } s;
+ struct cvmx_l2c_int_reg_s cn63xx;
+ struct cvmx_l2c_int_reg_cn63xxp1 {
+ uint64_t reserved_17_63:47;
+ uint64_t tad0:1;
+ uint64_t reserved_6_15:10;
+ uint64_t vrtpe:1;
+ uint64_t vrtadrng:1;
+ uint64_t vrtidrng:1;
+ uint64_t vrtwr:1;
+ uint64_t holewr:1;
+ uint64_t holerd:1;
+ } cn63xxp1;
+};
+
union cvmx_l2c_int_stat {
uint64_t u64;
struct cvmx_l2c_int_stat_s {
@@ -484,6 +741,24 @@ union cvmx_l2c_int_stat {
struct cvmx_l2c_int_stat_s cn56xxp1;
};
+union cvmx_l2c_iocx_pfc {
+ uint64_t u64;
+ struct cvmx_l2c_iocx_pfc_s {
+ uint64_t count:64;
+ } s;
+ struct cvmx_l2c_iocx_pfc_s cn63xx;
+ struct cvmx_l2c_iocx_pfc_s cn63xxp1;
+};
+
+union cvmx_l2c_iorx_pfc {
+ uint64_t u64;
+ struct cvmx_l2c_iorx_pfc_s {
+ uint64_t count:64;
+ } s;
+ struct cvmx_l2c_iorx_pfc_s cn63xx;
+ struct cvmx_l2c_iorx_pfc_s cn63xxp1;
+};
+
union cvmx_l2c_lckbase {
uint64_t u64;
struct cvmx_l2c_lckbase_s {
@@ -855,6 +1130,59 @@ union cvmx_l2c_ppgrp {
struct cvmx_l2c_ppgrp_s cn56xxp1;
};
+union cvmx_l2c_qos_iobx {
+ uint64_t u64;
+ struct cvmx_l2c_qos_iobx_s {
+ uint64_t reserved_6_63:58;
+ uint64_t dwblvl:2;
+ uint64_t reserved_2_3:2;
+ uint64_t lvl:2;
+ } s;
+ struct cvmx_l2c_qos_iobx_s cn63xx;
+ struct cvmx_l2c_qos_iobx_s cn63xxp1;
+};
+
+union cvmx_l2c_qos_ppx {
+ uint64_t u64;
+ struct cvmx_l2c_qos_ppx_s {
+ uint64_t reserved_2_63:62;
+ uint64_t lvl:2;
+ } s;
+ struct cvmx_l2c_qos_ppx_s cn63xx;
+ struct cvmx_l2c_qos_ppx_s cn63xxp1;
+};
+
+union cvmx_l2c_qos_wgt {
+ uint64_t u64;
+ struct cvmx_l2c_qos_wgt_s {
+ uint64_t reserved_32_63:32;
+ uint64_t wgt3:8;
+ uint64_t wgt2:8;
+ uint64_t wgt1:8;
+ uint64_t wgt0:8;
+ } s;
+ struct cvmx_l2c_qos_wgt_s cn63xx;
+ struct cvmx_l2c_qos_wgt_s cn63xxp1;
+};
+
+union cvmx_l2c_rscx_pfc {
+ uint64_t u64;
+ struct cvmx_l2c_rscx_pfc_s {
+ uint64_t count:64;
+ } s;
+ struct cvmx_l2c_rscx_pfc_s cn63xx;
+ struct cvmx_l2c_rscx_pfc_s cn63xxp1;
+};
+
+union cvmx_l2c_rsdx_pfc {
+ uint64_t u64;
+ struct cvmx_l2c_rsdx_pfc_s {
+ uint64_t count:64;
+ } s;
+ struct cvmx_l2c_rsdx_pfc_s cn63xx;
+ struct cvmx_l2c_rsdx_pfc_s cn63xxp1;
+};
+
union cvmx_l2c_spar0 {
uint64_t u64;
struct cvmx_l2c_spar0_s {
@@ -960,4 +1288,282 @@ union cvmx_l2c_spar4 {
struct cvmx_l2c_spar4_s cn58xxp1;
};
+union cvmx_l2c_tadx_ecc0 {
+ uint64_t u64;
+ struct cvmx_l2c_tadx_ecc0_s {
+ uint64_t reserved_58_63:6;
+ uint64_t ow3ecc:10;
+ uint64_t reserved_42_47:6;
+ uint64_t ow2ecc:10;
+ uint64_t reserved_26_31:6;
+ uint64_t ow1ecc:10;
+ uint64_t reserved_10_15:6;
+ uint64_t ow0ecc:10;
+ } s;
+ struct cvmx_l2c_tadx_ecc0_s cn63xx;
+ struct cvmx_l2c_tadx_ecc0_s cn63xxp1;
+};
+
+union cvmx_l2c_tadx_ecc1 {
+ uint64_t u64;
+ struct cvmx_l2c_tadx_ecc1_s {
+ uint64_t reserved_58_63:6;
+ uint64_t ow7ecc:10;
+ uint64_t reserved_42_47:6;
+ uint64_t ow6ecc:10;
+ uint64_t reserved_26_31:6;
+ uint64_t ow5ecc:10;
+ uint64_t reserved_10_15:6;
+ uint64_t ow4ecc:10;
+ } s;
+ struct cvmx_l2c_tadx_ecc1_s cn63xx;
+ struct cvmx_l2c_tadx_ecc1_s cn63xxp1;
+};
+
+union cvmx_l2c_tadx_ien {
+ uint64_t u64;
+ struct cvmx_l2c_tadx_ien_s {
+ uint64_t reserved_9_63:55;
+ uint64_t wrdislmc:1;
+ uint64_t rddislmc:1;
+ uint64_t noway:1;
+ uint64_t vbfdbe:1;
+ uint64_t vbfsbe:1;
+ uint64_t tagdbe:1;
+ uint64_t tagsbe:1;
+ uint64_t l2ddbe:1;
+ uint64_t l2dsbe:1;
+ } s;
+ struct cvmx_l2c_tadx_ien_s cn63xx;
+ struct cvmx_l2c_tadx_ien_cn63xxp1 {
+ uint64_t reserved_7_63:57;
+ uint64_t noway:1;
+ uint64_t vbfdbe:1;
+ uint64_t vbfsbe:1;
+ uint64_t tagdbe:1;
+ uint64_t tagsbe:1;
+ uint64_t l2ddbe:1;
+ uint64_t l2dsbe:1;
+ } cn63xxp1;
+};
+
+union cvmx_l2c_tadx_int {
+ uint64_t u64;
+ struct cvmx_l2c_tadx_int_s {
+ uint64_t reserved_9_63:55;
+ uint64_t wrdislmc:1;
+ uint64_t rddislmc:1;
+ uint64_t noway:1;
+ uint64_t vbfdbe:1;
+ uint64_t vbfsbe:1;
+ uint64_t tagdbe:1;
+ uint64_t tagsbe:1;
+ uint64_t l2ddbe:1;
+ uint64_t l2dsbe:1;
+ } s;
+ struct cvmx_l2c_tadx_int_s cn63xx;
+};
+
+union cvmx_l2c_tadx_pfc0 {
+ uint64_t u64;
+ struct cvmx_l2c_tadx_pfc0_s {
+ uint64_t count:64;
+ } s;
+ struct cvmx_l2c_tadx_pfc0_s cn63xx;
+ struct cvmx_l2c_tadx_pfc0_s cn63xxp1;
+};
+
+union cvmx_l2c_tadx_pfc1 {
+ uint64_t u64;
+ struct cvmx_l2c_tadx_pfc1_s {
+ uint64_t count:64;
+ } s;
+ struct cvmx_l2c_tadx_pfc1_s cn63xx;
+ struct cvmx_l2c_tadx_pfc1_s cn63xxp1;
+};
+
+union cvmx_l2c_tadx_pfc2 {
+ uint64_t u64;
+ struct cvmx_l2c_tadx_pfc2_s {
+ uint64_t count:64;
+ } s;
+ struct cvmx_l2c_tadx_pfc2_s cn63xx;
+ struct cvmx_l2c_tadx_pfc2_s cn63xxp1;
+};
+
+union cvmx_l2c_tadx_pfc3 {
+ uint64_t u64;
+ struct cvmx_l2c_tadx_pfc3_s {
+ uint64_t count:64;
+ } s;
+ struct cvmx_l2c_tadx_pfc3_s cn63xx;
+ struct cvmx_l2c_tadx_pfc3_s cn63xxp1;
+};
+
+union cvmx_l2c_tadx_prf {
+ uint64_t u64;
+ struct cvmx_l2c_tadx_prf_s {
+ uint64_t reserved_32_63:32;
+ uint64_t cnt3sel:8;
+ uint64_t cnt2sel:8;
+ uint64_t cnt1sel:8;
+ uint64_t cnt0sel:8;
+ } s;
+ struct cvmx_l2c_tadx_prf_s cn63xx;
+ struct cvmx_l2c_tadx_prf_s cn63xxp1;
+};
+
+union cvmx_l2c_tadx_tag {
+ uint64_t u64;
+ struct cvmx_l2c_tadx_tag_s {
+ uint64_t reserved_46_63:18;
+ uint64_t ecc:6;
+ uint64_t reserved_36_39:4;
+ uint64_t tag:19;
+ uint64_t reserved_4_16:13;
+ uint64_t use:1;
+ uint64_t valid:1;
+ uint64_t dirty:1;
+ uint64_t lock:1;
+ } s;
+ struct cvmx_l2c_tadx_tag_s cn63xx;
+ struct cvmx_l2c_tadx_tag_s cn63xxp1;
+};
+
+union cvmx_l2c_ver_id {
+ uint64_t u64;
+ struct cvmx_l2c_ver_id_s {
+ uint64_t mask:64;
+ } s;
+ struct cvmx_l2c_ver_id_s cn63xx;
+ struct cvmx_l2c_ver_id_s cn63xxp1;
+};
+
+union cvmx_l2c_ver_iob {
+ uint64_t u64;
+ struct cvmx_l2c_ver_iob_s {
+ uint64_t reserved_1_63:63;
+ uint64_t mask:1;
+ } s;
+ struct cvmx_l2c_ver_iob_s cn63xx;
+ struct cvmx_l2c_ver_iob_s cn63xxp1;
+};
+
+union cvmx_l2c_ver_msc {
+ uint64_t u64;
+ struct cvmx_l2c_ver_msc_s {
+ uint64_t reserved_2_63:62;
+ uint64_t invl2:1;
+ uint64_t dwb:1;
+ } s;
+ struct cvmx_l2c_ver_msc_s cn63xx;
+};
+
+union cvmx_l2c_ver_pp {
+ uint64_t u64;
+ struct cvmx_l2c_ver_pp_s {
+ uint64_t reserved_6_63:58;
+ uint64_t mask:6;
+ } s;
+ struct cvmx_l2c_ver_pp_s cn63xx;
+ struct cvmx_l2c_ver_pp_s cn63xxp1;
+};
+
+union cvmx_l2c_virtid_iobx {
+ uint64_t u64;
+ struct cvmx_l2c_virtid_iobx_s {
+ uint64_t reserved_14_63:50;
+ uint64_t dwbid:6;
+ uint64_t reserved_6_7:2;
+ uint64_t id:6;
+ } s;
+ struct cvmx_l2c_virtid_iobx_s cn63xx;
+ struct cvmx_l2c_virtid_iobx_s cn63xxp1;
+};
+
+union cvmx_l2c_virtid_ppx {
+ uint64_t u64;
+ struct cvmx_l2c_virtid_ppx_s {
+ uint64_t reserved_6_63:58;
+ uint64_t id:6;
+ } s;
+ struct cvmx_l2c_virtid_ppx_s cn63xx;
+ struct cvmx_l2c_virtid_ppx_s cn63xxp1;
+};
+
+union cvmx_l2c_vrt_ctl {
+ uint64_t u64;
+ struct cvmx_l2c_vrt_ctl_s {
+ uint64_t reserved_9_63:55;
+ uint64_t ooberr:1;
+ uint64_t reserved_7_7:1;
+ uint64_t memsz:3;
+ uint64_t numid:3;
+ uint64_t enable:1;
+ } s;
+ struct cvmx_l2c_vrt_ctl_s cn63xx;
+ struct cvmx_l2c_vrt_ctl_s cn63xxp1;
+};
+
+union cvmx_l2c_vrt_memx {
+ uint64_t u64;
+ struct cvmx_l2c_vrt_memx_s {
+ uint64_t reserved_36_63:28;
+ uint64_t parity:4;
+ uint64_t data:32;
+ } s;
+ struct cvmx_l2c_vrt_memx_s cn63xx;
+ struct cvmx_l2c_vrt_memx_s cn63xxp1;
+};
+
+union cvmx_l2c_wpar_iobx {
+ uint64_t u64;
+ struct cvmx_l2c_wpar_iobx_s {
+ uint64_t reserved_16_63:48;
+ uint64_t mask:16;
+ } s;
+ struct cvmx_l2c_wpar_iobx_s cn63xx;
+ struct cvmx_l2c_wpar_iobx_s cn63xxp1;
+};
+
+union cvmx_l2c_wpar_ppx {
+ uint64_t u64;
+ struct cvmx_l2c_wpar_ppx_s {
+ uint64_t reserved_16_63:48;
+ uint64_t mask:16;
+ } s;
+ struct cvmx_l2c_wpar_ppx_s cn63xx;
+ struct cvmx_l2c_wpar_ppx_s cn63xxp1;
+};
+
+union cvmx_l2c_xmcx_pfc {
+ uint64_t u64;
+ struct cvmx_l2c_xmcx_pfc_s {
+ uint64_t count:64;
+ } s;
+ struct cvmx_l2c_xmcx_pfc_s cn63xx;
+ struct cvmx_l2c_xmcx_pfc_s cn63xxp1;
+};
+
+union cvmx_l2c_xmc_cmd {
+ uint64_t u64;
+ struct cvmx_l2c_xmc_cmd_s {
+ uint64_t inuse:1;
+ uint64_t cmd:6;
+ uint64_t reserved_38_56:19;
+ uint64_t addr:38;
+ } s;
+ struct cvmx_l2c_xmc_cmd_s cn63xx;
+ struct cvmx_l2c_xmc_cmd_s cn63xxp1;
+};
+
+union cvmx_l2c_xmdx_pfc {
+ uint64_t u64;
+ struct cvmx_l2c_xmdx_pfc_s {
+ uint64_t count:64;
+ } s;
+ struct cvmx_l2c_xmdx_pfc_s cn63xx;
+ struct cvmx_l2c_xmdx_pfc_s cn63xxp1;
+};
+
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-l2c.h b/arch/mips/include/asm/octeon/cvmx-l2c.h
index 2a8c0902ea50..0b32c5b118e2 100644
--- a/arch/mips/include/asm/octeon/cvmx-l2c.h
+++ b/arch/mips/include/asm/octeon/cvmx-l2c.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
@@ -26,7 +26,6 @@
***********************license end**************************************/
/*
- *
* Interface to the Level 2 Cache (L2C) control, measurement, and debugging
* facilities.
*/
@@ -34,93 +33,126 @@
#ifndef __CVMX_L2C_H__
#define __CVMX_L2C_H__
-/* Deprecated macro, use function */
-#define CVMX_L2_ASSOC cvmx_l2c_get_num_assoc()
-
-/* Deprecated macro, use function */
-#define CVMX_L2_SET_BITS cvmx_l2c_get_set_bits()
+#define CVMX_L2_ASSOC cvmx_l2c_get_num_assoc() /* Deprecated macro, use function */
+#define CVMX_L2_SET_BITS cvmx_l2c_get_set_bits() /* Deprecated macro, use function */
+#define CVMX_L2_SETS cvmx_l2c_get_num_sets() /* Deprecated macro, use function */
-/* Deprecated macro, use function */
-#define CVMX_L2_SETS cvmx_l2c_get_num_sets()
#define CVMX_L2C_IDX_ADDR_SHIFT 7 /* based on 128 byte cache line size */
#define CVMX_L2C_IDX_MASK (cvmx_l2c_get_num_sets() - 1)
/* Defines for index aliasing computations */
-#define CVMX_L2C_TAG_ADDR_ALIAS_SHIFT \
- (CVMX_L2C_IDX_ADDR_SHIFT + cvmx_l2c_get_set_bits())
+#define CVMX_L2C_TAG_ADDR_ALIAS_SHIFT (CVMX_L2C_IDX_ADDR_SHIFT + cvmx_l2c_get_set_bits())
+#define CVMX_L2C_ALIAS_MASK (CVMX_L2C_IDX_MASK << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT)
+#define CVMX_L2C_MEMBANK_SELECT_SIZE 4096
-#define CVMX_L2C_ALIAS_MASK \
- (CVMX_L2C_IDX_MASK << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT)
+/* Defines for Virtualizations, valid only from Octeon II onwards. */
+#define CVMX_L2C_VRT_MAX_VIRTID_ALLOWED ((OCTEON_IS_MODEL(OCTEON_CN63XX)) ? 64 : 0)
+#define CVMX_L2C_VRT_MAX_MEMSZ_ALLOWED ((OCTEON_IS_MODEL(OCTEON_CN63XX)) ? 32 : 0)
union cvmx_l2c_tag {
uint64_t u64;
struct {
uint64_t reserved:28;
- uint64_t V:1; /* Line valid */
- uint64_t D:1; /* Line dirty */
- uint64_t L:1; /* Line locked */
- uint64_t U:1; /* Use, LRU eviction */
+ uint64_t V:1; /* Line valid */
+ uint64_t D:1; /* Line dirty */
+ uint64_t L:1; /* Line locked */
+ uint64_t U:1; /* Use, LRU eviction */
uint64_t addr:32; /* Phys mem (not all bits valid) */
} s;
};
+/* Number of L2C Tag-and-data sections (TADs) that are connected to LMC. */
+#define CVMX_L2C_TADS 1
+
/* L2C Performance Counter events. */
enum cvmx_l2c_event {
- CVMX_L2C_EVENT_CYCLES = 0,
- CVMX_L2C_EVENT_INSTRUCTION_MISS = 1,
- CVMX_L2C_EVENT_INSTRUCTION_HIT = 2,
- CVMX_L2C_EVENT_DATA_MISS = 3,
- CVMX_L2C_EVENT_DATA_HIT = 4,
- CVMX_L2C_EVENT_MISS = 5,
- CVMX_L2C_EVENT_HIT = 6,
- CVMX_L2C_EVENT_VICTIM_HIT = 7,
- CVMX_L2C_EVENT_INDEX_CONFLICT = 8,
- CVMX_L2C_EVENT_TAG_PROBE = 9,
- CVMX_L2C_EVENT_TAG_UPDATE = 10,
- CVMX_L2C_EVENT_TAG_COMPLETE = 11,
- CVMX_L2C_EVENT_TAG_DIRTY = 12,
- CVMX_L2C_EVENT_DATA_STORE_NOP = 13,
- CVMX_L2C_EVENT_DATA_STORE_READ = 14,
+ CVMX_L2C_EVENT_CYCLES = 0,
+ CVMX_L2C_EVENT_INSTRUCTION_MISS = 1,
+ CVMX_L2C_EVENT_INSTRUCTION_HIT = 2,
+ CVMX_L2C_EVENT_DATA_MISS = 3,
+ CVMX_L2C_EVENT_DATA_HIT = 4,
+ CVMX_L2C_EVENT_MISS = 5,
+ CVMX_L2C_EVENT_HIT = 6,
+ CVMX_L2C_EVENT_VICTIM_HIT = 7,
+ CVMX_L2C_EVENT_INDEX_CONFLICT = 8,
+ CVMX_L2C_EVENT_TAG_PROBE = 9,
+ CVMX_L2C_EVENT_TAG_UPDATE = 10,
+ CVMX_L2C_EVENT_TAG_COMPLETE = 11,
+ CVMX_L2C_EVENT_TAG_DIRTY = 12,
+ CVMX_L2C_EVENT_DATA_STORE_NOP = 13,
+ CVMX_L2C_EVENT_DATA_STORE_READ = 14,
CVMX_L2C_EVENT_DATA_STORE_WRITE = 15,
- CVMX_L2C_EVENT_FILL_DATA_VALID = 16,
- CVMX_L2C_EVENT_WRITE_REQUEST = 17,
- CVMX_L2C_EVENT_READ_REQUEST = 18,
+ CVMX_L2C_EVENT_FILL_DATA_VALID = 16,
+ CVMX_L2C_EVENT_WRITE_REQUEST = 17,
+ CVMX_L2C_EVENT_READ_REQUEST = 18,
CVMX_L2C_EVENT_WRITE_DATA_VALID = 19,
- CVMX_L2C_EVENT_XMC_NOP = 20,
- CVMX_L2C_EVENT_XMC_LDT = 21,
- CVMX_L2C_EVENT_XMC_LDI = 22,
- CVMX_L2C_EVENT_XMC_LDD = 23,
- CVMX_L2C_EVENT_XMC_STF = 24,
- CVMX_L2C_EVENT_XMC_STT = 25,
- CVMX_L2C_EVENT_XMC_STP = 26,
- CVMX_L2C_EVENT_XMC_STC = 27,
- CVMX_L2C_EVENT_XMC_DWB = 28,
- CVMX_L2C_EVENT_XMC_PL2 = 29,
- CVMX_L2C_EVENT_XMC_PSL1 = 30,
- CVMX_L2C_EVENT_XMC_IOBLD = 31,
- CVMX_L2C_EVENT_XMC_IOBST = 32,
- CVMX_L2C_EVENT_XMC_IOBDMA = 33,
- CVMX_L2C_EVENT_XMC_IOBRSP = 34,
- CVMX_L2C_EVENT_XMC_BUS_VALID = 35,
- CVMX_L2C_EVENT_XMC_MEM_DATA = 36,
- CVMX_L2C_EVENT_XMC_REFL_DATA = 37,
- CVMX_L2C_EVENT_XMC_IOBRSP_DATA = 38,
- CVMX_L2C_EVENT_RSC_NOP = 39,
- CVMX_L2C_EVENT_RSC_STDN = 40,
- CVMX_L2C_EVENT_RSC_FILL = 41,
- CVMX_L2C_EVENT_RSC_REFL = 42,
- CVMX_L2C_EVENT_RSC_STIN = 43,
- CVMX_L2C_EVENT_RSC_SCIN = 44,
- CVMX_L2C_EVENT_RSC_SCFL = 45,
- CVMX_L2C_EVENT_RSC_SCDN = 46,
- CVMX_L2C_EVENT_RSC_DATA_VALID = 47,
- CVMX_L2C_EVENT_RSC_VALID_FILL = 48,
- CVMX_L2C_EVENT_RSC_VALID_STRSP = 49,
- CVMX_L2C_EVENT_RSC_VALID_REFL = 50,
- CVMX_L2C_EVENT_LRF_REQ = 51,
- CVMX_L2C_EVENT_DT_RD_ALLOC = 52,
- CVMX_L2C_EVENT_DT_WR_INVAL = 53
+ CVMX_L2C_EVENT_XMC_NOP = 20,
+ CVMX_L2C_EVENT_XMC_LDT = 21,
+ CVMX_L2C_EVENT_XMC_LDI = 22,
+ CVMX_L2C_EVENT_XMC_LDD = 23,
+ CVMX_L2C_EVENT_XMC_STF = 24,
+ CVMX_L2C_EVENT_XMC_STT = 25,
+ CVMX_L2C_EVENT_XMC_STP = 26,
+ CVMX_L2C_EVENT_XMC_STC = 27,
+ CVMX_L2C_EVENT_XMC_DWB = 28,
+ CVMX_L2C_EVENT_XMC_PL2 = 29,
+ CVMX_L2C_EVENT_XMC_PSL1 = 30,
+ CVMX_L2C_EVENT_XMC_IOBLD = 31,
+ CVMX_L2C_EVENT_XMC_IOBST = 32,
+ CVMX_L2C_EVENT_XMC_IOBDMA = 33,
+ CVMX_L2C_EVENT_XMC_IOBRSP = 34,
+ CVMX_L2C_EVENT_XMC_BUS_VALID = 35,
+ CVMX_L2C_EVENT_XMC_MEM_DATA = 36,
+ CVMX_L2C_EVENT_XMC_REFL_DATA = 37,
+ CVMX_L2C_EVENT_XMC_IOBRSP_DATA = 38,
+ CVMX_L2C_EVENT_RSC_NOP = 39,
+ CVMX_L2C_EVENT_RSC_STDN = 40,
+ CVMX_L2C_EVENT_RSC_FILL = 41,
+ CVMX_L2C_EVENT_RSC_REFL = 42,
+ CVMX_L2C_EVENT_RSC_STIN = 43,
+ CVMX_L2C_EVENT_RSC_SCIN = 44,
+ CVMX_L2C_EVENT_RSC_SCFL = 45,
+ CVMX_L2C_EVENT_RSC_SCDN = 46,
+ CVMX_L2C_EVENT_RSC_DATA_VALID = 47,
+ CVMX_L2C_EVENT_RSC_VALID_FILL = 48,
+ CVMX_L2C_EVENT_RSC_VALID_STRSP = 49,
+ CVMX_L2C_EVENT_RSC_VALID_REFL = 50,
+ CVMX_L2C_EVENT_LRF_REQ = 51,
+ CVMX_L2C_EVENT_DT_RD_ALLOC = 52,
+ CVMX_L2C_EVENT_DT_WR_INVAL = 53,
+ CVMX_L2C_EVENT_MAX
+};
+
+/* L2C Performance Counter events for Octeon2. */
+enum cvmx_l2c_tad_event {
+ CVMX_L2C_TAD_EVENT_NONE = 0,
+ CVMX_L2C_TAD_EVENT_TAG_HIT = 1,
+ CVMX_L2C_TAD_EVENT_TAG_MISS = 2,
+ CVMX_L2C_TAD_EVENT_TAG_NOALLOC = 3,
+ CVMX_L2C_TAD_EVENT_TAG_VICTIM = 4,
+ CVMX_L2C_TAD_EVENT_SC_FAIL = 5,
+ CVMX_L2C_TAD_EVENT_SC_PASS = 6,
+ CVMX_L2C_TAD_EVENT_LFB_VALID = 7,
+ CVMX_L2C_TAD_EVENT_LFB_WAIT_LFB = 8,
+ CVMX_L2C_TAD_EVENT_LFB_WAIT_VAB = 9,
+ CVMX_L2C_TAD_EVENT_QUAD0_INDEX = 128,
+ CVMX_L2C_TAD_EVENT_QUAD0_READ = 129,
+ CVMX_L2C_TAD_EVENT_QUAD0_BANK = 130,
+ CVMX_L2C_TAD_EVENT_QUAD0_WDAT = 131,
+ CVMX_L2C_TAD_EVENT_QUAD1_INDEX = 144,
+ CVMX_L2C_TAD_EVENT_QUAD1_READ = 145,
+ CVMX_L2C_TAD_EVENT_QUAD1_BANK = 146,
+ CVMX_L2C_TAD_EVENT_QUAD1_WDAT = 147,
+ CVMX_L2C_TAD_EVENT_QUAD2_INDEX = 160,
+ CVMX_L2C_TAD_EVENT_QUAD2_READ = 161,
+ CVMX_L2C_TAD_EVENT_QUAD2_BANK = 162,
+ CVMX_L2C_TAD_EVENT_QUAD2_WDAT = 163,
+ CVMX_L2C_TAD_EVENT_QUAD3_INDEX = 176,
+ CVMX_L2C_TAD_EVENT_QUAD3_READ = 177,
+ CVMX_L2C_TAD_EVENT_QUAD3_BANK = 178,
+ CVMX_L2C_TAD_EVENT_QUAD3_WDAT = 179,
+ CVMX_L2C_TAD_EVENT_MAX
};
/**
@@ -132,10 +164,10 @@ enum cvmx_l2c_event {
* @clear_on_read: When asserted, any read of the performance counter
* clears the counter.
*
- * The routine does not clear the counter.
+ * @note The routine does not clear the counter.
*/
-void cvmx_l2c_config_perf(uint32_t counter,
- enum cvmx_l2c_event event, uint32_t clear_on_read);
+void cvmx_l2c_config_perf(uint32_t counter, enum cvmx_l2c_event event, uint32_t clear_on_read);
+
/**
* Read the given L2 Cache performance counter. The counter must be configured
* before reading, but this routine does not enforce this requirement.
@@ -160,18 +192,18 @@ int cvmx_l2c_get_core_way_partition(uint32_t core);
/**
* Partitions the L2 cache for a core
*
- * @core: The core that the partitioning applies to.
+ * @core: The core that the partitioning applies to.
+ * @mask: The partitioning of the ways expressed as a binary
+ * mask. A 0 bit allows the core to evict cache lines from
+ * a way, while a 1 bit blocks the core from evicting any
+ * lines from that way. There must be at least one allowed
+ * way (0 bit) in the mask.
*
- * @mask: The partitioning of the ways expressed as a binary mask. A 0
- * bit allows the core to evict cache lines from a way, while a
- * 1 bit blocks the core from evicting any lines from that
- * way. There must be at least one allowed way (0 bit) in the
- * mask.
- *
- * If any ways are blocked for all cores and the HW blocks, then those
- * ways will never have any cache lines evicted from them. All cores
- * and the hardware blocks are free to read from all ways regardless
- * of the partitioning.
+
+ * @note If any ways are blocked for all cores and the HW blocks, then
+ * those ways will never have any cache lines evicted from them.
+ * All cores and the hardware blocks are free to read from all
+ * ways regardless of the partitioning.
*/
int cvmx_l2c_set_core_way_partition(uint32_t core, uint32_t mask);
@@ -187,19 +219,21 @@ int cvmx_l2c_get_hw_way_partition(void);
/**
* Partitions the L2 cache for the hardware blocks.
*
- * @mask: The partitioning of the ways expressed as a binary mask. A 0
- * bit allows the core to evict cache lines from a way, while a
- * 1 bit blocks the core from evicting any lines from that
- * way. There must be at least one allowed way (0 bit) in the
- * mask.
+ * @mask: The partitioning of the ways expressed as a binary
+ * mask. A 0 bit allows the core to evict cache lines from
+ * a way, while a 1 bit blocks the core from evicting any
+ * lines from that way. There must be at least one allowed
+ * way (0 bit) in the mask.
*
- * If any ways are blocked for all cores and the HW blocks, then those
- * ways will never have any cache lines evicted from them. All cores
- * and the hardware blocks are free to read from all ways regardless
- * of the partitioning.
+
+ * @note If any ways are blocked for all cores and the HW blocks, then
+ * those ways will never have any cache lines evicted from them.
+ * All cores and the hardware blocks are free to read from all
+ * ways regardless of the partitioning.
*/
int cvmx_l2c_set_hw_way_partition(uint32_t mask);
+
/**
* Locks a line in the L2 cache at the specified physical address
*
@@ -263,13 +297,14 @@ int cvmx_l2c_unlock_mem_region(uint64_t start, uint64_t len);
*/
union cvmx_l2c_tag cvmx_l2c_get_tag(uint32_t association, uint32_t index);
-/* Wrapper around deprecated old function name */
-static inline union cvmx_l2c_tag cvmx_get_l2c_tag(uint32_t association,
- uint32_t index)
+/* Wrapper providing a deprecated old function name */
+static inline union cvmx_l2c_tag cvmx_get_l2c_tag(uint32_t association, uint32_t index) __attribute__((deprecated));
+static inline union cvmx_l2c_tag cvmx_get_l2c_tag(uint32_t association, uint32_t index)
{
return cvmx_l2c_get_tag(association, index);
}
+
/**
* Returns the cache index for a given physical address
*
diff --git a/arch/mips/include/asm/octeon/cvmx-l2d-defs.h b/arch/mips/include/asm/octeon/cvmx-l2d-defs.h
index d7102d455e1b..60543e0e77fc 100644
--- a/arch/mips/include/asm/octeon/cvmx-l2d-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-l2d-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
@@ -28,30 +28,18 @@
#ifndef __CVMX_L2D_DEFS_H__
#define __CVMX_L2D_DEFS_H__
-#define CVMX_L2D_BST0 \
- CVMX_ADD_IO_SEG(0x0001180080000780ull)
-#define CVMX_L2D_BST1 \
- CVMX_ADD_IO_SEG(0x0001180080000788ull)
-#define CVMX_L2D_BST2 \
- CVMX_ADD_IO_SEG(0x0001180080000790ull)
-#define CVMX_L2D_BST3 \
- CVMX_ADD_IO_SEG(0x0001180080000798ull)
-#define CVMX_L2D_ERR \
- CVMX_ADD_IO_SEG(0x0001180080000010ull)
-#define CVMX_L2D_FADR \
- CVMX_ADD_IO_SEG(0x0001180080000018ull)
-#define CVMX_L2D_FSYN0 \
- CVMX_ADD_IO_SEG(0x0001180080000020ull)
-#define CVMX_L2D_FSYN1 \
- CVMX_ADD_IO_SEG(0x0001180080000028ull)
-#define CVMX_L2D_FUS0 \
- CVMX_ADD_IO_SEG(0x00011800800007A0ull)
-#define CVMX_L2D_FUS1 \
- CVMX_ADD_IO_SEG(0x00011800800007A8ull)
-#define CVMX_L2D_FUS2 \
- CVMX_ADD_IO_SEG(0x00011800800007B0ull)
-#define CVMX_L2D_FUS3 \
- CVMX_ADD_IO_SEG(0x00011800800007B8ull)
+#define CVMX_L2D_BST0 (CVMX_ADD_IO_SEG(0x0001180080000780ull))
+#define CVMX_L2D_BST1 (CVMX_ADD_IO_SEG(0x0001180080000788ull))
+#define CVMX_L2D_BST2 (CVMX_ADD_IO_SEG(0x0001180080000790ull))
+#define CVMX_L2D_BST3 (CVMX_ADD_IO_SEG(0x0001180080000798ull))
+#define CVMX_L2D_ERR (CVMX_ADD_IO_SEG(0x0001180080000010ull))
+#define CVMX_L2D_FADR (CVMX_ADD_IO_SEG(0x0001180080000018ull))
+#define CVMX_L2D_FSYN0 (CVMX_ADD_IO_SEG(0x0001180080000020ull))
+#define CVMX_L2D_FSYN1 (CVMX_ADD_IO_SEG(0x0001180080000028ull))
+#define CVMX_L2D_FUS0 (CVMX_ADD_IO_SEG(0x00011800800007A0ull))
+#define CVMX_L2D_FUS1 (CVMX_ADD_IO_SEG(0x00011800800007A8ull))
+#define CVMX_L2D_FUS2 (CVMX_ADD_IO_SEG(0x00011800800007B0ull))
+#define CVMX_L2D_FUS3 (CVMX_ADD_IO_SEG(0x00011800800007B8ull))
union cvmx_l2d_bst0 {
uint64_t u64;
diff --git a/arch/mips/include/asm/octeon/cvmx-l2t-defs.h b/arch/mips/include/asm/octeon/cvmx-l2t-defs.h
index 2639a3f5ffc2..873968f55eeb 100644
--- a/arch/mips/include/asm/octeon/cvmx-l2t-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-l2t-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
@@ -28,8 +28,7 @@
#ifndef __CVMX_L2T_DEFS_H__
#define __CVMX_L2T_DEFS_H__
-#define CVMX_L2T_ERR \
- CVMX_ADD_IO_SEG(0x0001180080000008ull)
+#define CVMX_L2T_ERR (CVMX_ADD_IO_SEG(0x0001180080000008ull))
union cvmx_l2t_err {
uint64_t u64;
diff --git a/arch/mips/include/asm/octeon/cvmx-led-defs.h b/arch/mips/include/asm/octeon/cvmx-led-defs.h
index 16f174a4dadf..e25173bb8bb7 100644
--- a/arch/mips/include/asm/octeon/cvmx-led-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-led-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
@@ -28,32 +28,19 @@
#ifndef __CVMX_LED_DEFS_H__
#define __CVMX_LED_DEFS_H__
-#define CVMX_LED_BLINK \
- CVMX_ADD_IO_SEG(0x0001180000001A48ull)
-#define CVMX_LED_CLK_PHASE \
- CVMX_ADD_IO_SEG(0x0001180000001A08ull)
-#define CVMX_LED_CYLON \
- CVMX_ADD_IO_SEG(0x0001180000001AF8ull)
-#define CVMX_LED_DBG \
- CVMX_ADD_IO_SEG(0x0001180000001A18ull)
-#define CVMX_LED_EN \
- CVMX_ADD_IO_SEG(0x0001180000001A00ull)
-#define CVMX_LED_POLARITY \
- CVMX_ADD_IO_SEG(0x0001180000001A50ull)
-#define CVMX_LED_PRT \
- CVMX_ADD_IO_SEG(0x0001180000001A10ull)
-#define CVMX_LED_PRT_FMT \
- CVMX_ADD_IO_SEG(0x0001180000001A30ull)
-#define CVMX_LED_PRT_STATUSX(offset) \
- CVMX_ADD_IO_SEG(0x0001180000001A80ull + (((offset) & 7) * 8))
-#define CVMX_LED_UDD_CNTX(offset) \
- CVMX_ADD_IO_SEG(0x0001180000001A20ull + (((offset) & 1) * 8))
-#define CVMX_LED_UDD_DATX(offset) \
- CVMX_ADD_IO_SEG(0x0001180000001A38ull + (((offset) & 1) * 8))
-#define CVMX_LED_UDD_DAT_CLRX(offset) \
- CVMX_ADD_IO_SEG(0x0001180000001AC8ull + (((offset) & 1) * 16))
-#define CVMX_LED_UDD_DAT_SETX(offset) \
- CVMX_ADD_IO_SEG(0x0001180000001AC0ull + (((offset) & 1) * 16))
+#define CVMX_LED_BLINK (CVMX_ADD_IO_SEG(0x0001180000001A48ull))
+#define CVMX_LED_CLK_PHASE (CVMX_ADD_IO_SEG(0x0001180000001A08ull))
+#define CVMX_LED_CYLON (CVMX_ADD_IO_SEG(0x0001180000001AF8ull))
+#define CVMX_LED_DBG (CVMX_ADD_IO_SEG(0x0001180000001A18ull))
+#define CVMX_LED_EN (CVMX_ADD_IO_SEG(0x0001180000001A00ull))
+#define CVMX_LED_POLARITY (CVMX_ADD_IO_SEG(0x0001180000001A50ull))
+#define CVMX_LED_PRT (CVMX_ADD_IO_SEG(0x0001180000001A10ull))
+#define CVMX_LED_PRT_FMT (CVMX_ADD_IO_SEG(0x0001180000001A30ull))
+#define CVMX_LED_PRT_STATUSX(offset) (CVMX_ADD_IO_SEG(0x0001180000001A80ull) + ((offset) & 7) * 8)
+#define CVMX_LED_UDD_CNTX(offset) (CVMX_ADD_IO_SEG(0x0001180000001A20ull) + ((offset) & 1) * 8)
+#define CVMX_LED_UDD_DATX(offset) (CVMX_ADD_IO_SEG(0x0001180000001A38ull) + ((offset) & 1) * 8)
+#define CVMX_LED_UDD_DAT_CLRX(offset) (CVMX_ADD_IO_SEG(0x0001180000001AC8ull) + ((offset) & 1) * 16)
+#define CVMX_LED_UDD_DAT_SETX(offset) (CVMX_ADD_IO_SEG(0x0001180000001AC0ull) + ((offset) & 1) * 16)
union cvmx_led_blink {
uint64_t u64;
diff --git a/arch/mips/include/asm/octeon/cvmx-mio-defs.h b/arch/mips/include/asm/octeon/cvmx-mio-defs.h
index 6555f0530988..52b14a333ad4 100644
--- a/arch/mips/include/asm/octeon/cvmx-mio-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-mio-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
@@ -28,191 +28,117 @@
#ifndef __CVMX_MIO_DEFS_H__
#define __CVMX_MIO_DEFS_H__
-#define CVMX_MIO_BOOT_BIST_STAT \
- CVMX_ADD_IO_SEG(0x00011800000000F8ull)
-#define CVMX_MIO_BOOT_COMP \
- CVMX_ADD_IO_SEG(0x00011800000000B8ull)
-#define CVMX_MIO_BOOT_DMA_CFGX(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000100ull + (((offset) & 3) * 8))
-#define CVMX_MIO_BOOT_DMA_INTX(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000138ull + (((offset) & 3) * 8))
-#define CVMX_MIO_BOOT_DMA_INT_ENX(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000150ull + (((offset) & 3) * 8))
-#define CVMX_MIO_BOOT_DMA_TIMX(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000120ull + (((offset) & 3) * 8))
-#define CVMX_MIO_BOOT_ERR \
- CVMX_ADD_IO_SEG(0x00011800000000A0ull)
-#define CVMX_MIO_BOOT_INT \
- CVMX_ADD_IO_SEG(0x00011800000000A8ull)
-#define CVMX_MIO_BOOT_LOC_ADR \
- CVMX_ADD_IO_SEG(0x0001180000000090ull)
-#define CVMX_MIO_BOOT_LOC_CFGX(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000080ull + (((offset) & 1) * 8))
-#define CVMX_MIO_BOOT_LOC_DAT \
- CVMX_ADD_IO_SEG(0x0001180000000098ull)
-#define CVMX_MIO_BOOT_PIN_DEFS \
- CVMX_ADD_IO_SEG(0x00011800000000C0ull)
-#define CVMX_MIO_BOOT_REG_CFGX(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000000ull + (((offset) & 7) * 8))
-#define CVMX_MIO_BOOT_REG_TIMX(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000040ull + (((offset) & 7) * 8))
-#define CVMX_MIO_BOOT_THR \
- CVMX_ADD_IO_SEG(0x00011800000000B0ull)
-#define CVMX_MIO_FUS_BNK_DATX(offset) \
- CVMX_ADD_IO_SEG(0x0001180000001520ull + (((offset) & 3) * 8))
-#define CVMX_MIO_FUS_DAT0 \
- CVMX_ADD_IO_SEG(0x0001180000001400ull)
-#define CVMX_MIO_FUS_DAT1 \
- CVMX_ADD_IO_SEG(0x0001180000001408ull)
-#define CVMX_MIO_FUS_DAT2 \
- CVMX_ADD_IO_SEG(0x0001180000001410ull)
-#define CVMX_MIO_FUS_DAT3 \
- CVMX_ADD_IO_SEG(0x0001180000001418ull)
-#define CVMX_MIO_FUS_EMA \
- CVMX_ADD_IO_SEG(0x0001180000001550ull)
-#define CVMX_MIO_FUS_PDF \
- CVMX_ADD_IO_SEG(0x0001180000001420ull)
-#define CVMX_MIO_FUS_PLL \
- CVMX_ADD_IO_SEG(0x0001180000001580ull)
-#define CVMX_MIO_FUS_PROG \
- CVMX_ADD_IO_SEG(0x0001180000001510ull)
-#define CVMX_MIO_FUS_PROG_TIMES \
- CVMX_ADD_IO_SEG(0x0001180000001518ull)
-#define CVMX_MIO_FUS_RCMD \
- CVMX_ADD_IO_SEG(0x0001180000001500ull)
-#define CVMX_MIO_FUS_SPR_REPAIR_RES \
- CVMX_ADD_IO_SEG(0x0001180000001548ull)
-#define CVMX_MIO_FUS_SPR_REPAIR_SUM \
- CVMX_ADD_IO_SEG(0x0001180000001540ull)
-#define CVMX_MIO_FUS_UNLOCK \
- CVMX_ADD_IO_SEG(0x0001180000001578ull)
-#define CVMX_MIO_FUS_WADR \
- CVMX_ADD_IO_SEG(0x0001180000001508ull)
-#define CVMX_MIO_NDF_DMA_CFG \
- CVMX_ADD_IO_SEG(0x0001180000000168ull)
-#define CVMX_MIO_NDF_DMA_INT \
- CVMX_ADD_IO_SEG(0x0001180000000170ull)
-#define CVMX_MIO_NDF_DMA_INT_EN \
- CVMX_ADD_IO_SEG(0x0001180000000178ull)
-#define CVMX_MIO_PLL_CTL \
- CVMX_ADD_IO_SEG(0x0001180000001448ull)
-#define CVMX_MIO_PLL_SETTING \
- CVMX_ADD_IO_SEG(0x0001180000001440ull)
-#define CVMX_MIO_TWSX_INT(offset) \
- CVMX_ADD_IO_SEG(0x0001180000001010ull + (((offset) & 1) * 512))
-#define CVMX_MIO_TWSX_SW_TWSI(offset) \
- CVMX_ADD_IO_SEG(0x0001180000001000ull + (((offset) & 1) * 512))
-#define CVMX_MIO_TWSX_SW_TWSI_EXT(offset) \
- CVMX_ADD_IO_SEG(0x0001180000001018ull + (((offset) & 1) * 512))
-#define CVMX_MIO_TWSX_TWSI_SW(offset) \
- CVMX_ADD_IO_SEG(0x0001180000001008ull + (((offset) & 1) * 512))
-#define CVMX_MIO_UART2_DLH \
- CVMX_ADD_IO_SEG(0x0001180000000488ull)
-#define CVMX_MIO_UART2_DLL \
- CVMX_ADD_IO_SEG(0x0001180000000480ull)
-#define CVMX_MIO_UART2_FAR \
- CVMX_ADD_IO_SEG(0x0001180000000520ull)
-#define CVMX_MIO_UART2_FCR \
- CVMX_ADD_IO_SEG(0x0001180000000450ull)
-#define CVMX_MIO_UART2_HTX \
- CVMX_ADD_IO_SEG(0x0001180000000708ull)
-#define CVMX_MIO_UART2_IER \
- CVMX_ADD_IO_SEG(0x0001180000000408ull)
-#define CVMX_MIO_UART2_IIR \
- CVMX_ADD_IO_SEG(0x0001180000000410ull)
-#define CVMX_MIO_UART2_LCR \
- CVMX_ADD_IO_SEG(0x0001180000000418ull)
-#define CVMX_MIO_UART2_LSR \
- CVMX_ADD_IO_SEG(0x0001180000000428ull)
-#define CVMX_MIO_UART2_MCR \
- CVMX_ADD_IO_SEG(0x0001180000000420ull)
-#define CVMX_MIO_UART2_MSR \
- CVMX_ADD_IO_SEG(0x0001180000000430ull)
-#define CVMX_MIO_UART2_RBR \
- CVMX_ADD_IO_SEG(0x0001180000000400ull)
-#define CVMX_MIO_UART2_RFL \
- CVMX_ADD_IO_SEG(0x0001180000000608ull)
-#define CVMX_MIO_UART2_RFW \
- CVMX_ADD_IO_SEG(0x0001180000000530ull)
-#define CVMX_MIO_UART2_SBCR \
- CVMX_ADD_IO_SEG(0x0001180000000620ull)
-#define CVMX_MIO_UART2_SCR \
- CVMX_ADD_IO_SEG(0x0001180000000438ull)
-#define CVMX_MIO_UART2_SFE \
- CVMX_ADD_IO_SEG(0x0001180000000630ull)
-#define CVMX_MIO_UART2_SRR \
- CVMX_ADD_IO_SEG(0x0001180000000610ull)
-#define CVMX_MIO_UART2_SRT \
- CVMX_ADD_IO_SEG(0x0001180000000638ull)
-#define CVMX_MIO_UART2_SRTS \
- CVMX_ADD_IO_SEG(0x0001180000000618ull)
-#define CVMX_MIO_UART2_STT \
- CVMX_ADD_IO_SEG(0x0001180000000700ull)
-#define CVMX_MIO_UART2_TFL \
- CVMX_ADD_IO_SEG(0x0001180000000600ull)
-#define CVMX_MIO_UART2_TFR \
- CVMX_ADD_IO_SEG(0x0001180000000528ull)
-#define CVMX_MIO_UART2_THR \
- CVMX_ADD_IO_SEG(0x0001180000000440ull)
-#define CVMX_MIO_UART2_USR \
- CVMX_ADD_IO_SEG(0x0001180000000538ull)
-#define CVMX_MIO_UARTX_DLH(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000888ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_DLL(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000880ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_FAR(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000920ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_FCR(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000850ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_HTX(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000B08ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_IER(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000808ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_IIR(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000810ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_LCR(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000818ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_LSR(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000828ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_MCR(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000820ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_MSR(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000830ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_RBR(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000800ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_RFL(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000A08ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_RFW(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000930ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_SBCR(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000A20ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_SCR(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000838ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_SFE(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000A30ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_SRR(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000A10ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_SRT(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000A38ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_SRTS(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000A18ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_STT(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000B00ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_TFL(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000A00ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_TFR(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000928ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_THR(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000840ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_USR(offset) \
- CVMX_ADD_IO_SEG(0x0001180000000938ull + (((offset) & 1) * 1024))
+#define CVMX_MIO_BOOT_BIST_STAT (CVMX_ADD_IO_SEG(0x00011800000000F8ull))
+#define CVMX_MIO_BOOT_COMP (CVMX_ADD_IO_SEG(0x00011800000000B8ull))
+#define CVMX_MIO_BOOT_DMA_CFGX(offset) (CVMX_ADD_IO_SEG(0x0001180000000100ull) + ((offset) & 3) * 8)
+#define CVMX_MIO_BOOT_DMA_INTX(offset) (CVMX_ADD_IO_SEG(0x0001180000000138ull) + ((offset) & 3) * 8)
+#define CVMX_MIO_BOOT_DMA_INT_ENX(offset) (CVMX_ADD_IO_SEG(0x0001180000000150ull) + ((offset) & 3) * 8)
+#define CVMX_MIO_BOOT_DMA_TIMX(offset) (CVMX_ADD_IO_SEG(0x0001180000000120ull) + ((offset) & 3) * 8)
+#define CVMX_MIO_BOOT_ERR (CVMX_ADD_IO_SEG(0x00011800000000A0ull))
+#define CVMX_MIO_BOOT_INT (CVMX_ADD_IO_SEG(0x00011800000000A8ull))
+#define CVMX_MIO_BOOT_LOC_ADR (CVMX_ADD_IO_SEG(0x0001180000000090ull))
+#define CVMX_MIO_BOOT_LOC_CFGX(offset) (CVMX_ADD_IO_SEG(0x0001180000000080ull) + ((offset) & 1) * 8)
+#define CVMX_MIO_BOOT_LOC_DAT (CVMX_ADD_IO_SEG(0x0001180000000098ull))
+#define CVMX_MIO_BOOT_PIN_DEFS (CVMX_ADD_IO_SEG(0x00011800000000C0ull))
+#define CVMX_MIO_BOOT_REG_CFGX(offset) (CVMX_ADD_IO_SEG(0x0001180000000000ull) + ((offset) & 7) * 8)
+#define CVMX_MIO_BOOT_REG_TIMX(offset) (CVMX_ADD_IO_SEG(0x0001180000000040ull) + ((offset) & 7) * 8)
+#define CVMX_MIO_BOOT_THR (CVMX_ADD_IO_SEG(0x00011800000000B0ull))
+#define CVMX_MIO_FUS_BNK_DATX(offset) (CVMX_ADD_IO_SEG(0x0001180000001520ull) + ((offset) & 3) * 8)
+#define CVMX_MIO_FUS_DAT0 (CVMX_ADD_IO_SEG(0x0001180000001400ull))
+#define CVMX_MIO_FUS_DAT1 (CVMX_ADD_IO_SEG(0x0001180000001408ull))
+#define CVMX_MIO_FUS_DAT2 (CVMX_ADD_IO_SEG(0x0001180000001410ull))
+#define CVMX_MIO_FUS_DAT3 (CVMX_ADD_IO_SEG(0x0001180000001418ull))
+#define CVMX_MIO_FUS_EMA (CVMX_ADD_IO_SEG(0x0001180000001550ull))
+#define CVMX_MIO_FUS_PDF (CVMX_ADD_IO_SEG(0x0001180000001420ull))
+#define CVMX_MIO_FUS_PLL (CVMX_ADD_IO_SEG(0x0001180000001580ull))
+#define CVMX_MIO_FUS_PROG (CVMX_ADD_IO_SEG(0x0001180000001510ull))
+#define CVMX_MIO_FUS_PROG_TIMES (CVMX_ADD_IO_SEG(0x0001180000001518ull))
+#define CVMX_MIO_FUS_RCMD (CVMX_ADD_IO_SEG(0x0001180000001500ull))
+#define CVMX_MIO_FUS_READ_TIMES (CVMX_ADD_IO_SEG(0x0001180000001570ull))
+#define CVMX_MIO_FUS_REPAIR_RES0 (CVMX_ADD_IO_SEG(0x0001180000001558ull))
+#define CVMX_MIO_FUS_REPAIR_RES1 (CVMX_ADD_IO_SEG(0x0001180000001560ull))
+#define CVMX_MIO_FUS_REPAIR_RES2 (CVMX_ADD_IO_SEG(0x0001180000001568ull))
+#define CVMX_MIO_FUS_SPR_REPAIR_RES (CVMX_ADD_IO_SEG(0x0001180000001548ull))
+#define CVMX_MIO_FUS_SPR_REPAIR_SUM (CVMX_ADD_IO_SEG(0x0001180000001540ull))
+#define CVMX_MIO_FUS_UNLOCK (CVMX_ADD_IO_SEG(0x0001180000001578ull))
+#define CVMX_MIO_FUS_WADR (CVMX_ADD_IO_SEG(0x0001180000001508ull))
+#define CVMX_MIO_GPIO_COMP (CVMX_ADD_IO_SEG(0x00011800000000C8ull))
+#define CVMX_MIO_NDF_DMA_CFG (CVMX_ADD_IO_SEG(0x0001180000000168ull))
+#define CVMX_MIO_NDF_DMA_INT (CVMX_ADD_IO_SEG(0x0001180000000170ull))
+#define CVMX_MIO_NDF_DMA_INT_EN (CVMX_ADD_IO_SEG(0x0001180000000178ull))
+#define CVMX_MIO_PLL_CTL (CVMX_ADD_IO_SEG(0x0001180000001448ull))
+#define CVMX_MIO_PLL_SETTING (CVMX_ADD_IO_SEG(0x0001180000001440ull))
+#define CVMX_MIO_PTP_CLOCK_CFG (CVMX_ADD_IO_SEG(0x0001070000000F00ull))
+#define CVMX_MIO_PTP_CLOCK_COMP (CVMX_ADD_IO_SEG(0x0001070000000F18ull))
+#define CVMX_MIO_PTP_CLOCK_HI (CVMX_ADD_IO_SEG(0x0001070000000F10ull))
+#define CVMX_MIO_PTP_CLOCK_LO (CVMX_ADD_IO_SEG(0x0001070000000F08ull))
+#define CVMX_MIO_PTP_EVT_CNT (CVMX_ADD_IO_SEG(0x0001070000000F28ull))
+#define CVMX_MIO_PTP_TIMESTAMP (CVMX_ADD_IO_SEG(0x0001070000000F20ull))
+#define CVMX_MIO_RST_BOOT (CVMX_ADD_IO_SEG(0x0001180000001600ull))
+#define CVMX_MIO_RST_CFG (CVMX_ADD_IO_SEG(0x0001180000001610ull))
+#define CVMX_MIO_RST_CTLX(offset) (CVMX_ADD_IO_SEG(0x0001180000001618ull) + ((offset) & 1) * 8)
+#define CVMX_MIO_RST_DELAY (CVMX_ADD_IO_SEG(0x0001180000001608ull))
+#define CVMX_MIO_RST_INT (CVMX_ADD_IO_SEG(0x0001180000001628ull))
+#define CVMX_MIO_RST_INT_EN (CVMX_ADD_IO_SEG(0x0001180000001630ull))
+#define CVMX_MIO_TWSX_INT(offset) (CVMX_ADD_IO_SEG(0x0001180000001010ull) + ((offset) & 1) * 512)
+#define CVMX_MIO_TWSX_SW_TWSI(offset) (CVMX_ADD_IO_SEG(0x0001180000001000ull) + ((offset) & 1) * 512)
+#define CVMX_MIO_TWSX_SW_TWSI_EXT(offset) (CVMX_ADD_IO_SEG(0x0001180000001018ull) + ((offset) & 1) * 512)
+#define CVMX_MIO_TWSX_TWSI_SW(offset) (CVMX_ADD_IO_SEG(0x0001180000001008ull) + ((offset) & 1) * 512)
+#define CVMX_MIO_UART2_DLH (CVMX_ADD_IO_SEG(0x0001180000000488ull))
+#define CVMX_MIO_UART2_DLL (CVMX_ADD_IO_SEG(0x0001180000000480ull))
+#define CVMX_MIO_UART2_FAR (CVMX_ADD_IO_SEG(0x0001180000000520ull))
+#define CVMX_MIO_UART2_FCR (CVMX_ADD_IO_SEG(0x0001180000000450ull))
+#define CVMX_MIO_UART2_HTX (CVMX_ADD_IO_SEG(0x0001180000000708ull))
+#define CVMX_MIO_UART2_IER (CVMX_ADD_IO_SEG(0x0001180000000408ull))
+#define CVMX_MIO_UART2_IIR (CVMX_ADD_IO_SEG(0x0001180000000410ull))
+#define CVMX_MIO_UART2_LCR (CVMX_ADD_IO_SEG(0x0001180000000418ull))
+#define CVMX_MIO_UART2_LSR (CVMX_ADD_IO_SEG(0x0001180000000428ull))
+#define CVMX_MIO_UART2_MCR (CVMX_ADD_IO_SEG(0x0001180000000420ull))
+#define CVMX_MIO_UART2_MSR (CVMX_ADD_IO_SEG(0x0001180000000430ull))
+#define CVMX_MIO_UART2_RBR (CVMX_ADD_IO_SEG(0x0001180000000400ull))
+#define CVMX_MIO_UART2_RFL (CVMX_ADD_IO_SEG(0x0001180000000608ull))
+#define CVMX_MIO_UART2_RFW (CVMX_ADD_IO_SEG(0x0001180000000530ull))
+#define CVMX_MIO_UART2_SBCR (CVMX_ADD_IO_SEG(0x0001180000000620ull))
+#define CVMX_MIO_UART2_SCR (CVMX_ADD_IO_SEG(0x0001180000000438ull))
+#define CVMX_MIO_UART2_SFE (CVMX_ADD_IO_SEG(0x0001180000000630ull))
+#define CVMX_MIO_UART2_SRR (CVMX_ADD_IO_SEG(0x0001180000000610ull))
+#define CVMX_MIO_UART2_SRT (CVMX_ADD_IO_SEG(0x0001180000000638ull))
+#define CVMX_MIO_UART2_SRTS (CVMX_ADD_IO_SEG(0x0001180000000618ull))
+#define CVMX_MIO_UART2_STT (CVMX_ADD_IO_SEG(0x0001180000000700ull))
+#define CVMX_MIO_UART2_TFL (CVMX_ADD_IO_SEG(0x0001180000000600ull))
+#define CVMX_MIO_UART2_TFR (CVMX_ADD_IO_SEG(0x0001180000000528ull))
+#define CVMX_MIO_UART2_THR (CVMX_ADD_IO_SEG(0x0001180000000440ull))
+#define CVMX_MIO_UART2_USR (CVMX_ADD_IO_SEG(0x0001180000000538ull))
+#define CVMX_MIO_UARTX_DLH(offset) (CVMX_ADD_IO_SEG(0x0001180000000888ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_DLL(offset) (CVMX_ADD_IO_SEG(0x0001180000000880ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_FAR(offset) (CVMX_ADD_IO_SEG(0x0001180000000920ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_FCR(offset) (CVMX_ADD_IO_SEG(0x0001180000000850ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_HTX(offset) (CVMX_ADD_IO_SEG(0x0001180000000B08ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_IER(offset) (CVMX_ADD_IO_SEG(0x0001180000000808ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_IIR(offset) (CVMX_ADD_IO_SEG(0x0001180000000810ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_LCR(offset) (CVMX_ADD_IO_SEG(0x0001180000000818ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_LSR(offset) (CVMX_ADD_IO_SEG(0x0001180000000828ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_MCR(offset) (CVMX_ADD_IO_SEG(0x0001180000000820ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_MSR(offset) (CVMX_ADD_IO_SEG(0x0001180000000830ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_RBR(offset) (CVMX_ADD_IO_SEG(0x0001180000000800ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_RFL(offset) (CVMX_ADD_IO_SEG(0x0001180000000A08ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_RFW(offset) (CVMX_ADD_IO_SEG(0x0001180000000930ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_SBCR(offset) (CVMX_ADD_IO_SEG(0x0001180000000A20ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_SCR(offset) (CVMX_ADD_IO_SEG(0x0001180000000838ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_SFE(offset) (CVMX_ADD_IO_SEG(0x0001180000000A30ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_SRR(offset) (CVMX_ADD_IO_SEG(0x0001180000000A10ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_SRT(offset) (CVMX_ADD_IO_SEG(0x0001180000000A38ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_SRTS(offset) (CVMX_ADD_IO_SEG(0x0001180000000A18ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_STT(offset) (CVMX_ADD_IO_SEG(0x0001180000000B00ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_TFL(offset) (CVMX_ADD_IO_SEG(0x0001180000000A00ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_TFR(offset) (CVMX_ADD_IO_SEG(0x0001180000000928ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_THR(offset) (CVMX_ADD_IO_SEG(0x0001180000000840ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_USR(offset) (CVMX_ADD_IO_SEG(0x0001180000000938ull) + ((offset) & 1) * 1024)
union cvmx_mio_boot_bist_stat {
uint64_t u64;
struct cvmx_mio_boot_bist_stat_s {
- uint64_t reserved_2_63:62;
- uint64_t loc:1;
- uint64_t ncbi:1;
+ uint64_t reserved_0_63:64;
} s;
struct cvmx_mio_boot_bist_stat_cn30xx {
uint64_t reserved_4_63:60;
@@ -257,20 +183,33 @@ union cvmx_mio_boot_bist_stat {
struct cvmx_mio_boot_bist_stat_cn52xxp1 cn56xxp1;
struct cvmx_mio_boot_bist_stat_cn38xx cn58xx;
struct cvmx_mio_boot_bist_stat_cn38xx cn58xxp1;
+ struct cvmx_mio_boot_bist_stat_cn63xx {
+ uint64_t reserved_9_63:55;
+ uint64_t stat:9;
+ } cn63xx;
+ struct cvmx_mio_boot_bist_stat_cn63xx cn63xxp1;
};
union cvmx_mio_boot_comp {
uint64_t u64;
struct cvmx_mio_boot_comp_s {
+ uint64_t reserved_0_63:64;
+ } s;
+ struct cvmx_mio_boot_comp_cn50xx {
uint64_t reserved_10_63:54;
uint64_t pctl:5;
uint64_t nctl:5;
- } s;
- struct cvmx_mio_boot_comp_s cn50xx;
- struct cvmx_mio_boot_comp_s cn52xx;
- struct cvmx_mio_boot_comp_s cn52xxp1;
- struct cvmx_mio_boot_comp_s cn56xx;
- struct cvmx_mio_boot_comp_s cn56xxp1;
+ } cn50xx;
+ struct cvmx_mio_boot_comp_cn50xx cn52xx;
+ struct cvmx_mio_boot_comp_cn50xx cn52xxp1;
+ struct cvmx_mio_boot_comp_cn50xx cn56xx;
+ struct cvmx_mio_boot_comp_cn50xx cn56xxp1;
+ struct cvmx_mio_boot_comp_cn63xx {
+ uint64_t reserved_12_63:52;
+ uint64_t pctl:6;
+ uint64_t nctl:6;
+ } cn63xx;
+ struct cvmx_mio_boot_comp_cn63xx cn63xxp1;
};
union cvmx_mio_boot_dma_cfgx {
@@ -291,6 +230,8 @@ union cvmx_mio_boot_dma_cfgx {
struct cvmx_mio_boot_dma_cfgx_s cn52xxp1;
struct cvmx_mio_boot_dma_cfgx_s cn56xx;
struct cvmx_mio_boot_dma_cfgx_s cn56xxp1;
+ struct cvmx_mio_boot_dma_cfgx_s cn63xx;
+ struct cvmx_mio_boot_dma_cfgx_s cn63xxp1;
};
union cvmx_mio_boot_dma_intx {
@@ -304,6 +245,8 @@ union cvmx_mio_boot_dma_intx {
struct cvmx_mio_boot_dma_intx_s cn52xxp1;
struct cvmx_mio_boot_dma_intx_s cn56xx;
struct cvmx_mio_boot_dma_intx_s cn56xxp1;
+ struct cvmx_mio_boot_dma_intx_s cn63xx;
+ struct cvmx_mio_boot_dma_intx_s cn63xxp1;
};
union cvmx_mio_boot_dma_int_enx {
@@ -317,6 +260,8 @@ union cvmx_mio_boot_dma_int_enx {
struct cvmx_mio_boot_dma_int_enx_s cn52xxp1;
struct cvmx_mio_boot_dma_int_enx_s cn56xx;
struct cvmx_mio_boot_dma_int_enx_s cn56xxp1;
+ struct cvmx_mio_boot_dma_int_enx_s cn63xx;
+ struct cvmx_mio_boot_dma_int_enx_s cn63xxp1;
};
union cvmx_mio_boot_dma_timx {
@@ -342,6 +287,8 @@ union cvmx_mio_boot_dma_timx {
struct cvmx_mio_boot_dma_timx_s cn52xxp1;
struct cvmx_mio_boot_dma_timx_s cn56xx;
struct cvmx_mio_boot_dma_timx_s cn56xxp1;
+ struct cvmx_mio_boot_dma_timx_s cn63xx;
+ struct cvmx_mio_boot_dma_timx_s cn63xxp1;
};
union cvmx_mio_boot_err {
@@ -362,6 +309,8 @@ union cvmx_mio_boot_err {
struct cvmx_mio_boot_err_s cn56xxp1;
struct cvmx_mio_boot_err_s cn58xx;
struct cvmx_mio_boot_err_s cn58xxp1;
+ struct cvmx_mio_boot_err_s cn63xx;
+ struct cvmx_mio_boot_err_s cn63xxp1;
};
union cvmx_mio_boot_int {
@@ -382,6 +331,8 @@ union cvmx_mio_boot_int {
struct cvmx_mio_boot_int_s cn56xxp1;
struct cvmx_mio_boot_int_s cn58xx;
struct cvmx_mio_boot_int_s cn58xxp1;
+ struct cvmx_mio_boot_int_s cn63xx;
+ struct cvmx_mio_boot_int_s cn63xxp1;
};
union cvmx_mio_boot_loc_adr {
@@ -402,6 +353,8 @@ union cvmx_mio_boot_loc_adr {
struct cvmx_mio_boot_loc_adr_s cn56xxp1;
struct cvmx_mio_boot_loc_adr_s cn58xx;
struct cvmx_mio_boot_loc_adr_s cn58xxp1;
+ struct cvmx_mio_boot_loc_adr_s cn63xx;
+ struct cvmx_mio_boot_loc_adr_s cn63xxp1;
};
union cvmx_mio_boot_loc_cfgx {
@@ -424,6 +377,8 @@ union cvmx_mio_boot_loc_cfgx {
struct cvmx_mio_boot_loc_cfgx_s cn56xxp1;
struct cvmx_mio_boot_loc_cfgx_s cn58xx;
struct cvmx_mio_boot_loc_cfgx_s cn58xxp1;
+ struct cvmx_mio_boot_loc_cfgx_s cn63xx;
+ struct cvmx_mio_boot_loc_cfgx_s cn63xxp1;
};
union cvmx_mio_boot_loc_dat {
@@ -442,6 +397,8 @@ union cvmx_mio_boot_loc_dat {
struct cvmx_mio_boot_loc_dat_s cn56xxp1;
struct cvmx_mio_boot_loc_dat_s cn58xx;
struct cvmx_mio_boot_loc_dat_s cn58xxp1;
+ struct cvmx_mio_boot_loc_dat_s cn63xx;
+ struct cvmx_mio_boot_loc_dat_s cn63xxp1;
};
union cvmx_mio_boot_pin_defs {
@@ -478,6 +435,8 @@ union cvmx_mio_boot_pin_defs {
uint64_t term:2;
uint64_t reserved_0_8:9;
} cn56xx;
+ struct cvmx_mio_boot_pin_defs_cn52xx cn63xx;
+ struct cvmx_mio_boot_pin_defs_cn52xx cn63xxp1;
};
union cvmx_mio_boot_reg_cfgx {
@@ -539,6 +498,8 @@ union cvmx_mio_boot_reg_cfgx {
struct cvmx_mio_boot_reg_cfgx_s cn56xxp1;
struct cvmx_mio_boot_reg_cfgx_cn30xx cn58xx;
struct cvmx_mio_boot_reg_cfgx_cn30xx cn58xxp1;
+ struct cvmx_mio_boot_reg_cfgx_s cn63xx;
+ struct cvmx_mio_boot_reg_cfgx_s cn63xxp1;
};
union cvmx_mio_boot_reg_timx {
@@ -583,6 +544,8 @@ union cvmx_mio_boot_reg_timx {
struct cvmx_mio_boot_reg_timx_s cn56xxp1;
struct cvmx_mio_boot_reg_timx_s cn58xx;
struct cvmx_mio_boot_reg_timx_s cn58xxp1;
+ struct cvmx_mio_boot_reg_timx_s cn63xx;
+ struct cvmx_mio_boot_reg_timx_s cn63xxp1;
};
union cvmx_mio_boot_thr {
@@ -611,6 +574,8 @@ union cvmx_mio_boot_thr {
struct cvmx_mio_boot_thr_s cn56xxp1;
struct cvmx_mio_boot_thr_cn30xx cn58xx;
struct cvmx_mio_boot_thr_cn30xx cn58xxp1;
+ struct cvmx_mio_boot_thr_s cn63xx;
+ struct cvmx_mio_boot_thr_s cn63xxp1;
};
union cvmx_mio_fus_bnk_datx {
@@ -625,6 +590,8 @@ union cvmx_mio_fus_bnk_datx {
struct cvmx_mio_fus_bnk_datx_s cn56xxp1;
struct cvmx_mio_fus_bnk_datx_s cn58xx;
struct cvmx_mio_fus_bnk_datx_s cn58xxp1;
+ struct cvmx_mio_fus_bnk_datx_s cn63xx;
+ struct cvmx_mio_fus_bnk_datx_s cn63xxp1;
};
union cvmx_mio_fus_dat0 {
@@ -644,6 +611,8 @@ union cvmx_mio_fus_dat0 {
struct cvmx_mio_fus_dat0_s cn56xxp1;
struct cvmx_mio_fus_dat0_s cn58xx;
struct cvmx_mio_fus_dat0_s cn58xxp1;
+ struct cvmx_mio_fus_dat0_s cn63xx;
+ struct cvmx_mio_fus_dat0_s cn63xxp1;
};
union cvmx_mio_fus_dat1 {
@@ -663,12 +632,15 @@ union cvmx_mio_fus_dat1 {
struct cvmx_mio_fus_dat1_s cn56xxp1;
struct cvmx_mio_fus_dat1_s cn58xx;
struct cvmx_mio_fus_dat1_s cn58xxp1;
+ struct cvmx_mio_fus_dat1_s cn63xx;
+ struct cvmx_mio_fus_dat1_s cn63xxp1;
};
union cvmx_mio_fus_dat2 {
uint64_t u64;
struct cvmx_mio_fus_dat2_s {
- uint64_t reserved_34_63:30;
+ uint64_t reserved_35_63:29;
+ uint64_t dorm_crypto:1;
uint64_t fus318:1;
uint64_t raid_en:1;
uint64_t reserved_30_31:2;
@@ -775,14 +747,38 @@ union cvmx_mio_fus_dat2 {
uint64_t pp_dis:16;
} cn58xx;
struct cvmx_mio_fus_dat2_cn58xx cn58xxp1;
+ struct cvmx_mio_fus_dat2_cn63xx {
+ uint64_t reserved_35_63:29;
+ uint64_t dorm_crypto:1;
+ uint64_t fus318:1;
+ uint64_t raid_en:1;
+ uint64_t reserved_29_31:3;
+ uint64_t nodfa_cp2:1;
+ uint64_t nomul:1;
+ uint64_t nocrypto:1;
+ uint64_t reserved_24_25:2;
+ uint64_t chip_id:8;
+ uint64_t reserved_6_15:10;
+ uint64_t pp_dis:6;
+ } cn63xx;
+ struct cvmx_mio_fus_dat2_cn63xx cn63xxp1;
};
union cvmx_mio_fus_dat3 {
uint64_t u64;
struct cvmx_mio_fus_dat3_s {
- uint64_t reserved_32_63:32;
+ uint64_t reserved_58_63:6;
+ uint64_t pll_ctl:10;
+ uint64_t dfa_info_dte:3;
+ uint64_t dfa_info_clm:4;
+ uint64_t reserved_40_40:1;
+ uint64_t ema:2;
+ uint64_t efus_lck_rsv:1;
+ uint64_t efus_lck_man:1;
+ uint64_t pll_half_dis:1;
+ uint64_t l2c_crip:3;
uint64_t pll_div4:1;
- uint64_t zip_crip:2;
+ uint64_t reserved_29_30:2;
uint64_t bar2_en:1;
uint64_t efus_lck:1;
uint64_t efus_ign:1;
@@ -801,7 +797,17 @@ union cvmx_mio_fus_dat3 {
uint64_t nodfa_dte:1;
uint64_t icache:24;
} cn30xx;
- struct cvmx_mio_fus_dat3_s cn31xx;
+ struct cvmx_mio_fus_dat3_cn31xx {
+ uint64_t reserved_32_63:32;
+ uint64_t pll_div4:1;
+ uint64_t zip_crip:2;
+ uint64_t bar2_en:1;
+ uint64_t efus_lck:1;
+ uint64_t efus_ign:1;
+ uint64_t nozip:1;
+ uint64_t nodfa_dte:1;
+ uint64_t icache:24;
+ } cn31xx;
struct cvmx_mio_fus_dat3_cn38xx {
uint64_t reserved_31_63:33;
uint64_t zip_crip:2;
@@ -828,6 +834,27 @@ union cvmx_mio_fus_dat3 {
struct cvmx_mio_fus_dat3_cn38xx cn56xxp1;
struct cvmx_mio_fus_dat3_cn38xx cn58xx;
struct cvmx_mio_fus_dat3_cn38xx cn58xxp1;
+ struct cvmx_mio_fus_dat3_cn63xx {
+ uint64_t reserved_58_63:6;
+ uint64_t pll_ctl:10;
+ uint64_t dfa_info_dte:3;
+ uint64_t dfa_info_clm:4;
+ uint64_t reserved_40_40:1;
+ uint64_t ema:2;
+ uint64_t efus_lck_rsv:1;
+ uint64_t efus_lck_man:1;
+ uint64_t pll_half_dis:1;
+ uint64_t l2c_crip:3;
+ uint64_t reserved_31_31:1;
+ uint64_t zip_info:2;
+ uint64_t bar2_en:1;
+ uint64_t efus_lck:1;
+ uint64_t efus_ign:1;
+ uint64_t nozip:1;
+ uint64_t nodfa_dte:1;
+ uint64_t reserved_0_23:24;
+ } cn63xx;
+ struct cvmx_mio_fus_dat3_cn63xx cn63xxp1;
};
union cvmx_mio_fus_ema {
@@ -848,6 +875,8 @@ union cvmx_mio_fus_ema {
uint64_t ema:2;
} cn58xx;
struct cvmx_mio_fus_ema_cn58xx cn58xxp1;
+ struct cvmx_mio_fus_ema_s cn63xx;
+ struct cvmx_mio_fus_ema_s cn63xxp1;
};
union cvmx_mio_fus_pdf {
@@ -861,60 +890,96 @@ union cvmx_mio_fus_pdf {
struct cvmx_mio_fus_pdf_s cn56xx;
struct cvmx_mio_fus_pdf_s cn56xxp1;
struct cvmx_mio_fus_pdf_s cn58xx;
+ struct cvmx_mio_fus_pdf_s cn63xx;
+ struct cvmx_mio_fus_pdf_s cn63xxp1;
};
union cvmx_mio_fus_pll {
uint64_t u64;
struct cvmx_mio_fus_pll_s {
- uint64_t reserved_2_63:62;
+ uint64_t reserved_8_63:56;
+ uint64_t c_cout_rst:1;
+ uint64_t c_cout_sel:2;
+ uint64_t pnr_cout_rst:1;
+ uint64_t pnr_cout_sel:2;
uint64_t rfslip:1;
uint64_t fbslip:1;
} s;
- struct cvmx_mio_fus_pll_s cn50xx;
- struct cvmx_mio_fus_pll_s cn52xx;
- struct cvmx_mio_fus_pll_s cn52xxp1;
- struct cvmx_mio_fus_pll_s cn56xx;
- struct cvmx_mio_fus_pll_s cn56xxp1;
- struct cvmx_mio_fus_pll_s cn58xx;
- struct cvmx_mio_fus_pll_s cn58xxp1;
+ struct cvmx_mio_fus_pll_cn50xx {
+ uint64_t reserved_2_63:62;
+ uint64_t rfslip:1;
+ uint64_t fbslip:1;
+ } cn50xx;
+ struct cvmx_mio_fus_pll_cn50xx cn52xx;
+ struct cvmx_mio_fus_pll_cn50xx cn52xxp1;
+ struct cvmx_mio_fus_pll_cn50xx cn56xx;
+ struct cvmx_mio_fus_pll_cn50xx cn56xxp1;
+ struct cvmx_mio_fus_pll_cn50xx cn58xx;
+ struct cvmx_mio_fus_pll_cn50xx cn58xxp1;
+ struct cvmx_mio_fus_pll_s cn63xx;
+ struct cvmx_mio_fus_pll_s cn63xxp1;
};
union cvmx_mio_fus_prog {
uint64_t u64;
struct cvmx_mio_fus_prog_s {
- uint64_t reserved_1_63:63;
+ uint64_t reserved_2_63:62;
+ uint64_t soft:1;
uint64_t prog:1;
} s;
- struct cvmx_mio_fus_prog_s cn30xx;
- struct cvmx_mio_fus_prog_s cn31xx;
- struct cvmx_mio_fus_prog_s cn38xx;
- struct cvmx_mio_fus_prog_s cn38xxp2;
- struct cvmx_mio_fus_prog_s cn50xx;
- struct cvmx_mio_fus_prog_s cn52xx;
- struct cvmx_mio_fus_prog_s cn52xxp1;
- struct cvmx_mio_fus_prog_s cn56xx;
- struct cvmx_mio_fus_prog_s cn56xxp1;
- struct cvmx_mio_fus_prog_s cn58xx;
- struct cvmx_mio_fus_prog_s cn58xxp1;
+ struct cvmx_mio_fus_prog_cn30xx {
+ uint64_t reserved_1_63:63;
+ uint64_t prog:1;
+ } cn30xx;
+ struct cvmx_mio_fus_prog_cn30xx cn31xx;
+ struct cvmx_mio_fus_prog_cn30xx cn38xx;
+ struct cvmx_mio_fus_prog_cn30xx cn38xxp2;
+ struct cvmx_mio_fus_prog_cn30xx cn50xx;
+ struct cvmx_mio_fus_prog_cn30xx cn52xx;
+ struct cvmx_mio_fus_prog_cn30xx cn52xxp1;
+ struct cvmx_mio_fus_prog_cn30xx cn56xx;
+ struct cvmx_mio_fus_prog_cn30xx cn56xxp1;
+ struct cvmx_mio_fus_prog_cn30xx cn58xx;
+ struct cvmx_mio_fus_prog_cn30xx cn58xxp1;
+ struct cvmx_mio_fus_prog_s cn63xx;
+ struct cvmx_mio_fus_prog_s cn63xxp1;
};
union cvmx_mio_fus_prog_times {
uint64_t u64;
struct cvmx_mio_fus_prog_times_s {
+ uint64_t reserved_35_63:29;
+ uint64_t vgate_pin:1;
+ uint64_t fsrc_pin:1;
+ uint64_t prog_pin:1;
+ uint64_t reserved_6_31:26;
+ uint64_t setup:6;
+ } s;
+ struct cvmx_mio_fus_prog_times_cn50xx {
uint64_t reserved_33_63:31;
uint64_t prog_pin:1;
uint64_t out:8;
uint64_t sclk_lo:4;
uint64_t sclk_hi:12;
uint64_t setup:8;
- } s;
- struct cvmx_mio_fus_prog_times_s cn50xx;
- struct cvmx_mio_fus_prog_times_s cn52xx;
- struct cvmx_mio_fus_prog_times_s cn52xxp1;
- struct cvmx_mio_fus_prog_times_s cn56xx;
- struct cvmx_mio_fus_prog_times_s cn56xxp1;
- struct cvmx_mio_fus_prog_times_s cn58xx;
- struct cvmx_mio_fus_prog_times_s cn58xxp1;
+ } cn50xx;
+ struct cvmx_mio_fus_prog_times_cn50xx cn52xx;
+ struct cvmx_mio_fus_prog_times_cn50xx cn52xxp1;
+ struct cvmx_mio_fus_prog_times_cn50xx cn56xx;
+ struct cvmx_mio_fus_prog_times_cn50xx cn56xxp1;
+ struct cvmx_mio_fus_prog_times_cn50xx cn58xx;
+ struct cvmx_mio_fus_prog_times_cn50xx cn58xxp1;
+ struct cvmx_mio_fus_prog_times_cn63xx {
+ uint64_t reserved_35_63:29;
+ uint64_t vgate_pin:1;
+ uint64_t fsrc_pin:1;
+ uint64_t prog_pin:1;
+ uint64_t out:7;
+ uint64_t sclk_lo:4;
+ uint64_t sclk_hi:15;
+ uint64_t setup:6;
+ } cn63xx;
+ struct cvmx_mio_fus_prog_times_cn63xx cn63xxp1;
};
union cvmx_mio_fus_rcmd {
@@ -948,6 +1013,57 @@ union cvmx_mio_fus_rcmd {
struct cvmx_mio_fus_rcmd_s cn56xxp1;
struct cvmx_mio_fus_rcmd_cn30xx cn58xx;
struct cvmx_mio_fus_rcmd_cn30xx cn58xxp1;
+ struct cvmx_mio_fus_rcmd_s cn63xx;
+ struct cvmx_mio_fus_rcmd_s cn63xxp1;
+};
+
+union cvmx_mio_fus_read_times {
+ uint64_t u64;
+ struct cvmx_mio_fus_read_times_s {
+ uint64_t reserved_26_63:38;
+ uint64_t sch:4;
+ uint64_t fsh:4;
+ uint64_t prh:4;
+ uint64_t sdh:4;
+ uint64_t setup:10;
+ } s;
+ struct cvmx_mio_fus_read_times_s cn63xx;
+ struct cvmx_mio_fus_read_times_s cn63xxp1;
+};
+
+union cvmx_mio_fus_repair_res0 {
+ uint64_t u64;
+ struct cvmx_mio_fus_repair_res0_s {
+ uint64_t reserved_55_63:9;
+ uint64_t too_many:1;
+ uint64_t repair2:18;
+ uint64_t repair1:18;
+ uint64_t repair0:18;
+ } s;
+ struct cvmx_mio_fus_repair_res0_s cn63xx;
+ struct cvmx_mio_fus_repair_res0_s cn63xxp1;
+};
+
+union cvmx_mio_fus_repair_res1 {
+ uint64_t u64;
+ struct cvmx_mio_fus_repair_res1_s {
+ uint64_t reserved_54_63:10;
+ uint64_t repair5:18;
+ uint64_t repair4:18;
+ uint64_t repair3:18;
+ } s;
+ struct cvmx_mio_fus_repair_res1_s cn63xx;
+ struct cvmx_mio_fus_repair_res1_s cn63xxp1;
+};
+
+union cvmx_mio_fus_repair_res2 {
+ uint64_t u64;
+ struct cvmx_mio_fus_repair_res2_s {
+ uint64_t reserved_18_63:46;
+ uint64_t repair6:18;
+ } s;
+ struct cvmx_mio_fus_repair_res2_s cn63xx;
+ struct cvmx_mio_fus_repair_res2_s cn63xxp1;
};
union cvmx_mio_fus_spr_repair_res {
@@ -968,6 +1084,8 @@ union cvmx_mio_fus_spr_repair_res {
struct cvmx_mio_fus_spr_repair_res_s cn56xxp1;
struct cvmx_mio_fus_spr_repair_res_s cn58xx;
struct cvmx_mio_fus_spr_repair_res_s cn58xxp1;
+ struct cvmx_mio_fus_spr_repair_res_s cn63xx;
+ struct cvmx_mio_fus_spr_repair_res_s cn63xxp1;
};
union cvmx_mio_fus_spr_repair_sum {
@@ -986,6 +1104,8 @@ union cvmx_mio_fus_spr_repair_sum {
struct cvmx_mio_fus_spr_repair_sum_s cn56xxp1;
struct cvmx_mio_fus_spr_repair_sum_s cn58xx;
struct cvmx_mio_fus_spr_repair_sum_s cn58xxp1;
+ struct cvmx_mio_fus_spr_repair_sum_s cn63xx;
+ struct cvmx_mio_fus_spr_repair_sum_s cn63xxp1;
};
union cvmx_mio_fus_unlock {
@@ -1021,6 +1141,22 @@ union cvmx_mio_fus_wadr {
struct cvmx_mio_fus_wadr_cn52xx cn56xxp1;
struct cvmx_mio_fus_wadr_cn50xx cn58xx;
struct cvmx_mio_fus_wadr_cn50xx cn58xxp1;
+ struct cvmx_mio_fus_wadr_cn63xx {
+ uint64_t reserved_4_63:60;
+ uint64_t addr:4;
+ } cn63xx;
+ struct cvmx_mio_fus_wadr_cn63xx cn63xxp1;
+};
+
+union cvmx_mio_gpio_comp {
+ uint64_t u64;
+ struct cvmx_mio_gpio_comp_s {
+ uint64_t reserved_12_63:52;
+ uint64_t pctl:6;
+ uint64_t nctl:6;
+ } s;
+ struct cvmx_mio_gpio_comp_s cn63xx;
+ struct cvmx_mio_gpio_comp_s cn63xxp1;
};
union cvmx_mio_ndf_dma_cfg {
@@ -1038,6 +1174,8 @@ union cvmx_mio_ndf_dma_cfg {
uint64_t adr:36;
} s;
struct cvmx_mio_ndf_dma_cfg_s cn52xx;
+ struct cvmx_mio_ndf_dma_cfg_s cn63xx;
+ struct cvmx_mio_ndf_dma_cfg_s cn63xxp1;
};
union cvmx_mio_ndf_dma_int {
@@ -1047,6 +1185,8 @@ union cvmx_mio_ndf_dma_int {
uint64_t done:1;
} s;
struct cvmx_mio_ndf_dma_int_s cn52xx;
+ struct cvmx_mio_ndf_dma_int_s cn63xx;
+ struct cvmx_mio_ndf_dma_int_s cn63xxp1;
};
union cvmx_mio_ndf_dma_int_en {
@@ -1056,6 +1196,8 @@ union cvmx_mio_ndf_dma_int_en {
uint64_t done:1;
} s;
struct cvmx_mio_ndf_dma_int_en_s cn52xx;
+ struct cvmx_mio_ndf_dma_int_en_s cn63xx;
+ struct cvmx_mio_ndf_dma_int_en_s cn63xxp1;
};
union cvmx_mio_pll_ctl {
@@ -1078,6 +1220,173 @@ union cvmx_mio_pll_setting {
struct cvmx_mio_pll_setting_s cn31xx;
};
+union cvmx_mio_ptp_clock_cfg {
+ uint64_t u64;
+ struct cvmx_mio_ptp_clock_cfg_s {
+ uint64_t reserved_24_63:40;
+ uint64_t evcnt_in:6;
+ uint64_t evcnt_edge:1;
+ uint64_t evcnt_en:1;
+ uint64_t tstmp_in:6;
+ uint64_t tstmp_edge:1;
+ uint64_t tstmp_en:1;
+ uint64_t ext_clk_in:6;
+ uint64_t ext_clk_en:1;
+ uint64_t ptp_en:1;
+ } s;
+ struct cvmx_mio_ptp_clock_cfg_s cn63xx;
+ struct cvmx_mio_ptp_clock_cfg_s cn63xxp1;
+};
+
+union cvmx_mio_ptp_clock_comp {
+ uint64_t u64;
+ struct cvmx_mio_ptp_clock_comp_s {
+ uint64_t nanosec:32;
+ uint64_t frnanosec:32;
+ } s;
+ struct cvmx_mio_ptp_clock_comp_s cn63xx;
+ struct cvmx_mio_ptp_clock_comp_s cn63xxp1;
+};
+
+union cvmx_mio_ptp_clock_hi {
+ uint64_t u64;
+ struct cvmx_mio_ptp_clock_hi_s {
+ uint64_t nanosec:64;
+ } s;
+ struct cvmx_mio_ptp_clock_hi_s cn63xx;
+ struct cvmx_mio_ptp_clock_hi_s cn63xxp1;
+};
+
+union cvmx_mio_ptp_clock_lo {
+ uint64_t u64;
+ struct cvmx_mio_ptp_clock_lo_s {
+ uint64_t reserved_32_63:32;
+ uint64_t frnanosec:32;
+ } s;
+ struct cvmx_mio_ptp_clock_lo_s cn63xx;
+ struct cvmx_mio_ptp_clock_lo_s cn63xxp1;
+};
+
+union cvmx_mio_ptp_evt_cnt {
+ uint64_t u64;
+ struct cvmx_mio_ptp_evt_cnt_s {
+ uint64_t cntr:64;
+ } s;
+ struct cvmx_mio_ptp_evt_cnt_s cn63xx;
+ struct cvmx_mio_ptp_evt_cnt_s cn63xxp1;
+};
+
+union cvmx_mio_ptp_timestamp {
+ uint64_t u64;
+ struct cvmx_mio_ptp_timestamp_s {
+ uint64_t nanosec:64;
+ } s;
+ struct cvmx_mio_ptp_timestamp_s cn63xx;
+ struct cvmx_mio_ptp_timestamp_s cn63xxp1;
+};
+
+union cvmx_mio_rst_boot {
+ uint64_t u64;
+ struct cvmx_mio_rst_boot_s {
+ uint64_t reserved_36_63:28;
+ uint64_t c_mul:6;
+ uint64_t pnr_mul:6;
+ uint64_t qlm2_spd:4;
+ uint64_t qlm1_spd:4;
+ uint64_t qlm0_spd:4;
+ uint64_t lboot:10;
+ uint64_t rboot:1;
+ uint64_t rboot_pin:1;
+ } s;
+ struct cvmx_mio_rst_boot_s cn63xx;
+ struct cvmx_mio_rst_boot_s cn63xxp1;
+};
+
+union cvmx_mio_rst_cfg {
+ uint64_t u64;
+ struct cvmx_mio_rst_cfg_s {
+ uint64_t bist_delay:58;
+ uint64_t reserved_3_5:3;
+ uint64_t cntl_clr_bist:1;
+ uint64_t warm_clr_bist:1;
+ uint64_t soft_clr_bist:1;
+ } s;
+ struct cvmx_mio_rst_cfg_s cn63xx;
+ struct cvmx_mio_rst_cfg_cn63xxp1 {
+ uint64_t bist_delay:58;
+ uint64_t reserved_2_5:4;
+ uint64_t warm_clr_bist:1;
+ uint64_t soft_clr_bist:1;
+ } cn63xxp1;
+};
+
+union cvmx_mio_rst_ctlx {
+ uint64_t u64;
+ struct cvmx_mio_rst_ctlx_s {
+ uint64_t reserved_10_63:54;
+ uint64_t prst_link:1;
+ uint64_t rst_done:1;
+ uint64_t rst_link:1;
+ uint64_t host_mode:1;
+ uint64_t prtmode:2;
+ uint64_t rst_drv:1;
+ uint64_t rst_rcv:1;
+ uint64_t rst_chip:1;
+ uint64_t rst_val:1;
+ } s;
+ struct cvmx_mio_rst_ctlx_s cn63xx;
+ struct cvmx_mio_rst_ctlx_cn63xxp1 {
+ uint64_t reserved_9_63:55;
+ uint64_t rst_done:1;
+ uint64_t rst_link:1;
+ uint64_t host_mode:1;
+ uint64_t prtmode:2;
+ uint64_t rst_drv:1;
+ uint64_t rst_rcv:1;
+ uint64_t rst_chip:1;
+ uint64_t rst_val:1;
+ } cn63xxp1;
+};
+
+union cvmx_mio_rst_delay {
+ uint64_t u64;
+ struct cvmx_mio_rst_delay_s {
+ uint64_t reserved_32_63:32;
+ uint64_t soft_rst_dly:16;
+ uint64_t warm_rst_dly:16;
+ } s;
+ struct cvmx_mio_rst_delay_s cn63xx;
+ struct cvmx_mio_rst_delay_s cn63xxp1;
+};
+
+union cvmx_mio_rst_int {
+ uint64_t u64;
+ struct cvmx_mio_rst_int_s {
+ uint64_t reserved_10_63:54;
+ uint64_t perst1:1;
+ uint64_t perst0:1;
+ uint64_t reserved_2_7:6;
+ uint64_t rst_link1:1;
+ uint64_t rst_link0:1;
+ } s;
+ struct cvmx_mio_rst_int_s cn63xx;
+ struct cvmx_mio_rst_int_s cn63xxp1;
+};
+
+union cvmx_mio_rst_int_en {
+ uint64_t u64;
+ struct cvmx_mio_rst_int_en_s {
+ uint64_t reserved_10_63:54;
+ uint64_t perst1:1;
+ uint64_t perst0:1;
+ uint64_t reserved_2_7:6;
+ uint64_t rst_link1:1;
+ uint64_t rst_link0:1;
+ } s;
+ struct cvmx_mio_rst_int_en_s cn63xx;
+ struct cvmx_mio_rst_int_en_s cn63xxp1;
+};
+
union cvmx_mio_twsx_int {
uint64_t u64;
struct cvmx_mio_twsx_int_s {
@@ -1115,6 +1424,8 @@ union cvmx_mio_twsx_int {
struct cvmx_mio_twsx_int_s cn56xxp1;
struct cvmx_mio_twsx_int_s cn58xx;
struct cvmx_mio_twsx_int_s cn58xxp1;
+ struct cvmx_mio_twsx_int_s cn63xx;
+ struct cvmx_mio_twsx_int_s cn63xxp1;
};
union cvmx_mio_twsx_sw_twsi {
@@ -1144,6 +1455,8 @@ union cvmx_mio_twsx_sw_twsi {
struct cvmx_mio_twsx_sw_twsi_s cn56xxp1;
struct cvmx_mio_twsx_sw_twsi_s cn58xx;
struct cvmx_mio_twsx_sw_twsi_s cn58xxp1;
+ struct cvmx_mio_twsx_sw_twsi_s cn63xx;
+ struct cvmx_mio_twsx_sw_twsi_s cn63xxp1;
};
union cvmx_mio_twsx_sw_twsi_ext {
@@ -1164,6 +1477,8 @@ union cvmx_mio_twsx_sw_twsi_ext {
struct cvmx_mio_twsx_sw_twsi_ext_s cn56xxp1;
struct cvmx_mio_twsx_sw_twsi_ext_s cn58xx;
struct cvmx_mio_twsx_sw_twsi_ext_s cn58xxp1;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn63xx;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn63xxp1;
};
union cvmx_mio_twsx_twsi_sw {
@@ -1184,6 +1499,8 @@ union cvmx_mio_twsx_twsi_sw {
struct cvmx_mio_twsx_twsi_sw_s cn56xxp1;
struct cvmx_mio_twsx_twsi_sw_s cn58xx;
struct cvmx_mio_twsx_twsi_sw_s cn58xxp1;
+ struct cvmx_mio_twsx_twsi_sw_s cn63xx;
+ struct cvmx_mio_twsx_twsi_sw_s cn63xxp1;
};
union cvmx_mio_uartx_dlh {
@@ -1203,6 +1520,8 @@ union cvmx_mio_uartx_dlh {
struct cvmx_mio_uartx_dlh_s cn56xxp1;
struct cvmx_mio_uartx_dlh_s cn58xx;
struct cvmx_mio_uartx_dlh_s cn58xxp1;
+ struct cvmx_mio_uartx_dlh_s cn63xx;
+ struct cvmx_mio_uartx_dlh_s cn63xxp1;
};
union cvmx_mio_uartx_dll {
@@ -1222,6 +1541,8 @@ union cvmx_mio_uartx_dll {
struct cvmx_mio_uartx_dll_s cn56xxp1;
struct cvmx_mio_uartx_dll_s cn58xx;
struct cvmx_mio_uartx_dll_s cn58xxp1;
+ struct cvmx_mio_uartx_dll_s cn63xx;
+ struct cvmx_mio_uartx_dll_s cn63xxp1;
};
union cvmx_mio_uartx_far {
@@ -1241,6 +1562,8 @@ union cvmx_mio_uartx_far {
struct cvmx_mio_uartx_far_s cn56xxp1;
struct cvmx_mio_uartx_far_s cn58xx;
struct cvmx_mio_uartx_far_s cn58xxp1;
+ struct cvmx_mio_uartx_far_s cn63xx;
+ struct cvmx_mio_uartx_far_s cn63xxp1;
};
union cvmx_mio_uartx_fcr {
@@ -1265,6 +1588,8 @@ union cvmx_mio_uartx_fcr {
struct cvmx_mio_uartx_fcr_s cn56xxp1;
struct cvmx_mio_uartx_fcr_s cn58xx;
struct cvmx_mio_uartx_fcr_s cn58xxp1;
+ struct cvmx_mio_uartx_fcr_s cn63xx;
+ struct cvmx_mio_uartx_fcr_s cn63xxp1;
};
union cvmx_mio_uartx_htx {
@@ -1284,6 +1609,8 @@ union cvmx_mio_uartx_htx {
struct cvmx_mio_uartx_htx_s cn56xxp1;
struct cvmx_mio_uartx_htx_s cn58xx;
struct cvmx_mio_uartx_htx_s cn58xxp1;
+ struct cvmx_mio_uartx_htx_s cn63xx;
+ struct cvmx_mio_uartx_htx_s cn63xxp1;
};
union cvmx_mio_uartx_ier {
@@ -1308,6 +1635,8 @@ union cvmx_mio_uartx_ier {
struct cvmx_mio_uartx_ier_s cn56xxp1;
struct cvmx_mio_uartx_ier_s cn58xx;
struct cvmx_mio_uartx_ier_s cn58xxp1;
+ struct cvmx_mio_uartx_ier_s cn63xx;
+ struct cvmx_mio_uartx_ier_s cn63xxp1;
};
union cvmx_mio_uartx_iir {
@@ -1329,6 +1658,8 @@ union cvmx_mio_uartx_iir {
struct cvmx_mio_uartx_iir_s cn56xxp1;
struct cvmx_mio_uartx_iir_s cn58xx;
struct cvmx_mio_uartx_iir_s cn58xxp1;
+ struct cvmx_mio_uartx_iir_s cn63xx;
+ struct cvmx_mio_uartx_iir_s cn63xxp1;
};
union cvmx_mio_uartx_lcr {
@@ -1354,6 +1685,8 @@ union cvmx_mio_uartx_lcr {
struct cvmx_mio_uartx_lcr_s cn56xxp1;
struct cvmx_mio_uartx_lcr_s cn58xx;
struct cvmx_mio_uartx_lcr_s cn58xxp1;
+ struct cvmx_mio_uartx_lcr_s cn63xx;
+ struct cvmx_mio_uartx_lcr_s cn63xxp1;
};
union cvmx_mio_uartx_lsr {
@@ -1380,6 +1713,8 @@ union cvmx_mio_uartx_lsr {
struct cvmx_mio_uartx_lsr_s cn56xxp1;
struct cvmx_mio_uartx_lsr_s cn58xx;
struct cvmx_mio_uartx_lsr_s cn58xxp1;
+ struct cvmx_mio_uartx_lsr_s cn63xx;
+ struct cvmx_mio_uartx_lsr_s cn63xxp1;
};
union cvmx_mio_uartx_mcr {
@@ -1404,6 +1739,8 @@ union cvmx_mio_uartx_mcr {
struct cvmx_mio_uartx_mcr_s cn56xxp1;
struct cvmx_mio_uartx_mcr_s cn58xx;
struct cvmx_mio_uartx_mcr_s cn58xxp1;
+ struct cvmx_mio_uartx_mcr_s cn63xx;
+ struct cvmx_mio_uartx_mcr_s cn63xxp1;
};
union cvmx_mio_uartx_msr {
@@ -1430,6 +1767,8 @@ union cvmx_mio_uartx_msr {
struct cvmx_mio_uartx_msr_s cn56xxp1;
struct cvmx_mio_uartx_msr_s cn58xx;
struct cvmx_mio_uartx_msr_s cn58xxp1;
+ struct cvmx_mio_uartx_msr_s cn63xx;
+ struct cvmx_mio_uartx_msr_s cn63xxp1;
};
union cvmx_mio_uartx_rbr {
@@ -1449,6 +1788,8 @@ union cvmx_mio_uartx_rbr {
struct cvmx_mio_uartx_rbr_s cn56xxp1;
struct cvmx_mio_uartx_rbr_s cn58xx;
struct cvmx_mio_uartx_rbr_s cn58xxp1;
+ struct cvmx_mio_uartx_rbr_s cn63xx;
+ struct cvmx_mio_uartx_rbr_s cn63xxp1;
};
union cvmx_mio_uartx_rfl {
@@ -1468,6 +1809,8 @@ union cvmx_mio_uartx_rfl {
struct cvmx_mio_uartx_rfl_s cn56xxp1;
struct cvmx_mio_uartx_rfl_s cn58xx;
struct cvmx_mio_uartx_rfl_s cn58xxp1;
+ struct cvmx_mio_uartx_rfl_s cn63xx;
+ struct cvmx_mio_uartx_rfl_s cn63xxp1;
};
union cvmx_mio_uartx_rfw {
@@ -1489,6 +1832,8 @@ union cvmx_mio_uartx_rfw {
struct cvmx_mio_uartx_rfw_s cn56xxp1;
struct cvmx_mio_uartx_rfw_s cn58xx;
struct cvmx_mio_uartx_rfw_s cn58xxp1;
+ struct cvmx_mio_uartx_rfw_s cn63xx;
+ struct cvmx_mio_uartx_rfw_s cn63xxp1;
};
union cvmx_mio_uartx_sbcr {
@@ -1508,6 +1853,8 @@ union cvmx_mio_uartx_sbcr {
struct cvmx_mio_uartx_sbcr_s cn56xxp1;
struct cvmx_mio_uartx_sbcr_s cn58xx;
struct cvmx_mio_uartx_sbcr_s cn58xxp1;
+ struct cvmx_mio_uartx_sbcr_s cn63xx;
+ struct cvmx_mio_uartx_sbcr_s cn63xxp1;
};
union cvmx_mio_uartx_scr {
@@ -1527,6 +1874,8 @@ union cvmx_mio_uartx_scr {
struct cvmx_mio_uartx_scr_s cn56xxp1;
struct cvmx_mio_uartx_scr_s cn58xx;
struct cvmx_mio_uartx_scr_s cn58xxp1;
+ struct cvmx_mio_uartx_scr_s cn63xx;
+ struct cvmx_mio_uartx_scr_s cn63xxp1;
};
union cvmx_mio_uartx_sfe {
@@ -1546,6 +1895,8 @@ union cvmx_mio_uartx_sfe {
struct cvmx_mio_uartx_sfe_s cn56xxp1;
struct cvmx_mio_uartx_sfe_s cn58xx;
struct cvmx_mio_uartx_sfe_s cn58xxp1;
+ struct cvmx_mio_uartx_sfe_s cn63xx;
+ struct cvmx_mio_uartx_sfe_s cn63xxp1;
};
union cvmx_mio_uartx_srr {
@@ -1567,6 +1918,8 @@ union cvmx_mio_uartx_srr {
struct cvmx_mio_uartx_srr_s cn56xxp1;
struct cvmx_mio_uartx_srr_s cn58xx;
struct cvmx_mio_uartx_srr_s cn58xxp1;
+ struct cvmx_mio_uartx_srr_s cn63xx;
+ struct cvmx_mio_uartx_srr_s cn63xxp1;
};
union cvmx_mio_uartx_srt {
@@ -1586,6 +1939,8 @@ union cvmx_mio_uartx_srt {
struct cvmx_mio_uartx_srt_s cn56xxp1;
struct cvmx_mio_uartx_srt_s cn58xx;
struct cvmx_mio_uartx_srt_s cn58xxp1;
+ struct cvmx_mio_uartx_srt_s cn63xx;
+ struct cvmx_mio_uartx_srt_s cn63xxp1;
};
union cvmx_mio_uartx_srts {
@@ -1605,6 +1960,8 @@ union cvmx_mio_uartx_srts {
struct cvmx_mio_uartx_srts_s cn56xxp1;
struct cvmx_mio_uartx_srts_s cn58xx;
struct cvmx_mio_uartx_srts_s cn58xxp1;
+ struct cvmx_mio_uartx_srts_s cn63xx;
+ struct cvmx_mio_uartx_srts_s cn63xxp1;
};
union cvmx_mio_uartx_stt {
@@ -1624,6 +1981,8 @@ union cvmx_mio_uartx_stt {
struct cvmx_mio_uartx_stt_s cn56xxp1;
struct cvmx_mio_uartx_stt_s cn58xx;
struct cvmx_mio_uartx_stt_s cn58xxp1;
+ struct cvmx_mio_uartx_stt_s cn63xx;
+ struct cvmx_mio_uartx_stt_s cn63xxp1;
};
union cvmx_mio_uartx_tfl {
@@ -1643,6 +2002,8 @@ union cvmx_mio_uartx_tfl {
struct cvmx_mio_uartx_tfl_s cn56xxp1;
struct cvmx_mio_uartx_tfl_s cn58xx;
struct cvmx_mio_uartx_tfl_s cn58xxp1;
+ struct cvmx_mio_uartx_tfl_s cn63xx;
+ struct cvmx_mio_uartx_tfl_s cn63xxp1;
};
union cvmx_mio_uartx_tfr {
@@ -1662,6 +2023,8 @@ union cvmx_mio_uartx_tfr {
struct cvmx_mio_uartx_tfr_s cn56xxp1;
struct cvmx_mio_uartx_tfr_s cn58xx;
struct cvmx_mio_uartx_tfr_s cn58xxp1;
+ struct cvmx_mio_uartx_tfr_s cn63xx;
+ struct cvmx_mio_uartx_tfr_s cn63xxp1;
};
union cvmx_mio_uartx_thr {
@@ -1681,6 +2044,8 @@ union cvmx_mio_uartx_thr {
struct cvmx_mio_uartx_thr_s cn56xxp1;
struct cvmx_mio_uartx_thr_s cn58xx;
struct cvmx_mio_uartx_thr_s cn58xxp1;
+ struct cvmx_mio_uartx_thr_s cn63xx;
+ struct cvmx_mio_uartx_thr_s cn63xxp1;
};
union cvmx_mio_uartx_usr {
@@ -1704,6 +2069,8 @@ union cvmx_mio_uartx_usr {
struct cvmx_mio_uartx_usr_s cn56xxp1;
struct cvmx_mio_uartx_usr_s cn58xx;
struct cvmx_mio_uartx_usr_s cn58xxp1;
+ struct cvmx_mio_uartx_usr_s cn63xx;
+ struct cvmx_mio_uartx_usr_s cn63xxp1;
};
union cvmx_mio_uart2_dlh {
diff --git a/arch/mips/include/asm/octeon/cvmx-mixx-defs.h b/arch/mips/include/asm/octeon/cvmx-mixx-defs.h
index dab6dca492f9..7057c447e69e 100644
--- a/arch/mips/include/asm/octeon/cvmx-mixx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-mixx-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
@@ -28,52 +28,52 @@
#ifndef __CVMX_MIXX_DEFS_H__
#define __CVMX_MIXX_DEFS_H__
-#define CVMX_MIXX_BIST(offset) \
- CVMX_ADD_IO_SEG(0x0001070000100078ull + (((offset) & 1) * 2048))
-#define CVMX_MIXX_CTL(offset) \
- CVMX_ADD_IO_SEG(0x0001070000100020ull + (((offset) & 1) * 2048))
-#define CVMX_MIXX_INTENA(offset) \
- CVMX_ADD_IO_SEG(0x0001070000100050ull + (((offset) & 1) * 2048))
-#define CVMX_MIXX_IRCNT(offset) \
- CVMX_ADD_IO_SEG(0x0001070000100030ull + (((offset) & 1) * 2048))
-#define CVMX_MIXX_IRHWM(offset) \
- CVMX_ADD_IO_SEG(0x0001070000100028ull + (((offset) & 1) * 2048))
-#define CVMX_MIXX_IRING1(offset) \
- CVMX_ADD_IO_SEG(0x0001070000100010ull + (((offset) & 1) * 2048))
-#define CVMX_MIXX_IRING2(offset) \
- CVMX_ADD_IO_SEG(0x0001070000100018ull + (((offset) & 1) * 2048))
-#define CVMX_MIXX_ISR(offset) \
- CVMX_ADD_IO_SEG(0x0001070000100048ull + (((offset) & 1) * 2048))
-#define CVMX_MIXX_ORCNT(offset) \
- CVMX_ADD_IO_SEG(0x0001070000100040ull + (((offset) & 1) * 2048))
-#define CVMX_MIXX_ORHWM(offset) \
- CVMX_ADD_IO_SEG(0x0001070000100038ull + (((offset) & 1) * 2048))
-#define CVMX_MIXX_ORING1(offset) \
- CVMX_ADD_IO_SEG(0x0001070000100000ull + (((offset) & 1) * 2048))
-#define CVMX_MIXX_ORING2(offset) \
- CVMX_ADD_IO_SEG(0x0001070000100008ull + (((offset) & 1) * 2048))
-#define CVMX_MIXX_REMCNT(offset) \
- CVMX_ADD_IO_SEG(0x0001070000100058ull + (((offset) & 1) * 2048))
+#define CVMX_MIXX_BIST(offset) (CVMX_ADD_IO_SEG(0x0001070000100078ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_CTL(offset) (CVMX_ADD_IO_SEG(0x0001070000100020ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_INTENA(offset) (CVMX_ADD_IO_SEG(0x0001070000100050ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_IRCNT(offset) (CVMX_ADD_IO_SEG(0x0001070000100030ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_IRHWM(offset) (CVMX_ADD_IO_SEG(0x0001070000100028ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_IRING1(offset) (CVMX_ADD_IO_SEG(0x0001070000100010ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_IRING2(offset) (CVMX_ADD_IO_SEG(0x0001070000100018ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_ISR(offset) (CVMX_ADD_IO_SEG(0x0001070000100048ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_ORCNT(offset) (CVMX_ADD_IO_SEG(0x0001070000100040ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_ORHWM(offset) (CVMX_ADD_IO_SEG(0x0001070000100038ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_ORING1(offset) (CVMX_ADD_IO_SEG(0x0001070000100000ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_ORING2(offset) (CVMX_ADD_IO_SEG(0x0001070000100008ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_REMCNT(offset) (CVMX_ADD_IO_SEG(0x0001070000100058ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_TSCTL(offset) (CVMX_ADD_IO_SEG(0x0001070000100068ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_TSTAMP(offset) (CVMX_ADD_IO_SEG(0x0001070000100060ull) + ((offset) & 1) * 2048)
union cvmx_mixx_bist {
uint64_t u64;
struct cvmx_mixx_bist_s {
- uint64_t reserved_4_63:60;
+ uint64_t reserved_6_63:58;
+ uint64_t opfdat:1;
+ uint64_t mrgdat:1;
uint64_t mrqdat:1;
uint64_t ipfdat:1;
uint64_t irfdat:1;
uint64_t orfdat:1;
} s;
- struct cvmx_mixx_bist_s cn52xx;
- struct cvmx_mixx_bist_s cn52xxp1;
- struct cvmx_mixx_bist_s cn56xx;
- struct cvmx_mixx_bist_s cn56xxp1;
+ struct cvmx_mixx_bist_cn52xx {
+ uint64_t reserved_4_63:60;
+ uint64_t mrqdat:1;
+ uint64_t ipfdat:1;
+ uint64_t irfdat:1;
+ uint64_t orfdat:1;
+ } cn52xx;
+ struct cvmx_mixx_bist_cn52xx cn52xxp1;
+ struct cvmx_mixx_bist_cn52xx cn56xx;
+ struct cvmx_mixx_bist_cn52xx cn56xxp1;
+ struct cvmx_mixx_bist_s cn63xx;
+ struct cvmx_mixx_bist_s cn63xxp1;
};
union cvmx_mixx_ctl {
uint64_t u64;
struct cvmx_mixx_ctl_s {
- uint64_t reserved_8_63:56;
+ uint64_t reserved_12_63:52;
+ uint64_t ts_thresh:4;
uint64_t crc_strip:1;
uint64_t busy:1;
uint64_t en:1;
@@ -82,16 +82,28 @@ union cvmx_mixx_ctl {
uint64_t nbtarb:1;
uint64_t mrq_hwm:2;
} s;
- struct cvmx_mixx_ctl_s cn52xx;
- struct cvmx_mixx_ctl_s cn52xxp1;
- struct cvmx_mixx_ctl_s cn56xx;
- struct cvmx_mixx_ctl_s cn56xxp1;
+ struct cvmx_mixx_ctl_cn52xx {
+ uint64_t reserved_8_63:56;
+ uint64_t crc_strip:1;
+ uint64_t busy:1;
+ uint64_t en:1;
+ uint64_t reset:1;
+ uint64_t lendian:1;
+ uint64_t nbtarb:1;
+ uint64_t mrq_hwm:2;
+ } cn52xx;
+ struct cvmx_mixx_ctl_cn52xx cn52xxp1;
+ struct cvmx_mixx_ctl_cn52xx cn56xx;
+ struct cvmx_mixx_ctl_cn52xx cn56xxp1;
+ struct cvmx_mixx_ctl_s cn63xx;
+ struct cvmx_mixx_ctl_s cn63xxp1;
};
union cvmx_mixx_intena {
uint64_t u64;
struct cvmx_mixx_intena_s {
- uint64_t reserved_7_63:57;
+ uint64_t reserved_8_63:56;
+ uint64_t tsena:1;
uint64_t orunena:1;
uint64_t irunena:1;
uint64_t data_drpena:1;
@@ -100,10 +112,21 @@ union cvmx_mixx_intena {
uint64_t ivfena:1;
uint64_t ovfena:1;
} s;
- struct cvmx_mixx_intena_s cn52xx;
- struct cvmx_mixx_intena_s cn52xxp1;
- struct cvmx_mixx_intena_s cn56xx;
- struct cvmx_mixx_intena_s cn56xxp1;
+ struct cvmx_mixx_intena_cn52xx {
+ uint64_t reserved_7_63:57;
+ uint64_t orunena:1;
+ uint64_t irunena:1;
+ uint64_t data_drpena:1;
+ uint64_t ithena:1;
+ uint64_t othena:1;
+ uint64_t ivfena:1;
+ uint64_t ovfena:1;
+ } cn52xx;
+ struct cvmx_mixx_intena_cn52xx cn52xxp1;
+ struct cvmx_mixx_intena_cn52xx cn56xx;
+ struct cvmx_mixx_intena_cn52xx cn56xxp1;
+ struct cvmx_mixx_intena_s cn63xx;
+ struct cvmx_mixx_intena_s cn63xxp1;
};
union cvmx_mixx_ircnt {
@@ -116,6 +139,8 @@ union cvmx_mixx_ircnt {
struct cvmx_mixx_ircnt_s cn52xxp1;
struct cvmx_mixx_ircnt_s cn56xx;
struct cvmx_mixx_ircnt_s cn56xxp1;
+ struct cvmx_mixx_ircnt_s cn63xx;
+ struct cvmx_mixx_ircnt_s cn63xxp1;
};
union cvmx_mixx_irhwm {
@@ -129,6 +154,8 @@ union cvmx_mixx_irhwm {
struct cvmx_mixx_irhwm_s cn52xxp1;
struct cvmx_mixx_irhwm_s cn56xx;
struct cvmx_mixx_irhwm_s cn56xxp1;
+ struct cvmx_mixx_irhwm_s cn63xx;
+ struct cvmx_mixx_irhwm_s cn63xxp1;
};
union cvmx_mixx_iring1 {
@@ -136,14 +163,21 @@ union cvmx_mixx_iring1 {
struct cvmx_mixx_iring1_s {
uint64_t reserved_60_63:4;
uint64_t isize:20;
+ uint64_t ibase:37;
+ uint64_t reserved_0_2:3;
+ } s;
+ struct cvmx_mixx_iring1_cn52xx {
+ uint64_t reserved_60_63:4;
+ uint64_t isize:20;
uint64_t reserved_36_39:4;
uint64_t ibase:33;
uint64_t reserved_0_2:3;
- } s;
- struct cvmx_mixx_iring1_s cn52xx;
- struct cvmx_mixx_iring1_s cn52xxp1;
- struct cvmx_mixx_iring1_s cn56xx;
- struct cvmx_mixx_iring1_s cn56xxp1;
+ } cn52xx;
+ struct cvmx_mixx_iring1_cn52xx cn52xxp1;
+ struct cvmx_mixx_iring1_cn52xx cn56xx;
+ struct cvmx_mixx_iring1_cn52xx cn56xxp1;
+ struct cvmx_mixx_iring1_s cn63xx;
+ struct cvmx_mixx_iring1_s cn63xxp1;
};
union cvmx_mixx_iring2 {
@@ -158,12 +192,15 @@ union cvmx_mixx_iring2 {
struct cvmx_mixx_iring2_s cn52xxp1;
struct cvmx_mixx_iring2_s cn56xx;
struct cvmx_mixx_iring2_s cn56xxp1;
+ struct cvmx_mixx_iring2_s cn63xx;
+ struct cvmx_mixx_iring2_s cn63xxp1;
};
union cvmx_mixx_isr {
uint64_t u64;
struct cvmx_mixx_isr_s {
- uint64_t reserved_7_63:57;
+ uint64_t reserved_8_63:56;
+ uint64_t ts:1;
uint64_t orun:1;
uint64_t irun:1;
uint64_t data_drp:1;
@@ -172,10 +209,21 @@ union cvmx_mixx_isr {
uint64_t idblovf:1;
uint64_t odblovf:1;
} s;
- struct cvmx_mixx_isr_s cn52xx;
- struct cvmx_mixx_isr_s cn52xxp1;
- struct cvmx_mixx_isr_s cn56xx;
- struct cvmx_mixx_isr_s cn56xxp1;
+ struct cvmx_mixx_isr_cn52xx {
+ uint64_t reserved_7_63:57;
+ uint64_t orun:1;
+ uint64_t irun:1;
+ uint64_t data_drp:1;
+ uint64_t irthresh:1;
+ uint64_t orthresh:1;
+ uint64_t idblovf:1;
+ uint64_t odblovf:1;
+ } cn52xx;
+ struct cvmx_mixx_isr_cn52xx cn52xxp1;
+ struct cvmx_mixx_isr_cn52xx cn56xx;
+ struct cvmx_mixx_isr_cn52xx cn56xxp1;
+ struct cvmx_mixx_isr_s cn63xx;
+ struct cvmx_mixx_isr_s cn63xxp1;
};
union cvmx_mixx_orcnt {
@@ -188,6 +236,8 @@ union cvmx_mixx_orcnt {
struct cvmx_mixx_orcnt_s cn52xxp1;
struct cvmx_mixx_orcnt_s cn56xx;
struct cvmx_mixx_orcnt_s cn56xxp1;
+ struct cvmx_mixx_orcnt_s cn63xx;
+ struct cvmx_mixx_orcnt_s cn63xxp1;
};
union cvmx_mixx_orhwm {
@@ -200,6 +250,8 @@ union cvmx_mixx_orhwm {
struct cvmx_mixx_orhwm_s cn52xxp1;
struct cvmx_mixx_orhwm_s cn56xx;
struct cvmx_mixx_orhwm_s cn56xxp1;
+ struct cvmx_mixx_orhwm_s cn63xx;
+ struct cvmx_mixx_orhwm_s cn63xxp1;
};
union cvmx_mixx_oring1 {
@@ -207,14 +259,21 @@ union cvmx_mixx_oring1 {
struct cvmx_mixx_oring1_s {
uint64_t reserved_60_63:4;
uint64_t osize:20;
+ uint64_t obase:37;
+ uint64_t reserved_0_2:3;
+ } s;
+ struct cvmx_mixx_oring1_cn52xx {
+ uint64_t reserved_60_63:4;
+ uint64_t osize:20;
uint64_t reserved_36_39:4;
uint64_t obase:33;
uint64_t reserved_0_2:3;
- } s;
- struct cvmx_mixx_oring1_s cn52xx;
- struct cvmx_mixx_oring1_s cn52xxp1;
- struct cvmx_mixx_oring1_s cn56xx;
- struct cvmx_mixx_oring1_s cn56xxp1;
+ } cn52xx;
+ struct cvmx_mixx_oring1_cn52xx cn52xxp1;
+ struct cvmx_mixx_oring1_cn52xx cn56xx;
+ struct cvmx_mixx_oring1_cn52xx cn56xxp1;
+ struct cvmx_mixx_oring1_s cn63xx;
+ struct cvmx_mixx_oring1_s cn63xxp1;
};
union cvmx_mixx_oring2 {
@@ -229,6 +288,8 @@ union cvmx_mixx_oring2 {
struct cvmx_mixx_oring2_s cn52xxp1;
struct cvmx_mixx_oring2_s cn56xx;
struct cvmx_mixx_oring2_s cn56xxp1;
+ struct cvmx_mixx_oring2_s cn63xx;
+ struct cvmx_mixx_oring2_s cn63xxp1;
};
union cvmx_mixx_remcnt {
@@ -243,6 +304,31 @@ union cvmx_mixx_remcnt {
struct cvmx_mixx_remcnt_s cn52xxp1;
struct cvmx_mixx_remcnt_s cn56xx;
struct cvmx_mixx_remcnt_s cn56xxp1;
+ struct cvmx_mixx_remcnt_s cn63xx;
+ struct cvmx_mixx_remcnt_s cn63xxp1;
+};
+
+union cvmx_mixx_tsctl {
+ uint64_t u64;
+ struct cvmx_mixx_tsctl_s {
+ uint64_t reserved_21_63:43;
+ uint64_t tsavl:5;
+ uint64_t reserved_13_15:3;
+ uint64_t tstot:5;
+ uint64_t reserved_5_7:3;
+ uint64_t tscnt:5;
+ } s;
+ struct cvmx_mixx_tsctl_s cn63xx;
+ struct cvmx_mixx_tsctl_s cn63xxp1;
+};
+
+union cvmx_mixx_tstamp {
+ uint64_t u64;
+ struct cvmx_mixx_tstamp_s {
+ uint64_t tstamp:64;
+ } s;
+ struct cvmx_mixx_tstamp_s cn63xx;
+ struct cvmx_mixx_tstamp_s cn63xxp1;
};
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-npei-defs.h b/arch/mips/include/asm/octeon/cvmx-npei-defs.h
index 4b347bb8ce80..9899a9d2ba72 100644
--- a/arch/mips/include/asm/octeon/cvmx-npei-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-npei-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
@@ -28,206 +28,114 @@
#ifndef __CVMX_NPEI_DEFS_H__
#define __CVMX_NPEI_DEFS_H__
-#define CVMX_NPEI_BAR1_INDEXX(offset) \
- (0x0000000000000000ull + (((offset) & 31) * 16))
-#define CVMX_NPEI_BIST_STATUS \
- (0x0000000000000580ull)
-#define CVMX_NPEI_BIST_STATUS2 \
- (0x0000000000000680ull)
-#define CVMX_NPEI_CTL_PORT0 \
- (0x0000000000000250ull)
-#define CVMX_NPEI_CTL_PORT1 \
- (0x0000000000000260ull)
-#define CVMX_NPEI_CTL_STATUS \
- (0x0000000000000570ull)
-#define CVMX_NPEI_CTL_STATUS2 \
- (0x0000000000003C00ull)
-#define CVMX_NPEI_DATA_OUT_CNT \
- (0x00000000000005F0ull)
-#define CVMX_NPEI_DBG_DATA \
- (0x0000000000000510ull)
-#define CVMX_NPEI_DBG_SELECT \
- (0x0000000000000500ull)
-#define CVMX_NPEI_DMA0_INT_LEVEL \
- (0x00000000000005C0ull)
-#define CVMX_NPEI_DMA1_INT_LEVEL \
- (0x00000000000005D0ull)
-#define CVMX_NPEI_DMAX_COUNTS(offset) \
- (0x0000000000000450ull + (((offset) & 7) * 16))
-#define CVMX_NPEI_DMAX_DBELL(offset) \
- (0x00000000000003B0ull + (((offset) & 7) * 16))
-#define CVMX_NPEI_DMAX_IBUFF_SADDR(offset) \
- (0x0000000000000400ull + (((offset) & 7) * 16))
-#define CVMX_NPEI_DMAX_NADDR(offset) \
- (0x00000000000004A0ull + (((offset) & 7) * 16))
-#define CVMX_NPEI_DMA_CNTS \
- (0x00000000000005E0ull)
-#define CVMX_NPEI_DMA_CONTROL \
- (0x00000000000003A0ull)
-#define CVMX_NPEI_INT_A_ENB \
- (0x0000000000000560ull)
-#define CVMX_NPEI_INT_A_ENB2 \
- (0x0000000000003CE0ull)
-#define CVMX_NPEI_INT_A_SUM \
- (0x0000000000000550ull)
-#define CVMX_NPEI_INT_ENB \
- (0x0000000000000540ull)
-#define CVMX_NPEI_INT_ENB2 \
- (0x0000000000003CD0ull)
-#define CVMX_NPEI_INT_INFO \
- (0x0000000000000590ull)
-#define CVMX_NPEI_INT_SUM \
- (0x0000000000000530ull)
-#define CVMX_NPEI_INT_SUM2 \
- (0x0000000000003CC0ull)
-#define CVMX_NPEI_LAST_WIN_RDATA0 \
- (0x0000000000000600ull)
-#define CVMX_NPEI_LAST_WIN_RDATA1 \
- (0x0000000000000610ull)
-#define CVMX_NPEI_MEM_ACCESS_CTL \
- (0x00000000000004F0ull)
-#define CVMX_NPEI_MEM_ACCESS_SUBIDX(offset) \
- (0x0000000000000340ull + (((offset) & 31) * 16) - 16 * 12)
-#define CVMX_NPEI_MSI_ENB0 \
- (0x0000000000003C50ull)
-#define CVMX_NPEI_MSI_ENB1 \
- (0x0000000000003C60ull)
-#define CVMX_NPEI_MSI_ENB2 \
- (0x0000000000003C70ull)
-#define CVMX_NPEI_MSI_ENB3 \
- (0x0000000000003C80ull)
-#define CVMX_NPEI_MSI_RCV0 \
- (0x0000000000003C10ull)
-#define CVMX_NPEI_MSI_RCV1 \
- (0x0000000000003C20ull)
-#define CVMX_NPEI_MSI_RCV2 \
- (0x0000000000003C30ull)
-#define CVMX_NPEI_MSI_RCV3 \
- (0x0000000000003C40ull)
-#define CVMX_NPEI_MSI_RD_MAP \
- (0x0000000000003CA0ull)
-#define CVMX_NPEI_MSI_W1C_ENB0 \
- (0x0000000000003CF0ull)
-#define CVMX_NPEI_MSI_W1C_ENB1 \
- (0x0000000000003D00ull)
-#define CVMX_NPEI_MSI_W1C_ENB2 \
- (0x0000000000003D10ull)
-#define CVMX_NPEI_MSI_W1C_ENB3 \
- (0x0000000000003D20ull)
-#define CVMX_NPEI_MSI_W1S_ENB0 \
- (0x0000000000003D30ull)
-#define CVMX_NPEI_MSI_W1S_ENB1 \
- (0x0000000000003D40ull)
-#define CVMX_NPEI_MSI_W1S_ENB2 \
- (0x0000000000003D50ull)
-#define CVMX_NPEI_MSI_W1S_ENB3 \
- (0x0000000000003D60ull)
-#define CVMX_NPEI_MSI_WR_MAP \
- (0x0000000000003C90ull)
-#define CVMX_NPEI_PCIE_CREDIT_CNT \
- (0x0000000000003D70ull)
-#define CVMX_NPEI_PCIE_MSI_RCV \
- (0x0000000000003CB0ull)
-#define CVMX_NPEI_PCIE_MSI_RCV_B1 \
- (0x0000000000000650ull)
-#define CVMX_NPEI_PCIE_MSI_RCV_B2 \
- (0x0000000000000660ull)
-#define CVMX_NPEI_PCIE_MSI_RCV_B3 \
- (0x0000000000000670ull)
-#define CVMX_NPEI_PKTX_CNTS(offset) \
- (0x0000000000002400ull + (((offset) & 31) * 16))
-#define CVMX_NPEI_PKTX_INSTR_BADDR(offset) \
- (0x0000000000002800ull + (((offset) & 31) * 16))
-#define CVMX_NPEI_PKTX_INSTR_BAOFF_DBELL(offset) \
- (0x0000000000002C00ull + (((offset) & 31) * 16))
-#define CVMX_NPEI_PKTX_INSTR_FIFO_RSIZE(offset) \
- (0x0000000000003000ull + (((offset) & 31) * 16))
-#define CVMX_NPEI_PKTX_INSTR_HEADER(offset) \
- (0x0000000000003400ull + (((offset) & 31) * 16))
-#define CVMX_NPEI_PKTX_IN_BP(offset) \
- (0x0000000000003800ull + (((offset) & 31) * 16))
-#define CVMX_NPEI_PKTX_SLIST_BADDR(offset) \
- (0x0000000000001400ull + (((offset) & 31) * 16))
-#define CVMX_NPEI_PKTX_SLIST_BAOFF_DBELL(offset) \
- (0x0000000000001800ull + (((offset) & 31) * 16))
-#define CVMX_NPEI_PKTX_SLIST_FIFO_RSIZE(offset) \
- (0x0000000000001C00ull + (((offset) & 31) * 16))
-#define CVMX_NPEI_PKT_CNT_INT \
- (0x0000000000001110ull)
-#define CVMX_NPEI_PKT_CNT_INT_ENB \
- (0x0000000000001130ull)
-#define CVMX_NPEI_PKT_DATA_OUT_ES \
- (0x00000000000010B0ull)
-#define CVMX_NPEI_PKT_DATA_OUT_NS \
- (0x00000000000010A0ull)
-#define CVMX_NPEI_PKT_DATA_OUT_ROR \
- (0x0000000000001090ull)
-#define CVMX_NPEI_PKT_DPADDR \
- (0x0000000000001080ull)
-#define CVMX_NPEI_PKT_INPUT_CONTROL \
- (0x0000000000001150ull)
-#define CVMX_NPEI_PKT_INSTR_ENB \
- (0x0000000000001000ull)
-#define CVMX_NPEI_PKT_INSTR_RD_SIZE \
- (0x0000000000001190ull)
-#define CVMX_NPEI_PKT_INSTR_SIZE \
- (0x0000000000001020ull)
-#define CVMX_NPEI_PKT_INT_LEVELS \
- (0x0000000000001100ull)
-#define CVMX_NPEI_PKT_IN_BP \
- (0x00000000000006B0ull)
-#define CVMX_NPEI_PKT_IN_DONEX_CNTS(offset) \
- (0x0000000000002000ull + (((offset) & 31) * 16))
-#define CVMX_NPEI_PKT_IN_INSTR_COUNTS \
- (0x00000000000006A0ull)
-#define CVMX_NPEI_PKT_IN_PCIE_PORT \
- (0x00000000000011A0ull)
-#define CVMX_NPEI_PKT_IPTR \
- (0x0000000000001070ull)
-#define CVMX_NPEI_PKT_OUTPUT_WMARK \
- (0x0000000000001160ull)
-#define CVMX_NPEI_PKT_OUT_BMODE \
- (0x00000000000010D0ull)
-#define CVMX_NPEI_PKT_OUT_ENB \
- (0x0000000000001010ull)
-#define CVMX_NPEI_PKT_PCIE_PORT \
- (0x00000000000010E0ull)
-#define CVMX_NPEI_PKT_PORT_IN_RST \
- (0x0000000000000690ull)
-#define CVMX_NPEI_PKT_SLIST_ES \
- (0x0000000000001050ull)
-#define CVMX_NPEI_PKT_SLIST_ID_SIZE \
- (0x0000000000001180ull)
-#define CVMX_NPEI_PKT_SLIST_NS \
- (0x0000000000001040ull)
-#define CVMX_NPEI_PKT_SLIST_ROR \
- (0x0000000000001030ull)
-#define CVMX_NPEI_PKT_TIME_INT \
- (0x0000000000001120ull)
-#define CVMX_NPEI_PKT_TIME_INT_ENB \
- (0x0000000000001140ull)
-#define CVMX_NPEI_RSL_INT_BLOCKS \
- (0x0000000000000520ull)
-#define CVMX_NPEI_SCRATCH_1 \
- (0x0000000000000270ull)
-#define CVMX_NPEI_STATE1 \
- (0x0000000000000620ull)
-#define CVMX_NPEI_STATE2 \
- (0x0000000000000630ull)
-#define CVMX_NPEI_STATE3 \
- (0x0000000000000640ull)
-#define CVMX_NPEI_WINDOW_CTL \
- (0x0000000000000380ull)
-#define CVMX_NPEI_WIN_RD_ADDR \
- (0x0000000000000210ull)
-#define CVMX_NPEI_WIN_RD_DATA \
- (0x0000000000000240ull)
-#define CVMX_NPEI_WIN_WR_ADDR \
- (0x0000000000000200ull)
-#define CVMX_NPEI_WIN_WR_DATA \
- (0x0000000000000220ull)
-#define CVMX_NPEI_WIN_WR_MASK \
- (0x0000000000000230ull)
+#define CVMX_NPEI_BAR1_INDEXX(offset) (0x0000000000000000ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_BIST_STATUS (0x0000000000000580ull)
+#define CVMX_NPEI_BIST_STATUS2 (0x0000000000000680ull)
+#define CVMX_NPEI_CTL_PORT0 (0x0000000000000250ull)
+#define CVMX_NPEI_CTL_PORT1 (0x0000000000000260ull)
+#define CVMX_NPEI_CTL_STATUS (0x0000000000000570ull)
+#define CVMX_NPEI_CTL_STATUS2 (0x0000000000003C00ull)
+#define CVMX_NPEI_DATA_OUT_CNT (0x00000000000005F0ull)
+#define CVMX_NPEI_DBG_DATA (0x0000000000000510ull)
+#define CVMX_NPEI_DBG_SELECT (0x0000000000000500ull)
+#define CVMX_NPEI_DMA0_INT_LEVEL (0x00000000000005C0ull)
+#define CVMX_NPEI_DMA1_INT_LEVEL (0x00000000000005D0ull)
+#define CVMX_NPEI_DMAX_COUNTS(offset) (0x0000000000000450ull + ((offset) & 7) * 16)
+#define CVMX_NPEI_DMAX_DBELL(offset) (0x00000000000003B0ull + ((offset) & 7) * 16)
+#define CVMX_NPEI_DMAX_IBUFF_SADDR(offset) (0x0000000000000400ull + ((offset) & 7) * 16)
+#define CVMX_NPEI_DMAX_NADDR(offset) (0x00000000000004A0ull + ((offset) & 7) * 16)
+#define CVMX_NPEI_DMA_CNTS (0x00000000000005E0ull)
+#define CVMX_NPEI_DMA_CONTROL (0x00000000000003A0ull)
+#define CVMX_NPEI_DMA_PCIE_REQ_NUM (0x00000000000005B0ull)
+#define CVMX_NPEI_DMA_STATE1 (0x00000000000006C0ull)
+#define CVMX_NPEI_DMA_STATE1_P1 (0x0000000000000680ull)
+#define CVMX_NPEI_DMA_STATE2 (0x00000000000006D0ull)
+#define CVMX_NPEI_DMA_STATE2_P1 (0x0000000000000690ull)
+#define CVMX_NPEI_DMA_STATE3_P1 (0x00000000000006A0ull)
+#define CVMX_NPEI_DMA_STATE4_P1 (0x00000000000006B0ull)
+#define CVMX_NPEI_DMA_STATE5_P1 (0x00000000000006C0ull)
+#define CVMX_NPEI_INT_A_ENB (0x0000000000000560ull)
+#define CVMX_NPEI_INT_A_ENB2 (0x0000000000003CE0ull)
+#define CVMX_NPEI_INT_A_SUM (0x0000000000000550ull)
+#define CVMX_NPEI_INT_ENB (0x0000000000000540ull)
+#define CVMX_NPEI_INT_ENB2 (0x0000000000003CD0ull)
+#define CVMX_NPEI_INT_INFO (0x0000000000000590ull)
+#define CVMX_NPEI_INT_SUM (0x0000000000000530ull)
+#define CVMX_NPEI_INT_SUM2 (0x0000000000003CC0ull)
+#define CVMX_NPEI_LAST_WIN_RDATA0 (0x0000000000000600ull)
+#define CVMX_NPEI_LAST_WIN_RDATA1 (0x0000000000000610ull)
+#define CVMX_NPEI_MEM_ACCESS_CTL (0x00000000000004F0ull)
+#define CVMX_NPEI_MEM_ACCESS_SUBIDX(offset) (0x0000000000000340ull + ((offset) & 31) * 16 - 16*12)
+#define CVMX_NPEI_MSI_ENB0 (0x0000000000003C50ull)
+#define CVMX_NPEI_MSI_ENB1 (0x0000000000003C60ull)
+#define CVMX_NPEI_MSI_ENB2 (0x0000000000003C70ull)
+#define CVMX_NPEI_MSI_ENB3 (0x0000000000003C80ull)
+#define CVMX_NPEI_MSI_RCV0 (0x0000000000003C10ull)
+#define CVMX_NPEI_MSI_RCV1 (0x0000000000003C20ull)
+#define CVMX_NPEI_MSI_RCV2 (0x0000000000003C30ull)
+#define CVMX_NPEI_MSI_RCV3 (0x0000000000003C40ull)
+#define CVMX_NPEI_MSI_RD_MAP (0x0000000000003CA0ull)
+#define CVMX_NPEI_MSI_W1C_ENB0 (0x0000000000003CF0ull)
+#define CVMX_NPEI_MSI_W1C_ENB1 (0x0000000000003D00ull)
+#define CVMX_NPEI_MSI_W1C_ENB2 (0x0000000000003D10ull)
+#define CVMX_NPEI_MSI_W1C_ENB3 (0x0000000000003D20ull)
+#define CVMX_NPEI_MSI_W1S_ENB0 (0x0000000000003D30ull)
+#define CVMX_NPEI_MSI_W1S_ENB1 (0x0000000000003D40ull)
+#define CVMX_NPEI_MSI_W1S_ENB2 (0x0000000000003D50ull)
+#define CVMX_NPEI_MSI_W1S_ENB3 (0x0000000000003D60ull)
+#define CVMX_NPEI_MSI_WR_MAP (0x0000000000003C90ull)
+#define CVMX_NPEI_PCIE_CREDIT_CNT (0x0000000000003D70ull)
+#define CVMX_NPEI_PCIE_MSI_RCV (0x0000000000003CB0ull)
+#define CVMX_NPEI_PCIE_MSI_RCV_B1 (0x0000000000000650ull)
+#define CVMX_NPEI_PCIE_MSI_RCV_B2 (0x0000000000000660ull)
+#define CVMX_NPEI_PCIE_MSI_RCV_B3 (0x0000000000000670ull)
+#define CVMX_NPEI_PKTX_CNTS(offset) (0x0000000000002400ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKTX_INSTR_BADDR(offset) (0x0000000000002800ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKTX_INSTR_BAOFF_DBELL(offset) (0x0000000000002C00ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKTX_INSTR_FIFO_RSIZE(offset) (0x0000000000003000ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKTX_INSTR_HEADER(offset) (0x0000000000003400ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKTX_IN_BP(offset) (0x0000000000003800ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKTX_SLIST_BADDR(offset) (0x0000000000001400ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKTX_SLIST_BAOFF_DBELL(offset) (0x0000000000001800ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKTX_SLIST_FIFO_RSIZE(offset) (0x0000000000001C00ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKT_CNT_INT (0x0000000000001110ull)
+#define CVMX_NPEI_PKT_CNT_INT_ENB (0x0000000000001130ull)
+#define CVMX_NPEI_PKT_DATA_OUT_ES (0x00000000000010B0ull)
+#define CVMX_NPEI_PKT_DATA_OUT_NS (0x00000000000010A0ull)
+#define CVMX_NPEI_PKT_DATA_OUT_ROR (0x0000000000001090ull)
+#define CVMX_NPEI_PKT_DPADDR (0x0000000000001080ull)
+#define CVMX_NPEI_PKT_INPUT_CONTROL (0x0000000000001150ull)
+#define CVMX_NPEI_PKT_INSTR_ENB (0x0000000000001000ull)
+#define CVMX_NPEI_PKT_INSTR_RD_SIZE (0x0000000000001190ull)
+#define CVMX_NPEI_PKT_INSTR_SIZE (0x0000000000001020ull)
+#define CVMX_NPEI_PKT_INT_LEVELS (0x0000000000001100ull)
+#define CVMX_NPEI_PKT_IN_BP (0x00000000000006B0ull)
+#define CVMX_NPEI_PKT_IN_DONEX_CNTS(offset) (0x0000000000002000ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKT_IN_INSTR_COUNTS (0x00000000000006A0ull)
+#define CVMX_NPEI_PKT_IN_PCIE_PORT (0x00000000000011A0ull)
+#define CVMX_NPEI_PKT_IPTR (0x0000000000001070ull)
+#define CVMX_NPEI_PKT_OUTPUT_WMARK (0x0000000000001160ull)
+#define CVMX_NPEI_PKT_OUT_BMODE (0x00000000000010D0ull)
+#define CVMX_NPEI_PKT_OUT_ENB (0x0000000000001010ull)
+#define CVMX_NPEI_PKT_PCIE_PORT (0x00000000000010E0ull)
+#define CVMX_NPEI_PKT_PORT_IN_RST (0x0000000000000690ull)
+#define CVMX_NPEI_PKT_SLIST_ES (0x0000000000001050ull)
+#define CVMX_NPEI_PKT_SLIST_ID_SIZE (0x0000000000001180ull)
+#define CVMX_NPEI_PKT_SLIST_NS (0x0000000000001040ull)
+#define CVMX_NPEI_PKT_SLIST_ROR (0x0000000000001030ull)
+#define CVMX_NPEI_PKT_TIME_INT (0x0000000000001120ull)
+#define CVMX_NPEI_PKT_TIME_INT_ENB (0x0000000000001140ull)
+#define CVMX_NPEI_RSL_INT_BLOCKS (0x0000000000000520ull)
+#define CVMX_NPEI_SCRATCH_1 (0x0000000000000270ull)
+#define CVMX_NPEI_STATE1 (0x0000000000000620ull)
+#define CVMX_NPEI_STATE2 (0x0000000000000630ull)
+#define CVMX_NPEI_STATE3 (0x0000000000000640ull)
+#define CVMX_NPEI_WINDOW_CTL (0x0000000000000380ull)
+#define CVMX_NPEI_WIN_RD_ADDR (0x0000000000000210ull)
+#define CVMX_NPEI_WIN_RD_DATA (0x0000000000000240ull)
+#define CVMX_NPEI_WIN_WR_ADDR (0x0000000000000200ull)
+#define CVMX_NPEI_WIN_WR_DATA (0x0000000000000220ull)
+#define CVMX_NPEI_WIN_WR_MASK (0x0000000000000230ull)
union cvmx_npei_bar1_indexx {
uint32_t u32;
@@ -248,9 +156,7 @@ union cvmx_npei_bist_status {
uint64_t u64;
struct cvmx_npei_bist_status_s {
uint64_t pkt_rdf:1;
- uint64_t pkt_pmem:1;
- uint64_t pkt_p1:1;
- uint64_t reserved_60_60:1;
+ uint64_t reserved_60_62:3;
uint64_t pcr_gim:1;
uint64_t pkt_pif:1;
uint64_t pcsr_int:1;
@@ -301,9 +207,7 @@ union cvmx_npei_bist_status {
} s;
struct cvmx_npei_bist_status_cn52xx {
uint64_t pkt_rdf:1;
- uint64_t pkt_pmem:1;
- uint64_t pkt_p1:1;
- uint64_t reserved_60_60:1;
+ uint64_t reserved_60_62:3;
uint64_t pcr_gim:1;
uint64_t pkt_pif:1;
uint64_t pcsr_int:1;
@@ -410,66 +314,7 @@ union cvmx_npei_bist_status {
uint64_t msi:1;
uint64_t ncb_cmd:1;
} cn52xxp1;
- struct cvmx_npei_bist_status_cn56xx {
- uint64_t pkt_rdf:1;
- uint64_t reserved_60_62:3;
- uint64_t pcr_gim:1;
- uint64_t pkt_pif:1;
- uint64_t pcsr_int:1;
- uint64_t pcsr_im:1;
- uint64_t pcsr_cnt:1;
- uint64_t pcsr_id:1;
- uint64_t pcsr_sl:1;
- uint64_t pkt_imem:1;
- uint64_t pkt_pfm:1;
- uint64_t pkt_pof:1;
- uint64_t reserved_48_49:2;
- uint64_t pkt_pop0:1;
- uint64_t pkt_pop1:1;
- uint64_t d0_mem:1;
- uint64_t d1_mem:1;
- uint64_t d2_mem:1;
- uint64_t d3_mem:1;
- uint64_t d4_mem:1;
- uint64_t ds_mem:1;
- uint64_t reserved_36_39:4;
- uint64_t d0_pst:1;
- uint64_t d1_pst:1;
- uint64_t d2_pst:1;
- uint64_t d3_pst:1;
- uint64_t d4_pst:1;
- uint64_t n2p0_c:1;
- uint64_t n2p0_o:1;
- uint64_t n2p1_c:1;
- uint64_t n2p1_o:1;
- uint64_t cpl_p0:1;
- uint64_t cpl_p1:1;
- uint64_t p2n1_po:1;
- uint64_t p2n1_no:1;
- uint64_t p2n1_co:1;
- uint64_t p2n0_po:1;
- uint64_t p2n0_no:1;
- uint64_t p2n0_co:1;
- uint64_t p2n0_c0:1;
- uint64_t p2n0_c1:1;
- uint64_t p2n0_n:1;
- uint64_t p2n0_p0:1;
- uint64_t p2n0_p1:1;
- uint64_t p2n1_c0:1;
- uint64_t p2n1_c1:1;
- uint64_t p2n1_n:1;
- uint64_t p2n1_p0:1;
- uint64_t p2n1_p1:1;
- uint64_t csm0:1;
- uint64_t csm1:1;
- uint64_t dif0:1;
- uint64_t dif1:1;
- uint64_t dif2:1;
- uint64_t dif3:1;
- uint64_t dif4:1;
- uint64_t msi:1;
- uint64_t ncb_cmd:1;
- } cn56xx;
+ struct cvmx_npei_bist_status_cn52xx cn56xx;
struct cvmx_npei_bist_status_cn56xxp1 {
uint64_t reserved_58_63:6;
uint64_t pcsr_int:1;
@@ -536,7 +381,16 @@ union cvmx_npei_bist_status {
union cvmx_npei_bist_status2 {
uint64_t u64;
struct cvmx_npei_bist_status2_s {
- uint64_t reserved_5_63:59;
+ uint64_t reserved_14_63:50;
+ uint64_t prd_tag:1;
+ uint64_t prd_st0:1;
+ uint64_t prd_st1:1;
+ uint64_t prd_err:1;
+ uint64_t nrd_st:1;
+ uint64_t nwe_st:1;
+ uint64_t nwe_wr0:1;
+ uint64_t nwe_wr1:1;
+ uint64_t pkt_rd:1;
uint64_t psc_p0:1;
uint64_t psc_p1:1;
uint64_t pkt_gd:1;
@@ -630,8 +484,7 @@ union cvmx_npei_ctl_status {
} cn52xxp1;
struct cvmx_npei_ctl_status_s cn56xx;
struct cvmx_npei_ctl_status_cn56xxp1 {
- uint64_t reserved_16_63:48;
- uint64_t ring_en:1;
+ uint64_t reserved_15_63:49;
uint64_t lnk_rst:1;
uint64_t arb:1;
uint64_t pkt_bp:4;
@@ -756,14 +609,14 @@ union cvmx_npei_dmax_ibuff_saddr {
uint64_t saddr:29;
uint64_t reserved_0_6:7;
} s;
- struct cvmx_npei_dmax_ibuff_saddr_cn52xx {
+ struct cvmx_npei_dmax_ibuff_saddr_s cn52xx;
+ struct cvmx_npei_dmax_ibuff_saddr_cn52xxp1 {
uint64_t reserved_36_63:28;
uint64_t saddr:29;
uint64_t reserved_0_6:7;
- } cn52xx;
- struct cvmx_npei_dmax_ibuff_saddr_cn52xx cn52xxp1;
+ } cn52xxp1;
struct cvmx_npei_dmax_ibuff_saddr_s cn56xx;
- struct cvmx_npei_dmax_ibuff_saddr_cn52xx cn56xxp1;
+ struct cvmx_npei_dmax_ibuff_saddr_cn52xxp1 cn56xxp1;
};
union cvmx_npei_dmax_naddr {
@@ -817,7 +670,8 @@ union cvmx_npei_dma_cnts {
union cvmx_npei_dma_control {
uint64_t u64;
struct cvmx_npei_dma_control_s {
- uint64_t reserved_39_63:25;
+ uint64_t reserved_40_63:24;
+ uint64_t p_32b_m:1;
uint64_t dma4_enb:1;
uint64_t dma3_enb:1;
uint64_t dma2_enb:1;
@@ -853,7 +707,161 @@ union cvmx_npei_dma_control {
uint64_t csize:14;
} cn52xxp1;
struct cvmx_npei_dma_control_s cn56xx;
- struct cvmx_npei_dma_control_s cn56xxp1;
+ struct cvmx_npei_dma_control_cn56xxp1 {
+ uint64_t reserved_39_63:25;
+ uint64_t dma4_enb:1;
+ uint64_t dma3_enb:1;
+ uint64_t dma2_enb:1;
+ uint64_t dma1_enb:1;
+ uint64_t dma0_enb:1;
+ uint64_t b0_lend:1;
+ uint64_t dwb_denb:1;
+ uint64_t dwb_ichk:9;
+ uint64_t fpa_que:3;
+ uint64_t o_add1:1;
+ uint64_t o_ro:1;
+ uint64_t o_ns:1;
+ uint64_t o_es:2;
+ uint64_t o_mode:1;
+ uint64_t csize:14;
+ } cn56xxp1;
+};
+
+union cvmx_npei_dma_pcie_req_num {
+ uint64_t u64;
+ struct cvmx_npei_dma_pcie_req_num_s {
+ uint64_t dma_arb:1;
+ uint64_t reserved_53_62:10;
+ uint64_t pkt_cnt:5;
+ uint64_t reserved_45_47:3;
+ uint64_t dma4_cnt:5;
+ uint64_t reserved_37_39:3;
+ uint64_t dma3_cnt:5;
+ uint64_t reserved_29_31:3;
+ uint64_t dma2_cnt:5;
+ uint64_t reserved_21_23:3;
+ uint64_t dma1_cnt:5;
+ uint64_t reserved_13_15:3;
+ uint64_t dma0_cnt:5;
+ uint64_t reserved_5_7:3;
+ uint64_t dma_cnt:5;
+ } s;
+ struct cvmx_npei_dma_pcie_req_num_s cn52xx;
+ struct cvmx_npei_dma_pcie_req_num_s cn56xx;
+};
+
+union cvmx_npei_dma_state1 {
+ uint64_t u64;
+ struct cvmx_npei_dma_state1_s {
+ uint64_t reserved_40_63:24;
+ uint64_t d4_dwe:8;
+ uint64_t d3_dwe:8;
+ uint64_t d2_dwe:8;
+ uint64_t d1_dwe:8;
+ uint64_t d0_dwe:8;
+ } s;
+ struct cvmx_npei_dma_state1_s cn52xx;
+};
+
+union cvmx_npei_dma_state1_p1 {
+ uint64_t u64;
+ struct cvmx_npei_dma_state1_p1_s {
+ uint64_t reserved_60_63:4;
+ uint64_t d0_difst:7;
+ uint64_t d1_difst:7;
+ uint64_t d2_difst:7;
+ uint64_t d3_difst:7;
+ uint64_t d4_difst:7;
+ uint64_t d0_reqst:5;
+ uint64_t d1_reqst:5;
+ uint64_t d2_reqst:5;
+ uint64_t d3_reqst:5;
+ uint64_t d4_reqst:5;
+ } s;
+ struct cvmx_npei_dma_state1_p1_cn52xxp1 {
+ uint64_t reserved_60_63:4;
+ uint64_t d0_difst:7;
+ uint64_t d1_difst:7;
+ uint64_t d2_difst:7;
+ uint64_t d3_difst:7;
+ uint64_t reserved_25_31:7;
+ uint64_t d0_reqst:5;
+ uint64_t d1_reqst:5;
+ uint64_t d2_reqst:5;
+ uint64_t d3_reqst:5;
+ uint64_t reserved_0_4:5;
+ } cn52xxp1;
+ struct cvmx_npei_dma_state1_p1_s cn56xxp1;
+};
+
+union cvmx_npei_dma_state2 {
+ uint64_t u64;
+ struct cvmx_npei_dma_state2_s {
+ uint64_t reserved_28_63:36;
+ uint64_t ndwe:4;
+ uint64_t reserved_21_23:3;
+ uint64_t ndre:5;
+ uint64_t reserved_10_15:6;
+ uint64_t prd:10;
+ } s;
+ struct cvmx_npei_dma_state2_s cn52xx;
+};
+
+union cvmx_npei_dma_state2_p1 {
+ uint64_t u64;
+ struct cvmx_npei_dma_state2_p1_s {
+ uint64_t reserved_45_63:19;
+ uint64_t d0_dffst:9;
+ uint64_t d1_dffst:9;
+ uint64_t d2_dffst:9;
+ uint64_t d3_dffst:9;
+ uint64_t d4_dffst:9;
+ } s;
+ struct cvmx_npei_dma_state2_p1_cn52xxp1 {
+ uint64_t reserved_45_63:19;
+ uint64_t d0_dffst:9;
+ uint64_t d1_dffst:9;
+ uint64_t d2_dffst:9;
+ uint64_t d3_dffst:9;
+ uint64_t reserved_0_8:9;
+ } cn52xxp1;
+ struct cvmx_npei_dma_state2_p1_s cn56xxp1;
+};
+
+union cvmx_npei_dma_state3_p1 {
+ uint64_t u64;
+ struct cvmx_npei_dma_state3_p1_s {
+ uint64_t reserved_60_63:4;
+ uint64_t d0_drest:15;
+ uint64_t d1_drest:15;
+ uint64_t d2_drest:15;
+ uint64_t d3_drest:15;
+ } s;
+ struct cvmx_npei_dma_state3_p1_s cn52xxp1;
+ struct cvmx_npei_dma_state3_p1_s cn56xxp1;
+};
+
+union cvmx_npei_dma_state4_p1 {
+ uint64_t u64;
+ struct cvmx_npei_dma_state4_p1_s {
+ uint64_t reserved_52_63:12;
+ uint64_t d0_dwest:13;
+ uint64_t d1_dwest:13;
+ uint64_t d2_dwest:13;
+ uint64_t d3_dwest:13;
+ } s;
+ struct cvmx_npei_dma_state4_p1_s cn52xxp1;
+ struct cvmx_npei_dma_state4_p1_s cn56xxp1;
+};
+
+union cvmx_npei_dma_state5_p1 {
+ uint64_t u64;
+ struct cvmx_npei_dma_state5_p1_s {
+ uint64_t reserved_28_63:36;
+ uint64_t d4_drest:15;
+ uint64_t d4_dwest:13;
+ } s;
+ struct cvmx_npei_dma_state5_p1_s cn56xxp1;
};
union cvmx_npei_int_a_enb {
@@ -871,17 +879,7 @@ union cvmx_npei_int_a_enb {
uint64_t dma1_cpl:1;
uint64_t dma0_cpl:1;
} s;
- struct cvmx_npei_int_a_enb_cn52xx {
- uint64_t reserved_8_63:56;
- uint64_t p1_rdlk:1;
- uint64_t p0_rdlk:1;
- uint64_t pgl_err:1;
- uint64_t pdi_err:1;
- uint64_t pop_err:1;
- uint64_t pins_err:1;
- uint64_t dma1_cpl:1;
- uint64_t dma0_cpl:1;
- } cn52xx;
+ struct cvmx_npei_int_a_enb_s cn52xx;
struct cvmx_npei_int_a_enb_cn52xxp1 {
uint64_t reserved_2_63:62;
uint64_t dma1_cpl:1;
@@ -905,16 +903,7 @@ union cvmx_npei_int_a_enb2 {
uint64_t dma1_cpl:1;
uint64_t dma0_cpl:1;
} s;
- struct cvmx_npei_int_a_enb2_cn52xx {
- uint64_t reserved_8_63:56;
- uint64_t p1_rdlk:1;
- uint64_t p0_rdlk:1;
- uint64_t pgl_err:1;
- uint64_t pdi_err:1;
- uint64_t pop_err:1;
- uint64_t pins_err:1;
- uint64_t reserved_0_1:2;
- } cn52xx;
+ struct cvmx_npei_int_a_enb2_s cn52xx;
struct cvmx_npei_int_a_enb2_cn52xxp1 {
uint64_t reserved_2_63:62;
uint64_t dma1_cpl:1;
@@ -938,17 +927,7 @@ union cvmx_npei_int_a_sum {
uint64_t dma1_cpl:1;
uint64_t dma0_cpl:1;
} s;
- struct cvmx_npei_int_a_sum_cn52xx {
- uint64_t reserved_8_63:56;
- uint64_t p1_rdlk:1;
- uint64_t p0_rdlk:1;
- uint64_t pgl_err:1;
- uint64_t pdi_err:1;
- uint64_t pop_err:1;
- uint64_t pins_err:1;
- uint64_t dma1_cpl:1;
- uint64_t dma0_cpl:1;
- } cn52xx;
+ struct cvmx_npei_int_a_sum_s cn52xx;
struct cvmx_npei_int_a_sum_cn52xxp1 {
uint64_t reserved_2_63:62;
uint64_t dma1_cpl:1;
@@ -1550,10 +1529,7 @@ union cvmx_npei_int_sum {
uint64_t c0_se:1;
uint64_t reserved_20_20:1;
uint64_t c0_aeri:1;
- uint64_t ptime:1;
- uint64_t pcnt:1;
- uint64_t pidbof:1;
- uint64_t psldbof:1;
+ uint64_t reserved_15_18:4;
uint64_t dtime1:1;
uint64_t dtime0:1;
uint64_t dcnt1:1;
@@ -1959,7 +1935,6 @@ union cvmx_npei_pktx_cnts {
} s;
struct cvmx_npei_pktx_cnts_s cn52xx;
struct cvmx_npei_pktx_cnts_s cn56xx;
- struct cvmx_npei_pktx_cnts_s cn56xxp1;
};
union cvmx_npei_pktx_in_bp {
@@ -1970,7 +1945,6 @@ union cvmx_npei_pktx_in_bp {
} s;
struct cvmx_npei_pktx_in_bp_s cn52xx;
struct cvmx_npei_pktx_in_bp_s cn56xx;
- struct cvmx_npei_pktx_in_bp_s cn56xxp1;
};
union cvmx_npei_pktx_instr_baddr {
@@ -1981,7 +1955,6 @@ union cvmx_npei_pktx_instr_baddr {
} s;
struct cvmx_npei_pktx_instr_baddr_s cn52xx;
struct cvmx_npei_pktx_instr_baddr_s cn56xx;
- struct cvmx_npei_pktx_instr_baddr_s cn56xxp1;
};
union cvmx_npei_pktx_instr_baoff_dbell {
@@ -1992,7 +1965,6 @@ union cvmx_npei_pktx_instr_baoff_dbell {
} s;
struct cvmx_npei_pktx_instr_baoff_dbell_s cn52xx;
struct cvmx_npei_pktx_instr_baoff_dbell_s cn56xx;
- struct cvmx_npei_pktx_instr_baoff_dbell_s cn56xxp1;
};
union cvmx_npei_pktx_instr_fifo_rsize {
@@ -2006,7 +1978,6 @@ union cvmx_npei_pktx_instr_fifo_rsize {
} s;
struct cvmx_npei_pktx_instr_fifo_rsize_s cn52xx;
struct cvmx_npei_pktx_instr_fifo_rsize_s cn56xx;
- struct cvmx_npei_pktx_instr_fifo_rsize_s cn56xxp1;
};
union cvmx_npei_pktx_instr_header {
@@ -2014,21 +1985,20 @@ union cvmx_npei_pktx_instr_header {
struct cvmx_npei_pktx_instr_header_s {
uint64_t reserved_44_63:20;
uint64_t pbp:1;
- uint64_t rsv_f:5;
+ uint64_t reserved_38_42:5;
uint64_t rparmode:2;
- uint64_t rsv_e:1;
+ uint64_t reserved_35_35:1;
uint64_t rskp_len:7;
- uint64_t rsv_d:6;
+ uint64_t reserved_22_27:6;
uint64_t use_ihdr:1;
- uint64_t rsv_c:5;
+ uint64_t reserved_16_20:5;
uint64_t par_mode:2;
- uint64_t rsv_b:1;
+ uint64_t reserved_13_13:1;
uint64_t skp_len:7;
- uint64_t rsv_a:6;
+ uint64_t reserved_0_5:6;
} s;
struct cvmx_npei_pktx_instr_header_s cn52xx;
struct cvmx_npei_pktx_instr_header_s cn56xx;
- struct cvmx_npei_pktx_instr_header_s cn56xxp1;
};
union cvmx_npei_pktx_slist_baddr {
@@ -2039,7 +2009,6 @@ union cvmx_npei_pktx_slist_baddr {
} s;
struct cvmx_npei_pktx_slist_baddr_s cn52xx;
struct cvmx_npei_pktx_slist_baddr_s cn56xx;
- struct cvmx_npei_pktx_slist_baddr_s cn56xxp1;
};
union cvmx_npei_pktx_slist_baoff_dbell {
@@ -2050,7 +2019,6 @@ union cvmx_npei_pktx_slist_baoff_dbell {
} s;
struct cvmx_npei_pktx_slist_baoff_dbell_s cn52xx;
struct cvmx_npei_pktx_slist_baoff_dbell_s cn56xx;
- struct cvmx_npei_pktx_slist_baoff_dbell_s cn56xxp1;
};
union cvmx_npei_pktx_slist_fifo_rsize {
@@ -2061,7 +2029,6 @@ union cvmx_npei_pktx_slist_fifo_rsize {
} s;
struct cvmx_npei_pktx_slist_fifo_rsize_s cn52xx;
struct cvmx_npei_pktx_slist_fifo_rsize_s cn56xx;
- struct cvmx_npei_pktx_slist_fifo_rsize_s cn56xxp1;
};
union cvmx_npei_pkt_cnt_int {
@@ -2072,7 +2039,6 @@ union cvmx_npei_pkt_cnt_int {
} s;
struct cvmx_npei_pkt_cnt_int_s cn52xx;
struct cvmx_npei_pkt_cnt_int_s cn56xx;
- struct cvmx_npei_pkt_cnt_int_s cn56xxp1;
};
union cvmx_npei_pkt_cnt_int_enb {
@@ -2083,7 +2049,6 @@ union cvmx_npei_pkt_cnt_int_enb {
} s;
struct cvmx_npei_pkt_cnt_int_enb_s cn52xx;
struct cvmx_npei_pkt_cnt_int_enb_s cn56xx;
- struct cvmx_npei_pkt_cnt_int_enb_s cn56xxp1;
};
union cvmx_npei_pkt_data_out_es {
@@ -2093,7 +2058,6 @@ union cvmx_npei_pkt_data_out_es {
} s;
struct cvmx_npei_pkt_data_out_es_s cn52xx;
struct cvmx_npei_pkt_data_out_es_s cn56xx;
- struct cvmx_npei_pkt_data_out_es_s cn56xxp1;
};
union cvmx_npei_pkt_data_out_ns {
@@ -2104,7 +2068,6 @@ union cvmx_npei_pkt_data_out_ns {
} s;
struct cvmx_npei_pkt_data_out_ns_s cn52xx;
struct cvmx_npei_pkt_data_out_ns_s cn56xx;
- struct cvmx_npei_pkt_data_out_ns_s cn56xxp1;
};
union cvmx_npei_pkt_data_out_ror {
@@ -2115,7 +2078,6 @@ union cvmx_npei_pkt_data_out_ror {
} s;
struct cvmx_npei_pkt_data_out_ror_s cn52xx;
struct cvmx_npei_pkt_data_out_ror_s cn56xx;
- struct cvmx_npei_pkt_data_out_ror_s cn56xxp1;
};
union cvmx_npei_pkt_dpaddr {
@@ -2126,7 +2088,6 @@ union cvmx_npei_pkt_dpaddr {
} s;
struct cvmx_npei_pkt_dpaddr_s cn52xx;
struct cvmx_npei_pkt_dpaddr_s cn56xx;
- struct cvmx_npei_pkt_dpaddr_s cn56xxp1;
};
union cvmx_npei_pkt_in_bp {
@@ -2135,6 +2096,7 @@ union cvmx_npei_pkt_in_bp {
uint64_t reserved_32_63:32;
uint64_t bp:32;
} s;
+ struct cvmx_npei_pkt_in_bp_s cn52xx;
struct cvmx_npei_pkt_in_bp_s cn56xx;
};
@@ -2146,7 +2108,6 @@ union cvmx_npei_pkt_in_donex_cnts {
} s;
struct cvmx_npei_pkt_in_donex_cnts_s cn52xx;
struct cvmx_npei_pkt_in_donex_cnts_s cn56xx;
- struct cvmx_npei_pkt_in_donex_cnts_s cn56xxp1;
};
union cvmx_npei_pkt_in_instr_counts {
@@ -2184,7 +2145,6 @@ union cvmx_npei_pkt_input_control {
} s;
struct cvmx_npei_pkt_input_control_s cn52xx;
struct cvmx_npei_pkt_input_control_s cn56xx;
- struct cvmx_npei_pkt_input_control_s cn56xxp1;
};
union cvmx_npei_pkt_instr_enb {
@@ -2195,7 +2155,6 @@ union cvmx_npei_pkt_instr_enb {
} s;
struct cvmx_npei_pkt_instr_enb_s cn52xx;
struct cvmx_npei_pkt_instr_enb_s cn56xx;
- struct cvmx_npei_pkt_instr_enb_s cn56xxp1;
};
union cvmx_npei_pkt_instr_rd_size {
@@ -2215,7 +2174,6 @@ union cvmx_npei_pkt_instr_size {
} s;
struct cvmx_npei_pkt_instr_size_s cn52xx;
struct cvmx_npei_pkt_instr_size_s cn56xx;
- struct cvmx_npei_pkt_instr_size_s cn56xxp1;
};
union cvmx_npei_pkt_int_levels {
@@ -2227,7 +2185,6 @@ union cvmx_npei_pkt_int_levels {
} s;
struct cvmx_npei_pkt_int_levels_s cn52xx;
struct cvmx_npei_pkt_int_levels_s cn56xx;
- struct cvmx_npei_pkt_int_levels_s cn56xxp1;
};
union cvmx_npei_pkt_iptr {
@@ -2238,7 +2195,6 @@ union cvmx_npei_pkt_iptr {
} s;
struct cvmx_npei_pkt_iptr_s cn52xx;
struct cvmx_npei_pkt_iptr_s cn56xx;
- struct cvmx_npei_pkt_iptr_s cn56xxp1;
};
union cvmx_npei_pkt_out_bmode {
@@ -2249,7 +2205,6 @@ union cvmx_npei_pkt_out_bmode {
} s;
struct cvmx_npei_pkt_out_bmode_s cn52xx;
struct cvmx_npei_pkt_out_bmode_s cn56xx;
- struct cvmx_npei_pkt_out_bmode_s cn56xxp1;
};
union cvmx_npei_pkt_out_enb {
@@ -2260,7 +2215,6 @@ union cvmx_npei_pkt_out_enb {
} s;
struct cvmx_npei_pkt_out_enb_s cn52xx;
struct cvmx_npei_pkt_out_enb_s cn56xx;
- struct cvmx_npei_pkt_out_enb_s cn56xxp1;
};
union cvmx_npei_pkt_output_wmark {
@@ -2280,7 +2234,6 @@ union cvmx_npei_pkt_pcie_port {
} s;
struct cvmx_npei_pkt_pcie_port_s cn52xx;
struct cvmx_npei_pkt_pcie_port_s cn56xx;
- struct cvmx_npei_pkt_pcie_port_s cn56xxp1;
};
union cvmx_npei_pkt_port_in_rst {
@@ -2300,7 +2253,6 @@ union cvmx_npei_pkt_slist_es {
} s;
struct cvmx_npei_pkt_slist_es_s cn52xx;
struct cvmx_npei_pkt_slist_es_s cn56xx;
- struct cvmx_npei_pkt_slist_es_s cn56xxp1;
};
union cvmx_npei_pkt_slist_id_size {
@@ -2312,7 +2264,6 @@ union cvmx_npei_pkt_slist_id_size {
} s;
struct cvmx_npei_pkt_slist_id_size_s cn52xx;
struct cvmx_npei_pkt_slist_id_size_s cn56xx;
- struct cvmx_npei_pkt_slist_id_size_s cn56xxp1;
};
union cvmx_npei_pkt_slist_ns {
@@ -2323,7 +2274,6 @@ union cvmx_npei_pkt_slist_ns {
} s;
struct cvmx_npei_pkt_slist_ns_s cn52xx;
struct cvmx_npei_pkt_slist_ns_s cn56xx;
- struct cvmx_npei_pkt_slist_ns_s cn56xxp1;
};
union cvmx_npei_pkt_slist_ror {
@@ -2334,7 +2284,6 @@ union cvmx_npei_pkt_slist_ror {
} s;
struct cvmx_npei_pkt_slist_ror_s cn52xx;
struct cvmx_npei_pkt_slist_ror_s cn56xx;
- struct cvmx_npei_pkt_slist_ror_s cn56xxp1;
};
union cvmx_npei_pkt_time_int {
@@ -2345,7 +2294,6 @@ union cvmx_npei_pkt_time_int {
} s;
struct cvmx_npei_pkt_time_int_s cn52xx;
struct cvmx_npei_pkt_time_int_s cn56xx;
- struct cvmx_npei_pkt_time_int_s cn56xxp1;
};
union cvmx_npei_pkt_time_int_enb {
@@ -2356,7 +2304,6 @@ union cvmx_npei_pkt_time_int_enb {
} s;
struct cvmx_npei_pkt_time_int_enb_s cn52xx;
struct cvmx_npei_pkt_time_int_enb_s cn56xx;
- struct cvmx_npei_pkt_time_int_enb_s cn56xxp1;
};
union cvmx_npei_rsl_int_blocks {
@@ -2371,7 +2318,8 @@ union cvmx_npei_rsl_int_blocks {
uint64_t asxpcs0:1;
uint64_t reserved_21_21:1;
uint64_t pip:1;
- uint64_t reserved_18_19:2;
+ uint64_t spx1:1;
+ uint64_t spx0:1;
uint64_t lmc0:1;
uint64_t l2c:1;
uint64_t usb1:1;
@@ -2383,7 +2331,7 @@ union cvmx_npei_rsl_int_blocks {
uint64_t ipd:1;
uint64_t reserved_8_8:1;
uint64_t zip:1;
- uint64_t reserved_6_6:1;
+ uint64_t dfa:1;
uint64_t fpa:1;
uint64_t key:1;
uint64_t npei:1;
@@ -2393,37 +2341,8 @@ union cvmx_npei_rsl_int_blocks {
} s;
struct cvmx_npei_rsl_int_blocks_s cn52xx;
struct cvmx_npei_rsl_int_blocks_s cn52xxp1;
- struct cvmx_npei_rsl_int_blocks_cn56xx {
- uint64_t reserved_31_63:33;
- uint64_t iob:1;
- uint64_t lmc1:1;
- uint64_t agl:1;
- uint64_t reserved_24_27:4;
- uint64_t asxpcs1:1;
- uint64_t asxpcs0:1;
- uint64_t reserved_21_21:1;
- uint64_t pip:1;
- uint64_t reserved_18_19:2;
- uint64_t lmc0:1;
- uint64_t l2c:1;
- uint64_t reserved_15_15:1;
- uint64_t rad:1;
- uint64_t usb:1;
- uint64_t pow:1;
- uint64_t tim:1;
- uint64_t pko:1;
- uint64_t ipd:1;
- uint64_t reserved_8_8:1;
- uint64_t zip:1;
- uint64_t reserved_6_6:1;
- uint64_t fpa:1;
- uint64_t key:1;
- uint64_t npei:1;
- uint64_t gmx1:1;
- uint64_t gmx0:1;
- uint64_t mio:1;
- } cn56xx;
- struct cvmx_npei_rsl_int_blocks_cn56xx cn56xxp1;
+ struct cvmx_npei_rsl_int_blocks_s cn56xx;
+ struct cvmx_npei_rsl_int_blocks_s cn56xxp1;
};
union cvmx_npei_scratch_1 {
diff --git a/arch/mips/include/asm/octeon/cvmx-npi-defs.h b/arch/mips/include/asm/octeon/cvmx-npi-defs.h
index 4e03cd8561e3..f089c780060f 100644
--- a/arch/mips/include/asm/octeon/cvmx-npi-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-npi-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
@@ -28,246 +28,126 @@
#ifndef __CVMX_NPI_DEFS_H__
#define __CVMX_NPI_DEFS_H__
-#define CVMX_NPI_BASE_ADDR_INPUT0 \
- CVMX_ADD_IO_SEG(0x00011F0000000070ull)
-#define CVMX_NPI_BASE_ADDR_INPUT1 \
- CVMX_ADD_IO_SEG(0x00011F0000000080ull)
-#define CVMX_NPI_BASE_ADDR_INPUT2 \
- CVMX_ADD_IO_SEG(0x00011F0000000090ull)
-#define CVMX_NPI_BASE_ADDR_INPUT3 \
- CVMX_ADD_IO_SEG(0x00011F00000000A0ull)
-#define CVMX_NPI_BASE_ADDR_INPUTX(offset) \
- CVMX_ADD_IO_SEG(0x00011F0000000070ull + (((offset) & 3) * 16))
-#define CVMX_NPI_BASE_ADDR_OUTPUT0 \
- CVMX_ADD_IO_SEG(0x00011F00000000B8ull)
-#define CVMX_NPI_BASE_ADDR_OUTPUT1 \
- CVMX_ADD_IO_SEG(0x00011F00000000C0ull)
-#define CVMX_NPI_BASE_ADDR_OUTPUT2 \
- CVMX_ADD_IO_SEG(0x00011F00000000C8ull)
-#define CVMX_NPI_BASE_ADDR_OUTPUT3 \
- CVMX_ADD_IO_SEG(0x00011F00000000D0ull)
-#define CVMX_NPI_BASE_ADDR_OUTPUTX(offset) \
- CVMX_ADD_IO_SEG(0x00011F00000000B8ull + (((offset) & 3) * 8))
-#define CVMX_NPI_BIST_STATUS \
- CVMX_ADD_IO_SEG(0x00011F00000003F8ull)
-#define CVMX_NPI_BUFF_SIZE_OUTPUT0 \
- CVMX_ADD_IO_SEG(0x00011F00000000E0ull)
-#define CVMX_NPI_BUFF_SIZE_OUTPUT1 \
- CVMX_ADD_IO_SEG(0x00011F00000000E8ull)
-#define CVMX_NPI_BUFF_SIZE_OUTPUT2 \
- CVMX_ADD_IO_SEG(0x00011F00000000F0ull)
-#define CVMX_NPI_BUFF_SIZE_OUTPUT3 \
- CVMX_ADD_IO_SEG(0x00011F00000000F8ull)
-#define CVMX_NPI_BUFF_SIZE_OUTPUTX(offset) \
- CVMX_ADD_IO_SEG(0x00011F00000000E0ull + (((offset) & 3) * 8))
-#define CVMX_NPI_COMP_CTL \
- CVMX_ADD_IO_SEG(0x00011F0000000218ull)
-#define CVMX_NPI_CTL_STATUS \
- CVMX_ADD_IO_SEG(0x00011F0000000010ull)
-#define CVMX_NPI_DBG_SELECT \
- CVMX_ADD_IO_SEG(0x00011F0000000008ull)
-#define CVMX_NPI_DMA_CONTROL \
- CVMX_ADD_IO_SEG(0x00011F0000000128ull)
-#define CVMX_NPI_DMA_HIGHP_COUNTS \
- CVMX_ADD_IO_SEG(0x00011F0000000148ull)
-#define CVMX_NPI_DMA_HIGHP_NADDR \
- CVMX_ADD_IO_SEG(0x00011F0000000158ull)
-#define CVMX_NPI_DMA_LOWP_COUNTS \
- CVMX_ADD_IO_SEG(0x00011F0000000140ull)
-#define CVMX_NPI_DMA_LOWP_NADDR \
- CVMX_ADD_IO_SEG(0x00011F0000000150ull)
-#define CVMX_NPI_HIGHP_DBELL \
- CVMX_ADD_IO_SEG(0x00011F0000000120ull)
-#define CVMX_NPI_HIGHP_IBUFF_SADDR \
- CVMX_ADD_IO_SEG(0x00011F0000000110ull)
-#define CVMX_NPI_INPUT_CONTROL \
- CVMX_ADD_IO_SEG(0x00011F0000000138ull)
-#define CVMX_NPI_INT_ENB \
- CVMX_ADD_IO_SEG(0x00011F0000000020ull)
-#define CVMX_NPI_INT_SUM \
- CVMX_ADD_IO_SEG(0x00011F0000000018ull)
-#define CVMX_NPI_LOWP_DBELL \
- CVMX_ADD_IO_SEG(0x00011F0000000118ull)
-#define CVMX_NPI_LOWP_IBUFF_SADDR \
- CVMX_ADD_IO_SEG(0x00011F0000000108ull)
-#define CVMX_NPI_MEM_ACCESS_SUBID3 \
- CVMX_ADD_IO_SEG(0x00011F0000000028ull)
-#define CVMX_NPI_MEM_ACCESS_SUBID4 \
- CVMX_ADD_IO_SEG(0x00011F0000000030ull)
-#define CVMX_NPI_MEM_ACCESS_SUBID5 \
- CVMX_ADD_IO_SEG(0x00011F0000000038ull)
-#define CVMX_NPI_MEM_ACCESS_SUBID6 \
- CVMX_ADD_IO_SEG(0x00011F0000000040ull)
-#define CVMX_NPI_MEM_ACCESS_SUBIDX(offset) \
- CVMX_ADD_IO_SEG(0x00011F0000000028ull + (((offset) & 7) * 8) - 8 * 3)
-#define CVMX_NPI_MSI_RCV \
- (0x0000000000000190ull)
-#define CVMX_NPI_NPI_MSI_RCV \
- CVMX_ADD_IO_SEG(0x00011F0000001190ull)
-#define CVMX_NPI_NUM_DESC_OUTPUT0 \
- CVMX_ADD_IO_SEG(0x00011F0000000050ull)
-#define CVMX_NPI_NUM_DESC_OUTPUT1 \
- CVMX_ADD_IO_SEG(0x00011F0000000058ull)
-#define CVMX_NPI_NUM_DESC_OUTPUT2 \
- CVMX_ADD_IO_SEG(0x00011F0000000060ull)
-#define CVMX_NPI_NUM_DESC_OUTPUT3 \
- CVMX_ADD_IO_SEG(0x00011F0000000068ull)
-#define CVMX_NPI_NUM_DESC_OUTPUTX(offset) \
- CVMX_ADD_IO_SEG(0x00011F0000000050ull + (((offset) & 3) * 8))
-#define CVMX_NPI_OUTPUT_CONTROL \
- CVMX_ADD_IO_SEG(0x00011F0000000100ull)
-#define CVMX_NPI_P0_DBPAIR_ADDR \
- CVMX_ADD_IO_SEG(0x00011F0000000180ull)
-#define CVMX_NPI_P0_INSTR_ADDR \
- CVMX_ADD_IO_SEG(0x00011F00000001C0ull)
-#define CVMX_NPI_P0_INSTR_CNTS \
- CVMX_ADD_IO_SEG(0x00011F00000001A0ull)
-#define CVMX_NPI_P0_PAIR_CNTS \
- CVMX_ADD_IO_SEG(0x00011F0000000160ull)
-#define CVMX_NPI_P1_DBPAIR_ADDR \
- CVMX_ADD_IO_SEG(0x00011F0000000188ull)
-#define CVMX_NPI_P1_INSTR_ADDR \
- CVMX_ADD_IO_SEG(0x00011F00000001C8ull)
-#define CVMX_NPI_P1_INSTR_CNTS \
- CVMX_ADD_IO_SEG(0x00011F00000001A8ull)
-#define CVMX_NPI_P1_PAIR_CNTS \
- CVMX_ADD_IO_SEG(0x00011F0000000168ull)
-#define CVMX_NPI_P2_DBPAIR_ADDR \
- CVMX_ADD_IO_SEG(0x00011F0000000190ull)
-#define CVMX_NPI_P2_INSTR_ADDR \
- CVMX_ADD_IO_SEG(0x00011F00000001D0ull)
-#define CVMX_NPI_P2_INSTR_CNTS \
- CVMX_ADD_IO_SEG(0x00011F00000001B0ull)
-#define CVMX_NPI_P2_PAIR_CNTS \
- CVMX_ADD_IO_SEG(0x00011F0000000170ull)
-#define CVMX_NPI_P3_DBPAIR_ADDR \
- CVMX_ADD_IO_SEG(0x00011F0000000198ull)
-#define CVMX_NPI_P3_INSTR_ADDR \
- CVMX_ADD_IO_SEG(0x00011F00000001D8ull)
-#define CVMX_NPI_P3_INSTR_CNTS \
- CVMX_ADD_IO_SEG(0x00011F00000001B8ull)
-#define CVMX_NPI_P3_PAIR_CNTS \
- CVMX_ADD_IO_SEG(0x00011F0000000178ull)
-#define CVMX_NPI_PCI_BAR1_INDEXX(offset) \
- CVMX_ADD_IO_SEG(0x00011F0000001100ull + (((offset) & 31) * 4))
-#define CVMX_NPI_PCI_BIST_REG \
- CVMX_ADD_IO_SEG(0x00011F00000011C0ull)
-#define CVMX_NPI_PCI_BURST_SIZE \
- CVMX_ADD_IO_SEG(0x00011F00000000D8ull)
-#define CVMX_NPI_PCI_CFG00 \
- CVMX_ADD_IO_SEG(0x00011F0000001800ull)
-#define CVMX_NPI_PCI_CFG01 \
- CVMX_ADD_IO_SEG(0x00011F0000001804ull)
-#define CVMX_NPI_PCI_CFG02 \
- CVMX_ADD_IO_SEG(0x00011F0000001808ull)
-#define CVMX_NPI_PCI_CFG03 \
- CVMX_ADD_IO_SEG(0x00011F000000180Cull)
-#define CVMX_NPI_PCI_CFG04 \
- CVMX_ADD_IO_SEG(0x00011F0000001810ull)
-#define CVMX_NPI_PCI_CFG05 \
- CVMX_ADD_IO_SEG(0x00011F0000001814ull)
-#define CVMX_NPI_PCI_CFG06 \
- CVMX_ADD_IO_SEG(0x00011F0000001818ull)
-#define CVMX_NPI_PCI_CFG07 \
- CVMX_ADD_IO_SEG(0x00011F000000181Cull)
-#define CVMX_NPI_PCI_CFG08 \
- CVMX_ADD_IO_SEG(0x00011F0000001820ull)
-#define CVMX_NPI_PCI_CFG09 \
- CVMX_ADD_IO_SEG(0x00011F0000001824ull)
-#define CVMX_NPI_PCI_CFG10 \
- CVMX_ADD_IO_SEG(0x00011F0000001828ull)
-#define CVMX_NPI_PCI_CFG11 \
- CVMX_ADD_IO_SEG(0x00011F000000182Cull)
-#define CVMX_NPI_PCI_CFG12 \
- CVMX_ADD_IO_SEG(0x00011F0000001830ull)
-#define CVMX_NPI_PCI_CFG13 \
- CVMX_ADD_IO_SEG(0x00011F0000001834ull)
-#define CVMX_NPI_PCI_CFG15 \
- CVMX_ADD_IO_SEG(0x00011F000000183Cull)
-#define CVMX_NPI_PCI_CFG16 \
- CVMX_ADD_IO_SEG(0x00011F0000001840ull)
-#define CVMX_NPI_PCI_CFG17 \
- CVMX_ADD_IO_SEG(0x00011F0000001844ull)
-#define CVMX_NPI_PCI_CFG18 \
- CVMX_ADD_IO_SEG(0x00011F0000001848ull)
-#define CVMX_NPI_PCI_CFG19 \
- CVMX_ADD_IO_SEG(0x00011F000000184Cull)
-#define CVMX_NPI_PCI_CFG20 \
- CVMX_ADD_IO_SEG(0x00011F0000001850ull)
-#define CVMX_NPI_PCI_CFG21 \
- CVMX_ADD_IO_SEG(0x00011F0000001854ull)
-#define CVMX_NPI_PCI_CFG22 \
- CVMX_ADD_IO_SEG(0x00011F0000001858ull)
-#define CVMX_NPI_PCI_CFG56 \
- CVMX_ADD_IO_SEG(0x00011F00000018E0ull)
-#define CVMX_NPI_PCI_CFG57 \
- CVMX_ADD_IO_SEG(0x00011F00000018E4ull)
-#define CVMX_NPI_PCI_CFG58 \
- CVMX_ADD_IO_SEG(0x00011F00000018E8ull)
-#define CVMX_NPI_PCI_CFG59 \
- CVMX_ADD_IO_SEG(0x00011F00000018ECull)
-#define CVMX_NPI_PCI_CFG60 \
- CVMX_ADD_IO_SEG(0x00011F00000018F0ull)
-#define CVMX_NPI_PCI_CFG61 \
- CVMX_ADD_IO_SEG(0x00011F00000018F4ull)
-#define CVMX_NPI_PCI_CFG62 \
- CVMX_ADD_IO_SEG(0x00011F00000018F8ull)
-#define CVMX_NPI_PCI_CFG63 \
- CVMX_ADD_IO_SEG(0x00011F00000018FCull)
-#define CVMX_NPI_PCI_CNT_REG \
- CVMX_ADD_IO_SEG(0x00011F00000011B8ull)
-#define CVMX_NPI_PCI_CTL_STATUS_2 \
- CVMX_ADD_IO_SEG(0x00011F000000118Cull)
-#define CVMX_NPI_PCI_INT_ARB_CFG \
- CVMX_ADD_IO_SEG(0x00011F0000000130ull)
-#define CVMX_NPI_PCI_INT_ENB2 \
- CVMX_ADD_IO_SEG(0x00011F00000011A0ull)
-#define CVMX_NPI_PCI_INT_SUM2 \
- CVMX_ADD_IO_SEG(0x00011F0000001198ull)
-#define CVMX_NPI_PCI_READ_CMD \
- CVMX_ADD_IO_SEG(0x00011F0000000048ull)
-#define CVMX_NPI_PCI_READ_CMD_6 \
- CVMX_ADD_IO_SEG(0x00011F0000001180ull)
-#define CVMX_NPI_PCI_READ_CMD_C \
- CVMX_ADD_IO_SEG(0x00011F0000001184ull)
-#define CVMX_NPI_PCI_READ_CMD_E \
- CVMX_ADD_IO_SEG(0x00011F0000001188ull)
-#define CVMX_NPI_PCI_SCM_REG \
- CVMX_ADD_IO_SEG(0x00011F00000011A8ull)
-#define CVMX_NPI_PCI_TSR_REG \
- CVMX_ADD_IO_SEG(0x00011F00000011B0ull)
-#define CVMX_NPI_PORT32_INSTR_HDR \
- CVMX_ADD_IO_SEG(0x00011F00000001F8ull)
-#define CVMX_NPI_PORT33_INSTR_HDR \
- CVMX_ADD_IO_SEG(0x00011F0000000200ull)
-#define CVMX_NPI_PORT34_INSTR_HDR \
- CVMX_ADD_IO_SEG(0x00011F0000000208ull)
-#define CVMX_NPI_PORT35_INSTR_HDR \
- CVMX_ADD_IO_SEG(0x00011F0000000210ull)
-#define CVMX_NPI_PORT_BP_CONTROL \
- CVMX_ADD_IO_SEG(0x00011F00000001F0ull)
-#define CVMX_NPI_PX_DBPAIR_ADDR(offset) \
- CVMX_ADD_IO_SEG(0x00011F0000000180ull + (((offset) & 3) * 8))
-#define CVMX_NPI_PX_INSTR_ADDR(offset) \
- CVMX_ADD_IO_SEG(0x00011F00000001C0ull + (((offset) & 3) * 8))
-#define CVMX_NPI_PX_INSTR_CNTS(offset) \
- CVMX_ADD_IO_SEG(0x00011F00000001A0ull + (((offset) & 3) * 8))
-#define CVMX_NPI_PX_PAIR_CNTS(offset) \
- CVMX_ADD_IO_SEG(0x00011F0000000160ull + (((offset) & 3) * 8))
-#define CVMX_NPI_RSL_INT_BLOCKS \
- CVMX_ADD_IO_SEG(0x00011F0000000000ull)
-#define CVMX_NPI_SIZE_INPUT0 \
- CVMX_ADD_IO_SEG(0x00011F0000000078ull)
-#define CVMX_NPI_SIZE_INPUT1 \
- CVMX_ADD_IO_SEG(0x00011F0000000088ull)
-#define CVMX_NPI_SIZE_INPUT2 \
- CVMX_ADD_IO_SEG(0x00011F0000000098ull)
-#define CVMX_NPI_SIZE_INPUT3 \
- CVMX_ADD_IO_SEG(0x00011F00000000A8ull)
-#define CVMX_NPI_SIZE_INPUTX(offset) \
- CVMX_ADD_IO_SEG(0x00011F0000000078ull + (((offset) & 3) * 16))
-#define CVMX_NPI_WIN_READ_TO \
- CVMX_ADD_IO_SEG(0x00011F00000001E0ull)
+#define CVMX_NPI_BASE_ADDR_INPUT0 CVMX_NPI_BASE_ADDR_INPUTX(0)
+#define CVMX_NPI_BASE_ADDR_INPUT1 CVMX_NPI_BASE_ADDR_INPUTX(1)
+#define CVMX_NPI_BASE_ADDR_INPUT2 CVMX_NPI_BASE_ADDR_INPUTX(2)
+#define CVMX_NPI_BASE_ADDR_INPUT3 CVMX_NPI_BASE_ADDR_INPUTX(3)
+#define CVMX_NPI_BASE_ADDR_INPUTX(offset) (CVMX_ADD_IO_SEG(0x00011F0000000070ull) + ((offset) & 3) * 16)
+#define CVMX_NPI_BASE_ADDR_OUTPUT0 CVMX_NPI_BASE_ADDR_OUTPUTX(0)
+#define CVMX_NPI_BASE_ADDR_OUTPUT1 CVMX_NPI_BASE_ADDR_OUTPUTX(1)
+#define CVMX_NPI_BASE_ADDR_OUTPUT2 CVMX_NPI_BASE_ADDR_OUTPUTX(2)
+#define CVMX_NPI_BASE_ADDR_OUTPUT3 CVMX_NPI_BASE_ADDR_OUTPUTX(3)
+#define CVMX_NPI_BASE_ADDR_OUTPUTX(offset) (CVMX_ADD_IO_SEG(0x00011F00000000B8ull) + ((offset) & 3) * 8)
+#define CVMX_NPI_BIST_STATUS (CVMX_ADD_IO_SEG(0x00011F00000003F8ull))
+#define CVMX_NPI_BUFF_SIZE_OUTPUT0 CVMX_NPI_BUFF_SIZE_OUTPUTX(0)
+#define CVMX_NPI_BUFF_SIZE_OUTPUT1 CVMX_NPI_BUFF_SIZE_OUTPUTX(1)
+#define CVMX_NPI_BUFF_SIZE_OUTPUT2 CVMX_NPI_BUFF_SIZE_OUTPUTX(2)
+#define CVMX_NPI_BUFF_SIZE_OUTPUT3 CVMX_NPI_BUFF_SIZE_OUTPUTX(3)
+#define CVMX_NPI_BUFF_SIZE_OUTPUTX(offset) (CVMX_ADD_IO_SEG(0x00011F00000000E0ull) + ((offset) & 3) * 8)
+#define CVMX_NPI_COMP_CTL (CVMX_ADD_IO_SEG(0x00011F0000000218ull))
+#define CVMX_NPI_CTL_STATUS (CVMX_ADD_IO_SEG(0x00011F0000000010ull))
+#define CVMX_NPI_DBG_SELECT (CVMX_ADD_IO_SEG(0x00011F0000000008ull))
+#define CVMX_NPI_DMA_CONTROL (CVMX_ADD_IO_SEG(0x00011F0000000128ull))
+#define CVMX_NPI_DMA_HIGHP_COUNTS (CVMX_ADD_IO_SEG(0x00011F0000000148ull))
+#define CVMX_NPI_DMA_HIGHP_NADDR (CVMX_ADD_IO_SEG(0x00011F0000000158ull))
+#define CVMX_NPI_DMA_LOWP_COUNTS (CVMX_ADD_IO_SEG(0x00011F0000000140ull))
+#define CVMX_NPI_DMA_LOWP_NADDR (CVMX_ADD_IO_SEG(0x00011F0000000150ull))
+#define CVMX_NPI_HIGHP_DBELL (CVMX_ADD_IO_SEG(0x00011F0000000120ull))
+#define CVMX_NPI_HIGHP_IBUFF_SADDR (CVMX_ADD_IO_SEG(0x00011F0000000110ull))
+#define CVMX_NPI_INPUT_CONTROL (CVMX_ADD_IO_SEG(0x00011F0000000138ull))
+#define CVMX_NPI_INT_ENB (CVMX_ADD_IO_SEG(0x00011F0000000020ull))
+#define CVMX_NPI_INT_SUM (CVMX_ADD_IO_SEG(0x00011F0000000018ull))
+#define CVMX_NPI_LOWP_DBELL (CVMX_ADD_IO_SEG(0x00011F0000000118ull))
+#define CVMX_NPI_LOWP_IBUFF_SADDR (CVMX_ADD_IO_SEG(0x00011F0000000108ull))
+#define CVMX_NPI_MEM_ACCESS_SUBID3 CVMX_NPI_MEM_ACCESS_SUBIDX(3)
+#define CVMX_NPI_MEM_ACCESS_SUBID4 CVMX_NPI_MEM_ACCESS_SUBIDX(4)
+#define CVMX_NPI_MEM_ACCESS_SUBID5 CVMX_NPI_MEM_ACCESS_SUBIDX(5)
+#define CVMX_NPI_MEM_ACCESS_SUBID6 CVMX_NPI_MEM_ACCESS_SUBIDX(6)
+#define CVMX_NPI_MEM_ACCESS_SUBIDX(offset) (CVMX_ADD_IO_SEG(0x00011F0000000028ull) + ((offset) & 7) * 8 - 8*3)
+#define CVMX_NPI_MSI_RCV (0x0000000000000190ull)
+#define CVMX_NPI_NPI_MSI_RCV (CVMX_ADD_IO_SEG(0x00011F0000001190ull))
+#define CVMX_NPI_NUM_DESC_OUTPUT0 CVMX_NPI_NUM_DESC_OUTPUTX(0)
+#define CVMX_NPI_NUM_DESC_OUTPUT1 CVMX_NPI_NUM_DESC_OUTPUTX(1)
+#define CVMX_NPI_NUM_DESC_OUTPUT2 CVMX_NPI_NUM_DESC_OUTPUTX(2)
+#define CVMX_NPI_NUM_DESC_OUTPUT3 CVMX_NPI_NUM_DESC_OUTPUTX(3)
+#define CVMX_NPI_NUM_DESC_OUTPUTX(offset) (CVMX_ADD_IO_SEG(0x00011F0000000050ull) + ((offset) & 3) * 8)
+#define CVMX_NPI_OUTPUT_CONTROL (CVMX_ADD_IO_SEG(0x00011F0000000100ull))
+#define CVMX_NPI_P0_DBPAIR_ADDR CVMX_NPI_PX_DBPAIR_ADDR(0)
+#define CVMX_NPI_P0_INSTR_ADDR CVMX_NPI_PX_INSTR_ADDR(0)
+#define CVMX_NPI_P0_INSTR_CNTS CVMX_NPI_PX_INSTR_CNTS(0)
+#define CVMX_NPI_P0_PAIR_CNTS CVMX_NPI_PX_PAIR_CNTS(0)
+#define CVMX_NPI_P1_DBPAIR_ADDR CVMX_NPI_PX_DBPAIR_ADDR(1)
+#define CVMX_NPI_P1_INSTR_ADDR CVMX_NPI_PX_INSTR_ADDR(1)
+#define CVMX_NPI_P1_INSTR_CNTS CVMX_NPI_PX_INSTR_CNTS(1)
+#define CVMX_NPI_P1_PAIR_CNTS CVMX_NPI_PX_PAIR_CNTS(1)
+#define CVMX_NPI_P2_DBPAIR_ADDR CVMX_NPI_PX_DBPAIR_ADDR(2)
+#define CVMX_NPI_P2_INSTR_ADDR CVMX_NPI_PX_INSTR_ADDR(2)
+#define CVMX_NPI_P2_INSTR_CNTS CVMX_NPI_PX_INSTR_CNTS(2)
+#define CVMX_NPI_P2_PAIR_CNTS CVMX_NPI_PX_PAIR_CNTS(2)
+#define CVMX_NPI_P3_DBPAIR_ADDR CVMX_NPI_PX_DBPAIR_ADDR(3)
+#define CVMX_NPI_P3_INSTR_ADDR CVMX_NPI_PX_INSTR_ADDR(3)
+#define CVMX_NPI_P3_INSTR_CNTS CVMX_NPI_PX_INSTR_CNTS(3)
+#define CVMX_NPI_P3_PAIR_CNTS CVMX_NPI_PX_PAIR_CNTS(3)
+#define CVMX_NPI_PCI_BAR1_INDEXX(offset) (CVMX_ADD_IO_SEG(0x00011F0000001100ull) + ((offset) & 31) * 4)
+#define CVMX_NPI_PCI_BIST_REG (CVMX_ADD_IO_SEG(0x00011F00000011C0ull))
+#define CVMX_NPI_PCI_BURST_SIZE (CVMX_ADD_IO_SEG(0x00011F00000000D8ull))
+#define CVMX_NPI_PCI_CFG00 (CVMX_ADD_IO_SEG(0x00011F0000001800ull))
+#define CVMX_NPI_PCI_CFG01 (CVMX_ADD_IO_SEG(0x00011F0000001804ull))
+#define CVMX_NPI_PCI_CFG02 (CVMX_ADD_IO_SEG(0x00011F0000001808ull))
+#define CVMX_NPI_PCI_CFG03 (CVMX_ADD_IO_SEG(0x00011F000000180Cull))
+#define CVMX_NPI_PCI_CFG04 (CVMX_ADD_IO_SEG(0x00011F0000001810ull))
+#define CVMX_NPI_PCI_CFG05 (CVMX_ADD_IO_SEG(0x00011F0000001814ull))
+#define CVMX_NPI_PCI_CFG06 (CVMX_ADD_IO_SEG(0x00011F0000001818ull))
+#define CVMX_NPI_PCI_CFG07 (CVMX_ADD_IO_SEG(0x00011F000000181Cull))
+#define CVMX_NPI_PCI_CFG08 (CVMX_ADD_IO_SEG(0x00011F0000001820ull))
+#define CVMX_NPI_PCI_CFG09 (CVMX_ADD_IO_SEG(0x00011F0000001824ull))
+#define CVMX_NPI_PCI_CFG10 (CVMX_ADD_IO_SEG(0x00011F0000001828ull))
+#define CVMX_NPI_PCI_CFG11 (CVMX_ADD_IO_SEG(0x00011F000000182Cull))
+#define CVMX_NPI_PCI_CFG12 (CVMX_ADD_IO_SEG(0x00011F0000001830ull))
+#define CVMX_NPI_PCI_CFG13 (CVMX_ADD_IO_SEG(0x00011F0000001834ull))
+#define CVMX_NPI_PCI_CFG15 (CVMX_ADD_IO_SEG(0x00011F000000183Cull))
+#define CVMX_NPI_PCI_CFG16 (CVMX_ADD_IO_SEG(0x00011F0000001840ull))
+#define CVMX_NPI_PCI_CFG17 (CVMX_ADD_IO_SEG(0x00011F0000001844ull))
+#define CVMX_NPI_PCI_CFG18 (CVMX_ADD_IO_SEG(0x00011F0000001848ull))
+#define CVMX_NPI_PCI_CFG19 (CVMX_ADD_IO_SEG(0x00011F000000184Cull))
+#define CVMX_NPI_PCI_CFG20 (CVMX_ADD_IO_SEG(0x00011F0000001850ull))
+#define CVMX_NPI_PCI_CFG21 (CVMX_ADD_IO_SEG(0x00011F0000001854ull))
+#define CVMX_NPI_PCI_CFG22 (CVMX_ADD_IO_SEG(0x00011F0000001858ull))
+#define CVMX_NPI_PCI_CFG56 (CVMX_ADD_IO_SEG(0x00011F00000018E0ull))
+#define CVMX_NPI_PCI_CFG57 (CVMX_ADD_IO_SEG(0x00011F00000018E4ull))
+#define CVMX_NPI_PCI_CFG58 (CVMX_ADD_IO_SEG(0x00011F00000018E8ull))
+#define CVMX_NPI_PCI_CFG59 (CVMX_ADD_IO_SEG(0x00011F00000018ECull))
+#define CVMX_NPI_PCI_CFG60 (CVMX_ADD_IO_SEG(0x00011F00000018F0ull))
+#define CVMX_NPI_PCI_CFG61 (CVMX_ADD_IO_SEG(0x00011F00000018F4ull))
+#define CVMX_NPI_PCI_CFG62 (CVMX_ADD_IO_SEG(0x00011F00000018F8ull))
+#define CVMX_NPI_PCI_CFG63 (CVMX_ADD_IO_SEG(0x00011F00000018FCull))
+#define CVMX_NPI_PCI_CNT_REG (CVMX_ADD_IO_SEG(0x00011F00000011B8ull))
+#define CVMX_NPI_PCI_CTL_STATUS_2 (CVMX_ADD_IO_SEG(0x00011F000000118Cull))
+#define CVMX_NPI_PCI_INT_ARB_CFG (CVMX_ADD_IO_SEG(0x00011F0000000130ull))
+#define CVMX_NPI_PCI_INT_ENB2 (CVMX_ADD_IO_SEG(0x00011F00000011A0ull))
+#define CVMX_NPI_PCI_INT_SUM2 (CVMX_ADD_IO_SEG(0x00011F0000001198ull))
+#define CVMX_NPI_PCI_READ_CMD (CVMX_ADD_IO_SEG(0x00011F0000000048ull))
+#define CVMX_NPI_PCI_READ_CMD_6 (CVMX_ADD_IO_SEG(0x00011F0000001180ull))
+#define CVMX_NPI_PCI_READ_CMD_C (CVMX_ADD_IO_SEG(0x00011F0000001184ull))
+#define CVMX_NPI_PCI_READ_CMD_E (CVMX_ADD_IO_SEG(0x00011F0000001188ull))
+#define CVMX_NPI_PCI_SCM_REG (CVMX_ADD_IO_SEG(0x00011F00000011A8ull))
+#define CVMX_NPI_PCI_TSR_REG (CVMX_ADD_IO_SEG(0x00011F00000011B0ull))
+#define CVMX_NPI_PORT32_INSTR_HDR (CVMX_ADD_IO_SEG(0x00011F00000001F8ull))
+#define CVMX_NPI_PORT33_INSTR_HDR (CVMX_ADD_IO_SEG(0x00011F0000000200ull))
+#define CVMX_NPI_PORT34_INSTR_HDR (CVMX_ADD_IO_SEG(0x00011F0000000208ull))
+#define CVMX_NPI_PORT35_INSTR_HDR (CVMX_ADD_IO_SEG(0x00011F0000000210ull))
+#define CVMX_NPI_PORT_BP_CONTROL (CVMX_ADD_IO_SEG(0x00011F00000001F0ull))
+#define CVMX_NPI_PX_DBPAIR_ADDR(offset) (CVMX_ADD_IO_SEG(0x00011F0000000180ull) + ((offset) & 3) * 8)
+#define CVMX_NPI_PX_INSTR_ADDR(offset) (CVMX_ADD_IO_SEG(0x00011F00000001C0ull) + ((offset) & 3) * 8)
+#define CVMX_NPI_PX_INSTR_CNTS(offset) (CVMX_ADD_IO_SEG(0x00011F00000001A0ull) + ((offset) & 3) * 8)
+#define CVMX_NPI_PX_PAIR_CNTS(offset) (CVMX_ADD_IO_SEG(0x00011F0000000160ull) + ((offset) & 3) * 8)
+#define CVMX_NPI_RSL_INT_BLOCKS (CVMX_ADD_IO_SEG(0x00011F0000000000ull))
+#define CVMX_NPI_SIZE_INPUT0 CVMX_NPI_SIZE_INPUTX(0)
+#define CVMX_NPI_SIZE_INPUT1 CVMX_NPI_SIZE_INPUTX(1)
+#define CVMX_NPI_SIZE_INPUT2 CVMX_NPI_SIZE_INPUTX(2)
+#define CVMX_NPI_SIZE_INPUT3 CVMX_NPI_SIZE_INPUTX(3)
+#define CVMX_NPI_SIZE_INPUTX(offset) (CVMX_ADD_IO_SEG(0x00011F0000000078ull) + ((offset) & 3) * 16)
+#define CVMX_NPI_WIN_READ_TO (CVMX_ADD_IO_SEG(0x00011F00000001E0ull))
union cvmx_npi_base_addr_inputx {
uint64_t u64;
diff --git a/arch/mips/include/asm/octeon/cvmx-pci-defs.h b/arch/mips/include/asm/octeon/cvmx-pci-defs.h
index 90f8d6535753..6ff6d9d357ba 100644
--- a/arch/mips/include/asm/octeon/cvmx-pci-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pci-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
@@ -28,184 +28,91 @@
#ifndef __CVMX_PCI_DEFS_H__
#define __CVMX_PCI_DEFS_H__
-#define CVMX_PCI_BAR1_INDEXX(offset) \
- (0x0000000000000100ull + (((offset) & 31) * 4))
-#define CVMX_PCI_BIST_REG \
- (0x00000000000001C0ull)
-#define CVMX_PCI_CFG00 \
- (0x0000000000000000ull)
-#define CVMX_PCI_CFG01 \
- (0x0000000000000004ull)
-#define CVMX_PCI_CFG02 \
- (0x0000000000000008ull)
-#define CVMX_PCI_CFG03 \
- (0x000000000000000Cull)
-#define CVMX_PCI_CFG04 \
- (0x0000000000000010ull)
-#define CVMX_PCI_CFG05 \
- (0x0000000000000014ull)
-#define CVMX_PCI_CFG06 \
- (0x0000000000000018ull)
-#define CVMX_PCI_CFG07 \
- (0x000000000000001Cull)
-#define CVMX_PCI_CFG08 \
- (0x0000000000000020ull)
-#define CVMX_PCI_CFG09 \
- (0x0000000000000024ull)
-#define CVMX_PCI_CFG10 \
- (0x0000000000000028ull)
-#define CVMX_PCI_CFG11 \
- (0x000000000000002Cull)
-#define CVMX_PCI_CFG12 \
- (0x0000000000000030ull)
-#define CVMX_PCI_CFG13 \
- (0x0000000000000034ull)
-#define CVMX_PCI_CFG15 \
- (0x000000000000003Cull)
-#define CVMX_PCI_CFG16 \
- (0x0000000000000040ull)
-#define CVMX_PCI_CFG17 \
- (0x0000000000000044ull)
-#define CVMX_PCI_CFG18 \
- (0x0000000000000048ull)
-#define CVMX_PCI_CFG19 \
- (0x000000000000004Cull)
-#define CVMX_PCI_CFG20 \
- (0x0000000000000050ull)
-#define CVMX_PCI_CFG21 \
- (0x0000000000000054ull)
-#define CVMX_PCI_CFG22 \
- (0x0000000000000058ull)
-#define CVMX_PCI_CFG56 \
- (0x00000000000000E0ull)
-#define CVMX_PCI_CFG57 \
- (0x00000000000000E4ull)
-#define CVMX_PCI_CFG58 \
- (0x00000000000000E8ull)
-#define CVMX_PCI_CFG59 \
- (0x00000000000000ECull)
-#define CVMX_PCI_CFG60 \
- (0x00000000000000F0ull)
-#define CVMX_PCI_CFG61 \
- (0x00000000000000F4ull)
-#define CVMX_PCI_CFG62 \
- (0x00000000000000F8ull)
-#define CVMX_PCI_CFG63 \
- (0x00000000000000FCull)
-#define CVMX_PCI_CNT_REG \
- (0x00000000000001B8ull)
-#define CVMX_PCI_CTL_STATUS_2 \
- (0x000000000000018Cull)
-#define CVMX_PCI_DBELL_0 \
- (0x0000000000000080ull)
-#define CVMX_PCI_DBELL_1 \
- (0x0000000000000088ull)
-#define CVMX_PCI_DBELL_2 \
- (0x0000000000000090ull)
-#define CVMX_PCI_DBELL_3 \
- (0x0000000000000098ull)
-#define CVMX_PCI_DBELL_X(offset) \
- (0x0000000000000080ull + (((offset) & 3) * 8))
-#define CVMX_PCI_DMA_CNT0 \
- (0x00000000000000A0ull)
-#define CVMX_PCI_DMA_CNT1 \
- (0x00000000000000A8ull)
-#define CVMX_PCI_DMA_CNTX(offset) \
- (0x00000000000000A0ull + (((offset) & 1) * 8))
-#define CVMX_PCI_DMA_INT_LEV0 \
- (0x00000000000000A4ull)
-#define CVMX_PCI_DMA_INT_LEV1 \
- (0x00000000000000ACull)
-#define CVMX_PCI_DMA_INT_LEVX(offset) \
- (0x00000000000000A4ull + (((offset) & 1) * 8))
-#define CVMX_PCI_DMA_TIME0 \
- (0x00000000000000B0ull)
-#define CVMX_PCI_DMA_TIME1 \
- (0x00000000000000B4ull)
-#define CVMX_PCI_DMA_TIMEX(offset) \
- (0x00000000000000B0ull + (((offset) & 1) * 4))
-#define CVMX_PCI_INSTR_COUNT0 \
- (0x0000000000000084ull)
-#define CVMX_PCI_INSTR_COUNT1 \
- (0x000000000000008Cull)
-#define CVMX_PCI_INSTR_COUNT2 \
- (0x0000000000000094ull)
-#define CVMX_PCI_INSTR_COUNT3 \
- (0x000000000000009Cull)
-#define CVMX_PCI_INSTR_COUNTX(offset) \
- (0x0000000000000084ull + (((offset) & 3) * 8))
-#define CVMX_PCI_INT_ENB \
- (0x0000000000000038ull)
-#define CVMX_PCI_INT_ENB2 \
- (0x00000000000001A0ull)
-#define CVMX_PCI_INT_SUM \
- (0x0000000000000030ull)
-#define CVMX_PCI_INT_SUM2 \
- (0x0000000000000198ull)
-#define CVMX_PCI_MSI_RCV \
- (0x00000000000000F0ull)
-#define CVMX_PCI_PKTS_SENT0 \
- (0x0000000000000040ull)
-#define CVMX_PCI_PKTS_SENT1 \
- (0x0000000000000050ull)
-#define CVMX_PCI_PKTS_SENT2 \
- (0x0000000000000060ull)
-#define CVMX_PCI_PKTS_SENT3 \
- (0x0000000000000070ull)
-#define CVMX_PCI_PKTS_SENTX(offset) \
- (0x0000000000000040ull + (((offset) & 3) * 16))
-#define CVMX_PCI_PKTS_SENT_INT_LEV0 \
- (0x0000000000000048ull)
-#define CVMX_PCI_PKTS_SENT_INT_LEV1 \
- (0x0000000000000058ull)
-#define CVMX_PCI_PKTS_SENT_INT_LEV2 \
- (0x0000000000000068ull)
-#define CVMX_PCI_PKTS_SENT_INT_LEV3 \
- (0x0000000000000078ull)
-#define CVMX_PCI_PKTS_SENT_INT_LEVX(offset) \
- (0x0000000000000048ull + (((offset) & 3) * 16))
-#define CVMX_PCI_PKTS_SENT_TIME0 \
- (0x000000000000004Cull)
-#define CVMX_PCI_PKTS_SENT_TIME1 \
- (0x000000000000005Cull)
-#define CVMX_PCI_PKTS_SENT_TIME2 \
- (0x000000000000006Cull)
-#define CVMX_PCI_PKTS_SENT_TIME3 \
- (0x000000000000007Cull)
-#define CVMX_PCI_PKTS_SENT_TIMEX(offset) \
- (0x000000000000004Cull + (((offset) & 3) * 16))
-#define CVMX_PCI_PKT_CREDITS0 \
- (0x0000000000000044ull)
-#define CVMX_PCI_PKT_CREDITS1 \
- (0x0000000000000054ull)
-#define CVMX_PCI_PKT_CREDITS2 \
- (0x0000000000000064ull)
-#define CVMX_PCI_PKT_CREDITS3 \
- (0x0000000000000074ull)
-#define CVMX_PCI_PKT_CREDITSX(offset) \
- (0x0000000000000044ull + (((offset) & 3) * 16))
-#define CVMX_PCI_READ_CMD_6 \
- (0x0000000000000180ull)
-#define CVMX_PCI_READ_CMD_C \
- (0x0000000000000184ull)
-#define CVMX_PCI_READ_CMD_E \
- (0x0000000000000188ull)
-#define CVMX_PCI_READ_TIMEOUT \
- CVMX_ADD_IO_SEG(0x00011F00000000B0ull)
-#define CVMX_PCI_SCM_REG \
- (0x00000000000001A8ull)
-#define CVMX_PCI_TSR_REG \
- (0x00000000000001B0ull)
-#define CVMX_PCI_WIN_RD_ADDR \
- (0x0000000000000008ull)
-#define CVMX_PCI_WIN_RD_DATA \
- (0x0000000000000020ull)
-#define CVMX_PCI_WIN_WR_ADDR \
- (0x0000000000000000ull)
-#define CVMX_PCI_WIN_WR_DATA \
- (0x0000000000000010ull)
-#define CVMX_PCI_WIN_WR_MASK \
- (0x0000000000000018ull)
+#define CVMX_PCI_BAR1_INDEXX(offset) (0x0000000000000100ull + ((offset) & 31) * 4)
+#define CVMX_PCI_BIST_REG (0x00000000000001C0ull)
+#define CVMX_PCI_CFG00 (0x0000000000000000ull)
+#define CVMX_PCI_CFG01 (0x0000000000000004ull)
+#define CVMX_PCI_CFG02 (0x0000000000000008ull)
+#define CVMX_PCI_CFG03 (0x000000000000000Cull)
+#define CVMX_PCI_CFG04 (0x0000000000000010ull)
+#define CVMX_PCI_CFG05 (0x0000000000000014ull)
+#define CVMX_PCI_CFG06 (0x0000000000000018ull)
+#define CVMX_PCI_CFG07 (0x000000000000001Cull)
+#define CVMX_PCI_CFG08 (0x0000000000000020ull)
+#define CVMX_PCI_CFG09 (0x0000000000000024ull)
+#define CVMX_PCI_CFG10 (0x0000000000000028ull)
+#define CVMX_PCI_CFG11 (0x000000000000002Cull)
+#define CVMX_PCI_CFG12 (0x0000000000000030ull)
+#define CVMX_PCI_CFG13 (0x0000000000000034ull)
+#define CVMX_PCI_CFG15 (0x000000000000003Cull)
+#define CVMX_PCI_CFG16 (0x0000000000000040ull)
+#define CVMX_PCI_CFG17 (0x0000000000000044ull)
+#define CVMX_PCI_CFG18 (0x0000000000000048ull)
+#define CVMX_PCI_CFG19 (0x000000000000004Cull)
+#define CVMX_PCI_CFG20 (0x0000000000000050ull)
+#define CVMX_PCI_CFG21 (0x0000000000000054ull)
+#define CVMX_PCI_CFG22 (0x0000000000000058ull)
+#define CVMX_PCI_CFG56 (0x00000000000000E0ull)
+#define CVMX_PCI_CFG57 (0x00000000000000E4ull)
+#define CVMX_PCI_CFG58 (0x00000000000000E8ull)
+#define CVMX_PCI_CFG59 (0x00000000000000ECull)
+#define CVMX_PCI_CFG60 (0x00000000000000F0ull)
+#define CVMX_PCI_CFG61 (0x00000000000000F4ull)
+#define CVMX_PCI_CFG62 (0x00000000000000F8ull)
+#define CVMX_PCI_CFG63 (0x00000000000000FCull)
+#define CVMX_PCI_CNT_REG (0x00000000000001B8ull)
+#define CVMX_PCI_CTL_STATUS_2 (0x000000000000018Cull)
+#define CVMX_PCI_DBELL_X(offset) (0x0000000000000080ull + ((offset) & 3) * 8)
+#define CVMX_PCI_DMA_CNT0 CVMX_PCI_DMA_CNTX(0)
+#define CVMX_PCI_DMA_CNT1 CVMX_PCI_DMA_CNTX(1)
+#define CVMX_PCI_DMA_CNTX(offset) (0x00000000000000A0ull + ((offset) & 1) * 8)
+#define CVMX_PCI_DMA_INT_LEV0 CVMX_PCI_DMA_INT_LEVX(0)
+#define CVMX_PCI_DMA_INT_LEV1 CVMX_PCI_DMA_INT_LEVX(1)
+#define CVMX_PCI_DMA_INT_LEVX(offset) (0x00000000000000A4ull + ((offset) & 1) * 8)
+#define CVMX_PCI_DMA_TIME0 CVMX_PCI_DMA_TIMEX(0)
+#define CVMX_PCI_DMA_TIME1 CVMX_PCI_DMA_TIMEX(1)
+#define CVMX_PCI_DMA_TIMEX(offset) (0x00000000000000B0ull + ((offset) & 1) * 4)
+#define CVMX_PCI_INSTR_COUNT0 CVMX_PCI_INSTR_COUNTX(0)
+#define CVMX_PCI_INSTR_COUNT1 CVMX_PCI_INSTR_COUNTX(1)
+#define CVMX_PCI_INSTR_COUNT2 CVMX_PCI_INSTR_COUNTX(2)
+#define CVMX_PCI_INSTR_COUNT3 CVMX_PCI_INSTR_COUNTX(3)
+#define CVMX_PCI_INSTR_COUNTX(offset) (0x0000000000000084ull + ((offset) & 3) * 8)
+#define CVMX_PCI_INT_ENB (0x0000000000000038ull)
+#define CVMX_PCI_INT_ENB2 (0x00000000000001A0ull)
+#define CVMX_PCI_INT_SUM (0x0000000000000030ull)
+#define CVMX_PCI_INT_SUM2 (0x0000000000000198ull)
+#define CVMX_PCI_MSI_RCV (0x00000000000000F0ull)
+#define CVMX_PCI_PKTS_SENT0 CVMX_PCI_PKTS_SENTX(0)
+#define CVMX_PCI_PKTS_SENT1 CVMX_PCI_PKTS_SENTX(1)
+#define CVMX_PCI_PKTS_SENT2 CVMX_PCI_PKTS_SENTX(2)
+#define CVMX_PCI_PKTS_SENT3 CVMX_PCI_PKTS_SENTX(3)
+#define CVMX_PCI_PKTS_SENTX(offset) (0x0000000000000040ull + ((offset) & 3) * 16)
+#define CVMX_PCI_PKTS_SENT_INT_LEV0 CVMX_PCI_PKTS_SENT_INT_LEVX(0)
+#define CVMX_PCI_PKTS_SENT_INT_LEV1 CVMX_PCI_PKTS_SENT_INT_LEVX(1)
+#define CVMX_PCI_PKTS_SENT_INT_LEV2 CVMX_PCI_PKTS_SENT_INT_LEVX(2)
+#define CVMX_PCI_PKTS_SENT_INT_LEV3 CVMX_PCI_PKTS_SENT_INT_LEVX(3)
+#define CVMX_PCI_PKTS_SENT_INT_LEVX(offset) (0x0000000000000048ull + ((offset) & 3) * 16)
+#define CVMX_PCI_PKTS_SENT_TIME0 CVMX_PCI_PKTS_SENT_TIMEX(0)
+#define CVMX_PCI_PKTS_SENT_TIME1 CVMX_PCI_PKTS_SENT_TIMEX(1)
+#define CVMX_PCI_PKTS_SENT_TIME2 CVMX_PCI_PKTS_SENT_TIMEX(2)
+#define CVMX_PCI_PKTS_SENT_TIME3 CVMX_PCI_PKTS_SENT_TIMEX(3)
+#define CVMX_PCI_PKTS_SENT_TIMEX(offset) (0x000000000000004Cull + ((offset) & 3) * 16)
+#define CVMX_PCI_PKT_CREDITS0 CVMX_PCI_PKT_CREDITSX(0)
+#define CVMX_PCI_PKT_CREDITS1 CVMX_PCI_PKT_CREDITSX(1)
+#define CVMX_PCI_PKT_CREDITS2 CVMX_PCI_PKT_CREDITSX(2)
+#define CVMX_PCI_PKT_CREDITS3 CVMX_PCI_PKT_CREDITSX(3)
+#define CVMX_PCI_PKT_CREDITSX(offset) (0x0000000000000044ull + ((offset) & 3) * 16)
+#define CVMX_PCI_READ_CMD_6 (0x0000000000000180ull)
+#define CVMX_PCI_READ_CMD_C (0x0000000000000184ull)
+#define CVMX_PCI_READ_CMD_E (0x0000000000000188ull)
+#define CVMX_PCI_READ_TIMEOUT (CVMX_ADD_IO_SEG(0x00011F00000000B0ull))
+#define CVMX_PCI_SCM_REG (0x00000000000001A8ull)
+#define CVMX_PCI_TSR_REG (0x00000000000001B0ull)
+#define CVMX_PCI_WIN_RD_ADDR (0x0000000000000008ull)
+#define CVMX_PCI_WIN_RD_DATA (0x0000000000000020ull)
+#define CVMX_PCI_WIN_WR_ADDR (0x0000000000000000ull)
+#define CVMX_PCI_WIN_WR_DATA (0x0000000000000010ull)
+#define CVMX_PCI_WIN_WR_MASK (0x0000000000000018ull)
union cvmx_pci_bar1_indexx {
uint32_t u32;
diff --git a/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h b/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h
index 75574c918942..f8cb88902efb 100644
--- a/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
@@ -28,158 +28,83 @@
#ifndef __CVMX_PCIERCX_DEFS_H__
#define __CVMX_PCIERCX_DEFS_H__
-#define CVMX_PCIERCX_CFG000(offset) \
- (0x0000000000000000ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG001(offset) \
- (0x0000000000000004ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG002(offset) \
- (0x0000000000000008ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG003(offset) \
- (0x000000000000000Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG004(offset) \
- (0x0000000000000010ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG005(offset) \
- (0x0000000000000014ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG006(offset) \
- (0x0000000000000018ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG007(offset) \
- (0x000000000000001Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG008(offset) \
- (0x0000000000000020ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG009(offset) \
- (0x0000000000000024ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG010(offset) \
- (0x0000000000000028ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG011(offset) \
- (0x000000000000002Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG012(offset) \
- (0x0000000000000030ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG013(offset) \
- (0x0000000000000034ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG014(offset) \
- (0x0000000000000038ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG015(offset) \
- (0x000000000000003Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG016(offset) \
- (0x0000000000000040ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG017(offset) \
- (0x0000000000000044ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG020(offset) \
- (0x0000000000000050ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG021(offset) \
- (0x0000000000000054ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG022(offset) \
- (0x0000000000000058ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG023(offset) \
- (0x000000000000005Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG028(offset) \
- (0x0000000000000070ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG029(offset) \
- (0x0000000000000074ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG030(offset) \
- (0x0000000000000078ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG031(offset) \
- (0x000000000000007Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG032(offset) \
- (0x0000000000000080ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG033(offset) \
- (0x0000000000000084ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG034(offset) \
- (0x0000000000000088ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG035(offset) \
- (0x000000000000008Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG036(offset) \
- (0x0000000000000090ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG037(offset) \
- (0x0000000000000094ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG038(offset) \
- (0x0000000000000098ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG039(offset) \
- (0x000000000000009Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG040(offset) \
- (0x00000000000000A0ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG041(offset) \
- (0x00000000000000A4ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG042(offset) \
- (0x00000000000000A8ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG064(offset) \
- (0x0000000000000100ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG065(offset) \
- (0x0000000000000104ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG066(offset) \
- (0x0000000000000108ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG067(offset) \
- (0x000000000000010Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG068(offset) \
- (0x0000000000000110ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG069(offset) \
- (0x0000000000000114ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG070(offset) \
- (0x0000000000000118ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG071(offset) \
- (0x000000000000011Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG072(offset) \
- (0x0000000000000120ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG073(offset) \
- (0x0000000000000124ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG074(offset) \
- (0x0000000000000128ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG075(offset) \
- (0x000000000000012Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG076(offset) \
- (0x0000000000000130ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG077(offset) \
- (0x0000000000000134ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG448(offset) \
- (0x0000000000000700ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG449(offset) \
- (0x0000000000000704ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG450(offset) \
- (0x0000000000000708ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG451(offset) \
- (0x000000000000070Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG452(offset) \
- (0x0000000000000710ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG453(offset) \
- (0x0000000000000714ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG454(offset) \
- (0x0000000000000718ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG455(offset) \
- (0x000000000000071Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG456(offset) \
- (0x0000000000000720ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG458(offset) \
- (0x0000000000000728ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG459(offset) \
- (0x000000000000072Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG460(offset) \
- (0x0000000000000730ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG461(offset) \
- (0x0000000000000734ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG462(offset) \
- (0x0000000000000738ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG463(offset) \
- (0x000000000000073Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG464(offset) \
- (0x0000000000000740ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG465(offset) \
- (0x0000000000000744ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG466(offset) \
- (0x0000000000000748ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG467(offset) \
- (0x000000000000074Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG468(offset) \
- (0x0000000000000750ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG490(offset) \
- (0x00000000000007A8ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG491(offset) \
- (0x00000000000007ACull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG492(offset) \
- (0x00000000000007B0ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG516(offset) \
- (0x0000000000000810ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG517(offset) \
- (0x0000000000000814ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG000(block_id) (0x0000000000000000ull)
+#define CVMX_PCIERCX_CFG001(block_id) (0x0000000000000004ull)
+#define CVMX_PCIERCX_CFG002(block_id) (0x0000000000000008ull)
+#define CVMX_PCIERCX_CFG003(block_id) (0x000000000000000Cull)
+#define CVMX_PCIERCX_CFG004(block_id) (0x0000000000000010ull)
+#define CVMX_PCIERCX_CFG005(block_id) (0x0000000000000014ull)
+#define CVMX_PCIERCX_CFG006(block_id) (0x0000000000000018ull)
+#define CVMX_PCIERCX_CFG007(block_id) (0x000000000000001Cull)
+#define CVMX_PCIERCX_CFG008(block_id) (0x0000000000000020ull)
+#define CVMX_PCIERCX_CFG009(block_id) (0x0000000000000024ull)
+#define CVMX_PCIERCX_CFG010(block_id) (0x0000000000000028ull)
+#define CVMX_PCIERCX_CFG011(block_id) (0x000000000000002Cull)
+#define CVMX_PCIERCX_CFG012(block_id) (0x0000000000000030ull)
+#define CVMX_PCIERCX_CFG013(block_id) (0x0000000000000034ull)
+#define CVMX_PCIERCX_CFG014(block_id) (0x0000000000000038ull)
+#define CVMX_PCIERCX_CFG015(block_id) (0x000000000000003Cull)
+#define CVMX_PCIERCX_CFG016(block_id) (0x0000000000000040ull)
+#define CVMX_PCIERCX_CFG017(block_id) (0x0000000000000044ull)
+#define CVMX_PCIERCX_CFG020(block_id) (0x0000000000000050ull)
+#define CVMX_PCIERCX_CFG021(block_id) (0x0000000000000054ull)
+#define CVMX_PCIERCX_CFG022(block_id) (0x0000000000000058ull)
+#define CVMX_PCIERCX_CFG023(block_id) (0x000000000000005Cull)
+#define CVMX_PCIERCX_CFG028(block_id) (0x0000000000000070ull)
+#define CVMX_PCIERCX_CFG029(block_id) (0x0000000000000074ull)
+#define CVMX_PCIERCX_CFG030(block_id) (0x0000000000000078ull)
+#define CVMX_PCIERCX_CFG031(block_id) (0x000000000000007Cull)
+#define CVMX_PCIERCX_CFG032(block_id) (0x0000000000000080ull)
+#define CVMX_PCIERCX_CFG033(block_id) (0x0000000000000084ull)
+#define CVMX_PCIERCX_CFG034(block_id) (0x0000000000000088ull)
+#define CVMX_PCIERCX_CFG035(block_id) (0x000000000000008Cull)
+#define CVMX_PCIERCX_CFG036(block_id) (0x0000000000000090ull)
+#define CVMX_PCIERCX_CFG037(block_id) (0x0000000000000094ull)
+#define CVMX_PCIERCX_CFG038(block_id) (0x0000000000000098ull)
+#define CVMX_PCIERCX_CFG039(block_id) (0x000000000000009Cull)
+#define CVMX_PCIERCX_CFG040(block_id) (0x00000000000000A0ull)
+#define CVMX_PCIERCX_CFG041(block_id) (0x00000000000000A4ull)
+#define CVMX_PCIERCX_CFG042(block_id) (0x00000000000000A8ull)
+#define CVMX_PCIERCX_CFG064(block_id) (0x0000000000000100ull)
+#define CVMX_PCIERCX_CFG065(block_id) (0x0000000000000104ull)
+#define CVMX_PCIERCX_CFG066(block_id) (0x0000000000000108ull)
+#define CVMX_PCIERCX_CFG067(block_id) (0x000000000000010Cull)
+#define CVMX_PCIERCX_CFG068(block_id) (0x0000000000000110ull)
+#define CVMX_PCIERCX_CFG069(block_id) (0x0000000000000114ull)
+#define CVMX_PCIERCX_CFG070(block_id) (0x0000000000000118ull)
+#define CVMX_PCIERCX_CFG071(block_id) (0x000000000000011Cull)
+#define CVMX_PCIERCX_CFG072(block_id) (0x0000000000000120ull)
+#define CVMX_PCIERCX_CFG073(block_id) (0x0000000000000124ull)
+#define CVMX_PCIERCX_CFG074(block_id) (0x0000000000000128ull)
+#define CVMX_PCIERCX_CFG075(block_id) (0x000000000000012Cull)
+#define CVMX_PCIERCX_CFG076(block_id) (0x0000000000000130ull)
+#define CVMX_PCIERCX_CFG077(block_id) (0x0000000000000134ull)
+#define CVMX_PCIERCX_CFG448(block_id) (0x0000000000000700ull)
+#define CVMX_PCIERCX_CFG449(block_id) (0x0000000000000704ull)
+#define CVMX_PCIERCX_CFG450(block_id) (0x0000000000000708ull)
+#define CVMX_PCIERCX_CFG451(block_id) (0x000000000000070Cull)
+#define CVMX_PCIERCX_CFG452(block_id) (0x0000000000000710ull)
+#define CVMX_PCIERCX_CFG453(block_id) (0x0000000000000714ull)
+#define CVMX_PCIERCX_CFG454(block_id) (0x0000000000000718ull)
+#define CVMX_PCIERCX_CFG455(block_id) (0x000000000000071Cull)
+#define CVMX_PCIERCX_CFG456(block_id) (0x0000000000000720ull)
+#define CVMX_PCIERCX_CFG458(block_id) (0x0000000000000728ull)
+#define CVMX_PCIERCX_CFG459(block_id) (0x000000000000072Cull)
+#define CVMX_PCIERCX_CFG460(block_id) (0x0000000000000730ull)
+#define CVMX_PCIERCX_CFG461(block_id) (0x0000000000000734ull)
+#define CVMX_PCIERCX_CFG462(block_id) (0x0000000000000738ull)
+#define CVMX_PCIERCX_CFG463(block_id) (0x000000000000073Cull)
+#define CVMX_PCIERCX_CFG464(block_id) (0x0000000000000740ull)
+#define CVMX_PCIERCX_CFG465(block_id) (0x0000000000000744ull)
+#define CVMX_PCIERCX_CFG466(block_id) (0x0000000000000748ull)
+#define CVMX_PCIERCX_CFG467(block_id) (0x000000000000074Cull)
+#define CVMX_PCIERCX_CFG468(block_id) (0x0000000000000750ull)
+#define CVMX_PCIERCX_CFG490(block_id) (0x00000000000007A8ull)
+#define CVMX_PCIERCX_CFG491(block_id) (0x00000000000007ACull)
+#define CVMX_PCIERCX_CFG492(block_id) (0x00000000000007B0ull)
+#define CVMX_PCIERCX_CFG515(block_id) (0x000000000000080Cull)
+#define CVMX_PCIERCX_CFG516(block_id) (0x0000000000000810ull)
+#define CVMX_PCIERCX_CFG517(block_id) (0x0000000000000814ull)
union cvmx_pciercx_cfg000 {
uint32_t u32;
@@ -191,6 +116,8 @@ union cvmx_pciercx_cfg000 {
struct cvmx_pciercx_cfg000_s cn52xxp1;
struct cvmx_pciercx_cfg000_s cn56xx;
struct cvmx_pciercx_cfg000_s cn56xxp1;
+ struct cvmx_pciercx_cfg000_s cn63xx;
+ struct cvmx_pciercx_cfg000_s cn63xxp1;
};
union cvmx_pciercx_cfg001 {
@@ -225,6 +152,8 @@ union cvmx_pciercx_cfg001 {
struct cvmx_pciercx_cfg001_s cn52xxp1;
struct cvmx_pciercx_cfg001_s cn56xx;
struct cvmx_pciercx_cfg001_s cn56xxp1;
+ struct cvmx_pciercx_cfg001_s cn63xx;
+ struct cvmx_pciercx_cfg001_s cn63xxp1;
};
union cvmx_pciercx_cfg002 {
@@ -239,6 +168,8 @@ union cvmx_pciercx_cfg002 {
struct cvmx_pciercx_cfg002_s cn52xxp1;
struct cvmx_pciercx_cfg002_s cn56xx;
struct cvmx_pciercx_cfg002_s cn56xxp1;
+ struct cvmx_pciercx_cfg002_s cn63xx;
+ struct cvmx_pciercx_cfg002_s cn63xxp1;
};
union cvmx_pciercx_cfg003 {
@@ -254,6 +185,8 @@ union cvmx_pciercx_cfg003 {
struct cvmx_pciercx_cfg003_s cn52xxp1;
struct cvmx_pciercx_cfg003_s cn56xx;
struct cvmx_pciercx_cfg003_s cn56xxp1;
+ struct cvmx_pciercx_cfg003_s cn63xx;
+ struct cvmx_pciercx_cfg003_s cn63xxp1;
};
union cvmx_pciercx_cfg004 {
@@ -265,6 +198,8 @@ union cvmx_pciercx_cfg004 {
struct cvmx_pciercx_cfg004_s cn52xxp1;
struct cvmx_pciercx_cfg004_s cn56xx;
struct cvmx_pciercx_cfg004_s cn56xxp1;
+ struct cvmx_pciercx_cfg004_s cn63xx;
+ struct cvmx_pciercx_cfg004_s cn63xxp1;
};
union cvmx_pciercx_cfg005 {
@@ -276,6 +211,8 @@ union cvmx_pciercx_cfg005 {
struct cvmx_pciercx_cfg005_s cn52xxp1;
struct cvmx_pciercx_cfg005_s cn56xx;
struct cvmx_pciercx_cfg005_s cn56xxp1;
+ struct cvmx_pciercx_cfg005_s cn63xx;
+ struct cvmx_pciercx_cfg005_s cn63xxp1;
};
union cvmx_pciercx_cfg006 {
@@ -290,6 +227,8 @@ union cvmx_pciercx_cfg006 {
struct cvmx_pciercx_cfg006_s cn52xxp1;
struct cvmx_pciercx_cfg006_s cn56xx;
struct cvmx_pciercx_cfg006_s cn56xxp1;
+ struct cvmx_pciercx_cfg006_s cn63xx;
+ struct cvmx_pciercx_cfg006_s cn63xxp1;
};
union cvmx_pciercx_cfg007 {
@@ -317,6 +256,8 @@ union cvmx_pciercx_cfg007 {
struct cvmx_pciercx_cfg007_s cn52xxp1;
struct cvmx_pciercx_cfg007_s cn56xx;
struct cvmx_pciercx_cfg007_s cn56xxp1;
+ struct cvmx_pciercx_cfg007_s cn63xx;
+ struct cvmx_pciercx_cfg007_s cn63xxp1;
};
union cvmx_pciercx_cfg008 {
@@ -331,6 +272,8 @@ union cvmx_pciercx_cfg008 {
struct cvmx_pciercx_cfg008_s cn52xxp1;
struct cvmx_pciercx_cfg008_s cn56xx;
struct cvmx_pciercx_cfg008_s cn56xxp1;
+ struct cvmx_pciercx_cfg008_s cn63xx;
+ struct cvmx_pciercx_cfg008_s cn63xxp1;
};
union cvmx_pciercx_cfg009 {
@@ -347,6 +290,8 @@ union cvmx_pciercx_cfg009 {
struct cvmx_pciercx_cfg009_s cn52xxp1;
struct cvmx_pciercx_cfg009_s cn56xx;
struct cvmx_pciercx_cfg009_s cn56xxp1;
+ struct cvmx_pciercx_cfg009_s cn63xx;
+ struct cvmx_pciercx_cfg009_s cn63xxp1;
};
union cvmx_pciercx_cfg010 {
@@ -358,6 +303,8 @@ union cvmx_pciercx_cfg010 {
struct cvmx_pciercx_cfg010_s cn52xxp1;
struct cvmx_pciercx_cfg010_s cn56xx;
struct cvmx_pciercx_cfg010_s cn56xxp1;
+ struct cvmx_pciercx_cfg010_s cn63xx;
+ struct cvmx_pciercx_cfg010_s cn63xxp1;
};
union cvmx_pciercx_cfg011 {
@@ -369,6 +316,8 @@ union cvmx_pciercx_cfg011 {
struct cvmx_pciercx_cfg011_s cn52xxp1;
struct cvmx_pciercx_cfg011_s cn56xx;
struct cvmx_pciercx_cfg011_s cn56xxp1;
+ struct cvmx_pciercx_cfg011_s cn63xx;
+ struct cvmx_pciercx_cfg011_s cn63xxp1;
};
union cvmx_pciercx_cfg012 {
@@ -381,6 +330,8 @@ union cvmx_pciercx_cfg012 {
struct cvmx_pciercx_cfg012_s cn52xxp1;
struct cvmx_pciercx_cfg012_s cn56xx;
struct cvmx_pciercx_cfg012_s cn56xxp1;
+ struct cvmx_pciercx_cfg012_s cn63xx;
+ struct cvmx_pciercx_cfg012_s cn63xxp1;
};
union cvmx_pciercx_cfg013 {
@@ -393,6 +344,8 @@ union cvmx_pciercx_cfg013 {
struct cvmx_pciercx_cfg013_s cn52xxp1;
struct cvmx_pciercx_cfg013_s cn56xx;
struct cvmx_pciercx_cfg013_s cn56xxp1;
+ struct cvmx_pciercx_cfg013_s cn63xx;
+ struct cvmx_pciercx_cfg013_s cn63xxp1;
};
union cvmx_pciercx_cfg014 {
@@ -404,6 +357,8 @@ union cvmx_pciercx_cfg014 {
struct cvmx_pciercx_cfg014_s cn52xxp1;
struct cvmx_pciercx_cfg014_s cn56xx;
struct cvmx_pciercx_cfg014_s cn56xxp1;
+ struct cvmx_pciercx_cfg014_s cn63xx;
+ struct cvmx_pciercx_cfg014_s cn63xxp1;
};
union cvmx_pciercx_cfg015 {
@@ -429,6 +384,8 @@ union cvmx_pciercx_cfg015 {
struct cvmx_pciercx_cfg015_s cn52xxp1;
struct cvmx_pciercx_cfg015_s cn56xx;
struct cvmx_pciercx_cfg015_s cn56xxp1;
+ struct cvmx_pciercx_cfg015_s cn63xx;
+ struct cvmx_pciercx_cfg015_s cn63xxp1;
};
union cvmx_pciercx_cfg016 {
@@ -449,6 +406,8 @@ union cvmx_pciercx_cfg016 {
struct cvmx_pciercx_cfg016_s cn52xxp1;
struct cvmx_pciercx_cfg016_s cn56xx;
struct cvmx_pciercx_cfg016_s cn56xxp1;
+ struct cvmx_pciercx_cfg016_s cn63xx;
+ struct cvmx_pciercx_cfg016_s cn63xxp1;
};
union cvmx_pciercx_cfg017 {
@@ -471,6 +430,8 @@ union cvmx_pciercx_cfg017 {
struct cvmx_pciercx_cfg017_s cn52xxp1;
struct cvmx_pciercx_cfg017_s cn56xx;
struct cvmx_pciercx_cfg017_s cn56xxp1;
+ struct cvmx_pciercx_cfg017_s cn63xx;
+ struct cvmx_pciercx_cfg017_s cn63xxp1;
};
union cvmx_pciercx_cfg020 {
@@ -488,6 +449,8 @@ union cvmx_pciercx_cfg020 {
struct cvmx_pciercx_cfg020_s cn52xxp1;
struct cvmx_pciercx_cfg020_s cn56xx;
struct cvmx_pciercx_cfg020_s cn56xxp1;
+ struct cvmx_pciercx_cfg020_s cn63xx;
+ struct cvmx_pciercx_cfg020_s cn63xxp1;
};
union cvmx_pciercx_cfg021 {
@@ -500,6 +463,8 @@ union cvmx_pciercx_cfg021 {
struct cvmx_pciercx_cfg021_s cn52xxp1;
struct cvmx_pciercx_cfg021_s cn56xx;
struct cvmx_pciercx_cfg021_s cn56xxp1;
+ struct cvmx_pciercx_cfg021_s cn63xx;
+ struct cvmx_pciercx_cfg021_s cn63xxp1;
};
union cvmx_pciercx_cfg022 {
@@ -511,6 +476,8 @@ union cvmx_pciercx_cfg022 {
struct cvmx_pciercx_cfg022_s cn52xxp1;
struct cvmx_pciercx_cfg022_s cn56xx;
struct cvmx_pciercx_cfg022_s cn56xxp1;
+ struct cvmx_pciercx_cfg022_s cn63xx;
+ struct cvmx_pciercx_cfg022_s cn63xxp1;
};
union cvmx_pciercx_cfg023 {
@@ -523,6 +490,8 @@ union cvmx_pciercx_cfg023 {
struct cvmx_pciercx_cfg023_s cn52xxp1;
struct cvmx_pciercx_cfg023_s cn56xx;
struct cvmx_pciercx_cfg023_s cn56xxp1;
+ struct cvmx_pciercx_cfg023_s cn63xx;
+ struct cvmx_pciercx_cfg023_s cn63xxp1;
};
union cvmx_pciercx_cfg028 {
@@ -540,6 +509,8 @@ union cvmx_pciercx_cfg028 {
struct cvmx_pciercx_cfg028_s cn52xxp1;
struct cvmx_pciercx_cfg028_s cn56xx;
struct cvmx_pciercx_cfg028_s cn56xxp1;
+ struct cvmx_pciercx_cfg028_s cn63xx;
+ struct cvmx_pciercx_cfg028_s cn63xxp1;
};
union cvmx_pciercx_cfg029 {
@@ -561,6 +532,8 @@ union cvmx_pciercx_cfg029 {
struct cvmx_pciercx_cfg029_s cn52xxp1;
struct cvmx_pciercx_cfg029_s cn56xx;
struct cvmx_pciercx_cfg029_s cn56xxp1;
+ struct cvmx_pciercx_cfg029_s cn63xx;
+ struct cvmx_pciercx_cfg029_s cn63xxp1;
};
union cvmx_pciercx_cfg030 {
@@ -590,6 +563,8 @@ union cvmx_pciercx_cfg030 {
struct cvmx_pciercx_cfg030_s cn52xxp1;
struct cvmx_pciercx_cfg030_s cn56xx;
struct cvmx_pciercx_cfg030_s cn56xxp1;
+ struct cvmx_pciercx_cfg030_s cn63xx;
+ struct cvmx_pciercx_cfg030_s cn63xxp1;
};
union cvmx_pciercx_cfg031 {
@@ -611,6 +586,8 @@ union cvmx_pciercx_cfg031 {
struct cvmx_pciercx_cfg031_s cn52xxp1;
struct cvmx_pciercx_cfg031_s cn56xx;
struct cvmx_pciercx_cfg031_s cn56xxp1;
+ struct cvmx_pciercx_cfg031_s cn63xx;
+ struct cvmx_pciercx_cfg031_s cn63xxp1;
};
union cvmx_pciercx_cfg032 {
@@ -641,6 +618,8 @@ union cvmx_pciercx_cfg032 {
struct cvmx_pciercx_cfg032_s cn52xxp1;
struct cvmx_pciercx_cfg032_s cn56xx;
struct cvmx_pciercx_cfg032_s cn56xxp1;
+ struct cvmx_pciercx_cfg032_s cn63xx;
+ struct cvmx_pciercx_cfg032_s cn63xxp1;
};
union cvmx_pciercx_cfg033 {
@@ -663,6 +642,8 @@ union cvmx_pciercx_cfg033 {
struct cvmx_pciercx_cfg033_s cn52xxp1;
struct cvmx_pciercx_cfg033_s cn56xx;
struct cvmx_pciercx_cfg033_s cn56xxp1;
+ struct cvmx_pciercx_cfg033_s cn63xx;
+ struct cvmx_pciercx_cfg033_s cn63xxp1;
};
union cvmx_pciercx_cfg034 {
@@ -695,6 +676,8 @@ union cvmx_pciercx_cfg034 {
struct cvmx_pciercx_cfg034_s cn52xxp1;
struct cvmx_pciercx_cfg034_s cn56xx;
struct cvmx_pciercx_cfg034_s cn56xxp1;
+ struct cvmx_pciercx_cfg034_s cn63xx;
+ struct cvmx_pciercx_cfg034_s cn63xxp1;
};
union cvmx_pciercx_cfg035 {
@@ -713,6 +696,8 @@ union cvmx_pciercx_cfg035 {
struct cvmx_pciercx_cfg035_s cn52xxp1;
struct cvmx_pciercx_cfg035_s cn56xx;
struct cvmx_pciercx_cfg035_s cn56xxp1;
+ struct cvmx_pciercx_cfg035_s cn63xx;
+ struct cvmx_pciercx_cfg035_s cn63xxp1;
};
union cvmx_pciercx_cfg036 {
@@ -727,6 +712,8 @@ union cvmx_pciercx_cfg036 {
struct cvmx_pciercx_cfg036_s cn52xxp1;
struct cvmx_pciercx_cfg036_s cn56xx;
struct cvmx_pciercx_cfg036_s cn56xxp1;
+ struct cvmx_pciercx_cfg036_s cn63xx;
+ struct cvmx_pciercx_cfg036_s cn63xxp1;
};
union cvmx_pciercx_cfg037 {
@@ -740,6 +727,8 @@ union cvmx_pciercx_cfg037 {
struct cvmx_pciercx_cfg037_s cn52xxp1;
struct cvmx_pciercx_cfg037_s cn56xx;
struct cvmx_pciercx_cfg037_s cn56xxp1;
+ struct cvmx_pciercx_cfg037_s cn63xx;
+ struct cvmx_pciercx_cfg037_s cn63xxp1;
};
union cvmx_pciercx_cfg038 {
@@ -753,28 +742,51 @@ union cvmx_pciercx_cfg038 {
struct cvmx_pciercx_cfg038_s cn52xxp1;
struct cvmx_pciercx_cfg038_s cn56xx;
struct cvmx_pciercx_cfg038_s cn56xxp1;
+ struct cvmx_pciercx_cfg038_s cn63xx;
+ struct cvmx_pciercx_cfg038_s cn63xxp1;
};
union cvmx_pciercx_cfg039 {
uint32_t u32;
struct cvmx_pciercx_cfg039_s {
- uint32_t reserved_0_31:32;
+ uint32_t reserved_9_31:23;
+ uint32_t cls:1;
+ uint32_t slsv:7;
+ uint32_t reserved_0_0:1;
} s;
- struct cvmx_pciercx_cfg039_s cn52xx;
- struct cvmx_pciercx_cfg039_s cn52xxp1;
- struct cvmx_pciercx_cfg039_s cn56xx;
- struct cvmx_pciercx_cfg039_s cn56xxp1;
+ struct cvmx_pciercx_cfg039_cn52xx {
+ uint32_t reserved_0_31:32;
+ } cn52xx;
+ struct cvmx_pciercx_cfg039_cn52xx cn52xxp1;
+ struct cvmx_pciercx_cfg039_cn52xx cn56xx;
+ struct cvmx_pciercx_cfg039_cn52xx cn56xxp1;
+ struct cvmx_pciercx_cfg039_s cn63xx;
+ struct cvmx_pciercx_cfg039_cn52xx cn63xxp1;
};
union cvmx_pciercx_cfg040 {
uint32_t u32;
struct cvmx_pciercx_cfg040_s {
+ uint32_t reserved_17_31:15;
+ uint32_t cdl:1;
+ uint32_t reserved_13_15:3;
+ uint32_t cde:1;
+ uint32_t csos:1;
+ uint32_t emc:1;
+ uint32_t tm:3;
+ uint32_t sde:1;
+ uint32_t hasd:1;
+ uint32_t ec:1;
+ uint32_t tls:4;
+ } s;
+ struct cvmx_pciercx_cfg040_cn52xx {
uint32_t reserved_0_31:32;
- } s;
- struct cvmx_pciercx_cfg040_s cn52xx;
- struct cvmx_pciercx_cfg040_s cn52xxp1;
- struct cvmx_pciercx_cfg040_s cn56xx;
- struct cvmx_pciercx_cfg040_s cn56xxp1;
+ } cn52xx;
+ struct cvmx_pciercx_cfg040_cn52xx cn52xxp1;
+ struct cvmx_pciercx_cfg040_cn52xx cn56xx;
+ struct cvmx_pciercx_cfg040_cn52xx cn56xxp1;
+ struct cvmx_pciercx_cfg040_s cn63xx;
+ struct cvmx_pciercx_cfg040_s cn63xxp1;
};
union cvmx_pciercx_cfg041 {
@@ -786,6 +798,8 @@ union cvmx_pciercx_cfg041 {
struct cvmx_pciercx_cfg041_s cn52xxp1;
struct cvmx_pciercx_cfg041_s cn56xx;
struct cvmx_pciercx_cfg041_s cn56xxp1;
+ struct cvmx_pciercx_cfg041_s cn63xx;
+ struct cvmx_pciercx_cfg041_s cn63xxp1;
};
union cvmx_pciercx_cfg042 {
@@ -797,6 +811,8 @@ union cvmx_pciercx_cfg042 {
struct cvmx_pciercx_cfg042_s cn52xxp1;
struct cvmx_pciercx_cfg042_s cn56xx;
struct cvmx_pciercx_cfg042_s cn56xxp1;
+ struct cvmx_pciercx_cfg042_s cn63xx;
+ struct cvmx_pciercx_cfg042_s cn63xxp1;
};
union cvmx_pciercx_cfg064 {
@@ -810,6 +826,8 @@ union cvmx_pciercx_cfg064 {
struct cvmx_pciercx_cfg064_s cn52xxp1;
struct cvmx_pciercx_cfg064_s cn56xx;
struct cvmx_pciercx_cfg064_s cn56xxp1;
+ struct cvmx_pciercx_cfg064_s cn63xx;
+ struct cvmx_pciercx_cfg064_s cn63xxp1;
};
union cvmx_pciercx_cfg065 {
@@ -834,6 +852,8 @@ union cvmx_pciercx_cfg065 {
struct cvmx_pciercx_cfg065_s cn52xxp1;
struct cvmx_pciercx_cfg065_s cn56xx;
struct cvmx_pciercx_cfg065_s cn56xxp1;
+ struct cvmx_pciercx_cfg065_s cn63xx;
+ struct cvmx_pciercx_cfg065_s cn63xxp1;
};
union cvmx_pciercx_cfg066 {
@@ -858,6 +878,8 @@ union cvmx_pciercx_cfg066 {
struct cvmx_pciercx_cfg066_s cn52xxp1;
struct cvmx_pciercx_cfg066_s cn56xx;
struct cvmx_pciercx_cfg066_s cn56xxp1;
+ struct cvmx_pciercx_cfg066_s cn63xx;
+ struct cvmx_pciercx_cfg066_s cn63xxp1;
};
union cvmx_pciercx_cfg067 {
@@ -882,6 +904,8 @@ union cvmx_pciercx_cfg067 {
struct cvmx_pciercx_cfg067_s cn52xxp1;
struct cvmx_pciercx_cfg067_s cn56xx;
struct cvmx_pciercx_cfg067_s cn56xxp1;
+ struct cvmx_pciercx_cfg067_s cn63xx;
+ struct cvmx_pciercx_cfg067_s cn63xxp1;
};
union cvmx_pciercx_cfg068 {
@@ -901,6 +925,8 @@ union cvmx_pciercx_cfg068 {
struct cvmx_pciercx_cfg068_s cn52xxp1;
struct cvmx_pciercx_cfg068_s cn56xx;
struct cvmx_pciercx_cfg068_s cn56xxp1;
+ struct cvmx_pciercx_cfg068_s cn63xx;
+ struct cvmx_pciercx_cfg068_s cn63xxp1;
};
union cvmx_pciercx_cfg069 {
@@ -920,6 +946,8 @@ union cvmx_pciercx_cfg069 {
struct cvmx_pciercx_cfg069_s cn52xxp1;
struct cvmx_pciercx_cfg069_s cn56xx;
struct cvmx_pciercx_cfg069_s cn56xxp1;
+ struct cvmx_pciercx_cfg069_s cn63xx;
+ struct cvmx_pciercx_cfg069_s cn63xxp1;
};
union cvmx_pciercx_cfg070 {
@@ -936,6 +964,8 @@ union cvmx_pciercx_cfg070 {
struct cvmx_pciercx_cfg070_s cn52xxp1;
struct cvmx_pciercx_cfg070_s cn56xx;
struct cvmx_pciercx_cfg070_s cn56xxp1;
+ struct cvmx_pciercx_cfg070_s cn63xx;
+ struct cvmx_pciercx_cfg070_s cn63xxp1;
};
union cvmx_pciercx_cfg071 {
@@ -947,6 +977,8 @@ union cvmx_pciercx_cfg071 {
struct cvmx_pciercx_cfg071_s cn52xxp1;
struct cvmx_pciercx_cfg071_s cn56xx;
struct cvmx_pciercx_cfg071_s cn56xxp1;
+ struct cvmx_pciercx_cfg071_s cn63xx;
+ struct cvmx_pciercx_cfg071_s cn63xxp1;
};
union cvmx_pciercx_cfg072 {
@@ -958,6 +990,8 @@ union cvmx_pciercx_cfg072 {
struct cvmx_pciercx_cfg072_s cn52xxp1;
struct cvmx_pciercx_cfg072_s cn56xx;
struct cvmx_pciercx_cfg072_s cn56xxp1;
+ struct cvmx_pciercx_cfg072_s cn63xx;
+ struct cvmx_pciercx_cfg072_s cn63xxp1;
};
union cvmx_pciercx_cfg073 {
@@ -969,6 +1003,8 @@ union cvmx_pciercx_cfg073 {
struct cvmx_pciercx_cfg073_s cn52xxp1;
struct cvmx_pciercx_cfg073_s cn56xx;
struct cvmx_pciercx_cfg073_s cn56xxp1;
+ struct cvmx_pciercx_cfg073_s cn63xx;
+ struct cvmx_pciercx_cfg073_s cn63xxp1;
};
union cvmx_pciercx_cfg074 {
@@ -980,6 +1016,8 @@ union cvmx_pciercx_cfg074 {
struct cvmx_pciercx_cfg074_s cn52xxp1;
struct cvmx_pciercx_cfg074_s cn56xx;
struct cvmx_pciercx_cfg074_s cn56xxp1;
+ struct cvmx_pciercx_cfg074_s cn63xx;
+ struct cvmx_pciercx_cfg074_s cn63xxp1;
};
union cvmx_pciercx_cfg075 {
@@ -994,6 +1032,8 @@ union cvmx_pciercx_cfg075 {
struct cvmx_pciercx_cfg075_s cn52xxp1;
struct cvmx_pciercx_cfg075_s cn56xx;
struct cvmx_pciercx_cfg075_s cn56xxp1;
+ struct cvmx_pciercx_cfg075_s cn63xx;
+ struct cvmx_pciercx_cfg075_s cn63xxp1;
};
union cvmx_pciercx_cfg076 {
@@ -1013,6 +1053,8 @@ union cvmx_pciercx_cfg076 {
struct cvmx_pciercx_cfg076_s cn52xxp1;
struct cvmx_pciercx_cfg076_s cn56xx;
struct cvmx_pciercx_cfg076_s cn56xxp1;
+ struct cvmx_pciercx_cfg076_s cn63xx;
+ struct cvmx_pciercx_cfg076_s cn63xxp1;
};
union cvmx_pciercx_cfg077 {
@@ -1025,6 +1067,8 @@ union cvmx_pciercx_cfg077 {
struct cvmx_pciercx_cfg077_s cn52xxp1;
struct cvmx_pciercx_cfg077_s cn56xx;
struct cvmx_pciercx_cfg077_s cn56xxp1;
+ struct cvmx_pciercx_cfg077_s cn63xx;
+ struct cvmx_pciercx_cfg077_s cn63xxp1;
};
union cvmx_pciercx_cfg448 {
@@ -1037,6 +1081,8 @@ union cvmx_pciercx_cfg448 {
struct cvmx_pciercx_cfg448_s cn52xxp1;
struct cvmx_pciercx_cfg448_s cn56xx;
struct cvmx_pciercx_cfg448_s cn56xxp1;
+ struct cvmx_pciercx_cfg448_s cn63xx;
+ struct cvmx_pciercx_cfg448_s cn63xxp1;
};
union cvmx_pciercx_cfg449 {
@@ -1048,6 +1094,8 @@ union cvmx_pciercx_cfg449 {
struct cvmx_pciercx_cfg449_s cn52xxp1;
struct cvmx_pciercx_cfg449_s cn56xx;
struct cvmx_pciercx_cfg449_s cn56xxp1;
+ struct cvmx_pciercx_cfg449_s cn63xx;
+ struct cvmx_pciercx_cfg449_s cn63xxp1;
};
union cvmx_pciercx_cfg450 {
@@ -1064,6 +1112,8 @@ union cvmx_pciercx_cfg450 {
struct cvmx_pciercx_cfg450_s cn52xxp1;
struct cvmx_pciercx_cfg450_s cn56xx;
struct cvmx_pciercx_cfg450_s cn56xxp1;
+ struct cvmx_pciercx_cfg450_s cn63xx;
+ struct cvmx_pciercx_cfg450_s cn63xxp1;
};
union cvmx_pciercx_cfg451 {
@@ -1080,6 +1130,8 @@ union cvmx_pciercx_cfg451 {
struct cvmx_pciercx_cfg451_s cn52xxp1;
struct cvmx_pciercx_cfg451_s cn56xx;
struct cvmx_pciercx_cfg451_s cn56xxp1;
+ struct cvmx_pciercx_cfg451_s cn63xx;
+ struct cvmx_pciercx_cfg451_s cn63xxp1;
};
union cvmx_pciercx_cfg452 {
@@ -1103,6 +1155,8 @@ union cvmx_pciercx_cfg452 {
struct cvmx_pciercx_cfg452_s cn52xxp1;
struct cvmx_pciercx_cfg452_s cn56xx;
struct cvmx_pciercx_cfg452_s cn56xxp1;
+ struct cvmx_pciercx_cfg452_s cn63xx;
+ struct cvmx_pciercx_cfg452_s cn63xxp1;
};
union cvmx_pciercx_cfg453 {
@@ -1118,6 +1172,8 @@ union cvmx_pciercx_cfg453 {
struct cvmx_pciercx_cfg453_s cn52xxp1;
struct cvmx_pciercx_cfg453_s cn56xx;
struct cvmx_pciercx_cfg453_s cn56xxp1;
+ struct cvmx_pciercx_cfg453_s cn63xx;
+ struct cvmx_pciercx_cfg453_s cn63xxp1;
};
union cvmx_pciercx_cfg454 {
@@ -1136,6 +1192,8 @@ union cvmx_pciercx_cfg454 {
struct cvmx_pciercx_cfg454_s cn52xxp1;
struct cvmx_pciercx_cfg454_s cn56xx;
struct cvmx_pciercx_cfg454_s cn56xxp1;
+ struct cvmx_pciercx_cfg454_s cn63xx;
+ struct cvmx_pciercx_cfg454_s cn63xxp1;
};
union cvmx_pciercx_cfg455 {
@@ -1165,6 +1223,8 @@ union cvmx_pciercx_cfg455 {
struct cvmx_pciercx_cfg455_s cn52xxp1;
struct cvmx_pciercx_cfg455_s cn56xx;
struct cvmx_pciercx_cfg455_s cn56xxp1;
+ struct cvmx_pciercx_cfg455_s cn63xx;
+ struct cvmx_pciercx_cfg455_s cn63xxp1;
};
union cvmx_pciercx_cfg456 {
@@ -1178,6 +1238,8 @@ union cvmx_pciercx_cfg456 {
struct cvmx_pciercx_cfg456_s cn52xxp1;
struct cvmx_pciercx_cfg456_s cn56xx;
struct cvmx_pciercx_cfg456_s cn56xxp1;
+ struct cvmx_pciercx_cfg456_s cn63xx;
+ struct cvmx_pciercx_cfg456_s cn63xxp1;
};
union cvmx_pciercx_cfg458 {
@@ -1189,6 +1251,8 @@ union cvmx_pciercx_cfg458 {
struct cvmx_pciercx_cfg458_s cn52xxp1;
struct cvmx_pciercx_cfg458_s cn56xx;
struct cvmx_pciercx_cfg458_s cn56xxp1;
+ struct cvmx_pciercx_cfg458_s cn63xx;
+ struct cvmx_pciercx_cfg458_s cn63xxp1;
};
union cvmx_pciercx_cfg459 {
@@ -1200,6 +1264,8 @@ union cvmx_pciercx_cfg459 {
struct cvmx_pciercx_cfg459_s cn52xxp1;
struct cvmx_pciercx_cfg459_s cn56xx;
struct cvmx_pciercx_cfg459_s cn56xxp1;
+ struct cvmx_pciercx_cfg459_s cn63xx;
+ struct cvmx_pciercx_cfg459_s cn63xxp1;
};
union cvmx_pciercx_cfg460 {
@@ -1213,6 +1279,8 @@ union cvmx_pciercx_cfg460 {
struct cvmx_pciercx_cfg460_s cn52xxp1;
struct cvmx_pciercx_cfg460_s cn56xx;
struct cvmx_pciercx_cfg460_s cn56xxp1;
+ struct cvmx_pciercx_cfg460_s cn63xx;
+ struct cvmx_pciercx_cfg460_s cn63xxp1;
};
union cvmx_pciercx_cfg461 {
@@ -1226,6 +1294,8 @@ union cvmx_pciercx_cfg461 {
struct cvmx_pciercx_cfg461_s cn52xxp1;
struct cvmx_pciercx_cfg461_s cn56xx;
struct cvmx_pciercx_cfg461_s cn56xxp1;
+ struct cvmx_pciercx_cfg461_s cn63xx;
+ struct cvmx_pciercx_cfg461_s cn63xxp1;
};
union cvmx_pciercx_cfg462 {
@@ -1239,6 +1309,8 @@ union cvmx_pciercx_cfg462 {
struct cvmx_pciercx_cfg462_s cn52xxp1;
struct cvmx_pciercx_cfg462_s cn56xx;
struct cvmx_pciercx_cfg462_s cn56xxp1;
+ struct cvmx_pciercx_cfg462_s cn63xx;
+ struct cvmx_pciercx_cfg462_s cn63xxp1;
};
union cvmx_pciercx_cfg463 {
@@ -1253,6 +1325,8 @@ union cvmx_pciercx_cfg463 {
struct cvmx_pciercx_cfg463_s cn52xxp1;
struct cvmx_pciercx_cfg463_s cn56xx;
struct cvmx_pciercx_cfg463_s cn56xxp1;
+ struct cvmx_pciercx_cfg463_s cn63xx;
+ struct cvmx_pciercx_cfg463_s cn63xxp1;
};
union cvmx_pciercx_cfg464 {
@@ -1267,6 +1341,8 @@ union cvmx_pciercx_cfg464 {
struct cvmx_pciercx_cfg464_s cn52xxp1;
struct cvmx_pciercx_cfg464_s cn56xx;
struct cvmx_pciercx_cfg464_s cn56xxp1;
+ struct cvmx_pciercx_cfg464_s cn63xx;
+ struct cvmx_pciercx_cfg464_s cn63xxp1;
};
union cvmx_pciercx_cfg465 {
@@ -1281,6 +1357,8 @@ union cvmx_pciercx_cfg465 {
struct cvmx_pciercx_cfg465_s cn52xxp1;
struct cvmx_pciercx_cfg465_s cn56xx;
struct cvmx_pciercx_cfg465_s cn56xxp1;
+ struct cvmx_pciercx_cfg465_s cn63xx;
+ struct cvmx_pciercx_cfg465_s cn63xxp1;
};
union cvmx_pciercx_cfg466 {
@@ -1298,6 +1376,8 @@ union cvmx_pciercx_cfg466 {
struct cvmx_pciercx_cfg466_s cn52xxp1;
struct cvmx_pciercx_cfg466_s cn56xx;
struct cvmx_pciercx_cfg466_s cn56xxp1;
+ struct cvmx_pciercx_cfg466_s cn63xx;
+ struct cvmx_pciercx_cfg466_s cn63xxp1;
};
union cvmx_pciercx_cfg467 {
@@ -1313,6 +1393,8 @@ union cvmx_pciercx_cfg467 {
struct cvmx_pciercx_cfg467_s cn52xxp1;
struct cvmx_pciercx_cfg467_s cn56xx;
struct cvmx_pciercx_cfg467_s cn56xxp1;
+ struct cvmx_pciercx_cfg467_s cn63xx;
+ struct cvmx_pciercx_cfg467_s cn63xxp1;
};
union cvmx_pciercx_cfg468 {
@@ -1328,6 +1410,8 @@ union cvmx_pciercx_cfg468 {
struct cvmx_pciercx_cfg468_s cn52xxp1;
struct cvmx_pciercx_cfg468_s cn56xx;
struct cvmx_pciercx_cfg468_s cn56xxp1;
+ struct cvmx_pciercx_cfg468_s cn63xx;
+ struct cvmx_pciercx_cfg468_s cn63xxp1;
};
union cvmx_pciercx_cfg490 {
@@ -1342,6 +1426,8 @@ union cvmx_pciercx_cfg490 {
struct cvmx_pciercx_cfg490_s cn52xxp1;
struct cvmx_pciercx_cfg490_s cn56xx;
struct cvmx_pciercx_cfg490_s cn56xxp1;
+ struct cvmx_pciercx_cfg490_s cn63xx;
+ struct cvmx_pciercx_cfg490_s cn63xxp1;
};
union cvmx_pciercx_cfg491 {
@@ -1356,6 +1442,8 @@ union cvmx_pciercx_cfg491 {
struct cvmx_pciercx_cfg491_s cn52xxp1;
struct cvmx_pciercx_cfg491_s cn56xx;
struct cvmx_pciercx_cfg491_s cn56xxp1;
+ struct cvmx_pciercx_cfg491_s cn63xx;
+ struct cvmx_pciercx_cfg491_s cn63xxp1;
};
union cvmx_pciercx_cfg492 {
@@ -1370,6 +1458,23 @@ union cvmx_pciercx_cfg492 {
struct cvmx_pciercx_cfg492_s cn52xxp1;
struct cvmx_pciercx_cfg492_s cn56xx;
struct cvmx_pciercx_cfg492_s cn56xxp1;
+ struct cvmx_pciercx_cfg492_s cn63xx;
+ struct cvmx_pciercx_cfg492_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg515 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg515_s {
+ uint32_t reserved_21_31:11;
+ uint32_t s_d_e:1;
+ uint32_t ctcrb:1;
+ uint32_t cpyts:1;
+ uint32_t dsc:1;
+ uint32_t le:9;
+ uint32_t n_fts:8;
+ } s;
+ struct cvmx_pciercx_cfg515_s cn63xx;
+ struct cvmx_pciercx_cfg515_s cn63xxp1;
};
union cvmx_pciercx_cfg516 {
@@ -1381,6 +1486,8 @@ union cvmx_pciercx_cfg516 {
struct cvmx_pciercx_cfg516_s cn52xxp1;
struct cvmx_pciercx_cfg516_s cn56xx;
struct cvmx_pciercx_cfg516_s cn56xxp1;
+ struct cvmx_pciercx_cfg516_s cn63xx;
+ struct cvmx_pciercx_cfg516_s cn63xxp1;
};
union cvmx_pciercx_cfg517 {
@@ -1392,6 +1499,8 @@ union cvmx_pciercx_cfg517 {
struct cvmx_pciercx_cfg517_s cn52xxp1;
struct cvmx_pciercx_cfg517_s cn56xx;
struct cvmx_pciercx_cfg517_s cn56xxp1;
+ struct cvmx_pciercx_cfg517_s cn63xx;
+ struct cvmx_pciercx_cfg517_s cn63xxp1;
};
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pescx-defs.h b/arch/mips/include/asm/octeon/cvmx-pescx-defs.h
index f40cfaf84454..aef84851a94c 100644
--- a/arch/mips/include/asm/octeon/cvmx-pescx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pescx-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
@@ -28,38 +28,22 @@
#ifndef __CVMX_PESCX_DEFS_H__
#define __CVMX_PESCX_DEFS_H__
-#define CVMX_PESCX_BIST_STATUS(block_id) \
- CVMX_ADD_IO_SEG(0x00011800C8000018ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_BIST_STATUS2(block_id) \
- CVMX_ADD_IO_SEG(0x00011800C8000418ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_CFG_RD(block_id) \
- CVMX_ADD_IO_SEG(0x00011800C8000030ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_CFG_WR(block_id) \
- CVMX_ADD_IO_SEG(0x00011800C8000028ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_CPL_LUT_VALID(block_id) \
- CVMX_ADD_IO_SEG(0x00011800C8000098ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_CTL_STATUS(block_id) \
- CVMX_ADD_IO_SEG(0x00011800C8000000ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_CTL_STATUS2(block_id) \
- CVMX_ADD_IO_SEG(0x00011800C8000400ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_DBG_INFO(block_id) \
- CVMX_ADD_IO_SEG(0x00011800C8000008ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_DBG_INFO_EN(block_id) \
- CVMX_ADD_IO_SEG(0x00011800C80000A0ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_DIAG_STATUS(block_id) \
- CVMX_ADD_IO_SEG(0x00011800C8000020ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_P2N_BAR0_START(block_id) \
- CVMX_ADD_IO_SEG(0x00011800C8000080ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_P2N_BAR1_START(block_id) \
- CVMX_ADD_IO_SEG(0x00011800C8000088ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_P2N_BAR2_START(block_id) \
- CVMX_ADD_IO_SEG(0x00011800C8000090ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_P2P_BARX_END(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800C8000048ull + (((offset) & 3) * 16) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_P2P_BARX_START(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800C8000040ull + (((offset) & 3) * 16) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_TLP_CREDITS(block_id) \
- CVMX_ADD_IO_SEG(0x00011800C8000038ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_BIST_STATUS(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000018ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_BIST_STATUS2(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000418ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_CFG_RD(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000030ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_CFG_WR(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000028ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_CPL_LUT_VALID(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000098ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_CTL_STATUS(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000000ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_CTL_STATUS2(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000400ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_DBG_INFO(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000008ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_DBG_INFO_EN(block_id) (CVMX_ADD_IO_SEG(0x00011800C80000A0ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_DIAG_STATUS(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000020ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_P2N_BAR0_START(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000080ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_P2N_BAR1_START(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000088ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_P2N_BAR2_START(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000090ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_P2P_BARX_END(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800C8000048ull) + (((offset) & 3) + ((block_id) & 1) * 0x800000ull) * 16)
+#define CVMX_PESCX_P2P_BARX_START(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800C8000040ull) + (((offset) & 3) + ((block_id) & 1) * 0x800000ull) * 16)
+#define CVMX_PESCX_TLP_CREDITS(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000038ull) + ((block_id) & 1) * 0x8000000ull)
union cvmx_pescx_bist_status {
uint64_t u64;
diff --git a/arch/mips/include/asm/octeon/cvmx-pexp-defs.h b/arch/mips/include/asm/octeon/cvmx-pexp-defs.h
index 5ea5dc571b54..5ab8679d89af 100644
--- a/arch/mips/include/asm/octeon/cvmx-pexp-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pexp-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
@@ -35,195 +35,191 @@
#ifndef __CVMX_PEXP_DEFS_H__
#define __CVMX_PEXP_DEFS_H__
-#define CVMX_PEXP_NPEI_BAR1_INDEXX(offset) \
- CVMX_ADD_IO_SEG(0x00011F0000008000ull + (((offset) & 31) * 16))
-#define CVMX_PEXP_NPEI_BIST_STATUS \
- CVMX_ADD_IO_SEG(0x00011F0000008580ull)
-#define CVMX_PEXP_NPEI_BIST_STATUS2 \
- CVMX_ADD_IO_SEG(0x00011F0000008680ull)
-#define CVMX_PEXP_NPEI_CTL_PORT0 \
- CVMX_ADD_IO_SEG(0x00011F0000008250ull)
-#define CVMX_PEXP_NPEI_CTL_PORT1 \
- CVMX_ADD_IO_SEG(0x00011F0000008260ull)
-#define CVMX_PEXP_NPEI_CTL_STATUS \
- CVMX_ADD_IO_SEG(0x00011F0000008570ull)
-#define CVMX_PEXP_NPEI_CTL_STATUS2 \
- CVMX_ADD_IO_SEG(0x00011F000000BC00ull)
-#define CVMX_PEXP_NPEI_DATA_OUT_CNT \
- CVMX_ADD_IO_SEG(0x00011F00000085F0ull)
-#define CVMX_PEXP_NPEI_DBG_DATA \
- CVMX_ADD_IO_SEG(0x00011F0000008510ull)
-#define CVMX_PEXP_NPEI_DBG_SELECT \
- CVMX_ADD_IO_SEG(0x00011F0000008500ull)
-#define CVMX_PEXP_NPEI_DMA0_INT_LEVEL \
- CVMX_ADD_IO_SEG(0x00011F00000085C0ull)
-#define CVMX_PEXP_NPEI_DMA1_INT_LEVEL \
- CVMX_ADD_IO_SEG(0x00011F00000085D0ull)
-#define CVMX_PEXP_NPEI_DMAX_COUNTS(offset) \
- CVMX_ADD_IO_SEG(0x00011F0000008450ull + (((offset) & 7) * 16))
-#define CVMX_PEXP_NPEI_DMAX_DBELL(offset) \
- CVMX_ADD_IO_SEG(0x00011F00000083B0ull + (((offset) & 7) * 16))
-#define CVMX_PEXP_NPEI_DMAX_IBUFF_SADDR(offset) \
- CVMX_ADD_IO_SEG(0x00011F0000008400ull + (((offset) & 7) * 16))
-#define CVMX_PEXP_NPEI_DMAX_NADDR(offset) \
- CVMX_ADD_IO_SEG(0x00011F00000084A0ull + (((offset) & 7) * 16))
-#define CVMX_PEXP_NPEI_DMA_CNTS \
- CVMX_ADD_IO_SEG(0x00011F00000085E0ull)
-#define CVMX_PEXP_NPEI_DMA_CONTROL \
- CVMX_ADD_IO_SEG(0x00011F00000083A0ull)
-#define CVMX_PEXP_NPEI_INT_A_ENB \
- CVMX_ADD_IO_SEG(0x00011F0000008560ull)
-#define CVMX_PEXP_NPEI_INT_A_ENB2 \
- CVMX_ADD_IO_SEG(0x00011F000000BCE0ull)
-#define CVMX_PEXP_NPEI_INT_A_SUM \
- CVMX_ADD_IO_SEG(0x00011F0000008550ull)
-#define CVMX_PEXP_NPEI_INT_ENB \
- CVMX_ADD_IO_SEG(0x00011F0000008540ull)
-#define CVMX_PEXP_NPEI_INT_ENB2 \
- CVMX_ADD_IO_SEG(0x00011F000000BCD0ull)
-#define CVMX_PEXP_NPEI_INT_INFO \
- CVMX_ADD_IO_SEG(0x00011F0000008590ull)
-#define CVMX_PEXP_NPEI_INT_SUM \
- CVMX_ADD_IO_SEG(0x00011F0000008530ull)
-#define CVMX_PEXP_NPEI_INT_SUM2 \
- CVMX_ADD_IO_SEG(0x00011F000000BCC0ull)
-#define CVMX_PEXP_NPEI_LAST_WIN_RDATA0 \
- CVMX_ADD_IO_SEG(0x00011F0000008600ull)
-#define CVMX_PEXP_NPEI_LAST_WIN_RDATA1 \
- CVMX_ADD_IO_SEG(0x00011F0000008610ull)
-#define CVMX_PEXP_NPEI_MEM_ACCESS_CTL \
- CVMX_ADD_IO_SEG(0x00011F00000084F0ull)
-#define CVMX_PEXP_NPEI_MEM_ACCESS_SUBIDX(offset) \
- CVMX_ADD_IO_SEG(0x00011F0000008280ull + (((offset) & 31) * 16) - 16 * 12)
-#define CVMX_PEXP_NPEI_MSI_ENB0 \
- CVMX_ADD_IO_SEG(0x00011F000000BC50ull)
-#define CVMX_PEXP_NPEI_MSI_ENB1 \
- CVMX_ADD_IO_SEG(0x00011F000000BC60ull)
-#define CVMX_PEXP_NPEI_MSI_ENB2 \
- CVMX_ADD_IO_SEG(0x00011F000000BC70ull)
-#define CVMX_PEXP_NPEI_MSI_ENB3 \
- CVMX_ADD_IO_SEG(0x00011F000000BC80ull)
-#define CVMX_PEXP_NPEI_MSI_RCV0 \
- CVMX_ADD_IO_SEG(0x00011F000000BC10ull)
-#define CVMX_PEXP_NPEI_MSI_RCV1 \
- CVMX_ADD_IO_SEG(0x00011F000000BC20ull)
-#define CVMX_PEXP_NPEI_MSI_RCV2 \
- CVMX_ADD_IO_SEG(0x00011F000000BC30ull)
-#define CVMX_PEXP_NPEI_MSI_RCV3 \
- CVMX_ADD_IO_SEG(0x00011F000000BC40ull)
-#define CVMX_PEXP_NPEI_MSI_RD_MAP \
- CVMX_ADD_IO_SEG(0x00011F000000BCA0ull)
-#define CVMX_PEXP_NPEI_MSI_W1C_ENB0 \
- CVMX_ADD_IO_SEG(0x00011F000000BCF0ull)
-#define CVMX_PEXP_NPEI_MSI_W1C_ENB1 \
- CVMX_ADD_IO_SEG(0x00011F000000BD00ull)
-#define CVMX_PEXP_NPEI_MSI_W1C_ENB2 \
- CVMX_ADD_IO_SEG(0x00011F000000BD10ull)
-#define CVMX_PEXP_NPEI_MSI_W1C_ENB3 \
- CVMX_ADD_IO_SEG(0x00011F000000BD20ull)
-#define CVMX_PEXP_NPEI_MSI_W1S_ENB0 \
- CVMX_ADD_IO_SEG(0x00011F000000BD30ull)
-#define CVMX_PEXP_NPEI_MSI_W1S_ENB1 \
- CVMX_ADD_IO_SEG(0x00011F000000BD40ull)
-#define CVMX_PEXP_NPEI_MSI_W1S_ENB2 \
- CVMX_ADD_IO_SEG(0x00011F000000BD50ull)
-#define CVMX_PEXP_NPEI_MSI_W1S_ENB3 \
- CVMX_ADD_IO_SEG(0x00011F000000BD60ull)
-#define CVMX_PEXP_NPEI_MSI_WR_MAP \
- CVMX_ADD_IO_SEG(0x00011F000000BC90ull)
-#define CVMX_PEXP_NPEI_PCIE_CREDIT_CNT \
- CVMX_ADD_IO_SEG(0x00011F000000BD70ull)
-#define CVMX_PEXP_NPEI_PCIE_MSI_RCV \
- CVMX_ADD_IO_SEG(0x00011F000000BCB0ull)
-#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B1 \
- CVMX_ADD_IO_SEG(0x00011F0000008650ull)
-#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B2 \
- CVMX_ADD_IO_SEG(0x00011F0000008660ull)
-#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B3 \
- CVMX_ADD_IO_SEG(0x00011F0000008670ull)
-#define CVMX_PEXP_NPEI_PKTX_CNTS(offset) \
- CVMX_ADD_IO_SEG(0x00011F000000A400ull + (((offset) & 31) * 16))
-#define CVMX_PEXP_NPEI_PKTX_INSTR_BADDR(offset) \
- CVMX_ADD_IO_SEG(0x00011F000000A800ull + (((offset) & 31) * 16))
-#define CVMX_PEXP_NPEI_PKTX_INSTR_BAOFF_DBELL(offset) \
- CVMX_ADD_IO_SEG(0x00011F000000AC00ull + (((offset) & 31) * 16))
-#define CVMX_PEXP_NPEI_PKTX_INSTR_FIFO_RSIZE(offset) \
- CVMX_ADD_IO_SEG(0x00011F000000B000ull + (((offset) & 31) * 16))
-#define CVMX_PEXP_NPEI_PKTX_INSTR_HEADER(offset) \
- CVMX_ADD_IO_SEG(0x00011F000000B400ull + (((offset) & 31) * 16))
-#define CVMX_PEXP_NPEI_PKTX_IN_BP(offset) \
- CVMX_ADD_IO_SEG(0x00011F000000B800ull + (((offset) & 31) * 16))
-#define CVMX_PEXP_NPEI_PKTX_SLIST_BADDR(offset) \
- CVMX_ADD_IO_SEG(0x00011F0000009400ull + (((offset) & 31) * 16))
-#define CVMX_PEXP_NPEI_PKTX_SLIST_BAOFF_DBELL(offset) \
- CVMX_ADD_IO_SEG(0x00011F0000009800ull + (((offset) & 31) * 16))
-#define CVMX_PEXP_NPEI_PKTX_SLIST_FIFO_RSIZE(offset) \
- CVMX_ADD_IO_SEG(0x00011F0000009C00ull + (((offset) & 31) * 16))
-#define CVMX_PEXP_NPEI_PKT_CNT_INT \
- CVMX_ADD_IO_SEG(0x00011F0000009110ull)
-#define CVMX_PEXP_NPEI_PKT_CNT_INT_ENB \
- CVMX_ADD_IO_SEG(0x00011F0000009130ull)
-#define CVMX_PEXP_NPEI_PKT_DATA_OUT_ES \
- CVMX_ADD_IO_SEG(0x00011F00000090B0ull)
-#define CVMX_PEXP_NPEI_PKT_DATA_OUT_NS \
- CVMX_ADD_IO_SEG(0x00011F00000090A0ull)
-#define CVMX_PEXP_NPEI_PKT_DATA_OUT_ROR \
- CVMX_ADD_IO_SEG(0x00011F0000009090ull)
-#define CVMX_PEXP_NPEI_PKT_DPADDR \
- CVMX_ADD_IO_SEG(0x00011F0000009080ull)
-#define CVMX_PEXP_NPEI_PKT_INPUT_CONTROL \
- CVMX_ADD_IO_SEG(0x00011F0000009150ull)
-#define CVMX_PEXP_NPEI_PKT_INSTR_ENB \
- CVMX_ADD_IO_SEG(0x00011F0000009000ull)
-#define CVMX_PEXP_NPEI_PKT_INSTR_RD_SIZE \
- CVMX_ADD_IO_SEG(0x00011F0000009190ull)
-#define CVMX_PEXP_NPEI_PKT_INSTR_SIZE \
- CVMX_ADD_IO_SEG(0x00011F0000009020ull)
-#define CVMX_PEXP_NPEI_PKT_INT_LEVELS \
- CVMX_ADD_IO_SEG(0x00011F0000009100ull)
-#define CVMX_PEXP_NPEI_PKT_IN_BP \
- CVMX_ADD_IO_SEG(0x00011F00000086B0ull)
-#define CVMX_PEXP_NPEI_PKT_IN_DONEX_CNTS(offset) \
- CVMX_ADD_IO_SEG(0x00011F000000A000ull + (((offset) & 31) * 16))
-#define CVMX_PEXP_NPEI_PKT_IN_INSTR_COUNTS \
- CVMX_ADD_IO_SEG(0x00011F00000086A0ull)
-#define CVMX_PEXP_NPEI_PKT_IN_PCIE_PORT \
- CVMX_ADD_IO_SEG(0x00011F00000091A0ull)
-#define CVMX_PEXP_NPEI_PKT_IPTR \
- CVMX_ADD_IO_SEG(0x00011F0000009070ull)
-#define CVMX_PEXP_NPEI_PKT_OUTPUT_WMARK \
- CVMX_ADD_IO_SEG(0x00011F0000009160ull)
-#define CVMX_PEXP_NPEI_PKT_OUT_BMODE \
- CVMX_ADD_IO_SEG(0x00011F00000090D0ull)
-#define CVMX_PEXP_NPEI_PKT_OUT_ENB \
- CVMX_ADD_IO_SEG(0x00011F0000009010ull)
-#define CVMX_PEXP_NPEI_PKT_PCIE_PORT \
- CVMX_ADD_IO_SEG(0x00011F00000090E0ull)
-#define CVMX_PEXP_NPEI_PKT_PORT_IN_RST \
- CVMX_ADD_IO_SEG(0x00011F0000008690ull)
-#define CVMX_PEXP_NPEI_PKT_SLIST_ES \
- CVMX_ADD_IO_SEG(0x00011F0000009050ull)
-#define CVMX_PEXP_NPEI_PKT_SLIST_ID_SIZE \
- CVMX_ADD_IO_SEG(0x00011F0000009180ull)
-#define CVMX_PEXP_NPEI_PKT_SLIST_NS \
- CVMX_ADD_IO_SEG(0x00011F0000009040ull)
-#define CVMX_PEXP_NPEI_PKT_SLIST_ROR \
- CVMX_ADD_IO_SEG(0x00011F0000009030ull)
-#define CVMX_PEXP_NPEI_PKT_TIME_INT \
- CVMX_ADD_IO_SEG(0x00011F0000009120ull)
-#define CVMX_PEXP_NPEI_PKT_TIME_INT_ENB \
- CVMX_ADD_IO_SEG(0x00011F0000009140ull)
-#define CVMX_PEXP_NPEI_RSL_INT_BLOCKS \
- CVMX_ADD_IO_SEG(0x00011F0000008520ull)
-#define CVMX_PEXP_NPEI_SCRATCH_1 \
- CVMX_ADD_IO_SEG(0x00011F0000008270ull)
-#define CVMX_PEXP_NPEI_STATE1 \
- CVMX_ADD_IO_SEG(0x00011F0000008620ull)
-#define CVMX_PEXP_NPEI_STATE2 \
- CVMX_ADD_IO_SEG(0x00011F0000008630ull)
-#define CVMX_PEXP_NPEI_STATE3 \
- CVMX_ADD_IO_SEG(0x00011F0000008640ull)
-#define CVMX_PEXP_NPEI_WINDOW_CTL \
- CVMX_ADD_IO_SEG(0x00011F0000008380ull)
+#define CVMX_PEXP_NPEI_BAR1_INDEXX(offset) (CVMX_ADD_IO_SEG(0x00011F0000008000ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_BIST_STATUS (CVMX_ADD_IO_SEG(0x00011F0000008580ull))
+#define CVMX_PEXP_NPEI_BIST_STATUS2 (CVMX_ADD_IO_SEG(0x00011F0000008680ull))
+#define CVMX_PEXP_NPEI_CTL_PORT0 (CVMX_ADD_IO_SEG(0x00011F0000008250ull))
+#define CVMX_PEXP_NPEI_CTL_PORT1 (CVMX_ADD_IO_SEG(0x00011F0000008260ull))
+#define CVMX_PEXP_NPEI_CTL_STATUS (CVMX_ADD_IO_SEG(0x00011F0000008570ull))
+#define CVMX_PEXP_NPEI_CTL_STATUS2 (CVMX_ADD_IO_SEG(0x00011F000000BC00ull))
+#define CVMX_PEXP_NPEI_DATA_OUT_CNT (CVMX_ADD_IO_SEG(0x00011F00000085F0ull))
+#define CVMX_PEXP_NPEI_DBG_DATA (CVMX_ADD_IO_SEG(0x00011F0000008510ull))
+#define CVMX_PEXP_NPEI_DBG_SELECT (CVMX_ADD_IO_SEG(0x00011F0000008500ull))
+#define CVMX_PEXP_NPEI_DMA0_INT_LEVEL (CVMX_ADD_IO_SEG(0x00011F00000085C0ull))
+#define CVMX_PEXP_NPEI_DMA1_INT_LEVEL (CVMX_ADD_IO_SEG(0x00011F00000085D0ull))
+#define CVMX_PEXP_NPEI_DMAX_COUNTS(offset) (CVMX_ADD_IO_SEG(0x00011F0000008450ull) + ((offset) & 7) * 16)
+#define CVMX_PEXP_NPEI_DMAX_DBELL(offset) (CVMX_ADD_IO_SEG(0x00011F00000083B0ull) + ((offset) & 7) * 16)
+#define CVMX_PEXP_NPEI_DMAX_IBUFF_SADDR(offset) (CVMX_ADD_IO_SEG(0x00011F0000008400ull) + ((offset) & 7) * 16)
+#define CVMX_PEXP_NPEI_DMAX_NADDR(offset) (CVMX_ADD_IO_SEG(0x00011F00000084A0ull) + ((offset) & 7) * 16)
+#define CVMX_PEXP_NPEI_DMA_CNTS (CVMX_ADD_IO_SEG(0x00011F00000085E0ull))
+#define CVMX_PEXP_NPEI_DMA_CONTROL (CVMX_ADD_IO_SEG(0x00011F00000083A0ull))
+#define CVMX_PEXP_NPEI_DMA_PCIE_REQ_NUM (CVMX_ADD_IO_SEG(0x00011F00000085B0ull))
+#define CVMX_PEXP_NPEI_DMA_STATE1 (CVMX_ADD_IO_SEG(0x00011F00000086C0ull))
+#define CVMX_PEXP_NPEI_DMA_STATE1_P1 (CVMX_ADD_IO_SEG(0x00011F0000008680ull))
+#define CVMX_PEXP_NPEI_DMA_STATE2 (CVMX_ADD_IO_SEG(0x00011F00000086D0ull))
+#define CVMX_PEXP_NPEI_DMA_STATE2_P1 (CVMX_ADD_IO_SEG(0x00011F0000008690ull))
+#define CVMX_PEXP_NPEI_DMA_STATE3_P1 (CVMX_ADD_IO_SEG(0x00011F00000086A0ull))
+#define CVMX_PEXP_NPEI_DMA_STATE4_P1 (CVMX_ADD_IO_SEG(0x00011F00000086B0ull))
+#define CVMX_PEXP_NPEI_DMA_STATE5_P1 (CVMX_ADD_IO_SEG(0x00011F00000086C0ull))
+#define CVMX_PEXP_NPEI_INT_A_ENB (CVMX_ADD_IO_SEG(0x00011F0000008560ull))
+#define CVMX_PEXP_NPEI_INT_A_ENB2 (CVMX_ADD_IO_SEG(0x00011F000000BCE0ull))
+#define CVMX_PEXP_NPEI_INT_A_SUM (CVMX_ADD_IO_SEG(0x00011F0000008550ull))
+#define CVMX_PEXP_NPEI_INT_ENB (CVMX_ADD_IO_SEG(0x00011F0000008540ull))
+#define CVMX_PEXP_NPEI_INT_ENB2 (CVMX_ADD_IO_SEG(0x00011F000000BCD0ull))
+#define CVMX_PEXP_NPEI_INT_INFO (CVMX_ADD_IO_SEG(0x00011F0000008590ull))
+#define CVMX_PEXP_NPEI_INT_SUM (CVMX_ADD_IO_SEG(0x00011F0000008530ull))
+#define CVMX_PEXP_NPEI_INT_SUM2 (CVMX_ADD_IO_SEG(0x00011F000000BCC0ull))
+#define CVMX_PEXP_NPEI_LAST_WIN_RDATA0 (CVMX_ADD_IO_SEG(0x00011F0000008600ull))
+#define CVMX_PEXP_NPEI_LAST_WIN_RDATA1 (CVMX_ADD_IO_SEG(0x00011F0000008610ull))
+#define CVMX_PEXP_NPEI_MEM_ACCESS_CTL (CVMX_ADD_IO_SEG(0x00011F00000084F0ull))
+#define CVMX_PEXP_NPEI_MEM_ACCESS_SUBIDX(offset) (CVMX_ADD_IO_SEG(0x00011F0000008280ull) + ((offset) & 31) * 16 - 16*12)
+#define CVMX_PEXP_NPEI_MSI_ENB0 (CVMX_ADD_IO_SEG(0x00011F000000BC50ull))
+#define CVMX_PEXP_NPEI_MSI_ENB1 (CVMX_ADD_IO_SEG(0x00011F000000BC60ull))
+#define CVMX_PEXP_NPEI_MSI_ENB2 (CVMX_ADD_IO_SEG(0x00011F000000BC70ull))
+#define CVMX_PEXP_NPEI_MSI_ENB3 (CVMX_ADD_IO_SEG(0x00011F000000BC80ull))
+#define CVMX_PEXP_NPEI_MSI_RCV0 (CVMX_ADD_IO_SEG(0x00011F000000BC10ull))
+#define CVMX_PEXP_NPEI_MSI_RCV1 (CVMX_ADD_IO_SEG(0x00011F000000BC20ull))
+#define CVMX_PEXP_NPEI_MSI_RCV2 (CVMX_ADD_IO_SEG(0x00011F000000BC30ull))
+#define CVMX_PEXP_NPEI_MSI_RCV3 (CVMX_ADD_IO_SEG(0x00011F000000BC40ull))
+#define CVMX_PEXP_NPEI_MSI_RD_MAP (CVMX_ADD_IO_SEG(0x00011F000000BCA0ull))
+#define CVMX_PEXP_NPEI_MSI_W1C_ENB0 (CVMX_ADD_IO_SEG(0x00011F000000BCF0ull))
+#define CVMX_PEXP_NPEI_MSI_W1C_ENB1 (CVMX_ADD_IO_SEG(0x00011F000000BD00ull))
+#define CVMX_PEXP_NPEI_MSI_W1C_ENB2 (CVMX_ADD_IO_SEG(0x00011F000000BD10ull))
+#define CVMX_PEXP_NPEI_MSI_W1C_ENB3 (CVMX_ADD_IO_SEG(0x00011F000000BD20ull))
+#define CVMX_PEXP_NPEI_MSI_W1S_ENB0 (CVMX_ADD_IO_SEG(0x00011F000000BD30ull))
+#define CVMX_PEXP_NPEI_MSI_W1S_ENB1 (CVMX_ADD_IO_SEG(0x00011F000000BD40ull))
+#define CVMX_PEXP_NPEI_MSI_W1S_ENB2 (CVMX_ADD_IO_SEG(0x00011F000000BD50ull))
+#define CVMX_PEXP_NPEI_MSI_W1S_ENB3 (CVMX_ADD_IO_SEG(0x00011F000000BD60ull))
+#define CVMX_PEXP_NPEI_MSI_WR_MAP (CVMX_ADD_IO_SEG(0x00011F000000BC90ull))
+#define CVMX_PEXP_NPEI_PCIE_CREDIT_CNT (CVMX_ADD_IO_SEG(0x00011F000000BD70ull))
+#define CVMX_PEXP_NPEI_PCIE_MSI_RCV (CVMX_ADD_IO_SEG(0x00011F000000BCB0ull))
+#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B1 (CVMX_ADD_IO_SEG(0x00011F0000008650ull))
+#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B2 (CVMX_ADD_IO_SEG(0x00011F0000008660ull))
+#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B3 (CVMX_ADD_IO_SEG(0x00011F0000008670ull))
+#define CVMX_PEXP_NPEI_PKTX_CNTS(offset) (CVMX_ADD_IO_SEG(0x00011F000000A400ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKTX_INSTR_BADDR(offset) (CVMX_ADD_IO_SEG(0x00011F000000A800ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKTX_INSTR_BAOFF_DBELL(offset) (CVMX_ADD_IO_SEG(0x00011F000000AC00ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKTX_INSTR_FIFO_RSIZE(offset) (CVMX_ADD_IO_SEG(0x00011F000000B000ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKTX_INSTR_HEADER(offset) (CVMX_ADD_IO_SEG(0x00011F000000B400ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKTX_IN_BP(offset) (CVMX_ADD_IO_SEG(0x00011F000000B800ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKTX_SLIST_BADDR(offset) (CVMX_ADD_IO_SEG(0x00011F0000009400ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKTX_SLIST_BAOFF_DBELL(offset) (CVMX_ADD_IO_SEG(0x00011F0000009800ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKTX_SLIST_FIFO_RSIZE(offset) (CVMX_ADD_IO_SEG(0x00011F0000009C00ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKT_CNT_INT (CVMX_ADD_IO_SEG(0x00011F0000009110ull))
+#define CVMX_PEXP_NPEI_PKT_CNT_INT_ENB (CVMX_ADD_IO_SEG(0x00011F0000009130ull))
+#define CVMX_PEXP_NPEI_PKT_DATA_OUT_ES (CVMX_ADD_IO_SEG(0x00011F00000090B0ull))
+#define CVMX_PEXP_NPEI_PKT_DATA_OUT_NS (CVMX_ADD_IO_SEG(0x00011F00000090A0ull))
+#define CVMX_PEXP_NPEI_PKT_DATA_OUT_ROR (CVMX_ADD_IO_SEG(0x00011F0000009090ull))
+#define CVMX_PEXP_NPEI_PKT_DPADDR (CVMX_ADD_IO_SEG(0x00011F0000009080ull))
+#define CVMX_PEXP_NPEI_PKT_INPUT_CONTROL (CVMX_ADD_IO_SEG(0x00011F0000009150ull))
+#define CVMX_PEXP_NPEI_PKT_INSTR_ENB (CVMX_ADD_IO_SEG(0x00011F0000009000ull))
+#define CVMX_PEXP_NPEI_PKT_INSTR_RD_SIZE (CVMX_ADD_IO_SEG(0x00011F0000009190ull))
+#define CVMX_PEXP_NPEI_PKT_INSTR_SIZE (CVMX_ADD_IO_SEG(0x00011F0000009020ull))
+#define CVMX_PEXP_NPEI_PKT_INT_LEVELS (CVMX_ADD_IO_SEG(0x00011F0000009100ull))
+#define CVMX_PEXP_NPEI_PKT_IN_BP (CVMX_ADD_IO_SEG(0x00011F00000086B0ull))
+#define CVMX_PEXP_NPEI_PKT_IN_DONEX_CNTS(offset) (CVMX_ADD_IO_SEG(0x00011F000000A000ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKT_IN_INSTR_COUNTS (CVMX_ADD_IO_SEG(0x00011F00000086A0ull))
+#define CVMX_PEXP_NPEI_PKT_IN_PCIE_PORT (CVMX_ADD_IO_SEG(0x00011F00000091A0ull))
+#define CVMX_PEXP_NPEI_PKT_IPTR (CVMX_ADD_IO_SEG(0x00011F0000009070ull))
+#define CVMX_PEXP_NPEI_PKT_OUTPUT_WMARK (CVMX_ADD_IO_SEG(0x00011F0000009160ull))
+#define CVMX_PEXP_NPEI_PKT_OUT_BMODE (CVMX_ADD_IO_SEG(0x00011F00000090D0ull))
+#define CVMX_PEXP_NPEI_PKT_OUT_ENB (CVMX_ADD_IO_SEG(0x00011F0000009010ull))
+#define CVMX_PEXP_NPEI_PKT_PCIE_PORT (CVMX_ADD_IO_SEG(0x00011F00000090E0ull))
+#define CVMX_PEXP_NPEI_PKT_PORT_IN_RST (CVMX_ADD_IO_SEG(0x00011F0000008690ull))
+#define CVMX_PEXP_NPEI_PKT_SLIST_ES (CVMX_ADD_IO_SEG(0x00011F0000009050ull))
+#define CVMX_PEXP_NPEI_PKT_SLIST_ID_SIZE (CVMX_ADD_IO_SEG(0x00011F0000009180ull))
+#define CVMX_PEXP_NPEI_PKT_SLIST_NS (CVMX_ADD_IO_SEG(0x00011F0000009040ull))
+#define CVMX_PEXP_NPEI_PKT_SLIST_ROR (CVMX_ADD_IO_SEG(0x00011F0000009030ull))
+#define CVMX_PEXP_NPEI_PKT_TIME_INT (CVMX_ADD_IO_SEG(0x00011F0000009120ull))
+#define CVMX_PEXP_NPEI_PKT_TIME_INT_ENB (CVMX_ADD_IO_SEG(0x00011F0000009140ull))
+#define CVMX_PEXP_NPEI_RSL_INT_BLOCKS (CVMX_ADD_IO_SEG(0x00011F0000008520ull))
+#define CVMX_PEXP_NPEI_SCRATCH_1 (CVMX_ADD_IO_SEG(0x00011F0000008270ull))
+#define CVMX_PEXP_NPEI_STATE1 (CVMX_ADD_IO_SEG(0x00011F0000008620ull))
+#define CVMX_PEXP_NPEI_STATE2 (CVMX_ADD_IO_SEG(0x00011F0000008630ull))
+#define CVMX_PEXP_NPEI_STATE3 (CVMX_ADD_IO_SEG(0x00011F0000008640ull))
+#define CVMX_PEXP_NPEI_WINDOW_CTL (CVMX_ADD_IO_SEG(0x00011F0000008380ull))
+#define CVMX_PEXP_SLI_BIST_STATUS (CVMX_ADD_IO_SEG(0x00011F0000010580ull))
+#define CVMX_PEXP_SLI_CTL_PORTX(offset) (CVMX_ADD_IO_SEG(0x00011F0000010050ull) + ((offset) & 1) * 16)
+#define CVMX_PEXP_SLI_CTL_STATUS (CVMX_ADD_IO_SEG(0x00011F0000010570ull))
+#define CVMX_PEXP_SLI_DATA_OUT_CNT (CVMX_ADD_IO_SEG(0x00011F00000105F0ull))
+#define CVMX_PEXP_SLI_DBG_DATA (CVMX_ADD_IO_SEG(0x00011F0000010310ull))
+#define CVMX_PEXP_SLI_DBG_SELECT (CVMX_ADD_IO_SEG(0x00011F0000010300ull))
+#define CVMX_PEXP_SLI_DMAX_CNT(offset) (CVMX_ADD_IO_SEG(0x00011F0000010400ull) + ((offset) & 1) * 16)
+#define CVMX_PEXP_SLI_DMAX_INT_LEVEL(offset) (CVMX_ADD_IO_SEG(0x00011F00000103E0ull) + ((offset) & 1) * 16)
+#define CVMX_PEXP_SLI_DMAX_TIM(offset) (CVMX_ADD_IO_SEG(0x00011F0000010420ull) + ((offset) & 1) * 16)
+#define CVMX_PEXP_SLI_INT_ENB_CIU (CVMX_ADD_IO_SEG(0x00011F0000013CD0ull))
+#define CVMX_PEXP_SLI_INT_ENB_PORTX(offset) (CVMX_ADD_IO_SEG(0x00011F0000010340ull) + ((offset) & 1) * 16)
+#define CVMX_PEXP_SLI_INT_SUM (CVMX_ADD_IO_SEG(0x00011F0000010330ull))
+#define CVMX_PEXP_SLI_LAST_WIN_RDATA0 (CVMX_ADD_IO_SEG(0x00011F0000010600ull))
+#define CVMX_PEXP_SLI_LAST_WIN_RDATA1 (CVMX_ADD_IO_SEG(0x00011F0000010610ull))
+#define CVMX_PEXP_SLI_MAC_CREDIT_CNT (CVMX_ADD_IO_SEG(0x00011F0000013D70ull))
+#define CVMX_PEXP_SLI_MEM_ACCESS_CTL (CVMX_ADD_IO_SEG(0x00011F00000102F0ull))
+#define CVMX_PEXP_SLI_MEM_ACCESS_SUBIDX(offset) (CVMX_ADD_IO_SEG(0x00011F00000100E0ull) + ((offset) & 31) * 16 - 16*12)
+#define CVMX_PEXP_SLI_MSI_ENB0 (CVMX_ADD_IO_SEG(0x00011F0000013C50ull))
+#define CVMX_PEXP_SLI_MSI_ENB1 (CVMX_ADD_IO_SEG(0x00011F0000013C60ull))
+#define CVMX_PEXP_SLI_MSI_ENB2 (CVMX_ADD_IO_SEG(0x00011F0000013C70ull))
+#define CVMX_PEXP_SLI_MSI_ENB3 (CVMX_ADD_IO_SEG(0x00011F0000013C80ull))
+#define CVMX_PEXP_SLI_MSI_RCV0 (CVMX_ADD_IO_SEG(0x00011F0000013C10ull))
+#define CVMX_PEXP_SLI_MSI_RCV1 (CVMX_ADD_IO_SEG(0x00011F0000013C20ull))
+#define CVMX_PEXP_SLI_MSI_RCV2 (CVMX_ADD_IO_SEG(0x00011F0000013C30ull))
+#define CVMX_PEXP_SLI_MSI_RCV3 (CVMX_ADD_IO_SEG(0x00011F0000013C40ull))
+#define CVMX_PEXP_SLI_MSI_RD_MAP (CVMX_ADD_IO_SEG(0x00011F0000013CA0ull))
+#define CVMX_PEXP_SLI_MSI_W1C_ENB0 (CVMX_ADD_IO_SEG(0x00011F0000013CF0ull))
+#define CVMX_PEXP_SLI_MSI_W1C_ENB1 (CVMX_ADD_IO_SEG(0x00011F0000013D00ull))
+#define CVMX_PEXP_SLI_MSI_W1C_ENB2 (CVMX_ADD_IO_SEG(0x00011F0000013D10ull))
+#define CVMX_PEXP_SLI_MSI_W1C_ENB3 (CVMX_ADD_IO_SEG(0x00011F0000013D20ull))
+#define CVMX_PEXP_SLI_MSI_W1S_ENB0 (CVMX_ADD_IO_SEG(0x00011F0000013D30ull))
+#define CVMX_PEXP_SLI_MSI_W1S_ENB1 (CVMX_ADD_IO_SEG(0x00011F0000013D40ull))
+#define CVMX_PEXP_SLI_MSI_W1S_ENB2 (CVMX_ADD_IO_SEG(0x00011F0000013D50ull))
+#define CVMX_PEXP_SLI_MSI_W1S_ENB3 (CVMX_ADD_IO_SEG(0x00011F0000013D60ull))
+#define CVMX_PEXP_SLI_MSI_WR_MAP (CVMX_ADD_IO_SEG(0x00011F0000013C90ull))
+#define CVMX_PEXP_SLI_PCIE_MSI_RCV (CVMX_ADD_IO_SEG(0x00011F0000013CB0ull))
+#define CVMX_PEXP_SLI_PCIE_MSI_RCV_B1 (CVMX_ADD_IO_SEG(0x00011F0000010650ull))
+#define CVMX_PEXP_SLI_PCIE_MSI_RCV_B2 (CVMX_ADD_IO_SEG(0x00011F0000010660ull))
+#define CVMX_PEXP_SLI_PCIE_MSI_RCV_B3 (CVMX_ADD_IO_SEG(0x00011F0000010670ull))
+#define CVMX_PEXP_SLI_PKTX_CNTS(offset) (CVMX_ADD_IO_SEG(0x00011F0000012400ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKTX_INSTR_BADDR(offset) (CVMX_ADD_IO_SEG(0x00011F0000012800ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKTX_INSTR_BAOFF_DBELL(offset) (CVMX_ADD_IO_SEG(0x00011F0000012C00ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKTX_INSTR_FIFO_RSIZE(offset) (CVMX_ADD_IO_SEG(0x00011F0000013000ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKTX_INSTR_HEADER(offset) (CVMX_ADD_IO_SEG(0x00011F0000013400ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKTX_IN_BP(offset) (CVMX_ADD_IO_SEG(0x00011F0000013800ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKTX_OUT_SIZE(offset) (CVMX_ADD_IO_SEG(0x00011F0000010C00ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKTX_SLIST_BADDR(offset) (CVMX_ADD_IO_SEG(0x00011F0000011400ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKTX_SLIST_BAOFF_DBELL(offset) (CVMX_ADD_IO_SEG(0x00011F0000011800ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKTX_SLIST_FIFO_RSIZE(offset) (CVMX_ADD_IO_SEG(0x00011F0000011C00ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKT_CNT_INT (CVMX_ADD_IO_SEG(0x00011F0000011130ull))
+#define CVMX_PEXP_SLI_PKT_CNT_INT_ENB (CVMX_ADD_IO_SEG(0x00011F0000011150ull))
+#define CVMX_PEXP_SLI_PKT_CTL (CVMX_ADD_IO_SEG(0x00011F0000011220ull))
+#define CVMX_PEXP_SLI_PKT_DATA_OUT_ES (CVMX_ADD_IO_SEG(0x00011F00000110B0ull))
+#define CVMX_PEXP_SLI_PKT_DATA_OUT_NS (CVMX_ADD_IO_SEG(0x00011F00000110A0ull))
+#define CVMX_PEXP_SLI_PKT_DATA_OUT_ROR (CVMX_ADD_IO_SEG(0x00011F0000011090ull))
+#define CVMX_PEXP_SLI_PKT_DPADDR (CVMX_ADD_IO_SEG(0x00011F0000011080ull))
+#define CVMX_PEXP_SLI_PKT_INPUT_CONTROL (CVMX_ADD_IO_SEG(0x00011F0000011170ull))
+#define CVMX_PEXP_SLI_PKT_INSTR_ENB (CVMX_ADD_IO_SEG(0x00011F0000011000ull))
+#define CVMX_PEXP_SLI_PKT_INSTR_RD_SIZE (CVMX_ADD_IO_SEG(0x00011F00000111A0ull))
+#define CVMX_PEXP_SLI_PKT_INSTR_SIZE (CVMX_ADD_IO_SEG(0x00011F0000011020ull))
+#define CVMX_PEXP_SLI_PKT_INT_LEVELS (CVMX_ADD_IO_SEG(0x00011F0000011120ull))
+#define CVMX_PEXP_SLI_PKT_IN_BP (CVMX_ADD_IO_SEG(0x00011F0000011210ull))
+#define CVMX_PEXP_SLI_PKT_IN_DONEX_CNTS(offset) (CVMX_ADD_IO_SEG(0x00011F0000012000ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKT_IN_INSTR_COUNTS (CVMX_ADD_IO_SEG(0x00011F0000011200ull))
+#define CVMX_PEXP_SLI_PKT_IN_PCIE_PORT (CVMX_ADD_IO_SEG(0x00011F00000111B0ull))
+#define CVMX_PEXP_SLI_PKT_IPTR (CVMX_ADD_IO_SEG(0x00011F0000011070ull))
+#define CVMX_PEXP_SLI_PKT_OUTPUT_WMARK (CVMX_ADD_IO_SEG(0x00011F0000011180ull))
+#define CVMX_PEXP_SLI_PKT_OUT_BMODE (CVMX_ADD_IO_SEG(0x00011F00000110D0ull))
+#define CVMX_PEXP_SLI_PKT_OUT_ENB (CVMX_ADD_IO_SEG(0x00011F0000011010ull))
+#define CVMX_PEXP_SLI_PKT_PCIE_PORT (CVMX_ADD_IO_SEG(0x00011F00000110E0ull))
+#define CVMX_PEXP_SLI_PKT_PORT_IN_RST (CVMX_ADD_IO_SEG(0x00011F00000111F0ull))
+#define CVMX_PEXP_SLI_PKT_SLIST_ES (CVMX_ADD_IO_SEG(0x00011F0000011050ull))
+#define CVMX_PEXP_SLI_PKT_SLIST_NS (CVMX_ADD_IO_SEG(0x00011F0000011040ull))
+#define CVMX_PEXP_SLI_PKT_SLIST_ROR (CVMX_ADD_IO_SEG(0x00011F0000011030ull))
+#define CVMX_PEXP_SLI_PKT_TIME_INT (CVMX_ADD_IO_SEG(0x00011F0000011140ull))
+#define CVMX_PEXP_SLI_PKT_TIME_INT_ENB (CVMX_ADD_IO_SEG(0x00011F0000011160ull))
+#define CVMX_PEXP_SLI_S2M_PORTX_CTL(offset) (CVMX_ADD_IO_SEG(0x00011F0000013D80ull) + ((offset) & 1) * 16)
+#define CVMX_PEXP_SLI_SCRATCH_1 (CVMX_ADD_IO_SEG(0x00011F00000103C0ull))
+#define CVMX_PEXP_SLI_SCRATCH_2 (CVMX_ADD_IO_SEG(0x00011F00000103D0ull))
+#define CVMX_PEXP_SLI_STATE1 (CVMX_ADD_IO_SEG(0x00011F0000010620ull))
+#define CVMX_PEXP_SLI_STATE2 (CVMX_ADD_IO_SEG(0x00011F0000010630ull))
+#define CVMX_PEXP_SLI_STATE3 (CVMX_ADD_IO_SEG(0x00011F0000010640ull))
+#define CVMX_PEXP_SLI_WINDOW_CTL (CVMX_ADD_IO_SEG(0x00011F00000102E0ull))
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pow-defs.h b/arch/mips/include/asm/octeon/cvmx-pow-defs.h
index 2d82e24be51c..39fd75b03f77 100644
--- a/arch/mips/include/asm/octeon/cvmx-pow-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pow-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
@@ -28,52 +28,29 @@
#ifndef __CVMX_POW_DEFS_H__
#define __CVMX_POW_DEFS_H__
-#define CVMX_POW_BIST_STAT \
- CVMX_ADD_IO_SEG(0x00016700000003F8ull)
-#define CVMX_POW_DS_PC \
- CVMX_ADD_IO_SEG(0x0001670000000398ull)
-#define CVMX_POW_ECC_ERR \
- CVMX_ADD_IO_SEG(0x0001670000000218ull)
-#define CVMX_POW_INT_CTL \
- CVMX_ADD_IO_SEG(0x0001670000000220ull)
-#define CVMX_POW_IQ_CNTX(offset) \
- CVMX_ADD_IO_SEG(0x0001670000000340ull + (((offset) & 7) * 8))
-#define CVMX_POW_IQ_COM_CNT \
- CVMX_ADD_IO_SEG(0x0001670000000388ull)
-#define CVMX_POW_IQ_INT \
- CVMX_ADD_IO_SEG(0x0001670000000238ull)
-#define CVMX_POW_IQ_INT_EN \
- CVMX_ADD_IO_SEG(0x0001670000000240ull)
-#define CVMX_POW_IQ_THRX(offset) \
- CVMX_ADD_IO_SEG(0x00016700000003A0ull + (((offset) & 7) * 8))
-#define CVMX_POW_NOS_CNT \
- CVMX_ADD_IO_SEG(0x0001670000000228ull)
-#define CVMX_POW_NW_TIM \
- CVMX_ADD_IO_SEG(0x0001670000000210ull)
-#define CVMX_POW_PF_RST_MSK \
- CVMX_ADD_IO_SEG(0x0001670000000230ull)
-#define CVMX_POW_PP_GRP_MSKX(offset) \
- CVMX_ADD_IO_SEG(0x0001670000000000ull + (((offset) & 15) * 8))
-#define CVMX_POW_QOS_RNDX(offset) \
- CVMX_ADD_IO_SEG(0x00016700000001C0ull + (((offset) & 7) * 8))
-#define CVMX_POW_QOS_THRX(offset) \
- CVMX_ADD_IO_SEG(0x0001670000000180ull + (((offset) & 7) * 8))
-#define CVMX_POW_TS_PC \
- CVMX_ADD_IO_SEG(0x0001670000000390ull)
-#define CVMX_POW_WA_COM_PC \
- CVMX_ADD_IO_SEG(0x0001670000000380ull)
-#define CVMX_POW_WA_PCX(offset) \
- CVMX_ADD_IO_SEG(0x0001670000000300ull + (((offset) & 7) * 8))
-#define CVMX_POW_WQ_INT \
- CVMX_ADD_IO_SEG(0x0001670000000200ull)
-#define CVMX_POW_WQ_INT_CNTX(offset) \
- CVMX_ADD_IO_SEG(0x0001670000000100ull + (((offset) & 15) * 8))
-#define CVMX_POW_WQ_INT_PC \
- CVMX_ADD_IO_SEG(0x0001670000000208ull)
-#define CVMX_POW_WQ_INT_THRX(offset) \
- CVMX_ADD_IO_SEG(0x0001670000000080ull + (((offset) & 15) * 8))
-#define CVMX_POW_WS_PCX(offset) \
- CVMX_ADD_IO_SEG(0x0001670000000280ull + (((offset) & 15) * 8))
+#define CVMX_POW_BIST_STAT (CVMX_ADD_IO_SEG(0x00016700000003F8ull))
+#define CVMX_POW_DS_PC (CVMX_ADD_IO_SEG(0x0001670000000398ull))
+#define CVMX_POW_ECC_ERR (CVMX_ADD_IO_SEG(0x0001670000000218ull))
+#define CVMX_POW_INT_CTL (CVMX_ADD_IO_SEG(0x0001670000000220ull))
+#define CVMX_POW_IQ_CNTX(offset) (CVMX_ADD_IO_SEG(0x0001670000000340ull) + ((offset) & 7) * 8)
+#define CVMX_POW_IQ_COM_CNT (CVMX_ADD_IO_SEG(0x0001670000000388ull))
+#define CVMX_POW_IQ_INT (CVMX_ADD_IO_SEG(0x0001670000000238ull))
+#define CVMX_POW_IQ_INT_EN (CVMX_ADD_IO_SEG(0x0001670000000240ull))
+#define CVMX_POW_IQ_THRX(offset) (CVMX_ADD_IO_SEG(0x00016700000003A0ull) + ((offset) & 7) * 8)
+#define CVMX_POW_NOS_CNT (CVMX_ADD_IO_SEG(0x0001670000000228ull))
+#define CVMX_POW_NW_TIM (CVMX_ADD_IO_SEG(0x0001670000000210ull))
+#define CVMX_POW_PF_RST_MSK (CVMX_ADD_IO_SEG(0x0001670000000230ull))
+#define CVMX_POW_PP_GRP_MSKX(offset) (CVMX_ADD_IO_SEG(0x0001670000000000ull) + ((offset) & 15) * 8)
+#define CVMX_POW_QOS_RNDX(offset) (CVMX_ADD_IO_SEG(0x00016700000001C0ull) + ((offset) & 7) * 8)
+#define CVMX_POW_QOS_THRX(offset) (CVMX_ADD_IO_SEG(0x0001670000000180ull) + ((offset) & 7) * 8)
+#define CVMX_POW_TS_PC (CVMX_ADD_IO_SEG(0x0001670000000390ull))
+#define CVMX_POW_WA_COM_PC (CVMX_ADD_IO_SEG(0x0001670000000380ull))
+#define CVMX_POW_WA_PCX(offset) (CVMX_ADD_IO_SEG(0x0001670000000300ull) + ((offset) & 7) * 8)
+#define CVMX_POW_WQ_INT (CVMX_ADD_IO_SEG(0x0001670000000200ull))
+#define CVMX_POW_WQ_INT_CNTX(offset) (CVMX_ADD_IO_SEG(0x0001670000000100ull) + ((offset) & 15) * 8)
+#define CVMX_POW_WQ_INT_PC (CVMX_ADD_IO_SEG(0x0001670000000208ull))
+#define CVMX_POW_WQ_INT_THRX(offset) (CVMX_ADD_IO_SEG(0x0001670000000080ull) + ((offset) & 15) * 8)
+#define CVMX_POW_WS_PCX(offset) (CVMX_ADD_IO_SEG(0x0001670000000280ull) + ((offset) & 15) * 8)
union cvmx_pow_bist_stat {
uint64_t u64;
@@ -160,6 +137,19 @@ union cvmx_pow_bist_stat {
struct cvmx_pow_bist_stat_cn56xx cn56xxp1;
struct cvmx_pow_bist_stat_cn38xx cn58xx;
struct cvmx_pow_bist_stat_cn38xx cn58xxp1;
+ struct cvmx_pow_bist_stat_cn63xx {
+ uint64_t reserved_22_63:42;
+ uint64_t pp:6;
+ uint64_t reserved_12_15:4;
+ uint64_t cam:1;
+ uint64_t nbr:3;
+ uint64_t nbt:4;
+ uint64_t index:1;
+ uint64_t fidx:1;
+ uint64_t pend:1;
+ uint64_t adr:1;
+ } cn63xx;
+ struct cvmx_pow_bist_stat_cn63xx cn63xxp1;
};
union cvmx_pow_ds_pc {
@@ -179,6 +169,8 @@ union cvmx_pow_ds_pc {
struct cvmx_pow_ds_pc_s cn56xxp1;
struct cvmx_pow_ds_pc_s cn58xx;
struct cvmx_pow_ds_pc_s cn58xxp1;
+ struct cvmx_pow_ds_pc_s cn63xx;
+ struct cvmx_pow_ds_pc_s cn63xxp1;
};
union cvmx_pow_ecc_err {
@@ -219,6 +211,8 @@ union cvmx_pow_ecc_err {
struct cvmx_pow_ecc_err_s cn56xxp1;
struct cvmx_pow_ecc_err_s cn58xx;
struct cvmx_pow_ecc_err_s cn58xxp1;
+ struct cvmx_pow_ecc_err_s cn63xx;
+ struct cvmx_pow_ecc_err_s cn63xxp1;
};
union cvmx_pow_int_ctl {
@@ -239,6 +233,8 @@ union cvmx_pow_int_ctl {
struct cvmx_pow_int_ctl_s cn56xxp1;
struct cvmx_pow_int_ctl_s cn58xx;
struct cvmx_pow_int_ctl_s cn58xxp1;
+ struct cvmx_pow_int_ctl_s cn63xx;
+ struct cvmx_pow_int_ctl_s cn63xxp1;
};
union cvmx_pow_iq_cntx {
@@ -258,6 +254,8 @@ union cvmx_pow_iq_cntx {
struct cvmx_pow_iq_cntx_s cn56xxp1;
struct cvmx_pow_iq_cntx_s cn58xx;
struct cvmx_pow_iq_cntx_s cn58xxp1;
+ struct cvmx_pow_iq_cntx_s cn63xx;
+ struct cvmx_pow_iq_cntx_s cn63xxp1;
};
union cvmx_pow_iq_com_cnt {
@@ -277,6 +275,8 @@ union cvmx_pow_iq_com_cnt {
struct cvmx_pow_iq_com_cnt_s cn56xxp1;
struct cvmx_pow_iq_com_cnt_s cn58xx;
struct cvmx_pow_iq_com_cnt_s cn58xxp1;
+ struct cvmx_pow_iq_com_cnt_s cn63xx;
+ struct cvmx_pow_iq_com_cnt_s cn63xxp1;
};
union cvmx_pow_iq_int {
@@ -289,6 +289,8 @@ union cvmx_pow_iq_int {
struct cvmx_pow_iq_int_s cn52xxp1;
struct cvmx_pow_iq_int_s cn56xx;
struct cvmx_pow_iq_int_s cn56xxp1;
+ struct cvmx_pow_iq_int_s cn63xx;
+ struct cvmx_pow_iq_int_s cn63xxp1;
};
union cvmx_pow_iq_int_en {
@@ -301,6 +303,8 @@ union cvmx_pow_iq_int_en {
struct cvmx_pow_iq_int_en_s cn52xxp1;
struct cvmx_pow_iq_int_en_s cn56xx;
struct cvmx_pow_iq_int_en_s cn56xxp1;
+ struct cvmx_pow_iq_int_en_s cn63xx;
+ struct cvmx_pow_iq_int_en_s cn63xxp1;
};
union cvmx_pow_iq_thrx {
@@ -313,6 +317,8 @@ union cvmx_pow_iq_thrx {
struct cvmx_pow_iq_thrx_s cn52xxp1;
struct cvmx_pow_iq_thrx_s cn56xx;
struct cvmx_pow_iq_thrx_s cn56xxp1;
+ struct cvmx_pow_iq_thrx_s cn63xx;
+ struct cvmx_pow_iq_thrx_s cn63xxp1;
};
union cvmx_pow_nos_cnt {
@@ -341,6 +347,11 @@ union cvmx_pow_nos_cnt {
struct cvmx_pow_nos_cnt_s cn56xxp1;
struct cvmx_pow_nos_cnt_s cn58xx;
struct cvmx_pow_nos_cnt_s cn58xxp1;
+ struct cvmx_pow_nos_cnt_cn63xx {
+ uint64_t reserved_11_63:53;
+ uint64_t nos_cnt:11;
+ } cn63xx;
+ struct cvmx_pow_nos_cnt_cn63xx cn63xxp1;
};
union cvmx_pow_nw_tim {
@@ -360,6 +371,8 @@ union cvmx_pow_nw_tim {
struct cvmx_pow_nw_tim_s cn56xxp1;
struct cvmx_pow_nw_tim_s cn58xx;
struct cvmx_pow_nw_tim_s cn58xxp1;
+ struct cvmx_pow_nw_tim_s cn63xx;
+ struct cvmx_pow_nw_tim_s cn63xxp1;
};
union cvmx_pow_pf_rst_msk {
@@ -375,6 +388,8 @@ union cvmx_pow_pf_rst_msk {
struct cvmx_pow_pf_rst_msk_s cn56xxp1;
struct cvmx_pow_pf_rst_msk_s cn58xx;
struct cvmx_pow_pf_rst_msk_s cn58xxp1;
+ struct cvmx_pow_pf_rst_msk_s cn63xx;
+ struct cvmx_pow_pf_rst_msk_s cn63xxp1;
};
union cvmx_pow_pp_grp_mskx {
@@ -405,6 +420,8 @@ union cvmx_pow_pp_grp_mskx {
struct cvmx_pow_pp_grp_mskx_s cn56xxp1;
struct cvmx_pow_pp_grp_mskx_s cn58xx;
struct cvmx_pow_pp_grp_mskx_s cn58xxp1;
+ struct cvmx_pow_pp_grp_mskx_s cn63xx;
+ struct cvmx_pow_pp_grp_mskx_s cn63xxp1;
};
union cvmx_pow_qos_rndx {
@@ -427,6 +444,8 @@ union cvmx_pow_qos_rndx {
struct cvmx_pow_qos_rndx_s cn56xxp1;
struct cvmx_pow_qos_rndx_s cn58xx;
struct cvmx_pow_qos_rndx_s cn58xxp1;
+ struct cvmx_pow_qos_rndx_s cn63xx;
+ struct cvmx_pow_qos_rndx_s cn63xxp1;
};
union cvmx_pow_qos_thrx {
@@ -485,6 +504,19 @@ union cvmx_pow_qos_thrx {
struct cvmx_pow_qos_thrx_s cn56xxp1;
struct cvmx_pow_qos_thrx_s cn58xx;
struct cvmx_pow_qos_thrx_s cn58xxp1;
+ struct cvmx_pow_qos_thrx_cn63xx {
+ uint64_t reserved_59_63:5;
+ uint64_t des_cnt:11;
+ uint64_t reserved_47_47:1;
+ uint64_t buf_cnt:11;
+ uint64_t reserved_35_35:1;
+ uint64_t free_cnt:11;
+ uint64_t reserved_22_23:2;
+ uint64_t max_thr:10;
+ uint64_t reserved_10_11:2;
+ uint64_t min_thr:10;
+ } cn63xx;
+ struct cvmx_pow_qos_thrx_cn63xx cn63xxp1;
};
union cvmx_pow_ts_pc {
@@ -504,6 +536,8 @@ union cvmx_pow_ts_pc {
struct cvmx_pow_ts_pc_s cn56xxp1;
struct cvmx_pow_ts_pc_s cn58xx;
struct cvmx_pow_ts_pc_s cn58xxp1;
+ struct cvmx_pow_ts_pc_s cn63xx;
+ struct cvmx_pow_ts_pc_s cn63xxp1;
};
union cvmx_pow_wa_com_pc {
@@ -523,6 +557,8 @@ union cvmx_pow_wa_com_pc {
struct cvmx_pow_wa_com_pc_s cn56xxp1;
struct cvmx_pow_wa_com_pc_s cn58xx;
struct cvmx_pow_wa_com_pc_s cn58xxp1;
+ struct cvmx_pow_wa_com_pc_s cn63xx;
+ struct cvmx_pow_wa_com_pc_s cn63xxp1;
};
union cvmx_pow_wa_pcx {
@@ -542,6 +578,8 @@ union cvmx_pow_wa_pcx {
struct cvmx_pow_wa_pcx_s cn56xxp1;
struct cvmx_pow_wa_pcx_s cn58xx;
struct cvmx_pow_wa_pcx_s cn58xxp1;
+ struct cvmx_pow_wa_pcx_s cn63xx;
+ struct cvmx_pow_wa_pcx_s cn63xxp1;
};
union cvmx_pow_wq_int {
@@ -562,6 +600,8 @@ union cvmx_pow_wq_int {
struct cvmx_pow_wq_int_s cn56xxp1;
struct cvmx_pow_wq_int_s cn58xx;
struct cvmx_pow_wq_int_s cn58xxp1;
+ struct cvmx_pow_wq_int_s cn63xx;
+ struct cvmx_pow_wq_int_s cn63xxp1;
};
union cvmx_pow_wq_int_cntx {
@@ -604,6 +644,15 @@ union cvmx_pow_wq_int_cntx {
struct cvmx_pow_wq_int_cntx_s cn56xxp1;
struct cvmx_pow_wq_int_cntx_s cn58xx;
struct cvmx_pow_wq_int_cntx_s cn58xxp1;
+ struct cvmx_pow_wq_int_cntx_cn63xx {
+ uint64_t reserved_28_63:36;
+ uint64_t tc_cnt:4;
+ uint64_t reserved_23_23:1;
+ uint64_t ds_cnt:11;
+ uint64_t reserved_11_11:1;
+ uint64_t iq_cnt:11;
+ } cn63xx;
+ struct cvmx_pow_wq_int_cntx_cn63xx cn63xxp1;
};
union cvmx_pow_wq_int_pc {
@@ -626,6 +675,8 @@ union cvmx_pow_wq_int_pc {
struct cvmx_pow_wq_int_pc_s cn56xxp1;
struct cvmx_pow_wq_int_pc_s cn58xx;
struct cvmx_pow_wq_int_pc_s cn58xxp1;
+ struct cvmx_pow_wq_int_pc_s cn63xx;
+ struct cvmx_pow_wq_int_pc_s cn63xxp1;
};
union cvmx_pow_wq_int_thrx {
@@ -674,6 +725,16 @@ union cvmx_pow_wq_int_thrx {
struct cvmx_pow_wq_int_thrx_s cn56xxp1;
struct cvmx_pow_wq_int_thrx_s cn58xx;
struct cvmx_pow_wq_int_thrx_s cn58xxp1;
+ struct cvmx_pow_wq_int_thrx_cn63xx {
+ uint64_t reserved_29_63:35;
+ uint64_t tc_en:1;
+ uint64_t tc_thr:4;
+ uint64_t reserved_22_23:2;
+ uint64_t ds_thr:10;
+ uint64_t reserved_10_11:2;
+ uint64_t iq_thr:10;
+ } cn63xx;
+ struct cvmx_pow_wq_int_thrx_cn63xx cn63xxp1;
};
union cvmx_pow_ws_pcx {
@@ -693,6 +754,8 @@ union cvmx_pow_ws_pcx {
struct cvmx_pow_ws_pcx_s cn56xxp1;
struct cvmx_pow_ws_pcx_s cn58xx;
struct cvmx_pow_ws_pcx_s cn58xxp1;
+ struct cvmx_pow_ws_pcx_s cn63xx;
+ struct cvmx_pow_ws_pcx_s cn63xxp1;
};
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-rnm-defs.h b/arch/mips/include/asm/octeon/cvmx-rnm-defs.h
index 4586958c97be..c45da1f35ea7 100644
--- a/arch/mips/include/asm/octeon/cvmx-rnm-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-rnm-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
@@ -30,10 +30,11 @@
#include <linux/types.h>
-#define CVMX_RNM_BIST_STATUS \
- CVMX_ADD_IO_SEG(0x0001180040000008ull)
-#define CVMX_RNM_CTL_STATUS \
- CVMX_ADD_IO_SEG(0x0001180040000000ull)
+#define CVMX_RNM_BIST_STATUS (CVMX_ADD_IO_SEG(0x0001180040000008ull))
+#define CVMX_RNM_CTL_STATUS (CVMX_ADD_IO_SEG(0x0001180040000000ull))
+#define CVMX_RNM_EER_DBG (CVMX_ADD_IO_SEG(0x0001180040000018ull))
+#define CVMX_RNM_EER_KEY (CVMX_ADD_IO_SEG(0x0001180040000010ull))
+#define CVMX_RNM_SERIAL_NUM (CVMX_ADD_IO_SEG(0x0001180040000020ull))
union cvmx_rnm_bist_status {
uint64_t u64;
@@ -53,12 +54,16 @@ union cvmx_rnm_bist_status {
struct cvmx_rnm_bist_status_s cn56xxp1;
struct cvmx_rnm_bist_status_s cn58xx;
struct cvmx_rnm_bist_status_s cn58xxp1;
+ struct cvmx_rnm_bist_status_s cn63xx;
+ struct cvmx_rnm_bist_status_s cn63xxp1;
};
union cvmx_rnm_ctl_status {
uint64_t u64;
struct cvmx_rnm_ctl_status_s {
- uint64_t reserved_9_63:55;
+ uint64_t reserved_11_63:53;
+ uint64_t eer_lck:1;
+ uint64_t eer_val:1;
uint64_t ent_sel:4;
uint64_t exp_ent:1;
uint64_t rng_rst:1;
@@ -76,13 +81,49 @@ union cvmx_rnm_ctl_status {
struct cvmx_rnm_ctl_status_cn30xx cn31xx;
struct cvmx_rnm_ctl_status_cn30xx cn38xx;
struct cvmx_rnm_ctl_status_cn30xx cn38xxp2;
- struct cvmx_rnm_ctl_status_s cn50xx;
- struct cvmx_rnm_ctl_status_s cn52xx;
- struct cvmx_rnm_ctl_status_s cn52xxp1;
- struct cvmx_rnm_ctl_status_s cn56xx;
- struct cvmx_rnm_ctl_status_s cn56xxp1;
- struct cvmx_rnm_ctl_status_s cn58xx;
- struct cvmx_rnm_ctl_status_s cn58xxp1;
+ struct cvmx_rnm_ctl_status_cn50xx {
+ uint64_t reserved_9_63:55;
+ uint64_t ent_sel:4;
+ uint64_t exp_ent:1;
+ uint64_t rng_rst:1;
+ uint64_t rnm_rst:1;
+ uint64_t rng_en:1;
+ uint64_t ent_en:1;
+ } cn50xx;
+ struct cvmx_rnm_ctl_status_cn50xx cn52xx;
+ struct cvmx_rnm_ctl_status_cn50xx cn52xxp1;
+ struct cvmx_rnm_ctl_status_cn50xx cn56xx;
+ struct cvmx_rnm_ctl_status_cn50xx cn56xxp1;
+ struct cvmx_rnm_ctl_status_cn50xx cn58xx;
+ struct cvmx_rnm_ctl_status_cn50xx cn58xxp1;
+ struct cvmx_rnm_ctl_status_s cn63xx;
+ struct cvmx_rnm_ctl_status_s cn63xxp1;
+};
+
+union cvmx_rnm_eer_dbg {
+ uint64_t u64;
+ struct cvmx_rnm_eer_dbg_s {
+ uint64_t dat:64;
+ } s;
+ struct cvmx_rnm_eer_dbg_s cn63xx;
+ struct cvmx_rnm_eer_dbg_s cn63xxp1;
+};
+
+union cvmx_rnm_eer_key {
+ uint64_t u64;
+ struct cvmx_rnm_eer_key_s {
+ uint64_t key:64;
+ } s;
+ struct cvmx_rnm_eer_key_s cn63xx;
+ struct cvmx_rnm_eer_key_s cn63xxp1;
+};
+
+union cvmx_rnm_serial_num {
+ uint64_t u64;
+ struct cvmx_rnm_serial_num_s {
+ uint64_t dat:64;
+ } s;
+ struct cvmx_rnm_serial_num_s cn63xx;
};
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-smix-defs.h b/arch/mips/include/asm/octeon/cvmx-smix-defs.h
index 9ae45fcbe3e3..4f3c0666e94a 100644
--- a/arch/mips/include/asm/octeon/cvmx-smix-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-smix-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
@@ -28,16 +28,11 @@
#ifndef __CVMX_SMIX_DEFS_H__
#define __CVMX_SMIX_DEFS_H__
-#define CVMX_SMIX_CLK(offset) \
- CVMX_ADD_IO_SEG(0x0001180000001818ull + (((offset) & 1) * 256))
-#define CVMX_SMIX_CMD(offset) \
- CVMX_ADD_IO_SEG(0x0001180000001800ull + (((offset) & 1) * 256))
-#define CVMX_SMIX_EN(offset) \
- CVMX_ADD_IO_SEG(0x0001180000001820ull + (((offset) & 1) * 256))
-#define CVMX_SMIX_RD_DAT(offset) \
- CVMX_ADD_IO_SEG(0x0001180000001810ull + (((offset) & 1) * 256))
-#define CVMX_SMIX_WR_DAT(offset) \
- CVMX_ADD_IO_SEG(0x0001180000001808ull + (((offset) & 1) * 256))
+#define CVMX_SMIX_CLK(offset) (CVMX_ADD_IO_SEG(0x0001180000001818ull) + ((offset) & 1) * 256)
+#define CVMX_SMIX_CMD(offset) (CVMX_ADD_IO_SEG(0x0001180000001800ull) + ((offset) & 1) * 256)
+#define CVMX_SMIX_EN(offset) (CVMX_ADD_IO_SEG(0x0001180000001820ull) + ((offset) & 1) * 256)
+#define CVMX_SMIX_RD_DAT(offset) (CVMX_ADD_IO_SEG(0x0001180000001810ull) + ((offset) & 1) * 256)
+#define CVMX_SMIX_WR_DAT(offset) (CVMX_ADD_IO_SEG(0x0001180000001808ull) + ((offset) & 1) * 256)
union cvmx_smix_clk {
uint64_t u64;
@@ -56,7 +51,8 @@ union cvmx_smix_clk {
struct cvmx_smix_clk_cn30xx {
uint64_t reserved_21_63:43;
uint64_t sample_hi:5;
- uint64_t reserved_14_15:2;
+ uint64_t sample_mode:1;
+ uint64_t reserved_14_14:1;
uint64_t clk_idle:1;
uint64_t preamble:1;
uint64_t sample:4;
@@ -65,23 +61,15 @@ union cvmx_smix_clk {
struct cvmx_smix_clk_cn30xx cn31xx;
struct cvmx_smix_clk_cn30xx cn38xx;
struct cvmx_smix_clk_cn30xx cn38xxp2;
- struct cvmx_smix_clk_cn50xx {
- uint64_t reserved_25_63:39;
- uint64_t mode:1;
- uint64_t reserved_21_23:3;
- uint64_t sample_hi:5;
- uint64_t reserved_14_15:2;
- uint64_t clk_idle:1;
- uint64_t preamble:1;
- uint64_t sample:4;
- uint64_t phase:8;
- } cn50xx;
+ struct cvmx_smix_clk_s cn50xx;
struct cvmx_smix_clk_s cn52xx;
- struct cvmx_smix_clk_cn50xx cn52xxp1;
+ struct cvmx_smix_clk_s cn52xxp1;
struct cvmx_smix_clk_s cn56xx;
- struct cvmx_smix_clk_cn50xx cn56xxp1;
+ struct cvmx_smix_clk_s cn56xxp1;
struct cvmx_smix_clk_cn30xx cn58xx;
struct cvmx_smix_clk_cn30xx cn58xxp1;
+ struct cvmx_smix_clk_s cn63xx;
+ struct cvmx_smix_clk_s cn63xxp1;
};
union cvmx_smix_cmd {
@@ -112,6 +100,8 @@ union cvmx_smix_cmd {
struct cvmx_smix_cmd_s cn56xxp1;
struct cvmx_smix_cmd_cn30xx cn58xx;
struct cvmx_smix_cmd_cn30xx cn58xxp1;
+ struct cvmx_smix_cmd_s cn63xx;
+ struct cvmx_smix_cmd_s cn63xxp1;
};
union cvmx_smix_en {
@@ -131,6 +121,8 @@ union cvmx_smix_en {
struct cvmx_smix_en_s cn56xxp1;
struct cvmx_smix_en_s cn58xx;
struct cvmx_smix_en_s cn58xxp1;
+ struct cvmx_smix_en_s cn63xx;
+ struct cvmx_smix_en_s cn63xxp1;
};
union cvmx_smix_rd_dat {
@@ -152,6 +144,8 @@ union cvmx_smix_rd_dat {
struct cvmx_smix_rd_dat_s cn56xxp1;
struct cvmx_smix_rd_dat_s cn58xx;
struct cvmx_smix_rd_dat_s cn58xxp1;
+ struct cvmx_smix_rd_dat_s cn63xx;
+ struct cvmx_smix_rd_dat_s cn63xxp1;
};
union cvmx_smix_wr_dat {
@@ -173,6 +167,8 @@ union cvmx_smix_wr_dat {
struct cvmx_smix_wr_dat_s cn56xxp1;
struct cvmx_smix_wr_dat_s cn58xx;
struct cvmx_smix_wr_dat_s cn58xxp1;
+ struct cvmx_smix_wr_dat_s cn63xx;
+ struct cvmx_smix_wr_dat_s cn63xxp1;
};
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-uctlx-defs.h b/arch/mips/include/asm/octeon/cvmx-uctlx-defs.h
new file mode 100644
index 000000000000..594f1b68cd62
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-uctlx-defs.h
@@ -0,0 +1,261 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2010 Cavium Networks
+ *
+ * This file 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 file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_UCTLX_TYPEDEFS_H__
+#define __CVMX_UCTLX_TYPEDEFS_H__
+
+#define CVMX_UCTLX_BIST_STATUS(block_id) (CVMX_ADD_IO_SEG(0x000118006F0000A0ull))
+#define CVMX_UCTLX_CLK_RST_CTL(block_id) (CVMX_ADD_IO_SEG(0x000118006F000000ull))
+#define CVMX_UCTLX_EHCI_CTL(block_id) (CVMX_ADD_IO_SEG(0x000118006F000080ull))
+#define CVMX_UCTLX_EHCI_FLA(block_id) (CVMX_ADD_IO_SEG(0x000118006F0000A8ull))
+#define CVMX_UCTLX_ERTO_CTL(block_id) (CVMX_ADD_IO_SEG(0x000118006F000090ull))
+#define CVMX_UCTLX_IF_ENA(block_id) (CVMX_ADD_IO_SEG(0x000118006F000030ull))
+#define CVMX_UCTLX_INT_ENA(block_id) (CVMX_ADD_IO_SEG(0x000118006F000028ull))
+#define CVMX_UCTLX_INT_REG(block_id) (CVMX_ADD_IO_SEG(0x000118006F000020ull))
+#define CVMX_UCTLX_OHCI_CTL(block_id) (CVMX_ADD_IO_SEG(0x000118006F000088ull))
+#define CVMX_UCTLX_ORTO_CTL(block_id) (CVMX_ADD_IO_SEG(0x000118006F000098ull))
+#define CVMX_UCTLX_PPAF_WM(block_id) (CVMX_ADD_IO_SEG(0x000118006F000038ull))
+#define CVMX_UCTLX_UPHY_CTL_STATUS(block_id) (CVMX_ADD_IO_SEG(0x000118006F000008ull))
+#define CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(offset, block_id) (CVMX_ADD_IO_SEG(0x000118006F000010ull) + (((offset) & 1) + ((block_id) & 0) * 0x0ull) * 8)
+
+union cvmx_uctlx_bist_status {
+ uint64_t u64;
+ struct cvmx_uctlx_bist_status_s {
+ uint64_t reserved_6_63:58;
+ uint64_t data_bis:1;
+ uint64_t desc_bis:1;
+ uint64_t erbm_bis:1;
+ uint64_t orbm_bis:1;
+ uint64_t wrbm_bis:1;
+ uint64_t ppaf_bis:1;
+ } s;
+ struct cvmx_uctlx_bist_status_s cn63xx;
+ struct cvmx_uctlx_bist_status_s cn63xxp1;
+};
+
+union cvmx_uctlx_clk_rst_ctl {
+ uint64_t u64;
+ struct cvmx_uctlx_clk_rst_ctl_s {
+ uint64_t reserved_25_63:39;
+ uint64_t clear_bist:1;
+ uint64_t start_bist:1;
+ uint64_t ehci_sm:1;
+ uint64_t ohci_clkcktrst:1;
+ uint64_t ohci_sm:1;
+ uint64_t ohci_susp_lgcy:1;
+ uint64_t app_start_clk:1;
+ uint64_t o_clkdiv_rst:1;
+ uint64_t h_clkdiv_byp:1;
+ uint64_t h_clkdiv_rst:1;
+ uint64_t h_clkdiv_en:1;
+ uint64_t o_clkdiv_en:1;
+ uint64_t h_div:4;
+ uint64_t p_refclk_sel:2;
+ uint64_t p_refclk_div:2;
+ uint64_t reserved_4_4:1;
+ uint64_t p_com_on:1;
+ uint64_t p_por:1;
+ uint64_t p_prst:1;
+ uint64_t hrst:1;
+ } s;
+ struct cvmx_uctlx_clk_rst_ctl_s cn63xx;
+ struct cvmx_uctlx_clk_rst_ctl_s cn63xxp1;
+};
+
+union cvmx_uctlx_ehci_ctl {
+ uint64_t u64;
+ struct cvmx_uctlx_ehci_ctl_s {
+ uint64_t reserved_20_63:44;
+ uint64_t desc_rbm:1;
+ uint64_t reg_nb:1;
+ uint64_t l2c_dc:1;
+ uint64_t l2c_bc:1;
+ uint64_t l2c_0pag:1;
+ uint64_t l2c_stt:1;
+ uint64_t l2c_buff_emod:2;
+ uint64_t l2c_desc_emod:2;
+ uint64_t inv_reg_a2:1;
+ uint64_t ehci_64b_addr_en:1;
+ uint64_t l2c_addr_msb:8;
+ } s;
+ struct cvmx_uctlx_ehci_ctl_s cn63xx;
+ struct cvmx_uctlx_ehci_ctl_s cn63xxp1;
+};
+
+union cvmx_uctlx_ehci_fla {
+ uint64_t u64;
+ struct cvmx_uctlx_ehci_fla_s {
+ uint64_t reserved_6_63:58;
+ uint64_t fla:6;
+ } s;
+ struct cvmx_uctlx_ehci_fla_s cn63xx;
+ struct cvmx_uctlx_ehci_fla_s cn63xxp1;
+};
+
+union cvmx_uctlx_erto_ctl {
+ uint64_t u64;
+ struct cvmx_uctlx_erto_ctl_s {
+ uint64_t reserved_32_63:32;
+ uint64_t to_val:27;
+ uint64_t reserved_0_4:5;
+ } s;
+ struct cvmx_uctlx_erto_ctl_s cn63xx;
+ struct cvmx_uctlx_erto_ctl_s cn63xxp1;
+};
+
+union cvmx_uctlx_if_ena {
+ uint64_t u64;
+ struct cvmx_uctlx_if_ena_s {
+ uint64_t reserved_1_63:63;
+ uint64_t en:1;
+ } s;
+ struct cvmx_uctlx_if_ena_s cn63xx;
+ struct cvmx_uctlx_if_ena_s cn63xxp1;
+};
+
+union cvmx_uctlx_int_ena {
+ uint64_t u64;
+ struct cvmx_uctlx_int_ena_s {
+ uint64_t reserved_8_63:56;
+ uint64_t ec_ovf_e:1;
+ uint64_t oc_ovf_e:1;
+ uint64_t wb_pop_e:1;
+ uint64_t wb_psh_f:1;
+ uint64_t cf_psh_f:1;
+ uint64_t or_psh_f:1;
+ uint64_t er_psh_f:1;
+ uint64_t pp_psh_f:1;
+ } s;
+ struct cvmx_uctlx_int_ena_s cn63xx;
+ struct cvmx_uctlx_int_ena_s cn63xxp1;
+};
+
+union cvmx_uctlx_int_reg {
+ uint64_t u64;
+ struct cvmx_uctlx_int_reg_s {
+ uint64_t reserved_8_63:56;
+ uint64_t ec_ovf_e:1;
+ uint64_t oc_ovf_e:1;
+ uint64_t wb_pop_e:1;
+ uint64_t wb_psh_f:1;
+ uint64_t cf_psh_f:1;
+ uint64_t or_psh_f:1;
+ uint64_t er_psh_f:1;
+ uint64_t pp_psh_f:1;
+ } s;
+ struct cvmx_uctlx_int_reg_s cn63xx;
+ struct cvmx_uctlx_int_reg_s cn63xxp1;
+};
+
+union cvmx_uctlx_ohci_ctl {
+ uint64_t u64;
+ struct cvmx_uctlx_ohci_ctl_s {
+ uint64_t reserved_19_63:45;
+ uint64_t reg_nb:1;
+ uint64_t l2c_dc:1;
+ uint64_t l2c_bc:1;
+ uint64_t l2c_0pag:1;
+ uint64_t l2c_stt:1;
+ uint64_t l2c_buff_emod:2;
+ uint64_t l2c_desc_emod:2;
+ uint64_t inv_reg_a2:1;
+ uint64_t reserved_8_8:1;
+ uint64_t l2c_addr_msb:8;
+ } s;
+ struct cvmx_uctlx_ohci_ctl_s cn63xx;
+ struct cvmx_uctlx_ohci_ctl_s cn63xxp1;
+};
+
+union cvmx_uctlx_orto_ctl {
+ uint64_t u64;
+ struct cvmx_uctlx_orto_ctl_s {
+ uint64_t reserved_32_63:32;
+ uint64_t to_val:24;
+ uint64_t reserved_0_7:8;
+ } s;
+ struct cvmx_uctlx_orto_ctl_s cn63xx;
+ struct cvmx_uctlx_orto_ctl_s cn63xxp1;
+};
+
+union cvmx_uctlx_ppaf_wm {
+ uint64_t u64;
+ struct cvmx_uctlx_ppaf_wm_s {
+ uint64_t reserved_5_63:59;
+ uint64_t wm:5;
+ } s;
+ struct cvmx_uctlx_ppaf_wm_s cn63xx;
+ struct cvmx_uctlx_ppaf_wm_s cn63xxp1;
+};
+
+union cvmx_uctlx_uphy_ctl_status {
+ uint64_t u64;
+ struct cvmx_uctlx_uphy_ctl_status_s {
+ uint64_t reserved_10_63:54;
+ uint64_t bist_done:1;
+ uint64_t bist_err:1;
+ uint64_t hsbist:1;
+ uint64_t fsbist:1;
+ uint64_t lsbist:1;
+ uint64_t siddq:1;
+ uint64_t vtest_en:1;
+ uint64_t uphy_bist:1;
+ uint64_t bist_en:1;
+ uint64_t ate_reset:1;
+ } s;
+ struct cvmx_uctlx_uphy_ctl_status_s cn63xx;
+ struct cvmx_uctlx_uphy_ctl_status_s cn63xxp1;
+};
+
+union cvmx_uctlx_uphy_portx_ctl_status {
+ uint64_t u64;
+ struct cvmx_uctlx_uphy_portx_ctl_status_s {
+ uint64_t reserved_43_63:21;
+ uint64_t tdata_out:4;
+ uint64_t txbiststuffenh:1;
+ uint64_t txbiststuffen:1;
+ uint64_t dmpulldown:1;
+ uint64_t dppulldown:1;
+ uint64_t vbusvldext:1;
+ uint64_t portreset:1;
+ uint64_t txhsvxtune:2;
+ uint64_t txvreftune:4;
+ uint64_t txrisetune:1;
+ uint64_t txpreemphasistune:1;
+ uint64_t txfslstune:4;
+ uint64_t sqrxtune:3;
+ uint64_t compdistune:3;
+ uint64_t loop_en:1;
+ uint64_t tclk:1;
+ uint64_t tdata_sel:1;
+ uint64_t taddr_in:4;
+ uint64_t tdata_in:8;
+ } s;
+ struct cvmx_uctlx_uphy_portx_ctl_status_s cn63xx;
+ struct cvmx_uctlx_uphy_portx_ctl_status_s cn63xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/octeon-model.h b/arch/mips/include/asm/octeon/octeon-model.h
index cf50336eca2e..700f88e31cad 100644
--- a/arch/mips/include/asm/octeon/octeon-model.h
+++ b/arch/mips/include/asm/octeon/octeon-model.h
@@ -35,14 +35,6 @@
#ifndef __OCTEON_MODEL_H__
#define __OCTEON_MODEL_H__
-/* NOTE: These must match what is checked in common-config.mk */
-/* Defines to represent the different versions of Octeon. */
-
-/*
- * IMPORTANT: When the default pass is updated for an Octeon Model,
- * the corresponding change must also be made in the oct-sim script.
- */
-
/*
* The defines below should be used with the OCTEON_IS_MODEL() macro
* to determine what model of chip the software is running on. Models
@@ -71,6 +63,21 @@
#define OM_IGNORE_MINOR_REVISION 0x08000000
#define OM_FLAG_MASK 0xff000000
+#define OM_MATCH_5XXX_FAMILY_MODELS 0x20000000 /* Match all cn5XXX Octeon models. */
+#define OM_MATCH_6XXX_FAMILY_MODELS 0x40000000 /* Match all cn6XXX Octeon models. */
+
+/*
+ * CN6XXX models with new revision encoding
+ */
+#define OCTEON_CN63XX_PASS1_0 0x000d9000
+#define OCTEON_CN63XX_PASS1_1 0x000d9001
+#define OCTEON_CN63XX_PASS1_2 0x000d9002
+#define OCTEON_CN63XX_PASS2_0 0x000d9008
+
+#define OCTEON_CN63XX (OCTEON_CN63XX_PASS2_0 | OM_IGNORE_REVISION)
+#define OCTEON_CN63XX_PASS1_X (OCTEON_CN63XX_PASS1_0 | OM_IGNORE_MINOR_REVISION)
+#define OCTEON_CN63XX_PASS2_X (OCTEON_CN63XX_PASS2_0 | OM_IGNORE_MINOR_REVISION)
+
/*
* CN5XXX models with new revision encoding
*/
@@ -189,6 +196,9 @@
| OM_MATCH_PREVIOUS_MODELS \
| OM_IGNORE_REVISION)
+#define OCTEON_CN5XXX (OCTEON_CN58XX_PASS1_0 | OM_MATCH_5XXX_FAMILY_MODELS)
+#define OCTEON_CN6XXX (OCTEON_CN63XX_PASS1_0 | OM_MATCH_6XXX_FAMILY_MODELS)
+
/* The revision byte (low byte) has two different encodings.
* CN3XXX:
*
@@ -222,6 +232,7 @@
| OCTEON_58XX_MODEL_MASK)
#define OCTEON_58XX_MODEL_MINOR_REV_MASK (OCTEON_58XX_MODEL_REV_MASK \
& 0x00fffff8)
+#define OCTEON_5XXX_MODEL_MASK 0x00ff0fc0
#define __OCTEON_MATCH_MASK__(x, y, z) (((x) & (z)) == ((y) & (z)))
@@ -273,6 +284,15 @@ static inline int __OCTEON_IS_MODEL_COMPILE__(uint32_t arg_model,
__OCTEON_MATCH_MASK__((chip_model), (arg_model),
OCTEON_58XX_MODEL_REV_MASK))
return 1;
+
+ if (((arg_model & OM_MATCH_5XXX_FAMILY_MODELS) == OM_MATCH_5XXX_FAMILY_MODELS) &&
+ ((chip_model) >= OCTEON_CN58XX_PASS1_0) && ((chip_model) < OCTEON_CN63XX_PASS1_0))
+ return 1;
+
+ if (((arg_model & OM_MATCH_6XXX_FAMILY_MODELS) == OM_MATCH_6XXX_FAMILY_MODELS) &&
+ ((chip_model) >= OCTEON_CN63XX_PASS1_0))
+ return 1;
+
if ((arg_model & OM_MATCH_PREVIOUS_MODELS) &&
((chip_model & OCTEON_58XX_MODEL_MASK) <
(arg_model & OCTEON_58XX_MODEL_MASK)))
diff --git a/arch/mips/include/asm/octeon/octeon.h b/arch/mips/include/asm/octeon/octeon.h
index 917a6c413b1a..6b34afd0d4e7 100644
--- a/arch/mips/include/asm/octeon/octeon.h
+++ b/arch/mips/include/asm/octeon/octeon.h
@@ -35,6 +35,7 @@ extern int octeon_is_simulation(void);
extern int octeon_is_pci_host(void);
extern int octeon_usb_is_ref_clk(void);
extern uint64_t octeon_get_clock_rate(void);
+extern u64 octeon_get_io_clock_rate(void);
extern const char *octeon_board_type_string(void);
extern const char *octeon_get_pci_interrupts(void);
extern int octeon_get_southbridge_interrupt(void);
diff --git a/arch/mips/include/asm/octeon/pci-octeon.h b/arch/mips/include/asm/octeon/pci-octeon.h
index ece78043acf6..fba2ba200f58 100644
--- a/arch/mips/include/asm/octeon/pci-octeon.h
+++ b/arch/mips/include/asm/octeon/pci-octeon.h
@@ -36,6 +36,16 @@ extern int (*octeon_pcibios_map_irq)(const struct pci_dev *dev,
u8 slot, u8 pin);
/*
+ * For PCI (not PCIe) the BAR2 base address.
+ */
+#define OCTEON_BAR2_PCI_ADDRESS 0x8000000000ull
+
+/*
+ * For PCI (not PCIe) the base of the memory mapped by BAR1
+ */
+extern u64 octeon_bar1_pci_phys;
+
+/*
* The following defines are used when octeon_dma_bar_type =
* OCTEON_DMA_BAR_TYPE_BIG
*/
diff --git a/arch/mips/include/asm/pci/bridge.h b/arch/mips/include/asm/pci/bridge.h
index 5f4b9d4e4114..f1f508e4f971 100644
--- a/arch/mips/include/asm/pci/bridge.h
+++ b/arch/mips/include/asm/pci/bridge.h
@@ -839,7 +839,7 @@ struct bridge_controller {
nasid_t nasid;
unsigned int widget_id;
unsigned int irq_cpu;
- dma64_addr_t baddr;
+ u64 baddr;
unsigned int pci_int[8];
};
diff --git a/arch/mips/include/asm/perf_event.h b/arch/mips/include/asm/perf_event.h
new file mode 100644
index 000000000000..e00007cf8162
--- /dev/null
+++ b/arch/mips/include/asm/perf_event.h
@@ -0,0 +1,25 @@
+/*
+ * linux/arch/mips/include/asm/perf_event.h
+ *
+ * Copyright (C) 2010 MIPS Technologies, Inc.
+ * Author: Deng-Cheng Zhu
+ *
+ * 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 __MIPS_PERF_EVENT_H__
+#define __MIPS_PERF_EVENT_H__
+
+/*
+ * MIPS performance counters do not raise NMI upon overflow, a regular
+ * interrupt will be signaled. Hence we can do the pending perf event
+ * work at the tail of the irq handler.
+ */
+static inline void
+set_perf_event_pending(void)
+{
+}
+
+#endif /* __MIPS_PERF_EVENT_H__ */
diff --git a/arch/mips/include/asm/pgtable-32.h b/arch/mips/include/asm/pgtable-32.h
index ae90412556d0..8a153d2fa62a 100644
--- a/arch/mips/include/asm/pgtable-32.h
+++ b/arch/mips/include/asm/pgtable-32.h
@@ -154,10 +154,7 @@ pfn_pte(unsigned long pfn, pgprot_t prot)
#define pte_offset_map(dir, address) \
((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address))
-#define pte_offset_map_nested(dir, address) \
- ((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address))
#define pte_unmap(pte) ((void)(pte))
-#define pte_unmap_nested(pte) ((void)(pte))
#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
diff --git a/arch/mips/include/asm/pgtable-64.h b/arch/mips/include/asm/pgtable-64.h
index 1be4b0fa30da..55908fd56b1f 100644
--- a/arch/mips/include/asm/pgtable-64.h
+++ b/arch/mips/include/asm/pgtable-64.h
@@ -113,10 +113,10 @@
#endif
#define PTRS_PER_PTE ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t))
-#if PGDIR_SIZE >= TASK_SIZE
+#if PGDIR_SIZE >= TASK_SIZE64
#define USER_PTRS_PER_PGD (1)
#else
-#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE)
+#define USER_PTRS_PER_PGD (TASK_SIZE64 / PGDIR_SIZE)
#endif
#define FIRST_USER_ADDRESS 0UL
@@ -257,10 +257,7 @@ static inline pmd_t *pmd_offset(pud_t * pud, unsigned long address)
((pte_t *) pmd_page_vaddr(*(dir)) + __pte_offset(address))
#define pte_offset_map(dir, address) \
((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address))
-#define pte_offset_map_nested(dir, address) \
- ((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address))
#define pte_unmap(pte) ((void)(pte))
-#define pte_unmap_nested(pte) ((void)(pte))
/*
* Initialize a new pgd / pmd table with invalid pointers.
diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h
index 0d629bb93cbe..ead6928fa6b8 100644
--- a/arch/mips/include/asm/processor.h
+++ b/arch/mips/include/asm/processor.h
@@ -50,13 +50,10 @@ extern unsigned int vced_count, vcei_count;
* so don't change it unless you know what you are doing.
*/
#define TASK_SIZE 0x7fff8000UL
-#define STACK_TOP ((TASK_SIZE & PAGE_MASK) - SPECIAL_PAGES_SIZE)
-/*
- * This decides where the kernel will search for a free chunk of vm
- * space during mmap's.
- */
-#define TASK_UNMAPPED_BASE ((TASK_SIZE / 3) & ~(PAGE_SIZE))
+#ifdef __KERNEL__
+#define STACK_TOP_MAX TASK_SIZE
+#endif
#define TASK_IS_32BIT_ADDR 1
@@ -71,28 +68,29 @@ extern unsigned int vced_count, vcei_count;
* 8192EB ...
*/
#define TASK_SIZE32 0x7fff8000UL
-#define TASK_SIZE 0x10000000000UL
-#define STACK_TOP \
- (((test_thread_flag(TIF_32BIT_ADDR) ? \
- TASK_SIZE32 : TASK_SIZE) & PAGE_MASK) - SPECIAL_PAGES_SIZE)
+#define TASK_SIZE64 0x10000000000UL
+#define TASK_SIZE (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE64)
+
+#ifdef __KERNEL__
+#define STACK_TOP_MAX TASK_SIZE64
+#endif
+
-/*
- * This decides where the kernel will search for a free chunk of vm
- * space during mmap's.
- */
-#define TASK_UNMAPPED_BASE \
- (test_thread_flag(TIF_32BIT_ADDR) ? \
- PAGE_ALIGN(TASK_SIZE32 / 3) : PAGE_ALIGN(TASK_SIZE / 3))
#define TASK_SIZE_OF(tsk) \
- (test_tsk_thread_flag(tsk, TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE)
+ (test_tsk_thread_flag(tsk, TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE64)
#define TASK_IS_32BIT_ADDR test_thread_flag(TIF_32BIT_ADDR)
#endif
-#ifdef __KERNEL__
-#define STACK_TOP_MAX TASK_SIZE
-#endif
+#define STACK_TOP ((TASK_SIZE & PAGE_MASK) - SPECIAL_PAGES_SIZE)
+
+/*
+ * This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE PAGE_ALIGN(TASK_SIZE / 3)
+
#define NUM_FPU_REGS 32
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/system.h b/arch/mips/include/asm/system.h
index bb937ccfba1e..6018c80ce37a 100644
--- a/arch/mips/include/asm/system.h
+++ b/arch/mips/include/asm/system.h
@@ -115,21 +115,19 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
} else if (kernel_uses_llsc) {
unsigned long dummy;
- __asm__ __volatile__(
- " .set mips3 \n"
- "1: ll %0, %3 # xchg_u32 \n"
- " .set mips0 \n"
- " move %2, %z4 \n"
- " .set mips3 \n"
- " sc %2, %1 \n"
- " beqz %2, 2f \n"
- " .subsection 2 \n"
- "2: b 1b \n"
- " .previous \n"
- " .set mips0 \n"
- : "=&r" (retval), "=m" (*m), "=&r" (dummy)
- : "R" (*m), "Jr" (val)
- : "memory");
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " ll %0, %3 # xchg_u32 \n"
+ " .set mips0 \n"
+ " move %2, %z4 \n"
+ " .set mips3 \n"
+ " sc %2, %1 \n"
+ " .set mips0 \n"
+ : "=&r" (retval), "=m" (*m), "=&r" (dummy)
+ : "R" (*m), "Jr" (val)
+ : "memory");
+ } while (unlikely(!dummy));
} else {
unsigned long flags;
@@ -167,19 +165,17 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
} else if (kernel_uses_llsc) {
unsigned long dummy;
- __asm__ __volatile__(
- " .set mips3 \n"
- "1: lld %0, %3 # xchg_u64 \n"
- " move %2, %z4 \n"
- " scd %2, %1 \n"
- " beqz %2, 2f \n"
- " .subsection 2 \n"
- "2: b 1b \n"
- " .previous \n"
- " .set mips0 \n"
- : "=&r" (retval), "=m" (*m), "=&r" (dummy)
- : "R" (*m), "Jr" (val)
- : "memory");
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " lld %0, %3 # xchg_u64 \n"
+ " move %2, %z4 \n"
+ " scd %2, %1 \n"
+ " .set mips0 \n"
+ : "=&r" (retval), "=m" (*m), "=&r" (dummy)
+ : "R" (*m), "Jr" (val)
+ : "memory");
+ } while (unlikely(!dummy));
} else {
unsigned long flags;
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h
index 70df9c0d3c5b..d309556cacf8 100644
--- a/arch/mips/include/asm/thread_info.h
+++ b/arch/mips/include/asm/thread_info.h
@@ -83,6 +83,8 @@ register struct thread_info *__current_thread_info __asm__("$28");
#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
#define THREAD_MASK (THREAD_SIZE - 1UL)
+#define STACK_WARN (THREAD_SIZE / 8)
+
#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
#ifdef CONFIG_DEBUG_STACK_USAGE
diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h
index c2d53c18fd36..653a412c036c 100644
--- a/arch/mips/include/asm/uaccess.h
+++ b/arch/mips/include/asm/uaccess.h
@@ -35,7 +35,9 @@
#ifdef CONFIG_64BIT
-#define __UA_LIMIT (- TASK_SIZE)
+extern u64 __ua_limit;
+
+#define __UA_LIMIT __ua_limit
#define __UA_ADDR ".dword"
#define __UA_LA "dla"
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/kernel/Makefile b/arch/mips/kernel/Makefile
index 06f848299785..22b2e0e38617 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -96,10 +96,14 @@ 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
obj-$(CONFIG_MIPS_CPUFREQ) += cpufreq/
+obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
+
CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS)
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/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index b1b304ea2128..71620e19827a 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -25,6 +25,8 @@
#include <asm/system.h>
#include <asm/watch.h>
#include <asm/spram.h>
+#include <asm/uaccess.h>
+
/*
* Not all of the MIPS CPUs have the "wait" instruction available. Moreover,
* the implementation of the "wait" feature differs between CPU families. This
@@ -181,12 +183,13 @@ void __init check_wait(void)
case CPU_5KC:
case CPU_25KF:
case CPU_PR4450:
- case CPU_BCM3302:
- case CPU_BCM6338:
- case CPU_BCM6348:
- case CPU_BCM6358:
+ case CPU_BMIPS3300:
+ case CPU_BMIPS4350:
+ case CPU_BMIPS4380:
+ case CPU_BMIPS5000:
case CPU_CAVIUM_OCTEON:
case CPU_CAVIUM_OCTEON_PLUS:
+ case CPU_CAVIUM_OCTEON2:
case CPU_JZRISC:
cpu_wait = r4k_wait;
break;
@@ -902,33 +905,37 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
{
decode_configs(c);
switch (c->processor_id & 0xff00) {
- case PRID_IMP_BCM3302:
- /* same as PRID_IMP_BCM6338 */
- c->cputype = CPU_BCM3302;
- __cpu_name[cpu] = "Broadcom BCM3302";
- break;
- case PRID_IMP_BCM4710:
- c->cputype = CPU_BCM4710;
- __cpu_name[cpu] = "Broadcom BCM4710";
- break;
- case PRID_IMP_BCM6345:
- c->cputype = CPU_BCM6345;
- __cpu_name[cpu] = "Broadcom BCM6345";
+ case PRID_IMP_BMIPS32:
+ c->cputype = CPU_BMIPS32;
+ __cpu_name[cpu] = "Broadcom BMIPS32";
+ break;
+ case PRID_IMP_BMIPS3300:
+ case PRID_IMP_BMIPS3300_ALT:
+ case PRID_IMP_BMIPS3300_BUG:
+ c->cputype = CPU_BMIPS3300;
+ __cpu_name[cpu] = "Broadcom BMIPS3300";
+ break;
+ case PRID_IMP_BMIPS43XX: {
+ int rev = c->processor_id & 0xff;
+
+ if (rev >= PRID_REV_BMIPS4380_LO &&
+ rev <= PRID_REV_BMIPS4380_HI) {
+ c->cputype = CPU_BMIPS4380;
+ __cpu_name[cpu] = "Broadcom BMIPS4380";
+ } else {
+ c->cputype = CPU_BMIPS4350;
+ __cpu_name[cpu] = "Broadcom BMIPS4350";
+ }
break;
- case PRID_IMP_BCM6348:
- c->cputype = CPU_BCM6348;
- __cpu_name[cpu] = "Broadcom BCM6348";
+ }
+ case PRID_IMP_BMIPS5000:
+ c->cputype = CPU_BMIPS5000;
+ __cpu_name[cpu] = "Broadcom BMIPS5000";
+ c->options |= MIPS_CPU_ULRI;
break;
- case PRID_IMP_BCM4350:
- switch (c->processor_id & 0xf0) {
- case PRID_REV_BCM6358:
- c->cputype = CPU_BCM6358;
- __cpu_name[cpu] = "Broadcom BCM6358";
- break;
- default:
- c->cputype = CPU_UNKNOWN;
- break;
- }
+ case PRID_IMP_BMIPS4KC:
+ c->cputype = CPU_4KC;
+ __cpu_name[cpu] = "MIPS 4Kc";
break;
}
}
@@ -953,6 +960,12 @@ platform:
if (cpu == 0)
__elf_platform = "octeon";
break;
+ case PRID_IMP_CAVIUM_CN63XX:
+ c->cputype = CPU_CAVIUM_OCTEON2;
+ __cpu_name[cpu] = "Cavium Octeon II";
+ if (cpu == 0)
+ __elf_platform = "octeon2";
+ break;
default:
printk(KERN_INFO "Unknown Octeon chip!\n");
c->cputype = CPU_UNKNOWN;
@@ -976,6 +989,12 @@ static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu)
}
}
+#ifdef CONFIG_64BIT
+/* For use by uaccess.h */
+u64 __ua_limit;
+EXPORT_SYMBOL(__ua_limit);
+#endif
+
const char *__cpu_name[NR_CPUS];
const char *__elf_platform;
@@ -1053,6 +1072,11 @@ __cpuinit void cpu_probe(void)
c->srsets = 1;
cpu_probe_vmbits(c);
+
+#ifdef CONFIG_64BIT
+ if (cpu == 0)
+ __ua_limit = ~((1ull << cpu_vmbits) - 1);
+#endif
}
__cpuinit void cpu_report(void)
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 82ba9f62f49e..1774271af848 100644
--- a/arch/mips/kernel/irq-gic.c
+++ b/arch/mips/kernel/irq-gic.c
@@ -3,11 +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/irq.h>
#include <linux/hardirq.h>
#include <asm-generic/bitops/find.h>
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.c b/arch/mips/kernel/irq.c
index c6345f579a8a..4f93db58a79e 100644
--- a/arch/mips/kernel/irq.c
+++ b/arch/mips/kernel/irq.c
@@ -151,6 +151,29 @@ void __init init_IRQ(void)
#endif
}
+#ifdef DEBUG_STACKOVERFLOW
+static inline void check_stack_overflow(void)
+{
+ unsigned long sp;
+
+ __asm__ __volatile__("move %0, $sp" : "=r" (sp));
+ sp &= THREAD_MASK;
+
+ /*
+ * Check for stack overflow: is there less than STACK_WARN free?
+ * STACK_WARN is defined as 1/8 of THREAD_SIZE by default.
+ */
+ if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) {
+ printk("do_IRQ: stack overflow: %ld\n",
+ sp - sizeof(struct thread_info));
+ dump_stack();
+ }
+}
+#else
+static inline void check_stack_overflow(void) {}
+#endif
+
+
/*
* do_IRQ handles all normal device IRQ's (the special
* SMP cross-CPU interrupts have their own specific
@@ -159,6 +182,7 @@ void __init init_IRQ(void)
void __irq_entry do_IRQ(unsigned int irq)
{
irq_enter();
+ check_stack_overflow();
__DO_IRQ_SMTC_HOOK(irq);
generic_handle_irq(irq);
irq_exit();
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/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/perf_event.c b/arch/mips/kernel/perf_event.c
new file mode 100644
index 000000000000..2b7f3f703b83
--- /dev/null
+++ b/arch/mips/kernel/perf_event.c
@@ -0,0 +1,601 @@
+/*
+ * Linux performance counter support for MIPS.
+ *
+ * Copyright (C) 2010 MIPS Technologies, Inc.
+ * Author: Deng-Cheng Zhu
+ *
+ * This code is based on the implementation for ARM, which is in turn
+ * based on the sparc64 perf event code and the x86 code. Performance
+ * counter access is based on the MIPS Oprofile code. And the callchain
+ * support references the code of MIPS stacktrace.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
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/cpumask.h>
+#include <linux/interrupt.h>
+#include <linux/smp.h>
+#include <linux/kernel.h>
+#include <linux/perf_event.h>
+#include <linux/uaccess.h>
+
+#include <asm/irq.h>
+#include <asm/irq_regs.h>
+#include <asm/stacktrace.h>
+#include <asm/time.h> /* For perf_irq */
+
+/* These are for 32bit counters. For 64bit ones, define them accordingly. */
+#define MAX_PERIOD ((1ULL << 32) - 1)
+#define VALID_COUNT 0x7fffffff
+#define TOTAL_BITS 32
+#define HIGHEST_BIT 31
+
+#define MIPS_MAX_HWEVENTS 4
+
+struct cpu_hw_events {
+ /* Array of events on this cpu. */
+ struct perf_event *events[MIPS_MAX_HWEVENTS];
+
+ /*
+ * Set the bit (indexed by the counter number) when the counter
+ * is used for an event.
+ */
+ unsigned long used_mask[BITS_TO_LONGS(MIPS_MAX_HWEVENTS)];
+
+ /*
+ * The borrowed MSB for the performance counter. A MIPS performance
+ * counter uses its bit 31 (for 32bit counters) or bit 63 (for 64bit
+ * counters) as a factor of determining whether a counter overflow
+ * should be signaled. So here we use a separate MSB for each
+ * counter to make things easy.
+ */
+ unsigned long msbs[BITS_TO_LONGS(MIPS_MAX_HWEVENTS)];
+
+ /*
+ * Software copy of the control register for each performance counter.
+ * MIPS CPUs vary in performance counters. They use this differently,
+ * and even may not use it.
+ */
+ unsigned int saved_ctrl[MIPS_MAX_HWEVENTS];
+};
+DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
+ .saved_ctrl = {0},
+};
+
+/* The description of MIPS performance events. */
+struct mips_perf_event {
+ unsigned int event_id;
+ /*
+ * MIPS performance counters are indexed starting from 0.
+ * CNTR_EVEN indicates the indexes of the counters to be used are
+ * even numbers.
+ */
+ unsigned int cntr_mask;
+ #define CNTR_EVEN 0x55555555
+ #define CNTR_ODD 0xaaaaaaaa
+#ifdef CONFIG_MIPS_MT_SMP
+ enum {
+ T = 0,
+ V = 1,
+ P = 2,
+ } range;
+#else
+ #define T
+ #define V
+ #define P
+#endif
+};
+
+static struct mips_perf_event raw_event;
+static DEFINE_MUTEX(raw_event_mutex);
+
+#define UNSUPPORTED_PERF_EVENT_ID 0xffffffff
+#define C(x) PERF_COUNT_HW_CACHE_##x
+
+struct mips_pmu {
+ const char *name;
+ int irq;
+ irqreturn_t (*handle_irq)(int irq, void *dev);
+ int (*handle_shared_irq)(void);
+ void (*start)(void);
+ void (*stop)(void);
+ int (*alloc_counter)(struct cpu_hw_events *cpuc,
+ struct hw_perf_event *hwc);
+ u64 (*read_counter)(unsigned int idx);
+ void (*write_counter)(unsigned int idx, u64 val);
+ void (*enable_event)(struct hw_perf_event *evt, int idx);
+ void (*disable_event)(int idx);
+ const struct mips_perf_event *(*map_raw_event)(u64 config);
+ const struct mips_perf_event (*general_event_map)[PERF_COUNT_HW_MAX];
+ const struct mips_perf_event (*cache_event_map)
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX];
+ unsigned int num_counters;
+};
+
+static const struct mips_pmu *mipspmu;
+
+static int
+mipspmu_event_set_period(struct perf_event *event,
+ struct hw_perf_event *hwc,
+ int idx)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ s64 left = local64_read(&hwc->period_left);
+ s64 period = hwc->sample_period;
+ int ret = 0;
+ u64 uleft;
+ unsigned long flags;
+
+ if (unlikely(left <= -period)) {
+ left = period;
+ local64_set(&hwc->period_left, left);
+ hwc->last_period = period;
+ ret = 1;
+ }
+
+ if (unlikely(left <= 0)) {
+ left += period;
+ local64_set(&hwc->period_left, left);
+ hwc->last_period = period;
+ ret = 1;
+ }
+
+ if (left > (s64)MAX_PERIOD)
+ left = MAX_PERIOD;
+
+ local64_set(&hwc->prev_count, (u64)-left);
+
+ local_irq_save(flags);
+ uleft = (u64)(-left) & MAX_PERIOD;
+ uleft > VALID_COUNT ?
+ set_bit(idx, cpuc->msbs) : clear_bit(idx, cpuc->msbs);
+ mipspmu->write_counter(idx, (u64)(-left) & VALID_COUNT);
+ local_irq_restore(flags);
+
+ perf_event_update_userpage(event);
+
+ return ret;
+}
+
+static int mipspmu_enable(struct perf_event *event)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ struct hw_perf_event *hwc = &event->hw;
+ int idx;
+ int err = 0;
+
+ /* To look for a free counter for this event. */
+ idx = mipspmu->alloc_counter(cpuc, hwc);
+ if (idx < 0) {
+ err = idx;
+ goto out;
+ }
+
+ /*
+ * If there is an event in the counter we are going to use then
+ * make sure it is disabled.
+ */
+ event->hw.idx = idx;
+ mipspmu->disable_event(idx);
+ cpuc->events[idx] = event;
+
+ /* Set the period for the event. */
+ mipspmu_event_set_period(event, hwc, idx);
+
+ /* Enable the event. */
+ mipspmu->enable_event(hwc, idx);
+
+ /* Propagate our changes to the userspace mapping. */
+ perf_event_update_userpage(event);
+
+out:
+ return err;
+}
+
+static void mipspmu_event_update(struct perf_event *event,
+ struct hw_perf_event *hwc,
+ int idx)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ unsigned long flags;
+ int shift = 64 - TOTAL_BITS;
+ s64 prev_raw_count, new_raw_count;
+ s64 delta;
+
+again:
+ prev_raw_count = local64_read(&hwc->prev_count);
+ local_irq_save(flags);
+ /* Make the counter value be a "real" one. */
+ new_raw_count = mipspmu->read_counter(idx);
+ if (new_raw_count & (test_bit(idx, cpuc->msbs) << HIGHEST_BIT)) {
+ new_raw_count &= VALID_COUNT;
+ clear_bit(idx, cpuc->msbs);
+ } else
+ new_raw_count |= (test_bit(idx, cpuc->msbs) << HIGHEST_BIT);
+ local_irq_restore(flags);
+
+ if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
+ new_raw_count) != prev_raw_count)
+ goto again;
+
+ delta = (new_raw_count << shift) - (prev_raw_count << shift);
+ delta >>= shift;
+
+ local64_add(delta, &event->count);
+ local64_sub(delta, &hwc->period_left);
+
+ return;
+}
+
+static void mipspmu_disable(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 || idx >= mipspmu->num_counters);
+
+ /* We are working on a local event. */
+ mipspmu->disable_event(idx);
+
+ barrier();
+
+ mipspmu_event_update(event, hwc, idx);
+ cpuc->events[idx] = NULL;
+ clear_bit(idx, cpuc->used_mask);
+
+ perf_event_update_userpage(event);
+}
+
+static void mipspmu_unthrottle(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+
+ mipspmu->enable_event(hwc, hwc->idx);
+}
+
+static void mipspmu_read(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+
+ /* Don't read disabled counters! */
+ if (hwc->idx < 0)
+ return;
+
+ mipspmu_event_update(event, hwc, hwc->idx);
+}
+
+static struct pmu pmu = {
+ .enable = mipspmu_enable,
+ .disable = mipspmu_disable,
+ .unthrottle = mipspmu_unthrottle,
+ .read = mipspmu_read,
+};
+
+static atomic_t active_events = ATOMIC_INIT(0);
+static DEFINE_MUTEX(pmu_reserve_mutex);
+static int (*save_perf_irq)(void);
+
+static int mipspmu_get_irq(void)
+{
+ int err;
+
+ if (mipspmu->irq >= 0) {
+ /* Request my own irq handler. */
+ err = request_irq(mipspmu->irq, mipspmu->handle_irq,
+ IRQF_DISABLED | IRQF_NOBALANCING,
+ "mips_perf_pmu", NULL);
+ if (err) {
+ pr_warning("Unable to request IRQ%d for MIPS "
+ "performance counters!\n", mipspmu->irq);
+ }
+ } else if (cp0_perfcount_irq < 0) {
+ /*
+ * We are sharing the irq number with the timer interrupt.
+ */
+ save_perf_irq = perf_irq;
+ perf_irq = mipspmu->handle_shared_irq;
+ err = 0;
+ } else {
+ pr_warning("The platform hasn't properly defined its "
+ "interrupt controller.\n");
+ err = -ENOENT;
+ }
+
+ return err;
+}
+
+static void mipspmu_free_irq(void)
+{
+ if (mipspmu->irq >= 0)
+ free_irq(mipspmu->irq, NULL);
+ else if (cp0_perfcount_irq < 0)
+ perf_irq = save_perf_irq;
+}
+
+static inline unsigned int
+mipspmu_perf_event_encode(const struct mips_perf_event *pev)
+{
+/*
+ * Top 8 bits for range, next 16 bits for cntr_mask, lowest 8 bits for
+ * event_id.
+ */
+#ifdef CONFIG_MIPS_MT_SMP
+ return ((unsigned int)pev->range << 24) |
+ (pev->cntr_mask & 0xffff00) |
+ (pev->event_id & 0xff);
+#else
+ return (pev->cntr_mask & 0xffff00) |
+ (pev->event_id & 0xff);
+#endif
+}
+
+static const struct mips_perf_event *
+mipspmu_map_general_event(int idx)
+{
+ const struct mips_perf_event *pev;
+
+ pev = ((*mipspmu->general_event_map)[idx].event_id ==
+ UNSUPPORTED_PERF_EVENT_ID ? ERR_PTR(-EOPNOTSUPP) :
+ &(*mipspmu->general_event_map)[idx]);
+
+ return pev;
+}
+
+static const struct mips_perf_event *
+mipspmu_map_cache_event(u64 config)
+{
+ unsigned int cache_type, cache_op, cache_result;
+ const struct mips_perf_event *pev;
+
+ cache_type = (config >> 0) & 0xff;
+ if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
+ return ERR_PTR(-EINVAL);
+
+ cache_op = (config >> 8) & 0xff;
+ if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
+ return ERR_PTR(-EINVAL);
+
+ cache_result = (config >> 16) & 0xff;
+ if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
+ return ERR_PTR(-EINVAL);
+
+ pev = &((*mipspmu->cache_event_map)
+ [cache_type]
+ [cache_op]
+ [cache_result]);
+
+ if (pev->event_id == UNSUPPORTED_PERF_EVENT_ID)
+ return ERR_PTR(-EOPNOTSUPP);
+
+ return pev;
+
+}
+
+static int validate_event(struct cpu_hw_events *cpuc,
+ struct perf_event *event)
+{
+ struct hw_perf_event fake_hwc = event->hw;
+
+ if (event->pmu && event->pmu != &pmu)
+ return 0;
+
+ return mipspmu->alloc_counter(cpuc, &fake_hwc) >= 0;
+}
+
+static int validate_group(struct perf_event *event)
+{
+ struct perf_event *sibling, *leader = event->group_leader;
+ struct cpu_hw_events fake_cpuc;
+
+ memset(&fake_cpuc, 0, sizeof(fake_cpuc));
+
+ if (!validate_event(&fake_cpuc, leader))
+ return -ENOSPC;
+
+ list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
+ if (!validate_event(&fake_cpuc, sibling))
+ return -ENOSPC;
+ }
+
+ if (!validate_event(&fake_cpuc, event))
+ return -ENOSPC;
+
+ return 0;
+}
+
+/*
+ * mipsxx/rm9000/loongson2 have different performance counters, they have
+ * specific low-level init routines.
+ */
+static void reset_counters(void *arg);
+static int __hw_perf_event_init(struct perf_event *event);
+
+static void hw_perf_event_destroy(struct perf_event *event)
+{
+ if (atomic_dec_and_mutex_lock(&active_events,
+ &pmu_reserve_mutex)) {
+ /*
+ * We must not call the destroy function with interrupts
+ * disabled.
+ */
+ on_each_cpu(reset_counters,
+ (void *)(long)mipspmu->num_counters, 1);
+ mipspmu_free_irq();
+ mutex_unlock(&pmu_reserve_mutex);
+ }
+}
+
+const struct pmu *hw_perf_event_init(struct perf_event *event)
+{
+ int err = 0;
+
+ if (!mipspmu || event->cpu >= nr_cpumask_bits ||
+ (event->cpu >= 0 && !cpu_online(event->cpu)))
+ return ERR_PTR(-ENODEV);
+
+ if (!atomic_inc_not_zero(&active_events)) {
+ if (atomic_read(&active_events) > MIPS_MAX_HWEVENTS) {
+ atomic_dec(&active_events);
+ return ERR_PTR(-ENOSPC);
+ }
+
+ mutex_lock(&pmu_reserve_mutex);
+ if (atomic_read(&active_events) == 0)
+ err = mipspmu_get_irq();
+
+ if (!err)
+ atomic_inc(&active_events);
+ mutex_unlock(&pmu_reserve_mutex);
+ }
+
+ if (err)
+ return ERR_PTR(err);
+
+ err = __hw_perf_event_init(event);
+ if (err)
+ hw_perf_event_destroy(event);
+
+ return err ? ERR_PTR(err) : &pmu;
+}
+
+void hw_perf_enable(void)
+{
+ if (mipspmu)
+ mipspmu->start();
+}
+
+void hw_perf_disable(void)
+{
+ if (mipspmu)
+ mipspmu->stop();
+}
+
+/* This is needed by specific irq handlers in perf_event_*.c */
+static void
+handle_associated_event(struct cpu_hw_events *cpuc,
+ int idx, struct perf_sample_data *data, struct pt_regs *regs)
+{
+ struct perf_event *event = cpuc->events[idx];
+ struct hw_perf_event *hwc = &event->hw;
+
+ mipspmu_event_update(event, hwc, idx);
+ data->period = event->hw.last_period;
+ if (!mipspmu_event_set_period(event, hwc, idx))
+ return;
+
+ if (perf_event_overflow(event, 0, data, regs))
+ mipspmu->disable_event(idx);
+}
+
+#include "perf_event_mipsxx.c"
+
+/* 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;
+}
+
+/*
+ * Leave userspace callchain empty for now. When we find a way to trace
+ * the user stack callchains, we add here.
+ */
+static void
+perf_callchain_user(struct pt_regs *regs,
+ struct perf_callchain_entry *entry)
+{
+}
+
+static void save_raw_perf_callchain(struct perf_callchain_entry *entry,
+ unsigned long reg29)
+{
+ unsigned long *sp = (unsigned long *)reg29;
+ unsigned long addr;
+
+ while (!kstack_end(sp)) {
+ addr = *sp++;
+ if (__kernel_text_address(addr)) {
+ callchain_store(entry, addr);
+ if (entry->nr >= PERF_MAX_STACK_DEPTH)
+ break;
+ }
+ }
+}
+
+static void
+perf_callchain_kernel(struct pt_regs *regs,
+ struct perf_callchain_entry *entry)
+{
+ unsigned long sp = regs->regs[29];
+#ifdef CONFIG_KALLSYMS
+ unsigned long ra = regs->regs[31];
+ unsigned long pc = regs->cp0_epc;
+
+ callchain_store(entry, PERF_CONTEXT_KERNEL);
+ if (raw_show_trace || !__kernel_text_address(pc)) {
+ unsigned long stack_page =
+ (unsigned long)task_stack_page(current);
+ if (stack_page && sp >= stack_page &&
+ sp <= stack_page + THREAD_SIZE - 32)
+ save_raw_perf_callchain(entry, sp);
+ return;
+ }
+ do {
+ callchain_store(entry, pc);
+ if (entry->nr >= PERF_MAX_STACK_DEPTH)
+ break;
+ pc = unwind_stack(current, &sp, pc, &ra);
+ } while (pc);
+#else
+ callchain_store(entry, PERF_CONTEXT_KERNEL);
+ save_raw_perf_callchain(entry, sp);
+#endif
+}
+
+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)
+ regs = task_pt_regs(current);
+ else
+ regs = NULL;
+ }
+ if (regs)
+ 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/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c
new file mode 100644
index 000000000000..5c7c6fc07565
--- /dev/null
+++ b/arch/mips/kernel/perf_event_mipsxx.c
@@ -0,0 +1,1052 @@
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) || \
+ defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_SB1)
+
+#define M_CONFIG1_PC (1 << 4)
+
+#define M_PERFCTL_EXL (1UL << 0)
+#define M_PERFCTL_KERNEL (1UL << 1)
+#define M_PERFCTL_SUPERVISOR (1UL << 2)
+#define M_PERFCTL_USER (1UL << 3)
+#define M_PERFCTL_INTERRUPT_ENABLE (1UL << 4)
+#define M_PERFCTL_EVENT(event) (((event) & 0x3ff) << 5)
+#define M_PERFCTL_VPEID(vpe) ((vpe) << 16)
+#define M_PERFCTL_MT_EN(filter) ((filter) << 20)
+#define M_TC_EN_ALL M_PERFCTL_MT_EN(0)
+#define M_TC_EN_VPE M_PERFCTL_MT_EN(1)
+#define M_TC_EN_TC M_PERFCTL_MT_EN(2)
+#define M_PERFCTL_TCID(tcid) ((tcid) << 22)
+#define M_PERFCTL_WIDE (1UL << 30)
+#define M_PERFCTL_MORE (1UL << 31)
+
+#define M_PERFCTL_COUNT_EVENT_WHENEVER (M_PERFCTL_EXL | \
+ M_PERFCTL_KERNEL | \
+ M_PERFCTL_USER | \
+ M_PERFCTL_SUPERVISOR | \
+ M_PERFCTL_INTERRUPT_ENABLE)
+
+#ifdef CONFIG_MIPS_MT_SMP
+#define M_PERFCTL_CONFIG_MASK 0x3fff801f
+#else
+#define M_PERFCTL_CONFIG_MASK 0x1f
+#endif
+#define M_PERFCTL_EVENT_MASK 0xfe0
+
+#define M_COUNTER_OVERFLOW (1UL << 31)
+
+#ifdef CONFIG_MIPS_MT_SMP
+static int cpu_has_mipsmt_pertccounters;
+
+/*
+ * FIXME: For VSMP, vpe_id() is redefined for Perf-events, because
+ * cpu_data[cpuid].vpe_id reports 0 for _both_ CPUs.
+ */
+#if defined(CONFIG_HW_PERF_EVENTS)
+#define vpe_id() (cpu_has_mipsmt_pertccounters ? \
+ 0 : smp_processor_id())
+#else
+#define vpe_id() (cpu_has_mipsmt_pertccounters ? \
+ 0 : cpu_data[smp_processor_id()].vpe_id)
+#endif
+
+/* Copied from op_model_mipsxx.c */
+static inline unsigned int vpe_shift(void)
+{
+ if (num_possible_cpus() > 1)
+ return 1;
+
+ return 0;
+}
+#else /* !CONFIG_MIPS_MT_SMP */
+#define vpe_id() 0
+
+static inline unsigned int vpe_shift(void)
+{
+ return 0;
+}
+#endif /* CONFIG_MIPS_MT_SMP */
+
+static inline unsigned int
+counters_total_to_per_cpu(unsigned int counters)
+{
+ return counters >> vpe_shift();
+}
+
+static inline unsigned int
+counters_per_cpu_to_total(unsigned int counters)
+{
+ return counters << vpe_shift();
+}
+
+#define __define_perf_accessors(r, n, np) \
+ \
+static inline unsigned int r_c0_ ## r ## n(void) \
+{ \
+ unsigned int cpu = vpe_id(); \
+ \
+ switch (cpu) { \
+ case 0: \
+ return read_c0_ ## r ## n(); \
+ case 1: \
+ return read_c0_ ## r ## np(); \
+ default: \
+ BUG(); \
+ } \
+ return 0; \
+} \
+ \
+static inline void w_c0_ ## r ## n(unsigned int value) \
+{ \
+ unsigned int cpu = vpe_id(); \
+ \
+ switch (cpu) { \
+ case 0: \
+ write_c0_ ## r ## n(value); \
+ return; \
+ case 1: \
+ write_c0_ ## r ## np(value); \
+ return; \
+ default: \
+ BUG(); \
+ } \
+ return; \
+} \
+
+__define_perf_accessors(perfcntr, 0, 2)
+__define_perf_accessors(perfcntr, 1, 3)
+__define_perf_accessors(perfcntr, 2, 0)
+__define_perf_accessors(perfcntr, 3, 1)
+
+__define_perf_accessors(perfctrl, 0, 2)
+__define_perf_accessors(perfctrl, 1, 3)
+__define_perf_accessors(perfctrl, 2, 0)
+__define_perf_accessors(perfctrl, 3, 1)
+
+static inline int __n_counters(void)
+{
+ if (!(read_c0_config1() & M_CONFIG1_PC))
+ return 0;
+ if (!(read_c0_perfctrl0() & M_PERFCTL_MORE))
+ return 1;
+ if (!(read_c0_perfctrl1() & M_PERFCTL_MORE))
+ return 2;
+ if (!(read_c0_perfctrl2() & M_PERFCTL_MORE))
+ return 3;
+
+ return 4;
+}
+
+static inline int n_counters(void)
+{
+ int counters;
+
+ switch (current_cpu_type()) {
+ case CPU_R10000:
+ counters = 2;
+ break;
+
+ case CPU_R12000:
+ case CPU_R14000:
+ counters = 4;
+ break;
+
+ default:
+ counters = __n_counters();
+ }
+
+ return counters;
+}
+
+static void reset_counters(void *arg)
+{
+ int counters = (int)(long)arg;
+ switch (counters) {
+ case 4:
+ w_c0_perfctrl3(0);
+ w_c0_perfcntr3(0);
+ case 3:
+ w_c0_perfctrl2(0);
+ w_c0_perfcntr2(0);
+ case 2:
+ w_c0_perfctrl1(0);
+ w_c0_perfcntr1(0);
+ case 1:
+ w_c0_perfctrl0(0);
+ w_c0_perfcntr0(0);
+ }
+}
+
+static inline u64
+mipsxx_pmu_read_counter(unsigned int idx)
+{
+ switch (idx) {
+ case 0:
+ return r_c0_perfcntr0();
+ case 1:
+ return r_c0_perfcntr1();
+ case 2:
+ return r_c0_perfcntr2();
+ case 3:
+ return r_c0_perfcntr3();
+ default:
+ WARN_ONCE(1, "Invalid performance counter number (%d)\n", idx);
+ return 0;
+ }
+}
+
+static inline void
+mipsxx_pmu_write_counter(unsigned int idx, u64 val)
+{
+ switch (idx) {
+ case 0:
+ w_c0_perfcntr0(val);
+ return;
+ case 1:
+ w_c0_perfcntr1(val);
+ return;
+ case 2:
+ w_c0_perfcntr2(val);
+ return;
+ case 3:
+ w_c0_perfcntr3(val);
+ return;
+ }
+}
+
+static inline unsigned int
+mipsxx_pmu_read_control(unsigned int idx)
+{
+ switch (idx) {
+ case 0:
+ return r_c0_perfctrl0();
+ case 1:
+ return r_c0_perfctrl1();
+ case 2:
+ return r_c0_perfctrl2();
+ case 3:
+ return r_c0_perfctrl3();
+ default:
+ WARN_ONCE(1, "Invalid performance counter number (%d)\n", idx);
+ return 0;
+ }
+}
+
+static inline void
+mipsxx_pmu_write_control(unsigned int idx, unsigned int val)
+{
+ switch (idx) {
+ case 0:
+ w_c0_perfctrl0(val);
+ return;
+ case 1:
+ w_c0_perfctrl1(val);
+ return;
+ case 2:
+ w_c0_perfctrl2(val);
+ return;
+ case 3:
+ w_c0_perfctrl3(val);
+ return;
+ }
+}
+
+#ifdef CONFIG_MIPS_MT_SMP
+static DEFINE_RWLOCK(pmuint_rwlock);
+#endif
+
+/* 24K/34K/1004K cores can share the same event map. */
+static const struct mips_perf_event mipsxxcore_event_map
+ [PERF_COUNT_HW_MAX] = {
+ [PERF_COUNT_HW_CPU_CYCLES] = { 0x00, CNTR_EVEN | CNTR_ODD, P },
+ [PERF_COUNT_HW_INSTRUCTIONS] = { 0x01, CNTR_EVEN | CNTR_ODD, T },
+ [PERF_COUNT_HW_CACHE_REFERENCES] = { UNSUPPORTED_PERF_EVENT_ID },
+ [PERF_COUNT_HW_CACHE_MISSES] = { UNSUPPORTED_PERF_EVENT_ID },
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 0x02, CNTR_EVEN, T },
+ [PERF_COUNT_HW_BRANCH_MISSES] = { 0x02, CNTR_ODD, T },
+ [PERF_COUNT_HW_BUS_CYCLES] = { UNSUPPORTED_PERF_EVENT_ID },
+};
+
+/* 74K core has different branch event code. */
+static const struct mips_perf_event mipsxx74Kcore_event_map
+ [PERF_COUNT_HW_MAX] = {
+ [PERF_COUNT_HW_CPU_CYCLES] = { 0x00, CNTR_EVEN | CNTR_ODD, P },
+ [PERF_COUNT_HW_INSTRUCTIONS] = { 0x01, CNTR_EVEN | CNTR_ODD, T },
+ [PERF_COUNT_HW_CACHE_REFERENCES] = { UNSUPPORTED_PERF_EVENT_ID },
+ [PERF_COUNT_HW_CACHE_MISSES] = { UNSUPPORTED_PERF_EVENT_ID },
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 0x27, CNTR_EVEN, T },
+ [PERF_COUNT_HW_BRANCH_MISSES] = { 0x27, CNTR_ODD, T },
+ [PERF_COUNT_HW_BUS_CYCLES] = { UNSUPPORTED_PERF_EVENT_ID },
+};
+
+/* 24K/34K/1004K cores can share the same cache event map. */
+static const struct mips_perf_event mipsxxcore_cache_map
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+[C(L1D)] = {
+ /*
+ * Like some other architectures (e.g. ARM), the performance
+ * counters don't differentiate between read and write
+ * accesses/misses, so this isn't strictly correct, but it's the
+ * best we can do. Writes and reads get combined.
+ */
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x0a, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x0b, CNTR_EVEN | CNTR_ODD, T },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { 0x0a, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x0b, CNTR_EVEN | CNTR_ODD, T },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ },
+},
+[C(L1I)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x09, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x09, CNTR_ODD, T },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { 0x09, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x09, CNTR_ODD, T },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { 0x14, CNTR_EVEN, T },
+ /*
+ * Note that MIPS has only "hit" events countable for
+ * the prefetch operation.
+ */
+ [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ },
+},
+[C(LL)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x15, CNTR_ODD, P },
+ [C(RESULT_MISS)] = { 0x16, CNTR_EVEN, P },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { 0x15, CNTR_ODD, P },
+ [C(RESULT_MISS)] = { 0x16, CNTR_EVEN, P },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ },
+},
+[C(DTLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x06, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x06, CNTR_ODD, T },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { 0x06, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x06, CNTR_ODD, T },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ },
+},
+[C(ITLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x05, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x05, CNTR_ODD, T },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { 0x05, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x05, CNTR_ODD, T },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ },
+},
+[C(BPU)] = {
+ /* Using the same code for *HW_BRANCH* */
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x02, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x02, CNTR_ODD, T },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { 0x02, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x02, CNTR_ODD, T },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ },
+},
+};
+
+/* 74K core has completely different cache event map. */
+static const struct mips_perf_event mipsxx74Kcore_cache_map
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+[C(L1D)] = {
+ /*
+ * Like some other architectures (e.g. ARM), the performance
+ * counters don't differentiate between read and write
+ * accesses/misses, so this isn't strictly correct, but it's the
+ * best we can do. Writes and reads get combined.
+ */
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x17, CNTR_ODD, T },
+ [C(RESULT_MISS)] = { 0x18, CNTR_ODD, T },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { 0x17, CNTR_ODD, T },
+ [C(RESULT_MISS)] = { 0x18, CNTR_ODD, T },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ },
+},
+[C(L1I)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x06, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x06, CNTR_ODD, T },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { 0x06, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x06, CNTR_ODD, T },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { 0x34, CNTR_EVEN, T },
+ /*
+ * Note that MIPS has only "hit" events countable for
+ * the prefetch operation.
+ */
+ [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ },
+},
+[C(LL)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x1c, CNTR_ODD, P },
+ [C(RESULT_MISS)] = { 0x1d, CNTR_EVEN | CNTR_ODD, P },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { 0x1c, CNTR_ODD, P },
+ [C(RESULT_MISS)] = { 0x1d, CNTR_EVEN | CNTR_ODD, P },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ },
+},
+[C(DTLB)] = {
+ /* 74K core does not have specific DTLB events. */
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ },
+},
+[C(ITLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x04, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x04, CNTR_ODD, T },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { 0x04, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x04, CNTR_ODD, T },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ },
+},
+[C(BPU)] = {
+ /* Using the same code for *HW_BRANCH* */
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x27, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x27, CNTR_ODD, T },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { 0x27, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x27, CNTR_ODD, T },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ },
+},
+};
+
+#ifdef CONFIG_MIPS_MT_SMP
+static void
+check_and_calc_range(struct perf_event *event,
+ const struct mips_perf_event *pev)
+{
+ struct hw_perf_event *hwc = &event->hw;
+
+ if (event->cpu >= 0) {
+ if (pev->range > V) {
+ /*
+ * The user selected an event that is processor
+ * wide, while expecting it to be VPE wide.
+ */
+ hwc->config_base |= M_TC_EN_ALL;
+ } else {
+ /*
+ * FIXME: cpu_data[event->cpu].vpe_id reports 0
+ * for both CPUs.
+ */
+ hwc->config_base |= M_PERFCTL_VPEID(event->cpu);
+ hwc->config_base |= M_TC_EN_VPE;
+ }
+ } else
+ hwc->config_base |= M_TC_EN_ALL;
+}
+#else
+static void
+check_and_calc_range(struct perf_event *event,
+ const struct mips_perf_event *pev)
+{
+}
+#endif
+
+static int __hw_perf_event_init(struct perf_event *event)
+{
+ struct perf_event_attr *attr = &event->attr;
+ struct hw_perf_event *hwc = &event->hw;
+ const struct mips_perf_event *pev;
+ int err;
+
+ /* Returning MIPS event descriptor for generic perf event. */
+ if (PERF_TYPE_HARDWARE == event->attr.type) {
+ if (event->attr.config >= PERF_COUNT_HW_MAX)
+ return -EINVAL;
+ pev = mipspmu_map_general_event(event->attr.config);
+ } else if (PERF_TYPE_HW_CACHE == event->attr.type) {
+ pev = mipspmu_map_cache_event(event->attr.config);
+ } else if (PERF_TYPE_RAW == event->attr.type) {
+ /* We are working on the global raw event. */
+ mutex_lock(&raw_event_mutex);
+ pev = mipspmu->map_raw_event(event->attr.config);
+ } else {
+ /* The event type is not (yet) supported. */
+ return -EOPNOTSUPP;
+ }
+
+ if (IS_ERR(pev)) {
+ if (PERF_TYPE_RAW == event->attr.type)
+ mutex_unlock(&raw_event_mutex);
+ return PTR_ERR(pev);
+ }
+
+ /*
+ * We allow max flexibility on how each individual counter shared
+ * by the single CPU operates (the mode exclusion and the range).
+ */
+ hwc->config_base = M_PERFCTL_INTERRUPT_ENABLE;
+
+ /* Calculate range bits and validate it. */
+ if (num_possible_cpus() > 1)
+ check_and_calc_range(event, pev);
+
+ hwc->event_base = mipspmu_perf_event_encode(pev);
+ if (PERF_TYPE_RAW == event->attr.type)
+ mutex_unlock(&raw_event_mutex);
+
+ if (!attr->exclude_user)
+ hwc->config_base |= M_PERFCTL_USER;
+ if (!attr->exclude_kernel) {
+ hwc->config_base |= M_PERFCTL_KERNEL;
+ /* MIPS kernel mode: KSU == 00b || EXL == 1 || ERL == 1 */
+ hwc->config_base |= M_PERFCTL_EXL;
+ }
+ if (!attr->exclude_hv)
+ hwc->config_base |= M_PERFCTL_SUPERVISOR;
+
+ hwc->config_base &= M_PERFCTL_CONFIG_MASK;
+ /*
+ * The event can belong to another cpu. We do not assign a local
+ * counter for it for now.
+ */
+ hwc->idx = -1;
+ hwc->config = 0;
+
+ if (!hwc->sample_period) {
+ hwc->sample_period = MAX_PERIOD;
+ hwc->last_period = hwc->sample_period;
+ local64_set(&hwc->period_left, hwc->sample_period);
+ }
+
+ err = 0;
+ if (event->group_leader != event) {
+ err = validate_group(event);
+ if (err)
+ return -EINVAL;
+ }
+
+ event->destroy = hw_perf_event_destroy;
+
+ return err;
+}
+
+static void pause_local_counters(void)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ int counters = mipspmu->num_counters;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ switch (counters) {
+ case 4:
+ cpuc->saved_ctrl[3] = r_c0_perfctrl3();
+ w_c0_perfctrl3(cpuc->saved_ctrl[3] &
+ ~M_PERFCTL_COUNT_EVENT_WHENEVER);
+ case 3:
+ cpuc->saved_ctrl[2] = r_c0_perfctrl2();
+ w_c0_perfctrl2(cpuc->saved_ctrl[2] &
+ ~M_PERFCTL_COUNT_EVENT_WHENEVER);
+ case 2:
+ cpuc->saved_ctrl[1] = r_c0_perfctrl1();
+ w_c0_perfctrl1(cpuc->saved_ctrl[1] &
+ ~M_PERFCTL_COUNT_EVENT_WHENEVER);
+ case 1:
+ cpuc->saved_ctrl[0] = r_c0_perfctrl0();
+ w_c0_perfctrl0(cpuc->saved_ctrl[0] &
+ ~M_PERFCTL_COUNT_EVENT_WHENEVER);
+ }
+ local_irq_restore(flags);
+}
+
+static void resume_local_counters(void)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ int counters = mipspmu->num_counters;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ switch (counters) {
+ case 4:
+ w_c0_perfctrl3(cpuc->saved_ctrl[3]);
+ case 3:
+ w_c0_perfctrl2(cpuc->saved_ctrl[2]);
+ case 2:
+ w_c0_perfctrl1(cpuc->saved_ctrl[1]);
+ case 1:
+ w_c0_perfctrl0(cpuc->saved_ctrl[0]);
+ }
+ local_irq_restore(flags);
+}
+
+static int mipsxx_pmu_handle_shared_irq(void)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ struct perf_sample_data data;
+ unsigned int counters = mipspmu->num_counters;
+ unsigned int counter;
+ int handled = IRQ_NONE;
+ struct pt_regs *regs;
+
+ if (cpu_has_mips_r2 && !(read_c0_cause() & (1 << 26)))
+ return handled;
+
+ /*
+ * First we pause the local counters, so that when we are locked
+ * here, the counters are all paused. When it gets locked due to
+ * perf_disable(), the timer interrupt handler will be delayed.
+ *
+ * See also mipsxx_pmu_start().
+ */
+ pause_local_counters();
+#ifdef CONFIG_MIPS_MT_SMP
+ read_lock(&pmuint_rwlock);
+#endif
+
+ regs = get_irq_regs();
+
+ perf_sample_data_init(&data, 0);
+
+ switch (counters) {
+#define HANDLE_COUNTER(n) \
+ case n + 1: \
+ if (test_bit(n, cpuc->used_mask)) { \
+ counter = r_c0_perfcntr ## n(); \
+ if (counter & M_COUNTER_OVERFLOW) { \
+ w_c0_perfcntr ## n(counter & \
+ VALID_COUNT); \
+ if (test_and_change_bit(n, cpuc->msbs)) \
+ handle_associated_event(cpuc, \
+ n, &data, regs); \
+ handled = IRQ_HANDLED; \
+ } \
+ }
+ HANDLE_COUNTER(3)
+ HANDLE_COUNTER(2)
+ HANDLE_COUNTER(1)
+ HANDLE_COUNTER(0)
+ }
+
+ /*
+ * Do all the work for the pending perf events. We can do this
+ * in here because the performance counter interrupt is a regular
+ * interrupt, not NMI.
+ */
+ if (handled == IRQ_HANDLED)
+ perf_event_do_pending();
+
+#ifdef CONFIG_MIPS_MT_SMP
+ read_unlock(&pmuint_rwlock);
+#endif
+ resume_local_counters();
+ return handled;
+}
+
+static irqreturn_t
+mipsxx_pmu_handle_irq(int irq, void *dev)
+{
+ return mipsxx_pmu_handle_shared_irq();
+}
+
+static void mipsxx_pmu_start(void)
+{
+#ifdef CONFIG_MIPS_MT_SMP
+ write_unlock(&pmuint_rwlock);
+#endif
+ resume_local_counters();
+}
+
+/*
+ * MIPS performance counters can be per-TC. The control registers can
+ * not be directly accessed accross CPUs. Hence if we want to do global
+ * control, we need cross CPU calls. on_each_cpu() can help us, but we
+ * can not make sure this function is called with interrupts enabled. So
+ * here we pause local counters and then grab a rwlock and leave the
+ * counters on other CPUs alone. If any counter interrupt raises while
+ * we own the write lock, simply pause local counters on that CPU and
+ * spin in the handler. Also we know we won't be switched to another
+ * CPU after pausing local counters and before grabbing the lock.
+ */
+static void mipsxx_pmu_stop(void)
+{
+ pause_local_counters();
+#ifdef CONFIG_MIPS_MT_SMP
+ write_lock(&pmuint_rwlock);
+#endif
+}
+
+static int
+mipsxx_pmu_alloc_counter(struct cpu_hw_events *cpuc,
+ struct hw_perf_event *hwc)
+{
+ int i;
+
+ /*
+ * We only need to care the counter mask. The range has been
+ * checked definitely.
+ */
+ unsigned long cntr_mask = (hwc->event_base >> 8) & 0xffff;
+
+ for (i = mipspmu->num_counters - 1; i >= 0; i--) {
+ /*
+ * Note that some MIPS perf events can be counted by both
+ * even and odd counters, wheresas many other are only by
+ * even _or_ odd counters. This introduces an issue that
+ * when the former kind of event takes the counter the
+ * latter kind of event wants to use, then the "counter
+ * allocation" for the latter event will fail. In fact if
+ * they can be dynamically swapped, they both feel happy.
+ * But here we leave this issue alone for now.
+ */
+ if (test_bit(i, &cntr_mask) &&
+ !test_and_set_bit(i, cpuc->used_mask))
+ return i;
+ }
+
+ return -EAGAIN;
+}
+
+static void
+mipsxx_pmu_enable_event(struct hw_perf_event *evt, int idx)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ unsigned long flags;
+
+ WARN_ON(idx < 0 || idx >= mipspmu->num_counters);
+
+ local_irq_save(flags);
+ cpuc->saved_ctrl[idx] = M_PERFCTL_EVENT(evt->event_base & 0xff) |
+ (evt->config_base & M_PERFCTL_CONFIG_MASK) |
+ /* Make sure interrupt enabled. */
+ M_PERFCTL_INTERRUPT_ENABLE;
+ /*
+ * We do not actually let the counter run. Leave it until start().
+ */
+ local_irq_restore(flags);
+}
+
+static void
+mipsxx_pmu_disable_event(int idx)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ unsigned long flags;
+
+ WARN_ON(idx < 0 || idx >= mipspmu->num_counters);
+
+ local_irq_save(flags);
+ cpuc->saved_ctrl[idx] = mipsxx_pmu_read_control(idx) &
+ ~M_PERFCTL_COUNT_EVENT_WHENEVER;
+ mipsxx_pmu_write_control(idx, cpuc->saved_ctrl[idx]);
+ local_irq_restore(flags);
+}
+
+/* 24K */
+#define IS_UNSUPPORTED_24K_EVENT(r, b) \
+ ((b) == 12 || (r) == 151 || (r) == 152 || (b) == 26 || \
+ (b) == 27 || (r) == 28 || (r) == 158 || (b) == 31 || \
+ (b) == 32 || (b) == 34 || (b) == 36 || (r) == 168 || \
+ (r) == 172 || (b) == 47 || ((b) >= 56 && (b) <= 63) || \
+ ((b) >= 68 && (b) <= 127))
+#define IS_BOTH_COUNTERS_24K_EVENT(b) \
+ ((b) == 0 || (b) == 1 || (b) == 11)
+
+/* 34K */
+#define IS_UNSUPPORTED_34K_EVENT(r, b) \
+ ((b) == 12 || (r) == 27 || (r) == 158 || (b) == 36 || \
+ (b) == 38 || (r) == 175 || ((b) >= 56 && (b) <= 63) || \
+ ((b) >= 68 && (b) <= 127))
+#define IS_BOTH_COUNTERS_34K_EVENT(b) \
+ ((b) == 0 || (b) == 1 || (b) == 11)
+#ifdef CONFIG_MIPS_MT_SMP
+#define IS_RANGE_P_34K_EVENT(r, b) \
+ ((b) == 0 || (r) == 18 || (b) == 21 || (b) == 22 || \
+ (b) == 25 || (b) == 39 || (r) == 44 || (r) == 174 || \
+ (r) == 176 || ((b) >= 50 && (b) <= 55) || \
+ ((b) >= 64 && (b) <= 67))
+#define IS_RANGE_V_34K_EVENT(r) ((r) == 47)
+#endif
+
+/* 74K */
+#define IS_UNSUPPORTED_74K_EVENT(r, b) \
+ ((r) == 5 || ((r) >= 135 && (r) <= 137) || \
+ ((b) >= 10 && (b) <= 12) || (b) == 22 || (b) == 27 || \
+ (b) == 33 || (b) == 34 || ((b) >= 47 && (b) <= 49) || \
+ (r) == 178 || (b) == 55 || (b) == 57 || (b) == 60 || \
+ (b) == 61 || (r) == 62 || (r) == 191 || \
+ ((b) >= 64 && (b) <= 127))
+#define IS_BOTH_COUNTERS_74K_EVENT(b) \
+ ((b) == 0 || (b) == 1)
+
+/* 1004K */
+#define IS_UNSUPPORTED_1004K_EVENT(r, b) \
+ ((b) == 12 || (r) == 27 || (r) == 158 || (b) == 38 || \
+ (r) == 175 || (b) == 63 || ((b) >= 68 && (b) <= 127))
+#define IS_BOTH_COUNTERS_1004K_EVENT(b) \
+ ((b) == 0 || (b) == 1 || (b) == 11)
+#ifdef CONFIG_MIPS_MT_SMP
+#define IS_RANGE_P_1004K_EVENT(r, b) \
+ ((b) == 0 || (r) == 18 || (b) == 21 || (b) == 22 || \
+ (b) == 25 || (b) == 36 || (b) == 39 || (r) == 44 || \
+ (r) == 174 || (r) == 176 || ((b) >= 50 && (b) <= 59) || \
+ (r) == 188 || (b) == 61 || (b) == 62 || \
+ ((b) >= 64 && (b) <= 67))
+#define IS_RANGE_V_1004K_EVENT(r) ((r) == 47)
+#endif
+
+/*
+ * User can use 0-255 raw events, where 0-127 for the events of even
+ * counters, and 128-255 for odd counters. Note that bit 7 is used to
+ * indicate the parity. So, for example, when user wants to take the
+ * Event Num of 15 for odd counters (by referring to the user manual),
+ * then 128 needs to be added to 15 as the input for the event config,
+ * i.e., 143 (0x8F) to be used.
+ */
+static const struct mips_perf_event *
+mipsxx_pmu_map_raw_event(u64 config)
+{
+ unsigned int raw_id = config & 0xff;
+ unsigned int base_id = raw_id & 0x7f;
+
+ switch (current_cpu_type()) {
+ case CPU_24K:
+ if (IS_UNSUPPORTED_24K_EVENT(raw_id, base_id))
+ return ERR_PTR(-EOPNOTSUPP);
+ raw_event.event_id = base_id;
+ if (IS_BOTH_COUNTERS_24K_EVENT(base_id))
+ raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
+ else
+ raw_event.cntr_mask =
+ raw_id > 127 ? CNTR_ODD : CNTR_EVEN;
+#ifdef CONFIG_MIPS_MT_SMP
+ /*
+ * This is actually doing nothing. Non-multithreading
+ * CPUs will not check and calculate the range.
+ */
+ raw_event.range = P;
+#endif
+ break;
+ case CPU_34K:
+ if (IS_UNSUPPORTED_34K_EVENT(raw_id, base_id))
+ return ERR_PTR(-EOPNOTSUPP);
+ raw_event.event_id = base_id;
+ if (IS_BOTH_COUNTERS_34K_EVENT(base_id))
+ raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
+ else
+ raw_event.cntr_mask =
+ raw_id > 127 ? CNTR_ODD : CNTR_EVEN;
+#ifdef CONFIG_MIPS_MT_SMP
+ if (IS_RANGE_P_34K_EVENT(raw_id, base_id))
+ raw_event.range = P;
+ else if (unlikely(IS_RANGE_V_34K_EVENT(raw_id)))
+ raw_event.range = V;
+ else
+ raw_event.range = T;
+#endif
+ break;
+ case CPU_74K:
+ if (IS_UNSUPPORTED_74K_EVENT(raw_id, base_id))
+ return ERR_PTR(-EOPNOTSUPP);
+ raw_event.event_id = base_id;
+ if (IS_BOTH_COUNTERS_74K_EVENT(base_id))
+ raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
+ else
+ raw_event.cntr_mask =
+ raw_id > 127 ? CNTR_ODD : CNTR_EVEN;
+#ifdef CONFIG_MIPS_MT_SMP
+ raw_event.range = P;
+#endif
+ break;
+ case CPU_1004K:
+ if (IS_UNSUPPORTED_1004K_EVENT(raw_id, base_id))
+ return ERR_PTR(-EOPNOTSUPP);
+ raw_event.event_id = base_id;
+ if (IS_BOTH_COUNTERS_1004K_EVENT(base_id))
+ raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
+ else
+ raw_event.cntr_mask =
+ raw_id > 127 ? CNTR_ODD : CNTR_EVEN;
+#ifdef CONFIG_MIPS_MT_SMP
+ if (IS_RANGE_P_1004K_EVENT(raw_id, base_id))
+ raw_event.range = P;
+ else if (unlikely(IS_RANGE_V_1004K_EVENT(raw_id)))
+ raw_event.range = V;
+ else
+ raw_event.range = T;
+#endif
+ break;
+ }
+
+ return &raw_event;
+}
+
+static struct mips_pmu mipsxxcore_pmu = {
+ .handle_irq = mipsxx_pmu_handle_irq,
+ .handle_shared_irq = mipsxx_pmu_handle_shared_irq,
+ .start = mipsxx_pmu_start,
+ .stop = mipsxx_pmu_stop,
+ .alloc_counter = mipsxx_pmu_alloc_counter,
+ .read_counter = mipsxx_pmu_read_counter,
+ .write_counter = mipsxx_pmu_write_counter,
+ .enable_event = mipsxx_pmu_enable_event,
+ .disable_event = mipsxx_pmu_disable_event,
+ .map_raw_event = mipsxx_pmu_map_raw_event,
+ .general_event_map = &mipsxxcore_event_map,
+ .cache_event_map = &mipsxxcore_cache_map,
+};
+
+static struct mips_pmu mipsxx74Kcore_pmu = {
+ .handle_irq = mipsxx_pmu_handle_irq,
+ .handle_shared_irq = mipsxx_pmu_handle_shared_irq,
+ .start = mipsxx_pmu_start,
+ .stop = mipsxx_pmu_stop,
+ .alloc_counter = mipsxx_pmu_alloc_counter,
+ .read_counter = mipsxx_pmu_read_counter,
+ .write_counter = mipsxx_pmu_write_counter,
+ .enable_event = mipsxx_pmu_enable_event,
+ .disable_event = mipsxx_pmu_disable_event,
+ .map_raw_event = mipsxx_pmu_map_raw_event,
+ .general_event_map = &mipsxx74Kcore_event_map,
+ .cache_event_map = &mipsxx74Kcore_cache_map,
+};
+
+static int __init
+init_hw_perf_events(void)
+{
+ int counters, irq;
+
+ pr_info("Performance counters: ");
+
+ counters = n_counters();
+ if (counters == 0) {
+ pr_cont("No available PMU.\n");
+ return -ENODEV;
+ }
+
+#ifdef CONFIG_MIPS_MT_SMP
+ cpu_has_mipsmt_pertccounters = read_c0_config7() & (1<<19);
+ if (!cpu_has_mipsmt_pertccounters)
+ counters = counters_total_to_per_cpu(counters);
+#endif
+
+#ifdef MSC01E_INT_BASE
+ if (cpu_has_veic) {
+ /*
+ * Using platform specific interrupt controller defines.
+ */
+ irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR;
+ } else {
+#endif
+ if (cp0_perfcount_irq >= 0)
+ irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
+ else
+ irq = -1;
+#ifdef MSC01E_INT_BASE
+ }
+#endif
+
+ on_each_cpu(reset_counters, (void *)(long)counters, 1);
+
+ switch (current_cpu_type()) {
+ case CPU_24K:
+ mipsxxcore_pmu.name = "mips/24K";
+ mipsxxcore_pmu.num_counters = counters;
+ mipsxxcore_pmu.irq = irq;
+ mipspmu = &mipsxxcore_pmu;
+ break;
+ case CPU_34K:
+ mipsxxcore_pmu.name = "mips/34K";
+ mipsxxcore_pmu.num_counters = counters;
+ mipsxxcore_pmu.irq = irq;
+ mipspmu = &mipsxxcore_pmu;
+ break;
+ case CPU_74K:
+ mipsxx74Kcore_pmu.name = "mips/74K";
+ mipsxx74Kcore_pmu.num_counters = counters;
+ mipsxx74Kcore_pmu.irq = irq;
+ mipspmu = &mipsxx74Kcore_pmu;
+ break;
+ case CPU_1004K:
+ mipsxxcore_pmu.name = "mips/1004K";
+ mipsxxcore_pmu.num_counters = counters;
+ mipsxxcore_pmu.irq = irq;
+ mipspmu = &mipsxxcore_pmu;
+ break;
+ default:
+ pr_cont("Either hardware does not support performance "
+ "counters, or not yet implemented.\n");
+ return -ENODEV;
+ }
+
+ if (mipspmu)
+ pr_cont("%s PMU enabled, %d counters available to each "
+ "CPU, irq %d%s\n", mipspmu->name, counters, irq,
+ irq < 0 ? " (share with timer interrupt)" : "");
+
+ return 0;
+}
+arch_initcall(init_hw_perf_events);
+
+#endif /* defined(CONFIG_CPU_MIPS32)... */
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 c8777333e198..d21c388c0116 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -255,9 +255,13 @@ int ptrace_set_watch_regs(struct task_struct *child,
return 0;
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int ret;
+ void __user *addrp = (void __user *) addr;
+ void __user *datavp = (void __user *) data;
+ unsigned long __user *datalp = (void __user *) data;
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
@@ -386,7 +390,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
ret = -EIO;
goto out;
}
- ret = put_user(tmp, (unsigned long __user *) data);
+ ret = put_user(tmp, datalp);
break;
}
@@ -478,34 +482,31 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
}
case PTRACE_GETREGS:
- ret = ptrace_getregs(child, (__s64 __user *) data);
+ ret = ptrace_getregs(child, datavp);
break;
case PTRACE_SETREGS:
- ret = ptrace_setregs(child, (__s64 __user *) data);
+ ret = ptrace_setregs(child, datavp);
break;
case PTRACE_GETFPREGS:
- ret = ptrace_getfpregs(child, (__u32 __user *) data);
+ ret = ptrace_getfpregs(child, datavp);
break;
case PTRACE_SETFPREGS:
- ret = ptrace_setfpregs(child, (__u32 __user *) data);
+ ret = ptrace_setfpregs(child, datavp);
break;
case PTRACE_GET_THREAD_AREA:
- ret = put_user(task_thread_info(child)->tp_value,
- (unsigned long __user *) data);
+ ret = put_user(task_thread_info(child)->tp_value, datalp);
break;
case PTRACE_GET_WATCH_REGS:
- ret = ptrace_get_watch_regs(child,
- (struct pt_watch_regs __user *) addr);
+ ret = ptrace_get_watch_regs(child, addrp);
break;
case PTRACE_SET_WATCH_REGS:
- ret = ptrace_set_watch_regs(child,
- (struct pt_watch_regs __user *) addr);
+ ret = ptrace_set_watch_regs(child, addrp);
break;
default:
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/setup.c b/arch/mips/kernel/setup.c
index 85aef3fc6716..acd3f2c49c06 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,7 +488,9 @@ static void __init arch_mem_init(char **cmdline_p)
}
bootmem_init();
+ device_tree_init();
sparse_init();
+ plat_swiotlb_setup();
paging_init();
}
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..8e9fbe75894e 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -28,6 +28,8 @@
#include <linux/kprobes.h>
#include <linux/notifier.h>
#include <linux/kdb.h>
+#include <linux/irq.h>
+#include <linux/perf_event.h>
#include <asm/bootinfo.h>
#include <asm/branch.h>
@@ -51,7 +53,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);
@@ -576,10 +577,16 @@ static inline int simulate_sc(struct pt_regs *regs, unsigned int opcode)
*/
static int simulate_llsc(struct pt_regs *regs, unsigned int opcode)
{
- if ((opcode & OPCODE) == LL)
+ if ((opcode & OPCODE) == LL) {
+ perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS,
+ 1, 0, regs, 0);
return simulate_ll(regs, opcode);
- if ((opcode & OPCODE) == SC)
+ }
+ if ((opcode & OPCODE) == SC) {
+ perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS,
+ 1, 0, regs, 0);
return simulate_sc(regs, opcode);
+ }
return -1; /* Must be something else ... */
}
@@ -595,6 +602,8 @@ static int simulate_rdhwr(struct pt_regs *regs, unsigned int opcode)
if ((opcode & OPCODE) == SPEC3 && (opcode & FUNC) == RDHWR) {
int rd = (opcode & RD) >> 11;
int rt = (opcode & RT) >> 16;
+ perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS,
+ 1, 0, regs, 0);
switch (rd) {
case 0: /* CPU number */
regs->regs[rt] = smp_processor_id();
@@ -630,8 +639,11 @@ static int simulate_rdhwr(struct pt_regs *regs, unsigned int opcode)
static int simulate_sync(struct pt_regs *regs, unsigned int opcode)
{
- if ((opcode & OPCODE) == SPEC0 && (opcode & FUNC) == SYNC)
+ if ((opcode & OPCODE) == SPEC0 && (opcode & FUNC) == SYNC) {
+ perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS,
+ 1, 0, regs, 0);
return 0;
+ }
return -1; /* Must be something else ... */
}
@@ -1469,6 +1481,7 @@ void __cpuinit per_cpu_trap_init(void)
{
unsigned int cpu = smp_processor_id();
unsigned int status_set = ST0_CU0;
+ unsigned int hwrena = cpu_hwrena_impl_bits;
#ifdef CONFIG_MIPS_MT_SMTC
int secondaryTC = 0;
int bootTC = (cpu == 0);
@@ -1501,14 +1514,14 @@ void __cpuinit per_cpu_trap_init(void)
change_c0_status(ST0_CU|ST0_MX|ST0_RE|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX,
status_set);
- if (cpu_has_mips_r2) {
- unsigned int enable = 0x0000000f | cpu_hwrena_impl_bits;
+ if (cpu_has_mips_r2)
+ hwrena |= 0x0000000f;
- if (!noulri && cpu_has_userlocal)
- enable |= (1 << 29);
+ if (!noulri && cpu_has_userlocal)
+ hwrena |= (1 << 29);
- write_c0_hwrena(enable);
- }
+ if (hwrena)
+ write_c0_hwrena(hwrena);
#ifdef CONFIG_MIPS_MT_SMTC
if (!secondaryTC) {
diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c
index 33d5a5ce4a29..cfea1adfa153 100644
--- a/arch/mips/kernel/unaligned.c
+++ b/arch/mips/kernel/unaligned.c
@@ -78,6 +78,8 @@
#include <linux/smp.h>
#include <linux/sched.h>
#include <linux/debugfs.h>
+#include <linux/perf_event.h>
+
#include <asm/asm.h>
#include <asm/branch.h>
#include <asm/byteorder.h>
@@ -109,6 +111,9 @@ static void emulate_load_store_insn(struct pt_regs *regs,
unsigned long value;
unsigned int res;
+ perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS,
+ 1, 0, regs, 0);
+
/*
* This load never faults.
*/
@@ -511,6 +516,8 @@ asmlinkage void do_ade(struct pt_regs *regs)
unsigned int __user *pc;
mm_segment_t seg;
+ perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS,
+ 1, 0, regs, regs->cp0_badvaddr);
/*
* Did we catch a fault trying to load an instruction?
* Or are we running in MIPS16 mode?
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/loongson/Kconfig b/arch/mips/loongson/Kconfig
index c97ca69b94e0..6e1b77fec7ea 100644
--- a/arch/mips/loongson/Kconfig
+++ b/arch/mips/loongson/Kconfig
@@ -20,7 +20,6 @@ config LEMOTE_FULOONG2E
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_SUPPORTS_HIGHMEM
select SYS_HAS_EARLY_PRINTK
- select GENERIC_HARDIRQS_NO__DO_IRQ
select GENERIC_ISA_DMA_SUPPORT_BROKEN
select CPU_HAS_WB
select LOONGSON_MC146818
@@ -40,7 +39,6 @@ config LEMOTE_MACH2F
select CS5536
select CSRC_R4K if ! MIPS_EXTERNAL_TIMER
select DMA_NONCOHERENT
- select GENERIC_HARDIRQS_NO__DO_IRQ
select GENERIC_ISA_DMA_SUPPORT_BROKEN
select HW_HAS_PCI
select I8259
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index 47842b7d26ae..b2ad1b0910ff 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.
@@ -37,6 +36,7 @@
#include <linux/sched.h>
#include <linux/module.h>
#include <linux/debugfs.h>
+#include <linux/perf_event.h>
#include <asm/inst.h>
#include <asm/bootinfo.h>
@@ -259,6 +259,8 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
}
emul:
+ perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS,
+ 1, 0, xcp, 0);
MIPS_FPU_EMU_INC_STATS(emulated);
switch (MIPSInst_OPCODE(ir)) {
case ldc1_op:{
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/c-octeon.c b/arch/mips/mm/c-octeon.c
index 0f9c488044d1..16c4d256b76f 100644
--- a/arch/mips/mm/c-octeon.c
+++ b/arch/mips/mm/c-octeon.c
@@ -181,10 +181,10 @@ static void __cpuinit probe_octeon(void)
unsigned int config1;
struct cpuinfo_mips *c = &current_cpu_data;
+ config1 = read_c0_config1();
switch (c->cputype) {
case CPU_CAVIUM_OCTEON:
case CPU_CAVIUM_OCTEON_PLUS:
- config1 = read_c0_config1();
c->icache.linesz = 2 << ((config1 >> 19) & 7);
c->icache.sets = 64 << ((config1 >> 22) & 7);
c->icache.ways = 1 + ((config1 >> 16) & 7);
@@ -204,6 +204,20 @@ static void __cpuinit probe_octeon(void)
c->options |= MIPS_CPU_PREFETCH;
break;
+ case CPU_CAVIUM_OCTEON2:
+ c->icache.linesz = 2 << ((config1 >> 19) & 7);
+ c->icache.sets = 8;
+ c->icache.ways = 37;
+ c->icache.flags |= MIPS_CACHE_VTAG;
+ icache_size = c->icache.sets * c->icache.ways * c->icache.linesz;
+
+ c->dcache.linesz = 128;
+ c->dcache.ways = 32;
+ c->dcache.sets = 8;
+ dcache_size = c->dcache.sets * c->dcache.ways * c->dcache.linesz;
+ c->options |= MIPS_CPU_PREFETCH;
+ break;
+
default:
panic("Unsupported Cavium Networks CPU type\n");
break;
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 6721ee2b1e8b..b4923a75cb4b 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -42,14 +42,14 @@
* o collapses to normal function call on UP kernels
* o collapses to normal function call on systems with a single shared
* primary cache.
+ * o doesn't disable interrupts on the local CPU
*/
-static inline void r4k_on_each_cpu(void (*func) (void *info), void *info,
- int wait)
+static inline void r4k_on_each_cpu(void (*func) (void *info), void *info)
{
preempt_disable();
#if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC)
- smp_call_function(func, info, wait);
+ smp_call_function(func, info, 1);
#endif
func(info);
preempt_enable();
@@ -363,7 +363,7 @@ static inline void local_r4k___flush_cache_all(void * args)
static void r4k___flush_cache_all(void)
{
- r4k_on_each_cpu(local_r4k___flush_cache_all, NULL, 1);
+ r4k_on_each_cpu(local_r4k___flush_cache_all, NULL);
}
static inline int has_valid_asid(const struct mm_struct *mm)
@@ -410,7 +410,7 @@ static void r4k_flush_cache_range(struct vm_area_struct *vma,
int exec = vma->vm_flags & VM_EXEC;
if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc))
- r4k_on_each_cpu(local_r4k_flush_cache_range, vma, 1);
+ r4k_on_each_cpu(local_r4k_flush_cache_range, vma);
}
static inline void local_r4k_flush_cache_mm(void * args)
@@ -442,7 +442,7 @@ static void r4k_flush_cache_mm(struct mm_struct *mm)
if (!cpu_has_dc_aliases)
return;
- r4k_on_each_cpu(local_r4k_flush_cache_mm, mm, 1);
+ r4k_on_each_cpu(local_r4k_flush_cache_mm, mm);
}
struct flush_cache_page_args {
@@ -534,7 +534,7 @@ static void r4k_flush_cache_page(struct vm_area_struct *vma,
args.addr = addr;
args.pfn = pfn;
- r4k_on_each_cpu(local_r4k_flush_cache_page, &args, 1);
+ r4k_on_each_cpu(local_r4k_flush_cache_page, &args);
}
static inline void local_r4k_flush_data_cache_page(void * addr)
@@ -547,8 +547,7 @@ static void r4k_flush_data_cache_page(unsigned long addr)
if (in_atomic())
local_r4k_flush_data_cache_page((void *)addr);
else
- r4k_on_each_cpu(local_r4k_flush_data_cache_page, (void *) addr,
- 1);
+ r4k_on_each_cpu(local_r4k_flush_data_cache_page, (void *) addr);
}
struct flush_icache_range_args {
@@ -589,7 +588,7 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end)
args.start = start;
args.end = end;
- r4k_on_each_cpu(local_r4k_flush_icache_range_ipi, &args, 1);
+ r4k_on_each_cpu(local_r4k_flush_icache_range_ipi, &args);
instruction_hazard();
}
@@ -710,7 +709,7 @@ static void local_r4k_flush_cache_sigtramp(void * arg)
static void r4k_flush_cache_sigtramp(unsigned long addr)
{
- r4k_on_each_cpu(local_r4k_flush_cache_sigtramp, (void *) addr, 1);
+ r4k_on_each_cpu(local_r4k_flush_cache_sigtramp, (void *) addr);
}
static void r4k_flush_icache_all(void)
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 469d4019f795..4fc1a0fbe007 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -95,10 +95,9 @@ void *dma_alloc_noncoherent(struct device *dev, size_t size,
return ret;
}
-
EXPORT_SYMBOL(dma_alloc_noncoherent);
-void *dma_alloc_coherent(struct device *dev, size_t size,
+static void *mips_dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t * dma_handle, gfp_t gfp)
{
void *ret;
@@ -123,7 +122,6 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
return ret;
}
-EXPORT_SYMBOL(dma_alloc_coherent);
void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
dma_addr_t dma_handle)
@@ -131,10 +129,9 @@ void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL);
free_pages((unsigned long) vaddr, get_order(size));
}
-
EXPORT_SYMBOL(dma_free_noncoherent);
-void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
+static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr,
dma_addr_t dma_handle)
{
unsigned long addr = (unsigned long) vaddr;
@@ -151,8 +148,6 @@ void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
free_pages(addr, get_order(size));
}
-EXPORT_SYMBOL(dma_free_coherent);
-
static inline void __dma_sync(unsigned long addr, size_t size,
enum dma_data_direction direction)
{
@@ -174,21 +169,8 @@ static inline void __dma_sync(unsigned long addr, size_t size,
}
}
-dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
- enum dma_data_direction direction)
-{
- unsigned long addr = (unsigned long) ptr;
-
- if (!plat_device_is_coherent(dev))
- __dma_sync(addr, size, direction);
-
- return plat_map_dma_mem(dev, ptr, size);
-}
-
-EXPORT_SYMBOL(dma_map_single);
-
-void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
- enum dma_data_direction direction)
+static void mips_dma_unmap_page(struct device *dev, dma_addr_t dma_addr,
+ size_t size, enum dma_data_direction direction, struct dma_attrs *attrs)
{
if (cpu_is_noncoherent_r10000(dev))
__dma_sync(dma_addr_to_virt(dev, dma_addr), size,
@@ -197,15 +179,11 @@ void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
plat_unmap_dma_mem(dev, dma_addr, size, direction);
}
-EXPORT_SYMBOL(dma_unmap_single);
-
-int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
- enum dma_data_direction direction)
+static int mips_dma_map_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction direction, struct dma_attrs *attrs)
{
int i;
- BUG_ON(direction == DMA_NONE);
-
for (i = 0; i < nents; i++, sg++) {
unsigned long addr;
@@ -219,33 +197,27 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
return nents;
}
-EXPORT_SYMBOL(dma_map_sg);
-
-dma_addr_t dma_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size, enum dma_data_direction direction)
+static dma_addr_t mips_dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
- BUG_ON(direction == DMA_NONE);
+ unsigned long addr;
- if (!plat_device_is_coherent(dev)) {
- unsigned long addr;
+ addr = (unsigned long) page_address(page) + offset;
- addr = (unsigned long) page_address(page) + offset;
+ if (!plat_device_is_coherent(dev))
__dma_sync(addr, size, direction);
- }
- return plat_map_dma_mem_page(dev, page) + offset;
+ return plat_map_dma_mem(dev, (void *)addr, size);
}
-EXPORT_SYMBOL(dma_map_page);
-
-void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
- enum dma_data_direction direction)
+static void mips_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nhwentries, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
unsigned long addr;
int i;
- BUG_ON(direction == DMA_NONE);
-
for (i = 0; i < nhwentries; i++, sg++) {
if (!plat_device_is_coherent(dev) &&
direction != DMA_TO_DEVICE) {
@@ -257,13 +229,9 @@ void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
}
}
-EXPORT_SYMBOL(dma_unmap_sg);
-
-void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
- size_t size, enum dma_data_direction direction)
+static void mips_dma_sync_single_for_cpu(struct device *dev,
+ dma_addr_t dma_handle, size_t size, enum dma_data_direction direction)
{
- BUG_ON(direction == DMA_NONE);
-
if (cpu_is_noncoherent_r10000(dev)) {
unsigned long addr;
@@ -272,13 +240,9 @@ void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
}
}
-EXPORT_SYMBOL(dma_sync_single_for_cpu);
-
-void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
- size_t size, enum dma_data_direction direction)
+static void mips_dma_sync_single_for_device(struct device *dev,
+ dma_addr_t dma_handle, size_t size, enum dma_data_direction direction)
{
- BUG_ON(direction == DMA_NONE);
-
plat_extra_sync_for_device(dev);
if (!plat_device_is_coherent(dev)) {
unsigned long addr;
@@ -288,46 +252,11 @@ void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
}
}
-EXPORT_SYMBOL(dma_sync_single_for_device);
-
-void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
- unsigned long offset, size_t size, enum dma_data_direction direction)
-{
- BUG_ON(direction == DMA_NONE);
-
- if (cpu_is_noncoherent_r10000(dev)) {
- unsigned long addr;
-
- addr = dma_addr_to_virt(dev, dma_handle);
- __dma_sync(addr + offset, size, direction);
- }
-}
-
-EXPORT_SYMBOL(dma_sync_single_range_for_cpu);
-
-void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
- unsigned long offset, size_t size, enum dma_data_direction direction)
-{
- BUG_ON(direction == DMA_NONE);
-
- plat_extra_sync_for_device(dev);
- if (!plat_device_is_coherent(dev)) {
- unsigned long addr;
-
- addr = dma_addr_to_virt(dev, dma_handle);
- __dma_sync(addr + offset, size, direction);
- }
-}
-
-EXPORT_SYMBOL(dma_sync_single_range_for_device);
-
-void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
- enum dma_data_direction direction)
+static void mips_dma_sync_sg_for_cpu(struct device *dev,
+ struct scatterlist *sg, int nelems, enum dma_data_direction direction)
{
int i;
- BUG_ON(direction == DMA_NONE);
-
/* Make sure that gcc doesn't leave the empty loop body. */
for (i = 0; i < nelems; i++, sg++) {
if (cpu_is_noncoherent_r10000(dev))
@@ -336,15 +265,11 @@ void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
}
}
-EXPORT_SYMBOL(dma_sync_sg_for_cpu);
-
-void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
- enum dma_data_direction direction)
+static void mips_dma_sync_sg_for_device(struct device *dev,
+ struct scatterlist *sg, int nelems, enum dma_data_direction direction)
{
int i;
- BUG_ON(direction == DMA_NONE);
-
/* Make sure that gcc doesn't leave the empty loop body. */
for (i = 0; i < nelems; i++, sg++) {
if (!plat_device_is_coherent(dev))
@@ -353,24 +278,18 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nele
}
}
-EXPORT_SYMBOL(dma_sync_sg_for_device);
-
-int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+int mips_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
{
return plat_dma_mapping_error(dev, dma_addr);
}
-EXPORT_SYMBOL(dma_mapping_error);
-
-int dma_supported(struct device *dev, u64 mask)
+int mips_dma_supported(struct device *dev, u64 mask)
{
return plat_dma_supported(dev, mask);
}
-EXPORT_SYMBOL(dma_supported);
-
-void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
- enum dma_data_direction direction)
+void mips_dma_cache_sync(struct device *dev, void *vaddr, size_t size,
+ enum dma_data_direction direction)
{
BUG_ON(direction == DMA_NONE);
@@ -379,4 +298,30 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
__dma_sync((unsigned long)vaddr, size, direction);
}
-EXPORT_SYMBOL(dma_cache_sync);
+static struct dma_map_ops mips_default_dma_map_ops = {
+ .alloc_coherent = mips_dma_alloc_coherent,
+ .free_coherent = mips_dma_free_coherent,
+ .map_page = mips_dma_map_page,
+ .unmap_page = mips_dma_unmap_page,
+ .map_sg = mips_dma_map_sg,
+ .unmap_sg = mips_dma_unmap_sg,
+ .sync_single_for_cpu = mips_dma_sync_single_for_cpu,
+ .sync_single_for_device = mips_dma_sync_single_for_device,
+ .sync_sg_for_cpu = mips_dma_sync_sg_for_cpu,
+ .sync_sg_for_device = mips_dma_sync_sg_for_device,
+ .mapping_error = mips_dma_mapping_error,
+ .dma_supported = mips_dma_supported
+};
+
+struct dma_map_ops *mips_dma_map_ops = &mips_default_dma_map_ops;
+EXPORT_SYMBOL(mips_dma_map_ops);
+
+#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
+
+static int __init mips_dma_init(void)
+{
+ dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
+
+ return 0;
+}
+fs_initcall(mips_dma_init);
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index 783ad0065fdf..137ee76a0045 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -18,6 +18,7 @@
#include <linux/smp.h>
#include <linux/module.h>
#include <linux/kprobes.h>
+#include <linux/perf_event.h>
#include <asm/branch.h>
#include <asm/mmu_context.h>
@@ -144,6 +145,7 @@ good_area:
* the fault.
*/
fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0);
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
if (unlikely(fault & VM_FAULT_ERROR)) {
if (fault & VM_FAULT_OOM)
goto out_of_memory;
@@ -151,10 +153,15 @@ good_area:
goto do_sigbus;
BUG();
}
- if (fault & VM_FAULT_MAJOR)
+ if (fault & VM_FAULT_MAJOR) {
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ,
+ 1, 0, regs, address);
tsk->maj_flt++;
- else
+ } else {
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN,
+ 1, 0, regs, address);
tsk->min_flt++;
+ }
up_read(&mm->mmap_sem);
return;
diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c
index 6a2b1bf9ef11..3634c7ea06ac 100644
--- a/arch/mips/mm/highmem.c
+++ b/arch/mips/mm/highmem.c
@@ -9,7 +9,7 @@ static pte_t *kmap_pte;
unsigned long highstart_pfn, highend_pfn;
-void *__kmap(struct page *page)
+void *kmap(struct page *page)
{
void *addr;
@@ -21,16 +21,16 @@ void *__kmap(struct page *page)
return addr;
}
-EXPORT_SYMBOL(__kmap);
+EXPORT_SYMBOL(kmap);
-void __kunmap(struct page *page)
+void kunmap(struct page *page)
{
BUG_ON(in_interrupt());
if (!PageHighMem(page))
return;
kunmap_high(page);
}
-EXPORT_SYMBOL(__kunmap);
+EXPORT_SYMBOL(kunmap);
/*
* kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because
@@ -41,17 +41,17 @@ EXPORT_SYMBOL(__kunmap);
* kmaps are appropriate for short, tight code paths only.
*/
-void *__kmap_atomic(struct page *page, enum km_type type)
+void *__kmap_atomic(struct page *page)
{
- enum fixed_addresses idx;
unsigned long vaddr;
+ int idx, type;
/* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
pagefault_disable();
if (!PageHighMem(page))
return page_address(page);
- debug_kmap_atomic(type);
+ type = kmap_atomic_idx_push();
idx = type + KM_TYPE_NR*smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
#ifdef CONFIG_DEBUG_HIGHMEM
@@ -64,43 +64,48 @@ void *__kmap_atomic(struct page *page, enum km_type type)
}
EXPORT_SYMBOL(__kmap_atomic);
-void __kunmap_atomic_notypecheck(void *kvaddr, enum km_type type)
+void __kunmap_atomic(void *kvaddr)
{
-#ifdef CONFIG_DEBUG_HIGHMEM
unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
- enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
+ int type;
if (vaddr < FIXADDR_START) { // FIXME
pagefault_enable();
return;
}
- BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
+ type = kmap_atomic_idx();
+#ifdef CONFIG_DEBUG_HIGHMEM
+ {
+ int idx = type + KM_TYPE_NR * smp_processor_id();
- /*
- * force other mappings to Oops if they'll try to access
- * this pte without first remap it
- */
- pte_clear(&init_mm, vaddr, kmap_pte-idx);
- local_flush_tlb_one(vaddr);
-#endif
+ BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
+ /*
+ * force other mappings to Oops if they'll try to access
+ * this pte without first remap it
+ */
+ pte_clear(&init_mm, vaddr, kmap_pte-idx);
+ local_flush_tlb_one(vaddr);
+ }
+#endif
+ kmap_atomic_idx_pop();
pagefault_enable();
}
-EXPORT_SYMBOL(__kunmap_atomic_notypecheck);
+EXPORT_SYMBOL(__kunmap_atomic);
/*
* This is the same as kmap_atomic() but can map memory that doesn't
* have a struct page associated with it.
*/
-void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
+void *kmap_atomic_pfn(unsigned long pfn)
{
- enum fixed_addresses idx;
unsigned long vaddr;
+ int idx, type;
pagefault_disable();
- debug_kmap_atomic(type);
+ type = kmap_atomic_idx_push();
idx = type + KM_TYPE_NR*smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
set_pte(kmap_pte-idx, pfn_pte(pfn, PAGE_KERNEL));
@@ -109,7 +114,7 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
return (void*) vaddr;
}
-struct page *__kmap_atomic_to_page(void *ptr)
+struct page *kmap_atomic_to_page(void *ptr)
{
unsigned long idx, vaddr = (unsigned long)ptr;
pte_t *pte;
diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c
index 5ab5fa8c1d82..505fecad4684 100644
--- a/arch/mips/mm/sc-mips.c
+++ b/arch/mips/mm/sc-mips.c
@@ -57,6 +57,34 @@ static struct bcache_ops mips_sc_ops = {
.bc_inv = mips_sc_inv
};
+/*
+ * Check if the L2 cache controller is activated on a particular platform.
+ * MTI's L2 controller and the L2 cache controller of Broadcom's BMIPS
+ * cores both use c0_config2's bit 12 as "L2 Bypass" bit, that is the
+ * cache being disabled. However there is no guarantee for this to be
+ * true on all platforms. In an act of stupidity the spec defined bits
+ * 12..15 as implementation defined so below function will eventually have
+ * to be replaced by a platform specific probe.
+ */
+static inline int mips_sc_is_activated(struct cpuinfo_mips *c)
+{
+ /* Check the bypass bit (L2B) */
+ switch (c->cputype) {
+ case CPU_34K:
+ case CPU_74K:
+ case CPU_1004K:
+ case CPU_BMIPS5000:
+ if (config2 & (1 << 12))
+ return 0;
+ }
+
+ tmp = (config2 >> 4) & 0x0f;
+ if (0 < tmp && tmp <= 7)
+ c->scache.linesz = 2 << tmp;
+ else
+ return 0;
+}
+
static inline int __init mips_sc_probe(void)
{
struct cpuinfo_mips *c = &current_cpu_data;
@@ -79,10 +107,8 @@ static inline int __init mips_sc_probe(void)
return 0;
config2 = read_c0_config2();
- tmp = (config2 >> 4) & 0x0f;
- if (0 < tmp && tmp <= 7)
- c->scache.linesz = 2 << tmp;
- else
+
+ if (!mips_sc_is_activated(c))
return 0;
tmp = (config2 >> 8) & 0x0f;
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 4510e61883eb..93816f3bca67 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -338,13 +338,12 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l,
case CPU_4KSC:
case CPU_20KC:
case CPU_25KF:
- case CPU_BCM3302:
- case CPU_BCM4710:
+ case CPU_BMIPS32:
+ case CPU_BMIPS3300:
+ case CPU_BMIPS4350:
+ case CPU_BMIPS4380:
+ case CPU_BMIPS5000:
case CPU_LOONGSON2:
- case CPU_BCM6338:
- case CPU_BCM6345:
- case CPU_BCM6348:
- case CPU_BCM6358:
case CPU_R5500:
if (m4kc_tlbp_war())
uasm_i_nop(p);
diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c
index d2647a4e012b..23afdebc8e5c 100644
--- a/arch/mips/mm/uasm.c
+++ b/arch/mips/mm/uasm.c
@@ -405,7 +405,6 @@ I_u1u2u3(_mfc0)
I_u1u2u3(_mtc0)
I_u2u1u3(_ori)
I_u3u1u2(_or)
-I_u2s3u1(_pref)
I_0(_rfe)
I_u2s3u1(_sc)
I_u2s3u1(_scd)
@@ -427,6 +426,25 @@ I_u1(_syscall);
I_u1u2s3(_bbit0);
I_u1u2s3(_bbit1);
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+#include <asm/octeon/octeon.h>
+void __uasminit uasm_i_pref(u32 **buf, unsigned int a, signed int b,
+ unsigned int c)
+{
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X) && a <= 24 && a != 5)
+ /*
+ * As per erratum Core-14449, replace prefetches 0-4,
+ * 6-24 with 'pref 28'.
+ */
+ build_insn(buf, insn_pref, c, 28, b);
+ else
+ build_insn(buf, insn_pref, c, a, b);
+}
+UASM_EXPORT_SYMBOL(uasm_i_pref);
+#else
+I_u2s3u1(_pref)
+#endif
+
/* Handle labels. */
void __uasminit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid)
{
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-octeon.c b/arch/mips/pci/pci-octeon.c
index d248b707eff3..2d74fc9ae3ba 100644
--- a/arch/mips/pci/pci-octeon.c
+++ b/arch/mips/pci/pci-octeon.c
@@ -11,6 +11,7 @@
#include <linux/interrupt.h>
#include <linux/time.h>
#include <linux/delay.h>
+#include <linux/swiotlb.h>
#include <asm/time.h>
@@ -19,6 +20,8 @@
#include <asm/octeon/cvmx-pci-defs.h>
#include <asm/octeon/pci-octeon.h>
+#include <dma-coherence.h>
+
#define USE_OCTEON_INTERNAL_ARBITER
/*
@@ -32,6 +35,8 @@
/* Octeon't PCI controller uses did=3, subdid=3 for PCI memory. */
#define OCTEON_PCI_MEMSPACE_OFFSET (0x00011b0000000000ull)
+u64 octeon_bar1_pci_phys;
+
/**
* This is the bit decoding used for the Octeon PCI controller addresses
*/
@@ -170,6 +175,8 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
pci_write_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, dconfig);
}
+ dev->dev.archdata.dma_ops = octeon_pci_dma_map_ops;
+
return 0;
}
@@ -618,12 +625,10 @@ static int __init octeon_pci_setup(void)
* before the readl()'s below. We don't want BAR2 overlapping
* with BAR0/BAR1 during these reads.
*/
- octeon_npi_write32(CVMX_NPI_PCI_CFG08, 0);
- octeon_npi_write32(CVMX_NPI_PCI_CFG09, 0x80);
-
- /* Disable the BAR1 movable mappings */
- for (index = 0; index < 32; index++)
- octeon_npi_write32(CVMX_NPI_PCI_BAR1_INDEXX(index), 0);
+ octeon_npi_write32(CVMX_NPI_PCI_CFG08,
+ (u32)(OCTEON_BAR2_PCI_ADDRESS & 0xffffffffull));
+ octeon_npi_write32(CVMX_NPI_PCI_CFG09,
+ (u32)(OCTEON_BAR2_PCI_ADDRESS >> 32));
if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG) {
/* Remap the Octeon BAR 0 to 0-2GB */
@@ -637,6 +642,25 @@ static int __init octeon_pci_setup(void)
octeon_npi_write32(CVMX_NPI_PCI_CFG06, 2ul << 30);
octeon_npi_write32(CVMX_NPI_PCI_CFG07, 0);
+ /* BAR1 movable mappings set for identity mapping */
+ octeon_bar1_pci_phys = 0x80000000ull;
+ for (index = 0; index < 32; index++) {
+ union cvmx_pci_bar1_indexx bar1_index;
+
+ bar1_index.u32 = 0;
+ /* Address bits[35:22] sent to L2C */
+ bar1_index.s.addr_idx =
+ (octeon_bar1_pci_phys >> 22) + index;
+ /* Don't put PCI accesses in L2. */
+ bar1_index.s.ca = 1;
+ /* Endian Swap Mode */
+ bar1_index.s.end_swp = 1;
+ /* Set '1' when the selected address range is valid. */
+ bar1_index.s.addr_v = 1;
+ octeon_npi_write32(CVMX_NPI_PCI_BAR1_INDEXX(index),
+ bar1_index.u32);
+ }
+
/* Devices go after BAR1 */
octeon_pci_mem_resource.start =
OCTEON_PCI_MEMSPACE_OFFSET + (4ul << 30) -
@@ -652,6 +676,27 @@ static int __init octeon_pci_setup(void)
octeon_npi_write32(CVMX_NPI_PCI_CFG06, 0);
octeon_npi_write32(CVMX_NPI_PCI_CFG07, 0);
+ /* BAR1 movable regions contiguous to cover the swiotlb */
+ octeon_bar1_pci_phys =
+ virt_to_phys(octeon_swiotlb) & ~((1ull << 22) - 1);
+
+ for (index = 0; index < 32; index++) {
+ union cvmx_pci_bar1_indexx bar1_index;
+
+ bar1_index.u32 = 0;
+ /* Address bits[35:22] sent to L2C */
+ bar1_index.s.addr_idx =
+ (octeon_bar1_pci_phys >> 22) + index;
+ /* Don't put PCI accesses in L2. */
+ bar1_index.s.ca = 1;
+ /* Endian Swap Mode */
+ bar1_index.s.end_swp = 1;
+ /* Set '1' when the selected address range is valid. */
+ bar1_index.s.addr_v = 1;
+ octeon_npi_write32(CVMX_NPI_PCI_BAR1_INDEXX(index),
+ bar1_index.u32);
+ }
+
/* Devices go after BAR0 */
octeon_pci_mem_resource.start =
OCTEON_PCI_MEMSPACE_OFFSET + (128ul << 20) +
@@ -667,6 +712,9 @@ static int __init octeon_pci_setup(void)
* was setup properly.
*/
cvmx_write_csr(CVMX_NPI_PCI_INT_SUM2, -1);
+
+ octeon_pci_dma_init();
+
return 0;
}
diff --git a/arch/mips/pci/pcie-octeon.c b/arch/mips/pci/pcie-octeon.c
index 861361e0c9af..385f035b24e4 100644
--- a/arch/mips/pci/pcie-octeon.c
+++ b/arch/mips/pci/pcie-octeon.c
@@ -75,6 +75,8 @@ union cvmx_pcie_address {
} mem;
};
+#include <dma-coherence.h>
+
/**
* Return the Core virtual base address for PCIe IO access. IOs are
* read/written as an offset from this address.
@@ -1391,6 +1393,9 @@ static int __init octeon_pcie_setup(void)
cvmx_pcie_get_io_size(1) - 1;
register_pci_controller(&octeon_pcie1_controller);
}
+
+ octeon_pci_dma_init();
+
return 0;
}
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/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/Kconfig b/arch/mn10300/Kconfig
index 7c2a2f7f8dc1..41ba38513c89 100644
--- a/arch/mn10300/Kconfig
+++ b/arch/mn10300/Kconfig
@@ -1,16 +1,20 @@
-#
-# For a description of the syntax of this configuration file,
-# see Documentation/kbuild/kconfig-language.txt.
-#
-
-mainmenu "Linux Kernel Configuration"
-
config MN10300
def_bool y
select HAVE_OPROFILE
-config AM33
- def_bool y
+config AM33_2
+ def_bool n
+
+config AM33_3
+ def_bool n
+
+config AM34_2
+ def_bool n
+ select MN10300_HAS_ATOMIC_OPS_UNIT
+ select MN10300_HAS_CACHE_SNOOP
+
+config ERRATUM_NEED_TO_RELOAD_MMUCTR
+ def_bool y if AM33_3 || AM34_2
config MMU
def_bool y
@@ -37,7 +41,7 @@ config GENERIC_CALIBRATE_DELAY
def_bool y
config GENERIC_CMOS_UPDATE
- def_bool y
+ def_bool n
config GENERIC_FIND_NEXT_BIT
def_bool y
@@ -45,6 +49,27 @@ config GENERIC_FIND_NEXT_BIT
config GENERIC_HWEIGHT
def_bool y
+config GENERIC_TIME
+ def_bool y
+
+config GENERIC_CLOCKEVENTS
+ def_bool y
+
+config GENERIC_CLOCKEVENTS_BUILD
+ def_bool y
+ depends on GENERIC_CLOCKEVENTS
+
+config GENERIC_CLOCKEVENTS_BROADCAST
+ bool
+
+config CEVT_MN10300
+ def_bool y
+ depends on GENERIC_CLOCKEVENTS
+
+config CSRC_MN10300
+ def_bool y
+ depends on GENERIC_TIME
+
config GENERIC_BUG
def_bool y
@@ -61,18 +86,12 @@ config GENERIC_HARDIRQS
config HOTPLUG_CPU
def_bool n
-config HZ
- int
- default 1000
-
-mainmenu "Matsushita MN10300/AM33 Kernel Configuration"
-
source "init/Kconfig"
source "kernel/Kconfig.freezer"
-menu "Matsushita MN10300 system setup"
+menu "Panasonic MN10300 system setup"
choice
prompt "Unit type"
@@ -87,6 +106,10 @@ config MN10300_UNIT_ASB2303
config MN10300_UNIT_ASB2305
bool "ASB2305"
+config MN10300_UNIT_ASB2364
+ bool "ASB2364"
+ select SMSC911X_ARCH_HOOKS if SMSC911X
+
endchoice
choice
@@ -99,57 +122,51 @@ choice
config MN10300_PROC_MN103E010
bool "MN103E010"
depends on MN10300_UNIT_ASB2303 || MN10300_UNIT_ASB2305
+ select AM33_2
+ select MN10300_PROC_HAS_TTYSM0
+ select MN10300_PROC_HAS_TTYSM1
+ select MN10300_PROC_HAS_TTYSM2
+
+config MN10300_PROC_MN2WS0050
+ bool "MN2WS0050"
+ depends on MN10300_UNIT_ASB2364
+ select AM34_2
select MN10300_PROC_HAS_TTYSM0
select MN10300_PROC_HAS_TTYSM1
select MN10300_PROC_HAS_TTYSM2
endchoice
-choice
- prompt "Processor core support"
- default MN10300_CPU_AM33V2
+config MN10300_HAS_ATOMIC_OPS_UNIT
+ def_bool n
help
- This option specifies the processor core for which the kernel will be
- compiled. It affects the instruction set used.
-
-config MN10300_CPU_AM33V2
- bool "AM33v2"
-
-endchoice
+ This should be enabled if the processor has an atomic ops unit
+ capable of doing LL/SC equivalent operations.
config FPU
bool "FPU present"
default y
- depends on MN10300_PROC_MN103E010
+ depends on MN10300_PROC_MN103E010 || MN10300_PROC_MN2WS0050
-choice
- prompt "CPU Caching mode"
- default MN10300_CACHE_WBACK
+config LAZY_SAVE_FPU
+ bool "Save FPU state lazily"
+ default y
+ depends on FPU && !SMP
help
- This option determines the caching mode for the kernel.
+ Enable this to be lazy in the saving of the FPU state to the owning
+ task's thread struct. This is useful if most tasks on the system
+ don't use the FPU as only those tasks that use it will pass it
+ between them, and the state needn't be saved for a task that isn't
+ using it.
- Write-Back caching mode involves the all reads and writes causing
- the affected cacheline to be read into the cache first before being
- operated upon. Memory is not then updated by a write until the cache
- is filled and a cacheline needs to be displaced from the cache to
- make room. Only at that point is it written back.
+ This can't be so easily used on SMP as the process that owns the FPU
+ state on a CPU may be currently running on another CPU, so for the
+ moment, it is disabled.
- Write-Through caching only fetches cachelines from memory on a
- read. Writes always get written directly to memory. If the affected
- cacheline is also in cache, it will be updated too.
+source "arch/mn10300/mm/Kconfig.cache"
- The final option is to turn of caching entirely.
-
-config MN10300_CACHE_WBACK
- bool "Write-Back"
-
-config MN10300_CACHE_WTHRU
- bool "Write-Through"
-
-config MN10300_CACHE_DISABLED
- bool "Disabled"
-
-endchoice
+config MN10300_TLB_USE_PIDR
+ def_bool y
menu "Memory layout options"
@@ -170,24 +187,55 @@ config KERNEL_TEXT_ADDRESS
config KERNEL_ZIMAGE_BASE_ADDRESS
hex "Base address of compressed vmlinux image"
- default "0x90700000"
+ default "0x50700000"
+
+config BOOT_STACK_OFFSET
+ hex
+ default "0xF00" if SMP
+ default "0xFF0" if !SMP
+config BOOT_STACK_SIZE
+ hex
+ depends on SMP
+ default "0x100"
endmenu
-config PREEMPT
- bool "Preemptible Kernel"
- help
- This option reduces the latency of the kernel when reacting to
- real-time or interactive events by allowing a low priority process to
- be preempted even if it is in kernel mode executing a system call.
- This allows applications to run more reliably even when the system is
- under load.
+config SMP
+ bool "Symmetric multi-processing support"
+ default y
+ depends on MN10300_PROC_MN2WS0038 || MN10300_PROC_MN2WS0050
+ ---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
+ you have a system with more than one CPU, say Y.
- Say Y here if you are building a kernel for a desktop, embedded
- or real-time system. Say N if you are unsure.
+ If you say N here, the kernel will run on single and multiprocessor
+ machines, but will use only one CPU of a multiprocessor machine. If
+ you say Y here, the kernel will run on many, but not all,
+ singleprocessor machines. On a singleprocessor machine, the kernel
+ will run faster if you say N here.
+
+ See also <file:Documentation/i386/IO-APIC.txt>,
+ <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at
+ <http://www.tldp.org/docs.html#howto>.
+
+ If you don't know what to do here, say N.
+
+config NR_CPUS
+ int
+ depends on SMP
+ default "2"
+
+config USE_GENERIC_SMP_HELPERS
+ bool
+ depends on SMP
+ default y
+
+source "kernel/Kconfig.preempt"
config MN10300_CURRENT_IN_E2
bool "Hold current task address in E2 register"
+ depends on !SMP
default y
help
This option removes the E2/R2 register from the set available to gcc
@@ -209,12 +257,15 @@ config MN10300_USING_JTAG
suppresses the use of certain hardware debugging features, such as
single-stepping, which are taken over completely by the JTAG unit.
+source "kernel/Kconfig.hz"
+source "kernel/time/Kconfig"
+
config MN10300_RTC
bool "Using MN10300 RTC"
- depends on MN10300_PROC_MN103E010
+ depends on MN10300_PROC_MN103E010 || MN10300_PROC_MN2WS0050
+ select GENERIC_CMOS_UPDATE
default n
help
-
This option enables support for the RTC, thus enabling time to be
tracked, even when system is powered down. This is available on-chip
on the MN103E010.
@@ -306,14 +357,23 @@ config MN10300_TTYSM1
choice
prompt "Select the timer to supply the clock for SIF1"
- default MN10300_TTYSM0_TIMER9
+ default MN10300_TTYSM1_TIMER12 \
+ if !(AM33_2 || AM33_3)
+ default MN10300_TTYSM1_TIMER9 \
+ if AM33_2 || AM33_3
depends on MN10300_TTYSM1
+config MN10300_TTYSM1_TIMER12
+ bool "Use timer 12 (16-bit)"
+ depends on !(AM33_2 || AM33_3)
+
config MN10300_TTYSM1_TIMER9
bool "Use timer 9 (16-bit)"
+ depends on AM33_2 || AM33_3
config MN10300_TTYSM1_TIMER3
bool "Use timer 3 (8-bit)"
+ depends on AM33_2 || AM33_3
endchoice
@@ -328,17 +388,107 @@ config MN10300_TTYSM2
choice
prompt "Select the timer to supply the clock for SIF2"
- default MN10300_TTYSM0_TIMER10
+ default MN10300_TTYSM2_TIMER3 \
+ if !(AM33_2 || AM33_3)
+ default MN10300_TTYSM2_TIMER10 \
+ if AM33_2 || AM33_3
depends on MN10300_TTYSM2
+config MN10300_TTYSM2_TIMER9
+ bool "Use timer 9 (16-bit)"
+ depends on !(AM33_2 || AM33_3)
+
+config MN10300_TTYSM2_TIMER1
+ bool "Use timer 1 (8-bit)"
+ depends on !(AM33_2 || AM33_3)
+
+config MN10300_TTYSM2_TIMER3
+ bool "Use timer 3 (8-bit)"
+ depends on !(AM33_2 || AM33_3)
+
config MN10300_TTYSM2_TIMER10
bool "Use timer 10 (16-bit)"
+ depends on AM33_2 || AM33_3
endchoice
config MN10300_TTYSM2_CTS
bool "Enable the use of the CTS line /dev/ttySM2"
- depends on MN10300_TTYSM2
+ depends on MN10300_TTYSM2 && AM33_2
+
+endmenu
+
+menu "Interrupt request priority options"
+
+comment "[!] NOTE: A lower number/level indicates a higher priority (0 is highest, 6 is lowest)"
+
+comment "____Non-maskable interrupt levels____"
+comment "The following must be set to a higher priority than local_irq_disable() and on-chip serial"
+
+config GDBSTUB_IRQ_LEVEL
+ int "GDBSTUB interrupt priority"
+ depends on GDBSTUB
+ range 0 1 if LINUX_CLI_LEVEL = 2
+ range 0 2 if LINUX_CLI_LEVEL = 3
+ range 0 3 if LINUX_CLI_LEVEL = 4
+ range 0 4 if LINUX_CLI_LEVEL = 5
+ range 0 5 if LINUX_CLI_LEVEL = 6
+ default 0
+
+comment "The following must be set to a higher priority than local_irq_disable()"
+
+config MN10300_SERIAL_IRQ_LEVEL
+ int "MN10300 on-chip serial interrupt priority"
+ depends on MN10300_TTYSM
+ range 1 1 if LINUX_CLI_LEVEL = 2
+ range 1 2 if LINUX_CLI_LEVEL = 3
+ range 1 3 if LINUX_CLI_LEVEL = 4
+ range 1 4 if LINUX_CLI_LEVEL = 5
+ range 1 5 if LINUX_CLI_LEVEL = 6
+ default 1
+
+comment "-"
+comment "____Maskable interrupt levels____"
+
+config LINUX_CLI_LEVEL
+ int "The highest interrupt priority excluded by local_irq_disable() (2-6)"
+ range 2 6
+ default 2
+ help
+ local_irq_disable() doesn't actually disable maskable interrupts -
+ what it does is restrict the levels of interrupt which are permitted
+ (a lower level indicates a higher priority) by lowering the value in
+ EPSW.IM from 7. Any interrupt is permitted for which the level is
+ lower than EPSW.IM.
+
+ Certain interrupts, such as GDBSTUB and virtual MN10300 on-chip
+ serial DMA interrupts are allowed to interrupt normal disabled
+ sections.
+
+comment "The following must be set to a equal to or lower priority than LINUX_CLI_LEVEL"
+
+config TIMER_IRQ_LEVEL
+ int "Kernel timer interrupt priority"
+ range LINUX_CLI_LEVEL 6
+ default 4
+
+config PCI_IRQ_LEVEL
+ int "PCI interrupt priority"
+ depends on PCI
+ range LINUX_CLI_LEVEL 6
+ default 5
+
+config ETHERNET_IRQ_LEVEL
+ int "Ethernet interrupt priority"
+ depends on SMC91X || SMC911X || SMSC911X
+ range LINUX_CLI_LEVEL 6
+ default 6
+
+config EXT_SERIAL_IRQ_LEVEL
+ int "External serial port interrupt priority"
+ depends on SERIAL_8250
+ range LINUX_CLI_LEVEL 6
+ default 6
endmenu
diff --git a/arch/mn10300/Makefile b/arch/mn10300/Makefile
index ac5c6bdb2f05..7120282bf0d8 100644
--- a/arch/mn10300/Makefile
+++ b/arch/mn10300/Makefile
@@ -36,6 +36,9 @@ endif
ifeq ($(CONFIG_MN10300_PROC_MN103E010),y)
PROCESSOR := mn103e010
endif
+ifeq ($(CONFIG_MN10300_PROC_MN2WS0050),y)
+PROCESSOR := mn2ws0050
+endif
ifeq ($(CONFIG_MN10300_UNIT_ASB2303),y)
UNIT := asb2303
@@ -43,6 +46,9 @@ endif
ifeq ($(CONFIG_MN10300_UNIT_ASB2305),y)
UNIT := asb2305
endif
+ifeq ($(CONFIG_MN10300_UNIT_ASB2364),y)
+UNIT := asb2364
+endif
head-y := arch/mn10300/kernel/head.o arch/mn10300/kernel/init_task.o
diff --git a/arch/mn10300/boot/compressed/head.S b/arch/mn10300/boot/compressed/head.S
index 502e1eb56709..7b50345b9e84 100644
--- a/arch/mn10300/boot/compressed/head.S
+++ b/arch/mn10300/boot/compressed/head.S
@@ -14,10 +14,29 @@
#include <linux/linkage.h>
#include <asm/cpu-regs.h>
+#include <asm/cache.h>
+#ifdef CONFIG_SMP
+#include <proc/smp-regs.h>
+#endif
.globl startup_32
startup_32:
- # first save off parameters from bootloader
+#ifdef CONFIG_SMP
+ #
+ # Secondary CPUs jump directly to the kernel entry point
+ #
+ # Must save primary CPU's D0-D2 registers as they hold boot parameters
+ #
+ mov (CPUID), d3
+ and CPUID_MASK,d3
+ beq startup_primary
+ mov CONFIG_KERNEL_TEXT_ADDRESS,a0
+ jmp (a0)
+
+startup_primary:
+#endif /* CONFIG_SMP */
+
+ # first save parameters from bootloader
mov param_save_area,a0
mov d0,(a0)
mov d1,(4,a0)
@@ -37,8 +56,15 @@ startup_32:
mov (a0),d0
btst CHCTR_ICBUSY|CHCTR_DCBUSY,d0 # wait till not busy
lne
- mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD,d0 # writethru dcache
+
+#ifdef CONFIG_MN10300_CACHE_ENABLED
+#ifdef CONFIG_MN10300_CACHE_WBACK
+ mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK,d0
+#else
+ mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRTHROUGH,d0
+#endif /* WBACK */
movhu d0,(a0) # enable
+#endif /* !ENABLED */
# clear the BSS area
mov __bss_start,a0
@@ -54,6 +80,9 @@ bssclear_end:
# decompress the kernel
call decompress_kernel[],0
+#ifdef CONFIG_MN10300_CACHE_WBACK
+ call mn10300_dcache_flush_inv[],0
+#endif
# disable caches again
mov CHCTR,a0
@@ -69,10 +98,46 @@ bssclear_end:
mov (4,a0),d1
mov (8,a0),d2
+ # jump to the kernel proper entry point
mov a3,sp
mov CONFIG_KERNEL_TEXT_ADDRESS,a0
jmp (a0)
+
+###############################################################################
+#
+# Cache flush routines
+#
+###############################################################################
+#ifdef CONFIG_MN10300_CACHE_WBACK
+mn10300_dcache_flush_inv:
+ movhu (CHCTR),d0
+ btst CHCTR_DCEN,d0
+ beq mn10300_dcache_flush_inv_end
+
+ mov L1_CACHE_NENTRIES,d1
+ clr a1
+
+mn10300_dcache_flush_inv_loop:
+ mov (DCACHE_PURGE_WAY0(0),a1),d0 # unconditional purge
+ mov (DCACHE_PURGE_WAY1(0),a1),d0 # unconditional purge
+ mov (DCACHE_PURGE_WAY2(0),a1),d0 # unconditional purge
+ mov (DCACHE_PURGE_WAY3(0),a1),d0 # unconditional purge
+
+ add L1_CACHE_BYTES,a1
+ add -1,d1
+ bne mn10300_dcache_flush_inv_loop
+
+mn10300_dcache_flush_inv_end:
+ ret [],0
+#endif /* CONFIG_MN10300_CACHE_WBACK */
+
+
+###############################################################################
+#
+# Data areas
+#
+###############################################################################
.data
.align 4
param_save_area:
diff --git a/arch/mn10300/configs/asb2303_defconfig b/arch/mn10300/configs/asb2303_defconfig
index d80dfcb2c902..3f749b69ca71 100644
--- a/arch/mn10300/configs/asb2303_defconfig
+++ b/arch/mn10300/configs/asb2303_defconfig
@@ -12,6 +12,8 @@ CONFIG_SLAB=y
CONFIG_PROFILING=y
# CONFIG_BLOCK is not set
CONFIG_PREEMPT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
CONFIG_MN10300_RTC=y
CONFIG_MN10300_TTYSM_CONSOLE=y
CONFIG_MN10300_TTYSM0=y
diff --git a/arch/mn10300/configs/asb2364_defconfig b/arch/mn10300/configs/asb2364_defconfig
new file mode 100644
index 000000000000..83ce2f27b12a
--- /dev/null
+++ b/arch/mn10300/configs/asb2364_defconfig
@@ -0,0 +1,98 @@
+CONFIG_EXPERIMENTAL=y
+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_CGROUPS=y
+CONFIG_CGROUP_NS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_RELAY=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EMBEDDED=y
+# CONFIG_KALLSYMS is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_SLAB=y
+CONFIG_PROFILING=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLOCK is not set
+CONFIG_MN10300_UNIT_ASB2364=y
+CONFIG_PREEMPT=y
+# CONFIG_MN10300_USING_JTAG is not set
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_MN10300_TTYSM_CONSOLE=y
+CONFIG_MN10300_TTYSM0=y
+CONFIG_MN10300_TTYSM0_TIMER2=y
+CONFIG_MN10300_TTYSM1=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=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=y
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_CONNECTOR=y
+CONFIG_MTD=y
+CONFIG_MTD_DEBUG=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_CFI_I4=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMSC911X=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# 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 is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_PROC_KCORE=y
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_STRIP_ASM_SYMS=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
diff --git a/arch/mn10300/include/asm/atomic.h b/arch/mn10300/include/asm/atomic.h
index f0cc1f84a72f..92d2f9298e38 100644
--- a/arch/mn10300/include/asm/atomic.h
+++ b/arch/mn10300/include/asm/atomic.h
@@ -1 +1,351 @@
+/* MN10300 Atomic counter operations
+ *
+ * Copyright (C) 2007 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_ATOMIC_H
+#define _ASM_ATOMIC_H
+
+#include <asm/irqflags.h>
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_SMP
+#ifdef CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT
+static inline
+unsigned long __xchg(volatile unsigned long *m, unsigned long val)
+{
+ unsigned long status;
+ unsigned long oldval;
+
+ asm volatile(
+ "1: mov %4,(_AAR,%3) \n"
+ " mov (_ADR,%3),%1 \n"
+ " mov %5,(_ADR,%3) \n"
+ " mov (_ADR,%3),%0 \n" /* flush */
+ " mov (_ASR,%3),%0 \n"
+ " or %0,%0 \n"
+ " bne 1b \n"
+ : "=&r"(status), "=&r"(oldval), "=m"(*m)
+ : "a"(ATOMIC_OPS_BASE_ADDR), "r"(m), "r"(val)
+ : "memory", "cc");
+
+ return oldval;
+}
+
+static inline unsigned long __cmpxchg(volatile unsigned long *m,
+ unsigned long old, unsigned long new)
+{
+ unsigned long status;
+ unsigned long oldval;
+
+ asm volatile(
+ "1: mov %4,(_AAR,%3) \n"
+ " mov (_ADR,%3),%1 \n"
+ " cmp %5,%1 \n"
+ " bne 2f \n"
+ " mov %6,(_ADR,%3) \n"
+ "2: mov (_ADR,%3),%0 \n" /* flush */
+ " mov (_ASR,%3),%0 \n"
+ " or %0,%0 \n"
+ " bne 1b \n"
+ : "=&r"(status), "=&r"(oldval), "=m"(*m)
+ : "a"(ATOMIC_OPS_BASE_ADDR), "r"(m),
+ "r"(old), "r"(new)
+ : "memory", "cc");
+
+ return oldval;
+}
+#else /* CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT */
+#error "No SMP atomic operation support!"
+#endif /* CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT */
+
+#else /* CONFIG_SMP */
+
+/*
+ * Emulate xchg for non-SMP MN10300
+ */
+struct __xchg_dummy { unsigned long a[100]; };
+#define __xg(x) ((struct __xchg_dummy *)(x))
+
+static inline
+unsigned long __xchg(volatile unsigned long *m, unsigned long val)
+{
+ unsigned long oldval;
+ unsigned long flags;
+
+ flags = arch_local_cli_save();
+ oldval = *m;
+ *m = val;
+ arch_local_irq_restore(flags);
+ return oldval;
+}
+
+/*
+ * Emulate cmpxchg for non-SMP MN10300
+ */
+static inline unsigned long __cmpxchg(volatile unsigned long *m,
+ unsigned long old, unsigned long new)
+{
+ unsigned long oldval;
+ unsigned long flags;
+
+ flags = arch_local_cli_save();
+ oldval = *m;
+ if (oldval == old)
+ *m = new;
+ arch_local_irq_restore(flags);
+ return oldval;
+}
+
+#endif /* CONFIG_SMP */
+
+#define xchg(ptr, v) \
+ ((__typeof__(*(ptr))) __xchg((unsigned long *)(ptr), \
+ (unsigned long)(v)))
+
+#define cmpxchg(ptr, o, n) \
+ ((__typeof__(*(ptr))) __cmpxchg((unsigned long *)(ptr), \
+ (unsigned long)(o), \
+ (unsigned long)(n)))
+
+#define atomic_xchg(ptr, v) (xchg(&(ptr)->counter, (v)))
+#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), (old), (new)))
+
+#endif /* !__ASSEMBLY__ */
+
+#ifndef CONFIG_SMP
#include <asm-generic/atomic.h>
+#else
+
+/*
+ * Atomic operations that C can't guarantee us. Useful for
+ * resource counting etc..
+ */
+
+#define ATOMIC_INIT(i) { (i) }
+
+#ifdef __KERNEL__
+
+/**
+ * atomic_read - read atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically reads the value of @v. Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+#define atomic_read(v) ((v)->counter)
+
+/**
+ * atomic_set - set atomic variable
+ * @v: pointer of type atomic_t
+ * @i: required value
+ *
+ * Atomically sets the value of @v to @i. Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+#define atomic_set(v, i) (((v)->counter) = (i))
+
+/**
+ * atomic_add_return - add integer to atomic variable
+ * @i: integer value to add
+ * @v: pointer of type atomic_t
+ *
+ * Atomically adds @i to @v and returns the result
+ * Note that the guaranteed useful range of an atomic_t is only 24 bits.
+ */
+static inline int atomic_add_return(int i, atomic_t *v)
+{
+ int retval;
+#ifdef CONFIG_SMP
+ int status;
+
+ asm volatile(
+ "1: mov %4,(_AAR,%3) \n"
+ " mov (_ADR,%3),%1 \n"
+ " add %5,%1 \n"
+ " mov %1,(_ADR,%3) \n"
+ " mov (_ADR,%3),%0 \n" /* flush */
+ " mov (_ASR,%3),%0 \n"
+ " or %0,%0 \n"
+ " bne 1b \n"
+ : "=&r"(status), "=&r"(retval), "=m"(v->counter)
+ : "a"(ATOMIC_OPS_BASE_ADDR), "r"(&v->counter), "r"(i)
+ : "memory", "cc");
+
+#else
+ unsigned long flags;
+
+ flags = arch_local_cli_save();
+ retval = v->counter;
+ retval += i;
+ v->counter = retval;
+ arch_local_irq_restore(flags);
+#endif
+ return retval;
+}
+
+/**
+ * atomic_sub_return - subtract integer from atomic variable
+ * @i: integer value to subtract
+ * @v: pointer of type atomic_t
+ *
+ * Atomically subtracts @i from @v and returns the result
+ * Note that the guaranteed useful range of an atomic_t is only 24 bits.
+ */
+static inline int atomic_sub_return(int i, atomic_t *v)
+{
+ int retval;
+#ifdef CONFIG_SMP
+ int status;
+
+ asm volatile(
+ "1: mov %4,(_AAR,%3) \n"
+ " mov (_ADR,%3),%1 \n"
+ " sub %5,%1 \n"
+ " mov %1,(_ADR,%3) \n"
+ " mov (_ADR,%3),%0 \n" /* flush */
+ " mov (_ASR,%3),%0 \n"
+ " or %0,%0 \n"
+ " bne 1b \n"
+ : "=&r"(status), "=&r"(retval), "=m"(v->counter)
+ : "a"(ATOMIC_OPS_BASE_ADDR), "r"(&v->counter), "r"(i)
+ : "memory", "cc");
+
+#else
+ unsigned long flags;
+ flags = arch_local_cli_save();
+ retval = v->counter;
+ retval -= i;
+ v->counter = retval;
+ arch_local_irq_restore(flags);
+#endif
+ return retval;
+}
+
+static inline int atomic_add_negative(int i, atomic_t *v)
+{
+ return atomic_add_return(i, v) < 0;
+}
+
+static inline void atomic_add(int i, atomic_t *v)
+{
+ atomic_add_return(i, v);
+}
+
+static inline void atomic_sub(int i, atomic_t *v)
+{
+ atomic_sub_return(i, v);
+}
+
+static inline void atomic_inc(atomic_t *v)
+{
+ atomic_add_return(1, v);
+}
+
+static inline void atomic_dec(atomic_t *v)
+{
+ atomic_sub_return(1, v);
+}
+
+#define atomic_dec_return(v) atomic_sub_return(1, (v))
+#define atomic_inc_return(v) atomic_add_return(1, (v))
+
+#define atomic_sub_and_test(i, v) (atomic_sub_return((i), (v)) == 0)
+#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
+#define atomic_inc_and_test(v) (atomic_add_return(1, (v)) == 0)
+
+#define atomic_add_unless(v, a, u) \
+({ \
+ int c, old; \
+ c = atomic_read(v); \
+ while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
+ c = old; \
+ c != (u); \
+})
+
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
+/**
+ * atomic_clear_mask - Atomically clear bits in memory
+ * @mask: Mask of the bits to be cleared
+ * @v: pointer to word in memory
+ *
+ * Atomically clears the bits set in mask from the memory word specified.
+ */
+static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
+{
+#ifdef CONFIG_SMP
+ int status;
+
+ asm volatile(
+ "1: mov %3,(_AAR,%2) \n"
+ " mov (_ADR,%2),%0 \n"
+ " and %4,%0 \n"
+ " mov %0,(_ADR,%2) \n"
+ " mov (_ADR,%2),%0 \n" /* flush */
+ " mov (_ASR,%2),%0 \n"
+ " or %0,%0 \n"
+ " bne 1b \n"
+ : "=&r"(status), "=m"(*addr)
+ : "a"(ATOMIC_OPS_BASE_ADDR), "r"(addr), "r"(~mask)
+ : "memory", "cc");
+#else
+ unsigned long flags;
+
+ mask = ~mask;
+ flags = arch_local_cli_save();
+ *addr &= mask;
+ arch_local_irq_restore(flags);
+#endif
+}
+
+/**
+ * atomic_set_mask - Atomically set bits in memory
+ * @mask: Mask of the bits to be set
+ * @v: pointer to word in memory
+ *
+ * Atomically sets the bits set in mask from the memory word specified.
+ */
+static inline void atomic_set_mask(unsigned long mask, unsigned long *addr)
+{
+#ifdef CONFIG_SMP
+ int status;
+
+ asm volatile(
+ "1: mov %3,(_AAR,%2) \n"
+ " mov (_ADR,%2),%0 \n"
+ " or %4,%0 \n"
+ " mov %0,(_ADR,%2) \n"
+ " mov (_ADR,%2),%0 \n" /* flush */
+ " mov (_ASR,%2),%0 \n"
+ " or %0,%0 \n"
+ " bne 1b \n"
+ : "=&r"(status), "=m"(*addr)
+ : "a"(ATOMIC_OPS_BASE_ADDR), "r"(addr), "r"(mask)
+ : "memory", "cc");
+#else
+ unsigned long flags;
+
+ flags = arch_local_cli_save();
+ *addr |= mask;
+ arch_local_irq_restore(flags);
+#endif
+}
+
+/* Atomic operations are already serializing on MN10300??? */
+#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 /* __KERNEL__ */
+#endif /* CONFIG_SMP */
+#endif /* _ASM_ATOMIC_H */
diff --git a/arch/mn10300/include/asm/bitops.h b/arch/mn10300/include/asm/bitops.h
index 3f50e9661076..3b8a868188f5 100644
--- a/arch/mn10300/include/asm/bitops.h
+++ b/arch/mn10300/include/asm/bitops.h
@@ -57,7 +57,7 @@
#define clear_bit(nr, addr) ___clear_bit((nr), (addr))
-static inline void __clear_bit(int nr, volatile void *addr)
+static inline void __clear_bit(unsigned long nr, volatile void *addr)
{
unsigned int *a = (unsigned int *) addr;
int mask;
@@ -70,15 +70,15 @@ static inline void __clear_bit(int nr, volatile void *addr)
/*
* test bit
*/
-static inline int test_bit(int nr, const volatile void *addr)
+static inline int test_bit(unsigned long nr, const volatile void *addr)
{
- return 1UL & (((const unsigned int *) addr)[nr >> 5] >> (nr & 31));
+ return 1UL & (((const volatile unsigned int *) addr)[nr >> 5] >> (nr & 31));
}
/*
* change bit
*/
-static inline void __change_bit(int nr, volatile void *addr)
+static inline void __change_bit(unsigned long nr, volatile void *addr)
{
int mask;
unsigned int *a = (unsigned int *) addr;
@@ -88,7 +88,7 @@ static inline void __change_bit(int nr, volatile void *addr)
*a ^= mask;
}
-extern void change_bit(int nr, volatile void *addr);
+extern void change_bit(unsigned long nr, volatile void *addr);
/*
* test and set bit
@@ -135,7 +135,7 @@ extern void change_bit(int nr, volatile void *addr);
/*
* test and change bit
*/
-static inline int __test_and_change_bit(int nr, volatile void *addr)
+static inline int __test_and_change_bit(unsigned long nr, volatile void *addr)
{
int mask, retval;
unsigned int *a = (unsigned int *)addr;
@@ -148,7 +148,7 @@ static inline int __test_and_change_bit(int nr, volatile void *addr)
return retval;
}
-extern int test_and_change_bit(int nr, volatile void *addr);
+extern int test_and_change_bit(unsigned long nr, volatile void *addr);
#include <asm-generic/bitops/lock.h>
diff --git a/arch/mn10300/include/asm/cache.h b/arch/mn10300/include/asm/cache.h
index 781bf613366d..f29cde2cfc91 100644
--- a/arch/mn10300/include/asm/cache.h
+++ b/arch/mn10300/include/asm/cache.h
@@ -43,14 +43,18 @@
/* instruction cache access registers */
#define ICACHE_DATA(WAY, ENTRY, OFF) \
- __SYSREG(0xc8000000 + (WAY) * L1_CACHE_WAYDISP + (ENTRY) * 0x10 + (OFF) * 4, u32)
+ __SYSREG(0xc8000000 + (WAY) * L1_CACHE_WAYDISP + \
+ (ENTRY) * L1_CACHE_BYTES + (OFF) * 4, u32)
#define ICACHE_TAG(WAY, ENTRY) \
- __SYSREG(0xc8100000 + (WAY) * L1_CACHE_WAYDISP + (ENTRY) * 0x10, u32)
+ __SYSREG(0xc8100000 + (WAY) * L1_CACHE_WAYDISP + \
+ (ENTRY) * L1_CACHE_BYTES, u32)
-/* instruction cache access registers */
+/* data cache access registers */
#define DCACHE_DATA(WAY, ENTRY, OFF) \
- __SYSREG(0xc8200000 + (WAY) * L1_CACHE_WAYDISP + (ENTRY) * 0x10 + (OFF) * 4, u32)
+ __SYSREG(0xc8200000 + (WAY) * L1_CACHE_WAYDISP + \
+ (ENTRY) * L1_CACHE_BYTES + (OFF) * 4, u32)
#define DCACHE_TAG(WAY, ENTRY) \
- __SYSREG(0xc8300000 + (WAY) * L1_CACHE_WAYDISP + (ENTRY) * 0x10, u32)
+ __SYSREG(0xc8300000 + (WAY) * L1_CACHE_WAYDISP + \
+ (ENTRY) * L1_CACHE_BYTES, u32)
#endif /* _ASM_CACHE_H */
diff --git a/arch/mn10300/include/asm/cacheflush.h b/arch/mn10300/include/asm/cacheflush.h
index 29e692f7f030..faed90240ded 100644
--- a/arch/mn10300/include/asm/cacheflush.h
+++ b/arch/mn10300/include/asm/cacheflush.h
@@ -17,66 +17,55 @@
#include <linux/mm.h>
/*
- * virtually-indexed cache management (our cache is physically indexed)
+ * Primitive routines
*/
-#define flush_cache_all() do {} while (0)
-#define flush_cache_mm(mm) do {} while (0)
-#define flush_cache_dup_mm(mm) do {} while (0)
-#define flush_cache_range(mm, start, end) do {} while (0)
-#define flush_cache_page(vma, vmaddr, pfn) do {} while (0)
-#define flush_cache_vmap(start, end) do {} while (0)
-#define flush_cache_vunmap(start, end) do {} while (0)
-#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
-#define flush_dcache_page(page) do {} while (0)
-#define flush_dcache_mmap_lock(mapping) do {} while (0)
-#define flush_dcache_mmap_unlock(mapping) do {} while (0)
-
-/*
- * physically-indexed cache management
- */
-#ifndef CONFIG_MN10300_CACHE_DISABLED
-
-extern void flush_icache_range(unsigned long start, unsigned long end);
-extern void flush_icache_page(struct vm_area_struct *vma, struct page *pg);
-
-#else
-
-#define flush_icache_range(start, end) do {} while (0)
-#define flush_icache_page(vma, pg) do {} while (0)
-
-#endif
-
-#define flush_icache_user_range(vma, pg, adr, len) \
- flush_icache_range(adr, adr + len)
-
-#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
- do { \
- memcpy(dst, src, len); \
- flush_icache_page(vma, page); \
- } while (0)
-
-#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
- memcpy(dst, src, len)
-
-/*
- * primitive routines
- */
-#ifndef CONFIG_MN10300_CACHE_DISABLED
+#ifdef CONFIG_MN10300_CACHE_ENABLED
+extern void mn10300_local_icache_inv(void);
+extern void mn10300_local_icache_inv_page(unsigned long start);
+extern void mn10300_local_icache_inv_range(unsigned long start, unsigned long end);
+extern void mn10300_local_icache_inv_range2(unsigned long start, unsigned long size);
+extern void mn10300_local_dcache_inv(void);
+extern void mn10300_local_dcache_inv_page(unsigned long start);
+extern void mn10300_local_dcache_inv_range(unsigned long start, unsigned long end);
+extern void mn10300_local_dcache_inv_range2(unsigned long start, unsigned long size);
extern void mn10300_icache_inv(void);
+extern void mn10300_icache_inv_page(unsigned long start);
+extern void mn10300_icache_inv_range(unsigned long start, unsigned long end);
+extern void mn10300_icache_inv_range2(unsigned long start, unsigned long size);
extern void mn10300_dcache_inv(void);
-extern void mn10300_dcache_inv_page(unsigned start);
-extern void mn10300_dcache_inv_range(unsigned start, unsigned end);
-extern void mn10300_dcache_inv_range2(unsigned start, unsigned size);
+extern void mn10300_dcache_inv_page(unsigned long start);
+extern void mn10300_dcache_inv_range(unsigned long start, unsigned long end);
+extern void mn10300_dcache_inv_range2(unsigned long start, unsigned long size);
#ifdef CONFIG_MN10300_CACHE_WBACK
+extern void mn10300_local_dcache_flush(void);
+extern void mn10300_local_dcache_flush_page(unsigned long start);
+extern void mn10300_local_dcache_flush_range(unsigned long start, unsigned long end);
+extern void mn10300_local_dcache_flush_range2(unsigned long start, unsigned long size);
+extern void mn10300_local_dcache_flush_inv(void);
+extern void mn10300_local_dcache_flush_inv_page(unsigned long start);
+extern void mn10300_local_dcache_flush_inv_range(unsigned long start, unsigned long end);
+extern void mn10300_local_dcache_flush_inv_range2(unsigned long start, unsigned long size);
extern void mn10300_dcache_flush(void);
-extern void mn10300_dcache_flush_page(unsigned start);
-extern void mn10300_dcache_flush_range(unsigned start, unsigned end);
-extern void mn10300_dcache_flush_range2(unsigned start, unsigned size);
+extern void mn10300_dcache_flush_page(unsigned long start);
+extern void mn10300_dcache_flush_range(unsigned long start, unsigned long end);
+extern void mn10300_dcache_flush_range2(unsigned long start, unsigned long size);
extern void mn10300_dcache_flush_inv(void);
-extern void mn10300_dcache_flush_inv_page(unsigned start);
-extern void mn10300_dcache_flush_inv_range(unsigned start, unsigned end);
-extern void mn10300_dcache_flush_inv_range2(unsigned start, unsigned size);
+extern void mn10300_dcache_flush_inv_page(unsigned long start);
+extern void mn10300_dcache_flush_inv_range(unsigned long start, unsigned long end);
+extern void mn10300_dcache_flush_inv_range2(unsigned long start, unsigned long size);
#else
+#define mn10300_local_dcache_flush() do {} while (0)
+#define mn10300_local_dcache_flush_page(start) do {} while (0)
+#define mn10300_local_dcache_flush_range(start, end) do {} while (0)
+#define mn10300_local_dcache_flush_range2(start, size) do {} while (0)
+#define mn10300_local_dcache_flush_inv() \
+ mn10300_local_dcache_inv()
+#define mn10300_local_dcache_flush_inv_page(start) \
+ mn10300_local_dcache_inv_page(start)
+#define mn10300_local_dcache_flush_inv_range(start, end) \
+ mn10300_local_dcache_inv_range(start, end)
+#define mn10300_local_dcache_flush_inv_range2(start, size) \
+ mn10300_local_dcache_inv_range2(start, size)
#define mn10300_dcache_flush() do {} while (0)
#define mn10300_dcache_flush_page(start) do {} while (0)
#define mn10300_dcache_flush_range(start, end) do {} while (0)
@@ -90,7 +79,26 @@ extern void mn10300_dcache_flush_inv_range2(unsigned start, unsigned size);
mn10300_dcache_inv_range2((start), (size))
#endif /* CONFIG_MN10300_CACHE_WBACK */
#else
+#define mn10300_local_icache_inv() do {} while (0)
+#define mn10300_local_icache_inv_page(start) do {} while (0)
+#define mn10300_local_icache_inv_range(start, end) do {} while (0)
+#define mn10300_local_icache_inv_range2(start, size) do {} while (0)
+#define mn10300_local_dcache_inv() do {} while (0)
+#define mn10300_local_dcache_inv_page(start) do {} while (0)
+#define mn10300_local_dcache_inv_range(start, end) do {} while (0)
+#define mn10300_local_dcache_inv_range2(start, size) do {} while (0)
+#define mn10300_local_dcache_flush() do {} while (0)
+#define mn10300_local_dcache_flush_inv_page(start) do {} while (0)
+#define mn10300_local_dcache_flush_inv() do {} while (0)
+#define mn10300_local_dcache_flush_inv_range(start, end)do {} while (0)
+#define mn10300_local_dcache_flush_inv_range2(start, size) do {} while (0)
+#define mn10300_local_dcache_flush_page(start) do {} while (0)
+#define mn10300_local_dcache_flush_range(start, end) do {} while (0)
+#define mn10300_local_dcache_flush_range2(start, size) do {} while (0)
#define mn10300_icache_inv() do {} while (0)
+#define mn10300_icache_inv_page(start) do {} while (0)
+#define mn10300_icache_inv_range(start, end) do {} while (0)
+#define mn10300_icache_inv_range2(start, size) do {} while (0)
#define mn10300_dcache_inv() do {} while (0)
#define mn10300_dcache_inv_page(start) do {} while (0)
#define mn10300_dcache_inv_range(start, end) do {} while (0)
@@ -103,10 +111,56 @@ extern void mn10300_dcache_flush_inv_range2(unsigned start, unsigned size);
#define mn10300_dcache_flush_page(start) do {} while (0)
#define mn10300_dcache_flush_range(start, end) do {} while (0)
#define mn10300_dcache_flush_range2(start, size) do {} while (0)
-#endif /* CONFIG_MN10300_CACHE_DISABLED */
+#endif /* CONFIG_MN10300_CACHE_ENABLED */
+
+/*
+ * Virtually-indexed cache management (our cache is physically indexed)
+ */
+#define flush_cache_all() do {} while (0)
+#define flush_cache_mm(mm) do {} while (0)
+#define flush_cache_dup_mm(mm) do {} while (0)
+#define flush_cache_range(mm, start, end) do {} while (0)
+#define flush_cache_page(vma, vmaddr, pfn) do {} while (0)
+#define flush_cache_vmap(start, end) do {} while (0)
+#define flush_cache_vunmap(start, end) do {} while (0)
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
+#define flush_dcache_page(page) do {} while (0)
+#define flush_dcache_mmap_lock(mapping) do {} while (0)
+#define flush_dcache_mmap_unlock(mapping) do {} while (0)
+
+/*
+ * Physically-indexed cache management
+ */
+#if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE)
+extern void flush_icache_page(struct vm_area_struct *vma, struct page *page);
+extern void flush_icache_range(unsigned long start, unsigned long end);
+#elif defined(CONFIG_MN10300_CACHE_INV_ICACHE)
+static inline void flush_icache_page(struct vm_area_struct *vma,
+ struct page *page)
+{
+ mn10300_icache_inv_page(page_to_phys(page));
+}
+extern void flush_icache_range(unsigned long start, unsigned long end);
+#else
+#define flush_icache_range(start, end) do {} while (0)
+#define flush_icache_page(vma, pg) do {} while (0)
+#endif
+
+
+#define flush_icache_user_range(vma, pg, adr, len) \
+ flush_icache_range(adr, adr + len)
+
+#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
+ do { \
+ memcpy(dst, src, len); \
+ flush_icache_page(vma, page); \
+ } while (0)
+
+#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
+ memcpy(dst, src, len)
/*
- * internal debugging function
+ * Internal debugging function
*/
#ifdef CONFIG_DEBUG_PAGEALLOC
extern void kernel_map_pages(struct page *page, int numpages, int enable);
diff --git a/arch/mn10300/include/asm/cpu-regs.h b/arch/mn10300/include/asm/cpu-regs.h
index 757e9b5388ea..90ed4a365c97 100644
--- a/arch/mn10300/include/asm/cpu-regs.h
+++ b/arch/mn10300/include/asm/cpu-regs.h
@@ -15,7 +15,6 @@
#include <linux/types.h>
#endif
-#ifdef CONFIG_MN10300_CPU_AM33V2
/* we tell the compiler to pretend to be AM33 so that it doesn't try and use
* the FP regs, but tell the assembler that we're actually allowed AM33v2
* instructions */
@@ -24,7 +23,6 @@ asm(" .am33_2\n");
#else
.am33_2
#endif
-#endif
#ifdef __KERNEL__
@@ -58,6 +56,9 @@ asm(" .am33_2\n");
#define EPSW_nAR 0x00040000 /* register bank control */
#define EPSW_ML 0x00080000 /* monitor level */
#define EPSW_FE 0x00100000 /* FPU enable */
+#define EPSW_IM_SHIFT 8 /* EPSW_IM_SHIFT determines the interrupt mode */
+
+#define NUM2EPSW_IM(num) ((num) << EPSW_IM_SHIFT)
/* FPU registers */
#define FPCR_EF_I 0x00000001 /* inexact result FPU exception flag */
@@ -99,9 +100,11 @@ asm(" .am33_2\n");
#define CPUREV __SYSREGC(0xc0000050, u32) /* CPU revision register */
#define CPUREV_TYPE 0x0000000f /* CPU type */
#define CPUREV_TYPE_S 0
-#define CPUREV_TYPE_AM33V1 0x00000000 /* - AM33 V1 core, AM33/1.00 arch */
-#define CPUREV_TYPE_AM33V2 0x00000001 /* - AM33 V2 core, AM33/2.00 arch */
-#define CPUREV_TYPE_AM34V1 0x00000002 /* - AM34 V1 core, AM33/2.00 arch */
+#define CPUREV_TYPE_AM33_1 0x00000000 /* - AM33-1 core, AM33/1.00 arch */
+#define CPUREV_TYPE_AM33_2 0x00000001 /* - AM33-2 core, AM33/2.00 arch */
+#define CPUREV_TYPE_AM34_1 0x00000002 /* - AM34-1 core, AM33/2.00 arch */
+#define CPUREV_TYPE_AM33_3 0x00000003 /* - AM33-3 core, AM33/2.00 arch */
+#define CPUREV_TYPE_AM34_2 0x00000004 /* - AM34-2 core, AM33/3.00 arch */
#define CPUREV_REVISION 0x000000f0 /* CPU revision */
#define CPUREV_REVISION_S 4
#define CPUREV_ICWAY 0x00000f00 /* number of instruction cache ways */
@@ -180,6 +183,21 @@ asm(" .am33_2\n");
#define CHCTR_ICWMD 0x0f00 /* instruction cache way mode */
#define CHCTR_DCWMD 0xf000 /* data cache way mode */
+#ifdef CONFIG_AM34_2
+#define ICIVCR __SYSREG(0xc0000c00, u32) /* icache area invalidate control */
+#define ICIVCR_ICIVBSY 0x00000008 /* icache area invalidate busy */
+#define ICIVCR_ICI 0x00000001 /* icache area invalidate */
+
+#define ICIVMR __SYSREG(0xc0000c04, u32) /* icache area invalidate mask */
+
+#define DCPGCR __SYSREG(0xc0000c10, u32) /* data cache area purge control */
+#define DCPGCR_DCPGBSY 0x00000008 /* data cache area purge busy */
+#define DCPGCR_DCP 0x00000002 /* data cache area purge */
+#define DCPGCR_DCI 0x00000001 /* data cache area invalidate */
+
+#define DCPGMR __SYSREG(0xc0000c14, u32) /* data cache area purge mask */
+#endif /* CONFIG_AM34_2 */
+
/* MMU control registers */
#define MMUCTR __SYSREG(0xc0000090, u32) /* MMU control register */
#define MMUCTR_IRP 0x0000003f /* instruction TLB replace pointer */
@@ -203,6 +221,9 @@ asm(" .am33_2\n");
#define MMUCTR_DTL_LOCK0_3 0x03000000 /* - entry 0-3 locked */
#define MMUCTR_DTL_LOCK0_7 0x04000000 /* - entry 0-7 locked */
#define MMUCTR_DTL_LOCK0_15 0x05000000 /* - entry 0-15 locked */
+#ifdef CONFIG_AM34_2
+#define MMUCTR_WTE 0x80000000 /* write-through cache TLB entry bit enable */
+#endif
#define PIDR __SYSREG(0xc0000094, u16) /* PID register */
#define PIDR_PID 0x00ff /* process identifier */
@@ -231,14 +252,6 @@ asm(" .am33_2\n");
#define xPTEL_PS_4Mb 0x00000c00 /* - 4Mb page */
#define xPTEL_PPN 0xfffff006 /* physical page number */
-#define xPTEL_V_BIT 0 /* bit numbers corresponding to above masks */
-#define xPTEL_UNUSED1_BIT 1
-#define xPTEL_UNUSED2_BIT 2
-#define xPTEL_C_BIT 3
-#define xPTEL_PV_BIT 4
-#define xPTEL_D_BIT 5
-#define xPTEL_G_BIT 9
-
#define IPTEU __SYSREG(0xc00000a4, u32) /* instruction TLB virtual addr */
#define DPTEU __SYSREG(0xc00000b4, u32) /* data TLB virtual addr */
#define xPTEU_VPN 0xfffffc00 /* virtual page number */
@@ -262,7 +275,16 @@ asm(" .am33_2\n");
#define xPTEL2_PS_128Kb 0x00000100 /* - 128Kb page */
#define xPTEL2_PS_1Kb 0x00000200 /* - 1Kb page */
#define xPTEL2_PS_4Mb 0x00000300 /* - 4Mb page */
-#define xPTEL2_PPN 0xfffffc00 /* physical page number */
+#define xPTEL2_CWT 0x00000400 /* cacheable write-through */
+#define xPTEL2_UNUSED1 0x00000800 /* unused bit (broadcast mask) */
+#define xPTEL2_PPN 0xfffff000 /* physical page number */
+
+#define xPTEL2_V_BIT 0 /* bit numbers corresponding to above masks */
+#define xPTEL2_C_BIT 1
+#define xPTEL2_PV_BIT 2
+#define xPTEL2_D_BIT 3
+#define xPTEL2_G_BIT 7
+#define xPTEL2_UNUSED1_BIT 11
#define MMUFCR __SYSREGC(0xc000009c, u32) /* MMU exception cause */
#define MMUFCR_IFC __SYSREGC(0xc000009c, u16) /* MMU instruction excep cause */
@@ -285,6 +307,47 @@ asm(" .am33_2\n");
#define MMUFCR_xFC_PR_RWK_RWU 0x01c0 /* - R/W kernel and R/W user */
#define MMUFCR_xFC_ILLADDR 0x0200 /* illegal address excep flag */
+#ifdef CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT
+/* atomic operation registers */
+#define AAR __SYSREG(0xc0000a00, u32) /* cacheable address */
+#define AAR2 __SYSREG(0xc0000a04, u32) /* uncacheable address */
+#define ADR __SYSREG(0xc0000a08, u32) /* data */
+#define ASR __SYSREG(0xc0000a0c, u32) /* status */
+#define AARU __SYSREG(0xd400aa00, u32) /* user address */
+#define ADRU __SYSREG(0xd400aa08, u32) /* user data */
+#define ASRU __SYSREG(0xd400aa0c, u32) /* user status */
+
+#define ASR_RW 0x00000008 /* read */
+#define ASR_BW 0x00000004 /* bus error */
+#define ASR_IW 0x00000002 /* interrupt */
+#define ASR_LW 0x00000001 /* bus lock */
+
+#define ASRU_RW ASR_RW /* read */
+#define ASRU_BW ASR_BW /* bus error */
+#define ASRU_IW ASR_IW /* interrupt */
+#define ASRU_LW ASR_LW /* bus lock */
+
+/* in inline ASM, we stick the base pointer in to a reg and use offsets from
+ * it */
+#define ATOMIC_OPS_BASE_ADDR 0xc0000a00
+#ifndef __ASSEMBLY__
+asm(
+ "_AAR = 0\n"
+ "_AAR2 = 4\n"
+ "_ADR = 8\n"
+ "_ASR = 12\n");
+#else
+#define _AAR 0
+#define _AAR2 4
+#define _ADR 8
+#define _ASR 12
+#endif
+
+/* physical page address for userspace atomic operations registers */
+#define USER_ATOMIC_OPS_PAGE_ADDR 0xd400a000
+
+#endif /* CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT */
+
#endif /* __KERNEL__ */
#endif /* _ASM_CPU_REGS_H */
diff --git a/arch/mn10300/include/asm/dmactl-regs.h b/arch/mn10300/include/asm/dmactl-regs.h
index 58a199da0f4a..80337b339c90 100644
--- a/arch/mn10300/include/asm/dmactl-regs.h
+++ b/arch/mn10300/include/asm/dmactl-regs.h
@@ -11,91 +11,6 @@
#ifndef _ASM_DMACTL_REGS_H
#define _ASM_DMACTL_REGS_H
-#include <asm/cpu-regs.h>
-
-#ifdef __KERNEL__
-
-/* DMA registers */
-#define DMxCTR(N) __SYSREG(0xd2000000 + ((N) * 0x100), u32) /* control reg */
-#define DMxCTR_BG 0x0000001f /* transfer request source */
-#define DMxCTR_BG_SOFT 0x00000000 /* - software source */
-#define DMxCTR_BG_SC0TX 0x00000002 /* - serial port 0 transmission */
-#define DMxCTR_BG_SC0RX 0x00000003 /* - serial port 0 reception */
-#define DMxCTR_BG_SC1TX 0x00000004 /* - serial port 1 transmission */
-#define DMxCTR_BG_SC1RX 0x00000005 /* - serial port 1 reception */
-#define DMxCTR_BG_SC2TX 0x00000006 /* - serial port 2 transmission */
-#define DMxCTR_BG_SC2RX 0x00000007 /* - serial port 2 reception */
-#define DMxCTR_BG_TM0UFLOW 0x00000008 /* - timer 0 underflow */
-#define DMxCTR_BG_TM1UFLOW 0x00000009 /* - timer 1 underflow */
-#define DMxCTR_BG_TM2UFLOW 0x0000000a /* - timer 2 underflow */
-#define DMxCTR_BG_TM3UFLOW 0x0000000b /* - timer 3 underflow */
-#define DMxCTR_BG_TM6ACMPCAP 0x0000000c /* - timer 6A compare/capture */
-#define DMxCTR_BG_AFE 0x0000000d /* - analogue front-end interrupt source */
-#define DMxCTR_BG_ADC 0x0000000e /* - A/D conversion end interrupt source */
-#define DMxCTR_BG_IRDA 0x0000000f /* - IrDA interrupt source */
-#define DMxCTR_BG_RTC 0x00000010 /* - RTC interrupt source */
-#define DMxCTR_BG_XIRQ0 0x00000011 /* - XIRQ0 pin interrupt source */
-#define DMxCTR_BG_XIRQ1 0x00000012 /* - XIRQ1 pin interrupt source */
-#define DMxCTR_BG_XDMR0 0x00000013 /* - external request 0 source (XDMR0 pin) */
-#define DMxCTR_BG_XDMR1 0x00000014 /* - external request 1 source (XDMR1 pin) */
-#define DMxCTR_SAM 0x000000e0 /* DMA transfer src addr mode */
-#define DMxCTR_SAM_INCR 0x00000000 /* - increment */
-#define DMxCTR_SAM_DECR 0x00000020 /* - decrement */
-#define DMxCTR_SAM_FIXED 0x00000040 /* - fixed */
-#define DMxCTR_DAM 0x00000000 /* DMA transfer dest addr mode */
-#define DMxCTR_DAM_INCR 0x00000000 /* - increment */
-#define DMxCTR_DAM_DECR 0x00000100 /* - decrement */
-#define DMxCTR_DAM_FIXED 0x00000200 /* - fixed */
-#define DMxCTR_TM 0x00001800 /* DMA transfer mode */
-#define DMxCTR_TM_BATCH 0x00000000 /* - batch transfer */
-#define DMxCTR_TM_INTERM 0x00001000 /* - intermittent transfer */
-#define DMxCTR_UT 0x00006000 /* DMA transfer unit */
-#define DMxCTR_UT_1 0x00000000 /* - 1 byte */
-#define DMxCTR_UT_2 0x00002000 /* - 2 byte */
-#define DMxCTR_UT_4 0x00004000 /* - 4 byte */
-#define DMxCTR_UT_16 0x00006000 /* - 16 byte */
-#define DMxCTR_TEN 0x00010000 /* DMA channel transfer enable */
-#define DMxCTR_RQM 0x00060000 /* external request input source mode */
-#define DMxCTR_RQM_FALLEDGE 0x00000000 /* - falling edge */
-#define DMxCTR_RQM_RISEEDGE 0x00020000 /* - rising edge */
-#define DMxCTR_RQM_LOLEVEL 0x00040000 /* - low level */
-#define DMxCTR_RQM_HILEVEL 0x00060000 /* - high level */
-#define DMxCTR_RQF 0x01000000 /* DMA transfer request flag */
-#define DMxCTR_XEND 0x80000000 /* DMA transfer end flag */
-
-#define DMxSRC(N) __SYSREG(0xd2000004 + ((N) * 0x100), u32) /* control reg */
-
-#define DMxDST(N) __SYSREG(0xd2000008 + ((N) * 0x100), u32) /* src addr reg */
-
-#define DMxSIZ(N) __SYSREG(0xd200000c + ((N) * 0x100), u32) /* dest addr reg */
-#define DMxSIZ_CT 0x000fffff /* number of bytes to transfer */
-
-#define DMxCYC(N) __SYSREG(0xd2000010 + ((N) * 0x100), u32) /* intermittent
- * size reg */
-#define DMxCYC_CYC 0x000000ff /* number of interrmittent transfers -1 */
-
-#define DM0IRQ 16 /* DMA channel 0 complete IRQ */
-#define DM1IRQ 17 /* DMA channel 1 complete IRQ */
-#define DM2IRQ 18 /* DMA channel 2 complete IRQ */
-#define DM3IRQ 19 /* DMA channel 3 complete IRQ */
-
-#define DM0ICR GxICR(DM0IRQ) /* DMA channel 0 complete intr ctrl reg */
-#define DM1ICR GxICR(DM0IR1) /* DMA channel 1 complete intr ctrl reg */
-#define DM2ICR GxICR(DM0IR2) /* DMA channel 2 complete intr ctrl reg */
-#define DM3ICR GxICR(DM0IR3) /* DMA channel 3 complete intr ctrl reg */
-
-#ifndef __ASSEMBLY__
-
-struct mn10300_dmactl_regs {
- u32 ctr;
- const void *src;
- void *dst;
- u32 siz;
- u32 cyc;
-} __attribute__((aligned(0x100)));
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* __KERNEL__ */
+#include <proc/dmactl-regs.h>
#endif /* _ASM_DMACTL_REGS_H */
diff --git a/arch/mn10300/include/asm/elf.h b/arch/mn10300/include/asm/elf.h
index e5fa97cd9a14..8157c9267f42 100644
--- a/arch/mn10300/include/asm/elf.h
+++ b/arch/mn10300/include/asm/elf.h
@@ -32,6 +32,12 @@
#define R_MN10300_ALIGN 34 /* Alignment requirement. */
/*
+ * AM33/AM34 HW Capabilities
+ */
+#define HWCAP_MN10300_ATOMIC_OP_UNIT 1 /* Has AM34 Atomic Operations */
+
+
+/*
* ELF register definitions..
*/
typedef unsigned long elf_greg_t;
@@ -47,8 +53,6 @@ typedef struct {
u_int32_t fpcr;
} elf_fpregset_t;
-extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
-
/*
* This is used to ensure we don't load something for the wrong architecture
*/
@@ -130,7 +134,11 @@ do { \
* instruction set this CPU supports. This could be done in user space,
* but it's not easy, and we've already done it here.
*/
+#ifdef CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT
+#define ELF_HWCAP (HWCAP_MN10300_ATOMIC_OP_UNIT)
+#else
#define ELF_HWCAP (0)
+#endif
/*
* This yields a string that ld.so will use to load implementation
diff --git a/arch/mn10300/include/asm/exceptions.h b/arch/mn10300/include/asm/exceptions.h
index fa16466ef3f9..ca3e20508c77 100644
--- a/arch/mn10300/include/asm/exceptions.h
+++ b/arch/mn10300/include/asm/exceptions.h
@@ -15,8 +15,8 @@
/*
* define the breakpoint instruction opcode to use
- * - note that the JTAG unit steals 0xFF, so we want to avoid that if we can
- * (can use 0xF7)
+ * - note that the JTAG unit steals 0xFF, so you can't use JTAG and GDBSTUB at
+ * the same time.
*/
#define GDBSTUB_BKPT 0xFF
@@ -90,7 +90,6 @@ enum exception_code {
extern void __set_intr_stub(enum exception_code code, void *handler);
extern void set_intr_stub(enum exception_code code, void *handler);
-extern void set_jtag_stub(enum exception_code code, void *handler);
struct pt_regs;
@@ -102,7 +101,6 @@ extern asmlinkage void dtlb_aerror(void);
extern asmlinkage void raw_bus_error(void);
extern asmlinkage void double_fault(void);
extern asmlinkage int system_call(struct pt_regs *);
-extern asmlinkage void fpu_exception(struct pt_regs *, enum exception_code);
extern asmlinkage void nmi(struct pt_regs *, enum exception_code);
extern asmlinkage void uninitialised_exception(struct pt_regs *,
enum exception_code);
@@ -116,6 +114,8 @@ extern void die(const char *, struct pt_regs *, enum exception_code)
extern int die_if_no_fixup(const char *, struct pt_regs *, enum exception_code);
+#define NUM2EXCEP_IRQ_LEVEL(num) (EXCEP_IRQ_LEVEL0 + (num) * 8)
+
#endif /* __ASSEMBLY__ */
#endif /* _ASM_EXCEPTIONS_H */
diff --git a/arch/mn10300/include/asm/fpu.h b/arch/mn10300/include/asm/fpu.h
index 64a2b83a7a6a..b7625de8eade 100644
--- a/arch/mn10300/include/asm/fpu.h
+++ b/arch/mn10300/include/asm/fpu.h
@@ -12,74 +12,125 @@
#ifndef _ASM_FPU_H
#define _ASM_FPU_H
-#include <asm/processor.h>
+#ifndef __ASSEMBLY__
+
+#include <linux/sched.h>
+#include <asm/exceptions.h>
#include <asm/sigcontext.h>
-#include <asm/user.h>
#ifdef __KERNEL__
-/* the task that owns the FPU state */
+extern asmlinkage void fpu_disabled(void);
+
+#ifdef CONFIG_FPU
+
+#ifdef CONFIG_LAZY_SAVE_FPU
+/* the task that currently owns the FPU state */
extern struct task_struct *fpu_state_owner;
+#endif
-#define set_using_fpu(tsk) \
-do { \
- (tsk)->thread.fpu_flags |= THREAD_USING_FPU; \
-} while (0)
+#if (THREAD_USING_FPU & ~0xff)
+#error THREAD_USING_FPU must be smaller than 0x100.
+#endif
-#define clear_using_fpu(tsk) \
-do { \
- (tsk)->thread.fpu_flags &= ~THREAD_USING_FPU; \
-} while (0)
+static inline void set_using_fpu(struct task_struct *tsk)
+{
+ asm volatile(
+ "bset %0,(0,%1)"
+ :
+ : "i"(THREAD_USING_FPU), "a"(&tsk->thread.fpu_flags)
+ : "memory", "cc");
+}
-#define is_using_fpu(tsk) ((tsk)->thread.fpu_flags & THREAD_USING_FPU)
+static inline void clear_using_fpu(struct task_struct *tsk)
+{
+ asm volatile(
+ "bclr %0,(0,%1)"
+ :
+ : "i"(THREAD_USING_FPU), "a"(&tsk->thread.fpu_flags)
+ : "memory", "cc");
+}
-#define unlazy_fpu(tsk) \
-do { \
- preempt_disable(); \
- if (fpu_state_owner == (tsk)) \
- fpu_save(&tsk->thread.fpu_state); \
- preempt_enable(); \
-} while (0)
-
-#define exit_fpu() \
-do { \
- struct task_struct *__tsk = current; \
- preempt_disable(); \
- if (fpu_state_owner == __tsk) \
- fpu_state_owner = NULL; \
- preempt_enable(); \
-} while (0)
-
-#define flush_fpu() \
-do { \
- struct task_struct *__tsk = current; \
- preempt_disable(); \
- if (fpu_state_owner == __tsk) { \
- fpu_state_owner = NULL; \
- __tsk->thread.uregs->epsw &= ~EPSW_FE; \
- } \
- preempt_enable(); \
- clear_using_fpu(__tsk); \
-} while (0)
+#define is_using_fpu(tsk) ((tsk)->thread.fpu_flags & THREAD_USING_FPU)
-extern asmlinkage void fpu_init_state(void);
extern asmlinkage void fpu_kill_state(struct task_struct *);
-extern asmlinkage void fpu_disabled(struct pt_regs *, enum exception_code);
extern asmlinkage void fpu_exception(struct pt_regs *, enum exception_code);
-
-#ifdef CONFIG_FPU
+extern asmlinkage void fpu_invalid_op(struct pt_regs *, enum exception_code);
+extern asmlinkage void fpu_init_state(void);
extern asmlinkage void fpu_save(struct fpu_state_struct *);
-extern asmlinkage void fpu_restore(struct fpu_state_struct *);
-#else
-#define fpu_save(a)
-#define fpu_restore(a)
-#endif /* CONFIG_FPU */
-
-/*
- * signal frame handlers
- */
extern int fpu_setup_sigcontext(struct fpucontext *buf);
extern int fpu_restore_sigcontext(struct fpucontext *buf);
+static inline void unlazy_fpu(struct task_struct *tsk)
+{
+ preempt_disable();
+#ifndef CONFIG_LAZY_SAVE_FPU
+ if (tsk->thread.fpu_flags & THREAD_HAS_FPU) {
+ fpu_save(&tsk->thread.fpu_state);
+ tsk->thread.fpu_flags &= ~THREAD_HAS_FPU;
+ tsk->thread.uregs->epsw &= ~EPSW_FE;
+ }
+#else
+ if (fpu_state_owner == tsk)
+ fpu_save(&tsk->thread.fpu_state);
+#endif
+ preempt_enable();
+}
+
+static inline void exit_fpu(void)
+{
+#ifdef CONFIG_LAZY_SAVE_FPU
+ struct task_struct *tsk = current;
+
+ preempt_disable();
+ if (fpu_state_owner == tsk)
+ fpu_state_owner = NULL;
+ preempt_enable();
+#endif
+}
+
+static inline void flush_fpu(void)
+{
+ struct task_struct *tsk = current;
+
+ preempt_disable();
+#ifndef CONFIG_LAZY_SAVE_FPU
+ if (tsk->thread.fpu_flags & THREAD_HAS_FPU) {
+ tsk->thread.fpu_flags &= ~THREAD_HAS_FPU;
+ tsk->thread.uregs->epsw &= ~EPSW_FE;
+ }
+#else
+ if (fpu_state_owner == tsk) {
+ fpu_state_owner = NULL;
+ tsk->thread.uregs->epsw &= ~EPSW_FE;
+ }
+#endif
+ preempt_enable();
+ clear_using_fpu(tsk);
+}
+
+#else /* CONFIG_FPU */
+
+extern asmlinkage
+void unexpected_fpu_exception(struct pt_regs *, enum exception_code);
+#define fpu_invalid_op unexpected_fpu_exception
+#define fpu_exception unexpected_fpu_exception
+
+struct task_struct;
+struct fpu_state_struct;
+static inline bool is_using_fpu(struct task_struct *tsk) { return false; }
+static inline void set_using_fpu(struct task_struct *tsk) {}
+static inline void clear_using_fpu(struct task_struct *tsk) {}
+static inline void fpu_init_state(void) {}
+static inline void fpu_save(struct fpu_state_struct *s) {}
+static inline void fpu_kill_state(struct task_struct *tsk) {}
+static inline void unlazy_fpu(struct task_struct *tsk) {}
+static inline void exit_fpu(void) {}
+static inline void flush_fpu(void) {}
+static inline int fpu_setup_sigcontext(struct fpucontext *buf) { return 0; }
+static inline int fpu_restore_sigcontext(struct fpucontext *buf) { return 0; }
+#endif /* CONFIG_FPU */
+
#endif /* __KERNEL__ */
+#endif /* !__ASSEMBLY__ */
#endif /* _ASM_FPU_H */
diff --git a/arch/mn10300/include/asm/frame.inc b/arch/mn10300/include/asm/frame.inc
index 5b1949bdf039..2ee58e3eb6b3 100644
--- a/arch/mn10300/include/asm/frame.inc
+++ b/arch/mn10300/include/asm/frame.inc
@@ -18,6 +18,7 @@
#ifndef __ASM_OFFSETS_H__
#include <asm/asm-offsets.h>
#endif
+#include <asm/thread_info.h>
#define pi break
@@ -37,11 +38,15 @@
movm [d2,d3,a2,a3,exreg0,exreg1,exother],(sp)
mov sp,fp # FRAME pointer in A3
add -12,sp # allow for calls to be made
- mov (__frame),a1
- mov a1,(REG_NEXT,fp)
- mov fp,(__frame)
- and ~EPSW_FE,epsw # disable the FPU inside the kernel
+ # push the exception frame onto the front of the list
+ GET_THREAD_INFO a1
+ mov (TI_frame,a1),a0
+ mov a0,(REG_NEXT,fp)
+ mov fp,(TI_frame,a1)
+
+ # disable the FPU inside the kernel
+ and ~EPSW_FE,epsw
# we may be holding current in E2
#ifdef CONFIG_MN10300_CURRENT_IN_E2
@@ -57,10 +62,11 @@
.macro RESTORE_ALL
# peel back the stack to the calling frame
# - this permits execve() to discard extra frames due to kernel syscalls
- mov (__frame),fp
+ GET_THREAD_INFO a0
+ mov (TI_frame,a0),fp
mov fp,sp
- mov (REG_NEXT,fp),d0 # userspace has regs->next == 0
- mov d0,(__frame)
+ mov (REG_NEXT,fp),d0
+ mov d0,(TI_frame,a0) # userspace has regs->next == 0
#ifndef CONFIG_MN10300_USING_JTAG
mov (REG_EPSW,fp),d0
diff --git a/arch/mn10300/include/asm/gdb-stub.h b/arch/mn10300/include/asm/gdb-stub.h
index 41ed26763964..f5495ad82b77 100644
--- a/arch/mn10300/include/asm/gdb-stub.h
+++ b/arch/mn10300/include/asm/gdb-stub.h
@@ -110,7 +110,7 @@ extern asmlinkage void gdbstub_exception(struct pt_regs *, enum exception_code);
extern asmlinkage void __gdbstub_bug_trap(void);
extern asmlinkage void __gdbstub_pause(void);
-#ifndef CONFIG_MN10300_CACHE_DISABLED
+#ifdef CONFIG_MN10300_CACHE_ENABLED
extern asmlinkage void gdbstub_purge_cache(void);
#else
#define gdbstub_purge_cache() do {} while (0)
diff --git a/arch/mn10300/include/asm/hardirq.h b/arch/mn10300/include/asm/hardirq.h
index 54d950117674..0000d650b55f 100644
--- a/arch/mn10300/include/asm/hardirq.h
+++ b/arch/mn10300/include/asm/hardirq.h
@@ -19,9 +19,10 @@
/* assembly code in softirq.h is sensitive to the offsets of these fields */
typedef struct {
unsigned int __softirq_pending;
- unsigned long idle_timestamp;
+#ifdef CONFIG_MN10300_WD_TIMER
unsigned int __nmi_count; /* arch dependent */
unsigned int __irq_count; /* arch dependent */
+#endif
} ____cacheline_aligned irq_cpustat_t;
#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
diff --git a/arch/mn10300/include/asm/highmem.h b/arch/mn10300/include/asm/highmem.h
index b0b187a29b88..bfe2d88604d9 100644
--- a/arch/mn10300/include/asm/highmem.h
+++ b/arch/mn10300/include/asm/highmem.h
@@ -70,15 +70,16 @@ static inline void kunmap(struct page *page)
* be used in IRQ contexts, so in some (very limited) cases we need
* it.
*/
-static inline unsigned long kmap_atomic(struct page *page, enum km_type type)
+static inline unsigned long __kmap_atomic(struct page *page)
{
- enum fixed_addresses idx;
unsigned long vaddr;
+ int idx, type;
+ pagefault_disable();
if (page < highmem_start_page)
return page_address(page);
- debug_kmap_atomic(type);
+ type = kmap_atomic_idx_push();
idx = type + KM_TYPE_NR * smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
#if HIGHMEM_DEBUG
@@ -86,31 +87,42 @@ static inline unsigned long kmap_atomic(struct page *page, enum km_type type)
BUG();
#endif
set_pte(kmap_pte - idx, mk_pte(page, kmap_prot));
- __flush_tlb_one(vaddr);
+ local_flush_tlb_one(vaddr);
return vaddr;
}
-static inline void kunmap_atomic_notypecheck(unsigned long vaddr, enum km_type type)
+static inline void __kunmap_atomic(unsigned long vaddr)
{
-#if HIGHMEM_DEBUG
- enum fixed_addresses idx = type + KM_TYPE_NR * smp_processor_id();
+ int type;
- if (vaddr < FIXADDR_START) /* FIXME */
+ if (vaddr < FIXADDR_START) { /* FIXME */
+ pagefault_enable();
return;
+ }
- if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx))
- BUG();
+ type = kmap_atomic_idx();
- /*
- * force other mappings to Oops if they'll try to access
- * this pte without first remap it
- */
- pte_clear(kmap_pte - idx);
- __flush_tlb_one(vaddr);
+#if HIGHMEM_DEBUG
+ {
+ unsigned int idx;
+ idx = type + KM_TYPE_NR * smp_processor_id();
+
+ if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx))
+ BUG();
+
+ /*
+ * force other mappings to Oops if they'll try to access
+ * this pte without first remap it
+ */
+ pte_clear(kmap_pte - idx);
+ local_flush_tlb_one(vaddr);
+ }
#endif
-}
+ kmap_atomic_idx_pop();
+ pagefault_enable();
+}
#endif /* __KERNEL__ */
#endif /* _ASM_HIGHMEM_H */
diff --git a/arch/mn10300/include/asm/intctl-regs.h b/arch/mn10300/include/asm/intctl-regs.h
index ba544c796c5a..585b708c2bc0 100644
--- a/arch/mn10300/include/asm/intctl-regs.h
+++ b/arch/mn10300/include/asm/intctl-regs.h
@@ -15,24 +15,19 @@
#ifdef __KERNEL__
-/* interrupt controller registers */
-#define GxICR(X) __SYSREG(0xd4000000 + (X) * 4, u16) /* group irq ctrl regs */
-
-#define IAGR __SYSREG(0xd4000100, u16) /* intr acceptance group reg */
-#define IAGR_GN 0x00fc /* group number register
- * (documentation _has_ to be wrong)
- */
+/*
+ * Interrupt controller registers
+ * - Registers 64-191 are at addresses offset from the main array
+ */
+#define GxICR(X) \
+ __SYSREG(0xd4000000 + (X) * 4 + \
+ (((X) >= 64) && ((X) < 192)) * 0xf00, u16)
-#define EXTMD __SYSREG(0xd4000200, u16) /* external pin intr spec reg */
-#define GET_XIRQ_TRIGGER(X) ((EXTMD >> ((X) * 2)) & 3)
+#define GxICR_u8(X) \
+ __SYSREG(0xd4000000 + (X) * 4 + \
+ (((X) >= 64) && ((X) < 192)) * 0xf00, u8)
-#define SET_XIRQ_TRIGGER(X,Y) \
-do { \
- u16 x = EXTMD; \
- x &= ~(3 << ((X) * 2)); \
- x |= ((Y) & 3) << ((X) * 2); \
- EXTMD = x; \
-} while (0)
+#include <proc/intctl-regs.h>
#define XIRQ_TRIGGER_LOWLEVEL 0
#define XIRQ_TRIGGER_HILEVEL 1
@@ -59,10 +54,18 @@ do { \
#define GxICR_LEVEL_5 0x5000 /* - level 5 */
#define GxICR_LEVEL_6 0x6000 /* - level 6 */
#define GxICR_LEVEL_SHIFT 12
+#define GxICR_NMI 0x8000 /* nmi request flag */
+
+#define NUM2GxICR_LEVEL(num) ((num) << GxICR_LEVEL_SHIFT)
#ifndef __ASSEMBLY__
extern void set_intr_level(int irq, u16 level);
-extern void set_intr_postackable(int irq);
+extern void mn10300_intc_set_level(unsigned int irq, unsigned int level);
+extern void mn10300_intc_clear(unsigned int irq);
+extern void mn10300_intc_set(unsigned int irq);
+extern void mn10300_intc_enable(unsigned int irq);
+extern void mn10300_intc_disable(unsigned int irq);
+extern void mn10300_set_lateack_irq_type(int irq);
#endif
/* external interrupts */
diff --git a/arch/mn10300/include/asm/io.h b/arch/mn10300/include/asm/io.h
index c1a4119e6497..787255da744e 100644
--- a/arch/mn10300/include/asm/io.h
+++ b/arch/mn10300/include/asm/io.h
@@ -206,6 +206,19 @@ static inline void outsl(unsigned long addr, const void *buffer, int count)
#define iowrite32_rep(p, src, count) \
outsl((unsigned long) (p), (src), (count))
+#define readsb(p, dst, count) \
+ insb((unsigned long) (p), (dst), (count))
+#define readsw(p, dst, count) \
+ insw((unsigned long) (p), (dst), (count))
+#define readsl(p, dst, count) \
+ insl((unsigned long) (p), (dst), (count))
+
+#define writesb(p, src, count) \
+ outsb((unsigned long) (p), (src), (count))
+#define writesw(p, src, count) \
+ outsw((unsigned long) (p), (src), (count))
+#define writesl(p, src, count) \
+ outsl((unsigned long) (p), (src), (count))
#define IO_SPACE_LIMIT 0xffffffff
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/irq.h b/arch/mn10300/include/asm/irq.h
index 25c045d16d1c..1a73fb3f60c6 100644
--- a/arch/mn10300/include/asm/irq.h
+++ b/arch/mn10300/include/asm/irq.h
@@ -21,8 +21,16 @@
/* this number is used when no interrupt has been assigned */
#define NO_IRQ INT_MAX
-/* hardware irq numbers */
-#define NR_IRQS GxICR_NUM_IRQS
+/*
+ * hardware irq numbers
+ * - the ASB2364 has an FPGA with an IRQ multiplexer on it
+ */
+#ifdef CONFIG_MN10300_UNIT_ASB2364
+#include <unit/irq.h>
+#else
+#define NR_CPU_IRQS GxICR_NUM_IRQS
+#define NR_IRQS NR_CPU_IRQS
+#endif
/* external hardware irq numbers */
#define NR_XIRQS GxICR_NUM_XIRQS
diff --git a/arch/mn10300/include/asm/irq_regs.h b/arch/mn10300/include/asm/irq_regs.h
index a848cd232eb4..97d0cb5af807 100644
--- a/arch/mn10300/include/asm/irq_regs.h
+++ b/arch/mn10300/include/asm/irq_regs.h
@@ -18,7 +18,11 @@
#define ARCH_HAS_OWN_IRQ_REGS
#ifndef __ASSEMBLY__
-#define get_irq_regs() (__frame)
+static inline __attribute__((const))
+struct pt_regs *get_irq_regs(void)
+{
+ return current_frame();
+}
#endif
#endif /* _ASM_IRQ_REGS_H */
diff --git a/arch/mn10300/include/asm/irqflags.h b/arch/mn10300/include/asm/irqflags.h
new file mode 100644
index 000000000000..7a7ae12c7119
--- /dev/null
+++ b/arch/mn10300/include/asm/irqflags.h
@@ -0,0 +1,216 @@
+/* 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>
+#ifndef __ASSEMBLY__
+#include <linux/smp.h>
+#endif
+
+/*
+ * 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
+ */
+#define MN10300_CLI_LEVEL (CONFIG_LINUX_CLI_LEVEL << EPSW_IM_SHIFT)
+
+#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;
+ int cpu = raw_smp_processor_id();
+
+ 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[cpu])
+ : "memory", "cc");
+}
+
+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_IE | EPSW_IM)) != (EPSW_IE | EPSW_IM_7);
+}
+
+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)
+{
+#ifdef CONFIG_SMP
+ arch_local_irq_enable();
+#else
+ 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
+}
+
+#define __sleep_cpu() \
+do { \
+ asm volatile( \
+ " bset %1,(%0)\n" \
+ "1: btst %1,(%0)\n" \
+ " bne 1b\n" \
+ : \
+ : "i"(&CPUM), "i"(CPUM_SLEEP) \
+ : "cc" \
+ ); \
+} while (0)
+
+static inline void arch_local_cli(void)
+{
+ asm volatile(
+ " and %0,epsw \n"
+ " nop \n"
+ " nop \n"
+ " nop \n"
+ :
+ : "i"(~EPSW_IE)
+ : "memory"
+ );
+}
+
+static inline unsigned long arch_local_cli_save(void)
+{
+ unsigned long flags = arch_local_save_flags();
+ arch_local_cli();
+ return flags;
+}
+
+static inline void arch_local_sti(void)
+{
+ asm volatile(
+ " or %0,epsw \n"
+ :
+ : "i"(EPSW_IE)
+ : "memory");
+}
+
+static inline void arch_local_change_intr_mask_level(unsigned long level)
+{
+ asm volatile(
+ " and %0,epsw \n"
+ " or %1,epsw \n"
+ :
+ : "i"(~EPSW_IM), "i"(EPSW_IE | level)
+ : "cc", "memory");
+}
+
+#else /* !__ASSEMBLY__ */
+
+#define LOCAL_SAVE_FLAGS(reg) \
+ mov epsw,reg
+
+#define LOCAL_IRQ_DISABLE \
+ and ~EPSW_IM,epsw; \
+ or EPSW_IE|MN10300_CLI_LEVEL,epsw; \
+ nop; \
+ nop; \
+ nop
+
+#define LOCAL_IRQ_ENABLE \
+ or EPSW_IE|EPSW_IM_7,epsw
+
+#define LOCAL_IRQ_RESTORE(reg) \
+ mov reg,epsw
+
+#define LOCAL_CLI_SAVE(reg) \
+ mov epsw,reg; \
+ and ~EPSW_IE,epsw; \
+ nop; \
+ nop; \
+ nop
+
+#define LOCAL_CLI \
+ and ~EPSW_IE,epsw; \
+ nop; \
+ nop; \
+ nop
+
+#define LOCAL_STI \
+ or EPSW_IE,epsw
+
+#define LOCAL_CHANGE_INTR_MASK_LEVEL(level) \
+ and ~EPSW_IM,epsw; \
+ or EPSW_IE|(level),epsw
+
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_IRQFLAGS_H */
diff --git a/arch/mn10300/include/asm/mmu_context.h b/arch/mn10300/include/asm/mmu_context.h
index cb294c244de3..c8f6c82672ad 100644
--- a/arch/mn10300/include/asm/mmu_context.h
+++ b/arch/mn10300/include/asm/mmu_context.h
@@ -27,28 +27,38 @@
#include <asm/tlbflush.h>
#include <asm-generic/mm_hooks.h>
+#define MMU_CONTEXT_TLBPID_NR 256
#define MMU_CONTEXT_TLBPID_MASK 0x000000ffUL
#define MMU_CONTEXT_VERSION_MASK 0xffffff00UL
#define MMU_CONTEXT_FIRST_VERSION 0x00000100UL
#define MMU_NO_CONTEXT 0x00000000UL
-
-extern unsigned long mmu_context_cache[NR_CPUS];
-#define mm_context(mm) (mm->context.tlbpid[smp_processor_id()])
+#define MMU_CONTEXT_TLBPID_LOCK_NR 0
#define enter_lazy_tlb(mm, tsk) do {} while (0)
+static inline void cpu_ran_vm(int cpu, struct mm_struct *mm)
+{
#ifdef CONFIG_SMP
-#define cpu_ran_vm(cpu, mm) \
- cpumask_set_cpu((cpu), mm_cpumask(mm))
-#define cpu_maybe_ran_vm(cpu, mm) \
- cpumask_test_and_set_cpu((cpu), mm_cpumask(mm))
+ cpumask_set_cpu(cpu, mm_cpumask(mm));
+#endif
+}
+
+static inline bool cpu_maybe_ran_vm(int cpu, struct mm_struct *mm)
+{
+#ifdef CONFIG_SMP
+ return cpumask_test_and_set_cpu(cpu, mm_cpumask(mm));
#else
-#define cpu_ran_vm(cpu, mm) do {} while (0)
-#define cpu_maybe_ran_vm(cpu, mm) true
-#endif /* CONFIG_SMP */
+ return true;
+#endif
+}
-/*
- * allocate an MMU context
+#ifdef CONFIG_MN10300_TLB_USE_PIDR
+extern unsigned long mmu_context_cache[NR_CPUS];
+#define mm_context(mm) (mm->context.tlbpid[smp_processor_id()])
+
+/**
+ * allocate_mmu_context - Allocate storage for the arch-specific MMU data
+ * @mm: The userspace VM context being set up
*/
static inline unsigned long allocate_mmu_context(struct mm_struct *mm)
{
@@ -58,7 +68,7 @@ static inline unsigned long allocate_mmu_context(struct mm_struct *mm)
if (!(mc & MMU_CONTEXT_TLBPID_MASK)) {
/* we exhausted the TLB PIDs of this version on this CPU, so we
* flush this CPU's TLB in its entirety and start new cycle */
- flush_tlb_all();
+ local_flush_tlb_all();
/* fix the TLB version if needed (we avoid version #0 so as to
* distingush MMU_NO_CONTEXT) */
@@ -101,22 +111,34 @@ static inline int init_new_context(struct task_struct *tsk,
}
/*
- * destroy context related info for an mm_struct that is about to be put to
- * rest
- */
-#define destroy_context(mm) do { } while (0)
-
-/*
* after we have set current->mm to a new value, this activates the context for
* the new mm so we see the new mappings.
*/
-static inline void activate_context(struct mm_struct *mm, int cpu)
+static inline void activate_context(struct mm_struct *mm)
{
PIDR = get_mmu_context(mm) & MMU_CONTEXT_TLBPID_MASK;
}
+#else /* CONFIG_MN10300_TLB_USE_PIDR */
-/*
- * change between virtual memory sets
+#define init_new_context(tsk, mm) (0)
+#define activate_context(mm) local_flush_tlb()
+
+#endif /* CONFIG_MN10300_TLB_USE_PIDR */
+
+/**
+ * destroy_context - Destroy mm context information
+ * @mm: The MM being destroyed.
+ *
+ * Destroy context related info for an mm_struct that is about to be put to
+ * rest
+ */
+#define destroy_context(mm) do {} while (0)
+
+/**
+ * switch_mm - Change between userspace virtual memory contexts
+ * @prev: The outgoing MM context.
+ * @next: The incoming MM context.
+ * @tsk: The incoming task.
*/
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
struct task_struct *tsk)
@@ -124,11 +146,12 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
int cpu = smp_processor_id();
if (prev != next) {
+#ifdef CONFIG_SMP
+ per_cpu(cpu_tlbstate, cpu).active_mm = next;
+#endif
cpu_ran_vm(cpu, next);
- activate_context(next, cpu);
PTBR = (unsigned long) next->pgd;
- } else if (!cpu_maybe_ran_vm(cpu, next)) {
- activate_context(next, cpu);
+ activate_context(next);
}
}
diff --git a/arch/mn10300/include/asm/pgalloc.h b/arch/mn10300/include/asm/pgalloc.h
index a19f11327cd8..146bacf193ea 100644
--- a/arch/mn10300/include/asm/pgalloc.h
+++ b/arch/mn10300/include/asm/pgalloc.h
@@ -11,7 +11,6 @@
#ifndef _ASM_PGALLOC_H
#define _ASM_PGALLOC_H
-#include <asm/processor.h>
#include <asm/page.h>
#include <linux/threads.h>
#include <linux/mm.h> /* for struct page */
diff --git a/arch/mn10300/include/asm/pgtable.h b/arch/mn10300/include/asm/pgtable.h
index 16d88577f3e0..a1e894b5f65b 100644
--- a/arch/mn10300/include/asm/pgtable.h
+++ b/arch/mn10300/include/asm/pgtable.h
@@ -90,46 +90,58 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
* The vmalloc() routines also leaves a hole of 4kB between each vmalloced
* area to catch addressing errors.
*/
+#ifndef __ASSEMBLY__
+#define VMALLOC_OFFSET (8UL * 1024 * 1024)
+#define VMALLOC_START (0x70000000UL)
+#define VMALLOC_END (0x7C000000UL)
+#else
#define VMALLOC_OFFSET (8 * 1024 * 1024)
#define VMALLOC_START (0x70000000)
#define VMALLOC_END (0x7C000000)
+#endif
#ifndef __ASSEMBLY__
extern pte_t kernel_vmalloc_ptes[(VMALLOC_END - VMALLOC_START) / PAGE_SIZE];
#endif
-/* IPTEL/DPTEL bit assignments */
-#define _PAGE_BIT_VALID xPTEL_V_BIT
-#define _PAGE_BIT_ACCESSED xPTEL_UNUSED1_BIT /* mustn't be loaded into IPTEL/DPTEL */
-#define _PAGE_BIT_NX xPTEL_UNUSED2_BIT /* mustn't be loaded into IPTEL/DPTEL */
-#define _PAGE_BIT_CACHE xPTEL_C_BIT
-#define _PAGE_BIT_PRESENT xPTEL_PV_BIT
-#define _PAGE_BIT_DIRTY xPTEL_D_BIT
-#define _PAGE_BIT_GLOBAL xPTEL_G_BIT
-
-#define _PAGE_VALID xPTEL_V
-#define _PAGE_ACCESSED xPTEL_UNUSED1
-#define _PAGE_NX xPTEL_UNUSED2 /* no-execute bit */
-#define _PAGE_CACHE xPTEL_C
-#define _PAGE_PRESENT xPTEL_PV
-#define _PAGE_DIRTY xPTEL_D
-#define _PAGE_PROT xPTEL_PR
-#define _PAGE_PROT_RKNU xPTEL_PR_ROK
-#define _PAGE_PROT_WKNU xPTEL_PR_RWK
-#define _PAGE_PROT_RKRU xPTEL_PR_ROK_ROU
-#define _PAGE_PROT_WKRU xPTEL_PR_RWK_ROU
-#define _PAGE_PROT_WKWU xPTEL_PR_RWK_RWU
-#define _PAGE_GLOBAL xPTEL_G
-#define _PAGE_PSE xPTEL_PS_4Mb /* 4MB page */
-
-#define _PAGE_FILE xPTEL_UNUSED1_BIT /* set:pagecache unset:swap */
-
-#define __PAGE_PROT_UWAUX 0x040
-#define __PAGE_PROT_USER 0x080
-#define __PAGE_PROT_WRITE 0x100
+/* IPTEL2/DPTEL2 bit assignments */
+#define _PAGE_BIT_VALID xPTEL2_V_BIT
+#define _PAGE_BIT_CACHE xPTEL2_C_BIT
+#define _PAGE_BIT_PRESENT xPTEL2_PV_BIT
+#define _PAGE_BIT_DIRTY xPTEL2_D_BIT
+#define _PAGE_BIT_GLOBAL xPTEL2_G_BIT
+#define _PAGE_BIT_ACCESSED xPTEL2_UNUSED1_BIT /* mustn't be loaded into IPTEL2/DPTEL2 */
+
+#define _PAGE_VALID xPTEL2_V
+#define _PAGE_CACHE xPTEL2_C
+#define _PAGE_PRESENT xPTEL2_PV
+#define _PAGE_DIRTY xPTEL2_D
+#define _PAGE_PROT xPTEL2_PR
+#define _PAGE_PROT_RKNU xPTEL2_PR_ROK
+#define _PAGE_PROT_WKNU xPTEL2_PR_RWK
+#define _PAGE_PROT_RKRU xPTEL2_PR_ROK_ROU
+#define _PAGE_PROT_WKRU xPTEL2_PR_RWK_ROU
+#define _PAGE_PROT_WKWU xPTEL2_PR_RWK_RWU
+#define _PAGE_GLOBAL xPTEL2_G
+#define _PAGE_PS_MASK xPTEL2_PS
+#define _PAGE_PS_4Kb xPTEL2_PS_4Kb
+#define _PAGE_PS_128Kb xPTEL2_PS_128Kb
+#define _PAGE_PS_1Kb xPTEL2_PS_1Kb
+#define _PAGE_PS_4Mb xPTEL2_PS_4Mb
+#define _PAGE_PSE xPTEL2_PS_4Mb /* 4MB page */
+#define _PAGE_CACHE_WT xPTEL2_CWT
+#define _PAGE_ACCESSED xPTEL2_UNUSED1
+#define _PAGE_NX 0 /* no-execute bit */
+
+/* If _PAGE_VALID is clear, we use these: */
+#define _PAGE_FILE xPTEL2_C /* set:pagecache unset:swap */
+#define _PAGE_PROTNONE 0x000 /* If not present */
+
+#define __PAGE_PROT_UWAUX 0x010
+#define __PAGE_PROT_USER 0x020
+#define __PAGE_PROT_WRITE 0x040
#define _PAGE_PRESENTV (_PAGE_PRESENT|_PAGE_VALID)
-#define _PAGE_PROTNONE 0x000 /* If not present */
#ifndef __ASSEMBLY__
@@ -170,6 +182,9 @@ extern pte_t kernel_vmalloc_ptes[(VMALLOC_END - VMALLOC_START) / PAGE_SIZE];
#define PAGE_KERNEL_LARGE __pgprot(__PAGE_KERNEL_LARGE)
#define PAGE_KERNEL_LARGE_EXEC __pgprot(__PAGE_KERNEL_LARGE_EXEC)
+#define __PAGE_USERIO (__PAGE_KERNEL_BASE | _PAGE_PROT_WKWU | _PAGE_NX)
+#define PAGE_USERIO __pgprot(__PAGE_USERIO)
+
/*
* Whilst the MN10300 can do page protection for execute (given separate data
* and insn TLBs), we are not supporting it at the moment. Write permission,
@@ -323,11 +338,7 @@ static inline int pte_exec_kernel(pte_t pte)
return 1;
}
-/*
- * Bits 0 and 1 are taken, split up the 29 bits of offset
- * into this range:
- */
-#define PTE_FILE_MAX_BITS 29
+#define PTE_FILE_MAX_BITS 30
#define pte_to_pgoff(pte) (pte_val(pte) >> 2)
#define pgoff_to_pte(off) __pte((off) << 2 | _PAGE_FILE)
@@ -373,8 +384,13 @@ static inline void ptep_mkdirty(pte_t *ptep)
* Macro to mark a page protection value as "uncacheable". On processors which
* do not support it, this is a no-op.
*/
-#define pgprot_noncached(prot) __pgprot(pgprot_val(prot) | _PAGE_CACHE)
+#define pgprot_noncached(prot) __pgprot(pgprot_val(prot) & ~_PAGE_CACHE)
+/*
+ * Macro to mark a page protection value as "Write-Through".
+ * On processors which do not support it, this is a no-op.
+ */
+#define pgprot_through(prot) __pgprot(pgprot_val(prot) | _PAGE_CACHE_WT)
/*
* Conversion functions: convert a page and protection to a page entry,
@@ -457,9 +473,7 @@ static inline int set_kernel_exec(unsigned long vaddr, int enable)
#define pte_offset_map(dir, address) \
((pte_t *) page_address(pmd_page(*(dir))) + pte_index(address))
-#define pte_offset_map_nested(dir, address) pte_offset_map(dir, address)
#define pte_unmap(pte) do {} while (0)
-#define pte_unmap_nested(pte) do {} while (0)
/*
* The MN10300 has external MMU info in the form of a TLB: this is adapted from
diff --git a/arch/mn10300/include/asm/processor.h b/arch/mn10300/include/asm/processor.h
index f7d4b0d285e8..4c1b5cc14c19 100644
--- a/arch/mn10300/include/asm/processor.h
+++ b/arch/mn10300/include/asm/processor.h
@@ -13,10 +13,13 @@
#ifndef _ASM_PROCESSOR_H
#define _ASM_PROCESSOR_H
+#include <linux/threads.h>
+#include <linux/thread_info.h>
#include <asm/page.h>
#include <asm/ptrace.h>
#include <asm/cpu-regs.h>
-#include <linux/threads.h>
+#include <asm/uaccess.h>
+#include <asm/current.h>
/* Forward declaration, a strange C thing */
struct task_struct;
@@ -33,6 +36,8 @@ struct mm_struct;
__pc; \
})
+extern void get_mem_info(unsigned long *mem_base, unsigned long *mem_size);
+
extern void show_registers(struct pt_regs *regs);
/*
@@ -43,17 +48,22 @@ extern void show_registers(struct pt_regs *regs);
struct mn10300_cpuinfo {
int type;
- unsigned long loops_per_sec;
+ unsigned long loops_per_jiffy;
char hard_math;
- unsigned long *pgd_quick;
- unsigned long *pte_quick;
- unsigned long pgtable_cache_sz;
};
extern struct mn10300_cpuinfo boot_cpu_data;
+#ifdef CONFIG_SMP
+#if CONFIG_NR_CPUS < 2 || CONFIG_NR_CPUS > 8
+# error Sorry, NR_CPUS should be 2 to 8
+#endif
+extern struct mn10300_cpuinfo cpu_data[];
+#define current_cpu_data cpu_data[smp_processor_id()]
+#else /* CONFIG_SMP */
#define cpu_data &boot_cpu_data
#define current_cpu_data boot_cpu_data
+#endif /* CONFIG_SMP */
extern void identify_cpu(struct mn10300_cpuinfo *);
extern void print_cpu_info(struct mn10300_cpuinfo *);
@@ -76,10 +86,6 @@ extern void dodgy_tsc(void);
*/
#define TASK_UNMAPPED_BASE 0x30000000
-typedef struct {
- unsigned long seg;
-} mm_segment_t;
-
struct fpu_state_struct {
unsigned long fs[32]; /* fpu registers */
unsigned long fpcr; /* fpu control register */
@@ -92,20 +98,19 @@ struct thread_struct {
unsigned long a3; /* kernel FP */
unsigned long wchan;
unsigned long usp;
- struct pt_regs *__frame;
unsigned long fpu_flags;
#define THREAD_USING_FPU 0x00000001 /* T if this task is using the FPU */
+#define THREAD_HAS_FPU 0x00000002 /* T if this task owns the FPU right now */
struct fpu_state_struct fpu_state;
};
-#define INIT_THREAD \
-{ \
- .uregs = init_uregs, \
- .pc = 0, \
- .sp = 0, \
- .a3 = 0, \
- .wchan = 0, \
- .__frame = NULL, \
+#define INIT_THREAD \
+{ \
+ .uregs = init_uregs, \
+ .pc = 0, \
+ .sp = 0, \
+ .a3 = 0, \
+ .wchan = 0, \
}
#define INIT_MMAP \
@@ -117,13 +122,20 @@ struct thread_struct {
* - need to discard the frame stacked by the kernel thread invoking the execve
* syscall (see RESTORE_ALL macro)
*/
-#define start_thread(regs, new_pc, new_sp) do { \
- set_fs(USER_DS); \
- __frame = current->thread.uregs; \
- __frame->epsw = EPSW_nSL | EPSW_IE | EPSW_IM; \
- __frame->pc = new_pc; \
- __frame->sp = new_sp; \
-} while (0)
+static inline void start_thread(struct pt_regs *regs,
+ unsigned long new_pc, unsigned long new_sp)
+{
+ struct thread_info *ti = current_thread_info();
+ struct pt_regs *frame0;
+ set_fs(USER_DS);
+
+ frame0 = thread_info_to_uregs(ti);
+ frame0->epsw = EPSW_nSL | EPSW_IE | EPSW_IM;
+ frame0->pc = new_pc;
+ frame0->sp = new_sp;
+ ti->frame = frame0;
+}
+
/* Free all resources held by a thread. */
extern void release_thread(struct task_struct *);
@@ -157,7 +169,7 @@ unsigned long get_wchan(struct task_struct *p);
static inline void prefetch(const void *x)
{
-#ifndef CONFIG_MN10300_CACHE_DISABLED
+#ifdef CONFIG_MN10300_CACHE_ENABLED
#ifdef CONFIG_MN10300_PROC_MN103E010
asm volatile ("nop; nop; dcpf (%0)" : : "r"(x));
#else
@@ -168,7 +180,7 @@ static inline void prefetch(const void *x)
static inline void prefetchw(const void *x)
{
-#ifndef CONFIG_MN10300_CACHE_DISABLED
+#ifdef CONFIG_MN10300_CACHE_ENABLED
#ifdef CONFIG_MN10300_PROC_MN103E010
asm volatile ("nop; nop; dcpf (%0)" : : "r"(x));
#else
diff --git a/arch/mn10300/include/asm/ptrace.h b/arch/mn10300/include/asm/ptrace.h
index 7c2e911052b6..b6961811d445 100644
--- a/arch/mn10300/include/asm/ptrace.h
+++ b/arch/mn10300/include/asm/ptrace.h
@@ -40,7 +40,6 @@
#define PT_PC 26
#define NR_PTREGS 27
-#ifndef __ASSEMBLY__
/*
* This defines the way registers are stored in the event of an exception
* - the strange order is due to the MOVM instruction
@@ -75,7 +74,6 @@ struct pt_regs {
unsigned long epsw;
unsigned long pc;
};
-#endif
/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
#define PTRACE_GETREGS 12
@@ -86,12 +84,7 @@ struct pt_regs {
/* options set using PTRACE_SETOPTIONS */
#define PTRACE_O_TRACESYSGOOD 0x00000001
-#if defined(__KERNEL__)
-
-extern struct pt_regs *__frame; /* current frame pointer */
-
-#if !defined(__ASSEMBLY__)
-struct task_struct;
+#ifdef __KERNEL__
#define user_mode(regs) (((regs)->epsw & EPSW_nSL) == EPSW_nSL)
#define instruction_pointer(regs) ((regs)->pc)
@@ -100,9 +93,7 @@ extern void show_regs(struct pt_regs *);
#define arch_has_single_step() (1)
-#endif /* !__ASSEMBLY */
-
#define profile_pc(regs) ((regs)->pc)
-#endif /* __KERNEL__ */
+#endif /* __KERNEL__ */
#endif /* _ASM_PTRACE_H */
diff --git a/arch/mn10300/include/asm/reset-regs.h b/arch/mn10300/include/asm/reset-regs.h
index 174523d50132..10c7502a113f 100644
--- a/arch/mn10300/include/asm/reset-regs.h
+++ b/arch/mn10300/include/asm/reset-regs.h
@@ -50,7 +50,7 @@ static inline void mn10300_proc_hard_reset(void)
RSTCTR |= RSTCTR_CHIPRST;
}
-extern unsigned int watchdog_alert_counter;
+extern unsigned int watchdog_alert_counter[];
extern void watchdog_go(void);
extern asmlinkage void watchdog_handler(void);
diff --git a/arch/mn10300/include/asm/rtc.h b/arch/mn10300/include/asm/rtc.h
index c295194cc703..6c14bb1d0d9b 100644
--- a/arch/mn10300/include/asm/rtc.h
+++ b/arch/mn10300/include/asm/rtc.h
@@ -15,25 +15,14 @@
#include <linux/init.h>
-extern void check_rtc_time(void);
extern void __init calibrate_clock(void);
-extern unsigned long __init get_initial_rtc_time(void);
#else /* !CONFIG_MN10300_RTC */
-static inline void check_rtc_time(void)
-{
-}
-
static inline void calibrate_clock(void)
{
}
-static inline unsigned long get_initial_rtc_time(void)
-{
- return 0;
-}
-
#endif /* !CONFIG_MN10300_RTC */
#include <asm-generic/rtc.h>
diff --git a/arch/mn10300/include/asm/rwlock.h b/arch/mn10300/include/asm/rwlock.h
new file mode 100644
index 000000000000..6d594d4a0e10
--- /dev/null
+++ b/arch/mn10300/include/asm/rwlock.h
@@ -0,0 +1,125 @@
+/*
+ * Helpers used by both rw spinlocks and rw semaphores.
+ *
+ * Based in part on code from semaphore.h and
+ * spinlock.h Copyright 1996 Linus Torvalds.
+ *
+ * Copyright 1999 Red Hat, Inc.
+ *
+ * Written by Benjamin LaHaise.
+ *
+ * Modified by Matsushita Electric Industrial Co., Ltd.
+ * Modifications:
+ * 13-Nov-2006 MEI Temporarily delete lock functions for SMP support.
+ *
+ * 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.
+ */
+#ifndef _ASM_RWLOCK_H
+#define _ASM_RWLOCK_H
+
+#define RW_LOCK_BIAS 0x01000000
+
+#ifndef CONFIG_SMP
+
+typedef struct { unsigned long a[100]; } __dummy_lock_t;
+#define __dummy_lock(lock) (*(__dummy_lock_t *)(lock))
+
+#define RW_LOCK_BIAS_STR "0x01000000"
+
+#define __build_read_lock_ptr(rw, helper) \
+ do { \
+ asm volatile( \
+ " mov (%0),d3 \n" \
+ " sub 1,d3 \n" \
+ " mov d3,(%0) \n" \
+ " blt 1f \n" \
+ " bra 2f \n" \
+ "1: jmp 3f \n" \
+ "2: \n" \
+ " .section .text.lock,\"ax\" \n" \
+ "3: call "helper"[],0 \n" \
+ " jmp 2b \n" \
+ " .previous" \
+ : \
+ : "d" (rw) \
+ : "memory", "d3", "cc"); \
+ } while (0)
+
+#define __build_read_lock_const(rw, helper) \
+ do { \
+ asm volatile( \
+ " mov (%0),d3 \n" \
+ " sub 1,d3 \n" \
+ " mov d3,(%0) \n" \
+ " blt 1f \n" \
+ " bra 2f \n" \
+ "1: jmp 3f \n" \
+ "2: \n" \
+ " .section .text.lock,\"ax\" \n" \
+ "3: call "helper"[],0 \n" \
+ " jmp 2b \n" \
+ " .previous" \
+ : \
+ : "d" (rw) \
+ : "memory", "d3", "cc"); \
+ } while (0)
+
+#define __build_read_lock(rw, helper) \
+ do { \
+ if (__builtin_constant_p(rw)) \
+ __build_read_lock_const(rw, helper); \
+ else \
+ __build_read_lock_ptr(rw, helper); \
+ } while (0)
+
+#define __build_write_lock_ptr(rw, helper) \
+ do { \
+ asm volatile( \
+ " mov (%0),d3 \n" \
+ " sub 1,d3 \n" \
+ " mov d3,(%0) \n" \
+ " blt 1f \n" \
+ " bra 2f \n" \
+ "1: jmp 3f \n" \
+ "2: \n" \
+ " .section .text.lock,\"ax\" \n" \
+ "3: call "helper"[],0 \n" \
+ " jmp 2b \n" \
+ " .previous" \
+ : \
+ : "d" (rw) \
+ : "memory", "d3", "cc"); \
+ } while (0)
+
+#define __build_write_lock_const(rw, helper) \
+ do { \
+ asm volatile( \
+ " mov (%0),d3 \n" \
+ " sub 1,d3 \n" \
+ " mov d3,(%0) \n" \
+ " blt 1f \n" \
+ " bra 2f \n" \
+ "1: jmp 3f \n" \
+ "2: \n" \
+ " .section .text.lock,\"ax\" \n" \
+ "3: call "helper"[],0 \n" \
+ " jmp 2b \n" \
+ " .previous" \
+ : \
+ : "d" (rw) \
+ : "memory", "d3", "cc"); \
+ } while (0)
+
+#define __build_write_lock(rw, helper) \
+ do { \
+ if (__builtin_constant_p(rw)) \
+ __build_write_lock_const(rw, helper); \
+ else \
+ __build_write_lock_ptr(rw, helper); \
+ } while (0)
+
+#endif /* CONFIG_SMP */
+#endif /* _ASM_RWLOCK_H */
diff --git a/arch/mn10300/include/asm/serial-regs.h b/arch/mn10300/include/asm/serial-regs.h
index 6498469e93ac..8320cda32f5a 100644
--- a/arch/mn10300/include/asm/serial-regs.h
+++ b/arch/mn10300/include/asm/serial-regs.h
@@ -20,18 +20,25 @@
/* serial port 0 */
#define SC0CTR __SYSREG(0xd4002000, u16) /* control reg */
#define SC01CTR_CK 0x0007 /* clock source select */
-#define SC0CTR_CK_TM8UFLOW_8 0x0000 /* - 1/8 timer 8 underflow (serial port 0 only) */
-#define SC1CTR_CK_TM9UFLOW_8 0x0000 /* - 1/8 timer 9 underflow (serial port 1 only) */
#define SC01CTR_CK_IOCLK_8 0x0001 /* - 1/8 IOCLK */
#define SC01CTR_CK_IOCLK_32 0x0002 /* - 1/32 IOCLK */
+#define SC01CTR_CK_EXTERN_8 0x0006 /* - 1/8 external closk */
+#define SC01CTR_CK_EXTERN 0x0007 /* - external closk */
+#if defined(CONFIG_AM33_2) || defined(CONFIG_AM33_3)
+#define SC0CTR_CK_TM8UFLOW_8 0x0000 /* - 1/8 timer 8 underflow (serial port 0 only) */
#define SC0CTR_CK_TM2UFLOW_2 0x0003 /* - 1/2 timer 2 underflow (serial port 0 only) */
-#define SC1CTR_CK_TM3UFLOW_2 0x0003 /* - 1/2 timer 3 underflow (serial port 1 only) */
-#define SC0CTR_CK_TM0UFLOW_8 0x0004 /* - 1/8 timer 1 underflow (serial port 0 only) */
-#define SC1CTR_CK_TM1UFLOW_8 0x0004 /* - 1/8 timer 2 underflow (serial port 1 only) */
+#define SC0CTR_CK_TM0UFLOW_8 0x0004 /* - 1/8 timer 0 underflow (serial port 0 only) */
#define SC0CTR_CK_TM2UFLOW_8 0x0005 /* - 1/8 timer 2 underflow (serial port 0 only) */
+#define SC1CTR_CK_TM9UFLOW_8 0x0000 /* - 1/8 timer 9 underflow (serial port 1 only) */
+#define SC1CTR_CK_TM3UFLOW_2 0x0003 /* - 1/2 timer 3 underflow (serial port 1 only) */
+#define SC1CTR_CK_TM1UFLOW_8 0x0004 /* - 1/8 timer 1 underflow (serial port 1 only) */
#define SC1CTR_CK_TM3UFLOW_8 0x0005 /* - 1/8 timer 3 underflow (serial port 1 only) */
-#define SC01CTR_CK_EXTERN_8 0x0006 /* - 1/8 external closk */
-#define SC01CTR_CK_EXTERN 0x0007 /* - external closk */
+#else /* CONFIG_AM33_2 || CONFIG_AM33_3 */
+#define SC0CTR_CK_TM8UFLOW_8 0x0000 /* - 1/8 timer 8 underflow (serial port 0 only) */
+#define SC0CTR_CK_TM0UFLOW_8 0x0004 /* - 1/8 timer 0 underflow (serial port 0 only) */
+#define SC0CTR_CK_TM2UFLOW_8 0x0005 /* - 1/8 timer 2 underflow (serial port 0 only) */
+#define SC1CTR_CK_TM12UFLOW_8 0x0000 /* - 1/8 timer 12 underflow (serial port 1 only) */
+#endif /* CONFIG_AM33_2 || CONFIG_AM33_3 */
#define SC01CTR_STB 0x0008 /* stop bit select */
#define SC01CTR_STB_1BIT 0x0000 /* - 1 stop bit */
#define SC01CTR_STB_2BIT 0x0008 /* - 2 stop bits */
@@ -100,11 +107,23 @@
/* serial port 2 */
#define SC2CTR __SYSREG(0xd4002020, u16) /* control reg */
+#ifdef CONFIG_AM33_2
#define SC2CTR_CK 0x0003 /* clock source select */
#define SC2CTR_CK_TM10UFLOW 0x0000 /* - timer 10 underflow */
#define SC2CTR_CK_TM2UFLOW 0x0001 /* - timer 2 underflow */
#define SC2CTR_CK_EXTERN 0x0002 /* - external closk */
#define SC2CTR_CK_TM3UFLOW 0x0003 /* - timer 3 underflow */
+#else /* CONFIG_AM33_2 */
+#define SC2CTR_CK 0x0007 /* clock source select */
+#define SC2CTR_CK_TM9UFLOW_8 0x0000 /* - 1/8 timer 9 underflow */
+#define SC2CTR_CK_IOCLK_8 0x0001 /* - 1/8 IOCLK */
+#define SC2CTR_CK_IOCLK_32 0x0002 /* - 1/32 IOCLK */
+#define SC2CTR_CK_TM3UFLOW_2 0x0003 /* - 1/2 timer 3 underflow */
+#define SC2CTR_CK_TM1UFLOW_8 0x0004 /* - 1/8 timer 1 underflow */
+#define SC2CTR_CK_TM3UFLOW_8 0x0005 /* - 1/8 timer 3 underflow */
+#define SC2CTR_CK_EXTERN_8 0x0006 /* - 1/8 external closk */
+#define SC2CTR_CK_EXTERN 0x0007 /* - external closk */
+#endif /* CONFIG_AM33_2 */
#define SC2CTR_STB 0x0008 /* stop bit select */
#define SC2CTR_STB_1BIT 0x0000 /* - 1 stop bit */
#define SC2CTR_STB_2BIT 0x0008 /* - 2 stop bits */
@@ -134,9 +153,14 @@
#define SC2ICR_RES 0x04 /* receive error select */
#define SC2ICR_RI 0x01 /* receive interrupt cause */
-#define SC2TXB __SYSREG(0xd4002018, u8) /* transmit buffer reg */
-#define SC2RXB __SYSREG(0xd4002019, u8) /* receive buffer reg */
-#define SC2STR __SYSREG(0xd400201c, u8) /* status reg */
+#define SC2TXB __SYSREG(0xd4002028, u8) /* transmit buffer reg */
+#define SC2RXB __SYSREG(0xd4002029, u8) /* receive buffer reg */
+
+#ifdef CONFIG_AM33_2
+#define SC2STR __SYSREG(0xd400202c, u8) /* status reg */
+#else /* CONFIG_AM33_2 */
+#define SC2STR __SYSREG(0xd400202c, u16) /* status reg */
+#endif /* CONFIG_AM33_2 */
#define SC2STR_OEF 0x0001 /* overrun error found */
#define SC2STR_PEF 0x0002 /* parity error found */
#define SC2STR_FEF 0x0004 /* framing error found */
@@ -146,10 +170,17 @@
#define SC2STR_RXF 0x0040 /* receive status */
#define SC2STR_TXF 0x0080 /* transmit status */
+#ifdef CONFIG_AM33_2
#define SC2TIM __SYSREG(0xd400202d, u8) /* status reg */
+#endif
+#ifdef CONFIG_AM33_2
#define SC2RXIRQ 24 /* serial 2 Receive IRQ */
#define SC2TXIRQ 25 /* serial 2 Transmit IRQ */
+#else /* CONFIG_AM33_2 */
+#define SC2RXIRQ 68 /* serial 2 Receive IRQ */
+#define SC2TXIRQ 69 /* serial 2 Transmit IRQ */
+#endif /* CONFIG_AM33_2 */
#define SC2RXICR GxICR(SC2RXIRQ) /* serial 2 receive intr ctrl reg */
#define SC2TXICR GxICR(SC2TXIRQ) /* serial 2 transmit intr ctrl reg */
diff --git a/arch/mn10300/include/asm/serial.h b/arch/mn10300/include/asm/serial.h
index a29445cddd6f..23a799293599 100644
--- a/arch/mn10300/include/asm/serial.h
+++ b/arch/mn10300/include/asm/serial.h
@@ -9,10 +9,8 @@
* 2 of the Licence, or (at your option) any later version.
*/
-/*
- * The ASB2305 has an 18.432 MHz clock the UART
- */
-#define BASE_BAUD (18432000 / 16)
+#ifndef _ASM_SERIAL_H
+#define _ASM_SERIAL_H
/* Standard COM flags (except for COM4, because of the 8514 problem) */
#ifdef CONFIG_SERIAL_DETECT_IRQ
@@ -34,3 +32,5 @@
#endif
#include <unit/serial.h>
+
+#endif /* _ASM_SERIAL_H */
diff --git a/arch/mn10300/include/asm/smp.h b/arch/mn10300/include/asm/smp.h
index 4eb8c61b7dab..a3930e43a958 100644
--- a/arch/mn10300/include/asm/smp.h
+++ b/arch/mn10300/include/asm/smp.h
@@ -3,6 +3,16 @@
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
+ * Modified by Matsushita Electric Industrial Co., Ltd.
+ * Modifications:
+ * 13-Nov-2006 MEI Define IPI-IRQ number and add inline/macro function
+ * for SMP support.
+ * 22-Jan-2007 MEI Add the define related to SMP_BOOT_IRQ.
+ * 23-Feb-2007 MEI Add the define related to SMP icahce invalidate.
+ * 23-Jun-2008 MEI Delete INTC_IPI.
+ * 22-Jul-2008 MEI Add smp_nmi_call_function and related defines.
+ * 04-Aug-2008 MEI Delete USE_DOIRQ_CACHE_IPI.
+ *
* 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
@@ -11,8 +21,85 @@
#ifndef _ASM_SMP_H
#define _ASM_SMP_H
-#ifdef CONFIG_SMP
-#error SMP not yet supported for MN10300
+#ifndef __ASSEMBLY__
+#include <linux/threads.h>
+#include <linux/cpumask.h>
#endif
+#ifdef CONFIG_SMP
+#include <proc/smp-regs.h>
+
+#define RESCHEDULE_IPI 63
+#define CALL_FUNC_SINGLE_IPI 192
+#define LOCAL_TIMER_IPI 193
+#define FLUSH_CACHE_IPI 194
+#define CALL_FUNCTION_NMI_IPI 195
+#define GDB_NMI_IPI 196
+
+#define SMP_BOOT_IRQ 195
+
+#define RESCHEDULE_GxICR_LV GxICR_LEVEL_6
+#define CALL_FUNCTION_GxICR_LV GxICR_LEVEL_4
+#define LOCAL_TIMER_GxICR_LV GxICR_LEVEL_4
+#define FLUSH_CACHE_GxICR_LV GxICR_LEVEL_0
+#define SMP_BOOT_GxICR_LV GxICR_LEVEL_0
+
+#define TIME_OUT_COUNT_BOOT_IPI 100
+#define DELAY_TIME_BOOT_IPI 75000
+
+
+#ifndef __ASSEMBLY__
+
+/**
+ * raw_smp_processor_id - Determine the raw CPU ID of the CPU running it
+ *
+ * What we really want to do is to use the CPUID hardware CPU register to get
+ * this information, but accesses to that aren't cached, and run at system bus
+ * speed, not CPU speed. A copy of this value is, however, stored in the
+ * thread_info struct, and that can be cached.
+ *
+ * An alternate way of dealing with this could be to use the EPSW.S bits to
+ * cache this information for systems with up to four CPUs.
+ */
+#if 0
+#define raw_smp_processor_id() (CPUID)
+#else
+#define raw_smp_processor_id() (current_thread_info()->cpu)
#endif
+
+static inline int cpu_logical_map(int cpu)
+{
+ return cpu;
+}
+
+static inline int cpu_number_map(int cpu)
+{
+ return cpu;
+}
+
+
+extern cpumask_t cpu_boot_map;
+
+extern void smp_init_cpus(void);
+extern void smp_cache_interrupt(void);
+extern void send_IPI_allbutself(int irq);
+extern int smp_nmi_call_function(smp_call_func_t func, void *info, int wait);
+
+extern void arch_send_call_function_single_ipi(int cpu);
+extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
+
+#ifdef CONFIG_HOTPLUG_CPU
+extern int __cpu_disable(void);
+extern void __cpu_die(unsigned int cpu);
+#endif /* CONFIG_HOTPLUG_CPU */
+
+#endif /* __ASSEMBLY__ */
+#else /* CONFIG_SMP */
+#ifndef __ASSEMBLY__
+
+static inline void smp_init_cpus(void) {}
+
+#endif /* __ASSEMBLY__ */
+#endif /* CONFIG_SMP */
+
+#endif /* _ASM_SMP_H */
diff --git a/arch/mn10300/include/asm/smsc911x.h b/arch/mn10300/include/asm/smsc911x.h
new file mode 100644
index 000000000000..2fcd1080322b
--- /dev/null
+++ b/arch/mn10300/include/asm/smsc911x.h
@@ -0,0 +1 @@
+#include <unit/smsc911x.h>
diff --git a/arch/mn10300/include/asm/spinlock.h b/arch/mn10300/include/asm/spinlock.h
index 4bf9c8b169e0..93429154e898 100644
--- a/arch/mn10300/include/asm/spinlock.h
+++ b/arch/mn10300/include/asm/spinlock.h
@@ -11,6 +11,183 @@
#ifndef _ASM_SPINLOCK_H
#define _ASM_SPINLOCK_H
-#error SMP spinlocks not implemented for MN10300
+#include <asm/atomic.h>
+#include <asm/rwlock.h>
+#include <asm/page.h>
+/*
+ * Simple spin lock operations. There are two variants, one clears IRQ's
+ * on the local processor, one does not.
+ *
+ * We make no fairness assumptions. They have a cost.
+ */
+
+#define arch_spin_is_locked(x) (*(volatile signed char *)(&(x)->slock) != 0)
+#define arch_spin_unlock_wait(x) do { barrier(); } while (arch_spin_is_locked(x))
+
+static inline void arch_spin_unlock(arch_spinlock_t *lock)
+{
+ asm volatile(
+ " bclr 1,(0,%0) \n"
+ :
+ : "a"(&lock->slock)
+ : "memory", "cc");
+}
+
+static inline int arch_spin_trylock(arch_spinlock_t *lock)
+{
+ int ret;
+
+ asm volatile(
+ " mov 1,%0 \n"
+ " bset %0,(%1) \n"
+ " bne 1f \n"
+ " clr %0 \n"
+ "1: xor 1,%0 \n"
+ : "=d"(ret)
+ : "a"(&lock->slock)
+ : "memory", "cc");
+
+ return ret;
+}
+
+static inline void arch_spin_lock(arch_spinlock_t *lock)
+{
+ asm volatile(
+ "1: bset 1,(0,%0) \n"
+ " bne 1b \n"
+ :
+ : "a"(&lock->slock)
+ : "memory", "cc");
+}
+
+static inline void arch_spin_lock_flags(arch_spinlock_t *lock,
+ unsigned long flags)
+{
+ int temp;
+
+ asm volatile(
+ "1: bset 1,(0,%2) \n"
+ " beq 3f \n"
+ " mov %1,epsw \n"
+ "2: mov (0,%2),%0 \n"
+ " or %0,%0 \n"
+ " bne 2b \n"
+ " mov %3,%0 \n"
+ " mov %0,epsw \n"
+ " nop \n"
+ " nop \n"
+ " bra 1b\n"
+ "3: \n"
+ : "=&d" (temp)
+ : "d" (flags), "a"(&lock->slock), "i"(EPSW_IE | MN10300_CLI_LEVEL)
+ : "memory", "cc");
+}
+
+#ifdef __KERNEL__
+
+/*
+ * Read-write spinlocks, allowing multiple readers
+ * but only one writer.
+ *
+ * NOTE! it is quite common to have readers in interrupts
+ * but no interrupt writers. For those circumstances we
+ * can "mix" irq-safe locks - any writer needs to get a
+ * irq-safe write-lock, but readers can get non-irqsafe
+ * read-locks.
+ */
+
+/**
+ * read_can_lock - would read_trylock() succeed?
+ * @lock: the rwlock in question.
+ */
+#define arch_read_can_lock(x) ((int)(x)->lock > 0)
+
+/**
+ * write_can_lock - would write_trylock() succeed?
+ * @lock: the rwlock in question.
+ */
+#define arch_write_can_lock(x) ((x)->lock == RW_LOCK_BIAS)
+
+/*
+ * On mn10300, we implement read-write locks as a 32-bit counter
+ * with the high bit (sign) being the "contended" bit.
+ */
+static inline void arch_read_lock(arch_rwlock_t *rw)
+{
+#if 0 //def CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT
+ __build_read_lock(rw, "__read_lock_failed");
+#else
+ {
+ atomic_t *count = (atomic_t *)rw;
+ while (atomic_dec_return(count) < 0)
+ atomic_inc(count);
+ }
+#endif
+}
+
+static inline void arch_write_lock(arch_rwlock_t *rw)
+{
+#if 0 //def CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT
+ __build_write_lock(rw, "__write_lock_failed");
+#else
+ {
+ atomic_t *count = (atomic_t *)rw;
+ while (!atomic_sub_and_test(RW_LOCK_BIAS, count))
+ atomic_add(RW_LOCK_BIAS, count);
+ }
+#endif
+}
+
+static inline void arch_read_unlock(arch_rwlock_t *rw)
+{
+#if 0 //def CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT
+ __build_read_unlock(rw);
+#else
+ {
+ atomic_t *count = (atomic_t *)rw;
+ atomic_inc(count);
+ }
+#endif
+}
+
+static inline void arch_write_unlock(arch_rwlock_t *rw)
+{
+#if 0 //def CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT
+ __build_write_unlock(rw);
+#else
+ {
+ atomic_t *count = (atomic_t *)rw;
+ atomic_add(RW_LOCK_BIAS, count);
+ }
+#endif
+}
+
+static inline int arch_read_trylock(arch_rwlock_t *lock)
+{
+ atomic_t *count = (atomic_t *)lock;
+ atomic_dec(count);
+ if (atomic_read(count) >= 0)
+ return 1;
+ atomic_inc(count);
+ return 0;
+}
+
+static inline int arch_write_trylock(arch_rwlock_t *lock)
+{
+ atomic_t *count = (atomic_t *)lock;
+ if (atomic_sub_and_test(RW_LOCK_BIAS, count))
+ return 1;
+ atomic_add(RW_LOCK_BIAS, count);
+ return 0;
+}
+
+#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
+#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
+
+#define _raw_spin_relax(lock) cpu_relax()
+#define _raw_read_relax(lock) cpu_relax()
+#define _raw_write_relax(lock) cpu_relax()
+
+#endif /* __KERNEL__ */
#endif /* _ASM_SPINLOCK_H */
diff --git a/arch/mn10300/include/asm/spinlock_types.h b/arch/mn10300/include/asm/spinlock_types.h
new file mode 100644
index 000000000000..653dc519b405
--- /dev/null
+++ b/arch/mn10300/include/asm/spinlock_types.h
@@ -0,0 +1,20 @@
+#ifndef _ASM_SPINLOCK_TYPES_H
+#define _ASM_SPINLOCK_TYPES_H
+
+#ifndef __LINUX_SPINLOCK_TYPES_H
+# error "please don't include this file directly"
+#endif
+
+typedef struct arch_spinlock {
+ unsigned int slock;
+} arch_spinlock_t;
+
+#define __ARCH_SPIN_LOCK_UNLOCKED { 0 }
+
+typedef struct {
+ unsigned int lock;
+} arch_rwlock_t;
+
+#define __ARCH_RW_LOCK_UNLOCKED { RW_LOCK_BIAS }
+
+#endif /* _ASM_SPINLOCK_TYPES_H */
diff --git a/arch/mn10300/include/asm/system.h b/arch/mn10300/include/asm/system.h
index 3636c054dcd5..8ff3e5aaca41 100644
--- a/arch/mn10300/include/asm/system.h
+++ b/arch/mn10300/include/asm/system.h
@@ -12,11 +12,29 @@
#define _ASM_SYSTEM_H
#include <asm/cpu-regs.h>
+#include <asm/intctl-regs.h>
#ifdef __KERNEL__
#ifndef __ASSEMBLY__
#include <linux/kernel.h>
+#include <linux/irqflags.h>
+#include <asm/atomic.h>
+
+#if !defined(CONFIG_LAZY_SAVE_FPU)
+struct fpu_state_struct;
+extern asmlinkage void fpu_save(struct fpu_state_struct *);
+#define switch_fpu(prev, next) \
+ do { \
+ if ((prev)->thread.fpu_flags & THREAD_HAS_FPU) { \
+ (prev)->thread.fpu_flags &= ~THREAD_HAS_FPU; \
+ (prev)->thread.uregs->epsw &= ~EPSW_FE; \
+ fpu_save(&(prev)->thread.fpu_state); \
+ } \
+ } while (0)
+#else
+#define switch_fpu(prev, next) do {} while (0)
+#endif
struct task_struct;
struct thread_struct;
@@ -29,6 +47,7 @@ struct task_struct *__switch_to(struct thread_struct *prev,
/* context switching is now performed out-of-line in switch_to.S */
#define switch_to(prev, next, last) \
do { \
+ switch_fpu(prev, next); \
current->thread.wchan = (u_long) __builtin_return_address(0); \
(last) = __switch_to(&(prev)->thread, &(next)->thread, (prev)); \
mb(); \
@@ -39,8 +58,6 @@ do { \
#define nop() asm volatile ("nop")
-#endif /* !__ASSEMBLY__ */
-
/*
* Force strict CPU ordering.
* And yes, this is required on UP too when we're talking
@@ -67,172 +84,19 @@ do { \
#define smp_mb() mb()
#define smp_rmb() rmb()
#define smp_wmb() wmb()
-#else
+#define set_mb(var, value) do { xchg(&var, value); } while (0)
+#else /* CONFIG_SMP */
#define smp_mb() barrier()
#define smp_rmb() barrier()
#define smp_wmb() barrier()
-#endif
-
#define set_mb(var, value) do { var = value; mb(); } while (0)
+#endif /* CONFIG_SMP */
+
#define set_wmb(var, value) do { var = value; wmb(); } while (0)
#define read_barrier_depends() do {} while (0)
#define smp_read_barrier_depends() do {} while (0)
-/*****************************************************************************/
-/*
- * 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__
-
-struct __xchg_dummy { unsigned long a[100]; };
-#define __xg(x) ((struct __xchg_dummy *)(x))
-
-static inline
-unsigned long __xchg(volatile unsigned long *m, unsigned long val)
-{
- unsigned long retval;
- unsigned long flags;
-
- local_irq_save(flags);
- retval = *m;
- *m = val;
- local_irq_restore(flags);
- return retval;
-}
-
-#define xchg(ptr, v) \
- ((__typeof__(*(ptr))) __xchg((unsigned long *)(ptr), \
- (unsigned long)(v)))
-
-static inline unsigned long __cmpxchg(volatile unsigned long *m,
- unsigned long old, unsigned long new)
-{
- unsigned long retval;
- unsigned long flags;
-
- local_irq_save(flags);
- retval = *m;
- if (retval == old)
- *m = new;
- local_irq_restore(flags);
- return retval;
-}
-
-#define cmpxchg(ptr, o, n) \
- ((__typeof__(*(ptr))) __cmpxchg((unsigned long *)(ptr), \
- (unsigned long)(o), \
- (unsigned long)(n)))
-
#endif /* !__ASSEMBLY__ */
-
#endif /* __KERNEL__ */
#endif /* _ASM_SYSTEM_H */
diff --git a/arch/mn10300/include/asm/thread_info.h b/arch/mn10300/include/asm/thread_info.h
index 2001cb657a95..aa07a4a5d794 100644
--- a/arch/mn10300/include/asm/thread_info.h
+++ b/arch/mn10300/include/asm/thread_info.h
@@ -16,10 +16,6 @@
#include <asm/page.h>
-#ifndef __ASSEMBLY__
-#include <asm/processor.h>
-#endif
-
#define PREEMPT_ACTIVE 0x10000000
#ifdef CONFIG_4KSTACKS
@@ -38,10 +34,14 @@
* must also be changed
*/
#ifndef __ASSEMBLY__
+typedef struct {
+ unsigned long seg;
+} mm_segment_t;
struct thread_info {
struct task_struct *task; /* main task structure */
struct exec_domain *exec_domain; /* execution domain */
+ struct pt_regs *frame; /* current exception frame */
unsigned long flags; /* low level flags */
__u32 cpu; /* current CPU */
__s32 preempt_count; /* 0 => preemptable, <0 => BUG */
@@ -55,6 +55,10 @@ struct thread_info {
__u8 supervisor_stack[0];
};
+#define thread_info_to_uregs(ti) \
+ ((struct pt_regs *) \
+ ((unsigned long)ti + THREAD_SIZE - sizeof(struct pt_regs)))
+
#else /* !__ASSEMBLY__ */
#ifndef __ASM_OFFSETS_H__
@@ -102,6 +106,12 @@ struct thread_info *current_thread_info(void)
return ti;
}
+static inline __attribute__((const))
+struct pt_regs *current_frame(void)
+{
+ return current_thread_info()->frame;
+}
+
/* how to get the current stack pointer from C */
static inline unsigned long current_stack_pointer(void)
{
diff --git a/arch/mn10300/include/asm/timer-regs.h b/arch/mn10300/include/asm/timer-regs.h
index 1d883b7f94ab..c634977caf66 100644
--- a/arch/mn10300/include/asm/timer-regs.h
+++ b/arch/mn10300/include/asm/timer-regs.h
@@ -17,21 +17,27 @@
#ifdef __KERNEL__
-/* timer prescalar control */
+/*
+ * Timer prescalar control
+ */
#define TMPSCNT __SYSREG(0xd4003071, u8) /* timer prescaler control */
#define TMPSCNT_ENABLE 0x80 /* timer prescaler enable */
#define TMPSCNT_DISABLE 0x00 /* timer prescaler disable */
-/* 8 bit timers */
+/*
+ * 8-bit timers
+ */
#define TM0MD __SYSREG(0xd4003000, u8) /* timer 0 mode register */
#define TM0MD_SRC 0x07 /* timer source */
#define TM0MD_SRC_IOCLK 0x00 /* - IOCLK */
#define TM0MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */
#define TM0MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */
-#define TM0MD_SRC_TM2IO 0x03 /* - TM2IO pin input */
#define TM0MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */
#define TM0MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */
+#if defined(CONFIG_AM33_2)
+#define TM0MD_SRC_TM2IO 0x03 /* - TM2IO pin input */
#define TM0MD_SRC_TM0IO 0x07 /* - TM0IO pin input */
+#endif /* CONFIG_AM33_2 */
#define TM0MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
#define TM0MD_COUNT_ENABLE 0x80 /* timer count enable */
@@ -43,7 +49,9 @@
#define TM1MD_SRC_TM0CASCADE 0x03 /* - cascade with timer 0 */
#define TM1MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */
#define TM1MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */
+#if defined(CONFIG_AM33_2)
#define TM1MD_SRC_TM1IO 0x07 /* - TM1IO pin input */
+#endif /* CONFIG_AM33_2 */
#define TM1MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
#define TM1MD_COUNT_ENABLE 0x80 /* timer count enable */
@@ -55,7 +63,9 @@
#define TM2MD_SRC_TM1CASCADE 0x03 /* - cascade with timer 1 */
#define TM2MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */
#define TM2MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */
+#if defined(CONFIG_AM33_2)
#define TM2MD_SRC_TM2IO 0x07 /* - TM2IO pin input */
+#endif /* CONFIG_AM33_2 */
#define TM2MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
#define TM2MD_COUNT_ENABLE 0x80 /* timer count enable */
@@ -64,11 +74,13 @@
#define TM3MD_SRC_IOCLK 0x00 /* - IOCLK */
#define TM3MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */
#define TM3MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */
-#define TM3MD_SRC_TM1CASCADE 0x03 /* - cascade with timer 2 */
+#define TM3MD_SRC_TM2CASCADE 0x03 /* - cascade with timer 2 */
#define TM3MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */
#define TM3MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */
#define TM3MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */
+#if defined(CONFIG_AM33_2)
#define TM3MD_SRC_TM3IO 0x07 /* - TM3IO pin input */
+#endif /* CONFIG_AM33_2 */
#define TM3MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
#define TM3MD_COUNT_ENABLE 0x80 /* timer count enable */
@@ -96,7 +108,9 @@
#define TM2ICR GxICR(TM2IRQ) /* timer 2 uflow intr ctrl reg */
#define TM3ICR GxICR(TM3IRQ) /* timer 3 uflow intr ctrl reg */
-/* 16-bit timers 4,5 & 7-11 */
+/*
+ * 16-bit timers 4,5 & 7-15
+ */
#define TM4MD __SYSREG(0xd4003080, u8) /* timer 4 mode register */
#define TM4MD_SRC 0x07 /* timer source */
#define TM4MD_SRC_IOCLK 0x00 /* - IOCLK */
@@ -105,7 +119,9 @@
#define TM4MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */
#define TM4MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */
#define TM4MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */
+#if defined(CONFIG_AM33_2)
#define TM4MD_SRC_TM4IO 0x07 /* - TM4IO pin input */
+#endif /* CONFIG_AM33_2 */
#define TM4MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
#define TM4MD_COUNT_ENABLE 0x80 /* timer count enable */
@@ -118,7 +134,11 @@
#define TM5MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */
#define TM5MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */
#define TM5MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */
+#if defined(CONFIG_AM33_2)
#define TM5MD_SRC_TM5IO 0x07 /* - TM5IO pin input */
+#else /* !CONFIG_AM33_2 */
+#define TM5MD_SRC_TM7UFLOW 0x07 /* - timer 7 underflow */
+#endif /* CONFIG_AM33_2 */
#define TM5MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
#define TM5MD_COUNT_ENABLE 0x80 /* timer count enable */
@@ -130,7 +150,9 @@
#define TM7MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */
#define TM7MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */
#define TM7MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */
+#if defined(CONFIG_AM33_2)
#define TM7MD_SRC_TM7IO 0x07 /* - TM7IO pin input */
+#endif /* CONFIG_AM33_2 */
#define TM7MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
#define TM7MD_COUNT_ENABLE 0x80 /* timer count enable */
@@ -143,7 +165,11 @@
#define TM8MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */
#define TM8MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */
#define TM8MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */
+#if defined(CONFIG_AM33_2)
#define TM8MD_SRC_TM8IO 0x07 /* - TM8IO pin input */
+#else /* !CONFIG_AM33_2 */
+#define TM8MD_SRC_TM7UFLOW 0x07 /* - timer 7 underflow */
+#endif /* CONFIG_AM33_2 */
#define TM8MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
#define TM8MD_COUNT_ENABLE 0x80 /* timer count enable */
@@ -156,7 +182,11 @@
#define TM9MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */
#define TM9MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */
#define TM9MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */
+#if defined(CONFIG_AM33_2)
#define TM9MD_SRC_TM9IO 0x07 /* - TM9IO pin input */
+#else /* !CONFIG_AM33_2 */
+#define TM9MD_SRC_TM7UFLOW 0x07 /* - timer 7 underflow */
+#endif /* CONFIG_AM33_2 */
#define TM9MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
#define TM9MD_COUNT_ENABLE 0x80 /* timer count enable */
@@ -169,7 +199,11 @@
#define TM10MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */
#define TM10MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */
#define TM10MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */
+#if defined(CONFIG_AM33_2)
#define TM10MD_SRC_TM10IO 0x07 /* - TM10IO pin input */
+#else /* !CONFIG_AM33_2 */
+#define TM10MD_SRC_TM7UFLOW 0x07 /* - timer 7 underflow */
+#endif /* CONFIG_AM33_2 */
#define TM10MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
#define TM10MD_COUNT_ENABLE 0x80 /* timer count enable */
@@ -178,32 +212,101 @@
#define TM11MD_SRC_IOCLK 0x00 /* - IOCLK */
#define TM11MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */
#define TM11MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */
-#define TM11MD_SRC_TM7CASCADE 0x03 /* - cascade with timer 7 */
#define TM11MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */
#define TM11MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */
#define TM11MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */
+#if defined(CONFIG_AM33_2)
#define TM11MD_SRC_TM11IO 0x07 /* - TM11IO pin input */
+#else /* !CONFIG_AM33_2 */
+#define TM11MD_SRC_TM7UFLOW 0x07 /* - timer 7 underflow */
+#endif /* CONFIG_AM33_2 */
#define TM11MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
#define TM11MD_COUNT_ENABLE 0x80 /* timer count enable */
+#if defined(CONFIG_AM34_2)
+#define TM12MD __SYSREG(0xd4003180, u8) /* timer 11 mode register */
+#define TM12MD_SRC 0x07 /* timer source */
+#define TM12MD_SRC_IOCLK 0x00 /* - IOCLK */
+#define TM12MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */
+#define TM12MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */
+#define TM12MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */
+#define TM12MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */
+#define TM12MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */
+#define TM12MD_SRC_TM7UFLOW 0x07 /* - timer 7 underflow */
+#define TM12MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
+#define TM12MD_COUNT_ENABLE 0x80 /* timer count enable */
+
+#define TM13MD __SYSREG(0xd4003182, u8) /* timer 11 mode register */
+#define TM13MD_SRC 0x07 /* timer source */
+#define TM13MD_SRC_IOCLK 0x00 /* - IOCLK */
+#define TM13MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */
+#define TM13MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */
+#define TM13MD_SRC_TM12CASCADE 0x03 /* - cascade with timer 12 */
+#define TM13MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */
+#define TM13MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */
+#define TM13MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */
+#define TM13MD_SRC_TM7UFLOW 0x07 /* - timer 7 underflow */
+#define TM13MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
+#define TM13MD_COUNT_ENABLE 0x80 /* timer count enable */
+
+#define TM14MD __SYSREG(0xd4003184, u8) /* timer 11 mode register */
+#define TM14MD_SRC 0x07 /* timer source */
+#define TM14MD_SRC_IOCLK 0x00 /* - IOCLK */
+#define TM14MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */
+#define TM14MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */
+#define TM14MD_SRC_TM13CASCADE 0x03 /* - cascade with timer 13 */
+#define TM14MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */
+#define TM14MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */
+#define TM14MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */
+#define TM14MD_SRC_TM7UFLOW 0x07 /* - timer 7 underflow */
+#define TM14MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
+#define TM14MD_COUNT_ENABLE 0x80 /* timer count enable */
+
+#define TM15MD __SYSREG(0xd4003186, u8) /* timer 11 mode register */
+#define TM15MD_SRC 0x07 /* timer source */
+#define TM15MD_SRC_IOCLK 0x00 /* - IOCLK */
+#define TM15MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */
+#define TM15MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */
+#define TM15MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */
+#define TM15MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */
+#define TM15MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */
+#define TM15MD_SRC_TM7UFLOW 0x07 /* - timer 7 underflow */
+#define TM15MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
+#define TM15MD_COUNT_ENABLE 0x80 /* timer count enable */
+#endif /* CONFIG_AM34_2 */
+
+
#define TM4BR __SYSREG(0xd4003090, u16) /* timer 4 base register */
#define TM5BR __SYSREG(0xd4003092, u16) /* timer 5 base register */
+#define TM45BR __SYSREG(0xd4003090, u32) /* timer 4:5 base register */
#define TM7BR __SYSREG(0xd4003096, u16) /* timer 7 base register */
#define TM8BR __SYSREG(0xd4003098, u16) /* timer 8 base register */
#define TM9BR __SYSREG(0xd400309a, u16) /* timer 9 base register */
+#define TM89BR __SYSREG(0xd4003098, u32) /* timer 8:9 base register */
#define TM10BR __SYSREG(0xd400309c, u16) /* timer 10 base register */
#define TM11BR __SYSREG(0xd400309e, u16) /* timer 11 base register */
-#define TM45BR __SYSREG(0xd4003090, u32) /* timer 4:5 base register */
+#if defined(CONFIG_AM34_2)
+#define TM12BR __SYSREG(0xd4003190, u16) /* timer 12 base register */
+#define TM13BR __SYSREG(0xd4003192, u16) /* timer 13 base register */
+#define TM14BR __SYSREG(0xd4003194, u16) /* timer 14 base register */
+#define TM15BR __SYSREG(0xd4003196, u16) /* timer 15 base register */
+#endif /* CONFIG_AM34_2 */
#define TM4BC __SYSREG(0xd40030a0, u16) /* timer 4 binary counter */
#define TM5BC __SYSREG(0xd40030a2, u16) /* timer 5 binary counter */
#define TM45BC __SYSREG(0xd40030a0, u32) /* timer 4:5 binary counter */
-
#define TM7BC __SYSREG(0xd40030a6, u16) /* timer 7 binary counter */
#define TM8BC __SYSREG(0xd40030a8, u16) /* timer 8 binary counter */
#define TM9BC __SYSREG(0xd40030aa, u16) /* timer 9 binary counter */
+#define TM89BC __SYSREG(0xd40030a8, u32) /* timer 8:9 binary counter */
#define TM10BC __SYSREG(0xd40030ac, u16) /* timer 10 binary counter */
#define TM11BC __SYSREG(0xd40030ae, u16) /* timer 11 binary counter */
+#if defined(CONFIG_AM34_2)
+#define TM12BC __SYSREG(0xd40031a0, u16) /* timer 12 binary counter */
+#define TM13BC __SYSREG(0xd40031a2, u16) /* timer 13 binary counter */
+#define TM14BC __SYSREG(0xd40031a4, u16) /* timer 14 binary counter */
+#define TM15BC __SYSREG(0xd40031a6, u16) /* timer 15 binary counter */
+#endif /* CONFIG_AM34_2 */
#define TM4IRQ 6 /* timer 4 IRQ */
#define TM5IRQ 7 /* timer 5 IRQ */
@@ -212,6 +315,12 @@
#define TM9IRQ 13 /* timer 9 IRQ */
#define TM10IRQ 14 /* timer 10 IRQ */
#define TM11IRQ 15 /* timer 11 IRQ */
+#if defined(CONFIG_AM34_2)
+#define TM12IRQ 64 /* timer 12 IRQ */
+#define TM13IRQ 65 /* timer 13 IRQ */
+#define TM14IRQ 66 /* timer 14 IRQ */
+#define TM15IRQ 67 /* timer 15 IRQ */
+#endif /* CONFIG_AM34_2 */
#define TM4ICR GxICR(TM4IRQ) /* timer 4 uflow intr ctrl reg */
#define TM5ICR GxICR(TM5IRQ) /* timer 5 uflow intr ctrl reg */
@@ -220,8 +329,16 @@
#define TM9ICR GxICR(TM9IRQ) /* timer 9 uflow intr ctrl reg */
#define TM10ICR GxICR(TM10IRQ) /* timer 10 uflow intr ctrl reg */
#define TM11ICR GxICR(TM11IRQ) /* timer 11 uflow intr ctrl reg */
-
-/* 16-bit timer 6 */
+#if defined(CONFIG_AM34_2)
+#define TM12ICR GxICR(TM12IRQ) /* timer 12 uflow intr ctrl reg */
+#define TM13ICR GxICR(TM13IRQ) /* timer 13 uflow intr ctrl reg */
+#define TM14ICR GxICR(TM14IRQ) /* timer 14 uflow intr ctrl reg */
+#define TM15ICR GxICR(TM15IRQ) /* timer 15 uflow intr ctrl reg */
+#endif /* CONFIG_AM34_2 */
+
+/*
+ * 16-bit timer 6
+ */
#define TM6MD __SYSREG(0xd4003084, u16) /* timer6 mode register */
#define TM6MD_SRC 0x0007 /* timer source */
#define TM6MD_SRC_IOCLK 0x0000 /* - IOCLK */
@@ -229,10 +346,14 @@
#define TM6MD_SRC_IOCLK_32 0x0002 /* - 1/32 IOCLK */
#define TM6MD_SRC_TM0UFLOW 0x0004 /* - timer 0 underflow */
#define TM6MD_SRC_TM1UFLOW 0x0005 /* - timer 1 underflow */
-#define TM6MD_SRC_TM6IOB_BOTH 0x0006 /* - TM6IOB pin input (both edges) */
+#define TM6MD_SRC_TM2UFLOW 0x0006 /* - timer 2 underflow */
+#if defined(CONFIG_AM33_2)
+/* #define TM6MD_SRC_TM6IOB_BOTH 0x0006 */ /* - TM6IOB pin input (both edges) */
#define TM6MD_SRC_TM6IOB_SINGLE 0x0007 /* - TM6IOB pin input (single edge) */
-#define TM6MD_CLR_ENABLE 0x0010 /* clear count enable */
+#endif /* CONFIG_AM33_2 */
#define TM6MD_ONESHOT_ENABLE 0x0040 /* oneshot count */
+#define TM6MD_CLR_ENABLE 0x0010 /* clear count enable */
+#if defined(CONFIG_AM33_2)
#define TM6MD_TRIG_ENABLE 0x0080 /* TM6IOB pin trigger enable */
#define TM6MD_PWM 0x3800 /* PWM output mode */
#define TM6MD_PWM_DIS 0x0000 /* - disabled */
@@ -240,10 +361,15 @@
#define TM6MD_PWM_11BIT 0x1800 /* - 11 bits mode */
#define TM6MD_PWM_12BIT 0x3000 /* - 12 bits mode */
#define TM6MD_PWM_14BIT 0x3800 /* - 14 bits mode */
+#endif /* CONFIG_AM33_2 */
+
#define TM6MD_INIT_COUNTER 0x4000 /* initialize TMnBC to zero */
#define TM6MD_COUNT_ENABLE 0x8000 /* timer count enable */
#define TM6MDA __SYSREG(0xd40030b4, u8) /* timer6 cmp/cap A mode reg */
+#define TM6MDA_MODE_CMP_SINGLE 0x00 /* - compare, single buffer mode */
+#define TM6MDA_MODE_CMP_DOUBLE 0x40 /* - compare, double buffer mode */
+#if defined(CONFIG_AM33_2)
#define TM6MDA_OUT 0x07 /* output select */
#define TM6MDA_OUT_SETA_RESETB 0x00 /* - set at match A, reset at match B */
#define TM6MDA_OUT_SETA_RESETOV 0x01 /* - set at match A, reset at overflow */
@@ -251,30 +377,35 @@
#define TM6MDA_OUT_RESETA 0x03 /* - reset at match A */
#define TM6MDA_OUT_TOGGLE 0x04 /* - toggle on match A */
#define TM6MDA_MODE 0xc0 /* compare A register mode */
-#define TM6MDA_MODE_CMP_SINGLE 0x00 /* - compare, single buffer mode */
-#define TM6MDA_MODE_CMP_DOUBLE 0x40 /* - compare, double buffer mode */
#define TM6MDA_MODE_CAP_S_EDGE 0x80 /* - capture, single edge mode */
#define TM6MDA_MODE_CAP_D_EDGE 0xc0 /* - capture, double edge mode */
#define TM6MDA_EDGE 0x20 /* compare A edge select */
#define TM6MDA_EDGE_FALLING 0x00 /* capture on falling edge */
#define TM6MDA_EDGE_RISING 0x20 /* capture on rising edge */
#define TM6MDA_CAPTURE_ENABLE 0x10 /* capture enable */
+#else /* !CONFIG_AM33_2 */
+#define TM6MDA_MODE 0x40 /* compare A register mode */
+#endif /* CONFIG_AM33_2 */
#define TM6MDB __SYSREG(0xd40030b5, u8) /* timer6 cmp/cap B mode reg */
+#define TM6MDB_MODE_CMP_SINGLE 0x00 /* - compare, single buffer mode */
+#define TM6MDB_MODE_CMP_DOUBLE 0x40 /* - compare, double buffer mode */
+#if defined(CONFIG_AM33_2)
#define TM6MDB_OUT 0x07 /* output select */
#define TM6MDB_OUT_SETB_RESETA 0x00 /* - set at match B, reset at match A */
#define TM6MDB_OUT_SETB_RESETOV 0x01 /* - set at match B */
#define TM6MDB_OUT_RESETB 0x03 /* - reset at match B */
#define TM6MDB_OUT_TOGGLE 0x04 /* - toggle on match B */
#define TM6MDB_MODE 0xc0 /* compare B register mode */
-#define TM6MDB_MODE_CMP_SINGLE 0x00 /* - compare, single buffer mode */
-#define TM6MDB_MODE_CMP_DOUBLE 0x40 /* - compare, double buffer mode */
#define TM6MDB_MODE_CAP_S_EDGE 0x80 /* - capture, single edge mode */
#define TM6MDB_MODE_CAP_D_EDGE 0xc0 /* - capture, double edge mode */
#define TM6MDB_EDGE 0x20 /* compare B edge select */
#define TM6MDB_EDGE_FALLING 0x00 /* capture on falling edge */
#define TM6MDB_EDGE_RISING 0x20 /* capture on rising edge */
#define TM6MDB_CAPTURE_ENABLE 0x10 /* capture enable */
+#else /* !CONFIG_AM33_2 */
+#define TM6MDB_MODE 0x40 /* compare B register mode */
+#endif /* CONFIG_AM33_2 */
#define TM6CA __SYSREG(0xd40030c4, u16) /* timer6 cmp/capture reg A */
#define TM6CB __SYSREG(0xd40030d4, u16) /* timer6 cmp/capture reg B */
@@ -288,6 +419,34 @@
#define TM6AICR GxICR(TM6AIRQ) /* timer 6A intr control reg */
#define TM6BICR GxICR(TM6BIRQ) /* timer 6B intr control reg */
+#if defined(CONFIG_AM34_2)
+/*
+ * MTM: OS Tick-Timer
+ */
+#define TMTMD __SYSREG(0xd4004100, u8) /* Tick Timer mode register */
+#define TMTMD_TMTLDE 0x40 /* initialize TMTBC = TMTBR */
+#define TMTMD_TMTCNE 0x80 /* timer count enable */
+
+#define TMTBR __SYSREG(0xd4004110, u32) /* Tick Timer mode reg */
+#define TMTBC __SYSREG(0xd4004120, u32) /* Tick Timer mode reg */
+
+/*
+ * MTM: OS Timestamp-Timer
+ */
+#define TMSMD __SYSREG(0xd4004140, u8) /* Tick Timer mode register */
+#define TMSMD_TMSLDE 0x40 /* initialize TMSBC = TMSBR */
+#define TMSMD_TMSCNE 0x80 /* timer count enable */
+
+#define TMSBR __SYSREG(0xd4004150, u32) /* Tick Timer mode register */
+#define TMSBC __SYSREG(0xd4004160, u32) /* Tick Timer mode register */
+
+#define TMTIRQ 119 /* OS Tick timer IRQ */
+#define TMSIRQ 120 /* Timestamp timer IRQ */
+
+#define TMTICR GxICR(TMTIRQ) /* OS Tick timer uflow intr ctrl reg */
+#define TMSICR GxICR(TMSIRQ) /* Timestamp timer uflow intr ctrl reg */
+#endif /* CONFIG_AM34_2 */
+
#endif /* __KERNEL__ */
#endif /* _ASM_TIMER_REGS_H */
diff --git a/arch/mn10300/include/asm/timex.h b/arch/mn10300/include/asm/timex.h
index 8d031f9e117d..bd4e90dfe6c2 100644
--- a/arch/mn10300/include/asm/timex.h
+++ b/arch/mn10300/include/asm/timex.h
@@ -16,18 +16,30 @@
#define TICK_SIZE (tick_nsec / 1000)
-#define CLOCK_TICK_RATE 1193180 /* Underlying HZ - this should probably be set
- * to something appropriate, but what? */
-
-extern cycles_t cacheflush_time;
+#define CLOCK_TICK_RATE MN10300_JCCLK /* Underlying HZ */
#ifdef __KERNEL__
+extern cycles_t cacheflush_time;
+
static inline cycles_t get_cycles(void)
{
return read_timestamp_counter();
}
+extern int init_clockevents(void);
+extern int init_clocksource(void);
+
+static inline void setup_jiffies_interrupt(int irq,
+ struct irqaction *action)
+{
+ u16 tmp;
+ setup_irq(irq, action);
+ set_intr_level(irq, NUM2GxICR_LEVEL(CONFIG_TIMER_IRQ_LEVEL));
+ GxICR(irq) |= GxICR_ENABLE | GxICR_DETECT | GxICR_REQUEST;
+ tmp = GxICR(irq);
+}
+
#endif /* __KERNEL__ */
#endif /* _ASM_TIMEX_H */
diff --git a/arch/mn10300/include/asm/tlbflush.h b/arch/mn10300/include/asm/tlbflush.h
index 1a7e29281c5d..efddd6e1adea 100644
--- a/arch/mn10300/include/asm/tlbflush.h
+++ b/arch/mn10300/include/asm/tlbflush.h
@@ -11,24 +11,78 @@
#ifndef _ASM_TLBFLUSH_H
#define _ASM_TLBFLUSH_H
+#include <linux/mm.h>
#include <asm/processor.h>
-#define __flush_tlb() \
-do { \
- int w; \
- __asm__ __volatile__ \
- (" mov %1,%0 \n" \
- " or %2,%0 \n" \
- " mov %0,%1 \n" \
- : "=d"(w) \
- : "m"(MMUCTR), "i"(MMUCTR_IIV|MMUCTR_DIV) \
- : "cc", "memory" \
- ); \
-} while (0)
+struct tlb_state {
+ struct mm_struct *active_mm;
+ int state;
+};
+DECLARE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate);
-#define __flush_tlb_all() __flush_tlb()
-#define __flush_tlb_one(addr) __flush_tlb()
+/**
+ * local_flush_tlb - Flush the current MM's entries from the local CPU's TLBs
+ */
+static inline void local_flush_tlb(void)
+{
+ int w;
+ asm volatile(
+ " mov %1,%0 \n"
+ " or %2,%0 \n"
+ " mov %0,%1 \n"
+ : "=d"(w)
+ : "m"(MMUCTR), "i"(MMUCTR_IIV|MMUCTR_DIV)
+ : "cc", "memory");
+}
+
+/**
+ * local_flush_tlb_all - Flush all entries from the local CPU's TLBs
+ */
+static inline void local_flush_tlb_all(void)
+{
+ local_flush_tlb();
+}
+/**
+ * local_flush_tlb_one - Flush one entry from the local CPU's TLBs
+ */
+static inline void local_flush_tlb_one(unsigned long addr)
+{
+ local_flush_tlb();
+}
+
+/**
+ * local_flush_tlb_page - Flush a page's entry from the local CPU's TLBs
+ * @mm: The MM to flush for
+ * @addr: The address of the target page in RAM (not its page struct)
+ */
+static inline
+void local_flush_tlb_page(struct mm_struct *mm, unsigned long addr)
+{
+ unsigned long pteu, flags, cnx;
+
+ addr &= PAGE_MASK;
+
+ local_irq_save(flags);
+
+ cnx = 1;
+#ifdef CONFIG_MN10300_TLB_USE_PIDR
+ cnx = mm->context.tlbpid[smp_processor_id()];
+#endif
+ if (cnx) {
+ pteu = addr;
+#ifdef CONFIG_MN10300_TLB_USE_PIDR
+ pteu |= cnx & xPTEU_PID;
+#endif
+ IPTEU = pteu;
+ DPTEU = pteu;
+ if (IPTEL & xPTEL_V)
+ IPTEL = 0;
+ if (DPTEL & xPTEL_V)
+ DPTEL = 0;
+ }
+ local_irq_restore(flags);
+}
/*
* TLB flushing:
@@ -40,41 +94,61 @@ do { \
* - flush_tlb_range(mm, start, end) flushes a range of pages
* - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
*/
-#define flush_tlb_all() \
-do { \
- preempt_disable(); \
- __flush_tlb_all(); \
- preempt_enable(); \
-} while (0)
-
-#define flush_tlb_mm(mm) \
-do { \
- preempt_disable(); \
- __flush_tlb_all(); \
- preempt_enable(); \
-} while (0)
-
-#define flush_tlb_range(vma, start, end) \
-do { \
- unsigned long __s __attribute__((unused)) = (start); \
- unsigned long __e __attribute__((unused)) = (end); \
- preempt_disable(); \
- __flush_tlb_all(); \
- preempt_enable(); \
-} while (0)
-
-
-#define __flush_tlb_global() flush_tlb_all()
-#define flush_tlb() flush_tlb_all()
-#define flush_tlb_kernel_range(start, end) \
-do { \
- unsigned long __s __attribute__((unused)) = (start); \
- unsigned long __e __attribute__((unused)) = (end); \
- flush_tlb_all(); \
-} while (0)
-
-extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr);
-
-#define flush_tlb_pgtables(mm, start, end) do {} while (0)
+#ifdef CONFIG_SMP
+
+#include <asm/smp.h>
+
+extern void flush_tlb_all(void);
+extern void flush_tlb_current_task(void);
+extern void flush_tlb_mm(struct mm_struct *);
+extern void flush_tlb_page(struct vm_area_struct *, unsigned long);
+
+#define flush_tlb() flush_tlb_current_task()
+
+static inline void flush_tlb_range(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end)
+{
+ flush_tlb_mm(vma->vm_mm);
+}
+
+#else /* CONFIG_SMP */
+
+static inline void flush_tlb_all(void)
+{
+ preempt_disable();
+ local_flush_tlb_all();
+ preempt_enable();
+}
+
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+ preempt_disable();
+ local_flush_tlb_all();
+ preempt_enable();
+}
+
+static inline void flush_tlb_range(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end)
+{
+ preempt_disable();
+ local_flush_tlb_all();
+ preempt_enable();
+}
+
+#define flush_tlb_page(vma, addr) local_flush_tlb_page((vma)->vm_mm, addr)
+#define flush_tlb() flush_tlb_all()
+
+#endif /* CONFIG_SMP */
+
+static inline void flush_tlb_kernel_range(unsigned long start,
+ unsigned long end)
+{
+ flush_tlb_all();
+}
+
+static inline void flush_tlb_pgtables(struct mm_struct *mm,
+ unsigned long start, unsigned long end)
+{
+}
#endif /* _ASM_TLBFLUSH_H */
diff --git a/arch/mn10300/include/asm/uaccess.h b/arch/mn10300/include/asm/uaccess.h
index 197a7af3dd8a..679dee0bbd08 100644
--- a/arch/mn10300/include/asm/uaccess.h
+++ b/arch/mn10300/include/asm/uaccess.h
@@ -14,9 +14,8 @@
/*
* User space memory access functions
*/
-#include <linux/sched.h>
+#include <linux/thread_info.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
#include <asm/errno.h>
#define VERIFY_READ 0
@@ -29,7 +28,6 @@
*
* For historical reasons, these macros are grossly misnamed.
*/
-
#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
#define KERNEL_XDS MAKE_MM_SEG(0xBFFFFFFF)
@@ -377,7 +375,7 @@ unsigned long __generic_copy_to_user_nocheck(void *to, const void *from,
#if 0
-#error don't use - these macros don't increment to & from pointers
+#error "don't use - these macros don't increment to & from pointers"
/* Optimize just a little bit when we know the size of the move. */
#define __constant_copy_user(to, from, size) \
do { \
diff --git a/arch/mn10300/kernel/Makefile b/arch/mn10300/kernel/Makefile
index 23f2ab67574c..8f5f1e81baf5 100644
--- a/arch/mn10300/kernel/Makefile
+++ b/arch/mn10300/kernel/Makefile
@@ -3,13 +3,16 @@
#
extra-y := head.o init_task.o vmlinux.lds
-obj-y := process.o signal.o entry.o fpu.o traps.o irq.o \
+fpu-obj-y := fpu-nofpu.o fpu-nofpu-low.o
+fpu-obj-$(CONFIG_FPU) := fpu.o fpu-low.o
+
+obj-y := process.o signal.o entry.o traps.o irq.o \
ptrace.o setup.o time.o sys_mn10300.o io.o kthread.o \
- switch_to.o mn10300_ksyms.o kernel_execve.o
+ switch_to.o mn10300_ksyms.o kernel_execve.o $(fpu-obj-y)
-obj-$(CONFIG_MN10300_WD_TIMER) += mn10300-watchdog.o mn10300-watchdog-low.o
+obj-$(CONFIG_SMP) += smp.o smp-low.o
-obj-$(CONFIG_FPU) += fpu-low.o
+obj-$(CONFIG_MN10300_WD_TIMER) += mn10300-watchdog.o mn10300-watchdog-low.o
obj-$(CONFIG_MN10300_TTYSM) += mn10300-serial.o mn10300-serial-low.o \
mn10300-debug.o
@@ -17,7 +20,7 @@ obj-$(CONFIG_GDBSTUB) += gdb-stub.o gdb-low.o
obj-$(CONFIG_GDBSTUB_ON_TTYSx) += gdb-io-serial.o gdb-io-serial-low.o
obj-$(CONFIG_GDBSTUB_ON_TTYSMx) += gdb-io-ttysm.o gdb-io-ttysm-low.o
-ifneq ($(CONFIG_MN10300_CACHE_DISABLED),y)
+ifeq ($(CONFIG_MN10300_CACHE_ENABLED),y)
obj-$(CONFIG_GDBSTUB) += gdb-cache.o
endif
@@ -25,3 +28,5 @@ obj-$(CONFIG_MN10300_RTC) += rtc.o
obj-$(CONFIG_PROFILE) += profile.o profile-low.o
obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_KPROBES) += kprobes.o
+obj-$(CONFIG_CSRC_MN10300) += csrc-mn10300.o
+obj-$(CONFIG_CEVT_MN10300) += cevt-mn10300.o
diff --git a/arch/mn10300/kernel/asm-offsets.c b/arch/mn10300/kernel/asm-offsets.c
index 02dc7e461fef..96f24fab7de6 100644
--- a/arch/mn10300/kernel/asm-offsets.c
+++ b/arch/mn10300/kernel/asm-offsets.c
@@ -23,6 +23,7 @@ void foo(void)
OFFSET(TI_task, thread_info, task);
OFFSET(TI_exec_domain, thread_info, exec_domain);
+ OFFSET(TI_frame, thread_info, frame);
OFFSET(TI_flags, thread_info, flags);
OFFSET(TI_cpu, thread_info, cpu);
OFFSET(TI_preempt_count, thread_info, preempt_count);
@@ -66,7 +67,15 @@ void foo(void)
OFFSET(THREAD_SP, thread_struct, sp);
OFFSET(THREAD_A3, thread_struct, a3);
OFFSET(THREAD_USP, thread_struct, usp);
- OFFSET(THREAD_FRAME, thread_struct, __frame);
+#ifdef CONFIG_FPU
+ OFFSET(THREAD_FPU_FLAGS, thread_struct, fpu_flags);
+ OFFSET(THREAD_FPU_STATE, thread_struct, fpu_state);
+ DEFINE(__THREAD_USING_FPU, THREAD_USING_FPU);
+ DEFINE(__THREAD_HAS_FPU, THREAD_HAS_FPU);
+#endif /* CONFIG_FPU */
+ BLANK();
+
+ OFFSET(TASK_THREAD, task_struct, thread);
BLANK();
DEFINE(CLONE_VM_asm, CLONE_VM);
diff --git a/arch/mn10300/kernel/cevt-mn10300.c b/arch/mn10300/kernel/cevt-mn10300.c
new file mode 100644
index 000000000000..d4cb535bf786
--- /dev/null
+++ b/arch/mn10300/kernel/cevt-mn10300.c
@@ -0,0 +1,131 @@
+/* MN10300 clockevents
+ *
+ * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved.
+ * Written by Mark Salter (msalter@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/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/percpu.h>
+#include <linux/smp.h>
+#include <asm/timex.h>
+#include "internal.h"
+
+#ifdef CONFIG_SMP
+#if (CONFIG_NR_CPUS > 2) && !defined(CONFIG_GEENERIC_CLOCKEVENTS_BROADCAST)
+#error "This doesn't scale well! Need per-core local timers."
+#endif
+#else /* CONFIG_SMP */
+#define stop_jiffies_counter1()
+#define reload_jiffies_counter1(x)
+#define TMJC1IRQ TMJCIRQ
+#endif
+
+
+static int next_event(unsigned long delta,
+ struct clock_event_device *evt)
+{
+ unsigned int cpu = smp_processor_id();
+
+ if (cpu == 0) {
+ stop_jiffies_counter();
+ reload_jiffies_counter(delta - 1);
+ } else {
+ stop_jiffies_counter1();
+ reload_jiffies_counter1(delta - 1);
+ }
+ return 0;
+}
+
+static void set_clock_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ /* Nothing to do ... */
+}
+
+static DEFINE_PER_CPU(struct clock_event_device, mn10300_clockevent_device);
+static DEFINE_PER_CPU(struct irqaction, timer_irq);
+
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *cd;
+ unsigned int cpu = smp_processor_id();
+
+ if (cpu == 0)
+ stop_jiffies_counter();
+ else
+ stop_jiffies_counter1();
+
+ cd = &per_cpu(mn10300_clockevent_device, cpu);
+ cd->event_handler(cd);
+
+ return IRQ_HANDLED;
+}
+
+static void event_handler(struct clock_event_device *dev)
+{
+}
+
+int __init init_clockevents(void)
+{
+ struct clock_event_device *cd;
+ struct irqaction *iact;
+ unsigned int cpu = smp_processor_id();
+
+ cd = &per_cpu(mn10300_clockevent_device, cpu);
+
+ if (cpu == 0) {
+ stop_jiffies_counter();
+ cd->irq = TMJCIRQ;
+ } else {
+ stop_jiffies_counter1();
+ cd->irq = TMJC1IRQ;
+ }
+
+ cd->name = "Timestamp";
+ cd->features = CLOCK_EVT_FEAT_ONESHOT;
+
+ /* Calculate the min / max delta */
+ clockevent_set_clock(cd, MN10300_JCCLK);
+
+ cd->max_delta_ns = clockevent_delta2ns(TMJCBR_MAX, cd);
+ cd->min_delta_ns = clockevent_delta2ns(100, cd);
+
+ cd->rating = 200;
+ cd->cpumask = cpumask_of(smp_processor_id());
+ cd->set_mode = set_clock_mode;
+ cd->event_handler = event_handler;
+ cd->set_next_event = next_event;
+
+ iact = &per_cpu(timer_irq, cpu);
+ iact->flags = IRQF_DISABLED | IRQF_SHARED | IRQF_TIMER;
+ iact->handler = timer_interrupt;
+
+ clockevents_register_device(cd);
+
+#if defined(CONFIG_SMP) && !defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
+ /* setup timer irq affinity so it only runs on this cpu */
+ {
+ struct irq_desc *desc;
+ desc = irq_to_desc(cd->irq);
+ cpumask_copy(desc->affinity, cpumask_of(cpu));
+ iact->flags |= IRQF_NOBALANCING;
+ }
+#endif
+
+ if (cpu == 0) {
+ reload_jiffies_counter(MN10300_JC_PER_HZ - 1);
+ iact->name = "CPU0 Timer";
+ } else {
+ reload_jiffies_counter1(MN10300_JC_PER_HZ - 1);
+ iact->name = "CPU1 Timer";
+ }
+
+ setup_jiffies_interrupt(cd->irq, iact);
+
+ return 0;
+}
diff --git a/arch/mn10300/kernel/csrc-mn10300.c b/arch/mn10300/kernel/csrc-mn10300.c
new file mode 100644
index 000000000000..ba2f0c4d6e01
--- /dev/null
+++ b/arch/mn10300/kernel/csrc-mn10300.c
@@ -0,0 +1,35 @@
+/* MN10300 clocksource
+ *
+ * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved.
+ * Written by Mark Salter (msalter@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/clocksource.h>
+#include <linux/init.h>
+#include <asm/timex.h>
+#include "internal.h"
+
+static cycle_t mn10300_read(struct clocksource *cs)
+{
+ return read_timestamp_counter();
+}
+
+static struct clocksource clocksource_mn10300 = {
+ .name = "TSC",
+ .rating = 200,
+ .read = mn10300_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+int __init init_clocksource(void)
+{
+ startup_timestamp_counter();
+ clocksource_set_clock(&clocksource_mn10300, MN10300_TSCCLK);
+ clocksource_register(&clocksource_mn10300);
+ return 0;
+}
diff --git a/arch/mn10300/kernel/entry.S b/arch/mn10300/kernel/entry.S
index d9ed5a15c547..f00b9bafcd3e 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>
@@ -27,25 +28,17 @@
#include <asm/asm-offsets.h>
#include <asm/frame.inc>
+#if defined(CONFIG_SMP) && defined(CONFIG_GDBSTUB)
+#include <asm/gdb-stub.h>
+#endif /* CONFIG_SMP && CONFIG_GDBSTUB */
+
#ifdef CONFIG_PREEMPT
-#define preempt_stop __cli
+#define preempt_stop LOCAL_IRQ_DISABLE
#else
#define preempt_stop
#define resume_kernel restore_all
#endif
- .macro __cli
- and ~EPSW_IM,epsw
- or EPSW_IE|MN10300_CLI_LEVEL,epsw
- nop
- nop
- nop
- .endm
- .macro __sti
- or EPSW_IE|EPSW_IM_7,epsw
- .endm
-
-
.am33_2
###############################################################################
@@ -87,7 +80,7 @@ syscall_call:
syscall_exit:
# make sure we don't miss an interrupt setting need_resched or
# sigpending between sampling and the rti
- __cli
+ LOCAL_IRQ_DISABLE
mov (TI_flags,a2),d2
btst _TIF_ALLWORK_MASK,d2
bne syscall_exit_work
@@ -104,7 +97,7 @@ restore_all:
syscall_exit_work:
btst _TIF_SYSCALL_TRACE,d2
beq work_pending
- __sti # could let syscall_trace_exit() call
+ LOCAL_IRQ_ENABLE # could let syscall_trace_exit() call
# schedule() instead
mov fp,d0
call syscall_trace_exit[],0 # do_syscall_trace(regs)
@@ -120,7 +113,7 @@ work_resched:
# make sure we don't miss an interrupt setting need_resched or
# sigpending between sampling and the rti
- __cli
+ LOCAL_IRQ_DISABLE
# is there any work to be done other than syscall tracing?
mov (TI_flags,a2),d2
@@ -167,7 +160,7 @@ ret_from_intr:
ENTRY(resume_userspace)
# make sure we don't miss an interrupt setting need_resched or
# sigpending between sampling and the rti
- __cli
+ LOCAL_IRQ_DISABLE
# is there any work to be done on int/exception return?
mov (TI_flags,a2),d2
@@ -177,7 +170,7 @@ ENTRY(resume_userspace)
#ifdef CONFIG_PREEMPT
ENTRY(resume_kernel)
- __cli
+ LOCAL_IRQ_DISABLE
mov (TI_preempt_count,a2),d0 # non-zero preempt_count ?
cmp 0,d0
bne restore_all
@@ -215,31 +208,6 @@ ENTRY(irq_handler)
###############################################################################
#
-# Monitor Signal handler entry point
-#
-###############################################################################
-ENTRY(monitor_signal)
- movbu (0xae000001),d1
- cmp 1,d1
- beq monsignal
- ret [],0
-
-monsignal:
- or EPSW_NMID,epsw
- mov d0,a0
- mov a0,sp
- mov (REG_EPSW,fp),d1
- and ~EPSW_nSL,d1
- mov d1,(REG_EPSW,fp)
- movm (sp),[d2,d3,a2,a3,exreg0,exreg1,exother]
- mov (sp),a1
- mov a1,usp
- movm (sp),[other]
- add 4,sp
-here: jmp 0x8e000008-here+0x8e000008
-
-###############################################################################
-#
# Double Fault handler entry point
# - note that there will not be a stack, D0/A0 will hold EPSW/PC as were
#
@@ -275,6 +243,10 @@ double_fault_loop:
ENTRY(raw_bus_error)
add -4,sp
mov d0,(sp)
+#if defined(CONFIG_ERRATUM_NEED_TO_RELOAD_MMUCTR)
+ mov (MMUCTR),d0
+ mov d0,(MMUCTR)
+#endif
mov (BCBERR),d0 # what
btst BCBERR_BEMR_DMA,d0 # see if it was an external bus error
beq __common_exception_aux # it wasn't
@@ -301,11 +273,88 @@ ENTRY(nmi_handler)
add -4,sp
mov d0,(sp)
mov (TBR),d0
+
+#ifdef CONFIG_SMP
+ add -4,sp
+ mov d0,(sp) # save d0(TBR)
+ movhu (NMIAGR),d0
+ and NMIAGR_GN,d0
+ lsr 0x2,d0
+ cmp CALL_FUNCTION_NMI_IPI,d0
+ bne 5f # if not call function, jump
+
+ # function call nmi ipi
+ add 4,sp # no need to store TBR
+ mov GxICR_DETECT,d0 # clear NMI request
+ movbu d0,(GxICR(CALL_FUNCTION_NMI_IPI))
+ movhu (GxICR(CALL_FUNCTION_NMI_IPI)),d0
+ and ~EPSW_NMID,epsw # enable NMI
+
+ mov (sp),d0 # restore d0
+ SAVE_ALL
+ call smp_nmi_call_function_interrupt[],0
+ RESTORE_ALL
+
+5:
+#ifdef CONFIG_GDBSTUB
+ cmp GDB_NMI_IPI,d0
+ bne 3f # if not gdb nmi ipi, jump
+
+ # gdb nmi ipi
+ add 4,sp # no need to store TBR
+ mov GxICR_DETECT,d0 # clear NMI
+ movbu d0,(GxICR(GDB_NMI_IPI))
+ movhu (GxICR(GDB_NMI_IPI)),d0
+ and ~EPSW_NMID,epsw # enable NMI
+#ifdef CONFIG_MN10300_CACHE_ENABLED
+ mov (gdbstub_nmi_opr_type),d0
+ cmp GDBSTUB_NMI_CACHE_PURGE,d0
+ bne 4f # if not gdb cache purge, jump
+
+ # gdb cache purge nmi ipi
+ add -20,sp
+ mov d1,(4,sp)
+ mov a0,(8,sp)
+ mov a1,(12,sp)
+ mov mdr,d0
+ mov d0,(16,sp)
+ call gdbstub_local_purge_cache[],0
+ mov 0x1,d0
+ mov (CPUID),d1
+ asl d1,d0
+ mov gdbstub_nmi_cpumask,a0
+ bclr d0,(a0)
+ mov (4,sp),d1
+ mov (8,sp),a0
+ mov (12,sp),a1
+ mov (16,sp),d0
+ mov d0,mdr
+ add 20,sp
+ mov (sp),d0
+ add 4,sp
+ rti
+4:
+#endif /* CONFIG_MN10300_CACHE_ENABLED */
+ # gdb wait nmi ipi
+ mov (sp),d0
+ SAVE_ALL
+ call gdbstub_nmi_wait[],0
+ RESTORE_ALL
+3:
+#endif /* CONFIG_GDBSTUB */
+ mov (sp),d0 # restore TBR to d0
+ add 4,sp
+#endif /* CONFIG_SMP */
+
bra __common_exception_nonmi
ENTRY(__common_exception)
add -4,sp
mov d0,(sp)
+#if defined(CONFIG_ERRATUM_NEED_TO_RELOAD_MMUCTR)
+ mov (MMUCTR),d0
+ mov d0,(MMUCTR)
+#endif
__common_exception_aux:
mov (TBR),d0
@@ -330,15 +379,21 @@ __common_exception_nonmi:
mov d0,(REG_ORIG_D0,fp)
#ifdef CONFIG_GDBSTUB
+#ifdef CONFIG_SMP
+ call gdbstub_busy_check[],0
+ and d0,d0 # check return value
+ beq 2f
+#else /* CONFIG_SMP */
btst 0x01,(gdbstub_busy)
beq 2f
+#endif /* CONFIG_SMP */
and ~EPSW_IE,epsw
mov fp,d0
mov a2,d1
call gdbstub_exception[],0 # gdbstub itself caused an exception
bra restore_all
2:
-#endif
+#endif /* CONFIG_GDBSTUB */
mov fp,d0 # arg 0: stacked register file
mov a2,d1 # arg 1: exception number
@@ -373,11 +428,7 @@ ENTRY(set_excp_vector)
add exception_table,d0
mov d1,(d0)
mov 4,d1
-#if defined(CONFIG_MN10300_CACHE_WBACK)
- jmp mn10300_dcache_flush_inv_range2
-#else
ret [],0
-#endif
###############################################################################
#
diff --git a/arch/mn10300/kernel/fpu-low.S b/arch/mn10300/kernel/fpu-low.S
index 96cfd47e68d5..78df25cfae29 100644
--- a/arch/mn10300/kernel/fpu-low.S
+++ b/arch/mn10300/kernel/fpu-low.S
@@ -8,25 +8,14 @@
* as published by the Free Software Foundation; either version
* 2 of the Licence, or (at your option) any later version.
*/
+#include <linux/linkage.h>
#include <asm/cpu-regs.h>
+#include <asm/smp.h>
+#include <asm/thread_info.h>
+#include <asm/asm-offsets.h>
+#include <asm/frame.inc>
-###############################################################################
-#
-# void fpu_init_state(void)
-# - initialise the FPU
-#
-###############################################################################
- .globl fpu_init_state
- .type fpu_init_state,@function
-fpu_init_state:
- mov epsw,d0
- or EPSW_FE,epsw
-
-#ifdef CONFIG_MN10300_PROC_MN103E010
- nop
- nop
- nop
-#endif
+.macro FPU_INIT_STATE_ALL
fmov 0,fs0
fmov fs0,fs1
fmov fs0,fs2
@@ -60,7 +49,100 @@ fpu_init_state:
fmov fs0,fs30
fmov fs0,fs31
fmov FPCR_INIT,fpcr
+.endm
+
+.macro FPU_SAVE_ALL areg,dreg
+ fmov fs0,(\areg+)
+ fmov fs1,(\areg+)
+ fmov fs2,(\areg+)
+ fmov fs3,(\areg+)
+ fmov fs4,(\areg+)
+ fmov fs5,(\areg+)
+ fmov fs6,(\areg+)
+ fmov fs7,(\areg+)
+ fmov fs8,(\areg+)
+ fmov fs9,(\areg+)
+ fmov fs10,(\areg+)
+ fmov fs11,(\areg+)
+ fmov fs12,(\areg+)
+ fmov fs13,(\areg+)
+ fmov fs14,(\areg+)
+ fmov fs15,(\areg+)
+ fmov fs16,(\areg+)
+ fmov fs17,(\areg+)
+ fmov fs18,(\areg+)
+ fmov fs19,(\areg+)
+ fmov fs20,(\areg+)
+ fmov fs21,(\areg+)
+ fmov fs22,(\areg+)
+ fmov fs23,(\areg+)
+ fmov fs24,(\areg+)
+ fmov fs25,(\areg+)
+ fmov fs26,(\areg+)
+ fmov fs27,(\areg+)
+ fmov fs28,(\areg+)
+ fmov fs29,(\areg+)
+ fmov fs30,(\areg+)
+ fmov fs31,(\areg+)
+ fmov fpcr,\dreg
+ mov \dreg,(\areg)
+.endm
+
+.macro FPU_RESTORE_ALL areg,dreg
+ fmov (\areg+),fs0
+ fmov (\areg+),fs1
+ fmov (\areg+),fs2
+ fmov (\areg+),fs3
+ fmov (\areg+),fs4
+ fmov (\areg+),fs5
+ fmov (\areg+),fs6
+ fmov (\areg+),fs7
+ fmov (\areg+),fs8
+ fmov (\areg+),fs9
+ fmov (\areg+),fs10
+ fmov (\areg+),fs11
+ fmov (\areg+),fs12
+ fmov (\areg+),fs13
+ fmov (\areg+),fs14
+ fmov (\areg+),fs15
+ fmov (\areg+),fs16
+ fmov (\areg+),fs17
+ fmov (\areg+),fs18
+ fmov (\areg+),fs19
+ fmov (\areg+),fs20
+ fmov (\areg+),fs21
+ fmov (\areg+),fs22
+ fmov (\areg+),fs23
+ fmov (\areg+),fs24
+ fmov (\areg+),fs25
+ fmov (\areg+),fs26
+ fmov (\areg+),fs27
+ fmov (\areg+),fs28
+ fmov (\areg+),fs29
+ fmov (\areg+),fs30
+ fmov (\areg+),fs31
+ mov (\areg),\dreg
+ fmov \dreg,fpcr
+.endm
+###############################################################################
+#
+# void fpu_init_state(void)
+# - initialise the FPU
+#
+###############################################################################
+ .globl fpu_init_state
+ .type fpu_init_state,@function
+fpu_init_state:
+ mov epsw,d0
+ or EPSW_FE,epsw
+
+#ifdef CONFIG_MN10300_PROC_MN103E010
+ nop
+ nop
+ nop
+#endif
+ FPU_INIT_STATE_ALL
#ifdef CONFIG_MN10300_PROC_MN103E010
nop
nop
@@ -89,40 +171,7 @@ fpu_save:
nop
#endif
mov d0,a0
- fmov fs0,(a0+)
- fmov fs1,(a0+)
- fmov fs2,(a0+)
- fmov fs3,(a0+)
- fmov fs4,(a0+)
- fmov fs5,(a0+)
- fmov fs6,(a0+)
- fmov fs7,(a0+)
- fmov fs8,(a0+)
- fmov fs9,(a0+)
- fmov fs10,(a0+)
- fmov fs11,(a0+)
- fmov fs12,(a0+)
- fmov fs13,(a0+)
- fmov fs14,(a0+)
- fmov fs15,(a0+)
- fmov fs16,(a0+)
- fmov fs17,(a0+)
- fmov fs18,(a0+)
- fmov fs19,(a0+)
- fmov fs20,(a0+)
- fmov fs21,(a0+)
- fmov fs22,(a0+)
- fmov fs23,(a0+)
- fmov fs24,(a0+)
- fmov fs25,(a0+)
- fmov fs26,(a0+)
- fmov fs27,(a0+)
- fmov fs28,(a0+)
- fmov fs29,(a0+)
- fmov fs30,(a0+)
- fmov fs31,(a0+)
- fmov fpcr,d0
- mov d0,(a0)
+ FPU_SAVE_ALL a0,d0
#ifdef CONFIG_MN10300_PROC_MN103E010
nop
nop
@@ -135,63 +184,75 @@ fpu_save:
###############################################################################
#
-# void fpu_restore(struct fpu_state_struct *)
-# - restore the fpu state
-# - note that an FPU Operational exception might occur during this process
+# void fpu_disabled(void)
+# - handle an exception due to the FPU being disabled
+# when CONFIG_FPU is enabled
#
###############################################################################
- .globl fpu_restore
- .type fpu_restore,@function
-fpu_restore:
- mov epsw,d1
- or EPSW_FE,epsw /* enable the FPU so we can access it */
-
-#ifdef CONFIG_MN10300_PROC_MN103E010
+ .type fpu_disabled,@function
+ .globl fpu_disabled
+fpu_disabled:
+ or EPSW_nAR|EPSW_FE,epsw
nop
nop
-#endif
- mov d0,a0
- fmov (a0+),fs0
- fmov (a0+),fs1
- fmov (a0+),fs2
- fmov (a0+),fs3
- fmov (a0+),fs4
- fmov (a0+),fs5
- fmov (a0+),fs6
- fmov (a0+),fs7
- fmov (a0+),fs8
- fmov (a0+),fs9
- fmov (a0+),fs10
- fmov (a0+),fs11
- fmov (a0+),fs12
- fmov (a0+),fs13
- fmov (a0+),fs14
- fmov (a0+),fs15
- fmov (a0+),fs16
- fmov (a0+),fs17
- fmov (a0+),fs18
- fmov (a0+),fs19
- fmov (a0+),fs20
- fmov (a0+),fs21
- fmov (a0+),fs22
- fmov (a0+),fs23
- fmov (a0+),fs24
- fmov (a0+),fs25
- fmov (a0+),fs26
- fmov (a0+),fs27
- fmov (a0+),fs28
- fmov (a0+),fs29
- fmov (a0+),fs30
- fmov (a0+),fs31
- mov (a0),d0
- fmov d0,fpcr
-#ifdef CONFIG_MN10300_PROC_MN103E010
nop
+
+ mov sp,a1
+ mov (a1),d1 /* get epsw of user context */
+ and ~(THREAD_SIZE-1),a1 /* a1: (thread_info *ti) */
+ mov (TI_task,a1),a2 /* a2: (task_struct *tsk) */
+ btst EPSW_nSL,d1
+ beq fpu_used_in_kernel
+
+ or EPSW_FE,d1
+ mov d1,(sp)
+ mov (TASK_THREAD+THREAD_FPU_FLAGS,a2),d1
+#ifndef CONFIG_LAZY_SAVE_FPU
+ or __THREAD_HAS_FPU,d1
+ mov d1,(TASK_THREAD+THREAD_FPU_FLAGS,a2)
+#else /* !CONFIG_LAZY_SAVE_FPU */
+ mov (fpu_state_owner),a0
+ cmp 0,a0
+ beq fpu_regs_save_end
+
+ mov (TASK_THREAD+THREAD_UREGS,a0),a1
+ add TASK_THREAD+THREAD_FPU_STATE,a0
+ FPU_SAVE_ALL a0,d0
+
+ mov (REG_EPSW,a1),d0
+ and ~EPSW_FE,d0
+ mov d0,(REG_EPSW,a1)
+
+fpu_regs_save_end:
+ mov a2,(fpu_state_owner)
+#endif /* !CONFIG_LAZY_SAVE_FPU */
+
+ btst __THREAD_USING_FPU,d1
+ beq fpu_regs_init
+ add TASK_THREAD+THREAD_FPU_STATE,a2
+ FPU_RESTORE_ALL a2,d0
+ rti
+
+fpu_regs_init:
+ FPU_INIT_STATE_ALL
+ add TASK_THREAD+THREAD_FPU_FLAGS,a2
+ bset __THREAD_USING_FPU,(0,a2)
+ rti
+
+fpu_used_in_kernel:
+ and ~(EPSW_nAR|EPSW_FE),epsw
nop
nop
-#endif
- mov d1,epsw
- ret [],0
+ add -4,sp
+ SAVE_ALL
+ mov -1,d0
+ mov d0,(REG_ORIG_D0,fp)
+
+ and ~EPSW_NMID,epsw
+
+ mov fp,d0
+ call fpu_disabled_in_kernel[],0
+ jmp ret_from_exception
- .size fpu_restore,.-fpu_restore
+ .size fpu_disabled,.-fpu_disabled
diff --git a/arch/mn10300/kernel/fpu-nofpu-low.S b/arch/mn10300/kernel/fpu-nofpu-low.S
new file mode 100644
index 000000000000..7ea087a549f4
--- /dev/null
+++ b/arch/mn10300/kernel/fpu-nofpu-low.S
@@ -0,0 +1,39 @@
+/* MN10300 Low level FPU management operations
+ *
+ * Copyright (C) 2007 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/linkage.h>
+#include <asm/cpu-regs.h>
+#include <asm/smp.h>
+#include <asm/thread_info.h>
+#include <asm/asm-offsets.h>
+#include <asm/frame.inc>
+
+###############################################################################
+#
+# void fpu_disabled(void)
+# - handle an exception due to the FPU being disabled
+# when CONFIG_FPU is disabled
+#
+###############################################################################
+ .type fpu_disabled,@function
+ .globl fpu_disabled
+fpu_disabled:
+ add -4,sp
+ SAVE_ALL
+ mov -1,d0
+ mov d0,(REG_ORIG_D0,fp)
+
+ and ~EPSW_NMID,epsw
+
+ mov fp,d0
+ call unexpected_fpu_exception[],0
+ jmp ret_from_exception
+
+ .size fpu_disabled,.-fpu_disabled
diff --git a/arch/mn10300/kernel/fpu-nofpu.c b/arch/mn10300/kernel/fpu-nofpu.c
new file mode 100644
index 000000000000..31c765b92c5d
--- /dev/null
+++ b/arch/mn10300/kernel/fpu-nofpu.c
@@ -0,0 +1,30 @@
+/* MN10300 FPU management
+ *
+ * Copyright (C) 2007 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 <asm/fpu.h>
+
+/*
+ * handle an FPU operational exception
+ * - there's a possibility that if the FPU is asynchronous, the signal might
+ * be meant for a process other than the current one
+ */
+asmlinkage
+void unexpected_fpu_exception(struct pt_regs *regs, enum exception_code code)
+{
+ panic("An FPU exception was received, but there's no FPU enabled.");
+}
+
+/*
+ * fill in the FPU structure for a core dump
+ */
+int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpreg)
+{
+ return 0; /* not valid */
+}
diff --git a/arch/mn10300/kernel/fpu.c b/arch/mn10300/kernel/fpu.c
index e705f25ad5ff..5f9c3fa19a85 100644
--- a/arch/mn10300/kernel/fpu.c
+++ b/arch/mn10300/kernel/fpu.c
@@ -12,56 +12,19 @@
#include <asm/fpu.h>
#include <asm/elf.h>
#include <asm/exceptions.h>
+#include <asm/system.h>
+#ifdef CONFIG_LAZY_SAVE_FPU
struct task_struct *fpu_state_owner;
+#endif
/*
- * handle an exception due to the FPU being disabled
+ * error functions in FPU disabled exception
*/
-asmlinkage void fpu_disabled(struct pt_regs *regs, enum exception_code code)
+asmlinkage void fpu_disabled_in_kernel(struct pt_regs *regs)
{
- struct task_struct *tsk = current;
-
- if (!user_mode(regs))
- die_if_no_fixup("An FPU Disabled exception happened in"
- " kernel space\n",
- regs, code);
-
-#ifdef CONFIG_FPU
- preempt_disable();
-
- /* transfer the last process's FPU state to memory */
- if (fpu_state_owner) {
- fpu_save(&fpu_state_owner->thread.fpu_state);
- fpu_state_owner->thread.uregs->epsw &= ~EPSW_FE;
- }
-
- /* the current process now owns the FPU state */
- fpu_state_owner = tsk;
- regs->epsw |= EPSW_FE;
-
- /* load the FPU with the current process's FPU state or invent a new
- * clean one if the process doesn't have one */
- if (is_using_fpu(tsk)) {
- fpu_restore(&tsk->thread.fpu_state);
- } else {
- fpu_init_state();
- set_using_fpu(tsk);
- }
-
- preempt_enable();
-#else
- {
- siginfo_t info;
-
- info.si_signo = SIGFPE;
- info.si_errno = 0;
- info.si_addr = (void *) tsk->thread.uregs->pc;
- info.si_code = FPE_FLTINV;
-
- force_sig_info(SIGFPE, &info, tsk);
- }
-#endif /* CONFIG_FPU */
+ die_if_no_fixup("An FPU Disabled exception happened in kernel space\n",
+ regs, EXCEP_FPU_DISABLED);
}
/*
@@ -71,15 +34,16 @@ asmlinkage void fpu_disabled(struct pt_regs *regs, enum exception_code code)
*/
asmlinkage void fpu_exception(struct pt_regs *regs, enum exception_code code)
{
- struct task_struct *tsk = fpu_state_owner;
+ struct task_struct *tsk = current;
siginfo_t info;
+ u32 fpcr;
if (!user_mode(regs))
die_if_no_fixup("An FPU Operation exception happened in"
" kernel space\n",
regs, code);
- if (!tsk)
+ if (!is_using_fpu(tsk))
die_if_no_fixup("An FPU Operation exception happened,"
" but the FPU is not in use",
regs, code);
@@ -89,48 +53,45 @@ asmlinkage void fpu_exception(struct pt_regs *regs, enum exception_code code)
info.si_addr = (void *) tsk->thread.uregs->pc;
info.si_code = FPE_FLTINV;
-#ifdef CONFIG_FPU
- {
- u32 fpcr;
+ unlazy_fpu(tsk);
- /* get FPCR (we need to enable the FPU whilst we do this) */
- asm volatile(" or %1,epsw \n"
-#ifdef CONFIG_MN10300_PROC_MN103E010
- " nop \n"
- " nop \n"
- " nop \n"
-#endif
- " fmov fpcr,%0 \n"
-#ifdef CONFIG_MN10300_PROC_MN103E010
- " nop \n"
- " nop \n"
- " nop \n"
-#endif
- " and %2,epsw \n"
- : "=&d"(fpcr)
- : "i"(EPSW_FE), "i"(~EPSW_FE)
- );
-
- if (fpcr & FPCR_EC_Z)
- info.si_code = FPE_FLTDIV;
- else if (fpcr & FPCR_EC_O)
- info.si_code = FPE_FLTOVF;
- else if (fpcr & FPCR_EC_U)
- info.si_code = FPE_FLTUND;
- else if (fpcr & FPCR_EC_I)
- info.si_code = FPE_FLTRES;
- }
-#endif
+ fpcr = tsk->thread.fpu_state.fpcr;
+
+ if (fpcr & FPCR_EC_Z)
+ info.si_code = FPE_FLTDIV;
+ else if (fpcr & FPCR_EC_O)
+ info.si_code = FPE_FLTOVF;
+ else if (fpcr & FPCR_EC_U)
+ info.si_code = FPE_FLTUND;
+ else if (fpcr & FPCR_EC_I)
+ info.si_code = FPE_FLTRES;
force_sig_info(SIGFPE, &info, tsk);
}
/*
+ * handle an FPU invalid_op exception
+ * - Derived from DO_EINFO() macro in arch/mn10300/kernel/traps.c
+ */
+asmlinkage void fpu_invalid_op(struct pt_regs *regs, enum exception_code code)
+{
+ siginfo_t info;
+
+ if (!user_mode(regs))
+ die_if_no_fixup("FPU invalid opcode", regs, code);
+
+ info.si_signo = SIGILL;
+ info.si_errno = 0;
+ info.si_code = ILL_COPROC;
+ info.si_addr = (void *) regs->pc;
+ force_sig_info(info.si_signo, &info, current);
+}
+
+/*
* save the FPU state to a signal context
*/
int fpu_setup_sigcontext(struct fpucontext *fpucontext)
{
-#ifdef CONFIG_FPU
struct task_struct *tsk = current;
if (!is_using_fpu(tsk))
@@ -142,11 +103,19 @@ int fpu_setup_sigcontext(struct fpucontext *fpucontext)
*/
preempt_disable();
+#ifndef CONFIG_LAZY_SAVE_FPU
+ if (tsk->thread.fpu_flags & THREAD_HAS_FPU) {
+ fpu_save(&tsk->thread.fpu_state);
+ tsk->thread.uregs->epsw &= ~EPSW_FE;
+ tsk->thread.fpu_flags &= ~THREAD_HAS_FPU;
+ }
+#else /* !CONFIG_LAZY_SAVE_FPU */
if (fpu_state_owner == tsk) {
fpu_save(&tsk->thread.fpu_state);
fpu_state_owner->thread.uregs->epsw &= ~EPSW_FE;
fpu_state_owner = NULL;
}
+#endif /* !CONFIG_LAZY_SAVE_FPU */
preempt_enable();
@@ -161,9 +130,6 @@ int fpu_setup_sigcontext(struct fpucontext *fpucontext)
return -1;
return 1;
-#else
- return 0;
-#endif
}
/*
@@ -171,17 +137,23 @@ int fpu_setup_sigcontext(struct fpucontext *fpucontext)
*/
void fpu_kill_state(struct task_struct *tsk)
{
-#ifdef CONFIG_FPU
/* disown anything left in the FPU */
preempt_disable();
+#ifndef CONFIG_LAZY_SAVE_FPU
+ if (tsk->thread.fpu_flags & THREAD_HAS_FPU) {
+ tsk->thread.uregs->epsw &= ~EPSW_FE;
+ tsk->thread.fpu_flags &= ~THREAD_HAS_FPU;
+ }
+#else /* !CONFIG_LAZY_SAVE_FPU */
if (fpu_state_owner == tsk) {
fpu_state_owner->thread.uregs->epsw &= ~EPSW_FE;
fpu_state_owner = NULL;
}
+#endif /* !CONFIG_LAZY_SAVE_FPU */
preempt_enable();
-#endif
+
/* we no longer have a valid current FPU state */
clear_using_fpu(tsk);
}
@@ -195,8 +167,7 @@ int fpu_restore_sigcontext(struct fpucontext *fpucontext)
int ret;
/* load up the old FPU state */
- ret = copy_from_user(&tsk->thread.fpu_state,
- fpucontext,
+ ret = copy_from_user(&tsk->thread.fpu_state, fpucontext,
min(sizeof(struct fpu_state_struct),
sizeof(struct fpucontext)));
if (!ret)
diff --git a/arch/mn10300/kernel/gdb-io-serial-low.S b/arch/mn10300/kernel/gdb-io-serial-low.S
index 4998b24f5d3a..b1d0152e96cb 100644
--- a/arch/mn10300/kernel/gdb-io-serial-low.S
+++ b/arch/mn10300/kernel/gdb-io-serial-low.S
@@ -18,6 +18,7 @@
#include <asm/thread_info.h>
#include <asm/frame.inc>
#include <asm/intctl-regs.h>
+#include <asm/irqflags.h>
#include <unit/serial.h>
.text
@@ -69,7 +70,7 @@ gdbstub_io_rx_overflow:
bra gdbstub_io_rx_done
gdbstub_io_rx_enter:
- or EPSW_IE|EPSW_IM_1,epsw
+ LOCAL_CHANGE_INTR_MASK_LEVEL(NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL+1))
add -4,sp
SAVE_ALL
@@ -80,7 +81,7 @@ gdbstub_io_rx_enter:
mov fp,d0
call gdbstub_rx_irq[],0 # gdbstub_rx_irq(regs,excep)
- and ~EPSW_IE,epsw
+ LOCAL_CLI
bclr 0x01,(gdbstub_busy)
.globl gdbstub_return
diff --git a/arch/mn10300/kernel/gdb-io-serial.c b/arch/mn10300/kernel/gdb-io-serial.c
index ae663dc717e9..0d5d63c91dc3 100644
--- a/arch/mn10300/kernel/gdb-io-serial.c
+++ b/arch/mn10300/kernel/gdb-io-serial.c
@@ -23,6 +23,7 @@
#include <asm/exceptions.h>
#include <asm/serial-regs.h>
#include <unit/serial.h>
+#include <asm/smp.h>
/*
* initialise the GDB stub
@@ -45,22 +46,34 @@ void gdbstub_io_init(void)
XIRQxICR(GDBPORT_SERIAL_IRQ) = 0;
tmp = XIRQxICR(GDBPORT_SERIAL_IRQ);
+#if CONFIG_GDBSTUB_IRQ_LEVEL == 0
IVAR0 = EXCEP_IRQ_LEVEL0;
- set_intr_stub(EXCEP_IRQ_LEVEL0, gdbstub_io_rx_handler);
+#elif CONFIG_GDBSTUB_IRQ_LEVEL == 1
+ IVAR1 = EXCEP_IRQ_LEVEL1;
+#elif CONFIG_GDBSTUB_IRQ_LEVEL == 2
+ IVAR2 = EXCEP_IRQ_LEVEL2;
+#elif CONFIG_GDBSTUB_IRQ_LEVEL == 3
+ IVAR3 = EXCEP_IRQ_LEVEL3;
+#elif CONFIG_GDBSTUB_IRQ_LEVEL == 4
+ IVAR4 = EXCEP_IRQ_LEVEL4;
+#elif CONFIG_GDBSTUB_IRQ_LEVEL == 5
+ IVAR5 = EXCEP_IRQ_LEVEL5;
+#else
+#error "Unknown irq level for gdbstub."
+#endif
+
+ set_intr_stub(NUM2EXCEP_IRQ_LEVEL(CONFIG_GDBSTUB_IRQ_LEVEL),
+ gdbstub_io_rx_handler);
XIRQxICR(GDBPORT_SERIAL_IRQ) &= ~GxICR_REQUEST;
- XIRQxICR(GDBPORT_SERIAL_IRQ) = GxICR_ENABLE | GxICR_LEVEL_0;
+ XIRQxICR(GDBPORT_SERIAL_IRQ) =
+ GxICR_ENABLE | NUM2GxICR_LEVEL(CONFIG_GDBSTUB_IRQ_LEVEL);
tmp = XIRQxICR(GDBPORT_SERIAL_IRQ);
GDBPORT_SERIAL_IER = UART_IER_RDI | UART_IER_RLSI;
/* permit level 0 IRQs to take place */
- asm volatile(
- " and %0,epsw \n"
- " or %1,epsw \n"
- :
- : "i"(~EPSW_IM), "i"(EPSW_IE | EPSW_IM_1)
- );
+ local_change_intr_mask_level(NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1));
}
/*
@@ -87,6 +100,9 @@ int gdbstub_io_rx_char(unsigned char *_ch, int nonblock)
{
unsigned ix;
u8 ch, st;
+#if defined(CONFIG_MN10300_WD_TIMER)
+ int cpu;
+#endif
*_ch = 0xff;
@@ -104,8 +120,9 @@ int gdbstub_io_rx_char(unsigned char *_ch, int nonblock)
if (nonblock)
return -EAGAIN;
#ifdef CONFIG_MN10300_WD_TIMER
- watchdog_alert_counter = 0;
-#endif /* CONFIG_MN10300_WD_TIMER */
+ for (cpu = 0; cpu < NR_CPUS; cpu++)
+ watchdog_alert_counter[cpu] = 0;
+#endif
goto try_again;
}
diff --git a/arch/mn10300/kernel/gdb-io-ttysm.c b/arch/mn10300/kernel/gdb-io-ttysm.c
index a560bbc3137d..97dfda23342c 100644
--- a/arch/mn10300/kernel/gdb-io-ttysm.c
+++ b/arch/mn10300/kernel/gdb-io-ttysm.c
@@ -58,9 +58,12 @@ void __init gdbstub_io_init(void)
gdbstub_io_set_baud(115200);
/* we want to get serial receive interrupts */
- set_intr_level(gdbstub_port->rx_irq, GxICR_LEVEL_0);
- set_intr_level(gdbstub_port->tx_irq, GxICR_LEVEL_0);
- set_intr_stub(EXCEP_IRQ_LEVEL0, gdbstub_io_rx_handler);
+ set_intr_level(gdbstub_port->rx_irq,
+ NUM2GxICR_LEVEL(CONFIG_GDBSTUB_IRQ_LEVEL));
+ set_intr_level(gdbstub_port->tx_irq,
+ NUM2GxICR_LEVEL(CONFIG_GDBSTUB_IRQ_LEVEL));
+ set_intr_stub(NUM2EXCEP_IRQ_LEVEL(CONFIG_GDBSTUB_IRQ_LEVEL),
+ gdbstub_io_rx_handler);
*gdbstub_port->rx_icr |= GxICR_ENABLE;
tmp = *gdbstub_port->rx_icr;
@@ -84,12 +87,7 @@ void __init gdbstub_io_init(void)
tmp = *gdbstub_port->_control;
/* permit level 0 IRQs only */
- asm volatile(
- " and %0,epsw \n"
- " or %1,epsw \n"
- :
- : "i"(~EPSW_IM), "i"(EPSW_IE|EPSW_IM_1)
- );
+ local_change_intr_mask_level(NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1));
}
/*
@@ -184,6 +182,9 @@ int gdbstub_io_rx_char(unsigned char *_ch, int nonblock)
{
unsigned ix;
u8 ch, st;
+#if defined(CONFIG_MN10300_WD_TIMER)
+ int cpu;
+#endif
*_ch = 0xff;
@@ -201,8 +202,9 @@ try_again:
if (nonblock)
return -EAGAIN;
#ifdef CONFIG_MN10300_WD_TIMER
- watchdog_alert_counter = 0;
-#endif /* CONFIG_MN10300_WD_TIMER */
+ for (cpu = 0; cpu < NR_CPUS; cpu++)
+ watchdog_alert_counter[cpu] = 0;
+#endif
goto try_again;
}
diff --git a/arch/mn10300/kernel/gdb-stub.c b/arch/mn10300/kernel/gdb-stub.c
index 41b11706c8ed..a5fc3f05309b 100644
--- a/arch/mn10300/kernel/gdb-stub.c
+++ b/arch/mn10300/kernel/gdb-stub.c
@@ -440,15 +440,11 @@ static const unsigned char gdbstub_insn_sizes[256] =
static int __gdbstub_mark_bp(u8 *addr, int ix)
{
- if (addr < (u8 *) 0x70000000UL)
- return 0;
- /* 70000000-7fffffff: vmalloc area */
- if (addr < (u8 *) 0x80000000UL)
+ /* vmalloc area */
+ if (((u8 *) VMALLOC_START <= addr) && (addr < (u8 *) VMALLOC_END))
goto okay;
- if (addr < (u8 *) 0x8c000000UL)
- return 0;
- /* 8c000000-93ffffff: SRAM, SDRAM */
- if (addr < (u8 *) 0x94000000UL)
+ /* SRAM, SDRAM */
+ if (((u8 *) 0x80000000UL <= addr) && (addr < (u8 *) 0xa0000000UL))
goto okay;
return 0;
@@ -1197,9 +1193,8 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep)
mn10300_set_gdbleds(1);
asm volatile("mov mdr,%0" : "=d"(mdr));
- asm volatile("mov epsw,%0" : "=d"(epsw));
- asm volatile("mov %0,epsw"
- :: "d"((epsw & ~EPSW_IM) | EPSW_IE | EPSW_IM_1));
+ local_save_flags(epsw);
+ local_change_intr_mask_level(NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1));
gdbstub_store_fpu();
diff --git a/arch/mn10300/kernel/head.S b/arch/mn10300/kernel/head.S
index 14f27f3bfaf4..73e00fc78072 100644
--- a/arch/mn10300/kernel/head.S
+++ b/arch/mn10300/kernel/head.S
@@ -19,6 +19,12 @@
#include <asm/frame.inc>
#include <asm/param.h>
#include <unit/serial.h>
+#ifdef CONFIG_SMP
+#include <asm/smp.h>
+#include <asm/intctl-regs.h>
+#include <asm/cpu-regs.h>
+#include <proc/smp-regs.h>
+#endif /* CONFIG_SMP */
__HEAD
@@ -30,17 +36,51 @@
.globl _start
.type _start,@function
_start:
+#ifdef CONFIG_SMP
+ #
+ # If this is a secondary CPU (AP), then deal with that elsewhere
+ #
+ mov (CPUID),d3
+ and CPUID_MASK,d3
+ bne startup_secondary
+
+ #
+ # We're dealing with the primary CPU (BP) here, then.
+ # Keep BP's D0,D1,D2 register for boot check.
+ #
+
+ # Set up the Boot IPI for each secondary CPU
+ mov 0x1,a0
+loop_set_secondary_icr:
+ mov a0,a1
+ asl CROSS_ICR_CPU_SHIFT,a1
+ add CROSS_GxICR(SMP_BOOT_IRQ,0),a1
+ movhu (a1),d3
+ or GxICR_ENABLE|GxICR_LEVEL_0,d3
+ movhu d3,(a1)
+ movhu (a1),d3 # flush
+ inc a0
+ cmp NR_CPUS,a0
+ bne loop_set_secondary_icr
+#endif /* CONFIG_SMP */
+
# save commandline pointer
mov d0,a3
# preload the PGD pointer register
mov swapper_pg_dir,d0
mov d0,(PTBR)
+ clr d0
+ movbu d0,(PIDR)
# turn on the TLBs
mov MMUCTR_IIV|MMUCTR_DIV,d0
mov d0,(MMUCTR)
+#ifdef CONFIG_AM34_2
+ mov MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE|MMUCTR_WTE,d0
+#else
mov MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE,d0
+#endif
mov d0,(MMUCTR)
# turn on AM33v2 exception handling mode and set the trap table base
@@ -51,6 +91,11 @@ _start:
mov d0,(TBR)
# invalidate and enable both of the caches
+#ifdef CONFIG_SMP
+ mov ECHCTR,a0
+ clr d0
+ mov d0,(a0)
+#endif
mov CHCTR,a0
clr d0
movhu d0,(a0) # turn off first
@@ -61,18 +106,18 @@ _start:
btst CHCTR_ICBUSY|CHCTR_DCBUSY,d0 # wait till not busy
lne
-#ifndef CONFIG_MN10300_CACHE_DISABLED
+#ifdef CONFIG_MN10300_CACHE_ENABLED
#ifdef CONFIG_MN10300_CACHE_WBACK
#ifndef CONFIG_MN10300_CACHE_WBACK_NOWRALLOC
mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK,d0
#else
mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK|CHCTR_DCALMD,d0
-#endif /* CACHE_DISABLED */
+#endif /* NOWRALLOC */
#else
mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRTHROUGH,d0
#endif /* WBACK */
movhu d0,(a0) # enable
-#endif /* NOWRALLOC */
+#endif /* ENABLED */
# turn on RTS on the debug serial port if applicable
#ifdef CONFIG_MN10300_UNIT_ASB2305
@@ -206,6 +251,44 @@ __no_parameters:
call processor_init[],0
call unit_init[],0
+#ifdef CONFIG_SMP
+ # mark the primary CPU in cpu_boot_map
+ mov cpu_boot_map,a0
+ mov 0x1,d0
+ mov d0,(a0)
+
+ # signal each secondary CPU to begin booting
+ mov 0x1,d2 # CPU ID
+
+loop_request_boot_secondary:
+ mov d2,a0
+ # send SMP_BOOT_IPI to secondary CPU
+ asl CROSS_ICR_CPU_SHIFT,a0
+ add CROSS_GxICR(SMP_BOOT_IRQ,0),a0
+ movhu (a0),d0
+ or GxICR_REQUEST|GxICR_DETECT,d0
+ movhu d0,(a0)
+ movhu (a0),d0 # flush
+
+ # wait up to 100ms for AP's IPI to be received
+ clr d3
+wait_on_secondary_boot:
+ mov DELAY_TIME_BOOT_IPI,d0
+ call __delay[],0
+ inc d3
+ mov cpu_boot_map,a0
+ mov (a0),d0
+ lsr d2,d0
+ btst 0x1,d0
+ bne 1f
+ cmp TIME_OUT_COUNT_BOOT_IPI,d3
+ bne wait_on_secondary_boot
+1:
+ inc d2
+ cmp NR_CPUS,d2
+ bne loop_request_boot_secondary
+#endif /* CONFIG_SMP */
+
#ifdef CONFIG_GDBSTUB
call gdbstub_init[],0
@@ -217,7 +300,118 @@ __gdbstub_pause:
#endif
jmp start_kernel
- .size _start, _start-.
+ .size _start,.-_start
+
+###############################################################################
+#
+# Secondary CPU boot point
+#
+###############################################################################
+#ifdef CONFIG_SMP
+startup_secondary:
+ # preload the PGD pointer register
+ mov swapper_pg_dir,d0
+ mov d0,(PTBR)
+ clr d0
+ movbu d0,(PIDR)
+
+ # turn on the TLBs
+ mov MMUCTR_IIV|MMUCTR_DIV,d0
+ mov d0,(MMUCTR)
+#ifdef CONFIG_AM34_2
+ mov MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE|MMUCTR_WTE,d0
+#else
+ mov MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE,d0
+#endif
+ mov d0,(MMUCTR)
+
+ # turn on AM33v2 exception handling mode and set the trap table base
+ movhu (CPUP),d0
+ or CPUP_EXM_AM33V2,d0
+ movhu d0,(CPUP)
+
+ # set the interrupt vector table
+ mov CONFIG_INTERRUPT_VECTOR_BASE,d0
+ mov d0,(TBR)
+
+ # invalidate and enable both of the caches
+ mov ECHCTR,a0
+ clr d0
+ mov d0,(a0)
+ mov CHCTR,a0
+ clr d0
+ movhu d0,(a0) # turn off first
+ mov CHCTR_ICINV|CHCTR_DCINV,d0
+ movhu d0,(a0)
+ setlb
+ mov (a0),d0
+ btst CHCTR_ICBUSY|CHCTR_DCBUSY,d0 # wait till not busy (use CPU loop buffer)
+ lne
+
+#ifdef CONFIG_MN10300_CACHE_ENABLED
+#ifdef CONFIG_MN10300_CACHE_WBACK
+#ifndef CONFIG_MN10300_CACHE_WBACK_NOWRALLOC
+ mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK,d0
+#else
+ mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK|CHCTR_DCALMD,d0
+#endif /* !NOWRALLOC */
+#else
+ mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRTHROUGH,d0
+#endif /* WBACK */
+ movhu d0,(a0) # enable
+#endif /* ENABLED */
+
+ # Clear the boot IPI interrupt for this CPU
+ movhu (GxICR(SMP_BOOT_IRQ)),d0
+ and ~GxICR_REQUEST,d0
+ movhu d0,(GxICR(SMP_BOOT_IRQ))
+ movhu (GxICR(SMP_BOOT_IRQ)),d0 # flush
+
+ /* get stack */
+ mov CONFIG_INTERRUPT_VECTOR_BASE + CONFIG_BOOT_STACK_OFFSET,a0
+ mov (CPUID),d0
+ and CPUID_MASK,d0
+ mulu CONFIG_BOOT_STACK_SIZE,d0
+ sub d0,a0
+ mov a0,sp
+
+ # init interrupt for AP
+ call smp_prepare_cpu_init[],0
+
+ # mark this secondary CPU in cpu_boot_map
+ mov (CPUID),d0
+ mov 0x1,d1
+ asl d0,d1
+ mov cpu_boot_map,a0
+ bset d1,(a0)
+
+ or EPSW_IE|EPSW_IM_1,epsw # permit level 0 interrupts
+ nop
+ nop
+#ifdef CONFIG_MN10300_CACHE_WBACK
+ # flush the local cache if it's in writeback mode
+ call mn10300_local_dcache_flush_inv[],0
+ setlb
+ mov (CHCTR),d0
+ btst CHCTR_DCBUSY,d0 # wait till not busy (use CPU loop buffer)
+ lne
+#endif
+
+ # now sleep waiting for further instructions
+secondary_sleep:
+ mov CPUM_SLEEP,d0
+ movhu d0,(CPUM)
+ nop
+ nop
+ bra secondary_sleep
+ .size startup_secondary,.-startup_secondary
+#endif /* CONFIG_SMP */
+
+###############################################################################
+#
+#
+#
+###############################################################################
ENTRY(__head_end)
/*
diff --git a/arch/mn10300/kernel/internal.h b/arch/mn10300/kernel/internal.h
index eee2eee86267..6a064ab5af07 100644
--- a/arch/mn10300/kernel/internal.h
+++ b/arch/mn10300/kernel/internal.h
@@ -9,6 +9,9 @@
* 2 of the Licence, or (at your option) any later version.
*/
+struct clocksource;
+struct clock_event_device;
+
/*
* kthread.S
*/
@@ -18,3 +21,25 @@ extern int kernel_thread_helper(int);
* entry.S
*/
extern void ret_from_fork(struct task_struct *) __attribute__((noreturn));
+
+/*
+ * smp-low.S
+ */
+#ifdef CONFIG_SMP
+extern void mn10300_low_ipi_handler(void);
+#endif
+
+/*
+ * time.c
+ */
+extern irqreturn_t local_timer_interrupt(void);
+
+/*
+ * time.c
+ */
+#ifdef CONFIG_CEVT_MN10300
+extern void clockevent_set_clock(struct clock_event_device *, unsigned int);
+#endif
+#ifdef CONFIG_CSRC_MN10300
+extern void clocksource_set_clock(struct clocksource *, unsigned int);
+#endif
diff --git a/arch/mn10300/kernel/irq.c b/arch/mn10300/kernel/irq.c
index e2d5ed891f37..c2e44597c22b 100644
--- a/arch/mn10300/kernel/irq.c
+++ b/arch/mn10300/kernel/irq.c
@@ -12,11 +12,26 @@
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <linux/seq_file.h>
+#include <linux/cpumask.h>
#include <asm/setup.h>
+#include <asm/serial-regs.h>
-unsigned long __mn10300_irq_enabled_epsw = EPSW_IE | EPSW_IM_7;
+unsigned long __mn10300_irq_enabled_epsw[NR_CPUS] __cacheline_aligned_in_smp = {
+ [0 ... NR_CPUS - 1] = EPSW_IE | EPSW_IM_7
+};
EXPORT_SYMBOL(__mn10300_irq_enabled_epsw);
+#ifdef CONFIG_SMP
+static char irq_affinity_online[NR_IRQS] = {
+ [0 ... NR_IRQS - 1] = 0
+};
+
+#define NR_IRQ_WORDS ((NR_IRQS + 31) / 32)
+static unsigned long irq_affinity_request[NR_IRQ_WORDS] = {
+ [0 ... NR_IRQ_WORDS - 1] = 0
+};
+#endif /* CONFIG_SMP */
+
atomic_t irq_err_count;
/*
@@ -24,30 +39,67 @@ atomic_t irq_err_count;
*/
static void mn10300_cpupic_ack(unsigned int irq)
{
+ unsigned long flags;
u16 tmp;
- *(volatile u8 *) &GxICR(irq) = GxICR_DETECT;
+
+ flags = arch_local_cli_save();
+ GxICR_u8(irq) = GxICR_DETECT;
tmp = GxICR(irq);
+ arch_local_irq_restore(flags);
}
-static void mn10300_cpupic_mask(unsigned int irq)
+static void __mask_and_set_icr(unsigned int irq,
+ unsigned int mask, unsigned int set)
{
- u16 tmp = GxICR(irq);
- GxICR(irq) = (tmp & GxICR_LEVEL);
+ unsigned long flags;
+ u16 tmp;
+
+ flags = arch_local_cli_save();
+ tmp = GxICR(irq);
+ GxICR(irq) = (tmp & mask) | set;
tmp = GxICR(irq);
+ arch_local_irq_restore(flags);
+}
+
+static void mn10300_cpupic_mask(unsigned int irq)
+{
+ __mask_and_set_icr(irq, GxICR_LEVEL, 0);
}
static void mn10300_cpupic_mask_ack(unsigned int irq)
{
- u16 tmp = GxICR(irq);
- GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_DETECT;
- tmp = GxICR(irq);
+#ifdef CONFIG_SMP
+ unsigned long flags;
+ u16 tmp;
+
+ flags = arch_local_cli_save();
+
+ if (!test_and_clear_bit(irq, irq_affinity_request)) {
+ tmp = GxICR(irq);
+ GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_DETECT;
+ tmp = GxICR(irq);
+ } else {
+ u16 tmp2;
+ tmp = GxICR(irq);
+ GxICR(irq) = (tmp & GxICR_LEVEL);
+ tmp2 = GxICR(irq);
+
+ irq_affinity_online[irq] =
+ any_online_cpu(*irq_desc[irq].affinity);
+ CROSS_GxICR(irq, irq_affinity_online[irq]) =
+ (tmp & (GxICR_LEVEL | GxICR_ENABLE)) | GxICR_DETECT;
+ tmp = CROSS_GxICR(irq, irq_affinity_online[irq]);
+ }
+
+ arch_local_irq_restore(flags);
+#else /* CONFIG_SMP */
+ __mask_and_set_icr(irq, GxICR_LEVEL, GxICR_DETECT);
+#endif /* CONFIG_SMP */
}
static void mn10300_cpupic_unmask(unsigned int irq)
{
- u16 tmp = GxICR(irq);
- GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE;
- tmp = GxICR(irq);
+ __mask_and_set_icr(irq, GxICR_LEVEL, GxICR_ENABLE);
}
static void mn10300_cpupic_unmask_clear(unsigned int irq)
@@ -56,11 +108,89 @@ static void mn10300_cpupic_unmask_clear(unsigned int irq)
* device has ceased to assert its interrupt line and the interrupt
* channel has been disabled in the PIC, so for level-triggered
* interrupts we need to clear the request bit when we re-enable */
- u16 tmp = GxICR(irq);
- GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE | GxICR_DETECT;
- tmp = GxICR(irq);
+#ifdef CONFIG_SMP
+ unsigned long flags;
+ u16 tmp;
+
+ flags = arch_local_cli_save();
+
+ if (!test_and_clear_bit(irq, irq_affinity_request)) {
+ tmp = GxICR(irq);
+ GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE | GxICR_DETECT;
+ tmp = GxICR(irq);
+ } else {
+ tmp = GxICR(irq);
+
+ irq_affinity_online[irq] = any_online_cpu(*irq_desc[irq].affinity);
+ CROSS_GxICR(irq, irq_affinity_online[irq]) = (tmp & GxICR_LEVEL) | GxICR_ENABLE | GxICR_DETECT;
+ tmp = CROSS_GxICR(irq, irq_affinity_online[irq]);
+ }
+
+ arch_local_irq_restore(flags);
+#else /* CONFIG_SMP */
+ __mask_and_set_icr(irq, GxICR_LEVEL, GxICR_ENABLE | GxICR_DETECT);
+#endif /* CONFIG_SMP */
}
+#ifdef CONFIG_SMP
+static int
+mn10300_cpupic_setaffinity(unsigned int irq, const struct cpumask *mask)
+{
+ unsigned long flags;
+ int err;
+
+ flags = arch_local_cli_save();
+
+ /* check irq no */
+ switch (irq) {
+ case TMJCIRQ:
+ case RESCHEDULE_IPI:
+ case CALL_FUNC_SINGLE_IPI:
+ case LOCAL_TIMER_IPI:
+ case FLUSH_CACHE_IPI:
+ case CALL_FUNCTION_NMI_IPI:
+ case GDB_NMI_IPI:
+#ifdef CONFIG_MN10300_TTYSM0
+ case SC0RXIRQ:
+ case SC0TXIRQ:
+#ifdef CONFIG_MN10300_TTYSM0_TIMER8
+ case TM8IRQ:
+#elif CONFIG_MN10300_TTYSM0_TIMER2
+ case TM2IRQ:
+#endif /* CONFIG_MN10300_TTYSM0_TIMER8 */
+#endif /* CONFIG_MN10300_TTYSM0 */
+
+#ifdef CONFIG_MN10300_TTYSM1
+ case SC1RXIRQ:
+ case SC1TXIRQ:
+#ifdef CONFIG_MN10300_TTYSM1_TIMER12
+ case TM12IRQ:
+#elif CONFIG_MN10300_TTYSM1_TIMER9
+ case TM9IRQ:
+#elif CONFIG_MN10300_TTYSM1_TIMER3
+ case TM3IRQ:
+#endif /* CONFIG_MN10300_TTYSM1_TIMER12 */
+#endif /* CONFIG_MN10300_TTYSM1 */
+
+#ifdef CONFIG_MN10300_TTYSM2
+ case SC2RXIRQ:
+ case SC2TXIRQ:
+ case TM10IRQ:
+#endif /* CONFIG_MN10300_TTYSM2 */
+ err = -1;
+ break;
+
+ default:
+ set_bit(irq, irq_affinity_request);
+ err = 0;
+ break;
+ }
+
+ arch_local_irq_restore(flags);
+ return err;
+}
+#endif /* CONFIG_SMP */
+
/*
* MN10300 PIC level-triggered IRQ handling.
*
@@ -79,6 +209,9 @@ static struct irq_chip mn10300_cpu_pic_level = {
.mask = mn10300_cpupic_mask,
.mask_ack = mn10300_cpupic_mask,
.unmask = mn10300_cpupic_unmask_clear,
+#ifdef CONFIG_SMP
+ .set_affinity = mn10300_cpupic_setaffinity,
+#endif
};
/*
@@ -94,6 +227,9 @@ static struct irq_chip mn10300_cpu_pic_edge = {
.mask = mn10300_cpupic_mask,
.mask_ack = mn10300_cpupic_mask_ack,
.unmask = mn10300_cpupic_unmask,
+#ifdef CONFIG_SMP
+ .set_affinity = mn10300_cpupic_setaffinity,
+#endif
};
/*
@@ -111,14 +247,34 @@ void ack_bad_irq(int irq)
*/
void set_intr_level(int irq, u16 level)
{
- u16 tmp;
+ BUG_ON(in_interrupt());
- if (in_interrupt())
- BUG();
+ __mask_and_set_icr(irq, GxICR_ENABLE, level);
+}
- tmp = GxICR(irq);
- GxICR(irq) = (tmp & GxICR_ENABLE) | level;
- tmp = GxICR(irq);
+void mn10300_intc_set_level(unsigned int irq, unsigned int level)
+{
+ set_intr_level(irq, NUM2GxICR_LEVEL(level) & GxICR_LEVEL);
+}
+
+void mn10300_intc_clear(unsigned int irq)
+{
+ __mask_and_set_icr(irq, GxICR_LEVEL | GxICR_ENABLE, GxICR_DETECT);
+}
+
+void mn10300_intc_set(unsigned int irq)
+{
+ __mask_and_set_icr(irq, 0, GxICR_REQUEST | GxICR_DETECT);
+}
+
+void mn10300_intc_enable(unsigned int irq)
+{
+ mn10300_cpupic_unmask(irq);
+}
+
+void mn10300_intc_disable(unsigned int irq)
+{
+ mn10300_cpupic_mask(irq);
}
/*
@@ -126,7 +282,7 @@ void set_intr_level(int irq, u16 level)
* than before
* - see Documentation/mn10300/features.txt
*/
-void set_intr_postackable(int irq)
+void mn10300_set_lateack_irq_type(int irq)
{
set_irq_chip_and_handler(irq, &mn10300_cpu_pic_level,
handle_level_irq);
@@ -147,6 +303,7 @@ void __init init_IRQ(void)
* interrupts */
set_irq_chip_and_handler(irq, &mn10300_cpu_pic_edge,
handle_level_irq);
+
unit_init_IRQ();
}
@@ -156,20 +313,22 @@ void __init init_IRQ(void)
asmlinkage void do_IRQ(void)
{
unsigned long sp, epsw, irq_disabled_epsw, old_irq_enabled_epsw;
+ unsigned int cpu_id = smp_processor_id();
int irq;
sp = current_stack_pointer();
- if (sp - (sp & ~(THREAD_SIZE - 1)) < STACK_WARN)
- BUG();
+ BUG_ON(sp - (sp & ~(THREAD_SIZE - 1)) < STACK_WARN);
/* make sure local_irq_enable() doesn't muck up the interrupt priority
* setting in EPSW */
- old_irq_enabled_epsw = __mn10300_irq_enabled_epsw;
+ old_irq_enabled_epsw = __mn10300_irq_enabled_epsw[cpu_id];
local_save_flags(epsw);
- __mn10300_irq_enabled_epsw = EPSW_IE | (EPSW_IM & epsw);
+ __mn10300_irq_enabled_epsw[cpu_id] = EPSW_IE | (EPSW_IM & epsw);
irq_disabled_epsw = EPSW_IE | MN10300_CLI_LEVEL;
- __IRQ_STAT(smp_processor_id(), __irq_count)++;
+#ifdef CONFIG_MN10300_WD_TIMER
+ __IRQ_STAT(cpu_id, __irq_count)++;
+#endif
irq_enter();
@@ -189,7 +348,7 @@ asmlinkage void do_IRQ(void)
local_irq_restore(epsw);
}
- __mn10300_irq_enabled_epsw = old_irq_enabled_epsw;
+ __mn10300_irq_enabled_epsw[cpu_id] = old_irq_enabled_epsw;
irq_exit();
}
@@ -222,9 +381,16 @@ int show_interrupts(struct seq_file *p, void *v)
seq_printf(p, "%3d: ", i);
for_each_present_cpu(cpu)
seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
- seq_printf(p, " %14s.%u", irq_desc[i].chip->name,
- (GxICR(i) & GxICR_LEVEL) >>
- GxICR_LEVEL_SHIFT);
+
+ if (i < NR_CPU_IRQS)
+ seq_printf(p, " %14s.%u",
+ irq_desc[i].chip->name,
+ (GxICR(i) & GxICR_LEVEL) >>
+ GxICR_LEVEL_SHIFT);
+ else
+ seq_printf(p, " %14s",
+ irq_desc[i].chip->name);
+
seq_printf(p, " %s", action->name);
for (action = action->next;
@@ -240,11 +406,13 @@ int show_interrupts(struct seq_file *p, void *v)
/* polish off with NMI and error counters */
case NR_IRQS:
+#ifdef CONFIG_MN10300_WD_TIMER
seq_printf(p, "NMI: ");
for (j = 0; j < NR_CPUS; j++)
if (cpu_online(j))
seq_printf(p, "%10u ", nmi_count(j));
seq_putc(p, '\n');
+#endif
seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
break;
@@ -252,3 +420,51 @@ int show_interrupts(struct seq_file *p, void *v)
return 0;
}
+
+#ifdef CONFIG_HOTPLUG_CPU
+void migrate_irqs(void)
+{
+ irq_desc_t *desc;
+ int irq;
+ unsigned int self, new;
+ unsigned long flags;
+
+ self = smp_processor_id();
+ for (irq = 0; irq < NR_IRQS; irq++) {
+ desc = irq_desc + irq;
+
+ if (desc->status == IRQ_PER_CPU)
+ continue;
+
+ if (cpu_isset(self, irq_desc[irq].affinity) &&
+ !cpus_intersects(irq_affinity[irq], cpu_online_map)) {
+ int cpu_id;
+ cpu_id = first_cpu(cpu_online_map);
+ cpu_set(cpu_id, irq_desc[irq].affinity);
+ }
+ /* We need to operate irq_affinity_online atomically. */
+ arch_local_cli_save(flags);
+ if (irq_affinity_online[irq] == self) {
+ u16 x, tmp;
+
+ x = GxICR(irq);
+ GxICR(irq) = x & GxICR_LEVEL;
+ tmp = GxICR(irq);
+
+ new = any_online_cpu(irq_desc[irq].affinity);
+ irq_affinity_online[irq] = new;
+
+ CROSS_GxICR(irq, new) =
+ (x & GxICR_LEVEL) | GxICR_DETECT;
+ tmp = CROSS_GxICR(irq, new);
+
+ x &= GxICR_LEVEL | GxICR_ENABLE;
+ if (GxICR(irq) & GxICR_REQUEST) {
+ x |= GxICR_REQUEST | GxICR_DETECT;
+ CROSS_GxICR(irq, new) = x;
+ tmp = CROSS_GxICR(irq, new);
+ }
+ arch_local_irq_restore(flags);
+ }
+}
+#endif /* CONFIG_HOTPLUG_CPU */
diff --git a/arch/mn10300/kernel/kprobes.c b/arch/mn10300/kernel/kprobes.c
index 67e6389d625a..0311a7fcea16 100644
--- a/arch/mn10300/kernel/kprobes.c
+++ b/arch/mn10300/kernel/kprobes.c
@@ -377,8 +377,10 @@ void __kprobes arch_arm_kprobe(struct kprobe *p)
void __kprobes arch_disarm_kprobe(struct kprobe *p)
{
+#ifndef CONFIG_MN10300_CACHE_SNOOP
mn10300_dcache_flush();
mn10300_icache_inv();
+#endif
}
void arch_remove_kprobe(struct kprobe *p)
@@ -390,8 +392,10 @@ void __kprobes disarm_kprobe(struct kprobe *p, struct pt_regs *regs)
{
*p->addr = p->opcode;
regs->pc = (unsigned long) p->addr;
+#ifndef CONFIG_MN10300_CACHE_SNOOP
mn10300_dcache_flush();
mn10300_icache_inv();
+#endif
}
static inline
diff --git a/arch/mn10300/kernel/mn10300-serial-low.S b/arch/mn10300/kernel/mn10300-serial-low.S
index 66702d256610..dfc1b6f2fa9a 100644
--- a/arch/mn10300/kernel/mn10300-serial-low.S
+++ b/arch/mn10300/kernel/mn10300-serial-low.S
@@ -39,7 +39,7 @@
###############################################################################
.balign L1_CACHE_BYTES
ENTRY(mn10300_serial_vdma_interrupt)
- or EPSW_IE,psw # permit overriding by
+# or EPSW_IE,psw # permit overriding by
# debugging interrupts
movm [d2,d3,a2,a3,exreg0],(sp)
@@ -164,7 +164,7 @@ mnsc_vdma_tx_noint:
rti
mnsc_vdma_tx_empty:
- mov +(GxICR_LEVEL_1|GxICR_DETECT),d2
+ mov +(NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL)|GxICR_DETECT),d2
movhu d2,(e3) # disable the interrupt
movhu (e3),d2 # flush
@@ -175,7 +175,7 @@ mnsc_vdma_tx_break:
movhu (SCxCTR,e2),d2 # turn on break mode
or SC01CTR_BKE,d2
movhu d2,(SCxCTR,e2)
- mov +(GxICR_LEVEL_1|GxICR_DETECT),d2
+ mov +(NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL)|GxICR_DETECT),d2
movhu d2,(e3) # disable transmit interrupts on this
# channel
movhu (e3),d2 # flush
diff --git a/arch/mn10300/kernel/mn10300-serial.c b/arch/mn10300/kernel/mn10300-serial.c
index db509dd80565..996384dba45d 100644
--- a/arch/mn10300/kernel/mn10300-serial.c
+++ b/arch/mn10300/kernel/mn10300-serial.c
@@ -44,6 +44,11 @@ static const char serial_revdate[] = "2007-11-06";
#include <unit/timex.h>
#include "mn10300-serial.h"
+#ifdef CONFIG_SMP
+#undef GxICR
+#define GxICR(X) CROSS_GxICR(X, 0)
+#endif /* CONFIG_SMP */
+
#define kenter(FMT, ...) \
printk(KERN_DEBUG "-->%s(" FMT ")\n", __func__, ##__VA_ARGS__)
#define _enter(FMT, ...) \
@@ -57,6 +62,11 @@ static const char serial_revdate[] = "2007-11-06";
#define _proto(FMT, ...) \
no_printk(KERN_DEBUG "### MNSERIAL " FMT " ###\n", ##__VA_ARGS__)
+#ifndef CODMSB
+/* c_cflag bit meaning */
+#define CODMSB 004000000000 /* change Transfer bit-order */
+#endif
+
#define NR_UARTS 3
#ifdef CONFIG_MN10300_TTYSM_CONSOLE
@@ -152,26 +162,35 @@ struct mn10300_serial_port mn10300_serial_port_sif0 = {
.name = "ttySM0",
._iobase = &SC0CTR,
._control = &SC0CTR,
- ._status = (volatile u8 *) &SC0STR,
+ ._status = (volatile u8 *)&SC0STR,
._intr = &SC0ICR,
._rxb = &SC0RXB,
._txb = &SC0TXB,
.rx_name = "ttySM0:Rx",
.tx_name = "ttySM0:Tx",
-#ifdef CONFIG_MN10300_TTYSM0_TIMER8
+#if defined(CONFIG_MN10300_TTYSM0_TIMER8)
.tm_name = "ttySM0:Timer8",
._tmxmd = &TM8MD,
._tmxbr = &TM8BR,
._tmicr = &TM8ICR,
.tm_irq = TM8IRQ,
.div_timer = MNSCx_DIV_TIMER_16BIT,
-#else /* CONFIG_MN10300_TTYSM0_TIMER2 */
+#elif defined(CONFIG_MN10300_TTYSM0_TIMER0)
+ .tm_name = "ttySM0:Timer0",
+ ._tmxmd = &TM0MD,
+ ._tmxbr = (volatile u16 *)&TM0BR,
+ ._tmicr = &TM0ICR,
+ .tm_irq = TM0IRQ,
+ .div_timer = MNSCx_DIV_TIMER_8BIT,
+#elif defined(CONFIG_MN10300_TTYSM0_TIMER2)
.tm_name = "ttySM0:Timer2",
._tmxmd = &TM2MD,
- ._tmxbr = (volatile u16 *) &TM2BR,
+ ._tmxbr = (volatile u16 *)&TM2BR,
._tmicr = &TM2ICR,
.tm_irq = TM2IRQ,
.div_timer = MNSCx_DIV_TIMER_8BIT,
+#else
+#error "Unknown config for ttySM0"
#endif
.rx_irq = SC0RXIRQ,
.tx_irq = SC0TXIRQ,
@@ -205,26 +224,35 @@ struct mn10300_serial_port mn10300_serial_port_sif1 = {
.name = "ttySM1",
._iobase = &SC1CTR,
._control = &SC1CTR,
- ._status = (volatile u8 *) &SC1STR,
+ ._status = (volatile u8 *)&SC1STR,
._intr = &SC1ICR,
._rxb = &SC1RXB,
._txb = &SC1TXB,
.rx_name = "ttySM1:Rx",
.tx_name = "ttySM1:Tx",
-#ifdef CONFIG_MN10300_TTYSM1_TIMER9
+#if defined(CONFIG_MN10300_TTYSM1_TIMER9)
.tm_name = "ttySM1:Timer9",
._tmxmd = &TM9MD,
._tmxbr = &TM9BR,
._tmicr = &TM9ICR,
.tm_irq = TM9IRQ,
.div_timer = MNSCx_DIV_TIMER_16BIT,
-#else /* CONFIG_MN10300_TTYSM1_TIMER3 */
+#elif defined(CONFIG_MN10300_TTYSM1_TIMER3)
.tm_name = "ttySM1:Timer3",
._tmxmd = &TM3MD,
- ._tmxbr = (volatile u16 *) &TM3BR,
+ ._tmxbr = (volatile u16 *)&TM3BR,
._tmicr = &TM3ICR,
.tm_irq = TM3IRQ,
.div_timer = MNSCx_DIV_TIMER_8BIT,
+#elif defined(CONFIG_MN10300_TTYSM1_TIMER12)
+ .tm_name = "ttySM1/Timer12",
+ ._tmxmd = &TM12MD,
+ ._tmxbr = &TM12BR,
+ ._tmicr = &TM12ICR,
+ .tm_irq = TM12IRQ,
+ .div_timer = MNSCx_DIV_TIMER_16BIT,
+#else
+#error "Unknown config for ttySM1"
#endif
.rx_irq = SC1RXIRQ,
.tx_irq = SC1TXIRQ,
@@ -260,20 +288,45 @@ struct mn10300_serial_port mn10300_serial_port_sif2 = {
.uart.lock =
__SPIN_LOCK_UNLOCKED(mn10300_serial_port_sif2.uart.lock),
.name = "ttySM2",
- .rx_name = "ttySM2:Rx",
- .tx_name = "ttySM2:Tx",
- .tm_name = "ttySM2:Timer10",
._iobase = &SC2CTR,
._control = &SC2CTR,
- ._status = &SC2STR,
+ ._status = (volatile u8 *)&SC2STR,
._intr = &SC2ICR,
._rxb = &SC2RXB,
._txb = &SC2TXB,
+ .rx_name = "ttySM2:Rx",
+ .tx_name = "ttySM2:Tx",
+#if defined(CONFIG_MN10300_TTYSM2_TIMER10)
+ .tm_name = "ttySM2/Timer10",
._tmxmd = &TM10MD,
._tmxbr = &TM10BR,
._tmicr = &TM10ICR,
.tm_irq = TM10IRQ,
.div_timer = MNSCx_DIV_TIMER_16BIT,
+#elif defined(CONFIG_MN10300_TTYSM2_TIMER9)
+ .tm_name = "ttySM2/Timer9",
+ ._tmxmd = &TM9MD,
+ ._tmxbr = &TM9BR,
+ ._tmicr = &TM9ICR,
+ .tm_irq = TM9IRQ,
+ .div_timer = MNSCx_DIV_TIMER_16BIT,
+#elif defined(CONFIG_MN10300_TTYSM2_TIMER1)
+ .tm_name = "ttySM2/Timer1",
+ ._tmxmd = &TM1MD,
+ ._tmxbr = (volatile u16 *)&TM1BR,
+ ._tmicr = &TM1ICR,
+ .tm_irq = TM1IRQ,
+ .div_timer = MNSCx_DIV_TIMER_8BIT,
+#elif defined(CONFIG_MN10300_TTYSM2_TIMER3)
+ .tm_name = "ttySM2/Timer3",
+ ._tmxmd = &TM3MD,
+ ._tmxbr = (volatile u16 *)&TM3BR,
+ ._tmicr = &TM3ICR,
+ .tm_irq = TM3IRQ,
+ .div_timer = MNSCx_DIV_TIMER_8BIT,
+#else
+#error "Unknown config for ttySM2"
+#endif
.rx_irq = SC2RXIRQ,
.tx_irq = SC2TXIRQ,
.rx_icr = &GxICR(SC2RXIRQ),
@@ -322,9 +375,13 @@ struct mn10300_serial_port *mn10300_serial_ports[NR_UARTS + 1] = {
*/
static void mn10300_serial_mask_ack(unsigned int irq)
{
+ unsigned long flags;
u16 tmp;
+
+ flags = arch_local_cli_save();
GxICR(irq) = GxICR_LEVEL_6;
tmp = GxICR(irq); /* flush write buffer */
+ arch_local_irq_restore(flags);
}
static void mn10300_serial_nop(unsigned int irq)
@@ -348,23 +405,36 @@ struct mn10300_serial_int mn10300_serial_int_tbl[NR_IRQS];
static void mn10300_serial_dis_tx_intr(struct mn10300_serial_port *port)
{
+ unsigned long flags;
u16 x;
- *port->tx_icr = GxICR_LEVEL_1 | GxICR_DETECT;
+
+ flags = arch_local_cli_save();
+ *port->tx_icr = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL);
x = *port->tx_icr;
+ arch_local_irq_restore(flags);
}
static void mn10300_serial_en_tx_intr(struct mn10300_serial_port *port)
{
+ unsigned long flags;
u16 x;
- *port->tx_icr = GxICR_LEVEL_1 | GxICR_ENABLE;
+
+ flags = arch_local_cli_save();
+ *port->tx_icr =
+ NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL) | GxICR_ENABLE;
x = *port->tx_icr;
+ arch_local_irq_restore(flags);
}
static void mn10300_serial_dis_rx_intr(struct mn10300_serial_port *port)
{
+ unsigned long flags;
u16 x;
- *port->rx_icr = GxICR_LEVEL_1 | GxICR_DETECT;
+
+ flags = arch_local_cli_save();
+ *port->rx_icr = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL);
x = *port->rx_icr;
+ arch_local_irq_restore(flags);
}
/*
@@ -650,7 +720,7 @@ static unsigned int mn10300_serial_tx_empty(struct uart_port *_port)
static void mn10300_serial_set_mctrl(struct uart_port *_port,
unsigned int mctrl)
{
- struct mn10300_serial_port *port =
+ struct mn10300_serial_port *port __attribute__ ((unused)) =
container_of(_port, struct mn10300_serial_port, uart);
_enter("%s,%x", port->name, mctrl);
@@ -706,6 +776,7 @@ static void mn10300_serial_start_tx(struct uart_port *_port)
UART_XMIT_SIZE));
/* kick the virtual DMA controller */
+ arch_local_cli();
x = *port->tx_icr;
x |= GxICR_ENABLE;
@@ -716,10 +787,14 @@ static void mn10300_serial_start_tx(struct uart_port *_port)
_debug("CTR=%04hx ICR=%02hx STR=%04x TMD=%02hx TBR=%04hx ICR=%04hx",
*port->_control, *port->_intr, *port->_status,
- *port->_tmxmd, *port->_tmxbr, *port->tx_icr);
+ *port->_tmxmd,
+ (port->div_timer == MNSCx_DIV_TIMER_8BIT) ?
+ *(volatile u8 *)port->_tmxbr : *port->_tmxbr,
+ *port->tx_icr);
*port->tx_icr = x;
x = *port->tx_icr;
+ arch_local_sti();
}
/*
@@ -842,8 +917,10 @@ static int mn10300_serial_startup(struct uart_port *_port)
pint->port = port;
pint->vdma = mn10300_serial_vdma_tx_handler;
- set_intr_level(port->rx_irq, GxICR_LEVEL_1);
- set_intr_level(port->tx_irq, GxICR_LEVEL_1);
+ set_intr_level(port->rx_irq,
+ NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL));
+ set_intr_level(port->tx_irq,
+ NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL));
set_irq_chip(port->tm_irq, &mn10300_serial_pic);
if (request_irq(port->rx_irq, mn10300_serial_interrupt,
@@ -876,6 +953,7 @@ error:
*/
static void mn10300_serial_shutdown(struct uart_port *_port)
{
+ u16 x;
struct mn10300_serial_port *port =
container_of(_port, struct mn10300_serial_port, uart);
@@ -897,8 +975,12 @@ static void mn10300_serial_shutdown(struct uart_port *_port)
free_irq(port->rx_irq, port);
free_irq(port->tx_irq, port);
- *port->rx_icr = GxICR_LEVEL_1;
- *port->tx_icr = GxICR_LEVEL_1;
+ arch_local_cli();
+ *port->rx_icr = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL);
+ x = *port->rx_icr;
+ *port->tx_icr = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL);
+ x = *port->tx_icr;
+ arch_local_sti();
}
/*
@@ -947,11 +1029,66 @@ static void mn10300_serial_change_speed(struct mn10300_serial_port *port,
/* Determine divisor based on baud rate */
battempt = 0;
- if (div_timer == MNSCx_DIV_TIMER_16BIT)
- scxctr |= SC0CTR_CK_TM8UFLOW_8; /* ( == SC1CTR_CK_TM9UFLOW_8
- * == SC2CTR_CK_TM10UFLOW) */
- else if (div_timer == MNSCx_DIV_TIMER_8BIT)
+ switch (port->uart.line) {
+#ifdef CONFIG_MN10300_TTYSM0
+ case 0: /* ttySM0 */
+#if defined(CONFIG_MN10300_TTYSM0_TIMER8)
+ scxctr |= SC0CTR_CK_TM8UFLOW_8;
+#elif defined(CONFIG_MN10300_TTYSM0_TIMER0)
+ scxctr |= SC0CTR_CK_TM0UFLOW_8;
+#elif defined(CONFIG_MN10300_TTYSM0_TIMER2)
scxctr |= SC0CTR_CK_TM2UFLOW_8;
+#else
+#error "Unknown config for ttySM0"
+#endif
+ break;
+#endif /* CONFIG_MN10300_TTYSM0 */
+
+#ifdef CONFIG_MN10300_TTYSM1
+ case 1: /* ttySM1 */
+#if defined(CONFIG_AM33_2) || defined(CONFIG_AM33_3)
+#if defined(CONFIG_MN10300_TTYSM1_TIMER9)
+ scxctr |= SC1CTR_CK_TM9UFLOW_8;
+#elif defined(CONFIG_MN10300_TTYSM1_TIMER3)
+ scxctr |= SC1CTR_CK_TM3UFLOW_8;
+#else
+#error "Unknown config for ttySM1"
+#endif
+#else /* CONFIG_AM33_2 || CONFIG_AM33_3 */
+#if defined(CONFIG_MN10300_TTYSM1_TIMER12)
+ scxctr |= SC1CTR_CK_TM12UFLOW_8;
+#else
+#error "Unknown config for ttySM1"
+#endif
+#endif /* CONFIG_AM33_2 || CONFIG_AM33_3 */
+ break;
+#endif /* CONFIG_MN10300_TTYSM1 */
+
+#ifdef CONFIG_MN10300_TTYSM2
+ case 2: /* ttySM2 */
+#if defined(CONFIG_AM33_2)
+#if defined(CONFIG_MN10300_TTYSM2_TIMER10)
+ scxctr |= SC2CTR_CK_TM10UFLOW;
+#else
+#error "Unknown config for ttySM2"
+#endif
+#else /* CONFIG_AM33_2 */
+#if defined(CONFIG_MN10300_TTYSM2_TIMER9)
+ scxctr |= SC2CTR_CK_TM9UFLOW_8;
+#elif defined(CONFIG_MN10300_TTYSM2_TIMER1)
+ scxctr |= SC2CTR_CK_TM1UFLOW_8;
+#elif defined(CONFIG_MN10300_TTYSM2_TIMER3)
+ scxctr |= SC2CTR_CK_TM3UFLOW_8;
+#else
+#error "Unknown config for ttySM2"
+#endif
+#endif /* CONFIG_AM33_2 */
+ break;
+#endif /* CONFIG_MN10300_TTYSM2 */
+
+ default:
+ break;
+ }
try_alternative:
baud = uart_get_baud_rate(&port->uart, new, old, 0,
@@ -1195,6 +1332,12 @@ static void mn10300_serial_set_termios(struct uart_port *_port,
ctr &= ~SC2CTR_TWE;
*port->_control = ctr;
}
+
+ /* change Transfer bit-order (LSB/MSB) */
+ if (new->c_cflag & CODMSB)
+ *port->_control |= SC01CTR_OD_MSBFIRST; /* MSB MODE */
+ else
+ *port->_control &= ~SC01CTR_OD_MSBFIRST; /* LSB MODE */
}
/*
@@ -1302,11 +1445,16 @@ static int __init mn10300_serial_init(void)
printk(KERN_INFO "%s version %s (%s)\n",
serial_name, serial_version, serial_revdate);
-#ifdef CONFIG_MN10300_TTYSM2
- SC2TIM = 8; /* make the baud base of timer 2 IOCLK/8 */
+#if defined(CONFIG_MN10300_TTYSM2) && defined(CONFIG_AM33_2)
+ {
+ int tmp;
+ SC2TIM = 8; /* make the baud base of timer 2 IOCLK/8 */
+ tmp = SC2TIM;
+ }
#endif
- set_intr_stub(EXCEP_IRQ_LEVEL1, mn10300_serial_vdma_interrupt);
+ set_intr_stub(NUM2EXCEP_IRQ_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL),
+ mn10300_serial_vdma_interrupt);
ret = uart_register_driver(&mn10300_serial_driver);
if (!ret) {
@@ -1366,9 +1514,11 @@ static void mn10300_serial_console_write(struct console *co,
port = mn10300_serial_ports[co->index];
/* firstly hijack the serial port from the "virtual DMA" controller */
+ arch_local_cli();
txicr = *port->tx_icr;
- *port->tx_icr = GxICR_LEVEL_1;
+ *port->tx_icr = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL);
tmp = *port->tx_icr;
+ arch_local_sti();
/* the transmitter may be disabled */
scxctr = *port->_control;
@@ -1422,8 +1572,10 @@ static void mn10300_serial_console_write(struct console *co,
if (!(scxctr & SC01CTR_TXE))
*port->_control = scxctr;
+ arch_local_cli();
*port->tx_icr = txicr;
tmp = *port->tx_icr;
+ arch_local_sti();
}
/*
diff --git a/arch/mn10300/kernel/mn10300-watchdog-low.S b/arch/mn10300/kernel/mn10300-watchdog-low.S
index 996244745cca..f2f5c9cfaabd 100644
--- a/arch/mn10300/kernel/mn10300-watchdog-low.S
+++ b/arch/mn10300/kernel/mn10300-watchdog-low.S
@@ -16,6 +16,7 @@
#include <asm/intctl-regs.h>
#include <asm/timer-regs.h>
#include <asm/frame.inc>
+#include <linux/threads.h>
.text
@@ -53,7 +54,13 @@ watchdog_handler:
.type touch_nmi_watchdog,@function
touch_nmi_watchdog:
clr d0
- mov d0,(watchdog_alert_counter)
+ clr d1
+ mov watchdog_alert_counter, a0
+ setlb
+ mov d0, (a0+)
+ inc d1
+ cmp NR_CPUS, d1
+ lne
ret [],0
.size touch_nmi_watchdog,.-touch_nmi_watchdog
diff --git a/arch/mn10300/kernel/mn10300-watchdog.c b/arch/mn10300/kernel/mn10300-watchdog.c
index f362d9d138f1..c5e12bfd9fcd 100644
--- a/arch/mn10300/kernel/mn10300-watchdog.c
+++ b/arch/mn10300/kernel/mn10300-watchdog.c
@@ -30,7 +30,7 @@
static DEFINE_SPINLOCK(watchdog_print_lock);
static unsigned int watchdog;
static unsigned int watchdog_hz = 1;
-unsigned int watchdog_alert_counter;
+unsigned int watchdog_alert_counter[NR_CPUS];
EXPORT_SYMBOL(touch_nmi_watchdog);
@@ -39,9 +39,6 @@ EXPORT_SYMBOL(touch_nmi_watchdog);
* is to check its timer makes IRQ counts. If they are not
* changing then that CPU has some problem.
*
- * as these watchdog NMI IRQs are generated on every CPU, we only
- * have to check the current processor.
- *
* since NMIs dont listen to _any_ locks, we have to be extremely
* careful not to rely on unsafe variables. The printk might lock
* up though, so we have to break up any console locks first ...
@@ -69,8 +66,8 @@ int __init check_watchdog(void)
printk(KERN_INFO "OK.\n");
- /* now that we know it works we can reduce NMI frequency to
- * something more reasonable; makes a difference in some configs
+ /* now that we know it works we can reduce NMI frequency to something
+ * more reasonable; makes a difference in some configs
*/
watchdog_hz = 1;
@@ -121,15 +118,22 @@ void __init watchdog_go(void)
}
}
+#ifdef CONFIG_SMP
+static void watchdog_dump_register(void *dummy)
+{
+ printk(KERN_ERR "--- Register Dump (CPU%d) ---\n", CPUID);
+ show_registers(current_frame());
+}
+#endif
+
asmlinkage
void watchdog_interrupt(struct pt_regs *regs, enum exception_code excep)
{
-
/*
* Since current-> is always on the stack, and we always switch
* the stack NMI-atomically, it's safe to use smp_processor_id().
*/
- int sum, cpu = smp_processor_id();
+ int sum, cpu;
int irq = NMIIRQ;
u8 wdt, tmp;
@@ -138,43 +142,61 @@ void watchdog_interrupt(struct pt_regs *regs, enum exception_code excep)
tmp = WDCTR;
NMICR = NMICR_WDIF;
- nmi_count(cpu)++;
+ nmi_count(smp_processor_id())++;
kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
- sum = irq_stat[cpu].__irq_count;
-
- if (last_irq_sums[cpu] == sum) {
- /*
- * Ayiee, looks like this CPU is stuck ...
- * wait a few IRQs (5 seconds) before doing the oops ...
- */
- watchdog_alert_counter++;
- if (watchdog_alert_counter == 5 * watchdog_hz) {
- spin_lock(&watchdog_print_lock);
+
+ for_each_online_cpu(cpu) {
+
+ sum = irq_stat[cpu].__irq_count;
+
+ if ((last_irq_sums[cpu] == sum)
+#if defined(CONFIG_GDBSTUB) && defined(CONFIG_SMP)
+ && !(CHK_GDBSTUB_BUSY()
+ || atomic_read(&cpu_doing_single_step))
+#endif
+ ) {
/*
- * We are in trouble anyway, lets at least try
- * to get a message out.
+ * Ayiee, looks like this CPU is stuck ...
+ * wait a few IRQs (5 seconds) before doing the oops ...
*/
- bust_spinlocks(1);
- printk(KERN_ERR
- "NMI Watchdog detected LOCKUP on CPU%d,"
- " pc %08lx, registers:\n",
- cpu, regs->pc);
- show_registers(regs);
- printk("console shuts up ...\n");
- console_silent();
- spin_unlock(&watchdog_print_lock);
- bust_spinlocks(0);
+ watchdog_alert_counter[cpu]++;
+ if (watchdog_alert_counter[cpu] == 5 * watchdog_hz) {
+ spin_lock(&watchdog_print_lock);
+ /*
+ * We are in trouble anyway, lets at least try
+ * to get a message out.
+ */
+ bust_spinlocks(1);
+ printk(KERN_ERR
+ "NMI Watchdog detected LOCKUP on CPU%d,"
+ " pc %08lx, registers:\n",
+ cpu, regs->pc);
+#ifdef CONFIG_SMP
+ printk(KERN_ERR
+ "--- Register Dump (CPU%d) ---\n",
+ CPUID);
+#endif
+ show_registers(regs);
+#ifdef CONFIG_SMP
+ smp_nmi_call_function(watchdog_dump_register,
+ NULL, 1);
+#endif
+ printk(KERN_NOTICE "console shuts up ...\n");
+ console_silent();
+ spin_unlock(&watchdog_print_lock);
+ bust_spinlocks(0);
#ifdef CONFIG_GDBSTUB
- if (gdbstub_busy)
- gdbstub_exception(regs, excep);
- else
- gdbstub_intercept(regs, excep);
+ if (CHK_GDBSTUB_BUSY_AND_ACTIVE())
+ gdbstub_exception(regs, excep);
+ else
+ gdbstub_intercept(regs, excep);
#endif
- do_exit(SIGSEGV);
+ do_exit(SIGSEGV);
+ }
+ } else {
+ last_irq_sums[cpu] = sum;
+ watchdog_alert_counter[cpu] = 0;
}
- } else {
- last_irq_sums[cpu] = sum;
- watchdog_alert_counter = 0;
}
WDCTR = wdt | WDCTR_WDRST;
diff --git a/arch/mn10300/kernel/process.c b/arch/mn10300/kernel/process.c
index f48373e2bc1c..0d0f8049a17b 100644
--- a/arch/mn10300/kernel/process.c
+++ b/arch/mn10300/kernel/process.c
@@ -57,6 +57,7 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
void (*pm_power_off)(void);
EXPORT_SYMBOL(pm_power_off);
+#if !defined(CONFIG_SMP) || defined(CONFIG_HOTPLUG_CPU)
/*
* we use this if we don't have any better idle routine
*/
@@ -69,6 +70,35 @@ static void default_idle(void)
local_irq_enable();
}
+#else /* !CONFIG_SMP || CONFIG_HOTPLUG_CPU */
+/*
+ * On SMP it's slightly faster (but much more power-consuming!)
+ * to poll the ->work.need_resched flag instead of waiting for the
+ * cross-CPU IPI to arrive. Use this option with caution.
+ */
+static inline void poll_idle(void)
+{
+ int oldval;
+
+ local_irq_enable();
+
+ /*
+ * Deal with another CPU just having chosen a thread to
+ * run here:
+ */
+ oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
+
+ if (!oldval) {
+ set_thread_flag(TIF_POLLING_NRFLAG);
+ while (!need_resched())
+ cpu_relax();
+ clear_thread_flag(TIF_POLLING_NRFLAG);
+ } else {
+ set_need_resched();
+ }
+}
+#endif /* !CONFIG_SMP || CONFIG_HOTPLUG_CPU */
+
/*
* the idle thread
* - there's no useful work to be done, so just try to conserve power and have
@@ -77,8 +107,6 @@ static void default_idle(void)
*/
void cpu_idle(void)
{
- int cpu = smp_processor_id();
-
/* endless idle loop with no priority at all */
for (;;) {
while (!need_resched()) {
@@ -86,10 +114,13 @@ void cpu_idle(void)
smp_rmb();
idle = pm_idle;
- if (!idle)
+ if (!idle) {
+#if defined(CONFIG_SMP) && !defined(CONFIG_HOTPLUG_CPU)
+ idle = poll_idle;
+#else /* CONFIG_SMP && !CONFIG_HOTPLUG_CPU */
idle = default_idle;
-
- irq_stat[cpu].idle_timestamp = jiffies;
+#endif /* CONFIG_SMP && !CONFIG_HOTPLUG_CPU */
+ }
idle();
}
@@ -197,6 +228,7 @@ int copy_thread(unsigned long clone_flags,
unsigned long c_usp, unsigned long ustk_size,
struct task_struct *p, struct pt_regs *kregs)
{
+ struct thread_info *ti = task_thread_info(p);
struct pt_regs *c_uregs, *c_kregs, *uregs;
unsigned long c_ksp;
@@ -217,7 +249,7 @@ int copy_thread(unsigned long clone_flags,
/* the new TLS pointer is passed in as arg #5 to sys_clone() */
if (clone_flags & CLONE_SETTLS)
- c_uregs->e2 = __frame->d3;
+ c_uregs->e2 = current_frame()->d3;
/* set up the return kernel frame if called from kernel_thread() */
c_kregs = c_uregs;
@@ -235,7 +267,7 @@ int copy_thread(unsigned long clone_flags,
}
/* set up things up so the scheduler can start the new task */
- p->thread.__frame = c_kregs;
+ ti->frame = c_kregs;
p->thread.a3 = (unsigned long) c_kregs;
p->thread.sp = c_ksp;
p->thread.pc = (unsigned long) ret_from_fork;
@@ -247,25 +279,26 @@ int copy_thread(unsigned long clone_flags,
/*
* clone a process
- * - tlsptr is retrieved by copy_thread() from __frame->d3
+ * - tlsptr is retrieved by copy_thread() from current_frame()->d3
*/
asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp,
int __user *parent_tidptr, int __user *child_tidptr,
int __user *tlsptr)
{
- return do_fork(clone_flags, newsp ?: __frame->sp, __frame, 0,
- parent_tidptr, child_tidptr);
+ return do_fork(clone_flags, newsp ?: current_frame()->sp,
+ current_frame(), 0, parent_tidptr, child_tidptr);
}
asmlinkage long sys_fork(void)
{
- return do_fork(SIGCHLD, __frame->sp, __frame, 0, NULL, NULL);
+ return do_fork(SIGCHLD, current_frame()->sp,
+ current_frame(), 0, NULL, NULL);
}
asmlinkage long sys_vfork(void)
{
- return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, __frame->sp, __frame,
- 0, NULL, NULL);
+ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, current_frame()->sp,
+ current_frame(), 0, NULL, NULL);
}
asmlinkage long sys_execve(const char __user *name,
@@ -279,7 +312,7 @@ asmlinkage long sys_execve(const char __user *name,
error = PTR_ERR(filename);
if (IS_ERR(filename))
return error;
- error = do_execve(filename, argv, envp, __frame);
+ error = do_execve(filename, argv, envp, current_frame());
putname(filename);
return error;
}
diff --git a/arch/mn10300/kernel/profile.c b/arch/mn10300/kernel/profile.c
index 20d7d0306b16..4f342f75d00c 100644
--- a/arch/mn10300/kernel/profile.c
+++ b/arch/mn10300/kernel/profile.c
@@ -41,7 +41,7 @@ static __init int profile_init(void)
tmp = TM11ICR;
printk(KERN_INFO "Profiling initiated on timer 11, priority 0, %uHz\n",
- mn10300_ioclk / 8 / (TM11BR + 1));
+ MN10300_IOCLK / 8 / (TM11BR + 1));
printk(KERN_INFO "Profile histogram stored %p-%p\n",
prof_buffer, (u8 *)(prof_buffer + prof_len) - 1);
diff --git a/arch/mn10300/kernel/ptrace.c b/arch/mn10300/kernel/ptrace.c
index cf847dabc1bd..5c0b07e61006 100644
--- a/arch/mn10300/kernel/ptrace.c
+++ b/arch/mn10300/kernel/ptrace.c
@@ -295,31 +295,31 @@ void ptrace_disable(struct task_struct *child)
/*
* handle the arch-specific side of process tracing
*/
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
unsigned long tmp;
int ret;
+ unsigned long __user *datap = (unsigned long __user *) data;
switch (request) {
/* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR:
ret = -EIO;
- if ((addr & 3) || addr < 0 ||
- addr > sizeof(struct user) - 3)
+ if ((addr & 3) || addr > sizeof(struct user) - 3)
break;
tmp = 0; /* Default return condition */
if (addr < NR_PTREGS << 2)
tmp = get_stack_long(child,
ptrace_regid_to_frame[addr]);
- ret = put_user(tmp, (unsigned long *) data);
+ ret = put_user(tmp, datap);
break;
/* write the word at location addr in the USER area */
case PTRACE_POKEUSR:
ret = -EIO;
- if ((addr & 3) || addr < 0 ||
- addr > sizeof(struct user) - 3)
+ if ((addr & 3) || addr > sizeof(struct user) - 3)
break;
ret = 0;
@@ -332,25 +332,25 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
return copy_regset_to_user(child, &user_mn10300_native_view,
REGSET_GENERAL,
0, NR_PTREGS * sizeof(long),
- (void __user *)data);
+ datap);
case PTRACE_SETREGS: /* Set all integer regs in the child. */
return copy_regset_from_user(child, &user_mn10300_native_view,
REGSET_GENERAL,
0, NR_PTREGS * sizeof(long),
- (const void __user *)data);
+ datap);
case PTRACE_GETFPREGS: /* Get the child FPU state. */
return copy_regset_to_user(child, &user_mn10300_native_view,
REGSET_FPU,
0, sizeof(struct fpu_state_struct),
- (void __user *)data);
+ datap);
case PTRACE_SETFPREGS: /* Set the child FPU state. */
return copy_regset_from_user(child, &user_mn10300_native_view,
REGSET_FPU,
0, sizeof(struct fpu_state_struct),
- (const void __user *)data);
+ datap);
default:
ret = ptrace_request(child, request, addr, data);
diff --git a/arch/mn10300/kernel/rtc.c b/arch/mn10300/kernel/rtc.c
index 4eef0e7224f6..e9e20f9a4dd3 100644
--- a/arch/mn10300/kernel/rtc.c
+++ b/arch/mn10300/kernel/rtc.c
@@ -20,18 +20,22 @@
DEFINE_SPINLOCK(rtc_lock);
EXPORT_SYMBOL(rtc_lock);
-/* time for RTC to update itself in ioclks */
-static unsigned long mn10300_rtc_update_period;
-
+/*
+ * Read the current RTC time
+ */
void read_persistent_clock(struct timespec *ts)
{
struct rtc_time tm;
get_rtc_time(&tm);
- ts->tv_sec = mktime(tm.tm_year, tm.tm_mon, tm.tm_mday,
- tm.tm_hour, tm.tm_min, tm.tm_sec);
ts->tv_nsec = 0;
+ ts->tv_sec = mktime(tm.tm_year, tm.tm_mon, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
+
+ /* if rtc is way off in the past, set something reasonable */
+ if (ts->tv_sec < 0)
+ ts->tv_sec = mktime(2009, 1, 1, 12, 0, 0);
}
/*
@@ -115,39 +119,14 @@ int update_persistent_clock(struct timespec now)
*/
void __init calibrate_clock(void)
{
- unsigned long count0, counth, count1;
unsigned char status;
/* make sure the RTC is running and is set to operate in 24hr mode */
status = RTSRC;
RTCRB |= RTCRB_SET;
RTCRB |= RTCRB_TM_24HR;
+ RTCRB &= ~RTCRB_DM_BINARY;
RTCRA |= RTCRA_DVR;
RTCRA &= ~RTCRA_DVR;
RTCRB &= ~RTCRB_SET;
-
- /* work out the clock speed by counting clock cycles between ends of
- * the RTC update cycle - track the RTC through one complete update
- * cycle (1 second)
- */
- startup_timestamp_counter();
-
- while (!(RTCRA & RTCRA_UIP)) {}
- while ((RTCRA & RTCRA_UIP)) {}
-
- count0 = TMTSCBC;
-
- while (!(RTCRA & RTCRA_UIP)) {}
-
- counth = TMTSCBC;
-
- while ((RTCRA & RTCRA_UIP)) {}
-
- count1 = TMTSCBC;
-
- shutdown_timestamp_counter();
-
- MN10300_TSCCLK = count0 - count1; /* the timers count down */
- mn10300_rtc_update_period = counth - count1;
- MN10300_TSC_PER_HZ = MN10300_TSCCLK / HZ;
}
diff --git a/arch/mn10300/kernel/setup.c b/arch/mn10300/kernel/setup.c
index d464affcba0e..9e7a3209a3e1 100644
--- a/arch/mn10300/kernel/setup.c
+++ b/arch/mn10300/kernel/setup.c
@@ -22,6 +22,7 @@
#include <linux/init.h>
#include <linux/bootmem.h>
#include <linux/seq_file.h>
+#include <linux/cpu.h>
#include <asm/processor.h>
#include <linux/console.h>
#include <asm/uaccess.h>
@@ -30,7 +31,6 @@
#include <asm/io.h>
#include <asm/smp.h>
#include <proc/proc.h>
-#include <asm/busctl-regs.h>
#include <asm/fpu.h>
#include <asm/sections.h>
@@ -64,11 +64,13 @@ unsigned long memory_size;
struct thread_info *__current_ti = &init_thread_union.thread_info;
struct task_struct *__current = &init_task;
-#define mn10300_known_cpus 3
+#define mn10300_known_cpus 5
static const char *const mn10300_cputypes[] = {
- "am33v1",
- "am33v2",
- "am34v1",
+ "am33-1",
+ "am33-2",
+ "am34-1",
+ "am33-3",
+ "am34-2",
"unknown"
};
@@ -123,6 +125,7 @@ void __init setup_arch(char **cmdline_p)
cpu_init();
unit_setup();
+ smp_init_cpus();
parse_mem_cmdline(cmdline_p);
init_mm.start_code = (unsigned long)&_text;
@@ -179,57 +182,55 @@ void __init setup_arch(char **cmdline_p)
void __init cpu_init(void)
{
unsigned long cpurev = CPUREV, type;
- unsigned long base, size;
type = (CPUREV & CPUREV_TYPE) >> CPUREV_TYPE_S;
if (type > mn10300_known_cpus)
type = mn10300_known_cpus;
- printk(KERN_INFO "Matsushita %s, rev %ld\n",
+ printk(KERN_INFO "Panasonic %s, rev %ld\n",
mn10300_cputypes[type],
(cpurev & CPUREV_REVISION) >> CPUREV_REVISION_S);
- /* determine the memory size and base from the memory controller regs */
- memory_size = 0;
-
- base = SDBASE(0);
- if (base & SDBASE_CE) {
- size = (base & SDBASE_CBAM) << SDBASE_CBAM_SHIFT;
- size = ~size + 1;
- base &= SDBASE_CBA;
+ get_mem_info(&phys_memory_base, &memory_size);
+ phys_memory_end = phys_memory_base + memory_size;
- printk(KERN_INFO "SDRAM[0]: %luMb @%08lx\n", size >> 20, base);
- memory_size += size;
- phys_memory_base = base;
- }
+ fpu_init_state();
+}
- base = SDBASE(1);
- if (base & SDBASE_CE) {
- size = (base & SDBASE_CBAM) << SDBASE_CBAM_SHIFT;
- size = ~size + 1;
- base &= SDBASE_CBA;
+static struct cpu cpu_devices[NR_CPUS];
- printk(KERN_INFO "SDRAM[1]: %luMb @%08lx\n", size >> 20, base);
- memory_size += size;
- if (phys_memory_base == 0)
- phys_memory_base = base;
- }
+static int __init topology_init(void)
+{
+ int i;
- phys_memory_end = phys_memory_base + memory_size;
+ for_each_present_cpu(i)
+ register_cpu(&cpu_devices[i], i);
-#ifdef CONFIG_FPU
- fpu_init_state();
-#endif
+ return 0;
}
+subsys_initcall(topology_init);
+
/*
* Get CPU information for use by the procfs.
*/
static int show_cpuinfo(struct seq_file *m, void *v)
{
+#ifdef CONFIG_SMP
+ struct mn10300_cpuinfo *c = v;
+ unsigned long cpu_id = c - cpu_data;
+ unsigned long cpurev = c->type, type, icachesz, dcachesz;
+#else /* CONFIG_SMP */
+ unsigned long cpu_id = 0;
unsigned long cpurev = CPUREV, type, icachesz, dcachesz;
+#endif /* CONFIG_SMP */
- type = (CPUREV & CPUREV_TYPE) >> CPUREV_TYPE_S;
+#ifdef CONFIG_SMP
+ if (!cpu_online(cpu_id))
+ return 0;
+#endif
+
+ type = (cpurev & CPUREV_TYPE) >> CPUREV_TYPE_S;
if (type > mn10300_known_cpus)
type = mn10300_known_cpus;
@@ -244,13 +245,14 @@ static int show_cpuinfo(struct seq_file *m, void *v)
1024;
seq_printf(m,
- "processor : 0\n"
- "vendor_id : Matsushita\n"
+ "processor : %ld\n"
+ "vendor_id : " PROCESSOR_VENDOR_NAME "\n"
"cpu core : %s\n"
"cpu rev : %lu\n"
"model name : " PROCESSOR_MODEL_NAME "\n"
"icache size: %lu\n"
"dcache size: %lu\n",
+ cpu_id,
mn10300_cputypes[type],
(cpurev & CPUREV_REVISION) >> CPUREV_REVISION_S,
icachesz,
@@ -262,8 +264,13 @@ static int show_cpuinfo(struct seq_file *m, void *v)
"bogomips : %lu.%02lu\n\n",
MN10300_IOCLK / 1000000,
(MN10300_IOCLK / 10000) % 100,
+#ifdef CONFIG_SMP
+ c->loops_per_jiffy / (500000 / HZ),
+ (c->loops_per_jiffy / (5000 / HZ)) % 100
+#else /* CONFIG_SMP */
loops_per_jiffy / (500000 / HZ),
(loops_per_jiffy / (5000 / HZ)) % 100
+#endif /* CONFIG_SMP */
);
return 0;
diff --git a/arch/mn10300/kernel/signal.c b/arch/mn10300/kernel/signal.c
index d4de05ab7864..690f4e9507d7 100644
--- a/arch/mn10300/kernel/signal.c
+++ b/arch/mn10300/kernel/signal.c
@@ -91,7 +91,7 @@ asmlinkage long sys_sigaction(int sig,
*/
asmlinkage long sys_sigaltstack(const stack_t __user *uss, stack_t *uoss)
{
- return do_sigaltstack(uss, uoss, __frame->sp);
+ return do_sigaltstack(uss, uoss, current_frame()->sp);
}
/*
@@ -156,10 +156,11 @@ badframe:
*/
asmlinkage long sys_sigreturn(void)
{
- struct sigframe __user *frame = (struct sigframe __user *) __frame->sp;
+ struct sigframe __user *frame;
sigset_t set;
long d0;
+ frame = (struct sigframe __user *) current_frame()->sp;
if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
goto badframe;
if (__get_user(set.sig[0], &frame->sc.oldmask))
@@ -176,7 +177,7 @@ asmlinkage long sys_sigreturn(void)
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
- if (restore_sigcontext(__frame, &frame->sc, &d0))
+ if (restore_sigcontext(current_frame(), &frame->sc, &d0))
goto badframe;
return d0;
@@ -191,11 +192,11 @@ badframe:
*/
asmlinkage long sys_rt_sigreturn(void)
{
- struct rt_sigframe __user *frame =
- (struct rt_sigframe __user *) __frame->sp;
+ struct rt_sigframe __user *frame;
sigset_t set;
- unsigned long d0;
+ long d0;
+ frame = (struct rt_sigframe __user *) current_frame()->sp;
if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
goto badframe;
if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
@@ -207,10 +208,11 @@ asmlinkage long sys_rt_sigreturn(void)
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
- if (restore_sigcontext(__frame, &frame->uc.uc_mcontext, &d0))
+ if (restore_sigcontext(current_frame(), &frame->uc.uc_mcontext, &d0))
goto badframe;
- if (do_sigaltstack(&frame->uc.uc_stack, NULL, __frame->sp) == -EFAULT)
+ if (do_sigaltstack(&frame->uc.uc_stack, NULL, current_frame()->sp) ==
+ -EFAULT)
goto badframe;
return d0;
@@ -572,7 +574,7 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags)
if (thread_info_flags & _TIF_NOTIFY_RESUME) {
clear_thread_flag(TIF_NOTIFY_RESUME);
- tracehook_notify_resume(__frame);
+ tracehook_notify_resume(current_frame());
if (current->replacement_session_keyring)
key_replace_session_keyring();
}
diff --git a/arch/mn10300/kernel/smp-low.S b/arch/mn10300/kernel/smp-low.S
new file mode 100644
index 000000000000..72938cefc05e
--- /dev/null
+++ b/arch/mn10300/kernel/smp-low.S
@@ -0,0 +1,97 @@
+/* SMP IPI low-level handler
+ *
+ * Copyright (C) 2006-2007 Matsushita Electric Industrial Co., Ltd.
+ * 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.
+ *
+ */
+
+#include <linux/sys.h>
+#include <linux/linkage.h>
+#include <asm/smp.h>
+#include <asm/system.h>
+#include <asm/thread_info.h>
+#include <asm/cpu-regs.h>
+#include <proc/smp-regs.h>
+#include <asm/asm-offsets.h>
+#include <asm/frame.inc>
+
+ .am33_2
+
+###############################################################################
+#
+# IPI interrupt handler
+#
+###############################################################################
+ .globl mn10300_low_ipi_handler
+mn10300_low_ipi_handler:
+ add -4,sp
+ mov d0,(sp)
+ movhu (IAGR),d0
+ and IAGR_GN,d0
+ lsr 0x2,d0
+#ifdef CONFIG_MN10300_CACHE_ENABLED
+ cmp FLUSH_CACHE_IPI,d0
+ beq mn10300_flush_cache_ipi
+#endif
+ cmp SMP_BOOT_IRQ,d0
+ beq mn10300_smp_boot_ipi
+ /* OTHERS */
+ mov (sp),d0
+ add 4,sp
+#ifdef CONFIG_GDBSTUB
+ jmp gdbstub_io_rx_handler
+#else
+ jmp end
+#endif
+
+###############################################################################
+#
+# Cache flush IPI interrupt handler
+#
+###############################################################################
+#ifdef CONFIG_MN10300_CACHE_ENABLED
+mn10300_flush_cache_ipi:
+ mov (sp),d0
+ add 4,sp
+
+ /* FLUSH_CACHE_IPI */
+ add -4,sp
+ SAVE_ALL
+ mov GxICR_DETECT,d2
+ movbu d2,(GxICR(FLUSH_CACHE_IPI)) # ACK the interrupt
+ movhu (GxICR(FLUSH_CACHE_IPI)),d2
+ call smp_cache_interrupt[],0
+ RESTORE_ALL
+ jmp end
+#endif
+
+###############################################################################
+#
+# SMP boot CPU IPI interrupt handler
+#
+###############################################################################
+mn10300_smp_boot_ipi:
+ /* clear interrupt */
+ movhu (GxICR(SMP_BOOT_IRQ)),d0
+ and ~GxICR_REQUEST,d0
+ movhu d0,(GxICR(SMP_BOOT_IRQ))
+ mov (sp),d0
+ add 4,sp
+
+ # get stack
+ mov (CPUID),a0
+ add -1,a0
+ add a0,a0
+ add a0,a0
+ mov (start_stack,a0),a0
+ mov a0,sp
+ jmp initialize_secondary
+
+
+# Jump here after RTI to suppress the icache lookahead
+end:
diff --git a/arch/mn10300/kernel/smp.c b/arch/mn10300/kernel/smp.c
new file mode 100644
index 000000000000..0dcd1c686ba8
--- /dev/null
+++ b/arch/mn10300/kernel/smp.c
@@ -0,0 +1,1152 @@
+/* SMP support routines.
+ *
+ * Copyright (C) 2006-2008 Panasonic Corporation
+ * 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.
+ *
+ * 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 <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/jiffies.h>
+#include <linux/cpumask.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/profile.h>
+#include <linux/smp.h>
+#include <asm/tlbflush.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/processor.h>
+#include <asm/bug.h>
+#include <asm/exceptions.h>
+#include <asm/hardirq.h>
+#include <asm/fpu.h>
+#include <asm/mmu_context.h>
+#include <asm/thread_info.h>
+#include <asm/cpu-regs.h>
+#include <asm/intctl-regs.h>
+#include "internal.h"
+
+#ifdef CONFIG_HOTPLUG_CPU
+#include <linux/cpu.h>
+#include <asm/cacheflush.h>
+
+static unsigned long sleep_mode[NR_CPUS];
+
+static void run_sleep_cpu(unsigned int cpu);
+static void run_wakeup_cpu(unsigned int cpu);
+#endif /* CONFIG_HOTPLUG_CPU */
+
+/*
+ * Debug Message function
+ */
+
+#undef DEBUG_SMP
+#ifdef DEBUG_SMP
+#define Dprintk(fmt, ...) printk(KERN_DEBUG fmt, ##__VA_ARGS__)
+#else
+#define Dprintk(fmt, ...) no_printk(KERN_DEBUG fmt, ##__VA_ARGS__)
+#endif
+
+/* timeout value in msec for smp_nmi_call_function. zero is no timeout. */
+#define CALL_FUNCTION_NMI_IPI_TIMEOUT 0
+
+/*
+ * Structure and data for smp_nmi_call_function().
+ */
+struct nmi_call_data_struct {
+ smp_call_func_t func;
+ void *info;
+ cpumask_t started;
+ cpumask_t finished;
+ int wait;
+ char size_alignment[0]
+ __attribute__ ((__aligned__(SMP_CACHE_BYTES)));
+} __attribute__ ((__aligned__(SMP_CACHE_BYTES)));
+
+static DEFINE_SPINLOCK(smp_nmi_call_lock);
+static struct nmi_call_data_struct *nmi_call_data;
+
+/*
+ * Data structures and variables
+ */
+static cpumask_t cpu_callin_map; /* Bitmask of callin CPUs */
+static cpumask_t cpu_callout_map; /* Bitmask of callout CPUs */
+cpumask_t cpu_boot_map; /* Bitmask of boot APs */
+unsigned long start_stack[NR_CPUS - 1];
+
+/*
+ * Per CPU parameters
+ */
+struct mn10300_cpuinfo cpu_data[NR_CPUS] __cacheline_aligned;
+
+static int cpucount; /* The count of boot CPUs */
+static cpumask_t smp_commenced_mask;
+cpumask_t cpu_initialized __initdata = CPU_MASK_NONE;
+
+/*
+ * Function Prototypes
+ */
+static int do_boot_cpu(int);
+static void smp_show_cpu_info(int cpu_id);
+static void smp_callin(void);
+static void smp_online(void);
+static void smp_store_cpu_info(int);
+static void smp_cpu_init(void);
+static void smp_tune_scheduling(void);
+static void send_IPI_mask(const cpumask_t *cpumask, int irq);
+static void init_ipi(void);
+
+/*
+ * IPI Initialization interrupt definitions
+ */
+static void mn10300_ipi_disable(unsigned int irq);
+static void mn10300_ipi_enable(unsigned int irq);
+static void mn10300_ipi_ack(unsigned int irq);
+static void mn10300_ipi_nop(unsigned int irq);
+
+static struct irq_chip mn10300_ipi_type = {
+ .name = "cpu_ipi",
+ .disable = mn10300_ipi_disable,
+ .enable = mn10300_ipi_enable,
+ .ack = mn10300_ipi_ack,
+ .eoi = mn10300_ipi_nop
+};
+
+static irqreturn_t smp_reschedule_interrupt(int irq, void *dev_id);
+static irqreturn_t smp_call_function_interrupt(int irq, void *dev_id);
+
+static struct irqaction reschedule_ipi = {
+ .handler = smp_reschedule_interrupt,
+ .name = "smp reschedule IPI"
+};
+static struct irqaction call_function_ipi = {
+ .handler = smp_call_function_interrupt,
+ .name = "smp call function IPI"
+};
+
+#if !defined(CONFIG_GENERIC_CLOCKEVENTS) || defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
+static irqreturn_t smp_ipi_timer_interrupt(int irq, void *dev_id);
+static struct irqaction local_timer_ipi = {
+ .handler = smp_ipi_timer_interrupt,
+ .flags = IRQF_DISABLED,
+ .name = "smp local timer IPI"
+};
+#endif
+
+/**
+ * init_ipi - Initialise the IPI mechanism
+ */
+static void init_ipi(void)
+{
+ unsigned long flags;
+ u16 tmp16;
+
+ /* set up the reschedule IPI */
+ set_irq_chip_and_handler(RESCHEDULE_IPI,
+ &mn10300_ipi_type, handle_percpu_irq);
+ setup_irq(RESCHEDULE_IPI, &reschedule_ipi);
+ set_intr_level(RESCHEDULE_IPI, RESCHEDULE_GxICR_LV);
+ mn10300_ipi_enable(RESCHEDULE_IPI);
+
+ /* set up the call function IPI */
+ set_irq_chip_and_handler(CALL_FUNC_SINGLE_IPI,
+ &mn10300_ipi_type, handle_percpu_irq);
+ setup_irq(CALL_FUNC_SINGLE_IPI, &call_function_ipi);
+ set_intr_level(CALL_FUNC_SINGLE_IPI, CALL_FUNCTION_GxICR_LV);
+ mn10300_ipi_enable(CALL_FUNC_SINGLE_IPI);
+
+ /* set up the local timer IPI */
+#if !defined(CONFIG_GENERIC_CLOCKEVENTS) || \
+ defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
+ set_irq_chip_and_handler(LOCAL_TIMER_IPI,
+ &mn10300_ipi_type, handle_percpu_irq);
+ setup_irq(LOCAL_TIMER_IPI, &local_timer_ipi);
+ set_intr_level(LOCAL_TIMER_IPI, LOCAL_TIMER_GxICR_LV);
+ mn10300_ipi_enable(LOCAL_TIMER_IPI);
+#endif
+
+#ifdef CONFIG_MN10300_CACHE_ENABLED
+ /* set up the cache flush IPI */
+ flags = arch_local_cli_save();
+ __set_intr_stub(NUM2EXCEP_IRQ_LEVEL(FLUSH_CACHE_GxICR_LV),
+ mn10300_low_ipi_handler);
+ GxICR(FLUSH_CACHE_IPI) = FLUSH_CACHE_GxICR_LV | GxICR_DETECT;
+ mn10300_ipi_enable(FLUSH_CACHE_IPI);
+ arch_local_irq_restore(flags);
+#endif
+
+ /* set up the NMI call function IPI */
+ flags = arch_local_cli_save();
+ GxICR(CALL_FUNCTION_NMI_IPI) = GxICR_NMI | GxICR_ENABLE | GxICR_DETECT;
+ tmp16 = GxICR(CALL_FUNCTION_NMI_IPI);
+ arch_local_irq_restore(flags);
+
+ /* set up the SMP boot IPI */
+ flags = arch_local_cli_save();
+ __set_intr_stub(NUM2EXCEP_IRQ_LEVEL(SMP_BOOT_GxICR_LV),
+ mn10300_low_ipi_handler);
+ arch_local_irq_restore(flags);
+}
+
+/**
+ * mn10300_ipi_shutdown - Shut down handling of an IPI
+ * @irq: The IPI to be shut down.
+ */
+static void mn10300_ipi_shutdown(unsigned int irq)
+{
+ unsigned long flags;
+ u16 tmp;
+
+ flags = arch_local_cli_save();
+
+ tmp = GxICR(irq);
+ GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_DETECT;
+ tmp = GxICR(irq);
+
+ arch_local_irq_restore(flags);
+}
+
+/**
+ * mn10300_ipi_enable - Enable an IPI
+ * @irq: The IPI to be enabled.
+ */
+static void mn10300_ipi_enable(unsigned int irq)
+{
+ unsigned long flags;
+ u16 tmp;
+
+ flags = arch_local_cli_save();
+
+ tmp = GxICR(irq);
+ GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE;
+ tmp = GxICR(irq);
+
+ arch_local_irq_restore(flags);
+}
+
+/**
+ * mn10300_ipi_disable - Disable an IPI
+ * @irq: The IPI to be disabled.
+ */
+static void mn10300_ipi_disable(unsigned int irq)
+{
+ unsigned long flags;
+ u16 tmp;
+
+ flags = arch_local_cli_save();
+
+ tmp = GxICR(irq);
+ GxICR(irq) = tmp & GxICR_LEVEL;
+ tmp = GxICR(irq);
+
+ arch_local_irq_restore(flags);
+}
+
+/**
+ * mn10300_ipi_ack - Acknowledge an IPI interrupt in the PIC
+ * @irq: The IPI to be acknowledged.
+ *
+ * Clear the interrupt detection flag for the IPI on the appropriate interrupt
+ * channel in the PIC.
+ */
+static void mn10300_ipi_ack(unsigned int irq)
+{
+ unsigned long flags;
+ u16 tmp;
+
+ flags = arch_local_cli_save();
+ GxICR_u8(irq) = GxICR_DETECT;
+ tmp = GxICR(irq);
+ arch_local_irq_restore(flags);
+}
+
+/**
+ * mn10300_ipi_nop - Dummy IPI action
+ * @irq: The IPI to be acted upon.
+ */
+static void mn10300_ipi_nop(unsigned int irq)
+{
+}
+
+/**
+ * send_IPI_mask - Send IPIs to all CPUs in list
+ * @cpumask: The list of CPUs to target.
+ * @irq: The IPI request to be sent.
+ *
+ * Send the specified IPI to all the CPUs in the list, not waiting for them to
+ * finish before returning. The caller is responsible for synchronisation if
+ * that is needed.
+ */
+static void send_IPI_mask(const cpumask_t *cpumask, int irq)
+{
+ int i;
+ u16 tmp;
+
+ for (i = 0; i < NR_CPUS; i++) {
+ if (cpu_isset(i, *cpumask)) {
+ /* send IPI */
+ tmp = CROSS_GxICR(irq, i);
+ CROSS_GxICR(irq, i) =
+ tmp | GxICR_REQUEST | GxICR_DETECT;
+ tmp = CROSS_GxICR(irq, i); /* flush write buffer */
+ }
+ }
+}
+
+/**
+ * send_IPI_self - Send an IPI to this CPU.
+ * @irq: The IPI request to be sent.
+ *
+ * Send the specified IPI to the current CPU.
+ */
+void send_IPI_self(int irq)
+{
+ send_IPI_mask(cpumask_of(smp_processor_id()), irq);
+}
+
+/**
+ * send_IPI_allbutself - Send IPIs to all the other CPUs.
+ * @irq: The IPI request to be sent.
+ *
+ * Send the specified IPI to all CPUs in the system barring the current one,
+ * not waiting for them to finish before returning. The caller is responsible
+ * for synchronisation if that is needed.
+ */
+void send_IPI_allbutself(int irq)
+{
+ cpumask_t cpumask;
+
+ cpumask = cpu_online_map;
+ cpu_clear(smp_processor_id(), cpumask);
+ send_IPI_mask(&cpumask, irq);
+}
+
+void arch_send_call_function_ipi_mask(const struct cpumask *mask)
+{
+ BUG();
+ /*send_IPI_mask(mask, CALL_FUNCTION_IPI);*/
+}
+
+void arch_send_call_function_single_ipi(int cpu)
+{
+ send_IPI_mask(cpumask_of(cpu), CALL_FUNC_SINGLE_IPI);
+}
+
+/**
+ * smp_send_reschedule - Send reschedule IPI to a CPU
+ * @cpu: The CPU to target.
+ */
+void smp_send_reschedule(int cpu)
+{
+ send_IPI_mask(cpumask_of(cpu), RESCHEDULE_IPI);
+}
+
+/**
+ * smp_nmi_call_function - Send a call function NMI IPI to all CPUs
+ * @func: The function to ask to be run.
+ * @info: The context data to pass to that function.
+ * @wait: If true, wait (atomically) until function is run on all CPUs.
+ *
+ * Send a non-maskable request to all CPUs in the system, requesting them to
+ * run the specified function with the given context data, and, potentially, to
+ * wait for completion of that function on all CPUs.
+ *
+ * Returns 0 if successful, -ETIMEDOUT if we were asked to wait, but hit the
+ * timeout.
+ */
+int smp_nmi_call_function(smp_call_func_t func, void *info, int wait)
+{
+ struct nmi_call_data_struct data;
+ unsigned long flags;
+ unsigned int cnt;
+ int cpus, ret = 0;
+
+ cpus = num_online_cpus() - 1;
+ if (cpus < 1)
+ return 0;
+
+ data.func = func;
+ data.info = info;
+ data.started = cpu_online_map;
+ cpu_clear(smp_processor_id(), data.started);
+ data.wait = wait;
+ if (wait)
+ data.finished = data.started;
+
+ spin_lock_irqsave(&smp_nmi_call_lock, flags);
+ nmi_call_data = &data;
+ smp_mb();
+
+ /* Send a message to all other CPUs and wait for them to respond */
+ send_IPI_allbutself(CALL_FUNCTION_NMI_IPI);
+
+ /* Wait for response */
+ if (CALL_FUNCTION_NMI_IPI_TIMEOUT > 0) {
+ for (cnt = 0;
+ cnt < CALL_FUNCTION_NMI_IPI_TIMEOUT &&
+ !cpus_empty(data.started);
+ cnt++)
+ mdelay(1);
+
+ if (wait && cnt < CALL_FUNCTION_NMI_IPI_TIMEOUT) {
+ for (cnt = 0;
+ cnt < CALL_FUNCTION_NMI_IPI_TIMEOUT &&
+ !cpus_empty(data.finished);
+ cnt++)
+ mdelay(1);
+ }
+
+ if (cnt >= CALL_FUNCTION_NMI_IPI_TIMEOUT)
+ ret = -ETIMEDOUT;
+
+ } else {
+ /* If timeout value is zero, wait until cpumask has been
+ * cleared */
+ while (!cpus_empty(data.started))
+ barrier();
+ if (wait)
+ while (!cpus_empty(data.finished))
+ barrier();
+ }
+
+ spin_unlock_irqrestore(&smp_nmi_call_lock, flags);
+ return ret;
+}
+
+/**
+ * stop_this_cpu - Callback to stop a CPU.
+ * @unused: Callback context (ignored).
+ */
+void stop_this_cpu(void *unused)
+{
+ static volatile int stopflag;
+ unsigned long flags;
+
+#ifdef CONFIG_GDBSTUB
+ /* In case of single stepping smp_send_stop by other CPU,
+ * clear procindebug to avoid deadlock.
+ */
+ atomic_set(&procindebug[smp_processor_id()], 0);
+#endif /* CONFIG_GDBSTUB */
+
+ flags = arch_local_cli_save();
+ cpu_clear(smp_processor_id(), cpu_online_map);
+
+ while (!stopflag)
+ cpu_relax();
+
+ cpu_set(smp_processor_id(), cpu_online_map);
+ arch_local_irq_restore(flags);
+}
+
+/**
+ * smp_send_stop - Send a stop request to all CPUs.
+ */
+void smp_send_stop(void)
+{
+ smp_nmi_call_function(stop_this_cpu, NULL, 0);
+}
+
+/**
+ * smp_reschedule_interrupt - Reschedule IPI handler
+ * @irq: The interrupt number.
+ * @dev_id: The device ID.
+ *
+ * We need do nothing here, since the scheduling will be effected on our way
+ * back through entry.S.
+ *
+ * Returns IRQ_HANDLED to indicate we handled the interrupt successfully.
+ */
+static irqreturn_t smp_reschedule_interrupt(int irq, void *dev_id)
+{
+ /* do nothing */
+ return IRQ_HANDLED;
+}
+
+/**
+ * smp_call_function_interrupt - Call function IPI handler
+ * @irq: The interrupt number.
+ * @dev_id: The device ID.
+ *
+ * Returns IRQ_HANDLED to indicate we handled the interrupt successfully.
+ */
+static irqreturn_t smp_call_function_interrupt(int irq, void *dev_id)
+{
+ /* generic_smp_call_function_interrupt(); */
+ generic_smp_call_function_single_interrupt();
+ return IRQ_HANDLED;
+}
+
+/**
+ * smp_nmi_call_function_interrupt - Non-maskable call function IPI handler
+ */
+void smp_nmi_call_function_interrupt(void)
+{
+ smp_call_func_t func = nmi_call_data->func;
+ void *info = nmi_call_data->info;
+ int wait = nmi_call_data->wait;
+
+ /* Notify the initiating CPU that I've grabbed the data and am about to
+ * execute the function
+ */
+ smp_mb();
+ cpu_clear(smp_processor_id(), nmi_call_data->started);
+ (*func)(info);
+
+ if (wait) {
+ smp_mb();
+ cpu_clear(smp_processor_id(), nmi_call_data->finished);
+ }
+}
+
+#if !defined(CONFIG_GENERIC_CLOCKEVENTS) || \
+ defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
+/**
+ * smp_ipi_timer_interrupt - Local timer IPI handler
+ * @irq: The interrupt number.
+ * @dev_id: The device ID.
+ *
+ * Returns IRQ_HANDLED to indicate we handled the interrupt successfully.
+ */
+static irqreturn_t smp_ipi_timer_interrupt(int irq, void *dev_id)
+{
+ return local_timer_interrupt();
+}
+#endif
+
+void __init smp_init_cpus(void)
+{
+ int i;
+ for (i = 0; i < NR_CPUS; i++) {
+ set_cpu_possible(i, true);
+ set_cpu_present(i, true);
+ }
+}
+
+/**
+ * smp_cpu_init - Initialise AP in start_secondary.
+ *
+ * For this Application Processor, set up init_mm, initialise FPU and set
+ * interrupt level 0-6 setting.
+ */
+static void __init smp_cpu_init(void)
+{
+ unsigned long flags;
+ int cpu_id = smp_processor_id();
+ u16 tmp16;
+
+ if (test_and_set_bit(cpu_id, &cpu_initialized)) {
+ printk(KERN_WARNING "CPU#%d already initialized!\n", cpu_id);
+ for (;;)
+ local_irq_enable();
+ }
+ printk(KERN_INFO "Initializing CPU#%d\n", cpu_id);
+
+ atomic_inc(&init_mm.mm_count);
+ current->active_mm = &init_mm;
+ BUG_ON(current->mm);
+
+ enter_lazy_tlb(&init_mm, current);
+
+ /* Force FPU initialization */
+ clear_using_fpu(current);
+
+ GxICR(CALL_FUNC_SINGLE_IPI) = CALL_FUNCTION_GxICR_LV | GxICR_DETECT;
+ mn10300_ipi_enable(CALL_FUNC_SINGLE_IPI);
+
+ GxICR(LOCAL_TIMER_IPI) = LOCAL_TIMER_GxICR_LV | GxICR_DETECT;
+ mn10300_ipi_enable(LOCAL_TIMER_IPI);
+
+ GxICR(RESCHEDULE_IPI) = RESCHEDULE_GxICR_LV | GxICR_DETECT;
+ mn10300_ipi_enable(RESCHEDULE_IPI);
+
+#ifdef CONFIG_MN10300_CACHE_ENABLED
+ GxICR(FLUSH_CACHE_IPI) = FLUSH_CACHE_GxICR_LV | GxICR_DETECT;
+ mn10300_ipi_enable(FLUSH_CACHE_IPI);
+#endif
+
+ mn10300_ipi_shutdown(SMP_BOOT_IRQ);
+
+ /* Set up the non-maskable call function IPI */
+ flags = arch_local_cli_save();
+ GxICR(CALL_FUNCTION_NMI_IPI) = GxICR_NMI | GxICR_ENABLE | GxICR_DETECT;
+ tmp16 = GxICR(CALL_FUNCTION_NMI_IPI);
+ arch_local_irq_restore(flags);
+}
+
+/**
+ * smp_prepare_cpu_init - Initialise CPU in startup_secondary
+ *
+ * Set interrupt level 0-6 setting and init ICR of gdbstub.
+ */
+void smp_prepare_cpu_init(void)
+{
+ int loop;
+
+ /* Set the interrupt vector registers */
+ IVAR0 = EXCEP_IRQ_LEVEL0;
+ IVAR1 = EXCEP_IRQ_LEVEL1;
+ IVAR2 = EXCEP_IRQ_LEVEL2;
+ IVAR3 = EXCEP_IRQ_LEVEL3;
+ IVAR4 = EXCEP_IRQ_LEVEL4;
+ IVAR5 = EXCEP_IRQ_LEVEL5;
+ IVAR6 = EXCEP_IRQ_LEVEL6;
+
+ /* Disable all interrupts and set to priority 6 (lowest) */
+ for (loop = 0; loop < GxICR_NUM_IRQS; loop++)
+ GxICR(loop) = GxICR_LEVEL_6 | GxICR_DETECT;
+
+#ifdef CONFIG_GDBSTUB
+ /* initialise GDB-stub */
+ do {
+ unsigned long flags;
+ u16 tmp16;
+
+ flags = arch_local_cli_save();
+ GxICR(GDB_NMI_IPI) = GxICR_NMI | GxICR_ENABLE | GxICR_DETECT;
+ tmp16 = GxICR(GDB_NMI_IPI);
+ arch_local_irq_restore(flags);
+ } while (0);
+#endif
+}
+
+/**
+ * start_secondary - Activate a secondary CPU (AP)
+ * @unused: Thread parameter (ignored).
+ */
+int __init start_secondary(void *unused)
+{
+ smp_cpu_init();
+ smp_callin();
+ while (!cpu_isset(smp_processor_id(), smp_commenced_mask))
+ cpu_relax();
+
+ local_flush_tlb();
+ preempt_disable();
+ smp_online();
+
+#ifdef CONFIG_GENERIC_CLOCKEVENTS
+ init_clockevents();
+#endif
+ cpu_idle();
+ return 0;
+}
+
+/**
+ * smp_prepare_cpus - Boot up secondary CPUs (APs)
+ * @max_cpus: Maximum number of CPUs to boot.
+ *
+ * Call do_boot_cpu, and boot up APs.
+ */
+void __init smp_prepare_cpus(unsigned int max_cpus)
+{
+ int phy_id;
+
+ /* Setup boot CPU information */
+ smp_store_cpu_info(0);
+ smp_tune_scheduling();
+
+ init_ipi();
+
+ /* If SMP should be disabled, then finish */
+ if (max_cpus == 0) {
+ printk(KERN_INFO "SMP mode deactivated.\n");
+ goto smp_done;
+ }
+
+ /* Boot secondary CPUs (for which phy_id > 0) */
+ for (phy_id = 0; phy_id < NR_CPUS; phy_id++) {
+ /* Don't boot primary CPU */
+ if (max_cpus <= cpucount + 1)
+ continue;
+ if (phy_id != 0)
+ do_boot_cpu(phy_id);
+ set_cpu_possible(phy_id, true);
+ smp_show_cpu_info(phy_id);
+ }
+
+smp_done:
+ Dprintk("Boot done.\n");
+}
+
+/**
+ * smp_store_cpu_info - Save a CPU's information
+ * @cpu: The CPU to save for.
+ *
+ * Save boot_cpu_data and jiffy for the specified CPU.
+ */
+static void __init smp_store_cpu_info(int cpu)
+{
+ struct mn10300_cpuinfo *ci = &cpu_data[cpu];
+
+ *ci = boot_cpu_data;
+ ci->loops_per_jiffy = loops_per_jiffy;
+ ci->type = CPUREV;
+}
+
+/**
+ * smp_tune_scheduling - Set time slice value
+ *
+ * Nothing to do here.
+ */
+static void __init smp_tune_scheduling(void)
+{
+}
+
+/**
+ * do_boot_cpu: Boot up one CPU
+ * @phy_id: Physical ID of CPU to boot.
+ *
+ * Send an IPI to a secondary CPU to boot it. Returns 0 on success, 1
+ * otherwise.
+ */
+static int __init do_boot_cpu(int phy_id)
+{
+ struct task_struct *idle;
+ unsigned long send_status, callin_status;
+ int timeout, cpu_id;
+
+ send_status = GxICR_REQUEST;
+ callin_status = 0;
+ timeout = 0;
+ cpu_id = phy_id;
+
+ cpucount++;
+
+ /* Create idle thread for this CPU */
+ idle = fork_idle(cpu_id);
+ if (IS_ERR(idle))
+ panic("Failed fork for CPU#%d.", cpu_id);
+
+ idle->thread.pc = (unsigned long)start_secondary;
+
+ printk(KERN_NOTICE "Booting CPU#%d\n", cpu_id);
+ start_stack[cpu_id - 1] = idle->thread.sp;
+
+ task_thread_info(idle)->cpu = cpu_id;
+
+ /* Send boot IPI to AP */
+ send_IPI_mask(cpumask_of(phy_id), SMP_BOOT_IRQ);
+
+ Dprintk("Waiting for send to finish...\n");
+
+ /* Wait for AP's IPI receive in 100[ms] */
+ do {
+ udelay(1000);
+ send_status =
+ CROSS_GxICR(SMP_BOOT_IRQ, phy_id) & GxICR_REQUEST;
+ } while (send_status == GxICR_REQUEST && timeout++ < 100);
+
+ Dprintk("Waiting for cpu_callin_map.\n");
+
+ if (send_status == 0) {
+ /* Allow AP to start initializing */
+ cpu_set(cpu_id, cpu_callout_map);
+
+ /* Wait for setting cpu_callin_map */
+ timeout = 0;
+ do {
+ udelay(1000);
+ callin_status = cpu_isset(cpu_id, cpu_callin_map);
+ } while (callin_status == 0 && timeout++ < 5000);
+
+ if (callin_status == 0)
+ Dprintk("Not responding.\n");
+ } else {
+ printk(KERN_WARNING "IPI not delivered.\n");
+ }
+
+ if (send_status == GxICR_REQUEST || callin_status == 0) {
+ cpu_clear(cpu_id, cpu_callout_map);
+ cpu_clear(cpu_id, cpu_callin_map);
+ cpu_clear(cpu_id, cpu_initialized);
+ cpucount--;
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * smp_show_cpu_info - Show SMP CPU information
+ * @cpu: The CPU of interest.
+ */
+static void __init smp_show_cpu_info(int cpu)
+{
+ struct mn10300_cpuinfo *ci = &cpu_data[cpu];
+
+ printk(KERN_INFO
+ "CPU#%d : ioclk speed: %lu.%02luMHz : bogomips : %lu.%02lu\n",
+ cpu,
+ MN10300_IOCLK / 1000000,
+ (MN10300_IOCLK / 10000) % 100,
+ ci->loops_per_jiffy / (500000 / HZ),
+ (ci->loops_per_jiffy / (5000 / HZ)) % 100);
+}
+
+/**
+ * smp_callin - Set cpu_callin_map of the current CPU ID
+ */
+static void __init smp_callin(void)
+{
+ unsigned long timeout;
+ int cpu;
+
+ cpu = smp_processor_id();
+ timeout = jiffies + (2 * HZ);
+
+ if (cpu_isset(cpu, cpu_callin_map)) {
+ printk(KERN_ERR "CPU#%d already present.\n", cpu);
+ BUG();
+ }
+ Dprintk("CPU#%d waiting for CALLOUT\n", cpu);
+
+ /* Wait for AP startup 2s total */
+ while (time_before(jiffies, timeout)) {
+ if (cpu_isset(cpu, cpu_callout_map))
+ break;
+ cpu_relax();
+ }
+
+ if (!time_before(jiffies, timeout)) {
+ printk(KERN_ERR
+ "BUG: CPU#%d started up but did not get a callout!\n",
+ cpu);
+ BUG();
+ }
+
+#ifdef CONFIG_CALIBRATE_DELAY
+ calibrate_delay(); /* Get our bogomips */
+#endif
+
+ /* Save our processor parameters */
+ smp_store_cpu_info(cpu);
+
+ /* Allow the boot processor to continue */
+ cpu_set(cpu, cpu_callin_map);
+}
+
+/**
+ * smp_online - Set cpu_online_map
+ */
+static void __init smp_online(void)
+{
+ int cpu;
+
+ cpu = smp_processor_id();
+
+ local_irq_enable();
+
+ cpu_set(cpu, cpu_online_map);
+ smp_wmb();
+}
+
+/**
+ * smp_cpus_done -
+ * @max_cpus: Maximum CPU count.
+ *
+ * Do nothing.
+ */
+void __init smp_cpus_done(unsigned int max_cpus)
+{
+}
+
+/*
+ * smp_prepare_boot_cpu - Set up stuff for the boot processor.
+ *
+ * Set up the cpu_online_map, cpu_callout_map and cpu_callin_map of the boot
+ * processor (CPU 0).
+ */
+void __devinit smp_prepare_boot_cpu(void)
+{
+ cpu_set(0, cpu_callout_map);
+ cpu_set(0, cpu_callin_map);
+ current_thread_info()->cpu = 0;
+}
+
+/*
+ * initialize_secondary - Initialise a secondary CPU (Application Processor).
+ *
+ * Set SP register and jump to thread's PC address.
+ */
+void initialize_secondary(void)
+{
+ asm volatile (
+ "mov %0,sp \n"
+ "jmp (%1) \n"
+ :
+ : "a"(current->thread.sp), "a"(current->thread.pc));
+}
+
+/**
+ * __cpu_up - Set smp_commenced_mask for the nominated CPU
+ * @cpu: The target CPU.
+ */
+int __devinit __cpu_up(unsigned int cpu)
+{
+ int timeout;
+
+#ifdef CONFIG_HOTPLUG_CPU
+ if (num_online_cpus() == 1)
+ disable_hlt();
+ if (sleep_mode[cpu])
+ run_wakeup_cpu(cpu);
+#endif /* CONFIG_HOTPLUG_CPU */
+
+ cpu_set(cpu, smp_commenced_mask);
+
+ /* Wait 5s total for a response */
+ for (timeout = 0 ; timeout < 5000 ; timeout++) {
+ if (cpu_isset(cpu, cpu_online_map))
+ break;
+ udelay(1000);
+ }
+
+ BUG_ON(!cpu_isset(cpu, cpu_online_map));
+ return 0;
+}
+
+/**
+ * setup_profiling_timer - Set up the profiling timer
+ * @multiplier - The frequency multiplier to use
+ *
+ * The frequency of the profiling timer can be changed by writing a multiplier
+ * value into /proc/profile.
+ */
+int setup_profiling_timer(unsigned int multiplier)
+{
+ return -EINVAL;
+}
+
+/*
+ * CPU hotplug routines
+ */
+#ifdef CONFIG_HOTPLUG_CPU
+
+static DEFINE_PER_CPU(struct cpu, cpu_devices);
+
+static int __init topology_init(void)
+{
+ int cpu, ret;
+
+ for_each_cpu(cpu) {
+ ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu, NULL);
+ if (ret)
+ printk(KERN_WARNING
+ "topology_init: register_cpu %d failed (%d)\n",
+ cpu, ret);
+ }
+ return 0;
+}
+
+subsys_initcall(topology_init);
+
+int __cpu_disable(void)
+{
+ int cpu = smp_processor_id();
+ if (cpu == 0)
+ return -EBUSY;
+
+ migrate_irqs();
+ cpu_clear(cpu, current->active_mm->cpu_vm_mask);
+ return 0;
+}
+
+void __cpu_die(unsigned int cpu)
+{
+ run_sleep_cpu(cpu);
+
+ if (num_online_cpus() == 1)
+ enable_hlt();
+}
+
+#ifdef CONFIG_MN10300_CACHE_ENABLED
+static inline void hotplug_cpu_disable_cache(void)
+{
+ int tmp;
+ asm volatile(
+ " movhu (%1),%0 \n"
+ " and %2,%0 \n"
+ " movhu %0,(%1) \n"
+ "1: movhu (%1),%0 \n"
+ " btst %3,%0 \n"
+ " bne 1b \n"
+ : "=&r"(tmp)
+ : "a"(&CHCTR),
+ "i"(~(CHCTR_ICEN | CHCTR_DCEN)),
+ "i"(CHCTR_ICBUSY | CHCTR_DCBUSY)
+ : "memory", "cc");
+}
+
+static inline void hotplug_cpu_enable_cache(void)
+{
+ int tmp;
+ asm volatile(
+ "movhu (%1),%0 \n"
+ "or %2,%0 \n"
+ "movhu %0,(%1) \n"
+ : "=&r"(tmp)
+ : "a"(&CHCTR),
+ "i"(CHCTR_ICEN | CHCTR_DCEN)
+ : "memory", "cc");
+}
+
+static inline void hotplug_cpu_invalidate_cache(void)
+{
+ int tmp;
+ asm volatile (
+ "movhu (%1),%0 \n"
+ "or %2,%0 \n"
+ "movhu %0,(%1) \n"
+ : "=&r"(tmp)
+ : "a"(&CHCTR),
+ "i"(CHCTR_ICINV | CHCTR_DCINV)
+ : "cc");
+}
+
+#else /* CONFIG_MN10300_CACHE_ENABLED */
+#define hotplug_cpu_disable_cache() do {} while (0)
+#define hotplug_cpu_enable_cache() do {} while (0)
+#define hotplug_cpu_invalidate_cache() do {} while (0)
+#endif /* CONFIG_MN10300_CACHE_ENABLED */
+
+/**
+ * hotplug_cpu_nmi_call_function - Call a function on other CPUs for hotplug
+ * @cpumask: List of target CPUs.
+ * @func: The function to call on those CPUs.
+ * @info: The context data for the function to be called.
+ * @wait: Whether to wait for the calls to complete.
+ *
+ * Non-maskably call a function on another CPU for hotplug purposes.
+ *
+ * This function must be called with maskable interrupts disabled.
+ */
+static int hotplug_cpu_nmi_call_function(cpumask_t cpumask,
+ smp_call_func_t func, void *info,
+ int wait)
+{
+ /*
+ * The address and the size of nmi_call_func_mask_data
+ * need to be aligned on L1_CACHE_BYTES.
+ */
+ static struct nmi_call_data_struct nmi_call_func_mask_data
+ __cacheline_aligned;
+ unsigned long start, end;
+
+ start = (unsigned long)&nmi_call_func_mask_data;
+ end = start + sizeof(struct nmi_call_data_struct);
+
+ nmi_call_func_mask_data.func = func;
+ nmi_call_func_mask_data.info = info;
+ nmi_call_func_mask_data.started = cpumask;
+ nmi_call_func_mask_data.wait = wait;
+ if (wait)
+ nmi_call_func_mask_data.finished = cpumask;
+
+ spin_lock(&smp_nmi_call_lock);
+ nmi_call_data = &nmi_call_func_mask_data;
+ mn10300_local_dcache_flush_range(start, end);
+ smp_wmb();
+
+ send_IPI_mask(cpumask, CALL_FUNCTION_NMI_IPI);
+
+ do {
+ mn10300_local_dcache_inv_range(start, end);
+ barrier();
+ } while (!cpus_empty(nmi_call_func_mask_data.started));
+
+ if (wait) {
+ do {
+ mn10300_local_dcache_inv_range(start, end);
+ barrier();
+ } while (!cpus_empty(nmi_call_func_mask_data.finished));
+ }
+
+ spin_unlock(&smp_nmi_call_lock);
+ return 0;
+}
+
+static void restart_wakeup_cpu(void)
+{
+ unsigned int cpu = smp_processor_id();
+
+ cpu_set(cpu, cpu_callin_map);
+ local_flush_tlb();
+ cpu_set(cpu, cpu_online_map);
+ smp_wmb();
+}
+
+static void prepare_sleep_cpu(void *unused)
+{
+ sleep_mode[smp_processor_id()] = 1;
+ smp_mb();
+ mn10300_local_dcache_flush_inv();
+ hotplug_cpu_disable_cache();
+ hotplug_cpu_invalidate_cache();
+}
+
+/* when this function called, IE=0, NMID=0. */
+static void sleep_cpu(void *unused)
+{
+ unsigned int cpu_id = smp_processor_id();
+ /*
+ * CALL_FUNCTION_NMI_IPI for wakeup_cpu() shall not be requested,
+ * before this cpu goes in SLEEP mode.
+ */
+ do {
+ smp_mb();
+ __sleep_cpu();
+ } while (sleep_mode[cpu_id]);
+ restart_wakeup_cpu();
+}
+
+static void run_sleep_cpu(unsigned int cpu)
+{
+ unsigned long flags;
+ cpumask_t cpumask = cpumask_of(cpu);
+
+ flags = arch_local_cli_save();
+ hotplug_cpu_nmi_call_function(cpumask, prepare_sleep_cpu, NULL, 1);
+ hotplug_cpu_nmi_call_function(cpumask, sleep_cpu, NULL, 0);
+ udelay(1); /* delay for the cpu to sleep. */
+ arch_local_irq_restore(flags);
+}
+
+static void wakeup_cpu(void)
+{
+ hotplug_cpu_invalidate_cache();
+ hotplug_cpu_enable_cache();
+ smp_mb();
+ sleep_mode[smp_processor_id()] = 0;
+}
+
+static void run_wakeup_cpu(unsigned int cpu)
+{
+ unsigned long flags;
+
+ flags = arch_local_cli_save();
+#if NR_CPUS == 2
+ mn10300_local_dcache_flush_inv();
+#else
+ /*
+ * Before waking up the cpu,
+ * all online cpus should stop and flush D-Cache for global data.
+ */
+#error not support NR_CPUS > 2, when CONFIG_HOTPLUG_CPU=y.
+#endif
+ hotplug_cpu_nmi_call_function(cpumask_of(cpu), wakeup_cpu, NULL, 1);
+ arch_local_irq_restore(flags);
+}
+
+#endif /* CONFIG_HOTPLUG_CPU */
diff --git a/arch/mn10300/kernel/switch_to.S b/arch/mn10300/kernel/switch_to.S
index 630aad71b946..9074d0fb8788 100644
--- a/arch/mn10300/kernel/switch_to.S
+++ b/arch/mn10300/kernel/switch_to.S
@@ -15,6 +15,9 @@
#include <linux/linkage.h>
#include <asm/thread_info.h>
#include <asm/cpu-regs.h>
+#ifdef CONFIG_SMP
+#include <proc/smp-regs.h>
+#endif /* CONFIG_SMP */
.text
@@ -35,8 +38,6 @@ ENTRY(__switch_to)
mov d1,a1
# save prev context
- mov (__frame),d0
- mov d0,(THREAD_FRAME,a0)
mov __switch_back,d0
mov d0,(THREAD_PC,a0)
mov sp,a2
@@ -58,8 +59,6 @@ ENTRY(__switch_to)
mov a2,e2
#endif
- mov (THREAD_FRAME,a1),a2
- mov a2,(__frame)
mov (THREAD_PC,a1),a2
mov d2,d0 # for ret_from_fork
mov d0,a0 # for __switch_to
diff --git a/arch/mn10300/kernel/time.c b/arch/mn10300/kernel/time.c
index 8f7f6d22783d..f860a340acc9 100644
--- a/arch/mn10300/kernel/time.c
+++ b/arch/mn10300/kernel/time.c
@@ -17,29 +17,18 @@
#include <linux/smp.h>
#include <linux/profile.h>
#include <linux/cnt32_to_63.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
#include <asm/irq.h>
#include <asm/div64.h>
#include <asm/processor.h>
#include <asm/intctl-regs.h>
#include <asm/rtc.h>
-
-#ifdef CONFIG_MN10300_RTC
-unsigned long mn10300_ioclk; /* system I/O clock frequency */
-unsigned long mn10300_iobclk; /* system I/O clock frequency */
-unsigned long mn10300_tsc_per_HZ; /* number of ioclks per jiffy */
-#endif /* CONFIG_MN10300_RTC */
+#include "internal.h"
static unsigned long mn10300_last_tsc; /* time-stamp counter at last time
* interrupt occurred */
-static irqreturn_t timer_interrupt(int irq, void *dev_id);
-
-static struct irqaction timer_irq = {
- .handler = timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_SHARED | IRQF_TIMER,
- .name = "timer",
-};
-
static unsigned long sched_clock_multiplier;
/*
@@ -54,9 +43,12 @@ unsigned long long sched_clock(void)
unsigned long tsc, tmp;
unsigned product[3]; /* 96-bit intermediate value */
+ /* cnt32_to_63() is not safe with preemption */
+ preempt_disable();
+
/* read the TSC value
*/
- tsc = 0 - get_cycles(); /* get_cycles() counts down */
+ tsc = get_cycles();
/* expand to 64-bits.
* - sched_clock() must be called once a minute or better or the
@@ -64,6 +56,8 @@ unsigned long long sched_clock(void)
*/
tsc64.ll = cnt32_to_63(tsc) & 0x7fffffffffffffffULL;
+ preempt_enable();
+
/* scale the 64-bit TSC value to a nanosecond value via a 96-bit
* intermediate
*/
@@ -90,6 +84,20 @@ static void __init mn10300_sched_clock_init(void)
__muldiv64u(NSEC_PER_SEC, 1 << 16, MN10300_TSCCLK);
}
+/**
+ * local_timer_interrupt - Local timer interrupt handler
+ *
+ * Handle local timer interrupts for this CPU. They may have been propagated
+ * to this CPU from the CPU that actually gets them by way of an IPI.
+ */
+irqreturn_t local_timer_interrupt(void)
+{
+ profile_tick(CPU_PROFILING);
+ update_process_times(user_mode(get_irq_regs()));
+ return IRQ_HANDLED;
+}
+
+#ifndef CONFIG_GENERIC_TIME
/*
* advance the kernel's time keeping clocks (xtime and jiffies)
* - we use Timer 0 & 1 cascaded as a clock to nudge us the next time
@@ -98,27 +106,73 @@ static void __init mn10300_sched_clock_init(void)
static irqreturn_t timer_interrupt(int irq, void *dev_id)
{
unsigned tsc, elapse;
+ irqreturn_t ret;
write_seqlock(&xtime_lock);
while (tsc = get_cycles(),
- elapse = mn10300_last_tsc - tsc, /* time elapsed since last
+ elapse = tsc - mn10300_last_tsc, /* time elapsed since last
* tick */
elapse > MN10300_TSC_PER_HZ
) {
- mn10300_last_tsc -= MN10300_TSC_PER_HZ;
+ mn10300_last_tsc += MN10300_TSC_PER_HZ;
/* advance the kernel's time tracking system */
- profile_tick(CPU_PROFILING);
do_timer(1);
}
write_sequnlock(&xtime_lock);
- update_process_times(user_mode(get_irq_regs()));
+ ret = local_timer_interrupt();
+#ifdef CONFIG_SMP
+ send_IPI_allbutself(LOCAL_TIMER_IPI);
+#endif
+ return ret;
+}
- return IRQ_HANDLED;
+static struct irqaction timer_irq = {
+ .handler = timer_interrupt,
+ .flags = IRQF_DISABLED | IRQF_SHARED | IRQF_TIMER,
+ .name = "timer",
+};
+#endif /* CONFIG_GENERIC_TIME */
+
+#ifdef CONFIG_CSRC_MN10300
+void __init clocksource_set_clock(struct clocksource *cs, unsigned int clock)
+{
+ u64 temp;
+ u32 shift;
+
+ /* Find a shift value */
+ for (shift = 32; shift > 0; shift--) {
+ temp = (u64) NSEC_PER_SEC << shift;
+ do_div(temp, clock);
+ if ((temp >> 32) == 0)
+ break;
+ }
+ cs->shift = shift;
+ cs->mult = (u32) temp;
}
+#endif
+
+#if CONFIG_CEVT_MN10300
+void __cpuinit clockevent_set_clock(struct clock_event_device *cd,
+ unsigned int clock)
+{
+ u64 temp;
+ u32 shift;
+
+ /* Find a shift value */
+ for (shift = 32; shift > 0; shift--) {
+ temp = (u64) clock << shift;
+ do_div(temp, NSEC_PER_SEC);
+ if ((temp >> 32) == 0)
+ break;
+ }
+ cd->shift = shift;
+ cd->mult = (u32) temp;
+}
+#endif
/*
* initialise the various timers used by the main part of the kernel
@@ -131,21 +185,25 @@ void __init time_init(void)
*/
TMPSCNT |= TMPSCNT_ENABLE;
+#ifdef CONFIG_GENERIC_TIME
+ init_clocksource();
+#else
startup_timestamp_counter();
+#endif
printk(KERN_INFO
"timestamp counter I/O clock running at %lu.%02lu"
" (calibrated against RTC)\n",
MN10300_TSCCLK / 1000000, (MN10300_TSCCLK / 10000) % 100);
- mn10300_last_tsc = TMTSCBC;
-
- /* use timer 0 & 1 cascaded to tick at as close to HZ as possible */
- setup_irq(TMJCIRQ, &timer_irq);
+ mn10300_last_tsc = read_timestamp_counter();
- set_intr_level(TMJCIRQ, TMJCICR_LEVEL);
-
- startup_jiffies_counter();
+#ifdef CONFIG_GENERIC_CLOCKEVENTS
+ init_clockevents();
+#else
+ reload_jiffies_counter(MN10300_JC_PER_HZ - 1);
+ setup_jiffies_interrupt(TMJCIRQ, &timer_irq, CONFIG_TIMER_IRQ_LEVEL);
+#endif
#ifdef CONFIG_MN10300_WD_TIMER
/* start the watchdog timer */
diff --git a/arch/mn10300/kernel/traps.c b/arch/mn10300/kernel/traps.c
index 91365adba4f5..b90c3f160c77 100644
--- a/arch/mn10300/kernel/traps.c
+++ b/arch/mn10300/kernel/traps.c
@@ -45,9 +45,6 @@
#error "INTERRUPT_VECTOR_BASE not aligned to 16MiB boundary!"
#endif
-struct pt_regs *__frame; /* current frame pointer */
-EXPORT_SYMBOL(__frame);
-
int kstack_depth_to_print = 24;
spinlock_t die_lock = __SPIN_LOCK_UNLOCKED(die_lock);
@@ -101,7 +98,6 @@ DO_EINFO(SIGILL, {}, "invalid opcode", invalid_op, ILL_ILLOPC);
DO_EINFO(SIGILL, {}, "invalid ex opcode", invalid_exop, ILL_ILLOPC);
DO_EINFO(SIGBUS, {}, "invalid address", mem_error, BUS_ADRERR);
DO_EINFO(SIGBUS, {}, "bus error", bus_error, BUS_ADRERR);
-DO_EINFO(SIGILL, {}, "FPU invalid opcode", fpu_invalid_op, ILL_COPROC);
DO_ERROR(SIGTRAP,
#ifndef CONFIG_MN10300_USING_JTAG
@@ -222,11 +218,14 @@ void show_registers_only(struct pt_regs *regs)
printk(KERN_EMERG "threadinfo=%p task=%p)\n",
current_thread_info(), current);
- if ((unsigned long) current >= 0x90000000UL &&
- (unsigned long) current < 0x94000000UL)
+ if ((unsigned long) current >= PAGE_OFFSET &&
+ (unsigned long) current < (unsigned long)high_memory)
printk(KERN_EMERG "Process %s (pid: %d)\n",
current->comm, current->pid);
+#ifdef CONFIG_SMP
+ printk(KERN_EMERG "CPUID: %08x\n", CPUID);
+#endif
printk(KERN_EMERG "CPUP: %04hx\n", CPUP);
printk(KERN_EMERG "TBR: %08x\n", TBR);
printk(KERN_EMERG "DEAR: %08x\n", DEAR);
@@ -522,8 +521,12 @@ void __init set_intr_stub(enum exception_code code, void *handler)
{
unsigned long addr;
u8 *vector = (u8 *)(CONFIG_INTERRUPT_VECTOR_BASE + code);
+ unsigned long flags;
addr = (unsigned long) handler - (unsigned long) vector;
+
+ flags = arch_local_cli_save();
+
vector[0] = 0xdc; /* JMP handler */
vector[1] = addr;
vector[2] = addr >> 8;
@@ -533,30 +536,12 @@ void __init set_intr_stub(enum exception_code code, void *handler)
vector[6] = 0xcb;
vector[7] = 0xcb;
- mn10300_dcache_flush_inv();
- mn10300_icache_inv();
-}
-
-/*
- * set an interrupt stub to invoke the JTAG unit and then jump to a handler
- */
-void __init set_jtag_stub(enum exception_code code, void *handler)
-{
- unsigned long addr;
- u8 *vector = (u8 *)(CONFIG_INTERRUPT_VECTOR_BASE + code);
-
- addr = (unsigned long) handler - ((unsigned long) vector + 1);
- vector[0] = 0xff; /* PI to jump into JTAG debugger */
- vector[1] = 0xdc; /* jmp handler */
- vector[2] = addr;
- vector[3] = addr >> 8;
- vector[4] = addr >> 16;
- vector[5] = addr >> 24;
- vector[6] = 0xcb;
- vector[7] = 0xcb;
+ arch_local_irq_restore(flags);
+#ifndef CONFIG_MN10300_CACHE_SNOOP
mn10300_dcache_flush_inv();
- flush_icache_range((unsigned long) vector, (unsigned long) vector + 8);
+ mn10300_icache_inv();
+#endif
}
/*
@@ -581,7 +566,6 @@ void __init trap_init(void)
set_excp_vector(EXCEP_PRIVINSACC, insn_acc_error);
set_excp_vector(EXCEP_PRIVDATACC, data_acc_error);
set_excp_vector(EXCEP_DATINSACC, insn_acc_error);
- set_excp_vector(EXCEP_FPU_DISABLED, fpu_disabled);
set_excp_vector(EXCEP_FPU_UNIMPINS, fpu_invalid_op);
set_excp_vector(EXCEP_FPU_OPERATION, fpu_exception);
diff --git a/arch/mn10300/kernel/vmlinux.lds.S b/arch/mn10300/kernel/vmlinux.lds.S
index 10549dcfb610..febbeee7f2f5 100644
--- a/arch/mn10300/kernel/vmlinux.lds.S
+++ b/arch/mn10300/kernel/vmlinux.lds.S
@@ -70,7 +70,7 @@ SECTIONS
.exit.text : { EXIT_TEXT; }
.exit.data : { EXIT_DATA; }
- PERCPU(32)
+ PERCPU(PAGE_SIZE)
. = ALIGN(PAGE_SIZE);
__init_end = .;
/* freed after init ends here */
diff --git a/arch/mn10300/lib/bitops.c b/arch/mn10300/lib/bitops.c
index 440a7dcbf87b..a66c6cdaf442 100644
--- a/arch/mn10300/lib/bitops.c
+++ b/arch/mn10300/lib/bitops.c
@@ -15,7 +15,7 @@
/*
* try flipping a bit using BSET and BCLR
*/
-void change_bit(int nr, volatile void *addr)
+void change_bit(unsigned long nr, volatile void *addr)
{
if (test_bit(nr, addr))
goto try_clear_bit;
@@ -34,7 +34,7 @@ try_clear_bit:
/*
* try flipping a bit using BSET and BCLR and returning the old value
*/
-int test_and_change_bit(int nr, volatile void *addr)
+int test_and_change_bit(unsigned long nr, volatile void *addr)
{
if (test_bit(nr, addr))
goto try_clear_bit;
diff --git a/arch/mn10300/lib/delay.c b/arch/mn10300/lib/delay.c
index fdf6f710f94e..8e7ceb8ba33d 100644
--- a/arch/mn10300/lib/delay.c
+++ b/arch/mn10300/lib/delay.c
@@ -38,14 +38,14 @@ EXPORT_SYMBOL(__delay);
*/
void __udelay(unsigned long usecs)
{
- signed long ioclk, stop;
+ unsigned long start, stop, cnt;
/* usecs * CLK / 1E6 */
stop = __muldiv64u(usecs, MN10300_TSCCLK, 1000000);
- stop = TMTSCBC - stop;
+ start = TMTSCBC;
do {
- ioclk = TMTSCBC;
- } while (stop < ioclk);
+ cnt = start - TMTSCBC;
+ } while (cnt < stop);
}
EXPORT_SYMBOL(__udelay);
diff --git a/arch/mn10300/lib/do_csum.S b/arch/mn10300/lib/do_csum.S
index e138994e1667..1d27bba0cd8f 100644
--- a/arch/mn10300/lib/do_csum.S
+++ b/arch/mn10300/lib/do_csum.S
@@ -10,26 +10,25 @@
*/
#include <asm/cache.h>
- .section .text
- .balign L1_CACHE_BYTES
+ .section .text
+ .balign L1_CACHE_BYTES
###############################################################################
#
-# unsigned int do_csum(const unsigned char *buff, size_t len)
+# unsigned int do_csum(const unsigned char *buff, int len)
#
###############################################################################
.globl do_csum
- .type do_csum,@function
+ .type do_csum,@function
do_csum:
movm [d2,d3],(sp)
- mov d0,(12,sp)
- mov d1,(16,sp)
mov d1,d2 # count
mov d0,a0 # buff
+ mov a0,a1
clr d1 # accumulator
cmp +0,d2
- beq do_csum_done # return if zero-length buffer
+ ble do_csum_done # check for zero length or negative
# 4-byte align the buffer pointer
btst +3,a0
@@ -41,17 +40,15 @@ do_csum:
inc a0
asl +8,d0
add d0,d1
- addc +0,d1
add -1,d2
-do_csum_addr_not_odd:
+do_csum_addr_not_odd:
cmp +2,d2
bcs do_csum_fewer_than_4
btst +2,a0
beq do_csum_now_4b_aligned
movhu (a0+),d0
add d0,d1
- addc +0,d1
add -2,d2
cmp +4,d2
bcs do_csum_fewer_than_4
@@ -66,20 +63,20 @@ do_csum_now_4b_aligned:
do_csum_loop:
mov (a0+),d0
- add d0,d1
mov (a0+),e0
- addc e0,d1
mov (a0+),e1
- addc e1,d1
mov (a0+),e3
+ add d0,d1
+ addc e0,d1
+ addc e1,d1
addc e3,d1
mov (a0+),d0
- addc d0,d1
mov (a0+),e0
- addc e0,d1
mov (a0+),e1
- addc e1,d1
mov (a0+),e3
+ addc d0,d1
+ addc e0,d1
+ addc e1,d1
addc e3,d1
addc +0,d1
@@ -94,12 +91,12 @@ do_csum_remainder:
cmp +16,d2
bcs do_csum_fewer_than_16
mov (a0+),d0
- add d0,d1
mov (a0+),e0
- addc e0,d1
mov (a0+),e1
- addc e1,d1
mov (a0+),e3
+ add d0,d1
+ addc e0,d1
+ addc e1,d1
addc e3,d1
addc +0,d1
add -16,d2
@@ -131,9 +128,9 @@ do_csum_fewer_than_4:
xor_cmp d0,d0,+2,d2
bcs do_csum_fewer_than_2
movhu (a0+),d0
-do_csum_fewer_than_2:
and +1,d2
beq do_csum_add_last_bit
+do_csum_fewer_than_2:
movbu (a0),d3
add d3,d0
do_csum_add_last_bit:
@@ -142,21 +139,19 @@ do_csum_add_last_bit:
do_csum_done:
# compress the checksum down to 16 bits
- mov +0xffff0000,d2
- and d1,d2
+ mov +0xffff0000,d0
+ and d1,d0
asl +16,d1
- add d2,d1,d0
+ add d1,d0
addc +0xffff,d0
lsr +16,d0
# flip the halves of the word result if the buffer was oddly aligned
- mov (12,sp),d1
- and +1,d1
+ and +1,a1
beq do_csum_not_oddly_aligned
swaph d0,d0 # exchange bits 15:8 with 7:0
do_csum_not_oddly_aligned:
ret [d2,d3],8
-do_csum_end:
- .size do_csum, do_csum_end-do_csum
+ .size do_csum, .-do_csum
diff --git a/arch/mn10300/mm/Kconfig.cache b/arch/mn10300/mm/Kconfig.cache
new file mode 100644
index 000000000000..c4fd923a55a0
--- /dev/null
+++ b/arch/mn10300/mm/Kconfig.cache
@@ -0,0 +1,101 @@
+#
+# MN10300 CPU cache options
+#
+
+choice
+ prompt "CPU Caching mode"
+ default MN10300_CACHE_WBACK
+ help
+ This option determines the caching mode for the kernel.
+
+ Write-Back caching mode involves the all reads and writes causing
+ the affected cacheline to be read into the cache first before being
+ operated upon. Memory is not then updated by a write until the cache
+ is filled and a cacheline needs to be displaced from the cache to
+ make room. Only at that point is it written back.
+
+ Write-Through caching only fetches cachelines from memory on a
+ read. Writes always get written directly to memory. If the affected
+ cacheline is also in cache, it will be updated too.
+
+ The final option is to turn of caching entirely.
+
+config MN10300_CACHE_WBACK
+ bool "Write-Back"
+ help
+ The dcache operates in delayed write-back mode. It must be manually
+ flushed if writes are made that subsequently need to be executed or
+ to be DMA'd by a device.
+
+config MN10300_CACHE_WTHRU
+ bool "Write-Through"
+ help
+ The dcache operates in immediate write-through mode. Writes are
+ committed to RAM immediately in addition to being stored in the
+ cache. This means that the written data is immediately available for
+ execution or DMA.
+
+ This is not available for use with an SMP kernel if cache flushing
+ and invalidation by automatic purge register is not selected.
+
+config MN10300_CACHE_DISABLED
+ bool "Disabled"
+ help
+ The icache and dcache are disabled.
+
+endchoice
+
+config MN10300_CACHE_ENABLED
+ def_bool y if !MN10300_CACHE_DISABLED
+
+
+choice
+ prompt "CPU cache flush/invalidate method"
+ default MN10300_CACHE_MANAGE_BY_TAG if !AM34_2
+ default MN10300_CACHE_MANAGE_BY_REG if AM34_2
+ depends on MN10300_CACHE_ENABLED
+ help
+ This determines the method by which CPU cache flushing and
+ invalidation is performed.
+
+config MN10300_CACHE_MANAGE_BY_TAG
+ bool "Use the cache tag registers directly"
+ depends on !(SMP && MN10300_CACHE_WTHRU)
+
+config MN10300_CACHE_MANAGE_BY_REG
+ bool "Flush areas by way of automatic purge registers (AM34 only)"
+ depends on AM34_2
+
+endchoice
+
+config MN10300_CACHE_INV_BY_TAG
+ def_bool y if MN10300_CACHE_MANAGE_BY_TAG && MN10300_CACHE_ENABLED
+
+config MN10300_CACHE_INV_BY_REG
+ def_bool y if MN10300_CACHE_MANAGE_BY_REG && MN10300_CACHE_ENABLED
+
+config MN10300_CACHE_FLUSH_BY_TAG
+ def_bool y if MN10300_CACHE_MANAGE_BY_TAG && MN10300_CACHE_WBACK
+
+config MN10300_CACHE_FLUSH_BY_REG
+ def_bool y if MN10300_CACHE_MANAGE_BY_REG && MN10300_CACHE_WBACK
+
+
+config MN10300_HAS_CACHE_SNOOP
+ def_bool n
+
+config MN10300_CACHE_SNOOP
+ bool "Use CPU Cache Snooping"
+ depends on MN10300_CACHE_ENABLED && MN10300_HAS_CACHE_SNOOP
+ default y
+
+config MN10300_CACHE_FLUSH_ICACHE
+ def_bool y if MN10300_CACHE_WBACK && !MN10300_CACHE_SNOOP
+ help
+ Set if we need the dcache flushing before the icache is invalidated.
+
+config MN10300_CACHE_INV_ICACHE
+ def_bool y if MN10300_CACHE_WTHRU && !MN10300_CACHE_SNOOP
+ help
+ Set if we need the icache to be invalidated, even if the dcache is in
+ write-through mode and doesn't need flushing.
diff --git a/arch/mn10300/mm/Makefile b/arch/mn10300/mm/Makefile
index 1557277fbc5c..203fee23f7d7 100644
--- a/arch/mn10300/mm/Makefile
+++ b/arch/mn10300/mm/Makefile
@@ -2,11 +2,21 @@
# Makefile for the MN10300-specific memory management code
#
-cacheflush-y := cache.o cache-mn10300.o
-cacheflush-$(CONFIG_MN10300_CACHE_WBACK) += cache-flush-mn10300.o
+cache-smp-wback-$(CONFIG_MN10300_CACHE_WBACK) := cache-smp-flush.o
+
+cacheflush-y := cache.o
+cacheflush-$(CONFIG_SMP) += cache-smp.o cache-smp-inv.o $(cache-smp-wback-y)
+cacheflush-$(CONFIG_MN10300_CACHE_INV_ICACHE) += cache-inv-icache.o
+cacheflush-$(CONFIG_MN10300_CACHE_FLUSH_ICACHE) += cache-flush-icache.o
+cacheflush-$(CONFIG_MN10300_CACHE_INV_BY_TAG) += cache-inv-by-tag.o
+cacheflush-$(CONFIG_MN10300_CACHE_INV_BY_REG) += cache-inv-by-reg.o
+cacheflush-$(CONFIG_MN10300_CACHE_FLUSH_BY_TAG) += cache-flush-by-tag.o
+cacheflush-$(CONFIG_MN10300_CACHE_FLUSH_BY_REG) += cache-flush-by-reg.o
cacheflush-$(CONFIG_MN10300_CACHE_DISABLED) := cache-disabled.o
obj-y := \
init.o fault.o pgtable.o extable.o tlb-mn10300.o mmu-context.o \
misalignment.o dma-alloc.o $(cacheflush-y)
+
+obj-$(CONFIG_SMP) += tlb-smp.o
diff --git a/arch/mn10300/mm/cache-flush-by-reg.S b/arch/mn10300/mm/cache-flush-by-reg.S
new file mode 100644
index 000000000000..1dcae0211671
--- /dev/null
+++ b/arch/mn10300/mm/cache-flush-by-reg.S
@@ -0,0 +1,308 @@
+/* MN10300 CPU core caching routines, using indirect regs on cache controller
+ *
+ * Copyright (C) 2007 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/sys.h>
+#include <linux/linkage.h>
+#include <asm/smp.h>
+#include <asm/page.h>
+#include <asm/cache.h>
+#include <asm/irqflags.h>
+
+ .am33_2
+
+#ifndef CONFIG_SMP
+ .globl mn10300_dcache_flush
+ .globl mn10300_dcache_flush_page
+ .globl mn10300_dcache_flush_range
+ .globl mn10300_dcache_flush_range2
+ .globl mn10300_dcache_flush_inv
+ .globl mn10300_dcache_flush_inv_page
+ .globl mn10300_dcache_flush_inv_range
+ .globl mn10300_dcache_flush_inv_range2
+
+mn10300_dcache_flush = mn10300_local_dcache_flush
+mn10300_dcache_flush_page = mn10300_local_dcache_flush_page
+mn10300_dcache_flush_range = mn10300_local_dcache_flush_range
+mn10300_dcache_flush_range2 = mn10300_local_dcache_flush_range2
+mn10300_dcache_flush_inv = mn10300_local_dcache_flush_inv
+mn10300_dcache_flush_inv_page = mn10300_local_dcache_flush_inv_page
+mn10300_dcache_flush_inv_range = mn10300_local_dcache_flush_inv_range
+mn10300_dcache_flush_inv_range2 = mn10300_local_dcache_flush_inv_range2
+
+#endif /* !CONFIG_SMP */
+
+###############################################################################
+#
+# void mn10300_local_dcache_flush(void)
+# Flush the entire data cache back to RAM
+#
+###############################################################################
+ ALIGN
+ .globl mn10300_local_dcache_flush
+ .type mn10300_local_dcache_flush,@function
+mn10300_local_dcache_flush:
+ movhu (CHCTR),d0
+ btst CHCTR_DCEN,d0
+ beq mn10300_local_dcache_flush_end
+
+ mov DCPGCR,a0
+
+ LOCAL_CLI_SAVE(d1)
+
+ # wait for busy bit of area purge
+ setlb
+ mov (a0),d0
+ btst DCPGCR_DCPGBSY,d0
+ lne
+
+ # set mask
+ clr d0
+ mov d0,(DCPGMR)
+
+ # area purge
+ #
+ # DCPGCR = DCPGCR_DCP
+ #
+ mov DCPGCR_DCP,d0
+ mov d0,(a0)
+
+ # wait for busy bit of area purge
+ setlb
+ mov (a0),d0
+ btst DCPGCR_DCPGBSY,d0
+ lne
+
+ LOCAL_IRQ_RESTORE(d1)
+
+mn10300_local_dcache_flush_end:
+ ret [],0
+ .size mn10300_local_dcache_flush,.-mn10300_local_dcache_flush
+
+###############################################################################
+#
+# void mn10300_local_dcache_flush_page(unsigned long start)
+# void mn10300_local_dcache_flush_range(unsigned long start, unsigned long end)
+# void mn10300_local_dcache_flush_range2(unsigned long start, unsigned long size)
+# Flush a range of addresses on a page in the dcache
+#
+###############################################################################
+ ALIGN
+ .globl mn10300_local_dcache_flush_page
+ .globl mn10300_local_dcache_flush_range
+ .globl mn10300_local_dcache_flush_range2
+ .type mn10300_local_dcache_flush_page,@function
+ .type mn10300_local_dcache_flush_range,@function
+ .type mn10300_local_dcache_flush_range2,@function
+mn10300_local_dcache_flush_page:
+ and ~(PAGE_SIZE-1),d0
+ mov PAGE_SIZE,d1
+mn10300_local_dcache_flush_range2:
+ add d0,d1
+mn10300_local_dcache_flush_range:
+ movm [d2,d3,a2],(sp)
+
+ movhu (CHCTR),d2
+ btst CHCTR_DCEN,d2
+ beq mn10300_local_dcache_flush_range_end
+
+ # calculate alignsize
+ #
+ # alignsize = L1_CACHE_BYTES;
+ # for (i = (end - start - 1) / L1_CACHE_BYTES ; i > 0; i >>= 1)
+ # alignsize <<= 1;
+ # d2 = alignsize;
+ #
+ mov L1_CACHE_BYTES,d2
+ sub d0,d1,d3
+ add -1,d3
+ lsr L1_CACHE_SHIFT,d3
+ beq 2f
+1:
+ add d2,d2
+ lsr 1,d3
+ bne 1b
+2:
+ mov d1,a1 # a1 = end
+
+ LOCAL_CLI_SAVE(d3)
+ mov DCPGCR,a0
+
+ # wait for busy bit of area purge
+ setlb
+ mov (a0),d1
+ btst DCPGCR_DCPGBSY,d1
+ lne
+
+ # determine the mask
+ mov d2,d1
+ add -1,d1
+ not d1 # d1 = mask = ~(alignsize-1)
+ mov d1,(DCPGMR)
+
+ and d1,d0,a2 # a2 = mask & start
+
+dcpgloop:
+ # area purge
+ mov a2,d0
+ or DCPGCR_DCP,d0
+ mov d0,(a0) # DCPGCR = (mask & start) | DCPGCR_DCP
+
+ # wait for busy bit of area purge
+ setlb
+ mov (a0),d1
+ btst DCPGCR_DCPGBSY,d1
+ lne
+
+ # check purge of end address
+ add d2,a2 # a2 += alignsize
+ cmp a1,a2 # if (a2 < end) goto dcpgloop
+ bns dcpgloop
+
+ LOCAL_IRQ_RESTORE(d3)
+
+mn10300_local_dcache_flush_range_end:
+ ret [d2,d3,a2],12
+
+ .size mn10300_local_dcache_flush_page,.-mn10300_local_dcache_flush_page
+ .size mn10300_local_dcache_flush_range,.-mn10300_local_dcache_flush_range
+ .size mn10300_local_dcache_flush_range2,.-mn10300_local_dcache_flush_range2
+
+###############################################################################
+#
+# void mn10300_local_dcache_flush_inv(void)
+# Flush the entire data cache and invalidate all entries
+#
+###############################################################################
+ ALIGN
+ .globl mn10300_local_dcache_flush_inv
+ .type mn10300_local_dcache_flush_inv,@function
+mn10300_local_dcache_flush_inv:
+ movhu (CHCTR),d0
+ btst CHCTR_DCEN,d0
+ beq mn10300_local_dcache_flush_inv_end
+
+ mov DCPGCR,a0
+
+ LOCAL_CLI_SAVE(d1)
+
+ # wait for busy bit of area purge & invalidate
+ setlb
+ mov (a0),d0
+ btst DCPGCR_DCPGBSY,d0
+ lne
+
+ # set the mask to cover everything
+ clr d0
+ mov d0,(DCPGMR)
+
+ # area purge & invalidate
+ mov DCPGCR_DCP|DCPGCR_DCI,d0
+ mov d0,(a0)
+
+ # wait for busy bit of area purge & invalidate
+ setlb
+ mov (a0),d0
+ btst DCPGCR_DCPGBSY,d0
+ lne
+
+ LOCAL_IRQ_RESTORE(d1)
+
+mn10300_local_dcache_flush_inv_end:
+ ret [],0
+ .size mn10300_local_dcache_flush_inv,.-mn10300_local_dcache_flush_inv
+
+###############################################################################
+#
+# void mn10300_local_dcache_flush_inv_page(unsigned long start)
+# void mn10300_local_dcache_flush_inv_range(unsigned long start, unsigned long end)
+# void mn10300_local_dcache_flush_inv_range2(unsigned long start, unsigned long size)
+# Flush and invalidate a range of addresses on a page in the dcache
+#
+###############################################################################
+ ALIGN
+ .globl mn10300_local_dcache_flush_inv_page
+ .globl mn10300_local_dcache_flush_inv_range
+ .globl mn10300_local_dcache_flush_inv_range2
+ .type mn10300_local_dcache_flush_inv_page,@function
+ .type mn10300_local_dcache_flush_inv_range,@function
+ .type mn10300_local_dcache_flush_inv_range2,@function
+mn10300_local_dcache_flush_inv_page:
+ and ~(PAGE_SIZE-1),d0
+ mov PAGE_SIZE,d1
+mn10300_local_dcache_flush_inv_range2:
+ add d0,d1
+mn10300_local_dcache_flush_inv_range:
+ movm [d2,d3,a2],(sp)
+
+ movhu (CHCTR),d2
+ btst CHCTR_DCEN,d2
+ beq mn10300_local_dcache_flush_inv_range_end
+
+ # calculate alignsize
+ #
+ # alignsize = L1_CACHE_BYTES;
+ # for (i = (end - start - 1) / L1_CACHE_BYTES; i > 0; i >>= 1)
+ # alignsize <<= 1;
+ # d2 = alignsize
+ #
+ mov L1_CACHE_BYTES,d2
+ sub d0,d1,d3
+ add -1,d3
+ lsr L1_CACHE_SHIFT,d3
+ beq 2f
+1:
+ add d2,d2
+ lsr 1,d3
+ bne 1b
+2:
+ mov d1,a1 # a1 = end
+
+ LOCAL_CLI_SAVE(d3)
+ mov DCPGCR,a0
+
+ # wait for busy bit of area purge & invalidate
+ setlb
+ mov (a0),d1
+ btst DCPGCR_DCPGBSY,d1
+ lne
+
+ # set the mask
+ mov d2,d1
+ add -1,d1
+ not d1 # d1 = mask = ~(alignsize-1)
+ mov d1,(DCPGMR)
+
+ and d1,d0,a2 # a2 = mask & start
+
+dcpgivloop:
+ # area purge & invalidate
+ mov a2,d0
+ or DCPGCR_DCP|DCPGCR_DCI,d0
+ mov d0,(a0) # DCPGCR = (mask & start)|DCPGCR_DCP|DCPGCR_DCI
+
+ # wait for busy bit of area purge & invalidate
+ setlb
+ mov (a0),d1
+ btst DCPGCR_DCPGBSY,d1
+ lne
+
+ # check purge & invalidate of end address
+ add d2,a2 # a2 += alignsize
+ cmp a1,a2 # if (a2 < end) goto dcpgivloop
+ bns dcpgivloop
+
+ LOCAL_IRQ_RESTORE(d3)
+
+mn10300_local_dcache_flush_inv_range_end:
+ ret [d2,d3,a2],12
+ .size mn10300_local_dcache_flush_inv_page,.-mn10300_local_dcache_flush_inv_page
+ .size mn10300_local_dcache_flush_inv_range,.-mn10300_local_dcache_flush_inv_range
+ .size mn10300_local_dcache_flush_inv_range2,.-mn10300_local_dcache_flush_inv_range2
diff --git a/arch/mn10300/mm/cache-flush-by-tag.S b/arch/mn10300/mm/cache-flush-by-tag.S
new file mode 100644
index 000000000000..5cd6a27dd63e
--- /dev/null
+++ b/arch/mn10300/mm/cache-flush-by-tag.S
@@ -0,0 +1,251 @@
+/* MN10300 CPU core caching routines, using direct tag flushing
+ *
+ * Copyright (C) 2007 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/sys.h>
+#include <linux/linkage.h>
+#include <asm/smp.h>
+#include <asm/page.h>
+#include <asm/cache.h>
+#include <asm/irqflags.h>
+
+ .am33_2
+
+#ifndef CONFIG_SMP
+ .globl mn10300_dcache_flush
+ .globl mn10300_dcache_flush_page
+ .globl mn10300_dcache_flush_range
+ .globl mn10300_dcache_flush_range2
+ .globl mn10300_dcache_flush_inv
+ .globl mn10300_dcache_flush_inv_page
+ .globl mn10300_dcache_flush_inv_range
+ .globl mn10300_dcache_flush_inv_range2
+
+mn10300_dcache_flush = mn10300_local_dcache_flush
+mn10300_dcache_flush_page = mn10300_local_dcache_flush_page
+mn10300_dcache_flush_range = mn10300_local_dcache_flush_range
+mn10300_dcache_flush_range2 = mn10300_local_dcache_flush_range2
+mn10300_dcache_flush_inv = mn10300_local_dcache_flush_inv
+mn10300_dcache_flush_inv_page = mn10300_local_dcache_flush_inv_page
+mn10300_dcache_flush_inv_range = mn10300_local_dcache_flush_inv_range
+mn10300_dcache_flush_inv_range2 = mn10300_local_dcache_flush_inv_range2
+
+#endif /* !CONFIG_SMP */
+
+###############################################################################
+#
+# void mn10300_local_dcache_flush(void)
+# Flush the entire data cache back to RAM
+#
+###############################################################################
+ ALIGN
+ .globl mn10300_local_dcache_flush
+ .type mn10300_local_dcache_flush,@function
+mn10300_local_dcache_flush:
+ movhu (CHCTR),d0
+ btst CHCTR_DCEN,d0
+ beq mn10300_local_dcache_flush_end
+
+ # read the addresses tagged in the cache's tag RAM and attempt to flush
+ # those addresses specifically
+ # - we rely on the hardware to filter out invalid tag entry addresses
+ mov DCACHE_TAG(0,0),a0 # dcache tag RAM access address
+ mov DCACHE_PURGE(0,0),a1 # dcache purge request address
+ mov L1_CACHE_NWAYS*L1_CACHE_NENTRIES,d1 # total number of entries
+
+mn10300_local_dcache_flush_loop:
+ mov (a0),d0
+ and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0
+ or L1_CACHE_TAG_VALID,d0 # retain valid entries in the
+ # cache
+ mov d0,(a1) # conditional purge
+
+ add L1_CACHE_BYTES,a0
+ add L1_CACHE_BYTES,a1
+ add -1,d1
+ bne mn10300_local_dcache_flush_loop
+
+mn10300_local_dcache_flush_end:
+ ret [],0
+ .size mn10300_local_dcache_flush,.-mn10300_local_dcache_flush
+
+###############################################################################
+#
+# void mn10300_local_dcache_flush_page(unsigned long start)
+# void mn10300_local_dcache_flush_range(unsigned long start, unsigned long end)
+# void mn10300_local_dcache_flush_range2(unsigned long start, unsigned long size)
+# Flush a range of addresses on a page in the dcache
+#
+###############################################################################
+ ALIGN
+ .globl mn10300_local_dcache_flush_page
+ .globl mn10300_local_dcache_flush_range
+ .globl mn10300_local_dcache_flush_range2
+ .type mn10300_local_dcache_flush_page,@function
+ .type mn10300_local_dcache_flush_range,@function
+ .type mn10300_local_dcache_flush_range2,@function
+mn10300_local_dcache_flush_page:
+ and ~(PAGE_SIZE-1),d0
+ mov PAGE_SIZE,d1
+mn10300_local_dcache_flush_range2:
+ add d0,d1
+mn10300_local_dcache_flush_range:
+ movm [d2],(sp)
+
+ movhu (CHCTR),d2
+ btst CHCTR_DCEN,d2
+ beq mn10300_local_dcache_flush_range_end
+
+ sub d0,d1,a0
+ cmp MN10300_DCACHE_FLUSH_BORDER,a0
+ ble 1f
+
+ movm (sp),[d2]
+ bra mn10300_local_dcache_flush
+1:
+
+ # round start addr down
+ and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0
+ mov d0,a1
+
+ add L1_CACHE_BYTES,d1 # round end addr up
+ and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d1
+
+ # write a request to flush all instances of an address from the cache
+ mov DCACHE_PURGE(0,0),a0
+ mov a1,d0
+ and L1_CACHE_TAG_ENTRY,d0
+ add d0,a0 # starting dcache purge control
+ # reg address
+
+ sub a1,d1
+ lsr L1_CACHE_SHIFT,d1 # total number of entries to
+ # examine
+
+ or L1_CACHE_TAG_VALID,a1 # retain valid entries in the
+ # cache
+
+mn10300_local_dcache_flush_range_loop:
+ mov a1,(L1_CACHE_WAYDISP*0,a0) # conditionally purge this line
+ # all ways
+
+ add L1_CACHE_BYTES,a0
+ add L1_CACHE_BYTES,a1
+ and ~L1_CACHE_WAYDISP,a0 # make sure way stay on way 0
+ add -1,d1
+ bne mn10300_local_dcache_flush_range_loop
+
+mn10300_local_dcache_flush_range_end:
+ ret [d2],4
+
+ .size mn10300_local_dcache_flush_page,.-mn10300_local_dcache_flush_page
+ .size mn10300_local_dcache_flush_range,.-mn10300_local_dcache_flush_range
+ .size mn10300_local_dcache_flush_range2,.-mn10300_local_dcache_flush_range2
+
+###############################################################################
+#
+# void mn10300_local_dcache_flush_inv(void)
+# Flush the entire data cache and invalidate all entries
+#
+###############################################################################
+ ALIGN
+ .globl mn10300_local_dcache_flush_inv
+ .type mn10300_local_dcache_flush_inv,@function
+mn10300_local_dcache_flush_inv:
+ movhu (CHCTR),d0
+ btst CHCTR_DCEN,d0
+ beq mn10300_local_dcache_flush_inv_end
+
+ mov L1_CACHE_NENTRIES,d1
+ clr a1
+
+mn10300_local_dcache_flush_inv_loop:
+ mov (DCACHE_PURGE_WAY0(0),a1),d0 # unconditional purge
+ mov (DCACHE_PURGE_WAY1(0),a1),d0 # unconditional purge
+ mov (DCACHE_PURGE_WAY2(0),a1),d0 # unconditional purge
+ mov (DCACHE_PURGE_WAY3(0),a1),d0 # unconditional purge
+
+ add L1_CACHE_BYTES,a1
+ add -1,d1
+ bne mn10300_local_dcache_flush_inv_loop
+
+mn10300_local_dcache_flush_inv_end:
+ ret [],0
+ .size mn10300_local_dcache_flush_inv,.-mn10300_local_dcache_flush_inv
+
+###############################################################################
+#
+# void mn10300_local_dcache_flush_inv_page(unsigned long start)
+# void mn10300_local_dcache_flush_inv_range(unsigned long start, unsigned long end)
+# void mn10300_local_dcache_flush_inv_range2(unsigned long start, unsigned long size)
+# Flush and invalidate a range of addresses on a page in the dcache
+#
+###############################################################################
+ ALIGN
+ .globl mn10300_local_dcache_flush_inv_page
+ .globl mn10300_local_dcache_flush_inv_range
+ .globl mn10300_local_dcache_flush_inv_range2
+ .type mn10300_local_dcache_flush_inv_page,@function
+ .type mn10300_local_dcache_flush_inv_range,@function
+ .type mn10300_local_dcache_flush_inv_range2,@function
+mn10300_local_dcache_flush_inv_page:
+ and ~(PAGE_SIZE-1),d0
+ mov PAGE_SIZE,d1
+mn10300_local_dcache_flush_inv_range2:
+ add d0,d1
+mn10300_local_dcache_flush_inv_range:
+ movm [d2],(sp)
+
+ movhu (CHCTR),d2
+ btst CHCTR_DCEN,d2
+ beq mn10300_local_dcache_flush_inv_range_end
+
+ sub d0,d1,a0
+ cmp MN10300_DCACHE_FLUSH_INV_BORDER,a0
+ ble 1f
+
+ movm (sp),[d2]
+ bra mn10300_local_dcache_flush_inv
+1:
+
+ and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 # round start
+ # addr down
+ mov d0,a1
+
+ add L1_CACHE_BYTES,d1 # round end addr up
+ and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d1
+
+ # write a request to flush and invalidate all instances of an address
+ # from the cache
+ mov DCACHE_PURGE(0,0),a0
+ mov a1,d0
+ and L1_CACHE_TAG_ENTRY,d0
+ add d0,a0 # starting dcache purge control
+ # reg address
+
+ sub a1,d1
+ lsr L1_CACHE_SHIFT,d1 # total number of entries to
+ # examine
+
+mn10300_local_dcache_flush_inv_range_loop:
+ mov a1,(L1_CACHE_WAYDISP*0,a0) # conditionally purge this line
+ # in all ways
+
+ add L1_CACHE_BYTES,a0
+ add L1_CACHE_BYTES,a1
+ and ~L1_CACHE_WAYDISP,a0 # make sure way stay on way 0
+ add -1,d1
+ bne mn10300_local_dcache_flush_inv_range_loop
+
+mn10300_local_dcache_flush_inv_range_end:
+ ret [d2],4
+ .size mn10300_local_dcache_flush_inv_page,.-mn10300_local_dcache_flush_inv_page
+ .size mn10300_local_dcache_flush_inv_range,.-mn10300_local_dcache_flush_inv_range
+ .size mn10300_local_dcache_flush_inv_range2,.-mn10300_local_dcache_flush_inv_range2
diff --git a/arch/mn10300/mm/cache-flush-icache.c b/arch/mn10300/mm/cache-flush-icache.c
new file mode 100644
index 000000000000..fdb1a9db20f0
--- /dev/null
+++ b/arch/mn10300/mm/cache-flush-icache.c
@@ -0,0 +1,155 @@
+/* Flush dcache and invalidate icache when the dcache is in writeback mode
+ *
+ * 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.
+ */
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <asm/cacheflush.h>
+#include <asm/smp.h>
+#include "cache-smp.h"
+
+/**
+ * flush_icache_page - Flush a page from the dcache and invalidate the icache
+ * @vma: The VMA the page is part of.
+ * @page: The page to be flushed.
+ *
+ * Write a page back from the dcache and invalidate the icache so that we can
+ * run code from it that we've just written into it
+ */
+void flush_icache_page(struct vm_area_struct *vma, struct page *page)
+{
+ unsigned long start = page_to_phys(page);
+ unsigned long flags;
+
+ flags = smp_lock_cache();
+
+ mn10300_local_dcache_flush_page(start);
+ mn10300_local_icache_inv_page(start);
+
+ smp_cache_call(SMP_IDCACHE_INV_FLUSH_RANGE, start, start + PAGE_SIZE);
+ smp_unlock_cache(flags);
+}
+EXPORT_SYMBOL(flush_icache_page);
+
+/**
+ * flush_icache_page_range - Flush dcache and invalidate icache for part of a
+ * single page
+ * @start: The starting virtual address of the page part.
+ * @end: The ending virtual address of the page part.
+ *
+ * Flush the dcache and invalidate the icache for part of a single page, as
+ * determined by the virtual addresses given. The page must be in the paged
+ * area.
+ */
+static void flush_icache_page_range(unsigned long start, unsigned long end)
+{
+ unsigned long addr, size, off;
+ struct page *page;
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *ppte, pte;
+
+ /* work out how much of the page to flush */
+ off = start & ~PAGE_MASK;
+ size = end - start;
+
+ /* get the physical address the page is mapped to from the page
+ * tables */
+ pgd = pgd_offset(current->mm, start);
+ if (!pgd || !pgd_val(*pgd))
+ return;
+
+ pud = pud_offset(pgd, start);
+ if (!pud || !pud_val(*pud))
+ return;
+
+ pmd = pmd_offset(pud, start);
+ if (!pmd || !pmd_val(*pmd))
+ return;
+
+ ppte = pte_offset_map(pmd, start);
+ if (!ppte)
+ return;
+ pte = *ppte;
+ pte_unmap(ppte);
+
+ if (pte_none(pte))
+ return;
+
+ page = pte_page(pte);
+ if (!page)
+ return;
+
+ addr = page_to_phys(page);
+
+ /* flush the dcache and invalidate the icache coverage on that
+ * region */
+ mn10300_local_dcache_flush_range2(addr + off, size);
+ mn10300_local_icache_inv_range2(addr + off, size);
+ smp_cache_call(SMP_IDCACHE_INV_FLUSH_RANGE, start, end);
+}
+
+/**
+ * flush_icache_range - Globally flush dcache and invalidate icache for region
+ * @start: The starting virtual address of the region.
+ * @end: The ending virtual address of the region.
+ *
+ * This is used by the kernel to globally flush some code it has just written
+ * from the dcache back to RAM and then to globally invalidate the icache over
+ * that region so that that code can be run on all CPUs in the system.
+ */
+void flush_icache_range(unsigned long start, unsigned long end)
+{
+ unsigned long start_page, end_page;
+ unsigned long flags;
+
+ flags = smp_lock_cache();
+
+ if (end > 0x80000000UL) {
+ /* addresses above 0xa0000000 do not go through the cache */
+ if (end > 0xa0000000UL) {
+ end = 0xa0000000UL;
+ if (start >= end)
+ goto done;
+ }
+
+ /* kernel addresses between 0x80000000 and 0x9fffffff do not
+ * require page tables, so we just map such addresses
+ * directly */
+ start_page = (start >= 0x80000000UL) ? start : 0x80000000UL;
+ mn10300_local_dcache_flush_range(start_page, end);
+ mn10300_local_icache_inv_range(start_page, end);
+ smp_cache_call(SMP_IDCACHE_INV_FLUSH_RANGE, start_page, end);
+ if (start_page == start)
+ goto done;
+ end = start_page;
+ }
+
+ start_page = start & PAGE_MASK;
+ end_page = (end - 1) & PAGE_MASK;
+
+ if (start_page == end_page) {
+ /* the first and last bytes are on the same page */
+ flush_icache_page_range(start, end);
+ } else if (start_page + 1 == end_page) {
+ /* split over two virtually contiguous pages */
+ flush_icache_page_range(start, end_page);
+ flush_icache_page_range(end_page, end);
+ } else {
+ /* more than 2 pages; just flush the entire cache */
+ mn10300_dcache_flush();
+ mn10300_icache_inv();
+ smp_cache_call(SMP_IDCACHE_INV_FLUSH, 0, 0);
+ }
+
+done:
+ smp_unlock_cache(flags);
+}
+EXPORT_SYMBOL(flush_icache_range);
diff --git a/arch/mn10300/mm/cache-flush-mn10300.S b/arch/mn10300/mm/cache-flush-mn10300.S
deleted file mode 100644
index c8ed1cbac107..000000000000
--- a/arch/mn10300/mm/cache-flush-mn10300.S
+++ /dev/null
@@ -1,192 +0,0 @@
-/* MN10300 CPU core caching routines
- *
- * Copyright (C) 2007 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/sys.h>
-#include <linux/linkage.h>
-#include <asm/smp.h>
-#include <asm/page.h>
-#include <asm/cache.h>
-
- .am33_2
- .globl mn10300_dcache_flush
- .globl mn10300_dcache_flush_page
- .globl mn10300_dcache_flush_range
- .globl mn10300_dcache_flush_range2
- .globl mn10300_dcache_flush_inv
- .globl mn10300_dcache_flush_inv_page
- .globl mn10300_dcache_flush_inv_range
- .globl mn10300_dcache_flush_inv_range2
-
-###############################################################################
-#
-# void mn10300_dcache_flush(void)
-# Flush the entire data cache back to RAM
-#
-###############################################################################
- ALIGN
-mn10300_dcache_flush:
- movhu (CHCTR),d0
- btst CHCTR_DCEN,d0
- beq mn10300_dcache_flush_end
-
- # read the addresses tagged in the cache's tag RAM and attempt to flush
- # those addresses specifically
- # - we rely on the hardware to filter out invalid tag entry addresses
- mov DCACHE_TAG(0,0),a0 # dcache tag RAM access address
- mov DCACHE_PURGE(0,0),a1 # dcache purge request address
- mov L1_CACHE_NWAYS*L1_CACHE_NENTRIES,d1 # total number of entries
-
-mn10300_dcache_flush_loop:
- mov (a0),d0
- and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0
- or L1_CACHE_TAG_VALID,d0 # retain valid entries in the
- # cache
- mov d0,(a1) # conditional purge
-
-mn10300_dcache_flush_skip:
- add L1_CACHE_BYTES,a0
- add L1_CACHE_BYTES,a1
- add -1,d1
- bne mn10300_dcache_flush_loop
-
-mn10300_dcache_flush_end:
- ret [],0
-
-###############################################################################
-#
-# void mn10300_dcache_flush_page(unsigned start)
-# void mn10300_dcache_flush_range(unsigned start, unsigned end)
-# void mn10300_dcache_flush_range2(unsigned start, unsigned size)
-# Flush a range of addresses on a page in the dcache
-#
-###############################################################################
- ALIGN
-mn10300_dcache_flush_page:
- mov PAGE_SIZE,d1
-mn10300_dcache_flush_range2:
- add d0,d1
-mn10300_dcache_flush_range:
- movm [d2,d3],(sp)
-
- movhu (CHCTR),d2
- btst CHCTR_DCEN,d2
- beq mn10300_dcache_flush_range_end
-
- # round start addr down
- and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0
- mov d0,a1
-
- add L1_CACHE_BYTES,d1 # round end addr up
- and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d1
-
- # write a request to flush all instances of an address from the cache
- mov DCACHE_PURGE(0,0),a0
- mov a1,d0
- and L1_CACHE_TAG_ENTRY,d0
- add d0,a0 # starting dcache purge control
- # reg address
-
- sub a1,d1
- lsr L1_CACHE_SHIFT,d1 # total number of entries to
- # examine
-
- or L1_CACHE_TAG_VALID,a1 # retain valid entries in the
- # cache
-
-mn10300_dcache_flush_range_loop:
- mov a1,(L1_CACHE_WAYDISP*0,a0) # conditionally purge this line
- # all ways
-
- add L1_CACHE_BYTES,a0
- add L1_CACHE_BYTES,a1
- and ~L1_CACHE_WAYDISP,a0 # make sure way stay on way 0
- add -1,d1
- bne mn10300_dcache_flush_range_loop
-
-mn10300_dcache_flush_range_end:
- ret [d2,d3],8
-
-###############################################################################
-#
-# void mn10300_dcache_flush_inv(void)
-# Flush the entire data cache and invalidate all entries
-#
-###############################################################################
- ALIGN
-mn10300_dcache_flush_inv:
- movhu (CHCTR),d0
- btst CHCTR_DCEN,d0
- beq mn10300_dcache_flush_inv_end
-
- # hit each line in the dcache with an unconditional purge
- mov DCACHE_PURGE(0,0),a1 # dcache purge request address
- mov L1_CACHE_NWAYS*L1_CACHE_NENTRIES,d1 # total number of entries
-
-mn10300_dcache_flush_inv_loop:
- mov (a1),d0 # unconditional purge
-
- add L1_CACHE_BYTES,a1
- add -1,d1
- bne mn10300_dcache_flush_inv_loop
-
-mn10300_dcache_flush_inv_end:
- ret [],0
-
-###############################################################################
-#
-# void mn10300_dcache_flush_inv_page(unsigned start)
-# void mn10300_dcache_flush_inv_range(unsigned start, unsigned end)
-# void mn10300_dcache_flush_inv_range2(unsigned start, unsigned size)
-# Flush and invalidate a range of addresses on a page in the dcache
-#
-###############################################################################
- ALIGN
-mn10300_dcache_flush_inv_page:
- mov PAGE_SIZE,d1
-mn10300_dcache_flush_inv_range2:
- add d0,d1
-mn10300_dcache_flush_inv_range:
- movm [d2,d3],(sp)
- movhu (CHCTR),d2
- btst CHCTR_DCEN,d2
- beq mn10300_dcache_flush_inv_range_end
-
- and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 # round start
- # addr down
- mov d0,a1
-
- add L1_CACHE_BYTES,d1 # round end addr up
- and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d1
-
- # write a request to flush and invalidate all instances of an address
- # from the cache
- mov DCACHE_PURGE(0,0),a0
- mov a1,d0
- and L1_CACHE_TAG_ENTRY,d0
- add d0,a0 # starting dcache purge control
- # reg address
-
- sub a1,d1
- lsr L1_CACHE_SHIFT,d1 # total number of entries to
- # examine
-
-mn10300_dcache_flush_inv_range_loop:
- mov a1,(L1_CACHE_WAYDISP*0,a0) # conditionally purge this line
- # in all ways
-
- add L1_CACHE_BYTES,a0
- add L1_CACHE_BYTES,a1
- and ~L1_CACHE_WAYDISP,a0 # make sure way stay on way 0
- add -1,d1
- bne mn10300_dcache_flush_inv_range_loop
-
-mn10300_dcache_flush_inv_range_end:
- ret [d2,d3],8
diff --git a/arch/mn10300/mm/cache-inv-by-reg.S b/arch/mn10300/mm/cache-inv-by-reg.S
new file mode 100644
index 000000000000..c8950861ed77
--- /dev/null
+++ b/arch/mn10300/mm/cache-inv-by-reg.S
@@ -0,0 +1,356 @@
+/* MN10300 CPU cache invalidation routines, using automatic purge registers
+ *
+ * Copyright (C) 2007 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/sys.h>
+#include <linux/linkage.h>
+#include <asm/smp.h>
+#include <asm/page.h>
+#include <asm/cache.h>
+#include <asm/irqflags.h>
+#include <asm/cacheflush.h>
+
+#define mn10300_local_dcache_inv_range_intr_interval \
+ +((1 << MN10300_DCACHE_INV_RANGE_INTR_LOG2_INTERVAL) - 1)
+
+#if mn10300_local_dcache_inv_range_intr_interval > 0xff
+#error MN10300_DCACHE_INV_RANGE_INTR_LOG2_INTERVAL must be 8 or less
+#endif
+
+ .am33_2
+
+#ifndef CONFIG_SMP
+ .globl mn10300_icache_inv
+ .globl mn10300_icache_inv_page
+ .globl mn10300_icache_inv_range
+ .globl mn10300_icache_inv_range2
+ .globl mn10300_dcache_inv
+ .globl mn10300_dcache_inv_page
+ .globl mn10300_dcache_inv_range
+ .globl mn10300_dcache_inv_range2
+
+mn10300_icache_inv = mn10300_local_icache_inv
+mn10300_icache_inv_page = mn10300_local_icache_inv_page
+mn10300_icache_inv_range = mn10300_local_icache_inv_range
+mn10300_icache_inv_range2 = mn10300_local_icache_inv_range2
+mn10300_dcache_inv = mn10300_local_dcache_inv
+mn10300_dcache_inv_page = mn10300_local_dcache_inv_page
+mn10300_dcache_inv_range = mn10300_local_dcache_inv_range
+mn10300_dcache_inv_range2 = mn10300_local_dcache_inv_range2
+
+#endif /* !CONFIG_SMP */
+
+###############################################################################
+#
+# void mn10300_local_icache_inv(void)
+# Invalidate the entire icache
+#
+###############################################################################
+ ALIGN
+ .globl mn10300_local_icache_inv
+ .type mn10300_local_icache_inv,@function
+mn10300_local_icache_inv:
+ mov CHCTR,a0
+
+ movhu (a0),d0
+ btst CHCTR_ICEN,d0
+ beq mn10300_local_icache_inv_end
+
+ # invalidate
+ or CHCTR_ICINV,d0
+ movhu d0,(a0)
+ movhu (a0),d0
+
+mn10300_local_icache_inv_end:
+ ret [],0
+ .size mn10300_local_icache_inv,.-mn10300_local_icache_inv
+
+###############################################################################
+#
+# void mn10300_local_dcache_inv(void)
+# Invalidate the entire dcache
+#
+###############################################################################
+ ALIGN
+ .globl mn10300_local_dcache_inv
+ .type mn10300_local_dcache_inv,@function
+mn10300_local_dcache_inv:
+ mov CHCTR,a0
+
+ movhu (a0),d0
+ btst CHCTR_DCEN,d0
+ beq mn10300_local_dcache_inv_end
+
+ # invalidate
+ or CHCTR_DCINV,d0
+ movhu d0,(a0)
+ movhu (a0),d0
+
+mn10300_local_dcache_inv_end:
+ ret [],0
+ .size mn10300_local_dcache_inv,.-mn10300_local_dcache_inv
+
+###############################################################################
+#
+# void mn10300_local_dcache_inv_range(unsigned long start, unsigned long end)
+# void mn10300_local_dcache_inv_range2(unsigned long start, unsigned long size)
+# void mn10300_local_dcache_inv_page(unsigned long start)
+# Invalidate a range of addresses on a page in the dcache
+#
+###############################################################################
+ ALIGN
+ .globl mn10300_local_dcache_inv_page
+ .globl mn10300_local_dcache_inv_range
+ .globl mn10300_local_dcache_inv_range2
+ .type mn10300_local_dcache_inv_page,@function
+ .type mn10300_local_dcache_inv_range,@function
+ .type mn10300_local_dcache_inv_range2,@function
+mn10300_local_dcache_inv_page:
+ and ~(PAGE_SIZE-1),d0
+ mov PAGE_SIZE,d1
+mn10300_local_dcache_inv_range2:
+ add d0,d1
+mn10300_local_dcache_inv_range:
+ # If we are in writeback mode we check the start and end alignments,
+ # and if they're not cacheline-aligned, we must flush any bits outside
+ # the range that share cachelines with stuff inside the range
+#ifdef CONFIG_MN10300_CACHE_WBACK
+ btst ~(L1_CACHE_BYTES-1),d0
+ bne 1f
+ btst ~(L1_CACHE_BYTES-1),d1
+ beq 2f
+1:
+ bra mn10300_local_dcache_flush_inv_range
+2:
+#endif /* CONFIG_MN10300_CACHE_WBACK */
+
+ movm [d2,d3,a2],(sp)
+
+ mov CHCTR,a0
+ movhu (a0),d2
+ btst CHCTR_DCEN,d2
+ beq mn10300_local_dcache_inv_range_end
+
+ # round the addresses out to be full cachelines, unless we're in
+ # writeback mode, in which case we would be in flush and invalidate by
+ # now
+#ifndef CONFIG_MN10300_CACHE_WBACK
+ and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 # round start
+ # addr down
+
+ mov L1_CACHE_BYTES-1,d2
+ add d2,d1
+ and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d1 # round end addr up
+#endif /* !CONFIG_MN10300_CACHE_WBACK */
+
+ sub d0,d1,d2 # calculate the total size
+ mov d0,a2 # A2 = start address
+ mov d1,a1 # A1 = end address
+
+ LOCAL_CLI_SAVE(d3)
+
+ mov DCPGCR,a0 # make sure the purger isn't busy
+ setlb
+ mov (a0),d0
+ btst DCPGCR_DCPGBSY,d0
+ lne
+
+ # skip initial address alignment calculation if address is zero
+ mov d2,d1
+ cmp 0,a2
+ beq 1f
+
+dcivloop:
+ /* calculate alignsize
+ *
+ * alignsize = L1_CACHE_BYTES;
+ * while (! start & alignsize) {
+ * alignsize <<=1;
+ * }
+ * d1 = alignsize;
+ */
+ mov L1_CACHE_BYTES,d1
+ lsr 1,d1
+ setlb
+ add d1,d1
+ mov d1,d0
+ and a2,d0
+ leq
+
+1:
+ /* calculate invsize
+ *
+ * if (totalsize > alignsize) {
+ * invsize = alignsize;
+ * } else {
+ * invsize = totalsize;
+ * tmp = 0x80000000;
+ * while (! invsize & tmp) {
+ * tmp >>= 1;
+ * }
+ * invsize = tmp;
+ * }
+ * d1 = invsize
+ */
+ cmp d2,d1
+ bns 2f
+ mov d2,d1
+
+ mov 0x80000000,d0 # start from 31bit=1
+ setlb
+ lsr 1,d0
+ mov d0,e0
+ and d1,e0
+ leq
+ mov d0,d1
+
+2:
+ /* set mask
+ *
+ * mask = ~(invsize-1);
+ * DCPGMR = mask;
+ */
+ mov d1,d0
+ add -1,d0
+ not d0
+ mov d0,(DCPGMR)
+
+ # invalidate area
+ mov a2,d0
+ or DCPGCR_DCI,d0
+ mov d0,(a0) # DCPGCR = (mask & start) | DCPGCR_DCI
+
+ setlb # wait for the purge to complete
+ mov (a0),d0
+ btst DCPGCR_DCPGBSY,d0
+ lne
+
+ sub d1,d2 # decrease size remaining
+ add d1,a2 # increase next start address
+
+ /* check invalidating of end address
+ *
+ * a2 = a2 + invsize
+ * if (a2 < end) {
+ * goto dcivloop;
+ * } */
+ cmp a1,a2
+ bns dcivloop
+
+ LOCAL_IRQ_RESTORE(d3)
+
+mn10300_local_dcache_inv_range_end:
+ ret [d2,d3,a2],12
+ .size mn10300_local_dcache_inv_page,.-mn10300_local_dcache_inv_page
+ .size mn10300_local_dcache_inv_range,.-mn10300_local_dcache_inv_range
+ .size mn10300_local_dcache_inv_range2,.-mn10300_local_dcache_inv_range2
+
+###############################################################################
+#
+# void mn10300_local_icache_inv_page(unsigned long start)
+# void mn10300_local_icache_inv_range2(unsigned long start, unsigned long size)
+# void mn10300_local_icache_inv_range(unsigned long start, unsigned long end)
+# Invalidate a range of addresses on a page in the icache
+#
+###############################################################################
+ ALIGN
+ .globl mn10300_local_icache_inv_page
+ .globl mn10300_local_icache_inv_range
+ .globl mn10300_local_icache_inv_range2
+ .type mn10300_local_icache_inv_page,@function
+ .type mn10300_local_icache_inv_range,@function
+ .type mn10300_local_icache_inv_range2,@function
+mn10300_local_icache_inv_page:
+ and ~(PAGE_SIZE-1),d0
+ mov PAGE_SIZE,d1
+mn10300_local_icache_inv_range2:
+ add d0,d1
+mn10300_local_icache_inv_range:
+ movm [d2,d3,a2],(sp)
+
+ mov CHCTR,a0
+ movhu (a0),d2
+ btst CHCTR_ICEN,d2
+ beq mn10300_local_icache_inv_range_reg_end
+
+ /* calculate alignsize
+ *
+ * alignsize = L1_CACHE_BYTES;
+ * for (i = (end - start - 1) / L1_CACHE_BYTES ; i > 0; i >>= 1) {
+ * alignsize <<= 1;
+ * }
+ * d2 = alignsize;
+ */
+ mov L1_CACHE_BYTES,d2
+ sub d0,d1,d3
+ add -1,d3
+ lsr L1_CACHE_SHIFT,d3
+ beq 2f
+1:
+ add d2,d2
+ lsr 1,d3
+ bne 1b
+2:
+
+ /* a1 = end */
+ mov d1,a1
+
+ LOCAL_CLI_SAVE(d3)
+
+ mov ICIVCR,a0
+ /* wait for busy bit of area invalidation */
+ setlb
+ mov (a0),d1
+ btst ICIVCR_ICIVBSY,d1
+ lne
+
+ /* set mask
+ *
+ * mask = ~(alignsize-1);
+ * ICIVMR = mask;
+ */
+ mov d2,d1
+ add -1,d1
+ not d1
+ mov d1,(ICIVMR)
+ /* a2 = mask & start */
+ and d1,d0,a2
+
+icivloop:
+ /* area invalidate
+ *
+ * ICIVCR = (mask & start) | ICIVCR_ICI
+ */
+ mov a2,d0
+ or ICIVCR_ICI,d0
+ mov d0,(a0)
+
+ /* wait for busy bit of area invalidation */
+ setlb
+ mov (a0),d1
+ btst ICIVCR_ICIVBSY,d1
+ lne
+
+ /* check invalidating of end address
+ *
+ * a2 = a2 + alignsize
+ * if (a2 < end) {
+ * goto icivloop;
+ * } */
+ add d2,a2
+ cmp a1,a2
+ bns icivloop
+
+ LOCAL_IRQ_RESTORE(d3)
+
+mn10300_local_icache_inv_range_reg_end:
+ ret [d2,d3,a2],12
+ .size mn10300_local_icache_inv_page,.-mn10300_local_icache_inv_page
+ .size mn10300_local_icache_inv_range,.-mn10300_local_icache_inv_range
+ .size mn10300_local_icache_inv_range2,.-mn10300_local_icache_inv_range2
diff --git a/arch/mn10300/mm/cache-inv-by-tag.S b/arch/mn10300/mm/cache-inv-by-tag.S
new file mode 100644
index 000000000000..e9713b40c0ff
--- /dev/null
+++ b/arch/mn10300/mm/cache-inv-by-tag.S
@@ -0,0 +1,348 @@
+/* MN10300 CPU core caching routines
+ *
+ * Copyright (C) 2007 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/sys.h>
+#include <linux/linkage.h>
+#include <asm/smp.h>
+#include <asm/page.h>
+#include <asm/cache.h>
+#include <asm/irqflags.h>
+#include <asm/cacheflush.h>
+
+#define mn10300_local_dcache_inv_range_intr_interval \
+ +((1 << MN10300_DCACHE_INV_RANGE_INTR_LOG2_INTERVAL) - 1)
+
+#if mn10300_local_dcache_inv_range_intr_interval > 0xff
+#error MN10300_DCACHE_INV_RANGE_INTR_LOG2_INTERVAL must be 8 or less
+#endif
+
+ .am33_2
+
+ .globl mn10300_local_icache_inv_page
+ .globl mn10300_local_icache_inv_range
+ .globl mn10300_local_icache_inv_range2
+
+mn10300_local_icache_inv_page = mn10300_local_icache_inv
+mn10300_local_icache_inv_range = mn10300_local_icache_inv
+mn10300_local_icache_inv_range2 = mn10300_local_icache_inv
+
+#ifndef CONFIG_SMP
+ .globl mn10300_icache_inv
+ .globl mn10300_icache_inv_page
+ .globl mn10300_icache_inv_range
+ .globl mn10300_icache_inv_range2
+ .globl mn10300_dcache_inv
+ .globl mn10300_dcache_inv_page
+ .globl mn10300_dcache_inv_range
+ .globl mn10300_dcache_inv_range2
+
+mn10300_icache_inv = mn10300_local_icache_inv
+mn10300_icache_inv_page = mn10300_local_icache_inv_page
+mn10300_icache_inv_range = mn10300_local_icache_inv_range
+mn10300_icache_inv_range2 = mn10300_local_icache_inv_range2
+mn10300_dcache_inv = mn10300_local_dcache_inv
+mn10300_dcache_inv_page = mn10300_local_dcache_inv_page
+mn10300_dcache_inv_range = mn10300_local_dcache_inv_range
+mn10300_dcache_inv_range2 = mn10300_local_dcache_inv_range2
+
+#endif /* !CONFIG_SMP */
+
+###############################################################################
+#
+# void mn10300_local_icache_inv(void)
+# Invalidate the entire icache
+#
+###############################################################################
+ ALIGN
+ .globl mn10300_local_icache_inv
+ .type mn10300_local_icache_inv,@function
+mn10300_local_icache_inv:
+ mov CHCTR,a0
+
+ movhu (a0),d0
+ btst CHCTR_ICEN,d0
+ beq mn10300_local_icache_inv_end
+
+#if defined(CONFIG_AM33_2) || defined(CONFIG_AM33_3)
+ LOCAL_CLI_SAVE(d1)
+
+ # disable the icache
+ and ~CHCTR_ICEN,d0
+ movhu d0,(a0)
+
+ # and wait for it to calm down
+ setlb
+ movhu (a0),d0
+ btst CHCTR_ICBUSY,d0
+ lne
+
+ # invalidate
+ or CHCTR_ICINV,d0
+ movhu d0,(a0)
+
+ # wait for the cache to finish
+ mov CHCTR,a0
+ setlb
+ movhu (a0),d0
+ btst CHCTR_ICBUSY,d0
+ lne
+
+ # and reenable it
+ and ~CHCTR_ICINV,d0
+ or CHCTR_ICEN,d0
+ movhu d0,(a0)
+ movhu (a0),d0
+
+ LOCAL_IRQ_RESTORE(d1)
+#else /* CONFIG_AM33_2 || CONFIG_AM33_3 */
+ # invalidate
+ or CHCTR_ICINV,d0
+ movhu d0,(a0)
+ movhu (a0),d0
+#endif /* CONFIG_AM33_2 || CONFIG_AM33_3 */
+
+mn10300_local_icache_inv_end:
+ ret [],0
+ .size mn10300_local_icache_inv,.-mn10300_local_icache_inv
+
+###############################################################################
+#
+# void mn10300_local_dcache_inv(void)
+# Invalidate the entire dcache
+#
+###############################################################################
+ ALIGN
+ .globl mn10300_local_dcache_inv
+ .type mn10300_local_dcache_inv,@function
+mn10300_local_dcache_inv:
+ mov CHCTR,a0
+
+ movhu (a0),d0
+ btst CHCTR_DCEN,d0
+ beq mn10300_local_dcache_inv_end
+
+#if defined(CONFIG_AM33_2) || defined(CONFIG_AM33_3)
+ LOCAL_CLI_SAVE(d1)
+
+ # disable the dcache
+ and ~CHCTR_DCEN,d0
+ movhu d0,(a0)
+
+ # and wait for it to calm down
+ setlb
+ movhu (a0),d0
+ btst CHCTR_DCBUSY,d0
+ lne
+
+ # invalidate
+ or CHCTR_DCINV,d0
+ movhu d0,(a0)
+
+ # wait for the cache to finish
+ mov CHCTR,a0
+ setlb
+ movhu (a0),d0
+ btst CHCTR_DCBUSY,d0
+ lne
+
+ # and reenable it
+ and ~CHCTR_DCINV,d0
+ or CHCTR_DCEN,d0
+ movhu d0,(a0)
+ movhu (a0),d0
+
+ LOCAL_IRQ_RESTORE(d1)
+#else /* CONFIG_AM33_2 || CONFIG_AM33_3 */
+ # invalidate
+ or CHCTR_DCINV,d0
+ movhu d0,(a0)
+ movhu (a0),d0
+#endif /* CONFIG_AM33_2 || CONFIG_AM33_3 */
+
+mn10300_local_dcache_inv_end:
+ ret [],0
+ .size mn10300_local_dcache_inv,.-mn10300_local_dcache_inv
+
+###############################################################################
+#
+# void mn10300_local_dcache_inv_range(unsigned long start, unsigned long end)
+# void mn10300_local_dcache_inv_range2(unsigned long start, unsigned long size)
+# void mn10300_local_dcache_inv_page(unsigned long start)
+# Invalidate a range of addresses on a page in the dcache
+#
+###############################################################################
+ ALIGN
+ .globl mn10300_local_dcache_inv_page
+ .globl mn10300_local_dcache_inv_range
+ .globl mn10300_local_dcache_inv_range2
+ .type mn10300_local_dcache_inv_page,@function
+ .type mn10300_local_dcache_inv_range,@function
+ .type mn10300_local_dcache_inv_range2,@function
+mn10300_local_dcache_inv_page:
+ and ~(PAGE_SIZE-1),d0
+ mov PAGE_SIZE,d1
+mn10300_local_dcache_inv_range2:
+ add d0,d1
+mn10300_local_dcache_inv_range:
+ # If we are in writeback mode we check the start and end alignments,
+ # and if they're not cacheline-aligned, we must flush any bits outside
+ # the range that share cachelines with stuff inside the range
+#ifdef CONFIG_MN10300_CACHE_WBACK
+ btst ~(L1_CACHE_BYTES-1),d0
+ bne 1f
+ btst ~(L1_CACHE_BYTES-1),d1
+ beq 2f
+1:
+ bra mn10300_local_dcache_flush_inv_range
+2:
+#endif /* CONFIG_MN10300_CACHE_WBACK */
+
+ movm [d2,d3,a2],(sp)
+
+ mov CHCTR,a2
+ movhu (a2),d2
+ btst CHCTR_DCEN,d2
+ beq mn10300_local_dcache_inv_range_end
+
+#ifndef CONFIG_MN10300_CACHE_WBACK
+ and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 # round start
+ # addr down
+
+ add L1_CACHE_BYTES,d1 # round end addr up
+ and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d1
+#endif /* !CONFIG_MN10300_CACHE_WBACK */
+ mov d0,a1
+
+ clr d2 # we're going to clear tag RAM
+ # entries
+
+ # read the tags from the tag RAM, and if they indicate a valid dirty
+ # cache line then invalidate that line
+ mov DCACHE_TAG(0,0),a0
+ mov a1,d0
+ and L1_CACHE_TAG_ENTRY,d0
+ add d0,a0 # starting dcache tag RAM
+ # access address
+
+ sub a1,d1
+ lsr L1_CACHE_SHIFT,d1 # total number of entries to
+ # examine
+
+ and ~(L1_CACHE_DISPARITY-1),a1 # determine comparator base
+
+mn10300_local_dcache_inv_range_outer_loop:
+ LOCAL_CLI_SAVE(d3)
+
+ # disable the dcache
+ movhu (a2),d0
+ and ~CHCTR_DCEN,d0
+ movhu d0,(a2)
+
+ # and wait for it to calm down
+ setlb
+ movhu (a2),d0
+ btst CHCTR_DCBUSY,d0
+ lne
+
+mn10300_local_dcache_inv_range_loop:
+
+ # process the way 0 slot
+ mov (L1_CACHE_WAYDISP*0,a0),d0 # read the tag in the way 0 slot
+ btst L1_CACHE_TAG_VALID,d0
+ beq mn10300_local_dcache_inv_range_skip_0 # jump if this cacheline
+ # is not valid
+
+ xor a1,d0
+ lsr 12,d0
+ bne mn10300_local_dcache_inv_range_skip_0 # jump if not this cacheline
+
+ mov d2,(L1_CACHE_WAYDISP*0,a0) # kill the tag
+
+mn10300_local_dcache_inv_range_skip_0:
+
+ # process the way 1 slot
+ mov (L1_CACHE_WAYDISP*1,a0),d0 # read the tag in the way 1 slot
+ btst L1_CACHE_TAG_VALID,d0
+ beq mn10300_local_dcache_inv_range_skip_1 # jump if this cacheline
+ # is not valid
+
+ xor a1,d0
+ lsr 12,d0
+ bne mn10300_local_dcache_inv_range_skip_1 # jump if not this cacheline
+
+ mov d2,(L1_CACHE_WAYDISP*1,a0) # kill the tag
+
+mn10300_local_dcache_inv_range_skip_1:
+
+ # process the way 2 slot
+ mov (L1_CACHE_WAYDISP*2,a0),d0 # read the tag in the way 2 slot
+ btst L1_CACHE_TAG_VALID,d0
+ beq mn10300_local_dcache_inv_range_skip_2 # jump if this cacheline
+ # is not valid
+
+ xor a1,d0
+ lsr 12,d0
+ bne mn10300_local_dcache_inv_range_skip_2 # jump if not this cacheline
+
+ mov d2,(L1_CACHE_WAYDISP*2,a0) # kill the tag
+
+mn10300_local_dcache_inv_range_skip_2:
+
+ # process the way 3 slot
+ mov (L1_CACHE_WAYDISP*3,a0),d0 # read the tag in the way 3 slot
+ btst L1_CACHE_TAG_VALID,d0
+ beq mn10300_local_dcache_inv_range_skip_3 # jump if this cacheline
+ # is not valid
+
+ xor a1,d0
+ lsr 12,d0
+ bne mn10300_local_dcache_inv_range_skip_3 # jump if not this cacheline
+
+ mov d2,(L1_CACHE_WAYDISP*3,a0) # kill the tag
+
+mn10300_local_dcache_inv_range_skip_3:
+
+ # approx every N steps we re-enable the cache and see if there are any
+ # interrupts to be processed
+ # we also break out if we've reached the end of the loop
+ # (the bottom nibble of the count is zero in both cases)
+ add L1_CACHE_BYTES,a0
+ add L1_CACHE_BYTES,a1
+ and ~L1_CACHE_WAYDISP,a0
+ add -1,d1
+ btst mn10300_local_dcache_inv_range_intr_interval,d1
+ bne mn10300_local_dcache_inv_range_loop
+
+ # wait for the cache to finish what it's doing
+ setlb
+ movhu (a2),d0
+ btst CHCTR_DCBUSY,d0
+ lne
+
+ # and reenable it
+ or CHCTR_DCEN,d0
+ movhu d0,(a2)
+ movhu (a2),d0
+
+ # re-enable interrupts
+ # - we don't bother with delay NOPs as we'll have enough instructions
+ # before we disable interrupts again to give the interrupts a chance
+ # to happen
+ LOCAL_IRQ_RESTORE(d3)
+
+ # go around again if the counter hasn't yet reached zero
+ add 0,d1
+ bne mn10300_local_dcache_inv_range_outer_loop
+
+mn10300_local_dcache_inv_range_end:
+ ret [d2,d3,a2],12
+ .size mn10300_local_dcache_inv_page,.-mn10300_local_dcache_inv_page
+ .size mn10300_local_dcache_inv_range,.-mn10300_local_dcache_inv_range
+ .size mn10300_local_dcache_inv_range2,.-mn10300_local_dcache_inv_range2
diff --git a/arch/mn10300/mm/cache-inv-icache.c b/arch/mn10300/mm/cache-inv-icache.c
new file mode 100644
index 000000000000..a8933a60b2d4
--- /dev/null
+++ b/arch/mn10300/mm/cache-inv-icache.c
@@ -0,0 +1,129 @@
+/* Invalidate icache when dcache doesn't need invalidation as it's in
+ * write-through mode
+ *
+ * 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.
+ */
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <asm/cacheflush.h>
+#include <asm/smp.h>
+#include "cache-smp.h"
+
+/**
+ * flush_icache_page_range - Flush dcache and invalidate icache for part of a
+ * single page
+ * @start: The starting virtual address of the page part.
+ * @end: The ending virtual address of the page part.
+ *
+ * Invalidate the icache for part of a single page, as determined by the
+ * virtual addresses given. The page must be in the paged area. The dcache is
+ * not flushed as the cache must be in write-through mode to get here.
+ */
+static void flush_icache_page_range(unsigned long start, unsigned long end)
+{
+ unsigned long addr, size, off;
+ struct page *page;
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *ppte, pte;
+
+ /* work out how much of the page to flush */
+ off = start & ~PAGE_MASK;
+ size = end - start;
+
+ /* get the physical address the page is mapped to from the page
+ * tables */
+ pgd = pgd_offset(current->mm, start);
+ if (!pgd || !pgd_val(*pgd))
+ return;
+
+ pud = pud_offset(pgd, start);
+ if (!pud || !pud_val(*pud))
+ return;
+
+ pmd = pmd_offset(pud, start);
+ if (!pmd || !pmd_val(*pmd))
+ return;
+
+ ppte = pte_offset_map(pmd, start);
+ if (!ppte)
+ return;
+ pte = *ppte;
+ pte_unmap(ppte);
+
+ if (pte_none(pte))
+ return;
+
+ page = pte_page(pte);
+ if (!page)
+ return;
+
+ addr = page_to_phys(page);
+
+ /* invalidate the icache coverage on that region */
+ mn10300_local_icache_inv_range2(addr + off, size);
+ smp_cache_call(SMP_ICACHE_INV_FLUSH_RANGE, start, end);
+}
+
+/**
+ * flush_icache_range - Globally flush dcache and invalidate icache for region
+ * @start: The starting virtual address of the region.
+ * @end: The ending virtual address of the region.
+ *
+ * This is used by the kernel to globally flush some code it has just written
+ * from the dcache back to RAM and then to globally invalidate the icache over
+ * that region so that that code can be run on all CPUs in the system.
+ */
+void flush_icache_range(unsigned long start, unsigned long end)
+{
+ unsigned long start_page, end_page;
+ unsigned long flags;
+
+ flags = smp_lock_cache();
+
+ if (end > 0x80000000UL) {
+ /* addresses above 0xa0000000 do not go through the cache */
+ if (end > 0xa0000000UL) {
+ end = 0xa0000000UL;
+ if (start >= end)
+ goto done;
+ }
+
+ /* kernel addresses between 0x80000000 and 0x9fffffff do not
+ * require page tables, so we just map such addresses
+ * directly */
+ start_page = (start >= 0x80000000UL) ? start : 0x80000000UL;
+ mn10300_icache_inv_range(start_page, end);
+ smp_cache_call(SMP_ICACHE_INV_FLUSH_RANGE, start, end);
+ if (start_page == start)
+ goto done;
+ end = start_page;
+ }
+
+ start_page = start & PAGE_MASK;
+ end_page = (end - 1) & PAGE_MASK;
+
+ if (start_page == end_page) {
+ /* the first and last bytes are on the same page */
+ flush_icache_page_range(start, end);
+ } else if (start_page + 1 == end_page) {
+ /* split over two virtually contiguous pages */
+ flush_icache_page_range(start, end_page);
+ flush_icache_page_range(end_page, end);
+ } else {
+ /* more than 2 pages; just flush the entire cache */
+ mn10300_local_icache_inv();
+ smp_cache_call(SMP_ICACHE_INV, 0, 0);
+ }
+
+done:
+ smp_unlock_cache(flags);
+}
+EXPORT_SYMBOL(flush_icache_range);
diff --git a/arch/mn10300/mm/cache-mn10300.S b/arch/mn10300/mm/cache-mn10300.S
deleted file mode 100644
index e839d0aedd69..000000000000
--- a/arch/mn10300/mm/cache-mn10300.S
+++ /dev/null
@@ -1,289 +0,0 @@
-/* MN10300 CPU core caching routines
- *
- * Copyright (C) 2007 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/sys.h>
-#include <linux/linkage.h>
-#include <asm/smp.h>
-#include <asm/page.h>
-#include <asm/cache.h>
-
-#define mn10300_dcache_inv_range_intr_interval \
- +((1 << MN10300_DCACHE_INV_RANGE_INTR_LOG2_INTERVAL) - 1)
-
-#if mn10300_dcache_inv_range_intr_interval > 0xff
-#error MN10300_DCACHE_INV_RANGE_INTR_LOG2_INTERVAL must be 8 or less
-#endif
-
- .am33_2
-
- .globl mn10300_icache_inv
- .globl mn10300_dcache_inv
- .globl mn10300_dcache_inv_range
- .globl mn10300_dcache_inv_range2
- .globl mn10300_dcache_inv_page
-
-###############################################################################
-#
-# void mn10300_icache_inv(void)
-# Invalidate the entire icache
-#
-###############################################################################
- ALIGN
-mn10300_icache_inv:
- mov CHCTR,a0
-
- movhu (a0),d0
- btst CHCTR_ICEN,d0
- beq mn10300_icache_inv_end
-
- mov epsw,d1
- and ~EPSW_IE,epsw
- nop
- nop
-
- # disable the icache
- and ~CHCTR_ICEN,d0
- movhu d0,(a0)
-
- # and wait for it to calm down
- setlb
- movhu (a0),d0
- btst CHCTR_ICBUSY,d0
- lne
-
- # invalidate
- or CHCTR_ICINV,d0
- movhu d0,(a0)
-
- # wait for the cache to finish
- mov CHCTR,a0
- setlb
- movhu (a0),d0
- btst CHCTR_ICBUSY,d0
- lne
-
- # and reenable it
- and ~CHCTR_ICINV,d0
- or CHCTR_ICEN,d0
- movhu d0,(a0)
- movhu (a0),d0
-
- mov d1,epsw
-
-mn10300_icache_inv_end:
- ret [],0
-
-###############################################################################
-#
-# void mn10300_dcache_inv(void)
-# Invalidate the entire dcache
-#
-###############################################################################
- ALIGN
-mn10300_dcache_inv:
- mov CHCTR,a0
-
- movhu (a0),d0
- btst CHCTR_DCEN,d0
- beq mn10300_dcache_inv_end
-
- mov epsw,d1
- and ~EPSW_IE,epsw
- nop
- nop
-
- # disable the dcache
- and ~CHCTR_DCEN,d0
- movhu d0,(a0)
-
- # and wait for it to calm down
- setlb
- movhu (a0),d0
- btst CHCTR_DCBUSY,d0
- lne
-
- # invalidate
- or CHCTR_DCINV,d0
- movhu d0,(a0)
-
- # wait for the cache to finish
- mov CHCTR,a0
- setlb
- movhu (a0),d0
- btst CHCTR_DCBUSY,d0
- lne
-
- # and reenable it
- and ~CHCTR_DCINV,d0
- or CHCTR_DCEN,d0
- movhu d0,(a0)
- movhu (a0),d0
-
- mov d1,epsw
-
-mn10300_dcache_inv_end:
- ret [],0
-
-###############################################################################
-#
-# void mn10300_dcache_inv_range(unsigned start, unsigned end)
-# void mn10300_dcache_inv_range2(unsigned start, unsigned size)
-# void mn10300_dcache_inv_page(unsigned start)
-# Invalidate a range of addresses on a page in the dcache
-#
-###############################################################################
- ALIGN
-mn10300_dcache_inv_page:
- mov PAGE_SIZE,d1
-mn10300_dcache_inv_range2:
- add d0,d1
-mn10300_dcache_inv_range:
- movm [d2,d3,a2],(sp)
- mov CHCTR,a2
-
- movhu (a2),d2
- btst CHCTR_DCEN,d2
- beq mn10300_dcache_inv_range_end
-
- and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 # round start
- # addr down
- mov d0,a1
-
- add L1_CACHE_BYTES,d1 # round end addr up
- and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d1
-
- clr d2 # we're going to clear tag ram
- # entries
-
- # read the tags from the tag RAM, and if they indicate a valid dirty
- # cache line then invalidate that line
- mov DCACHE_TAG(0,0),a0
- mov a1,d0
- and L1_CACHE_TAG_ENTRY,d0
- add d0,a0 # starting dcache tag RAM
- # access address
-
- sub a1,d1
- lsr L1_CACHE_SHIFT,d1 # total number of entries to
- # examine
-
- and ~(L1_CACHE_DISPARITY-1),a1 # determine comparator base
-
-mn10300_dcache_inv_range_outer_loop:
- # disable interrupts
- mov epsw,d3
- and ~EPSW_IE,epsw
- nop # note that reading CHCTR and
- # AND'ing D0 occupy two delay
- # slots after disabling
- # interrupts
-
- # disable the dcache
- movhu (a2),d0
- and ~CHCTR_DCEN,d0
- movhu d0,(a2)
-
- # and wait for it to calm down
- setlb
- movhu (a2),d0
- btst CHCTR_DCBUSY,d0
- lne
-
-mn10300_dcache_inv_range_loop:
-
- # process the way 0 slot
- mov (L1_CACHE_WAYDISP*0,a0),d0 # read the tag in the way 0 slot
- btst L1_CACHE_TAG_VALID,d0
- beq mn10300_dcache_inv_range_skip_0 # jump if this cacheline is not
- # valid
-
- xor a1,d0
- lsr 12,d0
- bne mn10300_dcache_inv_range_skip_0 # jump if not this cacheline
-
- mov d2,(a0) # kill the tag
-
-mn10300_dcache_inv_range_skip_0:
-
- # process the way 1 slot
- mov (L1_CACHE_WAYDISP*1,a0),d0 # read the tag in the way 1 slot
- btst L1_CACHE_TAG_VALID,d0
- beq mn10300_dcache_inv_range_skip_1 # jump if this cacheline is not
- # valid
-
- xor a1,d0
- lsr 12,d0
- bne mn10300_dcache_inv_range_skip_1 # jump if not this cacheline
-
- mov d2,(a0) # kill the tag
-
-mn10300_dcache_inv_range_skip_1:
-
- # process the way 2 slot
- mov (L1_CACHE_WAYDISP*2,a0),d0 # read the tag in the way 2 slot
- btst L1_CACHE_TAG_VALID,d0
- beq mn10300_dcache_inv_range_skip_2 # jump if this cacheline is not
- # valid
-
- xor a1,d0
- lsr 12,d0
- bne mn10300_dcache_inv_range_skip_2 # jump if not this cacheline
-
- mov d2,(a0) # kill the tag
-
-mn10300_dcache_inv_range_skip_2:
-
- # process the way 3 slot
- mov (L1_CACHE_WAYDISP*3,a0),d0 # read the tag in the way 3 slot
- btst L1_CACHE_TAG_VALID,d0
- beq mn10300_dcache_inv_range_skip_3 # jump if this cacheline is not
- # valid
-
- xor a1,d0
- lsr 12,d0
- bne mn10300_dcache_inv_range_skip_3 # jump if not this cacheline
-
- mov d2,(a0) # kill the tag
-
-mn10300_dcache_inv_range_skip_3:
-
- # approx every N steps we re-enable the cache and see if there are any
- # interrupts to be processed
- # we also break out if we've reached the end of the loop
- # (the bottom nibble of the count is zero in both cases)
- add L1_CACHE_BYTES,a0
- add L1_CACHE_BYTES,a1
- add -1,d1
- btst mn10300_dcache_inv_range_intr_interval,d1
- bne mn10300_dcache_inv_range_loop
-
- # wait for the cache to finish what it's doing
- setlb
- movhu (a2),d0
- btst CHCTR_DCBUSY,d0
- lne
-
- # and reenable it
- or CHCTR_DCEN,d0
- movhu d0,(a2)
- movhu (a2),d0
-
- # re-enable interrupts
- # - we don't bother with delay NOPs as we'll have enough instructions
- # before we disable interrupts again to give the interrupts a chance
- # to happen
- mov d3,epsw
-
- # go around again if the counter hasn't yet reached zero
- add 0,d1
- bne mn10300_dcache_inv_range_outer_loop
-
-mn10300_dcache_inv_range_end:
- ret [d2,d3,a2],12
diff --git a/arch/mn10300/mm/cache-smp-flush.c b/arch/mn10300/mm/cache-smp-flush.c
new file mode 100644
index 000000000000..fd51af5eaf70
--- /dev/null
+++ b/arch/mn10300/mm/cache-smp-flush.c
@@ -0,0 +1,156 @@
+/* Functions for global dcache flush when writeback caching in SMP
+ *
+ * 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.
+ */
+#include <linux/mm.h>
+#include <asm/cacheflush.h>
+#include "cache-smp.h"
+
+/**
+ * mn10300_dcache_flush - Globally flush data cache
+ *
+ * Flush the data cache on all CPUs.
+ */
+void mn10300_dcache_flush(void)
+{
+ unsigned long flags;
+
+ flags = smp_lock_cache();
+ mn10300_local_dcache_flush();
+ smp_cache_call(SMP_DCACHE_FLUSH, 0, 0);
+ smp_unlock_cache(flags);
+}
+
+/**
+ * mn10300_dcache_flush_page - Globally flush a page of data cache
+ * @start: The address of the page of memory to be flushed.
+ *
+ * Flush a range of addresses in the data cache on all CPUs covering
+ * the page that includes the given address.
+ */
+void mn10300_dcache_flush_page(unsigned long start)
+{
+ unsigned long flags;
+
+ start &= ~(PAGE_SIZE-1);
+
+ flags = smp_lock_cache();
+ mn10300_local_dcache_flush_page(start);
+ smp_cache_call(SMP_DCACHE_FLUSH_RANGE, start, start + PAGE_SIZE);
+ smp_unlock_cache(flags);
+}
+
+/**
+ * mn10300_dcache_flush_range - Globally flush range of data cache
+ * @start: The start address of the region to be flushed.
+ * @end: The end address of the region to be flushed.
+ *
+ * Flush a range of addresses in the data cache on all CPUs, between start and
+ * end-1 inclusive.
+ */
+void mn10300_dcache_flush_range(unsigned long start, unsigned long end)
+{
+ unsigned long flags;
+
+ flags = smp_lock_cache();
+ mn10300_local_dcache_flush_range(start, end);
+ smp_cache_call(SMP_DCACHE_FLUSH_RANGE, start, end);
+ smp_unlock_cache(flags);
+}
+
+/**
+ * mn10300_dcache_flush_range2 - Globally flush range of data cache
+ * @start: The start address of the region to be flushed.
+ * @size: The size of the region to be flushed.
+ *
+ * Flush a range of addresses in the data cache on all CPUs, between start and
+ * start+size-1 inclusive.
+ */
+void mn10300_dcache_flush_range2(unsigned long start, unsigned long size)
+{
+ unsigned long flags;
+
+ flags = smp_lock_cache();
+ mn10300_local_dcache_flush_range2(start, size);
+ smp_cache_call(SMP_DCACHE_FLUSH_RANGE, start, start + size);
+ smp_unlock_cache(flags);
+}
+
+/**
+ * mn10300_dcache_flush_inv - Globally flush and invalidate data cache
+ *
+ * Flush and invalidate the data cache on all CPUs.
+ */
+void mn10300_dcache_flush_inv(void)
+{
+ unsigned long flags;
+
+ flags = smp_lock_cache();
+ mn10300_local_dcache_flush_inv();
+ smp_cache_call(SMP_DCACHE_FLUSH_INV, 0, 0);
+ smp_unlock_cache(flags);
+}
+
+/**
+ * mn10300_dcache_flush_inv_page - Globally flush and invalidate a page of data
+ * cache
+ * @start: The address of the page of memory to be flushed and invalidated.
+ *
+ * Flush and invalidate a range of addresses in the data cache on all CPUs
+ * covering the page that includes the given address.
+ */
+void mn10300_dcache_flush_inv_page(unsigned long start)
+{
+ unsigned long flags;
+
+ start &= ~(PAGE_SIZE-1);
+
+ flags = smp_lock_cache();
+ mn10300_local_dcache_flush_inv_page(start);
+ smp_cache_call(SMP_DCACHE_FLUSH_INV_RANGE, start, start + PAGE_SIZE);
+ smp_unlock_cache(flags);
+}
+
+/**
+ * mn10300_dcache_flush_inv_range - Globally flush and invalidate range of data
+ * cache
+ * @start: The start address of the region to be flushed and invalidated.
+ * @end: The end address of the region to be flushed and invalidated.
+ *
+ * Flush and invalidate a range of addresses in the data cache on all CPUs,
+ * between start and end-1 inclusive.
+ */
+void mn10300_dcache_flush_inv_range(unsigned long start, unsigned long end)
+{
+ unsigned long flags;
+
+ flags = smp_lock_cache();
+ mn10300_local_dcache_flush_inv_range(start, end);
+ smp_cache_call(SMP_DCACHE_FLUSH_INV_RANGE, start, end);
+ smp_unlock_cache(flags);
+}
+
+/**
+ * mn10300_dcache_flush_inv_range2 - Globally flush and invalidate range of data
+ * cache
+ * @start: The start address of the region to be flushed and invalidated.
+ * @size: The size of the region to be flushed and invalidated.
+ *
+ * Flush and invalidate a range of addresses in the data cache on all CPUs,
+ * between start and start+size-1 inclusive.
+ */
+void mn10300_dcache_flush_inv_range2(unsigned long start, unsigned long size)
+{
+ unsigned long flags;
+
+ flags = smp_lock_cache();
+ mn10300_local_dcache_flush_inv_range2(start, size);
+ smp_cache_call(SMP_DCACHE_FLUSH_INV_RANGE, start, start + size);
+ smp_unlock_cache(flags);
+}
diff --git a/arch/mn10300/mm/cache-smp-inv.c b/arch/mn10300/mm/cache-smp-inv.c
new file mode 100644
index 000000000000..ff1787358c8e
--- /dev/null
+++ b/arch/mn10300/mm/cache-smp-inv.c
@@ -0,0 +1,153 @@
+/* Functions for global i/dcache invalidation when caching in SMP
+ *
+ * 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.
+ */
+#include <linux/mm.h>
+#include <asm/cacheflush.h>
+#include "cache-smp.h"
+
+/**
+ * mn10300_icache_inv - Globally invalidate instruction cache
+ *
+ * Invalidate the instruction cache on all CPUs.
+ */
+void mn10300_icache_inv(void)
+{
+ unsigned long flags;
+
+ flags = smp_lock_cache();
+ mn10300_local_icache_inv();
+ smp_cache_call(SMP_ICACHE_INV, 0, 0);
+ smp_unlock_cache(flags);
+}
+
+/**
+ * mn10300_icache_inv_page - Globally invalidate a page of instruction cache
+ * @start: The address of the page of memory to be invalidated.
+ *
+ * Invalidate a range of addresses in the instruction cache on all CPUs
+ * covering the page that includes the given address.
+ */
+void mn10300_icache_inv_page(unsigned long start)
+{
+ unsigned long flags;
+
+ start &= ~(PAGE_SIZE-1);
+
+ flags = smp_lock_cache();
+ mn10300_local_icache_inv_page(start);
+ smp_cache_call(SMP_ICACHE_INV_RANGE, start, start + PAGE_SIZE);
+ smp_unlock_cache(flags);
+}
+
+/**
+ * mn10300_icache_inv_range - Globally invalidate range of instruction cache
+ * @start: The start address of the region to be invalidated.
+ * @end: The end address of the region to be invalidated.
+ *
+ * Invalidate a range of addresses in the instruction cache on all CPUs,
+ * between start and end-1 inclusive.
+ */
+void mn10300_icache_inv_range(unsigned long start, unsigned long end)
+{
+ unsigned long flags;
+
+ flags = smp_lock_cache();
+ mn10300_local_icache_inv_range(start, end);
+ smp_cache_call(SMP_ICACHE_INV_RANGE, start, end);
+ smp_unlock_cache(flags);
+}
+
+/**
+ * mn10300_icache_inv_range2 - Globally invalidate range of instruction cache
+ * @start: The start address of the region to be invalidated.
+ * @size: The size of the region to be invalidated.
+ *
+ * Invalidate a range of addresses in the instruction cache on all CPUs,
+ * between start and start+size-1 inclusive.
+ */
+void mn10300_icache_inv_range2(unsigned long start, unsigned long size)
+{
+ unsigned long flags;
+
+ flags = smp_lock_cache();
+ mn10300_local_icache_inv_range2(start, size);
+ smp_cache_call(SMP_ICACHE_INV_RANGE, start, start + size);
+ smp_unlock_cache(flags);
+}
+
+/**
+ * mn10300_dcache_inv - Globally invalidate data cache
+ *
+ * Invalidate the data cache on all CPUs.
+ */
+void mn10300_dcache_inv(void)
+{
+ unsigned long flags;
+
+ flags = smp_lock_cache();
+ mn10300_local_dcache_inv();
+ smp_cache_call(SMP_DCACHE_INV, 0, 0);
+ smp_unlock_cache(flags);
+}
+
+/**
+ * mn10300_dcache_inv_page - Globally invalidate a page of data cache
+ * @start: The address of the page of memory to be invalidated.
+ *
+ * Invalidate a range of addresses in the data cache on all CPUs covering the
+ * page that includes the given address.
+ */
+void mn10300_dcache_inv_page(unsigned long start)
+{
+ unsigned long flags;
+
+ start &= ~(PAGE_SIZE-1);
+
+ flags = smp_lock_cache();
+ mn10300_local_dcache_inv_page(start);
+ smp_cache_call(SMP_DCACHE_INV_RANGE, start, start + PAGE_SIZE);
+ smp_unlock_cache(flags);
+}
+
+/**
+ * mn10300_dcache_inv_range - Globally invalidate range of data cache
+ * @start: The start address of the region to be invalidated.
+ * @end: The end address of the region to be invalidated.
+ *
+ * Invalidate a range of addresses in the data cache on all CPUs, between start
+ * and end-1 inclusive.
+ */
+void mn10300_dcache_inv_range(unsigned long start, unsigned long end)
+{
+ unsigned long flags;
+
+ flags = smp_lock_cache();
+ mn10300_local_dcache_inv_range(start, end);
+ smp_cache_call(SMP_DCACHE_INV_RANGE, start, end);
+ smp_unlock_cache(flags);
+}
+
+/**
+ * mn10300_dcache_inv_range2 - Globally invalidate range of data cache
+ * @start: The start address of the region to be invalidated.
+ * @size: The size of the region to be invalidated.
+ *
+ * Invalidate a range of addresses in the data cache on all CPUs, between start
+ * and start+size-1 inclusive.
+ */
+void mn10300_dcache_inv_range2(unsigned long start, unsigned long size)
+{
+ unsigned long flags;
+
+ flags = smp_lock_cache();
+ mn10300_local_dcache_inv_range2(start, size);
+ smp_cache_call(SMP_DCACHE_INV_RANGE, start, start + size);
+ smp_unlock_cache(flags);
+}
diff --git a/arch/mn10300/mm/cache-smp.c b/arch/mn10300/mm/cache-smp.c
new file mode 100644
index 000000000000..4a6e9a4b5b27
--- /dev/null
+++ b/arch/mn10300/mm/cache-smp.c
@@ -0,0 +1,105 @@
+/* SMP global caching code
+ *
+ * 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.
+ */
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/threads.h>
+#include <linux/interrupt.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/cacheflush.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/smp.h>
+#include "cache-smp.h"
+
+DEFINE_SPINLOCK(smp_cache_lock);
+static unsigned long smp_cache_mask;
+static unsigned long smp_cache_start;
+static unsigned long smp_cache_end;
+static cpumask_t smp_cache_ipi_map; /* Bitmask of cache IPI done CPUs */
+
+/**
+ * smp_cache_interrupt - Handle IPI request to flush caches.
+ *
+ * Handle a request delivered by IPI to flush the current CPU's
+ * caches. The parameters are stored in smp_cache_*.
+ */
+void smp_cache_interrupt(void)
+{
+ unsigned long opr_mask = smp_cache_mask;
+
+ switch ((enum smp_dcache_ops)(opr_mask & SMP_DCACHE_OP_MASK)) {
+ case SMP_DCACHE_NOP:
+ break;
+ case SMP_DCACHE_INV:
+ mn10300_local_dcache_inv();
+ break;
+ case SMP_DCACHE_INV_RANGE:
+ mn10300_local_dcache_inv_range(smp_cache_start, smp_cache_end);
+ break;
+ case SMP_DCACHE_FLUSH:
+ mn10300_local_dcache_flush();
+ break;
+ case SMP_DCACHE_FLUSH_RANGE:
+ mn10300_local_dcache_flush_range(smp_cache_start,
+ smp_cache_end);
+ break;
+ case SMP_DCACHE_FLUSH_INV:
+ mn10300_local_dcache_flush_inv();
+ break;
+ case SMP_DCACHE_FLUSH_INV_RANGE:
+ mn10300_local_dcache_flush_inv_range(smp_cache_start,
+ smp_cache_end);
+ break;
+ }
+
+ switch ((enum smp_icache_ops)(opr_mask & SMP_ICACHE_OP_MASK)) {
+ case SMP_ICACHE_NOP:
+ break;
+ case SMP_ICACHE_INV:
+ mn10300_local_icache_inv();
+ break;
+ case SMP_ICACHE_INV_RANGE:
+ mn10300_local_icache_inv_range(smp_cache_start, smp_cache_end);
+ break;
+ }
+
+ cpu_clear(smp_processor_id(), smp_cache_ipi_map);
+}
+
+/**
+ * smp_cache_call - Issue an IPI to request the other CPUs flush caches
+ * @opr_mask: Cache operation flags
+ * @start: Start address of request
+ * @end: End address of request
+ *
+ * Send cache flush IPI to other CPUs. This invokes smp_cache_interrupt()
+ * above on those other CPUs and then waits for them to finish.
+ *
+ * The caller must hold smp_cache_lock.
+ */
+void smp_cache_call(unsigned long opr_mask,
+ unsigned long start, unsigned long end)
+{
+ smp_cache_mask = opr_mask;
+ smp_cache_start = start;
+ smp_cache_end = end;
+ smp_cache_ipi_map = cpu_online_map;
+ cpu_clear(smp_processor_id(), smp_cache_ipi_map);
+
+ send_IPI_allbutself(FLUSH_CACHE_IPI);
+
+ while (!cpus_empty(smp_cache_ipi_map))
+ /* nothing. lockup detection does not belong here */
+ mb();
+}
diff --git a/arch/mn10300/mm/cache-smp.h b/arch/mn10300/mm/cache-smp.h
new file mode 100644
index 000000000000..cb52892aa66a
--- /dev/null
+++ b/arch/mn10300/mm/cache-smp.h
@@ -0,0 +1,69 @@
+/* SMP caching definitions
+ *
+ * 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.
+ */
+
+
+/*
+ * Operation requests for smp_cache_call().
+ *
+ * One of smp_icache_ops and one of smp_dcache_ops can be OR'd together.
+ */
+enum smp_icache_ops {
+ SMP_ICACHE_NOP = 0x0000,
+ SMP_ICACHE_INV = 0x0001,
+ SMP_ICACHE_INV_RANGE = 0x0002,
+};
+#define SMP_ICACHE_OP_MASK 0x0003
+
+enum smp_dcache_ops {
+ SMP_DCACHE_NOP = 0x0000,
+ SMP_DCACHE_INV = 0x0004,
+ SMP_DCACHE_INV_RANGE = 0x0008,
+ SMP_DCACHE_FLUSH = 0x000c,
+ SMP_DCACHE_FLUSH_RANGE = 0x0010,
+ SMP_DCACHE_FLUSH_INV = 0x0014,
+ SMP_DCACHE_FLUSH_INV_RANGE = 0x0018,
+};
+#define SMP_DCACHE_OP_MASK 0x001c
+
+#define SMP_IDCACHE_INV_FLUSH (SMP_ICACHE_INV | SMP_DCACHE_FLUSH)
+#define SMP_IDCACHE_INV_FLUSH_RANGE (SMP_ICACHE_INV_RANGE | SMP_DCACHE_FLUSH_RANGE)
+
+/*
+ * cache-smp.c
+ */
+#ifdef CONFIG_SMP
+extern spinlock_t smp_cache_lock;
+
+extern void smp_cache_call(unsigned long opr_mask,
+ unsigned long addr, unsigned long end);
+
+static inline unsigned long smp_lock_cache(void)
+ __acquires(&smp_cache_lock)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&smp_cache_lock, flags);
+ return flags;
+}
+
+static inline void smp_unlock_cache(unsigned long flags)
+ __releases(&smp_cache_lock)
+{
+ spin_unlock_irqrestore(&smp_cache_lock, flags);
+}
+
+#else
+static inline unsigned long smp_lock_cache(void) { return 0; }
+static inline void smp_unlock_cache(unsigned long flags) {}
+static inline void smp_cache_call(unsigned long opr_mask,
+ unsigned long addr, unsigned long end)
+{
+}
+#endif /* CONFIG_SMP */
diff --git a/arch/mn10300/mm/cache.c b/arch/mn10300/mm/cache.c
index 9261217e8d2c..0a1f0aa92ebc 100644
--- a/arch/mn10300/mm/cache.c
+++ b/arch/mn10300/mm/cache.c
@@ -18,8 +18,13 @@
#include <asm/cacheflush.h>
#include <asm/io.h>
#include <asm/uaccess.h>
+#include <asm/smp.h>
+#include "cache-smp.h"
EXPORT_SYMBOL(mn10300_icache_inv);
+EXPORT_SYMBOL(mn10300_icache_inv_range);
+EXPORT_SYMBOL(mn10300_icache_inv_range2);
+EXPORT_SYMBOL(mn10300_icache_inv_page);
EXPORT_SYMBOL(mn10300_dcache_inv);
EXPORT_SYMBOL(mn10300_dcache_inv_range);
EXPORT_SYMBOL(mn10300_dcache_inv_range2);
@@ -37,96 +42,6 @@ EXPORT_SYMBOL(mn10300_dcache_flush_page);
#endif
/*
- * write a page back from the dcache and invalidate the icache so that we can
- * run code from it that we've just written into it
- */
-void flush_icache_page(struct vm_area_struct *vma, struct page *page)
-{
- mn10300_dcache_flush_page(page_to_phys(page));
- mn10300_icache_inv();
-}
-EXPORT_SYMBOL(flush_icache_page);
-
-/*
- * write some code we've just written back from the dcache and invalidate the
- * icache so that we can run that code
- */
-void flush_icache_range(unsigned long start, unsigned long end)
-{
-#ifdef CONFIG_MN10300_CACHE_WBACK
- 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);
-
- size = end - start;
- if (size > PAGE_SIZE - off)
- size = PAGE_SIZE - off;
-
- /* get the physical address the page is mapped to from the page
- * tables */
- pgd = pgd_offset(current->mm, start);
- if (!pgd || !pgd_val(*pgd))
- continue;
-
- pud = pud_offset(pgd, start);
- if (!pud || !pud_val(*pud))
- continue;
-
- pmd = pmd_offset(pud, start);
- if (!pmd || !pmd_val(*pmd))
- continue;
-
- ppte = pte_offset_map(pmd, start);
- if (!ppte)
- continue;
- pte = *ppte;
- pte_unmap(ppte);
-
- if (pte_none(pte))
- continue;
-
- page = pte_page(pte);
- if (!page)
- continue;
-
- addr = page_to_phys(page);
-
- /* flush the dcache and invalidate the icache coverage on that
- * region */
- mn10300_dcache_flush_range2(addr + off, size);
- }
-#endif
-
-invalidate:
- mn10300_icache_inv();
-}
-EXPORT_SYMBOL(flush_icache_range);
-
-/*
* allow userspace to flush the instruction cache
*/
asmlinkage long sys_cacheflush(unsigned long start, unsigned long end)
diff --git a/arch/mn10300/mm/fault.c b/arch/mn10300/mm/fault.c
index 81f153fa51b4..59c3da49d9d9 100644
--- a/arch/mn10300/mm/fault.c
+++ b/arch/mn10300/mm/fault.c
@@ -39,10 +39,6 @@ void bust_spinlocks(int yes)
{
if (yes) {
oops_in_progress = 1;
-#ifdef CONFIG_SMP
- /* Many serial drivers do __global_cli() */
- global_irq_lock = 0;
-#endif
} else {
int loglevel_save = console_loglevel;
#ifdef CONFIG_VT
@@ -100,8 +96,6 @@ static void print_pagetable_entries(pgd_t *pgdir, unsigned long address)
}
#endif
-asmlinkage void monitor_signal(struct pt_regs *);
-
/*
* This routine handles page faults. It determines the address,
* and the problem, and then passes it off to one of the appropriate
@@ -279,7 +273,6 @@ good_area:
*/
bad_area:
up_read(&mm->mmap_sem);
- monitor_signal(regs);
/* User mode accesses just cause a SIGSEGV */
if ((fault_code & MMUFCR_xFC_ACCESS) == MMUFCR_xFC_ACCESS_USR) {
@@ -292,7 +285,6 @@ bad_area:
}
no_context:
- monitor_signal(regs);
/* Are we prepared to handle this kernel fault? */
if (fixup_exception(regs))
return;
@@ -338,14 +330,13 @@ no_context:
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if ((fault_code & MMUFCR_xFC_ACCESS) != MMUFCR_xFC_ACCESS_USR)
- goto no_context;
- pagefault_out_of_memory();
- return;
+ printk(KERN_ALERT "VM: killing process %s\n", tsk->comm);
+ if ((fault_code & MMUFCR_xFC_ACCESS) == MMUFCR_xFC_ACCESS_USR)
+ do_exit(SIGKILL);
+ goto no_context;
do_sigbus:
up_read(&mm->mmap_sem);
- monitor_signal(regs);
/*
* Send a sigbus, regardless of whether we were in kernel
diff --git a/arch/mn10300/mm/init.c b/arch/mn10300/mm/init.c
index 6e6bc0e51521..48907cc3bdb7 100644
--- a/arch/mn10300/mm/init.c
+++ b/arch/mn10300/mm/init.c
@@ -41,6 +41,10 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
unsigned long highstart_pfn, highend_pfn;
+#ifdef CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT
+static struct vm_struct user_iomap_vm;
+#endif
+
/*
* set up paging
*/
@@ -73,7 +77,24 @@ void __init paging_init(void)
/* pass the memory from the bootmem allocator to the main allocator */
free_area_init(zones_size);
- __flush_tlb_all();
+#ifdef CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT
+ /* The Atomic Operation Unit registers need to be mapped to userspace
+ * for all processes. The following uses vm_area_register_early() to
+ * reserve the first page of the vmalloc area and sets the pte for that
+ * page.
+ *
+ * glibc hardcodes this virtual mapping, so we're pretty much stuck with
+ * it from now on.
+ */
+ user_iomap_vm.flags = VM_USERMAP;
+ user_iomap_vm.size = 1 << PAGE_SHIFT;
+ vm_area_register_early(&user_iomap_vm, PAGE_SIZE);
+ ppte = kernel_vmalloc_ptes;
+ set_pte(ppte, pfn_pte(USER_ATOMIC_OPS_PAGE_ADDR >> PAGE_SHIFT,
+ PAGE_USERIO));
+#endif
+
+ local_flush_tlb_all();
}
/*
@@ -84,8 +105,7 @@ void __init mem_init(void)
int codesize, reservedpages, datasize, initsize;
int tmp;
- if (!mem_map)
- BUG();
+ BUG_ON(!mem_map);
#define START_PFN (contig_page_data.bdata->node_min_pfn)
#define MAX_LOW_PFN (contig_page_data.bdata->node_low_pfn)
diff --git a/arch/mn10300/mm/misalignment.c b/arch/mn10300/mm/misalignment.c
index 6dffbf97ac26..eef989c1d0c1 100644
--- a/arch/mn10300/mm/misalignment.c
+++ b/arch/mn10300/mm/misalignment.c
@@ -449,8 +449,7 @@ found_opcode:
regs->pc, opcode, pop->opcode, pop->params[0], pop->params[1]);
tmp = format_tbl[pop->format].opsz;
- if (tmp > noc)
- BUG(); /* match was less complete than it ought to have been */
+ BUG_ON(tmp > noc); /* match was less complete than it ought to have been */
if (tmp < noc) {
tmp = noc - tmp;
diff --git a/arch/mn10300/mm/mmu-context.c b/arch/mn10300/mm/mmu-context.c
index 36ba02191d40..a4f7d3dcc6e6 100644
--- a/arch/mn10300/mm/mmu-context.c
+++ b/arch/mn10300/mm/mmu-context.c
@@ -13,40 +13,15 @@
#include <asm/mmu_context.h>
#include <asm/tlbflush.h>
+#ifdef CONFIG_MN10300_TLB_USE_PIDR
/*
* list of the MMU contexts last allocated on each CPU
*/
unsigned long mmu_context_cache[NR_CPUS] = {
- [0 ... NR_CPUS - 1] = MMU_CONTEXT_FIRST_VERSION * 2 - 1,
+ [0 ... NR_CPUS - 1] =
+ MMU_CONTEXT_FIRST_VERSION * 2 - (1 - MMU_CONTEXT_TLBPID_LOCK_NR),
};
-
-/*
- * flush the specified TLB entry
- */
-void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
-{
- unsigned long pteu, cnx, flags;
-
- addr &= PAGE_MASK;
-
- /* make sure the context doesn't migrate and defend against
- * interference from vmalloc'd regions */
- local_irq_save(flags);
-
- cnx = mm_context(vma->vm_mm);
-
- if (cnx != MMU_NO_CONTEXT) {
- pteu = addr | (cnx & 0x000000ffUL);
- IPTEU = pteu;
- DPTEU = pteu;
- if (IPTEL & xPTEL_V)
- IPTEL = 0;
- if (DPTEL & xPTEL_V)
- DPTEL = 0;
- }
-
- local_irq_restore(flags);
-}
+#endif /* CONFIG_MN10300_TLB_USE_PIDR */
/*
* preemptively set a TLB entry
@@ -63,10 +38,16 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t *pte
* interference from vmalloc'd regions */
local_irq_save(flags);
+ cnx = ~MMU_NO_CONTEXT;
+#ifdef CONFIG_MN10300_TLB_USE_PIDR
cnx = mm_context(vma->vm_mm);
+#endif
if (cnx != MMU_NO_CONTEXT) {
- pteu = addr | (cnx & 0x000000ffUL);
+ pteu = addr;
+#ifdef CONFIG_MN10300_TLB_USE_PIDR
+ pteu |= cnx & MMU_CONTEXT_TLBPID_MASK;
+#endif
if (!(pte_val(pte) & _PAGE_NX)) {
IPTEU = pteu;
if (IPTEL & xPTEL_V)
diff --git a/arch/mn10300/mm/pgtable.c b/arch/mn10300/mm/pgtable.c
index 9c1624c9e4e9..450f7ba3f8f2 100644
--- a/arch/mn10300/mm/pgtable.c
+++ b/arch/mn10300/mm/pgtable.c
@@ -59,7 +59,7 @@ void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags)
* It's enough to flush this one mapping.
* (PGE mappings get flushed as well)
*/
- __flush_tlb_one(vaddr);
+ local_flush_tlb_one(vaddr);
}
pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
diff --git a/arch/mn10300/mm/tlb-mn10300.S b/arch/mn10300/mm/tlb-mn10300.S
index 7095147dcb8b..b9940177d81b 100644
--- a/arch/mn10300/mm/tlb-mn10300.S
+++ b/arch/mn10300/mm/tlb-mn10300.S
@@ -27,7 +27,6 @@
###############################################################################
.type itlb_miss,@function
ENTRY(itlb_miss)
- and ~EPSW_NMID,epsw
#ifdef CONFIG_GDBSTUB
movm [d2,d3,a2],(sp)
#else
@@ -38,6 +37,12 @@ ENTRY(itlb_miss)
nop
#endif
+#if defined(CONFIG_ERRATUM_NEED_TO_RELOAD_MMUCTR)
+ mov (MMUCTR),d2
+ mov d2,(MMUCTR)
+#endif
+
+ and ~EPSW_NMID,epsw
mov (IPTEU),d3
mov (PTBR),a2
mov d3,d2
@@ -56,10 +61,16 @@ ENTRY(itlb_miss)
btst _PAGE_VALID,d2
beq itlb_miss_fault # jump if doesn't point to a page
# (might be a swap id)
+#if ((_PAGE_ACCESSED & 0xffffff00) == 0)
bset _PAGE_ACCESSED,(0,a2)
- and ~(xPTEL_UNUSED1|xPTEL_UNUSED2),d2
+#elif ((_PAGE_ACCESSED & 0xffff00ff) == 0)
+ bset +(_PAGE_ACCESSED >> 8),(1,a2)
+#else
+#error "_PAGE_ACCESSED value is out of range"
+#endif
+ and ~xPTEL2_UNUSED1,d2
itlb_miss_set:
- mov d2,(IPTEL) # change the TLB
+ mov d2,(IPTEL2) # change the TLB
#ifdef CONFIG_GDBSTUB
movm (sp),[d2,d3,a2]
#endif
@@ -79,7 +90,6 @@ itlb_miss_fault:
###############################################################################
.type dtlb_miss,@function
ENTRY(dtlb_miss)
- and ~EPSW_NMID,epsw
#ifdef CONFIG_GDBSTUB
movm [d2,d3,a2],(sp)
#else
@@ -90,6 +100,12 @@ ENTRY(dtlb_miss)
nop
#endif
+#if defined(CONFIG_ERRATUM_NEED_TO_RELOAD_MMUCTR)
+ mov (MMUCTR),d2
+ mov d2,(MMUCTR)
+#endif
+
+ and ~EPSW_NMID,epsw
mov (DPTEU),d3
mov (PTBR),a2
mov d3,d2
@@ -108,10 +124,16 @@ ENTRY(dtlb_miss)
btst _PAGE_VALID,d2
beq dtlb_miss_fault # jump if doesn't point to a page
# (might be a swap id)
+#if ((_PAGE_ACCESSED & 0xffffff00) == 0)
bset _PAGE_ACCESSED,(0,a2)
- and ~(xPTEL_UNUSED1|xPTEL_UNUSED2),d2
+#elif ((_PAGE_ACCESSED & 0xffff00ff) == 0)
+ bset +(_PAGE_ACCESSED >> 8),(1,a2)
+#else
+#error "_PAGE_ACCESSED value is out of range"
+#endif
+ and ~xPTEL2_UNUSED1,d2
dtlb_miss_set:
- mov d2,(DPTEL) # change the TLB
+ mov d2,(DPTEL2) # change the TLB
#ifdef CONFIG_GDBSTUB
movm (sp),[d2,d3,a2]
#endif
@@ -130,9 +152,15 @@ dtlb_miss_fault:
###############################################################################
.type itlb_aerror,@function
ENTRY(itlb_aerror)
- and ~EPSW_NMID,epsw
add -4,sp
SAVE_ALL
+
+#if defined(CONFIG_ERRATUM_NEED_TO_RELOAD_MMUCTR)
+ mov (MMUCTR),d1
+ mov d1,(MMUCTR)
+#endif
+
+ and ~EPSW_NMID,epsw
add -4,sp # need to pass three params
# calculate the fault code
@@ -140,15 +168,13 @@ ENTRY(itlb_aerror)
or 0x00010000,d1 # it's an instruction fetch
# determine the page address
- mov (IPTEU),a2
- mov a2,d0
+ mov (IPTEU),d0
and PAGE_MASK,d0
mov d0,(12,sp)
clr d0
- mov d0,(IPTEL)
+ mov d0,(IPTEL2)
- and ~EPSW_NMID,epsw
or EPSW_IE,epsw
mov fp,d0
call do_page_fault[],0 # do_page_fault(regs,code,addr
@@ -163,10 +189,16 @@ ENTRY(itlb_aerror)
###############################################################################
.type dtlb_aerror,@function
ENTRY(dtlb_aerror)
- and ~EPSW_NMID,epsw
add -4,sp
SAVE_ALL
+
+#if defined(CONFIG_ERRATUM_NEED_TO_RELOAD_MMUCTR)
+ mov (MMUCTR),d1
+ mov d1,(MMUCTR)
+#endif
+
add -4,sp # need to pass three params
+ and ~EPSW_NMID,epsw
# calculate the fault code
movhu (MMUFCR_DFC),d1
@@ -178,9 +210,8 @@ ENTRY(dtlb_aerror)
mov d0,(12,sp)
clr d0
- mov d0,(DPTEL)
+ mov d0,(DPTEL2)
- and ~EPSW_NMID,epsw
or EPSW_IE,epsw
mov fp,d0
call do_page_fault[],0 # do_page_fault(regs,code,addr
diff --git a/arch/mn10300/mm/tlb-smp.c b/arch/mn10300/mm/tlb-smp.c
new file mode 100644
index 000000000000..0b6a5ad1960e
--- /dev/null
+++ b/arch/mn10300/mm/tlb-smp.c
@@ -0,0 +1,214 @@
+/* SMP TLB support routines.
+ *
+ * Copyright (C) 2006-2008 Panasonic Corporation
+ * 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.
+ *
+ * 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 <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/jiffies.h>
+#include <linux/cpumask.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/profile.h>
+#include <linux/smp.h>
+#include <asm/tlbflush.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/processor.h>
+#include <asm/bug.h>
+#include <asm/exceptions.h>
+#include <asm/hardirq.h>
+#include <asm/fpu.h>
+#include <asm/mmu_context.h>
+#include <asm/thread_info.h>
+#include <asm/cpu-regs.h>
+#include <asm/intctl-regs.h>
+
+/*
+ * For flush TLB
+ */
+#define FLUSH_ALL 0xffffffff
+
+static cpumask_t flush_cpumask;
+static struct mm_struct *flush_mm;
+static unsigned long flush_va;
+static DEFINE_SPINLOCK(tlbstate_lock);
+
+DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) = {
+ &init_mm, 0
+};
+
+static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm,
+ unsigned long va);
+static void do_flush_tlb_all(void *info);
+
+/**
+ * smp_flush_tlb - Callback to invalidate the TLB.
+ * @unused: Callback context (ignored).
+ */
+void smp_flush_tlb(void *unused)
+{
+ unsigned long cpu_id;
+
+ cpu_id = get_cpu();
+
+ if (!cpu_isset(cpu_id, flush_cpumask))
+ /* This was a BUG() but until someone can quote me the line
+ * from the intel manual that guarantees an IPI to multiple
+ * CPUs is retried _only_ on the erroring CPUs its staying as a
+ * return
+ *
+ * BUG();
+ */
+ goto out;
+
+ if (flush_va == FLUSH_ALL)
+ local_flush_tlb();
+ else
+ local_flush_tlb_page(flush_mm, flush_va);
+
+ smp_mb__before_clear_bit();
+ cpu_clear(cpu_id, flush_cpumask);
+ smp_mb__after_clear_bit();
+out:
+ put_cpu();
+}
+
+/**
+ * flush_tlb_others - Tell the specified CPUs to invalidate their TLBs
+ * @cpumask: The list of CPUs to target.
+ * @mm: The VM context to flush from (if va!=FLUSH_ALL).
+ * @va: Virtual address to flush or FLUSH_ALL to flush everything.
+ */
+static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm,
+ unsigned long va)
+{
+ cpumask_t tmp;
+
+ /* A couple of sanity checks (to be removed):
+ * - mask must not be empty
+ * - current CPU must not be in mask
+ * - we do not send IPIs to as-yet unbooted CPUs.
+ */
+ BUG_ON(!mm);
+ BUG_ON(cpus_empty(cpumask));
+ BUG_ON(cpu_isset(smp_processor_id(), cpumask));
+
+ cpus_and(tmp, cpumask, cpu_online_map);
+ BUG_ON(!cpus_equal(cpumask, tmp));
+
+ /* I'm not happy about this global shared spinlock in the MM hot path,
+ * but we'll see how contended it is.
+ *
+ * Temporarily this turns IRQs off, so that lockups are detected by the
+ * NMI watchdog.
+ */
+ spin_lock(&tlbstate_lock);
+
+ flush_mm = mm;
+ flush_va = va;
+#if NR_CPUS <= BITS_PER_LONG
+ atomic_set_mask(cpumask.bits[0], &flush_cpumask.bits[0]);
+#else
+#error Not supported.
+#endif
+
+ /* FIXME: if NR_CPUS>=3, change send_IPI_mask */
+ smp_call_function(smp_flush_tlb, NULL, 1);
+
+ while (!cpus_empty(flush_cpumask))
+ /* Lockup detection does not belong here */
+ smp_mb();
+
+ flush_mm = NULL;
+ flush_va = 0;
+ spin_unlock(&tlbstate_lock);
+}
+
+/**
+ * flush_tlb_mm - Invalidate TLB of specified VM context
+ * @mm: The VM context to invalidate.
+ */
+void flush_tlb_mm(struct mm_struct *mm)
+{
+ cpumask_t cpu_mask;
+
+ preempt_disable();
+ cpu_mask = mm->cpu_vm_mask;
+ cpu_clear(smp_processor_id(), cpu_mask);
+
+ local_flush_tlb();
+ if (!cpus_empty(cpu_mask))
+ flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
+
+ preempt_enable();
+}
+
+/**
+ * flush_tlb_current_task - Invalidate TLB of current task
+ */
+void flush_tlb_current_task(void)
+{
+ struct mm_struct *mm = current->mm;
+ cpumask_t cpu_mask;
+
+ preempt_disable();
+ cpu_mask = mm->cpu_vm_mask;
+ cpu_clear(smp_processor_id(), cpu_mask);
+
+ local_flush_tlb();
+ if (!cpus_empty(cpu_mask))
+ flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
+
+ preempt_enable();
+}
+
+/**
+ * flush_tlb_page - Invalidate TLB of page
+ * @vma: The VM context to invalidate the page for.
+ * @va: The virtual address of the page to invalidate.
+ */
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long va)
+{
+ struct mm_struct *mm = vma->vm_mm;
+ cpumask_t cpu_mask;
+
+ preempt_disable();
+ cpu_mask = mm->cpu_vm_mask;
+ cpu_clear(smp_processor_id(), cpu_mask);
+
+ local_flush_tlb_page(mm, va);
+ if (!cpus_empty(cpu_mask))
+ flush_tlb_others(cpu_mask, mm, va);
+
+ preempt_enable();
+}
+
+/**
+ * do_flush_tlb_all - Callback to completely invalidate a TLB
+ * @unused: Callback context (ignored).
+ */
+static void do_flush_tlb_all(void *unused)
+{
+ local_flush_tlb_all();
+}
+
+/**
+ * flush_tlb_all - Completely invalidate TLBs on all CPUs
+ */
+void flush_tlb_all(void)
+{
+ on_each_cpu(do_flush_tlb_all, 0, 1);
+}
diff --git a/arch/mn10300/proc-mn103e010/include/proc/cache.h b/arch/mn10300/proc-mn103e010/include/proc/cache.h
index bdc1f9a59b4c..c1528004163c 100644
--- a/arch/mn10300/proc-mn103e010/include/proc/cache.h
+++ b/arch/mn10300/proc-mn103e010/include/proc/cache.h
@@ -30,4 +30,13 @@
*/
#define MN10300_DCACHE_INV_RANGE_INTR_LOG2_INTERVAL 4
+/*
+ * The size of range at which it becomes more economical to just flush the
+ * whole cache rather than trying to flush the specified range.
+ */
+#define MN10300_DCACHE_FLUSH_BORDER \
+ +(L1_CACHE_NWAYS * L1_CACHE_NENTRIES * L1_CACHE_BYTES)
+#define MN10300_DCACHE_FLUSH_INV_BORDER \
+ +(L1_CACHE_NWAYS * L1_CACHE_NENTRIES * L1_CACHE_BYTES)
+
#endif /* _ASM_PROC_CACHE_H */
diff --git a/arch/mn10300/proc-mn103e010/include/proc/clock.h b/arch/mn10300/proc-mn103e010/include/proc/clock.h
index aa23e147d620..704a819f1f4b 100644
--- a/arch/mn10300/proc-mn103e010/include/proc/clock.h
+++ b/arch/mn10300/proc-mn103e010/include/proc/clock.h
@@ -13,6 +13,4 @@
#include <unit/clock.h>
-#define MN10300_WDCLK MN10300_IOCLK
-
#endif /* _ASM_PROC_CLOCK_H */
diff --git a/arch/mn10300/proc-mn103e010/include/proc/dmactl-regs.h b/arch/mn10300/proc-mn103e010/include/proc/dmactl-regs.h
new file mode 100644
index 000000000000..d72d328d1f9c
--- /dev/null
+++ b/arch/mn10300/proc-mn103e010/include/proc/dmactl-regs.h
@@ -0,0 +1,102 @@
+/* MN103E010 on-board DMA controller registers
+ *
+ * Copyright (C) 2007 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_PROC_DMACTL_REGS_H
+#define _ASM_PROC_DMACTL_REGS_H
+
+#include <asm/cpu-regs.h>
+
+#ifdef __KERNEL__
+
+/* DMA registers */
+#define DMxCTR(N) __SYSREG(0xd2000000 + ((N) * 0x100), u32) /* control reg */
+#define DMxCTR_BG 0x0000001f /* transfer request source */
+#define DMxCTR_BG_SOFT 0x00000000 /* - software source */
+#define DMxCTR_BG_SC0TX 0x00000002 /* - serial port 0 transmission */
+#define DMxCTR_BG_SC0RX 0x00000003 /* - serial port 0 reception */
+#define DMxCTR_BG_SC1TX 0x00000004 /* - serial port 1 transmission */
+#define DMxCTR_BG_SC1RX 0x00000005 /* - serial port 1 reception */
+#define DMxCTR_BG_SC2TX 0x00000006 /* - serial port 2 transmission */
+#define DMxCTR_BG_SC2RX 0x00000007 /* - serial port 2 reception */
+#define DMxCTR_BG_TM0UFLOW 0x00000008 /* - timer 0 underflow */
+#define DMxCTR_BG_TM1UFLOW 0x00000009 /* - timer 1 underflow */
+#define DMxCTR_BG_TM2UFLOW 0x0000000a /* - timer 2 underflow */
+#define DMxCTR_BG_TM3UFLOW 0x0000000b /* - timer 3 underflow */
+#define DMxCTR_BG_TM6ACMPCAP 0x0000000c /* - timer 6A compare/capture */
+#define DMxCTR_BG_AFE 0x0000000d /* - analogue front-end interrupt source */
+#define DMxCTR_BG_ADC 0x0000000e /* - A/D conversion end interrupt source */
+#define DMxCTR_BG_IRDA 0x0000000f /* - IrDA interrupt source */
+#define DMxCTR_BG_RTC 0x00000010 /* - RTC interrupt source */
+#define DMxCTR_BG_XIRQ0 0x00000011 /* - XIRQ0 pin interrupt source */
+#define DMxCTR_BG_XIRQ1 0x00000012 /* - XIRQ1 pin interrupt source */
+#define DMxCTR_BG_XDMR0 0x00000013 /* - external request 0 source (XDMR0 pin) */
+#define DMxCTR_BG_XDMR1 0x00000014 /* - external request 1 source (XDMR1 pin) */
+#define DMxCTR_SAM 0x000000e0 /* DMA transfer src addr mode */
+#define DMxCTR_SAM_INCR 0x00000000 /* - increment */
+#define DMxCTR_SAM_DECR 0x00000020 /* - decrement */
+#define DMxCTR_SAM_FIXED 0x00000040 /* - fixed */
+#define DMxCTR_DAM 0x00000000 /* DMA transfer dest addr mode */
+#define DMxCTR_DAM_INCR 0x00000000 /* - increment */
+#define DMxCTR_DAM_DECR 0x00000100 /* - decrement */
+#define DMxCTR_DAM_FIXED 0x00000200 /* - fixed */
+#define DMxCTR_TM 0x00001800 /* DMA transfer mode */
+#define DMxCTR_TM_BATCH 0x00000000 /* - batch transfer */
+#define DMxCTR_TM_INTERM 0x00001000 /* - intermittent transfer */
+#define DMxCTR_UT 0x00006000 /* DMA transfer unit */
+#define DMxCTR_UT_1 0x00000000 /* - 1 byte */
+#define DMxCTR_UT_2 0x00002000 /* - 2 byte */
+#define DMxCTR_UT_4 0x00004000 /* - 4 byte */
+#define DMxCTR_UT_16 0x00006000 /* - 16 byte */
+#define DMxCTR_TEN 0x00010000 /* DMA channel transfer enable */
+#define DMxCTR_RQM 0x00060000 /* external request input source mode */
+#define DMxCTR_RQM_FALLEDGE 0x00000000 /* - falling edge */
+#define DMxCTR_RQM_RISEEDGE 0x00020000 /* - rising edge */
+#define DMxCTR_RQM_LOLEVEL 0x00040000 /* - low level */
+#define DMxCTR_RQM_HILEVEL 0x00060000 /* - high level */
+#define DMxCTR_RQF 0x01000000 /* DMA transfer request flag */
+#define DMxCTR_XEND 0x80000000 /* DMA transfer end flag */
+
+#define DMxSRC(N) __SYSREG(0xd2000004 + ((N) * 0x100), u32) /* control reg */
+
+#define DMxDST(N) __SYSREG(0xd2000008 + ((N) * 0x100), u32) /* src addr reg */
+
+#define DMxSIZ(N) __SYSREG(0xd200000c + ((N) * 0x100), u32) /* dest addr reg */
+#define DMxSIZ_CT 0x000fffff /* number of bytes to transfer */
+
+#define DMxCYC(N) __SYSREG(0xd2000010 + ((N) * 0x100), u32) /* intermittent
+ * size reg */
+#define DMxCYC_CYC 0x000000ff /* number of interrmittent transfers -1 */
+
+#define DM0IRQ 16 /* DMA channel 0 complete IRQ */
+#define DM1IRQ 17 /* DMA channel 1 complete IRQ */
+#define DM2IRQ 18 /* DMA channel 2 complete IRQ */
+#define DM3IRQ 19 /* DMA channel 3 complete IRQ */
+
+#define DM0ICR GxICR(DM0IRQ) /* DMA channel 0 complete intr ctrl reg */
+#define DM1ICR GxICR(DM0IR1) /* DMA channel 1 complete intr ctrl reg */
+#define DM2ICR GxICR(DM0IR2) /* DMA channel 2 complete intr ctrl reg */
+#define DM3ICR GxICR(DM0IR3) /* DMA channel 3 complete intr ctrl reg */
+
+#ifndef __ASSEMBLY__
+
+struct mn10300_dmactl_regs {
+ u32 ctr;
+ const void *src;
+ void *dst;
+ u32 siz;
+ u32 cyc;
+} __attribute__((aligned(0x100)));
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_PROC_DMACTL_REGS_H */
diff --git a/arch/mn10300/proc-mn103e010/include/proc/intctl-regs.h b/arch/mn10300/proc-mn103e010/include/proc/intctl-regs.h
new file mode 100644
index 000000000000..f537801a44ba
--- /dev/null
+++ b/arch/mn10300/proc-mn103e010/include/proc/intctl-regs.h
@@ -0,0 +1,29 @@
+#ifndef _ASM_PROC_INTCTL_REGS_H
+#define _ASM_PROC_INTCTL_REGS_H
+
+#ifndef _ASM_INTCTL_REGS_H
+# error "please don't include this file directly"
+#endif
+
+/* intr acceptance group reg */
+#define IAGR __SYSREG(0xd4000100, u16)
+
+/* group number register */
+#define IAGR_GN 0x00fc
+
+#define __GET_XIRQ_TRIGGER(X, Z) (((Z) >> ((X) * 2)) & 3)
+
+#define __SET_XIRQ_TRIGGER(X, Y, Z) \
+({ \
+ typeof(Z) x = (Z); \
+ x &= ~(3 << ((X) * 2)); \
+ x |= ((Y) & 3) << ((X) * 2); \
+ (Z) = x; \
+})
+
+/* external pin intr spec reg */
+#define EXTMD __SYSREG(0xd4000200, u16)
+#define GET_XIRQ_TRIGGER(X) __GET_XIRQ_TRIGGER(X, EXTMD)
+#define SET_XIRQ_TRIGGER(X, Y) __SET_XIRQ_TRIGGER(X, Y, EXTMD)
+
+#endif /* _ASM_PROC_INTCTL_REGS_H */
diff --git a/arch/mn10300/proc-mn103e010/include/proc/proc.h b/arch/mn10300/proc-mn103e010/include/proc/proc.h
index 22a2b93f70b7..39c4f8e7d2d3 100644
--- a/arch/mn10300/proc-mn103e010/include/proc/proc.h
+++ b/arch/mn10300/proc-mn103e010/include/proc/proc.h
@@ -12,7 +12,7 @@
#ifndef _ASM_PROC_PROC_H
#define _ASM_PROC_PROC_H
-#define PROCESSOR_VENDOR_NAME "Matsushita"
+#define PROCESSOR_VENDOR_NAME "Panasonic"
#define PROCESSOR_MODEL_NAME "mn103e010"
#endif /* _ASM_PROC_PROC_H */
diff --git a/arch/mn10300/proc-mn103e010/proc-init.c b/arch/mn10300/proc-mn103e010/proc-init.c
index 9a482efafa82..27b97980dca4 100644
--- a/arch/mn10300/proc-mn103e010/proc-init.c
+++ b/arch/mn10300/proc-mn103e010/proc-init.c
@@ -9,7 +9,9 @@
* 2 of the Licence, or (at your option) any later version.
*/
#include <linux/kernel.h>
+#include <asm/fpu.h>
#include <asm/rtc.h>
+#include <asm/busctl-regs.h>
/*
* initialise the on-silicon processor peripherals
@@ -28,6 +30,7 @@ asmlinkage void __init processor_init(void)
__set_intr_stub(EXCEP_DAERROR, dtlb_aerror);
__set_intr_stub(EXCEP_BUSERROR, raw_bus_error);
__set_intr_stub(EXCEP_DOUBLE_FAULT, double_fault);
+ __set_intr_stub(EXCEP_FPU_DISABLED, fpu_disabled);
__set_intr_stub(EXCEP_SYSCALL0, system_call);
__set_intr_stub(EXCEP_NMI, nmi_handler);
@@ -73,3 +76,37 @@ asmlinkage void __init processor_init(void)
calibrate_clock();
}
+
+/*
+ * determine the memory size and base from the memory controller regs
+ */
+void __init get_mem_info(unsigned long *mem_base, unsigned long *mem_size)
+{
+ unsigned long base, size;
+
+ *mem_base = 0;
+ *mem_size = 0;
+
+ base = SDBASE(0);
+ if (base & SDBASE_CE) {
+ size = (base & SDBASE_CBAM) << SDBASE_CBAM_SHIFT;
+ size = ~size + 1;
+ base &= SDBASE_CBA;
+
+ printk(KERN_INFO "SDRAM[0]: %luMb @%08lx\n", size >> 20, base);
+ *mem_size += size;
+ *mem_base = base;
+ }
+
+ base = SDBASE(1);
+ if (base & SDBASE_CE) {
+ size = (base & SDBASE_CBAM) << SDBASE_CBAM_SHIFT;
+ size = ~size + 1;
+ base &= SDBASE_CBA;
+
+ printk(KERN_INFO "SDRAM[1]: %luMb @%08lx\n", size >> 20, base);
+ *mem_size += size;
+ if (*mem_base == 0)
+ *mem_base = base;
+ }
+}
diff --git a/arch/mn10300/proc-mn2ws0050/Makefile b/arch/mn10300/proc-mn2ws0050/Makefile
new file mode 100644
index 000000000000..d4ca13309a85
--- /dev/null
+++ b/arch/mn10300/proc-mn2ws0050/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y := proc-init.o
diff --git a/arch/mn10300/proc-mn2ws0050/include/proc/cache.h b/arch/mn10300/proc-mn2ws0050/include/proc/cache.h
new file mode 100644
index 000000000000..cafd7b5b55b4
--- /dev/null
+++ b/arch/mn10300/proc-mn2ws0050/include/proc/cache.h
@@ -0,0 +1,48 @@
+/* Cache specification
+ *
+ * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * Modified by Matsushita Electric Industrial Co., Ltd.
+ * Modifications:
+ * 13-Nov-2006 MEI Add L1_CACHE_SHIFT_MAX definition.
+ * 29-Jul-2008 MEI Add define for MN10300_HAS_AREAPURGE_REG.
+ *
+ * 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.
+ */
+#ifndef _ASM_PROC_CACHE_H
+#define _ASM_PROC_CACHE_H
+
+/*
+ * L1 cache
+ */
+#define L1_CACHE_NWAYS 4 /* number of ways in caches */
+#define L1_CACHE_NENTRIES 128 /* number of entries in each way */
+#define L1_CACHE_BYTES 32 /* bytes per entry */
+#define L1_CACHE_SHIFT 5 /* shift for bytes per entry */
+#define L1_CACHE_WAYDISP 0x1000 /* distance from one way to the next */
+
+#define L1_CACHE_TAG_VALID 0x00000001 /* cache tag valid bit */
+#define L1_CACHE_TAG_DIRTY 0x00000008 /* data cache tag dirty bit */
+#define L1_CACHE_TAG_ENTRY 0x00000fe0 /* cache tag entry address mask */
+#define L1_CACHE_TAG_ADDRESS 0xfffff000 /* cache tag line address mask */
+
+/*
+ * specification of the interval between interrupt checking intervals whilst
+ * managing the cache with the interrupts disabled
+ */
+#define MN10300_DCACHE_INV_RANGE_INTR_LOG2_INTERVAL 4
+
+/*
+ * The size of range at which it becomes more economical to just flush the
+ * whole cache rather than trying to flush the specified range.
+ */
+#define MN10300_DCACHE_FLUSH_BORDER \
+ +(L1_CACHE_NWAYS * L1_CACHE_NENTRIES * L1_CACHE_BYTES)
+#define MN10300_DCACHE_FLUSH_INV_BORDER \
+ +(L1_CACHE_NWAYS * L1_CACHE_NENTRIES * L1_CACHE_BYTES)
+
+#endif /* _ASM_PROC_CACHE_H */
diff --git a/arch/mn10300/proc-mn2ws0050/include/proc/clock.h b/arch/mn10300/proc-mn2ws0050/include/proc/clock.h
new file mode 100644
index 000000000000..fe4c0a4a53a2
--- /dev/null
+++ b/arch/mn10300/proc-mn2ws0050/include/proc/clock.h
@@ -0,0 +1,20 @@
+/* clock.h: proc-specific clocks
+ *
+ * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * Modified by Matsushita Electric Industrial Co., Ltd.
+ * Modifications:
+ * 23-Feb-2007 MEI Delete define for watchdog timer.
+ *
+ * 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.
+ */
+#ifndef _ASM_PROC_CLOCK_H
+#define _ASM_PROC_CLOCK_H
+
+#include <unit/clock.h>
+
+#endif /* _ASM_PROC_CLOCK_H */
diff --git a/arch/mn10300/proc-mn2ws0050/include/proc/dmactl-regs.h b/arch/mn10300/proc-mn2ws0050/include/proc/dmactl-regs.h
new file mode 100644
index 000000000000..4c4319e241d1
--- /dev/null
+++ b/arch/mn10300/proc-mn2ws0050/include/proc/dmactl-regs.h
@@ -0,0 +1,103 @@
+/* MN2WS0050 on-board DMA controller registers
+ *
+ * Copyright (C) 2002 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 License
+ * version 2 as published by the Free Software Foundation.
+ */
+
+#ifndef _ASM_PROC_DMACTL_REGS_H
+#define _ASM_PROC_DMACTL_REGS_H
+
+#include <asm/cpu-regs.h>
+
+#ifdef __KERNEL__
+
+/* DMA registers */
+#define DMxCTR(N) __SYSREG(0xd4005000+(N*0x100), u32) /* control reg */
+#define DMxCTR_BG 0x0000001f /* transfer request source */
+#define DMxCTR_BG_SOFT 0x00000000 /* - software source */
+#define DMxCTR_BG_SC0TX 0x00000002 /* - serial port 0 transmission */
+#define DMxCTR_BG_SC0RX 0x00000003 /* - serial port 0 reception */
+#define DMxCTR_BG_SC1TX 0x00000004 /* - serial port 1 transmission */
+#define DMxCTR_BG_SC1RX 0x00000005 /* - serial port 1 reception */
+#define DMxCTR_BG_SC2TX 0x00000006 /* - serial port 2 transmission */
+#define DMxCTR_BG_SC2RX 0x00000007 /* - serial port 2 reception */
+#define DMxCTR_BG_TM0UFLOW 0x00000008 /* - timer 0 underflow */
+#define DMxCTR_BG_TM1UFLOW 0x00000009 /* - timer 1 underflow */
+#define DMxCTR_BG_TM2UFLOW 0x0000000a /* - timer 2 underflow */
+#define DMxCTR_BG_TM3UFLOW 0x0000000b /* - timer 3 underflow */
+#define DMxCTR_BG_TM6ACMPCAP 0x0000000c /* - timer 6A compare/capture */
+#define DMxCTR_BG_RYBY 0x0000000d /* - NAND Flash RY/BY request source */
+#define DMxCTR_BG_RMC 0x0000000e /* - remote controller output */
+#define DMxCTR_BG_XIRQ12 0x00000011 /* - XIRQ12 pin interrupt source */
+#define DMxCTR_BG_XIRQ13 0x00000012 /* - XIRQ13 pin interrupt source */
+#define DMxCTR_BG_TCK 0x00000014 /* - tick timer underflow */
+#define DMxCTR_BG_SC4TX 0x00000019 /* - serial port4 transmission */
+#define DMxCTR_BG_SC4RX 0x0000001a /* - serial port4 reception */
+#define DMxCTR_BG_SC5TX 0x0000001b /* - serial port5 transmission */
+#define DMxCTR_BG_SC5RX 0x0000001c /* - serial port5 reception */
+#define DMxCTR_BG_SC6TX 0x0000001d /* - serial port6 transmission */
+#define DMxCTR_BG_SC6RX 0x0000001e /* - serial port6 reception */
+#define DMxCTR_BG_TMSUFLOW 0x0000001f /* - timestamp timer underflow */
+#define DMxCTR_SAM 0x00000060 /* DMA transfer src addr mode */
+#define DMxCTR_SAM_INCR 0x00000000 /* - increment */
+#define DMxCTR_SAM_DECR 0x00000020 /* - decrement */
+#define DMxCTR_SAM_FIXED 0x00000040 /* - fixed */
+#define DMxCTR_DAM 0x00000300 /* DMA transfer dest addr mode */
+#define DMxCTR_DAM_INCR 0x00000000 /* - increment */
+#define DMxCTR_DAM_DECR 0x00000100 /* - decrement */
+#define DMxCTR_DAM_FIXED 0x00000200 /* - fixed */
+#define DMxCTR_UT 0x00006000 /* DMA transfer unit */
+#define DMxCTR_UT_1 0x00000000 /* - 1 byte */
+#define DMxCTR_UT_2 0x00002000 /* - 2 byte */
+#define DMxCTR_UT_4 0x00004000 /* - 4 byte */
+#define DMxCTR_UT_16 0x00006000 /* - 16 byte */
+#define DMxCTR_RRE 0x00008000 /* DMA round robin enable */
+#define DMxCTR_TEN 0x00010000 /* DMA channel transfer enable */
+#define DMxCTR_RQM 0x00060000 /* external request input source mode */
+#define DMxCTR_RQM_FALLEDGE 0x00000000 /* - falling edge */
+#define DMxCTR_RQM_RISEEDGE 0x00020000 /* - rising edge */
+#define DMxCTR_RQM_LOLEVEL 0x00040000 /* - low level */
+#define DMxCTR_RQM_HILEVEL 0x00060000 /* - high level */
+#define DMxCTR_RQF 0x01000000 /* DMA transfer request flag */
+#define DMxCTR_PERR 0x40000000 /* DMA transfer parameter error flag */
+#define DMxCTR_XEND 0x80000000 /* DMA transfer end flag */
+
+#define DMxSRC(N) __SYSREG(0xd4005004+(N*0x100), u32) /* control reg */
+
+#define DMxDST(N) __SYSREG(0xd4005008+(N*0x100), u32) /* source addr reg */
+
+#define DMxSIZ(N) __SYSREG(0xd400500c+(N*0x100), u32) /* dest addr reg */
+#define DMxSIZ_CT 0x000fffff /* number of bytes to transfer */
+
+#define DMxCYC(N) __SYSREG(0xd4005010+(N*0x100), u32) /* intermittent size reg */
+#define DMxCYC_CYC 0x000000ff /* number of interrmittent transfers -1 */
+
+#define DM0IRQ 16 /* DMA channel 0 complete IRQ */
+#define DM1IRQ 17 /* DMA channel 1 complete IRQ */
+#define DM2IRQ 18 /* DMA channel 2 complete IRQ */
+#define DM3IRQ 19 /* DMA channel 3 complete IRQ */
+
+#define DM0ICR GxICR(DM0IRQ) /* DMA channel 0 complete intr ctrl reg */
+#define DM1ICR GxICR(DM0IR1) /* DMA channel 1 complete intr ctrl reg */
+#define DM2ICR GxICR(DM0IR2) /* DMA channel 2 complete intr ctrl reg */
+#define DM3ICR GxICR(DM0IR3) /* DMA channel 3 complete intr ctrl reg */
+
+#ifndef __ASSEMBLY__
+
+struct mn10300_dmactl_regs {
+ u32 ctr;
+ const void *src;
+ void *dst;
+ u32 siz;
+ u32 cyc;
+} __attribute__((aligned(0x100)));
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_PROC_DMACTL_REGS_H */
diff --git a/arch/mn10300/proc-mn2ws0050/include/proc/intctl-regs.h b/arch/mn10300/proc-mn2ws0050/include/proc/intctl-regs.h
new file mode 100644
index 000000000000..a1e977273d19
--- /dev/null
+++ b/arch/mn10300/proc-mn2ws0050/include/proc/intctl-regs.h
@@ -0,0 +1,29 @@
+#ifndef _ASM_PROC_INTCTL_REGS_H
+#define _ASM_PROC_INTCTL_REGS_H
+
+#ifndef _ASM_INTCTL_REGS_H
+# error "please don't include this file directly"
+#endif
+
+/* intr acceptance group reg */
+#define IAGR __SYSREG(0xd4000100, u16)
+
+/* group number register */
+#define IAGR_GN 0x003fc
+
+#define __GET_XIRQ_TRIGGER(X, Z) (((Z) >> ((X) * 2)) & 3)
+
+#define __SET_XIRQ_TRIGGER(X, Y, Z) \
+({ \
+ typeof(Z) x = (Z); \
+ x &= ~(3 << ((X) * 2)); \
+ x |= ((Y) & 3) << ((X) * 2); \
+ (Z) = x; \
+})
+
+/* external pin intr spec reg */
+#define EXTMD0 __SYSREG(0xd4000200, u32)
+#define GET_XIRQ_TRIGGER(X) __GET_XIRQ_TRIGGER(X, EXTMD0)
+#define SET_XIRQ_TRIGGER(X, Y) __SET_XIRQ_TRIGGER(X, Y, EXTMD0)
+
+#endif /* _ASM_PROC_INTCTL_REGS_H */
diff --git a/arch/mn10300/proc-mn2ws0050/include/proc/irq.h b/arch/mn10300/proc-mn2ws0050/include/proc/irq.h
new file mode 100644
index 000000000000..37777a85ab6f
--- /dev/null
+++ b/arch/mn10300/proc-mn2ws0050/include/proc/irq.h
@@ -0,0 +1,49 @@
+/* MN2WS0050 on-board interrupt controller registers
+ *
+ * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * Modified by Matsushita Electric Industrial Co., Ltd.
+ * Modifications:
+ * 13-Nov-2006 MEI Define extended IRQ number for SMP support.
+ *
+ * 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.
+ */
+
+#ifndef _PROC_IRQ_H
+#define _PROC_IRQ_H
+
+#ifdef __KERNEL__
+
+#define GxICR_NUM_IRQS 163
+#ifdef CONFIG_SMP
+#define GxICR_NUM_EXT_IRQS 197
+#endif /* CONFIG_SMP */
+
+#define GxICR_NUM_XIRQS 16
+
+#define XIRQ0 34
+#define XIRQ1 35
+#define XIRQ2 36
+#define XIRQ3 37
+#define XIRQ4 38
+#define XIRQ5 39
+#define XIRQ6 40
+#define XIRQ7 41
+#define XIRQ8 42
+#define XIRQ9 43
+#define XIRQ10 44
+#define XIRQ11 45
+#define XIRQ12 46
+#define XIRQ13 47
+#define XIRQ14 48
+#define XIRQ15 49
+
+#define XIRQ2IRQ(num) (XIRQ0 + num)
+
+#endif /* __KERNEL__ */
+
+#endif /* _PROC_IRQ_H */
diff --git a/arch/mn10300/proc-mn2ws0050/include/proc/nand-regs.h b/arch/mn10300/proc-mn2ws0050/include/proc/nand-regs.h
new file mode 100644
index 000000000000..84448f3828b3
--- /dev/null
+++ b/arch/mn10300/proc-mn2ws0050/include/proc/nand-regs.h
@@ -0,0 +1,120 @@
+/* NAND flash interface register definitions
+ *
+ * Copyright (C) 2008-2009 Panasonic Corporation
+ * 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.
+ *
+ * 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 _PROC_NAND_REGS_H_
+#define _PROC_NAND_REGS_H_
+
+/* command register */
+#define FCOMMAND_0 __SYSREG(0xd8f00000, u8) /* fcommand[24:31] */
+#define FCOMMAND_1 __SYSREG(0xd8f00001, u8) /* fcommand[16:23] */
+#define FCOMMAND_2 __SYSREG(0xd8f00002, u8) /* fcommand[8:15] */
+#define FCOMMAND_3 __SYSREG(0xd8f00003, u8) /* fcommand[0:7] */
+
+/* for dma 16 byte trans, use FCOMMAND2 register */
+#define FCOMMAND2_0 __SYSREG(0xd8f00110, u8) /* fcommand2[24:31] */
+#define FCOMMAND2_1 __SYSREG(0xd8f00111, u8) /* fcommand2[16:23] */
+#define FCOMMAND2_2 __SYSREG(0xd8f00112, u8) /* fcommand2[8:15] */
+#define FCOMMAND2_3 __SYSREG(0xd8f00113, u8) /* fcommand2[0:7] */
+
+#define FCOMMAND_FIEN 0x80 /* nand flash I/F enable */
+#define FCOMMAND_BW_8BIT 0x00 /* 8bit bus width */
+#define FCOMMAND_BW_16BIT 0x40 /* 16bit bus width */
+#define FCOMMAND_BLOCKSZ_SMALL 0x00 /* small block */
+#define FCOMMAND_BLOCKSZ_LARGE 0x20 /* large block */
+#define FCOMMAND_DMASTART 0x10 /* dma start */
+#define FCOMMAND_RYBY 0x08 /* ready/busy flag */
+#define FCOMMAND_RYBYINTMSK 0x04 /* mask ready/busy interrupt */
+#define FCOMMAND_XFWP 0x02 /* write protect enable */
+#define FCOMMAND_XFCE 0x01 /* flash device disable */
+#define FCOMMAND_SEQKILL 0x10 /* stop seq-read */
+#define FCOMMAND_ANUM 0x07 /* address cycle */
+#define FCOMMAND_ANUM_NONE 0x00 /* address cycle none */
+#define FCOMMAND_ANUM_1CYC 0x01 /* address cycle 1cycle */
+#define FCOMMAND_ANUM_2CYC 0x02 /* address cycle 2cycle */
+#define FCOMMAND_ANUM_3CYC 0x03 /* address cycle 3cycle */
+#define FCOMMAND_ANUM_4CYC 0x04 /* address cycle 4cycle */
+#define FCOMMAND_ANUM_5CYC 0x05 /* address cycle 5cycle */
+#define FCOMMAND_FCMD_READ0 0x00 /* read1 command */
+#define FCOMMAND_FCMD_SEQIN 0x80 /* page program 1st command */
+#define FCOMMAND_FCMD_PAGEPROG 0x10 /* page program 2nd command */
+#define FCOMMAND_FCMD_RESET 0xff /* reset command */
+#define FCOMMAND_FCMD_ERASE1 0x60 /* erase 1st command */
+#define FCOMMAND_FCMD_ERASE2 0xd0 /* erase 2nd command */
+#define FCOMMAND_FCMD_STATUS 0x70 /* read status command */
+#define FCOMMAND_FCMD_READID 0x90 /* read id command */
+#define FCOMMAND_FCMD_READOOB 0x50 /* read3 command */
+/* address register */
+#define FADD __SYSREG(0xd8f00004, u32)
+/* address register 2 */
+#define FADD2 __SYSREG(0xd8f00008, u32)
+/* error judgement register */
+#define FJUDGE __SYSREG(0xd8f0000c, u32)
+#define FJUDGE_NOERR 0x0 /* no error */
+#define FJUDGE_1BITERR 0x1 /* 1bit error in data area */
+#define FJUDGE_PARITYERR 0x2 /* parity error */
+#define FJUDGE_UNCORRECTABLE 0x3 /* uncorrectable error */
+#define FJUDGE_ERRJDG_MSK 0x3 /* mask of judgement result */
+/* 1st ECC store register */
+#define FECC11 __SYSREG(0xd8f00010, u32)
+/* 2nd ECC store register */
+#define FECC12 __SYSREG(0xd8f00014, u32)
+/* 3rd ECC store register */
+#define FECC21 __SYSREG(0xd8f00018, u32)
+/* 4th ECC store register */
+#define FECC22 __SYSREG(0xd8f0001c, u32)
+/* 5th ECC store register */
+#define FECC31 __SYSREG(0xd8f00020, u32)
+/* 6th ECC store register */
+#define FECC32 __SYSREG(0xd8f00024, u32)
+/* 7th ECC store register */
+#define FECC41 __SYSREG(0xd8f00028, u32)
+/* 8th ECC store register */
+#define FECC42 __SYSREG(0xd8f0002c, u32)
+/* data register */
+#define FDATA __SYSREG(0xd8f00030, u32)
+/* access pulse register */
+#define FPWS __SYSREG(0xd8f00100, u32)
+#define FPWS_PWS1W_2CLK 0x00000000 /* write pulse width 1clock */
+#define FPWS_PWS1W_3CLK 0x01000000 /* write pulse width 2clock */
+#define FPWS_PWS1W_4CLK 0x02000000 /* write pulse width 4clock */
+#define FPWS_PWS1W_5CLK 0x03000000 /* write pulse width 5clock */
+#define FPWS_PWS1W_6CLK 0x04000000 /* write pulse width 6clock */
+#define FPWS_PWS1W_7CLK 0x05000000 /* write pulse width 7clock */
+#define FPWS_PWS1W_8CLK 0x06000000 /* write pulse width 8clock */
+#define FPWS_PWS1R_3CLK 0x00010000 /* read pulse width 3clock */
+#define FPWS_PWS1R_4CLK 0x00020000 /* read pulse width 4clock */
+#define FPWS_PWS1R_5CLK 0x00030000 /* read pulse width 5clock */
+#define FPWS_PWS1R_6CLK 0x00040000 /* read pulse width 6clock */
+#define FPWS_PWS1R_7CLK 0x00050000 /* read pulse width 7clock */
+#define FPWS_PWS1R_8CLK 0x00060000 /* read pulse width 8clock */
+#define FPWS_PWS2W_2CLK 0x00000100 /* write pulse interval 2clock */
+#define FPWS_PWS2W_3CLK 0x00000200 /* write pulse interval 3clock */
+#define FPWS_PWS2W_4CLK 0x00000300 /* write pulse interval 4clock */
+#define FPWS_PWS2W_5CLK 0x00000400 /* write pulse interval 5clock */
+#define FPWS_PWS2W_6CLK 0x00000500 /* write pulse interval 6clock */
+#define FPWS_PWS2R_2CLK 0x00000001 /* read pulse interval 2clock */
+#define FPWS_PWS2R_3CLK 0x00000002 /* read pulse interval 3clock */
+#define FPWS_PWS2R_4CLK 0x00000003 /* read pulse interval 4clock */
+#define FPWS_PWS2R_5CLK 0x00000004 /* read pulse interval 5clock */
+#define FPWS_PWS2R_6CLK 0x00000005 /* read pulse interval 6clock */
+/* command register 2 */
+#define FCOMMAND2 __SYSREG(0xd8f00110, u32)
+/* transfer frequency register */
+#define FNUM __SYSREG(0xd8f00114, u32)
+#define FSDATA_ADDR 0xd8f00400
+/* active data register */
+#define FSDATA __SYSREG(FSDATA_ADDR, u32)
+
+#endif /* _PROC_NAND_REGS_H_ */
diff --git a/arch/mn10300/proc-mn2ws0050/include/proc/proc.h b/arch/mn10300/proc-mn2ws0050/include/proc/proc.h
new file mode 100644
index 000000000000..90d5cadd05bd
--- /dev/null
+++ b/arch/mn10300/proc-mn2ws0050/include/proc/proc.h
@@ -0,0 +1,18 @@
+/* proc.h: MN2WS0050 processor description
+ *
+ * Copyright (C) 2002 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_PROC_PROC_H
+#define _ASM_PROC_PROC_H
+
+#define PROCESSOR_VENDOR_NAME "Panasonic"
+#define PROCESSOR_MODEL_NAME "mn2ws0050"
+
+#endif /* _ASM_PROC_PROC_H */
diff --git a/arch/mn10300/proc-mn2ws0050/include/proc/smp-regs.h b/arch/mn10300/proc-mn2ws0050/include/proc/smp-regs.h
new file mode 100644
index 000000000000..22f277fbb4de
--- /dev/null
+++ b/arch/mn10300/proc-mn2ws0050/include/proc/smp-regs.h
@@ -0,0 +1,51 @@
+/* MN10300/AM33v2 Microcontroller SMP registers
+ *
+ * Copyright (C) 2006 Matsushita Electric Industrial Co., Ltd.
+ * All Rights Reserved.
+ * Created:
+ * 13-Nov-2006 MEI Add extended cache and atomic operation register
+ * for SMP support.
+ * 23-Feb-2007 MEI Add define for gdbstub SMP.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_PROC_SMP_REGS_H
+#define _ASM_PROC_SMP_REGS_H
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+#endif
+#include <asm/cpu-regs.h>
+
+/*
+ * Reference to the interrupt controllers of other CPUs
+ */
+#define CROSS_ICR_CPU_SHIFT 16
+
+#define CROSS_GxICR(X, CPU) __SYSREG(0xc4000000 + (X) * 4 + \
+ ((X) >= 64 && (X) < 192) * 0xf00 + ((CPU) << CROSS_ICR_CPU_SHIFT), u16)
+#define CROSS_GxICR_u8(X, CPU) __SYSREG(0xc4000000 + (X) * 4 + \
+ (((X) >= 64) && ((X) < 192)) * 0xf00 + ((CPU) << CROSS_ICR_CPU_SHIFT), u8)
+
+/* CPU ID register */
+#define CPUID __SYSREGC(0xc0000054, u32)
+#define CPUID_MASK 0x00000007 /* CPU ID mask */
+
+/* extended cache control register */
+#define ECHCTR __SYSREG(0xc0000c20, u32)
+#define ECHCTR_IBCM 0x00000001 /* instruction cache broad cast mask */
+#define ECHCTR_DBCM 0x00000002 /* data cache broad cast mask */
+#define ECHCTR_ISPM 0x00000004 /* instruction cache snoop mask */
+#define ECHCTR_DSPM 0x00000008 /* data cache snoop mask */
+
+#define NMIAGR __SYSREG(0xd400013c, u16)
+#define NMIAGR_GN 0x03fc
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_PROC_SMP_REGS_H */
diff --git a/arch/mn10300/proc-mn2ws0050/proc-init.c b/arch/mn10300/proc-mn2ws0050/proc-init.c
new file mode 100644
index 000000000000..c58249b9525a
--- /dev/null
+++ b/arch/mn10300/proc-mn2ws0050/proc-init.c
@@ -0,0 +1,134 @@
+/* MN2WS0050 processor initialisation
+ *
+ * Copyright (C) 2005 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/atomic.h>
+#include <asm/smp.h>
+#include <asm/pgalloc.h>
+#include <asm/busctl-regs.h>
+#include <unit/timex.h>
+#include <asm/fpu.h>
+#include <asm/rtc.h>
+
+#define MEMCONF __SYSREGC(0xdf800400, u32)
+
+/*
+ * initialise the on-silicon processor peripherals
+ */
+asmlinkage void __init processor_init(void)
+{
+ int loop;
+
+ /* set up the exception table first */
+ for (loop = 0x000; loop < 0x400; loop += 8)
+ __set_intr_stub(loop, __common_exception);
+
+ __set_intr_stub(EXCEP_ITLBMISS, itlb_miss);
+ __set_intr_stub(EXCEP_DTLBMISS, dtlb_miss);
+ __set_intr_stub(EXCEP_IAERROR, itlb_aerror);
+ __set_intr_stub(EXCEP_DAERROR, dtlb_aerror);
+ __set_intr_stub(EXCEP_BUSERROR, raw_bus_error);
+ __set_intr_stub(EXCEP_DOUBLE_FAULT, double_fault);
+ __set_intr_stub(EXCEP_FPU_DISABLED, fpu_disabled);
+ __set_intr_stub(EXCEP_SYSCALL0, system_call);
+
+ __set_intr_stub(EXCEP_NMI, nmi_handler);
+ __set_intr_stub(EXCEP_WDT, nmi_handler);
+ __set_intr_stub(EXCEP_IRQ_LEVEL0, irq_handler);
+ __set_intr_stub(EXCEP_IRQ_LEVEL1, irq_handler);
+ __set_intr_stub(EXCEP_IRQ_LEVEL2, irq_handler);
+ __set_intr_stub(EXCEP_IRQ_LEVEL3, irq_handler);
+ __set_intr_stub(EXCEP_IRQ_LEVEL4, irq_handler);
+ __set_intr_stub(EXCEP_IRQ_LEVEL5, irq_handler);
+ __set_intr_stub(EXCEP_IRQ_LEVEL6, irq_handler);
+
+ IVAR0 = EXCEP_IRQ_LEVEL0;
+ IVAR1 = EXCEP_IRQ_LEVEL1;
+ IVAR2 = EXCEP_IRQ_LEVEL2;
+ IVAR3 = EXCEP_IRQ_LEVEL3;
+ IVAR4 = EXCEP_IRQ_LEVEL4;
+ IVAR5 = EXCEP_IRQ_LEVEL5;
+ IVAR6 = EXCEP_IRQ_LEVEL6;
+
+#ifndef CONFIG_MN10300_HAS_CACHE_SNOOP
+ mn10300_dcache_flush_inv();
+ mn10300_icache_inv();
+#endif
+
+ /* disable all interrupts and set to priority 6 (lowest) */
+#ifdef CONFIG_SMP
+ for (loop = 0; loop < GxICR_NUM_IRQS; loop++)
+ GxICR(loop) = GxICR_LEVEL_6 | GxICR_DETECT;
+#else /* !CONFIG_SMP */
+ for (loop = 0; loop < NR_IRQS; loop++)
+ GxICR(loop) = GxICR_LEVEL_6 | GxICR_DETECT;
+#endif /* !CONFIG_SMP */
+
+ /* clear the timers */
+ TM0MD = 0;
+ TM1MD = 0;
+ TM2MD = 0;
+ TM3MD = 0;
+ TM4MD = 0;
+ TM5MD = 0;
+ TM6MD = 0;
+ TM6MDA = 0;
+ TM6MDB = 0;
+ TM7MD = 0;
+ TM8MD = 0;
+ TM9MD = 0;
+ TM10MD = 0;
+ TM11MD = 0;
+ TM12MD = 0;
+ TM13MD = 0;
+ TM14MD = 0;
+ TM15MD = 0;
+
+ calibrate_clock();
+}
+
+/*
+ * determine the memory size and base from the memory controller regs
+ */
+void __init get_mem_info(unsigned long *mem_base, unsigned long *mem_size)
+{
+ unsigned long memconf = MEMCONF;
+ unsigned long size = 0; /* order: MByte */
+
+ *mem_base = 0x90000000; /* fixed address */
+
+ switch (memconf & 0x00000003) {
+ case 0x01:
+ size = 256 / 8; /* 256 Mbit per chip */
+ break;
+ case 0x02:
+ size = 512 / 8; /* 512 Mbit per chip */
+ break;
+ case 0x03:
+ size = 1024 / 8; /* 1 Gbit per chip */
+ break;
+ default:
+ panic("Invalid SDRAM size");
+ break;
+ }
+
+ printk(KERN_INFO "DDR2-SDRAM: %luMB x 2 @%08lx\n", size, *mem_base);
+
+ *mem_size = (size * 2) << 20;
+}
diff --git a/arch/mn10300/unit-asb2303/include/unit/clock.h b/arch/mn10300/unit-asb2303/include/unit/clock.h
index 2a0bf79ab968..0316907a012e 100644
--- a/arch/mn10300/unit-asb2303/include/unit/clock.h
+++ b/arch/mn10300/unit-asb2303/include/unit/clock.h
@@ -14,32 +14,11 @@
#ifndef __ASSEMBLY__
-#ifdef CONFIG_MN10300_RTC
-
-extern unsigned long mn10300_ioclk; /* IOCLK (crystal speed) in HZ */
-extern unsigned long mn10300_iobclk;
-extern unsigned long mn10300_tsc_per_HZ;
-
-#define MN10300_IOCLK mn10300_ioclk
-/* If this processors has a another clock, uncomment the below. */
-/* #define MN10300_IOBCLK mn10300_iobclk */
-
-#else /* !CONFIG_MN10300_RTC */
-
#define MN10300_IOCLK 33333333UL
/* #define MN10300_IOBCLK 66666666UL */
-#endif /* !CONFIG_MN10300_RTC */
-
-#define MN10300_JCCLK MN10300_IOCLK
-#define MN10300_TSCCLK MN10300_IOCLK
-
-#ifdef CONFIG_MN10300_RTC
-#define MN10300_TSC_PER_HZ mn10300_tsc_per_HZ
-#else /* !CONFIG_MN10300_RTC */
-#define MN10300_TSC_PER_HZ (MN10300_TSCCLK/HZ)
-#endif /* !CONFIG_MN10300_RTC */
-
#endif /* !__ASSEMBLY__ */
+#define MN10300_WDCLK MN10300_IOCLK
+
#endif /* _ASM_UNIT_CLOCK_H */
diff --git a/arch/mn10300/unit-asb2303/include/unit/serial.h b/arch/mn10300/unit-asb2303/include/unit/serial.h
index 047566cd2e36..991e356bac5f 100644
--- a/arch/mn10300/unit-asb2303/include/unit/serial.h
+++ b/arch/mn10300/unit-asb2303/include/unit/serial.h
@@ -22,6 +22,11 @@
#define SERIAL_IRQ XIRQ0 /* Dual serial (PC16552) (Hi) */
/*
+ * The ASB2303 has an 18.432 MHz clock the UART
+ */
+#define BASE_BAUD (18432000 / 16)
+
+/*
* dispose of the /dev/ttyS0 and /dev/ttyS1 serial ports
*/
#ifndef CONFIG_GDBSTUB_ON_TTYSx
diff --git a/arch/mn10300/unit-asb2303/include/unit/timex.h b/arch/mn10300/unit-asb2303/include/unit/timex.h
index f206b63c95b4..cc18fe7d8b90 100644
--- a/arch/mn10300/unit-asb2303/include/unit/timex.h
+++ b/arch/mn10300/unit-asb2303/include/unit/timex.h
@@ -1,6 +1,6 @@
-/* ASB2303-specific timer specifcations
+/* ASB2303-specific timer specifications
*
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2007, 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
@@ -17,67 +17,72 @@
#include <asm/timer-regs.h>
#include <unit/clock.h>
+#include <asm/param.h>
/*
* jiffies counter specifications
*/
#define TMJCBR_MAX 0xffff
-#define TMJCBC TM01BC
-
-#define TMJCMD TM01MD
-#define TMJCBR TM01BR
#define TMJCIRQ TM1IRQ
#define TMJCICR TM1ICR
-#define TMJCICR_LEVEL GxICR_LEVEL_5
#ifndef __ASSEMBLY__
-static inline void startup_jiffies_counter(void)
+#define MN10300_SRC_IOCLK MN10300_IOCLK
+
+#ifndef HZ
+# error HZ undeclared.
+#endif /* !HZ */
+/* use as little prescaling as possible to avoid losing accuracy */
+#if (MN10300_SRC_IOCLK + HZ / 2) / HZ - 1 <= TMJCBR_MAX
+# define IOCLK_PRESCALE 1
+# define JC_TIMER_CLKSRC TM0MD_SRC_IOCLK
+# define TSC_TIMER_CLKSRC TM4MD_SRC_IOCLK
+#elif (MN10300_SRC_IOCLK / 8 + HZ / 2) / HZ - 1 <= TMJCBR_MAX
+# define IOCLK_PRESCALE 8
+# define JC_TIMER_CLKSRC TM0MD_SRC_IOCLK_8
+# define TSC_TIMER_CLKSRC TM4MD_SRC_IOCLK_8
+#elif (MN10300_SRC_IOCLK / 32 + HZ / 2) / HZ - 1 <= TMJCBR_MAX
+# define IOCLK_PRESCALE 32
+# define JC_TIMER_CLKSRC TM0MD_SRC_IOCLK_32
+# define TSC_TIMER_CLKSRC TM4MD_SRC_IOCLK_32
+#else
+# error You lose.
+#endif
+
+#define MN10300_JCCLK (MN10300_SRC_IOCLK / IOCLK_PRESCALE)
+#define MN10300_TSCCLK (MN10300_SRC_IOCLK / IOCLK_PRESCALE)
+
+#define MN10300_JC_PER_HZ ((MN10300_JCCLK + HZ / 2) / HZ)
+#define MN10300_TSC_PER_HZ ((MN10300_TSCCLK + HZ / 2) / HZ)
+
+static inline void stop_jiffies_counter(void)
{
- unsigned rate;
- u16 md, t16;
-
- /* use as little prescaling as possible to avoid losing accuracy */
- md = TM0MD_SRC_IOCLK;
- rate = MN10300_JCCLK / HZ;
-
- if (rate > TMJCBR_MAX) {
- md = TM0MD_SRC_IOCLK_8;
- rate = MN10300_JCCLK / 8 / HZ;
-
- if (rate > TMJCBR_MAX) {
- md = TM0MD_SRC_IOCLK_32;
- rate = MN10300_JCCLK / 32 / HZ;
-
- if (rate > TMJCBR_MAX)
- BUG();
- }
- }
+ u16 tmp;
+ TM01MD = JC_TIMER_CLKSRC | TM1MD_SRC_TM0CASCADE << 8;
+ tmp = TM01MD;
+}
- TMJCBR = rate - 1;
- t16 = TMJCBR;
+static inline void reload_jiffies_counter(u32 cnt)
+{
+ u32 tmp;
- TMJCMD =
- md |
- TM1MD_SRC_TM0CASCADE << 8 |
- TM0MD_INIT_COUNTER |
- TM1MD_INIT_COUNTER << 8;
+ TM01BR = cnt;
+ tmp = TM01BR;
- TMJCMD =
- md |
- TM1MD_SRC_TM0CASCADE << 8 |
- TM0MD_COUNT_ENABLE |
- TM1MD_COUNT_ENABLE << 8;
+ TM01MD = JC_TIMER_CLKSRC | \
+ TM1MD_SRC_TM0CASCADE << 8 | \
+ TM0MD_INIT_COUNTER | \
+ TM1MD_INIT_COUNTER << 8;
- t16 = TMJCMD;
- TMJCICR |= GxICR_ENABLE | GxICR_DETECT | GxICR_REQUEST;
- t16 = TMJCICR;
-}
+ TM01MD = JC_TIMER_CLKSRC | \
+ TM1MD_SRC_TM0CASCADE << 8 | \
+ TM0MD_COUNT_ENABLE | \
+ TM1MD_COUNT_ENABLE << 8;
-static inline void shutdown_jiffies_counter(void)
-{
+ tmp = TM01MD;
}
#endif /* !__ASSEMBLY__ */
@@ -94,29 +99,39 @@ static inline void shutdown_jiffies_counter(void)
static inline void startup_timestamp_counter(void)
{
+ u32 t32;
+
/* set up timer 4 & 5 cascaded as a 32-bit counter to count real time
* - count down from 4Gig-1 to 0 and wrap at IOCLK rate
*/
TM45BR = TMTSCBR_MAX;
+ t32 = TM45BR;
- TM4MD = TM4MD_SRC_IOCLK;
+ TM4MD = TSC_TIMER_CLKSRC;
TM4MD |= TM4MD_INIT_COUNTER;
TM4MD &= ~TM4MD_INIT_COUNTER;
TM4ICR = 0;
+ t32 = TM4ICR;
TM5MD = TM5MD_SRC_TM4CASCADE;
TM5MD |= TM5MD_INIT_COUNTER;
TM5MD &= ~TM5MD_INIT_COUNTER;
TM5ICR = 0;
+ t32 = TM5ICR;
TM5MD |= TM5MD_COUNT_ENABLE;
TM4MD |= TM4MD_COUNT_ENABLE;
+ t32 = TM5MD;
+ t32 = TM4MD;
}
static inline void shutdown_timestamp_counter(void)
{
+ u8 t8;
TM4MD = 0;
TM5MD = 0;
+ t8 = TM4MD;
+ t8 = TM5MD;
}
/*
@@ -127,7 +142,7 @@ typedef unsigned long cycles_t;
static inline cycles_t read_timestamp_counter(void)
{
- return (cycles_t)TMTSCBC;
+ return (cycles_t)~TMTSCBC;
}
#endif /* !__ASSEMBLY__ */
diff --git a/arch/mn10300/unit-asb2303/unit-init.c b/arch/mn10300/unit-asb2303/unit-init.c
index 70e8cb4ea266..834a76aa551a 100644
--- a/arch/mn10300/unit-asb2303/unit-init.c
+++ b/arch/mn10300/unit-asb2303/unit-init.c
@@ -31,6 +31,14 @@ asmlinkage void __init unit_init(void)
SET_XIRQ_TRIGGER(3, XIRQ_TRIGGER_HILEVEL);
SET_XIRQ_TRIGGER(4, XIRQ_TRIGGER_LOWLEVEL);
SET_XIRQ_TRIGGER(5, XIRQ_TRIGGER_LOWLEVEL);
+
+#ifdef CONFIG_EXT_SERIAL_IRQ_LEVEL
+ set_intr_level(XIRQ0, NUM2GxICR_LEVEL(CONFIG_EXT_SERIAL_IRQ_LEVEL));
+#endif
+
+#ifdef CONFIG_ETHERNET_IRQ_LEVEL
+ set_intr_level(XIRQ3, NUM2GxICR_LEVEL(CONFIG_ETHERNET_IRQ_LEVEL));
+#endif
}
/*
@@ -51,7 +59,7 @@ void __init unit_init_IRQ(void)
switch (GET_XIRQ_TRIGGER(extnum)) {
case XIRQ_TRIGGER_HILEVEL:
case XIRQ_TRIGGER_LOWLEVEL:
- set_intr_postackable(XIRQ2IRQ(extnum));
+ mn10300_set_lateack_irq_type(XIRQ2IRQ(extnum));
break;
default:
break;
diff --git a/arch/mn10300/unit-asb2305/include/unit/clock.h b/arch/mn10300/unit-asb2305/include/unit/clock.h
index 67be3f2eb18e..29e3425431cf 100644
--- a/arch/mn10300/unit-asb2305/include/unit/clock.h
+++ b/arch/mn10300/unit-asb2305/include/unit/clock.h
@@ -14,32 +14,11 @@
#ifndef __ASSEMBLY__
-#ifdef CONFIG_MN10300_RTC
-
-extern unsigned long mn10300_ioclk; /* IOCLK (crystal speed) in HZ */
-extern unsigned long mn10300_iobclk;
-extern unsigned long mn10300_tsc_per_HZ;
-
-#define MN10300_IOCLK mn10300_ioclk
-/* If this processors has a another clock, uncomment the below. */
-/* #define MN10300_IOBCLK mn10300_iobclk */
-
-#else /* !CONFIG_MN10300_RTC */
-
#define MN10300_IOCLK 33333333UL
/* #define MN10300_IOBCLK 66666666UL */
-#endif /* !CONFIG_MN10300_RTC */
-
-#define MN10300_JCCLK MN10300_IOCLK
-#define MN10300_TSCCLK MN10300_IOCLK
-
-#ifdef CONFIG_MN10300_RTC
-#define MN10300_TSC_PER_HZ mn10300_tsc_per_HZ
-#else /* !CONFIG_MN10300_RTC */
-#define MN10300_TSC_PER_HZ (MN10300_TSCCLK/HZ)
-#endif /* !CONFIG_MN10300_RTC */
-
#endif /* !__ASSEMBLY__ */
+#define MN10300_WDCLK MN10300_IOCLK
+
#endif /* _ASM_UNIT_CLOCK_H */
diff --git a/arch/mn10300/unit-asb2305/include/unit/serial.h b/arch/mn10300/unit-asb2305/include/unit/serial.h
index 8086cc092cec..88c08219315f 100644
--- a/arch/mn10300/unit-asb2305/include/unit/serial.h
+++ b/arch/mn10300/unit-asb2305/include/unit/serial.h
@@ -21,6 +21,11 @@
#define SERIAL_IRQ XIRQ0 /* Dual serial (PC16552) (Hi) */
/*
+ * The ASB2305 has an 18.432 MHz clock the UART
+ */
+#define BASE_BAUD (18432000 / 16)
+
+/*
* dispose of the /dev/ttyS0 serial port
*/
#ifndef CONFIG_GDBSTUB_ON_TTYSx
diff --git a/arch/mn10300/unit-asb2305/include/unit/timex.h b/arch/mn10300/unit-asb2305/include/unit/timex.h
index d1c72d59fa9f..758af30d1a16 100644
--- a/arch/mn10300/unit-asb2305/include/unit/timex.h
+++ b/arch/mn10300/unit-asb2305/include/unit/timex.h
@@ -1,6 +1,6 @@
-/* ASB2305 timer specifcations
+/* ASB2305-specific timer specifications
*
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2007, 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
@@ -17,67 +17,72 @@
#include <asm/timer-regs.h>
#include <unit/clock.h>
+#include <asm/param.h>
/*
* jiffies counter specifications
*/
#define TMJCBR_MAX 0xffff
-#define TMJCBC TM01BC
-
-#define TMJCMD TM01MD
-#define TMJCBR TM01BR
#define TMJCIRQ TM1IRQ
#define TMJCICR TM1ICR
-#define TMJCICR_LEVEL GxICR_LEVEL_5
#ifndef __ASSEMBLY__
-static inline void startup_jiffies_counter(void)
+#define MN10300_SRC_IOCLK MN10300_IOCLK
+
+#ifndef HZ
+# error HZ undeclared.
+#endif /* !HZ */
+/* use as little prescaling as possible to avoid losing accuracy */
+#if (MN10300_SRC_IOCLK + HZ / 2) / HZ - 1 <= TMJCBR_MAX
+# define IOCLK_PRESCALE 1
+# define JC_TIMER_CLKSRC TM0MD_SRC_IOCLK
+# define TSC_TIMER_CLKSRC TM4MD_SRC_IOCLK
+#elif (MN10300_SRC_IOCLK / 8 + HZ / 2) / HZ - 1 <= TMJCBR_MAX
+# define IOCLK_PRESCALE 8
+# define JC_TIMER_CLKSRC TM0MD_SRC_IOCLK_8
+# define TSC_TIMER_CLKSRC TM4MD_SRC_IOCLK_8
+#elif (MN10300_SRC_IOCLK / 32 + HZ / 2) / HZ - 1 <= TMJCBR_MAX
+# define IOCLK_PRESCALE 32
+# define JC_TIMER_CLKSRC TM0MD_SRC_IOCLK_32
+# define TSC_TIMER_CLKSRC TM4MD_SRC_IOCLK_32
+#else
+# error You lose.
+#endif
+
+#define MN10300_JCCLK (MN10300_SRC_IOCLK / IOCLK_PRESCALE)
+#define MN10300_TSCCLK (MN10300_SRC_IOCLK / IOCLK_PRESCALE)
+
+#define MN10300_JC_PER_HZ ((MN10300_JCCLK + HZ / 2) / HZ)
+#define MN10300_TSC_PER_HZ ((MN10300_TSCCLK + HZ / 2) / HZ)
+
+static inline void stop_jiffies_counter(void)
{
- unsigned rate;
- u16 md, t16;
-
- /* use as little prescaling as possible to avoid losing accuracy */
- md = TM0MD_SRC_IOCLK;
- rate = MN10300_JCCLK / HZ;
-
- if (rate > TMJCBR_MAX) {
- md = TM0MD_SRC_IOCLK_8;
- rate = MN10300_JCCLK / 8 / HZ;
-
- if (rate > TMJCBR_MAX) {
- md = TM0MD_SRC_IOCLK_32;
- rate = MN10300_JCCLK / 32 / HZ;
-
- if (rate > TMJCBR_MAX)
- BUG();
- }
- }
+ u16 tmp;
+ TM01MD = JC_TIMER_CLKSRC | TM1MD_SRC_TM0CASCADE << 8;
+ tmp = TM01MD;
+}
- TMJCBR = rate - 1;
- t16 = TMJCBR;
+static inline void reload_jiffies_counter(u32 cnt)
+{
+ u32 tmp;
- TMJCMD =
- md |
- TM1MD_SRC_TM0CASCADE << 8 |
- TM0MD_INIT_COUNTER |
- TM1MD_INIT_COUNTER << 8;
+ TM01BR = cnt;
+ tmp = TM01BR;
- TMJCMD =
- md |
- TM1MD_SRC_TM0CASCADE << 8 |
- TM0MD_COUNT_ENABLE |
- TM1MD_COUNT_ENABLE << 8;
+ TM01MD = JC_TIMER_CLKSRC | \
+ TM1MD_SRC_TM0CASCADE << 8 | \
+ TM0MD_INIT_COUNTER | \
+ TM1MD_INIT_COUNTER << 8;
- t16 = TMJCMD;
- TMJCICR |= GxICR_ENABLE | GxICR_DETECT | GxICR_REQUEST;
- t16 = TMJCICR;
-}
+ TM01MD = JC_TIMER_CLKSRC | \
+ TM1MD_SRC_TM0CASCADE << 8 | \
+ TM0MD_COUNT_ENABLE | \
+ TM1MD_COUNT_ENABLE << 8;
-static inline void shutdown_jiffies_counter(void)
-{
+ tmp = TM01MD;
}
#endif /* !__ASSEMBLY__ */
@@ -94,29 +99,39 @@ static inline void shutdown_jiffies_counter(void)
static inline void startup_timestamp_counter(void)
{
+ u32 t32;
+
/* set up timer 4 & 5 cascaded as a 32-bit counter to count real time
* - count down from 4Gig-1 to 0 and wrap at IOCLK rate
*/
TM45BR = TMTSCBR_MAX;
+ t32 = TM45BR;
- TM4MD = TM4MD_SRC_IOCLK;
+ TM4MD = TSC_TIMER_CLKSRC;
TM4MD |= TM4MD_INIT_COUNTER;
TM4MD &= ~TM4MD_INIT_COUNTER;
TM4ICR = 0;
+ t32 = TM4ICR;
TM5MD = TM5MD_SRC_TM4CASCADE;
TM5MD |= TM5MD_INIT_COUNTER;
TM5MD &= ~TM5MD_INIT_COUNTER;
TM5ICR = 0;
+ t32 = TM5ICR;
TM5MD |= TM5MD_COUNT_ENABLE;
TM4MD |= TM4MD_COUNT_ENABLE;
+ t32 = TM5MD;
+ t32 = TM4MD;
}
static inline void shutdown_timestamp_counter(void)
{
+ u8 t8;
TM4MD = 0;
TM5MD = 0;
+ t8 = TM4MD;
+ t8 = TM5MD;
}
/*
@@ -127,7 +142,7 @@ typedef unsigned long cycles_t;
static inline cycles_t read_timestamp_counter(void)
{
- return (cycles_t) TMTSCBC;
+ return (cycles_t)~TMTSCBC;
}
#endif /* !__ASSEMBLY__ */
diff --git a/arch/mn10300/unit-asb2305/pci-asb2305.c b/arch/mn10300/unit-asb2305/pci-asb2305.c
index 45b40ac6c464..8e6763e6f250 100644
--- a/arch/mn10300/unit-asb2305/pci-asb2305.c
+++ b/arch/mn10300/unit-asb2305/pci-asb2305.c
@@ -93,7 +93,7 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
struct pci_bus *bus;
struct pci_dev *dev;
int idx;
- struct resource *r, *pr;
+ struct resource *r;
/* Depth-First Search on bus tree */
list_for_each_entry(bus, bus_list, node) {
@@ -105,10 +105,8 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
r = &dev->resource[idx];
if (!r->flags)
continue;
- pr = pci_find_parent_resource(dev, r);
if (!r->start ||
- !pr ||
- request_resource(pr, r) < 0) {
+ pci_claim_resource(dev, idx) < 0) {
printk(KERN_ERR "PCI:"
" Cannot allocate resource"
" region %d of bridge %s\n",
@@ -131,7 +129,7 @@ static void __init pcibios_allocate_resources(int pass)
struct pci_dev *dev = NULL;
int idx, disabled;
u16 command;
- struct resource *r, *pr;
+ struct resource *r;
for_each_pci_dev(dev) {
pci_read_config_word(dev, PCI_COMMAND, &command);
@@ -150,8 +148,7 @@ static void __init pcibios_allocate_resources(int pass)
" (f=%lx, d=%d, p=%d)\n",
pci_name(dev), r->start, r->end, r->flags,
disabled, pass);
- pr = pci_find_parent_resource(dev, r);
- if (!pr || request_resource(pr, r) < 0) {
+ if (pci_claim_resource(dev, idx) < 0) {
printk(KERN_ERR "PCI:"
" Cannot allocate resource"
" region %d of device %s\n",
@@ -184,7 +181,7 @@ static void __init pcibios_allocate_resources(int pass)
static int __init pcibios_assign_resources(void)
{
struct pci_dev *dev = NULL;
- struct resource *r, *pr;
+ struct resource *r;
if (!(pci_probe & PCI_ASSIGN_ROMS)) {
/* Try to use BIOS settings for ROMs, otherwise let
@@ -194,8 +191,7 @@ static int __init pcibios_assign_resources(void)
r = &dev->resource[PCI_ROM_RESOURCE];
if (!r->flags || !r->start)
continue;
- pr = pci_find_parent_resource(dev, r);
- if (!pr || request_resource(pr, r) < 0) {
+ if (pci_claim_resource(dev, PCI_ROM_RESOURCE) < 0) {
r->end -= r->start;
r->start = 0;
}
diff --git a/arch/mn10300/unit-asb2305/pci.c b/arch/mn10300/unit-asb2305/pci.c
index 6d8720a0a599..a4954fe82094 100644
--- a/arch/mn10300/unit-asb2305/pci.c
+++ b/arch/mn10300/unit-asb2305/pci.c
@@ -503,7 +503,7 @@ asmlinkage void __init unit_pci_init(void)
struct pci_ops *o = &pci_direct_ampci;
u32 x;
- set_intr_level(XIRQ1, GxICR_LEVEL_3);
+ set_intr_level(XIRQ1, NUM2GxICR_LEVEL(CONFIG_PCI_IRQ_LEVEL));
memset(&bus, 0, sizeof(bus));
diff --git a/arch/mn10300/unit-asb2305/unit-init.c b/arch/mn10300/unit-asb2305/unit-init.c
index a76c8e0ab90f..e1becd6b7571 100644
--- a/arch/mn10300/unit-asb2305/unit-init.c
+++ b/arch/mn10300/unit-asb2305/unit-init.c
@@ -26,8 +26,10 @@ asmlinkage void __init unit_init(void)
{
#ifndef CONFIG_GDBSTUB_ON_TTYSx
/* set the 16550 interrupt line to level 3 if not being used for GDB */
- set_intr_level(XIRQ0, GxICR_LEVEL_3);
+#ifdef CONFIG_EXT_SERIAL_IRQ_LEVEL
+ set_intr_level(XIRQ0, NUM2GxICR_LEVEL(CONFIG_EXT_SERIAL_IRQ_LEVEL));
#endif
+#endif /* CONFIG_GDBSTUB_ON_TTYSx */
}
/*
@@ -51,7 +53,7 @@ void __init unit_init_IRQ(void)
switch (GET_XIRQ_TRIGGER(extnum)) {
case XIRQ_TRIGGER_HILEVEL:
case XIRQ_TRIGGER_LOWLEVEL:
- set_intr_postackable(XIRQ2IRQ(extnum));
+ mn10300_set_lateack_irq_type(XIRQ2IRQ(extnum));
break;
default:
break;
diff --git a/arch/mn10300/unit-asb2364/Makefile b/arch/mn10300/unit-asb2364/Makefile
new file mode 100644
index 000000000000..b3263ecfc4ff
--- /dev/null
+++ b/arch/mn10300/unit-asb2364/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+obj-y := unit-init.o leds.o irq-fpga.o
+
+obj-$(CONFIG_SMSC911X) += smsc911x.o
diff --git a/arch/mn10300/unit-asb2364/include/unit/clock.h b/arch/mn10300/unit-asb2364/include/unit/clock.h
new file mode 100644
index 000000000000..d34ac9a7508b
--- /dev/null
+++ b/arch/mn10300/unit-asb2364/include/unit/clock.h
@@ -0,0 +1,29 @@
+/* clock.h: unit-specific clocks
+ *
+ * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * Modified by Matsushita Electric Industrial Co., Ltd.
+ * Modifications:
+ * 23-Feb-2007 MEI Add define for watchdog timer.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_UNIT_CLOCK_H
+#define _ASM_UNIT_CLOCK_H
+
+#ifndef __ASSEMBLY__
+
+#define MN10300_IOCLK 100000000UL /* for DDR800 */
+/*#define MN10300_IOCLK 83333333UL */ /* for DDR667 */
+#define MN10300_IOBCLK MN10300_IOCLK /* IOBCLK is equal to IOCLK */
+
+#endif /* !__ASSEMBLY__ */
+
+#define MN10300_WDCLK 27000000UL
+
+#endif /* _ASM_UNIT_CLOCK_H */
diff --git a/arch/mn10300/unit-asb2364/include/unit/fpga-regs.h b/arch/mn10300/unit-asb2364/include/unit/fpga-regs.h
new file mode 100644
index 000000000000..7cf12054db65
--- /dev/null
+++ b/arch/mn10300/unit-asb2364/include/unit/fpga-regs.h
@@ -0,0 +1,52 @@
+/* ASB2364 FPGA registers
+ */
+
+#ifndef _ASM_UNIT_FPGA_REGS_H
+#define _ASM_UNIT_FPGA_REGS_H
+
+#include <asm/cpu-regs.h>
+
+#ifdef __KERNEL__
+
+#define ASB2364_FPGA_REG_RESET_LAN __SYSREG(0xa9001300, u16)
+#define ASB2364_FPGA_REG_RESET_UART __SYSREG(0xa9001304, u16)
+#define ASB2364_FPGA_REG_RESET_I2C __SYSREG(0xa9001308, u16)
+#define ASB2364_FPGA_REG_RESET_USB __SYSREG(0xa900130c, u16)
+#define ASB2364_FPGA_REG_RESET_AV __SYSREG(0xa9001310, u16)
+
+#define ASB2364_FPGA_REG_IRQ(X) __SYSREG(0xa9001590+((X)*4), u16)
+#define ASB2364_FPGA_REG_IRQ_LAN ASB2364_FPGA_REG_IRQ(0)
+#define ASB2364_FPGA_REG_IRQ_UART ASB2364_FPGA_REG_IRQ(1)
+#define ASB2364_FPGA_REG_IRQ_I2C ASB2364_FPGA_REG_IRQ(2)
+#define ASB2364_FPGA_REG_IRQ_USB ASB2364_FPGA_REG_IRQ(3)
+#define ASB2364_FPGA_REG_IRQ_FPGA ASB2364_FPGA_REG_IRQ(5)
+
+#define ASB2364_FPGA_REG_MASK(X) __SYSREG(0xa9001590+((X)*4), u16)
+#define ASB2364_FPGA_REG_MASK_LAN ASB2364_FPGA_REG_MASK(0)
+#define ASB2364_FPGA_REG_MASK_UART ASB2364_FPGA_REG_MASK(1)
+#define ASB2364_FPGA_REG_MASK_I2C ASB2364_FPGA_REG_MASK(2)
+#define ASB2364_FPGA_REG_MASK_USB ASB2364_FPGA_REG_MASK(3)
+#define ASB2364_FPGA_REG_MASK_FPGA ASB2364_FPGA_REG_MASK(5)
+
+#define ASB2364_FPGA_REG_CPLD5_SET1 __SYSREG(0xa9002500, u16)
+#define ASB2364_FPGA_REG_CPLD5_SET2 __SYSREG(0xa9002504, u16)
+#define ASB2364_FPGA_REG_CPLD6_SET1 __SYSREG(0xa9002600, u16)
+#define ASB2364_FPGA_REG_CPLD6_SET2 __SYSREG(0xa9002604, u16)
+#define ASB2364_FPGA_REG_CPLD7_SET1 __SYSREG(0xa9002700, u16)
+#define ASB2364_FPGA_REG_CPLD7_SET2 __SYSREG(0xa9002704, u16)
+#define ASB2364_FPGA_REG_CPLD8_SET1 __SYSREG(0xa9002800, u16)
+#define ASB2364_FPGA_REG_CPLD8_SET2 __SYSREG(0xa9002804, u16)
+#define ASB2364_FPGA_REG_CPLD9_SET1 __SYSREG(0xa9002900, u16)
+#define ASB2364_FPGA_REG_CPLD9_SET2 __SYSREG(0xa9002904, u16)
+#define ASB2364_FPGA_REG_CPLD10_SET1 __SYSREG(0xa9002a00, u16)
+#define ASB2364_FPGA_REG_CPLD10_SET2 __SYSREG(0xa9002a04, u16)
+
+#define SyncExBus() \
+ do { \
+ unsigned short w; \
+ w = *(volatile short *)0xa9000000; \
+ } while (0)
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_UNIT_FPGA_REGS_H */
diff --git a/arch/mn10300/unit-asb2364/include/unit/irq.h b/arch/mn10300/unit-asb2364/include/unit/irq.h
new file mode 100644
index 000000000000..786148e46565
--- /dev/null
+++ b/arch/mn10300/unit-asb2364/include/unit/irq.h
@@ -0,0 +1,35 @@
+/* ASB2364 FPGA irq numbers
+ *
+ * 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 _UNIT_IRQ_H
+#define _UNIT_IRQ_H
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_SMP
+#define NR_CPU_IRQS GxICR_NUM_EXT_IRQS
+#else
+#define NR_CPU_IRQS GxICR_NUM_IRQS
+#endif
+
+enum {
+ FPGA_LAN_IRQ = NR_CPU_IRQS,
+ FPGA_UART_IRQ,
+ FPGA_I2C_IRQ,
+ FPGA_USB_IRQ,
+ FPGA_RESERVED_IRQ,
+ FPGA_FPGA_IRQ,
+ NR_IRQS
+};
+
+extern void __init irq_fpga_init(void);
+
+#endif /* !__ASSEMBLY__ */
+#endif /* _UNIT_IRQ_H */
diff --git a/arch/mn10300/unit-asb2364/include/unit/leds.h b/arch/mn10300/unit-asb2364/include/unit/leds.h
new file mode 100644
index 000000000000..03a3933ad323
--- /dev/null
+++ b/arch/mn10300/unit-asb2364/include/unit/leds.h
@@ -0,0 +1,54 @@
+/* Unit-specific leds
+ *
+ * Copyright (C) 2005 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_UNIT_LEDS_H
+#define _ASM_UNIT_LEDS_H
+
+#include <asm/pio-regs.h>
+#include <asm/cpu-regs.h>
+#include <asm/exceptions.h>
+
+#define MN10300_USE_7SEGLEDS 0
+
+#define ASB2364_7SEGLEDS __SYSREG(0xA9001630, u32)
+
+/*
+ * use the 7-segment LEDs to indicate states
+ */
+
+#if MN10300_USE_7SEGLEDS
+/* flip the 7-segment LEDs between "Gdb-" and "----" */
+#define mn10300_set_gdbleds(ONOFF) \
+ do { \
+ ASB2364_7SEGLEDS = (ONOFF) ? 0x8543077f : 0x7f7f7f7f; \
+ } while (0)
+#else
+#define mn10300_set_gdbleds(ONOFF) do {} while (0)
+#endif
+
+#if MN10300_USE_7SEGLEDS
+/* indicate double-fault by displaying "db-f" on the LEDs */
+#define mn10300_set_dbfleds \
+ mov 0x43077f1d,d0 ; \
+ mov d0,(ASB2364_7SEGLEDS)
+#else
+#define mn10300_set_dbfleds
+#endif
+
+#ifndef __ASSEMBLY__
+extern void peripheral_leds_display_exception(enum exception_code);
+extern void peripheral_leds_led_chase(void);
+extern void peripheral_leds7x4_display_dec(unsigned int, unsigned int);
+extern void peripheral_leds7x4_display_hex(unsigned int, unsigned int);
+extern void debug_to_serial(const char *, int);
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_UNIT_LEDS_H */
diff --git a/arch/mn10300/unit-asb2364/include/unit/serial.h b/arch/mn10300/unit-asb2364/include/unit/serial.h
new file mode 100644
index 000000000000..7f048bbfdfd7
--- /dev/null
+++ b/arch/mn10300/unit-asb2364/include/unit/serial.h
@@ -0,0 +1,151 @@
+/* Unit-specific 8250 serial ports
+ *
+ * Copyright (C) 2005 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_UNIT_SERIAL_H
+#define _ASM_UNIT_SERIAL_H
+
+#include <asm/cpu-regs.h>
+#include <proc/irq.h>
+#include <unit/fpga-regs.h>
+#include <linux/serial_reg.h>
+
+#define SERIAL_PORT0_BASE_ADDRESS 0xA8200000
+
+#define SERIAL_IRQ XIRQ1 /* single serial (TL16C550C) (Lo) */
+
+/*
+ * The ASB2364 has an 12.288 MHz clock
+ * for your UART.
+ *
+ * It'd be nice if someone built a serial card with a 24.576 MHz
+ * clock, since the 16550A is capable of handling a top speed of 1.5
+ * megabits/second; but this requires the faster clock.
+ */
+#define BASE_BAUD (12288000 / 16)
+
+/*
+ * dispose of the /dev/ttyS0 and /dev/ttyS1 serial ports
+ */
+#ifndef CONFIG_GDBSTUB_ON_TTYSx
+
+#define SERIAL_PORT_DFNS \
+ { \
+ .baud_base = BASE_BAUD, \
+ .irq = SERIAL_IRQ, \
+ .flags = STD_COM_FLAGS, \
+ .iomem_base = (u8 *) SERIAL_PORT0_BASE_ADDRESS, \
+ .iomem_reg_shift = 1, \
+ .io_type = SERIAL_IO_MEM, \
+ },
+
+#ifndef __ASSEMBLY__
+
+static inline void __debug_to_serial(const char *p, int n)
+{
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#else /* CONFIG_GDBSTUB_ON_TTYSx */
+
+#define SERIAL_PORT_DFNS /* stolen by gdb-stub */
+
+#if defined(CONFIG_GDBSTUB_ON_TTYS0)
+#define GDBPORT_SERIAL_RX __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_RX * 4, u8)
+#define GDBPORT_SERIAL_TX __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_TX * 4, u8)
+#define GDBPORT_SERIAL_DLL __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_DLL * 4, u8)
+#define GDBPORT_SERIAL_DLM __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_DLM * 4, u8)
+#define GDBPORT_SERIAL_IER __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_IER * 4, u8)
+#define GDBPORT_SERIAL_IIR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_IIR * 4, u8)
+#define GDBPORT_SERIAL_FCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_FCR * 4, u8)
+#define GDBPORT_SERIAL_LCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_LCR * 4, u8)
+#define GDBPORT_SERIAL_MCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_MCR * 4, u8)
+#define GDBPORT_SERIAL_LSR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_LSR * 4, u8)
+#define GDBPORT_SERIAL_MSR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_MSR * 4, u8)
+#define GDBPORT_SERIAL_SCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_SCR * 4, u8)
+#define GDBPORT_SERIAL_IRQ SERIAL_IRQ
+
+#elif defined(CONFIG_GDBSTUB_ON_TTYS1)
+#error The ASB2364 does not have a /dev/ttyS1
+#endif
+
+#ifndef __ASSEMBLY__
+
+static inline void __debug_to_serial(const char *p, int n)
+{
+ char ch;
+
+#define LSR_WAIT_FOR(STATE) \
+ do {} while (!(GDBPORT_SERIAL_LSR & UART_LSR_##STATE))
+#define FLOWCTL_QUERY(LINE) \
+ ({ GDBPORT_SERIAL_MSR & UART_MSR_##LINE; })
+#define FLOWCTL_WAIT_FOR(LINE) \
+ do {} while (!(GDBPORT_SERIAL_MSR & UART_MSR_##LINE))
+#define FLOWCTL_CLEAR(LINE) \
+ do { GDBPORT_SERIAL_MCR &= ~UART_MCR_##LINE; } while (0)
+#define FLOWCTL_SET(LINE) \
+ do { GDBPORT_SERIAL_MCR |= UART_MCR_##LINE; } while (0)
+
+ FLOWCTL_SET(DTR);
+
+ for (; n > 0; n--) {
+ LSR_WAIT_FOR(THRE);
+ FLOWCTL_WAIT_FOR(CTS);
+
+ ch = *p++;
+ if (ch == 0x0a) {
+ GDBPORT_SERIAL_TX = 0x0d;
+ LSR_WAIT_FOR(THRE);
+ FLOWCTL_WAIT_FOR(CTS);
+ }
+ GDBPORT_SERIAL_TX = ch;
+ }
+
+ FLOWCTL_CLEAR(DTR);
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* CONFIG_GDBSTUB_ON_TTYSx */
+
+#define SERIAL_INITIALIZE \
+do { \
+ /* release reset */ \
+ ASB2364_FPGA_REG_RESET_UART = 0x0001; \
+ SyncExBus(); \
+} while (0)
+
+#define SERIAL_CHECK_INTERRUPT \
+do { \
+ if ((ASB2364_FPGA_REG_IRQ_UART & 0x0001) == 0x0001) { \
+ return IRQ_NONE; \
+ } \
+} while (0)
+
+#define SERIAL_CLEAR_INTERRUPT \
+do { \
+ ASB2364_FPGA_REG_IRQ_UART = 0x0001; \
+ SyncExBus(); \
+} while (0)
+
+#define SERIAL_SET_INT_MASK \
+do { \
+ ASB2364_FPGA_REG_MASK_UART = 0x0001; \
+ SyncExBus(); \
+} while (0)
+
+#define SERIAL_CLEAR_INT_MASK \
+do { \
+ ASB2364_FPGA_REG_MASK_UART = 0x0000; \
+ SyncExBus(); \
+} while (0)
+
+#endif /* _ASM_UNIT_SERIAL_H */
diff --git a/arch/mn10300/unit-asb2364/include/unit/smsc911x.h b/arch/mn10300/unit-asb2364/include/unit/smsc911x.h
new file mode 100644
index 000000000000..4c1ede535fa9
--- /dev/null
+++ b/arch/mn10300/unit-asb2364/include/unit/smsc911x.h
@@ -0,0 +1,171 @@
+/* Support for the SMSC911x NIC
+ *
+ * Copyright (C) 2006 Matsushita Electric Industrial Co., Ltd.
+ * 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.
+ */
+#ifndef _ASM_UNIT_SMSC911X_H
+#define _ASM_UNIT_SMSC911X_H
+
+#include <linux/netdevice.h>
+#include <proc/irq.h>
+#include <unit/fpga-regs.h>
+
+#define MN10300_USE_EXT_EEPROM
+
+
+#define SMSC911X_BASE 0xA8000000UL
+#define SMSC911X_BASE_END 0xA8000100UL
+#define SMSC911X_IRQ FPGA_LAN_IRQ
+
+/*
+ * Allow the FPGA to be initialised by the SMSC911x driver
+ */
+#undef SMSC_INITIALIZE
+#define SMSC_INITIALIZE() \
+do { \
+ /* release reset */ \
+ ASB2364_FPGA_REG_RESET_LAN = 0x0001; \
+ SyncExBus(); \
+} while (0)
+
+#ifdef MN10300_USE_EXT_EEPROM
+#include <linux/delay.h>
+#include <unit/clock.h>
+
+#define EEPROM_ADDRESS 0xA0
+#define MAC_OFFSET 0x0008
+#define USE_IIC_CH 0 /* 0 or 1 */
+#define IIC_OFFSET (0x80000 * USE_IIC_CH)
+#define IIC_DTRM __SYSREG(0xd8400000 + IIC_OFFSET, u32)
+#define IIC_DREC __SYSREG(0xd8400004 + IIC_OFFSET, u32)
+#define IIC_MYADD __SYSREG(0xd8400008 + IIC_OFFSET, u32)
+#define IIC_CLK __SYSREG(0xd840000c + IIC_OFFSET, u32)
+#define IIC_BRST __SYSREG(0xd8400010 + IIC_OFFSET, u32)
+#define IIC_HOLD __SYSREG(0xd8400014 + IIC_OFFSET, u32)
+#define IIC_BSTS __SYSREG(0xd8400018 + IIC_OFFSET, u32)
+#define IIC_ICR __SYSREG(0xd4000080 + 4 * USE_IIC_CH, u16)
+
+#define IIC_CLK_PLS ((unsigned short)(MN10300_IOCLK / 100000 - 1))
+#define IIC_CLK_LOW ((unsigned short)(IIC_CLK_PLS / 2))
+
+#define SYS_IIC_DTRM_Bit_STA ((unsigned short)0x0400)
+#define SYS_IIC_DTRM_Bit_STO ((unsigned short)0x0200)
+#define SYS_IIC_DTRM_Bit_ACK ((unsigned short)0x0100)
+#define SYS_IIC_DTRM_Bit_DATA ((unsigned short)0x00FF)
+
+static inline void POLL_INT_REQ(volatile u16 *icr)
+{
+ unsigned long flags;
+ u16 tmp;
+
+ while (!(*icr & GxICR_REQUEST))
+ ;
+ flags = arch_local_cli_save();
+ tmp = *icr;
+ *icr = (tmp & GxICR_LEVEL) | GxICR_DETECT;
+ tmp = *icr;
+ arch_local_irq_restore(flags);
+}
+
+/*
+ * Implement the SMSC911x hook for MAC address retrieval
+ */
+#undef smsc_get_mac
+static inline int smsc_get_mac(struct net_device *dev)
+{
+ unsigned char *mac_buf = dev->dev_addr;
+ int i;
+ unsigned short value;
+ unsigned int data;
+ int mac_length = 6;
+ int check;
+ u16 orig_gicr, tmp;
+ unsigned long flags;
+
+ /* save original GnICR and clear GnICR.IE */
+ flags = arch_local_cli_save();
+ orig_gicr = IIC_ICR;
+ IIC_ICR = orig_gicr & GxICR_LEVEL;
+ tmp = IIC_ICR;
+ arch_local_irq_restore(flags);
+
+ IIC_MYADD = 0x00000008;
+ IIC_CLK = (IIC_CLK_LOW << 16) + (IIC_CLK_PLS);
+ /* bus hung recovery */
+
+ while (1) {
+ check = 0;
+ for (i = 0; i < 3; i++) {
+ if ((IIC_BSTS & 0x00000003) == 0x00000003)
+ check++;
+ udelay(3);
+ }
+
+ if (check == 3) {
+ IIC_BRST = 0x00000003;
+ break;
+ } else {
+ for (i = 0; i < 3; i++) {
+ IIC_BRST = 0x00000002;
+ udelay(8);
+ IIC_BRST = 0x00000003;
+ udelay(8);
+ }
+ }
+ }
+
+ IIC_BRST = 0x00000002;
+ IIC_BRST = 0x00000003;
+
+ value = SYS_IIC_DTRM_Bit_STA | SYS_IIC_DTRM_Bit_ACK;
+ value |= (((unsigned short)EEPROM_ADDRESS & SYS_IIC_DTRM_Bit_DATA) |
+ (unsigned short)0x0000);
+ IIC_DTRM = value;
+ POLL_INT_REQ(&IIC_ICR);
+
+ /** send offset of MAC address in EEPROM **/
+ IIC_DTRM = (unsigned char)((MAC_OFFSET & 0xFF00) >> 8);
+ POLL_INT_REQ(&IIC_ICR);
+
+ IIC_DTRM = (unsigned char)(MAC_OFFSET & 0x00FF);
+ POLL_INT_REQ(&IIC_ICR);
+
+ udelay(1000);
+
+ value = SYS_IIC_DTRM_Bit_STA;
+ value |= (((unsigned short)EEPROM_ADDRESS & SYS_IIC_DTRM_Bit_DATA) |
+ (unsigned short)0x0001);
+ IIC_DTRM = value;
+ POLL_INT_REQ(&IIC_ICR);
+
+ IIC_DTRM = 0x00000000;
+ while (mac_length > 0) {
+ POLL_INT_REQ(&IIC_ICR);
+
+ data = IIC_DREC;
+ mac_length--;
+ if (mac_length == 0)
+ value = 0x00000300; /* stop IIC bus */
+ else if (mac_length == 1)
+ value = 0x00000100; /* no ack */
+ else
+ value = 0x00000000; /* ack */
+ IIC_DTRM = value;
+ *mac_buf++ = (unsigned char)(data & 0xff);
+ }
+
+ /* restore GnICR.LV and GnICR.IE */
+ flags = arch_local_cli_save();
+ IIC_ICR = (orig_gicr & (GxICR_LEVEL | GxICR_ENABLE));
+ tmp = IIC_ICR;
+ arch_local_irq_restore(flags);
+
+ return 0;
+}
+#endif /* MN10300_USE_EXT_EEPROM */
+#endif /* _ASM_UNIT_SMSC911X_H */
diff --git a/arch/mn10300/unit-asb2364/include/unit/timex.h b/arch/mn10300/unit-asb2364/include/unit/timex.h
new file mode 100644
index 000000000000..ddb7ed010706
--- /dev/null
+++ b/arch/mn10300/unit-asb2364/include/unit/timex.h
@@ -0,0 +1,159 @@
+/* timex.h: MN2WS0038 architecture timer specifications
+ *
+ * Copyright (C) 2002, 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_UNIT_TIMEX_H
+#define _ASM_UNIT_TIMEX_H
+
+#ifndef __ASSEMBLY__
+#include <linux/irq.h>
+#endif /* __ASSEMBLY__ */
+
+#include <asm/timer-regs.h>
+#include <unit/clock.h>
+#include <asm/param.h>
+
+/*
+ * jiffies counter specifications
+ */
+
+#define TMJCBR_MAX 0xffffff /* 24bit */
+#define TMJCIRQ TMTIRQ
+
+#ifndef __ASSEMBLY__
+
+#define MN10300_SRC_IOBCLK MN10300_IOBCLK
+
+#ifndef HZ
+# error HZ undeclared.
+#endif /* !HZ */
+
+#define MN10300_JCCLK (MN10300_SRC_IOBCLK)
+#define MN10300_TSCCLK (MN10300_SRC_IOBCLK)
+
+#define MN10300_JC_PER_HZ ((MN10300_JCCLK + HZ / 2) / HZ)
+#define MN10300_TSC_PER_HZ ((MN10300_TSCCLK + HZ / 2) / HZ)
+
+/* Check bit width of MTM interval value that sets base register */
+#if (MN10300_JC_PER_HZ - 1) > TMJCBR_MAX
+# error MTM tick timer interval value is overflow.
+#endif
+
+static inline void stop_jiffies_counter(void)
+{
+ u16 tmp;
+ TMTMD = 0;
+ tmp = TMTMD;
+}
+
+static inline void reload_jiffies_counter(u32 cnt)
+{
+ u32 tmp;
+
+ TMTBR = cnt;
+ tmp = TMTBR;
+
+ TMTMD = TMTMD_TMTLDE;
+ TMTMD = TMTMD_TMTCNE;
+ tmp = TMTMD;
+}
+
+#if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_CLOCKEVENTS) && \
+ !defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
+/*
+ * If we aren't using broadcasting, each core needs its own event timer.
+ * Since CPU0 uses the tick timer which is 24-bits, we use timer 4 & 5
+ * cascaded to 32-bits for CPU1 (but only really use 24-bits to match
+ * CPU0).
+ */
+
+#define TMJC1IRQ TM5IRQ
+
+static inline void stop_jiffies_counter1(void)
+{
+ u8 tmp;
+ TM4MD = 0;
+ TM5MD = 0;
+ tmp = TM4MD;
+ tmp = TM5MD;
+}
+
+static inline void reload_jiffies_counter1(u32 cnt)
+{
+ u32 tmp;
+
+ TM45BR = cnt;
+ tmp = TM45BR;
+
+ TM4MD = TM4MD_INIT_COUNTER;
+ tmp = TM4MD;
+
+ TM5MD = TM5MD_SRC_TM4CASCADE | TM5MD_INIT_COUNTER;
+ TM5MD = TM5MD_SRC_TM4CASCADE | TM5MD_COUNT_ENABLE;
+ tmp = TM5MD;
+
+ TM4MD = TM4MD_COUNT_ENABLE;
+ tmp = TM4MD;
+}
+#endif /* CONFIG_SMP&GENERIC_CLOCKEVENTS&!GENERIC_CLOCKEVENTS_BROADCAST */
+
+#endif /* !__ASSEMBLY__ */
+
+
+/*
+ * timestamp counter specifications
+ */
+#define TMTSCBR_MAX 0xffffffff
+
+#ifndef __ASSEMBLY__
+
+/* Use 32-bit timestamp counter */
+#define TMTSCMD TMSMD
+#define TMTSCBR TMSBR
+#define TMTSCBC TMSBC
+#define TMTSCICR TMSICR
+
+static inline void startup_timestamp_counter(void)
+{
+ u32 sync;
+
+ /* set up TMS(Timestamp) 32bit timer register to count real time
+ * - count down from 4Gig-1 to 0 and wrap at IOBCLK rate
+ */
+
+ TMTSCBR = TMTSCBR_MAX;
+ sync = TMTSCBR;
+
+ TMTSCICR = 0;
+ sync = TMTSCICR;
+
+ TMTSCMD = TMTMD_TMTLDE;
+ TMTSCMD = TMTMD_TMTCNE;
+ sync = TMTSCMD;
+}
+
+static inline void shutdown_timestamp_counter(void)
+{
+ TMTSCMD = 0;
+}
+
+/*
+ * we use a cascaded pair of 16-bit down-counting timers to count I/O
+ * clock cycles for the purposes of time keeping
+ */
+typedef unsigned long cycles_t;
+
+static inline cycles_t read_timestamp_counter(void)
+{
+ return (cycles_t)~TMTSCBC;
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_UNIT_TIMEX_H */
diff --git a/arch/mn10300/unit-asb2364/irq-fpga.c b/arch/mn10300/unit-asb2364/irq-fpga.c
new file mode 100644
index 000000000000..fcf29754e4d1
--- /dev/null
+++ b/arch/mn10300/unit-asb2364/irq-fpga.c
@@ -0,0 +1,96 @@
+/* ASB2364 FPGA interrupt multiplexing
+ *
+ * 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.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <unit/fpga-regs.h>
+
+/*
+ * FPGA PIC operations
+ */
+static void asb2364_fpga_mask(unsigned int irq)
+{
+ ASB2364_FPGA_REG_MASK(irq - NR_CPU_IRQS) = 0x0001;
+ SyncExBus();
+}
+
+static void asb2364_fpga_ack(unsigned int irq)
+{
+ ASB2364_FPGA_REG_IRQ(irq - NR_CPU_IRQS) = 0x0001;
+ SyncExBus();
+}
+
+static void asb2364_fpga_mask_ack(unsigned int irq)
+{
+ ASB2364_FPGA_REG_MASK(irq - NR_CPU_IRQS) = 0x0001;
+ SyncExBus();
+ ASB2364_FPGA_REG_IRQ(irq - NR_CPU_IRQS) = 0x0001;
+ SyncExBus();
+}
+
+static void asb2364_fpga_unmask(unsigned int irq)
+{
+ ASB2364_FPGA_REG_MASK(irq - NR_CPU_IRQS) = 0x0000;
+ SyncExBus();
+}
+
+static struct irq_chip asb2364_fpga_pic = {
+ .name = "fpga",
+ .ack = asb2364_fpga_ack,
+ .mask = asb2364_fpga_mask,
+ .mask_ack = asb2364_fpga_mask_ack,
+ .unmask = asb2364_fpga_unmask,
+};
+
+/*
+ * FPGA PIC interrupt handler
+ */
+static irqreturn_t fpga_interrupt(int irq, void *_mask)
+{
+ if ((ASB2364_FPGA_REG_IRQ_LAN & 0x0001) != 0x0001)
+ generic_handle_irq(FPGA_LAN_IRQ);
+ if ((ASB2364_FPGA_REG_IRQ_UART & 0x0001) != 0x0001)
+ generic_handle_irq(FPGA_UART_IRQ);
+ if ((ASB2364_FPGA_REG_IRQ_I2C & 0x0001) != 0x0001)
+ generic_handle_irq(FPGA_I2C_IRQ);
+ if ((ASB2364_FPGA_REG_IRQ_USB & 0x0001) != 0x0001)
+ generic_handle_irq(FPGA_USB_IRQ);
+ if ((ASB2364_FPGA_REG_IRQ_FPGA & 0x0001) != 0x0001)
+ generic_handle_irq(FPGA_FPGA_IRQ);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * Define an interrupt action for each FPGA PIC output
+ */
+static struct irqaction fpga_irq[] = {
+ [0] = {
+ .handler = fpga_interrupt,
+ .flags = IRQF_DISABLED | IRQF_SHARED,
+ .name = "fpga",
+ },
+};
+
+/*
+ * Initialise the FPGA's PIC
+ */
+void __init irq_fpga_init(void)
+{
+ int irq;
+
+ for (irq = NR_CPU_IRQS; irq < NR_IRQS; irq++)
+ set_irq_chip_and_handler(irq, &asb2364_fpga_pic, handle_level_irq);
+
+ /* the FPGA drives the XIRQ1 input on the CPU PIC */
+ setup_irq(XIRQ1, &fpga_irq[0]);
+}
diff --git a/arch/mn10300/unit-asb2364/leds.c b/arch/mn10300/unit-asb2364/leds.c
new file mode 100644
index 000000000000..1ff830c372b3
--- /dev/null
+++ b/arch/mn10300/unit-asb2364/leds.c
@@ -0,0 +1,98 @@
+/* leds.c: ASB2364 peripheral 7seg LEDs x4 support
+ *
+ * Copyright (C) 2002 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 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/param.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/intctl-regs.h>
+#include <asm/rtc-regs.h>
+#include <unit/leds.h>
+
+#if MN10300_USE_7SEGLEDS
+static const u8 asb2364_led_hex_tbl[16] = {
+ 0x80, 0xf2, 0x48, 0x60, 0x32, 0x24, 0x04, 0xf0,
+ 0x00, 0x20, 0x10, 0x06, 0x8c, 0x42, 0x0c, 0x1c
+};
+
+static const u32 asb2364_led_chase_tbl[6] = {
+ ~0x02020202, /* top - segA */
+ ~0x04040404, /* right top - segB */
+ ~0x08080808, /* right bottom - segC */
+ ~0x10101010, /* bottom - segD */
+ ~0x20202020, /* left bottom - segE */
+ ~0x40404040, /* left top - segF */
+};
+
+static unsigned asb2364_led_chase;
+
+void peripheral_leds7x4_display_dec(unsigned int val, unsigned int points)
+{
+ u32 leds;
+
+ leds = asb2364_led_hex_tbl[(val/1000) % 10];
+ leds <<= 8;
+ leds |= asb2364_led_hex_tbl[(val/100) % 10];
+ leds <<= 8;
+ leds |= asb2364_led_hex_tbl[(val/10) % 10];
+ leds <<= 8;
+ leds |= asb2364_led_hex_tbl[val % 10];
+ leds |= points^0x01010101;
+
+ ASB2364_7SEGLEDS = leds;
+}
+
+void peripheral_leds7x4_display_hex(unsigned int val, unsigned int points)
+{
+ u32 leds;
+
+ leds = asb2364_led_hex_tbl[(val/1000) % 10];
+ leds <<= 8;
+ leds |= asb2364_led_hex_tbl[(val/100) % 10];
+ leds <<= 8;
+ leds |= asb2364_led_hex_tbl[(val/10) % 10];
+ leds <<= 8;
+ leds |= asb2364_led_hex_tbl[val % 10];
+ leds |= points^0x01010101;
+
+ ASB2364_7SEGLEDS = leds;
+}
+
+/* display triple horizontal bar and exception code */
+void peripheral_leds_display_exception(enum exception_code code)
+{
+ u32 leds;
+
+ leds = asb2364_led_hex_tbl[(code/0x100) % 0x10];
+ leds <<= 8;
+ leds |= asb2364_led_hex_tbl[(code/0x10) % 0x10];
+ leds <<= 8;
+ leds |= asb2364_led_hex_tbl[code % 0x10];
+ leds |= 0x6d010101;
+
+ ASB2364_7SEGLEDS = leds;
+}
+
+void peripheral_leds_led_chase(void)
+{
+ ASB2364_7SEGLEDS = asb2364_led_chase_tbl[asb2364_led_chase];
+ asb2364_led_chase++;
+ if (asb2364_led_chase >= 6)
+ asb2364_led_chase = 0;
+}
+#else /* MN10300_USE_7SEGLEDS */
+void peripheral_leds7x4_display_dec(unsigned int val, unsigned int points) { }
+void peripheral_leds7x4_display_hex(unsigned int val, unsigned int points) { }
+void peripheral_leds_display_exception(enum exception_code code) { }
+void peripheral_leds_led_chase(void) { }
+#endif /* MN10300_USE_7SEGLEDS */
diff --git a/arch/mn10300/unit-asb2364/smsc911x.c b/arch/mn10300/unit-asb2364/smsc911x.c
new file mode 100644
index 000000000000..544a73e94c81
--- /dev/null
+++ b/arch/mn10300/unit-asb2364/smsc911x.c
@@ -0,0 +1,58 @@
+/* Specification for the SMSC911x NIC
+ *
+ * Copyright (C) 2006 Matsushita Electric Industrial Co., Ltd.
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/smsc911x.h>
+#include <unit/smsc911x.h>
+
+static struct smsc911x_platform_config smsc911x_config = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+ .flags = SMSC911X_USE_32BIT,
+};
+
+static struct resource smsc911x_resources[] = {
+ [0] = {
+ .start = SMSC911X_BASE,
+ .end = SMSC911X_BASE_END,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = SMSC911X_IRQ,
+ .end = SMSC911X_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smsc911x_device = {
+ .name = "smsc911x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smsc911x_resources),
+ .resource = smsc911x_resources,
+ .dev = {
+ .platform_data = &smsc911x_config,
+ }
+};
+
+/*
+ * add platform devices
+ */
+static int __init unit_device_init(void)
+{
+ platform_device_register(&smsc911x_device);
+ return 0;
+}
+
+device_initcall(unit_device_init);
diff --git a/arch/mn10300/unit-asb2364/unit-init.c b/arch/mn10300/unit-asb2364/unit-init.c
new file mode 100644
index 000000000000..11440803db10
--- /dev/null
+++ b/arch/mn10300/unit-asb2364/unit-init.c
@@ -0,0 +1,88 @@
+/* ASB2364 initialisation
+ *
+ * Copyright (C) 2002 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 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/param.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+
+#include <asm/io.h>
+#include <asm/setup.h>
+#include <asm/processor.h>
+#include <asm/irq.h>
+#include <asm/intctl-regs.h>
+#include <unit/fpga-regs.h>
+
+/*
+ * initialise some of the unit hardware before gdbstub is set up
+ */
+asmlinkage void __init unit_init(void)
+{
+ /* set up the external interrupts */
+
+ /* XIRQ[0]: NAND RXBY */
+ /* SET_XIRQ_TRIGGER(0, XIRQ_TRIGGER_LOWLEVEL); */
+
+ /* XIRQ[1]: LAN, UART, I2C, USB, PCI, FPGA */
+ SET_XIRQ_TRIGGER(1, XIRQ_TRIGGER_LOWLEVEL);
+
+ /* XIRQ[2]: Extend Slot 1-9 */
+ /* SET_XIRQ_TRIGGER(2, XIRQ_TRIGGER_LOWLEVEL); */
+
+#if defined(CONFIG_EXT_SERIAL_IRQ_LEVEL) && \
+ defined(CONFIG_ETHERNET_IRQ_LEVEL) && \
+ (CONFIG_EXT_SERIAL_IRQ_LEVEL != CONFIG_ETHERNET_IRQ_LEVEL)
+# error CONFIG_EXT_SERIAL_IRQ_LEVEL != CONFIG_ETHERNET_IRQ_LEVEL
+#endif
+
+#if defined(CONFIG_EXT_SERIAL_IRQ_LEVEL)
+ set_intr_level(XIRQ1, NUM2GxICR_LEVEL(CONFIG_EXT_SERIAL_IRQ_LEVEL));
+#elif defined(CONFIG_ETHERNET_IRQ_LEVEL)
+ set_intr_level(XIRQ1, NUM2GxICR_LEVEL(CONFIG_ETHERNET_IRQ_LEVEL));
+#endif
+}
+
+/*
+ * initialise the rest of the unit hardware after gdbstub is ready
+ */
+asmlinkage void __init unit_setup(void)
+{
+
+}
+
+/*
+ * initialise the external interrupts used by a unit of this type
+ */
+void __init unit_init_IRQ(void)
+{
+ unsigned int extnum;
+
+ for (extnum = 0 ; extnum < NR_XIRQS ; extnum++) {
+ switch (GET_XIRQ_TRIGGER(extnum)) {
+ /* LEVEL triggered interrupts should be made
+ * post-ACK'able as they hold their lines until
+ * serviced
+ */
+ case XIRQ_TRIGGER_HILEVEL:
+ case XIRQ_TRIGGER_LOWLEVEL:
+ mn10300_set_lateack_irq_type(XIRQ2IRQ(extnum));
+ break;
+ default:
+ break;
+ }
+ }
+
+#define IRQCTL __SYSREG(0xd5000090, u32)
+ IRQCTL |= 0x02;
+
+ irq_fpga_init();
+}
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 907417d187e1..0888675c98dd 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -1,10 +1,3 @@
-#
-# For a description of the syntax of this configuration file,
-# see Documentation/kbuild/kconfig-language.txt.
-#
-
-mainmenu "Linux/PA-RISC Kernel Configuration"
-
config PARISC
def_bool y
select HAVE_IDE
@@ -16,8 +9,10 @@ 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
+ select GENERIC_HARDIRQS_NO__DO_IRQ
help
The PA-RISC microprocessor is designed by Hewlett-Packard and used
in many of their workstations & servers (HP9000 700 and 800 series,
@@ -84,6 +79,9 @@ config IRQ_PER_CPU
bool
default y
+config GENERIC_HARDIRQS_NO__DO_IRQ
+ def_bool y
+
# unless you want to implement ACPI on PA-RISC ... ;-)
config PM
bool
diff --git a/arch/parisc/include/asm/cache.h b/arch/parisc/include/asm/cache.h
index 039880e7d2c9..47f11c707b65 100644
--- a/arch/parisc/include/asm/cache.h
+++ b/arch/parisc/include/asm/cache.h
@@ -24,8 +24,6 @@
#ifndef __ASSEMBLY__
-#define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
-
#define SMP_CACHE_BYTES L1_CACHE_BYTES
#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
diff --git a/arch/parisc/include/asm/cacheflush.h b/arch/parisc/include/asm/cacheflush.h
index dba11aedce1b..f388a85bba11 100644
--- a/arch/parisc/include/asm/cacheflush.h
+++ b/arch/parisc/include/asm/cacheflush.h
@@ -126,20 +126,20 @@ static inline void *kmap(struct page *page)
#define kunmap(page) kunmap_parisc(page_address(page))
-static inline void *kmap_atomic(struct page *page, enum km_type idx)
+static inline void *__kmap_atomic(struct page *page)
{
pagefault_disable();
return page_address(page);
}
-static inline void kunmap_atomic_notypecheck(void *addr, enum km_type idx)
+static inline void __kunmap_atomic(void *addr)
{
kunmap_parisc(addr);
pagefault_enable();
}
-#define kmap_atomic_prot(page, idx, prot) kmap_atomic(page, idx)
-#define kmap_atomic_pfn(pfn, idx) kmap_atomic(pfn_to_page(pfn), (idx))
+#define kmap_atomic_prot(page, prot) kmap_atomic(page)
+#define kmap_atomic_pfn(pfn) kmap_atomic(pfn_to_page(pfn))
#define kmap_atomic_to_page(ptr) virt_to_page(ptr)
#endif
diff --git a/arch/parisc/include/asm/irq.h b/arch/parisc/include/asm/irq.h
index dfa26b67f919..c67dccf2e31f 100644
--- a/arch/parisc/include/asm/irq.h
+++ b/arch/parisc/include/asm/irq.h
@@ -40,7 +40,7 @@ struct irq_chip;
void no_ack_irq(unsigned int irq);
void no_end_irq(unsigned int irq);
void cpu_ack_irq(unsigned int irq);
-void cpu_end_irq(unsigned int irq);
+void cpu_eoi_irq(unsigned int irq);
extern int txn_alloc_irq(unsigned int nbits);
extern int txn_claim_irq(int);
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/pgtable.h b/arch/parisc/include/asm/pgtable.h
index 01c15035e783..865f37a8a881 100644
--- a/arch/parisc/include/asm/pgtable.h
+++ b/arch/parisc/include/asm/pgtable.h
@@ -397,9 +397,7 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
#define pte_offset_kernel(pmd, address) \
((pte_t *) pmd_page_vaddr(*(pmd)) + pte_index(address))
#define pte_offset_map(pmd, address) pte_offset_kernel(pmd, address)
-#define pte_offset_map_nested(pmd, address) pte_offset_kernel(pmd, address)
#define pte_unmap(pte) do { } while (0)
-#define pte_unmap_nested(pte) do { } while (0)
#define pte_unmap(pte) do { } while (0)
#define pte_unmap_nested(pte) do { } while (0)
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/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h
index 1ce7d2851d90..3eb82c2a5ec3 100644
--- a/arch/parisc/include/asm/unistd.h
+++ b/arch/parisc/include/asm/unistd.h
@@ -813,8 +813,9 @@
#define __NR_perf_event_open (__NR_Linux + 318)
#define __NR_recvmmsg (__NR_Linux + 319)
#define __NR_accept4 (__NR_Linux + 320)
+#define __NR_prlimit64 (__NR_Linux + 321)
-#define __NR_Linux_syscalls (__NR_accept4 + 1)
+#define __NR_Linux_syscalls (__NR_prlimit64 + 1)
#define __IGNORE_select /* newselect */
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index efbcee5d2220..5024f643b3b1 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -52,7 +52,7 @@ static volatile unsigned long cpu_eiem = 0;
*/
static DEFINE_PER_CPU(unsigned long, local_ack_eiem) = ~0UL;
-static void cpu_disable_irq(unsigned int irq)
+static void cpu_mask_irq(unsigned int irq)
{
unsigned long eirr_bit = EIEM_MASK(irq);
@@ -63,7 +63,7 @@ static void cpu_disable_irq(unsigned int irq)
* then gets disabled */
}
-static void cpu_enable_irq(unsigned int irq)
+static void cpu_unmask_irq(unsigned int irq)
{
unsigned long eirr_bit = EIEM_MASK(irq);
@@ -75,12 +75,6 @@ static void cpu_enable_irq(unsigned int irq)
smp_send_all_nop();
}
-static unsigned int cpu_startup_irq(unsigned int irq)
-{
- cpu_enable_irq(irq);
- return 0;
-}
-
void no_ack_irq(unsigned int irq) { }
void no_end_irq(unsigned int irq) { }
@@ -99,7 +93,7 @@ void cpu_ack_irq(unsigned int irq)
mtctl(mask, 23);
}
-void cpu_end_irq(unsigned int irq)
+void cpu_eoi_irq(unsigned int irq)
{
unsigned long mask = EIEM_MASK(irq);
int cpu = smp_processor_id();
@@ -146,12 +140,10 @@ static int cpu_set_affinity_irq(unsigned int irq, const struct cpumask *dest)
static struct irq_chip cpu_interrupt_type = {
.name = "CPU",
- .startup = cpu_startup_irq,
- .shutdown = cpu_disable_irq,
- .enable = cpu_enable_irq,
- .disable = cpu_disable_irq,
+ .mask = cpu_mask_irq,
+ .unmask = cpu_unmask_irq,
.ack = cpu_ack_irq,
- .end = cpu_end_irq,
+ .eoi = cpu_eoi_irq,
#ifdef CONFIG_SMP
.set_affinity = cpu_set_affinity_irq,
#endif
@@ -247,10 +239,11 @@ int cpu_claim_irq(unsigned int irq, struct irq_chip *type, void *data)
if (irq_desc[irq].chip != &cpu_interrupt_type)
return -EBUSY;
+ /* for iosapic interrupts */
if (type) {
- irq_desc[irq].chip = type;
- irq_desc[irq].chip_data = data;
- cpu_interrupt_type.enable(irq);
+ set_irq_chip_and_handler(irq, type, handle_level_irq);
+ set_irq_chip_data(irq, data);
+ cpu_unmask_irq(irq);
}
return 0;
}
@@ -368,7 +361,7 @@ void do_cpu_irq_mask(struct pt_regs *regs)
goto set_out;
}
#endif
- __do_IRQ(irq);
+ generic_handle_irq(irq);
out:
irq_exit();
@@ -398,14 +391,15 @@ static void claim_cpu_irqs(void)
{
int i;
for (i = CPU_IRQ_BASE; i <= CPU_IRQ_MAX; i++) {
- irq_desc[i].chip = &cpu_interrupt_type;
+ set_irq_chip_and_handler(i, &cpu_interrupt_type,
+ handle_level_irq);
}
- irq_desc[TIMER_IRQ].action = &timer_action;
- irq_desc[TIMER_IRQ].status = IRQ_PER_CPU;
+ set_irq_handler(TIMER_IRQ, handle_percpu_irq);
+ setup_irq(TIMER_IRQ, &timer_action);
#ifdef CONFIG_SMP
- irq_desc[IPI_IRQ].action = &ipi_action;
- irq_desc[IPI_IRQ].status = IRQ_PER_CPU;
+ set_irq_handler(IPI_IRQ, handle_percpu_irq);
+ setup_irq(IPI_IRQ, &ipi_action);
#endif
}
@@ -423,3 +417,4 @@ void __init init_IRQ(void)
set_eiem(cpu_eiem); /* EIEM : enable all external intr */
}
+
diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c
index 1ff366cb9685..66d1f17fdb94 100644
--- a/arch/parisc/kernel/pdc_cons.c
+++ b/arch/parisc/kernel/pdc_cons.c
@@ -12,6 +12,7 @@
* Copyright (C) 2001 Helge Deller <deller at parisc-linux.org>
* Copyright (C) 2001 Thomas Bogendoerfer <tsbogend at parisc-linux.org>
* Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org>
+ * Copyright (C) 2010 Guy Martin <gmsoft at tuxicoman.be>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -31,12 +32,11 @@
/*
* The PDC console is a simple console, which can be used for debugging
- * boot related problems on HP PA-RISC machines.
+ * boot related problems on HP PA-RISC machines. It is also useful when no
+ * other console works.
*
* This code uses the ROM (=PDC) based functions to read and write characters
* from and to PDC's boot path.
- * Since all character read from that path must be polled, this code never
- * can or will be a fully functional linux console.
*/
/* Define EARLY_BOOTUP_DEBUG to debug kernel related boot problems.
@@ -53,6 +53,7 @@
#include <asm/pdc.h> /* for iodc_call() proto and friends */
static DEFINE_SPINLOCK(pdc_console_lock);
+static struct console pdc_cons;
static void pdc_console_write(struct console *co, const char *s, unsigned count)
{
@@ -85,12 +86,138 @@ static int pdc_console_setup(struct console *co, char *options)
#if defined(CONFIG_PDC_CONSOLE)
#include <linux/vt_kern.h>
+#include <linux/tty_flip.h>
+
+#define PDC_CONS_POLL_DELAY (30 * HZ / 1000)
+
+static struct timer_list pdc_console_timer;
+
+extern struct console * console_drivers;
+
+static int pdc_console_tty_open(struct tty_struct *tty, struct file *filp)
+{
+
+ mod_timer(&pdc_console_timer, jiffies + PDC_CONS_POLL_DELAY);
+
+ return 0;
+}
+
+static void pdc_console_tty_close(struct tty_struct *tty, struct file *filp)
+{
+ if (!tty->count)
+ del_timer(&pdc_console_timer);
+}
+
+static int pdc_console_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
+{
+ pdc_console_write(NULL, buf, count);
+ return count;
+}
+
+static int pdc_console_tty_write_room(struct tty_struct *tty)
+{
+ return 32768; /* no limit, no buffer used */
+}
+
+static int pdc_console_tty_chars_in_buffer(struct tty_struct *tty)
+{
+ return 0; /* no buffer */
+}
+
+static struct tty_driver *pdc_console_tty_driver;
+
+static const struct tty_operations pdc_console_tty_ops = {
+ .open = pdc_console_tty_open,
+ .close = pdc_console_tty_close,
+ .write = pdc_console_tty_write,
+ .write_room = pdc_console_tty_write_room,
+ .chars_in_buffer = pdc_console_tty_chars_in_buffer,
+};
+
+static void pdc_console_poll(unsigned long unused)
+{
+
+ int data, count = 0;
+
+ struct tty_struct *tty = pdc_console_tty_driver->ttys[0];
+
+ if (!tty)
+ return;
+
+ while (1) {
+ data = pdc_console_poll_key(NULL);
+ if (data == -1)
+ break;
+ tty_insert_flip_char(tty, data & 0xFF, TTY_NORMAL);
+ count ++;
+ }
+
+ if (count)
+ tty_flip_buffer_push(tty);
+
+ if (tty->count && (pdc_cons.flags & CON_ENABLED))
+ mod_timer(&pdc_console_timer, jiffies + PDC_CONS_POLL_DELAY);
+}
+
+static int __init pdc_console_tty_driver_init(void)
+{
+
+ int err;
+ struct tty_driver *drv;
+
+ /* Check if the console driver is still registered.
+ * It is unregistered if the pdc console was not selected as the
+ * primary console. */
+
+ struct console *tmp = console_drivers;
+
+ for (tmp = console_drivers; tmp; tmp = tmp->next)
+ if (tmp == &pdc_cons)
+ break;
+
+ if (!tmp) {
+ printk(KERN_INFO "PDC console driver not registered anymore, not creating %s\n", pdc_cons.name);
+ return -ENODEV;
+ }
+
+ printk(KERN_INFO "The PDC console driver is still registered, removing CON_BOOT flag\n");
+ pdc_cons.flags &= ~CON_BOOT;
+
+ drv = alloc_tty_driver(1);
+
+ if (!drv)
+ return -ENOMEM;
+
+ drv->driver_name = "pdc_cons";
+ drv->name = "ttyB";
+ drv->major = MUX_MAJOR;
+ drv->minor_start = 0;
+ drv->type = TTY_DRIVER_TYPE_SYSTEM;
+ drv->init_termios = tty_std_termios;
+ drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
+ tty_set_operations(drv, &pdc_console_tty_ops);
+
+ err = tty_register_driver(drv);
+ if (err) {
+ printk(KERN_ERR "Unable to register the PDC console TTY driver\n");
+ return err;
+ }
+
+ pdc_console_tty_driver = drv;
+
+ /* No need to initialize the pdc_console_timer if tty isn't allocated */
+ init_timer(&pdc_console_timer);
+ pdc_console_timer.function = pdc_console_poll;
+
+ return 0;
+}
+
+module_init(pdc_console_tty_driver_init);
static struct tty_driver * pdc_console_device (struct console *c, int *index)
{
- extern struct tty_driver console_driver;
- *index = c->index ? c->index-1 : fg_console;
- return &console_driver;
+ *index = c->index;
+ return pdc_console_tty_driver;
}
#else
#define pdc_console_device NULL
@@ -101,7 +228,7 @@ static struct console pdc_cons = {
.write = pdc_console_write,
.device = pdc_console_device,
.setup = pdc_console_setup,
- .flags = CON_BOOT | CON_PRINTBUFFER | CON_ENABLED,
+ .flags = CON_BOOT | CON_PRINTBUFFER,
.index = -1,
};
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/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index c4f49e45129d..2905b1f52d30 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -110,7 +110,8 @@ void user_enable_block_step(struct task_struct *task)
pa_psw(task)->l = 0;
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
unsigned long tmp;
long ret = -EIO;
@@ -120,11 +121,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
/* Read the word at location addr in the USER area. For ptraced
processes, the kernel saves all regs on a syscall. */
case PTRACE_PEEKUSR:
- if ((addr & (sizeof(long)-1)) ||
- (unsigned long) addr >= sizeof(struct pt_regs))
+ if ((addr & (sizeof(unsigned long)-1)) ||
+ addr >= sizeof(struct pt_regs))
break;
tmp = *(unsigned long *) ((char *) task_regs(child) + addr);
- ret = put_user(tmp, (unsigned long *) data);
+ ret = put_user(tmp, (unsigned long __user *) data);
break;
/* Write the word at location addr in the USER area. This will need
@@ -151,8 +152,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
}
- if ((addr & (sizeof(long)-1)) ||
- (unsigned long) addr >= sizeof(struct pt_regs))
+ if ((addr & (sizeof(unsigned long)-1)) ||
+ addr >= sizeof(struct pt_regs))
break;
if ((addr >= PT_GR1 && addr <= PT_GR31) ||
addr == PT_IAOQ0 || addr == PT_IAOQ1 ||
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
index 3d52c978738f..74867dfdabe5 100644
--- a/arch/parisc/kernel/syscall_table.S
+++ b/arch/parisc/kernel/syscall_table.S
@@ -419,6 +419,7 @@
ENTRY_SAME(perf_event_open)
ENTRY_COMP(recvmmsg)
ENTRY_SAME(accept4) /* 320 */
+ ENTRY_SAME(prlimit64)
/* Nothing yet */
diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c
index 92d977bb5ea8..234e3682cf09 100644
--- a/arch/parisc/kernel/unaligned.c
+++ b/arch/parisc/kernel/unaligned.c
@@ -619,15 +619,12 @@ void handle_unaligned(struct pt_regs *regs)
flop=1;
ret = emulate_std(regs, R2(regs->iir),1);
break;
-
-#ifdef CONFIG_PA20
case OPCODE_LDD_L:
ret = emulate_ldd(regs, R2(regs->iir),0);
break;
case OPCODE_STD_L:
ret = emulate_std(regs, R2(regs->iir),0);
break;
-#endif
}
#endif
switch (regs->iir & OPCODE3_MASK)
diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c
index d58eac1a8288..76ed62ed785b 100644
--- a/arch/parisc/kernel/unwind.c
+++ b/arch/parisc/kernel/unwind.c
@@ -80,8 +80,11 @@ find_unwind_entry(unsigned long addr)
if (addr >= table->start &&
addr <= table->end)
e = find_unwind_entry_in_table(table, addr);
- if (e)
+ if (e) {
+ /* Move-to-front to exploit common traces */
+ list_move(&table->list, &unwind_tables);
break;
+ }
}
return e;
diff --git a/arch/parisc/math-emu/Makefile b/arch/parisc/math-emu/Makefile
index 1f3f225897f5..0bd63b08a79a 100644
--- a/arch/parisc/math-emu/Makefile
+++ b/arch/parisc/math-emu/Makefile
@@ -3,7 +3,7 @@
#
# See arch/parisc/math-emu/README
-EXTRA_CFLAGS += -Wno-parentheses -Wno-implicit-function-declaration \
+ccflags-y := -Wno-parentheses -Wno-implicit-function-declaration \
-Wno-uninitialized -Wno-strict-prototypes -Wno-return-type \
-Wno-implicit-int
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 631e5a0fb6ab..b6447190e1a2 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -1,9 +1,3 @@
-# For a description of the syntax of this configuration file,
-# see Documentation/kbuild/kconfig-language.txt.
-#
-
-mainmenu "Linux/PowerPC Kernel Configuration"
-
source "arch/powerpc/platforms/Kconfig.cputype"
config PPC32
@@ -138,6 +132,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
@@ -687,9 +682,12 @@ config 4xx_SOC
bool
config FSL_LBC
- bool
+ bool "Freescale Local Bus support"
+ depends on FSL_SOC
help
- Freescale Localbus support
+ Enables reporting of errors from the Freescale local bus
+ controller. Also contains some common code used by
+ drivers for specific local bus peripherals.
config FSL_GTM
bool
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/cputime.h b/arch/powerpc/include/asm/cputime.h
index 8bdc6a9e5773..1cf20bdfbeca 100644
--- a/arch/powerpc/include/asm/cputime.h
+++ b/arch/powerpc/include/asm/cputime.h
@@ -124,23 +124,23 @@ static inline u64 cputime64_to_jiffies64(const cputime_t ct)
}
/*
- * Convert cputime <-> milliseconds
+ * Convert cputime <-> microseconds
*/
extern u64 __cputime_msec_factor;
-static inline unsigned long cputime_to_msecs(const cputime_t ct)
+static inline unsigned long cputime_to_usecs(const cputime_t ct)
{
- return mulhdu(ct, __cputime_msec_factor);
+ return mulhdu(ct, __cputime_msec_factor) * USEC_PER_MSEC;
}
-static inline cputime_t msecs_to_cputime(const unsigned long ms)
+static inline cputime_t usecs_to_cputime(const unsigned long us)
{
cputime_t ct;
unsigned long sec;
/* have to be a little careful about overflow */
- ct = ms % 1000;
- sec = ms / 1000;
+ ct = us % 1000000;
+ sec = us / 1000000;
if (ct) {
ct *= tb_ticks_per_sec;
do_div(ct, 1000);
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/fsl_lbc.h b/arch/powerpc/include/asm/fsl_lbc.h
index 1b5a21041f9b..5c1bf3466749 100644
--- a/arch/powerpc/include/asm/fsl_lbc.h
+++ b/arch/powerpc/include/asm/fsl_lbc.h
@@ -1,9 +1,10 @@
/* Freescale Local Bus Controller
*
- * Copyright (c) 2006-2007 Freescale Semiconductor
+ * Copyright © 2006-2007, 2010 Freescale Semiconductor
*
* Authors: Nick Spence <nick.spence@freescale.com>,
* Scott Wood <scottwood@freescale.com>
+ * Jack Lan <jack.lan@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
@@ -26,6 +27,8 @@
#include <linux/compiler.h>
#include <linux/types.h>
#include <linux/io.h>
+#include <linux/device.h>
+#include <linux/spinlock.h>
struct fsl_lbc_bank {
__be32 br; /**< Base Register */
@@ -125,13 +128,23 @@ struct fsl_lbc_regs {
#define LTESR_ATMW 0x00800000
#define LTESR_ATMR 0x00400000
#define LTESR_CS 0x00080000
+#define LTESR_UPM 0x00000002
#define LTESR_CC 0x00000001
#define LTESR_NAND_MASK (LTESR_FCT | LTESR_PAR | LTESR_CC)
+#define LTESR_MASK (LTESR_BM | LTESR_FCT | LTESR_PAR | LTESR_WP \
+ | LTESR_ATMW | LTESR_ATMR | LTESR_CS | LTESR_UPM \
+ | LTESR_CC)
+#define LTESR_CLEAR 0xFFFFFFFF
+#define LTECCR_CLEAR 0xFFFFFFFF
+#define LTESR_STATUS LTESR_MASK
+#define LTEIR_ENABLE LTESR_MASK
+#define LTEDR_ENABLE 0x00000000
__be32 ltedr; /**< Transfer Error Disable Register */
__be32 lteir; /**< Transfer Error Interrupt Register */
__be32 lteatr; /**< Transfer Error Attributes Register */
__be32 ltear; /**< Transfer Error Address Register */
- u8 res6[0xC];
+ __be32 lteccr; /**< Transfer Error ECC Register */
+ u8 res6[0x8];
__be32 lbcr; /**< Configuration Register */
#define LBCR_LDIS 0x80000000
#define LBCR_LDIS_SHIFT 31
@@ -235,6 +248,7 @@ struct fsl_upm {
int width;
};
+extern u32 fsl_lbc_addr(phys_addr_t addr_base);
extern int fsl_lbc_find(phys_addr_t addr_base);
extern int fsl_upm_find(phys_addr_t addr_base, struct fsl_upm *upm);
@@ -265,7 +279,23 @@ static inline void fsl_upm_end_pattern(struct fsl_upm *upm)
cpu_relax();
}
+/* overview of the fsl lbc controller */
+
+struct fsl_lbc_ctrl {
+ /* device info */
+ struct device *dev;
+ struct fsl_lbc_regs __iomem *regs;
+ int irq;
+ wait_queue_head_t irq_wait;
+ spinlock_t lock;
+ void *nand;
+
+ /* status read from LTESR by irq handler */
+ unsigned int irq_status;
+};
+
extern int fsl_upm_run_pattern(struct fsl_upm *upm, void __iomem *io_base,
u32 mar);
+extern struct fsl_lbc_ctrl *fsl_lbc_ctrl_dev;
#endif /* __ASM_FSL_LBC_H */
diff --git a/arch/powerpc/include/asm/fsldma.h b/arch/powerpc/include/asm/fsldma.h
deleted file mode 100644
index debc5ed96d6e..000000000000
--- a/arch/powerpc/include/asm/fsldma.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Freescale MPC83XX / MPC85XX DMA Controller
- *
- * Copyright (c) 2009 Ira W. Snyder <iws@ovro.caltech.edu>
- *
- * 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_POWERPC_ASM_FSLDMA_H__
-#define __ARCH_POWERPC_ASM_FSLDMA_H__
-
-#include <linux/slab.h>
-#include <linux/dmaengine.h>
-
-/*
- * Definitions for the Freescale DMA controller's DMA_SLAVE implemention
- *
- * The Freescale DMA_SLAVE implementation was designed to handle many-to-many
- * transfers. An example usage would be an accelerated copy between two
- * scatterlists. Another example use would be an accelerated copy from
- * multiple non-contiguous device buffers into a single scatterlist.
- *
- * A DMA_SLAVE transaction is defined by a struct fsl_dma_slave. This
- * structure contains a list of hardware addresses that should be copied
- * to/from the scatterlist passed into device_prep_slave_sg(). The structure
- * also has some fields to enable hardware-specific features.
- */
-
-/**
- * struct fsl_dma_hw_addr
- * @entry: linked list entry
- * @address: the hardware address
- * @length: length to transfer
- *
- * Holds a single physical hardware address / length pair for use
- * with the DMAEngine DMA_SLAVE API.
- */
-struct fsl_dma_hw_addr {
- struct list_head entry;
-
- dma_addr_t address;
- size_t length;
-};
-
-/**
- * struct fsl_dma_slave
- * @addresses: a linked list of struct fsl_dma_hw_addr structures
- * @request_count: value for DMA request count
- * @src_loop_size: setup and enable constant source-address DMA transfers
- * @dst_loop_size: setup and enable constant destination address DMA transfers
- * @external_start: enable externally started DMA transfers
- * @external_pause: enable externally paused DMA transfers
- *
- * Holds a list of address / length pairs for use with the DMAEngine
- * DMA_SLAVE API implementation for the Freescale DMA controller.
- */
-struct fsl_dma_slave {
-
- /* List of hardware address/length pairs */
- struct list_head addresses;
-
- /* Support for extra controller features */
- unsigned int request_count;
- unsigned int src_loop_size;
- unsigned int dst_loop_size;
- bool external_start;
- bool external_pause;
-};
-
-/**
- * fsl_dma_slave_append - add an address/length pair to a struct fsl_dma_slave
- * @slave: the &struct fsl_dma_slave to add to
- * @address: the hardware address to add
- * @length: the length of bytes to transfer from @address
- *
- * Add a hardware address/length pair to a struct fsl_dma_slave. Returns 0 on
- * success, -ERRNO otherwise.
- */
-static inline int fsl_dma_slave_append(struct fsl_dma_slave *slave,
- dma_addr_t address, size_t length)
-{
- struct fsl_dma_hw_addr *addr;
-
- addr = kzalloc(sizeof(*addr), GFP_ATOMIC);
- if (!addr)
- return -ENOMEM;
-
- INIT_LIST_HEAD(&addr->entry);
- addr->address = address;
- addr->length = length;
-
- list_add_tail(&addr->entry, &slave->addresses);
- return 0;
-}
-
-/**
- * fsl_dma_slave_free - free a struct fsl_dma_slave
- * @slave: the struct fsl_dma_slave to free
- *
- * Free a struct fsl_dma_slave and all associated address/length pairs
- */
-static inline void fsl_dma_slave_free(struct fsl_dma_slave *slave)
-{
- struct fsl_dma_hw_addr *addr, *tmp;
-
- if (slave) {
- list_for_each_entry_safe(addr, tmp, &slave->addresses, entry) {
- list_del(&addr->entry);
- kfree(addr);
- }
-
- kfree(slave);
- }
-}
-
-/**
- * fsl_dma_slave_alloc - allocate a struct fsl_dma_slave
- * @gfp: the flags to pass to kmalloc when allocating this structure
- *
- * Allocate a struct fsl_dma_slave for use by the DMA_SLAVE API. Returns a new
- * struct fsl_dma_slave on success, or NULL on failure.
- */
-static inline struct fsl_dma_slave *fsl_dma_slave_alloc(gfp_t gfp)
-{
- struct fsl_dma_slave *slave;
-
- slave = kzalloc(sizeof(*slave), gfp);
- if (!slave)
- return NULL;
-
- INIT_LIST_HEAD(&slave->addresses);
- return slave;
-}
-
-#endif /* __ARCH_POWERPC_ASM_FSLDMA_H__ */
diff --git a/arch/powerpc/include/asm/highmem.h b/arch/powerpc/include/asm/highmem.h
index d10d64a4be38..dbc264010d0b 100644
--- a/arch/powerpc/include/asm/highmem.h
+++ b/arch/powerpc/include/asm/highmem.h
@@ -60,9 +60,8 @@ extern pte_t *pkmap_page_table;
extern void *kmap_high(struct page *page);
extern void kunmap_high(struct page *page);
-extern void *kmap_atomic_prot(struct page *page, enum km_type type,
- pgprot_t prot);
-extern void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type);
+extern void *kmap_atomic_prot(struct page *page, pgprot_t prot);
+extern void __kunmap_atomic(void *kvaddr);
static inline void *kmap(struct page *page)
{
@@ -80,9 +79,9 @@ static inline void kunmap(struct page *page)
kunmap_high(page);
}
-static inline void *kmap_atomic(struct page *page, enum km_type type)
+static inline void *__kmap_atomic(struct page *page)
{
- return kmap_atomic_prot(page, type, kmap_prot);
+ return kmap_atomic_prot(page, kmap_prot);
}
static inline struct page *kmap_atomic_to_page(void *ptr)
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/kgdb.h b/arch/powerpc/include/asm/kgdb.h
index edd217006d27..9db24e77b9f4 100644
--- a/arch/powerpc/include/asm/kgdb.h
+++ b/arch/powerpc/include/asm/kgdb.h
@@ -31,6 +31,7 @@ static inline void arch_kgdb_breakpoint(void)
asm(".long 0x7d821008"); /* twge r2, r2 */
}
#define CACHE_FLUSH_IS_SAFE 1
+#define DBG_MAX_REG_NUM 70
/* The number bytes of registers we have to save depends on a few
* things. For 64bit we default to not including vector registers and
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/pgtable-ppc32.h b/arch/powerpc/include/asm/pgtable-ppc32.h
index a7db96f2b5c3..47edde8c3556 100644
--- a/arch/powerpc/include/asm/pgtable-ppc32.h
+++ b/arch/powerpc/include/asm/pgtable-ppc32.h
@@ -308,12 +308,8 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
#define pte_offset_kernel(dir, addr) \
((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(addr))
#define pte_offset_map(dir, addr) \
- ((pte_t *) kmap_atomic(pmd_page(*(dir)), KM_PTE0) + pte_index(addr))
-#define pte_offset_map_nested(dir, addr) \
- ((pte_t *) kmap_atomic(pmd_page(*(dir)), KM_PTE1) + pte_index(addr))
-
-#define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0)
-#define pte_unmap_nested(pte) kunmap_atomic(pte, KM_PTE1)
+ ((pte_t *) kmap_atomic(pmd_page(*(dir))) + pte_index(addr))
+#define pte_unmap(pte) kunmap_atomic(pte)
/*
* Encode and decode a swap entry.
diff --git a/arch/powerpc/include/asm/pgtable-ppc64.h b/arch/powerpc/include/asm/pgtable-ppc64.h
index 49865045d56f..2b09cd522d33 100644
--- a/arch/powerpc/include/asm/pgtable-ppc64.h
+++ b/arch/powerpc/include/asm/pgtable-ppc64.h
@@ -193,9 +193,7 @@
(((pte_t *) pmd_page_vaddr(*(dir))) + (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
#define pte_offset_map(dir,addr) pte_offset_kernel((dir), (addr))
-#define pte_offset_map_nested(dir,addr) pte_offset_kernel((dir), (addr))
#define pte_unmap(pte) do { } while(0)
-#define pte_unmap_nested(pte) do { } while(0)
/* to find an entry in a kernel page-table-directory */
/* This now only contains the vmalloc pages */
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/kgdb.c b/arch/powerpc/kernel/kgdb.c
index 7f61a3ac787c..7a9db64f3f04 100644
--- a/arch/powerpc/kernel/kgdb.c
+++ b/arch/powerpc/kernel/kgdb.c
@@ -194,40 +194,6 @@ static int kgdb_dabr_match(struct pt_regs *regs)
ptr = (unsigned long *)ptr32; \
} while (0)
-
-void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
-{
- unsigned long *ptr = gdb_regs;
- int reg;
-
- memset(gdb_regs, 0, NUMREGBYTES);
-
- for (reg = 0; reg < 32; reg++)
- PACK64(ptr, regs->gpr[reg]);
-
-#ifdef CONFIG_FSL_BOOKE
-#ifdef CONFIG_SPE
- for (reg = 0; reg < 32; reg++)
- PACK64(ptr, current->thread.evr[reg]);
-#else
- ptr += 32;
-#endif
-#else
- /* fp registers not used by kernel, leave zero */
- ptr += 32 * 8 / sizeof(long);
-#endif
-
- PACK64(ptr, regs->nip);
- PACK64(ptr, regs->msr);
- PACK32(ptr, regs->ccr);
- PACK64(ptr, regs->link);
- PACK64(ptr, regs->ctr);
- PACK32(ptr, regs->xer);
-
- BUG_ON((unsigned long)ptr >
- (unsigned long)(((void *)gdb_regs) + NUMREGBYTES));
-}
-
void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
{
struct pt_regs *regs = (struct pt_regs *)(p->thread.ksp +
@@ -271,44 +237,140 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
(unsigned long)(((void *)gdb_regs) + NUMREGBYTES));
}
-#define UNPACK64(dest, ptr) do { dest = *(ptr++); } while (0)
+#define GDB_SIZEOF_REG sizeof(unsigned long)
+#define GDB_SIZEOF_REG_U32 sizeof(u32)
-#define UNPACK32(dest, ptr) do { \
- u32 *ptr32; \
- ptr32 = (u32 *)ptr; \
- dest = *(ptr32++); \
- ptr = (unsigned long *)ptr32; \
- } while (0)
+#ifdef CONFIG_FSL_BOOKE
+#define GDB_SIZEOF_FLOAT_REG sizeof(unsigned long)
+#else
+#define GDB_SIZEOF_FLOAT_REG sizeof(u64)
+#endif
-void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
+struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] =
{
- unsigned long *ptr = gdb_regs;
- int reg;
-
- for (reg = 0; reg < 32; reg++)
- UNPACK64(regs->gpr[reg], ptr);
+ { "r0", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[0]) },
+ { "r1", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[1]) },
+ { "r2", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[2]) },
+ { "r3", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[3]) },
+ { "r4", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[4]) },
+ { "r5", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[5]) },
+ { "r6", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[6]) },
+ { "r7", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[7]) },
+ { "r8", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[8]) },
+ { "r9", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[9]) },
+ { "r10", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[10]) },
+ { "r11", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[11]) },
+ { "r12", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[12]) },
+ { "r13", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[13]) },
+ { "r14", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[14]) },
+ { "r15", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[15]) },
+ { "r16", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[16]) },
+ { "r17", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[17]) },
+ { "r18", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[18]) },
+ { "r19", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[19]) },
+ { "r20", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[20]) },
+ { "r21", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[21]) },
+ { "r22", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[22]) },
+ { "r23", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[23]) },
+ { "r24", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[24]) },
+ { "r25", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[25]) },
+ { "r26", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[26]) },
+ { "r27", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[27]) },
+ { "r28", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[28]) },
+ { "r29", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[29]) },
+ { "r30", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[30]) },
+ { "r31", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[31]) },
+
+ { "f0", GDB_SIZEOF_FLOAT_REG, 0 },
+ { "f1", GDB_SIZEOF_FLOAT_REG, 1 },
+ { "f2", GDB_SIZEOF_FLOAT_REG, 2 },
+ { "f3", GDB_SIZEOF_FLOAT_REG, 3 },
+ { "f4", GDB_SIZEOF_FLOAT_REG, 4 },
+ { "f5", GDB_SIZEOF_FLOAT_REG, 5 },
+ { "f6", GDB_SIZEOF_FLOAT_REG, 6 },
+ { "f7", GDB_SIZEOF_FLOAT_REG, 7 },
+ { "f8", GDB_SIZEOF_FLOAT_REG, 8 },
+ { "f9", GDB_SIZEOF_FLOAT_REG, 9 },
+ { "f10", GDB_SIZEOF_FLOAT_REG, 10 },
+ { "f11", GDB_SIZEOF_FLOAT_REG, 11 },
+ { "f12", GDB_SIZEOF_FLOAT_REG, 12 },
+ { "f13", GDB_SIZEOF_FLOAT_REG, 13 },
+ { "f14", GDB_SIZEOF_FLOAT_REG, 14 },
+ { "f15", GDB_SIZEOF_FLOAT_REG, 15 },
+ { "f16", GDB_SIZEOF_FLOAT_REG, 16 },
+ { "f17", GDB_SIZEOF_FLOAT_REG, 17 },
+ { "f18", GDB_SIZEOF_FLOAT_REG, 18 },
+ { "f19", GDB_SIZEOF_FLOAT_REG, 19 },
+ { "f20", GDB_SIZEOF_FLOAT_REG, 20 },
+ { "f21", GDB_SIZEOF_FLOAT_REG, 21 },
+ { "f22", GDB_SIZEOF_FLOAT_REG, 22 },
+ { "f23", GDB_SIZEOF_FLOAT_REG, 23 },
+ { "f24", GDB_SIZEOF_FLOAT_REG, 24 },
+ { "f25", GDB_SIZEOF_FLOAT_REG, 25 },
+ { "f26", GDB_SIZEOF_FLOAT_REG, 26 },
+ { "f27", GDB_SIZEOF_FLOAT_REG, 27 },
+ { "f28", GDB_SIZEOF_FLOAT_REG, 28 },
+ { "f29", GDB_SIZEOF_FLOAT_REG, 29 },
+ { "f30", GDB_SIZEOF_FLOAT_REG, 30 },
+ { "f31", GDB_SIZEOF_FLOAT_REG, 31 },
+
+ { "pc", GDB_SIZEOF_REG, offsetof(struct pt_regs, nip) },
+ { "msr", GDB_SIZEOF_REG, offsetof(struct pt_regs, msr) },
+ { "cr", GDB_SIZEOF_REG_U32, offsetof(struct pt_regs, ccr) },
+ { "lr", GDB_SIZEOF_REG, offsetof(struct pt_regs, link) },
+ { "ctr", GDB_SIZEOF_REG_U32, offsetof(struct pt_regs, ctr) },
+ { "xer", GDB_SIZEOF_REG, offsetof(struct pt_regs, xer) },
+};
-#ifdef CONFIG_FSL_BOOKE
-#ifdef CONFIG_SPE
- for (reg = 0; reg < 32; reg++)
- UNPACK64(current->thread.evr[reg], ptr);
+char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
+{
+ if (regno >= DBG_MAX_REG_NUM || regno < 0)
+ return NULL;
+
+ if (regno < 32 || regno >= 64)
+ /* First 0 -> 31 gpr registers*/
+ /* pc, msr, ls... registers 64 -> 69 */
+ memcpy(mem, (void *)regs + dbg_reg_def[regno].offset,
+ dbg_reg_def[regno].size);
+
+ if (regno >= 32 && regno < 64) {
+ /* FP registers 32 -> 63 */
+#if defined(CONFIG_FSL_BOOKE) && defined(CONFIG_SPE)
+ if (current)
+ memcpy(mem, current->thread.evr[regno-32],
+ dbg_reg_def[regno].size);
#else
- ptr += 32;
+ /* fp registers not used by kernel, leave zero */
+ memset(mem, 0, dbg_reg_def[regno].size);
#endif
+ }
+
+ return dbg_reg_def[regno].name;
+}
+
+int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
+{
+ if (regno >= DBG_MAX_REG_NUM || regno < 0)
+ return -EINVAL;
+
+ if (regno < 32 || regno >= 64)
+ /* First 0 -> 31 gpr registers*/
+ /* pc, msr, ls... registers 64 -> 69 */
+ memcpy((void *)regs + dbg_reg_def[regno].offset, mem,
+ dbg_reg_def[regno].size);
+
+ if (regno >= 32 && regno < 64) {
+ /* FP registers 32 -> 63 */
+#if defined(CONFIG_FSL_BOOKE) && defined(CONFIG_SPE)
+ memcpy(current->thread.evr[regno-32], mem,
+ dbg_reg_def[regno].size);
#else
- /* fp registers not used by kernel, leave zero */
- ptr += 32 * 8 / sizeof(int);
+ /* fp registers not used by kernel, leave zero */
+ return 0;
#endif
+ }
- UNPACK64(regs->nip, ptr);
- UNPACK64(regs->msr, ptr);
- UNPACK32(regs->ccr, ptr);
- UNPACK64(regs->link, ptr);
- UNPACK64(regs->ctr, ptr);
- UNPACK32(regs->xer, ptr);
-
- BUG_ON((unsigned long)ptr >
- (unsigned long)(((void *)gdb_regs) + NUMREGBYTES));
+ return 0;
}
void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
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/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..a9b32967cff6 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1406,37 +1406,42 @@ static long ppc_del_hwdebug(struct task_struct *child, long addr, long data)
* Here are the old "legacy" powerpc specific getregs/setregs ptrace calls,
* we mark them as obsolete now, they will be removed in a future version
*/
-static long arch_ptrace_old(struct task_struct *child, long request, long addr,
- long data)
+static long arch_ptrace_old(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
+ void __user *datavp = (void __user *) data;
+
switch (request) {
case PPC_PTRACE_GETREGS: /* Get GPRs 0 - 31. */
return copy_regset_to_user(child, &user_ppc_native_view,
REGSET_GPR, 0, 32 * sizeof(long),
- (void __user *) data);
+ datavp);
case PPC_PTRACE_SETREGS: /* Set GPRs 0 - 31. */
return copy_regset_from_user(child, &user_ppc_native_view,
REGSET_GPR, 0, 32 * sizeof(long),
- (const void __user *) data);
+ datavp);
case PPC_PTRACE_GETFPREGS: /* Get FPRs 0 - 31. */
return copy_regset_to_user(child, &user_ppc_native_view,
REGSET_FPR, 0, 32 * sizeof(double),
- (void __user *) data);
+ datavp);
case PPC_PTRACE_SETFPREGS: /* Set FPRs 0 - 31. */
return copy_regset_from_user(child, &user_ppc_native_view,
REGSET_FPR, 0, 32 * sizeof(double),
- (const void __user *) data);
+ datavp);
}
return -EPERM;
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int ret = -EPERM;
+ void __user *datavp = (void __user *) data;
+ unsigned long __user *datalp = datavp;
switch (request) {
/* read the word at location addr in the USER area. */
@@ -1446,11 +1451,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
ret = -EIO;
/* convert to index and check */
#ifdef CONFIG_PPC32
- index = (unsigned long) addr >> 2;
+ index = addr >> 2;
if ((addr & 3) || (index > PT_FPSCR)
|| (child->thread.regs == NULL))
#else
- index = (unsigned long) addr >> 3;
+ index = addr >> 3;
if ((addr & 7) || (index > PT_FPSCR))
#endif
break;
@@ -1463,7 +1468,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
tmp = ((unsigned long *)child->thread.fpr)
[TS_FPRWIDTH * (index - PT_FPR0)];
}
- ret = put_user(tmp,(unsigned long __user *) data);
+ ret = put_user(tmp, datalp);
break;
}
@@ -1474,11 +1479,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
ret = -EIO;
/* convert to index and check */
#ifdef CONFIG_PPC32
- index = (unsigned long) addr >> 2;
+ index = addr >> 2;
if ((addr & 3) || (index > PT_FPSCR)
|| (child->thread.regs == NULL))
#else
- index = (unsigned long) addr >> 3;
+ index = addr >> 3;
if ((addr & 7) || (index > PT_FPSCR))
#endif
break;
@@ -1525,11 +1530,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
dbginfo.features = 0;
#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
- if (!access_ok(VERIFY_WRITE, data,
+ if (!access_ok(VERIFY_WRITE, datavp,
sizeof(struct ppc_debug_info)))
return -EFAULT;
- ret = __copy_to_user((struct ppc_debug_info __user *)data,
- &dbginfo, sizeof(struct ppc_debug_info)) ?
+ ret = __copy_to_user(datavp, &dbginfo,
+ sizeof(struct ppc_debug_info)) ?
-EFAULT : 0;
break;
}
@@ -1537,11 +1542,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
case PPC_PTRACE_SETHWDEBUG: {
struct ppc_hw_breakpoint bp_info;
- if (!access_ok(VERIFY_READ, data,
+ if (!access_ok(VERIFY_READ, datavp,
sizeof(struct ppc_hw_breakpoint)))
return -EFAULT;
- ret = __copy_from_user(&bp_info,
- (struct ppc_hw_breakpoint __user *)data,
+ ret = __copy_from_user(&bp_info, datavp,
sizeof(struct ppc_hw_breakpoint)) ?
-EFAULT : 0;
if (!ret)
@@ -1560,11 +1564,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
if (addr > 0)
break;
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
- ret = put_user(child->thread.dac1,
- (unsigned long __user *)data);
+ ret = put_user(child->thread.dac1, datalp);
#else
- ret = put_user(child->thread.dabr,
- (unsigned long __user *)data);
+ ret = put_user(child->thread.dabr, datalp);
#endif
break;
}
@@ -1580,7 +1582,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
return copy_regset_to_user(child, &user_ppc_native_view,
REGSET_GPR,
0, sizeof(struct pt_regs),
- (void __user *) data);
+ datavp);
#ifdef CONFIG_PPC64
case PTRACE_SETREGS64:
@@ -1589,19 +1591,19 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
return copy_regset_from_user(child, &user_ppc_native_view,
REGSET_GPR,
0, sizeof(struct pt_regs),
- (const void __user *) data);
+ datavp);
case PTRACE_GETFPREGS: /* Get the child FPU state (FPR0...31 + FPSCR) */
return copy_regset_to_user(child, &user_ppc_native_view,
REGSET_FPR,
0, sizeof(elf_fpregset_t),
- (void __user *) data);
+ datavp);
case PTRACE_SETFPREGS: /* Set the child FPU state (FPR0...31 + FPSCR) */
return copy_regset_from_user(child, &user_ppc_native_view,
REGSET_FPR,
0, sizeof(elf_fpregset_t),
- (const void __user *) data);
+ datavp);
#ifdef CONFIG_ALTIVEC
case PTRACE_GETVRREGS:
@@ -1609,40 +1611,40 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
REGSET_VMX,
0, (33 * sizeof(vector128) +
sizeof(u32)),
- (void __user *) data);
+ datavp);
case PTRACE_SETVRREGS:
return copy_regset_from_user(child, &user_ppc_native_view,
REGSET_VMX,
0, (33 * sizeof(vector128) +
sizeof(u32)),
- (const void __user *) data);
+ datavp);
#endif
#ifdef CONFIG_VSX
case PTRACE_GETVSRREGS:
return copy_regset_to_user(child, &user_ppc_native_view,
REGSET_VSX,
0, 32 * sizeof(double),
- (void __user *) data);
+ datavp);
case PTRACE_SETVSRREGS:
return copy_regset_from_user(child, &user_ppc_native_view,
REGSET_VSX,
0, 32 * sizeof(double),
- (const void __user *) data);
+ datavp);
#endif
#ifdef CONFIG_SPE
case PTRACE_GETEVRREGS:
/* Get the child spe register state. */
return copy_regset_to_user(child, &user_ppc_native_view,
REGSET_SPE, 0, 35 * sizeof(u32),
- (void __user *) data);
+ datavp);
case PTRACE_SETEVRREGS:
/* Set the child spe register state. */
return copy_regset_from_user(child, &user_ppc_native_view,
REGSET_SPE, 0, 35 * sizeof(u32),
- (const void __user *) data);
+ datavp);
#endif
/* Old reverse args ptrace callss */
@@ -1681,7 +1683,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..441d2a722f06 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -238,9 +238,7 @@ static inline void vio_cmo_dealloc(struct vio_dev *viodev, size_t size)
* memory in this pool does not change.
*/
if (spare_needed && reserve_freed) {
- tmp = min(spare_needed, min(reserve_freed,
- (viodev->cmo.entitled -
- VIO_CMO_MIN_ENT)));
+ tmp = min3(spare_needed, reserve_freed, (viodev->cmo.entitled - VIO_CMO_MIN_ENT));
vio_cmo.spare += tmp;
viodev->cmo.entitled -= tmp;
@@ -1184,7 +1182,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 +1257,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/highmem.c b/arch/powerpc/mm/highmem.c
index 857d4173f9c6..e7450bdbe83a 100644
--- a/arch/powerpc/mm/highmem.c
+++ b/arch/powerpc/mm/highmem.c
@@ -29,17 +29,17 @@
* be used in IRQ contexts, so in some (very limited) cases we need
* it.
*/
-void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot)
+void *kmap_atomic_prot(struct page *page, pgprot_t prot)
{
- unsigned int idx;
unsigned long vaddr;
+ int idx, type;
/* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
pagefault_disable();
if (!PageHighMem(page))
return page_address(page);
- debug_kmap_atomic(type);
+ type = kmap_atomic_idx_push();
idx = type + KM_TYPE_NR*smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
#ifdef CONFIG_DEBUG_HIGHMEM
@@ -52,26 +52,35 @@ void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot)
}
EXPORT_SYMBOL(kmap_atomic_prot);
-void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type)
+void __kunmap_atomic(void *kvaddr)
{
-#ifdef CONFIG_DEBUG_HIGHMEM
unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
- enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
+ int type;
if (vaddr < __fix_to_virt(FIX_KMAP_END)) {
pagefault_enable();
return;
}
- BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
+ type = kmap_atomic_idx();
- /*
- * force other mappings to Oops if they'll try to access
- * this pte without first remap it
- */
- pte_clear(&init_mm, vaddr, kmap_pte-idx);
- local_flush_tlb_page(NULL, vaddr);
+#ifdef CONFIG_DEBUG_HIGHMEM
+ {
+ unsigned int idx;
+
+ idx = type + KM_TYPE_NR * smp_processor_id();
+ BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
+
+ /*
+ * force other mappings to Oops if they'll try to access
+ * this pte without first remap it
+ */
+ pte_clear(&init_mm, vaddr, kmap_pte-idx);
+ local_flush_tlb_page(NULL, vaddr);
+ }
#endif
+
+ kmap_atomic_idx_pop();
pagefault_enable();
}
-EXPORT_SYMBOL(kunmap_atomic_notypecheck);
+EXPORT_SYMBOL(__kunmap_atomic);
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/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 e15afdf12343..7eb5c40c069f 100644
--- a/arch/powerpc/platforms/85xx/p1022_ds.c
+++ b/arch/powerpc/platforms/85xx/p1022_ds.c
@@ -319,6 +319,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/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index 5dec408d6703..3532b92de983 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -798,17 +798,17 @@ spufs_fill_super(struct super_block *sb, void *data, int silent)
return spufs_create_root(sb, data);
}
-static int
-spufs_get_sb(struct file_system_type *fstype, int flags,
- const char *name, void *data, struct vfsmount *mnt)
+static struct dentry *
+spufs_mount(struct file_system_type *fstype, int flags,
+ const char *name, void *data)
{
- return get_sb_single(fstype, flags, data, spufs_fill_super, mnt);
+ return mount_single(fstype, flags, data, spufs_fill_super);
}
static struct file_system_type spufs_type = {
.owner = THIS_MODULE,
.name = "spufs",
- .get_sb = spufs_get_sb,
+ .mount = spufs_mount,
.kill_sb = kill_litter_super,
};
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_lbc.c b/arch/powerpc/sysdev/fsl_lbc.c
index dceb8d1a843d..4fcb5a4e60dd 100644
--- a/arch/powerpc/sysdev/fsl_lbc.c
+++ b/arch/powerpc/sysdev/fsl_lbc.c
@@ -1,9 +1,12 @@
/*
* Freescale LBC and UPM routines.
*
- * Copyright (c) 2007-2008 MontaVista Software, Inc.
+ * Copyright © 2007-2008 MontaVista Software, Inc.
+ * Copyright © 2010 Freescale Semiconductor
*
* Author: Anton Vorontsov <avorontsov@ru.mvista.com>
+ * Author: Jack Lan <Jack.Lan@freescale.com>
+ * Author: Roy Zang <tie-fei.zang@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
@@ -19,39 +22,37 @@
#include <linux/types.h>
#include <linux/io.h>
#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/mod_devicetable.h>
#include <asm/prom.h>
#include <asm/fsl_lbc.h>
static spinlock_t fsl_lbc_lock = __SPIN_LOCK_UNLOCKED(fsl_lbc_lock);
-static struct fsl_lbc_regs __iomem *fsl_lbc_regs;
+struct fsl_lbc_ctrl *fsl_lbc_ctrl_dev;
+EXPORT_SYMBOL(fsl_lbc_ctrl_dev);
-static char __initdata *compat_lbc[] = {
- "fsl,pq2-localbus",
- "fsl,pq2pro-localbus",
- "fsl,pq3-localbus",
- "fsl,elbc",
-};
-
-static int __init fsl_lbc_init(void)
+/**
+ * fsl_lbc_addr - convert the base address
+ * @addr_base: base address of the memory bank
+ *
+ * This function converts a base address of lbc into the right format for the
+ * BR register. If the SOC has eLBC then it returns 32bit physical address
+ * else it convers a 34bit local bus physical address to correct format of
+ * 32bit address for BR register (Example: MPC8641).
+ */
+u32 fsl_lbc_addr(phys_addr_t addr_base)
{
- struct device_node *lbus;
- int i;
+ struct device_node *np = fsl_lbc_ctrl_dev->dev->of_node;
+ u32 addr = addr_base & 0xffff8000;
- for (i = 0; i < ARRAY_SIZE(compat_lbc); i++) {
- lbus = of_find_compatible_node(NULL, NULL, compat_lbc[i]);
- if (lbus)
- goto found;
- }
- return -ENODEV;
+ if (of_device_is_compatible(np, "fsl,elbc"))
+ return addr;
-found:
- fsl_lbc_regs = of_iomap(lbus, 0);
- of_node_put(lbus);
- if (!fsl_lbc_regs)
- return -ENOMEM;
- return 0;
+ return addr | ((addr_base & 0x300000000ull) >> 19);
}
-arch_initcall(fsl_lbc_init);
+EXPORT_SYMBOL(fsl_lbc_addr);
/**
* fsl_lbc_find - find Localbus bank
@@ -65,15 +66,17 @@ arch_initcall(fsl_lbc_init);
int fsl_lbc_find(phys_addr_t addr_base)
{
int i;
+ struct fsl_lbc_regs __iomem *lbc;
- if (!fsl_lbc_regs)
+ if (!fsl_lbc_ctrl_dev || !fsl_lbc_ctrl_dev->regs)
return -ENODEV;
- for (i = 0; i < ARRAY_SIZE(fsl_lbc_regs->bank); i++) {
- __be32 br = in_be32(&fsl_lbc_regs->bank[i].br);
- __be32 or = in_be32(&fsl_lbc_regs->bank[i].or);
+ lbc = fsl_lbc_ctrl_dev->regs;
+ for (i = 0; i < ARRAY_SIZE(lbc->bank); i++) {
+ __be32 br = in_be32(&lbc->bank[i].br);
+ __be32 or = in_be32(&lbc->bank[i].or);
- if (br & BR_V && (br & or & BR_BA) == addr_base)
+ if (br & BR_V && (br & or & BR_BA) == fsl_lbc_addr(addr_base))
return i;
}
@@ -94,22 +97,27 @@ int fsl_upm_find(phys_addr_t addr_base, struct fsl_upm *upm)
{
int bank;
__be32 br;
+ struct fsl_lbc_regs __iomem *lbc;
bank = fsl_lbc_find(addr_base);
if (bank < 0)
return bank;
- br = in_be32(&fsl_lbc_regs->bank[bank].br);
+ if (!fsl_lbc_ctrl_dev || !fsl_lbc_ctrl_dev->regs)
+ return -ENODEV;
+
+ lbc = fsl_lbc_ctrl_dev->regs;
+ br = in_be32(&lbc->bank[bank].br);
switch (br & BR_MSEL) {
case BR_MS_UPMA:
- upm->mxmr = &fsl_lbc_regs->mamr;
+ upm->mxmr = &lbc->mamr;
break;
case BR_MS_UPMB:
- upm->mxmr = &fsl_lbc_regs->mbmr;
+ upm->mxmr = &lbc->mbmr;
break;
case BR_MS_UPMC:
- upm->mxmr = &fsl_lbc_regs->mcmr;
+ upm->mxmr = &lbc->mcmr;
break;
default:
return -EINVAL;
@@ -148,9 +156,12 @@ int fsl_upm_run_pattern(struct fsl_upm *upm, void __iomem *io_base, u32 mar)
int ret = 0;
unsigned long flags;
+ if (!fsl_lbc_ctrl_dev || !fsl_lbc_ctrl_dev->regs)
+ return -ENODEV;
+
spin_lock_irqsave(&fsl_lbc_lock, flags);
- out_be32(&fsl_lbc_regs->mar, mar);
+ out_be32(&fsl_lbc_ctrl_dev->regs->mar, mar);
switch (upm->width) {
case 8:
@@ -172,3 +183,166 @@ int fsl_upm_run_pattern(struct fsl_upm *upm, void __iomem *io_base, u32 mar)
return ret;
}
EXPORT_SYMBOL(fsl_upm_run_pattern);
+
+static int __devinit fsl_lbc_ctrl_init(struct fsl_lbc_ctrl *ctrl)
+{
+ struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
+
+ /* clear event registers */
+ setbits32(&lbc->ltesr, LTESR_CLEAR);
+ out_be32(&lbc->lteatr, 0);
+ out_be32(&lbc->ltear, 0);
+ out_be32(&lbc->lteccr, LTECCR_CLEAR);
+ out_be32(&lbc->ltedr, LTEDR_ENABLE);
+
+ /* Enable interrupts for any detected events */
+ out_be32(&lbc->lteir, LTEIR_ENABLE);
+
+ return 0;
+}
+
+/*
+ * NOTE: This interrupt is used to report localbus events of various kinds,
+ * such as transaction errors on the chipselects.
+ */
+
+static irqreturn_t fsl_lbc_ctrl_irq(int irqno, void *data)
+{
+ struct fsl_lbc_ctrl *ctrl = data;
+ struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
+ u32 status;
+
+ status = in_be32(&lbc->ltesr);
+ if (!status)
+ return IRQ_NONE;
+
+ out_be32(&lbc->ltesr, LTESR_CLEAR);
+ out_be32(&lbc->lteatr, 0);
+ out_be32(&lbc->ltear, 0);
+ ctrl->irq_status = status;
+
+ if (status & LTESR_BM)
+ dev_err(ctrl->dev, "Local bus monitor time-out: "
+ "LTESR 0x%08X\n", status);
+ if (status & LTESR_WP)
+ dev_err(ctrl->dev, "Write protect error: "
+ "LTESR 0x%08X\n", status);
+ if (status & LTESR_ATMW)
+ dev_err(ctrl->dev, "Atomic write error: "
+ "LTESR 0x%08X\n", status);
+ if (status & LTESR_ATMR)
+ dev_err(ctrl->dev, "Atomic read error: "
+ "LTESR 0x%08X\n", status);
+ if (status & LTESR_CS)
+ dev_err(ctrl->dev, "Chip select error: "
+ "LTESR 0x%08X\n", status);
+ if (status & LTESR_UPM)
+ ;
+ if (status & LTESR_FCT) {
+ dev_err(ctrl->dev, "FCM command time-out: "
+ "LTESR 0x%08X\n", status);
+ smp_wmb();
+ wake_up(&ctrl->irq_wait);
+ }
+ if (status & LTESR_PAR) {
+ dev_err(ctrl->dev, "Parity or Uncorrectable ECC error: "
+ "LTESR 0x%08X\n", status);
+ smp_wmb();
+ wake_up(&ctrl->irq_wait);
+ }
+ if (status & LTESR_CC) {
+ smp_wmb();
+ wake_up(&ctrl->irq_wait);
+ }
+ if (status & ~LTESR_MASK)
+ dev_err(ctrl->dev, "Unknown error: "
+ "LTESR 0x%08X\n", status);
+ return IRQ_HANDLED;
+}
+
+/*
+ * fsl_lbc_ctrl_probe
+ *
+ * called by device layer when it finds a device matching
+ * one our driver can handled. This code allocates all of
+ * the resources needed for the controller only. The
+ * resources for the NAND banks themselves are allocated
+ * in the chip probe function.
+*/
+
+static int __devinit fsl_lbc_ctrl_probe(struct platform_device *dev)
+{
+ int ret;
+
+ if (!dev->dev.of_node) {
+ dev_err(&dev->dev, "Device OF-Node is NULL");
+ return -EFAULT;
+ }
+
+ fsl_lbc_ctrl_dev = kzalloc(sizeof(*fsl_lbc_ctrl_dev), GFP_KERNEL);
+ if (!fsl_lbc_ctrl_dev)
+ return -ENOMEM;
+
+ dev_set_drvdata(&dev->dev, fsl_lbc_ctrl_dev);
+
+ spin_lock_init(&fsl_lbc_ctrl_dev->lock);
+ init_waitqueue_head(&fsl_lbc_ctrl_dev->irq_wait);
+
+ fsl_lbc_ctrl_dev->regs = of_iomap(dev->dev.of_node, 0);
+ if (!fsl_lbc_ctrl_dev->regs) {
+ dev_err(&dev->dev, "failed to get memory region\n");
+ ret = -ENODEV;
+ goto err;
+ }
+
+ fsl_lbc_ctrl_dev->irq = irq_of_parse_and_map(dev->dev.of_node, 0);
+ if (fsl_lbc_ctrl_dev->irq == NO_IRQ) {
+ dev_err(&dev->dev, "failed to get irq resource\n");
+ ret = -ENODEV;
+ goto err;
+ }
+
+ fsl_lbc_ctrl_dev->dev = &dev->dev;
+
+ ret = fsl_lbc_ctrl_init(fsl_lbc_ctrl_dev);
+ if (ret < 0)
+ goto err;
+
+ ret = request_irq(fsl_lbc_ctrl_dev->irq, fsl_lbc_ctrl_irq, 0,
+ "fsl-lbc", fsl_lbc_ctrl_dev);
+ if (ret != 0) {
+ dev_err(&dev->dev, "failed to install irq (%d)\n",
+ fsl_lbc_ctrl_dev->irq);
+ ret = fsl_lbc_ctrl_dev->irq;
+ goto err;
+ }
+
+ return 0;
+
+err:
+ iounmap(fsl_lbc_ctrl_dev->regs);
+ kfree(fsl_lbc_ctrl_dev);
+ return ret;
+}
+
+static const struct of_device_id fsl_lbc_match[] = {
+ { .compatible = "fsl,elbc", },
+ { .compatible = "fsl,pq3-localbus", },
+ { .compatible = "fsl,pq2-localbus", },
+ { .compatible = "fsl,pq2pro-localbus", },
+ {},
+};
+
+static struct platform_driver fsl_lbc_ctrl_driver = {
+ .driver = {
+ .name = "fsl-lbc",
+ .of_match_table = fsl_lbc_match,
+ },
+ .probe = fsl_lbc_ctrl_probe,
+};
+
+static int __init fsl_lbc_init(void)
+{
+ return platform_driver_register(&fsl_lbc_ctrl_driver);
+}
+module_init(fsl_lbc_init);
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..9725369d432a 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -50,6 +50,7 @@
#define RIO_ATMU_REGS_OFFSET 0x10c00
#define RIO_P_MSG_REGS_OFFSET 0x11000
#define RIO_S_MSG_REGS_OFFSET 0x13000
+#define RIO_GCCSR 0x13c
#define RIO_ESCSR 0x158
#define RIO_CCSR 0x15c
#define RIO_LTLEDCSR 0x0608
@@ -87,6 +88,9 @@
#define RIO_IPWSR_PWD 0x00000008
#define RIO_IPWSR_PWB 0x00000004
+#define RIO_EPWISR_PINT 0x80000000
+#define RIO_EPWISR_PW 0x00000001
+
#define RIO_MSG_DESC_SIZE 32
#define RIO_MSG_BUFFER_SIZE 4096
#define RIO_MIN_TX_RING_SIZE 2
@@ -117,44 +121,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 {
@@ -1067,18 +1086,12 @@ fsl_rio_port_write_handler(int irq, void *dev_instance)
struct rio_priv *priv = port->priv;
u32 epwisr, tmp;
- ipwmr = in_be32(&priv->msg_regs->pwmr);
- ipwsr = in_be32(&priv->msg_regs->pwsr);
-
epwisr = in_be32(priv->regs_win + RIO_EPWISR);
- if (epwisr & 0x80000000) {
- tmp = in_be32(priv->regs_win + RIO_LTLEDCSR);
- pr_info("RIO_LTLEDCSR = 0x%x\n", tmp);
- out_be32(priv->regs_win + RIO_LTLEDCSR, 0);
- }
+ if (!(epwisr & RIO_EPWISR_PW))
+ goto pw_done;
- if (!(epwisr & 0x00000001))
- return IRQ_HANDLED;
+ ipwmr = in_be32(&priv->msg_regs->pwmr);
+ ipwsr = in_be32(&priv->msg_regs->pwsr);
#ifdef DEBUG_PW
pr_debug("PW Int->IPWMR: 0x%08x IPWSR: 0x%08x (", ipwmr, ipwsr);
@@ -1094,20 +1107,6 @@ fsl_rio_port_write_handler(int irq, void *dev_instance)
pr_debug(" PWB");
pr_debug(" )\n");
#endif
- out_be32(&priv->msg_regs->pwsr,
- ipwsr & (RIO_IPWSR_TE | RIO_IPWSR_QFI | RIO_IPWSR_PWD));
-
- if ((ipwmr & RIO_IPWMR_EIE) && (ipwsr & RIO_IPWSR_TE)) {
- priv->port_write_msg.err_count++;
- pr_info("RIO: Port-Write Transaction Err (%d)\n",
- priv->port_write_msg.err_count);
- }
- if (ipwsr & RIO_IPWSR_PWD) {
- priv->port_write_msg.discard_count++;
- pr_info("RIO: Port Discarded Port-Write Msg(s) (%d)\n",
- priv->port_write_msg.discard_count);
- }
-
/* Schedule deferred processing if PW was received */
if (ipwsr & RIO_IPWSR_QFI) {
/* Save PW message (if there is room in FIFO),
@@ -1119,16 +1118,43 @@ fsl_rio_port_write_handler(int irq, void *dev_instance)
RIO_PW_MSG_SIZE);
} else {
priv->port_write_msg.discard_count++;
- pr_info("RIO: ISR Discarded Port-Write Msg(s) (%d)\n",
+ pr_debug("RIO: ISR Discarded Port-Write Msg(s) (%d)\n",
priv->port_write_msg.discard_count);
}
+ /* Clear interrupt and issue Clear Queue command. This allows
+ * another port-write to be received.
+ */
+ out_be32(&priv->msg_regs->pwsr, RIO_IPWSR_QFI);
+ out_be32(&priv->msg_regs->pwmr, ipwmr | RIO_IPWMR_CQ);
+
schedule_work(&priv->pw_work);
}
- /* Issue Clear Queue command. This allows another
- * port-write to be received.
- */
- out_be32(&priv->msg_regs->pwmr, ipwmr | RIO_IPWMR_CQ);
+ if ((ipwmr & RIO_IPWMR_EIE) && (ipwsr & RIO_IPWSR_TE)) {
+ priv->port_write_msg.err_count++;
+ pr_debug("RIO: Port-Write Transaction Err (%d)\n",
+ priv->port_write_msg.err_count);
+ /* Clear Transaction Error: port-write controller should be
+ * disabled when clearing this error
+ */
+ out_be32(&priv->msg_regs->pwmr, ipwmr & ~RIO_IPWMR_PWE);
+ out_be32(&priv->msg_regs->pwsr, RIO_IPWSR_TE);
+ out_be32(&priv->msg_regs->pwmr, ipwmr);
+ }
+
+ if (ipwsr & RIO_IPWSR_PWD) {
+ priv->port_write_msg.discard_count++;
+ pr_debug("RIO: Port Discarded Port-Write Msg(s) (%d)\n",
+ priv->port_write_msg.discard_count);
+ out_be32(&priv->msg_regs->pwsr, RIO_IPWSR_PWD);
+ }
+
+pw_done:
+ if (epwisr & RIO_EPWISR_PINT) {
+ tmp = in_be32(priv->regs_win + RIO_LTLEDCSR);
+ pr_debug("RIO_LTLEDCSR = 0x%x\n", tmp);
+ out_be32(priv->regs_win + RIO_LTLEDCSR, 0);
+ }
return IRQ_HANDLED;
}
@@ -1446,6 +1472,7 @@ int fsl_rio_setup(struct platform_device *dev)
port->host_deviceid = fsl_rio_get_hdid(port->id);
port->priv = priv;
+ port->phys_efptr = 0x100;
rio_register_mport(port);
priv->regs_win = ioremap(regs.start, regs.end - regs.start + 1);
@@ -1493,6 +1520,12 @@ int fsl_rio_setup(struct platform_device *dev)
dev_info(&dev->dev, "RapidIO Common Transport System size: %d\n",
port->sys_size ? 65536 : 256);
+ if (port->host_deviceid >= 0)
+ out_be32(priv->regs_win + RIO_GCCSR, RIO_PORT_GEN_HOST |
+ RIO_PORT_GEN_MASTER | RIO_PORT_GEN_DISCOVERED);
+ else
+ out_be32(priv->regs_win + RIO_GCCSR, 0x00000000);
+
priv->atmu_regs = (struct rio_atmu_regs *)(priv->regs_win
+ RIO_ATMU_REGS_OFFSET);
priv->maint_atmu_regs = priv->atmu_regs + 1;
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/Kbuild b/arch/s390/Kbuild
new file mode 100644
index 000000000000..ae4b01060edd
--- /dev/null
+++ b/arch/s390/Kbuild
@@ -0,0 +1,6 @@
+obj-y += kernel/
+obj-y += mm/
+obj-y += crypto/
+obj-y += appldata/
+obj-y += hypfs/
+obj-y += kvm/
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index f0777a47e3a5..e0b98e71ff47 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -1,8 +1,3 @@
-#
-# For a description of the syntax of this configuration file,
-# see Documentation/kbuild/kconfig-language.txt.
-#
-
config SCHED_MC
def_bool y
depends on SMP
@@ -60,6 +55,9 @@ config NO_IOMEM
config NO_DMA
def_bool y
+config ARCH_DMA_ADDR_T_64BIT
+ def_bool 64BIT
+
config GENERIC_LOCKBREAK
bool
default y
@@ -75,8 +73,6 @@ config VIRT_CPU_ACCOUNTING
config ARCH_SUPPORTS_DEBUG_PAGEALLOC
def_bool y
-mainmenu "Linux Kernel Configuration"
-
config S390
def_bool y
select USE_GENERIC_SMP_HELPERS if SMP
@@ -84,6 +80,7 @@ config S390
select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_TRACE_MCOUNT_TEST
select HAVE_FTRACE_MCOUNT_RECORD
+ select HAVE_C_RECORDMCOUNT
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_DYNAMIC_FTRACE
select HAVE_FUNCTION_GRAPH_TRACER
@@ -95,11 +92,13 @@ 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
select HAVE_KERNEL_LZMA
select HAVE_KERNEL_LZO
+ select HAVE_GET_USER_PAGES_FAST
select ARCH_INLINE_SPIN_TRYLOCK
select ARCH_INLINE_SPIN_TRYLOCK_BH
select ARCH_INLINE_SPIN_LOCK
@@ -146,7 +145,7 @@ source "kernel/time/Kconfig"
config 64BIT
bool "64 bit kernel"
help
- Select this option if you have a 64 bit IBM zSeries machine
+ Select this option if you have an IBM z/Architecture machine
and want to use the 64 bit addressing mode.
config 32BIT
@@ -198,12 +197,28 @@ config HOTPLUG_CPU
can be controlled through /sys/devices/system/cpu/cpu#.
Say N if you want to disable CPU hotplug.
+config SCHED_MC
+ def_bool y
+ prompt "Multi-core scheduler support"
+ depends on SMP
+ help
+ Multi-core scheduler support improves the CPU scheduler's decision
+ making when dealing with multi-core CPU chips at a cost of slightly
+ increased overhead in some places.
+
+config SCHED_BOOK
+ bool "Book scheduler support"
+ depends on SMP && SCHED_MC
+ 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
help
This option is required for IEEE compliant floating point arithmetic
- on older S/390 machines. Say Y unless you know your machine doesn't
+ on older ESA/390 machines. Say Y unless you know your machine doesn't
need this.
config COMPAT
@@ -232,8 +247,8 @@ config S390_EXEC_PROTECT
space programs and it also selects the addressing mode option above.
The kernel parameter noexec=on will enable this feature and also
switch the addressing modes, default is disabled. Enabling this (via
- kernel parameter) on machines earlier than IBM System z9-109 EC/BC
- will reduce system performance.
+ kernel parameter) on machines earlier than IBM System z9 this will
+ reduce system performance.
comment "Code generation options"
@@ -242,41 +257,46 @@ choice
default MARCH_G5
config MARCH_G5
- bool "S/390 model G5 and G6"
+ bool "System/390 model G5 and G6"
depends on !64BIT
help
Select this to build a 31 bit kernel that works
- on all S/390 and zSeries machines.
+ on all ESA/390 and z/Architecture machines.
config MARCH_Z900
- bool "IBM eServer zSeries model z800 and z900"
+ bool "IBM zSeries model z800 and z900"
help
- Select this to optimize for zSeries machines. This
- will enable some optimizations that are not available
- on older 31 bit only CPUs.
+ Select this to enable optimizations for model z800/z900 (2064 and
+ 2066 series). This will enable some optimizations that are not
+ available on older ESA/390 (31 Bit) only CPUs.
config MARCH_Z990
- bool "IBM eServer zSeries model z890 and z990"
+ bool "IBM zSeries model z890 and z990"
help
- Select this enable optimizations for model z890/z990.
- This will be slightly faster but does not work on
- older machines such as the z900.
+ Select this to enable optimizations for model z890/z990 (2084 and
+ 2086 series). The kernel will be slightly faster but will not work
+ on older machines.
config MARCH_Z9_109
bool "IBM System z9"
help
- Select this to enable optimizations for IBM System z9-109, IBM
- System z9 Enterprise Class (z9 EC), and IBM System z9 Business
- Class (z9 BC). The kernel will be slightly faster but will not
- work on older machines such as the z990, z890, z900, and z800.
+ Select this to enable optimizations for IBM System z9 (2094 and
+ 2096 series). The kernel will be slightly faster but will not work
+ on older machines.
config MARCH_Z10
bool "IBM System z10"
help
- Select this to enable optimizations for IBM System z10. The
- kernel will be slightly faster but will not work on older
- machines such as the z990, z890, z900, z800, z9-109, z9-ec
- and z9-bc.
+ Select this to enable optimizations for IBM System z10 (2097 and
+ 2098 series). The kernel will be slightly faster but will not work
+ on older machines.
+
+config MARCH_Z196
+ bool "IBM zEnterprise 196"
+ help
+ Select this to enable optimizations for IBM zEnterprise 196
+ (2817 series). The kernel will be slightly faster but will not work
+ on older machines.
endchoice
diff --git a/arch/s390/Makefile b/arch/s390/Makefile
index 0c9e6c6d2a64..d5b8a6ade525 100644
--- a/arch/s390/Makefile
+++ b/arch/s390/Makefile
@@ -40,6 +40,7 @@ cflags-$(CONFIG_MARCH_Z900) += $(call cc-option,-march=z900)
cflags-$(CONFIG_MARCH_Z990) += $(call cc-option,-march=z990)
cflags-$(CONFIG_MARCH_Z9_109) += $(call cc-option,-march=z9-109)
cflags-$(CONFIG_MARCH_Z10) += $(call cc-option,-march=z10)
+cflags-$(CONFIG_MARCH_Z196) += $(call cc-option,-march=z196)
#KBUILD_IMAGE is necessary for make rpm
KBUILD_IMAGE :=arch/s390/boot/image
@@ -94,8 +95,8 @@ head-y := arch/s390/kernel/head.o
head-y += arch/s390/kernel/$(if $(CONFIG_64BIT),head64.o,head31.o)
head-y += arch/s390/kernel/init_task.o
-core-y += arch/s390/mm/ arch/s390/kernel/ arch/s390/crypto/ \
- arch/s390/appldata/ arch/s390/hypfs/ arch/s390/kvm/
+# See arch/s390/Kbuild for content of core part of the kernel
+core-y += arch/s390/
libs-y += arch/s390/lib/
drivers-y += drivers/s390/
diff --git a/arch/s390/crypto/crypt_s390.h b/arch/s390/crypto/crypt_s390.h
index 0ef9829f2ad6..7ee9a1b4ad9f 100644
--- a/arch/s390/crypto/crypt_s390.h
+++ b/arch/s390/crypto/crypt_s390.h
@@ -297,7 +297,7 @@ static inline int crypt_s390_func_available(int func)
int ret;
/* check if CPACF facility (bit 17) is available */
- if (!(stfl() & 1ULL << (31 - 17)))
+ if (!test_facility(17))
return 0;
switch (func & CRYPT_S390_OP_MASK) {
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..cd4a81be9cf8 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)
@@ -637,18 +638,21 @@ __init int hypfs_diag_init(void)
pr_err("The hardware system does not support hypfs\n");
return -ENODATA;
}
- rc = diag224_get_name_table();
- if (rc) {
- diag204_free_buffer();
- pr_err("The hardware system does not provide all "
- "functions required by hypfs\n");
- }
if (diag204_info_type == INFO_EXT) {
rc = hypfs_dbfs_init();
if (rc)
- diag204_free_buffer();
+ return rc;
}
- return rc;
+ if (MACHINE_IS_LPAR) {
+ rc = diag224_get_name_table();
+ if (rc) {
+ pr_err("The hardware system does not provide all "
+ "functions required by hypfs\n");
+ debugfs_remove(dbfs_d204_file);
+ return rc;
+ }
+ }
+ return 0;
}
void hypfs_diag_exit(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..47cc446dab8f 100644
--- a/arch/s390/hypfs/inode.c
+++ b/arch/s390/hypfs/inode.c
@@ -316,10 +316,10 @@ static int hypfs_fill_super(struct super_block *sb, void *data, int silent)
return 0;
}
-static int hypfs_get_super(struct file_system_type *fst, int flags,
- const char *devname, void *data, struct vfsmount *mnt)
+static struct dentry *hypfs_mount(struct file_system_type *fst, int flags,
+ const char *devname, void *data)
{
- return get_sb_single(fst, flags, data, hypfs_fill_super, mnt);
+ return mount_single(fst, flags, data, hypfs_fill_super);
}
static void hypfs_kill_super(struct super_block *sb)
@@ -449,12 +449,13 @@ 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 = {
.owner = THIS_MODULE,
.name = "s390_hypfs",
- .get_sb = hypfs_get_super,
+ .mount = hypfs_mount,
.kill_sb = hypfs_kill_super
};
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/ccwdev.h b/arch/s390/include/asm/ccwdev.h
index f3ba0fa98de6..e8501115eca8 100644
--- a/arch/s390/include/asm/ccwdev.h
+++ b/arch/s390/include/asm/ccwdev.h
@@ -92,6 +92,16 @@ struct ccw_device {
};
/*
+ * Possible events used by the path_event notifier.
+ */
+#define PE_NONE 0x0
+#define PE_PATH_GONE 0x1 /* A path is no longer available. */
+#define PE_PATH_AVAILABLE 0x2 /* A path has become available and
+ was successfully verified. */
+#define PE_PATHGROUP_ESTABLISHED 0x4 /* A pathgroup was reset and had
+ to be established again. */
+
+/*
* Possible CIO actions triggered by the unit check handler.
*/
enum uc_todo {
@@ -109,6 +119,7 @@ enum uc_todo {
* @set_online: called when setting device online
* @set_offline: called when setting device offline
* @notify: notify driver of device state changes
+ * @path_event: notify driver of channel path events
* @shutdown: called at device shutdown
* @prepare: prepare for pm state transition
* @complete: undo work done in @prepare
@@ -127,6 +138,7 @@ struct ccw_driver {
int (*set_online) (struct ccw_device *);
int (*set_offline) (struct ccw_device *);
int (*notify) (struct ccw_device *, int);
+ void (*path_event) (struct ccw_device *, int *);
void (*shutdown) (struct ccw_device *);
int (*prepare) (struct ccw_device *);
void (*complete) (struct ccw_device *);
diff --git a/arch/s390/include/asm/cpu.h b/arch/s390/include/asm/cpu.h
index 471234b90574..e0b69540216f 100644
--- a/arch/s390/include/asm/cpu.h
+++ b/arch/s390/include/asm/cpu.h
@@ -20,7 +20,7 @@ struct cpuid
unsigned int ident : 24;
unsigned int machine : 16;
unsigned int unused : 16;
-} __packed;
+} __attribute__ ((packed, aligned(8)));
#endif /* __ASSEMBLY__ */
#endif /* _ASM_S390_CPU_H */
diff --git a/arch/s390/include/asm/cputime.h b/arch/s390/include/asm/cputime.h
index 8b1a52a137c5..40e2ab0fa3f0 100644
--- a/arch/s390/include/asm/cputime.h
+++ b/arch/s390/include/asm/cputime.h
@@ -73,18 +73,18 @@ cputime64_to_jiffies64(cputime64_t cputime)
}
/*
- * Convert cputime to milliseconds and back.
+ * Convert cputime to microseconds and back.
*/
static inline unsigned int
-cputime_to_msecs(const cputime_t cputime)
+cputime_to_usecs(const cputime_t cputime)
{
- return cputime_div(cputime, 4096000);
+ return cputime_div(cputime, 4096);
}
static inline cputime_t
-msecs_to_cputime(const unsigned int m)
+usecs_to_cputime(const unsigned int m)
{
- return (cputime_t) m * 4096000;
+ return (cputime_t) m * 4096;
}
/*
diff --git a/arch/s390/include/asm/dasd.h b/arch/s390/include/asm/dasd.h
index 218bce81ec70..b604a9186f8e 100644
--- a/arch/s390/include/asm/dasd.h
+++ b/arch/s390/include/asm/dasd.h
@@ -217,6 +217,25 @@ typedef struct dasd_symmio_parms {
int rssd_result_len;
} __attribute__ ((packed)) dasd_symmio_parms_t;
+/*
+ * Data returned by Sense Path Group ID (SNID)
+ */
+struct dasd_snid_data {
+ struct {
+ __u8 group:2;
+ __u8 reserve:2;
+ __u8 mode:1;
+ __u8 res:3;
+ } __attribute__ ((packed)) path_state;
+ __u8 pgid[11];
+} __attribute__ ((packed));
+
+struct dasd_snid_ioctl_data {
+ struct dasd_snid_data data;
+ __u8 path_mask;
+} __attribute__ ((packed));
+
+
/********************************************************************************
* SECTION: Definition of IOCTLs
*
@@ -261,25 +280,10 @@ typedef struct dasd_symmio_parms {
/* Set Attributes (cache operations) */
#define BIODASDSATTR _IOW(DASD_IOCTL_LETTER,2,attrib_data_t)
+/* Get Sense Path Group ID (SNID) data */
+#define BIODASDSNID _IOWR(DASD_IOCTL_LETTER, 1, struct dasd_snid_ioctl_data)
+
#define BIODASDSYMMIO _IOWR(DASD_IOCTL_LETTER, 240, dasd_symmio_parms_t)
#endif /* DASD_H */
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
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/hugetlb.h b/arch/s390/include/asm/hugetlb.h
index bb8343d157bc..b56403c2df28 100644
--- a/arch/s390/include/asm/hugetlb.h
+++ b/arch/s390/include/asm/hugetlb.h
@@ -37,32 +37,6 @@ static inline int prepare_hugepage_range(struct file *file,
int arch_prepare_hugepage(struct page *page);
void arch_release_hugepage(struct page *page);
-static inline pte_t pte_mkhuge(pte_t pte)
-{
- /*
- * PROT_NONE needs to be remapped from the pte type to the ste type.
- * The HW invalid bit is also different for pte and ste. The pte
- * invalid bit happens to be the same as the ste _SEGMENT_ENTRY_LARGE
- * bit, so we don't have to clear it.
- */
- if (pte_val(pte) & _PAGE_INVALID) {
- if (pte_val(pte) & _PAGE_SWT)
- pte_val(pte) |= _HPAGE_TYPE_NONE;
- pte_val(pte) |= _SEGMENT_ENTRY_INV;
- }
- /*
- * Clear SW pte bits SWT and SWX, there are no SW bits in a segment
- * table entry.
- */
- pte_val(pte) &= ~(_PAGE_SWT | _PAGE_SWX);
- /*
- * Also set the change-override bit because we don't need dirty bit
- * tracking for hugetlbfs pages.
- */
- pte_val(pte) |= (_SEGMENT_ENTRY_LARGE | _SEGMENT_ENTRY_CO);
- return pte;
-}
-
static inline pte_t huge_pte_wrprotect(pte_t pte)
{
pte_val(pte) |= _PAGE_RO;
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/lowcore.h b/arch/s390/include/asm/lowcore.h
index 0f97ef2d92ac..65e172f8209d 100644
--- a/arch/s390/include/asm/lowcore.h
+++ b/arch/s390/include/asm/lowcore.h
@@ -150,9 +150,10 @@ struct _lowcore {
*/
__u32 ipib; /* 0x0e00 */
__u32 ipib_checksum; /* 0x0e04 */
+ __u8 pad_0x0e08[0x0f00-0x0e08]; /* 0x0e08 */
- /* Align to the top 1k of prefix area */
- __u8 pad_0x0e08[0x1000-0x0e08]; /* 0x0e08 */
+ /* Extended facility list */
+ __u64 stfle_fac_list[32]; /* 0x0f00 */
} __packed;
#else /* CONFIG_32BIT */
@@ -285,7 +286,11 @@ struct _lowcore {
*/
__u64 ipib; /* 0x0e00 */
__u32 ipib_checksum; /* 0x0e08 */
- __u8 pad_0x0e0c[0x11b8-0x0e0c]; /* 0x0e0c */
+ __u8 pad_0x0e0c[0x0f00-0x0e0c]; /* 0x0e0c */
+
+ /* Extended facility list */
+ __u64 stfle_fac_list[32]; /* 0x0f00 */
+ __u8 pad_0x1000[0x11b8-0x1000]; /* 0x1000 */
/* 64 bit extparam used for pfault/diag 250: defined by architecture */
__u64 ext_params2; /* 0x11B8 */
diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h
index af650fb47206..a8729ea7e9ac 100644
--- a/arch/s390/include/asm/page.h
+++ b/arch/s390/include/asm/page.h
@@ -108,9 +108,13 @@ typedef pte_t *pgtable_t;
#define __pgprot(x) ((pgprot_t) { (x) } )
static inline void
-page_set_storage_key(unsigned long addr, unsigned int skey)
+page_set_storage_key(unsigned long addr, unsigned int skey, int mapped)
{
- asm volatile("sske %0,%1" : : "d" (skey), "a" (addr));
+ if (!mapped)
+ asm volatile(".insn rrf,0xb22b0000,%0,%1,8,0"
+ : : "d" (skey), "a" (addr));
+ else
+ asm volatile("sske %0,%1" : : "d" (skey), "a" (addr));
}
static inline unsigned int
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/pgalloc.h b/arch/s390/include/asm/pgalloc.h
index 68940d0bad91..082eb4e50e8b 100644
--- a/arch/s390/include/asm/pgalloc.h
+++ b/arch/s390/include/asm/pgalloc.h
@@ -21,9 +21,11 @@
unsigned long *crst_table_alloc(struct mm_struct *, int);
void crst_table_free(struct mm_struct *, unsigned long *);
+void crst_table_free_rcu(struct mm_struct *, unsigned long *);
unsigned long *page_table_alloc(struct mm_struct *);
void page_table_free(struct mm_struct *, unsigned long *);
+void page_table_free_rcu(struct mm_struct *, unsigned long *);
void disable_noexec(struct mm_struct *, struct task_struct *);
static inline void clear_table(unsigned long *s, unsigned long val, size_t n)
@@ -176,4 +178,6 @@ static inline void pmd_populate(struct mm_struct *mm,
#define pte_free_kernel(mm, pte) page_table_free(mm, (unsigned long *) pte)
#define pte_free(mm, pte) page_table_free(mm, (unsigned long *) pte)
+extern void rcu_table_freelist_finish(void);
+
#endif /* _S390_PGALLOC_H */
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index 3157441ee1da..02ace3491c51 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -38,6 +38,7 @@
extern pgd_t swapper_pg_dir[] __attribute__ ((aligned (4096)));
extern void paging_init(void);
extern void vmem_map_init(void);
+extern void fault_init(void);
/*
* The S390 doesn't have any external MMU info: the kernel page
@@ -46,11 +47,27 @@ extern void vmem_map_init(void);
#define update_mmu_cache(vma, address, ptep) do { } while (0)
/*
- * ZERO_PAGE is a global shared page that is always zero: used
+ * ZERO_PAGE is a global shared page that is always zero; used
* for zero-mapped memory areas etc..
*/
-extern char empty_zero_page[PAGE_SIZE];
-#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
+
+extern unsigned long empty_zero_page;
+extern unsigned long zero_page_mask;
+
+#define ZERO_PAGE(vaddr) \
+ (virt_to_page((void *)(empty_zero_page + \
+ (((unsigned long)(vaddr)) &zero_page_mask))))
+
+#define is_zero_pfn is_zero_pfn
+static inline int is_zero_pfn(unsigned long pfn)
+{
+ extern unsigned long zero_pfn;
+ unsigned long offset_from_zero_pfn = pfn - zero_pfn;
+ return offset_from_zero_pfn <= (zero_page_mask >> PAGE_SHIFT);
+}
+
+#define my_zero_pfn(addr) page_to_pfn(ZERO_PAGE(addr))
+
#endif /* !__ASSEMBLY__ */
/*
@@ -300,6 +317,7 @@ extern unsigned long VMALLOC_START;
/* Bits in the segment table entry */
#define _SEGMENT_ENTRY_ORIGIN 0x7fffffc0UL /* page table origin */
+#define _SEGMENT_ENTRY_RO 0x200 /* page protection bit */
#define _SEGMENT_ENTRY_INV 0x20 /* invalid segment table entry */
#define _SEGMENT_ENTRY_COMMON 0x10 /* common segment bit */
#define _SEGMENT_ENTRY_PTL 0x0f /* page table length */
@@ -572,7 +590,7 @@ static inline void rcp_unlock(pte_t *ptep)
}
/* forward declaration for SetPageUptodate in page-flags.h*/
-static inline void page_clear_dirty(struct page *page);
+static inline void page_clear_dirty(struct page *page, int mapped);
#include <linux/page-flags.h>
static inline void ptep_rcp_copy(pte_t *ptep)
@@ -754,6 +772,34 @@ static inline pte_t pte_mkspecial(pte_t pte)
return pte;
}
+#ifdef CONFIG_HUGETLB_PAGE
+static inline pte_t pte_mkhuge(pte_t pte)
+{
+ /*
+ * PROT_NONE needs to be remapped from the pte type to the ste type.
+ * The HW invalid bit is also different for pte and ste. The pte
+ * invalid bit happens to be the same as the ste _SEGMENT_ENTRY_LARGE
+ * bit, so we don't have to clear it.
+ */
+ if (pte_val(pte) & _PAGE_INVALID) {
+ if (pte_val(pte) & _PAGE_SWT)
+ pte_val(pte) |= _HPAGE_TYPE_NONE;
+ pte_val(pte) |= _SEGMENT_ENTRY_INV;
+ }
+ /*
+ * Clear SW pte bits SWT and SWX, there are no SW bits in a segment
+ * table entry.
+ */
+ pte_val(pte) &= ~(_PAGE_SWT | _PAGE_SWX);
+ /*
+ * Also set the change-override bit because we don't need dirty bit
+ * tracking for hugetlbfs pages.
+ */
+ pte_val(pte) |= (_SEGMENT_ENTRY_LARGE | _SEGMENT_ENTRY_CO);
+ return pte;
+}
+#endif
+
#ifdef CONFIG_PGSTE
/*
* Get (and clear) the user dirty bit for a PTE.
@@ -782,7 +828,7 @@ static inline int kvm_s390_test_and_clear_page_dirty(struct mm_struct *mm,
}
dirty = test_and_clear_bit_simple(KVM_UD_BIT, pgste);
if (skey & _PAGE_CHANGED)
- page_clear_dirty(page);
+ page_clear_dirty(page, 1);
rcp_unlock(ptep);
return dirty;
}
@@ -957,9 +1003,9 @@ static inline int page_test_dirty(struct page *page)
}
#define __HAVE_ARCH_PAGE_CLEAR_DIRTY
-static inline void page_clear_dirty(struct page *page)
+static inline void page_clear_dirty(struct page *page, int mapped)
{
- page_set_storage_key(page_to_phys(page), PAGE_DEFAULT_KEY);
+ page_set_storage_key(page_to_phys(page), PAGE_DEFAULT_KEY, mapped);
}
/*
@@ -1048,9 +1094,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address)
#define pte_offset(pmd, addr) ((pte_t *) pmd_deref(*(pmd)) + pte_index(addr))
#define pte_offset_kernel(pmd, address) pte_offset(pmd,address)
#define pte_offset_map(pmd, address) pte_offset_kernel(pmd, address)
-#define pte_offset_map_nested(pmd, address) pte_offset_kernel(pmd, address)
#define pte_unmap(pte) do { } while (0)
-#define pte_unmap_nested(pte) do { } while (0)
/*
* 31 bit swap entry format:
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h
index 73e259834e10..8d6f87169577 100644
--- a/arch/s390/include/asm/processor.h
+++ b/arch/s390/include/asm/processor.h
@@ -82,8 +82,6 @@ struct thread_struct {
unsigned long prot_addr; /* address of protection-excep. */
unsigned int trap_no;
per_struct per_info;
- /* Used to give failing instruction back to user for ieee exceptions */
- unsigned long ieee_instruction_pointer;
/* pfault_wait is used to block the process on a pfault event */
unsigned long pfault_wait;
};
diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h
index e2c218dc68a6..d9d42b1e46fa 100644
--- a/arch/s390/include/asm/ptrace.h
+++ b/arch/s390/include/asm/ptrace.h
@@ -481,8 +481,7 @@ struct user_regs_struct
* watchpoints. This is the way intel does it.
*/
per_struct per_info;
- unsigned long ieee_instruction_pointer;
- /* Used to give failing instruction back to user for ieee exceptions */
+ unsigned long ieee_instruction_pointer; /* obsolete, always 0 */
};
#ifdef __KERNEL__
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/s390_ext.h b/arch/s390/include/asm/s390_ext.h
index 2afc060266a2..1a9307e70842 100644
--- a/arch/s390/include/asm/s390_ext.h
+++ b/arch/s390/include/asm/s390_ext.h
@@ -12,7 +12,7 @@
#include <linux/types.h>
-typedef void (*ext_int_handler_t)(__u16 code);
+typedef void (*ext_int_handler_t)(unsigned int, unsigned int, unsigned long);
typedef struct ext_int_info_t {
struct ext_int_info_t *next;
diff --git a/arch/s390/include/asm/scatterlist.h b/arch/s390/include/asm/scatterlist.h
index 35d786fe93ae..6d45ef6c12a7 100644
--- a/arch/s390/include/asm/scatterlist.h
+++ b/arch/s390/include/asm/scatterlist.h
@@ -1 +1,3 @@
#include <asm-generic/scatterlist.h>
+
+#define ARCH_HAS_SG_CHAIN
diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h
index 25e831d58e1e..d5e2ef10537d 100644
--- a/arch/s390/include/asm/setup.h
+++ b/arch/s390/include/asm/setup.h
@@ -73,6 +73,7 @@ extern unsigned int user_mode;
#define MACHINE_FLAG_PFMF (1UL << 11)
#define MACHINE_FLAG_LPAR (1UL << 12)
#define MACHINE_FLAG_SPP (1UL << 13)
+#define MACHINE_FLAG_TOPOLOGY (1UL << 14)
#define MACHINE_IS_VM (S390_lowcore.machine_flags & MACHINE_FLAG_VM)
#define MACHINE_IS_KVM (S390_lowcore.machine_flags & MACHINE_FLAG_KVM)
@@ -90,6 +91,7 @@ extern unsigned int user_mode;
#define MACHINE_HAS_HPAGE (0)
#define MACHINE_HAS_PFMF (0)
#define MACHINE_HAS_SPP (0)
+#define MACHINE_HAS_TOPOLOGY (0)
#else /* __s390x__ */
#define MACHINE_HAS_IEEE (1)
#define MACHINE_HAS_CSP (1)
@@ -100,6 +102,7 @@ extern unsigned int user_mode;
#define MACHINE_HAS_HPAGE (S390_lowcore.machine_flags & MACHINE_FLAG_HPAGE)
#define MACHINE_HAS_PFMF (S390_lowcore.machine_flags & MACHINE_FLAG_PFMF)
#define MACHINE_HAS_SPP (S390_lowcore.machine_flags & MACHINE_FLAG_SPP)
+#define MACHINE_HAS_TOPOLOGY (S390_lowcore.machine_flags & MACHINE_FLAG_TOPOLOGY)
#endif /* __s390x__ */
#define ZFCPDUMP_HSA_SIZE (32UL<<20)
diff --git a/arch/s390/include/asm/syscall.h b/arch/s390/include/asm/syscall.h
index 8429686951f9..5c0246b955d8 100644
--- a/arch/s390/include/asm/syscall.h
+++ b/arch/s390/include/asm/syscall.h
@@ -65,8 +65,6 @@ static inline void syscall_get_arguments(struct task_struct *task,
if (test_tsk_thread_flag(task, TIF_31BIT))
mask = 0xffffffff;
#endif
- if (i + n == 6)
- args[--n] = regs->args[0] & mask;
while (n-- > 0)
if (i + n > 0)
args[n] = regs->gprs[2 + i + n] & mask;
@@ -80,8 +78,6 @@ static inline void syscall_set_arguments(struct task_struct *task,
const unsigned long *args)
{
BUG_ON(i + n > 6);
- if (i + n == 6)
- regs->args[0] = args[--n];
while (n-- > 0)
if (i + n > 0)
regs->gprs[2 + i + n] = args[n];
diff --git a/arch/s390/include/asm/sysinfo.h b/arch/s390/include/asm/sysinfo.h
index 22bdb2a0ee5f..79d3d6e2e9c5 100644
--- a/arch/s390/include/asm/sysinfo.h
+++ b/arch/s390/include/asm/sysinfo.h
@@ -14,8 +14,13 @@
#ifndef __ASM_S390_SYSINFO_H
#define __ASM_S390_SYSINFO_H
+#include <asm/bitsperlong.h>
+
struct sysinfo_1_1_1 {
- char reserved_0[32];
+ unsigned short :16;
+ unsigned char ccr;
+ unsigned char cai;
+ char reserved_0[28];
char manufacturer[16];
char type[4];
char reserved_1[12];
@@ -104,6 +109,39 @@ struct sysinfo_3_2_2 {
char reserved_544[3552];
};
+#define TOPOLOGY_CPU_BITS 64
+#define TOPOLOGY_NR_MAG 6
+
+struct topology_cpu {
+ unsigned char reserved0[4];
+ unsigned char :6;
+ unsigned char pp:2;
+ unsigned char reserved1;
+ unsigned short origin;
+ unsigned long mask[TOPOLOGY_CPU_BITS / BITS_PER_LONG];
+};
+
+struct topology_container {
+ unsigned char reserved[7];
+ unsigned char id;
+};
+
+union topology_entry {
+ unsigned char nl;
+ struct topology_cpu cpu;
+ struct topology_container container;
+};
+
+struct sysinfo_15_1_x {
+ unsigned char reserved0[2];
+ unsigned short length;
+ unsigned char mag[TOPOLOGY_NR_MAG];
+ unsigned char reserved1;
+ unsigned char mnest;
+ unsigned char reserved2[4];
+ union topology_entry tle[0];
+};
+
static inline int stsi(void *sysinfo, int fc, int sel1, int sel2)
{
register int r0 asm("0") = (fc << 28) | sel1;
diff --git a/arch/s390/include/asm/system.h b/arch/s390/include/asm/system.h
index cef66210c846..3ad16dbf622e 100644
--- a/arch/s390/include/asm/system.h
+++ b/arch/s390/include/asm/system.h
@@ -85,19 +85,20 @@ static inline void restore_access_regs(unsigned int *acrs)
asm volatile("lam 0,15,%0" : : "Q" (*acrs));
}
-#define switch_to(prev,next,last) do { \
- if (prev == next) \
- break; \
- save_fp_regs(&prev->thread.fp_regs); \
- restore_fp_regs(&next->thread.fp_regs); \
- save_access_regs(&prev->thread.acrs[0]); \
- restore_access_regs(&next->thread.acrs[0]); \
- prev = __switch_to(prev,next); \
+#define switch_to(prev,next,last) do { \
+ if (prev->mm) { \
+ save_fp_regs(&prev->thread.fp_regs); \
+ save_access_regs(&prev->thread.acrs[0]); \
+ } \
+ if (next->mm) { \
+ restore_fp_regs(&next->thread.fp_regs); \
+ restore_access_regs(&next->thread.acrs[0]); \
+ } \
+ prev = __switch_to(prev,next); \
} while (0)
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 +400,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)
@@ -419,30 +420,21 @@ extern void smp_ctl_clear_bit(int cr, int bit);
#endif /* CONFIG_SMP */
-static inline unsigned int stfl(void)
-{
- asm volatile(
- " .insn s,0xb2b10000,0(0)\n" /* stfl */
- "0:\n"
- EX_TABLE(0b,0b));
- return S390_lowcore.stfl_fac_list;
-}
+#define MAX_FACILITY_BIT (256*8) /* stfle_fac_list has 256 bytes */
-static inline int __stfle(unsigned long long *list, int doublewords)
+/*
+ * The test_facility function uses the bit odering where the MSB is bit 0.
+ * That makes it easier to query facility bits with the bit number as
+ * documented in the Principles of Operation.
+ */
+static inline int test_facility(unsigned long nr)
{
- typedef struct { unsigned long long _[doublewords]; } addrtype;
- register unsigned long __nr asm("0") = doublewords - 1;
-
- asm volatile(".insn s,0xb2b00000,%0" /* stfle */
- : "=m" (*(addrtype *) list), "+d" (__nr) : : "cc");
- return __nr + 1;
-}
+ unsigned char *ptr;
-static inline int stfle(unsigned long long *list, int doublewords)
-{
- if (!(stfl() & (1UL << 24)))
- return -EOPNOTSUPP;
- return __stfle(list, doublewords);
+ if (nr >= MAX_FACILITY_BIT)
+ return 0;
+ ptr = (unsigned char *) &S390_lowcore.stfle_fac_list + (nr >> 3);
+ return (*ptr & (0x80 >> (nr & 7))) != 0;
}
static inline unsigned short stap(void)
diff --git a/arch/s390/include/asm/tlb.h b/arch/s390/include/asm/tlb.h
index fd1c00d08bf5..f1f644f2240a 100644
--- a/arch/s390/include/asm/tlb.h
+++ b/arch/s390/include/asm/tlb.h
@@ -64,10 +64,9 @@ static inline void tlb_flush_mmu(struct mmu_gather *tlb,
if (!tlb->fullmm && (tlb->nr_ptes > 0 || tlb->nr_pxds < TLB_NR_PTRS))
__tlb_flush_mm(tlb->mm);
while (tlb->nr_ptes > 0)
- pte_free(tlb->mm, tlb->array[--tlb->nr_ptes]);
+ page_table_free_rcu(tlb->mm, tlb->array[--tlb->nr_ptes]);
while (tlb->nr_pxds < TLB_NR_PTRS)
- /* pgd_free frees the pointer as region or segment table */
- pgd_free(tlb->mm, tlb->array[tlb->nr_pxds++]);
+ crst_table_free_rcu(tlb->mm, tlb->array[tlb->nr_pxds++]);
}
static inline void tlb_finish_mmu(struct mmu_gather *tlb,
@@ -75,6 +74,8 @@ static inline void tlb_finish_mmu(struct mmu_gather *tlb,
{
tlb_flush_mmu(tlb, start, end);
+ rcu_table_freelist_finish();
+
/* keep the page table cache within bounds */
check_pgt_cache();
@@ -103,7 +104,7 @@ static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
if (tlb->nr_ptes >= tlb->nr_pxds)
tlb_flush_mmu(tlb, 0, 0);
} else
- pte_free(tlb->mm, pte);
+ page_table_free(tlb->mm, (unsigned long *) pte);
}
/*
@@ -124,7 +125,7 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd,
if (tlb->nr_ptes >= tlb->nr_pxds)
tlb_flush_mmu(tlb, 0, 0);
} else
- pmd_free(tlb->mm, pmd);
+ crst_table_free(tlb->mm, (unsigned long *) pmd);
#endif
}
@@ -146,7 +147,7 @@ static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud,
if (tlb->nr_ptes >= tlb->nr_pxds)
tlb_flush_mmu(tlb, 0, 0);
} else
- pud_free(tlb->mm, pud);
+ crst_table_free(tlb->mm, (unsigned long *) pud);
#endif
}
diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h
index 831bd033ea77..c5338834ddbd 100644
--- a/arch/s390/include/asm/topology.h
+++ b/arch/s390/include/asm/topology.h
@@ -2,19 +2,38 @@
#define _ASM_S390_TOPOLOGY_H
#include <linux/cpumask.h>
-
-#define mc_capable() (1)
-
-const struct cpumask *cpu_coregroup_mask(unsigned int cpu);
+#include <asm/sysinfo.h>
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);
+void store_topology(struct sysinfo_15_1_x *info);
#define POLARIZATION_UNKNWN (-1)
#define POLARIZATION_HRZ (0)
@@ -30,6 +49,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/asm-offsets.c b/arch/s390/kernel/asm-offsets.c
index 5232278d79ad..33982e7ce04d 100644
--- a/arch/s390/kernel/asm-offsets.c
+++ b/arch/s390/kernel/asm-offsets.c
@@ -66,9 +66,9 @@ int main(void)
DEFINE(__VDSO_ECTG_BASE, offsetof(struct vdso_per_cpu_data, ectg_timer_base));
DEFINE(__VDSO_ECTG_USER, offsetof(struct vdso_per_cpu_data, ectg_user_time));
/* constants used by the vdso */
- DEFINE(CLOCK_REALTIME, CLOCK_REALTIME);
- DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC);
- DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
+ DEFINE(__CLOCK_REALTIME, CLOCK_REALTIME);
+ DEFINE(__CLOCK_MONOTONIC, CLOCK_MONOTONIC);
+ DEFINE(__CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
BLANK();
/* constants for SIGP */
DEFINE(__SIGP_STOP, sigp_stop);
@@ -84,6 +84,7 @@ int main(void)
DEFINE(__LC_SVC_INT_CODE, offsetof(struct _lowcore, svc_code));
DEFINE(__LC_PGM_ILC, offsetof(struct _lowcore, pgm_ilc));
DEFINE(__LC_PGM_INT_CODE, offsetof(struct _lowcore, pgm_code));
+ DEFINE(__LC_TRANS_EXC_CODE, offsetof(struct _lowcore, trans_exc_code));
DEFINE(__LC_PER_ATMID, offsetof(struct _lowcore, per_perc_atmid));
DEFINE(__LC_PER_ADDRESS, offsetof(struct _lowcore, per_address));
DEFINE(__LC_PER_ACCESS_ID, offsetof(struct _lowcore, per_access_id));
@@ -142,10 +143,8 @@ int main(void)
DEFINE(__LC_GPREGS_SAVE_AREA, offsetof(struct _lowcore, gpregs_save_area));
DEFINE(__LC_CREGS_SAVE_AREA, offsetof(struct _lowcore, cregs_save_area));
#ifdef CONFIG_32BIT
- DEFINE(__LC_PFAULT_INTPARM, offsetof(struct _lowcore, ext_params));
DEFINE(SAVE_AREA_BASE, offsetof(struct _lowcore, extended_save_area_addr));
#else /* CONFIG_32BIT */
- DEFINE(__LC_PFAULT_INTPARM, offsetof(struct _lowcore, ext_params2));
DEFINE(__LC_EXT_PARAMS2, offsetof(struct _lowcore, ext_params2));
DEFINE(SAVE_AREA_BASE, offsetof(struct _lowcore, floating_pt_save_area));
DEFINE(__LC_PASTE, offsetof(struct _lowcore, paste));
diff --git a/arch/s390/kernel/compat_ptrace.h b/arch/s390/kernel/compat_ptrace.h
index 123dd660d7fb..3141025724f4 100644
--- a/arch/s390/kernel/compat_ptrace.h
+++ b/arch/s390/kernel/compat_ptrace.h
@@ -51,8 +51,7 @@ struct user_regs_struct32
* watchpoints. This is the way intel does it.
*/
per_struct32 per_info;
- u32 ieee_instruction_pointer;
- /* Used to give failing instruction back to user for ieee exceptions */
+ u32 ieee_instruction_pointer; /* obsolete, always 0 */
};
struct user32 {
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/dis.c b/arch/s390/kernel/dis.c
index b39b27d68b45..c83726c9fe03 100644
--- a/arch/s390/kernel/dis.c
+++ b/arch/s390/kernel/dis.c
@@ -113,7 +113,7 @@ enum {
INSTR_INVALID,
INSTR_E,
INSTR_RIE_R0IU, INSTR_RIE_R0UU, INSTR_RIE_RRP, INSTR_RIE_RRPU,
- INSTR_RIE_RRUUU, INSTR_RIE_RUPI, INSTR_RIE_RUPU,
+ INSTR_RIE_RRUUU, INSTR_RIE_RUPI, INSTR_RIE_RUPU, INSTR_RIE_RRI0,
INSTR_RIL_RI, INSTR_RIL_RP, INSTR_RIL_RU, INSTR_RIL_UP,
INSTR_RIS_R0RDU, INSTR_RIS_R0UU, INSTR_RIS_RURDI, INSTR_RIS_RURDU,
INSTR_RI_RI, INSTR_RI_RP, INSTR_RI_RU, INSTR_RI_UP,
@@ -122,13 +122,14 @@ enum {
INSTR_RRE_RR, INSTR_RRE_RR_OPT,
INSTR_RRF_0UFF, INSTR_RRF_F0FF, INSTR_RRF_F0FF2, INSTR_RRF_F0FR,
INSTR_RRF_FFRU, INSTR_RRF_FUFF, INSTR_RRF_M0RR, INSTR_RRF_R0RR,
- INSTR_RRF_RURR, INSTR_RRF_U0FF, INSTR_RRF_U0RF, INSTR_RRF_U0RR,
- INSTR_RRF_UUFF, INSTR_RRR_F0FF, INSTR_RRS_RRRDU,
+ INSTR_RRF_R0RR2, INSTR_RRF_RURR, INSTR_RRF_U0FF, INSTR_RRF_U0RF,
+ INSTR_RRF_U0RR, INSTR_RRF_UUFF, INSTR_RRR_F0FF, INSTR_RRS_RRRDU,
INSTR_RR_FF, INSTR_RR_R0, INSTR_RR_RR, INSTR_RR_U0, INSTR_RR_UR,
INSTR_RSE_CCRD, INSTR_RSE_RRRD, INSTR_RSE_RURD,
INSTR_RSI_RRP,
INSTR_RSL_R0RD,
INSTR_RSY_AARD, INSTR_RSY_CCRD, INSTR_RSY_RRRD, INSTR_RSY_RURD,
+ INSTR_RSY_RDRM,
INSTR_RS_AARD, INSTR_RS_CCRD, INSTR_RS_R0RD, INSTR_RS_RRRD,
INSTR_RS_RURD,
INSTR_RXE_FRRD, INSTR_RXE_RRRD,
@@ -139,7 +140,7 @@ enum {
INSTR_SIY_IRD, INSTR_SIY_URD,
INSTR_SI_URD,
INSTR_SSE_RDRD,
- INSTR_SSF_RRDRD,
+ INSTR_SSF_RRDRD, INSTR_SSF_RRDRD2,
INSTR_SS_L0RDRD, INSTR_SS_LIRDRD, INSTR_SS_LLRDRD, INSTR_SS_RRRDRD,
INSTR_SS_RRRDRD2, INSTR_SS_RRRDRD3,
INSTR_S_00, INSTR_S_RD,
@@ -152,7 +153,7 @@ struct operand {
};
struct insn {
- const char name[6];
+ const char name[5];
unsigned char opfrag;
unsigned char format;
};
@@ -217,6 +218,7 @@ static const unsigned char formats[][7] = {
[INSTR_RIE_RRP] = { 0xff, R_8,R_12,J16_16,0,0,0 },
[INSTR_RIE_RRUUU] = { 0xff, R_8,R_12,U8_16,U8_24,U8_32,0 },
[INSTR_RIE_RUPI] = { 0xff, R_8,I8_32,U4_12,J16_16,0,0 },
+ [INSTR_RIE_RRI0] = { 0xff, R_8,R_12,I16_16,0,0,0 },
[INSTR_RIL_RI] = { 0x0f, R_8,I32_16,0,0,0,0 },
[INSTR_RIL_RP] = { 0x0f, R_8,J32_16,0,0,0,0 },
[INSTR_RIL_RU] = { 0x0f, R_8,U32_16,0,0,0,0 },
@@ -248,6 +250,7 @@ static const unsigned char formats[][7] = {
[INSTR_RRF_FUFF] = { 0xff, F_24,F_16,F_28,U4_20,0,0 },
[INSTR_RRF_M0RR] = { 0xff, R_24,R_28,M_16,0,0,0 },
[INSTR_RRF_R0RR] = { 0xff, R_24,R_16,R_28,0,0,0 },
+ [INSTR_RRF_R0RR2] = { 0xff, R_24,R_28,R_16,0,0,0 },
[INSTR_RRF_RURR] = { 0xff, R_24,R_28,R_16,U4_20,0,0 },
[INSTR_RRF_U0FF] = { 0xff, F_24,U4_16,F_28,0,0,0 },
[INSTR_RRF_U0RF] = { 0xff, R_24,U4_16,F_28,0,0,0 },
@@ -269,6 +272,7 @@ static const unsigned char formats[][7] = {
[INSTR_RSY_CCRD] = { 0xff, C_8,C_12,D20_20,B_16,0,0 },
[INSTR_RSY_RRRD] = { 0xff, R_8,R_12,D20_20,B_16,0,0 },
[INSTR_RSY_RURD] = { 0xff, R_8,U4_12,D20_20,B_16,0,0 },
+ [INSTR_RSY_RDRM] = { 0xff, R_8,D20_20,B_16,U4_12,0,0 },
[INSTR_RS_AARD] = { 0xff, A_8,A_12,D_20,B_16,0,0 },
[INSTR_RS_CCRD] = { 0xff, C_8,C_12,D_20,B_16,0,0 },
[INSTR_RS_R0RD] = { 0xff, R_8,D_20,B_16,0,0,0 },
@@ -290,6 +294,7 @@ static const unsigned char formats[][7] = {
[INSTR_SI_URD] = { 0xff, D_20,B_16,U8_8,0,0,0 },
[INSTR_SSE_RDRD] = { 0xff, D_20,B_16,D_36,B_32,0,0 },
[INSTR_SSF_RRDRD] = { 0x00, D_20,B_16,D_36,B_32,R_8,0 },
+ [INSTR_SSF_RRDRD2]= { 0x00, R_8,D_20,B_16,D_36,B_32,0 },
[INSTR_SS_L0RDRD] = { 0xff, D_20,L8_8,B_16,D_36,B_32,0 },
[INSTR_SS_LIRDRD] = { 0xff, D_20,L4_8,B_16,D_36,B_32,U4_12 },
[INSTR_SS_LLRDRD] = { 0xff, D_20,L4_8,B_16,D_36,L4_12,B_32 },
@@ -300,6 +305,36 @@ static const unsigned char formats[][7] = {
[INSTR_S_RD] = { 0xff, D_20,B_16,0,0,0,0 },
};
+enum {
+ LONG_INSN_ALGHSIK,
+ LONG_INSN_ALHSIK,
+ LONG_INSN_CLFHSI,
+ LONG_INSN_CLGFRL,
+ LONG_INSN_CLGHRL,
+ LONG_INSN_CLGHSI,
+ LONG_INSN_CLHHSI,
+ LONG_INSN_LLGFRL,
+ LONG_INSN_LLGHRL,
+ LONG_INSN_POPCNT,
+ LONG_INSN_RISBHG,
+ LONG_INSN_RISBLG,
+};
+
+static char *long_insn_name[] = {
+ [LONG_INSN_ALGHSIK] = "alghsik",
+ [LONG_INSN_ALHSIK] = "alhsik",
+ [LONG_INSN_CLFHSI] = "clfhsi",
+ [LONG_INSN_CLGFRL] = "clgfrl",
+ [LONG_INSN_CLGHRL] = "clghrl",
+ [LONG_INSN_CLGHSI] = "clghsi",
+ [LONG_INSN_CLHHSI] = "clhhsi",
+ [LONG_INSN_LLGFRL] = "llgfrl",
+ [LONG_INSN_LLGHRL] = "llghrl",
+ [LONG_INSN_POPCNT] = "popcnt",
+ [LONG_INSN_RISBHG] = "risbhg",
+ [LONG_INSN_RISBLG] = "risblk",
+};
+
static struct insn opcode[] = {
#ifdef CONFIG_64BIT
{ "lmd", 0xef, INSTR_SS_RRRDRD3 },
@@ -881,6 +916,35 @@ static struct insn opcode_b9[] = {
{ "pfmf", 0xaf, INSTR_RRE_RR },
{ "trte", 0xbf, INSTR_RRF_M0RR },
{ "trtre", 0xbd, INSTR_RRF_M0RR },
+ { "ahhhr", 0xc8, INSTR_RRF_R0RR2 },
+ { "shhhr", 0xc9, INSTR_RRF_R0RR2 },
+ { "alhhh", 0xca, INSTR_RRF_R0RR2 },
+ { "alhhl", 0xca, INSTR_RRF_R0RR2 },
+ { "slhhh", 0xcb, INSTR_RRF_R0RR2 },
+ { "chhr ", 0xcd, INSTR_RRE_RR },
+ { "clhhr", 0xcf, INSTR_RRE_RR },
+ { "ahhlr", 0xd8, INSTR_RRF_R0RR2 },
+ { "shhlr", 0xd9, INSTR_RRF_R0RR2 },
+ { "slhhl", 0xdb, INSTR_RRF_R0RR2 },
+ { "chlr", 0xdd, INSTR_RRE_RR },
+ { "clhlr", 0xdf, INSTR_RRE_RR },
+ { { 0, LONG_INSN_POPCNT }, 0xe1, INSTR_RRE_RR },
+ { "locgr", 0xe2, INSTR_RRF_M0RR },
+ { "ngrk", 0xe4, INSTR_RRF_R0RR2 },
+ { "ogrk", 0xe6, INSTR_RRF_R0RR2 },
+ { "xgrk", 0xe7, INSTR_RRF_R0RR2 },
+ { "agrk", 0xe8, INSTR_RRF_R0RR2 },
+ { "sgrk", 0xe9, INSTR_RRF_R0RR2 },
+ { "algrk", 0xea, INSTR_RRF_R0RR2 },
+ { "slgrk", 0xeb, INSTR_RRF_R0RR2 },
+ { "locr", 0xf2, INSTR_RRF_M0RR },
+ { "nrk", 0xf4, INSTR_RRF_R0RR2 },
+ { "ork", 0xf6, INSTR_RRF_R0RR2 },
+ { "xrk", 0xf7, INSTR_RRF_R0RR2 },
+ { "ark", 0xf8, INSTR_RRF_R0RR2 },
+ { "srk", 0xf9, INSTR_RRF_R0RR2 },
+ { "alrk", 0xfa, INSTR_RRF_R0RR2 },
+ { "slrk", 0xfb, INSTR_RRF_R0RR2 },
#endif
{ "kmac", 0x1e, INSTR_RRE_RR },
{ "lrvr", 0x1f, INSTR_RRE_RR },
@@ -949,9 +1013,9 @@ static struct insn opcode_c4[] = {
{ "lgfrl", 0x0c, INSTR_RIL_RP },
{ "lhrl", 0x05, INSTR_RIL_RP },
{ "lghrl", 0x04, INSTR_RIL_RP },
- { "llgfrl", 0x0e, INSTR_RIL_RP },
+ { { 0, LONG_INSN_LLGFRL }, 0x0e, INSTR_RIL_RP },
{ "llhrl", 0x02, INSTR_RIL_RP },
- { "llghrl", 0x06, INSTR_RIL_RP },
+ { { 0, LONG_INSN_LLGHRL }, 0x06, INSTR_RIL_RP },
{ "strl", 0x0f, INSTR_RIL_RP },
{ "stgrl", 0x0b, INSTR_RIL_RP },
{ "sthrl", 0x07, INSTR_RIL_RP },
@@ -968,9 +1032,9 @@ static struct insn opcode_c6[] = {
{ "cghrl", 0x04, INSTR_RIL_RP },
{ "clrl", 0x0f, INSTR_RIL_RP },
{ "clgrl", 0x0a, INSTR_RIL_RP },
- { "clgfrl", 0x0e, INSTR_RIL_RP },
+ { { 0, LONG_INSN_CLGFRL }, 0x0e, INSTR_RIL_RP },
{ "clhrl", 0x07, INSTR_RIL_RP },
- { "clghrl", 0x06, INSTR_RIL_RP },
+ { { 0, LONG_INSN_CLGHRL }, 0x06, INSTR_RIL_RP },
{ "pfdrl", 0x02, INSTR_RIL_UP },
{ "exrl", 0x00, INSTR_RIL_RP },
#endif
@@ -982,6 +1046,20 @@ static struct insn opcode_c8[] = {
{ "mvcos", 0x00, INSTR_SSF_RRDRD },
{ "ectg", 0x01, INSTR_SSF_RRDRD },
{ "csst", 0x02, INSTR_SSF_RRDRD },
+ { "lpd", 0x04, INSTR_SSF_RRDRD2 },
+ { "lpdg ", 0x05, INSTR_SSF_RRDRD2 },
+#endif
+ { "", 0, INSTR_INVALID }
+};
+
+static struct insn opcode_cc[] = {
+#ifdef CONFIG_64BIT
+ { "brcth", 0x06, INSTR_RIL_RP },
+ { "aih", 0x08, INSTR_RIL_RI },
+ { "alsih", 0x0a, INSTR_RIL_RI },
+ { "alsih", 0x0b, INSTR_RIL_RI },
+ { "cih", 0x0d, INSTR_RIL_RI },
+ { "clih ", 0x0f, INSTR_RIL_RI },
#endif
{ "", 0, INSTR_INVALID }
};
@@ -1063,6 +1141,16 @@ static struct insn opcode_e3[] = {
{ "mfy", 0x5c, INSTR_RXY_RRRD },
{ "mhy", 0x7c, INSTR_RXY_RRRD },
{ "pfd", 0x36, INSTR_RXY_URRD },
+ { "lbh", 0xc0, INSTR_RXY_RRRD },
+ { "llch", 0xc2, INSTR_RXY_RRRD },
+ { "stch", 0xc3, INSTR_RXY_RRRD },
+ { "lhh", 0xc4, INSTR_RXY_RRRD },
+ { "llhh", 0xc6, INSTR_RXY_RRRD },
+ { "sthh", 0xc7, INSTR_RXY_RRRD },
+ { "lfh", 0xca, INSTR_RXY_RRRD },
+ { "stfh", 0xcb, INSTR_RXY_RRRD },
+ { "chf", 0xcd, INSTR_RXY_RRRD },
+ { "clhf", 0xcf, INSTR_RXY_RRRD },
#endif
{ "lrv", 0x1e, INSTR_RXY_RRRD },
{ "lrvh", 0x1f, INSTR_RXY_RRRD },
@@ -1080,9 +1168,9 @@ static struct insn opcode_e5[] = {
{ "chhsi", 0x54, INSTR_SIL_RDI },
{ "chsi", 0x5c, INSTR_SIL_RDI },
{ "cghsi", 0x58, INSTR_SIL_RDI },
- { "clhhsi", 0x55, INSTR_SIL_RDU },
- { "clfhsi", 0x5d, INSTR_SIL_RDU },
- { "clghsi", 0x59, INSTR_SIL_RDU },
+ { { 0, LONG_INSN_CLHHSI }, 0x55, INSTR_SIL_RDU },
+ { { 0, LONG_INSN_CLFHSI }, 0x5d, INSTR_SIL_RDU },
+ { { 0, LONG_INSN_CLGHSI }, 0x59, INSTR_SIL_RDU },
{ "mvhhi", 0x44, INSTR_SIL_RDI },
{ "mvhi", 0x4c, INSTR_SIL_RDI },
{ "mvghi", 0x48, INSTR_SIL_RDI },
@@ -1137,6 +1225,24 @@ static struct insn opcode_eb[] = {
{ "alsi", 0x6e, INSTR_SIY_IRD },
{ "algsi", 0x7e, INSTR_SIY_IRD },
{ "ecag", 0x4c, INSTR_RSY_RRRD },
+ { "srak", 0xdc, INSTR_RSY_RRRD },
+ { "slak", 0xdd, INSTR_RSY_RRRD },
+ { "srlk", 0xde, INSTR_RSY_RRRD },
+ { "sllk", 0xdf, INSTR_RSY_RRRD },
+ { "locg", 0xe2, INSTR_RSY_RDRM },
+ { "stocg", 0xe3, INSTR_RSY_RDRM },
+ { "lang", 0xe4, INSTR_RSY_RRRD },
+ { "laog", 0xe6, INSTR_RSY_RRRD },
+ { "laxg", 0xe7, INSTR_RSY_RRRD },
+ { "laag", 0xe8, INSTR_RSY_RRRD },
+ { "laalg", 0xea, INSTR_RSY_RRRD },
+ { "loc", 0xf2, INSTR_RSY_RDRM },
+ { "stoc", 0xf3, INSTR_RSY_RDRM },
+ { "lan", 0xf4, INSTR_RSY_RRRD },
+ { "lao", 0xf6, INSTR_RSY_RRRD },
+ { "lax", 0xf7, INSTR_RSY_RRRD },
+ { "laa", 0xf8, INSTR_RSY_RRRD },
+ { "laal", 0xfa, INSTR_RSY_RRRD },
#endif
{ "rll", 0x1d, INSTR_RSY_RRRD },
{ "mvclu", 0x8e, INSTR_RSY_RRRD },
@@ -1172,6 +1278,12 @@ static struct insn opcode_ec[] = {
{ "rxsbg", 0x57, INSTR_RIE_RRUUU },
{ "rosbg", 0x56, INSTR_RIE_RRUUU },
{ "risbg", 0x55, INSTR_RIE_RRUUU },
+ { { 0, LONG_INSN_RISBLG }, 0x51, INSTR_RIE_RRUUU },
+ { { 0, LONG_INSN_RISBHG }, 0x5D, INSTR_RIE_RRUUU },
+ { "ahik", 0xd8, INSTR_RIE_RRI0 },
+ { "aghik", 0xd9, INSTR_RIE_RRI0 },
+ { { 0, LONG_INSN_ALHSIK }, 0xda, INSTR_RIE_RRI0 },
+ { { 0, LONG_INSN_ALGHSIK }, 0xdb, INSTR_RIE_RRI0 },
#endif
{ "", 0, INSTR_INVALID }
};
@@ -1321,6 +1433,9 @@ static struct insn *find_insn(unsigned char *code)
case 0xc8:
table = opcode_c8;
break;
+ case 0xcc:
+ table = opcode_cc;
+ break;
case 0xe3:
table = opcode_e3;
opfrag = code[5];
@@ -1367,7 +1482,11 @@ static int print_insn(char *buffer, unsigned char *code, unsigned long addr)
ptr = buffer;
insn = find_insn(code);
if (insn) {
- ptr += sprintf(ptr, "%.5s\t", insn->name);
+ if (insn->name[0] == '\0')
+ ptr += sprintf(ptr, "%s\t",
+ long_insn_name[(int) insn->name[1]]);
+ else
+ ptr += sprintf(ptr, "%.5s\t", insn->name);
/* Extract the operands. */
separator = 0;
for (ops = formats[insn->format] + 1, i = 0;
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index c00856ad4e5a..3b7e7dddc324 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -208,7 +208,8 @@ static noinline __init void init_kernel_storage_key(void)
end_pfn = PFN_UP(__pa(&_end));
for (init_pfn = 0 ; init_pfn < end_pfn; init_pfn++)
- page_set_storage_key(init_pfn << PAGE_SHIFT, PAGE_DEFAULT_KEY);
+ page_set_storage_key(init_pfn << PAGE_SHIFT,
+ PAGE_DEFAULT_KEY, 0);
}
static __initdata struct sysinfo_3_2_2 vmms __aligned(PAGE_SIZE);
@@ -255,13 +256,33 @@ static noinline __init void setup_lowcore_early(void)
s390_base_pgm_handler_fn = early_pgm_check_handler;
}
+static noinline __init void setup_facility_list(void)
+{
+ unsigned long nr;
+
+ S390_lowcore.stfl_fac_list = 0;
+ asm volatile(
+ " .insn s,0xb2b10000,0(0)\n" /* stfl */
+ "0:\n"
+ EX_TABLE(0b,0b) : "=m" (S390_lowcore.stfl_fac_list));
+ memcpy(&S390_lowcore.stfle_fac_list, &S390_lowcore.stfl_fac_list, 4);
+ nr = 4; /* # bytes stored by stfl */
+ if (test_facility(7)) {
+ /* More facility bits available with stfle */
+ register unsigned long reg0 asm("0") = MAX_FACILITY_BIT/64 - 1;
+ asm volatile(".insn s,0xb2b00000,%0" /* stfle */
+ : "=m" (S390_lowcore.stfle_fac_list), "+d" (reg0)
+ : : "cc");
+ nr = (reg0 + 1) * 8; /* # bytes stored by stfle */
+ }
+ memset((char *) S390_lowcore.stfle_fac_list + nr, 0,
+ MAX_FACILITY_BIT/8 - nr);
+}
+
static noinline __init void setup_hpage(void)
{
#ifndef CONFIG_DEBUG_PAGEALLOC
- unsigned int facilities;
-
- facilities = stfl();
- if (!(facilities & (1UL << 23)) || !(facilities & (1UL << 29)))
+ if (!test_facility(2) || !test_facility(8))
return;
S390_lowcore.machine_flags |= MACHINE_FLAG_HPAGE;
__ctl_set_bit(0, 23);
@@ -355,18 +376,15 @@ static __init void detect_diag44(void)
static __init void detect_machine_facilities(void)
{
#ifdef CONFIG_64BIT
- unsigned int facilities;
- unsigned long long facility_bits;
-
- facilities = stfl();
- if (facilities & (1 << 28))
+ if (test_facility(3))
S390_lowcore.machine_flags |= MACHINE_FLAG_IDTE;
- if (facilities & (1 << 23))
+ if (test_facility(8))
S390_lowcore.machine_flags |= MACHINE_FLAG_PFMF;
- if (facilities & (1 << 4))
+ if (test_facility(11))
+ S390_lowcore.machine_flags |= MACHINE_FLAG_TOPOLOGY;
+ if (test_facility(27))
S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS;
- if ((stfle(&facility_bits, 1) > 0) &&
- (facility_bits & (1ULL << (63 - 40))))
+ if (test_facility(40))
S390_lowcore.machine_flags |= MACHINE_FLAG_SPP;
#endif
}
@@ -447,6 +465,7 @@ void __init startup_init(void)
lockdep_off();
sort_main_extable();
setup_lowcore_early();
+ setup_facility_list();
detect_machine_type();
ipl_update_parameters();
setup_boot_command_line();
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index bea9ee37ac9d..1ecc337fb679 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -72,25 +72,9 @@ STACK_SIZE = 1 << STACK_SHIFT
l %r1,BASED(.Ltrace_irq_off_caller)
basr %r14,%r1
.endm
-
- .macro TRACE_IRQS_CHECK_ON
- tm SP_PSW(%r15),0x03 # irqs enabled?
- bz BASED(0f)
- TRACE_IRQS_ON
-0:
- .endm
-
- .macro TRACE_IRQS_CHECK_OFF
- tm SP_PSW(%r15),0x03 # irqs enabled?
- bz BASED(0f)
- TRACE_IRQS_OFF
-0:
- .endm
#else
#define TRACE_IRQS_ON
#define TRACE_IRQS_OFF
-#define TRACE_IRQS_CHECK_ON
-#define TRACE_IRQS_CHECK_OFF
#endif
#ifdef CONFIG_LOCKDEP
@@ -198,6 +182,12 @@ STACK_SIZE = 1 << STACK_SHIFT
lpsw \psworg # back to caller
.endm
+ .macro REENABLE_IRQS
+ mvc __SF_EMPTY(1,%r15),SP_PSW(%r15)
+ ni __SF_EMPTY(%r15),0xbf
+ ssm __SF_EMPTY(%r15)
+ .endm
+
/*
* Scheduler resume function, called by switch_to
* gpr2 = (task_struct *) prev
@@ -264,12 +254,11 @@ sysc_do_svc:
bnl BASED(sysc_nr_ok)
lr %r7,%r1 # copy svc number to %r7
sysc_nr_ok:
- mvc SP_ARGS(4,%r15),SP_R7(%r15)
-sysc_do_restart:
sth %r7,SP_SVCNR(%r15)
sll %r7,2 # svc number *4
l %r8,BASED(.Lsysc_table)
tm __TI_flags+2(%r9),_TIF_SYSCALL
+ mvc SP_ARGS(4,%r15),SP_R7(%r15)
l %r8,0(%r7,%r8) # get system call addr.
bnz BASED(sysc_tracesys)
basr %r14,%r8 # call sys_xxxx
@@ -357,7 +346,7 @@ sysc_restart:
l %r7,SP_R2(%r15) # load new svc number
mvc SP_R2(4,%r15),SP_ORIG_R2(%r15) # restore first argument
lm %r2,%r6,SP_R2(%r15) # load svc arguments
- b BASED(sysc_do_restart) # restart svc
+ b BASED(sysc_nr_ok) # restart svc
#
# _TIF_SINGLE_STEP is set, call do_single_step
@@ -390,6 +379,7 @@ sysc_tracesys:
l %r8,0(%r7,%r8)
sysc_tracego:
lm %r3,%r6,SP_R3(%r15)
+ mvc SP_ARGS(4,%r15),SP_R7(%r15)
l %r2,SP_ORIG_R2(%r15)
basr %r14,%r8 # call sys_xxx
st %r2,SP_R2(%r15) # store return value
@@ -440,13 +430,11 @@ kernel_execve:
br %r14
# execve succeeded.
0: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts
- TRACE_IRQS_OFF
l %r15,__LC_KERNEL_STACK # load ksp
s %r15,BASED(.Lc_spsize) # make room for registers & psw
l %r9,__LC_THREAD_INFO
mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs
xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
- TRACE_IRQS_ON
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
l %r1,BASED(.Lexecve_tail)
basr %r14,%r1
@@ -483,9 +471,10 @@ pgm_check_handler:
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
pgm_no_vtime:
- TRACE_IRQS_CHECK_OFF
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
l %r3,__LC_PGM_ILC # load program interruption code
+ l %r4,__LC_TRANS_EXC_CODE
+ REENABLE_IRQS
la %r8,0x7f
nr %r8,%r3
pgm_do_call:
@@ -495,7 +484,6 @@ pgm_do_call:
la %r2,SP_PTREGS(%r15) # address of register-save area
basr %r14,%r7 # branch to interrupt-handler
pgm_exit:
- TRACE_IRQS_CHECK_ON
b BASED(sysc_return)
#
@@ -523,7 +511,6 @@ pgm_per_std:
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
pgm_no_vtime2:
- TRACE_IRQS_CHECK_OFF
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
l %r1,__TI_task(%r9)
tm SP_PSW+1(%r15),0x01 # kernel per event ?
@@ -533,6 +520,8 @@ pgm_no_vtime2:
mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
l %r3,__LC_PGM_ILC # load program interruption code
+ l %r4,__LC_TRANS_EXC_CODE
+ REENABLE_IRQS
la %r8,0x7f
nr %r8,%r3 # clear per-event-bit and ilc
be BASED(pgm_exit2) # only per or per+check ?
@@ -542,8 +531,6 @@ pgm_no_vtime2:
la %r2,SP_PTREGS(%r15) # address of register-save area
basr %r14,%r7 # branch to interrupt-handler
pgm_exit2:
- TRACE_IRQS_ON
- stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
b BASED(sysc_return)
#
@@ -557,13 +544,11 @@ pgm_svcper:
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
lh %r7,0x8a # get svc number from lowcore
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
- TRACE_IRQS_OFF
l %r8,__TI_task(%r9)
mvc __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID
mvc __THREAD_per+__PER_address(4,%r8),__LC_PER_ADDRESS
mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
- TRACE_IRQS_ON
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
lm %r2,%r6,SP_R2(%r15) # load svc arguments
b BASED(sysc_do_svc)
@@ -572,6 +557,7 @@ pgm_svcper:
# per was called from kernel, must be kprobes
#
kernel_per:
+ REENABLE_IRQS
mvi SP_SVCNR(%r15),0xff # set trap indication to pgm check
mvi SP_SVCNR+1(%r15),0xff
la %r2,SP_PTREGS(%r15) # address of register-save area
@@ -737,7 +723,8 @@ ext_no_vtime:
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
TRACE_IRQS_OFF
la %r2,SP_PTREGS(%r15) # address of register-save area
- lh %r3,__LC_EXT_INT_CODE # get interruption code
+ l %r3,__LC_CPU_ADDRESS # get cpu address + interruption code
+ l %r4,__LC_EXT_PARAMS # get external parameters
l %r1,BASED(.Ldo_extint)
basr %r14,%r1
b BASED(io_return)
diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h
index ff579b6bde06..95c1dfc4ef31 100644
--- a/arch/s390/kernel/entry.h
+++ b/arch/s390/kernel/entry.h
@@ -5,7 +5,7 @@
#include <linux/signal.h>
#include <asm/ptrace.h>
-typedef void pgm_check_handler_t(struct pt_regs *, long);
+typedef void pgm_check_handler_t(struct pt_regs *, long, unsigned long);
extern pgm_check_handler_t *pgm_check_table[128];
pgm_check_handler_t do_protection_exception;
pgm_check_handler_t do_dat_exception;
@@ -19,7 +19,7 @@ void do_signal(struct pt_regs *regs);
int handle_signal32(unsigned long sig, struct k_sigaction *ka,
siginfo_t *info, sigset_t *oldset, struct pt_regs *regs);
-void do_extint(struct pt_regs *regs, unsigned short code);
+void do_extint(struct pt_regs *regs, unsigned int, unsigned int, unsigned long);
int __cpuinit start_secondary(void *cpuvoid);
void __init startup_init(void);
void die(const char * str, struct pt_regs * regs, long err);
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 8bccec15ea90..8f3e802174db 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -79,25 +79,9 @@ _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
basr %r2,%r0
brasl %r14,trace_hardirqs_off_caller
.endm
-
- .macro TRACE_IRQS_CHECK_ON
- tm SP_PSW(%r15),0x03 # irqs enabled?
- jz 0f
- TRACE_IRQS_ON
-0:
- .endm
-
- .macro TRACE_IRQS_CHECK_OFF
- tm SP_PSW(%r15),0x03 # irqs enabled?
- jz 0f
- TRACE_IRQS_OFF
-0:
- .endm
#else
#define TRACE_IRQS_ON
#define TRACE_IRQS_OFF
-#define TRACE_IRQS_CHECK_ON
-#define TRACE_IRQS_CHECK_OFF
#endif
#ifdef CONFIG_LOCKDEP
@@ -207,6 +191,12 @@ _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
0:
.endm
+ .macro REENABLE_IRQS
+ mvc __SF_EMPTY(1,%r15),SP_PSW(%r15)
+ ni __SF_EMPTY(%r15),0xbf
+ ssm __SF_EMPTY(%r15)
+ .endm
+
/*
* Scheduler resume function, called by switch_to
* gpr2 = (task_struct *) prev
@@ -256,7 +246,6 @@ sysc_saveall:
CREATE_STACK_FRAME __LC_SAVE_AREA
mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW
mvc SP_ILC(4,%r15),__LC_SVC_ILC
- stg %r7,SP_ARGS(%r15)
lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct
sysc_vtime:
UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
@@ -284,6 +273,7 @@ sysc_nr_ok:
sysc_noemu:
#endif
tm __TI_flags+6(%r12),_TIF_SYSCALL
+ mvc SP_ARGS(8,%r15),SP_R7(%r15)
lgf %r8,0(%r7,%r10) # load address of system call routine
jnz sysc_tracesys
basr %r14,%r8 # call sys_xxxx
@@ -397,6 +387,7 @@ sysc_tracesys:
lgf %r8,0(%r7,%r10)
sysc_tracego:
lmg %r3,%r6,SP_R3(%r15)
+ mvc SP_ARGS(8,%r15),SP_R7(%r15)
lg %r2,SP_ORIG_R2(%r15)
basr %r14,%r8 # call sys_xxx
stg %r2,SP_R2(%r15) # store return value
@@ -443,14 +434,12 @@ kernel_execve:
br %r14
# execve succeeded.
0: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts
-# TRACE_IRQS_OFF
lg %r15,__LC_KERNEL_STACK # load ksp
aghi %r15,-SP_SIZE # make room for registers & psw
lg %r13,__LC_SVC_NEW_PSW+8
mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs
lg %r12,__LC_THREAD_INFO
xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
-# TRACE_IRQS_ON
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
brasl %r14,execve_tail
j sysc_return
@@ -490,19 +479,18 @@ pgm_check_handler:
LAST_BREAK
pgm_no_vtime:
HANDLE_SIE_INTERCEPT
- TRACE_IRQS_CHECK_OFF
stg %r11,SP_ARGS(%r15)
lgf %r3,__LC_PGM_ILC # load program interruption code
+ lg %r4,__LC_TRANS_EXC_CODE
+ REENABLE_IRQS
lghi %r8,0x7f
ngr %r8,%r3
-pgm_do_call:
sll %r8,3
larl %r1,pgm_check_table
lg %r1,0(%r8,%r1) # load address of handler routine
la %r2,SP_PTREGS(%r15) # address of register-save area
basr %r14,%r1 # branch to interrupt-handler
pgm_exit:
- TRACE_IRQS_CHECK_ON
j sysc_return
#
@@ -533,7 +521,6 @@ pgm_per_std:
LAST_BREAK
pgm_no_vtime2:
HANDLE_SIE_INTERCEPT
- TRACE_IRQS_CHECK_OFF
lg %r1,__TI_task(%r12)
tm SP_PSW+1(%r15),0x01 # kernel per event ?
jz kernel_per
@@ -542,6 +529,8 @@ pgm_no_vtime2:
mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
oi __TI_flags+7(%r12),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
lgf %r3,__LC_PGM_ILC # load program interruption code
+ lg %r4,__LC_TRANS_EXC_CODE
+ REENABLE_IRQS
lghi %r8,0x7f
ngr %r8,%r3 # clear per-event-bit and ilc
je pgm_exit2
@@ -551,8 +540,6 @@ pgm_no_vtime2:
la %r2,SP_PTREGS(%r15) # address of register-save area
basr %r14,%r1 # branch to interrupt-handler
pgm_exit2:
- TRACE_IRQS_ON
- stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
j sysc_return
#
@@ -568,13 +555,11 @@ pgm_svcper:
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
LAST_BREAK
- TRACE_IRQS_OFF
lg %r8,__TI_task(%r12)
mvc __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID
mvc __THREAD_per+__PER_address(8,%r8),__LC_PER_ADDRESS
mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
oi __TI_flags+7(%r12),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
- TRACE_IRQS_ON
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
lmg %r2,%r6,SP_R2(%r15) # load svc arguments
j sysc_do_svc
@@ -583,6 +568,7 @@ pgm_svcper:
# per was called from kernel, must be kprobes
#
kernel_per:
+ REENABLE_IRQS
xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number
la %r2,SP_PTREGS(%r15) # address of register-save area
brasl %r14,do_single_step
@@ -743,8 +729,11 @@ ext_int_handler:
ext_no_vtime:
HANDLE_SIE_INTERCEPT
TRACE_IRQS_OFF
+ lghi %r1,4096
la %r2,SP_PTREGS(%r15) # address of register-save area
- llgh %r3,__LC_EXT_INT_CODE # get interruption code
+ llgf %r3,__LC_CPU_ADDRESS # get cpu address + interruption code
+ llgf %r4,__LC_EXT_PARAMS # get external parameter
+ lg %r5,__LC_EXT_PARAMS2-4096(%r1) # get 64 bit external parameter
brasl %r14,do_extint
j io_return
@@ -966,7 +955,6 @@ cleanup_system_call:
CREATE_STACK_FRAME __LC_SAVE_AREA
mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW
mvc SP_ILC(4,%r15),__LC_SVC_ILC
- stg %r7,SP_ARGS(%r15)
mvc 8(8,%r12),__LC_THREAD_INFO
cleanup_vtime:
clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+24)
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index db1696e210af..7061398341d5 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -488,7 +488,9 @@ startup:
.align 16
2: .long 0x000a0000,0x8badcccc
#if defined(CONFIG_64BIT)
-#if defined(CONFIG_MARCH_Z10)
+#if defined(CONFIG_MARCH_Z196)
+ .long 0xc100efe3, 0xf46c0000
+#elif defined(CONFIG_MARCH_Z10)
.long 0xc100efe3, 0xf0680000
#elif defined(CONFIG_MARCH_Z9_109)
.long 0xc100efc3, 0x00000000
@@ -498,7 +500,9 @@ startup:
.long 0xc0000000, 0x00000000
#endif
#else
-#if defined(CONFIG_MARCH_Z10)
+#if defined(CONFIG_MARCH_Z196)
+ .long 0x8100c880, 0x00000000
+#elif defined(CONFIG_MARCH_Z10)
.long 0x8100c880, 0x00000000
#elif defined(CONFIG_MARCH_Z9_109)
.long 0x8100c880, 0x00000000
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c
index 2a3d2bf6f083..d60fc4398516 100644
--- a/arch/s390/kernel/kprobes.c
+++ b/arch/s390/kernel/kprobes.c
@@ -316,6 +316,8 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
return 1;
ss_probe:
+ if (regs->psw.mask & (PSW_MASK_PER | PSW_MASK_IO))
+ local_irq_disable();
prepare_singlestep(p, regs);
kcb->kprobe_status = KPROBE_HIT_SS;
return 1;
@@ -463,6 +465,8 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs)
goto out;
}
reset_current_kprobe();
+ if (regs->psw.mask & (PSW_MASK_PER | PSW_MASK_IO))
+ local_irq_enable();
out:
preempt_enable_no_resched();
@@ -502,8 +506,11 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
regs->psw.mask |= kcb->kprobe_saved_imask;
if (kcb->kprobe_status == KPROBE_REENTER)
restore_previous_kprobe(kcb);
- else
+ else {
reset_current_kprobe();
+ if (regs->psw.mask & (PSW_MASK_PER | PSW_MASK_IO))
+ local_irq_enable();
+ }
preempt_enable_no_resched();
break;
case KPROBE_HIT_ACTIVE:
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/process.c b/arch/s390/kernel/process.c
index d3a2d1c6438e..ec2e03b22ead 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -76,17 +76,17 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
static void default_idle(void)
{
/* CPU is going idle. */
- local_irq_disable();
- if (need_resched()) {
- local_irq_enable();
- return;
- }
#ifdef CONFIG_HOTPLUG_CPU
if (cpu_is_offline(smp_processor_id())) {
preempt_enable_no_resched();
cpu_die();
}
#endif
+ local_irq_disable();
+ if (need_resched()) {
+ local_irq_enable();
+ return;
+ }
local_mcck_disable();
if (test_thread_flag(TIF_MCCK_PENDING)) {
local_mcck_enable();
diff --git a/arch/s390/kernel/processor.c b/arch/s390/kernel/processor.c
index ecb2d02b02e4..644548e615c6 100644
--- a/arch/s390/kernel/processor.c
+++ b/arch/s390/kernel/processor.c
@@ -42,7 +42,7 @@ void __cpuinit print_cpu_info(void)
struct cpuid *id = &per_cpu(cpu_id, smp_processor_id());
pr_info("Processor %d started, address %d, identification %06X\n",
- S390_lowcore.cpu_nr, S390_lowcore.cpu_addr, id->ident);
+ S390_lowcore.cpu_nr, stap(), id->ident);
}
/*
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 83339d33c4b1..019bb714db49 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -343,7 +343,8 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data)
return __poke_user(child, addr, data);
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
ptrace_area parea;
int copied, ret;
diff --git a/arch/s390/kernel/s390_ext.c b/arch/s390/kernel/s390_ext.c
index 9ce641b5291f..bd1db508e8af 100644
--- a/arch/s390/kernel/s390_ext.c
+++ b/arch/s390/kernel/s390_ext.c
@@ -113,12 +113,15 @@ int unregister_early_external_interrupt(__u16 code, ext_int_handler_t handler,
return 0;
}
-void __irq_entry do_extint(struct pt_regs *regs, unsigned short code)
+void __irq_entry do_extint(struct pt_regs *regs, unsigned int ext_int_code,
+ unsigned int param32, unsigned long param64)
{
+ struct pt_regs *old_regs;
+ unsigned short code;
ext_int_info_t *p;
int index;
- struct pt_regs *old_regs;
+ code = (unsigned short) ext_int_code;
old_regs = set_irq_regs(regs);
s390_idle_check(regs, S390_lowcore.int_clock,
S390_lowcore.async_enter_timer);
@@ -132,7 +135,7 @@ void __irq_entry do_extint(struct pt_regs *regs, unsigned short code)
index = ext_hash(code);
for (p = ext_int_hash[index]; p; p = p->next) {
if (likely(p->code == code))
- p->handler(code);
+ p->handler(ext_int_code, param32, param64);
}
irq_exit();
set_irq_regs(old_regs);
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index c8e8e1354e1d..6f6350826c81 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -409,6 +409,9 @@ setup_lowcore(void)
lc->current_task = (unsigned long) init_thread_union.thread_info.task;
lc->thread_info = (unsigned long) &init_thread_union;
lc->machine_flags = S390_lowcore.machine_flags;
+ lc->stfl_fac_list = S390_lowcore.stfl_fac_list;
+ memcpy(lc->stfle_fac_list, S390_lowcore.stfle_fac_list,
+ MAX_FACILITY_BIT/8);
#ifndef CONFIG_64BIT
if (MACHINE_HAS_IEEE) {
lc->extended_save_area_addr = (__u32)
@@ -627,7 +630,8 @@ setup_memory(void)
add_active_range(0, start_chunk, end_chunk);
pfn = max(start_chunk, start_pfn);
for (; pfn < end_chunk; pfn++)
- page_set_storage_key(PFN_PHYS(pfn), PAGE_DEFAULT_KEY);
+ page_set_storage_key(PFN_PHYS(pfn),
+ PAGE_DEFAULT_KEY, 0);
}
psw_set_key(PAGE_DEFAULT_KEY);
@@ -674,12 +678,9 @@ setup_memory(void)
static void __init setup_hwcaps(void)
{
static const int stfl_bits[6] = { 0, 2, 7, 17, 19, 21 };
- unsigned long long facility_list_extended;
- unsigned int facility_list;
struct cpuid cpu_id;
int i;
- facility_list = stfl();
/*
* The store facility list bits numbers as found in the principles
* of operation are numbered with bit 1UL<<31 as number 0 to
@@ -699,11 +700,10 @@ static void __init setup_hwcaps(void)
* HWCAP_S390_ETF3EH bit 8 (22 && 30).
*/
for (i = 0; i < 6; i++)
- if (facility_list & (1UL << (31 - stfl_bits[i])))
+ if (test_facility(stfl_bits[i]))
elf_hwcap |= 1UL << i;
- if ((facility_list & (1UL << (31 - 22)))
- && (facility_list & (1UL << (31 - 30))))
+ if (test_facility(22) && test_facility(30))
elf_hwcap |= HWCAP_S390_ETF3EH;
/*
@@ -719,12 +719,8 @@ static void __init setup_hwcaps(void)
* translated to:
* HWCAP_S390_DFP bit 6 (42 && 44).
*/
- if ((elf_hwcap & (1UL << 2)) &&
- __stfle(&facility_list_extended, 1) > 0) {
- if ((facility_list_extended & (1ULL << (63 - 42)))
- && (facility_list_extended & (1ULL << (63 - 44))))
- elf_hwcap |= HWCAP_S390_DFP;
- }
+ if ((elf_hwcap & (1UL << 2)) && test_facility(42) && test_facility(44))
+ elf_hwcap |= HWCAP_S390_DFP;
/*
* Huge page support HWCAP_S390_HPAGE is bit 7.
@@ -765,6 +761,9 @@ static void __init setup_hwcaps(void)
case 0x2098:
strcpy(elf_platform, "z10");
break;
+ case 0x2817:
+ strcpy(elf_platform, "z196");
+ break;
}
}
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 8127ebd59c4d..94cf510b8fe1 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -156,7 +156,8 @@ void smp_send_stop(void)
* cpus are handled.
*/
-static void do_ext_call_interrupt(__u16 code)
+static void do_ext_call_interrupt(unsigned int ext_int_code,
+ unsigned int param32, unsigned long param64)
{
unsigned long bits;
@@ -593,6 +594,8 @@ int __cpuinit __cpu_up(unsigned int cpu)
cpu_lowcore->kernel_asce = S390_lowcore.kernel_asce;
cpu_lowcore->machine_flags = S390_lowcore.machine_flags;
cpu_lowcore->ftrace_func = S390_lowcore.ftrace_func;
+ memcpy(cpu_lowcore->stfle_fac_list, S390_lowcore.stfle_fac_list,
+ MAX_FACILITY_BIT/8);
eieio();
while (sigp(cpu, sigp_restart) == sigp_busy)
diff --git a/arch/s390/kernel/sysinfo.c b/arch/s390/kernel/sysinfo.c
index a0ffc7717ed6..5c9e439bf3f6 100644
--- a/arch/s390/kernel/sysinfo.c
+++ b/arch/s390/kernel/sysinfo.c
@@ -15,6 +15,7 @@
#include <asm/ebcdic.h>
#include <asm/sysinfo.h>
#include <asm/cpcmd.h>
+#include <asm/topology.h>
/* Sigh, math-emu. Don't ask. */
#include <asm/sfp-util.h>
@@ -74,6 +75,44 @@ static int stsi_1_1_1(struct sysinfo_1_1_1 *info, char *page, int len)
"Model Temp. Capacity: %-16.16s %08u\n",
info->model_temp_cap,
*(u32 *) info->model_temp_cap_rating);
+ if (info->cai) {
+ len += sprintf(page + len,
+ "Capacity Adj. Ind.: %d\n",
+ info->cai);
+ len += sprintf(page + len, "Capacity Ch. Reason: %d\n",
+ info->ccr);
+ }
+ return len;
+}
+
+static int stsi_15_1_x(struct sysinfo_15_1_x *info, char *page, int len)
+{
+ static int max_mnest;
+ int i, rc;
+
+ len += sprintf(page + len, "\n");
+ if (!MACHINE_HAS_TOPOLOGY)
+ return len;
+ if (max_mnest) {
+ stsi(info, 15, 1, max_mnest);
+ } else {
+ for (max_mnest = 6; max_mnest > 1; max_mnest--) {
+ rc = stsi(info, 15, 1, max_mnest);
+ if (rc != -ENOSYS)
+ break;
+ }
+ }
+ len += sprintf(page + len, "CPU Topology HW: ");
+ for (i = 0; i < TOPOLOGY_NR_MAG; i++)
+ len += sprintf(page + len, " %d", info->mag[i]);
+ len += sprintf(page + len, "\n");
+#ifdef CONFIG_SCHED_MC
+ store_topology(info);
+ len += sprintf(page + len, "CPU Topology SW: ");
+ for (i = 0; i < TOPOLOGY_NR_MAG; i++)
+ len += sprintf(page + len, " %d", info->mag[i]);
+ len += sprintf(page + len, "\n");
+#endif
return len;
}
@@ -87,7 +126,6 @@ static int stsi_1_2_2(struct sysinfo_1_2_2 *info, char *page, int len)
ext = (struct sysinfo_1_2_2_extension *)
((unsigned long) info + info->acc_offset);
- len += sprintf(page + len, "\n");
len += sprintf(page + len, "CPUs Total: %d\n",
info->cpus_total);
len += sprintf(page + len, "CPUs Configured: %d\n",
@@ -217,6 +255,9 @@ static int proc_read_sysinfo(char *page, char **start,
len = stsi_1_1_1((struct sysinfo_1_1_1 *) info, page, len);
if (level >= 1)
+ len = stsi_15_1_x((struct sysinfo_15_1_x *) info, page, len);
+
+ if (level >= 1)
len = stsi_1_2_2((struct sysinfo_1_2_2 *) info, page, len);
if (level >= 2)
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 2896cac9c14a..f754a6dc4f94 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -155,7 +155,9 @@ void init_cpu_timer(void)
__ctl_set_bit(0, 4);
}
-static void clock_comparator_interrupt(__u16 code)
+static void clock_comparator_interrupt(unsigned int ext_int_code,
+ unsigned int param32,
+ unsigned long param64)
{
if (S390_lowcore.clock_comparator == -1ULL)
set_clock_comparator(S390_lowcore.clock_comparator);
@@ -164,14 +166,13 @@ static void clock_comparator_interrupt(__u16 code)
static void etr_timing_alert(struct etr_irq_parm *);
static void stp_timing_alert(struct stp_irq_parm *);
-static void timing_alert_interrupt(__u16 code)
+static void timing_alert_interrupt(unsigned int ext_int_code,
+ unsigned int param32, unsigned long param64)
{
- if (S390_lowcore.ext_params & 0x00c40000)
- etr_timing_alert((struct etr_irq_parm *)
- &S390_lowcore.ext_params);
- if (S390_lowcore.ext_params & 0x00038000)
- stp_timing_alert((struct stp_irq_parm *)
- &S390_lowcore.ext_params);
+ if (param32 & 0x00c40000)
+ etr_timing_alert((struct etr_irq_parm *) &param32);
+ if (param32 & 0x00038000)
+ stp_timing_alert((struct stp_irq_parm *) &param32);
}
static void etr_reset(void);
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c
index bcef00766a64..94b06c31fc8a 100644
--- a/arch/s390/kernel/topology.c
+++ b/arch/s390/kernel/topology.c
@@ -18,158 +18,140 @@
#include <linux/cpuset.h>
#include <asm/delay.h>
#include <asm/s390_ext.h>
-#include <asm/sysinfo.h>
-
-#define CPU_BITS 64
-#define NR_MAG 6
#define PTF_HORIZONTAL (0UL)
#define PTF_VERTICAL (1UL)
#define PTF_CHECK (2UL)
-struct tl_cpu {
- unsigned char reserved0[4];
- unsigned char :6;
- unsigned char pp:2;
- unsigned char reserved1;
- unsigned short origin;
- unsigned long mask[CPU_BITS / BITS_PER_LONG];
-};
-
-struct tl_container {
- unsigned char reserved[7];
- unsigned char id;
-};
-
-union tl_entry {
- unsigned char nl;
- struct tl_cpu cpu;
- struct tl_container container;
-};
-
-struct tl_info {
- unsigned char reserved0[2];
- unsigned short length;
- unsigned char mag[NR_MAG];
- unsigned char reserved1;
- unsigned char mnest;
- unsigned char reserved2[4];
- 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;
};
-static int topology_enabled;
+static int topology_enabled = 1;
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 sysinfo_15_1_x *tl_info;
static struct timer_list topology_timer;
static void set_topology_timer(void);
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;
+ if (!topology_enabled || !MACHINE_HAS_TOPOLOGY) {
+ cpumask_copy(&mask, cpumask_of(cpu));
+ return 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 topology_cpu *tl_cpu,
+ struct mask_info *book, struct mask_info *core)
{
unsigned int cpu;
- for (cpu = find_first_bit(&tl_cpu->mask[0], CPU_BITS);
- cpu < CPU_BITS;
- cpu = find_next_bit(&tl_cpu->mask[0], CPU_BITS, cpu + 1))
+ for (cpu = find_first_bit(&tl_cpu->mask[0], TOPOLOGY_CPU_BITS);
+ cpu < TOPOLOGY_CPU_BITS;
+ cpu = find_next_bit(&tl_cpu->mask[0], TOPOLOGY_CPU_BITS, cpu + 1))
{
unsigned int rcpu, lcpu;
- rcpu = CPU_BITS - 1 - cpu + tl_cpu->origin;
+ rcpu = TOPOLOGY_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)
+static union topology_entry *next_tle(union topology_entry *tle)
{
- if (tle->nl)
- return (union tl_entry *)((struct tl_container *)tle + 1);
- else
- return (union tl_entry *)((struct tl_cpu *)tle + 1);
+ if (!tle->nl)
+ return (union topology_entry *)((struct topology_cpu *)tle + 1);
+ return (union topology_entry *)((struct topology_container *)tle + 1);
}
-static void tl_to_cores(struct tl_info *info)
+static void tl_to_cores(struct sysinfo_15_1_x *info)
{
- union tl_entry *tle, *end;
- struct core_info *core = &core_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 topology_entry *tle, *end;
+
spin_lock_irq(&topology_lock);
- clear_cores();
+ clear_masks();
tle = info->tle;
- end = (union tl_entry *)((unsigned long)info + info->length);
+ end = (union topology_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();
- machine_has_topology = 0;
+ clear_masks();
goto out;
}
tle = next_tle(tle);
@@ -206,7 +188,7 @@ int topology_set_cpu_management(int fc)
int cpu;
int rc;
- if (!machine_has_topology)
+ if (!MACHINE_HAS_TOPOLOGY)
return -EOPNOTSUPP;
if (fc)
rc = ptf(PTF_VERTICAL);
@@ -221,24 +203,43 @@ 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);
+}
+
+void store_topology(struct sysinfo_15_1_x *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)
{
- struct tl_info *info = tl_info;
+ struct sysinfo_15_1_x *info = tl_info;
struct sys_device *sysdev;
int cpu;
- if (!machine_has_topology) {
+ if (!MACHINE_HAS_TOPOLOGY) {
update_cpu_core_map();
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) {
@@ -275,9 +276,9 @@ static void set_topology_timer(void)
static int __init early_parse_topology(char *p)
{
- if (strncmp(p, "on", 2))
+ if (strncmp(p, "off", 3))
return 0;
- topology_enabled = 1;
+ topology_enabled = 0;
return 0;
}
early_param("topology", early_parse_topology);
@@ -287,7 +288,7 @@ static int __init init_topology_update(void)
int rc;
rc = 0;
- if (!machine_has_topology) {
+ if (!MACHINE_HAS_TOPOLOGY) {
topology_update_polarization_simple();
goto out;
}
@@ -299,41 +300,37 @@ out:
}
__initcall(init_topology_update);
+static void alloc_masks(struct sysinfo_15_1_x *info, struct mask_info *mask,
+ int offset)
+{
+ int i, nr_masks;
+
+ nr_masks = info->mag[TOPOLOGY_NR_MAG - offset];
+ for (i = 0; i < info->mnest - offset; i++)
+ nr_masks *= info->mag[TOPOLOGY_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;
+ struct sysinfo_15_1_x *info;
int i;
- if (stfle(&facility_bits, 1) <= 0)
- return;
- if (!(facility_bits & (1ULL << 52)) || !(facility_bits & (1ULL << 61)))
+ if (!MACHINE_HAS_TOPOLOGY)
return;
- machine_has_topology = 1;
-
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++)
+ for (i = 0; i < TOPOLOGY_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/kernel/traps.c b/arch/s390/kernel/traps.c
index 5d8f0f3d0250..70640822621a 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -329,27 +329,19 @@ int is_valid_bugaddr(unsigned long addr)
return 1;
}
-static void __kprobes inline do_trap(long interruption_code, int signr,
- char *str, struct pt_regs *regs,
- siginfo_t *info)
+static inline void __kprobes do_trap(long pgm_int_code, int signr, char *str,
+ struct pt_regs *regs, siginfo_t *info)
{
- /*
- * We got all needed information from the lowcore and can
- * now safely switch on interrupts.
- */
- if (regs->psw.mask & PSW_MASK_PSTATE)
- local_irq_enable();
-
- if (notify_die(DIE_TRAP, str, regs, interruption_code,
- interruption_code, signr) == NOTIFY_STOP)
+ if (notify_die(DIE_TRAP, str, regs, pgm_int_code,
+ pgm_int_code, signr) == NOTIFY_STOP)
return;
if (regs->psw.mask & PSW_MASK_PSTATE) {
struct task_struct *tsk = current;
- tsk->thread.trap_no = interruption_code & 0xffff;
+ tsk->thread.trap_no = pgm_int_code & 0xffff;
force_sig_info(signr, info, tsk);
- report_user_fault(regs, interruption_code, signr);
+ report_user_fault(regs, pgm_int_code, signr);
} else {
const struct exception_table_entry *fixup;
fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN);
@@ -361,14 +353,16 @@ static void __kprobes inline do_trap(long interruption_code, int signr,
btt = report_bug(regs->psw.addr & PSW_ADDR_INSN, regs);
if (btt == BUG_TRAP_TYPE_WARN)
return;
- die(str, regs, interruption_code);
+ die(str, regs, pgm_int_code);
}
}
}
-static inline void __user *get_check_address(struct pt_regs *regs)
+static inline void __user *get_psw_address(struct pt_regs *regs,
+ long pgm_int_code)
{
- return (void __user *)((regs->psw.addr-S390_lowcore.pgm_ilc) & PSW_ADDR_INSN);
+ return (void __user *)
+ ((regs->psw.addr - (pgm_int_code >> 16)) & PSW_ADDR_INSN);
}
void __kprobes do_single_step(struct pt_regs *regs)
@@ -381,57 +375,57 @@ void __kprobes do_single_step(struct pt_regs *regs)
force_sig(SIGTRAP, current);
}
-static void default_trap_handler(struct pt_regs * regs, long interruption_code)
+static void default_trap_handler(struct pt_regs *regs, long pgm_int_code,
+ unsigned long trans_exc_code)
{
if (regs->psw.mask & PSW_MASK_PSTATE) {
- local_irq_enable();
- report_user_fault(regs, interruption_code, SIGSEGV);
+ report_user_fault(regs, pgm_int_code, SIGSEGV);
do_exit(SIGSEGV);
} else
- die("Unknown program exception", regs, interruption_code);
+ die("Unknown program exception", regs, pgm_int_code);
}
-#define DO_ERROR_INFO(signr, str, name, sicode, siaddr) \
-static void name(struct pt_regs * regs, long interruption_code) \
+#define DO_ERROR_INFO(name, signr, sicode, str) \
+static void name(struct pt_regs *regs, long pgm_int_code, \
+ unsigned long trans_exc_code) \
{ \
siginfo_t info; \
info.si_signo = signr; \
info.si_errno = 0; \
info.si_code = sicode; \
- info.si_addr = siaddr; \
- do_trap(interruption_code, signr, str, regs, &info); \
+ info.si_addr = get_psw_address(regs, pgm_int_code); \
+ do_trap(pgm_int_code, signr, str, regs, &info); \
}
-DO_ERROR_INFO(SIGILL, "addressing exception", addressing_exception,
- ILL_ILLADR, get_check_address(regs))
-DO_ERROR_INFO(SIGILL, "execute exception", execute_exception,
- ILL_ILLOPN, get_check_address(regs))
-DO_ERROR_INFO(SIGFPE, "fixpoint divide exception", divide_exception,
- FPE_INTDIV, get_check_address(regs))
-DO_ERROR_INFO(SIGFPE, "fixpoint overflow exception", overflow_exception,
- FPE_INTOVF, get_check_address(regs))
-DO_ERROR_INFO(SIGFPE, "HFP overflow exception", hfp_overflow_exception,
- FPE_FLTOVF, get_check_address(regs))
-DO_ERROR_INFO(SIGFPE, "HFP underflow exception", hfp_underflow_exception,
- FPE_FLTUND, get_check_address(regs))
-DO_ERROR_INFO(SIGFPE, "HFP significance exception", hfp_significance_exception,
- FPE_FLTRES, get_check_address(regs))
-DO_ERROR_INFO(SIGFPE, "HFP divide exception", hfp_divide_exception,
- FPE_FLTDIV, get_check_address(regs))
-DO_ERROR_INFO(SIGFPE, "HFP square root exception", hfp_sqrt_exception,
- FPE_FLTINV, get_check_address(regs))
-DO_ERROR_INFO(SIGILL, "operand exception", operand_exception,
- ILL_ILLOPN, get_check_address(regs))
-DO_ERROR_INFO(SIGILL, "privileged operation", privileged_op,
- ILL_PRVOPC, get_check_address(regs))
-DO_ERROR_INFO(SIGILL, "special operation exception", special_op_exception,
- ILL_ILLOPN, get_check_address(regs))
-DO_ERROR_INFO(SIGILL, "translation exception", translation_exception,
- ILL_ILLOPN, get_check_address(regs))
-
-static inline void
-do_fp_trap(struct pt_regs *regs, void __user *location,
- int fpc, long interruption_code)
+DO_ERROR_INFO(addressing_exception, SIGILL, ILL_ILLADR,
+ "addressing exception")
+DO_ERROR_INFO(execute_exception, SIGILL, ILL_ILLOPN,
+ "execute exception")
+DO_ERROR_INFO(divide_exception, SIGFPE, FPE_INTDIV,
+ "fixpoint divide exception")
+DO_ERROR_INFO(overflow_exception, SIGFPE, FPE_INTOVF,
+ "fixpoint overflow exception")
+DO_ERROR_INFO(hfp_overflow_exception, SIGFPE, FPE_FLTOVF,
+ "HFP overflow exception")
+DO_ERROR_INFO(hfp_underflow_exception, SIGFPE, FPE_FLTUND,
+ "HFP underflow exception")
+DO_ERROR_INFO(hfp_significance_exception, SIGFPE, FPE_FLTRES,
+ "HFP significance exception")
+DO_ERROR_INFO(hfp_divide_exception, SIGFPE, FPE_FLTDIV,
+ "HFP divide exception")
+DO_ERROR_INFO(hfp_sqrt_exception, SIGFPE, FPE_FLTINV,
+ "HFP square root exception")
+DO_ERROR_INFO(operand_exception, SIGILL, ILL_ILLOPN,
+ "operand exception")
+DO_ERROR_INFO(privileged_op, SIGILL, ILL_PRVOPC,
+ "privileged operation")
+DO_ERROR_INFO(special_op_exception, SIGILL, ILL_ILLOPN,
+ "special operation exception")
+DO_ERROR_INFO(translation_exception, SIGILL, ILL_ILLOPN,
+ "translation exception")
+
+static inline void do_fp_trap(struct pt_regs *regs, void __user *location,
+ int fpc, long pgm_int_code)
{
siginfo_t si;
@@ -453,26 +447,19 @@ do_fp_trap(struct pt_regs *regs, void __user *location,
else if (fpc & 0x0800) /* inexact */
si.si_code = FPE_FLTRES;
}
- current->thread.ieee_instruction_pointer = (addr_t) location;
- do_trap(interruption_code, SIGFPE,
+ do_trap(pgm_int_code, SIGFPE,
"floating point exception", regs, &si);
}
-static void illegal_op(struct pt_regs * regs, long interruption_code)
+static void illegal_op(struct pt_regs *regs, long pgm_int_code,
+ unsigned long trans_exc_code)
{
siginfo_t info;
__u8 opcode[6];
__u16 __user *location;
int signal = 0;
- location = get_check_address(regs);
-
- /*
- * We got all needed information from the lowcore and can
- * now safely switch on interrupts.
- */
- if (regs->psw.mask & PSW_MASK_PSTATE)
- local_irq_enable();
+ location = get_psw_address(regs, pgm_int_code);
if (regs->psw.mask & PSW_MASK_PSTATE) {
if (get_user(*((__u16 *) opcode), (__u16 __user *) location))
@@ -512,7 +499,7 @@ static void illegal_op(struct pt_regs * regs, long interruption_code)
* If we get an illegal op in kernel mode, send it through the
* kprobes notifier. If kprobes doesn't pick it up, SIGILL
*/
- if (notify_die(DIE_BPT, "bpt", regs, interruption_code,
+ if (notify_die(DIE_BPT, "bpt", regs, pgm_int_code,
3, SIGTRAP) != NOTIFY_STOP)
signal = SIGILL;
}
@@ -520,13 +507,13 @@ static void illegal_op(struct pt_regs * regs, long interruption_code)
#ifdef CONFIG_MATHEMU
if (signal == SIGFPE)
do_fp_trap(regs, location,
- current->thread.fp_regs.fpc, interruption_code);
+ current->thread.fp_regs.fpc, pgm_int_code);
else if (signal == SIGSEGV) {
info.si_signo = signal;
info.si_errno = 0;
info.si_code = SEGV_MAPERR;
info.si_addr = (void __user *) location;
- do_trap(interruption_code, signal,
+ do_trap(pgm_int_code, signal,
"user address fault", regs, &info);
} else
#endif
@@ -535,28 +522,22 @@ static void illegal_op(struct pt_regs * regs, long interruption_code)
info.si_errno = 0;
info.si_code = ILL_ILLOPC;
info.si_addr = (void __user *) location;
- do_trap(interruption_code, signal,
+ do_trap(pgm_int_code, signal,
"illegal operation", regs, &info);
}
}
#ifdef CONFIG_MATHEMU
-asmlinkage void
-specification_exception(struct pt_regs * regs, long interruption_code)
+asmlinkage void specification_exception(struct pt_regs *regs,
+ long pgm_int_code,
+ unsigned long trans_exc_code)
{
__u8 opcode[6];
__u16 __user *location = NULL;
int signal = 0;
- location = (__u16 __user *) get_check_address(regs);
-
- /*
- * We got all needed information from the lowcore and can
- * now safely switch on interrupts.
- */
- if (regs->psw.mask & PSW_MASK_PSTATE)
- local_irq_enable();
+ location = (__u16 __user *) get_psw_address(regs, pgm_int_code);
if (regs->psw.mask & PSW_MASK_PSTATE) {
get_user(*((__u16 *) opcode), location);
@@ -592,35 +573,29 @@ specification_exception(struct pt_regs * regs, long interruption_code)
if (signal == SIGFPE)
do_fp_trap(regs, location,
- current->thread.fp_regs.fpc, interruption_code);
+ current->thread.fp_regs.fpc, pgm_int_code);
else if (signal) {
siginfo_t info;
info.si_signo = signal;
info.si_errno = 0;
info.si_code = ILL_ILLOPN;
info.si_addr = location;
- do_trap(interruption_code, signal,
+ do_trap(pgm_int_code, signal,
"specification exception", regs, &info);
}
}
#else
-DO_ERROR_INFO(SIGILL, "specification exception", specification_exception,
- ILL_ILLOPN, get_check_address(regs));
+DO_ERROR_INFO(specification_exception, SIGILL, ILL_ILLOPN,
+ "specification exception");
#endif
-static void data_exception(struct pt_regs * regs, long interruption_code)
+static void data_exception(struct pt_regs *regs, long pgm_int_code,
+ unsigned long trans_exc_code)
{
__u16 __user *location;
int signal = 0;
- location = get_check_address(regs);
-
- /*
- * We got all needed information from the lowcore and can
- * now safely switch on interrupts.
- */
- if (regs->psw.mask & PSW_MASK_PSTATE)
- local_irq_enable();
+ location = get_psw_address(regs, pgm_int_code);
if (MACHINE_HAS_IEEE)
asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc));
@@ -686,19 +661,19 @@ static void data_exception(struct pt_regs * regs, long interruption_code)
signal = SIGILL;
if (signal == SIGFPE)
do_fp_trap(regs, location,
- current->thread.fp_regs.fpc, interruption_code);
+ current->thread.fp_regs.fpc, pgm_int_code);
else if (signal) {
siginfo_t info;
info.si_signo = signal;
info.si_errno = 0;
info.si_code = ILL_ILLOPN;
info.si_addr = location;
- do_trap(interruption_code, signal,
- "data exception", regs, &info);
+ do_trap(pgm_int_code, signal, "data exception", regs, &info);
}
}
-static void space_switch_exception(struct pt_regs * regs, long int_code)
+static void space_switch_exception(struct pt_regs *regs, long pgm_int_code,
+ unsigned long trans_exc_code)
{
siginfo_t info;
@@ -709,8 +684,8 @@ static void space_switch_exception(struct pt_regs * regs, long int_code)
info.si_signo = SIGILL;
info.si_errno = 0;
info.si_code = ILL_PRVOPC;
- info.si_addr = get_check_address(regs);
- do_trap(int_code, SIGILL, "space switch event", regs, &info);
+ info.si_addr = get_psw_address(regs, pgm_int_code);
+ do_trap(pgm_int_code, SIGILL, "space switch event", regs, &info);
}
asmlinkage void kernel_stack_overflow(struct pt_regs * regs)
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c
index 6b83870507d5..e3150dd2fe74 100644
--- a/arch/s390/kernel/vdso.c
+++ b/arch/s390/kernel/vdso.c
@@ -84,11 +84,7 @@ struct vdso_data *vdso_data = &vdso_data_store.data;
*/
static void vdso_init_data(struct vdso_data *vd)
{
- unsigned int facility_list;
-
- facility_list = stfl();
- vd->ectg_available =
- user_mode != HOME_SPACE_MODE && (facility_list & 1);
+ vd->ectg_available = user_mode != HOME_SPACE_MODE && test_facility(31);
}
#ifdef CONFIG_64BIT
diff --git a/arch/s390/kernel/vdso32/clock_getres.S b/arch/s390/kernel/vdso32/clock_getres.S
index 9532c4e6a9d2..36aaa25d05da 100644
--- a/arch/s390/kernel/vdso32/clock_getres.S
+++ b/arch/s390/kernel/vdso32/clock_getres.S
@@ -19,9 +19,9 @@
.type __kernel_clock_getres,@function
__kernel_clock_getres:
.cfi_startproc
- chi %r2,CLOCK_REALTIME
+ chi %r2,__CLOCK_REALTIME
je 0f
- chi %r2,CLOCK_MONOTONIC
+ chi %r2,__CLOCK_MONOTONIC
jne 3f
0: ltr %r3,%r3
jz 2f /* res == NULL */
@@ -34,6 +34,6 @@ __kernel_clock_getres:
3: lhi %r1,__NR_clock_getres /* fallback to svc */
svc 0
br %r14
-4: .long CLOCK_REALTIME_RES
+4: .long __CLOCK_REALTIME_RES
.cfi_endproc
.size __kernel_clock_getres,.-__kernel_clock_getres
diff --git a/arch/s390/kernel/vdso32/clock_gettime.S b/arch/s390/kernel/vdso32/clock_gettime.S
index 969643954273..b2224e0b974c 100644
--- a/arch/s390/kernel/vdso32/clock_gettime.S
+++ b/arch/s390/kernel/vdso32/clock_gettime.S
@@ -21,9 +21,9 @@ __kernel_clock_gettime:
.cfi_startproc
basr %r5,0
0: al %r5,21f-0b(%r5) /* get &_vdso_data */
- chi %r2,CLOCK_REALTIME
+ chi %r2,__CLOCK_REALTIME
je 10f
- chi %r2,CLOCK_MONOTONIC
+ chi %r2,__CLOCK_MONOTONIC
jne 19f
/* CLOCK_MONOTONIC */
diff --git a/arch/s390/kernel/vdso64/clock_getres.S b/arch/s390/kernel/vdso64/clock_getres.S
index 9ce8caafdb4e..176e1f75f9aa 100644
--- a/arch/s390/kernel/vdso64/clock_getres.S
+++ b/arch/s390/kernel/vdso64/clock_getres.S
@@ -19,9 +19,9 @@
.type __kernel_clock_getres,@function
__kernel_clock_getres:
.cfi_startproc
- cghi %r2,CLOCK_REALTIME
+ cghi %r2,__CLOCK_REALTIME
je 0f
- cghi %r2,CLOCK_MONOTONIC
+ cghi %r2,__CLOCK_MONOTONIC
je 0f
cghi %r2,-2 /* CLOCK_THREAD_CPUTIME_ID for this thread */
jne 2f
@@ -39,6 +39,6 @@ __kernel_clock_getres:
2: lghi %r1,__NR_clock_getres /* fallback to svc */
svc 0
br %r14
-3: .quad CLOCK_REALTIME_RES
+3: .quad __CLOCK_REALTIME_RES
.cfi_endproc
.size __kernel_clock_getres,.-__kernel_clock_getres
diff --git a/arch/s390/kernel/vdso64/clock_gettime.S b/arch/s390/kernel/vdso64/clock_gettime.S
index f40467884a03..d46c95ed5f19 100644
--- a/arch/s390/kernel/vdso64/clock_gettime.S
+++ b/arch/s390/kernel/vdso64/clock_gettime.S
@@ -20,11 +20,11 @@
__kernel_clock_gettime:
.cfi_startproc
larl %r5,_vdso_data
- cghi %r2,CLOCK_REALTIME
+ cghi %r2,__CLOCK_REALTIME
je 4f
cghi %r2,-2 /* CLOCK_THREAD_CPUTIME_ID for this thread */
je 9f
- cghi %r2,CLOCK_MONOTONIC
+ cghi %r2,__CLOCK_MONOTONIC
jne 12f
/* CLOCK_MONOTONIC */
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index 3479f1b0d4e0..56c8687b29b3 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -314,7 +314,8 @@ static void do_callbacks(struct list_head *cb_list)
/*
* Handler for the virtual CPU timer.
*/
-static void do_cpu_timer_interrupt(__u16 error_code)
+static void do_cpu_timer_interrupt(unsigned int ext_int_code,
+ unsigned int param32, unsigned long param64)
{
struct vtimer_queue *vq;
struct vtimer_list *event, *tmp;
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 4fe68650535c..985d825494f1 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -740,8 +740,8 @@ static int __init kvm_s390_init(void)
kvm_exit();
return -ENOMEM;
}
- stfle(facilities, 1);
- facilities[0] &= 0xff00fff3f0700000ULL;
+ memcpy(facilities, S390_lowcore.stfle_fac_list, 16);
+ facilities[0] &= 0xff00fff3f47c0000ULL;
return 0;
}
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index 44205507717c..9194a4b52b22 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -154,12 +154,12 @@ static int handle_chsc(struct kvm_vcpu *vcpu)
static int handle_stfl(struct kvm_vcpu *vcpu)
{
- unsigned int facility_list = stfl();
+ unsigned int facility_list;
int rc;
vcpu->stat.instruction_stfl++;
/* only pass the facility bits, which we can handle */
- facility_list &= 0xff00fff3;
+ facility_list = S390_lowcore.stfl_fac_list & 0xff00fff3;
rc = copy_to_guest(vcpu, offsetof(struct _lowcore, stfl_fac_list),
&facility_list, sizeof(facility_list));
diff --git a/arch/s390/mm/Makefile b/arch/s390/mm/Makefile
index eec054484419..6fbc6f3fbdf2 100644
--- a/arch/s390/mm/Makefile
+++ b/arch/s390/mm/Makefile
@@ -3,6 +3,6 @@
#
obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o maccess.o \
- page-states.o
+ page-states.o gup.o
obj-$(CONFIG_CMM) += cmm.o
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c
index a9550dca3e4b..c66ffd8dbbb7 100644
--- a/arch/s390/mm/cmm.c
+++ b/arch/s390/mm/cmm.c
@@ -23,7 +23,10 @@
#include <asm/pgalloc.h>
#include <asm/diag.h>
-static char *sender = "VMRMSVM";
+#ifdef CONFIG_CMM_IUCV
+static char *cmm_default_sender = "VMRMSVM";
+#endif
+static char *sender;
module_param(sender, charp, 0400);
MODULE_PARM_DESC(sender,
"Guest name that may send SMSG messages (default VMRMSVM)");
@@ -440,6 +443,8 @@ static int __init cmm_init(void)
int len = strlen(sender);
while (len--)
sender[len] = toupper(sender[len]);
+ } else {
+ sender = cmm_default_sender;
}
rc = smsg_register_callback(SMSG_PREFIX, cmm_smsg_target);
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 2505b2ea0ef1..fe5701e9efbf 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -52,6 +52,14 @@
#define VM_FAULT_BADMAP 0x020000
#define VM_FAULT_BADACCESS 0x040000
+static unsigned long store_indication;
+
+void fault_init(void)
+{
+ if (test_facility(2) && test_facility(75))
+ store_indication = 0xc00;
+}
+
static inline int notify_page_fault(struct pt_regs *regs)
{
int ret = 0;
@@ -199,14 +207,21 @@ static noinline void do_sigbus(struct pt_regs *regs, long int_code,
unsigned long trans_exc_code)
{
struct task_struct *tsk = current;
+ unsigned long address;
+ struct siginfo si;
/*
* Send a sigbus, regardless of whether we were in kernel
* or user mode.
*/
- tsk->thread.prot_addr = trans_exc_code & __FAIL_ADDR_MASK;
+ address = trans_exc_code & __FAIL_ADDR_MASK;
+ tsk->thread.prot_addr = address;
tsk->thread.trap_no = int_code;
- force_sig(SIGBUS, tsk);
+ si.si_signo = SIGBUS;
+ si.si_errno = 0;
+ si.si_code = BUS_ADRERR;
+ si.si_addr = (void __user *) address;
+ force_sig_info(SIGBUS, &si, tsk);
}
#ifdef CONFIG_S390_EXEC_PROTECT
@@ -266,10 +281,11 @@ static noinline void do_fault_error(struct pt_regs *regs, long int_code,
if (fault & VM_FAULT_OOM)
pagefault_out_of_memory();
else if (fault & VM_FAULT_SIGBUS) {
- do_sigbus(regs, int_code, trans_exc_code);
/* Kernel mode? Handle exceptions or die */
if (!(regs->psw.mask & PSW_MASK_PSTATE))
do_no_context(regs, int_code, trans_exc_code);
+ else
+ do_sigbus(regs, int_code, trans_exc_code);
} else
BUG();
break;
@@ -294,7 +310,7 @@ static inline int do_exception(struct pt_regs *regs, int access,
struct mm_struct *mm;
struct vm_area_struct *vma;
unsigned long address;
- int fault;
+ int fault, write;
if (notify_page_fault(regs))
return 0;
@@ -312,12 +328,6 @@ static inline int do_exception(struct pt_regs *regs, int access,
goto out;
address = trans_exc_code & __FAIL_ADDR_MASK;
- /*
- * When we get here, the fault happened in the current
- * task's user address space, so we can switch on the
- * interrupts again and then search the VMAs
- */
- local_irq_enable();
perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
down_read(&mm->mmap_sem);
@@ -348,8 +358,10 @@ static inline int do_exception(struct pt_regs *regs, int access,
* make sure we exit gracefully rather than endlessly redo
* the fault.
*/
- fault = handle_mm_fault(mm, vma, address,
- (access == VM_WRITE) ? FAULT_FLAG_WRITE : 0);
+ write = (access == VM_WRITE ||
+ (trans_exc_code & store_indication) == 0x400) ?
+ FAULT_FLAG_WRITE : 0;
+ fault = handle_mm_fault(mm, vma, address, write);
if (unlikely(fault & VM_FAULT_ERROR))
goto out_up;
@@ -374,20 +386,20 @@ out:
return fault;
}
-void __kprobes do_protection_exception(struct pt_regs *regs, long int_code)
+void __kprobes do_protection_exception(struct pt_regs *regs, long pgm_int_code,
+ unsigned long trans_exc_code)
{
- unsigned long trans_exc_code = S390_lowcore.trans_exc_code;
int fault;
/* Protection exception is supressing, decrement psw address. */
- regs->psw.addr -= (int_code >> 16);
+ regs->psw.addr -= (pgm_int_code >> 16);
/*
* Check for low-address protection. This needs to be treated
* as a special case because the translation exception code
* field is not guaranteed to contain valid data in this case.
*/
if (unlikely(!(trans_exc_code & 4))) {
- do_low_address(regs, int_code, trans_exc_code);
+ do_low_address(regs, pgm_int_code, trans_exc_code);
return;
}
fault = do_exception(regs, VM_WRITE, trans_exc_code);
@@ -395,9 +407,9 @@ void __kprobes do_protection_exception(struct pt_regs *regs, long int_code)
do_fault_error(regs, 4, trans_exc_code, fault);
}
-void __kprobes do_dat_exception(struct pt_regs *regs, long int_code)
+void __kprobes do_dat_exception(struct pt_regs *regs, long pgm_int_code,
+ unsigned long trans_exc_code)
{
- unsigned long trans_exc_code = S390_lowcore.trans_exc_code;
int access, fault;
access = VM_READ | VM_EXEC | VM_WRITE;
@@ -408,21 +420,19 @@ void __kprobes do_dat_exception(struct pt_regs *regs, long int_code)
#endif
fault = do_exception(regs, access, trans_exc_code);
if (unlikely(fault))
- do_fault_error(regs, int_code & 255, trans_exc_code, fault);
+ do_fault_error(regs, pgm_int_code & 255, trans_exc_code, fault);
}
#ifdef CONFIG_64BIT
-void __kprobes do_asce_exception(struct pt_regs *regs, long int_code)
+void __kprobes do_asce_exception(struct pt_regs *regs, long pgm_int_code,
+ unsigned long trans_exc_code)
{
- unsigned long trans_exc_code = S390_lowcore.trans_exc_code;
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
if (unlikely(!user_space_fault(trans_exc_code) || in_atomic() || !mm))
goto no_context;
- local_irq_enable();
-
down_read(&mm->mmap_sem);
vma = find_vma(mm, trans_exc_code & __FAIL_ADDR_MASK);
up_read(&mm->mmap_sem);
@@ -434,16 +444,16 @@ void __kprobes do_asce_exception(struct pt_regs *regs, long int_code)
/* User mode accesses just cause a SIGSEGV */
if (regs->psw.mask & PSW_MASK_PSTATE) {
- do_sigsegv(regs, int_code, SEGV_MAPERR, trans_exc_code);
+ do_sigsegv(regs, pgm_int_code, SEGV_MAPERR, trans_exc_code);
return;
}
no_context:
- do_no_context(regs, int_code, trans_exc_code);
+ do_no_context(regs, pgm_int_code, trans_exc_code);
}
#endif
-int __handle_fault(unsigned long uaddr, unsigned long int_code, int write_user)
+int __handle_fault(unsigned long uaddr, unsigned long pgm_int_code, int write)
{
struct pt_regs regs;
int access, fault;
@@ -454,14 +464,14 @@ int __handle_fault(unsigned long uaddr, unsigned long int_code, int write_user)
regs.psw.addr = (unsigned long) __builtin_return_address(0);
regs.psw.addr |= PSW_ADDR_AMODE;
uaddr &= PAGE_MASK;
- access = write_user ? VM_WRITE : VM_READ;
+ access = write ? VM_WRITE : VM_READ;
fault = do_exception(&regs, access, uaddr | 2);
if (unlikely(fault)) {
if (fault & VM_FAULT_OOM) {
pagefault_out_of_memory();
fault = 0;
} else if (fault & VM_FAULT_SIGBUS)
- do_sigbus(&regs, int_code, uaddr);
+ do_sigbus(&regs, pgm_int_code, uaddr);
}
return fault ? -EFAULT : 0;
}
@@ -527,7 +537,8 @@ void pfault_fini(void)
: : "a" (&refbk), "m" (refbk) : "cc");
}
-static void pfault_interrupt(__u16 int_code)
+static void pfault_interrupt(unsigned int ext_int_code,
+ unsigned int param32, unsigned long param64)
{
struct task_struct *tsk;
__u16 subcode;
@@ -538,14 +549,18 @@ static void pfault_interrupt(__u16 int_code)
* in the 'cpu address' field associated with the
* external interrupt.
*/
- subcode = S390_lowcore.cpu_addr;
+ subcode = ext_int_code >> 16;
if ((subcode & 0xff00) != __SUBCODE_MASK)
return;
/*
* Get the token (= address of the task structure of the affected task).
*/
- tsk = *(struct task_struct **) __LC_PFAULT_INTPARM;
+#ifdef CONFIG_64BIT
+ tsk = *(struct task_struct **) param64;
+#else
+ tsk = *(struct task_struct **) param32;
+#endif
if (subcode & 0x0080) {
/* signal bit is set -> a page has been swapped in by VM */
diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c
new file mode 100644
index 000000000000..38e641cdd977
--- /dev/null
+++ b/arch/s390/mm/gup.c
@@ -0,0 +1,225 @@
+/*
+ * Lockless get_user_pages_fast for s390
+ *
+ * Copyright IBM Corp. 2010
+ * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/hugetlb.h>
+#include <linux/vmstat.h>
+#include <linux/pagemap.h>
+#include <linux/rwsem.h>
+#include <asm/pgtable.h>
+
+/*
+ * The performance critical leaf functions are made noinline otherwise gcc
+ * inlines everything into a single function which results in too much
+ * register pressure.
+ */
+static inline int gup_pte_range(pmd_t *pmdp, pmd_t pmd, unsigned long addr,
+ unsigned long end, int write, struct page **pages, int *nr)
+{
+ unsigned long mask, result;
+ pte_t *ptep, pte;
+ struct page *page;
+
+ result = write ? 0 : _PAGE_RO;
+ mask = result | _PAGE_INVALID | _PAGE_SPECIAL;
+
+ ptep = ((pte_t *) pmd_deref(pmd)) + pte_index(addr);
+ do {
+ pte = *ptep;
+ barrier();
+ if ((pte_val(pte) & mask) != result)
+ return 0;
+ VM_BUG_ON(!pfn_valid(pte_pfn(pte)));
+ page = pte_page(pte);
+ if (!page_cache_get_speculative(page))
+ return 0;
+ if (unlikely(pte_val(pte) != pte_val(*ptep))) {
+ put_page(page);
+ return 0;
+ }
+ pages[*nr] = page;
+ (*nr)++;
+
+ } while (ptep++, addr += PAGE_SIZE, addr != end);
+
+ return 1;
+}
+
+static inline int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr,
+ unsigned long end, int write, struct page **pages, int *nr)
+{
+ unsigned long mask, result;
+ struct page *head, *page;
+ int refs;
+
+ result = write ? 0 : _SEGMENT_ENTRY_RO;
+ mask = result | _SEGMENT_ENTRY_INV;
+ if ((pmd_val(pmd) & mask) != result)
+ return 0;
+ VM_BUG_ON(!pfn_valid(pmd_val(pmd) >> PAGE_SHIFT));
+
+ refs = 0;
+ head = pmd_page(pmd);
+ page = head + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
+ do {
+ VM_BUG_ON(compound_head(page) != head);
+ pages[*nr] = page;
+ (*nr)++;
+ page++;
+ refs++;
+ } while (addr += PAGE_SIZE, addr != end);
+
+ if (!page_cache_add_speculative(head, refs)) {
+ *nr -= refs;
+ return 0;
+ }
+
+ if (unlikely(pmd_val(pmd) != pmd_val(*pmdp))) {
+ *nr -= refs;
+ while (refs--)
+ put_page(head);
+ }
+
+ return 1;
+}
+
+
+static inline int gup_pmd_range(pud_t *pudp, pud_t pud, unsigned long addr,
+ unsigned long end, int write, struct page **pages, int *nr)
+{
+ unsigned long next;
+ pmd_t *pmdp, pmd;
+
+ pmdp = (pmd_t *) pudp;
+#ifdef CONFIG_64BIT
+ if ((pud_val(pud) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3)
+ pmdp = (pmd_t *) pud_deref(pud);
+ pmdp += pmd_index(addr);
+#endif
+ do {
+ pmd = *pmdp;
+ barrier();
+ next = pmd_addr_end(addr, end);
+ if (pmd_none(pmd))
+ return 0;
+ if (unlikely(pmd_huge(pmd))) {
+ if (!gup_huge_pmd(pmdp, pmd, addr, next,
+ write, pages, nr))
+ return 0;
+ } else if (!gup_pte_range(pmdp, pmd, addr, next,
+ write, pages, nr))
+ return 0;
+ } while (pmdp++, addr = next, addr != end);
+
+ return 1;
+}
+
+static inline int gup_pud_range(pgd_t *pgdp, pgd_t pgd, unsigned long addr,
+ unsigned long end, int write, struct page **pages, int *nr)
+{
+ unsigned long next;
+ pud_t *pudp, pud;
+
+ pudp = (pud_t *) pgdp;
+#ifdef CONFIG_64BIT
+ if ((pgd_val(pgd) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R2)
+ pudp = (pud_t *) pgd_deref(pgd);
+ pudp += pud_index(addr);
+#endif
+ do {
+ pud = *pudp;
+ barrier();
+ next = pud_addr_end(addr, end);
+ if (pud_none(pud))
+ return 0;
+ if (!gup_pmd_range(pudp, pud, addr, next, write, pages, nr))
+ return 0;
+ } while (pudp++, addr = next, addr != end);
+
+ return 1;
+}
+
+/**
+ * get_user_pages_fast() - pin user pages in memory
+ * @start: starting user address
+ * @nr_pages: number of pages from start to pin
+ * @write: whether pages will be written to
+ * @pages: array that receives pointers to the pages pinned.
+ * Should be at least nr_pages long.
+ *
+ * Attempt to pin user pages in memory without taking mm->mmap_sem.
+ * If not successful, it will fall back to taking the lock and
+ * calling get_user_pages().
+ *
+ * Returns number of pages pinned. This may be fewer than the number
+ * requested. If nr_pages is 0 or negative, returns 0. If no pages
+ * were pinned, returns -errno.
+ */
+int get_user_pages_fast(unsigned long start, int nr_pages, int write,
+ struct page **pages)
+{
+ struct mm_struct *mm = current->mm;
+ unsigned long addr, len, end;
+ unsigned long next;
+ pgd_t *pgdp, pgd;
+ int nr = 0;
+
+ start &= PAGE_MASK;
+ addr = start;
+ len = (unsigned long) nr_pages << PAGE_SHIFT;
+ end = start + len;
+ if (end < start)
+ goto slow_irqon;
+
+ /*
+ * local_irq_disable() doesn't prevent pagetable teardown, but does
+ * prevent the pagetables from being freed on s390.
+ *
+ * So long as we atomically load page table pointers versus teardown,
+ * we can follow the address down to the the page and take a ref on it.
+ */
+ local_irq_disable();
+ pgdp = pgd_offset(mm, addr);
+ do {
+ pgd = *pgdp;
+ barrier();
+ next = pgd_addr_end(addr, end);
+ if (pgd_none(pgd))
+ goto slow;
+ if (!gup_pud_range(pgdp, pgd, addr, next, write, pages, &nr))
+ goto slow;
+ } while (pgdp++, addr = next, addr != end);
+ local_irq_enable();
+
+ VM_BUG_ON(nr != (end - start) >> PAGE_SHIFT);
+ return nr;
+
+ {
+ int ret;
+slow:
+ local_irq_enable();
+slow_irqon:
+ /* Try to get the remaining pages with get_user_pages */
+ start += nr << PAGE_SHIFT;
+ pages += nr;
+
+ down_read(&mm->mmap_sem);
+ ret = get_user_pages(current, mm, start,
+ (end - start) >> PAGE_SHIFT, write, 0, pages, NULL);
+ up_read(&mm->mmap_sem);
+
+ /* Have to be a bit careful with return values */
+ if (nr > 0) {
+ if (ret < 0)
+ ret = nr;
+ else
+ ret += nr;
+ }
+
+ return ret;
+ }
+}
diff --git a/arch/s390/mm/hugetlbpage.c b/arch/s390/mm/hugetlbpage.c
index f28c43d2f61d..639cd21f2218 100644
--- a/arch/s390/mm/hugetlbpage.c
+++ b/arch/s390/mm/hugetlbpage.c
@@ -68,7 +68,7 @@ void arch_release_hugepage(struct page *page)
ptep = (pte_t *) page[1].index;
if (!ptep)
return;
- pte_free(&init_mm, ptep);
+ page_table_free(&init_mm, (unsigned long *) ptep);
page[1].index = 0;
}
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index 30eb6d02ddb8..bb409332a484 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -38,19 +38,59 @@
#include <asm/tlbflush.h>
#include <asm/sections.h>
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-
pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((__aligned__(PAGE_SIZE)));
-char empty_zero_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
+unsigned long empty_zero_page, zero_page_mask;
EXPORT_SYMBOL(empty_zero_page);
+static unsigned long setup_zero_pages(void)
+{
+ struct cpuid cpu_id;
+ unsigned int order;
+ unsigned long size;
+ struct page *page;
+ int i;
+
+ get_cpu_id(&cpu_id);
+ switch (cpu_id.machine) {
+ case 0x9672: /* g5 */
+ case 0x2064: /* z900 */
+ case 0x2066: /* z900 */
+ case 0x2084: /* z990 */
+ case 0x2086: /* z990 */
+ case 0x2094: /* z9-109 */
+ case 0x2096: /* z9-109 */
+ order = 0;
+ break;
+ case 0x2097: /* z10 */
+ case 0x2098: /* z10 */
+ default:
+ order = 2;
+ break;
+ }
+
+ empty_zero_page = __get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
+ if (!empty_zero_page)
+ panic("Out of memory in setup_zero_pages");
+
+ page = virt_to_page((void *) empty_zero_page);
+ split_page(page, order);
+ for (i = 1 << order; i > 0; i--) {
+ SetPageReserved(page);
+ page++;
+ }
+
+ size = PAGE_SIZE << order;
+ zero_page_mask = (size - 1) & PAGE_MASK;
+
+ return 1UL << order;
+}
+
/*
* paging_init() sets up the page tables
*/
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 +112,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);
@@ -84,6 +124,7 @@ void __init paging_init(void)
#endif
max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
free_area_init_nodes(max_zone_pfns);
+ fault_init();
}
void __init mem_init(void)
@@ -93,14 +134,12 @@ void __init mem_init(void)
max_mapnr = num_physpages = max_low_pfn;
high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
- /* clear the zero-page */
- memset(empty_zero_page, 0, PAGE_SIZE);
-
/* Setup guest page hinting */
cmma_init();
/* this will put all low memory onto the freelists */
totalram_pages += free_all_bootmem();
+ totalram_pages -= setup_zero_pages(); /* Setup zeroed pages. */
reservedpages = 0;
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/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index 8d999249d357..0c719c61972e 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -15,6 +15,7 @@
#include <linux/spinlock.h>
#include <linux/module.h>
#include <linux/quicklist.h>
+#include <linux/rcupdate.h>
#include <asm/system.h>
#include <asm/pgtable.h>
@@ -23,6 +24,67 @@
#include <asm/tlbflush.h>
#include <asm/mmu_context.h>
+struct rcu_table_freelist {
+ struct rcu_head rcu;
+ struct mm_struct *mm;
+ unsigned int pgt_index;
+ unsigned int crst_index;
+ unsigned long *table[0];
+};
+
+#define RCU_FREELIST_SIZE \
+ ((PAGE_SIZE - sizeof(struct rcu_table_freelist)) \
+ / sizeof(unsigned long))
+
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
+static DEFINE_PER_CPU(struct rcu_table_freelist *, rcu_table_freelist);
+
+static void __page_table_free(struct mm_struct *mm, unsigned long *table);
+static void __crst_table_free(struct mm_struct *mm, unsigned long *table);
+
+static struct rcu_table_freelist *rcu_table_freelist_get(struct mm_struct *mm)
+{
+ struct rcu_table_freelist **batchp = &__get_cpu_var(rcu_table_freelist);
+ struct rcu_table_freelist *batch = *batchp;
+
+ if (batch)
+ return batch;
+ batch = (struct rcu_table_freelist *) __get_free_page(GFP_ATOMIC);
+ if (batch) {
+ batch->mm = mm;
+ batch->pgt_index = 0;
+ batch->crst_index = RCU_FREELIST_SIZE;
+ *batchp = batch;
+ }
+ return batch;
+}
+
+static void rcu_table_freelist_callback(struct rcu_head *head)
+{
+ struct rcu_table_freelist *batch =
+ container_of(head, struct rcu_table_freelist, rcu);
+
+ while (batch->pgt_index > 0)
+ __page_table_free(batch->mm, batch->table[--batch->pgt_index]);
+ while (batch->crst_index < RCU_FREELIST_SIZE)
+ __crst_table_free(batch->mm, batch->table[batch->crst_index++]);
+ free_page((unsigned long) batch);
+}
+
+void rcu_table_freelist_finish(void)
+{
+ struct rcu_table_freelist *batch = __get_cpu_var(rcu_table_freelist);
+
+ if (!batch)
+ return;
+ call_rcu(&batch->rcu, rcu_table_freelist_callback);
+ __get_cpu_var(rcu_table_freelist) = NULL;
+}
+
+static void smp_sync(void *arg)
+{
+}
+
#ifndef CONFIG_64BIT
#define ALLOC_ORDER 1
#define TABLES_PER_PAGE 4
@@ -78,25 +140,55 @@ unsigned long *crst_table_alloc(struct mm_struct *mm, int noexec)
}
page->index = page_to_phys(shadow);
}
- spin_lock(&mm->context.list_lock);
+ spin_lock_bh(&mm->context.list_lock);
list_add(&page->lru, &mm->context.crst_list);
- spin_unlock(&mm->context.list_lock);
+ spin_unlock_bh(&mm->context.list_lock);
return (unsigned long *) page_to_phys(page);
}
-void crst_table_free(struct mm_struct *mm, unsigned long *table)
+static void __crst_table_free(struct mm_struct *mm, unsigned long *table)
{
unsigned long *shadow = get_shadow_table(table);
- struct page *page = virt_to_page(table);
- spin_lock(&mm->context.list_lock);
- list_del(&page->lru);
- spin_unlock(&mm->context.list_lock);
if (shadow)
free_pages((unsigned long) shadow, ALLOC_ORDER);
free_pages((unsigned long) table, ALLOC_ORDER);
}
+void crst_table_free(struct mm_struct *mm, unsigned long *table)
+{
+ struct page *page = virt_to_page(table);
+
+ spin_lock_bh(&mm->context.list_lock);
+ list_del(&page->lru);
+ spin_unlock_bh(&mm->context.list_lock);
+ __crst_table_free(mm, table);
+}
+
+void crst_table_free_rcu(struct mm_struct *mm, unsigned long *table)
+{
+ struct rcu_table_freelist *batch;
+ struct page *page = virt_to_page(table);
+
+ spin_lock_bh(&mm->context.list_lock);
+ list_del(&page->lru);
+ spin_unlock_bh(&mm->context.list_lock);
+ if (atomic_read(&mm->mm_users) < 2 &&
+ cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) {
+ __crst_table_free(mm, table);
+ return;
+ }
+ batch = rcu_table_freelist_get(mm);
+ if (!batch) {
+ smp_call_function(smp_sync, NULL, 1);
+ __crst_table_free(mm, table);
+ return;
+ }
+ batch->table[--batch->crst_index] = table;
+ if (batch->pgt_index >= batch->crst_index)
+ rcu_table_freelist_finish();
+}
+
#ifdef CONFIG_64BIT
int crst_table_upgrade(struct mm_struct *mm, unsigned long limit)
{
@@ -108,7 +200,7 @@ repeat:
table = crst_table_alloc(mm, mm->context.noexec);
if (!table)
return -ENOMEM;
- spin_lock(&mm->page_table_lock);
+ spin_lock_bh(&mm->page_table_lock);
if (mm->context.asce_limit < limit) {
pgd = (unsigned long *) mm->pgd;
if (mm->context.asce_limit <= (1UL << 31)) {
@@ -130,7 +222,7 @@ repeat:
mm->task_size = mm->context.asce_limit;
table = NULL;
}
- spin_unlock(&mm->page_table_lock);
+ spin_unlock_bh(&mm->page_table_lock);
if (table)
crst_table_free(mm, table);
if (mm->context.asce_limit < limit)
@@ -182,7 +274,7 @@ unsigned long *page_table_alloc(struct mm_struct *mm)
unsigned long bits;
bits = (mm->context.noexec || mm->context.has_pgste) ? 3UL : 1UL;
- spin_lock(&mm->context.list_lock);
+ spin_lock_bh(&mm->context.list_lock);
page = NULL;
if (!list_empty(&mm->context.pgtable_list)) {
page = list_first_entry(&mm->context.pgtable_list,
@@ -191,7 +283,7 @@ unsigned long *page_table_alloc(struct mm_struct *mm)
page = NULL;
}
if (!page) {
- spin_unlock(&mm->context.list_lock);
+ spin_unlock_bh(&mm->context.list_lock);
page = alloc_page(GFP_KERNEL|__GFP_REPEAT);
if (!page)
return NULL;
@@ -202,7 +294,7 @@ unsigned long *page_table_alloc(struct mm_struct *mm)
clear_table_pgstes(table);
else
clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE);
- spin_lock(&mm->context.list_lock);
+ spin_lock_bh(&mm->context.list_lock);
list_add(&page->lru, &mm->context.pgtable_list);
}
table = (unsigned long *) page_to_phys(page);
@@ -213,10 +305,25 @@ unsigned long *page_table_alloc(struct mm_struct *mm)
page->flags |= bits;
if ((page->flags & FRAG_MASK) == ((1UL << TABLES_PER_PAGE) - 1))
list_move_tail(&page->lru, &mm->context.pgtable_list);
- spin_unlock(&mm->context.list_lock);
+ spin_unlock_bh(&mm->context.list_lock);
return table;
}
+static void __page_table_free(struct mm_struct *mm, unsigned long *table)
+{
+ struct page *page;
+ unsigned long bits;
+
+ bits = ((unsigned long) table) & 15;
+ table = (unsigned long *)(((unsigned long) table) ^ bits);
+ page = pfn_to_page(__pa(table) >> PAGE_SHIFT);
+ page->flags ^= bits;
+ if (!(page->flags & FRAG_MASK)) {
+ pgtable_page_dtor(page);
+ __free_page(page);
+ }
+}
+
void page_table_free(struct mm_struct *mm, unsigned long *table)
{
struct page *page;
@@ -225,7 +332,7 @@ void page_table_free(struct mm_struct *mm, unsigned long *table)
bits = (mm->context.noexec || mm->context.has_pgste) ? 3UL : 1UL;
bits <<= (__pa(table) & (PAGE_SIZE - 1)) / 256 / sizeof(unsigned long);
page = pfn_to_page(__pa(table) >> PAGE_SHIFT);
- spin_lock(&mm->context.list_lock);
+ spin_lock_bh(&mm->context.list_lock);
page->flags ^= bits;
if (page->flags & FRAG_MASK) {
/* Page now has some free pgtable fragments. */
@@ -234,18 +341,48 @@ void page_table_free(struct mm_struct *mm, unsigned long *table)
} else
/* All fragments of the 4K page have been freed. */
list_del(&page->lru);
- spin_unlock(&mm->context.list_lock);
+ spin_unlock_bh(&mm->context.list_lock);
if (page) {
pgtable_page_dtor(page);
__free_page(page);
}
}
+void page_table_free_rcu(struct mm_struct *mm, unsigned long *table)
+{
+ struct rcu_table_freelist *batch;
+ struct page *page;
+ unsigned long bits;
+
+ if (atomic_read(&mm->mm_users) < 2 &&
+ cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) {
+ page_table_free(mm, table);
+ return;
+ }
+ batch = rcu_table_freelist_get(mm);
+ if (!batch) {
+ smp_call_function(smp_sync, NULL, 1);
+ page_table_free(mm, table);
+ return;
+ }
+ bits = (mm->context.noexec || mm->context.has_pgste) ? 3UL : 1UL;
+ bits <<= (__pa(table) & (PAGE_SIZE - 1)) / 256 / sizeof(unsigned long);
+ page = pfn_to_page(__pa(table) >> PAGE_SHIFT);
+ spin_lock_bh(&mm->context.list_lock);
+ /* Delayed freeing with rcu prevents reuse of pgtable fragments */
+ list_del_init(&page->lru);
+ spin_unlock_bh(&mm->context.list_lock);
+ table = (unsigned long *)(((unsigned long) table) | bits);
+ batch->table[batch->pgt_index++] = table;
+ if (batch->pgt_index >= batch->crst_index)
+ rcu_table_freelist_finish();
+}
+
void disable_noexec(struct mm_struct *mm, struct task_struct *tsk)
{
struct page *page;
- spin_lock(&mm->context.list_lock);
+ spin_lock_bh(&mm->context.list_lock);
/* Free shadow region and segment tables. */
list_for_each_entry(page, &mm->context.crst_list, lru)
if (page->index) {
@@ -255,7 +392,7 @@ void disable_noexec(struct mm_struct *mm, struct task_struct *tsk)
/* "Free" second halves of page tables. */
list_for_each_entry(page, &mm->context.pgtable_list, lru)
page->flags &= ~SECOND_HALVES;
- spin_unlock(&mm->context.list_lock);
+ spin_unlock_bh(&mm->context.list_lock);
mm->context.noexec = 0;
update_mm(mm, tsk);
}
@@ -312,6 +449,8 @@ int s390_enable_sie(void)
tsk->mm = tsk->active_mm = mm;
preempt_disable();
update_mm(mm, tsk);
+ atomic_inc(&mm->context.attach_count);
+ atomic_dec(&old_mm->context.attach_count);
cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
preempt_enable();
task_unlock(tsk);
diff --git a/arch/score/Kconfig b/arch/score/Kconfig
index be4a15584751..4293fdcb5398 100644
--- a/arch/score/Kconfig
+++ b/arch/score/Kconfig
@@ -1,8 +1,3 @@
-# For a description of the syntax of this configuration file,
-# see Documentation/kbuild/kconfig-language.txt.
-
-mainmenu "Linux/SCORE Kernel Configuration"
-
menu "Machine selection"
choice
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/score/include/asm/pgtable.h b/arch/score/include/asm/pgtable.h
index ccf38f06c57d..2fd469807683 100644
--- a/arch/score/include/asm/pgtable.h
+++ b/arch/score/include/asm/pgtable.h
@@ -88,10 +88,7 @@ static inline void pmd_clear(pmd_t *pmdp)
#define pte_offset_map(dir, address) \
((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address))
-#define pte_offset_map_nested(dir, address) \
- ((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address))
#define pte_unmap(pte) ((void)(pte))
-#define pte_unmap_nested(pte) ((void)(pte))
/*
* Bits 9(_PAGE_PRESENT) and 10(_PAGE_FILE)are taken,
diff --git a/arch/score/kernel/ptrace.c b/arch/score/kernel/ptrace.c
index 174c6422b096..55836188b217 100644
--- a/arch/score/kernel/ptrace.c
+++ b/arch/score/kernel/ptrace.c
@@ -325,7 +325,8 @@ void ptrace_disable(struct task_struct *child)
}
long
-arch_ptrace(struct task_struct *child, long request, long addr, long data)
+arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int ret;
unsigned long __user *datap = (void __user *)data;
@@ -335,14 +336,14 @@ arch_ptrace(struct task_struct *child, long request, long addr, long data)
ret = copy_regset_to_user(child, &user_score_native_view,
REGSET_GENERAL,
0, sizeof(struct pt_regs),
- (void __user *)datap);
+ datap);
break;
case PTRACE_SETREGS:
ret = copy_regset_from_user(child, &user_score_native_view,
REGSET_GENERAL,
0, sizeof(struct pt_regs),
- (const void __user *)datap);
+ datap);
break;
default:
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 33990fa95af0..5c075f562eba 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -1,10 +1,3 @@
-#
-# For a description of the syntax of this configuration file,
-# see Documentation/kbuild/kconfig-language.txt.
-#
-
-mainmenu "Linux/SuperH Kernel Configuration"
-
config SUPERH
def_bool y
select EMBEDDED
@@ -16,6 +9,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,8 +17,12 @@ config SUPERH
select HAVE_KERNEL_LZMA
select HAVE_KERNEL_LZO
select HAVE_SYSCALL_TRACEPOINTS
+ select HAVE_REGS_AND_STACK_ACCESS_API
+ select HAVE_GENERIC_HARDIRQS
+ select HAVE_SPARSE_IRQ
select RTC_LIB
select GENERIC_ATOMIC64
+ select GENERIC_HARDIRQS_NO_DEPRECATED
help
The SuperH is a RISC processor targeted for use in embedded systems
and consumer electronics; it was also used in the Sega Dreamcast
@@ -45,8 +43,9 @@ 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
+ select SPARSE_IRQ
config SUPERH64
def_bool ARCH = "sh64"
@@ -76,19 +75,9 @@ config GENERIC_FIND_NEXT_BIT
config GENERIC_HWEIGHT
def_bool y
-config GENERIC_HARDIRQS
- def_bool y
-
-config GENERIC_HARDIRQS_NO__DO_IRQ
- def_bool y
-
config IRQ_PER_CPU
def_bool y
-config SPARSE_IRQ
- def_bool y
- depends on SUPERH32
-
config GENERIC_GPIO
def_bool n
@@ -249,6 +238,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 +459,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 +564,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 +733,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-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c
index 3da116f47f01..07ea908c510d 100644
--- a/arch/sh/boards/mach-ap325rxa/setup.c
+++ b/arch/sh/boards/mach-ap325rxa/setup.c
@@ -176,6 +176,21 @@ static void ap320_wvga_power_off(void *board_data)
__raw_writew(0, FPGA_LCDREG);
}
+const static struct fb_videomode ap325rxa_lcdc_modes[] = {
+ {
+ .name = "LB070WV1",
+ .xres = 800,
+ .yres = 480,
+ .left_margin = 32,
+ .right_margin = 160,
+ .hsync_len = 8,
+ .upper_margin = 63,
+ .lower_margin = 80,
+ .vsync_len = 1,
+ .sync = 0, /* hsync and vsync are active low */
+ },
+};
+
static struct sh_mobile_lcdc_info lcdc_info = {
.clock_source = LCDC_CLK_EXTERNAL,
.ch[0] = {
@@ -183,18 +198,8 @@ static struct sh_mobile_lcdc_info lcdc_info = {
.bpp = 16,
.interface_type = RGB18,
.clock_divider = 1,
- .lcd_cfg = {
- .name = "LB070WV1",
- .xres = 800,
- .yres = 480,
- .left_margin = 32,
- .right_margin = 160,
- .hsync_len = 8,
- .upper_margin = 63,
- .lower_margin = 80,
- .vsync_len = 1,
- .sync = 0, /* hsync and vsync are active low */
- },
+ .lcd_cfg = ap325rxa_lcdc_modes,
+ .num_cfg = ARRAY_SIZE(ap325rxa_lcdc_modes),
.lcd_size_cfg = { /* 7.0 inch */
.width = 152,
.height = 91,
@@ -481,7 +486,6 @@ static struct soc_camera_link ov7725_link = {
.power = ov7725_power,
.board_info = &ap325rxa_i2c_camera[0],
.i2c_adapter_id = 0,
- .module_name = "ov772x",
.priv = &ov7725_info,
};
diff --git a/arch/sh/boards/mach-cayman/irq.c b/arch/sh/boards/mach-cayman/irq.c
index 1394b078db36..d7ac5af9d102 100644
--- a/arch/sh/boards/mach-cayman/irq.c
+++ b/arch/sh/boards/mach-cayman/irq.c
@@ -55,8 +55,9 @@ static struct irqaction cayman_action_pci2 = {
.flags = IRQF_DISABLED,
};
-static void enable_cayman_irq(unsigned int irq)
+static void enable_cayman_irq(struct irq_data *data)
{
+ unsigned int irq = data->irq;
unsigned long flags;
unsigned long mask;
unsigned int reg;
@@ -72,8 +73,9 @@ static void enable_cayman_irq(unsigned int irq)
local_irq_restore(flags);
}
-void disable_cayman_irq(unsigned int irq)
+static void disable_cayman_irq(struct irq_data *data)
{
+ unsigned int irq = data->irq;
unsigned long flags;
unsigned long mask;
unsigned int reg;
@@ -89,16 +91,10 @@ void disable_cayman_irq(unsigned int irq)
local_irq_restore(flags);
}
-static void ack_cayman_irq(unsigned int irq)
-{
- disable_cayman_irq(irq);
-}
-
struct irq_chip cayman_irq_type = {
.name = "Cayman-IRQ",
- .unmask = enable_cayman_irq,
- .mask = disable_cayman_irq,
- .mask_ack = ack_cayman_irq,
+ .irq_unmask = enable_cayman_irq,
+ .irq_mask = disable_cayman_irq,
};
int cayman_irq_demux(int evt)
diff --git a/arch/sh/boards/mach-dreamcast/irq.c b/arch/sh/boards/mach-dreamcast/irq.c
index d932667410ab..72e7ac9549da 100644
--- a/arch/sh/boards/mach-dreamcast/irq.c
+++ b/arch/sh/boards/mach-dreamcast/irq.c
@@ -60,8 +60,9 @@
*/
/* Disable the hardware event by masking its bit in its EMR */
-static inline void disable_systemasic_irq(unsigned int irq)
+static inline void disable_systemasic_irq(struct irq_data *data)
{
+ unsigned int irq = data->irq;
__u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
__u32 mask;
@@ -71,8 +72,9 @@ static inline void disable_systemasic_irq(unsigned int irq)
}
/* Enable the hardware event by setting its bit in its EMR */
-static inline void enable_systemasic_irq(unsigned int irq)
+static inline void enable_systemasic_irq(struct irq_data *data)
{
+ unsigned int irq = data->irq;
__u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
__u32 mask;
@@ -82,18 +84,19 @@ static inline void enable_systemasic_irq(unsigned int irq)
}
/* Acknowledge a hardware event by writing its bit back to its ESR */
-static void mask_ack_systemasic_irq(unsigned int irq)
+static void mask_ack_systemasic_irq(struct irq_data *data)
{
+ unsigned int irq = data->irq;
__u32 esr = ESR_BASE + (LEVEL(irq) << 2);
- disable_systemasic_irq(irq);
+ disable_systemasic_irq(data);
outl((1 << EVENT_BIT(irq)), esr);
}
struct irq_chip systemasic_int = {
.name = "System ASIC",
- .mask = disable_systemasic_irq,
- .mask_ack = mask_ack_systemasic_irq,
- .unmask = enable_systemasic_irq,
+ .irq_mask = disable_systemasic_irq,
+ .irq_mask_ack = mask_ack_systemasic_irq,
+ .irq_unmask = enable_systemasic_irq,
};
/*
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 1d7b495a7db4..2eaeb9e59585 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -231,14 +231,41 @@ static struct platform_device usb1_common_device = {
};
/* LCDC */
+const static struct fb_videomode ecovec_lcd_modes[] = {
+ {
+ .name = "Panel",
+ .xres = 800,
+ .yres = 480,
+ .left_margin = 220,
+ .right_margin = 110,
+ .hsync_len = 70,
+ .upper_margin = 20,
+ .lower_margin = 5,
+ .vsync_len = 5,
+ .sync = 0, /* hsync and vsync are active low */
+ },
+};
+
+const static struct fb_videomode ecovec_dvi_modes[] = {
+ {
+ .name = "DVI",
+ .xres = 1280,
+ .yres = 720,
+ .left_margin = 220,
+ .right_margin = 110,
+ .hsync_len = 40,
+ .upper_margin = 20,
+ .lower_margin = 5,
+ .vsync_len = 5,
+ .sync = 0, /* hsync and vsync are active low */
+ },
+};
+
static struct sh_mobile_lcdc_info lcdc_info = {
.ch[0] = {
.interface_type = RGB18,
.chan = LCDC_CHAN_MAINLCD,
.bpp = 16,
- .lcd_cfg = {
- .sync = 0, /* hsync and vsync are active low */
- },
.lcd_size_cfg = { /* 7.0 inch */
.width = 152,
.height = 91,
@@ -620,7 +647,6 @@ static struct soc_camera_link tw9910_link = {
.bus_id = 1,
.power = tw9910_power,
.board_info = &i2c_camera[0],
- .module_name = "tw9910",
.priv = &tw9910_info,
};
@@ -644,7 +670,6 @@ static struct soc_camera_link mt9t112_link1 = {
.power = mt9t112_power1,
.bus_id = 0,
.board_info = &i2c_camera[1],
- .module_name = "mt9t112",
.priv = &mt9t112_info1,
};
@@ -667,7 +692,6 @@ static struct soc_camera_link mt9t112_link2 = {
.power = mt9t112_power2,
.bus_id = 1,
.board_info = &i2c_camera[2],
- .module_name = "mt9t112",
.priv = &mt9t112_info2,
};
@@ -793,7 +817,6 @@ static struct sh_vou_pdata sh_vou_pdata = {
.flags = SH_VOU_HSYNC_LOW | SH_VOU_VSYNC_LOW,
.board_info = &ak8813,
.i2c_adap = 0,
- .module_name = "ak881x",
};
static struct resource sh_vou_resources[] = {
@@ -1079,33 +1102,18 @@ static int __init arch_setup(void)
if (gpio_get_value(GPIO_PTE6)) {
/* DVI */
lcdc_info.clock_source = LCDC_CLK_EXTERNAL;
- lcdc_info.ch[0].clock_divider = 1,
- lcdc_info.ch[0].lcd_cfg.name = "DVI";
- lcdc_info.ch[0].lcd_cfg.xres = 1280;
- lcdc_info.ch[0].lcd_cfg.yres = 720;
- lcdc_info.ch[0].lcd_cfg.left_margin = 220;
- lcdc_info.ch[0].lcd_cfg.right_margin = 110;
- lcdc_info.ch[0].lcd_cfg.hsync_len = 40;
- lcdc_info.ch[0].lcd_cfg.upper_margin = 20;
- lcdc_info.ch[0].lcd_cfg.lower_margin = 5;
- lcdc_info.ch[0].lcd_cfg.vsync_len = 5;
+ lcdc_info.ch[0].clock_divider = 1;
+ lcdc_info.ch[0].lcd_cfg = ecovec_dvi_modes;
+ lcdc_info.ch[0].num_cfg = ARRAY_SIZE(ecovec_dvi_modes);
gpio_set_value(GPIO_PTA2, 1);
gpio_set_value(GPIO_PTU1, 1);
} else {
/* Panel */
-
lcdc_info.clock_source = LCDC_CLK_PERIPHERAL;
- lcdc_info.ch[0].clock_divider = 2,
- lcdc_info.ch[0].lcd_cfg.name = "Panel";
- lcdc_info.ch[0].lcd_cfg.xres = 800;
- lcdc_info.ch[0].lcd_cfg.yres = 480;
- lcdc_info.ch[0].lcd_cfg.left_margin = 220;
- lcdc_info.ch[0].lcd_cfg.right_margin = 110;
- lcdc_info.ch[0].lcd_cfg.hsync_len = 70;
- lcdc_info.ch[0].lcd_cfg.upper_margin = 20;
- lcdc_info.ch[0].lcd_cfg.lower_margin = 5;
- lcdc_info.ch[0].lcd_cfg.vsync_len = 5;
+ lcdc_info.ch[0].clock_divider = 2;
+ lcdc_info.ch[0].lcd_cfg = ecovec_lcd_modes;
+ lcdc_info.ch[0].num_cfg = ARRAY_SIZE(ecovec_lcd_modes);
gpio_set_value(GPIO_PTR1, 1);
@@ -1248,14 +1256,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 +1281,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-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c
index 68994a163f6c..9b60eaabf8f3 100644
--- a/arch/sh/boards/mach-kfr2r09/setup.c
+++ b/arch/sh/boards/mach-kfr2r09/setup.c
@@ -126,6 +126,21 @@ static struct platform_device kfr2r09_sh_keysc_device = {
},
};
+const static struct fb_videomode kfr2r09_lcdc_modes[] = {
+ {
+ .name = "TX07D34VM0AAA",
+ .xres = 240,
+ .yres = 400,
+ .left_margin = 0,
+ .right_margin = 16,
+ .hsync_len = 8,
+ .upper_margin = 0,
+ .lower_margin = 1,
+ .vsync_len = 1,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ },
+};
+
static struct sh_mobile_lcdc_info kfr2r09_sh_lcdc_info = {
.clock_source = LCDC_CLK_BUS,
.ch[0] = {
@@ -134,18 +149,8 @@ static struct sh_mobile_lcdc_info kfr2r09_sh_lcdc_info = {
.interface_type = SYS18,
.clock_divider = 6,
.flags = LCDC_FLAGS_DWPOL,
- .lcd_cfg = {
- .name = "TX07D34VM0AAA",
- .xres = 240,
- .yres = 400,
- .left_margin = 0,
- .right_margin = 16,
- .hsync_len = 8,
- .upper_margin = 0,
- .lower_margin = 1,
- .vsync_len = 1,
- .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
- },
+ .lcd_cfg = kfr2r09_lcdc_modes,
+ .num_cfg = ARRAY_SIZE(kfr2r09_lcdc_modes),
.lcd_size_cfg = {
.width = 35,
.height = 58,
@@ -333,7 +338,6 @@ static struct soc_camera_link rj54n1_link = {
.power = camera_power,
.board_info = &kfr2r09_i2c_camera,
.i2c_adapter_id = 1,
- .module_name = "rj54n1cb0c",
.priv = &rj54n1_priv,
};
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-landisk/irq.c b/arch/sh/boards/mach-landisk/irq.c
index 96f38a4187d0..e79412a40490 100644
--- a/arch/sh/boards/mach-landisk/irq.c
+++ b/arch/sh/boards/mach-landisk/irq.c
@@ -18,25 +18,24 @@
#include <linux/io.h>
#include <mach-landisk/mach/iodata_landisk.h>
-static void disable_landisk_irq(unsigned int irq)
+static void disable_landisk_irq(struct irq_data *data)
{
- unsigned char mask = 0xff ^ (0x01 << (irq - 5));
+ unsigned char mask = 0xff ^ (0x01 << (data->irq - 5));
__raw_writeb(__raw_readb(PA_IMASK) & mask, PA_IMASK);
}
-static void enable_landisk_irq(unsigned int irq)
+static void enable_landisk_irq(struct irq_data *data)
{
- unsigned char value = (0x01 << (irq - 5));
+ unsigned char value = (0x01 << (data->irq - 5));
__raw_writeb(__raw_readb(PA_IMASK) | value, PA_IMASK);
}
static struct irq_chip landisk_irq_chip __read_mostly = {
.name = "LANDISK",
- .mask = disable_landisk_irq,
- .unmask = enable_landisk_irq,
- .mask_ack = disable_landisk_irq,
+ .irq_mask = disable_landisk_irq,
+ .irq_unmask = enable_landisk_irq,
};
/*
@@ -50,7 +49,7 @@ void __init init_landisk_IRQ(void)
disable_irq_nosync(i);
set_irq_chip_and_handler_name(i, &landisk_irq_chip,
handle_level_irq, "level");
- enable_landisk_irq(i);
+ enable_landisk_irq(irq_get_irq_data(i));
}
__raw_writeb(0x00, PA_PWRINT_CLR);
}
diff --git a/arch/sh/boards/mach-microdev/irq.c b/arch/sh/boards/mach-microdev/irq.c
index a26d16669aa2..c35001fd9032 100644
--- a/arch/sh/boards/mach-microdev/irq.c
+++ b/arch/sh/boards/mach-microdev/irq.c
@@ -65,19 +65,9 @@ static const struct {
# error Inconsistancy in defining the IRQ# for primary IDE!
#endif
-static void enable_microdev_irq(unsigned int irq);
-static void disable_microdev_irq(unsigned int irq);
-static void mask_and_ack_microdev(unsigned int);
-
-static struct irq_chip microdev_irq_type = {
- .name = "MicroDev-IRQ",
- .unmask = enable_microdev_irq,
- .mask = disable_microdev_irq,
- .ack = mask_and_ack_microdev,
-};
-
-static void disable_microdev_irq(unsigned int irq)
+static void disable_microdev_irq(struct irq_data *data)
{
+ unsigned int irq = data->irq;
unsigned int fpgaIrq;
if (irq >= NUM_EXTERNAL_IRQS)
@@ -91,8 +81,9 @@ static void disable_microdev_irq(unsigned int irq)
__raw_writel(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTDSB_REG);
}
-static void enable_microdev_irq(unsigned int irq)
+static void enable_microdev_irq(struct irq_data *data)
{
+ unsigned int irq = data->irq;
unsigned long priorityReg, priorities, pri;
unsigned int fpgaIrq;
@@ -116,17 +107,18 @@ static void enable_microdev_irq(unsigned int irq)
__raw_writel(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTENB_REG);
}
+static struct irq_chip microdev_irq_type = {
+ .name = "MicroDev-IRQ",
+ .irq_unmask = enable_microdev_irq,
+ .irq_mask = disable_microdev_irq,
+};
+
/* This function sets the desired irq handler to be a MicroDev type */
static void __init make_microdev_irq(unsigned int irq)
{
disable_irq_nosync(irq);
set_irq_chip_and_handler(irq, &microdev_irq_type, handle_level_irq);
- disable_microdev_irq(irq);
-}
-
-static void mask_and_ack_microdev(unsigned int irq)
-{
- disable_microdev_irq(irq);
+ disable_microdev_irq(irq_get_irq_data(irq));
}
extern void __init init_microdev_irq(void)
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index 662debe4ead2..c8acfec98695 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -213,51 +213,55 @@ static struct platform_device migor_nand_flash_device = {
}
};
+const static struct fb_videomode migor_lcd_modes[] = {
+ {
+#if defined(CONFIG_SH_MIGOR_RTA_WVGA)
+ .name = "LB070WV1",
+ .xres = 800,
+ .yres = 480,
+ .left_margin = 64,
+ .right_margin = 16,
+ .hsync_len = 120,
+ .sync = 0,
+#elif defined(CONFIG_SH_MIGOR_QVGA)
+ .name = "PH240320T",
+ .xres = 320,
+ .yres = 240,
+ .left_margin = 0,
+ .right_margin = 16,
+ .hsync_len = 8,
+ .sync = FB_SYNC_HOR_HIGH_ACT,
+#endif
+ .upper_margin = 1,
+ .lower_margin = 17,
+ .vsync_len = 2,
+ },
+};
+
static struct sh_mobile_lcdc_info sh_mobile_lcdc_info = {
-#ifdef CONFIG_SH_MIGOR_RTA_WVGA
+#if defined(CONFIG_SH_MIGOR_RTA_WVGA)
.clock_source = LCDC_CLK_BUS,
.ch[0] = {
.chan = LCDC_CHAN_MAINLCD,
.bpp = 16,
.interface_type = RGB16,
.clock_divider = 2,
- .lcd_cfg = {
- .name = "LB070WV1",
- .xres = 800,
- .yres = 480,
- .left_margin = 64,
- .right_margin = 16,
- .hsync_len = 120,
- .upper_margin = 1,
- .lower_margin = 17,
- .vsync_len = 2,
- .sync = 0,
- },
+ .lcd_cfg = migor_lcd_modes,
+ .num_cfg = ARRAY_SIZE(migor_lcd_modes),
.lcd_size_cfg = { /* 7.0 inch */
.width = 152,
.height = 91,
},
}
-#endif
-#ifdef CONFIG_SH_MIGOR_QVGA
+#elif defined(CONFIG_SH_MIGOR_QVGA)
.clock_source = LCDC_CLK_PERIPHERAL,
.ch[0] = {
.chan = LCDC_CHAN_MAINLCD,
.bpp = 16,
.interface_type = SYS16A,
.clock_divider = 10,
- .lcd_cfg = {
- .name = "PH240320T",
- .xres = 320,
- .yres = 240,
- .left_margin = 0,
- .right_margin = 16,
- .hsync_len = 8,
- .upper_margin = 1,
- .lower_margin = 17,
- .vsync_len = 2,
- .sync = FB_SYNC_HOR_HIGH_ACT,
- },
+ .lcd_cfg = migor_lcd_modes,
+ .num_cfg = ARRAY_SIZE(migor_lcd_modes),
.lcd_size_cfg = { /* 2.4 inch */
.width = 49,
.height = 37,
@@ -450,7 +454,6 @@ static struct soc_camera_link ov7725_link = {
.power = ov7725_power,
.board_info = &migor_i2c_camera[0],
.i2c_adapter_id = 0,
- .module_name = "ov772x",
.priv = &ov7725_info,
};
@@ -463,7 +466,6 @@ static struct soc_camera_link tw9910_link = {
.power = tw9910_power,
.board_info = &migor_i2c_camera[1],
.i2c_adapter_id = 0,
- .module_name = "tw9910",
.priv = &tw9910_info,
};
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-se/7206/irq.c b/arch/sh/boards/mach-se/7206/irq.c
index 8d82175d83ab..883b21eacaa6 100644
--- a/arch/sh/boards/mach-se/7206/irq.c
+++ b/arch/sh/boards/mach-se/7206/irq.c
@@ -25,8 +25,9 @@
#define INTC_IPR01 0xfffe0818
#define INTC_ICR1 0xfffe0802
-static void disable_se7206_irq(unsigned int irq)
+static void disable_se7206_irq(struct irq_data *data)
{
+ unsigned int irq = data->irq;
unsigned short val;
unsigned short mask = 0xffff ^ (0x0f << 4 * (3 - (IRQ0_IRQ - irq)));
unsigned short msk0,msk1;
@@ -55,8 +56,9 @@ static void disable_se7206_irq(unsigned int irq)
__raw_writew(msk1, INTMSK1);
}
-static void enable_se7206_irq(unsigned int irq)
+static void enable_se7206_irq(struct irq_data *data)
{
+ unsigned int irq = data->irq;
unsigned short val;
unsigned short value = (0x0001 << 4 * (3 - (IRQ0_IRQ - irq)));
unsigned short msk0,msk1;
@@ -86,13 +88,14 @@ static void enable_se7206_irq(unsigned int irq)
__raw_writew(msk1, INTMSK1);
}
-static void eoi_se7206_irq(unsigned int irq)
+static void eoi_se7206_irq(struct irq_data *data)
{
unsigned short sts0,sts1;
+ unsigned int irq = data->irq;
struct irq_desc *desc = irq_to_desc(irq);
if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- enable_se7206_irq(irq);
+ enable_se7206_irq(data);
/* FPGA isr clear */
sts0 = __raw_readw(INTSTS0);
sts1 = __raw_readw(INTSTS1);
@@ -115,10 +118,9 @@ static void eoi_se7206_irq(unsigned int irq)
static struct irq_chip se7206_irq_chip __read_mostly = {
.name = "SE7206-FPGA",
- .mask = disable_se7206_irq,
- .unmask = enable_se7206_irq,
- .mask_ack = disable_se7206_irq,
- .eoi = eoi_se7206_irq,
+ .irq_mask = disable_se7206_irq,
+ .irq_unmask = enable_se7206_irq,
+ .irq_eoi = eoi_se7206_irq,
};
static void make_se7206_irq(unsigned int irq)
@@ -126,7 +128,7 @@ static void make_se7206_irq(unsigned int irq)
disable_irq_nosync(irq);
set_irq_chip_and_handler_name(irq, &se7206_irq_chip,
handle_level_irq, "level");
- disable_se7206_irq(irq);
+ disable_se7206_irq(irq_get_irq_data(irq));
}
/*
diff --git a/arch/sh/boards/mach-se/7343/irq.c b/arch/sh/boards/mach-se/7343/irq.c
index d4305c26e9f7..76255a19417f 100644
--- a/arch/sh/boards/mach-se/7343/irq.c
+++ b/arch/sh/boards/mach-se/7343/irq.c
@@ -18,23 +18,22 @@
unsigned int se7343_fpga_irq[SE7343_FPGA_IRQ_NR] = { 0, };
-static void disable_se7343_irq(unsigned int irq)
+static void disable_se7343_irq(struct irq_data *data)
{
- unsigned int bit = (unsigned int)get_irq_chip_data(irq);
+ unsigned int bit = (unsigned int)irq_data_get_irq_chip_data(data);
__raw_writew(__raw_readw(PA_CPLD_IMSK) | 1 << bit, PA_CPLD_IMSK);
}
-static void enable_se7343_irq(unsigned int irq)
+static void enable_se7343_irq(struct irq_data *data)
{
- unsigned int bit = (unsigned int)get_irq_chip_data(irq);
+ unsigned int bit = (unsigned int)irq_data_get_irq_chip_data(data);
__raw_writew(__raw_readw(PA_CPLD_IMSK) & ~(1 << bit), PA_CPLD_IMSK);
}
static struct irq_chip se7343_irq_chip __read_mostly = {
- .name = "SE7343-FPGA",
- .mask = disable_se7343_irq,
- .unmask = enable_se7343_irq,
- .mask_ack = disable_se7343_irq,
+ .name = "SE7343-FPGA",
+ .irq_mask = disable_se7343_irq,
+ .irq_unmask = enable_se7343_irq,
};
static void se7343_irq_demux(unsigned int irq, struct irq_desc *desc)
diff --git a/arch/sh/boards/mach-se/7722/irq.c b/arch/sh/boards/mach-se/7722/irq.c
index 61605db04ee6..c013f95628ed 100644
--- a/arch/sh/boards/mach-se/7722/irq.c
+++ b/arch/sh/boards/mach-se/7722/irq.c
@@ -18,23 +18,22 @@
unsigned int se7722_fpga_irq[SE7722_FPGA_IRQ_NR] = { 0, };
-static void disable_se7722_irq(unsigned int irq)
+static void disable_se7722_irq(struct irq_data *data)
{
- unsigned int bit = (unsigned int)get_irq_chip_data(irq);
+ unsigned int bit = (unsigned int)irq_data_get_irq_chip_data(data);
__raw_writew(__raw_readw(IRQ01_MASK) | 1 << bit, IRQ01_MASK);
}
-static void enable_se7722_irq(unsigned int irq)
+static void enable_se7722_irq(struct irq_data *data)
{
- unsigned int bit = (unsigned int)get_irq_chip_data(irq);
+ unsigned int bit = (unsigned int)irq_data_get_irq_chip_data(data);
__raw_writew(__raw_readw(IRQ01_MASK) & ~(1 << bit), IRQ01_MASK);
}
static struct irq_chip se7722_irq_chip __read_mostly = {
- .name = "SE7722-FPGA",
- .mask = disable_se7722_irq,
- .unmask = enable_se7722_irq,
- .mask_ack = disable_se7722_irq,
+ .name = "SE7722-FPGA",
+ .irq_mask = disable_se7722_irq,
+ .irq_unmask = enable_se7722_irq,
};
static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc)
diff --git a/arch/sh/boards/mach-se/7724/irq.c b/arch/sh/boards/mach-se/7724/irq.c
index 0942be2daef6..5bd87c22b65b 100644
--- a/arch/sh/boards/mach-se/7724/irq.c
+++ b/arch/sh/boards/mach-se/7724/irq.c
@@ -68,25 +68,26 @@ static struct fpga_irq get_fpga_irq(unsigned int irq)
return set;
}
-static void disable_se7724_irq(unsigned int irq)
+static void disable_se7724_irq(struct irq_data *data)
{
+ unsigned int irq = data->irq;
struct fpga_irq set = get_fpga_irq(fpga2irq(irq));
unsigned int bit = irq - set.base;
__raw_writew(__raw_readw(set.mraddr) | 0x0001 << bit, set.mraddr);
}
-static void enable_se7724_irq(unsigned int irq)
+static void enable_se7724_irq(struct irq_data *data)
{
+ unsigned int irq = data->irq;
struct fpga_irq set = get_fpga_irq(fpga2irq(irq));
unsigned int bit = irq - set.base;
__raw_writew(__raw_readw(set.mraddr) & ~(0x0001 << bit), set.mraddr);
}
static struct irq_chip se7724_irq_chip __read_mostly = {
- .name = "SE7724-FPGA",
- .mask = disable_se7724_irq,
- .unmask = enable_se7724_irq,
- .mask_ack = disable_se7724_irq,
+ .name = "SE7724-FPGA",
+ .irq_mask = disable_se7724_irq,
+ .irq_unmask = enable_se7724_irq,
};
static void se7724_irq_demux(unsigned int irq, struct irq_desc *desc)
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index 552ebd9ba82b..c31d228fdfc6 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -144,16 +144,42 @@ static struct platform_device nor_flash_device = {
};
/* LCDC */
+const static struct fb_videomode lcdc_720p_modes[] = {
+ {
+ .name = "LB070WV1",
+ .sync = 0, /* hsync and vsync are active low */
+ .xres = 1280,
+ .yres = 720,
+ .left_margin = 220,
+ .right_margin = 110,
+ .hsync_len = 40,
+ .upper_margin = 20,
+ .lower_margin = 5,
+ .vsync_len = 5,
+ },
+};
+
+const static struct fb_videomode lcdc_vga_modes[] = {
+ {
+ .name = "LB070WV1",
+ .sync = 0, /* hsync and vsync are active low */
+ .xres = 640,
+ .yres = 480,
+ .left_margin = 105,
+ .right_margin = 50,
+ .hsync_len = 96,
+ .upper_margin = 33,
+ .lower_margin = 10,
+ .vsync_len = 2,
+ },
+};
+
static struct sh_mobile_lcdc_info lcdc_info = {
.clock_source = LCDC_CLK_EXTERNAL,
.ch[0] = {
.chan = LCDC_CHAN_MAINLCD,
.bpp = 16,
.clock_divider = 1,
- .lcd_cfg = {
- .name = "LB070WV1",
- .sync = 0, /* hsync and vsync are active low */
- },
.lcd_size_cfg = { /* 7.0 inch */
.width = 152,
.height = 91,
@@ -550,7 +576,6 @@ static struct sh_vou_pdata sh_vou_pdata = {
.flags = SH_VOU_HSYNC_LOW | SH_VOU_VSYNC_LOW,
.board_info = &ak8813,
.i2c_adap = 0,
- .module_name = "ak881x",
};
static struct resource sh_vou_resources[] = {
@@ -909,24 +934,12 @@ static int __init devices_setup(void)
if (sw & SW41_B) {
/* 720p */
- lcdc_info.ch[0].lcd_cfg.xres = 1280;
- lcdc_info.ch[0].lcd_cfg.yres = 720;
- lcdc_info.ch[0].lcd_cfg.left_margin = 220;
- lcdc_info.ch[0].lcd_cfg.right_margin = 110;
- lcdc_info.ch[0].lcd_cfg.hsync_len = 40;
- lcdc_info.ch[0].lcd_cfg.upper_margin = 20;
- lcdc_info.ch[0].lcd_cfg.lower_margin = 5;
- lcdc_info.ch[0].lcd_cfg.vsync_len = 5;
+ lcdc_info.ch[0].lcd_cfg = lcdc_720p_modes;
+ lcdc_info.ch[0].num_cfg = ARRAY_SIZE(lcdc_720p_modes);
} else {
/* VGA */
- lcdc_info.ch[0].lcd_cfg.xres = 640;
- lcdc_info.ch[0].lcd_cfg.yres = 480;
- lcdc_info.ch[0].lcd_cfg.left_margin = 105;
- lcdc_info.ch[0].lcd_cfg.right_margin = 50;
- lcdc_info.ch[0].lcd_cfg.hsync_len = 96;
- lcdc_info.ch[0].lcd_cfg.upper_margin = 33;
- lcdc_info.ch[0].lcd_cfg.lower_margin = 10;
- lcdc_info.ch[0].lcd_cfg.vsync_len = 2;
+ lcdc_info.ch[0].lcd_cfg = lcdc_vga_modes;
+ lcdc_info.ch[0].num_cfg = ARRAY_SIZE(lcdc_vga_modes);
}
if (sw & SW41_A) {
diff --git a/arch/sh/boards/mach-systemh/irq.c b/arch/sh/boards/mach-systemh/irq.c
index 523aea5dc94e..e5ee13adeff4 100644
--- a/arch/sh/boards/mach-systemh/irq.c
+++ b/arch/sh/boards/mach-systemh/irq.c
@@ -23,54 +23,39 @@
static unsigned long *systemh_irq_mask_register = (unsigned long *)0xB3F10004;
static unsigned long *systemh_irq_request_register = (unsigned long *)0xB3F10000;
-/* forward declaration */
-static void enable_systemh_irq(unsigned int irq);
-static void disable_systemh_irq(unsigned int irq);
-static void mask_and_ack_systemh(unsigned int);
-
-static struct irq_chip systemh_irq_type = {
- .name = " SystemH Register",
- .unmask = enable_systemh_irq,
- .mask = disable_systemh_irq,
- .ack = mask_and_ack_systemh,
-};
-
-static void disable_systemh_irq(unsigned int irq)
+static void disable_systemh_irq(struct irq_data *data)
{
- if (systemh_irq_mask_register) {
- unsigned long val, mask = 0x01 << 1;
+ unsigned long val, mask = 0x01 << 1;
- /* Clear the "irq"th bit in the mask and set it in the request */
- val = __raw_readl((unsigned long)systemh_irq_mask_register);
- val &= ~mask;
- __raw_writel(val, (unsigned long)systemh_irq_mask_register);
+ /* Clear the "irq"th bit in the mask and set it in the request */
+ val = __raw_readl((unsigned long)systemh_irq_mask_register);
+ val &= ~mask;
+ __raw_writel(val, (unsigned long)systemh_irq_mask_register);
- val = __raw_readl((unsigned long)systemh_irq_request_register);
- val |= mask;
- __raw_writel(val, (unsigned long)systemh_irq_request_register);
- }
+ val = __raw_readl((unsigned long)systemh_irq_request_register);
+ val |= mask;
+ __raw_writel(val, (unsigned long)systemh_irq_request_register);
}
-static void enable_systemh_irq(unsigned int irq)
+static void enable_systemh_irq(struct irq_data *data)
{
- if (systemh_irq_mask_register) {
- unsigned long val, mask = 0x01 << 1;
+ unsigned long val, mask = 0x01 << 1;
- /* Set "irq"th bit in the mask register */
- val = __raw_readl((unsigned long)systemh_irq_mask_register);
- val |= mask;
- __raw_writel(val, (unsigned long)systemh_irq_mask_register);
- }
+ /* Set "irq"th bit in the mask register */
+ val = __raw_readl((unsigned long)systemh_irq_mask_register);
+ val |= mask;
+ __raw_writel(val, (unsigned long)systemh_irq_mask_register);
}
-static void mask_and_ack_systemh(unsigned int irq)
-{
- disable_systemh_irq(irq);
-}
+static struct irq_chip systemh_irq_type = {
+ .name = "SystemH Register",
+ .irq_unmask = enable_systemh_irq,
+ .irq_mask = disable_systemh_irq,
+};
void make_systemh_irq(unsigned int irq)
{
disable_irq_nosync(irq);
set_irq_chip_and_handler(irq, &systemh_irq_type, handle_level_irq);
- disable_systemh_irq(irq);
+ disable_systemh_irq(irq_get_irq_data(irq));
}
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..239e74066253
--- /dev/null
+++ b/arch/sh/boards/mach-x3proto/gpio.c
@@ -0,0 +1,136 @@
+/*
+ * 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_data *data = irq_get_irq_data(irq);
+ struct irq_chip *chip = irq_data_get_irq_chip(data);
+ unsigned long mask;
+ int pin;
+
+ chip->irq_mask_ack(data);
+
+ mask = __raw_readw(KEYDETR);
+
+ for_each_set_bit(pin, &mask, NR_BASEBOARD_GPIOS)
+ generic_handle_irq(x3proto_gpio_to_irq(NULL, pin));
+
+ chip->irq_unmask(data);
+}
+
+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/cchips/hd6446x/hd64461.c b/arch/sh/cchips/hd6446x/hd64461.c
index bcb31ae84a51..177a10b25cad 100644
--- a/arch/sh/cchips/hd6446x/hd64461.c
+++ b/arch/sh/cchips/hd6446x/hd64461.c
@@ -17,8 +17,9 @@
/* This belongs in cpu specific */
#define INTC_ICR1 0xA4140010UL
-static void hd64461_mask_irq(unsigned int irq)
+static void hd64461_mask_irq(struct irq_data *data)
{
+ unsigned int irq = data->irq;
unsigned short nimr;
unsigned short mask = 1 << (irq - HD64461_IRQBASE);
@@ -27,8 +28,9 @@ static void hd64461_mask_irq(unsigned int irq)
__raw_writew(nimr, HD64461_NIMR);
}
-static void hd64461_unmask_irq(unsigned int irq)
+static void hd64461_unmask_irq(struct irq_data *data)
{
+ unsigned int irq = data->irq;
unsigned short nimr;
unsigned short mask = 1 << (irq - HD64461_IRQBASE);
@@ -37,20 +39,21 @@ static void hd64461_unmask_irq(unsigned int irq)
__raw_writew(nimr, HD64461_NIMR);
}
-static void hd64461_mask_and_ack_irq(unsigned int irq)
+static void hd64461_mask_and_ack_irq(struct irq_data *data)
{
- hd64461_mask_irq(irq);
+ hd64461_mask_irq(data);
+
#ifdef CONFIG_HD64461_ENABLER
- if (irq == HD64461_IRQBASE + 13)
+ if (data->irq == HD64461_IRQBASE + 13)
__raw_writeb(0x00, HD64461_PCC1CSCR);
#endif
}
static struct irq_chip hd64461_irq_chip = {
.name = "HD64461-IRQ",
- .mask = hd64461_mask_irq,
- .mask_ack = hd64461_mask_and_ack_irq,
- .unmask = hd64461_unmask_irq,
+ .irq_mask = hd64461_mask_irq,
+ .irq_mask_ack = hd64461_mask_and_ack_irq,
+ .irq_unmask = hd64461_unmask_irq,
};
static void hd64461_irq_demux(unsigned int irq, struct irq_desc *desc)
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/pgtable.h b/arch/sh/include/asm/pgtable.h
index 02f77450cd8f..a15f1058bbf4 100644
--- a/arch/sh/include/asm/pgtable.h
+++ b/arch/sh/include/asm/pgtable.h
@@ -169,6 +169,8 @@ extern void page_table_range_init(unsigned long start, unsigned long end,
#define HAVE_ARCH_UNMAPPED_AREA
#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+#define __HAVE_ARCH_PTE_SPECIAL
+
#include <asm-generic/pgtable.h>
#endif /* __ASM_SH_PGTABLE_H */
diff --git a/arch/sh/include/asm/pgtable_32.h b/arch/sh/include/asm/pgtable_32.h
index e172d696e52b..43528ec656ba 100644
--- a/arch/sh/include/asm/pgtable_32.h
+++ b/arch/sh/include/asm/pgtable_32.h
@@ -378,8 +378,6 @@ PTE_BIT_FUNC(low, mkold, &= ~_PAGE_ACCESSED);
PTE_BIT_FUNC(low, mkyoung, |= _PAGE_ACCESSED);
PTE_BIT_FUNC(low, mkspecial, |= _PAGE_SPECIAL);
-#define __HAVE_ARCH_PTE_SPECIAL
-
/*
* Macro and implementation to make a page protection as uncachable.
*/
@@ -429,10 +427,7 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
#define pte_offset_kernel(dir, address) \
((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(address))
#define pte_offset_map(dir, address) pte_offset_kernel(dir, address)
-#define pte_offset_map_nested(dir, address) pte_offset_kernel(dir, address)
-
#define pte_unmap(pte) do { } while (0)
-#define pte_unmap_nested(pte) do { } while (0)
#ifdef CONFIG_X2TLB
#define pte_ERROR(e) \
diff --git a/arch/sh/include/asm/pgtable_64.h b/arch/sh/include/asm/pgtable_64.h
index 0ee46776dad6..42cb9dd52161 100644
--- a/arch/sh/include/asm/pgtable_64.h
+++ b/arch/sh/include/asm/pgtable_64.h
@@ -84,9 +84,7 @@ static __inline__ void set_pte(pte_t *pteptr, pte_t pteval)
((pte_t *) ((pmd_val(*(dir))) & PAGE_MASK) + pte_index((addr)))
#define pte_offset_map(dir,addr) pte_offset_kernel(dir, addr)
-#define pte_offset_map_nested(dir,addr) pte_offset_kernel(dir, addr)
#define pte_unmap(pte) do { } while (0)
-#define pte_unmap_nested(pte) do { } while (0)
#ifndef __ASSEMBLY__
#define IOBASE_VADDR 0xff000000
@@ -132,6 +130,7 @@ static __inline__ void set_pte(pte_t *pteptr, pte_t pteval)
* anything above the PPN field.
*/
#define _PAGE_WIRED _PAGE_EXT(0x001) /* software: wire the tlb entry */
+#define _PAGE_SPECIAL _PAGE_EXT(0x002)
#define _PAGE_CLEAR_FLAGS (_PAGE_PRESENT | _PAGE_FILE | _PAGE_SHARED | \
_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_WIRED)
@@ -175,7 +174,8 @@ static __inline__ void set_pte(pte_t *pteptr, pte_t pteval)
/* Default flags for a User page */
#define _PAGE_TABLE (_KERNPG_TABLE | _PAGE_USER)
-#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
+#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | \
+ _PAGE_SPECIAL)
/*
* We have full permissions (Read/Write/Execute/Shared).
@@ -265,7 +265,7 @@ static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; }
static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; }
-static inline int pte_special(pte_t pte){ return 0; }
+static inline int pte_special(pte_t pte){ return pte_val(pte) & _PAGE_SPECIAL; }
static inline pte_t pte_wrprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_WRITE)); return pte; }
static inline pte_t pte_mkclean(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_DIRTY)); return pte; }
@@ -274,8 +274,7 @@ static inline pte_t pte_mkwrite(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) |
static inline pte_t pte_mkdirty(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; }
static inline pte_t pte_mkyoung(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; }
static inline pte_t pte_mkhuge(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_SZHUGE)); return pte; }
-static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
-
+static inline pte_t pte_mkspecial(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_SPECIAL)); return pte; }
/*
* Conversion functions: convert a page and protection to a page entry.
diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h
index 0a58cb25a658..c9e7cbc4768a 100644
--- a/arch/sh/include/asm/processor.h
+++ b/arch/sh/include/asm/processor.h
@@ -89,6 +89,7 @@ struct sh_cpuinfo {
struct task_struct *idle;
#endif
+ unsigned int phys_bits;
unsigned long flags;
} __attribute__ ((aligned(L1_CACHE_BYTES)));
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/init.c b/arch/sh/kernel/cpu/init.c
index 97661061ff20..fac742e514ee 100644
--- a/arch/sh/kernel/cpu/init.c
+++ b/arch/sh/kernel/cpu/init.c
@@ -340,6 +340,8 @@ asmlinkage void __cpuinit cpu_init(void)
*/
current_cpu_data.asid_cache = NO_CONTEXT;
+ current_cpu_data.phys_bits = __in_29bit_mode() ? 29 : 32;
+
speculative_execution_init();
expmask_init();
diff --git a/arch/sh/kernel/cpu/irq/imask.c b/arch/sh/kernel/cpu/irq/imask.c
index a351ed84eec5..32c825c9488e 100644
--- a/arch/sh/kernel/cpu/irq/imask.c
+++ b/arch/sh/kernel/cpu/irq/imask.c
@@ -51,16 +51,20 @@ static inline void set_interrupt_registers(int ip)
: "t");
}
-static void mask_imask_irq(unsigned int irq)
+static void mask_imask_irq(struct irq_data *data)
{
+ unsigned int irq = data->irq;
+
clear_bit(irq, imask_mask);
if (interrupt_priority < IMASK_PRIORITY - irq)
interrupt_priority = IMASK_PRIORITY - irq;
set_interrupt_registers(interrupt_priority);
}
-static void unmask_imask_irq(unsigned int irq)
+static void unmask_imask_irq(struct irq_data *data)
{
+ unsigned int irq = data->irq;
+
set_bit(irq, imask_mask);
interrupt_priority = IMASK_PRIORITY -
find_first_zero_bit(imask_mask, IMASK_PRIORITY);
@@ -69,9 +73,9 @@ static void unmask_imask_irq(unsigned int irq)
static struct irq_chip imask_irq_chip = {
.name = "SR.IMASK",
- .mask = mask_imask_irq,
- .unmask = unmask_imask_irq,
- .mask_ack = mask_imask_irq,
+ .irq_mask = mask_imask_irq,
+ .irq_unmask = unmask_imask_irq,
+ .irq_mask_ack = mask_imask_irq,
};
void make_imask_irq(unsigned int irq)
diff --git a/arch/sh/kernel/cpu/irq/intc-sh5.c b/arch/sh/kernel/cpu/irq/intc-sh5.c
index 96a239583948..5af48f8357e5 100644
--- a/arch/sh/kernel/cpu/irq/intc-sh5.c
+++ b/arch/sh/kernel/cpu/irq/intc-sh5.c
@@ -76,39 +76,11 @@ int intc_evt_to_irq[(0xE20/0x20)+1] = {
};
static unsigned long intc_virt;
-
-static unsigned int startup_intc_irq(unsigned int irq);
-static void shutdown_intc_irq(unsigned int irq);
-static void enable_intc_irq(unsigned int irq);
-static void disable_intc_irq(unsigned int irq);
-static void mask_and_ack_intc(unsigned int);
-static void end_intc_irq(unsigned int irq);
-
-static struct irq_chip intc_irq_type = {
- .name = "INTC",
- .startup = startup_intc_irq,
- .shutdown = shutdown_intc_irq,
- .enable = enable_intc_irq,
- .disable = disable_intc_irq,
- .ack = mask_and_ack_intc,
- .end = end_intc_irq
-};
-
static int irlm; /* IRL mode */
-static unsigned int startup_intc_irq(unsigned int irq)
-{
- enable_intc_irq(irq);
- return 0; /* never anything pending */
-}
-
-static void shutdown_intc_irq(unsigned int irq)
-{
- disable_intc_irq(irq);
-}
-
-static void enable_intc_irq(unsigned int irq)
+static void enable_intc_irq(struct irq_data *data)
{
+ unsigned int irq = data->irq;
unsigned long reg;
unsigned long bitmask;
@@ -126,8 +98,9 @@ static void enable_intc_irq(unsigned int irq)
__raw_writel(bitmask, reg);
}
-static void disable_intc_irq(unsigned int irq)
+static void disable_intc_irq(struct irq_data *data)
{
+ unsigned int irq = data->irq;
unsigned long reg;
unsigned long bitmask;
@@ -142,15 +115,11 @@ static void disable_intc_irq(unsigned int irq)
__raw_writel(bitmask, reg);
}
-static void mask_and_ack_intc(unsigned int irq)
-{
- disable_intc_irq(irq);
-}
-
-static void end_intc_irq(unsigned int irq)
-{
- enable_intc_irq(irq);
-}
+static struct irq_chip intc_irq_type = {
+ .name = "INTC",
+ .irq_enable = enable_intc_irq,
+ .irq_disable = disable_intc_irq,
+};
void __init plat_irq_setup(void)
{
diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c
index 9282d965a1b6..7516c35ee514 100644
--- a/arch/sh/kernel/cpu/irq/ipr.c
+++ b/arch/sh/kernel/cpu/irq/ipr.c
@@ -24,25 +24,25 @@
#include <linux/module.h>
#include <linux/topology.h>
-static inline struct ipr_desc *get_ipr_desc(unsigned int irq)
+static inline struct ipr_desc *get_ipr_desc(struct irq_data *data)
{
- struct irq_chip *chip = get_irq_chip(irq);
+ struct irq_chip *chip = irq_data_get_irq_chip(data);
return container_of(chip, struct ipr_desc, chip);
}
-static void disable_ipr_irq(unsigned int irq)
+static void disable_ipr_irq(struct irq_data *data)
{
- struct ipr_data *p = get_irq_chip_data(irq);
- unsigned long addr = get_ipr_desc(irq)->ipr_offsets[p->ipr_idx];
+ struct ipr_data *p = irq_data_get_irq_chip_data(data);
+ unsigned long addr = get_ipr_desc(data)->ipr_offsets[p->ipr_idx];
/* Set the priority in IPR to 0 */
__raw_writew(__raw_readw(addr) & (0xffff ^ (0xf << p->shift)), addr);
(void)__raw_readw(addr); /* Read back to flush write posting */
}
-static void enable_ipr_irq(unsigned int irq)
+static void enable_ipr_irq(struct irq_data *data)
{
- struct ipr_data *p = get_irq_chip_data(irq);
- unsigned long addr = get_ipr_desc(irq)->ipr_offsets[p->ipr_idx];
+ struct ipr_data *p = irq_data_get_irq_chip_data(data);
+ unsigned long addr = get_ipr_desc(data)->ipr_offsets[p->ipr_idx];
/* Set priority in IPR back to original value */
__raw_writew(__raw_readw(addr) | (p->priority << p->shift), addr);
}
@@ -56,19 +56,18 @@ void register_ipr_controller(struct ipr_desc *desc)
{
int i;
- desc->chip.mask = disable_ipr_irq;
- desc->chip.unmask = enable_ipr_irq;
- desc->chip.mask_ack = disable_ipr_irq;
+ desc->chip.irq_mask = disable_ipr_irq;
+ desc->chip.irq_unmask = enable_ipr_irq;
for (i = 0; i < desc->nr_irqs; i++) {
struct ipr_data *p = desc->ipr_data + i;
- struct irq_desc *irq_desc;
+ int res;
BUG_ON(p->ipr_idx >= desc->nr_offsets);
BUG_ON(!desc->ipr_offsets[p->ipr_idx]);
- irq_desc = irq_to_desc_alloc_node(p->irq, numa_node_id());
- if (unlikely(!irq_desc)) {
+ res = irq_alloc_desc_at(p->irq, numa_node_id());
+ if (unlikely(res != p->irq && res != -EEXIST)) {
printk(KERN_INFO "can not get irq_desc for %d\n",
p->irq);
continue;
@@ -78,7 +77,7 @@ void register_ipr_controller(struct ipr_desc *desc)
set_irq_chip_and_handler_name(p->irq, &desc->chip,
handle_level_irq, "level");
set_irq_chip_data(p->irq, p);
- disable_ipr_irq(p->irq);
+ disable_ipr_irq(irq_get_irq_data(p->irq));
}
}
EXPORT_SYMBOL(register_ipr_controller);
diff --git a/arch/sh/kernel/cpu/sh4/perf_event.c b/arch/sh/kernel/cpu/sh4/perf_event.c
index 7f9ecc9c2d02..dbf3b4bb71fe 100644
--- a/arch/sh/kernel/cpu/sh4/perf_event.c
+++ b/arch/sh/kernel/cpu/sh4/perf_event.c
@@ -225,7 +225,7 @@ static void sh7750_pmu_enable_all(void)
}
static struct sh_pmu sh7750_pmu = {
- .name = "SH7750",
+ .name = "sh7750",
.num_events = 2,
.event_map = sh7750_event_map,
.max_events = ARRAY_SIZE(sh7750_general_events),
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..580276525731 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)
@@ -241,7 +259,7 @@ static void sh4a_pmu_enable_all(void)
}
static struct sh_pmu sh4a_pmu = {
- .name = "SH-4A",
+ .name = "sh4a",
.num_events = 2,
.event_map = sh4a_event_map,
.max_events = ARRAY_SIZE(sh4a_general_events),
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..68ecbe6c881a 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -56,6 +56,8 @@ int show_interrupts(struct seq_file *p, void *v)
int i = *(loff_t *)v, j, prec;
struct irqaction *action;
struct irq_desc *desc;
+ struct irq_data *data;
+ struct irq_chip *chip;
if (i > nr_irqs)
return 0;
@@ -77,6 +79,9 @@ int show_interrupts(struct seq_file *p, void *v)
if (!desc)
return 0;
+ data = irq_get_irq_data(i);
+ chip = irq_data_get_irq_chip(data);
+
raw_spin_lock_irqsave(&desc->lock, flags);
for_each_online_cpu(j)
any_count |= kstat_irqs_cpu(i, j);
@@ -87,7 +92,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, " %14s", desc->chip->name);
+ seq_printf(p, " %14s", chip->name);
seq_printf(p, "-%-8s", desc->name);
if (action) {
@@ -273,16 +278,12 @@ void __init init_IRQ(void)
{
plat_irq_setup();
- /*
- * Pin any of the legacy IRQ vectors that haven't already been
- * grabbed by the platform
- */
- reserve_irq_legacy();
-
/* Perform the machine specific initialisation */
if (sh_mv.mv_init_irq)
sh_mv.mv_init_irq();
+ intc_finalize();
+
irq_ctx_init(smp_processor_id());
}
@@ -290,18 +291,21 @@ 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
#ifdef CONFIG_HOTPLUG_CPU
-static void route_irq(struct irq_desc *desc, unsigned int irq, unsigned int cpu)
+static void route_irq(struct irq_data *data, unsigned int irq, unsigned int cpu)
{
+ struct irq_desc *desc = irq_to_desc(irq);
+ struct irq_chip *chip = irq_data_get_irq_chip(data);
+
printk(KERN_INFO "IRQ%u: moving from cpu%u to cpu%u\n",
- irq, desc->node, cpu);
+ irq, data->node, cpu);
raw_spin_lock_irq(&desc->lock);
- desc->chip->set_affinity(irq, cpumask_of(cpu));
+ chip->irq_set_affinity(data, cpumask_of(cpu), false);
raw_spin_unlock_irq(&desc->lock);
}
@@ -312,24 +316,25 @@ static void route_irq(struct irq_desc *desc, unsigned int irq, unsigned int cpu)
*/
void migrate_irqs(void)
{
- struct irq_desc *desc;
unsigned int irq, cpu = smp_processor_id();
- for_each_irq_desc(irq, desc) {
- if (desc->node == cpu) {
- unsigned int newcpu = cpumask_any_and(desc->affinity,
+ for_each_active_irq(irq) {
+ struct irq_data *data = irq_get_irq_data(irq);
+
+ if (data->node == cpu) {
+ unsigned int newcpu = cpumask_any_and(data->affinity,
cpu_online_mask);
if (newcpu >= nr_cpu_ids) {
if (printk_ratelimit())
printk(KERN_INFO "IRQ%u no longer affine to CPU%u\n",
irq, cpu);
- cpumask_setall(desc->affinity);
- newcpu = cpumask_any_and(desc->affinity,
+ cpumask_setall(data->affinity);
+ newcpu = cpumask_any_and(data->affinity,
cpu_online_mask);
}
- route_irq(desc, irq, newcpu);
+ route_irq(data, irq, newcpu);
}
}
}
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/irq_64.c b/arch/sh/kernel/irq_64.c
index 32365ba0e039..8fc05b997b6d 100644
--- a/arch/sh/kernel/irq_64.c
+++ b/arch/sh/kernel/irq_64.c
@@ -11,17 +11,17 @@
#include <linux/module.h>
#include <cpu/registers.h>
-void notrace raw_local_irq_restore(unsigned long flags)
+void notrace arch_local_irq_restore(unsigned long flags)
{
unsigned long long __dummy;
- if (flags == RAW_IRQ_DISABLED) {
+ if (flags == ARCH_IRQ_DISABLED) {
__asm__ __volatile__ (
"getcon " __SR ", %0\n\t"
"or %0, %1, %0\n\t"
"putcon %0, " __SR "\n\t"
: "=&r" (__dummy)
- : "r" (RAW_IRQ_DISABLED)
+ : "r" (ARCH_IRQ_DISABLED)
);
} else {
__asm__ __volatile__ (
@@ -29,13 +29,13 @@ void notrace raw_local_irq_restore(unsigned long flags)
"and %0, %1, %0\n\t"
"putcon %0, " __SR "\n\t"
: "=&r" (__dummy)
- : "r" (~RAW_IRQ_DISABLED)
+ : "r" (~ARCH_IRQ_DISABLED)
);
}
}
-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;
@@ -43,9 +43,9 @@ unsigned long notrace __raw_local_save_flags(void)
"getcon " __SR ", %0\n\t"
"and %0, %1, %0"
: "=&r" (flags)
- : "r" (RAW_IRQ_DISABLED)
+ : "r" (ARCH_IRQ_DISABLED)
);
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/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..90a15d29feeb 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.
*/
@@ -338,9 +365,9 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
return &user_sh_native_view;
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
- struct user * dummy = NULL;
unsigned long __user *datap = (unsigned long __user *)data;
int ret;
@@ -356,17 +383,20 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
if (addr < sizeof(struct pt_regs))
tmp = get_stack_long(child, addr);
- else if (addr >= (long) &dummy->fpu &&
- addr < (long) &dummy->u_fpvalid) {
+ else if (addr >= offsetof(struct user, fpu) &&
+ addr < offsetof(struct user, u_fpvalid)) {
if (!tsk_used_math(child)) {
- if (addr == (long)&dummy->fpu.fpscr)
+ if (addr == offsetof(struct user, fpu.fpscr))
tmp = FPSCR_INIT;
else
tmp = 0;
- } else
- tmp = ((long *)child->thread.xstate)
- [(addr - (long)&dummy->fpu) >> 2];
- } else if (addr == (long) &dummy->u_fpvalid)
+ } else {
+ unsigned long index;
+ index = addr - offsetof(struct user, fpu);
+ tmp = ((unsigned long *)child->thread.xstate)
+ [index >> 2];
+ }
+ } else if (addr == offsetof(struct user, u_fpvalid))
tmp = !!tsk_used_math(child);
else if (addr == PT_TEXT_ADDR)
tmp = child->mm->start_code;
@@ -390,13 +420,15 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
if (addr < sizeof(struct pt_regs))
ret = put_stack_long(child, addr, data);
- else if (addr >= (long) &dummy->fpu &&
- addr < (long) &dummy->u_fpvalid) {
+ else if (addr >= offsetof(struct user, fpu) &&
+ addr < offsetof(struct user, u_fpvalid)) {
+ unsigned long index;
+ index = addr - offsetof(struct user, fpu);
set_stopped_child_used_math(child);
- ((long *)child->thread.xstate)
- [(addr - (long)&dummy->fpu) >> 2] = data;
+ ((unsigned long *)child->thread.xstate)
+ [index >> 2] = data;
ret = 0;
- } else if (addr == (long) &dummy->u_fpvalid) {
+ } else if (addr == offsetof(struct user, u_fpvalid)) {
conditional_stopped_child_used_math(data, child);
ret = 0;
}
@@ -406,35 +438,35 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
return copy_regset_to_user(child, &user_sh_native_view,
REGSET_GENERAL,
0, sizeof(struct pt_regs),
- (void __user *)data);
+ datap);
case PTRACE_SETREGS:
return copy_regset_from_user(child, &user_sh_native_view,
REGSET_GENERAL,
0, sizeof(struct pt_regs),
- (const void __user *)data);
+ datap);
#ifdef CONFIG_SH_FPU
case PTRACE_GETFPREGS:
return copy_regset_to_user(child, &user_sh_native_view,
REGSET_FPU,
0, sizeof(struct user_fpu_struct),
- (void __user *)data);
+ datap);
case PTRACE_SETFPREGS:
return copy_regset_from_user(child, &user_sh_native_view,
REGSET_FPU,
0, sizeof(struct user_fpu_struct),
- (const void __user *)data);
+ datap);
#endif
#ifdef CONFIG_SH_DSP
case PTRACE_GETDSPREGS:
return copy_regset_to_user(child, &user_sh_native_view,
REGSET_DSP,
0, sizeof(struct pt_dspregs),
- (void __user *)data);
+ datap);
case PTRACE_SETDSPREGS:
return copy_regset_from_user(child, &user_sh_native_view,
REGSET_DSP,
0, sizeof(struct pt_dspregs),
- (const void __user *)data);
+ datap);
#endif
default:
ret = ptrace_request(child, request, addr, data);
diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c
index 5fd644da7f02..4436eacddb15 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.
*/
@@ -304,9 +383,11 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
return &user_sh64_native_view;
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int ret;
+ unsigned long __user *datap = (unsigned long __user *) data;
switch (request) {
/* read the word at location addr in the USER area. */
@@ -321,13 +402,15 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
tmp = get_stack_long(child, addr);
else if ((addr >= offsetof(struct user, fpu)) &&
(addr < offsetof(struct user, u_fpvalid))) {
- tmp = get_fpu_long(child, addr - offsetof(struct user, fpu));
+ unsigned long index;
+ index = addr - offsetof(struct user, fpu);
+ tmp = get_fpu_long(child, index);
} else if (addr == offsetof(struct user, u_fpvalid)) {
tmp = !!tsk_used_math(child);
} else {
break;
}
- ret = put_user(tmp, (unsigned long *)data);
+ ret = put_user(tmp, datap);
break;
}
@@ -358,7 +441,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
}
else if ((addr >= offsetof(struct user, fpu)) &&
(addr < offsetof(struct user, u_fpvalid))) {
- ret = put_fpu_long(child, addr - offsetof(struct user, fpu), data);
+ unsigned long index;
+ index = addr - offsetof(struct user, fpu);
+ ret = put_fpu_long(child, index, data);
}
break;
@@ -366,23 +451,23 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
return copy_regset_to_user(child, &user_sh64_native_view,
REGSET_GENERAL,
0, sizeof(struct pt_regs),
- (void __user *)data);
+ datap);
case PTRACE_SETREGS:
return copy_regset_from_user(child, &user_sh64_native_view,
REGSET_GENERAL,
0, sizeof(struct pt_regs),
- (const void __user *)data);
+ datap);
#ifdef CONFIG_SH_FPU
case PTRACE_GETFPREGS:
return copy_regset_to_user(child, &user_sh64_native_view,
REGSET_FPU,
0, sizeof(struct user_fpu_struct),
- (void __user *)data);
+ datap);
case PTRACE_SETFPREGS:
return copy_regset_from_user(child, &user_sh64_native_view,
REGSET_FPU,
0, sizeof(struct user_fpu_struct),
- (const void __user *)data);
+ datap);
#endif
default:
ret = ptrace_request(child, request, addr, data);
@@ -392,13 +477,13 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
return ret;
}
-asmlinkage int sh64_ptrace(long request, long pid, long addr, long data)
+asmlinkage int sh64_ptrace(long request, long pid,
+ unsigned long addr, unsigned 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 +493,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..d6b018c7ebdc 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>
@@ -42,6 +41,7 @@
#include <asm/smp.h>
#include <asm/mmu_context.h>
#include <asm/mmzone.h>
+#include <asm/sparsemem.h>
/*
* Initialize loops_per_jiffy as 10000000 (1000MIPS).
@@ -53,6 +53,7 @@ struct sh_cpuinfo cpu_data[NR_CPUS] __read_mostly = {
.type = CPU_SH_NONE,
.family = CPU_FAMILY_UNKNOWN,
.loops_per_jiffy = 10000000,
+ .phys_bits = MAX_PHYSMEM_BITS,
},
};
EXPORT_SYMBOL(cpu_data);
@@ -136,8 +137,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 +160,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);
@@ -432,6 +434,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
if (c->flags & CPU_HAS_L2_CACHE)
show_cacheinfo(m, "scache", c->scache);
+ seq_printf(m, "address sizes\t: %u bits physical\n", c->phys_bits);
+
seq_printf(m, "bogomips\t: %lu.%02lu\n",
c->loops_per_jiffy/(500000/HZ),
(c->loops_per_jiffy/(5000/HZ)) % 100);
@@ -458,17 +462,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..150aa326afff 100644
--- a/arch/sh/mm/Makefile
+++ b/arch/sh/mm/Makefile
@@ -15,7 +15,7 @@ cacheops-$(CONFIG_CPU_SHX3) += cache-shx3.o
obj-y += $(cacheops-y)
mmu-y := nommu.o extable_32.o
-mmu-$(CONFIG_MMU) := extable_$(BITS).o fault_$(BITS).o \
+mmu-$(CONFIG_MMU) := extable_$(BITS).o fault_$(BITS).o gup.o \
ioremap.o kmap.o pgtable.o tlbflush_$(BITS).o
obj-y += $(mmu-y)
@@ -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/gup.c b/arch/sh/mm/gup.c
new file mode 100644
index 000000000000..bf8daf9d9c9b
--- /dev/null
+++ b/arch/sh/mm/gup.c
@@ -0,0 +1,273 @@
+/*
+ * Lockless get_user_pages_fast for SuperH
+ *
+ * Copyright (C) 2009 - 2010 Paul Mundt
+ *
+ * Cloned from the x86 and PowerPC versions, by:
+ *
+ * Copyright (C) 2008 Nick Piggin
+ * Copyright (C) 2008 Novell Inc.
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/vmstat.h>
+#include <linux/highmem.h>
+#include <asm/pgtable.h>
+
+static inline pte_t gup_get_pte(pte_t *ptep)
+{
+#ifndef CONFIG_X2TLB
+ return ACCESS_ONCE(*ptep);
+#else
+ /*
+ * With get_user_pages_fast, we walk down the pagetables without
+ * taking any locks. For this we would like to load the pointers
+ * atomically, but that is not possible with 64-bit PTEs. What
+ * we do have is the guarantee that a pte will only either go
+ * from not present to present, or present to not present or both
+ * -- it will not switch to a completely different present page
+ * without a TLB flush in between; something that we are blocking
+ * by holding interrupts off.
+ *
+ * Setting ptes from not present to present goes:
+ * ptep->pte_high = h;
+ * smp_wmb();
+ * ptep->pte_low = l;
+ *
+ * And present to not present goes:
+ * ptep->pte_low = 0;
+ * smp_wmb();
+ * ptep->pte_high = 0;
+ *
+ * We must ensure here that the load of pte_low sees l iff pte_high
+ * sees h. We load pte_high *after* loading pte_low, which ensures we
+ * don't see an older value of pte_high. *Then* we recheck pte_low,
+ * which ensures that we haven't picked up a changed pte high. We might
+ * have got rubbish values from pte_low and pte_high, but we are
+ * guaranteed that pte_low will not have the present bit set *unless*
+ * it is 'l'. And get_user_pages_fast only operates on present ptes, so
+ * we're safe.
+ *
+ * gup_get_pte should not be used or copied outside gup.c without being
+ * very careful -- it does not atomically load the pte or anything that
+ * is likely to be useful for you.
+ */
+ pte_t pte;
+
+retry:
+ pte.pte_low = ptep->pte_low;
+ smp_rmb();
+ pte.pte_high = ptep->pte_high;
+ smp_rmb();
+ if (unlikely(pte.pte_low != ptep->pte_low))
+ goto retry;
+
+ return pte;
+#endif
+}
+
+/*
+ * The performance critical leaf functions are made noinline otherwise gcc
+ * inlines everything into a single function which results in too much
+ * register pressure.
+ */
+static noinline int gup_pte_range(pmd_t pmd, unsigned long addr,
+ unsigned long end, int write, struct page **pages, int *nr)
+{
+ u64 mask, result;
+ pte_t *ptep;
+
+#ifdef CONFIG_X2TLB
+ result = _PAGE_PRESENT | _PAGE_EXT(_PAGE_EXT_KERN_READ | _PAGE_EXT_USER_READ);
+ if (write)
+ result |= _PAGE_EXT(_PAGE_EXT_KERN_WRITE | _PAGE_EXT_USER_WRITE);
+#elif defined(CONFIG_SUPERH64)
+ result = _PAGE_PRESENT | _PAGE_USER | _PAGE_READ;
+ if (write)
+ result |= _PAGE_WRITE;
+#else
+ result = _PAGE_PRESENT | _PAGE_USER;
+ if (write)
+ result |= _PAGE_RW;
+#endif
+
+ mask = result | _PAGE_SPECIAL;
+
+ ptep = pte_offset_map(&pmd, addr);
+ do {
+ pte_t pte = gup_get_pte(ptep);
+ struct page *page;
+
+ if ((pte_val(pte) & mask) != result) {
+ pte_unmap(ptep);
+ return 0;
+ }
+ VM_BUG_ON(!pfn_valid(pte_pfn(pte)));
+ page = pte_page(pte);
+ get_page(page);
+ pages[*nr] = page;
+ (*nr)++;
+
+ } while (ptep++, addr += PAGE_SIZE, addr != end);
+ pte_unmap(ptep - 1);
+
+ return 1;
+}
+
+static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end,
+ int write, struct page **pages, int *nr)
+{
+ unsigned long next;
+ pmd_t *pmdp;
+
+ pmdp = pmd_offset(&pud, addr);
+ do {
+ pmd_t pmd = *pmdp;
+
+ next = pmd_addr_end(addr, end);
+ if (pmd_none(pmd))
+ return 0;
+ if (!gup_pte_range(pmd, addr, next, write, pages, nr))
+ return 0;
+ } while (pmdp++, addr = next, addr != end);
+
+ return 1;
+}
+
+static int gup_pud_range(pgd_t pgd, unsigned long addr, unsigned long end,
+ int write, struct page **pages, int *nr)
+{
+ unsigned long next;
+ pud_t *pudp;
+
+ pudp = pud_offset(&pgd, addr);
+ do {
+ pud_t pud = *pudp;
+
+ next = pud_addr_end(addr, end);
+ if (pud_none(pud))
+ return 0;
+ if (!gup_pmd_range(pud, addr, next, write, pages, nr))
+ return 0;
+ } while (pudp++, addr = next, addr != end);
+
+ return 1;
+}
+
+/*
+ * Like get_user_pages_fast() except its IRQ-safe in that it won't fall
+ * back to the regular GUP.
+ */
+int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
+ struct page **pages)
+{
+ struct mm_struct *mm = current->mm;
+ unsigned long addr, len, end;
+ unsigned long next;
+ unsigned long flags;
+ pgd_t *pgdp;
+ int nr = 0;
+
+ start &= PAGE_MASK;
+ addr = start;
+ len = (unsigned long) nr_pages << PAGE_SHIFT;
+ end = start + len;
+ if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ,
+ (void __user *)start, len)))
+ return 0;
+
+ /*
+ * This doesn't prevent pagetable teardown, but does prevent
+ * the pagetables and pages from being freed.
+ */
+ local_irq_save(flags);
+ pgdp = pgd_offset(mm, addr);
+ do {
+ pgd_t pgd = *pgdp;
+
+ next = pgd_addr_end(addr, end);
+ if (pgd_none(pgd))
+ break;
+ if (!gup_pud_range(pgd, addr, next, write, pages, &nr))
+ break;
+ } while (pgdp++, addr = next, addr != end);
+ local_irq_restore(flags);
+
+ return nr;
+}
+
+/**
+ * get_user_pages_fast() - pin user pages in memory
+ * @start: starting user address
+ * @nr_pages: number of pages from start to pin
+ * @write: whether pages will be written to
+ * @pages: array that receives pointers to the pages pinned.
+ * Should be at least nr_pages long.
+ *
+ * Attempt to pin user pages in memory without taking mm->mmap_sem.
+ * If not successful, it will fall back to taking the lock and
+ * calling get_user_pages().
+ *
+ * Returns number of pages pinned. This may be fewer than the number
+ * requested. If nr_pages is 0 or negative, returns 0. If no pages
+ * were pinned, returns -errno.
+ */
+int get_user_pages_fast(unsigned long start, int nr_pages, int write,
+ struct page **pages)
+{
+ struct mm_struct *mm = current->mm;
+ unsigned long addr, len, end;
+ unsigned long next;
+ pgd_t *pgdp;
+ int nr = 0;
+
+ start &= PAGE_MASK;
+ addr = start;
+ len = (unsigned long) nr_pages << PAGE_SHIFT;
+
+ end = start + len;
+ if (end < start)
+ goto slow_irqon;
+
+ local_irq_disable();
+ pgdp = pgd_offset(mm, addr);
+ do {
+ pgd_t pgd = *pgdp;
+
+ next = pgd_addr_end(addr, end);
+ if (pgd_none(pgd))
+ goto slow;
+ if (!gup_pud_range(pgd, addr, next, write, pages, &nr))
+ goto slow;
+ } while (pgdp++, addr = next, addr != end);
+ local_irq_enable();
+
+ VM_BUG_ON(nr != (end - start) >> PAGE_SHIFT);
+ return nr;
+
+ {
+ int ret;
+
+slow:
+ local_irq_enable();
+slow_irqon:
+ /* Try to get the remaining pages with get_user_pages */
+ start += nr << PAGE_SHIFT;
+ pages += nr;
+
+ down_read(&mm->mmap_sem);
+ ret = get_user_pages(current, mm, start,
+ (end - start) >> PAGE_SHIFT, write, 0, pages, NULL);
+ up_read(&mm->mmap_sem);
+
+ /* Have to be a bit careful with return values */
+ if (nr > 0) {
+ if (ret < 0)
+ ret = nr;
+ else
+ ret += nr;
+ }
+
+ return ret;
+ }
+}
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..ce3b119021e7 100644
--- a/arch/sh/oprofile/Makefile
+++ b/arch/sh/oprofile/Makefile
@@ -1,9 +1,15 @@
obj-$(CONFIG_OPROFILE) += oprofile.o
+CFLAGS_common.o += -DUTS_MACHINE='"$(UTS_MACHINE)"'
+
DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
oprof.o cpu_buffer.o buffer_sync.o \
event_buffer.o oprofile_files.o \
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/backtrace.c b/arch/sh/oprofile/backtrace.c
index 2bc74de23f08..37f3a75ea6cb 100644
--- a/arch/sh/oprofile/backtrace.c
+++ b/arch/sh/oprofile/backtrace.c
@@ -91,7 +91,7 @@ void sh_backtrace(struct pt_regs * const regs, unsigned int depth)
if (depth > backtrace_limit)
depth = backtrace_limit;
- stackaddr = (unsigned long *)regs->regs[15];
+ stackaddr = (unsigned long *)kernel_stack_pointer(regs);
if (!user_mode(regs)) {
if (depth)
unwind_stack(NULL, regs, stackaddr,
diff --git a/arch/sh/oprofile/common.c b/arch/sh/oprofile/common.c
index ac604937f3ee..b4c2d2b946dd 100644
--- a/arch/sh/oprofile/common.c
+++ b/arch/sh/oprofile/common.c
@@ -1,7 +1,7 @@
/*
* arch/sh/oprofile/init.c
*
- * Copyright (C) 2003 - 2008 Paul Mundt
+ * Copyright (C) 2003 - 2010 Paul Mundt
*
* Based on arch/mips/oprofile/common.c:
*
@@ -17,114 +17,48 @@
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/smp.h>
+#include <linux/perf_event.h>
+#include <linux/slab.h>
#include <asm/processor.h>
-#include "op_impl.h"
-
-static struct op_sh_model *model;
-
-static struct op_counter_config ctr[20];
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)
-{
- int i, ret = 0;
-
- for (i = 0; i < model->num_counters; i++) {
- struct dentry *dir;
- char buf[4];
-
- snprintf(buf, sizeof(buf), "%d", i);
- dir = oprofilefs_mkdir(sb, root, 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;
-}
-
-static int op_sh_start(void)
-{
- /* Enable performance monitoring for all counters. */
- on_each_cpu(model->cpu_start, NULL, 1);
-
- return 0;
-}
+#ifdef CONFIG_HW_PERF_EVENTS
+/*
+ * This will need to be reworked when multiple PMUs are supported.
+ */
+static char *sh_pmu_op_name;
-static void op_sh_stop(void)
+char *op_name_from_perf_id(void)
{
- /* Disable performance monitoring for all counters. */
- on_each_cpu(model->cpu_stop, NULL, 1);
+ return sh_pmu_op_name;
}
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))
+ if (perf_num_counters() == 0)
return -ENODEV;
- ret = lmodel->init();
- if (unlikely(ret != 0))
- return ret;
+ sh_pmu_op_name = kasprintf(GFP_KERNEL, "%s/%s",
+ UTS_MACHINE, perf_pmu_name());
+ if (unlikely(!sh_pmu_op_name))
+ return -ENOMEM;
- 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;
+ return oprofile_perf_init(ops);
}
-void oprofile_arch_exit(void)
+void __exit oprofile_arch_exit(void)
{
- if (model && model->exit)
- model->exit();
+ oprofile_perf_exit();
+ kfree(sh_pmu_op_name);
+}
+#else
+int __init oprofile_arch_init(struct oprofile_operations *ops)
+{
+ ops->backtrace = sh_backtrace;
+ 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..45d9c87d083a 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -1,9 +1,3 @@
-# For a description of the syntax of this configuration file,
-# see Documentation/kbuild/kconfig-language.txt.
-#
-
-mainmenu "Linux/SPARC Kernel Configuration"
-
config 64BIT
bool "64-bit kernel" if ARCH = "sparc"
default ARCH = "sparc64"
@@ -19,6 +13,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 +21,10 @@ config SPARC
select ARCH_WANT_OPTIONAL_GPIOLIB
select RTC_CLASS
select RTC_DRV_M48T59
- select HAVE_PERF_EVENTS
- select PERF_USE_VMALLOC
+ select HAVE_IRQ_WORK
select HAVE_DMA_ATTRS
select HAVE_DMA_API_DEBUG
+ select HAVE_ARCH_JUMP_LABEL
config SPARC32
def_bool !64BIT
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/highmem.h b/arch/sparc/include/asm/highmem.h
index ec23b0a87b98..3d7afbb7f4bb 100644
--- a/arch/sparc/include/asm/highmem.h
+++ b/arch/sparc/include/asm/highmem.h
@@ -70,8 +70,8 @@ static inline void kunmap(struct page *page)
kunmap_high(page);
}
-extern void *kmap_atomic(struct page *page, enum km_type type);
-extern void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type);
+extern void *__kmap_atomic(struct page *page);
+extern void __kunmap_atomic(void *kvaddr);
extern struct page *kmap_atomic_to_page(void *vaddr);
#define flush_cache_kmaps() flush_cache_all()
diff --git a/arch/sparc/include/asm/io_32.h b/arch/sparc/include/asm/io_32.h
index 2889574608db..c2ced21c9dc1 100644
--- a/arch/sparc/include/asm/io_32.h
+++ b/arch/sparc/include/asm/io_32.h
@@ -208,6 +208,21 @@ _memset_io(volatile void __iomem *dst, int c, __kernel_size_t n)
#define memset_io(d,c,sz) _memset_io(d,c,sz)
static inline void
+_sbus_memcpy_fromio(void *dst, const volatile void __iomem *src,
+ __kernel_size_t n)
+{
+ char *d = dst;
+
+ while (n--) {
+ char tmp = sbus_readb(src);
+ *d++ = tmp;
+ src++;
+ }
+}
+
+#define sbus_memcpy_fromio(d, s, sz) _sbus_memcpy_fromio(d, s, sz)
+
+static inline void
_memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n)
{
char *d = dst;
@@ -222,6 +237,22 @@ _memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n)
#define memcpy_fromio(d,s,sz) _memcpy_fromio(d,s,sz)
static inline void
+_sbus_memcpy_toio(volatile void __iomem *dst, const void *src,
+ __kernel_size_t n)
+{
+ const char *s = src;
+ volatile void __iomem *d = dst;
+
+ while (n--) {
+ char tmp = *s++;
+ sbus_writeb(tmp, d);
+ d++;
+ }
+}
+
+#define sbus_memcpy_toio(d, s, sz) _sbus_memcpy_toio(d, s, sz)
+
+static inline void
_memcpy_toio(volatile void __iomem *dst, const void *src, __kernel_size_t n)
{
const char *s = src;
diff --git a/arch/sparc/include/asm/io_64.h b/arch/sparc/include/asm/io_64.h
index 9517d063c79c..9c8965415f0a 100644
--- a/arch/sparc/include/asm/io_64.h
+++ b/arch/sparc/include/asm/io_64.h
@@ -419,6 +419,21 @@ _memset_io(volatile void __iomem *dst, int c, __kernel_size_t n)
#define memset_io(d,c,sz) _memset_io(d,c,sz)
static inline void
+_sbus_memcpy_fromio(void *dst, const volatile void __iomem *src,
+ __kernel_size_t n)
+{
+ char *d = dst;
+
+ while (n--) {
+ char tmp = sbus_readb(src);
+ *d++ = tmp;
+ src++;
+ }
+}
+
+#define sbus_memcpy_fromio(d, s, sz) _sbus_memcpy_fromio(d, s, sz)
+
+static inline void
_memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n)
{
char *d = dst;
@@ -433,6 +448,22 @@ _memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n)
#define memcpy_fromio(d,s,sz) _memcpy_fromio(d,s,sz)
static inline void
+_sbus_memcpy_toio(volatile void __iomem *dst, const void *src,
+ __kernel_size_t n)
+{
+ const char *s = src;
+ volatile void __iomem *d = dst;
+
+ while (n--) {
+ char tmp = *s++;
+ sbus_writeb(tmp, d);
+ d++;
+ }
+}
+
+#define sbus_memcpy_toio(d, s, sz) _sbus_memcpy_toio(d, s, sz)
+
+static inline void
_memcpy_toio(volatile void __iomem *dst, const void *src, __kernel_size_t n)
{
const char *s = src;
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..427d4684e0d2
--- /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>
+
+#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"\
+ ".align 4\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/pci_64.h b/arch/sparc/include/asm/pci_64.h
index 5312782f0b5e..948b686ec089 100644
--- a/arch/sparc/include/asm/pci_64.h
+++ b/arch/sparc/include/asm/pci_64.h
@@ -38,7 +38,7 @@ static inline void pcibios_penalize_isa_irq(int irq, int active)
* types on sparc64. However, it requires that the device
* can drive enough of the 64 bits.
*/
-#define PCI64_REQUIRED_MASK (~(dma64_addr_t)0)
+#define PCI64_REQUIRED_MASK (~(u64)0)
#define PCI64_ADDR_BASE 0xfffc000000000000UL
#ifdef CONFIG_PCI
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/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h
index 0ece77f47753..303bd4dc8292 100644
--- a/arch/sparc/include/asm/pgtable_32.h
+++ b/arch/sparc/include/asm/pgtable_32.h
@@ -304,10 +304,7 @@ BTFIXUPDEF_CALL(pte_t *, pte_offset_kernel, pmd_t *, unsigned long)
* and sun4c is guaranteed to have no highmem anyway.
*/
#define pte_offset_map(d, a) pte_offset_kernel(d,a)
-#define pte_offset_map_nested(d, a) pte_offset_kernel(d,a)
-
#define pte_unmap(pte) do{}while(0)
-#define pte_unmap_nested(pte) do{}while(0)
/* Certain architectures need to do special things when pte's
* within a page table are directly modified. Thus, the following
diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h
index f5b5fa76c02d..f8dddb7045bb 100644
--- a/arch/sparc/include/asm/pgtable_64.h
+++ b/arch/sparc/include/asm/pgtable_64.h
@@ -652,9 +652,7 @@ static inline int pte_special(pte_t pte)
((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
#define pte_offset_kernel pte_index
#define pte_offset_map pte_index
-#define pte_offset_map_nested pte_index
#define pte_unmap(pte) do { } while (0)
-#define pte_unmap_nested(pte) do { } while (0)
/* Actual page table PTE updates. */
extern void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr, pte_t *ptep, pte_t orig);
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..5ad6e5c5dbb3 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)
@@ -366,7 +365,7 @@ static int request_fast_irq(unsigned int irq,
unsigned long flags;
unsigned int cpu_irq;
int ret;
-#ifdef CONFIG_SMP
+#if defined CONFIG_SMP && !defined CONFIG_SPARC_LEON
struct tt_entry *trap_table;
extern struct tt_entry trapbase_cpu1, trapbase_cpu2, trapbase_cpu3;
#endif
@@ -426,7 +425,7 @@ static int request_fast_irq(unsigned int irq,
table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_four = SPARC_NOP;
INSTANTIATE(sparc_ttable)
-#ifdef CONFIG_SMP
+#if defined CONFIG_SMP && !defined CONFIG_SPARC_LEON
trap_table = &trapbase_cpu1; INSTANTIATE(trap_table)
trap_table = &trapbase_cpu2; INSTANTIATE(trap_table)
trap_table = &trapbase_cpu3; INSTANTIATE(trap_table)
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/leon_smp.c b/arch/sparc/kernel/leon_smp.c
index e1656fc41ccb..7524689b03d2 100644
--- a/arch/sparc/kernel/leon_smp.c
+++ b/arch/sparc/kernel/leon_smp.c
@@ -56,8 +56,8 @@ void __init leon_configure_cache_smp(void);
static inline unsigned long do_swap(volatile unsigned long *ptr,
unsigned long val)
{
- __asm__ __volatile__("swapa [%1] %2, %0\n\t" : "=&r"(val)
- : "r"(ptr), "i"(ASI_LEON_DCACHE_MISS)
+ __asm__ __volatile__("swapa [%2] %3, %0\n\t" : "=&r"(val)
+ : "0"(val), "r"(ptr), "i"(ASI_LEON_DCACHE_MISS)
: "memory");
return val;
}
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/ptrace_32.c b/arch/sparc/kernel/ptrace_32.c
index e608f397e11f..27b9e93d0121 100644
--- a/arch/sparc/kernel/ptrace_32.c
+++ b/arch/sparc/kernel/ptrace_32.c
@@ -323,18 +323,35 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
return &user_sparc32_view;
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+struct fps {
+ unsigned long regs[32];
+ unsigned long fsr;
+ unsigned long flags;
+ unsigned long extra;
+ unsigned long fpqd;
+ struct fq {
+ unsigned long *insnaddr;
+ unsigned long insn;
+ } fpq[16];
+};
+
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
unsigned long addr2 = current->thread.kregs->u_regs[UREG_I4];
+ void __user *addr2p;
const struct user_regset_view *view;
+ struct pt_regs __user *pregs;
+ struct fps __user *fps;
int ret;
view = task_user_regset_view(current);
+ addr2p = (void __user *) addr2;
+ pregs = (struct pt_regs __user *) addr;
+ fps = (struct fps __user *) addr;
switch(request) {
case PTRACE_GETREGS: {
- struct pt_regs __user *pregs = (struct pt_regs __user *) addr;
-
ret = copy_regset_to_user(child, view, REGSET_GENERAL,
32 * sizeof(u32),
4 * sizeof(u32),
@@ -348,8 +365,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
}
case PTRACE_SETREGS: {
- struct pt_regs __user *pregs = (struct pt_regs __user *) addr;
-
ret = copy_regset_from_user(child, view, REGSET_GENERAL,
32 * sizeof(u32),
4 * sizeof(u32),
@@ -363,19 +378,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
}
case PTRACE_GETFPREGS: {
- struct fps {
- unsigned long regs[32];
- unsigned long fsr;
- unsigned long flags;
- unsigned long extra;
- unsigned long fpqd;
- struct fq {
- unsigned long *insnaddr;
- unsigned long insn;
- } fpq[16];
- };
- struct fps __user *fps = (struct fps __user *) addr;
-
ret = copy_regset_to_user(child, view, REGSET_FP,
0 * sizeof(u32),
32 * sizeof(u32),
@@ -397,19 +399,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
}
case PTRACE_SETFPREGS: {
- struct fps {
- unsigned long regs[32];
- unsigned long fsr;
- unsigned long flags;
- unsigned long extra;
- unsigned long fpqd;
- struct fq {
- unsigned long *insnaddr;
- unsigned long insn;
- } fpq[16];
- };
- struct fps __user *fps = (struct fps __user *) addr;
-
ret = copy_regset_from_user(child, view, REGSET_FP,
0 * sizeof(u32),
32 * sizeof(u32),
@@ -424,8 +413,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
case PTRACE_READTEXT:
case PTRACE_READDATA:
- ret = ptrace_readdata(child, addr,
- (void __user *) addr2, data);
+ ret = ptrace_readdata(child, addr, addr2p, data);
if (ret == data)
ret = 0;
@@ -435,8 +423,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
case PTRACE_WRITETEXT:
case PTRACE_WRITEDATA:
- ret = ptrace_writedata(child, (void __user *) addr2,
- addr, data);
+ ret = ptrace_writedata(child, addr2p, addr, data);
if (ret == data)
ret = 0;
diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c
index aa90da08bf61..9ccc812bc09e 100644
--- a/arch/sparc/kernel/ptrace_64.c
+++ b/arch/sparc/kernel/ptrace_64.c
@@ -969,16 +969,19 @@ struct fps {
unsigned long fsr;
};
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
const struct user_regset_view *view = task_user_regset_view(current);
unsigned long addr2 = task_pt_regs(current)->u_regs[UREG_I4];
struct pt_regs __user *pregs;
struct fps __user *fps;
+ void __user *addr2p;
int ret;
- pregs = (struct pt_regs __user *) (unsigned long) addr;
- fps = (struct fps __user *) (unsigned long) addr;
+ pregs = (struct pt_regs __user *) addr;
+ fps = (struct fps __user *) addr;
+ addr2p = (void __user *) addr2;
switch (request) {
case PTRACE_PEEKUSR:
@@ -1029,8 +1032,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
case PTRACE_READTEXT:
case PTRACE_READDATA:
- ret = ptrace_readdata(child, addr,
- (char __user *)addr2, data);
+ ret = ptrace_readdata(child, addr, addr2p, data);
if (ret == data)
ret = 0;
else if (ret >= 0)
@@ -1039,8 +1041,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
case PTRACE_WRITETEXT:
case PTRACE_WRITEDATA:
- ret = ptrace_writedata(child, (char __user *) addr2,
- addr, data);
+ ret = ptrace_writedata(child, addr2p, addr, data);
if (ret == data)
ret = 0;
else if (ret >= 0)
diff --git a/arch/sparc/kernel/rtrap_32.S b/arch/sparc/kernel/rtrap_32.S
index 4da2e1f66290..5f5f74c2c2ca 100644
--- a/arch/sparc/kernel/rtrap_32.S
+++ b/arch/sparc/kernel/rtrap_32.S
@@ -78,9 +78,9 @@ signal_p:
call do_notify_resume
add %sp, STACKFRAME_SZ, %o0 ! pt_regs ptr
- /* Fall through. */
- ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr
- clr %l6
+ b signal_p
+ ld [%curptr + TI_FLAGS], %g2
+
ret_trap_continue:
sethi %hi(PSR_SYSCALL), %g1
andn %t_psr, %g1, %t_psr
diff --git a/arch/sparc/kernel/rtrap_64.S b/arch/sparc/kernel/rtrap_64.S
index 090b9e9ad5e3..77f1b95e0806 100644
--- a/arch/sparc/kernel/rtrap_64.S
+++ b/arch/sparc/kernel/rtrap_64.S
@@ -34,37 +34,9 @@ __handle_preemption:
__handle_user_windows:
call fault_in_user_windows
wrpr %g0, RTRAP_PSTATE, %pstate
- wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate
- /* Redo sched+sig checks */
- ldx [%g6 + TI_FLAGS], %l0
- andcc %l0, _TIF_NEED_RESCHED, %g0
-
- be,pt %xcc, 1f
- nop
- call schedule
- wrpr %g0, RTRAP_PSTATE, %pstate
- wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate
- ldx [%g6 + TI_FLAGS], %l0
-
-1: andcc %l0, _TIF_DO_NOTIFY_RESUME_MASK, %g0
- be,pt %xcc, __handle_user_windows_continue
- nop
- mov %l5, %o1
- add %sp, PTREGS_OFF, %o0
- mov %l0, %o2
-
- call do_notify_resume
- wrpr %g0, RTRAP_PSTATE, %pstate
- wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate
- /* Signal delivery can modify pt_regs tstate, so we must
- * reload it.
- */
- ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
- sethi %hi(0xf << 20), %l4
- and %l1, %l4, %l4
- ba,pt %xcc, __handle_user_windows_continue
+ ba,pt %xcc, __handle_preemption_continue
+ wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate
- andn %l1, %l4, %l1
__handle_userfpu:
rd %fprs, %l5
andcc %l5, FPRS_FEF, %g0
@@ -87,7 +59,7 @@ __handle_signal:
ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
sethi %hi(0xf << 20), %l4
and %l1, %l4, %l4
- ba,pt %xcc, __handle_signal_continue
+ ba,pt %xcc, __handle_preemption_continue
andn %l1, %l4, %l1
/* When returning from a NMI (%pil==15) interrupt we want to
@@ -177,11 +149,9 @@ __handle_preemption_continue:
bne,pn %xcc, __handle_preemption
andcc %l0, _TIF_DO_NOTIFY_RESUME_MASK, %g0
bne,pn %xcc, __handle_signal
-__handle_signal_continue:
ldub [%g6 + TI_WSAVED], %o2
brnz,pn %o2, __handle_user_windows
nop
-__handle_user_windows_continue:
sethi %hi(TSTATE_PEF), %o0
andcc %l1, %o0, %g0
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/fault_32.c b/arch/sparc/mm/fault_32.c
index bd8601601afa..5b836f5aea90 100644
--- a/arch/sparc/mm/fault_32.c
+++ b/arch/sparc/mm/fault_32.c
@@ -539,6 +539,12 @@ do_sigbus:
__do_fault_siginfo(BUS_ADRERR, SIGBUS, tsk->thread.kregs, address);
}
+static void check_stack_aligned(unsigned long sp)
+{
+ if (sp & 0x7UL)
+ force_sig(SIGILL, current);
+}
+
void window_overflow_fault(void)
{
unsigned long sp;
@@ -547,6 +553,8 @@ void window_overflow_fault(void)
if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK))
force_user_fault(sp + 0x38, 1);
force_user_fault(sp, 1);
+
+ check_stack_aligned(sp);
}
void window_underflow_fault(unsigned long sp)
@@ -554,6 +562,8 @@ void window_underflow_fault(unsigned long sp)
if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK))
force_user_fault(sp + 0x38, 0);
force_user_fault(sp, 0);
+
+ check_stack_aligned(sp);
}
void window_ret_fault(struct pt_regs *regs)
@@ -564,4 +574,6 @@ void window_ret_fault(struct pt_regs *regs)
if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK))
force_user_fault(sp + 0x38, 0);
force_user_fault(sp, 0);
+
+ check_stack_aligned(sp);
}
diff --git a/arch/sparc/mm/highmem.c b/arch/sparc/mm/highmem.c
index e139e9cbf5f7..4730eac0747b 100644
--- a/arch/sparc/mm/highmem.c
+++ b/arch/sparc/mm/highmem.c
@@ -29,17 +29,17 @@
#include <asm/tlbflush.h>
#include <asm/fixmap.h>
-void *kmap_atomic(struct page *page, enum km_type type)
+void *__kmap_atomic(struct page *page)
{
- unsigned long idx;
unsigned long vaddr;
+ long idx, type;
/* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
pagefault_disable();
if (!PageHighMem(page))
return page_address(page);
- debug_kmap_atomic(type);
+ type = kmap_atomic_idx_push();
idx = type + KM_TYPE_NR*smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
@@ -63,44 +63,52 @@ void *kmap_atomic(struct page *page, enum km_type type)
return (void*) vaddr;
}
-EXPORT_SYMBOL(kmap_atomic);
+EXPORT_SYMBOL(__kmap_atomic);
-void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type)
+void __kunmap_atomic(void *kvaddr)
{
-#ifdef CONFIG_DEBUG_HIGHMEM
unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
- unsigned long idx = type + KM_TYPE_NR*smp_processor_id();
+ int type;
if (vaddr < FIXADDR_START) { // FIXME
pagefault_enable();
return;
}
- BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx));
+ type = kmap_atomic_idx();
-/* XXX Fix - Anton */
+#ifdef CONFIG_DEBUG_HIGHMEM
+ {
+ unsigned long idx;
+
+ idx = type + KM_TYPE_NR * smp_processor_id();
+ BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx));
+
+ /* XXX Fix - Anton */
#if 0
- __flush_cache_one(vaddr);
+ __flush_cache_one(vaddr);
#else
- flush_cache_all();
+ flush_cache_all();
#endif
- /*
- * force other mappings to Oops if they'll try to access
- * this pte without first remap it
- */
- pte_clear(&init_mm, vaddr, kmap_pte-idx);
-/* XXX Fix - Anton */
+ /*
+ * force other mappings to Oops if they'll try to access
+ * this pte without first remap it
+ */
+ pte_clear(&init_mm, vaddr, kmap_pte-idx);
+ /* XXX Fix - Anton */
#if 0
- __flush_tlb_one(vaddr);
+ __flush_tlb_one(vaddr);
#else
- flush_tlb_all();
+ flush_tlb_all();
#endif
+ }
#endif
+ kmap_atomic_idx_pop();
pagefault_enable();
}
-EXPORT_SYMBOL(kunmap_atomic_notypecheck);
+EXPORT_SYMBOL(__kunmap_atomic);
/* We may be fed a pagetable here by ptep_to_xxx and others. */
struct page *kmap_atomic_to_page(void *ptr)
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/Kconfig b/arch/tile/Kconfig
index 1eb308cb711a..07ec8a865c1d 100644
--- a/arch/tile/Kconfig
+++ b/arch/tile/Kconfig
@@ -58,6 +58,9 @@ config ARCH_SUPPORTS_OPTIMIZED_INLINING
config ARCH_PHYS_ADDR_T_64BIT
def_bool y
+config ARCH_DMA_ADDR_T_64BIT
+ def_bool y
+
config LOCKDEP_SUPPORT
def_bool y
@@ -96,6 +99,7 @@ config HVC_TILE
config TILE
def_bool y
+ select HAVE_KVM if !TILEGX
select GENERIC_FIND_FIRST_BIT
select GENERIC_FIND_NEXT_BIT
select USE_GENERIC_SMP_HELPERS
@@ -113,8 +117,6 @@ config TILE
# config HUGETLB_PAGE_SIZE_VARIABLE
-mainmenu "Linux/TILE Kernel Configuration"
-
# Please note: TILE-Gx support is not yet finalized; this is
# the preliminary support. TILE-Gx drivers are only provided
# with the alpha or beta test versions for Tilera customers.
@@ -236,9 +238,9 @@ choice
If you are not absolutely sure what you are doing, leave this
option alone!
- config VMSPLIT_375G
+ config VMSPLIT_3_75G
bool "3.75G/0.25G user/kernel split (no kernel networking)"
- config VMSPLIT_35G
+ config VMSPLIT_3_5G
bool "3.5G/0.5G user/kernel split"
config VMSPLIT_3G
bool "3G/1G user/kernel split"
@@ -252,8 +254,8 @@ endchoice
config PAGE_OFFSET
hex
- default 0xF0000000 if VMSPLIT_375G
- default 0xE0000000 if VMSPLIT_35G
+ default 0xF0000000 if VMSPLIT_3_75G
+ default 0xE0000000 if VMSPLIT_3_5G
default 0xB0000000 if VMSPLIT_3G_OPT
default 0x80000000 if VMSPLIT_2G
default 0x40000000 if VMSPLIT_1G
@@ -314,6 +316,15 @@ config HARDWALL
bool "Hardwall support to allow access to user dynamic network"
default y
+config KERNEL_PL
+ int "Processor protection level for kernel"
+ range 1 2
+ default "1"
+ ---help---
+ This setting determines the processor protection level the
+ kernel will be built to run at. Generally you should use
+ the default value here.
+
endmenu # Tilera-specific configuration
menu "Bus options"
@@ -354,3 +365,5 @@ source "security/Kconfig"
source "crypto/Kconfig"
source "lib/Kconfig"
+
+source "arch/tile/kvm/Kconfig"
diff --git a/arch/tile/Makefile b/arch/tile/Makefile
index fd8f6bb5face..17acce70569b 100644
--- a/arch/tile/Makefile
+++ b/arch/tile/Makefile
@@ -26,8 +26,9 @@ $(error Set TILERA_ROOT or CROSS_COMPILE when building $(ARCH) on $(HOST_ARCH))
endif
endif
-
+ifneq ($(CONFIG_DEBUG_EXTRA_FLAGS),"")
KBUILD_CFLAGS += $(CONFIG_DEBUG_EXTRA_FLAGS)
+endif
LIBGCC_PATH := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
@@ -49,6 +50,20 @@ head-y := arch/tile/kernel/head_$(BITS).o
libs-y += arch/tile/lib/
libs-y += $(LIBGCC_PATH)
-
# See arch/tile/Kbuild for content of core part of the kernel
core-y += arch/tile/
+
+core-$(CONFIG_KVM) += arch/tile/kvm/
+
+ifdef TILERA_ROOT
+INSTALL_PATH ?= $(TILERA_ROOT)/tile/boot
+endif
+
+install:
+ install -D -m 755 vmlinux $(INSTALL_PATH)/vmlinux-$(KERNELRELEASE)
+ install -D -m 644 .config $(INSTALL_PATH)/config-$(KERNELRELEASE)
+ install -D -m 644 System.map $(INSTALL_PATH)/System.map-$(KERNELRELEASE)
+
+define archhelp
+ echo ' install - install kernel into $(INSTALL_PATH)'
+endef
diff --git a/arch/tile/include/arch/sim.h b/arch/tile/include/arch/sim.h
new file mode 100644
index 000000000000..74b7c1624d34
--- /dev/null
+++ b/arch/tile/include/arch/sim.h
@@ -0,0 +1,619 @@
+/*
+ * Copyright 2010 Tilera Corporation. 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, version 2.
+ *
+ * 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.
+ */
+
+/**
+ * @file
+ *
+ * Provides an API for controlling the simulator at runtime.
+ */
+
+/**
+ * @addtogroup arch_sim
+ * @{
+ *
+ * An API for controlling the simulator at runtime.
+ *
+ * The simulator's behavior can be modified while it is running.
+ * For example, human-readable trace output can be enabled and disabled
+ * around code of interest.
+ *
+ * There are two ways to modify simulator behavior:
+ * programmatically, by calling various sim_* functions, and
+ * interactively, by entering commands like "sim set functional true"
+ * at the tile-monitor prompt. Typing "sim help" at that prompt provides
+ * a list of interactive commands.
+ *
+ * All interactive commands can also be executed programmatically by
+ * passing a string to the sim_command function.
+ */
+
+#ifndef __ARCH_SIM_H__
+#define __ARCH_SIM_H__
+
+#include <arch/sim_def.h>
+#include <arch/abi.h>
+
+#ifndef __ASSEMBLER__
+
+#include <arch/spr_def.h>
+
+
+/**
+ * Return true if the current program is running under a simulator,
+ * rather than on real hardware. If running on hardware, other "sim_xxx()"
+ * calls have no useful effect.
+ */
+static inline int
+sim_is_simulator(void)
+{
+ return __insn_mfspr(SPR_SIM_CONTROL) != 0;
+}
+
+
+/**
+ * Checkpoint the simulator state to a checkpoint file.
+ *
+ * The checkpoint file name is either the default or the name specified
+ * on the command line with "--checkpoint-file".
+ */
+static __inline void
+sim_checkpoint(void)
+{
+ __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_CHECKPOINT);
+}
+
+
+/**
+ * Report whether or not various kinds of simulator tracing are enabled.
+ *
+ * @return The bitwise OR of these values:
+ *
+ * SIM_TRACE_CYCLES (--trace-cycles),
+ * SIM_TRACE_ROUTER (--trace-router),
+ * SIM_TRACE_REGISTER_WRITES (--trace-register-writes),
+ * SIM_TRACE_DISASM (--trace-disasm),
+ * SIM_TRACE_STALL_INFO (--trace-stall-info)
+ * SIM_TRACE_MEMORY_CONTROLLER (--trace-memory-controller)
+ * SIM_TRACE_L2_CACHE (--trace-l2)
+ * SIM_TRACE_LINES (--trace-lines)
+ */
+static __inline unsigned int
+sim_get_tracing(void)
+{
+ return __insn_mfspr(SPR_SIM_CONTROL) & SIM_TRACE_FLAG_MASK;
+}
+
+
+/**
+ * Turn on or off different kinds of simulator tracing.
+ *
+ * @param mask Either one of these special values:
+ *
+ * SIM_TRACE_NONE (turns off tracing),
+ * SIM_TRACE_ALL (turns on all possible tracing).
+ *
+ * or the bitwise OR of these values:
+ *
+ * SIM_TRACE_CYCLES (--trace-cycles),
+ * SIM_TRACE_ROUTER (--trace-router),
+ * SIM_TRACE_REGISTER_WRITES (--trace-register-writes),
+ * SIM_TRACE_DISASM (--trace-disasm),
+ * SIM_TRACE_STALL_INFO (--trace-stall-info)
+ * SIM_TRACE_MEMORY_CONTROLLER (--trace-memory-controller)
+ * SIM_TRACE_L2_CACHE (--trace-l2)
+ * SIM_TRACE_LINES (--trace-lines)
+ */
+static __inline void
+sim_set_tracing(unsigned int mask)
+{
+ __insn_mtspr(SPR_SIM_CONTROL, SIM_TRACE_SPR_ARG(mask));
+}
+
+
+/**
+ * Request dumping of different kinds of simulator state.
+ *
+ * @param mask Either this special value:
+ *
+ * SIM_DUMP_ALL (dump all known state)
+ *
+ * or the bitwise OR of these values:
+ *
+ * SIM_DUMP_REGS (the register file),
+ * SIM_DUMP_SPRS (the SPRs),
+ * SIM_DUMP_ITLB (the iTLB),
+ * SIM_DUMP_DTLB (the dTLB),
+ * SIM_DUMP_L1I (the L1 I-cache),
+ * SIM_DUMP_L1D (the L1 D-cache),
+ * SIM_DUMP_L2 (the L2 cache),
+ * SIM_DUMP_SNREGS (the switch register file),
+ * SIM_DUMP_SNITLB (the switch iTLB),
+ * SIM_DUMP_SNL1I (the switch L1 I-cache),
+ * SIM_DUMP_BACKTRACE (the current backtrace)
+ */
+static __inline void
+sim_dump(unsigned int mask)
+{
+ __insn_mtspr(SPR_SIM_CONTROL, SIM_DUMP_SPR_ARG(mask));
+}
+
+
+/**
+ * Print a string to the simulator stdout.
+ *
+ * @param str The string to be written; a newline is automatically added.
+ */
+static __inline void
+sim_print_string(const char* str)
+{
+ int i;
+ for (i = 0; str[i] != 0; i++)
+ {
+ __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PUTC |
+ (str[i] << _SIM_CONTROL_OPERATOR_BITS));
+ }
+ __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PUTC |
+ (SIM_PUTC_FLUSH_STRING << _SIM_CONTROL_OPERATOR_BITS));
+}
+
+
+/**
+ * Execute a simulator command string.
+ *
+ * Type 'sim help' at the tile-monitor prompt to learn what commands
+ * are available. Note the use of the tile-monitor "sim" command to
+ * pass commands to the simulator.
+ *
+ * The argument to sim_command() does not include the leading "sim"
+ * prefix used at the tile-monitor prompt; for example, you might call
+ * sim_command("trace disasm").
+ */
+static __inline void
+sim_command(const char* str)
+{
+ int c;
+ do
+ {
+ c = *str++;
+ __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_COMMAND |
+ (c << _SIM_CONTROL_OPERATOR_BITS));
+ }
+ while (c);
+}
+
+
+
+#ifndef __DOXYGEN__
+
+/**
+ * The underlying implementation of "_sim_syscall()".
+ *
+ * We use extra "and" instructions to ensure that all the values
+ * we are passing to the simulator are actually valid in the registers
+ * (i.e. returned from memory) prior to the SIM_CONTROL spr.
+ */
+static __inline int _sim_syscall0(int val)
+{
+ long result;
+ __asm__ __volatile__ ("mtspr SIM_CONTROL, r0"
+ : "=R00" (result) : "R00" (val));
+ return result;
+}
+
+static __inline int _sim_syscall1(int val, long arg1)
+{
+ long result;
+ __asm__ __volatile__ ("{ and zero, r1, r1; mtspr SIM_CONTROL, r0 }"
+ : "=R00" (result) : "R00" (val), "R01" (arg1));
+ return result;
+}
+
+static __inline int _sim_syscall2(int val, long arg1, long arg2)
+{
+ long result;
+ __asm__ __volatile__ ("{ and zero, r1, r2; mtspr SIM_CONTROL, r0 }"
+ : "=R00" (result)
+ : "R00" (val), "R01" (arg1), "R02" (arg2));
+ return result;
+}
+
+/* Note that _sim_syscall3() and higher are technically at risk of
+ receiving an interrupt right before the mtspr bundle, in which case
+ the register values for arguments 3 and up may still be in flight
+ to the core from a stack frame reload. */
+
+static __inline int _sim_syscall3(int val, long arg1, long arg2, long arg3)
+{
+ long result;
+ __asm__ __volatile__ ("{ and zero, r3, r3 };"
+ "{ and zero, r1, r2; mtspr SIM_CONTROL, r0 }"
+ : "=R00" (result)
+ : "R00" (val), "R01" (arg1), "R02" (arg2),
+ "R03" (arg3));
+ return result;
+}
+
+static __inline int _sim_syscall4(int val, long arg1, long arg2, long arg3,
+ long arg4)
+{
+ long result;
+ __asm__ __volatile__ ("{ and zero, r3, r4 };"
+ "{ and zero, r1, r2; mtspr SIM_CONTROL, r0 }"
+ : "=R00" (result)
+ : "R00" (val), "R01" (arg1), "R02" (arg2),
+ "R03" (arg3), "R04" (arg4));
+ return result;
+}
+
+static __inline int _sim_syscall5(int val, long arg1, long arg2, long arg3,
+ long arg4, long arg5)
+{
+ long result;
+ __asm__ __volatile__ ("{ and zero, r3, r4; and zero, r5, r5 };"
+ "{ and zero, r1, r2; mtspr SIM_CONTROL, r0 }"
+ : "=R00" (result)
+ : "R00" (val), "R01" (arg1), "R02" (arg2),
+ "R03" (arg3), "R04" (arg4), "R05" (arg5));
+ return result;
+}
+
+
+/**
+ * Make a special syscall to the simulator itself, if running under
+ * simulation. This is used as the implementation of other functions
+ * and should not be used outside this file.
+ *
+ * @param syscall_num The simulator syscall number.
+ * @param nr The number of additional arguments provided.
+ *
+ * @return Varies by syscall.
+ */
+#define _sim_syscall(syscall_num, nr, args...) \
+ _sim_syscall##nr( \
+ ((syscall_num) << _SIM_CONTROL_OPERATOR_BITS) | SIM_CONTROL_SYSCALL, args)
+
+
+/* Values for the "access_mask" parameters below. */
+#define SIM_WATCHPOINT_READ 1
+#define SIM_WATCHPOINT_WRITE 2
+#define SIM_WATCHPOINT_EXECUTE 4
+
+
+static __inline int
+sim_add_watchpoint(unsigned int process_id,
+ unsigned long address,
+ unsigned long size,
+ unsigned int access_mask,
+ unsigned long user_data)
+{
+ return _sim_syscall(SIM_SYSCALL_ADD_WATCHPOINT, 5, process_id,
+ address, size, access_mask, user_data);
+}
+
+
+static __inline int
+sim_remove_watchpoint(unsigned int process_id,
+ unsigned long address,
+ unsigned long size,
+ unsigned int access_mask,
+ unsigned long user_data)
+{
+ return _sim_syscall(SIM_SYSCALL_REMOVE_WATCHPOINT, 5, process_id,
+ address, size, access_mask, user_data);
+}
+
+
+/**
+ * Return value from sim_query_watchpoint.
+ */
+struct SimQueryWatchpointStatus
+{
+ /**
+ * 0 if a watchpoint fired, 1 if no watchpoint fired, or -1 for
+ * error (meaning a bad process_id).
+ */
+ int syscall_status;
+
+ /**
+ * The address of the watchpoint that fired (this is the address
+ * passed to sim_add_watchpoint, not an address within that range
+ * that actually triggered the watchpoint).
+ */
+ unsigned long address;
+
+ /** The arbitrary user_data installed by sim_add_watchpoint. */
+ unsigned long user_data;
+};
+
+
+static __inline struct SimQueryWatchpointStatus
+sim_query_watchpoint(unsigned int process_id)
+{
+ struct SimQueryWatchpointStatus status;
+ long val = SIM_CONTROL_SYSCALL |
+ (SIM_SYSCALL_QUERY_WATCHPOINT << _SIM_CONTROL_OPERATOR_BITS);
+ __asm__ __volatile__ ("{ and zero, r1, r1; mtspr SIM_CONTROL, r0 }"
+ : "=R00" (status.syscall_status),
+ "=R01" (status.address),
+ "=R02" (status.user_data)
+ : "R00" (val), "R01" (process_id));
+ return status;
+}
+
+
+/* On the simulator, confirm lines have been evicted everywhere. */
+static __inline void
+sim_validate_lines_evicted(unsigned long long pa, unsigned long length)
+{
+#ifdef __LP64__
+ _sim_syscall(SIM_SYSCALL_VALIDATE_LINES_EVICTED, 2, pa, length);
+#else
+ _sim_syscall(SIM_SYSCALL_VALIDATE_LINES_EVICTED, 4,
+ 0 /* dummy */, (long)(pa), (long)(pa >> 32), length);
+#endif
+}
+
+
+#endif /* !__DOXYGEN__ */
+
+
+
+
+/**
+ * Modify the shaping parameters of a shim.
+ *
+ * @param shim The shim to modify. One of:
+ * SIM_CONTROL_SHAPING_GBE_0
+ * SIM_CONTROL_SHAPING_GBE_1
+ * SIM_CONTROL_SHAPING_GBE_2
+ * SIM_CONTROL_SHAPING_GBE_3
+ * SIM_CONTROL_SHAPING_XGBE_0
+ * SIM_CONTROL_SHAPING_XGBE_1
+ *
+ * @param type The type of shaping. This should be the same type of
+ * shaping that is already in place on the shim. One of:
+ * SIM_CONTROL_SHAPING_MULTIPLIER
+ * SIM_CONTROL_SHAPING_PPS
+ * SIM_CONTROL_SHAPING_BPS
+ *
+ * @param units The magnitude of the rate. One of:
+ * SIM_CONTROL_SHAPING_UNITS_SINGLE
+ * SIM_CONTROL_SHAPING_UNITS_KILO
+ * SIM_CONTROL_SHAPING_UNITS_MEGA
+ * SIM_CONTROL_SHAPING_UNITS_GIGA
+ *
+ * @param rate The rate to which to change it. This must fit in
+ * SIM_CONTROL_SHAPING_RATE_BITS bits or a warning is issued and
+ * the shaping is not changed.
+ *
+ * @return 0 if no problems were detected in the arguments to sim_set_shaping
+ * or 1 if problems were detected (for example, rate does not fit in 17 bits).
+ */
+static __inline int
+sim_set_shaping(unsigned shim,
+ unsigned type,
+ unsigned units,
+ unsigned rate)
+{
+ if ((rate & ~((1 << SIM_CONTROL_SHAPING_RATE_BITS) - 1)) != 0)
+ return 1;
+
+ __insn_mtspr(SPR_SIM_CONTROL, SIM_SHAPING_SPR_ARG(shim, type, units, rate));
+ return 0;
+}
+
+#ifdef __tilegx__
+
+/** Enable a set of mPIPE links. Pass a -1 link_mask to enable all links. */
+static __inline void
+sim_enable_mpipe_links(unsigned mpipe, unsigned long link_mask)
+{
+ __insn_mtspr(SPR_SIM_CONTROL,
+ (SIM_CONTROL_ENABLE_MPIPE_LINK_MAGIC_BYTE |
+ (mpipe << 8) | (1 << 16) | ((uint_reg_t)link_mask << 32)));
+}
+
+/** Disable a set of mPIPE links. Pass a -1 link_mask to disable all links. */
+static __inline void
+sim_disable_mpipe_links(unsigned mpipe, unsigned long link_mask)
+{
+ __insn_mtspr(SPR_SIM_CONTROL,
+ (SIM_CONTROL_ENABLE_MPIPE_LINK_MAGIC_BYTE |
+ (mpipe << 8) | (0 << 16) | ((uint_reg_t)link_mask << 32)));
+}
+
+#endif /* __tilegx__ */
+
+
+/*
+ * An API for changing "functional" mode.
+ */
+
+#ifndef __DOXYGEN__
+
+#define sim_enable_functional() \
+ __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_ENABLE_FUNCTIONAL)
+
+#define sim_disable_functional() \
+ __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_DISABLE_FUNCTIONAL)
+
+#endif /* __DOXYGEN__ */
+
+
+/*
+ * Profiler support.
+ */
+
+/**
+ * Turn profiling on for the current task.
+ *
+ * Note that this has no effect if run in an environment without
+ * profiling support (thus, the proper flags to the simulator must
+ * be supplied).
+ */
+static __inline void
+sim_profiler_enable(void)
+{
+ __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PROFILER_ENABLE);
+}
+
+
+/** Turn profiling off for the current task. */
+static __inline void
+sim_profiler_disable(void)
+{
+ __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PROFILER_DISABLE);
+}
+
+
+/**
+ * Turn profiling on or off for the current task.
+ *
+ * @param enabled If true, turns on profiling. If false, turns it off.
+ *
+ * Note that this has no effect if run in an environment without
+ * profiling support (thus, the proper flags to the simulator must
+ * be supplied).
+ */
+static __inline void
+sim_profiler_set_enabled(int enabled)
+{
+ int val =
+ enabled ? SIM_CONTROL_PROFILER_ENABLE : SIM_CONTROL_PROFILER_DISABLE;
+ __insn_mtspr(SPR_SIM_CONTROL, val);
+}
+
+
+/**
+ * Return true if and only if profiling is currently enabled
+ * for the current task.
+ *
+ * This returns false even if sim_profiler_enable() was called
+ * if the current execution environment does not support profiling.
+ */
+static __inline int
+sim_profiler_is_enabled(void)
+{
+ return ((__insn_mfspr(SPR_SIM_CONTROL) & SIM_PROFILER_ENABLED_MASK) != 0);
+}
+
+
+/**
+ * Reset profiling counters to zero for the current task.
+ *
+ * Resetting can be done while profiling is enabled. It does not affect
+ * the chip-wide profiling counters.
+ */
+static __inline void
+sim_profiler_clear(void)
+{
+ __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PROFILER_CLEAR);
+}
+
+
+/**
+ * Enable specified chip-level profiling counters.
+ *
+ * Does not affect the per-task profiling counters.
+ *
+ * @param mask Either this special value:
+ *
+ * SIM_CHIP_ALL (enables all chip-level components).
+ *
+ * or the bitwise OR of these values:
+ *
+ * SIM_CHIP_MEMCTL (enable all memory controllers)
+ * SIM_CHIP_XAUI (enable all XAUI controllers)
+ * SIM_CHIP_MPIPE (enable all MPIPE controllers)
+ */
+static __inline void
+sim_profiler_chip_enable(unsigned int mask)
+{
+ __insn_mtspr(SPR_SIM_CONTROL, SIM_PROFILER_CHIP_ENABLE_SPR_ARG(mask));
+}
+
+
+/**
+ * Disable specified chip-level profiling counters.
+ *
+ * Does not affect the per-task profiling counters.
+ *
+ * @param mask Either this special value:
+ *
+ * SIM_CHIP_ALL (disables all chip-level components).
+ *
+ * or the bitwise OR of these values:
+ *
+ * SIM_CHIP_MEMCTL (disable all memory controllers)
+ * SIM_CHIP_XAUI (disable all XAUI controllers)
+ * SIM_CHIP_MPIPE (disable all MPIPE controllers)
+ */
+static __inline void
+sim_profiler_chip_disable(unsigned int mask)
+{
+ __insn_mtspr(SPR_SIM_CONTROL, SIM_PROFILER_CHIP_DISABLE_SPR_ARG(mask));
+}
+
+
+/**
+ * Reset specified chip-level profiling counters to zero.
+ *
+ * Does not affect the per-task profiling counters.
+ *
+ * @param mask Either this special value:
+ *
+ * SIM_CHIP_ALL (clears all chip-level components).
+ *
+ * or the bitwise OR of these values:
+ *
+ * SIM_CHIP_MEMCTL (clear all memory controllers)
+ * SIM_CHIP_XAUI (clear all XAUI controllers)
+ * SIM_CHIP_MPIPE (clear all MPIPE controllers)
+ */
+static __inline void
+sim_profiler_chip_clear(unsigned int mask)
+{
+ __insn_mtspr(SPR_SIM_CONTROL, SIM_PROFILER_CHIP_CLEAR_SPR_ARG(mask));
+}
+
+
+/*
+ * Event support.
+ */
+
+#ifndef __DOXYGEN__
+
+static __inline void
+sim_event_begin(unsigned int x)
+{
+#if defined(__tile__) && !defined(__NO_EVENT_SPR__)
+ __insn_mtspr(SPR_EVENT_BEGIN, x);
+#endif
+}
+
+static __inline void
+sim_event_end(unsigned int x)
+{
+#if defined(__tile__) && !defined(__NO_EVENT_SPR__)
+ __insn_mtspr(SPR_EVENT_END, x);
+#endif
+}
+
+#endif /* !__DOXYGEN__ */
+
+#endif /* !__ASSEMBLER__ */
+
+#endif /* !__ARCH_SIM_H__ */
+
+/** @} */
diff --git a/arch/tile/include/arch/sim_def.h b/arch/tile/include/arch/sim_def.h
index 6418fbde063e..7a17082c3773 100644
--- a/arch/tile/include/arch/sim_def.h
+++ b/arch/tile/include/arch/sim_def.h
@@ -1,477 +1,461 @@
-// Copyright 2010 Tilera Corporation. 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, version 2.
-//
-// 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.
-
-//! @file
-//!
-//! Some low-level simulator definitions.
-//!
+/*
+ * Copyright 2010 Tilera Corporation. 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, version 2.
+ *
+ * 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.
+ */
+
+/**
+ * @file
+ *
+ * Some low-level simulator definitions.
+ */
#ifndef __ARCH_SIM_DEF_H__
#define __ARCH_SIM_DEF_H__
-//! Internal: the low bits of the SIM_CONTROL_* SPR values specify
-//! the operation to perform, and the remaining bits are
-//! an operation-specific parameter (often unused).
-//!
+/**
+ * Internal: the low bits of the SIM_CONTROL_* SPR values specify
+ * the operation to perform, and the remaining bits are
+ * an operation-specific parameter (often unused).
+ */
#define _SIM_CONTROL_OPERATOR_BITS 8
-//== Values which can be written to SPR_SIM_CONTROL.
+/*
+ * Values which can be written to SPR_SIM_CONTROL.
+ */
-//! If written to SPR_SIM_CONTROL, stops profiling.
-//!
+/** If written to SPR_SIM_CONTROL, stops profiling. */
#define SIM_CONTROL_PROFILER_DISABLE 0
-//! If written to SPR_SIM_CONTROL, starts profiling.
-//!
+/** If written to SPR_SIM_CONTROL, starts profiling. */
#define SIM_CONTROL_PROFILER_ENABLE 1
-//! If written to SPR_SIM_CONTROL, clears profiling counters.
-//!
+/** If written to SPR_SIM_CONTROL, clears profiling counters. */
#define SIM_CONTROL_PROFILER_CLEAR 2
-//! If written to SPR_SIM_CONTROL, checkpoints the simulator.
-//!
+/** If written to SPR_SIM_CONTROL, checkpoints the simulator. */
#define SIM_CONTROL_CHECKPOINT 3
-//! If written to SPR_SIM_CONTROL, combined with a mask (shifted by 8),
-//! sets the tracing mask to the given mask. See "sim_set_tracing()".
-//!
+/**
+ * If written to SPR_SIM_CONTROL, combined with a mask (shifted by 8),
+ * sets the tracing mask to the given mask. See "sim_set_tracing()".
+ */
#define SIM_CONTROL_SET_TRACING 4
-//! If written to SPR_SIM_CONTROL, combined with a mask (shifted by 8),
-//! dumps the requested items of machine state to the log.
-//!
+/**
+ * If written to SPR_SIM_CONTROL, combined with a mask (shifted by 8),
+ * dumps the requested items of machine state to the log.
+ */
#define SIM_CONTROL_DUMP 5
-//! If written to SPR_SIM_CONTROL, clears chip-level profiling counters.
-//!
+/** If written to SPR_SIM_CONTROL, clears chip-level profiling counters. */
#define SIM_CONTROL_PROFILER_CHIP_CLEAR 6
-//! If written to SPR_SIM_CONTROL, disables chip-level profiling.
-//!
+/** If written to SPR_SIM_CONTROL, disables chip-level profiling. */
#define SIM_CONTROL_PROFILER_CHIP_DISABLE 7
-//! If written to SPR_SIM_CONTROL, enables chip-level profiling.
-//!
+/** If written to SPR_SIM_CONTROL, enables chip-level profiling. */
#define SIM_CONTROL_PROFILER_CHIP_ENABLE 8
-//! If written to SPR_SIM_CONTROL, enables chip-level functional mode
-//!
+/** If written to SPR_SIM_CONTROL, enables chip-level functional mode */
#define SIM_CONTROL_ENABLE_FUNCTIONAL 9
-//! If written to SPR_SIM_CONTROL, disables chip-level functional mode.
-//!
+/** If written to SPR_SIM_CONTROL, disables chip-level functional mode. */
#define SIM_CONTROL_DISABLE_FUNCTIONAL 10
-//! If written to SPR_SIM_CONTROL, enables chip-level functional mode.
-//! All tiles must perform this write for functional mode to be enabled.
-//! Ignored in naked boot mode unless --functional is specified.
-//! WARNING: Only the hypervisor startup code should use this!
-//!
+/**
+ * If written to SPR_SIM_CONTROL, enables chip-level functional mode.
+ * All tiles must perform this write for functional mode to be enabled.
+ * Ignored in naked boot mode unless --functional is specified.
+ * WARNING: Only the hypervisor startup code should use this!
+ */
#define SIM_CONTROL_ENABLE_FUNCTIONAL_BARRIER 11
-//! If written to SPR_SIM_CONTROL, combined with a character (shifted by 8),
-//! writes a string directly to the simulator output. Written to once for
-//! each character in the string, plus a final NUL. Instead of NUL,
-//! you can also use "SIM_PUTC_FLUSH_STRING" or "SIM_PUTC_FLUSH_BINARY".
-//!
-// ISSUE: Document the meaning of "newline", and the handling of NUL.
-//
+/**
+ * If written to SPR_SIM_CONTROL, combined with a character (shifted by 8),
+ * writes a string directly to the simulator output. Written to once for
+ * each character in the string, plus a final NUL. Instead of NUL,
+ * you can also use "SIM_PUTC_FLUSH_STRING" or "SIM_PUTC_FLUSH_BINARY".
+ */
+/* ISSUE: Document the meaning of "newline", and the handling of NUL. */
#define SIM_CONTROL_PUTC 12
-//! If written to SPR_SIM_CONTROL, clears the --grind-coherence state for
-//! this core. This is intended to be used before a loop that will
-//! invalidate the cache by loading new data and evicting all current data.
-//! Generally speaking, this API should only be used by system code.
-//!
+/**
+ * If written to SPR_SIM_CONTROL, clears the --grind-coherence state for
+ * this core. This is intended to be used before a loop that will
+ * invalidate the cache by loading new data and evicting all current data.
+ * Generally speaking, this API should only be used by system code.
+ */
#define SIM_CONTROL_GRINDER_CLEAR 13
-//! If written to SPR_SIM_CONTROL, shuts down the simulator.
-//!
+/** If written to SPR_SIM_CONTROL, shuts down the simulator. */
#define SIM_CONTROL_SHUTDOWN 14
-//! If written to SPR_SIM_CONTROL, combined with a pid (shifted by 8),
-//! indicates that a fork syscall just created the given process.
-//!
+/**
+ * If written to SPR_SIM_CONTROL, combined with a pid (shifted by 8),
+ * indicates that a fork syscall just created the given process.
+ */
#define SIM_CONTROL_OS_FORK 15
-//! If written to SPR_SIM_CONTROL, combined with a pid (shifted by 8),
-//! indicates that an exit syscall was just executed by the given process.
-//!
+/**
+ * If written to SPR_SIM_CONTROL, combined with a pid (shifted by 8),
+ * indicates that an exit syscall was just executed by the given process.
+ */
#define SIM_CONTROL_OS_EXIT 16
-//! If written to SPR_SIM_CONTROL, combined with a pid (shifted by 8),
-//! indicates that the OS just switched to the given process.
-//!
+/**
+ * If written to SPR_SIM_CONTROL, combined with a pid (shifted by 8),
+ * indicates that the OS just switched to the given process.
+ */
#define SIM_CONTROL_OS_SWITCH 17
-//! If written to SPR_SIM_CONTROL, combined with a character (shifted by 8),
-//! indicates that an exec syscall was just executed. Written to once for
-//! each character in the executable name, plus a final NUL.
-//!
+/**
+ * If written to SPR_SIM_CONTROL, combined with a character (shifted by 8),
+ * indicates that an exec syscall was just executed. Written to once for
+ * each character in the executable name, plus a final NUL.
+ */
#define SIM_CONTROL_OS_EXEC 18
-//! If written to SPR_SIM_CONTROL, combined with a character (shifted by 8),
-//! indicates that an interpreter (PT_INTERP) was loaded. Written to once
-//! for each character in "ADDR:PATH", plus a final NUL, where "ADDR" is a
-//! hex load address starting with "0x", and "PATH" is the executable name.
-//!
+/**
+ * If written to SPR_SIM_CONTROL, combined with a character (shifted by 8),
+ * indicates that an interpreter (PT_INTERP) was loaded. Written to once
+ * for each character in "ADDR:PATH", plus a final NUL, where "ADDR" is a
+ * hex load address starting with "0x", and "PATH" is the executable name.
+ */
#define SIM_CONTROL_OS_INTERP 19
-//! If written to SPR_SIM_CONTROL, combined with a character (shifted by 8),
-//! indicates that a dll was loaded. Written to once for each character
-//! in "ADDR:PATH", plus a final NUL, where "ADDR" is a hexadecimal load
-//! address starting with "0x", and "PATH" is the executable name.
-//!
+/**
+ * If written to SPR_SIM_CONTROL, combined with a character (shifted by 8),
+ * indicates that a dll was loaded. Written to once for each character
+ * in "ADDR:PATH", plus a final NUL, where "ADDR" is a hexadecimal load
+ * address starting with "0x", and "PATH" is the executable name.
+ */
#define SIM_CONTROL_DLOPEN 20
-//! If written to SPR_SIM_CONTROL, combined with a character (shifted by 8),
-//! indicates that a dll was unloaded. Written to once for each character
-//! in "ADDR", plus a final NUL, where "ADDR" is a hexadecimal load
-//! address starting with "0x".
-//!
+/**
+ * If written to SPR_SIM_CONTROL, combined with a character (shifted by 8),
+ * indicates that a dll was unloaded. Written to once for each character
+ * in "ADDR", plus a final NUL, where "ADDR" is a hexadecimal load
+ * address starting with "0x".
+ */
#define SIM_CONTROL_DLCLOSE 21
-//! If written to SPR_SIM_CONTROL, combined with a flag (shifted by 8),
-//! indicates whether to allow data reads to remotely-cached
-//! dirty cache lines to be cached locally without grinder warnings or
-//! assertions (used by Linux kernel fast memcpy).
-//!
+/**
+ * If written to SPR_SIM_CONTROL, combined with a flag (shifted by 8),
+ * indicates whether to allow data reads to remotely-cached
+ * dirty cache lines to be cached locally without grinder warnings or
+ * assertions (used by Linux kernel fast memcpy).
+ */
#define SIM_CONTROL_ALLOW_MULTIPLE_CACHING 22
-//! If written to SPR_SIM_CONTROL, enables memory tracing.
-//!
+/** If written to SPR_SIM_CONTROL, enables memory tracing. */
#define SIM_CONTROL_ENABLE_MEM_LOGGING 23
-//! If written to SPR_SIM_CONTROL, disables memory tracing.
-//!
+/** If written to SPR_SIM_CONTROL, disables memory tracing. */
#define SIM_CONTROL_DISABLE_MEM_LOGGING 24
-//! If written to SPR_SIM_CONTROL, changes the shaping parameters of one of
-//! the gbe or xgbe shims. Must specify the shim id, the type, the units, and
-//! the rate, as defined in SIM_SHAPING_SPR_ARG.
-//!
+/**
+ * If written to SPR_SIM_CONTROL, changes the shaping parameters of one of
+ * the gbe or xgbe shims. Must specify the shim id, the type, the units, and
+ * the rate, as defined in SIM_SHAPING_SPR_ARG.
+ */
#define SIM_CONTROL_SHAPING 25
-//! If written to SPR_SIM_CONTROL, combined with character (shifted by 8),
-//! requests that a simulator command be executed. Written to once for each
-//! character in the command, plus a final NUL.
-//!
+/**
+ * If written to SPR_SIM_CONTROL, combined with character (shifted by 8),
+ * requests that a simulator command be executed. Written to once for each
+ * character in the command, plus a final NUL.
+ */
#define SIM_CONTROL_COMMAND 26
-//! If written to SPR_SIM_CONTROL, indicates that the simulated system
-//! is panicking, to allow debugging via --debug-on-panic.
-//!
+/**
+ * If written to SPR_SIM_CONTROL, indicates that the simulated system
+ * is panicking, to allow debugging via --debug-on-panic.
+ */
#define SIM_CONTROL_PANIC 27
-//! If written to SPR_SIM_CONTROL, triggers a simulator syscall.
-//! See "sim_syscall()" for more info.
-//!
+/**
+ * If written to SPR_SIM_CONTROL, triggers a simulator syscall.
+ * See "sim_syscall()" for more info.
+ */
#define SIM_CONTROL_SYSCALL 32
-//! If written to SPR_SIM_CONTROL, combined with a pid (shifted by 8),
-//! provides the pid that subsequent SIM_CONTROL_OS_FORK writes should
-//! use as the pid, rather than the default previous SIM_CONTROL_OS_SWITCH.
-//!
+/**
+ * If written to SPR_SIM_CONTROL, combined with a pid (shifted by 8),
+ * provides the pid that subsequent SIM_CONTROL_OS_FORK writes should
+ * use as the pid, rather than the default previous SIM_CONTROL_OS_SWITCH.
+ */
#define SIM_CONTROL_OS_FORK_PARENT 33
-//! If written to SPR_SIM_CONTROL, combined with a mPIPE shim number
-//! (shifted by 8), clears the pending magic data section. The cleared
-//! pending magic data section and any subsequently appended magic bytes
-//! will only take effect when the classifier blast programmer is run.
+/**
+ * If written to SPR_SIM_CONTROL, combined with a mPIPE shim number
+ * (shifted by 8), clears the pending magic data section. The cleared
+ * pending magic data section and any subsequently appended magic bytes
+ * will only take effect when the classifier blast programmer is run.
+ */
#define SIM_CONTROL_CLEAR_MPIPE_MAGIC_BYTES 34
-//! If written to SPR_SIM_CONTROL, combined with a mPIPE shim number
-//! (shifted by 8) and a byte of data (shifted by 16), appends that byte
-//! to the shim's pending magic data section. The pending magic data
-//! section takes effect when the classifier blast programmer is run.
+/**
+ * If written to SPR_SIM_CONTROL, combined with a mPIPE shim number
+ * (shifted by 8) and a byte of data (shifted by 16), appends that byte
+ * to the shim's pending magic data section. The pending magic data
+ * section takes effect when the classifier blast programmer is run.
+ */
#define SIM_CONTROL_APPEND_MPIPE_MAGIC_BYTE 35
-//! If written to SPR_SIM_CONTROL, combined with a mPIPE shim number
-//! (shifted by 8), an enable=1/disable=0 bit (shifted by 16), and a
-//! mask of links (shifted by 32), enable or disable the corresponding
-//! mPIPE links.
+/**
+ * If written to SPR_SIM_CONTROL, combined with a mPIPE shim number
+ * (shifted by 8), an enable=1/disable=0 bit (shifted by 16), and a
+ * mask of links (shifted by 32), enable or disable the corresponding
+ * mPIPE links.
+ */
#define SIM_CONTROL_ENABLE_MPIPE_LINK_MAGIC_BYTE 36
-//== Syscall numbers for use with "sim_syscall()".
-//! Syscall number for sim_add_watchpoint().
-//!
+/*
+ * Syscall numbers for use with "sim_syscall()".
+ */
+
+/** Syscall number for sim_add_watchpoint(). */
#define SIM_SYSCALL_ADD_WATCHPOINT 2
-//! Syscall number for sim_remove_watchpoint().
-//!
+/** Syscall number for sim_remove_watchpoint(). */
#define SIM_SYSCALL_REMOVE_WATCHPOINT 3
-//! Syscall number for sim_query_watchpoint().
-//!
+/** Syscall number for sim_query_watchpoint(). */
#define SIM_SYSCALL_QUERY_WATCHPOINT 4
-//! Syscall number that asserts that the cache lines whose 64-bit PA
-//! is passed as the second argument to sim_syscall(), and over a
-//! range passed as the third argument, are no longer in cache.
-//! The simulator raises an error if this is not the case.
-//!
+/**
+ * Syscall number that asserts that the cache lines whose 64-bit PA
+ * is passed as the second argument to sim_syscall(), and over a
+ * range passed as the third argument, are no longer in cache.
+ * The simulator raises an error if this is not the case.
+ */
#define SIM_SYSCALL_VALIDATE_LINES_EVICTED 5
-//== Bit masks which can be shifted by 8, combined with
-//== SIM_CONTROL_SET_TRACING, and written to SPR_SIM_CONTROL.
+/*
+ * Bit masks which can be shifted by 8, combined with
+ * SIM_CONTROL_SET_TRACING, and written to SPR_SIM_CONTROL.
+ */
-//! @addtogroup arch_sim
-//! @{
+/**
+ * @addtogroup arch_sim
+ * @{
+ */
-//! Enable --trace-cycle when passed to simulator_set_tracing().
-//!
+/** Enable --trace-cycle when passed to simulator_set_tracing(). */
#define SIM_TRACE_CYCLES 0x01
-//! Enable --trace-router when passed to simulator_set_tracing().
-//!
+/** Enable --trace-router when passed to simulator_set_tracing(). */
#define SIM_TRACE_ROUTER 0x02
-//! Enable --trace-register-writes when passed to simulator_set_tracing().
-//!
+/** Enable --trace-register-writes when passed to simulator_set_tracing(). */
#define SIM_TRACE_REGISTER_WRITES 0x04
-//! Enable --trace-disasm when passed to simulator_set_tracing().
-//!
+/** Enable --trace-disasm when passed to simulator_set_tracing(). */
#define SIM_TRACE_DISASM 0x08
-//! Enable --trace-stall-info when passed to simulator_set_tracing().
-//!
+/** Enable --trace-stall-info when passed to simulator_set_tracing(). */
#define SIM_TRACE_STALL_INFO 0x10
-//! Enable --trace-memory-controller when passed to simulator_set_tracing().
-//!
+/** Enable --trace-memory-controller when passed to simulator_set_tracing(). */
#define SIM_TRACE_MEMORY_CONTROLLER 0x20
-//! Enable --trace-l2 when passed to simulator_set_tracing().
-//!
+/** Enable --trace-l2 when passed to simulator_set_tracing(). */
#define SIM_TRACE_L2_CACHE 0x40
-//! Enable --trace-lines when passed to simulator_set_tracing().
-//!
+/** Enable --trace-lines when passed to simulator_set_tracing(). */
#define SIM_TRACE_LINES 0x80
-//! Turn off all tracing when passed to simulator_set_tracing().
-//!
+/** Turn off all tracing when passed to simulator_set_tracing(). */
#define SIM_TRACE_NONE 0
-//! Turn on all tracing when passed to simulator_set_tracing().
-//!
+/** Turn on all tracing when passed to simulator_set_tracing(). */
#define SIM_TRACE_ALL (-1)
-//! @}
+/** @} */
-//! Computes the value to write to SPR_SIM_CONTROL to set tracing flags.
-//!
+/** Computes the value to write to SPR_SIM_CONTROL to set tracing flags. */
#define SIM_TRACE_SPR_ARG(mask) \
(SIM_CONTROL_SET_TRACING | ((mask) << _SIM_CONTROL_OPERATOR_BITS))
-//== Bit masks which can be shifted by 8, combined with
-//== SIM_CONTROL_DUMP, and written to SPR_SIM_CONTROL.
+/*
+ * Bit masks which can be shifted by 8, combined with
+ * SIM_CONTROL_DUMP, and written to SPR_SIM_CONTROL.
+ */
-//! @addtogroup arch_sim
-//! @{
+/**
+ * @addtogroup arch_sim
+ * @{
+ */
-//! Dump the general-purpose registers.
-//!
+/** Dump the general-purpose registers. */
#define SIM_DUMP_REGS 0x001
-//! Dump the SPRs.
-//!
+/** Dump the SPRs. */
#define SIM_DUMP_SPRS 0x002
-//! Dump the ITLB.
-//!
+/** Dump the ITLB. */
#define SIM_DUMP_ITLB 0x004
-//! Dump the DTLB.
-//!
+/** Dump the DTLB. */
#define SIM_DUMP_DTLB 0x008
-//! Dump the L1 I-cache.
-//!
+/** Dump the L1 I-cache. */
#define SIM_DUMP_L1I 0x010
-//! Dump the L1 D-cache.
-//!
+/** Dump the L1 D-cache. */
#define SIM_DUMP_L1D 0x020
-//! Dump the L2 cache.
-//!
+/** Dump the L2 cache. */
#define SIM_DUMP_L2 0x040
-//! Dump the switch registers.
-//!
+/** Dump the switch registers. */
#define SIM_DUMP_SNREGS 0x080
-//! Dump the switch ITLB.
-//!
+/** Dump the switch ITLB. */
#define SIM_DUMP_SNITLB 0x100
-//! Dump the switch L1 I-cache.
-//!
+/** Dump the switch L1 I-cache. */
#define SIM_DUMP_SNL1I 0x200
-//! Dump the current backtrace.
-//!
+/** Dump the current backtrace. */
#define SIM_DUMP_BACKTRACE 0x400
-//! Only dump valid lines in caches.
-//!
+/** Only dump valid lines in caches. */
#define SIM_DUMP_VALID_LINES 0x800
-//! Dump everything that is dumpable.
-//!
+/** Dump everything that is dumpable. */
#define SIM_DUMP_ALL (-1 & ~SIM_DUMP_VALID_LINES)
-// @}
+/** @} */
-//! Computes the value to write to SPR_SIM_CONTROL to dump machine state.
-//!
+/** Computes the value to write to SPR_SIM_CONTROL to dump machine state. */
#define SIM_DUMP_SPR_ARG(mask) \
(SIM_CONTROL_DUMP | ((mask) << _SIM_CONTROL_OPERATOR_BITS))
-//== Bit masks which can be shifted by 8, combined with
-//== SIM_CONTROL_PROFILER_CHIP_xxx, and written to SPR_SIM_CONTROL.
+/*
+ * Bit masks which can be shifted by 8, combined with
+ * SIM_CONTROL_PROFILER_CHIP_xxx, and written to SPR_SIM_CONTROL.
+ */
-//! @addtogroup arch_sim
-//! @{
+/**
+ * @addtogroup arch_sim
+ * @{
+ */
-//! Use with with SIM_PROFILER_CHIP_xxx to control the memory controllers.
-//!
+/** Use with with SIM_PROFILER_CHIP_xxx to control the memory controllers. */
#define SIM_CHIP_MEMCTL 0x001
-//! Use with with SIM_PROFILER_CHIP_xxx to control the XAUI interface.
-//!
+/** Use with with SIM_PROFILER_CHIP_xxx to control the XAUI interface. */
#define SIM_CHIP_XAUI 0x002
-//! Use with with SIM_PROFILER_CHIP_xxx to control the PCIe interface.
-//!
+/** Use with with SIM_PROFILER_CHIP_xxx to control the PCIe interface. */
#define SIM_CHIP_PCIE 0x004
-//! Use with with SIM_PROFILER_CHIP_xxx to control the MPIPE interface.
-//!
+/** Use with with SIM_PROFILER_CHIP_xxx to control the MPIPE interface. */
#define SIM_CHIP_MPIPE 0x008
-//! Reference all chip devices.
-//!
+/** Use with with SIM_PROFILER_CHIP_xxx to control the TRIO interface. */
+#define SIM_CHIP_TRIO 0x010
+
+/** Reference all chip devices. */
#define SIM_CHIP_ALL (-1)
-//! @}
+/** @} */
-//! Computes the value to write to SPR_SIM_CONTROL to clear chip statistics.
-//!
+/** Computes the value to write to SPR_SIM_CONTROL to clear chip statistics. */
#define SIM_PROFILER_CHIP_CLEAR_SPR_ARG(mask) \
(SIM_CONTROL_PROFILER_CHIP_CLEAR | ((mask) << _SIM_CONTROL_OPERATOR_BITS))
-//! Computes the value to write to SPR_SIM_CONTROL to disable chip statistics.
-//!
+/** Computes the value to write to SPR_SIM_CONTROL to disable chip statistics.*/
#define SIM_PROFILER_CHIP_DISABLE_SPR_ARG(mask) \
(SIM_CONTROL_PROFILER_CHIP_DISABLE | ((mask) << _SIM_CONTROL_OPERATOR_BITS))
-//! Computes the value to write to SPR_SIM_CONTROL to enable chip statistics.
-//!
+/** Computes the value to write to SPR_SIM_CONTROL to enable chip statistics. */
#define SIM_PROFILER_CHIP_ENABLE_SPR_ARG(mask) \
(SIM_CONTROL_PROFILER_CHIP_ENABLE | ((mask) << _SIM_CONTROL_OPERATOR_BITS))
-// Shim bitrate controls.
+/* Shim bitrate controls. */
-//! The number of bits used to store the shim id.
-//!
+/** The number of bits used to store the shim id. */
#define SIM_CONTROL_SHAPING_SHIM_ID_BITS 3
-//! @addtogroup arch_sim
-//! @{
+/**
+ * @addtogroup arch_sim
+ * @{
+ */
-//! Change the gbe 0 bitrate.
-//!
+/** Change the gbe 0 bitrate. */
#define SIM_CONTROL_SHAPING_GBE_0 0x0
-//! Change the gbe 1 bitrate.
-//!
+/** Change the gbe 1 bitrate. */
#define SIM_CONTROL_SHAPING_GBE_1 0x1
-//! Change the gbe 2 bitrate.
-//!
+/** Change the gbe 2 bitrate. */
#define SIM_CONTROL_SHAPING_GBE_2 0x2
-//! Change the gbe 3 bitrate.
-//!
+/** Change the gbe 3 bitrate. */
#define SIM_CONTROL_SHAPING_GBE_3 0x3
-//! Change the xgbe 0 bitrate.
-//!
+/** Change the xgbe 0 bitrate. */
#define SIM_CONTROL_SHAPING_XGBE_0 0x4
-//! Change the xgbe 1 bitrate.
-//!
+/** Change the xgbe 1 bitrate. */
#define SIM_CONTROL_SHAPING_XGBE_1 0x5
-//! The type of shaping to do.
-//!
+/** The type of shaping to do. */
#define SIM_CONTROL_SHAPING_TYPE_BITS 2
-//! Control the multiplier.
-//!
+/** Control the multiplier. */
#define SIM_CONTROL_SHAPING_MULTIPLIER 0
-//! Control the PPS.
-//!
+/** Control the PPS. */
#define SIM_CONTROL_SHAPING_PPS 1
-//! Control the BPS.
-//!
+/** Control the BPS. */
#define SIM_CONTROL_SHAPING_BPS 2
-//! The number of bits for the units for the shaping parameter.
-//!
+/** The number of bits for the units for the shaping parameter. */
#define SIM_CONTROL_SHAPING_UNITS_BITS 2
-//! Provide a number in single units.
-//!
+/** Provide a number in single units. */
#define SIM_CONTROL_SHAPING_UNITS_SINGLE 0
-//! Provide a number in kilo units.
-//!
+/** Provide a number in kilo units. */
#define SIM_CONTROL_SHAPING_UNITS_KILO 1
-//! Provide a number in mega units.
-//!
+/** Provide a number in mega units. */
#define SIM_CONTROL_SHAPING_UNITS_MEGA 2
-//! Provide a number in giga units.
-//!
+/** Provide a number in giga units. */
#define SIM_CONTROL_SHAPING_UNITS_GIGA 3
-// @}
+/** @} */
-//! How many bits are available for the rate.
-//!
+/** How many bits are available for the rate. */
#define SIM_CONTROL_SHAPING_RATE_BITS \
(32 - (_SIM_CONTROL_OPERATOR_BITS + \
SIM_CONTROL_SHAPING_SHIM_ID_BITS + \
SIM_CONTROL_SHAPING_TYPE_BITS + \
SIM_CONTROL_SHAPING_UNITS_BITS))
-//! Computes the value to write to SPR_SIM_CONTROL to change a bitrate.
-//!
+/** Computes the value to write to SPR_SIM_CONTROL to change a bitrate. */
#define SIM_SHAPING_SPR_ARG(shim, type, units, rate) \
(SIM_CONTROL_SHAPING | \
((shim) | \
@@ -483,30 +467,36 @@
SIM_CONTROL_SHAPING_UNITS_BITS))) << _SIM_CONTROL_OPERATOR_BITS)
-//== Values returned when reading SPR_SIM_CONTROL.
-// ISSUE: These names should share a longer common prefix.
+/*
+ * Values returned when reading SPR_SIM_CONTROL.
+ * ISSUE: These names should share a longer common prefix.
+ */
-//! When reading SPR_SIM_CONTROL, the mask of simulator tracing bits
-//! (SIM_TRACE_xxx values).
-//!
+/**
+ * When reading SPR_SIM_CONTROL, the mask of simulator tracing bits
+ * (SIM_TRACE_xxx values).
+ */
#define SIM_TRACE_FLAG_MASK 0xFFFF
-//! When reading SPR_SIM_CONTROL, the mask for whether profiling is enabled.
-//!
+/** When reading SPR_SIM_CONTROL, the mask for whether profiling is enabled. */
#define SIM_PROFILER_ENABLED_MASK 0x10000
-//== Special arguments for "SIM_CONTROL_PUTC".
+/*
+ * Special arguments for "SIM_CONTROL_PUTC".
+ */
-//! Flag value for forcing a PUTC string-flush, including
-//! coordinate/cycle prefix and newline.
-//!
+/**
+ * Flag value for forcing a PUTC string-flush, including
+ * coordinate/cycle prefix and newline.
+ */
#define SIM_PUTC_FLUSH_STRING 0x100
-//! Flag value for forcing a PUTC binary-data-flush, which skips the
-//! prefix and does not append a newline.
-//!
+/**
+ * Flag value for forcing a PUTC binary-data-flush, which skips the
+ * prefix and does not append a newline.
+ */
#define SIM_PUTC_FLUSH_BINARY 0x101
-#endif //__ARCH_SIM_DEF_H__
+#endif /* __ARCH_SIM_DEF_H__ */
diff --git a/arch/tile/include/arch/spr_def.h b/arch/tile/include/arch/spr_def.h
index c8fdbd9a45e6..442fcba0d122 100644
--- a/arch/tile/include/arch/spr_def.h
+++ b/arch/tile/include/arch/spr_def.h
@@ -12,8 +12,93 @@
* more details.
*/
+/*
+ * In addition to including the proper base SPR definition file, depending
+ * on machine architecture, this file defines several macros which allow
+ * kernel code to use protection-level dependent SPRs without worrying
+ * about which PL it's running at. In these macros, the PL that the SPR
+ * or interrupt number applies to is replaced by K.
+ */
+
+#if CONFIG_KERNEL_PL != 1 && CONFIG_KERNEL_PL != 2
+#error CONFIG_KERNEL_PL must be 1 or 2
+#endif
+
+/* Concatenate 4 strings. */
+#define __concat4(a, b, c, d) a ## b ## c ## d
+#define _concat4(a, b, c, d) __concat4(a, b, c, d)
+
#ifdef __tilegx__
#include <arch/spr_def_64.h>
+
+/* TILE-Gx dependent, protection-level dependent SPRs. */
+
+#define SPR_INTERRUPT_MASK_K \
+ _concat4(SPR_INTERRUPT_MASK_, CONFIG_KERNEL_PL,,)
+#define SPR_INTERRUPT_MASK_SET_K \
+ _concat4(SPR_INTERRUPT_MASK_SET_, CONFIG_KERNEL_PL,,)
+#define SPR_INTERRUPT_MASK_RESET_K \
+ _concat4(SPR_INTERRUPT_MASK_RESET_, CONFIG_KERNEL_PL,,)
+#define SPR_INTERRUPT_VECTOR_BASE_K \
+ _concat4(SPR_INTERRUPT_VECTOR_BASE_, CONFIG_KERNEL_PL,,)
+
+#define SPR_IPI_MASK_K \
+ _concat4(SPR_IPI_MASK_, CONFIG_KERNEL_PL,,)
+#define SPR_IPI_MASK_RESET_K \
+ _concat4(SPR_IPI_MASK_RESET_, CONFIG_KERNEL_PL,,)
+#define SPR_IPI_MASK_SET_K \
+ _concat4(SPR_IPI_MASK_SET_, CONFIG_KERNEL_PL,,)
+#define SPR_IPI_EVENT_K \
+ _concat4(SPR_IPI_EVENT_, CONFIG_KERNEL_PL,,)
+#define SPR_IPI_EVENT_RESET_K \
+ _concat4(SPR_IPI_EVENT_RESET_, CONFIG_KERNEL_PL,,)
+#define SPR_IPI_MASK_SET_K \
+ _concat4(SPR_IPI_MASK_SET_, CONFIG_KERNEL_PL,,)
+#define INT_IPI_K \
+ _concat4(INT_IPI_, CONFIG_KERNEL_PL,,)
+
+#define SPR_SINGLE_STEP_CONTROL_K \
+ _concat4(SPR_SINGLE_STEP_CONTROL_, CONFIG_KERNEL_PL,,)
+#define SPR_SINGLE_STEP_EN_K_K \
+ _concat4(SPR_SINGLE_STEP_EN_, CONFIG_KERNEL_PL, _, CONFIG_KERNEL_PL)
+#define INT_SINGLE_STEP_K \
+ _concat4(INT_SINGLE_STEP_, CONFIG_KERNEL_PL,,)
+
#else
#include <arch/spr_def_32.h>
+
+/* TILEPro dependent, protection-level dependent SPRs. */
+
+#define SPR_INTERRUPT_MASK_K_0 \
+ _concat4(SPR_INTERRUPT_MASK_, CONFIG_KERNEL_PL, _0,)
+#define SPR_INTERRUPT_MASK_K_1 \
+ _concat4(SPR_INTERRUPT_MASK_, CONFIG_KERNEL_PL, _1,)
+#define SPR_INTERRUPT_MASK_SET_K_0 \
+ _concat4(SPR_INTERRUPT_MASK_SET_, CONFIG_KERNEL_PL, _0,)
+#define SPR_INTERRUPT_MASK_SET_K_1 \
+ _concat4(SPR_INTERRUPT_MASK_SET_, CONFIG_KERNEL_PL, _1,)
+#define SPR_INTERRUPT_MASK_RESET_K_0 \
+ _concat4(SPR_INTERRUPT_MASK_RESET_, CONFIG_KERNEL_PL, _0,)
+#define SPR_INTERRUPT_MASK_RESET_K_1 \
+ _concat4(SPR_INTERRUPT_MASK_RESET_, CONFIG_KERNEL_PL, _1,)
+
#endif
+
+/* Generic protection-level dependent SPRs. */
+
+#define SPR_SYSTEM_SAVE_K_0 \
+ _concat4(SPR_SYSTEM_SAVE_, CONFIG_KERNEL_PL, _0,)
+#define SPR_SYSTEM_SAVE_K_1 \
+ _concat4(SPR_SYSTEM_SAVE_, CONFIG_KERNEL_PL, _1,)
+#define SPR_SYSTEM_SAVE_K_2 \
+ _concat4(SPR_SYSTEM_SAVE_, CONFIG_KERNEL_PL, _2,)
+#define SPR_SYSTEM_SAVE_K_3 \
+ _concat4(SPR_SYSTEM_SAVE_, CONFIG_KERNEL_PL, _3,)
+#define SPR_EX_CONTEXT_K_0 \
+ _concat4(SPR_EX_CONTEXT_, CONFIG_KERNEL_PL, _0,)
+#define SPR_EX_CONTEXT_K_1 \
+ _concat4(SPR_EX_CONTEXT_, CONFIG_KERNEL_PL, _1,)
+#define SPR_INTCTRL_K_STATUS \
+ _concat4(SPR_INTCTRL_, CONFIG_KERNEL_PL, _STATUS,)
+#define INT_INTCTRL_K \
+ _concat4(INT_INTCTRL_, CONFIG_KERNEL_PL,,)
diff --git a/arch/tile/include/arch/spr_def_32.h b/arch/tile/include/arch/spr_def_32.h
index b4fc06864df6..bbc1f4c924ee 100644
--- a/arch/tile/include/arch/spr_def_32.h
+++ b/arch/tile/include/arch/spr_def_32.h
@@ -56,58 +56,93 @@
#define SPR_EX_CONTEXT_1_1__ICS_SHIFT 2
#define SPR_EX_CONTEXT_1_1__ICS_RMASK 0x1
#define SPR_EX_CONTEXT_1_1__ICS_MASK 0x4
+#define SPR_EX_CONTEXT_2_0 0x4605
+#define SPR_EX_CONTEXT_2_1 0x4606
+#define SPR_EX_CONTEXT_2_1__PL_SHIFT 0
+#define SPR_EX_CONTEXT_2_1__PL_RMASK 0x3
+#define SPR_EX_CONTEXT_2_1__PL_MASK 0x3
+#define SPR_EX_CONTEXT_2_1__ICS_SHIFT 2
+#define SPR_EX_CONTEXT_2_1__ICS_RMASK 0x1
+#define SPR_EX_CONTEXT_2_1__ICS_MASK 0x4
#define SPR_FAIL 0x4e09
#define SPR_INTCTRL_0_STATUS 0x4a07
#define SPR_INTCTRL_1_STATUS 0x4807
+#define SPR_INTCTRL_2_STATUS 0x4607
#define SPR_INTERRUPT_CRITICAL_SECTION 0x4e0a
#define SPR_INTERRUPT_MASK_0_0 0x4a08
#define SPR_INTERRUPT_MASK_0_1 0x4a09
#define SPR_INTERRUPT_MASK_1_0 0x4809
#define SPR_INTERRUPT_MASK_1_1 0x480a
+#define SPR_INTERRUPT_MASK_2_0 0x4608
+#define SPR_INTERRUPT_MASK_2_1 0x4609
#define SPR_INTERRUPT_MASK_RESET_0_0 0x4a0a
#define SPR_INTERRUPT_MASK_RESET_0_1 0x4a0b
#define SPR_INTERRUPT_MASK_RESET_1_0 0x480b
#define SPR_INTERRUPT_MASK_RESET_1_1 0x480c
+#define SPR_INTERRUPT_MASK_RESET_2_0 0x460a
+#define SPR_INTERRUPT_MASK_RESET_2_1 0x460b
#define SPR_INTERRUPT_MASK_SET_0_0 0x4a0c
#define SPR_INTERRUPT_MASK_SET_0_1 0x4a0d
#define SPR_INTERRUPT_MASK_SET_1_0 0x480d
#define SPR_INTERRUPT_MASK_SET_1_1 0x480e
+#define SPR_INTERRUPT_MASK_SET_2_0 0x460c
+#define SPR_INTERRUPT_MASK_SET_2_1 0x460d
#define SPR_MPL_DMA_CPL_SET_0 0x5800
#define SPR_MPL_DMA_CPL_SET_1 0x5801
+#define SPR_MPL_DMA_CPL_SET_2 0x5802
#define SPR_MPL_DMA_NOTIFY_SET_0 0x3800
#define SPR_MPL_DMA_NOTIFY_SET_1 0x3801
+#define SPR_MPL_DMA_NOTIFY_SET_2 0x3802
#define SPR_MPL_INTCTRL_0_SET_0 0x4a00
#define SPR_MPL_INTCTRL_0_SET_1 0x4a01
+#define SPR_MPL_INTCTRL_0_SET_2 0x4a02
#define SPR_MPL_INTCTRL_1_SET_0 0x4800
#define SPR_MPL_INTCTRL_1_SET_1 0x4801
+#define SPR_MPL_INTCTRL_1_SET_2 0x4802
+#define SPR_MPL_INTCTRL_2_SET_0 0x4600
+#define SPR_MPL_INTCTRL_2_SET_1 0x4601
+#define SPR_MPL_INTCTRL_2_SET_2 0x4602
#define SPR_MPL_SN_ACCESS_SET_0 0x0800
#define SPR_MPL_SN_ACCESS_SET_1 0x0801
+#define SPR_MPL_SN_ACCESS_SET_2 0x0802
#define SPR_MPL_SN_CPL_SET_0 0x5a00
#define SPR_MPL_SN_CPL_SET_1 0x5a01
+#define SPR_MPL_SN_CPL_SET_2 0x5a02
#define SPR_MPL_SN_FIREWALL_SET_0 0x2c00
#define SPR_MPL_SN_FIREWALL_SET_1 0x2c01
+#define SPR_MPL_SN_FIREWALL_SET_2 0x2c02
#define SPR_MPL_SN_NOTIFY_SET_0 0x2a00
#define SPR_MPL_SN_NOTIFY_SET_1 0x2a01
+#define SPR_MPL_SN_NOTIFY_SET_2 0x2a02
#define SPR_MPL_UDN_ACCESS_SET_0 0x0c00
#define SPR_MPL_UDN_ACCESS_SET_1 0x0c01
+#define SPR_MPL_UDN_ACCESS_SET_2 0x0c02
#define SPR_MPL_UDN_AVAIL_SET_0 0x4000
#define SPR_MPL_UDN_AVAIL_SET_1 0x4001
+#define SPR_MPL_UDN_AVAIL_SET_2 0x4002
#define SPR_MPL_UDN_CA_SET_0 0x3c00
#define SPR_MPL_UDN_CA_SET_1 0x3c01
+#define SPR_MPL_UDN_CA_SET_2 0x3c02
#define SPR_MPL_UDN_COMPLETE_SET_0 0x1400
#define SPR_MPL_UDN_COMPLETE_SET_1 0x1401
+#define SPR_MPL_UDN_COMPLETE_SET_2 0x1402
#define SPR_MPL_UDN_FIREWALL_SET_0 0x3000
#define SPR_MPL_UDN_FIREWALL_SET_1 0x3001
+#define SPR_MPL_UDN_FIREWALL_SET_2 0x3002
#define SPR_MPL_UDN_REFILL_SET_0 0x1000
#define SPR_MPL_UDN_REFILL_SET_1 0x1001
+#define SPR_MPL_UDN_REFILL_SET_2 0x1002
#define SPR_MPL_UDN_TIMER_SET_0 0x3600
#define SPR_MPL_UDN_TIMER_SET_1 0x3601
+#define SPR_MPL_UDN_TIMER_SET_2 0x3602
#define SPR_MPL_WORLD_ACCESS_SET_0 0x4e00
#define SPR_MPL_WORLD_ACCESS_SET_1 0x4e01
+#define SPR_MPL_WORLD_ACCESS_SET_2 0x4e02
#define SPR_PASS 0x4e0b
#define SPR_PERF_COUNT_0 0x4205
#define SPR_PERF_COUNT_1 0x4206
#define SPR_PERF_COUNT_CTL 0x4207
+#define SPR_PERF_COUNT_DN_CTL 0x4210
#define SPR_PERF_COUNT_STS 0x4208
#define SPR_PROC_STATUS 0x4f00
#define SPR_SIM_CONTROL 0x4e0c
@@ -124,6 +159,10 @@
#define SPR_SYSTEM_SAVE_1_1 0x4901
#define SPR_SYSTEM_SAVE_1_2 0x4902
#define SPR_SYSTEM_SAVE_1_3 0x4903
+#define SPR_SYSTEM_SAVE_2_0 0x4700
+#define SPR_SYSTEM_SAVE_2_1 0x4701
+#define SPR_SYSTEM_SAVE_2_2 0x4702
+#define SPR_SYSTEM_SAVE_2_3 0x4703
#define SPR_TILE_COORD 0x4c17
#define SPR_TILE_RTF_HWM 0x4e10
#define SPR_TILE_TIMER_CONTROL 0x3205
diff --git a/arch/tile/include/asm/backtrace.h b/arch/tile/include/asm/backtrace.h
index 758ca4619d50..f18887d82399 100644
--- a/arch/tile/include/asm/backtrace.h
+++ b/arch/tile/include/asm/backtrace.h
@@ -146,7 +146,10 @@ enum {
CALLER_SP_IN_R52_BASE = 4,
- CALLER_SP_OFFSET_BASE = 8
+ CALLER_SP_OFFSET_BASE = 8,
+
+ /* Marks the entry point of certain functions. */
+ ENTRY_POINT_INFO_OP = 16
};
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/compat.h b/arch/tile/include/asm/compat.h
index 8b60ec8b2d19..c3ae570c0a5d 100644
--- a/arch/tile/include/asm/compat.h
+++ b/arch/tile/include/asm/compat.h
@@ -216,15 +216,16 @@ struct compat_siginfo;
struct compat_sigaltstack;
long compat_sys_execve(const char __user *path,
const compat_uptr_t __user *argv,
- const compat_uptr_t __user *envp);
+ const compat_uptr_t __user *envp, struct pt_regs *);
long compat_sys_rt_sigaction(int sig, struct compat_sigaction __user *act,
struct compat_sigaction __user *oact,
size_t sigsetsize);
long compat_sys_rt_sigqueueinfo(int pid, int sig,
struct compat_siginfo __user *uinfo);
-long compat_sys_rt_sigreturn(void);
+long compat_sys_rt_sigreturn(struct pt_regs *);
long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
- struct compat_sigaltstack __user *uoss_ptr);
+ struct compat_sigaltstack __user *uoss_ptr,
+ struct pt_regs *);
long compat_sys_truncate64(char __user *filename, u32 dummy, u32 low, u32 high);
long compat_sys_ftruncate64(unsigned int fd, u32 dummy, u32 low, u32 high);
long compat_sys_pread64(unsigned int fd, char __user *ubuf, size_t count,
@@ -255,4 +256,12 @@ long tile_compat_sys_ptrace(compat_long_t request, compat_long_t pid,
/* Tilera Linux syscalls that don't have "compat" versions. */
#define compat_sys_flush_cache sys_flush_cache
+/* These are the intvec_64.S trampolines. */
+long _compat_sys_execve(const char __user *path,
+ const compat_uptr_t __user *argv,
+ const compat_uptr_t __user *envp);
+long _compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
+ struct compat_sigaltstack __user *uoss_ptr);
+long _compat_sys_rt_sigreturn(void);
+
#endif /* _ASM_TILE_COMPAT_H */
diff --git a/arch/tile/include/asm/highmem.h b/arch/tile/include/asm/highmem.h
index d155db6fa9bd..e0f7ee186721 100644
--- a/arch/tile/include/asm/highmem.h
+++ b/arch/tile/include/asm/highmem.h
@@ -60,12 +60,12 @@ void *kmap_fix_kpte(struct page *page, int finished);
/* This macro is used only in map_new_virtual() to map "page". */
#define kmap_prot page_to_kpgprot(page)
-void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type);
-void *kmap_atomic_pfn(unsigned long pfn, enum km_type type);
-void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot);
+void *__kmap_atomic(struct page *page);
+void __kunmap_atomic(void *kvaddr);
+void *kmap_atomic_pfn(unsigned long pfn);
+void *kmap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot);
struct page *kmap_atomic_to_page(void *ptr);
-void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot);
-void *kmap_atomic(struct page *page, enum km_type type);
+void *kmap_atomic_prot(struct page *page, pgprot_t prot);
void kmap_atomic_fix_kpte(struct page *page, int finished);
#define flush_cache_kmaps() do { } while (0)
diff --git a/arch/tile/include/asm/irqflags.h b/arch/tile/include/asm/irqflags.h
index 45cf67c2f286..641e4ff3d805 100644
--- a/arch/tile/include/asm/irqflags.h
+++ b/arch/tile/include/asm/irqflags.h
@@ -47,53 +47,53 @@
int __n = (n); \
int __mask = 1 << (__n & 0x1f); \
if (__n < 32) \
- __insn_mtspr(SPR_INTERRUPT_MASK_SET_1_0, __mask); \
+ __insn_mtspr(SPR_INTERRUPT_MASK_SET_K_0, __mask); \
else \
- __insn_mtspr(SPR_INTERRUPT_MASK_SET_1_1, __mask); \
+ __insn_mtspr(SPR_INTERRUPT_MASK_SET_K_1, __mask); \
} while (0)
#define interrupt_mask_reset(n) do { \
int __n = (n); \
int __mask = 1 << (__n & 0x1f); \
if (__n < 32) \
- __insn_mtspr(SPR_INTERRUPT_MASK_RESET_1_0, __mask); \
+ __insn_mtspr(SPR_INTERRUPT_MASK_RESET_K_0, __mask); \
else \
- __insn_mtspr(SPR_INTERRUPT_MASK_RESET_1_1, __mask); \
+ __insn_mtspr(SPR_INTERRUPT_MASK_RESET_K_1, __mask); \
} while (0)
#define interrupt_mask_check(n) ({ \
int __n = (n); \
(((__n < 32) ? \
- __insn_mfspr(SPR_INTERRUPT_MASK_1_0) : \
- __insn_mfspr(SPR_INTERRUPT_MASK_1_1)) \
+ __insn_mfspr(SPR_INTERRUPT_MASK_K_0) : \
+ __insn_mfspr(SPR_INTERRUPT_MASK_K_1)) \
>> (__n & 0x1f)) & 1; \
})
#define interrupt_mask_set_mask(mask) do { \
unsigned long long __m = (mask); \
- __insn_mtspr(SPR_INTERRUPT_MASK_SET_1_0, (unsigned long)(__m)); \
- __insn_mtspr(SPR_INTERRUPT_MASK_SET_1_1, (unsigned long)(__m>>32)); \
+ __insn_mtspr(SPR_INTERRUPT_MASK_SET_K_0, (unsigned long)(__m)); \
+ __insn_mtspr(SPR_INTERRUPT_MASK_SET_K_1, (unsigned long)(__m>>32)); \
} while (0)
#define interrupt_mask_reset_mask(mask) do { \
unsigned long long __m = (mask); \
- __insn_mtspr(SPR_INTERRUPT_MASK_RESET_1_0, (unsigned long)(__m)); \
- __insn_mtspr(SPR_INTERRUPT_MASK_RESET_1_1, (unsigned long)(__m>>32)); \
+ __insn_mtspr(SPR_INTERRUPT_MASK_RESET_K_0, (unsigned long)(__m)); \
+ __insn_mtspr(SPR_INTERRUPT_MASK_RESET_K_1, (unsigned long)(__m>>32)); \
} while (0)
#else
#define interrupt_mask_set(n) \
- __insn_mtspr(SPR_INTERRUPT_MASK_SET_1, (1UL << (n)))
+ __insn_mtspr(SPR_INTERRUPT_MASK_SET_K, (1UL << (n)))
#define interrupt_mask_reset(n) \
- __insn_mtspr(SPR_INTERRUPT_MASK_RESET_1, (1UL << (n)))
+ __insn_mtspr(SPR_INTERRUPT_MASK_RESET_K, (1UL << (n)))
#define interrupt_mask_check(n) \
- ((__insn_mfspr(SPR_INTERRUPT_MASK_1) >> (n)) & 1)
+ ((__insn_mfspr(SPR_INTERRUPT_MASK_K) >> (n)) & 1)
#define interrupt_mask_set_mask(mask) \
- __insn_mtspr(SPR_INTERRUPT_MASK_SET_1, (mask))
+ __insn_mtspr(SPR_INTERRUPT_MASK_SET_K, (mask))
#define interrupt_mask_reset_mask(mask) \
- __insn_mtspr(SPR_INTERRUPT_MASK_RESET_1, (mask))
+ __insn_mtspr(SPR_INTERRUPT_MASK_RESET_K, (mask))
#endif
/*
* The set of interrupts we want active if irqs are enabled.
* Note that in particular, the tile timer interrupt comes and goes
* from this set, since we have no other way to turn off the timer.
- * Likewise, INTCTRL_1 is removed and re-added during device
+ * Likewise, INTCTRL_K is removed and re-added during device
* interrupts, as is the the hardwall UDN_FIREWALL interrupt.
* We use a low bit (MEM_ERROR) as our sentinel value and make sure it
* is always claimed as an "active interrupt" so we can query that bit
@@ -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)
@@ -168,14 +170,14 @@ DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask);
/* Return 0 or 1 to indicate whether interrupts are currently disabled. */
#define IRQS_DISABLED(tmp) \
- mfspr tmp, INTERRUPT_MASK_1; \
+ mfspr tmp, SPR_INTERRUPT_MASK_K; \
andi tmp, tmp, 1
/* Load up a pointer to &interrupts_enabled_mask. */
#define GET_INTERRUPTS_ENABLED_MASK_PTR(reg) \
- moveli reg, hw2_last(interrupts_enabled_mask); \
- shl16insli reg, reg, hw1(interrupts_enabled_mask); \
- shl16insli reg, reg, hw0(interrupts_enabled_mask); \
+ moveli reg, hw2_last(interrupts_enabled_mask); \
+ shl16insli reg, reg, hw1(interrupts_enabled_mask); \
+ shl16insli reg, reg, hw0(interrupts_enabled_mask); \
add reg, reg, tp
/* Disable interrupts. */
@@ -183,18 +185,18 @@ DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask);
moveli tmp0, hw2_last(LINUX_MASKABLE_INTERRUPTS); \
shl16insli tmp0, tmp0, hw1(LINUX_MASKABLE_INTERRUPTS); \
shl16insli tmp0, tmp0, hw0(LINUX_MASKABLE_INTERRUPTS); \
- mtspr INTERRUPT_MASK_SET_1, tmp0
+ mtspr SPR_INTERRUPT_MASK_SET_K, tmp0
/* Disable ALL synchronous interrupts (used by NMI entry). */
#define IRQ_DISABLE_ALL(tmp) \
movei tmp, -1; \
- mtspr INTERRUPT_MASK_SET_1, tmp
+ mtspr SPR_INTERRUPT_MASK_SET_K, tmp
/* Enable interrupts. */
#define IRQ_ENABLE(tmp0, tmp1) \
GET_INTERRUPTS_ENABLED_MASK_PTR(tmp0); \
ld tmp0, tmp0; \
- mtspr INTERRUPT_MASK_RESET_1, tmp0
+ mtspr SPR_INTERRUPT_MASK_RESET_K, tmp0
#else /* !__tilegx__ */
@@ -208,14 +210,14 @@ DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask);
* (making the original code's write of the "high" mask word idempotent).
*/
#define IRQS_DISABLED(tmp) \
- mfspr tmp, INTERRUPT_MASK_1_0; \
+ mfspr tmp, SPR_INTERRUPT_MASK_K_0; \
shri tmp, tmp, INT_MEM_ERROR; \
andi tmp, tmp, 1
/* Load up a pointer to &interrupts_enabled_mask. */
#define GET_INTERRUPTS_ENABLED_MASK_PTR(reg) \
- moveli reg, lo16(interrupts_enabled_mask); \
- auli reg, reg, ha16(interrupts_enabled_mask);\
+ moveli reg, lo16(interrupts_enabled_mask); \
+ auli reg, reg, ha16(interrupts_enabled_mask); \
add reg, reg, tp
/* Disable interrupts. */
@@ -225,16 +227,16 @@ DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask);
moveli tmp1, lo16(LINUX_MASKABLE_INTERRUPTS) \
}; \
{ \
- mtspr INTERRUPT_MASK_SET_1_0, tmp0; \
+ mtspr SPR_INTERRUPT_MASK_SET_K_0, tmp0; \
auli tmp1, tmp1, ha16(LINUX_MASKABLE_INTERRUPTS) \
}; \
- mtspr INTERRUPT_MASK_SET_1_1, tmp1
+ mtspr SPR_INTERRUPT_MASK_SET_K_1, tmp1
/* Disable ALL synchronous interrupts (used by NMI entry). */
#define IRQ_DISABLE_ALL(tmp) \
movei tmp, -1; \
- mtspr INTERRUPT_MASK_SET_1_0, tmp; \
- mtspr INTERRUPT_MASK_SET_1_1, tmp
+ mtspr SPR_INTERRUPT_MASK_SET_K_0, tmp; \
+ mtspr SPR_INTERRUPT_MASK_SET_K_1, tmp
/* Enable interrupts. */
#define IRQ_ENABLE(tmp0, tmp1) \
@@ -244,8 +246,8 @@ DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask);
addi tmp1, tmp0, 4 \
}; \
lw tmp1, tmp1; \
- mtspr INTERRUPT_MASK_RESET_1_0, tmp0; \
- mtspr INTERRUPT_MASK_RESET_1_1, tmp1
+ mtspr SPR_INTERRUPT_MASK_RESET_K_0, tmp0; \
+ mtspr SPR_INTERRUPT_MASK_RESET_K_1, tmp1
#endif
/*
diff --git a/arch/tile/include/asm/mman.h b/arch/tile/include/asm/mman.h
index 4c6811e3e8dc..81b8fc348d63 100644
--- a/arch/tile/include/asm/mman.h
+++ b/arch/tile/include/asm/mman.h
@@ -23,6 +23,7 @@
#define MAP_POPULATE 0x0040 /* populate (prefault) pagetables */
#define MAP_NONBLOCK 0x0080 /* do not block on IO */
#define MAP_GROWSDOWN 0x0100 /* stack-like segment */
+#define MAP_STACK MAP_GROWSDOWN /* provide convenience alias */
#define MAP_LOCKED 0x0200 /* pages are locked */
#define MAP_NORESERVE 0x0400 /* don't check for reservations */
#define MAP_DENYWRITE 0x0800 /* ETXTBSY */
diff --git a/arch/tile/include/asm/page.h b/arch/tile/include/asm/page.h
index 7d90641cf18d..7979a45430d3 100644
--- a/arch/tile/include/asm/page.h
+++ b/arch/tile/include/asm/page.h
@@ -199,17 +199,17 @@ static inline __attribute_const__ int get_order(unsigned long size)
* If you want more physical memory than this then see the CONFIG_HIGHMEM
* option in the kernel configuration.
*
- * The top two 16MB chunks in the table below (VIRT and HV) are
- * unavailable to Linux. Since the kernel interrupt vectors must live
- * at 0xfd000000, we map all of the bottom of RAM at this address with
- * a huge page table entry to minimize its ITLB footprint (as well as
- * at PAGE_OFFSET). The last architected requirement is that user
- * interrupt vectors live at 0xfc000000, so we make that range of
- * memory available to user processes. The remaining regions are sized
- * as shown; after the first four addresses, we show "typical" values,
- * since the actual addresses depend on kernel #defines.
+ * The top 16MB chunk in the table below is unavailable to Linux. Since
+ * the kernel interrupt vectors must live at ether 0xfe000000 or 0xfd000000
+ * (depending on whether the kernel is at PL2 or Pl1), we map all of the
+ * bottom of RAM at this address with a huge page table entry to minimize
+ * its ITLB footprint (as well as at PAGE_OFFSET). The last architected
+ * requirement is that user interrupt vectors live at 0xfc000000, so we
+ * make that range of memory available to user processes. The remaining
+ * regions are sized as shown; the first four addresses use the PL 1
+ * values, and after that, we show "typical" values, since the actual
+ * addresses depend on kernel #defines.
*
- * MEM_VIRT_INTRPT 0xff000000
* MEM_HV_INTRPT 0xfe000000
* MEM_SV_INTRPT (kernel code) 0xfd000000
* MEM_USER_INTRPT (user vector) 0xfc000000
@@ -221,9 +221,14 @@ static inline __attribute_const__ int get_order(unsigned long size)
*/
#define MEM_USER_INTRPT _AC(0xfc000000, UL)
+#if CONFIG_KERNEL_PL == 1
#define MEM_SV_INTRPT _AC(0xfd000000, UL)
#define MEM_HV_INTRPT _AC(0xfe000000, UL)
-#define MEM_VIRT_INTRPT _AC(0xff000000, UL)
+#else
+#define MEM_GUEST_INTRPT _AC(0xfd000000, UL)
+#define MEM_SV_INTRPT _AC(0xfe000000, UL)
+#define MEM_HV_INTRPT _AC(0xff000000, UL)
+#endif
#define INTRPT_SIZE 0x4000
diff --git a/arch/tile/include/asm/pgtable.h b/arch/tile/include/asm/pgtable.h
index b3367379d537..dc4ccdd855bc 100644
--- a/arch/tile/include/asm/pgtable.h
+++ b/arch/tile/include/asm/pgtable.h
@@ -347,15 +347,10 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
extern pte_t *_pte_offset_map(pmd_t *, unsigned long address, enum km_type);
#define pte_offset_map(dir, address) \
_pte_offset_map(dir, address, KM_PTE0)
-#define pte_offset_map_nested(dir, address) \
- _pte_offset_map(dir, address, KM_PTE1)
#define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0)
-#define pte_unmap_nested(pte) kunmap_atomic(pte, KM_PTE1)
#else
#define pte_offset_map(dir, address) pte_offset_kernel(dir, address)
-#define pte_offset_map_nested(dir, address) pte_offset_map(dir, address)
#define pte_unmap(pte) do { } while (0)
-#define pte_unmap_nested(pte) do { } while (0)
#endif
/* Clear a non-executable kernel PTE and flush it from the TLB. */
diff --git a/arch/tile/include/asm/processor.h b/arch/tile/include/asm/processor.h
index ccd5f8425688..1747ff3946b2 100644
--- a/arch/tile/include/asm/processor.h
+++ b/arch/tile/include/asm/processor.h
@@ -328,18 +328,21 @@ extern int kdata_huge;
* Note that assembly code assumes that USER_PL is zero.
*/
#define USER_PL 0
-#define KERNEL_PL 1
+#if CONFIG_KERNEL_PL == 2
+#define GUEST_PL 1
+#endif
+#define KERNEL_PL CONFIG_KERNEL_PL
-/* SYSTEM_SAVE_1_0 holds the current cpu number ORed with ksp0. */
+/* SYSTEM_SAVE_K_0 holds the current cpu number ORed with ksp0. */
#define CPU_LOG_MASK_VALUE 12
#define CPU_MASK_VALUE ((1 << CPU_LOG_MASK_VALUE) - 1)
#if CONFIG_NR_CPUS > CPU_MASK_VALUE
# error Too many cpus!
#endif
#define raw_smp_processor_id() \
- ((int)__insn_mfspr(SPR_SYSTEM_SAVE_1_0) & CPU_MASK_VALUE)
+ ((int)__insn_mfspr(SPR_SYSTEM_SAVE_K_0) & CPU_MASK_VALUE)
#define get_current_ksp0() \
- (__insn_mfspr(SPR_SYSTEM_SAVE_1_0) & ~CPU_MASK_VALUE)
+ (__insn_mfspr(SPR_SYSTEM_SAVE_K_0) & ~CPU_MASK_VALUE)
#define next_current_ksp0(task) ({ \
unsigned long __ksp0 = task_ksp0(task); \
int __cpu = raw_smp_processor_id(); \
diff --git a/arch/tile/include/asm/ptrace.h b/arch/tile/include/asm/ptrace.h
index 4a02bb073979..ac6d343129d3 100644
--- a/arch/tile/include/asm/ptrace.h
+++ b/arch/tile/include/asm/ptrace.h
@@ -62,8 +62,8 @@ struct pt_regs {
pt_reg_t lr; /* aliases regs[TREG_LR] */
/* Saved special registers. */
- pt_reg_t pc; /* stored in EX_CONTEXT_1_0 */
- pt_reg_t ex1; /* stored in EX_CONTEXT_1_1 (PL and ICS bit) */
+ pt_reg_t pc; /* stored in EX_CONTEXT_K_0 */
+ pt_reg_t ex1; /* stored in EX_CONTEXT_K_1 (PL and ICS bit) */
pt_reg_t faultnum; /* fault number (INT_SWINT_1 for syscall) */
pt_reg_t orig_r0; /* r0 at syscall entry, else zero */
pt_reg_t flags; /* flags (see below) */
diff --git a/arch/tile/include/asm/syscalls.h b/arch/tile/include/asm/syscalls.h
index ce99ffefeacf..3b5507c31eae 100644
--- a/arch/tile/include/asm/syscalls.h
+++ b/arch/tile/include/asm/syscalls.h
@@ -32,8 +32,9 @@ extern void *compat_sys_call_table[];
/*
* Note that by convention, any syscall which requires the current
- * register set takes an additional "struct pt_regs *" pointer; the
- * sys_xxx() function just adds the pointer and tail-calls to _sys_xxx().
+ * register set takes an additional "struct pt_regs *" pointer; a
+ * _sys_xxx() trampoline in intvec*.S just sets up the pointer and
+ * jumps to sys_xxx().
*/
/* kernel/sys.c */
@@ -43,66 +44,17 @@ long sys32_fadvise64(int fd, u32 offset_lo, u32 offset_hi,
int sys32_fadvise64_64(int fd, u32 offset_lo, u32 offset_hi,
u32 len_lo, u32 len_hi, int advice);
long sys_flush_cache(void);
-long sys_mmap2(unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long pgoff);
-#ifdef __tilegx__
-long sys_mmap(unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, off_t pgoff);
+#ifndef __tilegx__ /* No mmap() in the 32-bit kernel. */
+#define sys_mmap sys_mmap
#endif
-/* kernel/process.c */
-long sys_clone(unsigned long clone_flags, unsigned long newsp,
- void __user *parent_tid, void __user *child_tid);
-long _sys_clone(unsigned long clone_flags, unsigned long newsp,
- void __user *parent_tid, void __user *child_tid,
- struct pt_regs *regs);
-long sys_fork(void);
-long _sys_fork(struct pt_regs *regs);
-long sys_vfork(void);
-long _sys_vfork(struct pt_regs *regs);
-long sys_execve(const char __user *filename,
- const char __user *const __user *argv,
- const char __user *const __user *envp);
-long _sys_execve(const char __user *filename,
- const char __user *const __user *argv,
- const char __user *const __user *envp, struct pt_regs *regs);
-
-/* kernel/signal.c */
-long sys_sigaltstack(const stack_t __user *, stack_t __user *);
-long _sys_sigaltstack(const stack_t __user *, stack_t __user *,
- struct pt_regs *);
-long sys_rt_sigreturn(void);
-long _sys_rt_sigreturn(struct pt_regs *regs);
-
-/* platform-independent functions */
-long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize);
-long sys_rt_sigaction(int sig, const struct sigaction __user *act,
- struct sigaction __user *oact, size_t sigsetsize);
-
#ifndef __tilegx__
/* mm/fault.c */
-int sys_cmpxchg_badaddr(unsigned long address);
-int _sys_cmpxchg_badaddr(unsigned long address, struct pt_regs *);
+long sys_cmpxchg_badaddr(unsigned long address, struct pt_regs *);
+long _sys_cmpxchg_badaddr(unsigned long address);
#endif
#ifdef CONFIG_COMPAT
-long compat_sys_execve(const char __user *path,
- const compat_uptr_t __user *argv,
- const compat_uptr_t __user *envp);
-long _compat_sys_execve(const char __user *path,
- const compat_uptr_t __user *argv,
- const compat_uptr_t __user *envp,
- struct pt_regs *regs);
-long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
- struct compat_sigaltstack __user *uoss_ptr);
-long _compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
- struct compat_sigaltstack __user *uoss_ptr,
- struct pt_regs *regs);
-long compat_sys_rt_sigreturn(void);
-long _compat_sys_rt_sigreturn(struct pt_regs *regs);
-
/* These four are not defined for 64-bit, but serve as "compat" syscalls. */
long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg);
long sys_fstat64(unsigned long fd, struct stat64 __user *statbuf);
@@ -110,4 +62,15 @@ long sys_truncate64(const char __user *path, loff_t length);
long sys_ftruncate64(unsigned int fd, loff_t length);
#endif
+/* These are the intvec*.S trampolines. */
+long _sys_sigaltstack(const stack_t __user *, stack_t __user *);
+long _sys_rt_sigreturn(void);
+long _sys_clone(unsigned long clone_flags, unsigned long newsp,
+ void __user *parent_tid, void __user *child_tid);
+long _sys_execve(const char __user *filename,
+ const char __user *const __user *argv,
+ const char __user *const __user *envp);
+
+#include <asm-generic/syscalls.h>
+
#endif /* _ASM_TILE_SYSCALLS_H */
diff --git a/arch/tile/include/asm/system.h b/arch/tile/include/asm/system.h
index f749be327ce0..5388850deeb2 100644
--- a/arch/tile/include/asm/system.h
+++ b/arch/tile/include/asm/system.h
@@ -89,6 +89,10 @@
#define get_cycles_low() __insn_mfspr(SPR_CYCLE) /* just get all 64 bits */
#endif
+#if !CHIP_HAS_MF_WAITS_FOR_VICTIMS()
+int __mb_incoherent(void); /* Helper routine for mb_incoherent(). */
+#endif
+
/* Fence to guarantee visibility of stores to incoherent memory. */
static inline void
mb_incoherent(void)
@@ -97,7 +101,6 @@ mb_incoherent(void)
#if !CHIP_HAS_MF_WAITS_FOR_VICTIMS()
{
- int __mb_incoherent(void);
#if CHIP_HAS_TILE_WRITE_PENDING()
const unsigned long WRITE_TIMEOUT_CYCLES = 400;
unsigned long start = get_cycles_low();
@@ -161,7 +164,7 @@ extern struct task_struct *_switch_to(struct task_struct *prev,
/* Helper function for _switch_to(). */
extern struct task_struct *__switch_to(struct task_struct *prev,
struct task_struct *next,
- unsigned long new_system_save_1_0);
+ unsigned long new_system_save_k_0);
/* Address that switched-away from tasks are at. */
extern unsigned long get_switch_to_pc(void);
@@ -214,13 +217,6 @@ int hardwall_deactivate(struct task_struct *task);
} while (0)
#endif
-/* Invoke the simulator "syscall" mechanism (see arch/tile/kernel/entry.S). */
-extern int _sim_syscall(int syscall_num, ...);
-#define sim_syscall(syscall_num, ...) \
- _sim_syscall(SIM_CONTROL_SYSCALL + \
- ((syscall_num) << _SIM_CONTROL_OPERATOR_BITS), \
- ## __VA_ARGS__)
-
/*
* Kernel threads can check to see if they need to migrate their
* stack whenever they return from a context switch; for user
diff --git a/arch/tile/include/asm/traps.h b/arch/tile/include/asm/traps.h
index 432a9c15c8a2..d06e35f57201 100644
--- a/arch/tile/include/asm/traps.h
+++ b/arch/tile/include/asm/traps.h
@@ -59,4 +59,8 @@ void do_hardwall_trap(struct pt_regs *, int fault_num);
void do_breakpoint(struct pt_regs *, int fault_num);
+#ifdef __tilegx__
+void gx_singlestep_handle(struct pt_regs *, int fault_num);
+#endif
+
#endif /* _ASM_TILE_SYSCALLS_H */
diff --git a/arch/tile/include/hv/hypervisor.h b/arch/tile/include/hv/hypervisor.h
index 9bd303a141b2..f672544cd4f9 100644
--- a/arch/tile/include/hv/hypervisor.h
+++ b/arch/tile/include/hv/hypervisor.h
@@ -1003,37 +1003,37 @@ int hv_console_write(HV_VirtAddr bytes, int len);
* when these occur in a client's interrupt critical section, they must
* be delivered through the downcall mechanism.
*
- * A downcall is initially delivered to the client as an INTCTRL_1
- * interrupt. Upon entry to the INTCTRL_1 vector, the client must
- * immediately invoke the hv_downcall_dispatch service. This service
- * will not return; instead it will cause one of the client's actual
- * downcall-handling interrupt vectors to be entered. The EX_CONTEXT
- * registers in the client will be set so that when the client irets,
- * it will return to the code which was interrupted by the INTCTRL_1
- * interrupt.
- *
- * Under some circumstances, the firing of INTCTRL_1 can race with
+ * A downcall is initially delivered to the client as an INTCTRL_CL
+ * interrupt, where CL is the client's PL. Upon entry to the INTCTRL_CL
+ * vector, the client must immediately invoke the hv_downcall_dispatch
+ * service. This service will not return; instead it will cause one of
+ * the client's actual downcall-handling interrupt vectors to be entered.
+ * The EX_CONTEXT registers in the client will be set so that when the
+ * client irets, it will return to the code which was interrupted by the
+ * INTCTRL_CL interrupt.
+ *
+ * Under some circumstances, the firing of INTCTRL_CL can race with
* the lowering of a device interrupt. In such a case, the
* hv_downcall_dispatch service may issue an iret instruction instead
* of entering one of the client's actual downcall-handling interrupt
* vectors. This will return execution to the location that was
- * interrupted by INTCTRL_1.
+ * interrupted by INTCTRL_CL.
*
* Any saving of registers should be done by the actual handling
- * vectors; no registers should be changed by the INTCTRL_1 handler.
+ * vectors; no registers should be changed by the INTCTRL_CL handler.
* In particular, the client should not use a jal instruction to invoke
* the hv_downcall_dispatch service, as that would overwrite the client's
* lr register. Note that the hv_downcall_dispatch service may overwrite
* one or more of the client's system save registers.
*
- * The client must not modify the INTCTRL_1_STATUS SPR. The hypervisor
+ * The client must not modify the INTCTRL_CL_STATUS SPR. The hypervisor
* will set this register to cause a downcall to happen, and will clear
* it when no further downcalls are pending.
*
- * When a downcall vector is entered, the INTCTRL_1 interrupt will be
+ * When a downcall vector is entered, the INTCTRL_CL interrupt will be
* masked. When the client is done processing a downcall, and is ready
* to accept another, it must unmask this interrupt; if more downcalls
- * are pending, this will cause the INTCTRL_1 vector to be reentered.
+ * are pending, this will cause the INTCTRL_CL vector to be reentered.
* Currently the following interrupt vectors can be entered through a
* downcall:
*
diff --git a/arch/tile/kernel/backtrace.c b/arch/tile/kernel/backtrace.c
index d3c41c1ff6bd..55a6a74974b4 100644
--- a/arch/tile/kernel/backtrace.c
+++ b/arch/tile/kernel/backtrace.c
@@ -369,6 +369,10 @@ static void find_caller_pc_and_caller_sp(CallerLocation *location,
/* Weird; reserved value, ignore it. */
continue;
}
+ if (info_operand & ENTRY_POINT_INFO_OP) {
+ /* This info op is ignored by the backtracer. */
+ continue;
+ }
/* Skip info ops which are not in the
* "one_ago" mode we want right now.
diff --git a/arch/tile/kernel/compat.c b/arch/tile/kernel/compat.c
index b1e06d041555..77739cdd9462 100644
--- a/arch/tile/kernel/compat.c
+++ b/arch/tile/kernel/compat.c
@@ -154,8 +154,14 @@ long tile_compat_sys_msgrcv(int msqid,
#define compat_sys_fstat64 sys_newfstat
#define compat_sys_fstatat64 sys_newfstatat
-/* Pass full 64-bit values through ptrace. */
-#define compat_sys_ptrace tile_compat_sys_ptrace
+/* The native sys_ptrace dynamically handles compat binaries. */
+#define compat_sys_ptrace sys_ptrace
+
+/* Call the trampolines to manage pt_regs where necessary. */
+#define compat_sys_execve _compat_sys_execve
+#define compat_sys_sigaltstack _compat_sys_sigaltstack
+#define compat_sys_rt_sigreturn _compat_sys_rt_sigreturn
+#define sys_clone _sys_clone
/*
* Note that we can't include <linux/unistd.h> here since the header
diff --git a/arch/tile/kernel/compat_signal.c b/arch/tile/kernel/compat_signal.c
index 9c710db43f13..fb64b99959d4 100644
--- a/arch/tile/kernel/compat_signal.c
+++ b/arch/tile/kernel/compat_signal.c
@@ -256,9 +256,9 @@ int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from)
return err;
}
-long _compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
- struct compat_sigaltstack __user *uoss_ptr,
- struct pt_regs *regs)
+long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
+ struct compat_sigaltstack __user *uoss_ptr,
+ struct pt_regs *regs)
{
stack_t uss, uoss;
int ret;
@@ -291,7 +291,7 @@ long _compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
return ret;
}
-long _compat_sys_rt_sigreturn(struct pt_regs *regs)
+long compat_sys_rt_sigreturn(struct pt_regs *regs)
{
struct compat_rt_sigframe __user *frame =
(struct compat_rt_sigframe __user *) compat_ptr(regs->sp);
@@ -312,7 +312,7 @@ long _compat_sys_rt_sigreturn(struct pt_regs *regs)
if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
goto badframe;
- if (_compat_sys_sigaltstack(&frame->uc.uc_stack, NULL, regs) != 0)
+ if (compat_sys_sigaltstack(&frame->uc.uc_stack, NULL, regs) != 0)
goto badframe;
return r0;
diff --git a/arch/tile/kernel/entry.S b/arch/tile/kernel/entry.S
index 3d01383b1b0e..fd8dc42abdcb 100644
--- a/arch/tile/kernel/entry.S
+++ b/arch/tile/kernel/entry.S
@@ -15,7 +15,9 @@
#include <linux/linkage.h>
#include <linux/unistd.h>
#include <asm/irqflags.h>
+#include <asm/processor.h>
#include <arch/abi.h>
+#include <arch/spr_def.h>
#ifdef __tilegx__
#define bnzt bnezt
@@ -25,28 +27,6 @@ STD_ENTRY(current_text_addr)
{ move r0, lr; jrp lr }
STD_ENDPROC(current_text_addr)
-STD_ENTRY(_sim_syscall)
- /*
- * Wait for r0-r9 to be ready (and lr on the off chance we
- * want the syscall to locate its caller), then make a magic
- * simulator syscall.
- *
- * We carefully stall until the registers are readable in case they
- * are the target of a slow load, etc. so that tile-sim will
- * definitely be able to read all of them inside the magic syscall.
- *
- * Technically this is wrong for r3-r9 and lr, since an interrupt
- * could come in and restore the registers with a slow load right
- * before executing the mtspr. We may need to modify tile-sim to
- * explicitly stall for this case, but we do not yet have
- * a way to implement such a stall.
- */
- { and zero, lr, r9 ; and zero, r8, r7 }
- { and zero, r6, r5 ; and zero, r4, r3 }
- { and zero, r2, r1 ; mtspr SIM_CONTROL, r0 }
- { jrp lr }
- STD_ENDPROC(_sim_syscall)
-
/*
* Implement execve(). The i386 code has a note that forking from kernel
* space results in no copy on write until the execve, so we should be
@@ -102,7 +82,7 @@ STD_ENTRY(KBacktraceIterator_init_current)
STD_ENTRY(cpu_idle_on_new_stack)
{
move sp, r1
- mtspr SYSTEM_SAVE_1_0, r2
+ mtspr SPR_SYSTEM_SAVE_K_0, r2
}
jal free_thread_info
j cpu_idle
@@ -124,15 +104,15 @@ STD_ENTRY(smp_nap)
STD_ENTRY(_cpu_idle)
{
lnk r0
- movei r1, 1
+ movei r1, KERNEL_PL
}
{
addli r0, r0, _cpu_idle_nap - .
mtspr INTERRUPT_CRITICAL_SECTION, r1
}
- IRQ_ENABLE(r2, r3) /* unmask, but still with ICS set */
- mtspr EX_CONTEXT_1_1, r1 /* PL1, ICS clear */
- mtspr EX_CONTEXT_1_0, r0
+ IRQ_ENABLE(r2, r3) /* unmask, but still with ICS set */
+ mtspr SPR_EX_CONTEXT_K_1, r1 /* Kernel PL, ICS clear */
+ mtspr SPR_EX_CONTEXT_K_0, r0
iret
.global _cpu_idle_nap
_cpu_idle_nap:
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/head_32.S b/arch/tile/kernel/head_32.S
index 2b4f6c091701..90e7c4435693 100644
--- a/arch/tile/kernel/head_32.S
+++ b/arch/tile/kernel/head_32.S
@@ -23,6 +23,7 @@
#include <asm/asm-offsets.h>
#include <hv/hypervisor.h>
#include <arch/chip.h>
+#include <arch/spr_def.h>
/*
* This module contains the entry code for kernel images. It performs the
@@ -76,7 +77,7 @@ ENTRY(_start)
}
1:
- /* Get our processor number and save it away in SAVE_1_0. */
+ /* Get our processor number and save it away in SAVE_K_0. */
jal hv_inquire_topology
mulll_uu r4, r1, r2 /* r1 == y, r2 == width */
add r4, r4, r0 /* r0 == x, so r4 == cpu == y*width + x */
@@ -124,7 +125,7 @@ ENTRY(_start)
lw r0, r0
lw sp, r1
or r4, sp, r4
- mtspr SYSTEM_SAVE_1_0, r4 /* save ksp0 + cpu */
+ mtspr SPR_SYSTEM_SAVE_K_0, r4 /* save ksp0 + cpu */
addi sp, sp, -STACK_TOP_DELTA
{
move lr, zero /* stop backtraces in the called function */
diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S
index 8f58bdff20d7..f5821626247f 100644
--- a/arch/tile/kernel/intvec_32.S
+++ b/arch/tile/kernel/intvec_32.S
@@ -32,8 +32,8 @@
# error "No support for kernel preemption currently"
#endif
-#if INT_INTCTRL_1 < 32 || INT_INTCTRL_1 >= 48
-# error INT_INTCTRL_1 coded to set high interrupt mask
+#if INT_INTCTRL_K < 32 || INT_INTCTRL_K >= 48
+# error INT_INTCTRL_K coded to set high interrupt mask
#endif
#define PTREGS_PTR(reg, ptreg) addli reg, sp, C_ABI_SAVE_AREA_SIZE + (ptreg)
@@ -132,8 +132,8 @@ intvec_\vecname:
/* Temporarily save a register so we have somewhere to work. */
- mtspr SYSTEM_SAVE_1_1, r0
- mfspr r0, EX_CONTEXT_1_1
+ mtspr SPR_SYSTEM_SAVE_K_1, r0
+ mfspr r0, SPR_EX_CONTEXT_K_1
/* The cmpxchg code clears sp to force us to reset it here on fault. */
{
@@ -167,18 +167,18 @@ intvec_\vecname:
* The page_fault handler may be downcalled directly by the
* hypervisor even when Linux is running and has ICS set.
*
- * In this case the contents of EX_CONTEXT_1_1 reflect the
+ * In this case the contents of EX_CONTEXT_K_1 reflect the
* previous fault and can't be relied on to choose whether or
* not to reinitialize the stack pointer. So we add a test
- * to see whether SYSTEM_SAVE_1_2 has the high bit set,
+ * to see whether SYSTEM_SAVE_K_2 has the high bit set,
* and if so we don't reinitialize sp, since we must be coming
* from Linux. (In fact the precise case is !(val & ~1),
* but any Linux PC has to have the high bit set.)
*
- * Note that the hypervisor *always* sets SYSTEM_SAVE_1_2 for
+ * Note that the hypervisor *always* sets SYSTEM_SAVE_K_2 for
* any path that turns into a downcall to one of our TLB handlers.
*/
- mfspr r0, SYSTEM_SAVE_1_2
+ mfspr r0, SPR_SYSTEM_SAVE_K_2
{
blz r0, 0f /* high bit in S_S_1_2 is for a PC to use */
move r0, sp
@@ -187,12 +187,12 @@ intvec_\vecname:
2:
/*
- * SYSTEM_SAVE_1_0 holds the cpu number in the low bits, and
+ * SYSTEM_SAVE_K_0 holds the cpu number in the low bits, and
* the current stack top in the higher bits. So we recover
* our stack top by just masking off the low bits, then
* point sp at the top aligned address on the actual stack page.
*/
- mfspr r0, SYSTEM_SAVE_1_0
+ mfspr r0, SPR_SYSTEM_SAVE_K_0
mm r0, r0, zero, LOG2_THREAD_SIZE, 31
0:
@@ -254,7 +254,7 @@ intvec_\vecname:
sw sp, r3
addli sp, sp, PTREGS_OFFSET_PC - PTREGS_OFFSET_REG(3)
}
- mfspr r0, EX_CONTEXT_1_0
+ mfspr r0, SPR_EX_CONTEXT_K_0
.ifc \processing,handle_syscall
/*
* Bump the saved PC by one bundle so that when we return, we won't
@@ -267,7 +267,7 @@ intvec_\vecname:
sw sp, r0
addli sp, sp, PTREGS_OFFSET_EX1 - PTREGS_OFFSET_PC
}
- mfspr r0, EX_CONTEXT_1_1
+ mfspr r0, SPR_EX_CONTEXT_K_1
{
sw sp, r0
addi sp, sp, PTREGS_OFFSET_FAULTNUM - PTREGS_OFFSET_EX1
@@ -289,7 +289,7 @@ intvec_\vecname:
.endif
addli sp, sp, PTREGS_OFFSET_REG(0) - PTREGS_OFFSET_FAULTNUM
}
- mfspr r0, SYSTEM_SAVE_1_1 /* Original r0 */
+ mfspr r0, SPR_SYSTEM_SAVE_K_1 /* Original r0 */
{
sw sp, r0
addi sp, sp, -PTREGS_OFFSET_REG(0) - 4
@@ -309,12 +309,12 @@ intvec_\vecname:
* See discussion below at "finish_interrupt_save".
*/
.ifc \c_routine, do_page_fault
- mfspr r2, SYSTEM_SAVE_1_3 /* address of page fault */
- mfspr r3, SYSTEM_SAVE_1_2 /* info about page fault */
+ mfspr r2, SPR_SYSTEM_SAVE_K_3 /* address of page fault */
+ mfspr r3, SPR_SYSTEM_SAVE_K_2 /* info about page fault */
.else
.ifc \vecnum, INT_DOUBLE_FAULT
{
- mfspr r2, SYSTEM_SAVE_1_2 /* double fault info from HV */
+ mfspr r2, SPR_SYSTEM_SAVE_K_2 /* double fault info from HV */
movei r3, 0
}
.else
@@ -467,7 +467,7 @@ intvec_\vecname:
/* Load tp with our per-cpu offset. */
#ifdef CONFIG_SMP
{
- mfspr r20, SYSTEM_SAVE_1_0
+ mfspr r20, SPR_SYSTEM_SAVE_K_0
moveli r21, lo16(__per_cpu_offset)
}
{
@@ -487,7 +487,7 @@ intvec_\vecname:
* We load flags in r32 here so we can jump to .Lrestore_regs
* directly after do_page_fault_ics() if necessary.
*/
- mfspr r32, EX_CONTEXT_1_1
+ mfspr r32, SPR_EX_CONTEXT_K_1
{
andi r32, r32, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */
PTREGS_PTR(r21, PTREGS_OFFSET_FLAGS)
@@ -957,11 +957,11 @@ STD_ENTRY(interrupt_return)
pop_reg_zero r21, r3, sp, PTREGS_OFFSET_EX1 - PTREGS_OFFSET_PC
pop_reg_zero lr, r4, sp, PTREGS_OFFSET_REG(52) - PTREGS_OFFSET_EX1
{
- mtspr EX_CONTEXT_1_0, r21
+ mtspr SPR_EX_CONTEXT_K_0, r21
move r5, zero
}
{
- mtspr EX_CONTEXT_1_1, lr
+ mtspr SPR_EX_CONTEXT_K_1, lr
andi lr, lr, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */
}
@@ -1020,7 +1020,7 @@ STD_ENTRY(interrupt_return)
/* Set r1 to errno if we are returning an error, otherwise zero. */
{
- moveli r29, 1024
+ moveli r29, 4096
sub r1, zero, r0
}
slt_u r29, r1, r29
@@ -1199,7 +1199,7 @@ STD_ENTRY(interrupt_return)
STD_ENDPROC(interrupt_return)
/*
- * This interrupt variant clears the INT_INTCTRL_1 interrupt mask bit
+ * This interrupt variant clears the INT_INTCTRL_K interrupt mask bit
* before returning, so we can properly get more downcalls.
*/
.pushsection .text.handle_interrupt_downcall,"ax"
@@ -1208,11 +1208,11 @@ handle_interrupt_downcall:
check_single_stepping normal, .Ldispatch_downcall
.Ldispatch_downcall:
- /* Clear INTCTRL_1 from the set of interrupts we ever enable. */
+ /* Clear INTCTRL_K from the set of interrupts we ever enable. */
GET_INTERRUPTS_ENABLED_MASK_PTR(r30)
{
addi r30, r30, 4
- movei r31, INT_MASK(INT_INTCTRL_1)
+ movei r31, INT_MASK(INT_INTCTRL_K)
}
{
lw r20, r30
@@ -1227,7 +1227,7 @@ handle_interrupt_downcall:
}
FEEDBACK_REENTER(handle_interrupt_downcall)
- /* Allow INTCTRL_1 to be enabled next time we enable interrupts. */
+ /* Allow INTCTRL_K to be enabled next time we enable interrupts. */
lw r20, r30
or r20, r20, r31
sw r30, r20
@@ -1472,7 +1472,12 @@ handle_ill:
lw r26, r24
sw r28, r26
- /* Clear TIF_SINGLESTEP */
+ /*
+ * Clear TIF_SINGLESTEP to prevent recursion if we execute an ill.
+ * The normal non-arch flow redundantly clears TIF_SINGLESTEP, but we
+ * need to clear it here and can't really impose on all other arches.
+ * So what's another write between friends?
+ */
GET_THREAD_INFO(r0)
addi r1, r0, THREAD_INFO_FLAGS_OFFSET
@@ -1509,7 +1514,7 @@ handle_ill:
/* Various stub interrupt handlers and syscall handlers */
STD_ENTRY_LOCAL(_kernel_double_fault)
- mfspr r1, EX_CONTEXT_1_0
+ mfspr r1, SPR_EX_CONTEXT_K_0
move r2, lr
move r3, sp
move r4, r52
@@ -1518,34 +1523,29 @@ STD_ENTRY_LOCAL(_kernel_double_fault)
STD_ENDPROC(_kernel_double_fault)
STD_ENTRY_LOCAL(bad_intr)
- mfspr r2, EX_CONTEXT_1_0
+ mfspr r2, SPR_EX_CONTEXT_K_0
panic "Unhandled interrupt %#x: PC %#lx"
STD_ENDPROC(bad_intr)
/* Put address of pt_regs in reg and jump. */
#define PTREGS_SYSCALL(x, reg) \
- STD_ENTRY(x); \
+ STD_ENTRY(_##x); \
{ \
PTREGS_PTR(reg, PTREGS_OFFSET_BASE); \
- j _##x \
+ j x \
}; \
- STD_ENDPROC(x)
+ STD_ENDPROC(_##x)
PTREGS_SYSCALL(sys_execve, r3)
PTREGS_SYSCALL(sys_sigaltstack, r2)
PTREGS_SYSCALL(sys_rt_sigreturn, r0)
+PTREGS_SYSCALL(sys_cmpxchg_badaddr, r1)
-/* Save additional callee-saves to pt_regs, put address in reg and jump. */
-#define PTREGS_SYSCALL_ALL_REGS(x, reg) \
- STD_ENTRY(x); \
- push_extra_callee_saves reg; \
- j _##x; \
- STD_ENDPROC(x)
-
-PTREGS_SYSCALL_ALL_REGS(sys_fork, r0)
-PTREGS_SYSCALL_ALL_REGS(sys_vfork, r0)
-PTREGS_SYSCALL_ALL_REGS(sys_clone, r4)
-PTREGS_SYSCALL_ALL_REGS(sys_cmpxchg_badaddr, r1)
+/* Save additional callee-saves to pt_regs, put address in r4 and jump. */
+STD_ENTRY(_sys_clone)
+ push_extra_callee_saves r4
+ j sys_clone
+ STD_ENDPROC(_sys_clone)
/*
* This entrypoint is taken for the cmpxchg and atomic_update fast
@@ -1558,12 +1558,14 @@ PTREGS_SYSCALL_ALL_REGS(sys_cmpxchg_badaddr, r1)
* to be available to it on entry. It does not modify any callee-save
* registers (including "lr"). It does not check what PL it is being
* called at, so you'd better not call it other than at PL0.
+ * The <atomic.h> wrapper assumes it only clobbers r20-r29, so if
+ * it ever is necessary to use more registers, be aware.
*
* It does not use the stack, but since it might be re-interrupted by
* a page fault which would assume the stack was valid, it does
* save/restore the stack pointer and zero it out to make sure it gets reset.
* Since we always keep interrupts disabled, the hypervisor won't
- * clobber our EX_CONTEXT_1_x registers, so we don't save/restore them
+ * clobber our EX_CONTEXT_K_x registers, so we don't save/restore them
* (other than to advance the PC on return).
*
* We have to manually validate the user vs kernel address range
@@ -1769,7 +1771,7 @@ ENTRY(sys_cmpxchg)
/* Do slow mtspr here so the following "mf" waits less. */
{
move sp, r27
- mtspr EX_CONTEXT_1_0, r28
+ mtspr SPR_EX_CONTEXT_K_0, r28
}
mf
@@ -1788,7 +1790,7 @@ ENTRY(sys_cmpxchg)
}
{
move sp, r27
- mtspr EX_CONTEXT_1_0, r28
+ mtspr SPR_EX_CONTEXT_K_0, r28
}
iret
@@ -1816,7 +1818,7 @@ ENTRY(sys_cmpxchg)
#endif
/* Issue the slow SPR here while the tns result is in flight. */
- mfspr r28, EX_CONTEXT_1_0
+ mfspr r28, SPR_EX_CONTEXT_K_0
{
addi r28, r28, 8 /* return to the instruction after the swint1 */
@@ -1904,7 +1906,7 @@ ENTRY(sys_cmpxchg)
.Lcmpxchg64_mismatch:
{
move sp, r27
- mtspr EX_CONTEXT_1_0, r28
+ mtspr SPR_EX_CONTEXT_K_0, r28
}
mf
{
@@ -1985,8 +1987,13 @@ int_unalign:
int_hand INT_PERF_COUNT, PERF_COUNT, \
op_handle_perf_interrupt, handle_nmi
int_hand INT_INTCTRL_3, INTCTRL_3, bad_intr
+#if CONFIG_KERNEL_PL == 2
+ dc_dispatch INT_INTCTRL_2, INTCTRL_2
+ int_hand INT_INTCTRL_1, INTCTRL_1, bad_intr
+#else
int_hand INT_INTCTRL_2, INTCTRL_2, bad_intr
dc_dispatch INT_INTCTRL_1, INTCTRL_1
+#endif
int_hand INT_INTCTRL_0, INTCTRL_0, bad_intr
int_hand INT_MESSAGE_RCV_DWNCL, MESSAGE_RCV_DWNCL, \
hv_message_intr, handle_interrupt_downcall
diff --git a/arch/tile/kernel/irq.c b/arch/tile/kernel/irq.c
index 596c60086930..e63917687e99 100644
--- a/arch/tile/kernel/irq.c
+++ b/arch/tile/kernel/irq.c
@@ -61,9 +61,9 @@ static DEFINE_SPINLOCK(available_irqs_lock);
#if CHIP_HAS_IPI()
/* Use SPRs to manipulate device interrupts. */
-#define mask_irqs(irq_mask) __insn_mtspr(SPR_IPI_MASK_SET_1, irq_mask)
-#define unmask_irqs(irq_mask) __insn_mtspr(SPR_IPI_MASK_RESET_1, irq_mask)
-#define clear_irqs(irq_mask) __insn_mtspr(SPR_IPI_EVENT_RESET_1, irq_mask)
+#define mask_irqs(irq_mask) __insn_mtspr(SPR_IPI_MASK_SET_K, irq_mask)
+#define unmask_irqs(irq_mask) __insn_mtspr(SPR_IPI_MASK_RESET_K, irq_mask)
+#define clear_irqs(irq_mask) __insn_mtspr(SPR_IPI_EVENT_RESET_K, irq_mask)
#else
/* Use HV to manipulate device interrupts. */
#define mask_irqs(irq_mask) hv_disable_intr(irq_mask)
@@ -89,16 +89,16 @@ void tile_dev_intr(struct pt_regs *regs, int intnum)
* masked by a previous interrupt. Then, mask out the ones
* we're going to handle.
*/
- unsigned long masked = __insn_mfspr(SPR_IPI_MASK_1);
- original_irqs = __insn_mfspr(SPR_IPI_EVENT_1) & ~masked;
- __insn_mtspr(SPR_IPI_MASK_SET_1, original_irqs);
+ unsigned long masked = __insn_mfspr(SPR_IPI_MASK_K);
+ original_irqs = __insn_mfspr(SPR_IPI_EVENT_K) & ~masked;
+ __insn_mtspr(SPR_IPI_MASK_SET_K, original_irqs);
#else
/*
* Hypervisor performs the equivalent of the Gx code above and
* then puts the pending interrupt mask into a system save reg
* for us to find.
*/
- original_irqs = __insn_mfspr(SPR_SYSTEM_SAVE_1_3);
+ original_irqs = __insn_mfspr(SPR_SYSTEM_SAVE_K_3);
#endif
remaining_irqs = original_irqs;
@@ -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,
@@ -225,7 +225,7 @@ void __cpuinit setup_irq_regs(void)
/* Enable interrupt delivery. */
unmask_irqs(~0UL);
#if CHIP_HAS_IPI()
- raw_local_irq_unmask(INT_IPI_1);
+ raw_local_irq_unmask(INT_IPI_K);
#endif
}
@@ -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/tile/kernel/messaging.c b/arch/tile/kernel/messaging.c
index 6d23ed271d10..997e3933f726 100644
--- a/arch/tile/kernel/messaging.c
+++ b/arch/tile/kernel/messaging.c
@@ -34,7 +34,7 @@ void __cpuinit init_messaging(void)
panic("hv_register_message_state: error %d", rc);
/* Make sure downcall interrupts will be enabled. */
- raw_local_irq_unmask(INT_INTCTRL_1);
+ raw_local_irq_unmask(INT_INTCTRL_K);
}
void hv_message_intr(struct pt_regs *regs, int intnum)
diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c
index 84c29111756c..8430f45daea6 100644
--- a/arch/tile/kernel/process.c
+++ b/arch/tile/kernel/process.c
@@ -214,9 +214,10 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
/*
* Copy the callee-saved registers from the passed pt_regs struct
* into the context-switch callee-saved registers area.
- * We have to restore the callee-saved registers since we may
- * be cloning a userspace task with userspace register state,
- * and we won't be unwinding the same kernel frames to restore them.
+ * This way when we start the interrupt-return sequence, the
+ * callee-save registers will be correctly in registers, which
+ * is how we assume the compiler leaves them as we start doing
+ * the normal return-from-interrupt path after calling C code.
* Zero out the C ABI save area to mark the top of the stack.
*/
ksp = (unsigned long) childregs;
@@ -304,15 +305,25 @@ int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
/* Allow user processes to access the DMA SPRs */
void grant_dma_mpls(void)
{
+#if CONFIG_KERNEL_PL == 2
+ __insn_mtspr(SPR_MPL_DMA_CPL_SET_1, 1);
+ __insn_mtspr(SPR_MPL_DMA_NOTIFY_SET_1, 1);
+#else
__insn_mtspr(SPR_MPL_DMA_CPL_SET_0, 1);
__insn_mtspr(SPR_MPL_DMA_NOTIFY_SET_0, 1);
+#endif
}
/* Forbid user processes from accessing the DMA SPRs */
void restrict_dma_mpls(void)
{
+#if CONFIG_KERNEL_PL == 2
+ __insn_mtspr(SPR_MPL_DMA_CPL_SET_2, 1);
+ __insn_mtspr(SPR_MPL_DMA_NOTIFY_SET_2, 1);
+#else
__insn_mtspr(SPR_MPL_DMA_CPL_SET_1, 1);
__insn_mtspr(SPR_MPL_DMA_NOTIFY_SET_1, 1);
+#endif
}
/* Pause the DMA engine, then save off its state registers. */
@@ -523,19 +534,14 @@ struct task_struct *__sched _switch_to(struct task_struct *prev,
* Switch kernel SP, PC, and callee-saved registers.
* In the context of the new task, return the old task pointer
* (i.e. the task that actually called __switch_to).
- * Pass the value to use for SYSTEM_SAVE_1_0 when we reset our sp.
+ * Pass the value to use for SYSTEM_SAVE_K_0 when we reset our sp.
*/
return __switch_to(prev, next, next_current_ksp0(next));
}
-long _sys_fork(struct pt_regs *regs)
-{
- return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL);
-}
-
-long _sys_clone(unsigned long clone_flags, unsigned long newsp,
- void __user *parent_tidptr, void __user *child_tidptr,
- struct pt_regs *regs)
+SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
+ void __user *, parent_tidptr, void __user *, child_tidptr,
+ struct pt_regs *, regs)
{
if (!newsp)
newsp = regs->sp;
@@ -543,18 +549,13 @@ long _sys_clone(unsigned long clone_flags, unsigned long newsp,
parent_tidptr, child_tidptr);
}
-long _sys_vfork(struct pt_regs *regs)
-{
- return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp,
- regs, 0, NULL, NULL);
-}
-
/*
* sys_execve() executes a new program.
*/
-long _sys_execve(const char __user *path,
- const char __user *const __user *argv,
- const char __user *const __user *envp, struct pt_regs *regs)
+SYSCALL_DEFINE4(execve, const char __user *, path,
+ const char __user *const __user *, argv,
+ const char __user *const __user *, envp,
+ struct pt_regs *, regs)
{
long error;
char *filename;
@@ -570,9 +571,10 @@ out:
}
#ifdef CONFIG_COMPAT
-long _compat_sys_execve(const char __user *path,
- const compat_uptr_t __user *argv,
- const compat_uptr_t __user *envp, struct pt_regs *regs)
+long compat_sys_execve(const char __user *path,
+ const compat_uptr_t __user *argv,
+ const compat_uptr_t __user *envp,
+ struct pt_regs *regs)
{
long error;
char *filename;
diff --git a/arch/tile/kernel/ptrace.c b/arch/tile/kernel/ptrace.c
index 7161bd03d2fd..9cd29884c09f 100644
--- a/arch/tile/kernel/ptrace.c
+++ b/arch/tile/kernel/ptrace.c
@@ -32,25 +32,6 @@ void user_disable_single_step(struct task_struct *child)
}
/*
- * This routine will put a word on the process's privileged stack.
- */
-static void putreg(struct task_struct *task,
- unsigned long addr, unsigned long value)
-{
- unsigned int regno = addr / sizeof(unsigned long);
- struct pt_regs *childregs = task_pt_regs(task);
- childregs->regs[regno] = value;
- childregs->flags |= PT_FLAGS_RESTORE_REGS;
-}
-
-static unsigned long getreg(struct task_struct *task, unsigned long addr)
-{
- unsigned int regno = addr / sizeof(unsigned long);
- struct pt_regs *childregs = task_pt_regs(task);
- return childregs->regs[regno];
-}
-
-/*
* Called by kernel/ptrace.c when detaching..
*/
void ptrace_disable(struct task_struct *child)
@@ -64,61 +45,77 @@ void ptrace_disable(struct task_struct *child)
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
- unsigned long __user *datap;
+ unsigned long __user *datap = (long __user __force *)data;
unsigned long tmp;
int i;
long ret = -EIO;
-
-#ifdef CONFIG_COMPAT
- if (task_thread_info(current)->status & TS_COMPAT)
- data = (u32)data;
- if (task_thread_info(child)->status & TS_COMPAT)
- addr = (u32)addr;
-#endif
- datap = (unsigned long __user __force *)data;
+ unsigned long *childregs;
+ char *childreg;
switch (request) {
case PTRACE_PEEKUSR: /* Read register from pt_regs. */
- if (addr & (sizeof(data)-1))
- break;
- if (addr < 0 || addr >= PTREGS_SIZE)
+ if (addr >= PTREGS_SIZE)
break;
- tmp = getreg(child, addr); /* Read register */
- ret = put_user(tmp, datap);
+ childreg = (char *)task_pt_regs(child) + addr;
+#ifdef CONFIG_COMPAT
+ if (is_compat_task()) {
+ if (addr & (sizeof(compat_long_t)-1))
+ break;
+ ret = put_user(*(compat_long_t *)childreg,
+ (compat_long_t __user *)datap);
+ } else
+#endif
+ {
+ if (addr & (sizeof(long)-1))
+ break;
+ ret = put_user(*(long *)childreg, datap);
+ }
break;
case PTRACE_POKEUSR: /* Write register in pt_regs. */
- if (addr & (sizeof(data)-1))
- break;
- if (addr < 0 || addr >= PTREGS_SIZE)
+ if (addr >= PTREGS_SIZE)
break;
- putreg(child, addr, data); /* Write register */
+ childreg = (char *)task_pt_regs(child) + addr;
+#ifdef CONFIG_COMPAT
+ if (is_compat_task()) {
+ if (addr & (sizeof(compat_long_t)-1))
+ break;
+ *(compat_long_t *)childreg = data;
+ } else
+#endif
+ {
+ if (addr & (sizeof(long)-1))
+ break;
+ *(long *)childreg = data;
+ }
ret = 0;
break;
case PTRACE_GETREGS: /* Get all registers from the child. */
if (!access_ok(VERIFY_WRITE, datap, PTREGS_SIZE))
break;
- for (i = 0; i < PTREGS_SIZE; i += sizeof(long)) {
- ret = __put_user(getreg(child, i), datap);
+ childregs = (long *)task_pt_regs(child);
+ for (i = 0; i < sizeof(struct pt_regs)/sizeof(unsigned long);
+ ++i) {
+ ret = __put_user(childregs[i], &datap[i]);
if (ret != 0)
break;
- datap++;
}
break;
case PTRACE_SETREGS: /* Set all registers in the child. */
if (!access_ok(VERIFY_READ, datap, PTREGS_SIZE))
break;
- for (i = 0; i < PTREGS_SIZE; i += sizeof(long)) {
- ret = __get_user(tmp, datap);
+ childregs = (long *)task_pt_regs(child);
+ for (i = 0; i < sizeof(struct pt_regs)/sizeof(unsigned long);
+ ++i) {
+ ret = __get_user(childregs[i], &datap[i]);
if (ret != 0)
break;
- putreg(child, i, tmp);
- datap++;
}
break;
diff --git a/arch/tile/kernel/regs_32.S b/arch/tile/kernel/regs_32.S
index e88d6e122783..caa13101c264 100644
--- a/arch/tile/kernel/regs_32.S
+++ b/arch/tile/kernel/regs_32.S
@@ -85,7 +85,7 @@ STD_ENTRY_SECTION(__switch_to, .sched.text)
{
/* Update sp and ksp0 simultaneously to avoid backtracer warnings. */
move sp, r13
- mtspr SYSTEM_SAVE_1_0, r2
+ mtspr SPR_SYSTEM_SAVE_K_0, r2
}
FOR_EACH_CALLEE_SAVED_REG(LOAD_REG)
.L__switch_to_pc:
diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c
index e7d54c73d5c1..ae51cad12da0 100644
--- a/arch/tile/kernel/setup.c
+++ b/arch/tile/kernel/setup.c
@@ -30,8 +30,6 @@
#include <linux/timex.h>
#include <asm/setup.h>
#include <asm/sections.h>
-#include <asm/sections.h>
-#include <asm/cacheflush.h>
#include <asm/cacheflush.h>
#include <asm/pgalloc.h>
#include <asm/mmu_context.h>
@@ -187,11 +185,11 @@ early_param("vmalloc", parse_vmalloc);
#ifdef CONFIG_HIGHMEM
/*
- * Determine for each controller where its lowmem is mapped and how
- * much of it is mapped there. On controller zero, the first few
- * megabytes are mapped at 0xfd000000 as code, so in principle we
- * could start our data mappings higher up, but for now we don't
- * bother, to avoid additional confusion.
+ * Determine for each controller where its lowmem is mapped and how much of
+ * it is mapped there. On controller zero, the first few megabytes are
+ * already mapped in as code at MEM_SV_INTRPT, so in principle we could
+ * start our data mappings higher up, but for now we don't bother, to avoid
+ * additional confusion.
*
* One question is whether, on systems with more than 768 Mb and
* controllers of different sizes, to map in a proportionate amount of
@@ -311,7 +309,7 @@ static void __init setup_memory(void)
#endif
/* We are using a char to hold the cpu_2_node[] mapping */
- BUG_ON(MAX_NUMNODES > 127);
+ BUILD_BUG_ON(MAX_NUMNODES > 127);
/* Discover the ranges of memory available to us */
for (i = 0; ; ++i) {
@@ -876,6 +874,9 @@ void __cpuinit setup_cpu(int boot)
#if CHIP_HAS_SN_PROC()
raw_local_irq_unmask(INT_SNITLB_MISS);
#endif
+#ifdef __tilegx__
+ raw_local_irq_unmask(INT_SINGLE_STEP_K);
+#endif
/*
* Allow user access to many generic SPRs, like the cycle
@@ -893,11 +894,12 @@ void __cpuinit setup_cpu(int boot)
#endif
/*
- * Set the MPL for interrupt control 0 to user level.
- * This includes access to the SYSTEM_SAVE and EX_CONTEXT SPRs,
- * as well as the PL 0 interrupt mask.
+ * Set the MPL for interrupt control 0 & 1 to the corresponding
+ * values. This includes access to the SYSTEM_SAVE and EX_CONTEXT
+ * SPRs, as well as the interrupt mask.
*/
__insn_mtspr(SPR_MPL_INTCTRL_0_SET_0, 1);
+ __insn_mtspr(SPR_MPL_INTCTRL_1_SET_1, 1);
/* Initialize IRQ support for this cpu. */
setup_irq_regs();
@@ -1033,7 +1035,7 @@ static void __init validate_va(void)
* In addition, make sure we CAN'T use the end of memory, since
* we use the last chunk of each pgd for the pgd_list.
*/
- int i, fc_fd_ok = 0;
+ int i, user_kernel_ok = 0;
unsigned long max_va = 0;
unsigned long list_va =
((PGD_LIST_OFFSET / sizeof(pgd_t)) << PGDIR_SHIFT);
@@ -1044,13 +1046,13 @@ static void __init validate_va(void)
break;
if (range.start <= MEM_USER_INTRPT &&
range.start + range.size >= MEM_HV_INTRPT)
- fc_fd_ok = 1;
+ user_kernel_ok = 1;
if (range.start == 0)
max_va = range.size;
BUG_ON(range.start + range.size > list_va);
}
- if (!fc_fd_ok)
- early_panic("Hypervisor not configured for VAs 0xfc/0xfd\n");
+ if (!user_kernel_ok)
+ early_panic("Hypervisor not configured for user/kernel VAs\n");
if (max_va == 0)
early_panic("Hypervisor not configured for low VAs\n");
if (max_va < KERNEL_HIGH_VADDR)
@@ -1334,6 +1336,10 @@ static void __init pcpu_fc_populate_pte(unsigned long addr)
pte_t *pte;
BUG_ON(pgd_addr_invalid(addr));
+ if (addr < VMALLOC_START || addr >= VMALLOC_END)
+ panic("PCPU addr %#lx outside vmalloc range %#lx..%#lx;"
+ " try increasing CONFIG_VMALLOC_RESERVE\n",
+ addr, VMALLOC_START, VMALLOC_END);
pgd = swapper_pg_dir + pgd_index(addr);
pud = pud_offset(pgd, addr);
diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c
index ce183aa1492c..fb28e85ae3ae 100644
--- a/arch/tile/kernel/signal.c
+++ b/arch/tile/kernel/signal.c
@@ -41,8 +41,8 @@
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
-long _sys_sigaltstack(const stack_t __user *uss,
- stack_t __user *uoss, struct pt_regs *regs)
+SYSCALL_DEFINE3(sigaltstack, const stack_t __user *, uss,
+ stack_t __user *, uoss, struct pt_regs *, regs)
{
return do_sigaltstack(uss, uoss, regs->sp);
}
@@ -78,7 +78,7 @@ int restore_sigcontext(struct pt_regs *regs,
}
/* sigreturn() returns long since it restores r0 in the interrupted code. */
-long _sys_rt_sigreturn(struct pt_regs *regs)
+SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs)
{
struct rt_sigframe __user *frame =
(struct rt_sigframe __user *)(regs->sp);
diff --git a/arch/tile/kernel/single_step.c b/arch/tile/kernel/single_step.c
index 5ec4b9c651f2..1eb3b39e36c7 100644
--- a/arch/tile/kernel/single_step.c
+++ b/arch/tile/kernel/single_step.c
@@ -15,7 +15,7 @@
* Derived from iLib's single-stepping code.
*/
-#ifndef __tilegx__ /* No support for single-step yet. */
+#ifndef __tilegx__ /* Hardware support for single step unavailable. */
/* These functions are only used on the TILE platform */
#include <linux/slab.h>
@@ -660,4 +660,75 @@ void single_step_once(struct pt_regs *regs)
regs->pc += 8;
}
+#else
+#include <linux/smp.h>
+#include <linux/ptrace.h>
+#include <arch/spr_def.h>
+
+static DEFINE_PER_CPU(unsigned long, ss_saved_pc);
+
+
+/*
+ * Called directly on the occasion of an interrupt.
+ *
+ * If the process doesn't have single step set, then we use this as an
+ * opportunity to turn single step off.
+ *
+ * It has been mentioned that we could conditionally turn off single stepping
+ * on each entry into the kernel and rely on single_step_once to turn it
+ * on for the processes that matter (as we already do), but this
+ * implementation is somewhat more efficient in that we muck with registers
+ * once on a bum interrupt rather than on every entry into the kernel.
+ *
+ * If SINGLE_STEP_CONTROL_K has CANCELED set, then an interrupt occurred,
+ * so we have to run through this process again before we can say that an
+ * instruction has executed.
+ *
+ * swint will set CANCELED, but it's a legitimate instruction. Fortunately
+ * it changes the PC. If it hasn't changed, then we know that the interrupt
+ * wasn't generated by swint and we'll need to run this process again before
+ * we can say an instruction has executed.
+ *
+ * If either CANCELED == 0 or the PC's changed, we send out SIGTRAPs and get
+ * on with our lives.
+ */
+
+void gx_singlestep_handle(struct pt_regs *regs, int fault_num)
+{
+ unsigned long *ss_pc = &__get_cpu_var(ss_saved_pc);
+ struct thread_info *info = (void *)current_thread_info();
+ int is_single_step = test_ti_thread_flag(info, TIF_SINGLESTEP);
+ unsigned long control = __insn_mfspr(SPR_SINGLE_STEP_CONTROL_K);
+
+ if (is_single_step == 0) {
+ __insn_mtspr(SPR_SINGLE_STEP_EN_K_K, 0);
+
+ } else if ((*ss_pc != regs->pc) ||
+ (!(control & SPR_SINGLE_STEP_CONTROL_1__CANCELED_MASK))) {
+
+ ptrace_notify(SIGTRAP);
+ control |= SPR_SINGLE_STEP_CONTROL_1__CANCELED_MASK;
+ control |= SPR_SINGLE_STEP_CONTROL_1__INHIBIT_MASK;
+ __insn_mtspr(SPR_SINGLE_STEP_CONTROL_K, control);
+ }
+}
+
+
+/*
+ * Called from need_singlestep. Set up the control registers and the enable
+ * register, then return back.
+ */
+
+void single_step_once(struct pt_regs *regs)
+{
+ unsigned long *ss_pc = &__get_cpu_var(ss_saved_pc);
+ unsigned long control = __insn_mfspr(SPR_SINGLE_STEP_CONTROL_K);
+
+ *ss_pc = regs->pc;
+ control |= SPR_SINGLE_STEP_CONTROL_1__CANCELED_MASK;
+ control |= SPR_SINGLE_STEP_CONTROL_1__INHIBIT_MASK;
+ __insn_mtspr(SPR_SINGLE_STEP_CONTROL_K, control);
+ __insn_mtspr(SPR_SINGLE_STEP_EN_K_K, 1 << USER_PL);
+}
+
#endif /* !__tilegx__ */
diff --git a/arch/tile/kernel/smp.c b/arch/tile/kernel/smp.c
index 1cb5ec79de04..75255d90aff3 100644
--- a/arch/tile/kernel/smp.c
+++ b/arch/tile/kernel/smp.c
@@ -212,7 +212,7 @@ void __init ipi_init(void)
tile.x = cpu_x(cpu);
tile.y = cpu_y(cpu);
- if (hv_get_ipi_pte(tile, 1, &pte) != 0)
+ if (hv_get_ipi_pte(tile, KERNEL_PL, &pte) != 0)
panic("Failed to initialize IPI for cpu %d\n", cpu);
offset = hv_pte_get_pfn(pte) << PAGE_SHIFT;
diff --git a/arch/tile/kernel/stack.c b/arch/tile/kernel/stack.c
index ea2e0ce28380..0d54106be3d6 100644
--- a/arch/tile/kernel/stack.c
+++ b/arch/tile/kernel/stack.c
@@ -30,6 +30,10 @@
#include <arch/abi.h>
#include <arch/interrupts.h>
+#define KBT_ONGOING 0 /* Backtrace still ongoing */
+#define KBT_DONE 1 /* Backtrace cleanly completed */
+#define KBT_RUNNING 2 /* Can't run backtrace on a running task */
+#define KBT_LOOP 3 /* Backtrace entered a loop */
/* Is address on the specified kernel stack? */
static int in_kernel_stack(struct KBacktraceIterator *kbt, VirtualAddress sp)
@@ -207,11 +211,11 @@ static int KBacktraceIterator_next_item_inclusive(
for (;;) {
do {
if (!KBacktraceIterator_is_sigreturn(kbt))
- return 1;
+ return KBT_ONGOING;
} while (backtrace_next(&kbt->it));
if (!KBacktraceIterator_restart(kbt))
- return 0;
+ return KBT_DONE;
}
}
@@ -264,7 +268,7 @@ void KBacktraceIterator_init(struct KBacktraceIterator *kbt,
kbt->pgtable = NULL;
kbt->verbose = 0; /* override in caller if desired */
kbt->profile = 0; /* override in caller if desired */
- kbt->end = 0;
+ kbt->end = KBT_ONGOING;
kbt->new_context = 0;
if (is_current) {
HV_PhysAddr pgdir_pa = hv_inquire_context().page_table;
@@ -290,7 +294,7 @@ void KBacktraceIterator_init(struct KBacktraceIterator *kbt,
if (regs == NULL) {
if (is_current || t->state == TASK_RUNNING) {
/* Can't do this; we need registers */
- kbt->end = 1;
+ kbt->end = KBT_RUNNING;
return;
}
pc = get_switch_to_pc();
@@ -305,26 +309,29 @@ void KBacktraceIterator_init(struct KBacktraceIterator *kbt,
}
backtrace_init(&kbt->it, read_memory_func, kbt, pc, lr, sp, r52);
- kbt->end = !KBacktraceIterator_next_item_inclusive(kbt);
+ kbt->end = KBacktraceIterator_next_item_inclusive(kbt);
}
EXPORT_SYMBOL(KBacktraceIterator_init);
int KBacktraceIterator_end(struct KBacktraceIterator *kbt)
{
- return kbt->end;
+ return kbt->end != KBT_ONGOING;
}
EXPORT_SYMBOL(KBacktraceIterator_end);
void KBacktraceIterator_next(struct KBacktraceIterator *kbt)
{
+ VirtualAddress old_pc = kbt->it.pc, old_sp = kbt->it.sp;
kbt->new_context = 0;
- if (!backtrace_next(&kbt->it) &&
- !KBacktraceIterator_restart(kbt)) {
- kbt->end = 1;
- return;
- }
-
- kbt->end = !KBacktraceIterator_next_item_inclusive(kbt);
+ if (!backtrace_next(&kbt->it) && !KBacktraceIterator_restart(kbt)) {
+ kbt->end = KBT_DONE;
+ return;
+ }
+ kbt->end = KBacktraceIterator_next_item_inclusive(kbt);
+ if (old_pc == kbt->it.pc && old_sp == kbt->it.sp) {
+ /* Trapped in a loop; give up. */
+ kbt->end = KBT_LOOP;
+ }
}
EXPORT_SYMBOL(KBacktraceIterator_next);
@@ -387,6 +394,8 @@ void tile_show_stack(struct KBacktraceIterator *kbt, int headers)
break;
}
}
+ if (kbt->end == KBT_LOOP)
+ pr_err("Stack dump stopped; next frame identical to this one\n");
if (headers)
pr_err("Stack dump complete\n");
}
diff --git a/arch/tile/kernel/sys.c b/arch/tile/kernel/sys.c
index f0f87eab8c39..7e764669a022 100644
--- a/arch/tile/kernel/sys.c
+++ b/arch/tile/kernel/sys.c
@@ -110,6 +110,15 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
#define sys_sync_file_range sys_sync_file_range2
#endif
+/* Call the trampolines to manage pt_regs where necessary. */
+#define sys_execve _sys_execve
+#define sys_sigaltstack _sys_sigaltstack
+#define sys_rt_sigreturn _sys_rt_sigreturn
+#define sys_clone _sys_clone
+#ifndef __tilegx__
+#define sys_cmpxchg_badaddr _sys_cmpxchg_badaddr
+#endif
+
/*
* Note that we can't include <linux/unistd.h> here since the header
* guard will defeat us; <asm/unistd.h> checks for __SYSCALL as well.
diff --git a/arch/tile/kernel/traps.c b/arch/tile/kernel/traps.c
index 0f362dc2c57f..5474fc2e77e8 100644
--- a/arch/tile/kernel/traps.c
+++ b/arch/tile/kernel/traps.c
@@ -260,7 +260,7 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
address = regs->pc;
break;
case INT_UNALIGN_DATA:
-#ifndef __tilegx__ /* FIXME: GX: no single-step yet */
+#ifndef __tilegx__ /* Emulated support for single step debugging */
if (unaligned_fixup >= 0) {
struct single_step_state *state =
current_thread_info()->step_state;
@@ -278,7 +278,7 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
case INT_DOUBLE_FAULT:
/*
* For double fault, "reason" is actually passed as
- * SYSTEM_SAVE_1_2, the hypervisor's double-fault info, so
+ * SYSTEM_SAVE_K_2, the hypervisor's double-fault info, so
* we can provide the original fault number rather than
* the uninteresting "INT_DOUBLE_FAULT" so the user can
* learn what actually struck while PL0 ICS was set.
diff --git a/arch/tile/kvm/Kconfig b/arch/tile/kvm/Kconfig
new file mode 100644
index 000000000000..b88f9c047781
--- /dev/null
+++ b/arch/tile/kvm/Kconfig
@@ -0,0 +1,38 @@
+#
+# KVM configuration
+#
+
+source "virt/kvm/Kconfig"
+
+menuconfig VIRTUALIZATION
+ bool "Virtualization"
+ ---help---
+ Say Y here to get to see options for using your Linux host to run
+ other operating systems inside virtual machines (guests).
+ This option alone does not add any kernel code.
+
+ If you say N, all options in this submenu will be skipped and
+ disabled.
+
+if VIRTUALIZATION
+
+config KVM
+ tristate "Kernel-based Virtual Machine (KVM) support"
+ depends on HAVE_KVM && MODULES && EXPERIMENTAL
+ select PREEMPT_NOTIFIERS
+ select ANON_INODES
+ ---help---
+ Support hosting paravirtualized guest machines.
+
+ This module provides access to the hardware capabilities through
+ a character device node named /dev/kvm.
+
+ To compile this as a module, choose M here: the module
+ will be called kvm.
+
+ If unsure, say N.
+
+source drivers/vhost/Kconfig
+source drivers/virtio/Kconfig
+
+endif # VIRTUALIZATION
diff --git a/arch/tile/lib/Makefile b/arch/tile/lib/Makefile
index 746dc81ed3c4..93122d5b1558 100644
--- a/arch/tile/lib/Makefile
+++ b/arch/tile/lib/Makefile
@@ -3,8 +3,8 @@
#
lib-y = cacheflush.o checksum.o cpumask.o delay.o \
- mb_incoherent.o uaccess.o \
- memcpy_$(BITS).o memchr_$(BITS).o memmove_$(BITS).o memset_$(BITS).o \
+ mb_incoherent.o uaccess.o memmove.o \
+ memcpy_$(BITS).o memchr_$(BITS).o memset_$(BITS).o \
strchr_$(BITS).o strlen_$(BITS).o
ifeq ($(CONFIG_TILEGX),y)
diff --git a/arch/tile/lib/atomic_32.c b/arch/tile/lib/atomic_32.c
index 8040b42a8eea..7a5cc706ab62 100644
--- a/arch/tile/lib/atomic_32.c
+++ b/arch/tile/lib/atomic_32.c
@@ -300,7 +300,7 @@ void __init __init_atomic_per_cpu(void)
#else /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
/* Validate power-of-two and "bigger than cpus" assumption */
- BUG_ON(ATOMIC_HASH_SIZE & (ATOMIC_HASH_SIZE-1));
+ BUILD_BUG_ON(ATOMIC_HASH_SIZE & (ATOMIC_HASH_SIZE-1));
BUG_ON(ATOMIC_HASH_SIZE < nr_cpu_ids);
/*
@@ -314,17 +314,17 @@ void __init __init_atomic_per_cpu(void)
BUG_ON((unsigned long)atomic_locks % PAGE_SIZE != 0);
/* The locks must all fit on one page. */
- BUG_ON(ATOMIC_HASH_SIZE * sizeof(int) > PAGE_SIZE);
+ BUILD_BUG_ON(ATOMIC_HASH_SIZE * sizeof(int) > PAGE_SIZE);
/*
* We use the page offset of the atomic value's address as
* an index into atomic_locks, excluding the low 3 bits.
* That should not produce more indices than ATOMIC_HASH_SIZE.
*/
- BUG_ON((PAGE_SIZE >> 3) > ATOMIC_HASH_SIZE);
+ BUILD_BUG_ON((PAGE_SIZE >> 3) > ATOMIC_HASH_SIZE);
#endif /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
/* The futex code makes this assumption, so we validate it here. */
- BUG_ON(sizeof(atomic_t) != sizeof(int));
+ BUILD_BUG_ON(sizeof(atomic_t) != sizeof(int));
}
diff --git a/arch/tile/lib/exports.c b/arch/tile/lib/exports.c
index ce5dbf56578f..1509c5597653 100644
--- a/arch/tile/lib/exports.c
+++ b/arch/tile/lib/exports.c
@@ -45,6 +45,9 @@ EXPORT_SYMBOL(__copy_from_user_zeroing);
EXPORT_SYMBOL(__copy_in_user_inatomic);
#endif
+/* arch/tile/lib/mb_incoherent.S */
+EXPORT_SYMBOL(__mb_incoherent);
+
/* hypervisor glue */
#include <hv/hypervisor.h>
EXPORT_SYMBOL(hv_dev_open);
diff --git a/arch/tile/lib/memcpy_32.S b/arch/tile/lib/memcpy_32.S
index 30c3b7ebb55d..2a419a6122db 100644
--- a/arch/tile/lib/memcpy_32.S
+++ b/arch/tile/lib/memcpy_32.S
@@ -10,14 +10,16 @@
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
- *
- * This file shares the implementation of the userspace memcpy and
- * the kernel's memcpy, copy_to_user and copy_from_user.
*/
#include <arch/chip.h>
+/*
+ * This file shares the implementation of the userspace memcpy and
+ * the kernel's memcpy, copy_to_user and copy_from_user.
+ */
+
#include <linux/linkage.h>
/* On TILE64, we wrap these functions via arch/tile/lib/memcpy_tile64.c */
@@ -53,9 +55,9 @@
*/
ENTRY(__copy_from_user_inatomic)
.type __copy_from_user_inatomic, @function
- FEEDBACK_ENTER_EXPLICIT(__copy_from_user_inatomic, \
+ FEEDBACK_ENTER_EXPLICIT(__copy_from_user_inatomic, \
.text.memcpy_common, \
- .Lend_memcpy_common - __copy_from_user_inatomic)
+ .Lend_memcpy_common - __copy_from_user_inatomic)
{ movei r29, IS_COPY_FROM_USER; j memcpy_common }
.size __copy_from_user_inatomic, . - __copy_from_user_inatomic
@@ -64,7 +66,7 @@ ENTRY(__copy_from_user_inatomic)
*/
ENTRY(__copy_from_user_zeroing)
.type __copy_from_user_zeroing, @function
- FEEDBACK_REENTER(__copy_from_user_inatomic)
+ FEEDBACK_REENTER(__copy_from_user_inatomic)
{ movei r29, IS_COPY_FROM_USER_ZEROING; j memcpy_common }
.size __copy_from_user_zeroing, . - __copy_from_user_zeroing
@@ -74,13 +76,13 @@ ENTRY(__copy_from_user_zeroing)
*/
ENTRY(__copy_to_user_inatomic)
.type __copy_to_user_inatomic, @function
- FEEDBACK_REENTER(__copy_from_user_inatomic)
+ FEEDBACK_REENTER(__copy_from_user_inatomic)
{ movei r29, IS_COPY_TO_USER; j memcpy_common }
.size __copy_to_user_inatomic, . - __copy_to_user_inatomic
ENTRY(memcpy)
.type memcpy, @function
- FEEDBACK_REENTER(__copy_from_user_inatomic)
+ FEEDBACK_REENTER(__copy_from_user_inatomic)
{ movei r29, IS_MEMCPY }
.size memcpy, . - memcpy
/* Fall through */
@@ -157,35 +159,35 @@ EX: { sw r0, r3; addi r0, r0, 4; addi r2, r2, -4 }
{ addi r3, r1, 60; andi r9, r9, -64 }
#if CHIP_HAS_WH64()
- /* No need to prefetch dst, we'll just do the wh64
- * right before we copy a line.
+ /* No need to prefetch dst, we'll just do the wh64
+ * right before we copy a line.
*/
#endif
EX: { lw r5, r3; addi r3, r3, 64; movei r4, 1 }
- /* Intentionally stall for a few cycles to leave L2 cache alone. */
- { bnzt zero, .; move r27, lr }
+ /* Intentionally stall for a few cycles to leave L2 cache alone. */
+ { bnzt zero, .; move r27, lr }
EX: { lw r6, r3; addi r3, r3, 64 }
- /* Intentionally stall for a few cycles to leave L2 cache alone. */
- { bnzt zero, . }
+ /* Intentionally stall for a few cycles to leave L2 cache alone. */
+ { bnzt zero, . }
EX: { lw r7, r3; addi r3, r3, 64 }
#if !CHIP_HAS_WH64()
- /* Prefetch the dest */
- /* Intentionally stall for a few cycles to leave L2 cache alone. */
- { bnzt zero, . }
- /* Use a real load to cause a TLB miss if necessary. We aren't using
- * r28, so this should be fine.
- */
+ /* Prefetch the dest */
+ /* Intentionally stall for a few cycles to leave L2 cache alone. */
+ { bnzt zero, . }
+ /* Use a real load to cause a TLB miss if necessary. We aren't using
+ * r28, so this should be fine.
+ */
EX: { lw r28, r9; addi r9, r9, 64 }
- /* Intentionally stall for a few cycles to leave L2 cache alone. */
- { bnzt zero, . }
- { prefetch r9; addi r9, r9, 64 }
- /* Intentionally stall for a few cycles to leave L2 cache alone. */
- { bnzt zero, . }
- { prefetch r9; addi r9, r9, 64 }
+ /* Intentionally stall for a few cycles to leave L2 cache alone. */
+ { bnzt zero, . }
+ { prefetch r9; addi r9, r9, 64 }
+ /* Intentionally stall for a few cycles to leave L2 cache alone. */
+ { bnzt zero, . }
+ { prefetch r9; addi r9, r9, 64 }
#endif
- /* Intentionally stall for a few cycles to leave L2 cache alone. */
- { bz zero, .Lbig_loop2 }
+ /* Intentionally stall for a few cycles to leave L2 cache alone. */
+ { bz zero, .Lbig_loop2 }
/* On entry to this loop:
* - r0 points to the start of dst line 0
@@ -197,7 +199,7 @@ EX: { lw r28, r9; addi r9, r9, 64 }
* to some "safe" recently loaded address.
* - r5 contains *(r1 + 60) [i.e. last word of source line 0]
* - r6 contains *(r1 + 64 + 60) [i.e. last word of source line 1]
- * - r9 contains ((r0 + 63) & -64)
+ * - r9 contains ((r0 + 63) & -64)
* [start of next dst cache line.]
*/
@@ -208,137 +210,137 @@ EX: { lw r28, r9; addi r9, r9, 64 }
/* Copy line 0, first stalling until r5 is ready. */
EX: { move r12, r5; lw r16, r1 }
{ bz r4, .Lcopy_8_check; slti_u r8, r2, 8 }
- /* Prefetch several lines ahead. */
+ /* Prefetch several lines ahead. */
EX: { lw r5, r3; addi r3, r3, 64 }
- { jal .Lcopy_line }
+ { jal .Lcopy_line }
/* Copy line 1, first stalling until r6 is ready. */
EX: { move r12, r6; lw r16, r1 }
{ bz r4, .Lcopy_8_check; slti_u r8, r2, 8 }
- /* Prefetch several lines ahead. */
+ /* Prefetch several lines ahead. */
EX: { lw r6, r3; addi r3, r3, 64 }
{ jal .Lcopy_line }
/* Copy line 2, first stalling until r7 is ready. */
EX: { move r12, r7; lw r16, r1 }
{ bz r4, .Lcopy_8_check; slti_u r8, r2, 8 }
- /* Prefetch several lines ahead. */
+ /* Prefetch several lines ahead. */
EX: { lw r7, r3; addi r3, r3, 64 }
- /* Use up a caches-busy cycle by jumping back to the top of the
- * loop. Might as well get it out of the way now.
- */
- { j .Lbig_loop }
+ /* Use up a caches-busy cycle by jumping back to the top of the
+ * loop. Might as well get it out of the way now.
+ */
+ { j .Lbig_loop }
/* On entry:
* - r0 points to the destination line.
* - r1 points to the source line.
- * - r3 is the next prefetch address.
+ * - r3 is the next prefetch address.
* - r9 holds the last address used for wh64.
* - r12 = WORD_15
- * - r16 = WORD_0.
- * - r17 == r1 + 16.
- * - r27 holds saved lr to restore.
+ * - r16 = WORD_0.
+ * - r17 == r1 + 16.
+ * - r27 holds saved lr to restore.
*
* On exit:
* - r0 is incremented by 64.
* - r1 is incremented by 64, unless that would point to a word
- * beyond the end of the source array, in which case it is redirected
- * to point to an arbitrary word already in the cache.
+ * beyond the end of the source array, in which case it is redirected
+ * to point to an arbitrary word already in the cache.
* - r2 is decremented by 64.
- * - r3 is unchanged, unless it points to a word beyond the
- * end of the source array, in which case it is redirected
- * to point to an arbitrary word already in the cache.
- * Redirecting is OK since if we are that close to the end
- * of the array we will not come back to this subroutine
- * and use the contents of the prefetched address.
+ * - r3 is unchanged, unless it points to a word beyond the
+ * end of the source array, in which case it is redirected
+ * to point to an arbitrary word already in the cache.
+ * Redirecting is OK since if we are that close to the end
+ * of the array we will not come back to this subroutine
+ * and use the contents of the prefetched address.
* - r4 is nonzero iff r2 >= 64.
- * - r9 is incremented by 64, unless it points beyond the
- * end of the last full destination cache line, in which
- * case it is redirected to a "safe address" that can be
- * clobbered (sp - 64)
+ * - r9 is incremented by 64, unless it points beyond the
+ * end of the last full destination cache line, in which
+ * case it is redirected to a "safe address" that can be
+ * clobbered (sp - 64)
* - lr contains the value in r27.
*/
/* r26 unused */
.Lcopy_line:
- /* TODO: when r3 goes past the end, we would like to redirect it
- * to prefetch the last partial cache line (if any) just once, for the
- * benefit of the final cleanup loop. But we don't want to
- * prefetch that line more than once, or subsequent prefetches
- * will go into the RTF. But then .Lbig_loop should unconditionally
- * branch to top of loop to execute final prefetch, and its
- * nop should become a conditional branch.
- */
-
- /* We need two non-memory cycles here to cover the resources
- * used by the loads initiated by the caller.
- */
- { add r15, r1, r2 }
+ /* TODO: when r3 goes past the end, we would like to redirect it
+ * to prefetch the last partial cache line (if any) just once, for the
+ * benefit of the final cleanup loop. But we don't want to
+ * prefetch that line more than once, or subsequent prefetches
+ * will go into the RTF. But then .Lbig_loop should unconditionally
+ * branch to top of loop to execute final prefetch, and its
+ * nop should become a conditional branch.
+ */
+
+ /* We need two non-memory cycles here to cover the resources
+ * used by the loads initiated by the caller.
+ */
+ { add r15, r1, r2 }
.Lcopy_line2:
- { slt_u r13, r3, r15; addi r17, r1, 16 }
+ { slt_u r13, r3, r15; addi r17, r1, 16 }
- /* NOTE: this will stall for one cycle as L1 is busy. */
+ /* NOTE: this will stall for one cycle as L1 is busy. */
- /* Fill second L1D line. */
+ /* Fill second L1D line. */
EX: { lw r17, r17; addi r1, r1, 48; mvz r3, r13, r1 } /* r17 = WORD_4 */
#if CHIP_HAS_WH64()
- /* Prepare destination line for writing. */
+ /* Prepare destination line for writing. */
EX: { wh64 r9; addi r9, r9, 64 }
#else
- /* Prefetch dest line */
+ /* Prefetch dest line */
{ prefetch r9; addi r9, r9, 64 }
#endif
- /* Load seven words that are L1D hits to cover wh64 L2 usage. */
+ /* Load seven words that are L1D hits to cover wh64 L2 usage. */
- /* Load the three remaining words from the last L1D line, which
- * we know has already filled the L1D.
- */
+ /* Load the three remaining words from the last L1D line, which
+ * we know has already filled the L1D.
+ */
EX: { lw r4, r1; addi r1, r1, 4; addi r20, r1, 16 } /* r4 = WORD_12 */
EX: { lw r8, r1; addi r1, r1, 4; slt_u r13, r20, r15 }/* r8 = WORD_13 */
EX: { lw r11, r1; addi r1, r1, -52; mvz r20, r13, r1 } /* r11 = WORD_14 */
- /* Load the three remaining words from the first L1D line, first
- * stalling until it has filled by "looking at" r16.
- */
+ /* Load the three remaining words from the first L1D line, first
+ * stalling until it has filled by "looking at" r16.
+ */
EX: { lw r13, r1; addi r1, r1, 4; move zero, r16 } /* r13 = WORD_1 */
EX: { lw r14, r1; addi r1, r1, 4 } /* r14 = WORD_2 */
EX: { lw r15, r1; addi r1, r1, 8; addi r10, r0, 60 } /* r15 = WORD_3 */
- /* Load second word from the second L1D line, first
- * stalling until it has filled by "looking at" r17.
- */
+ /* Load second word from the second L1D line, first
+ * stalling until it has filled by "looking at" r17.
+ */
EX: { lw r19, r1; addi r1, r1, 4; move zero, r17 } /* r19 = WORD_5 */
- /* Store last word to the destination line, potentially dirtying it
- * for the first time, which keeps the L2 busy for two cycles.
- */
+ /* Store last word to the destination line, potentially dirtying it
+ * for the first time, which keeps the L2 busy for two cycles.
+ */
EX: { sw r10, r12 } /* store(WORD_15) */
- /* Use two L1D hits to cover the sw L2 access above. */
+ /* Use two L1D hits to cover the sw L2 access above. */
EX: { lw r10, r1; addi r1, r1, 4 } /* r10 = WORD_6 */
EX: { lw r12, r1; addi r1, r1, 4 } /* r12 = WORD_7 */
- /* Fill third L1D line. */
+ /* Fill third L1D line. */
EX: { lw r18, r1; addi r1, r1, 4 } /* r18 = WORD_8 */
- /* Store first L1D line. */
+ /* Store first L1D line. */
EX: { sw r0, r16; addi r0, r0, 4; add r16, r0, r2 } /* store(WORD_0) */
EX: { sw r0, r13; addi r0, r0, 4; andi r16, r16, -64 } /* store(WORD_1) */
EX: { sw r0, r14; addi r0, r0, 4; slt_u r16, r9, r16 } /* store(WORD_2) */
#if CHIP_HAS_WH64()
EX: { sw r0, r15; addi r0, r0, 4; addi r13, sp, -64 } /* store(WORD_3) */
#else
- /* Back up the r9 to a cache line we are already storing to
+ /* Back up the r9 to a cache line we are already storing to
* if it gets past the end of the dest vector. Strictly speaking,
* we don't need to back up to the start of a cache line, but it's free
* and tidy, so why not?
- */
+ */
EX: { sw r0, r15; addi r0, r0, 4; andi r13, r0, -64 } /* store(WORD_3) */
#endif
- /* Store second L1D line. */
+ /* Store second L1D line. */
EX: { sw r0, r17; addi r0, r0, 4; mvz r9, r16, r13 }/* store(WORD_4) */
EX: { sw r0, r19; addi r0, r0, 4 } /* store(WORD_5) */
EX: { sw r0, r10; addi r0, r0, 4 } /* store(WORD_6) */
@@ -348,30 +350,30 @@ EX: { lw r13, r1; addi r1, r1, 4; move zero, r18 } /* r13 = WORD_9 */
EX: { lw r14, r1; addi r1, r1, 4 } /* r14 = WORD_10 */
EX: { lw r15, r1; move r1, r20 } /* r15 = WORD_11 */
- /* Store third L1D line. */
+ /* Store third L1D line. */
EX: { sw r0, r18; addi r0, r0, 4 } /* store(WORD_8) */
EX: { sw r0, r13; addi r0, r0, 4 } /* store(WORD_9) */
EX: { sw r0, r14; addi r0, r0, 4 } /* store(WORD_10) */
EX: { sw r0, r15; addi r0, r0, 4 } /* store(WORD_11) */
- /* Store rest of fourth L1D line. */
+ /* Store rest of fourth L1D line. */
EX: { sw r0, r4; addi r0, r0, 4 } /* store(WORD_12) */
- {
+ {
EX: sw r0, r8 /* store(WORD_13) */
- addi r0, r0, 4
+ addi r0, r0, 4
/* Will r2 be > 64 after we subtract 64 below? */
- shri r4, r2, 7
- }
- {
+ shri r4, r2, 7
+ }
+ {
EX: sw r0, r11 /* store(WORD_14) */
- addi r0, r0, 8
- /* Record 64 bytes successfully copied. */
- addi r2, r2, -64
- }
+ addi r0, r0, 8
+ /* Record 64 bytes successfully copied. */
+ addi r2, r2, -64
+ }
{ jrp lr; move lr, r27 }
- /* Convey to the backtrace library that the stack frame is size
+ /* Convey to the backtrace library that the stack frame is size
* zero, and the real return address is on the stack rather than
* in 'lr'.
*/
diff --git a/arch/tile/lib/memmove_32.c b/arch/tile/lib/memmove.c
index fd615ae6ade7..fd615ae6ade7 100644
--- a/arch/tile/lib/memmove_32.c
+++ b/arch/tile/lib/memmove.c
diff --git a/arch/tile/lib/memset_32.c b/arch/tile/lib/memset_32.c
index d014c1fbcbc2..57dbb3a5bff8 100644
--- a/arch/tile/lib/memset_32.c
+++ b/arch/tile/lib/memset_32.c
@@ -18,6 +18,7 @@
#include <linux/string.h>
#include <linux/module.h>
+#undef memset
void *memset(void *s, int c, size_t n)
{
diff --git a/arch/tile/lib/strlen_32.c b/arch/tile/lib/strlen_32.c
index f26f88e11e4a..4974292a5534 100644
--- a/arch/tile/lib/strlen_32.c
+++ b/arch/tile/lib/strlen_32.c
@@ -16,6 +16,8 @@
#include <linux/string.h>
#include <linux/module.h>
+#undef strlen
+
size_t strlen(const char *s)
{
/* Get an aligned pointer. */
diff --git a/arch/tile/mm/fault.c b/arch/tile/mm/fault.c
index 704f3e8a4385..f295b4ac941d 100644
--- a/arch/tile/mm/fault.c
+++ b/arch/tile/mm/fault.c
@@ -66,10 +66,10 @@ static noinline void force_sig_info_fault(int si_signo, int si_code,
#ifndef __tilegx__
/*
* Synthesize the fault a PL0 process would get by doing a word-load of
- * an unaligned address or a high kernel address. Called indirectly
- * from sys_cmpxchg() in kernel/intvec.S.
+ * an unaligned address or a high kernel address.
*/
-int _sys_cmpxchg_badaddr(unsigned long address, struct pt_regs *regs)
+SYSCALL_DEFINE2(cmpxchg_badaddr, unsigned long, address,
+ struct pt_regs *, regs)
{
if (address >= PAGE_OFFSET)
force_sig_info_fault(SIGSEGV, SEGV_MAPERR, address,
@@ -563,10 +563,10 @@ do_sigbus:
/*
* When we take an ITLB or DTLB fault or access violation in the
* supervisor while the critical section bit is set, the hypervisor is
- * reluctant to write new values into the EX_CONTEXT_1_x registers,
+ * reluctant to write new values into the EX_CONTEXT_K_x registers,
* since that might indicate we have not yet squirreled the SPR
* contents away and can thus safely take a recursive interrupt.
- * Accordingly, the hypervisor passes us the PC via SYSTEM_SAVE_1_2.
+ * Accordingly, the hypervisor passes us the PC via SYSTEM_SAVE_K_2.
*
* Note that this routine is called before homecache_tlb_defer_enter(),
* which means that we can properly unlock any atomics that might
@@ -610,7 +610,7 @@ struct intvec_state do_page_fault_ics(struct pt_regs *regs, int fault_num,
* fault. We didn't set up a kernel stack on initial entry to
* sys_cmpxchg, but instead had one set up by the fault, which
* (because sys_cmpxchg never releases ICS) came to us via the
- * SYSTEM_SAVE_1_2 mechanism, and thus EX_CONTEXT_1_[01] are
+ * SYSTEM_SAVE_K_2 mechanism, and thus EX_CONTEXT_K_[01] are
* still referencing the original user code. We release the
* atomic lock and rewrite pt_regs so that it appears that we
* came from user-space directly, and after we finish the
diff --git a/arch/tile/mm/highmem.c b/arch/tile/mm/highmem.c
index 12ab137e7d4f..abb57331cf6e 100644
--- a/arch/tile/mm/highmem.c
+++ b/arch/tile/mm/highmem.c
@@ -56,50 +56,6 @@ void kunmap(struct page *page)
}
EXPORT_SYMBOL(kunmap);
-static void debug_kmap_atomic_prot(enum km_type type)
-{
-#ifdef CONFIG_DEBUG_HIGHMEM
- static unsigned warn_count = 10;
-
- if (unlikely(warn_count == 0))
- return;
-
- if (unlikely(in_interrupt())) {
- if (in_irq()) {
- if (type != KM_IRQ0 && type != KM_IRQ1 &&
- type != KM_BIO_SRC_IRQ &&
- /* type != KM_BIO_DST_IRQ && */
- type != KM_BOUNCE_READ) {
- WARN_ON(1);
- warn_count--;
- }
- } else if (!irqs_disabled()) { /* softirq */
- if (type != KM_IRQ0 && type != KM_IRQ1 &&
- type != KM_SOFTIRQ0 && type != KM_SOFTIRQ1 &&
- type != KM_SKB_SUNRPC_DATA &&
- type != KM_SKB_DATA_SOFTIRQ &&
- type != KM_BOUNCE_READ) {
- WARN_ON(1);
- warn_count--;
- }
- }
- }
-
- if (type == KM_IRQ0 || type == KM_IRQ1 || type == KM_BOUNCE_READ ||
- type == KM_BIO_SRC_IRQ /* || type == KM_BIO_DST_IRQ */) {
- if (!irqs_disabled()) {
- WARN_ON(1);
- warn_count--;
- }
- } else if (type == KM_SOFTIRQ0 || type == KM_SOFTIRQ1) {
- if (irq_count() == 0 && !irqs_disabled()) {
- WARN_ON(1);
- warn_count--;
- }
- }
-#endif
-}
-
/*
* Describe a single atomic mapping of a page on a given cpu at a
* given address, and allow it to be linked into a list.
@@ -240,10 +196,10 @@ void kmap_atomic_fix_kpte(struct page *page, int finished)
* When holding an atomic kmap is is not legal to sleep, so atomic
* kmaps are appropriate for short, tight code paths only.
*/
-void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot)
+void *kmap_atomic_prot(struct page *page, pgprot_t prot)
{
- enum fixed_addresses idx;
unsigned long vaddr;
+ int idx, type;
pte_t *pte;
/* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
@@ -255,8 +211,7 @@ void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot)
if (!PageHighMem(page))
return page_address(page);
- debug_kmap_atomic_prot(type);
-
+ type = kmap_atomic_idx_push();
idx = type + KM_TYPE_NR*smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
pte = kmap_get_pte(vaddr);
@@ -269,28 +224,35 @@ void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot)
}
EXPORT_SYMBOL(kmap_atomic_prot);
-void *kmap_atomic(struct page *page, enum km_type type)
+void *__kmap_atomic(struct page *page)
{
/* PAGE_NONE is a magic value that tells us to check immutability. */
return kmap_atomic_prot(page, type, PAGE_NONE);
}
-EXPORT_SYMBOL(kmap_atomic);
+EXPORT_SYMBOL(__kmap_atomic);
-void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type)
+void __kunmap_atomic(void *kvaddr)
{
unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
- enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
- /*
- * Force other mappings to Oops if they try to access this pte without
- * first remapping it. Keeping stale mappings around is a bad idea.
- */
- if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) {
+ if (vaddr >= __fix_to_virt(FIX_KMAP_END) &&
+ vaddr <= __fix_to_virt(FIX_KMAP_BEGIN)) {
pte_t *pte = kmap_get_pte(vaddr);
pte_t pteval = *pte;
+ int idx, type;
+
+ type = kmap_atomic_idx();
+ idx = type + KM_TYPE_NR*smp_processor_id();
+
+ /*
+ * Force other mappings to Oops if they try to access this pte
+ * without first remapping it. Keeping stale mappings around
+ * is a bad idea.
+ */
BUG_ON(!pte_present(pteval) && !pte_migrating(pteval));
kmap_atomic_unregister(pte_page(pteval), vaddr);
kpte_clear_flush(pte, vaddr);
+ kmap_atomic_idx_pop();
} else {
/* Must be a lowmem page */
BUG_ON(vaddr < PAGE_OFFSET);
@@ -300,19 +262,19 @@ void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type)
arch_flush_lazy_mmu_mode();
pagefault_enable();
}
-EXPORT_SYMBOL(kunmap_atomic_notypecheck);
+EXPORT_SYMBOL(__kunmap_atomic);
/*
* This API is supposed to allow us to map memory without a "struct page".
* Currently we don't support this, though this may change in the future.
*/
-void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
+void *kmap_atomic_pfn(unsigned long pfn)
{
- return kmap_atomic(pfn_to_page(pfn), type);
+ return kmap_atomic(pfn_to_page(pfn));
}
-void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot)
+void *kmap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot)
{
- return kmap_atomic_prot(pfn_to_page(pfn), type, prot);
+ return kmap_atomic_prot(pfn_to_page(pfn), prot);
}
struct page *kmap_atomic_to_page(void *ptr)
diff --git a/arch/tile/mm/homecache.c b/arch/tile/mm/homecache.c
index fb3b4a55cec4..d78df3a6ee15 100644
--- a/arch/tile/mm/homecache.c
+++ b/arch/tile/mm/homecache.c
@@ -37,6 +37,8 @@
#include <asm/pgalloc.h>
#include <asm/homecache.h>
+#include <arch/sim.h>
+
#include "migrate.h"
@@ -217,13 +219,6 @@ static unsigned long cache_flush_length(unsigned long length)
return (length >= CHIP_L2_CACHE_SIZE()) ? HV_FLUSH_EVICT_L2 : length;
}
-/* On the simulator, confirm lines have been evicted everywhere. */
-static void validate_lines_evicted(unsigned long pfn, size_t length)
-{
- sim_syscall(SIM_SYSCALL_VALIDATE_LINES_EVICTED,
- (HV_PhysAddr)pfn << PAGE_SHIFT, length);
-}
-
/* Flush a page out of whatever cache(s) it is in. */
void homecache_flush_cache(struct page *page, int order)
{
@@ -234,7 +229,7 @@ void homecache_flush_cache(struct page *page, int order)
homecache_mask(page, pages, &home_mask);
flush_remote(pfn, length, &home_mask, 0, 0, 0, NULL, NULL, 0);
- validate_lines_evicted(pfn, pages * PAGE_SIZE);
+ sim_validate_lines_evicted(PFN_PHYS(pfn), pages * PAGE_SIZE);
}
diff --git a/arch/tile/mm/init.c b/arch/tile/mm/init.c
index d89c9eacd162..78e1982cb6c9 100644
--- a/arch/tile/mm/init.c
+++ b/arch/tile/mm/init.c
@@ -1060,7 +1060,7 @@ void free_initmem(void)
/*
* Free the pages mapped from 0xc0000000 that correspond to code
- * pages from 0xfd000000 that we won't use again after init.
+ * pages from MEM_SV_INTRPT that we won't use again after init.
*/
free_init_pages("unused kernel text",
(unsigned long)_sinittext - text_delta,
diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common
index 7c8e277f6d34..049d048b070d 100644
--- a/arch/um/Kconfig.common
+++ b/arch/um/Kconfig.common
@@ -19,8 +19,6 @@ config MMU
config NO_IOMEM
def_bool y
-mainmenu "Linux/Usermode Kernel Configuration"
-
config ISA
bool
diff --git a/arch/um/Kconfig.um b/arch/um/Kconfig.um
index ec2b8da1aba4..50d6aa20c353 100644
--- a/arch/um/Kconfig.um
+++ b/arch/um/Kconfig.um
@@ -120,6 +120,9 @@ config SMP
If you don't know what to do, say N.
+config GENERIC_HARDIRQS_NO__DO_IRQ
+ def_bool y
+
config NR_CPUS
int "Maximum number of CPUs (2-32)"
range 2 32
@@ -147,3 +150,6 @@ config KERNEL_STACK_ORDER
This option determines the size of UML kernel stacks. They will
be 1 << order pages. The default is OK unless you're running Valgrind
on UML, in which case, set this to 3.
+
+config NO_DMA
+ def_bool y
diff --git a/arch/um/defconfig b/arch/um/defconfig
index 6bd456f96f90..564f3de65b4a 100644
--- a/arch/um/defconfig
+++ b/arch/um/defconfig
@@ -566,7 +566,6 @@ CONFIG_CRC32=m
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_PLIST=y
-CONFIG_HAS_DMA=y
#
# SCSI device support
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 63c740a85b4c..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"
@@ -63,6 +63,8 @@ static int set_mixer(char *name, int *add)
__uml_setup("mixer=", set_mixer, "mixer=<mixer device>\n" MIXER_HELP);
#endif
+static DEFINE_MUTEX(hostaudio_mutex);
+
/* /dev/dsp file operations */
static ssize_t hostaudio_read(struct file *file, char __user *buffer,
@@ -198,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) {
@@ -259,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/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 9734994cba1e..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);
@@ -1101,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){
@@ -1120,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;
}
@@ -1128,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;
}
diff --git a/arch/um/include/asm/dma-mapping.h b/arch/um/include/asm/dma-mapping.h
deleted file mode 100644
index 1f469e80fdd3..000000000000
--- a/arch/um/include/asm/dma-mapping.h
+++ /dev/null
@@ -1,112 +0,0 @@
-#ifndef _ASM_DMA_MAPPING_H
-#define _ASM_DMA_MAPPING_H
-
-#include <asm/scatterlist.h>
-
-static inline int
-dma_supported(struct device *dev, u64 mask)
-{
- BUG();
- return(0);
-}
-
-static inline int
-dma_set_mask(struct device *dev, u64 dma_mask)
-{
- BUG();
- return(0);
-}
-
-static inline void *
-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
- gfp_t flag)
-{
- BUG();
- return((void *) 0);
-}
-
-static inline void
-dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
- dma_addr_t dma_handle)
-{
- BUG();
-}
-
-static inline dma_addr_t
-dma_map_single(struct device *dev, void *cpu_addr, size_t size,
- enum dma_data_direction direction)
-{
- BUG();
- return(0);
-}
-
-static inline void
-dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
- enum dma_data_direction direction)
-{
- BUG();
-}
-
-static inline dma_addr_t
-dma_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size,
- enum dma_data_direction direction)
-{
- BUG();
- return(0);
-}
-
-static inline void
-dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
- enum dma_data_direction direction)
-{
- BUG();
-}
-
-static inline int
-dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
- enum dma_data_direction direction)
-{
- BUG();
- return(0);
-}
-
-static inline void
-dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
- enum dma_data_direction direction)
-{
- BUG();
-}
-
-static inline void
-dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
- enum dma_data_direction direction)
-{
- BUG();
-}
-
-static inline void
-dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
- enum dma_data_direction direction)
-{
- BUG();
-}
-
-#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
-#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
-
-static inline void
-dma_cache_sync(struct device *dev, void *vaddr, size_t size,
- enum dma_data_direction direction)
-{
- BUG();
-}
-
-static inline int
-dma_mapping_error(struct device *dev, dma_addr_t dma_handle)
-{
- BUG();
- return 0;
-}
-
-#endif
diff --git a/arch/um/include/asm/pgtable.h b/arch/um/include/asm/pgtable.h
index a9f7251b4a8d..41474fb5eee7 100644
--- a/arch/um/include/asm/pgtable.h
+++ b/arch/um/include/asm/pgtable.h
@@ -338,9 +338,7 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(address))
#define pte_offset_map(dir, address) \
((pte_t *)page_address(pmd_page(*(dir))) + pte_index(address))
-#define pte_offset_map_nested(dir, address) pte_offset_map(dir, address)
#define pte_unmap(pte) do { } while (0)
-#define pte_unmap_nested(pte) do { } while (0)
struct mm_struct;
extern pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr);
diff --git a/arch/um/include/asm/system.h b/arch/um/include/asm/system.h
index 93af1cf0907d..68a90ecd1450 100644
--- a/arch/um/include/asm/system.h
+++ b/arch/um/include/asm/system.h
@@ -8,23 +8,38 @@ extern int set_signals(int enable);
extern void block_signals(void);
extern void unblock_signals(void);
-#define local_save_flags(flags) do { typecheck(unsigned long, flags); \
- (flags) = get_signals(); } while(0)
-#define local_irq_restore(flags) do { typecheck(unsigned long, flags); \
- set_signals(flags); } while(0)
-
-#define local_irq_save(flags) do { local_save_flags(flags); \
- local_irq_disable(); } while(0)
-
-#define local_irq_enable() unblock_signals()
-#define local_irq_disable() block_signals()
-
-#define irqs_disabled() \
-({ \
- unsigned long flags; \
- local_save_flags(flags); \
- (flags == 0); \
-})
+static inline unsigned long arch_local_save_flags(void)
+{
+ return get_signals();
+}
+
+static inline void arch_local_irq_restore(unsigned long flags)
+{
+ set_signals(flags);
+}
+
+static inline void arch_local_irq_enable(void)
+{
+ unblock_signals();
+}
+
+static inline void arch_local_irq_disable(void)
+{
+ block_signals();
+}
+
+static inline unsigned long arch_local_irq_save(void)
+{
+ unsigned long flags;
+ flags = arch_local_save_flags();
+ arch_local_irq_disable();
+ return flags;
+}
+
+static inline bool arch_irqs_disabled(void)
+{
+ return arch_local_save_flags() == 0;
+}
extern void *_switch_to(void *prev, void *next, void *last);
#define switch_to(prev, next, last) prev = _switch_to(prev, next, last)
diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S
index 69268014dd8e..a3cab6d3ae02 100644
--- a/arch/um/kernel/dyn.lds.S
+++ b/arch/um/kernel/dyn.lds.S
@@ -50,8 +50,18 @@ SECTIONS
.rela.got : { *(.rela.got) }
.rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
- .rel.plt : { *(.rel.plt) }
- .rela.plt : { *(.rela.plt) }
+ .rel.plt : {
+ *(.rel.plt)
+ PROVIDE_HIDDEN(__rel_iplt_start = .);
+ *(.rel.iplt)
+ PROVIDE_HIDDEN(__rel_iplt_end = .);
+ }
+ .rela.plt : {
+ *(.rela.plt)
+ PROVIDE_HIDDEN(__rela_iplt_start = .);
+ *(.rela.iplt)
+ PROVIDE_HIDDEN(__rela_iplt_end = .);
+ }
.init : {
KEEP (*(.init))
} =0x90909090
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..3f0ac9e0c966 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)
@@ -334,7 +334,7 @@ unsigned int do_IRQ(int irq, struct uml_pt_regs *regs)
{
struct pt_regs *old_regs = set_irq_regs((struct pt_regs *)regs);
irq_enter();
- __do_IRQ(irq);
+ generic_handle_irq(irq);
irq_exit();
set_irq_regs(old_regs);
return 1;
@@ -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,
@@ -391,17 +391,10 @@ void __init init_IRQ(void)
{
int i;
- irq_desc[TIMER_IRQ].status = IRQ_DISABLED;
- irq_desc[TIMER_IRQ].action = NULL;
- irq_desc[TIMER_IRQ].depth = 1;
- irq_desc[TIMER_IRQ].chip = &SIGVTALRM_irq_type;
- enable_irq(TIMER_IRQ);
+ set_irq_chip_and_handler(TIMER_IRQ, &SIGVTALRM_irq_type, handle_edge_irq);
+
for (i = 1; i < NR_IRQS; i++) {
- irq_desc[i].status = IRQ_DISABLED;
- irq_desc[i].action = NULL;
- irq_desc[i].depth = 1;
- irq_desc[i].chip = &normal_irq_type;
- enable_irq(i);
+ set_irq_chip_and_handler(i, &normal_irq_type, handle_edge_irq);
}
}
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index e0510496596c..a5e33f29bbeb 100644
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -42,10 +42,12 @@ void ptrace_disable(struct task_struct *child)
extern int peek_user(struct task_struct * child, long addr, long data);
extern int poke_user(struct task_struct * child, long addr, long data);
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int i, ret;
- unsigned long __user *p = (void __user *)(unsigned long)data;
+ unsigned long __user *p = (void __user *)data;
+ void __user *vp = p;
switch (request) {
/* read word at location addr. */
@@ -107,24 +109,20 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
#endif
#ifdef PTRACE_GETFPREGS
case PTRACE_GETFPREGS: /* Get the child FPU state. */
- ret = get_fpregs((struct user_i387_struct __user *) data,
- child);
+ ret = get_fpregs(vp, child);
break;
#endif
#ifdef PTRACE_SETFPREGS
case PTRACE_SETFPREGS: /* Set the child FPU state. */
- ret = set_fpregs((struct user_i387_struct __user *) data,
- child);
+ ret = set_fpregs(vp, child);
break;
#endif
case PTRACE_GET_THREAD_AREA:
- ret = ptrace_get_thread_area(child, addr,
- (struct user_desc __user *) data);
+ ret = ptrace_get_thread_area(child, addr, vp);
break;
case PTRACE_SET_THREAD_AREA:
- ret = ptrace_set_thread_area(child, addr,
- (struct user_desc __user *) data);
+ ret = ptrace_set_thread_area(child, addr, datavp);
break;
case PTRACE_FAULTINFO: {
@@ -134,7 +132,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
* On i386, ptrace_faultinfo is smaller!
*/
ret = copy_to_user(p, &child->thread.arch.faultinfo,
- sizeof(struct ptrace_faultinfo));
+ sizeof(struct ptrace_faultinfo)) ?
+ -EIO : 0;
break;
}
@@ -158,7 +157,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
#ifdef PTRACE_ARCH_PRCTL
case PTRACE_ARCH_PRCTL:
/* XXX Calls ptrace on the host - needs some SMP thinking */
- ret = arch_prctl(child, data, (void *) addr);
+ ret = arch_prctl(child, data, (void __user *) addr);
break;
#endif
default:
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
index ec6378550671..fbd99402d4d2 100644
--- a/arch/um/kernel/uml.lds.S
+++ b/arch/um/kernel/uml.lds.S
@@ -22,7 +22,7 @@ SECTIONS
_text = .;
_stext = .;
__init_begin = .;
- INIT_TEXT_SECTION(PAGE_SIZE)
+ INIT_TEXT_SECTION(0)
. = ALIGN(PAGE_SIZE);
.text :
@@ -43,6 +43,23 @@ SECTIONS
__syscall_stub_end = .;
}
+ /*
+ * These are needed even in a static link, even if they wind up being empty.
+ * Newer glibc needs these __rel{,a}_iplt_{start,end} symbols.
+ */
+ .rel.plt : {
+ *(.rel.plt)
+ PROVIDE_HIDDEN(__rel_iplt_start = .);
+ *(.rel.iplt)
+ PROVIDE_HIDDEN(__rel_iplt_end = .);
+ }
+ .rela.plt : {
+ *(.rela.plt)
+ PROVIDE_HIDDEN(__rela_iplt_start = .);
+ *(.rela.iplt)
+ PROVIDE_HIDDEN(__rela_iplt_end = .);
+ }
+
#include "asm/common.lds.S"
init.data : { INIT_DATA }
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c
index dec5678fc17f..6e3359d6a839 100644
--- a/arch/um/os-Linux/time.c
+++ b/arch/um/os-Linux/time.c
@@ -60,7 +60,7 @@ static inline long long timeval_to_ns(const struct timeval *tv)
long long disable_timer(void)
{
struct itimerval time = ((struct itimerval) { { 0, 0 }, { 0, 0 } });
- int remain, max = UM_NSEC_PER_SEC / UM_HZ;
+ long long remain, max = UM_NSEC_PER_SEC / UM_HZ;
if (setitimer(ITIMER_VIRTUAL, &time, &time) < 0)
printk(UM_KERN_ERR "disable_timer - setitimer failed, "
diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c
index c9b176534d65..d23b2d3ea384 100644
--- a/arch/um/sys-i386/ptrace.c
+++ b/arch/um/sys-i386/ptrace.c
@@ -203,8 +203,8 @@ int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
(unsigned long *) &fpregs);
}
-long subarch_ptrace(struct task_struct *child, long request, long addr,
- long data)
+long subarch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
return -EIO;
}
diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c
index f3458d7d1c5a..f43613643cdb 100644
--- a/arch/um/sys-x86_64/ptrace.c
+++ b/arch/um/sys-x86_64/ptrace.c
@@ -175,19 +175,18 @@ int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
return restore_fp_registers(userspace_pid[cpu], fpregs);
}
-long subarch_ptrace(struct task_struct *child, long request, long addr,
- long data)
+long subarch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int ret = -EIO;
+ void __user *datap = (void __user *) data;
switch (request) {
case PTRACE_GETFPXREGS: /* Get the child FPU state. */
- ret = get_fpregs((struct user_i387_struct __user *) data,
- child);
+ ret = get_fpregs(datap, child);
break;
case PTRACE_SETFPXREGS: /* Set the child FPU state. */
- ret = set_fpregs((struct user_i387_struct __user *) data,
- child);
+ ret = set_fpregs(datap, child);
break;
}
diff --git a/arch/x86/Kbuild b/arch/x86/Kbuild
index ad8ec356fb36..0e103236b754 100644
--- a/arch/x86/Kbuild
+++ b/arch/x86/Kbuild
@@ -14,3 +14,4 @@ obj-y += crypto/
obj-y += vdso/
obj-$(CONFIG_IA32_EMULATION) += ia32/
+obj-y += platform/
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index cea0cd9a316f..e8327686d3c5 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1,6 +1,3 @@
-# x86 configuration
-mainmenu "Linux Kernel Configuration for x86"
-
# Select 32 or 64 bit
config 64BIT
bool "64-bit kernel" if ARCH = "x86"
@@ -25,14 +22,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 +59,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 +199,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 +285,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
@@ -372,6 +344,7 @@ endif
config X86_VSMP
bool "ScaleMP vSMP"
+ select PARAVIRT_GUEST
select PARAVIRT
depends on X86_64 && PCI
depends on X86_EXTENDED_PLATFORM
@@ -517,25 +490,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 +544,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 +615,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 +740,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 +1104,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 +1285,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 +1868,7 @@ config PCI_GODIRECT
bool "Direct"
config PCI_GOOLPC
- bool "OLPC"
+ bool "OLPC XO-1"
depends on OLPC
config PCI_GOANY
@@ -1925,6 +1893,11 @@ config PCI_OLPC
def_bool y
depends on PCI && OLPC && (PCI_GOOLPC || PCI_GOANY)
+config PCI_XEN
+ def_bool y
+ depends on PCI && XEN
+ select SWIOTLB_XEN
+
config PCI_DOMAINS
def_bool y
depends on PCI
@@ -2061,14 +2034,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 +2056,7 @@ config OLPC_OPENFIRMWARE
endif # X86_32
-config K8_NB
+config AMD_NB
def_bool y
depends on CPU_SUP_AMD && PCI
@@ -2125,6 +2105,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/Makefile_32.cpu b/arch/x86/Makefile_32.cpu
index 1255d953c65d..f2ee1abb1df9 100644
--- a/arch/x86/Makefile_32.cpu
+++ b/arch/x86/Makefile_32.cpu
@@ -51,7 +51,18 @@ cflags-$(CONFIG_X86_GENERIC) += $(call tune,generic,$(call tune,i686))
# prologue (push %ebp, mov %esp, %ebp) which breaks the function graph
# tracer assumptions. For i686, generic, core2 this is set by the
# compiler anyway
-cflags-$(CONFIG_FUNCTION_GRAPH_TRACER) += $(call cc-option,-maccumulate-outgoing-args)
+ifeq ($(CONFIG_FUNCTION_GRAPH_TRACER), y)
+ADD_ACCUMULATE_OUTGOING_ARGS := y
+endif
+
+# Work around to a bug with asm goto with first implementations of it
+# in gcc causing gcc to mess up the push and pop of the stack in some
+# uses of asm goto.
+ifeq ($(CONFIG_JUMP_LABEL), y)
+ADD_ACCUMULATE_OUTGOING_ARGS := y
+endif
+
+cflags-$(ADD_ACCUMULATE_OUTGOING_ARGS) += $(call cc-option,-maccumulate-outgoing-args)
# Bug fix for binutils: this option is required in order to keep
# binutils from generating NOPL instructions against our will.
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/include/asm/acpi.h b/arch/x86/include/asm/acpi.h
index 92091de11113..55d106b5e31b 100644
--- a/arch/x86/include/asm/acpi.h
+++ b/arch/x86/include/asm/acpi.h
@@ -93,6 +93,9 @@ extern u8 acpi_sci_flags;
extern int acpi_sci_override_gsi;
void acpi_pic_sci_set_trigger(unsigned int, u16);
+extern int (*__acpi_register_gsi)(struct device *dev, u32 gsi,
+ int trigger, int polarity);
+
static inline void disable_acpi(void)
{
acpi_disabled = 1;
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/highmem.h b/arch/x86/include/asm/highmem.h
index 8caac76ac324..3bd04022fd0c 100644
--- a/arch/x86/include/asm/highmem.h
+++ b/arch/x86/include/asm/highmem.h
@@ -59,11 +59,12 @@ extern void kunmap_high(struct page *page);
void *kmap(struct page *page);
void kunmap(struct page *page);
-void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot);
-void *kmap_atomic(struct page *page, enum km_type type);
-void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type);
-void *kmap_atomic_pfn(unsigned long pfn, enum km_type type);
-void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot);
+
+void *kmap_atomic_prot(struct page *page, pgprot_t prot);
+void *__kmap_atomic(struct page *page);
+void __kunmap_atomic(void *kvaddr);
+void *kmap_atomic_pfn(unsigned long pfn);
+void *kmap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot);
struct page *kmap_atomic_to_page(void *ptr);
#define flush_cache_kmaps() do { } while (0)
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..072273082528 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -41,6 +41,8 @@
#include <asm-generic/int-ll64.h>
#include <asm/page.h>
+#include <xen/xen.h>
+
#define build_mmio_read(name, size, type, reg, barrier) \
static inline type name(const volatile void __iomem *addr) \
{ type ret; asm volatile("mov" size " %1,%0":reg (ret) \
@@ -206,6 +208,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 +351,18 @@ 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);
+
+#ifdef CONFIG_XEN
+struct bio_vec;
+
+extern bool xen_biovec_phys_mergeable(const struct bio_vec *vec1,
+ const struct bio_vec *vec2);
+
+#define BIOVEC_PHYS_MERGEABLE(vec1, vec2) \
+ (__BIOVEC_PHYS_MERGEABLE(vec1, vec2) && \
+ (!xen_domain() || xen_biovec_phys_mergeable(vec1, vec2)))
+#endif /* CONFIG_XEN */
#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..a6b28d017c2f 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -169,13 +169,8 @@ extern void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
extern int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
extern void probe_nr_irqs_gsi(void);
+extern int get_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/iomap.h b/arch/x86/include/asm/iomap.h
index c4191b3b7056..363e33eb6ec1 100644
--- a/arch/x86/include/asm/iomap.h
+++ b/arch/x86/include/asm/iomap.h
@@ -27,10 +27,10 @@
#include <asm/tlbflush.h>
void __iomem *
-iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot);
+iomap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot);
void
-iounmap_atomic(void __iomem *kvaddr, enum km_type type);
+iounmap_atomic(void __iomem *kvaddr);
int
iomap_create_wc(resource_size_t base, unsigned long size, pgprot_t *prot);
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..13b0ebaa512f 100644
--- a/arch/x86/include/asm/irq.h
+++ b/arch/x86/include/asm/irq.h
@@ -19,18 +19,14 @@ 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);
#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 c52e2eb40a1e..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);
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..3ea3dc487047 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -121,6 +121,7 @@
#define MSR_AMD64_IBSDCLINAD 0xc0011038
#define MSR_AMD64_IBSDCPHYSAD 0xc0011039
#define MSR_AMD64_IBSCTL 0xc001103a
+#define MSR_AMD64_IBSBRTARGET 0xc001103b
/* Fam 10h MSRs */
#define MSR_FAM10H_MMIO_CONF_BASE 0xc0010058
@@ -198,6 +199,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.h b/arch/x86/include/asm/olpc.h
index 101229b0d8ed..42a978c0c1b3 100644
--- a/arch/x86/include/asm/olpc.h
+++ b/arch/x86/include/asm/olpc.h
@@ -89,6 +89,8 @@ extern int olpc_ec_mask_unset(uint8_t bits);
/* EC commands */
#define EC_FIRMWARE_REV 0x08
+#define EC_WLAN_ENTER_RESET 0x35
+#define EC_WLAN_LEAVE_RESET 0x25
/* SCI source values */
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/pci.h b/arch/x86/include/asm/pci.h
index d395540ff894..ca0437c714b2 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -7,6 +7,7 @@
#include <linux/string.h>
#include <asm/scatterlist.h>
#include <asm/io.h>
+#include <asm/x86_init.h>
#ifdef __KERNEL__
@@ -94,8 +95,36 @@ static inline void early_quirks(void) { }
extern void pci_iommu_alloc(void);
-/* MSI arch hook */
-#define arch_setup_msi_irqs arch_setup_msi_irqs
+#ifdef CONFIG_PCI_MSI
+/* MSI arch specific hooks */
+static inline int x86_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+{
+ return x86_msi.setup_msi_irqs(dev, nvec, type);
+}
+
+static inline void x86_teardown_msi_irqs(struct pci_dev *dev)
+{
+ x86_msi.teardown_msi_irqs(dev);
+}
+
+static inline void x86_teardown_msi_irq(unsigned int irq)
+{
+ x86_msi.teardown_msi_irq(irq);
+}
+#define arch_setup_msi_irqs x86_setup_msi_irqs
+#define arch_teardown_msi_irqs x86_teardown_msi_irqs
+#define arch_teardown_msi_irq x86_teardown_msi_irq
+/* implemented in arch/x86/kernel/apic/io_apic. */
+int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type);
+void native_teardown_msi_irq(unsigned int irq);
+/* default to the implementation in drivers/lib/msi.c */
+#define HAVE_DEFAULT_MSI_TEARDOWN_IRQS
+void default_teardown_msi_irqs(struct pci_dev *dev);
+#else
+#define native_setup_msi_irqs NULL
+#define native_teardown_msi_irq NULL
+#define default_teardown_msi_irqs NULL
+#endif
#define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys)
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index 49c7219826f9..704526734bef 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -47,6 +47,7 @@ enum pci_bf_sort_state {
extern unsigned int pcibios_max_latency;
void pcibios_resource_survey(void);
+void pcibios_set_cache_line_size(void);
/* pci-pc.c */
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.h b/arch/x86/include/asm/perf_event.h
index 6e742cc4251b..550e26b1dbb3 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -111,17 +111,18 @@ union cpuid10_edx {
#define X86_PMC_IDX_FIXED_BTS (X86_PMC_IDX_FIXED + 16)
/* IbsFetchCtl bits/masks */
-#define IBS_FETCH_RAND_EN (1ULL<<57)
-#define IBS_FETCH_VAL (1ULL<<49)
-#define IBS_FETCH_ENABLE (1ULL<<48)
-#define IBS_FETCH_CNT 0xFFFF0000ULL
-#define IBS_FETCH_MAX_CNT 0x0000FFFFULL
+#define IBS_FETCH_RAND_EN (1ULL<<57)
+#define IBS_FETCH_VAL (1ULL<<49)
+#define IBS_FETCH_ENABLE (1ULL<<48)
+#define IBS_FETCH_CNT 0xFFFF0000ULL
+#define IBS_FETCH_MAX_CNT 0x0000FFFFULL
/* IbsOpCtl bits */
-#define IBS_OP_CNT_CTL (1ULL<<19)
-#define IBS_OP_VAL (1ULL<<18)
-#define IBS_OP_ENABLE (1ULL<<17)
-#define IBS_OP_MAX_CNT 0x0000FFFFULL
+#define IBS_OP_CNT_CTL (1ULL<<19)
+#define IBS_OP_VAL (1ULL<<18)
+#define IBS_OP_ENABLE (1ULL<<17)
+#define IBS_OP_MAX_CNT 0x0000FFFFULL
+#define IBS_OP_MAX_CNT_EXT 0x007FFFFFULL /* not a register bit mask */
#ifdef CONFIG_PERF_EVENTS
extern void init_hw_perf_events(void);
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..0c92113c4cb6 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) { }
@@ -49,24 +49,14 @@ extern void set_pmd_pfn(unsigned long, unsigned long, pgprot_t);
#endif
#if defined(CONFIG_HIGHPTE)
-#define __KM_PTE \
- (in_nmi() ? KM_NMI_PTE : \
- in_irq() ? KM_IRQ_PTE : \
- KM_PTE0)
#define pte_offset_map(dir, address) \
- ((pte_t *)kmap_atomic(pmd_page(*(dir)), __KM_PTE) + \
+ ((pte_t *)kmap_atomic(pmd_page(*(dir))) + \
pte_index((address)))
-#define pte_offset_map_nested(dir, address) \
- ((pte_t *)kmap_atomic(pmd_page(*(dir)), KM_PTE1) + \
- pte_index((address)))
-#define pte_unmap(pte) kunmap_atomic((pte), __KM_PTE)
-#define pte_unmap_nested(pte) kunmap_atomic((pte), KM_PTE1)
+#define pte_unmap(pte) kunmap_atomic((pte))
#else
#define pte_offset_map(dir, address) \
((pte_t *)page_address(pmd_page(*(dir))) + pte_index((address)))
-#define pte_offset_map_nested(dir, address) pte_offset_map((dir), (address))
#define pte_unmap(pte) do { } while (0)
-#define pte_unmap_nested(pte) do { } while (0)
#endif
/* Clear a kernel PTE and flush it from the TLB */
diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h
index 076052cd62be..f86da20347f2 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.
@@ -125,9 +127,7 @@ static inline int pgd_large(pgd_t pgd) { return 0; }
/* x86-64 always has all page tables mapped. */
#define pte_offset_map(dir, address) pte_offset_kernel((dir), (address))
-#define pte_offset_map_nested(dir, address) pte_offset_kernel((dir), (address))
#define pte_unmap(pte) ((void)(pte))/* NOP */
-#define pte_unmap_nested(pte) ((void)(pte)) /* NOP */
#define update_mmu_cache(vma, address, ptep) do { } while (0)
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/smp.h b/arch/x86/include/asm/smp.h
index 4cfc90824068..4c2f63c7fc1b 100644
--- a/arch/x86/include/asm/smp.h
+++ b/arch/x86/include/asm/smp.h
@@ -50,7 +50,7 @@ struct smp_ops {
void (*smp_prepare_cpus)(unsigned max_cpus);
void (*smp_cpus_done)(unsigned max_cpus);
- void (*smp_send_stop)(void);
+ void (*stop_other_cpus)(int wait);
void (*smp_send_reschedule)(int cpu);
int (*cpu_up)(unsigned cpu);
@@ -73,7 +73,12 @@ extern struct smp_ops smp_ops;
static inline void smp_send_stop(void)
{
- smp_ops.smp_send_stop();
+ smp_ops.stop_other_cpus(0);
+}
+
+static inline void stop_other_cpus(void)
+{
+ smp_ops.stop_other_cpus(1);
}
static inline void smp_prepare_boot_cpu(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/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h
index bf6b88ef8eeb..e969f691cbfd 100644
--- a/arch/x86/include/asm/uv/uv_hub.h
+++ b/arch/x86/include/asm/uv/uv_hub.h
@@ -5,7 +5,7 @@
*
* SGI UV architectural definitions
*
- * Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2007-2010 Silicon Graphics, Inc. All rights reserved.
*/
#ifndef _ASM_X86_UV_UV_HUB_H
@@ -77,7 +77,8 @@
*
* 1111110000000000
* 5432109876543210
- * pppppppppplc0cch
+ * pppppppppplc0cch Nehalem-EX
+ * ppppppppplcc0cch Westmere-EX
* sssssssssss
*
* p = pnode bits
@@ -148,12 +149,25 @@ struct uv_hub_info_s {
unsigned char m_val;
unsigned char n_val;
struct uv_scir_s scir;
+ unsigned char apic_pnode_shift;
};
DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
#define uv_hub_info (&__get_cpu_var(__uv_hub_info))
#define uv_cpu_hub_info(cpu) (&per_cpu(__uv_hub_info, cpu))
+union uvh_apicid {
+ unsigned long v;
+ struct uvh_apicid_s {
+ unsigned long local_apic_mask : 24;
+ unsigned long local_apic_shift : 5;
+ unsigned long unused1 : 3;
+ unsigned long pnode_mask : 24;
+ unsigned long pnode_shift : 5;
+ unsigned long unused2 : 3;
+ } s;
+};
+
/*
* Local & Global MMR space macros.
* Note: macros are intended to be used ONLY by inline functions
@@ -182,6 +196,7 @@ DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
#define UV_GLOBAL_MMR64_PNODE_BITS(p) \
(((unsigned long)(p)) << UV_GLOBAL_MMR64_PNODE_SHIFT)
+#define UVH_APICID 0x002D0E00L
#define UV_APIC_PNODE_SHIFT 6
/* Local Bus from cpu's perspective */
@@ -280,7 +295,7 @@ static inline void *uv_pnode_offset_to_vaddr(int pnode, unsigned long offset)
*/
static inline int uv_apicid_to_pnode(int apicid)
{
- return (apicid >> UV_APIC_PNODE_SHIFT);
+ return (apicid >> uv_hub_info->apic_pnode_shift);
}
/*
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/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index baa579c8e038..64642ad019fb 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -154,9 +154,18 @@ struct x86_platform_ops {
int (*i8042_detect)(void);
};
+struct pci_dev;
+
+struct x86_msi_ops {
+ int (*setup_msi_irqs)(struct pci_dev *dev, int nvec, int type);
+ void (*teardown_msi_irq)(unsigned int irq);
+ void (*teardown_msi_irqs)(struct pci_dev *dev);
+};
+
extern struct x86_init_ops x86_init;
extern struct x86_cpuinit_ops x86_cpuinit;
extern struct x86_platform_ops x86_platform;
+extern struct x86_msi_ops x86_msi;
extern void x86_init_noop(void);
extern void x86_init_uint_noop(unsigned int unused);
diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h
index 7fda040a76cd..a3c28ae4025b 100644
--- a/arch/x86/include/asm/xen/hypercall.h
+++ b/arch/x86/include/asm/xen/hypercall.h
@@ -200,6 +200,23 @@ extern struct { char _entry[32]; } hypercall_page[];
(type)__res; \
})
+static inline long
+privcmd_call(unsigned call,
+ unsigned long a1, unsigned long a2,
+ unsigned long a3, unsigned long a4,
+ unsigned long a5)
+{
+ __HYPERCALL_DECLS;
+ __HYPERCALL_5ARG(a1, a2, a3, a4, a5);
+
+ asm volatile("call *%[call]"
+ : __HYPERCALL_5PARAM
+ : [call] "a" (&hypercall_page[call])
+ : __HYPERCALL_CLOBBER5);
+
+ return (long)__res;
+}
+
static inline int
HYPERVISOR_set_trap_table(struct trap_info *table)
{
diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h
index bf5f7d32bd08..dd8c1414b3d5 100644
--- a/arch/x86/include/asm/xen/page.h
+++ b/arch/x86/include/asm/xen/page.h
@@ -37,14 +37,21 @@ typedef struct xpaddr {
extern unsigned long get_phys_to_machine(unsigned long pfn);
-extern void set_phys_to_machine(unsigned long pfn, unsigned long mfn);
+extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn);
static inline unsigned long pfn_to_mfn(unsigned long pfn)
{
+ unsigned long mfn;
+
if (xen_feature(XENFEAT_auto_translated_physmap))
return pfn;
- return get_phys_to_machine(pfn) & ~FOREIGN_FRAME_BIT;
+ mfn = get_phys_to_machine(pfn);
+
+ if (mfn != INVALID_P2M_ENTRY)
+ mfn &= ~FOREIGN_FRAME_BIT;
+
+ return mfn;
}
static inline int phys_to_machine_mapping_valid(unsigned long pfn)
@@ -159,6 +166,7 @@ static inline pte_t __pte_ma(pteval_t x)
#define pgd_val_ma(x) ((x).pgd)
+void xen_set_domain_pte(pte_t *ptep, pte_t pteval, unsigned domid);
xmaddr_t arbitrary_virt_to_machine(void *address);
unsigned long arbitrary_virt_to_mfn(void *vaddr);
diff --git a/arch/x86/include/asm/xen/pci.h b/arch/x86/include/asm/xen/pci.h
new file mode 100644
index 000000000000..2329b3eaf8d3
--- /dev/null
+++ b/arch/x86/include/asm/xen/pci.h
@@ -0,0 +1,65 @@
+#ifndef _ASM_X86_XEN_PCI_H
+#define _ASM_X86_XEN_PCI_H
+
+#if defined(CONFIG_PCI_XEN)
+extern int __init pci_xen_init(void);
+extern int __init pci_xen_hvm_init(void);
+#define pci_xen 1
+#else
+#define pci_xen 0
+#define pci_xen_init (0)
+static inline int pci_xen_hvm_init(void)
+{
+ return -1;
+}
+#endif
+#if defined(CONFIG_XEN_DOM0)
+void __init xen_setup_pirqs(void);
+#else
+static inline void __init xen_setup_pirqs(void)
+{
+}
+#endif
+
+#if defined(CONFIG_PCI_MSI)
+#if defined(CONFIG_PCI_XEN)
+/* The drivers/pci/xen-pcifront.c sets this structure to
+ * its own functions.
+ */
+struct xen_pci_frontend_ops {
+ int (*enable_msi)(struct pci_dev *dev, int **vectors);
+ void (*disable_msi)(struct pci_dev *dev);
+ int (*enable_msix)(struct pci_dev *dev, int **vectors, int nvec);
+ void (*disable_msix)(struct pci_dev *dev);
+};
+
+extern struct xen_pci_frontend_ops *xen_pci_frontend;
+
+static inline int xen_pci_frontend_enable_msi(struct pci_dev *dev,
+ int **vectors)
+{
+ if (xen_pci_frontend && xen_pci_frontend->enable_msi)
+ return xen_pci_frontend->enable_msi(dev, vectors);
+ return -ENODEV;
+}
+static inline void xen_pci_frontend_disable_msi(struct pci_dev *dev)
+{
+ if (xen_pci_frontend && xen_pci_frontend->disable_msi)
+ xen_pci_frontend->disable_msi(dev);
+}
+static inline int xen_pci_frontend_enable_msix(struct pci_dev *dev,
+ int **vectors, int nvec)
+{
+ if (xen_pci_frontend && xen_pci_frontend->enable_msix)
+ return xen_pci_frontend->enable_msix(dev, vectors, nvec);
+ return -ENODEV;
+}
+static inline void xen_pci_frontend_disable_msix(struct pci_dev *dev)
+{
+ if (xen_pci_frontend && xen_pci_frontend->disable_msix)
+ xen_pci_frontend->disable_msix(dev);
+}
+#endif /* CONFIG_PCI_XEN */
+#endif /* CONFIG_PCI_MSI */
+
+#endif /* _ASM_X86_XEN_PCI_H */
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index fedf32a8c3ec..9e13763b6092 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -34,8 +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-$(CONFIG_X86_VISWS) += visws_quirks.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_32) += probe_roms_32.o
obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o
obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o
@@ -44,6 +44,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
@@ -56,7 +57,6 @@ obj-$(CONFIG_INTEL_TXT) += tboot.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-y += cpu/
obj-y += acpi/
-obj-$(CONFIG_SFI) += sfi.o
obj-y += reboot.o
obj-$(CONFIG_MCA) += mca_32.o
obj-$(CONFIG_X86_MSR) += msr.o
@@ -80,20 +80,19 @@ obj-$(CONFIG_KEXEC) += relocate_kernel_$(BITS).o crash.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o
obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_MODULES) += module.o
-obj-$(CONFIG_EFI) += efi.o efi_$(BITS).o efi_stub_$(BITS).o
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
@@ -102,13 +101,6 @@ obj-$(CONFIG_PARAVIRT_CLOCK) += pvclock.o
obj-$(CONFIG_PCSPKR_PLATFORM) += pcspeaker.o
-obj-$(CONFIG_SCx200) += scx200.o
-scx200-y += scx200_32.o
-
-obj-$(CONFIG_OLPC) += olpc.o
-obj-$(CONFIG_OLPC_OPENFIRMWARE) += olpc_ofw.o
-obj-$(CONFIG_X86_MRST) += mrst.o
-
microcode-y := microcode_core.o
microcode-$(CONFIG_MICROCODE_INTEL) += microcode_intel.o
microcode-$(CONFIG_MICROCODE_AMD) += microcode_amd.o
@@ -121,8 +113,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/boot.c b/arch/x86/kernel/acpi/boot.c
index c05872aa3ce0..71232b941b6c 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -513,35 +513,62 @@ int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
return 0;
}
-/*
- * success: return IRQ number (>=0)
- * failure: return < 0
- */
-int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
+static int acpi_register_gsi_pic(struct device *dev, u32 gsi,
+ int trigger, int polarity)
{
- unsigned int irq;
- unsigned int plat_gsi = gsi;
-
#ifdef CONFIG_PCI
/*
* Make sure all (legacy) PCI IRQs are set as level-triggered.
*/
- if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) {
- if (trigger == ACPI_LEVEL_SENSITIVE)
- eisa_set_level_irq(gsi);
- }
+ if (trigger == ACPI_LEVEL_SENSITIVE)
+ eisa_set_level_irq(gsi);
#endif
+ return gsi;
+}
+
+static int acpi_register_gsi_ioapic(struct device *dev, u32 gsi,
+ int trigger, int polarity)
+{
#ifdef CONFIG_X86_IO_APIC
- if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) {
- plat_gsi = mp_register_gsi(dev, gsi, trigger, polarity);
- }
+ gsi = mp_register_gsi(dev, gsi, trigger, polarity);
#endif
+
+ return gsi;
+}
+
+int (*__acpi_register_gsi)(struct device *dev, u32 gsi,
+ int trigger, int polarity) = acpi_register_gsi_pic;
+
+/*
+ * success: return IRQ number (>=0)
+ * failure: return < 0
+ */
+int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
+{
+ unsigned int irq;
+ unsigned int plat_gsi = gsi;
+
+ plat_gsi = (*__acpi_register_gsi)(dev, gsi, trigger, polarity);
irq = gsi_to_irq(plat_gsi);
return irq;
}
+void __init acpi_set_irq_model_pic(void)
+{
+ acpi_irq_model = ACPI_IRQ_MODEL_PIC;
+ __acpi_register_gsi = acpi_register_gsi_pic;
+ acpi_ioapic = 0;
+}
+
+void __init acpi_set_irq_model_ioapic(void)
+{
+ acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC;
+ __acpi_register_gsi = acpi_register_gsi_ioapic;
+ acpi_ioapic = 1;
+}
+
/*
* ACPI based hotplug support for CPU
*/
@@ -1259,8 +1286,7 @@ static void __init acpi_process_madt(void)
*/
error = acpi_parse_madt_ioapic_entries();
if (!error) {
- acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC;
- acpi_ioapic = 1;
+ acpi_set_irq_model_ioapic();
smp_found_config = 1;
}
diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c
index fb16f17e59be..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
@@ -65,16 +66,6 @@ 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..69fd72aa5594 100644
--- a/arch/x86/kernel/acpi/sleep.c
+++ b/arch/x86/kernel/acpi/sleep.c
@@ -7,11 +7,16 @@
#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>
+#endif
+
#include "realmode/wakeup.h"
#include "sleep.h"
@@ -90,7 +95,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 +130,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 +138,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..5079f24c955a 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,33 @@ 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, cpu_online_mask);
return addr;
}
+#if defined(CONFIG_DYNAMIC_FTRACE) || defined(HAVE_JUMP_LABEL)
+
+#ifdef CONFIG_X86_64
+unsigned char ideal_nop5[5] = { 0x66, 0x66, 0x66, 0x66, 0x90 };
+#else
+unsigned char ideal_nop5[5] = { 0x3e, 0x8d, 0x74, 0x26, 0x00 };
+#endif
+
+void __init arch_init_ideal_nop5(void)
+{
+ /*
+ * There is no good nop for all x86 archs. This selection
+ * algorithm should be unified with the one in find_nop_table(),
+ * but this should be good enough for now.
+ *
+ * For cases other than the ones below, use the safe (as in
+ * always functional) defaults above.
+ */
+#ifdef CONFIG_X86_64
+ /* Don't use these on 32 bits due to broken virtualizers */
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
+ memcpy(ideal_nop5, p6_nops[5], 5);
+#endif
+}
+#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 5c5b8f3dddb5..7cc0a721f628 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,170 +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;
-
- cfg->vector = old_cfg->vector;
- cfg->move_in_progress = old_cfg->move_in_progress;
- cpumask_copy(cfg->domain, old_cfg->domain);
- cpumask_copy(cfg->old_domain, old_cfg->old_domain);
-
- 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 *cfg)
-{
- free_cpumask_var(cfg->domain);
- free_cpumask_var(cfg->old_domain);
- kfree(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];
@@ -451,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);
@@ -481,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;
@@ -493,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);
@@ -508,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");
}
@@ -571,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)
{
/*
@@ -587,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)
@@ -694,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;
}
@@ -1259,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
@@ -1268,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.
@@ -1327,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,
@@ -1358,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:
@@ -1382,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);
@@ -1431,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
@@ -1471,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);
}
@@ -1484,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");
@@ -1525,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)
@@ -1552,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;
/*
@@ -1570,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)) {
@@ -1591,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));
}
@@ -1642,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);
@@ -1729,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;
@@ -2239,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);
@@ -2312,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;
@@ -2322,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
/*
@@ -2395,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);
@@ -2427,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;
}
@@ -2511,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))
@@ -2526,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();
}
@@ -2572,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) {
/*
@@ -2584,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);
@@ -2593,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
@@ -2658,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));
@@ -2678,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 */
@@ -2709,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
@@ -2776,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,
@@ -2788,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);
}
}
}
@@ -2797,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;
@@ -2805,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;
@@ -2813,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");
}
@@ -2930,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;
@@ -2942,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());
/*
@@ -3001,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?
@@ -3009,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);
@@ -3037,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;
}
@@ -3052,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");
}
@@ -3069,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");
@@ -3244,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;
@@ -3301,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 (irq_remapped(cfg))
+ 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);
}
/*
@@ -3332,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;
@@ -3340,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)
@@ -3392,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;
}
@@ -3421,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;
@@ -3461,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,
};
/*
@@ -3513,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)
@@ -3523,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");
@@ -3538,15 +3331,12 @@ static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq)
return 0;
}
-int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+int native_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)
@@ -3599,25 +3389,24 @@ error:
return ret;
}
-void arch_teardown_msi_irq(unsigned int irq)
+void native_teardown_msi_irq(unsigned int irq)
{
destroy_irq(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;
@@ -3633,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)
@@ -3661,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;
}
@@ -3688,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);
@@ -3733,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
@@ -3768,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)
@@ -3867,6 +3650,11 @@ void __init probe_nr_irqs_gsi(void)
printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi);
}
+int get_nr_irqs_gsi(void)
+{
+ return nr_irqs_gsi;
+}
+
#ifdef CONFIG_SPARSE_IRQ
int __init arch_probe_nr_irqs(void)
{
@@ -3885,14 +3673,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;
@@ -3908,13 +3695,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;
@@ -3924,15 +3709,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;
}
@@ -4125,14 +3909,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);
}
}
@@ -4316,19 +4100,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/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c
index f744f54cb248..ed4118de249e 100644
--- a/arch/x86/kernel/apic/x2apic_uv_x.c
+++ b/arch/x86/kernel/apic/x2apic_uv_x.c
@@ -5,7 +5,7 @@
*
* SGI UV APIC functions (note: not an Intel compatible APIC)
*
- * Copyright (C) 2007-2009 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2007-2010 Silicon Graphics, Inc. All rights reserved.
*/
#include <linux/cpumask.h>
#include <linux/hardirq.h>
@@ -41,6 +41,7 @@ DEFINE_PER_CPU(int, x2apic_extra_bits);
static enum uv_system_type uv_system_type;
static u64 gru_start_paddr, gru_end_paddr;
+static union uvh_apicid uvh_apicid;
int uv_min_hub_revision_id;
EXPORT_SYMBOL_GPL(uv_min_hub_revision_id);
static DEFINE_SPINLOCK(uv_nmi_lock);
@@ -70,12 +71,27 @@ static int early_get_nodeid(void)
return node_id.s.node_id;
}
+static void __init early_get_apic_pnode_shift(void)
+{
+ unsigned long *mmr;
+
+ mmr = early_ioremap(UV_LOCAL_MMR_BASE | UVH_APICID, sizeof(*mmr));
+ uvh_apicid.v = *mmr;
+ early_iounmap(mmr, sizeof(*mmr));
+ if (!uvh_apicid.v)
+ /*
+ * Old bios, use default value
+ */
+ uvh_apicid.s.pnode_shift = UV_APIC_PNODE_SHIFT;
+}
+
static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
{
int nodeid;
if (!strcmp(oem_id, "SGI")) {
nodeid = early_get_nodeid();
+ early_get_apic_pnode_shift();
x86_platform.is_untracked_pat_range = uv_is_untracked_pat_range;
x86_platform.nmi_init = uv_nmi_init;
if (!strcmp(oem_table_id, "UVL"))
@@ -84,7 +100,7 @@ static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
uv_system_type = UV_X2APIC;
else if (!strcmp(oem_table_id, "UVH")) {
__get_cpu_var(x2apic_extra_bits) =
- nodeid << (UV_APIC_PNODE_SHIFT - 1);
+ nodeid << (uvh_apicid.s.pnode_shift - 1);
uv_system_type = UV_NON_UNIQUE_APIC;
return 1;
}
@@ -716,6 +732,10 @@ void __init uv_system_init(void)
int apicid = per_cpu(x86_cpu_to_apicid, cpu);
nid = cpu_to_node(cpu);
+ /*
+ * apic_pnode_shift must be set before calling uv_apicid_to_pnode();
+ */
+ uv_cpu_hub_info(cpu)->apic_pnode_shift = uvh_apicid.s.pnode_shift;
pnode = uv_apicid_to_pnode(apicid);
blade = boot_pnode_to_blade(pnode);
lcpu = uv_blade_info[blade].nr_possible_cpus;
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 f2f9ac7da25c..4b68bda30938 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -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 f668bb1f7d43..e765633f210e 100644
--- a/arch/x86/kernel/cpu/cpu.h
+++ b/arch/x86/kernel/cpu/cpu.h
@@ -32,6 +32,7 @@ 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);
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
index cd8da247dda1..a2baafb2fe6d 100644
--- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -701,6 +701,7 @@ static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy)
per_cpu(acfreq_data, policy->cpu) = NULL;
acpi_processor_unregister_performance(data->acpi_data,
policy->cpu);
+ kfree(data->freq_table);
kfree(data);
}
diff --git a/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c b/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c
index 733093d60436..141abebc4516 100644
--- a/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c
+++ b/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c
@@ -393,7 +393,7 @@ static struct cpufreq_driver nforce2_driver = {
* Detects nForce2 A2 and C1 stepping
*
*/
-static unsigned int nforce2_detect_chipset(void)
+static int nforce2_detect_chipset(void)
{
nforce2_dev = pci_get_subsys(PCI_VENDOR_ID_NVIDIA,
PCI_DEVICE_ID_NVIDIA_NFORCE2,
diff --git a/arch/x86/kernel/cpu/cpufreq/longrun.c b/arch/x86/kernel/cpu/cpufreq/longrun.c
index fc09f142d94d..d9f51367666b 100644
--- a/arch/x86/kernel/cpu/cpufreq/longrun.c
+++ b/arch/x86/kernel/cpu/cpufreq/longrun.c
@@ -35,7 +35,7 @@ static unsigned int longrun_low_freq, longrun_high_freq;
* Reads the current LongRun policy by access to MSR_TMTA_LONGRUN_FLAGS
* and MSR_TMTA_LONGRUN_CTRL
*/
-static void __init longrun_get_policy(struct cpufreq_policy *policy)
+static void __cpuinit longrun_get_policy(struct cpufreq_policy *policy)
{
u32 msr_lo, msr_hi;
@@ -165,7 +165,7 @@ static unsigned int longrun_get(unsigned int cpu)
* TMTA rules:
* performance_pctg = (target_freq - low_freq)/(high_freq - low_freq)
*/
-static unsigned int __cpuinit longrun_determine_freqs(unsigned int *low_freq,
+static int __cpuinit longrun_determine_freqs(unsigned int *low_freq,
unsigned int *high_freq)
{
u32 msr_lo, msr_hi;
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index b4389441efbb..d16c2c53d6bf 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -170,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;
/*
@@ -284,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..17ad03366211 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
@@ -327,6 +327,7 @@ static void __cpuinit amd_calc_l3_indices(struct amd_l3_cache *l3)
l3->subcaches[3] = sc3 = !(val & BIT(12)) + !(val & BIT(13));
l3->indices = (max(max(max(sc0, sc1), sc2), sc3) << 10) - 1;
+ l3->indices = (max(max3(sc0, sc1, sc2), sc3) << 10) - 1;
}
static struct amd_l3_cache * __cpuinit amd_init_l3_cache(int node)
@@ -369,7 +370,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 +378,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 +557,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 +1001,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 39aaee5c1ab2..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) {
@@ -162,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 169d8804a9f8..4b683267eca5 100644
--- a/arch/x86/kernel/cpu/mcheck/therm_throt.c
+++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c
@@ -350,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..ed6310183efb 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -49,7 +49,6 @@ static unsigned long
copy_from_user_nmi(void *to, const void __user *from, unsigned long n)
{
unsigned long offset, addr = (unsigned long)from;
- int type = in_nmi() ? KM_NMI : KM_IRQ0;
unsigned long size, len = 0;
struct page *page;
void *map;
@@ -63,9 +62,9 @@ copy_from_user_nmi(void *to, const void __user *from, unsigned long n)
offset = addr & (PAGE_SIZE - 1);
size = min(PAGE_SIZE - offset, n - len);
- map = kmap_atomic(page, type);
+ map = kmap_atomic(page);
memcpy(to, map+offset, size);
- kunmap_atomic(map, type);
+ kunmap_atomic(map);
put_page(page);
len += size;
@@ -238,6 +237,7 @@ struct x86_pmu {
* Intel DebugStore bits
*/
int bts, pebs;
+ int bts_active, pebs_active;
int pebs_record_size;
void (*drain_pebs)(struct pt_regs *regs);
struct event_constraint *pebs_constraints;
@@ -381,7 +381,7 @@ static void release_pmc_hardware(void) {}
#endif
-static int reserve_ds_buffers(void);
+static void reserve_ds_buffers(void);
static void release_ds_buffers(void);
static void hw_perf_event_destroy(struct perf_event *event)
@@ -478,7 +478,7 @@ static int x86_setup_perfctr(struct perf_event *event)
if ((attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS) &&
(hwc->sample_period == 1)) {
/* BTS is not supported by this architecture. */
- if (!x86_pmu.bts)
+ if (!x86_pmu.bts_active)
return -EOPNOTSUPP;
/* BTS is currently only allowed for user-mode. */
@@ -497,12 +497,13 @@ static int x86_pmu_hw_config(struct perf_event *event)
int precise = 0;
/* Support for constant skid */
- if (x86_pmu.pebs)
+ if (x86_pmu.pebs_active) {
precise++;
- /* Support for IP fixup */
- if (x86_pmu.lbr_nr)
- precise++;
+ /* Support for IP fixup */
+ if (x86_pmu.lbr_nr)
+ precise++;
+ }
if (event->attr.precise_ip > precise)
return -EOPNOTSUPP;
@@ -531,7 +532,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;
@@ -544,11 +545,8 @@ static int __hw_perf_event_init(struct perf_event *event)
if (atomic_read(&active_events) == 0) {
if (!reserve_pmc_hardware())
err = -EBUSY;
- else {
- err = reserve_ds_buffers();
- if (err)
- release_pmc_hardware();
- }
+ else
+ reserve_ds_buffers();
}
if (!err)
atomic_inc(&active_events);
@@ -584,7 +582,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 +617,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 +799,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 +838,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 +857,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 +961,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 +975,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 +1092,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 +1127,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 +1150,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 +1170,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 +1185,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 +1194,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 +1383,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 +1418,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 +1432,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 +1446,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 +1456,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 +1464,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 +1486,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 +1564,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 +1599,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 +1645,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 +1656,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 +1693,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 +1706,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 +1736,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..b7dcd9f2b8a0 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c
@@ -74,6 +74,107 @@ static void fini_debug_store_on_cpu(int cpu)
wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA, 0, 0);
}
+static int alloc_pebs_buffer(int cpu)
+{
+ struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+ int node = cpu_to_node(cpu);
+ int max, thresh = 1; /* always use a single PEBS record */
+ void *buffer;
+
+ if (!x86_pmu.pebs)
+ return 0;
+
+ buffer = kmalloc_node(PEBS_BUFFER_SIZE, GFP_KERNEL | __GFP_ZERO, node);
+ if (unlikely(!buffer))
+ return -ENOMEM;
+
+ max = PEBS_BUFFER_SIZE / x86_pmu.pebs_record_size;
+
+ ds->pebs_buffer_base = (u64)(unsigned long)buffer;
+ ds->pebs_index = ds->pebs_buffer_base;
+ ds->pebs_absolute_maximum = ds->pebs_buffer_base +
+ max * x86_pmu.pebs_record_size;
+
+ ds->pebs_interrupt_threshold = ds->pebs_buffer_base +
+ thresh * x86_pmu.pebs_record_size;
+
+ return 0;
+}
+
+static void release_pebs_buffer(int cpu)
+{
+ struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+
+ if (!ds || !x86_pmu.pebs)
+ return;
+
+ kfree((void *)(unsigned long)ds->pebs_buffer_base);
+ ds->pebs_buffer_base = 0;
+}
+
+static int alloc_bts_buffer(int cpu)
+{
+ struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+ int node = cpu_to_node(cpu);
+ int max, thresh;
+ void *buffer;
+
+ if (!x86_pmu.bts)
+ return 0;
+
+ buffer = kmalloc_node(BTS_BUFFER_SIZE, GFP_KERNEL | __GFP_ZERO, node);
+ if (unlikely(!buffer))
+ return -ENOMEM;
+
+ max = BTS_BUFFER_SIZE / BTS_RECORD_SIZE;
+ thresh = max / 16;
+
+ ds->bts_buffer_base = (u64)(unsigned long)buffer;
+ ds->bts_index = ds->bts_buffer_base;
+ ds->bts_absolute_maximum = ds->bts_buffer_base +
+ max * BTS_RECORD_SIZE;
+ ds->bts_interrupt_threshold = ds->bts_absolute_maximum -
+ thresh * BTS_RECORD_SIZE;
+
+ return 0;
+}
+
+static void release_bts_buffer(int cpu)
+{
+ struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+
+ if (!ds || !x86_pmu.bts)
+ return;
+
+ kfree((void *)(unsigned long)ds->bts_buffer_base);
+ ds->bts_buffer_base = 0;
+}
+
+static int alloc_ds_buffer(int cpu)
+{
+ int node = cpu_to_node(cpu);
+ struct debug_store *ds;
+
+ ds = kmalloc_node(sizeof(*ds), GFP_KERNEL | __GFP_ZERO, node);
+ if (unlikely(!ds))
+ return -ENOMEM;
+
+ per_cpu(cpu_hw_events, cpu).ds = ds;
+
+ return 0;
+}
+
+static void release_ds_buffer(int cpu)
+{
+ struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+
+ if (!ds)
+ return;
+
+ per_cpu(cpu_hw_events, cpu).ds = NULL;
+ kfree(ds);
+}
+
static void release_ds_buffers(void)
{
int cpu;
@@ -82,93 +183,77 @@ static void release_ds_buffers(void)
return;
get_online_cpus();
-
for_each_online_cpu(cpu)
fini_debug_store_on_cpu(cpu);
for_each_possible_cpu(cpu) {
- struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
-
- if (!ds)
- continue;
-
- per_cpu(cpu_hw_events, cpu).ds = NULL;
-
- kfree((void *)(unsigned long)ds->pebs_buffer_base);
- kfree((void *)(unsigned long)ds->bts_buffer_base);
- kfree(ds);
+ release_pebs_buffer(cpu);
+ release_bts_buffer(cpu);
+ release_ds_buffer(cpu);
}
-
put_online_cpus();
}
-static int reserve_ds_buffers(void)
+static void reserve_ds_buffers(void)
{
- int cpu, err = 0;
+ int bts_err = 0, pebs_err = 0;
+ int cpu;
+
+ x86_pmu.bts_active = 0;
+ x86_pmu.pebs_active = 0;
if (!x86_pmu.bts && !x86_pmu.pebs)
- return 0;
+ return;
+
+ if (!x86_pmu.bts)
+ bts_err = 1;
+
+ if (!x86_pmu.pebs)
+ pebs_err = 1;
get_online_cpus();
for_each_possible_cpu(cpu) {
- struct debug_store *ds;
- void *buffer;
- int max, thresh;
+ if (alloc_ds_buffer(cpu)) {
+ bts_err = 1;
+ pebs_err = 1;
+ }
+
+ if (!bts_err && alloc_bts_buffer(cpu))
+ bts_err = 1;
+
+ if (!pebs_err && alloc_pebs_buffer(cpu))
+ pebs_err = 1;
- err = -ENOMEM;
- ds = kzalloc(sizeof(*ds), GFP_KERNEL);
- if (unlikely(!ds))
+ if (bts_err && pebs_err)
break;
- per_cpu(cpu_hw_events, cpu).ds = ds;
-
- if (x86_pmu.bts) {
- buffer = kzalloc(BTS_BUFFER_SIZE, GFP_KERNEL);
- if (unlikely(!buffer))
- break;
-
- max = BTS_BUFFER_SIZE / BTS_RECORD_SIZE;
- thresh = max / 16;
-
- ds->bts_buffer_base = (u64)(unsigned long)buffer;
- ds->bts_index = ds->bts_buffer_base;
- ds->bts_absolute_maximum = ds->bts_buffer_base +
- max * BTS_RECORD_SIZE;
- ds->bts_interrupt_threshold = ds->bts_absolute_maximum -
- thresh * BTS_RECORD_SIZE;
- }
+ }
- if (x86_pmu.pebs) {
- buffer = kzalloc(PEBS_BUFFER_SIZE, GFP_KERNEL);
- if (unlikely(!buffer))
- break;
-
- max = PEBS_BUFFER_SIZE / x86_pmu.pebs_record_size;
-
- ds->pebs_buffer_base = (u64)(unsigned long)buffer;
- ds->pebs_index = ds->pebs_buffer_base;
- ds->pebs_absolute_maximum = ds->pebs_buffer_base +
- max * x86_pmu.pebs_record_size;
- /*
- * Always use single record PEBS
- */
- ds->pebs_interrupt_threshold = ds->pebs_buffer_base +
- x86_pmu.pebs_record_size;
- }
+ if (bts_err) {
+ for_each_possible_cpu(cpu)
+ release_bts_buffer(cpu);
+ }
- err = 0;
+ if (pebs_err) {
+ for_each_possible_cpu(cpu)
+ release_pebs_buffer(cpu);
}
- if (err)
- release_ds_buffers();
- else {
+ if (bts_err && pebs_err) {
+ for_each_possible_cpu(cpu)
+ release_ds_buffer(cpu);
+ } else {
+ if (x86_pmu.bts && !bts_err)
+ x86_pmu.bts_active = 1;
+
+ if (x86_pmu.pebs && !pebs_err)
+ x86_pmu.pebs_active = 1;
+
for_each_online_cpu(cpu)
init_debug_store_on_cpu(cpu);
}
put_online_cpus();
-
- return err;
}
/*
@@ -214,7 +299,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 +316,16 @@ static void intel_pmu_drain_bts_buffer(void)
struct pt_regs regs;
if (!event)
- return;
+ return 0;
- if (!ds)
- return;
+ if (!x86_pmu.bts_active)
+ 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 +341,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 +355,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 +577,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)
@@ -502,7 +588,7 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs)
struct pebs_record_core *at, *top;
int n;
- if (!ds || !x86_pmu.pebs)
+ if (!x86_pmu.pebs_active)
return;
at = (struct pebs_record_core *)(unsigned long)ds->pebs_buffer_base;
@@ -544,7 +630,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
u64 status = 0;
int bit, n;
- if (!ds || !x86_pmu.pebs)
+ if (!x86_pmu.pebs_active)
return;
at = (struct pebs_record_nhm *)(unsigned long)ds->pebs_buffer_base;
@@ -629,9 +715,8 @@ static void intel_ds_init(void)
#else /* CONFIG_CPU_SUP_INTEL */
-static int reserve_ds_buffers(void)
+static void reserve_ds_buffers(void)
{
- return 0;
}
static void release_ds_buffers(void)
diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c
index 249015173992..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);
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_32.c b/arch/x86/kernel/crash_dump_32.c
index 67414550c3cc..d5cd13945d5a 100644
--- a/arch/x86/kernel/crash_dump_32.c
+++ b/arch/x86/kernel/crash_dump_32.c
@@ -61,7 +61,7 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
if (!is_crashed_pfn_valid(pfn))
return -EFAULT;
- vaddr = kmap_atomic_pfn(pfn, KM_PTE0);
+ vaddr = kmap_atomic_pfn(pfn);
if (!userbuf) {
memcpy(buf, (vaddr + offset), csize);
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/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c
index 0f6376ffa2d9..1bc7f75a5bda 100644
--- a/arch/x86/kernel/dumpstack_32.c
+++ b/arch/x86/kernel/dumpstack_32.c
@@ -82,11 +82,11 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
if (kstack_end(stack))
break;
if (i && ((i % STACKSLOTS_PER_LINE) == 0))
- printk("\n%s", log_lvl);
- printk(" %08lx", *stack++);
+ printk(KERN_CONT "\n");
+ printk(KERN_CONT " %08lx", *stack++);
touch_nmi_watchdog();
}
- printk("\n");
+ printk(KERN_CONT "\n");
show_trace_log_lvl(task, regs, sp, bp, log_lvl);
}
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c
index 57a21f11c791..6a340485249a 100644
--- a/arch/x86/kernel/dumpstack_64.c
+++ b/arch/x86/kernel/dumpstack_64.c
@@ -265,20 +265,20 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
if (stack >= irq_stack && stack <= irq_stack_end) {
if (stack == irq_stack_end) {
stack = (unsigned long *) (irq_stack_end[-1]);
- printk(" <EOI> ");
+ printk(KERN_CONT " <EOI> ");
}
} else {
if (((long) stack & (THREAD_SIZE-1)) == 0)
break;
}
if (i && ((i % STACKSLOTS_PER_LINE) == 0))
- printk("\n%s", log_lvl);
- printk(" %016lx", *stack++);
+ printk(KERN_CONT "\n");
+ printk(KERN_CONT " %016lx", *stack++);
touch_nmi_watchdog();
}
preempt_enable();
- printk("\n");
+ printk(KERN_CONT "\n");
show_trace_log_lvl(task, regs, sp, bp, log_lvl);
}
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/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 7494999141b3..ae03cab4352e 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;
@@ -726,7 +713,7 @@ static int hpet_cpuhp_notify(struct notifier_block *n,
switch (action & 0xf) {
case CPU_ONLINE:
- INIT_DELAYED_WORK_ON_STACK(&work.work, hpet_work);
+ INIT_DELAYED_WORK_ONSTACK(&work.work, hpet_work);
init_completion(&work.complete);
/* FIXME: add schedule_work_on() */
schedule_delayed_work_on(cpu, &work.work, 0);
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..96656f207751 100644
--- a/arch/x86/kernel/irq_32.c
+++ b/arch/x86/kernel/irq_32.c
@@ -17,6 +17,7 @@
#include <linux/delay.h>
#include <linux/uaccess.h>
#include <linux/percpu.h>
+#include <linux/mm.h>
#include <asm/apic.h>
@@ -49,21 +50,17 @@ 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 void call_on_stack(void *func, void *stack)
{
asm volatile("xchgl %%ebx,%%esp \n"
@@ -129,7 +126,9 @@ void __cpuinit irq_ctx_init(int cpu)
if (per_cpu(hardirq_ctx, cpu))
return;
- irqctx = &per_cpu(hardirq_stack, cpu);
+ irqctx = page_address(alloc_pages_node(cpu_to_node(cpu),
+ THREAD_FLAGS,
+ THREAD_ORDER));
irqctx->tinfo.task = NULL;
irqctx->tinfo.exec_domain = NULL;
irqctx->tinfo.cpu = cpu;
@@ -138,7 +137,9 @@ void __cpuinit irq_ctx_init(int cpu)
per_cpu(hardirq_ctx, cpu) = irqctx;
- irqctx = &per_cpu(softirq_stack, cpu);
+ irqctx = page_address(alloc_pages_node(cpu_to_node(cpu),
+ THREAD_FLAGS,
+ THREAD_ORDER));
irqctx->tinfo.task = NULL;
irqctx->tinfo.exec_domain = NULL;
irqctx->tinfo.cpu = cpu;
@@ -151,11 +152,6 @@ void __cpuinit irq_ctx_init(int cpu)
cpu, per_cpu(hardirq_ctx, cpu), per_cpu(softirq_ctx, cpu));
}
-void irq_ctx_exit(int cpu)
-{
- per_cpu(hardirq_ctx, cpu) = NULL;
-}
-
asmlinkage void do_softirq(void)
{
unsigned long flags;
@@ -187,11 +183,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..ec592caac4b4 100644
--- a/arch/x86/kernel/kgdb.c
+++ b/arch/x86/kernel/kgdb.c
@@ -387,7 +387,7 @@ kgdb_set_hw_break(unsigned long addr, int len, enum kgdb_bptype bptype)
* disable hardware debugging while it is processing gdb packets or
* handling exception.
*/
-void kgdb_disable_hw_debug(struct pt_regs *regs)
+static void kgdb_disable_hw_debug(struct pt_regs *regs)
{
int i;
int cpu = raw_smp_processor_id();
@@ -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;
@@ -721,6 +724,7 @@ struct kgdb_arch arch_kgdb_ops = {
.flags = KGDB_HW_BREAKPOINT,
.set_hw_breakpoint = kgdb_set_hw_break,
.remove_hw_breakpoint = kgdb_remove_hw_break,
+ .disable_hw_break = kgdb_disable_hw_debug,
.remove_all_hw_break = kgdb_remove_all_hw_break,
.correct_hw_break = kgdb_correct_hw_break,
};
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 1c355c550960..8f2956091735 100644
--- a/arch/x86/kernel/module.c
+++ b/arch/x86/kernel/module.c
@@ -239,6 +239,9 @@ int module_finalize(const Elf_Ehdr *hdr,
apply_paravirt(pseg, pseg + para->sh_size);
}
+ /* make jump label nops */
+ jump_label_apply_nops(me);
+
return 0;
}
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/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/ptrace.c b/arch/x86/kernel/ptrace.c
index 70c4872cd8aa..45892dc4b72a 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -801,7 +801,8 @@ void ptrace_disable(struct task_struct *child)
static const struct user_regset_view user_x86_32_view; /* Initialized below. */
#endif
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int ret;
unsigned long __user *datap = (unsigned long __user *)data;
@@ -812,8 +813,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
unsigned long tmp;
ret = -EIO;
- if ((addr & (sizeof(data) - 1)) || addr < 0 ||
- addr >= sizeof(struct user))
+ if ((addr & (sizeof(data) - 1)) || addr >= sizeof(struct user))
break;
tmp = 0; /* Default return condition */
@@ -830,8 +830,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
ret = -EIO;
- if ((addr & (sizeof(data) - 1)) || addr < 0 ||
- addr >= sizeof(struct user))
+ if ((addr & (sizeof(data) - 1)) || addr >= sizeof(struct user))
break;
if (addr < sizeof(struct user_regs_struct))
@@ -888,17 +887,17 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
#if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
case PTRACE_GET_THREAD_AREA:
- if (addr < 0)
+ if ((int) addr < 0)
return -EIO;
ret = do_get_thread_area(child, addr,
- (struct user_desc __user *) data);
+ (struct user_desc __user *)data);
break;
case PTRACE_SET_THREAD_AREA:
- if (addr < 0)
+ if ((int) addr < 0)
return -EIO;
ret = do_set_thread_area(child, addr,
- (struct user_desc __user *) data, 0);
+ (struct user_desc __user *)data, 0);
break;
#endif
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..c495aa8d4815 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
@@ -641,7 +635,7 @@ void native_machine_shutdown(void)
/* O.K Now that I'm on the appropriate processor,
* stop all of the others.
*/
- smp_send_stop();
+ stop_other_cpus();
#endif
lapic_shutdown();
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index c3a4fbb2b996..21c6746338af 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,12 +763,14 @@ void __init setup_arch(char **cmdline_p)
#endif
4)) {
efi_enabled = 1;
- efi_reserve_early();
+ efi_memblock_x86_reserve_range();
}
#endif
x86_init.oem.arch_setup();
+ resource_alloc_from_bottom = 0;
+ iomem_resource.end = (1ULL << boot_cpu_data.x86_phys_bits) - 1;
setup_memory_map();
parse_setup_data();
/* update the e820_saved too */
@@ -838,11 +821,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 +843,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 +875,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 +896,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 +905,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 +948,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 +987,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 +998,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 +1060,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/smp.c b/arch/x86/kernel/smp.c
index d801210945d6..513deac7228d 100644
--- a/arch/x86/kernel/smp.c
+++ b/arch/x86/kernel/smp.c
@@ -159,10 +159,10 @@ asmlinkage void smp_reboot_interrupt(void)
irq_exit();
}
-static void native_smp_send_stop(void)
+static void native_stop_other_cpus(int wait)
{
unsigned long flags;
- unsigned long wait;
+ unsigned long timeout;
if (reboot_force)
return;
@@ -179,9 +179,12 @@ static void native_smp_send_stop(void)
if (num_online_cpus() > 1) {
apic->send_IPI_allbutself(REBOOT_VECTOR);
- /* Don't wait longer than a second */
- wait = USEC_PER_SEC;
- while (num_online_cpus() > 1 && wait--)
+ /*
+ * Don't wait longer than a second if the caller
+ * didn't ask us to wait.
+ */
+ timeout = USEC_PER_SEC;
+ while (num_online_cpus() > 1 && (wait || timeout--))
udelay(1);
}
@@ -227,7 +230,7 @@ struct smp_ops smp_ops = {
.smp_prepare_cpus = native_smp_prepare_cpus,
.smp_cpus_done = native_smp_cpus_done,
- .smp_send_stop = native_smp_send_stop,
+ .stop_other_cpus = native_stop_other_cpus,
.smp_send_reschedule = native_smp_send_reschedule,
.cpu_up = native_cpu_up,
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 8b3bfc4dd708..083e99d1b7df 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 {
@@ -742,7 +747,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu)
.done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
};
- INIT_WORK_ON_STACK(&c_idle.work, do_fork_idle);
+ INIT_WORK_ONSTACK(&c_idle.work, do_fork_idle);
alternatives_smp_switch(1);
@@ -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)",
@@ -1370,7 +1373,6 @@ void play_dead_common(void)
{
idle_task_exit();
reset_lazy_tlbstate();
- irq_ctx_exit(raw_smp_processor_id());
c1e_remove_cpu(raw_smp_processor_id());
mb();
@@ -1383,11 +1385,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/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/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/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index cd6da6bf3eca..ceb2911aa439 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -6,10 +6,12 @@
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/module.h>
+#include <linux/pci.h>
#include <asm/bios_ebda.h>
#include <asm/paravirt.h>
#include <asm/pci_x86.h>
+#include <asm/pci.h>
#include <asm/mpspec.h>
#include <asm/setup.h>
#include <asm/apic.h>
@@ -99,3 +101,8 @@ struct x86_platform_ops x86_platform = {
};
EXPORT_SYMBOL_GPL(x86_platform);
+struct x86_msi_ops x86_msi = {
+ .setup_msi_irqs = native_setup_msi_irqs,
+ .teardown_msi_irq = native_teardown_msi_irq,
+ .teardown_msi_irqs = default_teardown_msi_irqs,
+};
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 8a3f9f64f86f..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;
@@ -793,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;
@@ -804,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 = ?? */
@@ -901,7 +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);
- svm->vmcb->control.tsc_offset = 0-native_read_tsc();
+ 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
@@ -3167,9 +3313,6 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
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();
@@ -3291,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;
@@ -3333,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;
@@ -3354,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;
}
@@ -3497,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,
@@ -3519,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 7bddfab12013..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();
@@ -883,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)
@@ -897,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);
- }
}
}
@@ -1044,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;
}
@@ -1149,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, offset);
+}
+
+static void vmx_adjust_tsc_offset(struct kvm_vcpu *vcpu, s64 adjustment)
{
- vmcs_write64(TSC_OFFSET, guest_tsc - host_tsc);
+ u64 offset = vmcs_read64(TSC_OFFSET);
+ vmcs_write64(TSC_OFFSET, offset + adjustment);
}
/*
@@ -1227,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) {
@@ -1257,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) {
@@ -1856,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,
@@ -2515,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;
@@ -2656,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;
}
@@ -2834,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;
@@ -2875,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,
@@ -3346,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;
}
@@ -3358,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;
/*
@@ -3614,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;
}
@@ -3623,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) {
@@ -3790,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)
@@ -3816,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;
@@ -3839,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);
@@ -3847,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;
@@ -3863,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,
@@ -3885,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
@@ -4032,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
@@ -4043,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);
}
@@ -4119,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();
@@ -4334,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,
@@ -4356,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..7d90ceb882a4 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -11,6 +11,7 @@
#include <linux/kprobes.h> /* __kprobes, ... */
#include <linux/mmiotrace.h> /* kmmio_handler, ... */
#include <linux/perf_event.h> /* perf_sw_event */
+#include <linux/hugetlb.h> /* hstate_index_to_shift */
#include <asm/traps.h> /* dotraplinkage, ... */
#include <asm/pgalloc.h> /* pgd_*(), ... */
@@ -160,15 +161,20 @@ is_prefetch(struct pt_regs *regs, unsigned long error_code, unsigned long addr)
static void
force_sig_info_fault(int si_signo, int si_code, unsigned long address,
- struct task_struct *tsk)
+ struct task_struct *tsk, int fault)
{
+ unsigned lsb = 0;
siginfo_t info;
info.si_signo = si_signo;
info.si_errno = 0;
info.si_code = si_code;
info.si_addr = (void __user *)address;
- info.si_addr_lsb = si_code == BUS_MCEERR_AR ? PAGE_SHIFT : 0;
+ if (fault & VM_FAULT_HWPOISON_LARGE)
+ lsb = hstate_index_to_shift(VM_FAULT_GET_HINDEX(fault));
+ if (fault & VM_FAULT_HWPOISON)
+ lsb = PAGE_SHIFT;
+ info.si_addr_lsb = lsb;
force_sig_info(si_signo, &info, tsk);
}
@@ -229,7 +235,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 +266,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 +343,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 +364,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
@@ -731,7 +728,7 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,
tsk->thread.error_code = error_code | (address >= TASK_SIZE);
tsk->thread.trap_no = 14;
- force_sig_info_fault(SIGSEGV, si_code, address, tsk);
+ force_sig_info_fault(SIGSEGV, si_code, address, tsk, 0);
return;
}
@@ -816,14 +813,14 @@ do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address,
tsk->thread.trap_no = 14;
#ifdef CONFIG_MEMORY_FAILURE
- if (fault & VM_FAULT_HWPOISON) {
+ if (fault & (VM_FAULT_HWPOISON|VM_FAULT_HWPOISON_LARGE)) {
printk(KERN_ERR
"MCE: Killing %s:%d due to hardware memory corruption fault at %lx\n",
tsk->comm, tsk->pid, address);
code = BUS_MCEERR_AR;
}
#endif
- force_sig_info_fault(SIGBUS, code, address, tsk);
+ force_sig_info_fault(SIGBUS, code, address, tsk, fault);
}
static noinline void
@@ -833,7 +830,8 @@ mm_fault_error(struct pt_regs *regs, unsigned long error_code,
if (fault & VM_FAULT_OOM) {
out_of_memory(regs, error_code, address);
} else {
- if (fault & (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON))
+ if (fault & (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON|
+ VM_FAULT_HWPOISON_LARGE))
do_sigbus(regs, error_code, address, fault);
else
BUG();
@@ -894,8 +892,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);
@@ -915,9 +919,9 @@ spurious_fault(unsigned long error_code, unsigned long address)
int show_unhandled_signals = 1;
static inline int
-access_error(unsigned long error_code, int write, struct vm_area_struct *vma)
+access_error(unsigned long error_code, struct vm_area_struct *vma)
{
- if (write) {
+ if (error_code & PF_WRITE) {
/* write, present and write, not present: */
if (unlikely(!(vma->vm_flags & VM_WRITE)))
return 1;
@@ -952,8 +956,10 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code)
struct task_struct *tsk;
unsigned long address;
struct mm_struct *mm;
- int write;
int fault;
+ int write = error_code & PF_WRITE;
+ unsigned int flags = FAULT_FLAG_ALLOW_RETRY |
+ (write ? FAULT_FLAG_WRITE : 0);
tsk = current;
mm = tsk->mm;
@@ -1064,6 +1070,7 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code)
bad_area_nosemaphore(regs, error_code, address);
return;
}
+retry:
down_read(&mm->mmap_sem);
} else {
/*
@@ -1107,9 +1114,7 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code)
* we can handle it..
*/
good_area:
- write = error_code & PF_WRITE;
-
- if (unlikely(access_error(error_code, write, vma))) {
+ if (unlikely(access_error(error_code, vma))) {
bad_area_access_error(regs, error_code, address);
return;
}
@@ -1119,21 +1124,34 @@ good_area:
* make sure we exit gracefully rather than endlessly redo
* the fault:
*/
- fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0);
+ fault = handle_mm_fault(mm, vma, address, flags);
if (unlikely(fault & VM_FAULT_ERROR)) {
mm_fault_error(regs, error_code, address, fault);
return;
}
- if (fault & VM_FAULT_MAJOR) {
- tsk->maj_flt++;
- perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
- regs, address);
- } else {
- tsk->min_flt++;
- perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
- regs, address);
+ /*
+ * Major/minor page fault accounting is only done on the
+ * initial attempt. If we go through a retry, it is extremely
+ * likely that the page will be found in page cache at that point.
+ */
+ if (flags & FAULT_FLAG_ALLOW_RETRY) {
+ if (fault & VM_FAULT_MAJOR) {
+ tsk->maj_flt++;
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
+ regs, address);
+ } else {
+ tsk->min_flt++;
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
+ regs, address);
+ }
+ if (fault & VM_FAULT_RETRY) {
+ /* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
+ * of starvation. */
+ flags &= ~FAULT_FLAG_ALLOW_RETRY;
+ goto retry;
+ }
}
check_v8086_mode(regs, address, tsk);
diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c
index 5e8fa12ef861..b49962662101 100644
--- a/arch/x86/mm/highmem_32.c
+++ b/arch/x86/mm/highmem_32.c
@@ -9,6 +9,7 @@ void *kmap(struct page *page)
return page_address(page);
return kmap_high(page);
}
+EXPORT_SYMBOL(kmap);
void kunmap(struct page *page)
{
@@ -18,6 +19,7 @@ void kunmap(struct page *page)
return;
kunmap_high(page);
}
+EXPORT_SYMBOL(kunmap);
/*
* kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because
@@ -27,10 +29,10 @@ void kunmap(struct page *page)
* However when holding an atomic kmap it is not legal to sleep, so atomic
* kmaps are appropriate for short, tight code paths only.
*/
-void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot)
+void *kmap_atomic_prot(struct page *page, pgprot_t prot)
{
- enum fixed_addresses idx;
unsigned long vaddr;
+ int idx, type;
/* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
pagefault_disable();
@@ -38,8 +40,7 @@ void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot)
if (!PageHighMem(page))
return page_address(page);
- debug_kmap_atomic(type);
-
+ type = kmap_atomic_idx_push();
idx = type + KM_TYPE_NR*smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
BUG_ON(!pte_none(*(kmap_pte-idx)));
@@ -47,44 +48,57 @@ void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot)
return (void *)vaddr;
}
+EXPORT_SYMBOL(kmap_atomic_prot);
+
+void *__kmap_atomic(struct page *page)
+{
+ return kmap_atomic_prot(page, kmap_prot);
+}
+EXPORT_SYMBOL(__kmap_atomic);
-void *kmap_atomic(struct page *page, enum km_type type)
+/*
+ * This is the same as kmap_atomic() but can map memory that doesn't
+ * have a struct page associated with it.
+ */
+void *kmap_atomic_pfn(unsigned long pfn)
{
- return kmap_atomic_prot(page, type, kmap_prot);
+ return kmap_atomic_prot_pfn(pfn, kmap_prot);
}
+EXPORT_SYMBOL_GPL(kmap_atomic_pfn);
-void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type)
+void __kunmap_atomic(void *kvaddr)
{
unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
- enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
-
- /*
- * Force other mappings to Oops if they'll try to access this pte
- * without first remap it. Keeping stale mappings around is a bad idea
- * also, in case the page changes cacheability attributes or becomes
- * a protected page in a hypervisor.
- */
- if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx))
+
+ if (vaddr >= __fix_to_virt(FIX_KMAP_END) &&
+ vaddr <= __fix_to_virt(FIX_KMAP_BEGIN)) {
+ int idx, type;
+
+ type = kmap_atomic_idx();
+ idx = type + KM_TYPE_NR * smp_processor_id();
+
+#ifdef CONFIG_DEBUG_HIGHMEM
+ WARN_ON_ONCE(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
+#endif
+ /*
+ * Force other mappings to Oops if they'll try to access this
+ * pte without first remap it. Keeping stale mappings around
+ * is a bad idea also, in case the page changes cacheability
+ * attributes or becomes a protected page in a hypervisor.
+ */
kpte_clear_flush(kmap_pte-idx, vaddr);
- else {
+ kmap_atomic_idx_pop();
+ }
#ifdef CONFIG_DEBUG_HIGHMEM
+ else {
BUG_ON(vaddr < PAGE_OFFSET);
BUG_ON(vaddr >= (unsigned long)high_memory);
-#endif
}
+#endif
pagefault_enable();
}
-
-/*
- * This is the same as kmap_atomic() but can map memory that doesn't
- * have a struct page associated with it.
- */
-void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
-{
- return kmap_atomic_prot_pfn(pfn, type, kmap_prot);
-}
-EXPORT_SYMBOL_GPL(kmap_atomic_pfn); /* temporarily in use by i915 GEM until vmap */
+EXPORT_SYMBOL(__kunmap_atomic);
struct page *kmap_atomic_to_page(void *ptr)
{
@@ -98,12 +112,6 @@ struct page *kmap_atomic_to_page(void *ptr)
pte = kmap_pte - (idx - FIX_KMAP_BEGIN);
return pte_page(*pte);
}
-
-EXPORT_SYMBOL(kmap);
-EXPORT_SYMBOL(kunmap);
-EXPORT_SYMBOL(kmap_atomic);
-EXPORT_SYMBOL(kunmap_atomic_notypecheck);
-EXPORT_SYMBOL(kmap_atomic_prot);
EXPORT_SYMBOL(kmap_atomic_to_page);
void __init set_highmem_pages_init(void)
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..71a59296af80 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>
@@ -50,9 +51,6 @@
#include <asm/numa.h>
#include <asm/cacheflush.h>
#include <asm/init.h>
-#include <linux/bootmem.h>
-
-static unsigned long dma_reserve __initdata;
static int __init parse_direct_gbpages_off(char *arg)
{
@@ -98,6 +96,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 +328,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 +569,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 +600,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 +615,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 +825,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 +983,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/iomap_32.c b/arch/x86/mm/iomap_32.c
index 72fc70cf6184..7b179b499fa3 100644
--- a/arch/x86/mm/iomap_32.c
+++ b/arch/x86/mm/iomap_32.c
@@ -48,21 +48,20 @@ int iomap_create_wc(resource_size_t base, unsigned long size, pgprot_t *prot)
}
EXPORT_SYMBOL_GPL(iomap_create_wc);
-void
-iomap_free(resource_size_t base, unsigned long size)
+void iomap_free(resource_size_t base, unsigned long size)
{
io_free_memtype(base, base + size);
}
EXPORT_SYMBOL_GPL(iomap_free);
-void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot)
+void *kmap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot)
{
- enum fixed_addresses idx;
unsigned long vaddr;
+ int idx, type;
pagefault_disable();
- debug_kmap_atomic(type);
+ type = kmap_atomic_idx_push();
idx = type + KM_TYPE_NR * smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
set_pte(kmap_pte - idx, pfn_pte(pfn, prot));
@@ -72,10 +71,10 @@ void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot)
}
/*
- * Map 'pfn' using fixed map 'type' and protections 'prot'
+ * Map 'pfn' using protections 'prot'
*/
void __iomem *
-iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot)
+iomap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot)
{
/*
* For non-PAT systems, promote PAGE_KERNEL_WC to PAGE_KERNEL_UC_MINUS.
@@ -86,24 +85,34 @@ iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot)
if (!pat_enabled && pgprot_val(prot) == pgprot_val(PAGE_KERNEL_WC))
prot = PAGE_KERNEL_UC_MINUS;
- return (void __force __iomem *) kmap_atomic_prot_pfn(pfn, type, prot);
+ return (void __force __iomem *) kmap_atomic_prot_pfn(pfn, prot);
}
EXPORT_SYMBOL_GPL(iomap_atomic_prot_pfn);
void
-iounmap_atomic(void __iomem *kvaddr, enum km_type type)
+iounmap_atomic(void __iomem *kvaddr)
{
unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
- enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
- /*
- * Force other mappings to Oops if they'll try to access this pte
- * without first remap it. Keeping stale mappings around is a bad idea
- * also, in case the page changes cacheability attributes or becomes
- * a protected page in a hypervisor.
- */
- if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx))
+ if (vaddr >= __fix_to_virt(FIX_KMAP_END) &&
+ vaddr <= __fix_to_virt(FIX_KMAP_BEGIN)) {
+ int idx, type;
+
+ type = kmap_atomic_idx();
+ idx = type + KM_TYPE_NR * smp_processor_id();
+
+#ifdef CONFIG_DEBUG_HIGHMEM
+ WARN_ON_ONCE(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
+#endif
+ /*
+ * Force other mappings to Oops if they'll try to access this
+ * pte without first remap it. Keeping stale mappings around
+ * is a bad idea also, in case the page changes cacheability
+ * attributes or becomes a protected page in a hypervisor.
+ */
kpte_clear_flush(kmap_pte-idx, vaddr);
+ kmap_atomic_idx_pop();
+ }
pagefault_enable();
}
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..7ffc9b727efd 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,18 +172,15 @@ 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 */
end = max_pfn_mapped << PAGE_SHIFT;
- if (end > (MAX_DMA32_PFN<<PAGE_SHIFT))
- start = MAX_DMA32_PFN<<PAGE_SHIFT;
- else
- start = MAX_DMA_PFN<<PAGE_SHIFT;
- mem = find_e820_area(start, end, size, align);
- if (mem != -1L)
+ start = MAX_DMA_PFN << PAGE_SHIFT;
+ mem = memblock_find_in_range(start, end, size, align);
+ if (mem != MEMBLOCK_ERROR)
return __va(mem);
printk(KERN_ERR "Cannot find %lu bytes in node %d\n",
@@ -198,10 +196,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 +220,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 +232,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 +369,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 +405,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 +419,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 +428,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 +456,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 +485,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 +518,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 +527,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 +591,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 +644,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 +656,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 9c0d0d399c30..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
@@ -421,7 +422,7 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
}
for (i = 0; i < num_node_memblks; i++)
- e820_register_active_regions(memblk_nodeid[i],
+ memblock_x86_register_active_regions(memblk_nodeid[i],
node_memblk_range[i].start >> PAGE_SHIFT,
node_memblk_range[i].end >> PAGE_SHIFT);
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 f1575c9a2572..4e8baad36d37 100644
--- a/arch/x86/oprofile/nmi_int.c
+++ b/arch/x86/oprofile/nmi_int.c
@@ -695,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;
@@ -705,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;
@@ -731,6 +726,12 @@ int __init op_nmi_init(struct oprofile_operations *ops)
case 0x11:
cpu_type = "x86-64/family11h";
break;
+ case 0x12:
+ cpu_type = "x86-64/family12h";
+ break;
+ case 0x14:
+ cpu_type = "x86-64/family14h";
+ break;
default:
return -ENODEV;
}
@@ -790,13 +791,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..a011bcc0f943 100644
--- a/arch/x86/oprofile/op_model_amd.c
+++ b/arch/x86/oprofile/op_model_amd.c
@@ -48,31 +48,53 @@ static unsigned long reset_value[NUM_VIRT_COUNTERS];
static u32 ibs_caps;
-struct op_ibs_config {
+struct ibs_config {
unsigned long op_enabled;
unsigned long fetch_enabled;
unsigned long max_cnt_fetch;
unsigned long max_cnt_op;
unsigned long rand_en;
unsigned long dispatched_ops;
+ unsigned long branch_target;
};
-static struct op_ibs_config ibs_config;
-static u64 ibs_op_ctl;
+struct ibs_state {
+ u64 ibs_op_ctl;
+ int branch_target;
+ unsigned long sample_size;
+};
+
+static struct ibs_config ibs_config;
+static struct ibs_state ibs_state;
/*
* 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_FETCHSAM (1U<<1)
+#define IBS_CAPS_OPSAM (1U<<2)
+#define IBS_CAPS_RDWROPCNT (1U<<3)
+#define IBS_CAPS_OPCNT (1U<<4)
+#define IBS_CAPS_BRNTRGT (1U<<5)
+#define IBS_CAPS_OPCNTEXT (1U<<6)
+
+#define IBS_CAPS_DEFAULT (IBS_CAPS_AVAIL \
+ | IBS_CAPS_FETCHSAM \
+ | IBS_CAPS_OPSAM)
+
+/*
+ * IBS APIC setup
+ */
+#define IBSCTL 0x1cc
+#define IBSCTL_LVT_OFFSET_VALID (1ULL<<8)
+#define IBSCTL_LVT_OFFSET_MASK 0x0F
/*
* IBS randomization macros
@@ -92,12 +114,12 @@ static u32 get_ibs_caps(void)
/* check IBS cpuid feature flags */
max_level = cpuid_eax(0x80000000);
if (max_level < IBS_CPUID_FEATURES)
- return IBS_CAPS_AVAIL;
+ return IBS_CAPS_DEFAULT;
ibs_caps = cpuid_eax(IBS_CPUID_FEATURES);
if (!(ibs_caps & IBS_CAPS_AVAIL))
/* cpuid flags not valid */
- return IBS_CAPS_AVAIL;
+ return IBS_CAPS_DEFAULT;
return ibs_caps;
}
@@ -190,8 +212,8 @@ op_amd_handle_ibs(struct pt_regs * const regs,
rdmsrl(MSR_AMD64_IBSOPCTL, ctl);
if (ctl & IBS_OP_VAL) {
rdmsrl(MSR_AMD64_IBSOPRIP, val);
- oprofile_write_reserve(&entry, regs, val,
- IBS_OP_CODE, IBS_OP_SIZE);
+ oprofile_write_reserve(&entry, regs, val, IBS_OP_CODE,
+ ibs_state.sample_size);
oprofile_add_data64(&entry, val);
rdmsrl(MSR_AMD64_IBSOPDATA, val);
oprofile_add_data64(&entry, val);
@@ -203,10 +225,14 @@ op_amd_handle_ibs(struct pt_regs * const regs,
oprofile_add_data64(&entry, val);
rdmsrl(MSR_AMD64_IBSDCPHYSAD, val);
oprofile_add_data64(&entry, val);
+ if (ibs_state.branch_target) {
+ rdmsrl(MSR_AMD64_IBSBRTARGET, val);
+ oprofile_add_data(&entry, (unsigned long)val);
+ }
oprofile_write_commit(&entry);
/* reenable the IRQ */
- ctl = op_amd_randomize_ibs_op(ibs_op_ctl);
+ ctl = op_amd_randomize_ibs_op(ibs_state.ibs_op_ctl);
wrmsrl(MSR_AMD64_IBSOPCTL, ctl);
}
}
@@ -219,21 +245,32 @@ static inline void op_amd_start_ibs(void)
if (!ibs_caps)
return;
+ memset(&ibs_state, 0, sizeof(ibs_state));
+
+ /*
+ * Note: Since the max count settings may out of range we
+ * write back the actual used values so that userland can read
+ * it.
+ */
+
if (ibs_config.fetch_enabled) {
- val = (ibs_config.max_cnt_fetch >> 4) & IBS_FETCH_MAX_CNT;
+ val = ibs_config.max_cnt_fetch >> 4;
+ val = min(val, IBS_FETCH_MAX_CNT);
+ ibs_config.max_cnt_fetch = val << 4;
val |= ibs_config.rand_en ? IBS_FETCH_RAND_EN : 0;
val |= IBS_FETCH_ENABLE;
wrmsrl(MSR_AMD64_IBSFETCHCTL, val);
}
if (ibs_config.op_enabled) {
- ibs_op_ctl = ibs_config.max_cnt_op >> 4;
+ val = ibs_config.max_cnt_op >> 4;
if (!(ibs_caps & IBS_CAPS_RDWROPCNT)) {
/*
* IbsOpCurCnt not supported. See
* op_amd_randomize_ibs_op() for details.
*/
- ibs_op_ctl = clamp(ibs_op_ctl, 0x0081ULL, 0xFF80ULL);
+ val = clamp(val, 0x0081ULL, 0xFF80ULL);
+ ibs_config.max_cnt_op = val << 4;
} else {
/*
* The start value is randomized with a
@@ -241,13 +278,24 @@ static inline void op_amd_start_ibs(void)
* with the half of the randomized range. Also
* avoid underflows.
*/
- ibs_op_ctl = min(ibs_op_ctl + IBS_RANDOM_MAXCNT_OFFSET,
- IBS_OP_MAX_CNT);
+ val += IBS_RANDOM_MAXCNT_OFFSET;
+ if (ibs_caps & IBS_CAPS_OPCNTEXT)
+ val = min(val, IBS_OP_MAX_CNT_EXT);
+ else
+ val = min(val, IBS_OP_MAX_CNT);
+ ibs_config.max_cnt_op =
+ (val - IBS_RANDOM_MAXCNT_OFFSET) << 4;
+ }
+ val = ((val & ~IBS_OP_MAX_CNT) << 4) | (val & IBS_OP_MAX_CNT);
+ val |= ibs_config.dispatched_ops ? IBS_OP_CNT_CTL : 0;
+ val |= IBS_OP_ENABLE;
+ ibs_state.ibs_op_ctl = val;
+ ibs_state.sample_size = IBS_OP_SIZE;
+ if (ibs_config.branch_target) {
+ ibs_state.branch_target = 1;
+ ibs_state.sample_size++;
}
- if (ibs_caps & IBS_CAPS_OPCNT && ibs_config.dispatched_ops)
- ibs_op_ctl |= IBS_OP_CNT_CTL;
- ibs_op_ctl |= IBS_OP_ENABLE;
- val = op_amd_randomize_ibs_op(ibs_op_ctl);
+ val = op_amd_randomize_ibs_op(ibs_state.ibs_op_ctl);
wrmsrl(MSR_AMD64_IBSOPCTL, val);
}
}
@@ -266,6 +314,70 @@ 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)
+{
+ int offset;
+ u64 val;
+
+ rdmsrl(MSR_AMD64_IBSCTL, val);
+ offset = val & IBSCTL_LVT_OFFSET_MASK;
+
+ if (!(val & IBSCTL_LVT_OFFSET_VALID)) {
+ pr_err(FW_BUG "cpu %d, invalid IBS interrupt offset %d (MSR%08X=0x%016llx)\n",
+ smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
+ return 0;
+ }
+
+ if (!eilvt_is_available(offset)) {
+ pr_err(FW_BUG "cpu %d, IBS interrupt offset %d not available (MSR%08X=0x%016llx)\n",
+ smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
+ return 0;
+ }
+
+ return 1;
+}
+
+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 +488,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 +557,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,24 +573,63 @@ 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;
+}
+
/* initialize the APIC for the IBS interrupts if available */
static void init_ibs(void)
{
@@ -521,28 +667,33 @@ static int setup_ibs_files(struct super_block *sb, struct dentry *root)
/* model specific files */
/* setup some reasonable defaults */
+ memset(&ibs_config, 0, sizeof(ibs_config));
ibs_config.max_cnt_fetch = 250000;
- ibs_config.fetch_enabled = 0;
ibs_config.max_cnt_op = 250000;
- ibs_config.op_enabled = 0;
- ibs_config.dispatched_ops = 0;
-
- dir = oprofilefs_mkdir(sb, root, "ibs_fetch");
- oprofilefs_create_ulong(sb, dir, "enable",
- &ibs_config.fetch_enabled);
- oprofilefs_create_ulong(sb, dir, "max_count",
- &ibs_config.max_cnt_fetch);
- oprofilefs_create_ulong(sb, dir, "rand_enable",
- &ibs_config.rand_en);
-
- dir = oprofilefs_mkdir(sb, root, "ibs_op");
- oprofilefs_create_ulong(sb, dir, "enable",
- &ibs_config.op_enabled);
- oprofilefs_create_ulong(sb, dir, "max_count",
- &ibs_config.max_cnt_op);
- if (ibs_caps & IBS_CAPS_OPCNT)
- oprofilefs_create_ulong(sb, dir, "dispatched_ops",
- &ibs_config.dispatched_ops);
+
+ if (ibs_caps & IBS_CAPS_FETCHSAM) {
+ dir = oprofilefs_mkdir(sb, root, "ibs_fetch");
+ oprofilefs_create_ulong(sb, dir, "enable",
+ &ibs_config.fetch_enabled);
+ oprofilefs_create_ulong(sb, dir, "max_count",
+ &ibs_config.max_cnt_fetch);
+ oprofilefs_create_ulong(sb, dir, "rand_enable",
+ &ibs_config.rand_en);
+ }
+
+ if (ibs_caps & IBS_CAPS_OPSAM) {
+ dir = oprofilefs_mkdir(sb, root, "ibs_op");
+ oprofilefs_create_ulong(sb, dir, "enable",
+ &ibs_config.op_enabled);
+ oprofilefs_create_ulong(sb, dir, "max_count",
+ &ibs_config.max_cnt_op);
+ if (ibs_caps & IBS_CAPS_OPCNT)
+ oprofilefs_create_ulong(sb, dir, "dispatched_ops",
+ &ibs_config.dispatched_ops);
+ if (ibs_caps & IBS_CAPS_BRNTRGT)
+ oprofilefs_create_ulong(sb, dir, "branch_target",
+ &ibs_config.branch_target);
+ }
return 0;
}
diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile
index a0207a7fdf39..effd96e33f16 100644
--- a/arch/x86/pci/Makefile
+++ b/arch/x86/pci/Makefile
@@ -4,6 +4,7 @@ obj-$(CONFIG_PCI_BIOS) += pcbios.o
obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_$(BITS).o direct.o mmconfig-shared.o
obj-$(CONFIG_PCI_DIRECT) += direct.o
obj-$(CONFIG_PCI_OLPC) += olpc.o
+obj-$(CONFIG_PCI_XEN) += xen.o
obj-y += fixup.o
obj-$(CONFIG_ACPI) += acpi.o
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index a0772af64efb..f7c8a399978c 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -421,16 +421,10 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum)
return bus;
}
-
-int __init pcibios_init(void)
+void __init pcibios_set_cache_line_size(void)
{
struct cpuinfo_x86 *c = &boot_cpu_data;
- if (!raw_pci_ops) {
- printk(KERN_WARNING "PCI: System does not support PCI\n");
- return 0;
- }
-
/*
* Set PCI cacheline size to that of the CPU if the CPU has reported it.
* (For older CPUs that don't support cpuid, we se it to 32 bytes
@@ -445,7 +439,16 @@ int __init pcibios_init(void)
pci_dfl_cache_line_size = 32 >> 2;
printk(KERN_DEBUG "PCI: Unknown cacheline size. Setting to 32 bytes\n");
}
+}
+
+int __init pcibios_init(void)
+{
+ if (!raw_pci_ops) {
+ printk(KERN_WARNING "PCI: System does not support PCI\n");
+ return 0;
+ }
+ pcibios_set_cache_line_size();
pcibios_resource_survey();
if (pci_bf_sort >= pci_force_bf)
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index 55253095be84..c4bb261c106e 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -65,16 +65,21 @@ pcibios_align_resource(void *data, const struct resource *res,
resource_size_t size, resource_size_t align)
{
struct pci_dev *dev = data;
- resource_size_t start = res->start;
+ resource_size_t start = round_down(res->end - size + 1, align);
if (res->flags & IORESOURCE_IO) {
- if (skip_isa_ioresource_align(dev))
- return start;
- if (start & 0x300)
- start = (start + 0x3ff) & ~0x3ff;
+
+ /*
+ * If we're avoiding ISA aliases, the largest contiguous I/O
+ * port space is 256 bytes. Clearing bits 9 and 10 preserves
+ * all 256-byte and smaller alignments, so the result will
+ * still be correctly aligned.
+ */
+ if (!skip_isa_ioresource_align(dev))
+ start &= ~0x300;
} else if (res->flags & IORESOURCE_MEM) {
if (start < BIOS_END)
- start = BIOS_END;
+ start = res->end; /* fail; no space */
}
return start;
}
@@ -311,6 +316,8 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
*/
prot |= _PAGE_CACHE_UC_MINUS;
+ prot |= _PAGE_IOMAP; /* creating a mapping for IO */
+
vma->vm_page_prot = __pgprot(prot);
if (io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index f547ee05f715..9f9bfb705cf9 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -584,27 +584,28 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route
case PCI_DEVICE_ID_INTEL_ICH9_3:
case PCI_DEVICE_ID_INTEL_ICH9_4:
case PCI_DEVICE_ID_INTEL_ICH9_5:
- case PCI_DEVICE_ID_INTEL_TOLAPAI_0:
+ case PCI_DEVICE_ID_INTEL_EP80579_0:
case PCI_DEVICE_ID_INTEL_ICH10_0:
case PCI_DEVICE_ID_INTEL_ICH10_1:
case PCI_DEVICE_ID_INTEL_ICH10_2:
case PCI_DEVICE_ID_INTEL_ICH10_3:
+ case PCI_DEVICE_ID_INTEL_PATSBURG_LPC:
r->name = "PIIX/ICH";
r->get = pirq_piix_get;
r->set = pirq_piix_set;
return 1;
}
- if ((device >= PCI_DEVICE_ID_INTEL_PCH_LPC_MIN) &&
- (device <= PCI_DEVICE_ID_INTEL_PCH_LPC_MAX)) {
+ if ((device >= PCI_DEVICE_ID_INTEL_5_3400_SERIES_LPC_MIN) &&
+ (device <= PCI_DEVICE_ID_INTEL_5_3400_SERIES_LPC_MAX)) {
r->name = "PIIX/ICH";
r->get = pirq_piix_get;
r->set = pirq_piix_set;
return 1;
}
- if ((device >= PCI_DEVICE_ID_INTEL_CPT_LPC_MIN) &&
- (device <= PCI_DEVICE_ID_INTEL_CPT_LPC_MAX)) {
+ if ((device >= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN) &&
+ (device <= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX)) {
r->name = "PIIX/ICH";
r->get = pirq_piix_get;
r->set = pirq_piix_set;
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index a918553ebc75..e282886616a0 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -65,7 +65,6 @@ static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start,
int end, u64 addr)
{
struct pci_mmcfg_region *new;
- int num_buses;
struct resource *res;
if (addr == 0)
@@ -82,10 +81,9 @@ static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start,
list_add_sorted(new);
- num_buses = end - start + 1;
res = &new->res;
res->start = addr + PCI_MMCFG_BUS_OFFSET(start);
- res->end = addr + PCI_MMCFG_BUS_OFFSET(num_buses) - 1;
+ res->end = addr + PCI_MMCFG_BUS_OFFSET(end + 1) - 1;
res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
snprintf(new->name, PCI_MMCFG_RESOURCE_NAME_LEN,
"PCI MMCONFIG %04x [bus %02x-%02x]", segment, start, end);
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/pci/xen.c b/arch/x86/pci/xen.c
new file mode 100644
index 000000000000..117f5b8daf75
--- /dev/null
+++ b/arch/x86/pci/xen.c
@@ -0,0 +1,414 @@
+/*
+ * Xen PCI Frontend Stub - puts some "dummy" functions in to the Linux
+ * x86 PCI core to support the Xen PCI Frontend
+ *
+ * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/acpi.h>
+
+#include <linux/io.h>
+#include <asm/io_apic.h>
+#include <asm/pci_x86.h>
+
+#include <asm/xen/hypervisor.h>
+
+#include <xen/features.h>
+#include <xen/events.h>
+#include <asm/xen/pci.h>
+
+#ifdef CONFIG_ACPI
+static int xen_hvm_register_pirq(u32 gsi, int triggering)
+{
+ int rc, irq;
+ struct physdev_map_pirq map_irq;
+ int shareable = 0;
+ char *name;
+
+ if (!xen_hvm_domain())
+ return -1;
+
+ map_irq.domid = DOMID_SELF;
+ map_irq.type = MAP_PIRQ_TYPE_GSI;
+ map_irq.index = gsi;
+ map_irq.pirq = -1;
+
+ rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq);
+ if (rc) {
+ printk(KERN_WARNING "xen map irq failed %d\n", rc);
+ return -1;
+ }
+
+ if (triggering == ACPI_EDGE_SENSITIVE) {
+ shareable = 0;
+ name = "ioapic-edge";
+ } else {
+ shareable = 1;
+ name = "ioapic-level";
+ }
+
+ irq = xen_map_pirq_gsi(map_irq.pirq, gsi, shareable, name);
+
+ printk(KERN_DEBUG "xen: --> irq=%d, pirq=%d\n", irq, map_irq.pirq);
+
+ return irq;
+}
+
+static int acpi_register_gsi_xen_hvm(struct device *dev, u32 gsi,
+ int trigger, int polarity)
+{
+ return xen_hvm_register_pirq(gsi, trigger);
+}
+#endif
+
+#if defined(CONFIG_PCI_MSI)
+#include <linux/msi.h>
+#include <asm/msidef.h>
+
+struct xen_pci_frontend_ops *xen_pci_frontend;
+EXPORT_SYMBOL_GPL(xen_pci_frontend);
+
+static void xen_msi_compose_msg(struct pci_dev *pdev, unsigned int pirq,
+ struct msi_msg *msg)
+{
+ /* We set vector == 0 to tell the hypervisor we don't care about it,
+ * but we want a pirq setup instead.
+ * We use the dest_id field to pass the pirq that we want. */
+ msg->address_hi = MSI_ADDR_BASE_HI | MSI_ADDR_EXT_DEST_ID(pirq);
+ msg->address_lo =
+ MSI_ADDR_BASE_LO |
+ MSI_ADDR_DEST_MODE_PHYSICAL |
+ MSI_ADDR_REDIRECTION_CPU |
+ MSI_ADDR_DEST_ID(pirq);
+
+ msg->data =
+ MSI_DATA_TRIGGER_EDGE |
+ MSI_DATA_LEVEL_ASSERT |
+ /* delivery mode reserved */
+ (3 << 8) |
+ MSI_DATA_VECTOR(0);
+}
+
+static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+{
+ int irq, pirq, ret = 0;
+ struct msi_desc *msidesc;
+ struct msi_msg msg;
+
+ list_for_each_entry(msidesc, &dev->msi_list, list) {
+ xen_allocate_pirq_msi((type == PCI_CAP_ID_MSIX) ?
+ "msi-x" : "msi", &irq, &pirq);
+ if (irq < 0 || pirq < 0)
+ goto error;
+ printk(KERN_DEBUG "xen: msi --> irq=%d, pirq=%d\n", irq, pirq);
+ xen_msi_compose_msg(dev, pirq, &msg);
+ ret = set_irq_msi(irq, msidesc);
+ if (ret < 0)
+ goto error_while;
+ write_msi_msg(irq, &msg);
+ }
+ return 0;
+
+error_while:
+ unbind_from_irqhandler(irq, NULL);
+error:
+ if (ret == -ENODEV)
+ dev_err(&dev->dev, "Xen PCI frontend has not registered" \
+ " MSI/MSI-X support!\n");
+
+ return ret;
+}
+
+/*
+ * For MSI interrupts we have to use drivers/xen/event.s functions to
+ * allocate an irq_desc and setup the right */
+
+
+static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+{
+ int irq, ret, i;
+ struct msi_desc *msidesc;
+ int *v;
+
+ v = kzalloc(sizeof(int) * max(1, nvec), GFP_KERNEL);
+ if (!v)
+ return -ENOMEM;
+
+ if (type == PCI_CAP_ID_MSIX)
+ ret = xen_pci_frontend_enable_msix(dev, &v, nvec);
+ else
+ ret = xen_pci_frontend_enable_msi(dev, &v);
+ if (ret)
+ goto error;
+ i = 0;
+ list_for_each_entry(msidesc, &dev->msi_list, list) {
+ irq = xen_allocate_pirq(v[i], 0, /* not sharable */
+ (type == PCI_CAP_ID_MSIX) ?
+ "pcifront-msi-x" : "pcifront-msi");
+ if (irq < 0)
+ return -1;
+
+ ret = set_irq_msi(irq, msidesc);
+ if (ret)
+ goto error_while;
+ i++;
+ }
+ kfree(v);
+ return 0;
+
+error_while:
+ unbind_from_irqhandler(irq, NULL);
+error:
+ if (ret == -ENODEV)
+ dev_err(&dev->dev, "Xen PCI frontend has not registered" \
+ " MSI/MSI-X support!\n");
+
+ kfree(v);
+ return ret;
+}
+
+static void xen_teardown_msi_irqs(struct pci_dev *dev)
+{
+ struct msi_desc *msidesc;
+
+ msidesc = list_entry(dev->msi_list.next, struct msi_desc, list);
+ if (msidesc->msi_attrib.is_msix)
+ xen_pci_frontend_disable_msix(dev);
+ else
+ xen_pci_frontend_disable_msi(dev);
+}
+
+static void xen_teardown_msi_irq(unsigned int irq)
+{
+ xen_destroy_irq(irq);
+}
+
+static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+{
+ int irq, ret;
+ struct msi_desc *msidesc;
+
+ list_for_each_entry(msidesc, &dev->msi_list, list) {
+ irq = xen_create_msi_irq(dev, msidesc, type);
+ if (irq < 0)
+ return -1;
+
+ ret = set_irq_msi(irq, msidesc);
+ if (ret)
+ goto error;
+ }
+ return 0;
+
+error:
+ xen_destroy_irq(irq);
+ return ret;
+}
+#endif
+
+static int xen_pcifront_enable_irq(struct pci_dev *dev)
+{
+ int rc;
+ int share = 1;
+
+ dev_info(&dev->dev, "Xen PCI enabling IRQ: %d\n", dev->irq);
+
+ if (dev->irq < 0)
+ return -EINVAL;
+
+ if (dev->irq < NR_IRQS_LEGACY)
+ share = 0;
+
+ rc = xen_allocate_pirq(dev->irq, share, "pcifront");
+ if (rc < 0) {
+ dev_warn(&dev->dev, "Xen PCI IRQ: %d, failed to register:%d\n",
+ dev->irq, rc);
+ return rc;
+ }
+ return 0;
+}
+
+int __init pci_xen_init(void)
+{
+ if (!xen_pv_domain() || xen_initial_domain())
+ return -ENODEV;
+
+ printk(KERN_INFO "PCI: setting up Xen PCI frontend stub\n");
+
+ pcibios_set_cache_line_size();
+
+ pcibios_enable_irq = xen_pcifront_enable_irq;
+ pcibios_disable_irq = NULL;
+
+#ifdef CONFIG_ACPI
+ /* Keep ACPI out of the picture */
+ acpi_noirq = 1;
+#endif
+
+#ifdef CONFIG_PCI_MSI
+ x86_msi.setup_msi_irqs = xen_setup_msi_irqs;
+ x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
+ x86_msi.teardown_msi_irqs = xen_teardown_msi_irqs;
+#endif
+ return 0;
+}
+
+int __init pci_xen_hvm_init(void)
+{
+ if (!xen_feature(XENFEAT_hvm_pirqs))
+ return 0;
+
+#ifdef CONFIG_ACPI
+ /*
+ * We don't want to change the actual ACPI delivery model,
+ * just how GSIs get registered.
+ */
+ __acpi_register_gsi = acpi_register_gsi_xen_hvm;
+#endif
+
+#ifdef CONFIG_PCI_MSI
+ x86_msi.setup_msi_irqs = xen_hvm_setup_msi_irqs;
+ x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
+#endif
+ return 0;
+}
+
+#ifdef CONFIG_XEN_DOM0
+static int xen_register_pirq(u32 gsi, int triggering)
+{
+ int rc, irq;
+ struct physdev_map_pirq map_irq;
+ int shareable = 0;
+ char *name;
+
+ if (!xen_pv_domain())
+ return -1;
+
+ if (triggering == ACPI_EDGE_SENSITIVE) {
+ shareable = 0;
+ name = "ioapic-edge";
+ } else {
+ shareable = 1;
+ name = "ioapic-level";
+ }
+
+ irq = xen_allocate_pirq(gsi, shareable, name);
+
+ printk(KERN_DEBUG "xen: --> irq=%d\n", irq);
+
+ if (irq < 0)
+ goto out;
+
+ map_irq.domid = DOMID_SELF;
+ map_irq.type = MAP_PIRQ_TYPE_GSI;
+ map_irq.index = gsi;
+ map_irq.pirq = irq;
+
+ rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq);
+ if (rc) {
+ printk(KERN_WARNING "xen map irq failed %d\n", rc);
+ return -1;
+ }
+
+out:
+ return irq;
+}
+
+static int xen_register_gsi(u32 gsi, int triggering, int polarity)
+{
+ int rc, irq;
+ struct physdev_setup_gsi setup_gsi;
+
+ if (!xen_pv_domain())
+ return -1;
+
+ printk(KERN_DEBUG "xen: registering gsi %u triggering %d polarity %d\n",
+ gsi, triggering, polarity);
+
+ irq = xen_register_pirq(gsi, triggering);
+
+ setup_gsi.gsi = gsi;
+ setup_gsi.triggering = (triggering == ACPI_EDGE_SENSITIVE ? 0 : 1);
+ setup_gsi.polarity = (polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
+
+ rc = HYPERVISOR_physdev_op(PHYSDEVOP_setup_gsi, &setup_gsi);
+ if (rc == -EEXIST)
+ printk(KERN_INFO "Already setup the GSI :%d\n", gsi);
+ else if (rc) {
+ printk(KERN_ERR "Failed to setup GSI :%d, err_code:%d\n",
+ gsi, rc);
+ }
+
+ return irq;
+}
+
+static __init void xen_setup_acpi_sci(void)
+{
+ int rc;
+ int trigger, polarity;
+ int gsi = acpi_sci_override_gsi;
+
+ if (!gsi)
+ return;
+
+ rc = acpi_get_override_irq(gsi, &trigger, &polarity);
+ if (rc) {
+ printk(KERN_WARNING "xen: acpi_get_override_irq failed for acpi"
+ " sci, rc=%d\n", rc);
+ return;
+ }
+ trigger = trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
+ polarity = polarity ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
+
+ printk(KERN_INFO "xen: sci override: global_irq=%d trigger=%d "
+ "polarity=%d\n", gsi, trigger, polarity);
+
+ gsi = xen_register_gsi(gsi, trigger, polarity);
+ printk(KERN_INFO "xen: acpi sci %d\n", gsi);
+
+ return;
+}
+
+static int acpi_register_gsi_xen(struct device *dev, u32 gsi,
+ int trigger, int polarity)
+{
+ return xen_register_gsi(gsi, trigger, polarity);
+}
+
+static int __init pci_xen_initial_domain(void)
+{
+#ifdef CONFIG_PCI_MSI
+ x86_msi.setup_msi_irqs = xen_initdom_setup_msi_irqs;
+ x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
+#endif
+ xen_setup_acpi_sci();
+ __acpi_register_gsi = acpi_register_gsi_xen;
+
+ return 0;
+}
+
+void __init xen_setup_pirqs(void)
+{
+ int irq;
+
+ pci_xen_initial_domain();
+
+ if (0 == nr_ioapics) {
+ for (irq = 0; irq < NR_IRQS_LEGACY; irq++)
+ xen_allocate_pirq(irq, 0, "xt-pic");
+ return;
+ }
+
+ /* Pre-allocate legacy irqs */
+ for (irq = 0; irq < NR_IRQS_LEGACY; irq++) {
+ int trigger, polarity;
+
+ if (acpi_get_override_irq(irq, &trigger, &polarity) == -1)
+ continue;
+
+ xen_register_pirq(irq,
+ trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE);
+ }
+}
+#endif
diff --git a/arch/x86/platform/Makefile b/arch/x86/platform/Makefile
new file mode 100644
index 000000000000..7bf70b812fa2
--- /dev/null
+++ b/arch/x86/platform/Makefile
@@ -0,0 +1,8 @@
+# Platform specific code goes here
+obj-y += efi/
+obj-y += mrst/
+obj-y += olpc/
+obj-y += scx200/
+obj-y += sfi/
+obj-y += visws/
+obj-y += uv/
diff --git a/arch/x86/platform/efi/Makefile b/arch/x86/platform/efi/Makefile
new file mode 100644
index 000000000000..73b8be0f3675
--- /dev/null
+++ b/arch/x86/platform/efi/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_EFI) += efi.o efi_$(BITS).o efi_stub_$(BITS).o
diff --git a/arch/x86/kernel/efi.c b/arch/x86/platform/efi/efi.c
index c2fa9b8b497e..0fe27d7c6258 100644
--- a/arch/x86/kernel/efi.c
+++ b/arch/x86/platform/efi/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/efi_32.c b/arch/x86/platform/efi/efi_32.c
index 5cab48ee61a4..5cab48ee61a4 100644
--- a/arch/x86/kernel/efi_32.c
+++ b/arch/x86/platform/efi/efi_32.c
diff --git a/arch/x86/kernel/efi_64.c b/arch/x86/platform/efi/efi_64.c
index ac0621a7ac3d..ac0621a7ac3d 100644
--- a/arch/x86/kernel/efi_64.c
+++ b/arch/x86/platform/efi/efi_64.c
diff --git a/arch/x86/kernel/efi_stub_32.S b/arch/x86/platform/efi/efi_stub_32.S
index fbe66e626c09..fbe66e626c09 100644
--- a/arch/x86/kernel/efi_stub_32.S
+++ b/arch/x86/platform/efi/efi_stub_32.S
diff --git a/arch/x86/kernel/efi_stub_64.S b/arch/x86/platform/efi/efi_stub_64.S
index 4c07ccab8146..4c07ccab8146 100644
--- a/arch/x86/kernel/efi_stub_64.S
+++ b/arch/x86/platform/efi/efi_stub_64.S
diff --git a/arch/x86/platform/mrst/Makefile b/arch/x86/platform/mrst/Makefile
new file mode 100644
index 000000000000..efbbc552fa95
--- /dev/null
+++ b/arch/x86/platform/mrst/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_X86_MRST) += mrst.o
diff --git a/arch/x86/kernel/mrst.c b/arch/x86/platform/mrst/mrst.c
index 79ae68154e87..79ae68154e87 100644
--- a/arch/x86/kernel/mrst.c
+++ b/arch/x86/platform/mrst/mrst.c
diff --git a/arch/x86/platform/olpc/Makefile b/arch/x86/platform/olpc/Makefile
new file mode 100644
index 000000000000..c31b8fcb5a86
--- /dev/null
+++ b/arch/x86/platform/olpc/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_OLPC) += olpc.o
+obj-$(CONFIG_OLPC_XO1) += olpc-xo1.o
+obj-$(CONFIG_OLPC_OPENFIRMWARE) += olpc_ofw.o
diff --git a/arch/x86/platform/olpc/olpc-xo1.c b/arch/x86/platform/olpc/olpc-xo1.c
new file mode 100644
index 000000000000..f5442c03abc3
--- /dev/null
+++ b/arch/x86/platform/olpc/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/platform/olpc/olpc.c
index 0e0cdde519be..edaf3fe8dc5e 100644
--- a/arch/x86/kernel/olpc.c
+++ b/arch/x86/platform/olpc/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/platform/olpc/olpc_ofw.c
index 3218aa71ab5e..787320464379 100644
--- a/arch/x86/kernel/olpc_ofw.c
+++ b/arch/x86/platform/olpc/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/platform/scx200/Makefile b/arch/x86/platform/scx200/Makefile
new file mode 100644
index 000000000000..762b4c7f4314
--- /dev/null
+++ b/arch/x86/platform/scx200/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_SCx200) += scx200.o
+scx200-y += scx200_32.o
diff --git a/arch/x86/kernel/scx200_32.c b/arch/x86/platform/scx200/scx200_32.c
index 7e004acbe526..7e004acbe526 100644
--- a/arch/x86/kernel/scx200_32.c
+++ b/arch/x86/platform/scx200/scx200_32.c
diff --git a/arch/x86/platform/sfi/Makefile b/arch/x86/platform/sfi/Makefile
new file mode 100644
index 000000000000..cc5db1168a5e
--- /dev/null
+++ b/arch/x86/platform/sfi/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_SFI) += sfi.o
diff --git a/arch/x86/kernel/sfi.c b/arch/x86/platform/sfi/sfi.c
index cb22acf3ed09..dd4c281ffe57 100644
--- a/arch/x86/kernel/sfi.c
+++ b/arch/x86/platform/sfi/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/platform/uv/Makefile b/arch/x86/platform/uv/Makefile
new file mode 100644
index 000000000000..6c40995fefb8
--- /dev/null
+++ b/arch/x86/platform/uv/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_X86_UV) += tlb_uv.o bios_uv.o uv_irq.o uv_sysfs.o uv_time.o
diff --git a/arch/x86/kernel/bios_uv.c b/arch/x86/platform/uv/bios_uv.c
index 8bc57baaa9ad..8bc57baaa9ad 100644
--- a/arch/x86/kernel/bios_uv.c
+++ b/arch/x86/platform/uv/bios_uv.c
diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c
index 312ef0292815..20ea20a39e2a 100644
--- a/arch/x86/kernel/tlb_uv.c
+++ b/arch/x86/platform/uv/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/uv_irq.c b/arch/x86/platform/uv/uv_irq.c
index 1132129db792..7b24460917d5 100644
--- a/arch/x86/kernel/uv_irq.c
+++ b/arch/x86/platform/uv/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/uv_sysfs.c b/arch/x86/platform/uv/uv_sysfs.c
index 309c70fb7759..309c70fb7759 100644
--- a/arch/x86/kernel/uv_sysfs.c
+++ b/arch/x86/platform/uv/uv_sysfs.c
diff --git a/arch/x86/kernel/uv_time.c b/arch/x86/platform/uv/uv_time.c
index 56e421bc379b..56e421bc379b 100644
--- a/arch/x86/kernel/uv_time.c
+++ b/arch/x86/platform/uv/uv_time.c
diff --git a/arch/x86/platform/visws/Makefile b/arch/x86/platform/visws/Makefile
new file mode 100644
index 000000000000..91bc17ab2fd5
--- /dev/null
+++ b/arch/x86/platform/visws/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_X86_VISWS) += visws_quirks.o
diff --git a/arch/x86/kernel/visws_quirks.c b/arch/x86/platform/visws/visws_quirks.c
index e680ea52db9b..3371bd053b89 100644
--- a/arch/x86/kernel/visws_quirks.c
+++ b/arch/x86/platform/visws/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/xen/Kconfig b/arch/x86/xen/Kconfig
index 68128a1b401a..5b54892e4bc3 100644
--- a/arch/x86/xen/Kconfig
+++ b/arch/x86/xen/Kconfig
@@ -13,21 +13,28 @@ config XEN
kernel to boot in a paravirtualized environment under the
Xen hypervisor.
+config XEN_DOM0
+ def_bool y
+ depends on XEN && PCI_XEN && SWIOTLB_XEN
+ depends on X86_LOCAL_APIC && X86_IO_APIC && ACPI && PCI
+
+# Dummy symbol since people have come to rely on the PRIVILEGED_GUEST
+# name in tools.
+config XEN_PRIVILEGED_GUEST
+ def_bool XEN_DOM0
+
config XEN_PVHVM
def_bool y
depends on XEN
depends on X86_LOCAL_APIC
config XEN_MAX_DOMAIN_MEMORY
- int "Maximum allowed size of a domain in gigabytes"
- default 8 if X86_32
- default 32 if X86_64
+ int
+ default 128
depends on XEN
help
- The pseudo-physical to machine address array is sized
- according to the maximum possible memory size of a Xen
- domain. This array uses 1 page per gigabyte, so there's no
- need to be too stingy here.
+ This only affects the sizing of some bss arrays, the unused
+ portions of which are freed.
config XEN_SAVE_RESTORE
bool
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..235c0f4d3861 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>
@@ -45,6 +46,7 @@
#include <asm/paravirt.h>
#include <asm/apic.h>
#include <asm/page.h>
+#include <asm/xen/pci.h>
#include <asm/xen/hypercall.h>
#include <asm/xen/hypervisor.h>
#include <asm/fixmap.h>
@@ -58,7 +60,6 @@
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
#include <asm/reboot.h>
-#include <asm/setup.h>
#include <asm/stackprotector.h>
#include <asm/hypervisor.h>
@@ -135,9 +136,6 @@ static void xen_vcpu_setup(int cpu)
info.mfn = arbitrary_virt_to_mfn(vcpup);
info.offset = offset_in_page(vcpup);
- printk(KERN_DEBUG "trying to map vcpu_info %d at %p, mfn %llx, offset %d\n",
- cpu, vcpup, info.mfn, info.offset);
-
/* Check to see if the hypervisor will put the vcpu_info
structure where we want it, which allows direct access via
a percpu-variable. */
@@ -151,9 +149,6 @@ static void xen_vcpu_setup(int cpu)
/* This cpu is using the registered vcpu info, even if
later ones fail to. */
per_cpu(xen_vcpu, cpu) = vcpup;
-
- printk(KERN_DEBUG "cpu %d using vcpu_info at %p\n",
- cpu, vcpup);
}
}
@@ -242,6 +237,7 @@ static __init void xen_init_cpuid_mask(void)
cpuid_leaf1_edx_mask =
~((1 << X86_FEATURE_MCE) | /* disable MCE */
(1 << X86_FEATURE_MCA) | /* disable MCA */
+ (1 << X86_FEATURE_MTRR) | /* disable MTRR */
(1 << X86_FEATURE_ACC)); /* thermal monitoring */
if (!xen_initial_domain())
@@ -835,6 +831,11 @@ static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high)
Xen console noise. */
break;
+ case MSR_IA32_CR_PAT:
+ if (smp_processor_id() == 0)
+ xen_set_pat(((u64)high << 32) | low);
+ break;
+
default:
ret = native_write_msr_safe(msr, low, high);
}
@@ -873,8 +874,6 @@ void xen_setup_vcpu_info_placement(void)
/* xen_vcpu_setup managed to place the vcpu_info within the
percpu area for all cpus, so make use of it */
if (have_vcpu_info_placement) {
- printk(KERN_INFO "Xen: using vcpu_info placement\n");
-
pv_irq_ops.save_fl = __PV_IS_CALLEE_SAVE(xen_save_fl_direct);
pv_irq_ops.restore_fl = __PV_IS_CALLEE_SAVE(xen_restore_fl_direct);
pv_irq_ops.irq_disable = __PV_IS_CALLEE_SAVE(xen_irq_disable_direct);
@@ -1018,7 +1017,7 @@ static void xen_reboot(int reason)
struct sched_shutdown r = { .reason = reason };
#ifdef CONFIG_SMP
- smp_send_stop();
+ stop_other_cpus();
#endif
if (HYPERVISOR_sched_op(SCHEDOP_shutdown, &r))
@@ -1183,8 +1182,14 @@ 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);
+ xen_ident_map_ISA();
+
+ /* Allocate and initialize top and mid mfn levels for p2m structure */
+ xen_build_mfn_list_list();
init_mm.pgd = pgd;
@@ -1220,6 +1225,8 @@ asmlinkage void __init xen_start_kernel(void)
add_preferred_console("xenboot", 0, NULL);
add_preferred_console("tty", 0, NULL);
add_preferred_console("hvc", 0, NULL);
+ if (pci_xen)
+ x86_init.pci.arch_init = pci_xen_init;
} else {
/* Make sure ACS will be enabled */
pci_request_acs();
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 42086ac406af..c237b810b03f 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,8 @@
#include <asm/e820.h>
#include <asm/linkage.h>
#include <asm/page.h>
+#include <asm/init.h>
+#include <asm/pat.h>
#include <asm/xen/hypercall.h>
#include <asm/xen/hypervisor.h>
@@ -138,7 +141,8 @@ static inline void check_zero(void)
* large enough to allocate page table pages to allocate the rest.
* Each page can map 2MB.
*/
-static pte_t level1_ident_pgt[PTRS_PER_PTE * 4] __page_aligned_bss;
+#define LEVEL1_IDENT_ENTRIES (PTRS_PER_PTE * 4)
+static RESERVE_BRK_ARRAY(pte_t, level1_ident_pgt, LEVEL1_IDENT_ENTRIES);
#ifdef CONFIG_X86_64
/* l3 pud for userspace vsyscall mapping */
@@ -169,49 +173,182 @@ DEFINE_PER_CPU(unsigned long, xen_current_cr3); /* actual vcpu cr3 */
*/
#define USER_LIMIT ((STACK_TOP_MAX + PGDIR_SIZE - 1) & PGDIR_MASK)
+/*
+ * Xen leaves the responsibility for maintaining p2m mappings to the
+ * guests themselves, but it must also access and update the p2m array
+ * during suspend/resume when all the pages are reallocated.
+ *
+ * The p2m table is logically a flat array, but we implement it as a
+ * three-level tree to allow the address space to be sparse.
+ *
+ * Xen
+ * |
+ * p2m_top p2m_top_mfn
+ * / \ / \
+ * p2m_mid p2m_mid p2m_mid_mfn p2m_mid_mfn
+ * / \ / \ / /
+ * p2m p2m p2m p2m p2m p2m p2m ...
+ *
+ * The p2m_mid_mfn pages are mapped by p2m_top_mfn_p.
+ *
+ * The p2m_top and p2m_top_mfn levels are limited to 1 page, so the
+ * maximum representable pseudo-physical address space is:
+ * P2M_TOP_PER_PAGE * P2M_MID_PER_PAGE * P2M_PER_PAGE pages
+ *
+ * P2M_PER_PAGE depends on the architecture, as a mfn is always
+ * unsigned long (8 bytes on 64-bit, 4 bytes on 32), leading to
+ * 512 and 1024 entries respectively.
+ */
-#define P2M_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(unsigned long))
-#define TOP_ENTRIES (MAX_DOMAIN_PAGES / P2M_ENTRIES_PER_PAGE)
+unsigned long xen_max_p2m_pfn __read_mostly;
-/* Placeholder for holes in the address space */
-static unsigned long p2m_missing[P2M_ENTRIES_PER_PAGE] __page_aligned_data =
- { [ 0 ... P2M_ENTRIES_PER_PAGE-1 ] = ~0UL };
+#define P2M_PER_PAGE (PAGE_SIZE / sizeof(unsigned long))
+#define P2M_MID_PER_PAGE (PAGE_SIZE / sizeof(unsigned long *))
+#define P2M_TOP_PER_PAGE (PAGE_SIZE / sizeof(unsigned long **))
- /* Array of pointers to pages containing p2m entries */
-static unsigned long *p2m_top[TOP_ENTRIES] __page_aligned_data =
- { [ 0 ... TOP_ENTRIES - 1] = &p2m_missing[0] };
+#define MAX_P2M_PFN (P2M_TOP_PER_PAGE * P2M_MID_PER_PAGE * P2M_PER_PAGE)
-/* Arrays of p2m arrays expressed in mfns used for save/restore */
-static unsigned long p2m_top_mfn[TOP_ENTRIES] __page_aligned_bss;
+/* Placeholders for holes in the address space */
+static RESERVE_BRK_ARRAY(unsigned long, p2m_missing, P2M_PER_PAGE);
+static RESERVE_BRK_ARRAY(unsigned long *, p2m_mid_missing, P2M_MID_PER_PAGE);
+static RESERVE_BRK_ARRAY(unsigned long, p2m_mid_missing_mfn, P2M_MID_PER_PAGE);
-static unsigned long p2m_top_mfn_list[TOP_ENTRIES / P2M_ENTRIES_PER_PAGE]
- __page_aligned_bss;
+static RESERVE_BRK_ARRAY(unsigned long **, p2m_top, P2M_TOP_PER_PAGE);
+static RESERVE_BRK_ARRAY(unsigned long, p2m_top_mfn, P2M_TOP_PER_PAGE);
+static RESERVE_BRK_ARRAY(unsigned long *, p2m_top_mfn_p, P2M_TOP_PER_PAGE);
+
+RESERVE_BRK(p2m_mid, PAGE_SIZE * (MAX_DOMAIN_PAGES / (P2M_PER_PAGE * P2M_MID_PER_PAGE)));
+RESERVE_BRK(p2m_mid_mfn, PAGE_SIZE * (MAX_DOMAIN_PAGES / (P2M_PER_PAGE * P2M_MID_PER_PAGE)));
static inline unsigned p2m_top_index(unsigned long pfn)
{
- BUG_ON(pfn >= MAX_DOMAIN_PAGES);
- return pfn / P2M_ENTRIES_PER_PAGE;
+ BUG_ON(pfn >= MAX_P2M_PFN);
+ return pfn / (P2M_MID_PER_PAGE * P2M_PER_PAGE);
+}
+
+static inline unsigned p2m_mid_index(unsigned long pfn)
+{
+ return (pfn / P2M_PER_PAGE) % P2M_MID_PER_PAGE;
}
static inline unsigned p2m_index(unsigned long pfn)
{
- return pfn % P2M_ENTRIES_PER_PAGE;
+ return pfn % P2M_PER_PAGE;
+}
+
+static void p2m_top_init(unsigned long ***top)
+{
+ unsigned i;
+
+ for (i = 0; i < P2M_TOP_PER_PAGE; i++)
+ top[i] = p2m_mid_missing;
+}
+
+static void p2m_top_mfn_init(unsigned long *top)
+{
+ unsigned i;
+
+ for (i = 0; i < P2M_TOP_PER_PAGE; i++)
+ top[i] = virt_to_mfn(p2m_mid_missing_mfn);
+}
+
+static void p2m_top_mfn_p_init(unsigned long **top)
+{
+ unsigned i;
+
+ for (i = 0; i < P2M_TOP_PER_PAGE; i++)
+ top[i] = p2m_mid_missing_mfn;
+}
+
+static void p2m_mid_init(unsigned long **mid)
+{
+ unsigned i;
+
+ for (i = 0; i < P2M_MID_PER_PAGE; i++)
+ mid[i] = p2m_missing;
}
-/* Build the parallel p2m_top_mfn structures */
+static void p2m_mid_mfn_init(unsigned long *mid)
+{
+ unsigned i;
+
+ for (i = 0; i < P2M_MID_PER_PAGE; i++)
+ mid[i] = virt_to_mfn(p2m_missing);
+}
+
+static void p2m_init(unsigned long *p2m)
+{
+ unsigned i;
+
+ for (i = 0; i < P2M_MID_PER_PAGE; i++)
+ p2m[i] = INVALID_P2M_ENTRY;
+}
+
+/*
+ * Build the parallel p2m_top_mfn and p2m_mid_mfn structures
+ *
+ * This is called both at boot time, and after resuming from suspend:
+ * - At boot time we're called very early, and must use extend_brk()
+ * to allocate memory.
+ *
+ * - After resume we're called from within stop_machine, but the mfn
+ * tree should alreay be completely allocated.
+ */
void xen_build_mfn_list_list(void)
{
- unsigned pfn, idx;
+ unsigned long pfn;
- for (pfn = 0; pfn < MAX_DOMAIN_PAGES; pfn += P2M_ENTRIES_PER_PAGE) {
- unsigned topidx = p2m_top_index(pfn);
+ /* Pre-initialize p2m_top_mfn to be completely missing */
+ if (p2m_top_mfn == NULL) {
+ p2m_mid_missing_mfn = extend_brk(PAGE_SIZE, PAGE_SIZE);
+ p2m_mid_mfn_init(p2m_mid_missing_mfn);
- p2m_top_mfn[topidx] = virt_to_mfn(p2m_top[topidx]);
+ p2m_top_mfn_p = extend_brk(PAGE_SIZE, PAGE_SIZE);
+ p2m_top_mfn_p_init(p2m_top_mfn_p);
+
+ p2m_top_mfn = extend_brk(PAGE_SIZE, PAGE_SIZE);
+ p2m_top_mfn_init(p2m_top_mfn);
+ } else {
+ /* Reinitialise, mfn's all change after migration */
+ p2m_mid_mfn_init(p2m_mid_missing_mfn);
}
- for (idx = 0; idx < ARRAY_SIZE(p2m_top_mfn_list); idx++) {
- unsigned topidx = idx * P2M_ENTRIES_PER_PAGE;
- p2m_top_mfn_list[idx] = virt_to_mfn(&p2m_top_mfn[topidx]);
+ for (pfn = 0; pfn < xen_max_p2m_pfn; pfn += P2M_PER_PAGE) {
+ unsigned topidx = p2m_top_index(pfn);
+ unsigned mididx = p2m_mid_index(pfn);
+ unsigned long **mid;
+ unsigned long *mid_mfn_p;
+
+ mid = p2m_top[topidx];
+ mid_mfn_p = p2m_top_mfn_p[topidx];
+
+ /* Don't bother allocating any mfn mid levels if
+ * they're just missing, just update the stored mfn,
+ * since all could have changed over a migrate.
+ */
+ if (mid == p2m_mid_missing) {
+ BUG_ON(mididx);
+ BUG_ON(mid_mfn_p != p2m_mid_missing_mfn);
+ p2m_top_mfn[topidx] = virt_to_mfn(p2m_mid_missing_mfn);
+ pfn += (P2M_MID_PER_PAGE - 1) * P2M_PER_PAGE;
+ continue;
+ }
+
+ if (mid_mfn_p == p2m_mid_missing_mfn) {
+ /*
+ * XXX boot-time only! We should never find
+ * missing parts of the mfn tree after
+ * runtime. extend_brk() will BUG if we call
+ * it too late.
+ */
+ mid_mfn_p = extend_brk(PAGE_SIZE, PAGE_SIZE);
+ p2m_mid_mfn_init(mid_mfn_p);
+
+ p2m_top_mfn_p[topidx] = mid_mfn_p;
+ }
+
+ p2m_top_mfn[topidx] = virt_to_mfn(mid_mfn_p);
+ mid_mfn_p[mididx] = virt_to_mfn(mid[mididx]);
}
}
@@ -220,8 +357,8 @@ void xen_setup_mfn_list_list(void)
BUG_ON(HYPERVISOR_shared_info == &xen_dummy_shared_info);
HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
- virt_to_mfn(p2m_top_mfn_list);
- HYPERVISOR_shared_info->arch.max_pfn = xen_start_info->nr_pages;
+ virt_to_mfn(p2m_top_mfn);
+ HYPERVISOR_shared_info->arch.max_pfn = xen_max_p2m_pfn;
}
/* Set up p2m_top to point to the domain-builder provided p2m pages */
@@ -229,98 +366,176 @@ void __init xen_build_dynamic_phys_to_machine(void)
{
unsigned long *mfn_list = (unsigned long *)xen_start_info->mfn_list;
unsigned long max_pfn = min(MAX_DOMAIN_PAGES, xen_start_info->nr_pages);
- unsigned pfn;
+ unsigned long pfn;
+
+ xen_max_p2m_pfn = max_pfn;
+
+ p2m_missing = extend_brk(PAGE_SIZE, PAGE_SIZE);
+ p2m_init(p2m_missing);
+
+ p2m_mid_missing = extend_brk(PAGE_SIZE, PAGE_SIZE);
+ p2m_mid_init(p2m_mid_missing);
+
+ p2m_top = extend_brk(PAGE_SIZE, PAGE_SIZE);
+ p2m_top_init(p2m_top);
- for (pfn = 0; pfn < max_pfn; pfn += P2M_ENTRIES_PER_PAGE) {
+ /*
+ * The domain builder gives us a pre-constructed p2m array in
+ * mfn_list for all the pages initially given to us, so we just
+ * need to graft that into our tree structure.
+ */
+ for (pfn = 0; pfn < max_pfn; pfn += P2M_PER_PAGE) {
unsigned topidx = p2m_top_index(pfn);
+ unsigned mididx = p2m_mid_index(pfn);
- p2m_top[topidx] = &mfn_list[pfn];
- }
+ if (p2m_top[topidx] == p2m_mid_missing) {
+ unsigned long **mid = extend_brk(PAGE_SIZE, PAGE_SIZE);
+ p2m_mid_init(mid);
- xen_build_mfn_list_list();
+ p2m_top[topidx] = mid;
+ }
+
+ p2m_top[topidx][mididx] = &mfn_list[pfn];
+ }
}
unsigned long get_phys_to_machine(unsigned long pfn)
{
- unsigned topidx, idx;
+ unsigned topidx, mididx, idx;
- if (unlikely(pfn >= MAX_DOMAIN_PAGES))
+ if (unlikely(pfn >= MAX_P2M_PFN))
return INVALID_P2M_ENTRY;
topidx = p2m_top_index(pfn);
+ mididx = p2m_mid_index(pfn);
idx = p2m_index(pfn);
- return p2m_top[topidx][idx];
+
+ return p2m_top[topidx][mididx][idx];
}
EXPORT_SYMBOL_GPL(get_phys_to_machine);
-/* install a new p2m_top page */
-bool install_p2mtop_page(unsigned long pfn, unsigned long *p)
+static void *alloc_p2m_page(void)
{
- unsigned topidx = p2m_top_index(pfn);
- unsigned long **pfnp, *mfnp;
- unsigned i;
+ return (void *)__get_free_page(GFP_KERNEL | __GFP_REPEAT);
+}
+
+static void free_p2m_page(void *p)
+{
+ free_page((unsigned long)p);
+}
- pfnp = &p2m_top[topidx];
- mfnp = &p2m_top_mfn[topidx];
+/*
+ * Fully allocate the p2m structure for a given pfn. We need to check
+ * that both the top and mid levels are allocated, and make sure the
+ * parallel mfn tree is kept in sync. We may race with other cpus, so
+ * the new pages are installed with cmpxchg; if we lose the race then
+ * simply free the page we allocated and use the one that's there.
+ */
+static bool alloc_p2m(unsigned long pfn)
+{
+ unsigned topidx, mididx;
+ unsigned long ***top_p, **mid;
+ unsigned long *top_mfn_p, *mid_mfn;
- for (i = 0; i < P2M_ENTRIES_PER_PAGE; i++)
- p[i] = INVALID_P2M_ENTRY;
+ topidx = p2m_top_index(pfn);
+ mididx = p2m_mid_index(pfn);
- if (cmpxchg(pfnp, p2m_missing, p) == p2m_missing) {
- *mfnp = virt_to_mfn(p);
- return true;
+ top_p = &p2m_top[topidx];
+ mid = *top_p;
+
+ if (mid == p2m_mid_missing) {
+ /* Mid level is missing, allocate a new one */
+ mid = alloc_p2m_page();
+ if (!mid)
+ return false;
+
+ p2m_mid_init(mid);
+
+ if (cmpxchg(top_p, p2m_mid_missing, mid) != p2m_mid_missing)
+ free_p2m_page(mid);
}
- return false;
-}
+ top_mfn_p = &p2m_top_mfn[topidx];
+ mid_mfn = p2m_top_mfn_p[topidx];
-static void alloc_p2m(unsigned long pfn)
-{
- unsigned long *p;
+ BUG_ON(virt_to_mfn(mid_mfn) != *top_mfn_p);
+
+ if (mid_mfn == p2m_mid_missing_mfn) {
+ /* Separately check the mid mfn level */
+ unsigned long missing_mfn;
+ unsigned long mid_mfn_mfn;
- p = (void *)__get_free_page(GFP_KERNEL | __GFP_NOFAIL);
- BUG_ON(p == NULL);
+ mid_mfn = alloc_p2m_page();
+ if (!mid_mfn)
+ return false;
- if (!install_p2mtop_page(pfn, p))
- free_page((unsigned long)p);
+ p2m_mid_mfn_init(mid_mfn);
+
+ missing_mfn = virt_to_mfn(p2m_mid_missing_mfn);
+ mid_mfn_mfn = virt_to_mfn(mid_mfn);
+ if (cmpxchg(top_mfn_p, missing_mfn, mid_mfn_mfn) != missing_mfn)
+ free_p2m_page(mid_mfn);
+ else
+ p2m_top_mfn_p[topidx] = mid_mfn;
+ }
+
+ if (p2m_top[topidx][mididx] == p2m_missing) {
+ /* p2m leaf page is missing */
+ unsigned long *p2m;
+
+ p2m = alloc_p2m_page();
+ if (!p2m)
+ return false;
+
+ p2m_init(p2m);
+
+ if (cmpxchg(&mid[mididx], p2m_missing, p2m) != p2m_missing)
+ free_p2m_page(p2m);
+ else
+ mid_mfn[mididx] = virt_to_mfn(p2m);
+ }
+
+ return true;
}
/* Try to install p2m mapping; fail if intermediate bits missing */
bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn)
{
- unsigned topidx, idx;
+ unsigned topidx, mididx, idx;
- if (unlikely(pfn >= MAX_DOMAIN_PAGES)) {
+ if (unlikely(pfn >= MAX_P2M_PFN)) {
BUG_ON(mfn != INVALID_P2M_ENTRY);
return true;
}
topidx = p2m_top_index(pfn);
- if (p2m_top[topidx] == p2m_missing) {
- if (mfn == INVALID_P2M_ENTRY)
- return true;
- return false;
- }
-
+ mididx = p2m_mid_index(pfn);
idx = p2m_index(pfn);
- p2m_top[topidx][idx] = mfn;
+
+ if (p2m_top[topidx][mididx] == p2m_missing)
+ return mfn == INVALID_P2M_ENTRY;
+
+ p2m_top[topidx][mididx][idx] = mfn;
return true;
}
-void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
+bool set_phys_to_machine(unsigned long pfn, unsigned long mfn)
{
if (unlikely(xen_feature(XENFEAT_auto_translated_physmap))) {
BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY);
- return;
+ return true;
}
if (unlikely(!__set_phys_to_machine(pfn, mfn))) {
- alloc_p2m(pfn);
+ if (!alloc_p2m(pfn))
+ return false;
if (!__set_phys_to_machine(pfn, mfn))
- BUG();
+ return false;
}
+
+ return true;
}
unsigned long arbitrary_virt_to_mfn(void *vaddr)
@@ -359,7 +574,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 +590,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);
@@ -395,7 +612,7 @@ static bool xen_iomap_pte(pte_t pte)
return pte_flags(pte) & _PAGE_IOMAP;
}
-static void xen_set_iomap_pte(pte_t *ptep, pte_t pteval)
+void xen_set_domain_pte(pte_t *ptep, pte_t pteval, unsigned domid)
{
struct multicall_space mcs;
struct mmu_update *u;
@@ -407,10 +624,16 @@ static void xen_set_iomap_pte(pte_t *ptep, pte_t pteval)
u->ptr = arbitrary_virt_to_machine(ptep).maddr;
u->val = pte_val_ma(pteval);
- MULTI_mmu_update(mcs.mc, mcs.args, 1, NULL, DOMID_IO);
+ MULTI_mmu_update(mcs.mc, mcs.args, 1, NULL, domid);
xen_mc_issue(PARAVIRT_LAZY_MMU);
}
+EXPORT_SYMBOL_GPL(xen_set_domain_pte);
+
+static void xen_set_iomap_pte(pte_t *ptep, pte_t pteval)
+{
+ xen_set_domain_pte(ptep, pteval, DOMID_IO);
+}
static void xen_extend_mmu_update(const struct mmu_update *update)
{
@@ -557,7 +780,20 @@ static pteval_t pte_pfn_to_mfn(pteval_t val)
if (val & _PAGE_PRESENT) {
unsigned long pfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT;
pteval_t flags = val & PTE_FLAGS_MASK;
- val = ((pteval_t)pfn_to_mfn(pfn) << PAGE_SHIFT) | flags;
+ unsigned long mfn = pfn_to_mfn(pfn);
+
+ /*
+ * If there's no mfn for the pfn, then just create an
+ * empty non-present pte. Unfortunately this loses
+ * information about the original pfn, so
+ * pte_mfn_to_pfn is asymmetric.
+ */
+ if (unlikely(mfn == INVALID_P2M_ENTRY)) {
+ mfn = 0;
+ flags = 0;
+ }
+
+ val = ((pteval_t)mfn << PAGE_SHIFT) | flags;
}
return val;
@@ -579,10 +815,18 @@ static pteval_t iomap_pte(pteval_t val)
pteval_t xen_pte_val(pte_t pte)
{
- if (xen_initial_domain() && (pte.pte & _PAGE_IOMAP))
- return pte.pte;
+ pteval_t pteval = pte.pte;
+
+ /* If this is a WC pte, convert back from Xen WC to Linux WC */
+ if ((pteval & (_PAGE_PAT | _PAGE_PCD | _PAGE_PWT)) == _PAGE_PAT) {
+ WARN_ON(!pat_enabled);
+ pteval = (pteval & ~_PAGE_PAT) | _PAGE_PWT;
+ }
+
+ if (xen_initial_domain() && (pteval & _PAGE_IOMAP))
+ return pteval;
- return pte_mfn_to_pfn(pte.pte);
+ return pte_mfn_to_pfn(pteval);
}
PV_CALLEE_SAVE_REGS_THUNK(xen_pte_val);
@@ -592,10 +836,48 @@ pgdval_t xen_pgd_val(pgd_t pgd)
}
PV_CALLEE_SAVE_REGS_THUNK(xen_pgd_val);
+/*
+ * Xen's PAT setup is part of its ABI, though I assume entries 6 & 7
+ * are reserved for now, to correspond to the Intel-reserved PAT
+ * types.
+ *
+ * We expect Linux's PAT set as follows:
+ *
+ * Idx PTE flags Linux Xen Default
+ * 0 WB WB WB
+ * 1 PWT WC WT WT
+ * 2 PCD UC- UC- UC-
+ * 3 PCD PWT UC UC UC
+ * 4 PAT WB WC WB
+ * 5 PAT PWT WC WP WT
+ * 6 PAT PCD UC- UC UC-
+ * 7 PAT PCD PWT UC UC UC
+ */
+
+void xen_set_pat(u64 pat)
+{
+ /* We expect Linux to use a PAT setting of
+ * UC UC- WC WB (ignoring the PAT flag) */
+ WARN_ON(pat != 0x0007010600070106ull);
+}
+
pte_t xen_make_pte(pteval_t pte)
{
phys_addr_t addr = (pte & PTE_PFN_MASK);
+ /* If Linux is trying to set a WC pte, then map to the Xen WC.
+ * If _PAGE_PAT is set, then it probably means it is really
+ * _PAGE_PSE, so avoid fiddling with the PAT mapping and hope
+ * things work out OK...
+ *
+ * (We should never see kernel mappings with _PAGE_PSE set,
+ * but we could see hugetlbfs mappings, I think.).
+ */
+ if (pat_enabled && !WARN_ON(pte & _PAGE_PAT)) {
+ if ((pte & (_PAGE_PCD | _PAGE_PWT)) == _PAGE_PWT)
+ pte = (pte & ~(_PAGE_PCD | _PAGE_PWT)) | _PAGE_PAT;
+ }
+
/*
* Unprivileged domains are allowed to do IOMAPpings for
* PCI passthrough, but not map ISA space. The ISA
@@ -1508,13 +1790,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 +1821,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)
{
@@ -1682,6 +1975,7 @@ static void *m2v(phys_addr_t maddr)
return __ka(m2p(maddr));
}
+/* Set the page permissions on an identity-mapped pages */
static void set_page_prot(void *addr, pgprot_t prot)
{
unsigned long pfn = __pa(addr) >> PAGE_SHIFT;
@@ -1697,6 +1991,9 @@ static __init void xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn)
unsigned ident_pte;
unsigned long pfn;
+ level1_ident_pgt = extend_brk(sizeof(pte_t) * LEVEL1_IDENT_ENTRIES,
+ PAGE_SIZE);
+
ident_pte = 0;
pfn = 0;
for (pmdidx = 0; pmdidx < PTRS_PER_PMD && pfn < max_pfn; pmdidx++) {
@@ -1707,7 +2004,7 @@ static __init void xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn)
pte_page = m2v(pmd[pmdidx].pmd);
else {
/* Check for free pte pages */
- if (ident_pte == ARRAY_SIZE(level1_ident_pgt))
+ if (ident_pte == LEVEL1_IDENT_ENTRIES)
break;
pte_page = &level1_ident_pgt[ident_pte];
@@ -1814,7 +2111,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");
@@ -1822,13 +2119,15 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
return pgd;
}
#else /* !CONFIG_X86_64 */
-static pmd_t level2_kernel_pgt[PTRS_PER_PMD] __page_aligned_bss;
+static RESERVE_BRK_ARRAY(pmd_t, level2_kernel_pgt, PTRS_PER_PMD);
__init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
unsigned long max_pfn)
{
pmd_t *kernel_pmd;
+ level2_kernel_pgt = extend_brk(sizeof(pmd_t *) * PTRS_PER_PMD, PAGE_SIZE);
+
max_pfn_mapped = PFN_DOWN(__pa(xen_start_info->pt_base) +
xen_start_info->nr_pt_frames * PAGE_SIZE +
512*1024);
@@ -1852,7 +2151,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");
@@ -1861,6 +2160,8 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
}
#endif /* CONFIG_X86_64 */
+static unsigned char dummy_mapping[PAGE_SIZE] __page_aligned_bss;
+
static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
{
pte_t pte;
@@ -1881,15 +2182,28 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
#else
case VSYSCALL_LAST_PAGE ... VSYSCALL_FIRST_PAGE:
#endif
-#ifdef CONFIG_X86_LOCAL_APIC
- case FIX_APIC_BASE: /* maps dummy local APIC */
-#endif
case FIX_TEXT_POKE0:
case FIX_TEXT_POKE1:
/* All local page mappings */
pte = pfn_pte(phys, prot);
break;
+#ifdef CONFIG_X86_LOCAL_APIC
+ case FIX_APIC_BASE: /* maps dummy local APIC */
+ pte = pfn_pte(PFN_DOWN(__pa(dummy_mapping)), PAGE_KERNEL);
+ break;
+#endif
+
+#ifdef CONFIG_X86_IO_APIC
+ case FIX_IO_APIC_BASE_0 ... FIX_IO_APIC_BASE_END:
+ /*
+ * We just don't map the IO APIC - all access is via
+ * hypercalls. Keep the address in the pte for reference.
+ */
+ pte = pfn_pte(PFN_DOWN(__pa(dummy_mapping)), PAGE_KERNEL);
+ break;
+#endif
+
case FIX_PARAVIRT_BOOTMAP:
/* This is an MFN, but it isn't an IO mapping from the
IO domain */
@@ -1914,6 +2228,29 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
#endif
}
+__init void xen_ident_map_ISA(void)
+{
+ unsigned long pa;
+
+ /*
+ * If we're dom0, then linear map the ISA machine addresses into
+ * the kernel's address space.
+ */
+ if (!xen_initial_domain())
+ return;
+
+ xen_raw_printk("Xen: setup ISA identity maps\n");
+
+ for (pa = ISA_START_ADDRESS; pa < ISA_END_ADDRESS; pa += PAGE_SIZE) {
+ pte_t pte = mfn_pte(PFN_DOWN(pa), PAGE_KERNEL_IO);
+
+ if (HYPERVISOR_update_va_mapping(PAGE_OFFSET + pa, pte, 0))
+ BUG();
+ }
+
+ xen_flush_tlb();
+}
+
static __init void xen_post_allocator_init(void)
{
pv_mmu_ops.set_pte = xen_set_pte;
@@ -1969,14 +2306,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,
@@ -2027,6 +2359,8 @@ void __init xen_init_mmu_ops(void)
pv_mmu_ops = xen_mmu_ops;
vmap_lazy_unmap = false;
+
+ memset(dummy_mapping, 0xff, PAGE_SIZE);
}
/* Protected by xen_reservation_lock. */
@@ -2259,6 +2593,72 @@ void __init xen_hvm_init_mmu_ops(void)
}
#endif
+#define REMAP_BATCH_SIZE 16
+
+struct remap_data {
+ unsigned long mfn;
+ pgprot_t prot;
+ struct mmu_update *mmu_update;
+};
+
+static int remap_area_mfn_pte_fn(pte_t *ptep, pgtable_t token,
+ unsigned long addr, void *data)
+{
+ struct remap_data *rmd = data;
+ pte_t pte = pte_mkspecial(pfn_pte(rmd->mfn++, rmd->prot));
+
+ rmd->mmu_update->ptr = arbitrary_virt_to_machine(ptep).maddr;
+ rmd->mmu_update->val = pte_val_ma(pte);
+ rmd->mmu_update++;
+
+ return 0;
+}
+
+int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
+ unsigned long addr,
+ unsigned long mfn, int nr,
+ pgprot_t prot, unsigned domid)
+{
+ struct remap_data rmd;
+ struct mmu_update mmu_update[REMAP_BATCH_SIZE];
+ int batch;
+ unsigned long range;
+ int err = 0;
+
+ prot = __pgprot(pgprot_val(prot) | _PAGE_IOMAP);
+
+ vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
+
+ rmd.mfn = mfn;
+ rmd.prot = prot;
+
+ while (nr) {
+ batch = min(REMAP_BATCH_SIZE, nr);
+ range = (unsigned long)batch << PAGE_SHIFT;
+
+ rmd.mmu_update = mmu_update;
+ err = apply_to_page_range(vma->vm_mm, addr, range,
+ remap_area_mfn_pte_fn, &rmd);
+ if (err)
+ goto out;
+
+ err = -EFAULT;
+ if (HYPERVISOR_mmu_update(mmu_update, batch, NULL, domid) < 0)
+ goto out;
+
+ nr -= batch;
+ addr += range;
+ }
+
+ err = 0;
+out:
+
+ flush_tlb_all();
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range);
+
#ifdef CONFIG_XEN_DEBUG_FS
static struct dentry *d_mmu_debug;
diff --git a/arch/x86/xen/mmu.h b/arch/x86/xen/mmu.h
index fa938c4aa2f7..537bb9aab777 100644
--- a/arch/x86/xen/mmu.h
+++ b/arch/x86/xen/mmu.h
@@ -12,7 +12,6 @@ enum pt_level {
bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn);
-bool install_p2mtop_page(unsigned long pfn, unsigned long *p);
void set_pte_mfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags);
diff --git a/arch/x86/xen/pci-swiotlb-xen.c b/arch/x86/xen/pci-swiotlb-xen.c
index a013ec9d0c54..bfd0632fe65e 100644
--- a/arch/x86/xen/pci-swiotlb-xen.c
+++ b/arch/x86/xen/pci-swiotlb-xen.c
@@ -1,10 +1,12 @@
/* Glue code to lib/swiotlb-xen.c */
#include <linux/dma-mapping.h>
+#include <linux/pci.h>
#include <xen/swiotlb-xen.h>
#include <asm/xen/hypervisor.h>
#include <xen/xen.h>
+#include <asm/iommu_table.h>
int xen_swiotlb __read_mostly;
@@ -54,5 +56,12 @@ void __init pci_xen_swiotlb_init(void)
if (xen_swiotlb) {
xen_swiotlb_init(1);
dma_ops = &xen_swiotlb_dma_ops;
+
+ /* Make sure ACS will be enabled */
+ pci_request_acs();
}
}
+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..b1dbdaa23ecc 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>
@@ -17,8 +18,10 @@
#include <asm/xen/hypervisor.h>
#include <asm/xen/hypercall.h>
+#include <xen/xen.h>
#include <xen/page.h>
#include <xen/interface/callback.h>
+#include <xen/interface/memory.h>
#include <xen/interface/physdev.h>
#include <xen/interface/memory.h>
#include <xen/features.h>
@@ -33,6 +36,39 @@ extern void xen_sysenter_target(void);
extern void xen_syscall_target(void);
extern void xen_syscall32_target(void);
+/* Amount of extra memory space we add to the e820 ranges */
+phys_addr_t xen_extra_mem_start, xen_extra_mem_size;
+
+/*
+ * The maximum amount of extra memory compared to the base size. The
+ * main scaling factor is the size of struct page. At extreme ratios
+ * of base:extra, all the base memory can be filled with page
+ * structures for the extra memory, leaving no space for anything
+ * else.
+ *
+ * 10x seems like a reasonable balance between scaling flexibility and
+ * leaving a practically usable system.
+ */
+#define EXTRA_MEM_RATIO (10)
+
+static __init void xen_add_extra_mem(unsigned long pages)
+{
+ u64 size = (u64)pages * PAGE_SIZE;
+ u64 extra_start = xen_extra_mem_start + xen_extra_mem_size;
+
+ if (!pages)
+ return;
+
+ e820_add_region(extra_start, size, E820_RAM);
+ sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
+
+ memblock_x86_reserve_range(extra_start, extra_start + size, "XEN EXTRA");
+
+ xen_extra_mem_size += size;
+
+ xen_max_p2m_pfn = PFN_DOWN(extra_start + size);
+}
+
static unsigned long __init xen_release_chunk(phys_addr_t start_addr,
phys_addr_t end_addr)
{
@@ -104,21 +140,73 @@ static unsigned long __init xen_return_unused_memory(unsigned long max_pfn,
/**
* machine_specific_memory_setup - Hook for machine specific memory setup.
**/
-
char * __init xen_memory_setup(void)
{
+ static struct e820entry map[E820MAX] __initdata;
+
unsigned long max_pfn = xen_start_info->nr_pages;
+ unsigned long long mem_end;
+ int rc;
+ struct xen_memory_map memmap;
+ unsigned long extra_pages = 0;
+ unsigned long extra_limit;
+ int i;
+ int op;
max_pfn = min(MAX_DOMAIN_PAGES, max_pfn);
+ mem_end = PFN_PHYS(max_pfn);
+
+ memmap.nr_entries = E820MAX;
+ set_xen_guest_handle(memmap.buffer, map);
+
+ op = xen_initial_domain() ?
+ XENMEM_machine_memory_map :
+ XENMEM_memory_map;
+ rc = HYPERVISOR_memory_op(op, &memmap);
+ if (rc == -ENOSYS) {
+ memmap.nr_entries = 1;
+ map[0].addr = 0ULL;
+ map[0].size = mem_end;
+ /* 8MB slack (to balance backend allocations). */
+ map[0].size += 8ULL << 20;
+ map[0].type = E820_RAM;
+ rc = 0;
+ }
+ BUG_ON(rc);
e820.nr_map = 0;
+ xen_extra_mem_start = mem_end;
+ for (i = 0; i < memmap.nr_entries; i++) {
+ unsigned long long end = map[i].addr + map[i].size;
+
+ if (map[i].type == E820_RAM) {
+ if (map[i].addr < mem_end && end > mem_end) {
+ /* Truncate region to max_mem. */
+ u64 delta = end - mem_end;
- e820_add_region(0, PFN_PHYS((u64)max_pfn), E820_RAM);
+ map[i].size -= delta;
+ extra_pages += PFN_DOWN(delta);
+
+ end = mem_end;
+ }
+ }
+
+ if (end > xen_extra_mem_start)
+ xen_extra_mem_start = end;
+
+ /* If region is non-RAM or below mem_end, add what remains */
+ if ((map[i].type != E820_RAM || map[i].addr < mem_end) &&
+ map[i].size > 0)
+ e820_add_region(map[i].addr, map[i].size, map[i].type);
+ }
/*
* Even though this is normal, usable memory under Xen, reserve
* ISA memory anyway because too many things think they can poke
* about in there.
+ *
+ * In a dom0 kernel, this region is identity mapped with the
+ * hardware ISA area, so it really is out of bounds.
*/
e820_add_region(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS,
E820_RESERVED);
@@ -129,13 +217,35 @@ 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");
sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
- xen_return_unused_memory(xen_start_info->nr_pages, &e820);
+ extra_pages += xen_return_unused_memory(xen_start_info->nr_pages, &e820);
+
+ /*
+ * Clamp the amount of extra memory to a EXTRA_MEM_RATIO
+ * factor the base size. On non-highmem systems, the base
+ * size is the full initial memory allocation; on highmem it
+ * is limited to the max size of lowmem, so that it doesn't
+ * get completely filled.
+ *
+ * In principle there could be a problem in lowmem systems if
+ * the initial memory is also very large with respect to
+ * lowmem, but we won't try to deal with that here.
+ */
+ extra_limit = min(EXTRA_MEM_RATIO * min(max_pfn, PFN_DOWN(MAXMEM)),
+ max_pfn + extra_pages);
+
+ if (extra_limit >= max_pfn)
+ extra_pages = extra_limit - max_pfn;
+ else
+ extra_pages = 0;
+
+ if (!xen_initial_domain())
+ xen_add_extra_mem(extra_pages);
return "Xen";
}
@@ -260,7 +370,5 @@ void __init xen_arch_setup(void)
pm_idle = xen_idle;
- paravirt_disable_iospace();
-
fiddle_vdso();
}
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 25f232b18a82..72a4c7959045 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -28,6 +28,7 @@
#include <asm/xen/interface.h>
#include <asm/xen/hypercall.h>
+#include <xen/xen.h>
#include <xen/page.h>
#include <xen/events.h>
@@ -156,11 +157,35 @@ static void __init xen_fill_possible_map(void)
{
int i, rc;
+ if (xen_initial_domain())
+ return;
+
+ for (i = 0; i < nr_cpu_ids; i++) {
+ rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL);
+ if (rc >= 0) {
+ num_processors++;
+ set_cpu_possible(i, true);
+ }
+ }
+}
+
+static void __init xen_filter_cpu_maps(void)
+{
+ int i, rc;
+
+ if (!xen_initial_domain())
+ return;
+
+ num_processors = 0;
+ disabled_cpus = 0;
for (i = 0; i < nr_cpu_ids; i++) {
rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL);
if (rc >= 0) {
num_processors++;
set_cpu_possible(i, true);
+ } else {
+ set_cpu_possible(i, false);
+ set_cpu_present(i, false);
}
}
}
@@ -174,6 +199,7 @@ static void __init xen_smp_prepare_boot_cpu(void)
old memory can be recycled */
make_lowmem_page_readwrite(xen_initial_gdt);
+ xen_filter_cpu_maps();
xen_setup_vcpu_info_placement();
}
@@ -400,9 +426,9 @@ static void stop_self(void *v)
BUG();
}
-static void xen_smp_send_stop(void)
+static void xen_stop_other_cpus(int wait)
{
- smp_call_function(stop_self, NULL, 0);
+ smp_call_function(stop_self, NULL, wait);
}
static void xen_smp_send_reschedule(int cpu)
@@ -470,7 +496,7 @@ static const struct smp_ops xen_smp_ops __initdata = {
.cpu_disable = xen_cpu_disable,
.play_dead = xen_play_dead,
- .smp_send_stop = xen_smp_send_stop,
+ .stop_other_cpus = xen_stop_other_cpus,
.smp_send_reschedule = xen_smp_send_reschedule,
.send_call_func_ipi = xen_smp_send_call_function_ipi,
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/xen-ops.h b/arch/x86/xen/xen-ops.h
index 7c8ab86163e9..64044747348e 100644
--- a/arch/x86/xen/xen-ops.h
+++ b/arch/x86/xen/xen-ops.h
@@ -30,6 +30,9 @@ void xen_setup_machphys_mapping(void);
pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn);
void xen_ident_map_ISA(void);
void xen_reserve_top(void);
+extern unsigned long xen_max_p2m_pfn;
+
+void xen_set_pat(u64);
char * __init xen_memory_setup(void);
void __init xen_arch_setup(void);
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 0859bfd8ae93..d373d159e75e 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -1,8 +1,3 @@
-# For a description of the syntax of this configuration file,
-# see Documentation/kbuild/kconfig-language.txt.
-
-mainmenu "Linux/Xtensa Kernel Configuration"
-
config FRAME_POINTER
def_bool n
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/pgtable.h b/arch/xtensa/include/asm/pgtable.h
index 76bf35554117..b03c043ce75b 100644
--- a/arch/xtensa/include/asm/pgtable.h
+++ b/arch/xtensa/include/asm/pgtable.h
@@ -324,10 +324,7 @@ ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
#define pte_offset_kernel(dir,addr) \
((pte_t*) pmd_page_vaddr(*(dir)) + pte_index(addr))
#define pte_offset_map(dir,addr) pte_offset_kernel((dir),(addr))
-#define pte_offset_map_nested(dir,addr) pte_offset_kernel((dir),(addr))
-
#define pte_unmap(pte) do { } while (0)
-#define pte_unmap_nested(pte) do { } while (0)
/*
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)
diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c
index 9d4e1ceb3f09..c72c9473ef99 100644
--- a/arch/xtensa/kernel/ptrace.c
+++ b/arch/xtensa/kernel/ptrace.c
@@ -256,9 +256,11 @@ int ptrace_pokeusr(struct task_struct *child, long regno, long val)
return 0;
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int ret = -EPERM;
+ void __user *datap = (void __user *) data;
switch (request) {
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -267,7 +269,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
case PTRACE_PEEKUSR: /* read register specified by addr. */
- ret = ptrace_peekusr(child, addr, (void __user *) data);
+ ret = ptrace_peekusr(child, addr, datap);
break;
case PTRACE_POKETEXT: /* write the word at location addr. */
@@ -280,19 +282,19 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
case PTRACE_GETREGS:
- ret = ptrace_getregs(child, (void __user *) data);
+ ret = ptrace_getregs(child, datap);
break;
case PTRACE_SETREGS:
- ret = ptrace_setregs(child, (void __user *) data);
+ ret = ptrace_setregs(child, datap);
break;
case PTRACE_GETXTREGS:
- ret = ptrace_getxregs(child, (void __user *) data);
+ ret = ptrace_getxregs(child, datap);
break;
case PTRACE_SETXTREGS:
- ret = ptrace_setxregs(child, (void __user *) data);
+ ret = ptrace_setxregs(child, datap);
break;
default: